From 7638395fd9e0555bd35f192b8feea96644d4d0cb Mon Sep 17 00:00:00 2001 From: Bernard Potocki Date: Tue, 8 Sep 2015 10:36:49 +0200 Subject: [PATCH] Update Ember.js to 2.0.1 --- index.html | 6 +- js/libs/ember-1.12.0.debug.js | 47872 ------------------ js/libs/ember-2.0.1.debug.js | 52682 ++++++++++++++++++++ js/libs/ember-template-compiler-1.12.0.js | 16139 ------ js/libs/ember-template-compiler-2.0.1.js | 22107 ++++++++ 5 files changed, 74792 insertions(+), 64014 deletions(-) delete mode 100644 js/libs/ember-1.12.0.debug.js create mode 100644 js/libs/ember-2.0.1.debug.js delete mode 100644 js/libs/ember-template-compiler-1.12.0.js create mode 100644 js/libs/ember-template-compiler-2.0.1.js diff --git a/index.html b/index.html index 377f84a..cbe1276 100644 --- a/index.html +++ b/index.html @@ -15,15 +15,15 @@

Welcome to Ember.js

- - + + diff --git a/js/libs/ember-1.12.0.debug.js b/js/libs/ember-1.12.0.debug.js deleted file mode 100644 index 92ceb71..0000000 --- a/js/libs/ember-1.12.0.debug.js +++ /dev/null @@ -1,47872 +0,0 @@ -/*! - * @overview Ember - JavaScript Application Framework - * @copyright Copyright 2011-2015 Tilde Inc. and contributors - * Portions Copyright 2006-2011 Strobe Inc. - * Portions Copyright 2008-2011 Apple Inc. All rights reserved. - * @license Licensed under MIT license - * See https://raw.github.com/emberjs/ember.js/master/LICENSE - * @version 1.12.0 - */ - -(function() { -var enifed, requireModule, eriuqer, requirejs, Ember; -var mainContext = this; - -(function() { - - Ember = this.Ember = this.Ember || {}; - if (typeof Ember === 'undefined') { Ember = {}; }; - - if (typeof Ember.__loader === 'undefined') { - var registry = {}; - var seen = {}; - - enifed = function(name, deps, callback) { - var value = { }; - - if (!callback) { - value.deps = []; - value.callback = deps; - } else { - value.deps = deps; - value.callback = callback; - } - - registry[name] = value; - }; - - requirejs = eriuqer = requireModule = function(name) { - return internalRequire(name, null); - } - - function internalRequire(name, referrerName) { - var exports = seen[name]; - - if (exports !== undefined) { - return exports; - } - - exports = seen[name] = {}; - - if (!registry[name]) { - if (referrerName) { - throw new Error('Could not find module ' + name + ' required by: ' + referrerName); - } else { - throw new Error('Could not find module ' + name); - } - } - - var mod = registry[name]; - var deps = mod.deps; - var callback = mod.callback; - var reified = []; - var length = deps.length; - - for (var i=0; i 3) { - args = new Array(length - 3); - for (var i = 3; i < length; i++) { - args[i-3] = arguments[i]; - } - } else { - args = undefined; - } - - if (!this.currentInstance) { createAutorun(this); } - return this.currentInstance.schedule(queueName, target, method, args, false, stack); - }, - - deferOnce: function(queueName, target, method /* , args */) { - if (!method) { - method = target; - target = null; - } - - if (isString(method)) { - method = target[method]; - } - - var stack = this.DEBUG ? new Error() : undefined; - var length = arguments.length; - var args; - - if (length > 3) { - args = new Array(length - 3); - for (var i = 3; i < length; i++) { - args[i-3] = arguments[i]; - } - } else { - args = undefined; - } - - if (!this.currentInstance) { - createAutorun(this); - } - return this.currentInstance.schedule(queueName, target, method, args, true, stack); - }, - - setTimeout: function() { - var l = arguments.length; - var args = new Array(l); - - for (var x = 0; x < l; x++) { - args[x] = arguments[x]; - } - - var length = args.length, - method, wait, target, - methodOrTarget, methodOrWait, methodOrArgs; - - if (length === 0) { - return; - } else if (length === 1) { - method = args.shift(); - wait = 0; - } else if (length === 2) { - methodOrTarget = args[0]; - methodOrWait = args[1]; - - if (isFunction(methodOrWait) || isFunction(methodOrTarget[methodOrWait])) { - target = args.shift(); - method = args.shift(); - wait = 0; - } else if (isCoercableNumber(methodOrWait)) { - method = args.shift(); - wait = args.shift(); - } else { - method = args.shift(); - wait = 0; - } - } else { - var last = args[args.length - 1]; - - if (isCoercableNumber(last)) { - wait = args.pop(); - } else { - wait = 0; - } - - methodOrTarget = args[0]; - methodOrArgs = args[1]; - - if (isFunction(methodOrArgs) || (isString(methodOrArgs) && - methodOrTarget !== null && - methodOrArgs in methodOrTarget)) { - target = args.shift(); - method = args.shift(); - } else { - method = args.shift(); - } - } - - var executeAt = now() + parseInt(wait, 10); - - if (isString(method)) { - method = target[method]; - } - - var onError = getOnError(this.options); - - function fn() { - if (onError) { - try { - method.apply(target, args); - } catch (e) { - onError(e); - } - } else { - method.apply(target, args); - } - } - - // find position to insert - var i = searchTimer(executeAt, this._timers); - - this._timers.splice(i, 0, executeAt, fn); - - updateLaterTimer(this, executeAt, wait); - - return fn; - }, - - throttle: function(target, method /* , args, wait, [immediate] */) { - var backburner = this; - var args = arguments; - var immediate = pop.call(args); - var wait, throttler, index, timer; - - if (isNumber(immediate) || isString(immediate)) { - wait = immediate; - immediate = true; - } else { - wait = pop.call(args); - } - - wait = parseInt(wait, 10); - - index = findThrottler(target, method, this._throttlers); - if (index > -1) { return this._throttlers[index]; } // throttled - - timer = global.setTimeout(function() { - if (!immediate) { - backburner.run.apply(backburner, args); - } - var index = findThrottler(target, method, backburner._throttlers); - if (index > -1) { - backburner._throttlers.splice(index, 1); - } - }, wait); - - if (immediate) { - this.run.apply(this, args); - } - - throttler = [target, method, timer]; - - this._throttlers.push(throttler); - - return throttler; - }, - - debounce: function(target, method /* , args, wait, [immediate] */) { - var backburner = this; - var args = arguments; - var immediate = pop.call(args); - var wait, index, debouncee, timer; - - if (isNumber(immediate) || isString(immediate)) { - wait = immediate; - immediate = false; - } else { - wait = pop.call(args); - } - - wait = parseInt(wait, 10); - // Remove debouncee - index = findDebouncee(target, method, this._debouncees); - - if (index > -1) { - debouncee = this._debouncees[index]; - this._debouncees.splice(index, 1); - clearTimeout(debouncee[2]); - } - - timer = global.setTimeout(function() { - if (!immediate) { - backburner.run.apply(backburner, args); - } - var index = findDebouncee(target, method, backburner._debouncees); - if (index > -1) { - backburner._debouncees.splice(index, 1); - } - }, wait); - - if (immediate && index === -1) { - backburner.run.apply(backburner, args); - } - - debouncee = [ - target, - method, - timer - ]; - - backburner._debouncees.push(debouncee); - - return debouncee; - }, - - cancelTimers: function() { - var clearItems = function(item) { - clearTimeout(item[2]); - }; - - each(this._throttlers, clearItems); - this._throttlers = []; - - each(this._debouncees, clearItems); - this._debouncees = []; - - if (this._laterTimer) { - clearTimeout(this._laterTimer); - this._laterTimer = null; - } - this._timers = []; - - if (this._autorun) { - clearTimeout(this._autorun); - this._autorun = null; - } - }, - - hasTimers: function() { - return !!this._timers.length || !!this._debouncees.length || !!this._throttlers.length || this._autorun; - }, - - cancel: function(timer) { - var timerType = typeof timer; - - if (timer && timerType === 'object' && timer.queue && timer.method) { // we're cancelling a deferOnce - return timer.queue.cancel(timer); - } else if (timerType === 'function') { // we're cancelling a setTimeout - for (var i = 0, l = this._timers.length; i < l; i += 2) { - if (this._timers[i + 1] === timer) { - this._timers.splice(i, 2); // remove the two elements - if (i === 0) { - if (this._laterTimer) { // Active timer? Then clear timer and reset for future timer - clearTimeout(this._laterTimer); - this._laterTimer = null; - } - if (this._timers.length > 0) { // Update to next available timer when available - updateLaterTimer(this, this._timers[0], this._timers[0] - now()); - } - } - return true; - } - } - } else if (Object.prototype.toString.call(timer) === "[object Array]"){ // we're cancelling a throttle or debounce - return this._cancelItem(findThrottler, this._throttlers, timer) || - this._cancelItem(findDebouncee, this._debouncees, timer); - } else { - return; // timer was null or not a timer - } - }, - - _cancelItem: function(findMethod, array, timer){ - var item, index; - - if (timer.length < 3) { return false; } - - index = findMethod(timer[0], timer[1], array); - - if (index > -1) { - - item = array[index]; - - if (item[2] === timer[2]) { - array.splice(index, 1); - clearTimeout(timer[2]); - return true; - } - } - - return false; - } - }; - - Backburner.prototype.schedule = Backburner.prototype.defer; - Backburner.prototype.scheduleOnce = Backburner.prototype.deferOnce; - Backburner.prototype.later = Backburner.prototype.setTimeout; - - if (needsIETryCatchFix) { - var originalRun = Backburner.prototype.run; - Backburner.prototype.run = wrapInTryCatch(originalRun); - - var originalEnd = Backburner.prototype.end; - Backburner.prototype.end = wrapInTryCatch(originalEnd); - } - - function getOnError(options) { - return options.onError || (options.onErrorTarget && options.onErrorTarget[options.onErrorMethod]); - } - - function createAutorun(backburner) { - backburner.begin(); - backburner._autorun = global.setTimeout(function() { - backburner._autorun = null; - backburner.end(); - }); - } - - function updateLaterTimer(backburner, executeAt, wait) { - var n = now(); - if (!backburner._laterTimer || executeAt < backburner._laterTimerExpiresAt || backburner._laterTimerExpiresAt < n) { - - if (backburner._laterTimer) { - // Clear when: - // - Already expired - // - New timer is earlier - clearTimeout(backburner._laterTimer); - - if (backburner._laterTimerExpiresAt < n) { // If timer was never triggered - // Calculate the left-over wait-time - wait = Math.max(0, executeAt - n); - } - } - - backburner._laterTimer = global.setTimeout(function() { - backburner._laterTimer = null; - backburner._laterTimerExpiresAt = null; - executeTimers(backburner); - }, wait); - - backburner._laterTimerExpiresAt = n + wait; - } - } - - function executeTimers(backburner) { - var n = now(); - var fns, i, l; - - backburner.run(function() { - i = searchTimer(n, backburner._timers); - - fns = backburner._timers.splice(0, i); - - for (i = 1, l = fns.length; i < l; i += 2) { - backburner.schedule(backburner.options.defaultQueue, null, fns[i]); - } - }); - - if (backburner._timers.length) { - updateLaterTimer(backburner, backburner._timers[0], backburner._timers[0] - n); - } - } - - function findDebouncee(target, method, debouncees) { - return findItem(target, method, debouncees); - } - - function findThrottler(target, method, throttlers) { - return findItem(target, method, throttlers); - } - - function findItem(target, method, collection) { - var item; - var index = -1; - - for (var i = 0, l = collection.length; i < l; i++) { - item = collection[i]; - if (item[0] === target && item[1] === method) { - index = i; - break; - } - } - - return index; - } - - __exports__["default"] = Backburner; - }); -enifed("backburner.umd", - ["./backburner"], - function(__dependency1__) { - "use strict"; - var Backburner = __dependency1__["default"]; - - /* global define:true module:true window: true */ - if (typeof enifed === 'function' && enifed.amd) { - enifed(function() { return Backburner; }); - } else if (typeof module !== 'undefined' && module.exports) { - module.exports = Backburner; - } else if (typeof this !== 'undefined') { - this['Backburner'] = Backburner; - } - }); -enifed("backburner/binary-search", - ["exports"], - function(__exports__) { - "use strict"; - __exports__["default"] = function binarySearch(time, timers) { - var start = 0; - var end = timers.length - 2; - var middle, l; - - while (start < end) { - // since timers is an array of pairs 'l' will always - // be an integer - l = (end - start) / 2; - - // compensate for the index in case even number - // of pairs inside timers - middle = start + l - (l % 2); - - if (time >= timers[middle]) { - start = middle + 2; - } else { - end = middle; - } - } - - return (time >= timers[start]) ? start + 2 : start; - } - }); -enifed("backburner/deferred-action-queues", - ["./utils","./queue","exports"], - function(__dependency1__, __dependency2__, __exports__) { - "use strict"; - var each = __dependency1__.each; - var Queue = __dependency2__["default"]; - - function DeferredActionQueues(queueNames, options) { - var queues = this.queues = Object.create(null); - this.queueNames = queueNames = queueNames || []; - - this.options = options; - - each(queueNames, function(queueName) { - queues[queueName] = new Queue(queueName, options[queueName], options); - }); - } - - function noSuchQueue(name) { - throw new Error("You attempted to schedule an action in a queue (" + name + ") that doesn't exist"); - } - - DeferredActionQueues.prototype = { - schedule: function(name, target, method, args, onceFlag, stack) { - var queues = this.queues; - var queue = queues[name]; - - if (!queue) { - noSuchQueue(name); - } - - if (onceFlag) { - return queue.pushUnique(target, method, args, stack); - } else { - return queue.push(target, method, args, stack); - } - }, - - flush: function() { - var queues = this.queues; - var queueNames = this.queueNames; - var queueName, queue, queueItems, priorQueueNameIndex; - var queueNameIndex = 0; - var numberOfQueues = queueNames.length; - var options = this.options; - - while (queueNameIndex < numberOfQueues) { - queueName = queueNames[queueNameIndex]; - queue = queues[queueName]; - - var numberOfQueueItems = queue._queue.length; - - if (numberOfQueueItems === 0) { - queueNameIndex++; - } else { - queue.flush(false /* async */); - queueNameIndex = 0; - } - } - } - }; - - __exports__["default"] = DeferredActionQueues; - }); -enifed("backburner/platform", - ["exports"], - function(__exports__) { - "use strict"; - // In IE 6-8, try/finally doesn't work without a catch. - // Unfortunately, this is impossible to test for since wrapping it in a parent try/catch doesn't trigger the bug. - // This tests for another broken try/catch behavior that only exhibits in the same versions of IE. - var needsIETryCatchFix = (function(e,x){ - try{ x(); } - catch(e) { } // jshint ignore:line - return !!e; - })(); - __exports__.needsIETryCatchFix = needsIETryCatchFix; - }); -enifed("backburner/queue", - ["./utils","exports"], - function(__dependency1__, __exports__) { - "use strict"; - var isString = __dependency1__.isString; - - function Queue(name, options, globalOptions) { - this.name = name; - this.globalOptions = globalOptions || {}; - this.options = options; - this._queue = []; - this.targetQueues = Object.create(null); - this._queueBeingFlushed = undefined; - } - - Queue.prototype = { - push: function(target, method, args, stack) { - var queue = this._queue; - queue.push(target, method, args, stack); - - return { - queue: this, - target: target, - method: method - }; - }, - - pushUniqueWithoutGuid: function(target, method, args, stack) { - var queue = this._queue; - - for (var i = 0, l = queue.length; i < l; i += 4) { - var currentTarget = queue[i]; - var currentMethod = queue[i+1]; - - if (currentTarget === target && currentMethod === method) { - queue[i+2] = args; // replace args - queue[i+3] = stack; // replace stack - return; - } - } - - queue.push(target, method, args, stack); - }, - - targetQueue: function(targetQueue, target, method, args, stack) { - var queue = this._queue; - - for (var i = 0, l = targetQueue.length; i < l; i += 4) { - var currentMethod = targetQueue[i]; - var currentIndex = targetQueue[i + 1]; - - if (currentMethod === method) { - queue[currentIndex + 2] = args; // replace args - queue[currentIndex + 3] = stack; // replace stack - return; - } - } - - targetQueue.push( - method, - queue.push(target, method, args, stack) - 4 - ); - }, - - pushUniqueWithGuid: function(guid, target, method, args, stack) { - var hasLocalQueue = this.targetQueues[guid]; - - if (hasLocalQueue) { - this.targetQueue(hasLocalQueue, target, method, args, stack); - } else { - this.targetQueues[guid] = [ - method, - this._queue.push(target, method, args, stack) - 4 - ]; - } - - return { - queue: this, - target: target, - method: method - }; - }, - - pushUnique: function(target, method, args, stack) { - var queue = this._queue, currentTarget, currentMethod, i, l; - var KEY = this.globalOptions.GUID_KEY; - - if (target && KEY) { - var guid = target[KEY]; - if (guid) { - return this.pushUniqueWithGuid(guid, target, method, args, stack); - } - } - - this.pushUniqueWithoutGuid(target, method, args, stack); - - return { - queue: this, - target: target, - method: method - }; - }, - - invoke: function(target, method, args, _, _errorRecordedForStack) { - if (args && args.length > 0) { - method.apply(target, args); - } else { - method.call(target); - } - }, - - invokeWithOnError: function(target, method, args, onError, errorRecordedForStack) { - try { - if (args && args.length > 0) { - method.apply(target, args); - } else { - method.call(target); - } - } catch(error) { - onError(error, errorRecordedForStack); - } - }, - - flush: function(sync) { - var queue = this._queue; - var length = queue.length; - - if (length === 0) { - return; - } - - var globalOptions = this.globalOptions; - var options = this.options; - var before = options && options.before; - var after = options && options.after; - var onError = globalOptions.onError || (globalOptions.onErrorTarget && - globalOptions.onErrorTarget[globalOptions.onErrorMethod]); - var target, method, args, errorRecordedForStack; - var invoke = onError ? this.invokeWithOnError : this.invoke; - - this.targetQueues = Object.create(null); - var queueItems = this._queueBeingFlushed = this._queue.slice(); - this._queue = []; - - if (before) { - before(); - } - - for (var i = 0; i < length; i += 4) { - target = queueItems[i]; - method = queueItems[i+1]; - args = queueItems[i+2]; - errorRecordedForStack = queueItems[i+3]; // Debugging assistance - - if (isString(method)) { - method = target[method]; - } - - // method could have been nullified / canceled during flush - if (method) { - // - // ** Attention intrepid developer ** - // - // To find out the stack of this task when it was scheduled onto - // the run loop, add the following to your app.js: - // - // Ember.run.backburner.DEBUG = true; // NOTE: This slows your app, don't leave it on in production. - // - // Once that is in place, when you are at a breakpoint and navigate - // here in the stack explorer, you can look at `errorRecordedForStack.stack`, - // which will be the captured stack when this job was scheduled. - // - invoke(target, method, args, onError, errorRecordedForStack); - } - } - - if (after) { - after(); - } - - this._queueBeingFlushed = undefined; - - if (sync !== false && - this._queue.length > 0) { - // check if new items have been added - this.flush(true); - } - }, - - cancel: function(actionToCancel) { - var queue = this._queue, currentTarget, currentMethod, i, l; - var target = actionToCancel.target; - var method = actionToCancel.method; - var GUID_KEY = this.globalOptions.GUID_KEY; - - if (GUID_KEY && this.targetQueues && target) { - var targetQueue = this.targetQueues[target[GUID_KEY]]; - - if (targetQueue) { - for (i = 0, l = targetQueue.length; i < l; i++) { - if (targetQueue[i] === method) { - targetQueue.splice(i, 1); - } - } - } - } - - for (i = 0, l = queue.length; i < l; i += 4) { - currentTarget = queue[i]; - currentMethod = queue[i+1]; - - if (currentTarget === target && - currentMethod === method) { - queue.splice(i, 4); - return true; - } - } - - // if not found in current queue - // could be in the queue that is being flushed - queue = this._queueBeingFlushed; - - if (!queue) { - return; - } - - for (i = 0, l = queue.length; i < l; i += 4) { - currentTarget = queue[i]; - currentMethod = queue[i+1]; - - if (currentTarget === target && - currentMethod === method) { - // don't mess with array during flush - // just nullify the method - queue[i+1] = null; - return true; - } - } - } - }; - - __exports__["default"] = Queue; - }); -enifed("backburner/utils", - ["exports"], - function(__exports__) { - "use strict"; - var NUMBER = /\d+/; - - function each(collection, callback) { - for (var i = 0; i < collection.length; i++) { - callback(collection[i]); - } - } - - __exports__.each = each;// Date.now is not available in browsers < IE9 - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now#Compatibility - var now = Date.now || function() { return new Date().getTime(); }; - __exports__.now = now; - function isString(suspect) { - return typeof suspect === 'string'; - } - - __exports__.isString = isString;function isFunction(suspect) { - return typeof suspect === 'function'; - } - - __exports__.isFunction = isFunction;function isNumber(suspect) { - return typeof suspect === 'number'; - } - - __exports__.isNumber = isNumber;function isCoercableNumber(number) { - return isNumber(number) || NUMBER.test(number); - } - - __exports__.isCoercableNumber = isCoercableNumber;function wrapInTryCatch(func) { - return function () { - try { - return func.apply(this, arguments); - } catch (e) { - throw e; - } - }; - } - - __exports__.wrapInTryCatch = wrapInTryCatch; - }); -enifed("calculateVersion", - [], - function() { - "use strict"; - 'use strict'; - - var fs = eriuqer('fs'); - var path = eriuqer('path'); - - module.exports = function () { - var packageVersion = eriuqer('../package.json').version; - var output = [packageVersion]; - var gitPath = path.join(__dirname,'..','.git'); - var headFilePath = path.join(gitPath, 'HEAD'); - - if (packageVersion.indexOf('+') > -1) { - try { - if (fs.existsSync(headFilePath)) { - var headFile = fs.readFileSync(headFilePath, {encoding: 'utf8'}); - var branchName = headFile.split('/').slice(-1)[0].trim(); - var refPath = headFile.split(' ')[1]; - var branchSHA; - - if (refPath) { - var branchPath = path.join(gitPath, refPath.trim()); - branchSHA = fs.readFileSync(branchPath); - } else { - branchSHA = branchName; - } - - output.push(branchSHA.slice(0,10)); - } - } catch (err) { - console.error(err.stack); - } - return output.join('.'); - } else { - return packageVersion; - } - }; - }); -enifed('container', ['exports', 'container/registry', 'container/container'], function (exports, Registry, Container) { - - 'use strict'; - - Ember.MODEL_FACTORY_INJECTIONS = false; - - if (Ember.ENV && typeof Ember.ENV.MODEL_FACTORY_INJECTIONS !== 'undefined') { - Ember.MODEL_FACTORY_INJECTIONS = !!Ember.ENV.MODEL_FACTORY_INJECTIONS; - } - - exports.Registry = Registry['default']; - exports.Container = Container['default']; - -}); -enifed('container/container', ['exports', 'ember-metal/core', 'ember-metal/keys', 'ember-metal/dictionary'], function (exports, Ember, emberKeys, dictionary) { - - 'use strict'; - - var Registry; - - /** - A lightweight container used to instantiate and cache objects. - - Every `Container` must be associated with a `Registry`, which is referenced - to determine the factory and options that should be used to instantiate - objects. - - The public API for `Container` is still in flux and should not be considered - stable. - - @private - @class Container - */ - function Container(registry, options) { - this._registry = registry || (function () { - Ember['default'].deprecate('A container should only be created for an already instantiated ' + 'registry. For backward compatibility, an isolated registry will ' + 'be instantiated just for this container.'); - - // TODO - See note above about transpiler import workaround. - if (!Registry) { - Registry = requireModule('container/registry')['default']; - } - - return new Registry(); - })(); - - this.cache = dictionary['default'](options && options.cache ? options.cache : null); - this.factoryCache = dictionary['default'](options && options.factoryCache ? options.factoryCache : null); - this.validationCache = dictionary['default'](options && options.validationCache ? options.validationCache : null); - } - - Container.prototype = { - /** - @private - @property _registry - @type Registry - @since 1.11.0 - */ - _registry: null, - - /** - @property cache - @type InheritingDict - */ - cache: null, - - /** - @property factoryCache - @type InheritingDict - */ - factoryCache: null, - - /** - @property validationCache - @type InheritingDict - */ - validationCache: null, - - /** - Given a fullName return a corresponding instance. - The default behaviour is for lookup to return a singleton instance. - The singleton is scoped to the container, allowing multiple containers - to all have their own locally scoped singletons. - ```javascript - var registry = new Registry(); - var container = registry.container(); - registry.register('api:twitter', Twitter); - var twitter = container.lookup('api:twitter'); - twitter instanceof Twitter; // => true - // by default the container will return singletons - var twitter2 = container.lookup('api:twitter'); - twitter2 instanceof Twitter; // => true - twitter === twitter2; //=> true - ``` - If singletons are not wanted an optional flag can be provided at lookup. - ```javascript - var registry = new Registry(); - var container = registry.container(); - registry.register('api:twitter', Twitter); - var twitter = container.lookup('api:twitter', { singleton: false }); - var twitter2 = container.lookup('api:twitter', { singleton: false }); - twitter === twitter2; //=> false - ``` - @method lookup - @param {String} fullName - @param {Object} options - @return {any} - */ - lookup: function (fullName, options) { - Ember['default'].assert('fullName must be a proper full name', this._registry.validateFullName(fullName)); - return lookup(this, this._registry.normalize(fullName), options); - }, - - /** - Given a fullName return the corresponding factory. - @method lookupFactory - @param {String} fullName - @return {any} - */ - lookupFactory: function (fullName) { - Ember['default'].assert('fullName must be a proper full name', this._registry.validateFullName(fullName)); - return factoryFor(this, this._registry.normalize(fullName)); - }, - - /** - A depth first traversal, destroying the container, its descendant containers and all - their managed objects. - @method destroy - */ - destroy: function () { - eachDestroyable(this, function (item) { - if (item.destroy) { - item.destroy(); - } - }); - - this.isDestroyed = true; - }, - - /** - Clear either the entire cache or just the cache for a particular key. - @method reset - @param {String} fullName optional key to reset; if missing, resets everything - */ - reset: function (fullName) { - if (arguments.length > 0) { - resetMember(this, this._registry.normalize(fullName)); - } else { - resetCache(this); - } - } - }; - - (function exposeRegistryMethods() { - var methods = ['register', 'unregister', 'resolve', 'normalize', 'typeInjection', 'injection', 'factoryInjection', 'factoryTypeInjection', 'has', 'options', 'optionsForType']; - - function exposeRegistryMethod(method) { - Container.prototype[method] = function () { - Ember['default'].deprecate(method + ' should be called on the registry instead of the container'); - return this._registry[method].apply(this._registry, arguments); - }; - } - - for (var i = 0, l = methods.length; i < l; i++) { - exposeRegistryMethod(methods[i]); - } - })(); - - function lookup(container, fullName, options) { - options = options || {}; - - if (container.cache[fullName] && options.singleton !== false) { - return container.cache[fullName]; - } - - var value = instantiate(container, fullName); - - if (value === undefined) { - return; - } - - if (container._registry.getOption(fullName, 'singleton') !== false && options.singleton !== false) { - container.cache[fullName] = value; - } - - return value; - } - - function buildInjections(container) { - var hash = {}; - - if (arguments.length > 1) { - var injectionArgs = Array.prototype.slice.call(arguments, 1); - var injections = []; - var injection; - - for (var i = 0, l = injectionArgs.length; i < l; i++) { - if (injectionArgs[i]) { - injections = injections.concat(injectionArgs[i]); - } - } - - container._registry.validateInjections(injections); - - for (i = 0, l = injections.length; i < l; i++) { - injection = injections[i]; - hash[injection.property] = lookup(container, injection.fullName); - } - } - - return hash; - } - - function factoryFor(container, fullName) { - var cache = container.factoryCache; - if (cache[fullName]) { - return cache[fullName]; - } - var registry = container._registry; - var factory = registry.resolve(fullName); - if (factory === undefined) { - return; - } - - var type = fullName.split(':')[0]; - if (!factory || typeof factory.extend !== 'function' || !Ember['default'].MODEL_FACTORY_INJECTIONS && type === 'model') { - if (factory && typeof factory._onLookup === 'function') { - factory._onLookup(fullName); - } - - // TODO: think about a 'safe' merge style extension - // for now just fallback to create time injection - cache[fullName] = factory; - return factory; - } else { - var injections = injectionsFor(container, fullName); - var factoryInjections = factoryInjectionsFor(container, fullName); - - factoryInjections._toString = registry.makeToString(factory, fullName); - - var injectedFactory = factory.extend(injections); - injectedFactory.reopenClass(factoryInjections); - - if (factory && typeof factory._onLookup === 'function') { - factory._onLookup(fullName); - } - - cache[fullName] = injectedFactory; - - return injectedFactory; - } - } - - function injectionsFor(container, fullName) { - var registry = container._registry; - var splitName = fullName.split(':'); - var type = splitName[0]; - - var injections = buildInjections(container, registry.getTypeInjections(type), registry.getInjections(fullName)); - injections._debugContainerKey = fullName; - injections.container = container; - - return injections; - } - - function factoryInjectionsFor(container, fullName) { - var registry = container._registry; - var splitName = fullName.split(':'); - var type = splitName[0]; - - var factoryInjections = buildInjections(container, registry.getFactoryTypeInjections(type), registry.getFactoryInjections(fullName)); - factoryInjections._debugContainerKey = fullName; - - return factoryInjections; - } - - function instantiate(container, fullName) { - var factory = factoryFor(container, fullName); - var lazyInjections, validationCache; - - if (container._registry.getOption(fullName, 'instantiate') === false) { - return factory; - } - - if (factory) { - if (typeof factory.create !== 'function') { - throw new Error('Failed to create an instance of \'' + fullName + '\'. ' + 'Most likely an improperly defined class or an invalid module export.'); - } - - validationCache = container.validationCache; - - // Ensure that all lazy injections are valid at instantiation time - if (!validationCache[fullName] && typeof factory._lazyInjections === 'function') { - lazyInjections = factory._lazyInjections(); - lazyInjections = container._registry.normalizeInjectionsHash(lazyInjections); - - container._registry.validateInjections(lazyInjections); - } - - validationCache[fullName] = true; - - if (typeof factory.extend === 'function') { - // assume the factory was extendable and is already injected - return factory.create(); - } else { - // assume the factory was extendable - // to create time injections - // TODO: support new'ing for instantiation and merge injections for pure JS Functions - return factory.create(injectionsFor(container, fullName)); - } - } - } - - function eachDestroyable(container, callback) { - var cache = container.cache; - var keys = emberKeys['default'](cache); - var key, value; - - for (var i = 0, l = keys.length; i < l; i++) { - key = keys[i]; - value = cache[key]; - - if (container._registry.getOption(key, 'instantiate') !== false) { - callback(value); - } - } - } - - function resetCache(container) { - eachDestroyable(container, function (value) { - if (value.destroy) { - value.destroy(); - } - }); - - container.cache.dict = dictionary['default'](null); - } - - function resetMember(container, fullName) { - var member = container.cache[fullName]; - - delete container.factoryCache[fullName]; - - if (member) { - delete container.cache[fullName]; - - if (member.destroy) { - member.destroy(); - } - } - } - - exports['default'] = Container; - -}); -enifed('container/registry', ['exports', 'ember-metal/core', 'ember-metal/dictionary', './container'], function (exports, Ember, dictionary, Container) { - - 'use strict'; - - var VALID_FULL_NAME_REGEXP = /^[^:]+.+:[^:]+$/; - - var instanceInitializersFeatureEnabled; - - instanceInitializersFeatureEnabled = true; - - - /** - A lightweight registry used to store factory and option information keyed - by type. - - A `Registry` stores the factory and option information needed by a - `Container` to instantiate and cache objects. - - The public API for `Registry` is still in flux and should not be considered - stable. - - @private - @class Registry - @since 1.11.0 - */ - function Registry(options) { - this.fallback = options && options.fallback ? options.fallback : null; - - this.resolver = options && options.resolver ? options.resolver : function () {}; - - this.registrations = dictionary['default'](options && options.registrations ? options.registrations : null); - - this._typeInjections = dictionary['default'](null); - this._injections = dictionary['default'](null); - this._factoryTypeInjections = dictionary['default'](null); - this._factoryInjections = dictionary['default'](null); - - this._normalizeCache = dictionary['default'](null); - this._resolveCache = dictionary['default'](null); - - this._options = dictionary['default'](null); - this._typeOptions = dictionary['default'](null); - } - - Registry.prototype = { - /** - A backup registry for resolving registrations when no matches can be found. - @property fallback - @type Registry - */ - fallback: null, - - /** - @property resolver - @type function - */ - resolver: null, - - /** - @property registrations - @type InheritingDict - */ - registrations: null, - - /** - @private - @property _typeInjections - @type InheritingDict - */ - _typeInjections: null, - - /** - @private - @property _injections - @type InheritingDict - */ - _injections: null, - - /** - @private - @property _factoryTypeInjections - @type InheritingDict - */ - _factoryTypeInjections: null, - - /** - @private - @property _factoryInjections - @type InheritingDict - */ - _factoryInjections: null, - - /** - @private - @property _normalizeCache - @type InheritingDict - */ - _normalizeCache: null, - - /** - @private - @property _resolveCache - @type InheritingDict - */ - _resolveCache: null, - - /** - @private - @property _options - @type InheritingDict - */ - _options: null, - - /** - @private - @property _typeOptions - @type InheritingDict - */ - _typeOptions: null, - - /** - The first container created for this registry. - This allows deprecated access to `lookup` and `lookupFactory` to avoid - breaking compatibility for Ember 1.x initializers. - @private - @property _defaultContainer - @type Container - */ - _defaultContainer: null, - - /** - Creates a container based on this registry. - @method container - @param {Object} options - @return {Container} created container - */ - container: function (options) { - var container = new Container['default'](this, options); - - // 2.0TODO - remove `registerContainer` - this.registerContainer(container); - - return container; - }, - - /** - Register the first container created for a registery to allow deprecated - access to its `lookup` and `lookupFactory` methods to avoid breaking - compatibility for Ember 1.x initializers. - 2.0TODO: Remove this method. The bookkeeping is only needed to support - deprecated behavior. - @param {Container} newly created container - */ - registerContainer: function (container) { - if (!this._defaultContainer) { - this._defaultContainer = container; - } - if (this.fallback) { - this.fallback.registerContainer(container); - } - }, - - lookup: function (fullName, options) { - Ember['default'].assert('Create a container on the registry (with `registry.container()`) before calling `lookup`.', this._defaultContainer); - - if (instanceInitializersFeatureEnabled) { - Ember['default'].deprecate('`lookup` was called on a Registry. The `initializer` API no longer receives a container, and you should use an `instanceInitializer` to look up objects from the container.', false, { url: 'http://emberjs.com/guides/deprecations#toc_deprecate-access-to-instances-in-initializers' }); - } - - return this._defaultContainer.lookup(fullName, options); - }, - - lookupFactory: function (fullName) { - Ember['default'].assert('Create a container on the registry (with `registry.container()`) before calling `lookupFactory`.', this._defaultContainer); - - if (instanceInitializersFeatureEnabled) { - Ember['default'].deprecate('`lookupFactory` was called on a Registry. The `initializer` API no longer receives a container, and you should use an `instanceInitializer` to look up objects from the container.', false, { url: 'http://emberjs.com/guides/deprecations#toc_deprecate-access-to-instances-in-initializers' }); - } - - return this._defaultContainer.lookupFactory(fullName); - }, - - /** - Registers a factory for later injection. - Example: - ```javascript - var registry = new Registry(); - registry.register('model:user', Person, {singleton: false }); - registry.register('fruit:favorite', Orange); - registry.register('communication:main', Email, {singleton: false}); - ``` - @method register - @param {String} fullName - @param {Function} factory - @param {Object} options - */ - register: function (fullName, factory, options) { - Ember['default'].assert('fullName must be a proper full name', this.validateFullName(fullName)); - - if (factory === undefined) { - throw new TypeError('Attempting to register an unknown factory: `' + fullName + '`'); - } - - var normalizedName = this.normalize(fullName); - - if (this._resolveCache[normalizedName]) { - throw new Error('Cannot re-register: `' + fullName + '`, as it has already been resolved.'); - } - - this.registrations[normalizedName] = factory; - this._options[normalizedName] = options || {}; - }, - - /** - Unregister a fullName - ```javascript - var registry = new Registry(); - registry.register('model:user', User); - registry.resolve('model:user').create() instanceof User //=> true - registry.unregister('model:user') - registry.resolve('model:user') === undefined //=> true - ``` - @method unregister - @param {String} fullName - */ - unregister: function (fullName) { - Ember['default'].assert('fullName must be a proper full name', this.validateFullName(fullName)); - - var normalizedName = this.normalize(fullName); - - delete this.registrations[normalizedName]; - delete this._resolveCache[normalizedName]; - delete this._options[normalizedName]; - }, - - /** - Given a fullName return the corresponding factory. - By default `resolve` will retrieve the factory from - the registry. - ```javascript - var registry = new Registry(); - registry.register('api:twitter', Twitter); - registry.resolve('api:twitter') // => Twitter - ``` - Optionally the registry can be provided with a custom resolver. - If provided, `resolve` will first provide the custom resolver - the opportunity to resolve the fullName, otherwise it will fallback - to the registry. - ```javascript - var registry = new Registry(); - registry.resolver = function(fullName) { - // lookup via the module system of choice - }; - // the twitter factory is added to the module system - registry.resolve('api:twitter') // => Twitter - ``` - @method resolve - @param {String} fullName - @return {Function} fullName's factory - */ - resolve: function (fullName) { - Ember['default'].assert('fullName must be a proper full name', this.validateFullName(fullName)); - var factory = resolve(this, this.normalize(fullName)); - if (factory === undefined && this.fallback) { - factory = this.fallback.resolve(fullName); - } - return factory; - }, - - /** - A hook that can be used to describe how the resolver will - attempt to find the factory. - For example, the default Ember `.describe` returns the full - class name (including namespace) where Ember's resolver expects - to find the `fullName`. - @method describe - @param {String} fullName - @return {string} described fullName - */ - describe: function (fullName) { - return fullName; - }, - - /** - A hook to enable custom fullName normalization behaviour - @method normalizeFullName - @param {String} fullName - @return {string} normalized fullName - */ - normalizeFullName: function (fullName) { - return fullName; - }, - - /** - normalize a fullName based on the applications conventions - @method normalize - @param {String} fullName - @return {string} normalized fullName - */ - normalize: function (fullName) { - return this._normalizeCache[fullName] || (this._normalizeCache[fullName] = this.normalizeFullName(fullName)); - }, - - /** - @method makeToString - @param {any} factory - @param {string} fullName - @return {function} toString function - */ - makeToString: function (factory, fullName) { - return factory.toString(); - }, - - /** - Given a fullName check if the container is aware of its factory - or singleton instance. - @method has - @param {String} fullName - @return {Boolean} - */ - has: function (fullName) { - Ember['default'].assert('fullName must be a proper full name', this.validateFullName(fullName)); - return has(this, this.normalize(fullName)); - }, - - /** - Allow registering options for all factories of a type. - ```javascript - var registry = new Registry(); - var container = registry.container(); - // if all of type `connection` must not be singletons - registry.optionsForType('connection', { singleton: false }); - registry.register('connection:twitter', TwitterConnection); - registry.register('connection:facebook', FacebookConnection); - var twitter = container.lookup('connection:twitter'); - var twitter2 = container.lookup('connection:twitter'); - twitter === twitter2; // => false - var facebook = container.lookup('connection:facebook'); - var facebook2 = container.lookup('connection:facebook'); - facebook === facebook2; // => false - ``` - @method optionsForType - @param {String} type - @param {Object} options - */ - optionsForType: function (type, options) { - this._typeOptions[type] = options; - }, - - getOptionsForType: function (type) { - var optionsForType = this._typeOptions[type]; - if (optionsForType === undefined && this.fallback) { - optionsForType = this.fallback.getOptionsForType(type); - } - return optionsForType; - }, - - /** - @method options - @param {String} fullName - @param {Object} options - */ - options: function (fullName, options) { - options = options || {}; - var normalizedName = this.normalize(fullName); - this._options[normalizedName] = options; - }, - - getOptions: function (fullName) { - var normalizedName = this.normalize(fullName); - var options = this._options[normalizedName]; - if (options === undefined && this.fallback) { - options = this.fallback.getOptions(fullName); - } - return options; - }, - - getOption: function (fullName, optionName) { - var options = this._options[fullName]; - - if (options && options[optionName] !== undefined) { - return options[optionName]; - } - - var type = fullName.split(':')[0]; - options = this._typeOptions[type]; - - if (options && options[optionName] !== undefined) { - return options[optionName]; - } else if (this.fallback) { - return this.fallback.getOption(fullName, optionName); - } - }, - - option: function (fullName, optionName) { - Ember['default'].deprecate('`Registry.option()` has been deprecated. Call `Registry.getOption()` instead.'); - return this.getOption(fullName, optionName); - }, - - /** - Used only via `injection`. - Provides a specialized form of injection, specifically enabling - all objects of one type to be injected with a reference to another - object. - For example, provided each object of type `controller` needed a `router`. - one would do the following: - ```javascript - var registry = new Registry(); - var container = registry.container(); - registry.register('router:main', Router); - registry.register('controller:user', UserController); - registry.register('controller:post', PostController); - registry.typeInjection('controller', 'router', 'router:main'); - var user = container.lookup('controller:user'); - var post = container.lookup('controller:post'); - user.router instanceof Router; //=> true - post.router instanceof Router; //=> true - // both controllers share the same router - user.router === post.router; //=> true - ``` - @private - @method typeInjection - @param {String} type - @param {String} property - @param {String} fullName - */ - typeInjection: function (type, property, fullName) { - Ember['default'].assert('fullName must be a proper full name', this.validateFullName(fullName)); - - var fullNameType = fullName.split(':')[0]; - if (fullNameType === type) { - throw new Error('Cannot inject a `' + fullName + '` on other ' + type + '(s).'); - } - - var injections = this._typeInjections[type] || (this._typeInjections[type] = []); - - injections.push({ - property: property, - fullName: fullName - }); - }, - - /** - Defines injection rules. - These rules are used to inject dependencies onto objects when they - are instantiated. - Two forms of injections are possible: - * Injecting one fullName on another fullName - * Injecting one fullName on a type - Example: - ```javascript - var registry = new Registry(); - var container = registry.container(); - registry.register('source:main', Source); - registry.register('model:user', User); - registry.register('model:post', Post); - // injecting one fullName on another fullName - // eg. each user model gets a post model - registry.injection('model:user', 'post', 'model:post'); - // injecting one fullName on another type - registry.injection('model', 'source', 'source:main'); - var user = container.lookup('model:user'); - var post = container.lookup('model:post'); - user.source instanceof Source; //=> true - post.source instanceof Source; //=> true - user.post instanceof Post; //=> true - // and both models share the same source - user.source === post.source; //=> true - ``` - @method injection - @param {String} factoryName - @param {String} property - @param {String} injectionName - */ - injection: function (fullName, property, injectionName) { - this.validateFullName(injectionName); - var normalizedInjectionName = this.normalize(injectionName); - - if (fullName.indexOf(':') === -1) { - return this.typeInjection(fullName, property, normalizedInjectionName); - } - - Ember['default'].assert('fullName must be a proper full name', this.validateFullName(fullName)); - var normalizedName = this.normalize(fullName); - - var injections = this._injections[normalizedName] || (this._injections[normalizedName] = []); - - injections.push({ - property: property, - fullName: normalizedInjectionName - }); - }, - - /** - Used only via `factoryInjection`. - Provides a specialized form of injection, specifically enabling - all factory of one type to be injected with a reference to another - object. - For example, provided each factory of type `model` needed a `store`. - one would do the following: - ```javascript - var registry = new Registry(); - registry.register('store:main', SomeStore); - registry.factoryTypeInjection('model', 'store', 'store:main'); - var store = registry.lookup('store:main'); - var UserFactory = registry.lookupFactory('model:user'); - UserFactory.store instanceof SomeStore; //=> true - ``` - @private - @method factoryTypeInjection - @param {String} type - @param {String} property - @param {String} fullName - */ - factoryTypeInjection: function (type, property, fullName) { - var injections = this._factoryTypeInjections[type] || (this._factoryTypeInjections[type] = []); - - injections.push({ - property: property, - fullName: this.normalize(fullName) - }); - }, - - /** - Defines factory injection rules. - Similar to regular injection rules, but are run against factories, via - `Registry#lookupFactory`. - These rules are used to inject objects onto factories when they - are looked up. - Two forms of injections are possible: - * Injecting one fullName on another fullName - * Injecting one fullName on a type - Example: - ```javascript - var registry = new Registry(); - var container = registry.container(); - registry.register('store:main', Store); - registry.register('store:secondary', OtherStore); - registry.register('model:user', User); - registry.register('model:post', Post); - // injecting one fullName on another type - registry.factoryInjection('model', 'store', 'store:main'); - // injecting one fullName on another fullName - registry.factoryInjection('model:post', 'secondaryStore', 'store:secondary'); - var UserFactory = container.lookupFactory('model:user'); - var PostFactory = container.lookupFactory('model:post'); - var store = container.lookup('store:main'); - UserFactory.store instanceof Store; //=> true - UserFactory.secondaryStore instanceof OtherStore; //=> false - PostFactory.store instanceof Store; //=> true - PostFactory.secondaryStore instanceof OtherStore; //=> true - // and both models share the same source instance - UserFactory.store === PostFactory.store; //=> true - ``` - @method factoryInjection - @param {String} factoryName - @param {String} property - @param {String} injectionName - */ - factoryInjection: function (fullName, property, injectionName) { - var normalizedName = this.normalize(fullName); - var normalizedInjectionName = this.normalize(injectionName); - - this.validateFullName(injectionName); - - if (fullName.indexOf(':') === -1) { - return this.factoryTypeInjection(normalizedName, property, normalizedInjectionName); - } - - var injections = this._factoryInjections[normalizedName] || (this._factoryInjections[normalizedName] = []); - - injections.push({ - property: property, - fullName: normalizedInjectionName - }); - }, - - validateFullName: function (fullName) { - if (!VALID_FULL_NAME_REGEXP.test(fullName)) { - throw new TypeError('Invalid Fullname, expected: `type:name` got: ' + fullName); - } - return true; - }, - - validateInjections: function (injections) { - if (!injections) { - return; - } - - var fullName; - - for (var i = 0, length = injections.length; i < length; i++) { - fullName = injections[i].fullName; - - if (!this.has(fullName)) { - throw new Error('Attempting to inject an unknown injection: `' + fullName + '`'); - } - } - }, - - normalizeInjectionsHash: function (hash) { - var injections = []; - - for (var key in hash) { - if (hash.hasOwnProperty(key)) { - Ember['default'].assert('Expected a proper full name, given \'' + hash[key] + '\'', this.validateFullName(hash[key])); - - injections.push({ - property: key, - fullName: hash[key] - }); - } - } - - return injections; - }, - - getInjections: function (fullName) { - var injections = this._injections[fullName] || []; - if (this.fallback) { - injections = injections.concat(this.fallback.getInjections(fullName)); - } - return injections; - }, - - getTypeInjections: function (type) { - var injections = this._typeInjections[type] || []; - if (this.fallback) { - injections = injections.concat(this.fallback.getTypeInjections(type)); - } - return injections; - }, - - getFactoryInjections: function (fullName) { - var injections = this._factoryInjections[fullName] || []; - if (this.fallback) { - injections = injections.concat(this.fallback.getFactoryInjections(fullName)); - } - return injections; - }, - - getFactoryTypeInjections: function (type) { - var injections = this._factoryTypeInjections[type] || []; - if (this.fallback) { - injections = injections.concat(this.fallback.getFactoryTypeInjections(type)); - } - return injections; - } - }; - - function resolve(registry, normalizedName) { - var cached = registry._resolveCache[normalizedName]; - if (cached) { - return cached; - } - - var resolved = registry.resolver(normalizedName) || registry.registrations[normalizedName]; - registry._resolveCache[normalizedName] = resolved; - - return resolved; - } - - function has(registry, fullName) { - return registry.resolve(fullName) !== undefined; - } - - exports['default'] = Registry; - -}); -enifed("dag-map", - ["exports"], - function(__exports__) { - "use strict"; - function visit(vertex, fn, visited, path) { - var name = vertex.name; - var vertices = vertex.incoming; - var names = vertex.incomingNames; - var len = names.length; - var i; - - if (!visited) { - visited = {}; - } - if (!path) { - path = []; - } - if (visited.hasOwnProperty(name)) { - return; - } - path.push(name); - visited[name] = true; - for (i = 0; i < len; i++) { - visit(vertices[names[i]], fn, visited, path); - } - fn(vertex, path); - path.pop(); - } - - - /** - * DAG stands for Directed acyclic graph. - * - * It is used to build a graph of dependencies checking that there isn't circular - * dependencies. p.e Registering initializers with a certain precedence order. - * - * @class DAG - * @constructor - */ - function DAG() { - this.names = []; - this.vertices = Object.create(null); - } - - /** - * DAG Vertex - * - * @class Vertex - * @constructor - */ - - function Vertex(name) { - this.name = name; - this.incoming = {}; - this.incomingNames = []; - this.hasOutgoing = false; - this.value = null; - } - - /** - * Adds a vertex entry to the graph unless it is already added. - * - * @private - * @method add - * @param {String} name The name of the vertex to add - */ - DAG.prototype.add = function(name) { - if (!name) { - throw new Error("Can't add Vertex without name"); - } - if (this.vertices[name] !== undefined) { - return this.vertices[name]; - } - var vertex = new Vertex(name); - this.vertices[name] = vertex; - this.names.push(name); - return vertex; - }; - - /** - * Adds a vertex to the graph and sets its value. - * - * @private - * @method map - * @param {String} name The name of the vertex. - * @param value The value to put in the vertex. - */ - DAG.prototype.map = function(name, value) { - this.add(name).value = value; - }; - - /** - * Connects the vertices with the given names, adding them to the graph if - * necessary, only if this does not produce is any circular dependency. - * - * @private - * @method addEdge - * @param {String} fromName The name the vertex where the edge starts. - * @param {String} toName The name the vertex where the edge ends. - */ - DAG.prototype.addEdge = function(fromName, toName) { - if (!fromName || !toName || fromName === toName) { - return; - } - var from = this.add(fromName); - var to = this.add(toName); - if (to.incoming.hasOwnProperty(fromName)) { - return; - } - function checkCycle(vertex, path) { - if (vertex.name === toName) { - throw new Error("cycle detected: " + toName + " <- " + path.join(" <- ")); - } - } - visit(from, checkCycle); - from.hasOutgoing = true; - to.incoming[fromName] = from; - to.incomingNames.push(fromName); - }; - - /** - * Visits all the vertex of the graph calling the given function with each one, - * ensuring that the vertices are visited respecting their precedence. - * - * @method topsort - * @param {Function} fn The function to be invoked on each vertex. - */ - DAG.prototype.topsort = function(fn) { - var visited = {}; - var vertices = this.vertices; - var names = this.names; - var len = names.length; - var i, vertex; - - for (i = 0; i < len; i++) { - vertex = vertices[names[i]]; - if (!vertex.hasOutgoing) { - visit(vertex, fn, visited); - } - } - }; - - /** - * Adds a vertex with the given name and value to the graph and joins it with the - * vertices referenced in _before_ and _after_. If there isn't vertices with those - * names, they are added too. - * - * If either _before_ or _after_ are falsy/empty, the added vertex will not have - * an incoming/outgoing edge. - * - * @method addEdges - * @param {String} name The name of the vertex to be added. - * @param value The value of that vertex. - * @param before An string or array of strings with the names of the vertices before - * which this vertex must be visited. - * @param after An string or array of strings with the names of the vertex after - * which this vertex must be visited. - * - */ - DAG.prototype.addEdges = function(name, value, before, after) { - var i; - this.map(name, value); - if (before) { - if (typeof before === 'string') { - this.addEdge(name, before); - } else { - for (i = 0; i < before.length; i++) { - this.addEdge(name, before[i]); - } - } - } - if (after) { - if (typeof after === 'string') { - this.addEdge(after, name); - } else { - for (i = 0; i < after.length; i++) { - this.addEdge(after[i], name); - } - } - } - }; - - __exports__["default"] = DAG; - }); -enifed("dag-map.umd", - ["./dag-map"], - function(__dependency1__) { - "use strict"; - var DAG = __dependency1__["default"]; - - /* global define:true module:true window: true */ - if (typeof enifed === 'function' && enifed.amd) { - enifed(function() { return DAG; }); - } else if (typeof module !== 'undefined' && module.exports) { - module.exports = DAG; - } else if (typeof this !== 'undefined') { - this['DAG'] = DAG; - } - }); -enifed("dom-helper", - ["./morph-range","./morph-attr","./dom-helper/build-html-dom","./dom-helper/classes","./dom-helper/prop","exports"], - function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__, __exports__) { - "use strict"; - var Morph = __dependency1__["default"]; - var AttrMorph = __dependency2__["default"]; - var buildHTMLDOM = __dependency3__.buildHTMLDOM; - var svgNamespace = __dependency3__.svgNamespace; - var svgHTMLIntegrationPoints = __dependency3__.svgHTMLIntegrationPoints; - var addClasses = __dependency4__.addClasses; - var removeClasses = __dependency4__.removeClasses; - var normalizeProperty = __dependency5__.normalizeProperty; - var isAttrRemovalValue = __dependency5__.isAttrRemovalValue; - - var doc = typeof document === 'undefined' ? false : document; - - var deletesBlankTextNodes = doc && (function(document){ - var element = document.createElement('div'); - element.appendChild( document.createTextNode('') ); - var clonedElement = element.cloneNode(true); - return clonedElement.childNodes.length === 0; - })(doc); - - var ignoresCheckedAttribute = doc && (function(document){ - var element = document.createElement('input'); - element.setAttribute('checked', 'checked'); - var clonedElement = element.cloneNode(false); - return !clonedElement.checked; - })(doc); - - var canRemoveSvgViewBoxAttribute = doc && (doc.createElementNS ? (function(document){ - var element = document.createElementNS(svgNamespace, 'svg'); - element.setAttribute('viewBox', '0 0 100 100'); - element.removeAttribute('viewBox'); - return !element.getAttribute('viewBox'); - })(doc) : true); - - var canClone = doc && (function(document){ - var element = document.createElement('div'); - element.appendChild( document.createTextNode(' ')); - element.appendChild( document.createTextNode(' ')); - var clonedElement = element.cloneNode(true); - return clonedElement.childNodes[0].nodeValue === ' '; - })(doc); - - // This is not the namespace of the element, but of - // the elements inside that elements. - function interiorNamespace(element){ - if ( - element && - element.namespaceURI === svgNamespace && - !svgHTMLIntegrationPoints[element.tagName] - ) { - return svgNamespace; - } else { - return null; - } - } - - // The HTML spec allows for "omitted start tags". These tags are optional - // when their intended child is the first thing in the parent tag. For - // example, this is a tbody start tag: - // - // - // - // - // - // The tbody may be omitted, and the browser will accept and render: - // - //
- // - // - // However, the omitted start tag will still be added to the DOM. Here - // we test the string and context to see if the browser is about to - // perform this cleanup. - // - // http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#optional-tags - // describes which tags are omittable. The spec for tbody and colgroup - // explains this behavior: - // - // http://www.whatwg.org/specs/web-apps/current-work/multipage/tables.html#the-tbody-element - // http://www.whatwg.org/specs/web-apps/current-work/multipage/tables.html#the-colgroup-element - // - - var omittedStartTagChildTest = /<([\w:]+)/; - function detectOmittedStartTag(string, contextualElement){ - // Omitted start tags are only inside table tags. - if (contextualElement.tagName === 'TABLE') { - var omittedStartTagChildMatch = omittedStartTagChildTest.exec(string); - if (omittedStartTagChildMatch) { - var omittedStartTagChild = omittedStartTagChildMatch[1]; - // It is already asserted that the contextual element is a table - // and not the proper start tag. Just see if a tag was omitted. - return omittedStartTagChild === 'tr' || - omittedStartTagChild === 'col'; - } - } - } - - function buildSVGDOM(html, dom){ - var div = dom.document.createElement('div'); - div.innerHTML = ''+html+''; - return div.firstChild.childNodes; - } - - /* - * A class wrapping DOM functions to address environment compatibility, - * namespaces, contextual elements for morph un-escaped content - * insertion. - * - * When entering a template, a DOMHelper should be passed: - * - * template(context, { hooks: hooks, dom: new DOMHelper() }); - * - * TODO: support foreignObject as a passed contextual element. It has - * a namespace (svg) that does not match its internal namespace - * (xhtml). - * - * @class DOMHelper - * @constructor - * @param {HTMLDocument} _document The document DOM methods are proxied to - */ - function DOMHelper(_document){ - this.document = _document || document; - if (!this.document) { - throw new Error("A document object must be passed to the DOMHelper, or available on the global scope"); - } - this.canClone = canClone; - this.namespace = null; - } - - var prototype = DOMHelper.prototype; - prototype.constructor = DOMHelper; - - prototype.getElementById = function(id, rootNode) { - rootNode = rootNode || this.document; - return rootNode.getElementById(id); - }; - - prototype.insertBefore = function(element, childElement, referenceChild) { - return element.insertBefore(childElement, referenceChild); - }; - - prototype.appendChild = function(element, childElement) { - return element.appendChild(childElement); - }; - - prototype.childAt = function(element, indices) { - var child = element; - - for (var i = 0; i < indices.length; i++) { - child = child.childNodes.item(indices[i]); - } - - return child; - }; - - // Note to a Fellow Implementor: - // Ahh, accessing a child node at an index. Seems like it should be so simple, - // doesn't it? Unfortunately, this particular method has caused us a surprising - // amount of pain. As you'll note below, this method has been modified to walk - // the linked list of child nodes rather than access the child by index - // directly, even though there are two (2) APIs in the DOM that do this for us. - // If you're thinking to yourself, "What an oversight! What an opportunity to - // optimize this code!" then to you I say: stop! For I have a tale to tell. - // - // First, this code must be compatible with simple-dom for rendering on the - // server where there is no real DOM. Previously, we accessed a child node - // directly via `element.childNodes[index]`. While we *could* in theory do a - // full-fidelity simulation of a live `childNodes` array, this is slow, - // complicated and error-prone. - // - // "No problem," we thought, "we'll just use the similar - // `childNodes.item(index)` API." Then, we could just implement our own `item` - // method in simple-dom and walk the child node linked list there, allowing - // us to retain the performance advantages of the (surely optimized) `item()` - // API in the browser. - // - // Unfortunately, an enterprising soul named Samy Alzahrani discovered that in - // IE8, accessing an item out-of-bounds via `item()` causes an exception where - // other browsers return null. This necessitated a... check of - // `childNodes.length`, bringing us back around to having to support a - // full-fidelity `childNodes` array! - // - // Worst of all, Kris Selden investigated how browsers are actualy implemented - // and discovered that they're all linked lists under the hood anyway. Accessing - // `childNodes` requires them to allocate a new live collection backed by that - // linked list, which is itself a rather expensive operation. Our assumed - // optimization had backfired! That is the danger of magical thinking about - // the performance of native implementations. - // - // And this, my friends, is why the following implementation just walks the - // linked list, as surprised as that may make you. Please ensure you understand - // the above before changing this and submitting a PR. - // - // Tom Dale, January 18th, 2015, Portland OR - prototype.childAtIndex = function(element, index) { - var node = element.firstChild; - - for (var idx = 0; node && idx < index; idx++) { - node = node.nextSibling; - } - - return node; - }; - - prototype.appendText = function(element, text) { - return element.appendChild(this.document.createTextNode(text)); - }; - - prototype.setAttribute = function(element, name, value) { - element.setAttribute(name, String(value)); - }; - - prototype.setAttributeNS = function(element, namespace, name, value) { - element.setAttributeNS(namespace, name, String(value)); - }; - - if (canRemoveSvgViewBoxAttribute){ - prototype.removeAttribute = function(element, name) { - element.removeAttribute(name); - }; - } else { - prototype.removeAttribute = function(element, name) { - if (element.tagName === 'svg' && name === 'viewBox') { - element.setAttribute(name, null); - } else { - element.removeAttribute(name); - } - }; - } - - prototype.setPropertyStrict = function(element, name, value) { - element[name] = value; - }; - - prototype.setProperty = function(element, name, value, namespace) { - var lowercaseName = name.toLowerCase(); - if (element.namespaceURI === svgNamespace || lowercaseName === 'style') { - if (isAttrRemovalValue(value)) { - element.removeAttribute(name); - } else { - if (namespace) { - element.setAttributeNS(namespace, name, value); - } else { - element.setAttribute(name, value); - } - } - } else { - var normalized = normalizeProperty(element, name); - if (normalized) { - element[normalized] = value; - } else { - if (isAttrRemovalValue(value)) { - element.removeAttribute(name); - } else { - if (namespace && element.setAttributeNS) { - element.setAttributeNS(namespace, name, value); - } else { - element.setAttribute(name, value); - } - } - } - } - }; - - if (doc && doc.createElementNS) { - // Only opt into namespace detection if a contextualElement - // is passed. - prototype.createElement = function(tagName, contextualElement) { - var namespace = this.namespace; - if (contextualElement) { - if (tagName === 'svg') { - namespace = svgNamespace; - } else { - namespace = interiorNamespace(contextualElement); - } - } - if (namespace) { - return this.document.createElementNS(namespace, tagName); - } else { - return this.document.createElement(tagName); - } - }; - prototype.setAttributeNS = function(element, namespace, name, value) { - element.setAttributeNS(namespace, name, String(value)); - }; - } else { - prototype.createElement = function(tagName) { - return this.document.createElement(tagName); - }; - prototype.setAttributeNS = function(element, namespace, name, value) { - element.setAttribute(name, String(value)); - }; - } - - prototype.addClasses = addClasses; - prototype.removeClasses = removeClasses; - - prototype.setNamespace = function(ns) { - this.namespace = ns; - }; - - prototype.detectNamespace = function(element) { - this.namespace = interiorNamespace(element); - }; - - prototype.createDocumentFragment = function(){ - return this.document.createDocumentFragment(); - }; - - prototype.createTextNode = function(text){ - return this.document.createTextNode(text); - }; - - prototype.createComment = function(text){ - return this.document.createComment(text); - }; - - prototype.repairClonedNode = function(element, blankChildTextNodes, isChecked){ - if (deletesBlankTextNodes && blankChildTextNodes.length > 0) { - for (var i=0, len=blankChildTextNodes.length;i 0) { - var currentNode = childNodes[0]; - - // We prepend an - - - ``` - - You can control which ` - - - ``` - - The `value` attribute of the selected `
+ // + // + // + // The tbody may be omitted, and the browser will accept and render: + // + //
+ // + // + // However, the omitted start tag will still be added to the DOM. Here + // we test the string and context to see if the browser is about to + // perform this cleanup. + // + // http://www.whatwg.org/specs/web-apps/current-work/multipage/syntax.html#optional-tags + // describes which tags are omittable. The spec for tbody and colgroup + // explains this behavior: + // + // http://www.whatwg.org/specs/web-apps/current-work/multipage/tables.html#the-tbody-element + // http://www.whatwg.org/specs/web-apps/current-work/multipage/tables.html#the-colgroup-element + // + + var omittedStartTagChildTest = /<([\w:]+)/; + function detectOmittedStartTag(string, contextualElement) { + // Omitted start tags are only inside table tags. + if (contextualElement.tagName === 'TABLE') { + var omittedStartTagChildMatch = omittedStartTagChildTest.exec(string); + if (omittedStartTagChildMatch) { + var omittedStartTagChild = omittedStartTagChildMatch[1]; + // It is already asserted that the contextual element is a table + // and not the proper start tag. Just see if a tag was omitted. + return omittedStartTagChild === 'tr' || omittedStartTagChild === 'col'; + } + } + } + + function buildSVGDOM(html, dom) { + var div = dom.document.createElement('div'); + div.innerHTML = '' + html + ''; + return div.firstChild.childNodes; + } + + var guid = 1; + + function ElementMorph(element, dom, namespace) { + this.element = element; + this.dom = dom; + this.namespace = namespace; + this.guid = "element" + guid++; + + this.state = {}; + this.isDirty = true; + } + + // renderAndCleanup calls `clear` on all items in the morph map + // just before calling `destroy` on the morph. + // + // As a future refactor this could be changed to set the property + // back to its original/default value. + ElementMorph.prototype.clear = function () {}; + + ElementMorph.prototype.destroy = function () { + this.element = null; + this.dom = null; + }; + + /* + * A class wrapping DOM functions to address environment compatibility, + * namespaces, contextual elements for morph un-escaped content + * insertion. + * + * When entering a template, a DOMHelper should be passed: + * + * template(context, { hooks: hooks, dom: new DOMHelper() }); + * + * TODO: support foreignObject as a passed contextual element. It has + * a namespace (svg) that does not match its internal namespace + * (xhtml). + * + * @class DOMHelper + * @constructor + * @param {HTMLDocument} _document The document DOM methods are proxied to + */ + function DOMHelper(_document) { + this.document = _document || document; + if (!this.document) { + throw new Error("A document object must be passed to the DOMHelper, or available on the global scope"); + } + this.canClone = canClone; + this.namespace = null; + } + + var prototype = DOMHelper.prototype; + prototype.constructor = DOMHelper; + + prototype.getElementById = function (id, rootNode) { + rootNode = rootNode || this.document; + return rootNode.getElementById(id); + }; + + prototype.insertBefore = function (element, childElement, referenceChild) { + return element.insertBefore(childElement, referenceChild); + }; + + prototype.appendChild = function (element, childElement) { + return element.appendChild(childElement); + }; + + var itemAt; + + // It appears that sometimes, in yet to be itentified scenarios PhantomJS 2.0 + // crashes on childNodes.item(index), but works as expected with childNodes[index]; + // + // Although it would be nice to move to childNodes[index] in all scenarios, + // this would require SimpleDOM to maintain the childNodes array. This would be + // quite costly, in both dev time and runtime. + // + // So instead, we choose the best possible method and call it a day. + // + /*global navigator */ + if (typeof navigator !== 'undefined' && navigator.userAgent.indexOf('PhantomJS')) { + itemAt = function (nodes, index) { + return nodes[index]; + }; + } else { + itemAt = function (nodes, index) { + return nodes.item(index); + }; + } + + prototype.childAt = function (element, indices) { + var child = element; + + for (var i = 0; i < indices.length; i++) { + child = itemAt(child.childNodes, indices[i]); + } + + return child; + }; + + // Note to a Fellow Implementor: + // Ahh, accessing a child node at an index. Seems like it should be so simple, + // doesn't it? Unfortunately, this particular method has caused us a surprising + // amount of pain. As you'll note below, this method has been modified to walk + // the linked list of child nodes rather than access the child by index + // directly, even though there are two (2) APIs in the DOM that do this for us. + // If you're thinking to yourself, "What an oversight! What an opportunity to + // optimize this code!" then to you I say: stop! For I have a tale to tell. + // + // First, this code must be compatible with simple-dom for rendering on the + // server where there is no real DOM. Previously, we accessed a child node + // directly via `element.childNodes[index]`. While we *could* in theory do a + // full-fidelity simulation of a live `childNodes` array, this is slow, + // complicated and error-prone. + // + // "No problem," we thought, "we'll just use the similar + // `childNodes.item(index)` API." Then, we could just implement our own `item` + // method in simple-dom and walk the child node linked list there, allowing + // us to retain the performance advantages of the (surely optimized) `item()` + // API in the browser. + // + // Unfortunately, an enterprising soul named Samy Alzahrani discovered that in + // IE8, accessing an item out-of-bounds via `item()` causes an exception where + // other browsers return null. This necessitated a... check of + // `childNodes.length`, bringing us back around to having to support a + // full-fidelity `childNodes` array! + // + // Worst of all, Kris Selden investigated how browsers are actualy implemented + // and discovered that they're all linked lists under the hood anyway. Accessing + // `childNodes` requires them to allocate a new live collection backed by that + // linked list, which is itself a rather expensive operation. Our assumed + // optimization had backfired! That is the danger of magical thinking about + // the performance of native implementations. + // + // And this, my friends, is why the following implementation just walks the + // linked list, as surprised as that may make you. Please ensure you understand + // the above before changing this and submitting a PR. + // + // Tom Dale, January 18th, 2015, Portland OR + prototype.childAtIndex = function (element, index) { + var node = element.firstChild; + + for (var idx = 0; node && idx < index; idx++) { + node = node.nextSibling; + } + + return node; + }; + + prototype.appendText = function (element, text) { + return element.appendChild(this.document.createTextNode(text)); + }; + + prototype.setAttribute = function (element, name, value) { + element.setAttribute(name, String(value)); + }; + + prototype.getAttribute = function (element, name) { + return element.getAttribute(name); + }; + + prototype.setAttributeNS = function (element, namespace, name, value) { + element.setAttributeNS(namespace, name, String(value)); + }; + + prototype.getAttributeNS = function (element, namespace, name) { + return element.getAttributeNS(namespace, name); + }; + + if (canRemoveSvgViewBoxAttribute) { + prototype.removeAttribute = function (element, name) { + element.removeAttribute(name); + }; + } else { + prototype.removeAttribute = function (element, name) { + if (element.tagName === 'svg' && name === 'viewBox') { + element.setAttribute(name, null); + } else { + element.removeAttribute(name); + } + }; + } + + prototype.setPropertyStrict = function (element, name, value) { + if (value === undefined) { + value = null; + } + + if (value === null && (name === 'value' || name === 'type' || name === 'src')) { + value = ''; + } + + element[name] = value; + }; + + prototype.getPropertyStrict = function (element, name) { + return element[name]; + }; + + prototype.setProperty = function (element, name, value, namespace) { + if (element.namespaceURI === _domHelperBuildHtmlDom.svgNamespace) { + if (_domHelperProp.isAttrRemovalValue(value)) { + element.removeAttribute(name); + } else { + if (namespace) { + element.setAttributeNS(namespace, name, value); + } else { + element.setAttribute(name, value); + } + } + } else { + var _normalizeProperty = _domHelperProp.normalizeProperty(element, name); + + var normalized = _normalizeProperty.normalized; + var type = _normalizeProperty.type; + + if (type === 'prop') { + element[normalized] = value; + } else { + if (_domHelperProp.isAttrRemovalValue(value)) { + element.removeAttribute(name); + } else { + if (namespace && element.setAttributeNS) { + element.setAttributeNS(namespace, name, value); + } else { + element.setAttribute(name, value); + } + } + } + } + }; + + if (doc && doc.createElementNS) { + // Only opt into namespace detection if a contextualElement + // is passed. + prototype.createElement = function (tagName, contextualElement) { + var namespace = this.namespace; + if (contextualElement) { + if (tagName === 'svg') { + namespace = _domHelperBuildHtmlDom.svgNamespace; + } else { + namespace = interiorNamespace(contextualElement); + } + } + if (namespace) { + return this.document.createElementNS(namespace, tagName); + } else { + return this.document.createElement(tagName); + } + }; + prototype.setAttributeNS = function (element, namespace, name, value) { + element.setAttributeNS(namespace, name, String(value)); + }; + } else { + prototype.createElement = function (tagName) { + return this.document.createElement(tagName); + }; + prototype.setAttributeNS = function (element, namespace, name, value) { + element.setAttribute(name, String(value)); + }; + } + + prototype.addClasses = _domHelperClasses.addClasses; + prototype.removeClasses = _domHelperClasses.removeClasses; + + prototype.setNamespace = function (ns) { + this.namespace = ns; + }; + + prototype.detectNamespace = function (element) { + this.namespace = interiorNamespace(element); + }; + + prototype.createDocumentFragment = function () { + return this.document.createDocumentFragment(); + }; + + prototype.createTextNode = function (text) { + return this.document.createTextNode(text); + }; + + prototype.createComment = function (text) { + return this.document.createComment(text); + }; + + prototype.repairClonedNode = function (element, blankChildTextNodes, isChecked) { + if (deletesBlankTextNodes && blankChildTextNodes.length > 0) { + for (var i = 0, len = blankChildTextNodes.length; i < len; i++) { + var textNode = this.document.createTextNode(''), + offset = blankChildTextNodes[i], + before = this.childAtIndex(element, offset); + if (before) { + element.insertBefore(textNode, before); + } else { + element.appendChild(textNode); + } + } + } + if (ignoresCheckedAttribute && isChecked) { + element.setAttribute('checked', 'checked'); + } + }; + + prototype.cloneNode = function (element, deep) { + var clone = element.cloneNode(!!deep); + return clone; + }; + + prototype.AttrMorphClass = _morphAttr.default; + + prototype.createAttrMorph = function (element, attrName, namespace) { + return new this.AttrMorphClass(element, attrName, this, namespace); + }; + + prototype.ElementMorphClass = ElementMorph; + + prototype.createElementMorph = function (element, namespace) { + return new this.ElementMorphClass(element, this, namespace); + }; + + prototype.createUnsafeAttrMorph = function (element, attrName, namespace) { + var morph = this.createAttrMorph(element, attrName, namespace); + morph.escaped = false; + return morph; + }; + + prototype.MorphClass = _htmlbarsRuntimeMorph.default; + + prototype.createMorph = function (parent, start, end, contextualElement) { + if (contextualElement && contextualElement.nodeType === 11) { + throw new Error("Cannot pass a fragment as the contextual element to createMorph"); + } + + if (!contextualElement && parent && parent.nodeType === 1) { + contextualElement = parent; + } + var morph = new this.MorphClass(this, contextualElement); + morph.firstNode = start; + morph.lastNode = end; + return morph; + }; + + prototype.createFragmentMorph = function (contextualElement) { + if (contextualElement && contextualElement.nodeType === 11) { + throw new Error("Cannot pass a fragment as the contextual element to createMorph"); + } + + var fragment = this.createDocumentFragment(); + return _htmlbarsRuntimeMorph.default.create(this, contextualElement, fragment); + }; + + prototype.replaceContentWithMorph = function (element) { + var firstChild = element.firstChild; + + if (!firstChild) { + var comment = this.createComment(''); + this.appendChild(element, comment); + return _htmlbarsRuntimeMorph.default.create(this, element, comment); + } else { + var morph = _htmlbarsRuntimeMorph.default.attach(this, element, firstChild, element.lastChild); + morph.clear(); + return morph; + } + }; + + prototype.createUnsafeMorph = function (parent, start, end, contextualElement) { + var morph = this.createMorph(parent, start, end, contextualElement); + morph.parseTextAsHTML = true; + return morph; + }; + + // This helper is just to keep the templates good looking, + // passing integers instead of element references. + prototype.createMorphAt = function (parent, startIndex, endIndex, contextualElement) { + var single = startIndex === endIndex; + var start = this.childAtIndex(parent, startIndex); + var end = single ? start : this.childAtIndex(parent, endIndex); + return this.createMorph(parent, start, end, contextualElement); + }; + + prototype.createUnsafeMorphAt = function (parent, startIndex, endIndex, contextualElement) { + var morph = this.createMorphAt(parent, startIndex, endIndex, contextualElement); + morph.parseTextAsHTML = true; + return morph; + }; + + prototype.insertMorphBefore = function (element, referenceChild, contextualElement) { + var insertion = this.document.createComment(''); + element.insertBefore(insertion, referenceChild); + return this.createMorph(element, insertion, insertion, contextualElement); + }; + + prototype.appendMorph = function (element, contextualElement) { + var insertion = this.document.createComment(''); + element.appendChild(insertion); + return this.createMorph(element, insertion, insertion, contextualElement); + }; + + prototype.insertBoundary = function (fragment, index) { + // this will always be null or firstChild + var child = index === null ? null : this.childAtIndex(fragment, index); + this.insertBefore(fragment, this.createTextNode(''), child); + }; + + prototype.setMorphHTML = function (morph, html) { + morph.setHTML(html); + }; + + prototype.parseHTML = function (html, contextualElement) { + var childNodes; + + if (interiorNamespace(contextualElement) === _domHelperBuildHtmlDom.svgNamespace) { + childNodes = buildSVGDOM(html, this); + } else { + var nodes = _domHelperBuildHtmlDom.buildHTMLDOM(html, contextualElement, this); + if (detectOmittedStartTag(html, contextualElement)) { + var node = nodes[0]; + while (node && node.nodeType !== 1) { + node = node.nextSibling; + } + childNodes = node.childNodes; + } else { + childNodes = nodes; + } + } + + // Copy node list to a fragment. + var fragment = this.document.createDocumentFragment(); + + if (childNodes && childNodes.length > 0) { + var currentNode = childNodes[0]; + + // We prepend an