From b89a7ee8b956c96a1dcee995ea840feddc5d4b27 Mon Sep 17 00:00:00 2001 From: Pierre Frisch Date: Thu, 22 Dec 2011 07:25:50 -0800 Subject: First commit of Ninja to ninja-internal Signed-off-by: Valerio Virgillito --- node_modules/montage/ui/loader.reel/loader.js | 472 ++++++++++++++++++++++++++ 1 file changed, 472 insertions(+) create mode 100755 node_modules/montage/ui/loader.reel/loader.js (limited to 'node_modules/montage/ui/loader.reel') diff --git a/node_modules/montage/ui/loader.reel/loader.js b/node_modules/montage/ui/loader.reel/loader.js new file mode 100755 index 00000000..3809d334 --- /dev/null +++ b/node_modules/montage/ui/loader.reel/loader.js @@ -0,0 +1,472 @@ +/* + This file contains proprietary software owned by Motorola Mobility, Inc.
+ No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+ (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ + + /** + @module montage/ui/loader + */ + +var Montage = require("core/core").Montage, + Component = require("ui/component").Component, + logger = require("core/logger").logger("loader"), + bootstrappingTimeoutPropertyName = "_montageStartBootstrappingTimeout", + MONTAGE_BOOTSTRAPPER_ELEMENT_ID = "montage-app-bootstrapper", + MONTAGE_LOADER_ELEMENT_ID = "montage-app-loader", + BOOTSTRAPPING_CLASS_NAME = "montage-app-bootstrapping", + LOADING_CLASS_NAME = "montage-app-loading", + LOADED_CLASS_NAME = "montage-app-loaded", + PRELOADING = 0, + BOOTSTRAPPING = 1, + LOADING = 2, + LOADED = 3; + +/** + @class module:montage/ui/loader.Loader + @extends module:montage/ui/component.Component + */ + +exports.Loader = Montage.create(Component, /** @lends module:montage/ui/loader.Loader# */ { + + // Configuration Properties + +/** + The main module to require +*/ + mainModule: { + enumerable: false, + value: "main.reel" + }, + +/** + The name of the object to read from the mainModule exports +*/ + mainName: { + enumerable: false, + value: "Main" + }, + +/** + Whether or not to include framework modules in the collection of required and initialized modules +*/ + includeFrameworkModules: { + enumerable: false, + value: false + }, + +/** + The minimum amount of time the bootstrapping indicator must be shown for +*/ + minimumBootstrappingDuration: { + enumerable: false, + value: 1500 + }, + +/** + The minimum amount of time the loading indicator must be shown for +*/ + minimumLoadingDuration: { + enumerable: false, + value: 2000 + }, + + _initializedModules: { + enumerable: false, + value: null + }, + +/** + The initialized modules...FIXME +*/ + initializedModules: { + dependencies: ["includeFrameworkModules"], + enumerable: false, + get: function() { + if (!this._initializedModules || this.includeFrameworkModules) { + return this._initializedModules; + } else { + return this._initializedModules.slice(this._frameworkModuleCount - 1); + } + }, + set: function(value) { + this._initializedModules = value; + } + }, + + _requiredModules: { + enumerable: false, + value: null + }, + +/** + The required modules for this application ... FIXME +*/ + requiredModules: { + dependencies: ["includeFrameworkModules"], + enumerable: false, + get: function() { + if (!this._requiredModules || this.includeFrameworkModules) { + return this._requiredModules; + } else { + return this._requiredModules.slice(this._frameworkModuleCount - 1); + } + }, + set: function(value) { + this._requiredModules = value; + } + }, + + // States + + _currentStage: { + enumerable: false, + value: PRELOADING + }, + +/** + Current loading stage. +*/ + currentStage: { + enumerable: false, + get: function() { + return this._currentStage; + }, + set: function(value) { + if (value === this._currentStage) { + return; + } + + if (logger.isDebug) { + logger.debug(this, "CURRENT STAGE: " + value); + } + this._currentStage = value; + this.needsDraw = true; + } + }, + + _readyToShowLoader: { + enumerable: false, + value: false + }, + +/** + Boolean that specifies whether the loader is loading the application's main component. +*/ + isLoadingMainComponent: { + enumerable: false, + value: null + }, + +/** + Specifies whether the loader is ready to show the loading graphic...FIXME +*/ + readyToShowLoader: { + enumerable: false, + get: function() { + return this._readyToShowLoader; + }, + set: function(value) { + if (value !== this._readyToShowLoader) { + return; + } + + this._readyToShowLoader = value; + this.needsDraw = true; + } + }, + +/** + Specifies whether the main component is ready to be displayed. +*/ + readyToShowMainComponent: { + enumerable: false, + get: function() { + return !!this._mainComponent; + } + }, + + // Internal Properties + + _frameworkModuleCount: { + enumerable: false, + value: null + }, + + hasTemplate: { + enumerable: false, + value: false + }, + + _mainComponent: { + enumerable: false, + value: null + }, + + _showLoadingTimeout: { + enumerable: false, + value: null + }, + + _showMainComponentTimeout: { + enumerable: false, + value: null + }, + + // Implementation + + templateDidLoad: { + value: function() { + + if (logger.isDebug) { + logger.debug(this, "templateDidLoad"); + } + + this.element = document.documentElement; + this.readyToShowLoader = true; + + var timing = document._montageTiming, + remainingBootstrappingDelay, + self = this; + + if (timing.bootstrappingStartTime) { + + if (logger.isDebug) { + logger.debug(this, "had already started bootstrapping"); + } + + // We just found out we were bootstrapping… + this.currentStage = BOOTSTRAPPING; + + // but we're technically done bootstrapping and can show loader now if we should + timing.bootstrappingEndTime = Date.now(); + + remainingBootstrappingDelay = this.minimumBootstrappingDuration - (timing.bootstrappingEndTime - timing.bootstrappingStartTime) + + if (remainingBootstrappingDelay > 0) { + if (logger.isDebug) { + logger.debug(this, "still need to show bootstrapper for another " + remainingBootstrappingDelay + "ms"); + } + this._showLoadingTimeout = setTimeout(function() { + self._revealLoader(); + }, remainingBootstrappingDelay); + } else { + this._revealLoader(); + } + } else { + // The bootstrapper hasn't decided to show yet, that's fine let's try to load main + if (logger.isDebug) { + logger.debug(this, "bootstrapping has not started yet…"); + } + this._loadMainComponent(); + } + } + }, + + _revealLoader: { + value: function() { + + if (logger.isDebug) { + logger.debug(this, "_revealLoader"); + } + + this.currentStage = LOADING; + document._montageTiming.loadingStartTime = Date.now(); + + this._frameworkModuleCount = window.require.progress.requiredModules.length; + + Object.defineBinding(this, "initializedModules", { + boundObject: window.require, + boundObjectPropertyPath: "progress.initializedModules", + oneway: true + }); + + Object.defineBinding(this, "requiredModules", { + boundObject: window.require, + boundObjectPropertyPath: "progress.requiredModules", + oneway: true + }); + + var i, + loaderElement = document.getElementById(MONTAGE_LOADER_ELEMENT_ID), + children, + iChild, + iComponent; + + if (loaderElement) { + children = loaderElement.children; + + for (i = 0; (iChild = children[i]); i++) { + if ((iComponent = iChild.controller)) { + this.childComponents.push(iComponent); + iComponent._cachedParentComponent = this; + iComponent.needsDraw = true; + } + } + } + + } + }, + + _revealMainComponent: { + value: function() { + if (logger.isDebug) { + logger.debug(this, "_revealMainComponent"); + } + this.currentStage = LOADED; + } + }, + + _loadMainComponent: { + value: function() { + if (logger.isDebug) { + logger.debug(this, "_loadMainComponent"); + } + this.isLoadingMainComponent = true; + var self = this; + window.require.async(this.mainModule) + .then(function (exports) { + return self._mainLoadedCallback(exports); + }) + .end(); + } + }, + + _mainLoadedCallback: { + value: function(exports) { + if (logger.isDebug) { + logger.debug(this, "_mainLoadedCallback"); + } + // We've loaded the class for the mainComponent + // instantiate it and lets find out what else we need to load + // based on its template + this._mainComponent = exports[this.mainName].create(); + this.childComponents.push(this._mainComponent); + this._mainComponent._cachedParentComponent = this; + this._mainComponent.element = document.createElement("div"); + this._mainComponent.needsDraw = true; + } + }, + + childComponentWillPrepareForDraw: { + value: function(child) { + var self = this; + + // if the mainComponent is ready to draw... + if (child === this._mainComponent) { + + if (logger.isDebug) { + logger.debug(this, "main preparing to draw"); + } + this.isLoadingMainComponent = false; + + // Determine old content + this._contentToRemove = document.createRange(); + this._contentToRemove.selectNodeContents(document.body); + + // Add new content so mainComponent can actually draw + this.childComponents = [this._mainComponent]; + document.body.appendChild(this._mainComponent.element); + + var startBootstrappingTimeout = document[bootstrappingTimeoutPropertyName], + timing = document._montageTiming, + remainingBootstrappingDelay, + remainingLoadingDelay; + + // if we hadn't even started to say we were bootstrapping… + if (!timing.bootstrappingStartTime) { + // don't bother showing bootstrapping, just show the mainComponent + if (logger.isDebug) { + logger.debug(this, "bootstrapper never shown"); + } + clearTimeout(startBootstrappingTimeout); + startBootstrappingTimeout = null; + this._revealMainComponent(); + } + + // Otherwise if we started bootstrapping, but never started loading… + else if (timing.bootstrappingStartTime && !timing.loadingStartTime) { + + // don't ever show the loader and wait until we've bootstrapped for the minimumBootstrappingDuration + clearTimeout(this._showLoadingTimeout); + this._showLoadingTimeout = null; + + timing.bootstrappingEndTime = Date.now(); + + if ((remainingBootstrappingDelay = this.minimumBootstrappingDuration - (timing.bootstrappingEndTime - timing.bootstrappingStartTime)) > 0) { + if (logger.isDebug) { + logger.debug(this, "show bootstrapper for another " + remainingBootstrappingDelay + "ms"); + } + this._showMainComponentTimeout = setTimeout(function () { + if (logger.isDebug) { + logger.debug(this, "ok, shown bootstrapper long enough"); + } + self._revealMainComponent(); + }, remainingBootstrappingDelay); + } + } + + //Otherwise, we apparently started showing loading progress… + else if (timing.loadingStartTime) { + timing.loadingEndTime = Date.now(); + + // wait until we've loaded for the minimumLoadingDuration + // TODO this is not precise, but it's a decent start for scheduling the delay + if ((remainingLoadingDelay = this.minimumLoadingDuration - (timing.loadingEndTime - timing.loadingStartTime)) > 0) { + if (logger.isDebug) { + logger.debug(this, "show loader for another " + remainingLoadingDelay + "ms"); + } + this._showMainComponentTimeout = setTimeout(function () { + if (logger.isDebug) { + logger.debug(this, "ok, shown loader long enough"); + } + self._revealMainComponent();; + }, remainingLoadingDelay); + } else { + // or we showed loading long enough, go ahead and show mainComponent + this._revealMainComponent(); + } + } + + + } + } + }, + + _contentToRemove: { + enumerable: false, + value: null + }, + + draw: { + value: function() { + // start loading the mainComponent if we haven't already + if (!this.readyToShowMainComponent && !this.isLoadingMainComponent) { + if (logger.isDebug) { + logger.debug(this, "draw; start loading main component"); + } + this._loadMainComponent(); + } + + // Reflect the current loading stage + if (LOADING === this.currentStage) { + + this.element.classList.remove(BOOTSTRAPPING_CLASS_NAME); + this.element.classList.add(LOADING_CLASS_NAME); + + } else if (LOADED === this.currentStage && this._contentToRemove) { + + this.element.classList.remove(BOOTSTRAPPING_CLASS_NAME); + this.element.classList.remove(LOADING_CLASS_NAME); + + this._contentToRemove.extractContents(); + this._contentToRemove.detach(); + this._contentToRemove = null; + + this.element.classList.add(LOADED_CLASS_NAME); + } + + } + } + +}); -- cgit v1.2.3