summaryrefslogtreecommitdiffstats
path: root/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/flight/lib/registry.js
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/flight/lib/registry.js220
1 files changed, 220 insertions, 0 deletions
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/flight/lib/registry.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/flight/lib/registry.js
new file mode 100644
index 0000000000..baaa3b10a7
--- /dev/null
+++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/flight/lib/registry.js
@@ -0,0 +1,220 @@
+// ==========================================
+// Copyright 2013 Twitter, Inc
+// Licensed under The MIT License
+// http://opensource.org/licenses/MIT
+// ==========================================
+
+"use strict";
+
+define(
+
+ [
+ './utils'
+ ],
+
+ function (util) {
+
+ function parseEventArgs(instance, args) {
+ var element, type, callback;
+ var end = args.length;
+
+ if (typeof args[end - 1] === 'function') {
+ end -= 1;
+ callback = args[end];
+ }
+
+ if (typeof args[end - 1] === 'object') {
+ end -= 1;
+ }
+
+ if (end == 2) {
+ element = args[0];
+ type = args[1];
+ } else {
+ element = instance.node;
+ type = args[0];
+ }
+
+ return {
+ element: element,
+ type: type,
+ callback: callback
+ };
+ }
+
+ function matchEvent(a, b) {
+ return (
+ (a.element == b.element) &&
+ (a.type == b.type) &&
+ (b.callback == null || (a.callback == b.callback))
+ );
+ }
+
+ function Registry() {
+
+ var registry = this;
+
+ (this.reset = function() {
+ this.components = [];
+ this.allInstances = {};
+ this.events = [];
+ }).call(this);
+
+ function ComponentInfo(component) {
+ this.component = component;
+ this.attachedTo = [];
+ this.instances = {};
+
+ this.addInstance = function(instance) {
+ var instanceInfo = new InstanceInfo(instance);
+ this.instances[instance.identity] = instanceInfo;
+ this.attachedTo.push(instance.node);
+
+ return instanceInfo;
+ }
+
+ this.removeInstance = function(instance) {
+ delete this.instances[instance.identity];
+ var indexOfNode = this.attachedTo.indexOf(instance.node);
+ (indexOfNode > -1) && this.attachedTo.splice(indexOfNode, 1);
+
+ if (!this.instances.length) {
+ //if I hold no more instances remove me from registry
+ registry.removeComponentInfo(this);
+ }
+ }
+
+ this.isAttachedTo = function(node) {
+ return this.attachedTo.indexOf(node) > -1;
+ }
+ }
+
+ function InstanceInfo(instance) {
+ this.instance = instance;
+ this.events = [];
+
+ this.addBind = function(event) {
+ this.events.push(event);
+ registry.events.push(event);
+ };
+
+ this.removeBind = function(event) {
+ for (var i = 0, e; e = this.events[i]; i++) {
+ if (matchEvent(e, event)) {
+ this.events.splice(i, 1);
+ }
+ }
+ }
+ }
+
+ this.addInstance = function(instance) {
+ var component = this.findComponentInfo(instance);
+
+ if (!component) {
+ component = new ComponentInfo(instance.constructor);
+ this.components.push(component);
+ }
+
+ var inst = component.addInstance(instance);
+
+ this.allInstances[instance.identity] = inst;
+
+ return component;
+ };
+
+ this.removeInstance = function(instance) {
+ var index, instInfo = this.findInstanceInfo(instance);
+
+ //remove from component info
+ var componentInfo = this.findComponentInfo(instance);
+ componentInfo && componentInfo.removeInstance(instance);
+
+ //remove from registry
+ delete this.allInstances[instance.identity];
+ };
+
+ this.removeComponentInfo = function(componentInfo) {
+ var index = this.components.indexOf(componentInfo);
+ (index > -1) && this.components.splice(index, 1);
+ };
+
+ this.findComponentInfo = function(which) {
+ var component = which.attachTo ? which : which.constructor;
+
+ for (var i = 0, c; c = this.components[i]; i++) {
+ if (c.component === component) {
+ return c;
+ }
+ }
+
+ return null;
+ };
+
+ this.findInstanceInfo = function(instance) {
+ return this.allInstances[instance.identity] || null;
+ };
+
+ this.findInstanceInfoByNode = function(node) {
+ var result = [];
+ Object.keys(this.allInstances).forEach(function(k) {
+ var thisInstanceInfo = this.allInstances[k];
+ if(thisInstanceInfo.instance.node === node) {
+ result.push(thisInstanceInfo);
+ }
+ }, this);
+ return result;
+ };
+
+ this.on = function(componentOn) {
+ var instance = registry.findInstanceInfo(this), boundCallback;
+
+ // unpacking arguments by hand benchmarked faster
+ var l = arguments.length, i = 1;
+ var otherArgs = new Array(l - 1);
+ for (; i < l; i++) otherArgs[i - 1] = arguments[i];
+
+ if (instance) {
+ boundCallback = componentOn.apply(null, otherArgs);
+ if (boundCallback) {
+ otherArgs[otherArgs.length-1] = boundCallback;
+ }
+ var event = parseEventArgs(this, otherArgs);
+ instance.addBind(event);
+ }
+ };
+
+ this.off = function(el, type, callback) {
+ var event = parseEventArgs(this, arguments),
+ instance = registry.findInstanceInfo(this);
+
+ if (instance) {
+ instance.removeBind(event);
+ }
+ };
+
+ //debug tools may want to add advice to trigger
+ if (window.DEBUG && DEBUG.enabled) {
+ registry.trigger = new Function;
+ }
+
+ this.teardown = function() {
+ registry.removeInstance(this);
+ };
+
+ this.withRegistration = function() {
+ this.before('initialize', function() {
+ registry.addInstance(this);
+ });
+
+ this.around('on', registry.on);
+ this.after('off', registry.off);
+ //debug tools may want to add advice to trigger
+ window.DEBUG && DEBUG.enabled && this.after('trigger', registry.trigger);
+ this.after('teardown', {obj:registry, fnName:'teardown'});
+ };
+
+ }
+
+ return new Registry;
+ }
+);