diff --git a/js/libs/flight/.bower.json b/js/libs/flight/.bower.json deleted file mode 100644 index 67cb940..0000000 --- a/js/libs/flight/.bower.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "flight", - "description": "Clientside component infrastructure", - "main": "lib/index.js", - "version": "1.1.4", - "ignore": [ - "doc", - "tools", - "test", - ".gitignore", - ".travis.yml", - "CHANGELOG.md", - "CONTRIBUTING.md", - "Makefile", - "karma.conf.js", - "package.json" - ], - "dependencies": { - "es5-shim": "2.0.0", - "jquery": ">=1.8.0" - }, - "homepage": "https://github.com/flightjs/flight", - "_release": "1.1.4", - "_resolution": { - "type": "version", - "tag": "v1.1.4", - "commit": "5da831ba9026330b692ecf5668cad8832f1f19cd" - }, - "_source": "git://github.com/flightjs/flight.git", - "_target": "~1.1.4", - "_originalSource": "flight", - "_direct": true -} \ No newline at end of file diff --git a/js/libs/flight/LICENSE b/js/libs/flight/LICENSE deleted file mode 100644 index 0ea0689..0000000 --- a/js/libs/flight/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2013-2014 Twitter, Inc and others - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/js/libs/flight/README.md b/js/libs/flight/README.md deleted file mode 100644 index 5825758..0000000 --- a/js/libs/flight/README.md +++ /dev/null @@ -1,242 +0,0 @@ -# Flight - -[![Build Status](https://travis-ci.org/flightjs/flight.png?branch=master)](http://travis-ci.org/flightjs/flight) - -[Flight](http://flightjs.github.io/) is a lightweight, component-based, -event-driven JavaScript framework that maps behavior to DOM nodes. It was -created at Twitter, and is used by the [twitter.com](https://twitter.com/) and -[TweetDeck](https://web.tweetdeck.com/) web applications. - -* [Website](http://flightjs.github.io/) -* [API documentation](doc/README.md) -* [Flight example app](http://flightjs.github.io/example-app/) ([Source](https://github.com/flightjs/example-app)) -* [Flight's Google Group](https://groups.google.com/forum/?fromgroups#!forum/twitter-flight) -* [Flight on Twitter](https://twitter.com/flight) - - -## Why Flight? - -Flight is only ~5K minified and gzipped. It's built upon jQuery, and has -first-class support for Asynchronous Module Definition (AMD) and [Bower](http://bower.io/). - -Flight components are highly portable and easily testable. This is because a -Flight component (and its API) is entirely decoupled from other components. -Flight components communicate only by triggering and subscribing to events. - -Flight also includes a simple and safe -[mixin](https://javascriptweblog.wordpress.com/2011/05/31/a-fresh-look-at-javascript-mixins/) -infrastructure, allowing components to be easily extended with minimal -boilerplate. - - -## Development tools - -Flight has supporting projects that provide everything you need to setup, -write, and test your application. - -* [Flight generator](https://github.com/flightjs/generator-flight/) - Recommended. One-step to setup everything you need to work with Flight. - -* [Flight package generator](https://github.com/flightjs/generator-flight-package/) - Recommended. One-step to setup everything you need to write and test a - standalone Flight component. - -* [Jasmine Flight](https://github.com/flightjs/jasmine-flight/) - Extensions for the Jasmine test framework. - -* [Mocha Flight](https://github.com/flightjs/mocha-flight/) - Extensions for the Mocha test framework. - - -## Finding and writing standalone components - -You can browse all the [Flight components](http://flight-components.jit.su) -available at this time. They can also be found by searching the Bower registry: - -``` -bower search flight -``` - -The easiest way to write a standalone Flight component is to use the [Flight -package generator](https://github.com/flightjs/generator-flight-package/): - -``` -yo flight-package foo -``` - - -## Installation - -If you prefer not to use the Flight generators, it's highly recommended that -you install Flight as an AMD package (including all the correct dependencies). -This is best done with [Bower](http://bower.io/), a package manager for the web. - -``` -npm install -g bower -bower install --save flight -``` - -You will have to reference Flight's installed dependencies – -[ES5-shim](https://github.com/kriskowal/es5-shim) and -[jQuery](http://jquery.com) – and use an AMD module loader like -[Require.js](http://requirejs.org/) or -[Loadrunner](https://github.com/danwrong/loadrunner). - -```html - - - - -... -``` - -## Standalone version - -Alternatively, you can manually install the [standalone -version](http://flightjs.github.io/release/latest/flight.js) of Flight, also -available on [cdnjs](http://cdnjs.com/). It exposes all of its modules as -properties of a global variable, `flight`: - -```html -... - - -``` - -N.B. You will also need to manually install the correct versions of Flight's -dependencies: ES5 Shim and jQuery. - -## Browser Support - -Chrome, Firefox, Safari, Opera, IE 7+. - -## Quick Overview - -Here's a brief introduction to Flight's key concepts and syntax. Read the [API -documentation](doc) for a comprehensive overview. - -### Example - -A simple example of how to write and use a Flight component. - -```js -define(function (require) { - var defineComponent = require('flight/lib/component'); - - // define the component - return defineComponent(inbox); - - function inbox() { - // define custom functions here - this.doSomething = function() { - //... - } - - this.doSomethingElse = function() { - //... - } - - // now initialize the component - this.after('initialize', function() { - this.on('click', this.doSomething); - this.on('mouseover', this.doSomethingElse); - }); - } -}); -``` - -```js -/* attach an inbox component to a node with id 'inbox' */ - -define(function (require) { - var Inbox = require('inbox'); - - Inbox.attachTo('#inbox', { - 'nextPageSelector': '#nextPage', - 'previousPageSelector': '#previousPage', - }); -}); -``` - -### Components ([API](doc/component_api.md)) - -- A Component is nothing more than a constructor with properties mixed into its prototype. -- Every Component comes with a set of basic functionality such as event handling and component registration. -(see [Base API](doc/base_api.md)) -- Additionally, each Component definition mixes in a set of custom properties which describe its behavior. -- When a component is attached to a DOM node, a new instance of that component is created. Each component -instance references the DOM node via its `node` property. -- Component instances cannot be referenced directly; they communicate with other components via events. - -### Interacting with the DOM - -Once attached, component instances have direct access to their node object via the `node` property. (There's -also a jQuery version of the node available via the `$node` property.) - -### Events in Flight - -Events are how Flight components interact. The Component prototype supplies methods for triggering events as -well as for subscribing to and unsubscribing from events. These Component event methods are actually just convenient -wrappers around regular event methods on DOM nodes. - -### Mixins ([API](doc/mixin_api.md)) - -- In Flight, a mixin is a function which assigns properties to a target object (represented by the `this` -keyword). -- A typical mixin defines a set of functionality that will be useful to more than one component. -- One mixin can be applied to any number of [Component](#components) definitions. -- One Component definition can have any number of mixins applied to it. -- Each Component defines a [*core*](#core_mixin) mixin within its own module. -- A mixin can itself have mixins applied to it. - -### Advice ([API](doc/advice_api.md)) - -In Flight, advice is a mixin (`'lib/advice.js'`) that defines `before`, `after` and `around` methods. - -These can be used to modify existing functions by adding custom code. All Components have advice mixed in to -their prototype so that mixins can augment existing functions without requiring knowledge -of the original implementation. Moreover, since Component's are seeded with an empty `initialize` method, -Component definitions will typically use `after` to define custom `initialize` behavior. - -### Debugging ([API](doc/debug_api.md)) - -Flight ships with a debug module which can help you trace the sequence of event triggering and binding. By default -console logging is turned off, but you can you can log `trigger`, `on` and `off` events by means of the following console -commands. - -## Authors - -+ [@angus-c](http://github.com/angus-c) -+ [@danwrong](http://github.com/danwrong) -+ [@kpk](http://github.com/kennethkufluk) - -Thanks for assistance and contributions: -[@sayrer](https://github.com/sayrer), -[@shinypb](https://github.com/shinypb), -[@kloots](https://github.com/kloots), -[@marcelduran](https://github.com/marcelduran), -[@tbrd](https://github.com/tbrd), -[@necolas](https://github.com/necolas), -[@fat](https://github.com/fat), -[@mkuklis](https://github.com/mkuklis), -[@jrburke](https://github.com/jrburke), -[@garann](https://github.com/garann), -[@WebReflection](https://github.com/WebReflection), -[@coldhead](https://github.com/coldhead), -[@paulirish](https://github.com/paulirish), -[@nimbupani](https://github.com/nimbupani), -[@mootcycle](https://github.com/mootcycle). - -Special thanks to the rest of the Twitter web team for their abundant -contributions and feedback. - - -## License - -Copyright 2013 Twitter, Inc and other contributors. - -Licensed under the MIT License diff --git a/js/libs/flight/bower.json b/js/libs/flight/bower.json deleted file mode 100644 index d47ee28..0000000 --- a/js/libs/flight/bower.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "flight", - "description": "Clientside component infrastructure", - "main": "lib/index.js", - "version": "1.1.4", - "ignore": [ - "doc", - "tools", - "test", - ".gitignore", - ".travis.yml", - "CHANGELOG.md", - "CONTRIBUTING.md", - "Makefile", - "karma.conf.js", - "package.json" - ], - "dependencies": { - "es5-shim": "2.0.0", - "jquery": ">=1.8.0" - } -} diff --git a/js/libs/flight/lib/advice.js b/js/libs/flight/lib/advice.js deleted file mode 100644 index 898c340..0000000 --- a/js/libs/flight/lib/advice.js +++ /dev/null @@ -1,69 +0,0 @@ -// ========================================== -// Copyright 2013 Twitter, Inc -// Licensed under The MIT License -// http://opensource.org/licenses/MIT -// ========================================== - -define( - - [ - './compose' - ], - - function(compose) { - 'use strict'; - - var advice = { - - around: function(base, wrapped) { - return function composedAround() { - // unpacking arguments by hand benchmarked faster - var i = 0, l = arguments.length, args = new Array(l + 1); - args[0] = base.bind(this); - for (; i < l; i++) args[i + 1] = arguments[i]; - - return wrapped.apply(this, args); - }; - }, - - before: function(base, before) { - var beforeFn = (typeof before == 'function') ? before : before.obj[before.fnName]; - return function composedBefore() { - beforeFn.apply(this, arguments); - return base.apply(this, arguments); - }; - }, - - after: function(base, after) { - var afterFn = (typeof after == 'function') ? after : after.obj[after.fnName]; - return function composedAfter() { - var res = (base.unbound || base).apply(this, arguments); - afterFn.apply(this, arguments); - return res; - }; - }, - - // a mixin that allows other mixins to augment existing functions by adding additional - // code before, after or around. - withAdvice: function() { - ['before', 'after', 'around'].forEach(function(m) { - this[m] = function(method, fn) { - - compose.unlockProperty(this, method, function() { - if (typeof this[method] == 'function') { - this[method] = advice[m](this[method], fn); - } else { - this[method] = fn; - } - - return this[method]; - }); - - }; - }, this); - } - }; - - return advice; - } -); diff --git a/js/libs/flight/lib/base.js b/js/libs/flight/lib/base.js deleted file mode 100644 index 7237940..0000000 --- a/js/libs/flight/lib/base.js +++ /dev/null @@ -1,237 +0,0 @@ -// ========================================== -// Copyright 2013 Twitter, Inc -// Licensed under The MIT License -// http://opensource.org/licenses/MIT -// ========================================== - -define( - - [ - './utils', - './registry', - './debug' - ], - - function(utils, registry, debug) { - 'use strict'; - - // common mixin allocates basic functionality - used by all component prototypes - // callback context is bound to component - var componentId = 0; - - function teardownInstance(instanceInfo){ - instanceInfo.events.slice().forEach(function(event) { - var args = [event.type]; - - event.element && args.unshift(event.element); - (typeof event.callback == 'function') && args.push(event.callback); - - this.off.apply(this, args); - }, instanceInfo.instance); - } - - function checkSerializable(type, data) { - try { - window.postMessage(data, '*'); - } catch(e) { - console.log('unserializable data for event',type,':',data); - throw new Error( - ['The event', type, 'on component', this.toString(), 'was triggered with non-serializable data'].join(' ') - ); - } - } - - function proxyEventTo(targetEvent) { - return function(e, data) { - $(e.target).trigger(targetEvent, data); - }; - } - - function withBase() { - - // delegate trigger, bind and unbind to an element - // if $element not supplied, use component's node - // other arguments are passed on - // event can be either a string specifying the type - // of the event, or a hash specifying both the type - // and a default function to be called. - this.trigger = function() { - var $element, type, data, event, defaultFn; - var lastIndex = arguments.length - 1, lastArg = arguments[lastIndex]; - - if (typeof lastArg != 'string' && !(lastArg && lastArg.defaultBehavior)) { - lastIndex--; - data = lastArg; - } - - if (lastIndex == 1) { - $element = $(arguments[0]); - event = arguments[1]; - } else { - $element = this.$node; - event = arguments[0]; - } - - if (event.defaultBehavior) { - defaultFn = event.defaultBehavior; - event = $.Event(event.type); - } - - type = event.type || event; - - if (debug.enabled && window.postMessage) { - checkSerializable.call(this, type, data); - } - - if (typeof this.attr.eventData === 'object') { - data = $.extend(true, {}, this.attr.eventData, data); - } - - $element.trigger((event || type), data); - - if (defaultFn && !event.isDefaultPrevented()) { - (this[defaultFn] || defaultFn).call(this); - } - - return $element; - }; - - this.on = function() { - var $element, type, callback, originalCb; - var lastIndex = arguments.length - 1, origin = arguments[lastIndex]; - - if (typeof origin == 'object') { - //delegate callback - originalCb = utils.delegate( - this.resolveDelegateRules(origin) - ); - } else if (typeof origin == 'string') { - originalCb = proxyEventTo(origin); - } else { - originalCb = origin; - } - - if (lastIndex == 2) { - $element = $(arguments[0]); - type = arguments[1]; - } else { - $element = this.$node; - type = arguments[0]; - } - - if (typeof originalCb != 'function' && typeof originalCb != 'object') { - throw new Error('Unable to bind to "' + type + '" because the given callback is not a function or an object'); - } - - callback = originalCb.bind(this); - callback.target = originalCb; - callback.context = this; - - $element.on(type, callback); - - // store every bound version of the callback - originalCb.bound || (originalCb.bound = []); - originalCb.bound.push(callback); - - return callback; - }; - - this.off = function() { - var $element, type, callback; - var lastIndex = arguments.length - 1; - - if (typeof arguments[lastIndex] == 'function') { - callback = arguments[lastIndex]; - lastIndex -= 1; - } - - if (lastIndex == 1) { - $element = $(arguments[0]); - type = arguments[1]; - } else { - $element = this.$node; - type = arguments[0]; - } - - if (callback) { - //this callback may be the original function or a bound version - var boundFunctions = callback.target ? callback.target.bound : callback.bound || []; - //set callback to version bound against this instance - boundFunctions && boundFunctions.some(function(fn, i, arr) { - if (fn.context && (this.identity == fn.context.identity)) { - arr.splice(i, 1); - callback = fn; - return true; - } - }, this); - } - - return $element.off(type, callback); - }; - - this.resolveDelegateRules = function(ruleInfo) { - var rules = {}; - - Object.keys(ruleInfo).forEach(function(r) { - if (!(r in this.attr)) { - throw new Error('Component "' + this.toString() + '" wants to listen on "' + r + '" but no such attribute was defined.'); - } - rules[this.attr[r]] = (typeof ruleInfo[r] == 'string') ? proxyEventTo(ruleInfo[r]) : ruleInfo[r]; - }, this); - - return rules; - }; - - this.defaultAttrs = function(defaults) { - utils.push(this.defaults, defaults, true) || (this.defaults = defaults); - }; - - this.select = function(attributeKey) { - return this.$node.find(this.attr[attributeKey]); - }; - - this.initialize = function(node, attrs) { - attrs || (attrs = {}); - //only assign identity if there isn't one (initialize can be called multiple times) - this.identity || (this.identity = componentId++); - - if (!node) { - throw new Error('Component needs a node'); - } - - if (node.jquery) { - this.node = node[0]; - this.$node = node; - } else { - this.node = node; - this.$node = $(node); - } - - // merge defaults with supplied options - // put options in attr.__proto__ to avoid merge overhead - var attr = Object.create(attrs); - for (var key in this.defaults) { - if (!attrs.hasOwnProperty(key)) { - attr[key] = this.defaults[key]; - } - } - - this.attr = attr; - - Object.keys(this.defaults || {}).forEach(function(key) { - if (this.defaults[key] === null && this.attr[key] === null) { - throw new Error('Required attribute "' + key + '" not specified in attachTo for component "' + this.toString() + '".'); - } - }, this); - - return this; - }; - - this.teardown = function() { - teardownInstance(registry.findInstanceInfo(this)); - }; - } - - return withBase; - } -); diff --git a/js/libs/flight/lib/component.js b/js/libs/flight/lib/component.js deleted file mode 100644 index 779f877..0000000 --- a/js/libs/flight/lib/component.js +++ /dev/null @@ -1,136 +0,0 @@ -// ========================================== -// Copyright 2013 Twitter, Inc -// Licensed under The MIT License -// http://opensource.org/licenses/MIT -// ========================================== - -define( - - [ - './advice', - './utils', - './compose', - './base', - './registry', - './logger', - './debug' - ], - - function(advice, utils, compose, withBase, registry, withLogging, debug) { - 'use strict'; - - var functionNameRegEx = /function (.*?)\s?\(/; - - // teardown for all instances of this constructor - function teardownAll() { - var componentInfo = registry.findComponentInfo(this); - - componentInfo && Object.keys(componentInfo.instances).forEach(function(k) { - var info = componentInfo.instances[k]; - // It's possible that a previous teardown caused another component to teardown, - // so we can't assume that the instances object is as it was. - if (info && info.instance) { - info.instance.teardown(); - } - }); - } - - function checkSerializable(type, data) { - try { - window.postMessage(data, '*'); - } catch(e) { - console.log('unserializable data for event',type,':',data); - throw new Error( - ['The event', type, 'on component', this.toString(), 'was triggered with non-serializable data'].join(' ') - ); - } - } - - function attachTo(selector/*, options args */) { - // unpacking arguments by hand benchmarked faster - var l = arguments.length; - var args = new Array(l - 1); - for (var i = 1; i < l; i++) args[i - 1] = arguments[i]; - - if (!selector) { - throw new Error('Component needs to be attachTo\'d a jQuery object, native node or selector string'); - } - - var options = utils.merge.apply(utils, args); - var componentInfo = registry.findComponentInfo(this); - - $(selector).each(function(i, node) { - if (componentInfo && componentInfo.isAttachedTo(node)) { - // already attached - return; - } - - (new this).initialize(node, options); - }.bind(this)); - } - - function prettyPrintMixins() { - //could be called from constructor or constructor.prototype - var mixedIn = this.mixedIn || this.prototype.mixedIn || []; - return mixedIn.map(function(mixin) { - if (mixin.name == null) { - // function name property not supported by this browser, use regex - var m = mixin.toString().match(functionNameRegEx); - return (m && m[1]) ? m[1] : ''; - } else { - return (mixin.name != 'withBase') ? mixin.name : ''; - } - }).filter(Boolean).join(', '); - }; - - - // define the constructor for a custom component type - // takes an unlimited number of mixin functions as arguments - // typical api call with 3 mixins: define(timeline, withTweetCapability, withScrollCapability); - function define(/*mixins*/) { - // unpacking arguments by hand benchmarked faster - var l = arguments.length; - var mixins = new Array(l); - for (var i = 0; i < l; i++) mixins[i] = arguments[i]; - - var Component = function() {}; - - Component.toString = Component.prototype.toString = prettyPrintMixins; - if (debug.enabled) { - Component.describe = Component.prototype.describe = Component.toString(); - } - - // 'options' is optional hash to be merged with 'defaults' in the component definition - Component.attachTo = attachTo; - // enables extension of existing "base" Components - Component.mixin = function() { - var newComponent = define(); //TODO: fix pretty print - var newPrototype = Object.create(Component.prototype); - newPrototype.mixedIn = [].concat(Component.prototype.mixedIn); - compose.mixin(newPrototype, arguments); - newComponent.prototype = newPrototype; - newComponent.prototype.constructor = newComponent; - return newComponent; - }; - Component.teardownAll = teardownAll; - - // prepend common mixins to supplied list, then mixin all flavors - if (debug.enabled) { - mixins.unshift(withLogging); - } - mixins.unshift(withBase, advice.withAdvice, registry.withRegistration); - compose.mixin(Component.prototype, mixins); - - return Component; - } - - define.teardownAll = function() { - registry.components.slice().forEach(function(c) { - c.component.teardownAll(); - }); - registry.reset(); - }; - - return define; - } -); diff --git a/js/libs/flight/lib/compose.js b/js/libs/flight/lib/compose.js deleted file mode 100644 index 38f021e..0000000 --- a/js/libs/flight/lib/compose.js +++ /dev/null @@ -1,85 +0,0 @@ -// ========================================== -// Copyright 2013 Twitter, Inc -// Licensed under The MIT License -// http://opensource.org/licenses/MIT -// ========================================== - -define( - - [ - './utils', - './debug' - ], - - function(utils, debug) { - 'use strict'; - - //enumerables are shims - getOwnPropertyDescriptor shim doesn't work - var canWriteProtect = debug.enabled && !utils.isEnumerable(Object, 'getOwnPropertyDescriptor'); - //whitelist of unlockable property names - var dontLock = ['mixedIn']; - - if (canWriteProtect) { - //IE8 getOwnPropertyDescriptor is built-in but throws exeption on non DOM objects - try { - Object.getOwnPropertyDescriptor(Object, 'keys'); - } catch(e) { - canWriteProtect = false; - } - } - - function setPropertyWritability(obj, isWritable) { - if (!canWriteProtect) { - return; - } - - var props = Object.create(null); - - Object.keys(obj).forEach( - function (key) { - if (dontLock.indexOf(key) < 0) { - var desc = Object.getOwnPropertyDescriptor(obj, key); - desc.writable = isWritable; - props[key] = desc; - } - } - ); - - Object.defineProperties(obj, props); - } - - function unlockProperty(obj, prop, op) { - var writable; - - if (!canWriteProtect || !obj.hasOwnProperty(prop)) { - op.call(obj); - return; - } - - writable = Object.getOwnPropertyDescriptor(obj, prop).writable; - Object.defineProperty(obj, prop, { writable: true }); - op.call(obj); - Object.defineProperty(obj, prop, { writable: writable }); - } - - function mixin(base, mixins) { - base.mixedIn = base.hasOwnProperty('mixedIn') ? base.mixedIn : []; - - for (var i=0; i', ['(', typeof obj[prop], ')'].join(''), obj[prop]); - } - if (Object.prototype.toString.call(obj[prop]) == '[object Object]' && (obj[prop] != obj) && path.split('.').indexOf(prop) == -1) { - traverse(util, searchTerm, {obj: obj[prop], path: [path,prop].join('.')}); - } - }); - } - - function search(util, expected, searchTerm, options) { - if (!expected || typeof searchTerm == expected) { - traverse(util, searchTerm, options); - } else { - console.error([searchTerm, 'must be', expected].join(' ')); - } - } - - var tests = { - 'name': function(searchTerm, obj, prop) {return searchTerm == prop;}, - 'nameContains': function(searchTerm, obj, prop) {return prop.indexOf(searchTerm) > -1;}, - 'type': function(searchTerm, obj, prop) {return obj[prop] instanceof searchTerm;}, - 'value': function(searchTerm, obj, prop) {return obj[prop] === searchTerm;}, - 'valueCoerced': function(searchTerm, obj, prop) {return obj[prop] == searchTerm;} - }; - - function byName(searchTerm, options) {search('name', 'string', searchTerm, options);} - function byNameContains(searchTerm, options) {search('nameContains', 'string', searchTerm, options);} - function byType(searchTerm, options) {search('type', 'function', searchTerm, options);} - function byValue(searchTerm, options) {search('value', null, searchTerm, options);} - function byValueCoerced(searchTerm, options) {search('valueCoerced', null, searchTerm, options);} - function custom(fn, options) {traverse(fn, null, options);} - - // ========================================== - // Event logging - // ========================================== - - var ALL = 'all'; //no filter - - //log nothing by default - var logFilter = { - eventNames: [], - actions: [] - } - - function filterEventLogsByAction(/*actions*/) { - var actions = [].slice.call(arguments); - - logFilter.eventNames.length || (logFilter.eventNames = ALL); - logFilter.actions = actions.length ? actions : ALL; - saveLogFilter(); - } - - function filterEventLogsByName(/*eventNames*/) { - var eventNames = [].slice.call(arguments); - - logFilter.actions.length || (logFilter.actions = ALL); - logFilter.eventNames = eventNames.length ? eventNames : ALL; - saveLogFilter(); - } - - function hideAllEventLogs() { - logFilter.actions = []; - logFilter.eventNames = []; - saveLogFilter(); - } - - function showAllEventLogs() { - logFilter.actions = ALL; - logFilter.eventNames = ALL; - saveLogFilter(); - } - - function saveLogFilter() { - try { - if (window.localStorage) { - localStorage.setItem('logFilter_eventNames', logFilter.eventNames); - localStorage.setItem('logFilter_actions', logFilter.actions); - } - } catch (ignored) {}; - } - - function retrieveLogFilter() { - var eventNames, actions; - try { - eventNames = (window.localStorage && localStorage.getItem('logFilter_eventNames')); - actions = (window.localStorage && localStorage.getItem('logFilter_actions')); - } catch(ignored) { - return; - } - eventNames && (logFilter.eventNames = eventNames); - actions && (logFilter.actions = actions); - - // reconstitute arrays in place - Object.keys(logFilter).forEach(function(k) { - var thisProp = logFilter[k]; - if (typeof thisProp == 'string' && thisProp !== ALL) { - logFilter[k] = thisProp ? thisProp.split(',') : []; - } - }); - } - - return { - - enable: function(enable) { - this.enabled = !!enable; - - if (enable && window.console) { - console.info('Booting in DEBUG mode'); - console.info('You can configure event logging with DEBUG.events.logAll()/logNone()/logByName()/logByAction()'); - } - - retrieveLogFilter(); - - window.DEBUG = this; - }, - - find: { - byName: byName, - byNameContains: byNameContains, - byType: byType, - byValue: byValue, - byValueCoerced: byValueCoerced, - custom: custom - }, - - events: { - logFilter: logFilter, - - // Accepts any number of action args - // e.g. DEBUG.events.logByAction("on", "off") - logByAction: filterEventLogsByAction, - - // Accepts any number of event name args (inc. regex or wildcards) - // e.g. DEBUG.events.logByName(/ui.*/, "*Thread*"); - logByName: filterEventLogsByName, - - logAll: showAllEventLogs, - logNone: hideAllEventLogs - } - }; - } -); diff --git a/js/libs/flight/lib/index.js b/js/libs/flight/lib/index.js deleted file mode 100644 index 09806aa..0000000 --- a/js/libs/flight/lib/index.js +++ /dev/null @@ -1,31 +0,0 @@ -// ========================================== -// Copyright 2013 Twitter, Inc -// Licensed under The MIT License -// http://opensource.org/licenses/MIT -// ========================================== - -define( - - [ - './advice', - './component', - './compose', - './logger', - './registry', - './utils' - ], - - function(advice, component, compose, logger, registry, utils) { - 'use strict'; - - return { - advice: advice, - component: component, - compose: compose, - logger: logger, - registry: registry, - utils: utils - }; - - } -); diff --git a/js/libs/flight/lib/logger.js b/js/libs/flight/lib/logger.js deleted file mode 100644 index efbd010..0000000 --- a/js/libs/flight/lib/logger.js +++ /dev/null @@ -1,100 +0,0 @@ -// ========================================== -// Copyright 2013 Twitter, Inc -// Licensed under The MIT License -// http://opensource.org/licenses/MIT -// ========================================== - -define( - - [ - './utils' - ], - - function(utils) { - 'use strict'; - - var actionSymbols = { - on: '<-', - trigger: '->', - off: 'x ' - }; - - function elemToString(elem) { - var tagStr = elem.tagName ? elem.tagName.toLowerCase() : elem.toString(); - var classStr = elem.className ? '.' + (elem.className) : ''; - var result = tagStr + classStr; - return elem.tagName ? ['\'', '\''].join(result) : result; - } - - function log(action, component, eventArgs) { - if (!window.DEBUG || !window.DEBUG.enabled) return; - var name, eventType, elem, fn, payload, logFilter, toRegExp, actionLoggable, nameLoggable, info; - - if (typeof eventArgs[eventArgs.length-1] == 'function') { - fn = eventArgs.pop(); - fn = fn.unbound || fn; // use unbound version if any (better info) - } - - if (eventArgs.length == 1) { - elem = component.$node[0]; - eventType = eventArgs[0]; - } else if ((eventArgs.length == 2) && typeof eventArgs[1] == 'object' && !eventArgs[1].type) { - //2 args, first arg is not elem - elem = component.$node[0]; - eventType = eventArgs[0]; - if (action == "trigger") { - payload = eventArgs[1]; - } - } else { - //2+ args, first arg is elem - elem = eventArgs[0]; - eventType = eventArgs[1]; - if (action == "trigger") { - payload = eventArgs[2]; - } - } - - name = typeof eventType == 'object' ? eventType.type : eventType; - - logFilter = DEBUG.events.logFilter; - - // no regex for you, actions... - actionLoggable = logFilter.actions == 'all' || (logFilter.actions.indexOf(action) > -1); - // event name filter allow wildcards or regex... - toRegExp = function(expr) { - return expr.test ? expr : new RegExp('^' + expr.replace(/\*/g, '.*') + '$'); - }; - nameLoggable = - logFilter.eventNames == 'all' || - logFilter.eventNames.some(function(e) {return toRegExp(e).test(name);}); - - if (actionLoggable && nameLoggable) { - info = [actionSymbols[action], action, '[' + name + ']']; - payload && info.push(payload); - info.push(elemToString(elem)); - info.push(component.constructor.describe.split(' ').slice(0,3).join(' ')); - console.groupCollapsed && action == 'trigger' && console.groupCollapsed(action, name); - console.info.apply(console, info); - } - } - - function withLogging() { - this.before('trigger', function() { - log('trigger', this, utils.toArray(arguments)); - }); - if (console.groupCollapsed) { - this.after('trigger', function() { - console.groupEnd(); - }); - } - this.before('on', function() { - log('on', this, utils.toArray(arguments)); - }); - this.before('off', function() { - log('off', this, utils.toArray(arguments)); - }); - } - - return withLogging; - } -); diff --git a/js/libs/flight/lib/registry.js b/js/libs/flight/lib/registry.js deleted file mode 100644 index 4861cb2..0000000 --- a/js/libs/flight/lib/registry.js +++ /dev/null @@ -1,228 +0,0 @@ -// ========================================== -// Copyright 2013 Twitter, Inc -// Licensed under The MIT License -// http://opensource.org/licenses/MIT -// ========================================== - -define( - - [], - - function() { - 'use strict'; - - 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 (!Object.keys(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.getBoundEventNames = function(instance) { - return this.findInstanceInfo(instance).events.map(function(ev) { - return ev.type; - }); - }; - - 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); - } - - //remove from global event registry - for (var i = 0, e; e = registry.events[i]; i++) { - if (matchEvent(e, event)) { - registry.events.splice(i, 1); - } - } - }; - - // debug tools may want to add advice to trigger - registry.trigger = function() {}; - - this.teardown = function() { - registry.removeInstance(this); - }; - - this.withRegistration = function() { - this.after('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; - } -); diff --git a/js/libs/flight/lib/utils.js b/js/libs/flight/lib/utils.js deleted file mode 100644 index 21c9221..0000000 --- a/js/libs/flight/lib/utils.js +++ /dev/null @@ -1,263 +0,0 @@ -// ========================================== -// Copyright 2013 Twitter, Inc -// Licensed under The MIT License -// http://opensource.org/licenses/MIT -// ========================================== - -define( - - [], - - function() { - 'use strict'; - - var arry = []; - var DEFAULT_INTERVAL = 100; - - var utils = { - - isDomObj: function(obj) { - return !!(obj.nodeType || (obj === window)); - }, - - toArray: function(obj, from) { - return arry.slice.call(obj, from); - }, - - // returns new object representing multiple objects merged together - // optional final argument is boolean which specifies if merge is recursive - // original objects are unmodified - // - // usage: - // var base = {a:2, b:6}; - // var extra = {b:3, c:4}; - // merge(base, extra); //{a:2, b:3, c:4} - // base; //{a:2, b:6} - // - // var base = {a:2, b:6}; - // var extra = {b:3, c:4}; - // var extraExtra = {a:4, d:9}; - // merge(base, extra, extraExtra); //{a:4, b:3, c:4. d: 9} - // base; //{a:2, b:6} - // - // var base = {a:2, b:{bb:4, cc:5}}; - // var extra = {a:4, b:{cc:7, dd:1}}; - // merge(base, extra, true); //{a:4, b:{bb:4, cc:7, dd:1}} - // base; //{a:2, b:6} - - merge: function(/*obj1, obj2,....deepCopy*/) { - // unpacking arguments by hand benchmarked faster - var l = arguments.length, - i = 0, - args = new Array(l + 1); - for (; i < l; i++) args[i + 1] = arguments[i]; - - if (l === 0) { - return {}; - } - - //start with empty object so a copy is created - args[0] = {}; - - if (args[args.length - 1] === true) { - //jquery extend requires deep copy as first arg - args.pop(); - args.unshift(true); - } - - return $.extend.apply(undefined, args); - }, - - // updates base in place by copying properties of extra to it - // optionally clobber protected - // usage: - // var base = {a:2, b:6}; - // var extra = {c:4}; - // push(base, extra); //{a:2, b:6, c:4} - // base; //{a:2, b:6, c:4} - // - // var base = {a:2, b:6}; - // var extra = {b: 4 c:4}; - // push(base, extra, true); //Error ("utils.push attempted to overwrite 'b' while running in protected mode") - // base; //{a:2, b:6} - // - // objects with the same key will merge recursively when protect is false - // eg: - // var base = {a:16, b:{bb:4, cc:10}}; - // var extra = {b:{cc:25, dd:19}, c:5}; - // push(base, extra); //{a:16, {bb:4, cc:25, dd:19}, c:5} - // - push: function(base, extra, protect) { - if (base) { - Object.keys(extra || {}).forEach(function(key) { - if (base[key] && protect) { - throw new Error('utils.push attempted to overwrite "' + key + '" while running in protected mode'); - } - - if (typeof base[key] == 'object' && typeof extra[key] == 'object') { - // recurse - this.push(base[key], extra[key]); - } else { - // no protect, so extra wins - base[key] = extra[key]; - } - }, this); - } - - return base; - }, - - isEnumerable: function(obj, property) { - return Object.keys(obj).indexOf(property) > -1; - }, - - // build a function from other function(s) - // utils.compose(a,b,c) -> a(b(c())); - // implementation lifted from underscore.js (c) 2009-2012 Jeremy Ashkenas - compose: function() { - var funcs = arguments; - - return function() { - var args = arguments; - - for (var i = funcs.length-1; i >= 0; i--) { - args = [funcs[i].apply(this, args)]; - } - - return args[0]; - }; - }, - - // Can only unique arrays of homogeneous primitives, e.g. an array of only strings, an array of only booleans, or an array of only numerics - uniqueArray: function(array) { - var u = {}, a = []; - - for (var i = 0, l = array.length; i < l; ++i) { - if (u.hasOwnProperty(array[i])) { - continue; - } - - a.push(array[i]); - u[array[i]] = 1; - } - - return a; - }, - - debounce: function(func, wait, immediate) { - if (typeof wait != 'number') { - wait = DEFAULT_INTERVAL; - } - - var timeout, result; - - return function() { - var context = this, args = arguments; - var later = function() { - timeout = null; - if (!immediate) { - result = func.apply(context, args); - } - }; - var callNow = immediate && !timeout; - - clearTimeout(timeout); - timeout = setTimeout(later, wait); - - if (callNow) { - result = func.apply(context, args); - } - - return result; - }; - }, - - throttle: function(func, wait) { - if (typeof wait != 'number') { - wait = DEFAULT_INTERVAL; - } - - var context, args, timeout, throttling, more, result; - var whenDone = this.debounce(function(){ - more = throttling = false; - }, wait); - - return function() { - context = this; args = arguments; - var later = function() { - timeout = null; - if (more) { - result = func.apply(context, args); - } - whenDone(); - }; - - if (!timeout) { - timeout = setTimeout(later, wait); - } - - if (throttling) { - more = true; - } else { - throttling = true; - result = func.apply(context, args); - } - - whenDone(); - return result; - }; - }, - - countThen: function(num, base) { - return function() { - if (!--num) { return base.apply(this, arguments); } - }; - }, - - delegate: function(rules) { - return function(e, data) { - var target = $(e.target), parent; - - Object.keys(rules).forEach(function(selector) { - if (!e.isPropagationStopped() && (parent = target.closest(selector)).length) { - data = data || {}; - data.el = parent[0]; - return rules[selector].apply(this, [e, data]); - } - }, this); - }; - }, - - // ensures that a function will only be called once. - // usage: - // will only create the application once - // var initialize = utils.once(createApplication) - // initialize(); - // initialize(); - // - // will only delete a record once - // var myHanlder = function () { - // $.ajax({type: 'DELETE', url: 'someurl.com', data: {id: 1}}); - // }; - // this.on('click', utils.once(myHandler)); - // - once: function(func) { - var ran, result; - - return function() { - if (ran) { - return result; - } - - ran = true; - result = func.apply(this, arguments); - - return result; - }; - } - - }; - - return utils; - } -);