From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- .../MotionMark/resources/extensions.js | 670 +++++++++++++++++++++ 1 file changed, 670 insertions(+) create mode 100644 third_party/webkit/PerformanceTests/MotionMark/resources/extensions.js (limited to 'third_party/webkit/PerformanceTests/MotionMark/resources/extensions.js') diff --git a/third_party/webkit/PerformanceTests/MotionMark/resources/extensions.js b/third_party/webkit/PerformanceTests/MotionMark/resources/extensions.js new file mode 100644 index 0000000000..fb9d500877 --- /dev/null +++ b/third_party/webkit/PerformanceTests/MotionMark/resources/extensions.js @@ -0,0 +1,670 @@ +Utilities = +{ + _parse: function(str, sep) + { + var output = {}; + str.split(sep).forEach(function(part) { + var item = part.split("="); + var value = decodeURIComponent(item[1]); + if (value[0] == "'" ) + output[item[0]] = value.substr(1, value.length - 2); + else + output[item[0]] = value; + }); + return output; + }, + + parseParameters: function() + { + return this._parse(window.location.search.substr(1), "&"); + }, + + parseArguments: function(str) + { + return this._parse(str, " "); + }, + + extendObject: function(obj1, obj2) + { + for (var attrname in obj2) + obj1[attrname] = obj2[attrname]; + return obj1; + }, + + copyObject: function(obj) + { + return this.extendObject({}, obj); + }, + + mergeObjects: function(obj1, obj2) + { + return this.extendObject(this.copyObject(obj1), obj2); + }, + + createClass: function(classConstructor, classMethods) + { + classConstructor.prototype = classMethods; + return classConstructor; + }, + + createSubclass: function(superclass, classConstructor, classMethods) + { + classConstructor.prototype = Object.create(superclass.prototype); + classConstructor.prototype.constructor = classConstructor; + if (classMethods) + Utilities.extendObject(classConstructor.prototype, classMethods); + return classConstructor; + }, + + createElement: function(name, attrs, parentElement) + { + var element = document.createElement(name); + + for (var key in attrs) + element.setAttribute(key, attrs[key]); + + parentElement.appendChild(element); + return element; + }, + + createSVGElement: function(name, attrs, xlinkAttrs, parentElement) + { + const svgNamespace = "http://www.w3.org/2000/svg"; + const xlinkNamespace = "http://www.w3.org/1999/xlink"; + + var element = document.createElementNS(svgNamespace, name); + + for (var key in attrs) + element.setAttribute(key, attrs[key]); + + for (var key in xlinkAttrs) + element.setAttributeNS(xlinkNamespace, key, xlinkAttrs[key]); + + parentElement.appendChild(element); + return element; + }, + + browserPrefix: function() + { + // Get the HTML element's CSSStyleDeclaration + var styles = window.getComputedStyle(document.documentElement, ''); + + // Convert the styles list to an array + var stylesArray = Array.prototype.slice.call(styles); + + // Concatenate all the styles in one big string + var stylesString = stylesArray.join(''); + + // Search the styles string for a known prefix type, settle on Opera if none is found. + var prefixes = stylesString.match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o']); + + // prefixes has two elements; e.g. for webkit it has ['-webkit-', 'webkit']; + var prefix = prefixes[1]; + + // Have 'O' before 'Moz' in the string so it is matched first. + var dom = ('WebKit|O|Moz|MS').match(new RegExp(prefix, 'i'))[0]; + + // Return all the required prefixes. + return { + dom: dom, + lowercase: prefix, + css: '-' + prefix + '-', + js: prefix[0].toUpperCase() + prefix.substr(1) + }; + }, + + setElementPrefixedProperty: function(element, property, value) + { + element.style[property] = element.style[this.browserPrefix().js + property[0].toUpperCase() + property.substr(1)] = value; + }, + + stripNonASCIICharacters: function(inputString) + { + return inputString.replace(/[ .,]/g, ''); + }, + + convertObjectToQueryString: function(object) + { + var queryString = []; + for (var property in object) { + if (object.hasOwnProperty(property)) + queryString.push(encodeURIComponent(property) + "=" + encodeURIComponent(object[property])); + } + return "?" + queryString.join("&"); + }, + + convertQueryStringToObject: function(queryString) + { + queryString = queryString.substring(1); + if (!queryString) + return null; + + var object = {}; + queryString.split("&").forEach(function(parameter) { + var components = parameter.split("="); + object[components[0]] = components[1]; + }); + return object; + }, + + progressValue: function(value, min, max) + { + return (value - min) / (max - min); + }, + + lerp: function(value, min, max) + { + return min + (max - min) * value; + }, + + toFixedNumber: function(number, precision) + { + if (number.toFixed) + return Number(number.toFixed(precision)); + return number; + } +}; + +Array.prototype.swap = function(i, j) +{ + var t = this[i]; + this[i] = this[j]; + this[j] = t; + return this; +} + +if (!Array.prototype.fill) { + Array.prototype.fill = function(value) { + if (this == null) + throw new TypeError('Array.prototype.fill called on null or undefined'); + + var object = Object(this); + var len = parseInt(object.length, 10); + var start = arguments[1]; + var relativeStart = parseInt(start, 10) || 0; + var k = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len); + var end = arguments[2]; + var relativeEnd = end === undefined ? len : (parseInt(end) || 0) ; + var final = relativeEnd < 0 ? Math.max(len + relativeEnd, 0) : Math.min(relativeEnd, len); + + for (; k < final; k++) + object[k] = value; + + return object; + }; +} + +if (!Array.prototype.find) { + Array.prototype.find = function(predicate) { + if (this == null) + throw new TypeError('Array.prototype.find called on null or undefined'); + if (typeof predicate !== 'function') + throw new TypeError('predicate must be a function'); + + var list = Object(this); + var length = list.length >>> 0; + var thisArg = arguments[1]; + var value; + + for (var i = 0; i < length; i++) { + value = list[i]; + if (predicate.call(thisArg, value, i, list)) + return value; + } + return undefined; + }; +} + +Array.prototype.shuffle = function() +{ + for (var index = this.length - 1; index >= 0; --index) { + var randomIndex = Math.floor(Math.random() * (index + 1)); + this.swap(index, randomIndex); + } + return this; +} + +Point = Utilities.createClass( + function(x, y) + { + this.x = x; + this.y = y; + }, { + + // Used when the point object is used as a size object. + get width() + { + return this.x; + }, + + // Used when the point object is used as a size object. + get height() + { + return this.y; + }, + + // Used when the point object is used as a size object. + get center() + { + return new Point(this.x / 2, this.y / 2); + }, + + str: function() + { + return "x = " + this.x + ", y = " + this.y; + }, + + add: function(other) + { + if(isNaN(other.x)) + return new Point(this.x + other, this.y + other); + return new Point(this.x + other.x, this.y + other.y); + }, + + subtract: function(other) + { + if(isNaN(other.x)) + return new Point(this.x - other, this.y - other); + return new Point(this.x - other.x, this.y - other.y); + }, + + multiply: function(other) + { + if(isNaN(other.x)) + return new Point(this.x * other, this.y * other); + return new Point(this.x * other.x, this.y * other.y); + }, + + move: function(angle, velocity, timeDelta) + { + return this.add(Point.pointOnCircle(angle, velocity * (timeDelta / 1000))); + }, + + length: function() { + return Math.sqrt( this.x * this.x + this.y * this.y ); + }, + + normalize: function() { + var l = Math.sqrt( this.x * this.x + this.y * this.y ); + this.x /= l; + this.y /= l; + return this; + } +}); + +Utilities.extendObject(Point, { + zero: new Point(0, 0), + + pointOnCircle: function(angle, radius) + { + return new Point(radius * Math.cos(angle), radius * Math.sin(angle)); + }, + + pointOnEllipse: function(angle, radiuses) + { + return new Point(radiuses.x * Math.cos(angle), radiuses.y * Math.sin(angle)); + }, + + elementClientSize: function(element) + { + var rect = element.getBoundingClientRect(); + return new Point(rect.width, rect.height); + } +}); + +Insets = Utilities.createClass( + function(top, right, bottom, left) + { + this.top = top; + this.right = right; + this.bottom = bottom; + this.left = left; + }, { + + get width() + { + return this.left + this.right; + }, + + get height() + { + return this.top + this.bottom; + }, + + get size() + { + return new Point(this.width, this.height); + } +}); + +Insets.elementPadding = function(element) +{ + var styles = window.getComputedStyle(element); + return new Insets( + parseFloat(styles.paddingTop), + parseFloat(styles.paddingRight), + parseFloat(styles.paddingBottom), + parseFloat(styles.paddingTop)); +} + +UnitBezier = Utilities.createClass( + function(point1, point2) + { + // First and last points in the Bézier curve are assumed to be (0,0) and (!,1) + this._c = point1.multiply(3); + this._b = point2.subtract(point1).multiply(3).subtract(this._c); + this._a = new Point(1, 1).subtract(this._c).subtract(this._b); + }, { + + epsilon: 1e-5, + derivativeEpsilon: 1e-6, + + solve: function(x) + { + return this.sampleY(this.solveForT(x)); + }, + + sampleX: function(t) + { + return ((this._a.x * t + this._b.x) * t + this._c.x) * t; + }, + + sampleY: function(t) + { + return ((this._a.y * t + this._b.y) * t + this._c.y) * t; + }, + + sampleDerivativeX: function(t) + { + return(3 * this._a.x * t + 2 * this._b.x) * t + this._c.x; + }, + + solveForT: function(x) + { + var t0, t1, t2, x2, d2, i; + + for (t2 = x, i = 0; i < 8; ++i) { + x2 = this.sampleX(t2) - x; + if (Math.abs(x2) < this.epsilon) + return t2; + d2 = this.sampleDerivativeX(t2); + if (Math.abs(d2) < this.derivativeEpsilon) + break; + t2 = t2 - x2 / d2; + } + + t0 = 0; + t1 = 1; + t2 = x; + + if (t2 < t0) + return t0; + if (t2 > t1) + return t1; + + while (t0 < t1) { + x2 = this.sampleX(t2); + if (Math.abs(x2 - x) < this.epsilon) + return t2; + if (x > x2) + t0 = t2; + else + t1 = t2; + t2 = (t1 - t0) * .5 + t0; + } + + return t2; + } +}); + +SimplePromise = Utilities.createClass( + function() + { + this._chainedPromise = null; + this._callback = null; + }, { + + then: function (callback) + { + if (this._callback) + throw "SimplePromise doesn't support multiple calls to then"; + + this._callback = callback; + this._chainedPromise = new SimplePromise; + + if (this._resolved) + this.resolve(this._resolvedValue); + + return this._chainedPromise; + }, + + resolve: function (value) + { + if (!this._callback) { + this._resolved = true; + this._resolvedValue = value; + return; + } + + var result = this._callback(value); + if (result instanceof SimplePromise) { + var chainedPromise = this._chainedPromise; + result.then(function (result) { chainedPromise.resolve(result); }); + } else + this._chainedPromise.resolve(result); + } +}); + +var Heap = Utilities.createClass( + function(maxSize, compare) + { + this._maxSize = maxSize; + this._compare = compare; + this._size = 0; + this._values = new Array(this._maxSize); + }, { + + // This is a binary heap represented in an array. The root element is stored + // in the first element in the array. The root is followed by its two children. + // Then its four grandchildren and so on. So every level in the binary heap is + // doubled in the following level. Here is an example of the node indices and + // how they are related to their parents and children. + // =========================================================================== + // 0 1 2 3 4 5 6 + // PARENT -1 0 0 1 1 2 2 + // LEFT 1 3 5 7 9 11 13 + // RIGHT 2 4 6 8 10 12 14 + // =========================================================================== + _parentIndex: function(i) + { + return i > 0 ? Math.floor((i - 1) / 2) : -1; + }, + + _leftIndex: function(i) + { + var leftIndex = i * 2 + 1; + return leftIndex < this._size ? leftIndex : -1; + }, + + _rightIndex: function(i) + { + var rightIndex = i * 2 + 2; + return rightIndex < this._size ? rightIndex : -1; + }, + + // Return the child index that may violate the heap property at index i. + _childIndex: function(i) + { + var left = this._leftIndex(i); + var right = this._rightIndex(i); + + if (left != -1 && right != -1) + return this._compare(this._values[left], this._values[right]) > 0 ? left : right; + + return left != -1 ? left : right; + }, + + init: function() + { + this._size = 0; + }, + + top: function() + { + return this._size ? this._values[0] : NaN; + }, + + push: function(value) + { + if (this._size == this._maxSize) { + // If size is bounded and the new value can be a parent of the top() + // if the size were unbounded, just ignore the new value. + if (this._compare(value, this.top()) > 0) + return; + this.pop(); + } + this._values[this._size++] = value; + this._bubble(this._size - 1); + }, + + pop: function() + { + if (!this._size) + return NaN; + + this._values[0] = this._values[--this._size]; + this._sink(0); + }, + + _bubble: function(i) + { + // Fix the heap property at index i given that parent is the only node that + // may violate the heap property. + for (var pi = this._parentIndex(i); pi != -1; i = pi, pi = this._parentIndex(pi)) { + if (this._compare(this._values[pi], this._values[i]) > 0) + break; + + this._values.swap(pi, i); + } + }, + + _sink: function(i) + { + // Fix the heap property at index i given that each of the left and the right + // sub-trees satisfies the heap property. + for (var ci = this._childIndex(i); ci != -1; i = ci, ci = this._childIndex(ci)) { + if (this._compare(this._values[i], this._values[ci]) > 0) + break; + + this._values.swap(ci, i); + } + }, + + str: function() + { + var out = "Heap[" + this._size + "] = ["; + for (var i = 0; i < this._size; ++i) { + out += this._values[i]; + if (i < this._size - 1) + out += ", "; + } + return out + "]"; + }, + + values: function(size) { + // Return the last "size" heap elements values. + var values = this._values.slice(0, this._size); + return values.sort(this._compare).slice(0, Math.min(size, this._size)); + } +}); + +Utilities.extendObject(Heap, { + createMinHeap: function(maxSize) + { + return new Heap(maxSize, function(a, b) { return b - a; }); + }, + + createMaxHeap: function(maxSize) { + return new Heap(maxSize, function(a, b) { return a - b; }); + } +}); + +var SampleData = Utilities.createClass( + function(fieldMap, data) + { + this.fieldMap = fieldMap || {}; + this.data = data || []; + }, { + + get length() + { + return this.data.length; + }, + + addField: function(name, index) + { + this.fieldMap[name] = index; + }, + + push: function(datum) + { + this.data.push(datum); + }, + + sort: function(sortFunction) + { + this.data.sort(sortFunction); + }, + + slice: function(begin, end) + { + return new SampleData(this.fieldMap, this.data.slice(begin, end)); + }, + + forEach: function(iterationFunction) + { + this.data.forEach(iterationFunction); + }, + + createDatum: function() + { + return []; + }, + + getFieldInDatum: function(datum, fieldName) + { + if (typeof datum === 'number') + datum = this.data[datum]; + return datum[this.fieldMap[fieldName]]; + }, + + setFieldInDatum: function(datum, fieldName, value) + { + if (typeof datum === 'number') + datum = this.data[datum]; + return datum[this.fieldMap[fieldName]] = value; + }, + + at: function(index) + { + return this.data[index]; + }, + + toArray: function() + { + var array = []; + + this.data.forEach(function(datum) { + var newDatum = {}; + array.push(newDatum); + + for (var fieldName in this.fieldMap) { + var value = this.getFieldInDatum(datum, fieldName); + if (value !== null && value !== undefined) + newDatum[fieldName] = value; + } + }, this); + + return array; + } +}); -- cgit v1.2.3