summaryrefslogtreecommitdiffstats
path: root/third_party/webkit/PerformanceTests/MotionMark/resources/extensions.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 19:33:14 +0000
commit36d22d82aa202bb199967e9512281e9a53db42c9 (patch)
tree105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/webkit/PerformanceTests/MotionMark/resources/extensions.js
parentInitial commit. (diff)
downloadfirefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz
firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/webkit/PerformanceTests/MotionMark/resources/extensions.js')
-rw-r--r--third_party/webkit/PerformanceTests/MotionMark/resources/extensions.js670
1 files changed, 670 insertions, 0 deletions
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;
+ }
+});