Created
September 20, 2012 10:04
-
-
Save pingyen/3755036 to your computer and use it in GitHub Desktop.
WinJS base.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <loc filename="Metadata\base_loc_oam.xml" format="messagebundle" /> | |
/*! | |
© Microsoft. All rights reserved. | |
This library is supported for use in Windows Store apps only. | |
Build: 1.0.9200.20498.win8_ldr.120817-1716 | |
Version: Microsoft.WinJS.1.0 | |
*/ | |
/// <reference path="ms-appx://Microsoft.WinJS.1.0/js/base.js" /> | |
(function baseInit(global, undefined) { | |
"use strict"; | |
function initializeProperties(target, members) { | |
var keys = Object.keys(members); | |
var properties; | |
var i, len; | |
for (i = 0, len = keys.length; i < len; i++) { | |
var key = keys[i]; | |
var enumerable = key.charCodeAt(0) !== /*_*/95; | |
var member = members[key]; | |
if (member && typeof member === 'object') { | |
if (member.value !== undefined || typeof member.get === 'function' || typeof member.set === 'function') { | |
if (member.enumerable === undefined) { | |
member.enumerable = enumerable; | |
} | |
properties = properties || {}; | |
properties[key] = member; | |
continue; | |
} | |
} | |
if (!enumerable) { | |
properties = properties || {}; | |
properties[key] = { value: member, enumerable: enumerable, configurable: true, writable: true } | |
continue; | |
} | |
target[key] = member; | |
} | |
if (properties) { | |
Object.defineProperties(target, properties); | |
} | |
} | |
(function (rootNamespace) { | |
// Create the rootNamespace in the global namespace | |
if (!global[rootNamespace]) { | |
global[rootNamespace] = Object.create(Object.prototype); | |
} | |
// Cache the rootNamespace we just created in a local variable | |
var _rootNamespace = global[rootNamespace]; | |
if (!_rootNamespace.Namespace) { | |
_rootNamespace.Namespace = Object.create(Object.prototype); | |
} | |
function defineWithParent(parentNamespace, name, members) { | |
/// <signature helpKeyword="WinJS.Namespace.defineWithParent"> | |
/// <summary locid="WinJS.Namespace.defineWithParent"> | |
/// Defines a new namespace with the specified name under the specified parent namespace. | |
/// </summary> | |
/// <param name="parentNamespace" type="Object" locid="WinJS.Namespace.defineWithParent_p:parentNamespace"> | |
/// The parent namespace. | |
/// </param> | |
/// <param name="name" type="String" locid="WinJS.Namespace.defineWithParent_p:name"> | |
/// The name of the new namespace. | |
/// </param> | |
/// <param name="members" type="Object" locid="WinJS.Namespace.defineWithParent_p:members"> | |
/// The members of the new namespace. | |
/// </param> | |
/// <returns type="Object" locid="WinJS.Namespace.defineWithParent_returnValue"> | |
/// The newly-defined namespace. | |
/// </returns> | |
/// </signature> | |
var currentNamespace = parentNamespace, | |
namespaceFragments = name.split("."); | |
for (var i = 0, len = namespaceFragments.length; i < len; i++) { | |
var namespaceName = namespaceFragments[i]; | |
if (!currentNamespace[namespaceName]) { | |
Object.defineProperty(currentNamespace, namespaceName, | |
{ value: {}, writable: false, enumerable: true, configurable: true } | |
); | |
} | |
currentNamespace = currentNamespace[namespaceName]; | |
} | |
if (members) { | |
initializeProperties(currentNamespace, members); | |
} | |
return currentNamespace; | |
} | |
function define(name, members) { | |
/// <signature helpKeyword="WinJS.Namespace.define"> | |
/// <summary locid="WinJS.Namespace.define"> | |
/// Defines a new namespace with the specified name. | |
/// </summary> | |
/// <param name="name" type="String" locid="WinJS.Namespace.define_p:name"> | |
/// The name of the namespace. This could be a dot-separated name for nested namespaces. | |
/// </param> | |
/// <param name="members" type="Object" locid="WinJS.Namespace.define_p:members"> | |
/// The members of the new namespace. | |
/// </param> | |
/// <returns type="Object" locid="WinJS.Namespace.define_returnValue"> | |
/// The newly-defined namespace. | |
/// </returns> | |
/// </signature> | |
return defineWithParent(global, name, members); | |
} | |
// Establish members of the "WinJS.Namespace" namespace | |
Object.defineProperties(_rootNamespace.Namespace, { | |
defineWithParent: { value: defineWithParent, writable: true, enumerable: true, configurable: true }, | |
define: { value: define, writable: true, enumerable: true, configurable: true } | |
}); | |
})("WinJS"); | |
(function (WinJS) { | |
function define(constructor, instanceMembers, staticMembers) { | |
/// <signature helpKeyword="WinJS.Class.define"> | |
/// <summary locid="WinJS.Class.define"> | |
/// Defines a class using the given constructor and the specified instance members. | |
/// </summary> | |
/// <param name="constructor" type="Function" locid="WinJS.Class.define_p:constructor"> | |
/// A constructor function that is used to instantiate this class. | |
/// </param> | |
/// <param name="instanceMembers" type="Object" locid="WinJS.Class.define_p:instanceMembers"> | |
/// The set of instance fields, properties, and methods made available on the class. | |
/// </param> | |
/// <param name="staticMembers" type="Object" locid="WinJS.Class.define_p:staticMembers"> | |
/// The set of static fields, properties, and methods made available on the class. | |
/// </param> | |
/// <returns type="Function" locid="WinJS.Class.define_returnValue"> | |
/// The newly-defined class. | |
/// </returns> | |
/// </signature> | |
constructor = constructor || function () { }; | |
WinJS.Utilities.markSupportedForProcessing(constructor); | |
if (instanceMembers) { | |
initializeProperties(constructor.prototype, instanceMembers); | |
} | |
if (staticMembers) { | |
initializeProperties(constructor, staticMembers); | |
} | |
return constructor; | |
} | |
function derive(baseClass, constructor, instanceMembers, staticMembers) { | |
/// <signature helpKeyword="WinJS.Class.derive"> | |
/// <summary locid="WinJS.Class.derive"> | |
/// Creates a sub-class based on the supplied baseClass parameter, using prototypal inheritance. | |
/// </summary> | |
/// <param name="baseClass" type="Function" locid="WinJS.Class.derive_p:baseClass"> | |
/// The class to inherit from. | |
/// </param> | |
/// <param name="constructor" type="Function" locid="WinJS.Class.derive_p:constructor"> | |
/// A constructor function that is used to instantiate this class. | |
/// </param> | |
/// <param name="instanceMembers" type="Object" locid="WinJS.Class.derive_p:instanceMembers"> | |
/// The set of instance fields, properties, and methods to be made available on the class. | |
/// </param> | |
/// <param name="staticMembers" type="Object" locid="WinJS.Class.derive_p:staticMembers"> | |
/// The set of static fields, properties, and methods to be made available on the class. | |
/// </param> | |
/// <returns type="Function" locid="WinJS.Class.derive_returnValue"> | |
/// The newly-defined class. | |
/// </returns> | |
/// </signature> | |
if (baseClass) { | |
constructor = constructor || function () { }; | |
var basePrototype = baseClass.prototype; | |
constructor.prototype = Object.create(basePrototype); | |
WinJS.Utilities.markSupportedForProcessing(constructor); | |
Object.defineProperty(constructor.prototype, "constructor", { value: constructor, writable: true, configurable: true, enumerable: true }); | |
if (instanceMembers) { | |
initializeProperties(constructor.prototype, instanceMembers); | |
} | |
if (staticMembers) { | |
initializeProperties(constructor, staticMembers); | |
} | |
return constructor; | |
} else { | |
return define(constructor, instanceMembers, staticMembers); | |
} | |
} | |
function mix(constructor) { | |
/// <signature helpKeyword="WinJS.Class.mix"> | |
/// <summary locid="WinJS.Class.mix"> | |
/// Defines a class using the given constructor and the union of the set of instance members | |
/// specified by all the mixin objects. The mixin parameter list is of variable length. | |
/// </summary> | |
/// <param name="constructor" locid="WinJS.Class.mix_p:constructor"> | |
/// A constructor function that is used to instantiate this class. | |
/// </param> | |
/// <returns type="Function" locid="WinJS.Class.mix_returnValue"> | |
/// The newly-defined class. | |
/// </returns> | |
/// </signature> | |
constructor = constructor || function () { }; | |
var i, len; | |
for (i = 1, len = arguments.length; i < len; i++) { | |
initializeProperties(constructor.prototype, arguments[i]); | |
} | |
return constructor; | |
} | |
// Establish members of "WinJS.Class" namespace | |
WinJS.Namespace.define("WinJS.Class", { | |
define: define, | |
derive: derive, | |
mix: mix | |
}); | |
})(WinJS); | |
})(this); | |
(function baseUtilsInit(global, WinJS) { | |
"use strict"; | |
var hasWinRT = !!global.Windows; | |
var strings = { | |
get notSupportedForProcessing() { return WinJS.Resources._getWinJSString("base/notSupportedForProcessing").value; } | |
}; | |
function nop(v) { | |
return v; | |
} | |
function getMemberFiltered(name, root, filter) { | |
return name.split(".").reduce(function (currentNamespace, name) { | |
if (currentNamespace) { | |
return filter(currentNamespace[name]); | |
} | |
return null; | |
}, root); | |
} | |
// Establish members of "WinJS.Utilities" namespace | |
WinJS.Namespace.define("WinJS.Utilities", { | |
// Used for mocking in tests | |
_setHasWinRT: { | |
value: function (value) { | |
hasWinRT = value; | |
}, | |
configurable: false, | |
writable: false, | |
enumerable: false | |
}, | |
/// <field type="Boolean" locid="WinJS.Utilities.hasWinRT" helpKeyword="WinJS.Utilities.hasWinRT">Determine if WinRT is accessible in this script context.</field> | |
hasWinRT: { | |
get: function () { return hasWinRT; }, | |
configurable: false, | |
enumerable: true | |
}, | |
_getMemberFiltered: getMemberFiltered, | |
getMember: function (name, root) { | |
/// <signature helpKeyword="WinJS.Utilities.getMember"> | |
/// <summary locid="WinJS.Utilities.getMember"> | |
/// Gets the leaf-level type or namespace specified by the name parameter. | |
/// </summary> | |
/// <param name="name" locid="WinJS.Utilities.getMember_p:name"> | |
/// The name of the member. | |
/// </param> | |
/// <param name="root" locid="WinJS.Utilities.getMember_p:root"> | |
/// The root to start in. Defaults to the global object. | |
/// </param> | |
/// <returns type="Object" locid="WinJS.Utilities.getMember_returnValue"> | |
/// The leaf-level type or namespace in the specified parent namespace. | |
/// </returns> | |
/// </signature> | |
if (!name) { | |
return null; | |
} | |
return getMemberFiltered(name, root || global, nop); | |
}, | |
ready: function (callback, async) { | |
/// <signature helpKeyword="WinJS.Utilities.ready"> | |
/// <summary locid="WinJS.Utilities.ready"> | |
/// Ensures that the specified function executes only after the DOMContentLoaded event has fired | |
/// for the current page. | |
/// </summary> | |
/// <returns type="WinJS.Promise" locid="WinJS.Utilities.ready_returnValue">A promise that completes after DOMContentLoaded has occurred.</returns> | |
/// <param name="callback" optional="true" locid="WinJS.Utilities.ready_p:callback"> | |
/// A function that executes after DOMContentLoaded has occurred. | |
/// </param> | |
/// <param name="async" optional="true" locid="WinJS.Utilities.ready_p:async"> | |
/// If true, the callback should be executed asynchronously. | |
/// </param> | |
/// </signature> | |
return new WinJS.Promise(function (c, e) { | |
function complete() { | |
if (callback) { | |
try { | |
callback(); | |
c(); | |
} | |
catch (err) { | |
e(err); | |
} | |
} | |
else { | |
c(); | |
} | |
} | |
var readyState = WinJS.Utilities.testReadyState; | |
if (!readyState) { | |
if (global.document) { | |
readyState = document.readyState; | |
} | |
else { | |
readyState = "complete"; | |
} | |
} | |
if (readyState === "complete" || (global.document && document.body !== null)) { | |
if (async) { | |
msSetImmediate(complete); | |
} | |
else { | |
complete(); | |
} | |
} | |
else { | |
global.addEventListener("DOMContentLoaded", complete, false); | |
} | |
}); | |
}, | |
/// <field type="Boolean" locid="WinJS.Utilities.strictProcessing" helpKeyword="WinJS.Utilities.strictProcessing">Determines if strict declarative processing is enabled in this script context.</field> | |
strictProcessing: { | |
get: function () { return true; }, | |
configurable: false, | |
enumerable: true, | |
}, | |
markSupportedForProcessing: { | |
value: function (func) { | |
/// <signature helpKeyword="WinJS.Utilities.markSupportedForProcessing"> | |
/// <summary locid="WinJS.Utilities.markSupportedForProcessing"> | |
/// Marks a function as being compatible with declarative processing, such as WinJS.UI.processAll | |
/// or WinJS.Binding.processAll. | |
/// </summary> | |
/// <param name="func" type="Function" locid="WinJS.Utilities.markSupportedForProcessing_p:func"> | |
/// The function to be marked as compatible with declarative processing. | |
/// </param> | |
/// <returns type="Function" locid="WinJS.Utilities.markSupportedForProcessing_returnValue"> | |
/// The input function. | |
/// </returns> | |
/// </signature> | |
func.supportedForProcessing = true; | |
return func; | |
}, | |
configurable: false, | |
writable: false, | |
enumerable: true | |
}, | |
requireSupportedForProcessing: { | |
value: function (value) { | |
/// <signature helpKeyword="WinJS.Utilities.requireSupportedForProcessing"> | |
/// <summary locid="WinJS.Utilities.requireSupportedForProcessing"> | |
/// Asserts that the value is compatible with declarative processing, such as WinJS.UI.processAll | |
/// or WinJS.Binding.processAll. If it is not compatible an exception will be thrown. | |
/// </summary> | |
/// <param name="value" type="Object" locid="WinJS.Utilities.requireSupportedForProcessing_p:value"> | |
/// The value to be tested for compatibility with declarative processing. If the | |
/// value is a function it must be marked with a property 'supportedForProcessing' | |
/// with a value of true. | |
/// </param> | |
/// <returns type="Object" locid="WinJS.Utilities.requireSupportedForProcessing_returnValue"> | |
/// The input value. | |
/// </returns> | |
/// </signature> | |
var supportedForProcessing = true; | |
supportedForProcessing = supportedForProcessing && !(value === global); | |
supportedForProcessing = supportedForProcessing && !(value === global.location); | |
supportedForProcessing = supportedForProcessing && !(value instanceof HTMLIFrameElement); | |
supportedForProcessing = supportedForProcessing && !(typeof value === "function" && !value.supportedForProcessing); | |
switch (global.frames.length) { | |
case 0: | |
break; | |
case 1: | |
supportedForProcessing = supportedForProcessing && !(value === global.frames[0]); | |
break; | |
default: | |
for (var i = 0, len = global.frames.length; supportedForProcessing && i < len; i++) { | |
supportedForProcessing = supportedForProcessing && !(value === global.frames[i]); | |
} | |
break; | |
} | |
if (supportedForProcessing) { | |
return value; | |
} | |
throw new WinJS.ErrorFromName("WinJS.Utilities.requireSupportedForProcessing", WinJS.Resources._formatString(strings.notSupportedForProcessing, value)); | |
}, | |
configurable: false, | |
writable: false, | |
enumerable: true | |
}, | |
}); | |
WinJS.Namespace.define("WinJS", { | |
validation: false, | |
strictProcessing: { | |
value: function () { | |
/// <signature helpKeyword="WinJS.strictProcessing"> | |
/// <summary locid="WinJS.strictProcessing"> | |
/// Strict processing is always enforced, this method has no effect. | |
/// </summary> | |
/// </signature> | |
}, | |
configurable: false, | |
writable: false, | |
enumerable: false | |
}, | |
}); | |
})(this, WinJS); | |
(function logInit() { | |
"use strict"; | |
var spaceR = /\s+/g; | |
var typeR = /^(error|warn|info|log)$/; | |
function format(message, tag, type) { | |
/// <signature helpKeyword="WinJS.Utilities.formatLog"> | |
/// <summary locid="WinJS.Utilities.formatLog"> | |
/// Adds tags and type to a logging message. | |
/// </summary> | |
/// <param name="message" type="String" locid="WinJS.Utilities.startLog_p:message">The message to be formatted.</param> | |
/// <param name="tag" type="String" locid="WinJS.Utilities.startLog_p:tag">The tag(s) to be applied to the message. Multiple tags should be separated by spaces.</param> | |
/// <param name="type" type="String" locid="WinJS.Utilities.startLog_p:type">The type of the message.</param> | |
/// <returns type="String" locid="WinJS.Utilities.startLog_returnValue">The formatted message.</returns> | |
/// </signature> | |
var m = message; | |
if (typeof (m) === "function") { m = m(); } | |
return ((type && typeR.test(type)) ? ("") : (type ? (type + ": ") : "")) + | |
(tag ? tag.replace(spaceR, ":") + ": " : "") + | |
m; | |
} | |
function defAction(message, tag, type) { | |
var m = WinJS.Utilities.formatLog(message, tag, type); | |
console[(type && typeR.test(type)) ? type : "log"](m); | |
} | |
function escape(s) { | |
// \s (whitespace) is used as separator, so don't escape it | |
return s.replace(/[-[\]{}()*+?.,\\^$|#]/g, "\\$&"); | |
} | |
WinJS.Namespace.define("WinJS.Utilities", { | |
startLog: function (options) { | |
/// <signature helpKeyword="WinJS.Utilities.startLog"> | |
/// <summary locid="WinJS.Utilities.startLog"> | |
/// Configures a logger that writes messages containing the specified tags from WinJS.log to console.log. | |
/// </summary> | |
/// <param name="options" type="String" locid="WinJS.Utilities.startLog_p:options">The tags for messages to log. Multiple tags should be separated by spaces.</param> | |
/// </signature> | |
/// <signature> | |
/// <summary locid="WinJS.Utilities.startLog2"> | |
/// Configure a logger to write WinJS.log output. | |
/// </summary> | |
/// <param name="options" type="Object" locid="WinJS.Utilities.startLog_p:options2"> | |
/// May contain .type, .tags, .excludeTags and .action properties. | |
/// - .type is a required tag. | |
/// - .excludeTags is a space-separated list of tags, any of which will result in a message not being logged. | |
/// - .tags is a space-separated list of tags, any of which will result in a message being logged. | |
/// - .action is a function that, if present, will be called with the log message, tags and type. The default is to log to the console. | |
/// </param> | |
/// </signature> | |
options = options || {}; | |
if (typeof options === "string") { | |
options = { tags: options }; | |
} | |
var el = options.type && new RegExp("^(" + escape(options.type).replace(spaceR, " ").split(" ").join("|") + ")$"); | |
var not = options.excludeTags && new RegExp("(^|\\s)(" + escape(options.excludeTags).replace(spaceR, " ").split(" ").join("|") + ")(\\s|$)", "i"); | |
var has = options.tags && new RegExp("(^|\\s)(" + escape(options.tags).replace(spaceR, " ").split(" ").join("|") + ")(\\s|$)", "i"); | |
var action = options.action || defAction; | |
if (!el && !not && !has && !WinJS.log) { | |
WinJS.log = action; | |
return; | |
} | |
var result = function (message, tag, type) { | |
if (!((el && !el.test(type)) // if the expected log level is not satisfied | |
|| (not && not.test(tag)) // if any of the excluded categories exist | |
|| (has && !has.test(tag)))) { // if at least one of the included categories doesn't exist | |
action(message, tag, type); | |
} | |
result.next && result.next(message, tag, type); | |
}; | |
result.next = WinJS.log; | |
WinJS.log = result; | |
}, | |
stopLog: function () { | |
/// <signature helpKeyword="WinJS.Utilities.stopLog"> | |
/// <summary locid="WinJS.Utilities.stopLog"> | |
/// Removes the previously set up logger. | |
/// </summary> | |
/// </signature> | |
delete WinJS.log; | |
}, | |
formatLog: format | |
}); | |
})(); | |
(function eventsInit(WinJS, undefined) { | |
"use strict"; | |
function createEventProperty(name) { | |
var eventPropStateName = "_on" + name + "state"; | |
return { | |
get: function () { | |
var state = this[eventPropStateName]; | |
return state && state.userHandler; | |
}, | |
set: function (handler) { | |
var state = this[eventPropStateName]; | |
if (handler) { | |
if (!state) { | |
state = { wrapper: function (evt) { return state.userHandler(evt); }, userHandler: handler }; | |
Object.defineProperty(this, eventPropStateName, { value: state, enumerable: false, writable:true, configurable: true }); | |
this.addEventListener(name, state.wrapper, false); | |
} | |
state.userHandler = handler; | |
} else if (state) { | |
this.removeEventListener(name, state.wrapper, false); | |
this[eventPropStateName] = null; | |
} | |
}, | |
enumerable: true | |
} | |
} | |
function createEventProperties(events) { | |
/// <signature helpKeyword="WinJS.Utilities.createEventProperties"> | |
/// <summary locid="WinJS.Utilities.createEventProperties"> | |
/// Creates an object that has one property for each name passed to the function. | |
/// </summary> | |
/// <param name="events" locid="WinJS.Utilities.createEventProperties_p:events"> | |
/// A variable list of property names. | |
/// </param> | |
/// <returns type="Object" locid="WinJS.Utilities.createEventProperties_returnValue"> | |
/// The object with the specified properties. The names of the properties are prefixed with 'on'. | |
/// </returns> | |
/// </signature> | |
var props = {}; | |
for (var i = 0, len = arguments.length; i < len; i++) { | |
var name = arguments[i]; | |
props["on" + name] = createEventProperty(name); | |
} | |
return props; | |
} | |
var EventMixinEvent = WinJS.Class.define( | |
function EventMixinEvent_ctor(type, detail, target) { | |
this.detail = detail; | |
this.target = target; | |
this.timeStamp = Date.now(); | |
this.type = type; | |
}, | |
{ | |
bubbles: { value: false, writable: false }, | |
cancelable: { value: false, writable: false }, | |
currentTarget: { | |
get: function () { return this.target; } | |
}, | |
defaultPrevented: { | |
get: function () { return this._preventDefaultCalled; } | |
}, | |
trusted: { value: false, writable: false }, | |
eventPhase: { value: 0, writable: false }, | |
target: null, | |
timeStamp: null, | |
type: null, | |
preventDefault: function () { | |
this._preventDefaultCalled = true; | |
}, | |
stopImmediatePropagation: function () { | |
this._stopImmediatePropagationCalled = true; | |
}, | |
stopPropagation: function () { | |
} | |
}, { | |
supportedForProcessing: false, | |
} | |
); | |
var eventMixin = { | |
_listeners: null, | |
addEventListener: function (type, listener, useCapture) { | |
/// <signature helpKeyword="WinJS.Utilities.eventMixin.addEventListener"> | |
/// <summary locid="WinJS.Utilities.eventMixin.addEventListener"> | |
/// Adds an event listener to the control. | |
/// </summary> | |
/// <param name="type" locid="WinJS.Utilities.eventMixin.addEventListener_p:type"> | |
/// The type (name) of the event. | |
/// </param> | |
/// <param name="listener" locid="WinJS.Utilities.eventMixin.addEventListener_p:listener"> | |
/// The listener to invoke when the event gets raised. | |
/// </param> | |
/// <param name="useCapture" locid="WinJS.Utilities.eventMixin.addEventListener_p:useCapture"> | |
/// if true initiates capture, otherwise false. | |
/// </param> | |
/// </signature> | |
useCapture = useCapture || false; | |
this._listeners = this._listeners || {}; | |
var eventListeners = (this._listeners[type] = this._listeners[type] || []); | |
for (var i = 0, len = eventListeners.length; i < len; i++) { | |
var l = eventListeners[i]; | |
if (l.useCapture === useCapture && l.listener === listener) { | |
return; | |
} | |
} | |
eventListeners.push({ listener: listener, useCapture: useCapture }); | |
}, | |
dispatchEvent: function (type, details) { | |
/// <signature helpKeyword="WinJS.Utilities.eventMixin.dispatchEvent"> | |
/// <summary locid="WinJS.Utilities.eventMixin.dispatchEvent"> | |
/// Raises an event of the specified type and with the specified additional properties. | |
/// </summary> | |
/// <param name="type" locid="WinJS.Utilities.eventMixin.dispatchEvent_p:type"> | |
/// The type (name) of the event. | |
/// </param> | |
/// <param name="details" locid="WinJS.Utilities.eventMixin.dispatchEvent_p:details"> | |
/// The set of additional properties to be attached to the event object when the event is raised. | |
/// </param> | |
/// <returns type="Boolean" locid="WinJS.Utilities.eventMixin.dispatchEvent_returnValue"> | |
/// true if preventDefault was called on the event. | |
/// </returns> | |
/// </signature> | |
var listeners = this._listeners && this._listeners[type]; | |
if (listeners) { | |
var eventValue = new EventMixinEvent(type, details, this); | |
// Need to copy the array to protect against people unregistering while we are dispatching | |
listeners = listeners.slice(0, listeners.length); | |
for (var i = 0, len = listeners.length; i < len && !eventValue._stopImmediatePropagationCalled; i++) { | |
listeners[i].listener(eventValue); | |
} | |
return eventValue.defaultPrevented || false; | |
} | |
return false; | |
}, | |
removeEventListener: function (type, listener, useCapture) { | |
/// <signature helpKeyword="WinJS.Utilities.eventMixin.removeEventListener"> | |
/// <summary locid="WinJS.Utilities.eventMixin.removeEventListener"> | |
/// Removes an event listener from the control. | |
/// </summary> | |
/// <param name="type" locid="WinJS.Utilities.eventMixin.removeEventListener_p:type"> | |
/// The type (name) of the event. | |
/// </param> | |
/// <param name="listener" locid="WinJS.Utilities.eventMixin.removeEventListener_p:listener"> | |
/// The listener to remove. | |
/// </param> | |
/// <param name="useCapture" locid="WinJS.Utilities.eventMixin.removeEventListener_p:useCapture"> | |
/// Specifies whether to initiate capture. | |
/// </param> | |
/// </signature> | |
useCapture = useCapture || false; | |
var listeners = this._listeners && this._listeners[type]; | |
if (listeners) { | |
for (var i = 0, len = listeners.length; i < len; i++) { | |
var l = listeners[i]; | |
if (l.listener === listener && l.useCapture === useCapture) { | |
listeners.splice(i, 1); | |
if (listeners.length === 0) { | |
delete this._listeners[type]; | |
} | |
// Only want to remove one element for each call to removeEventListener | |
break; | |
} | |
} | |
} | |
} | |
}; | |
WinJS.Namespace.define("WinJS.Utilities", { | |
_createEventProperty: createEventProperty, | |
createEventProperties: createEventProperties, | |
eventMixin: eventMixin | |
}); | |
})(WinJS); | |
(function resourcesInit(global, WinJS, undefined) { | |
"use strict"; | |
var resourceMap; | |
var mrtEventHook = false; | |
var contextChangedET = "contextchanged"; | |
var ListenerType = WinJS.Class.mix(WinJS.Class.define(null, { /* empty */ }, { supportedForProcessing: false }), WinJS.Utilities.eventMixin); | |
var listeners = new ListenerType(); | |
var strings = { | |
get malformedFormatStringInput() { return WinJS.Resources._getWinJSString("base/malformedFormatStringInput").value; }, | |
}; | |
WinJS.Namespace.define("WinJS.Resources", { | |
addEventListener: function (type, listener, useCapture) { | |
/// <signature helpKeyword="WinJS.Resources.addEventListener"> | |
/// <summary locid="WinJS.Resources.addEventListener"> | |
/// Registers an event handler for the specified event. | |
/// </summary> | |
/// <param name="type" type="String" locid="WinJS.Resources.addEventListener_p:type"> | |
/// The name of the event to handle. | |
/// </param> | |
/// <param name="listener" type="Function" locid="WinJS.Resources.addEventListener_p:listener"> | |
/// The listener to invoke when the event gets raised. | |
/// </param> | |
/// <param name="useCapture" type="Boolean" locid="WinJS.Resources.addEventListener_p:useCapture"> | |
/// Set to true to register the event handler for the capturing phase; set to false to register for the bubbling phase. | |
/// </param> | |
/// </signature> | |
if (WinJS.Utilities.hasWinRT && !mrtEventHook) { | |
if (type === contextChangedET) { | |
try { | |
Windows.ApplicationModel.Resources.Core.ResourceManager.current.defaultContext.qualifierValues.addEventListener("mapchanged", function (e) { | |
WinJS.Resources.dispatchEvent(contextChangedET, { qualifier: e.key, changed: e.target[e.key] }); | |
}, false); | |
mrtEventHook = true; | |
} catch (e) { | |
} | |
} | |
} | |
listeners.addEventListener(type, listener, useCapture); | |
}, | |
removeEventListener: listeners.removeEventListener.bind(listeners), | |
dispatchEvent: listeners.dispatchEvent.bind(listeners), | |
_formatString: function (string) { | |
var args = arguments; | |
if (args.length > 1) { | |
string = string.replace(/({{)|(}})|{(\d+)}|({)|(})/g, function (unused, left, right, index, illegalLeft, illegalRight) { | |
if (illegalLeft || illegalRight) { throw WinJS.Resources._formatString(strings.malformedFormatStringInput, illegalLeft || illegalRight); } | |
return (left && "{") || (right && "}") || args[(index|0) + 1]; | |
}); | |
} | |
return string; | |
}, | |
_getStringWinRT: function (resourceId) { | |
if (!resourceMap) { | |
var mainResourceMap = Windows.ApplicationModel.Resources.Core.ResourceManager.current.mainResourceMap; | |
try { | |
resourceMap = mainResourceMap.getSubtree('Resources'); | |
} | |
catch (e) { | |
} | |
if (!resourceMap) { | |
resourceMap = mainResourceMap; | |
} | |
} | |
var stringValue; | |
var langValue; | |
var resCandidate; | |
try { | |
resCandidate = resourceMap.getValue(resourceId); | |
if (resCandidate) { | |
stringValue = resCandidate.valueAsString; | |
if (stringValue === undefined) { | |
stringValue = resCandidate.toString(); | |
} | |
} | |
} | |
catch (e) {} | |
if (!stringValue) { | |
return { value: resourceId, empty: true }; | |
} | |
try { | |
langValue = resCandidate.getQualifierValue("Language"); | |
} | |
catch (e) { | |
return { value: stringValue }; | |
} | |
return { value: stringValue, lang: langValue }; | |
}, | |
_getStringJS: function (resourceId) { | |
var str = global.strings && global.strings[resourceId]; | |
if (typeof str === "string") { | |
str = { value: str }; | |
} | |
return str || { value: resourceId, empty: true }; | |
} | |
}); | |
Object.defineProperties(WinJS.Resources, WinJS.Utilities.createEventProperties(contextChangedET)); | |
var getStringImpl; | |
WinJS.Resources.getString = function (resourceId) { | |
/// <signature helpKeyword="WinJS.Resources.getString"> | |
/// <summary locid="WinJS.Resources.getString"> | |
/// Retrieves the resource string that has the specified resource id. | |
/// </summary> | |
/// <param name="resourceId" type="Number" locid="WinJS.Resources.getString._p:resourceId"> | |
/// The resource id of the string to retrieve. | |
/// </param> | |
/// <returns type="Object" locid="WinJS.Resources.getString_returnValue"> | |
/// An object that can contain these properties: | |
/// | |
/// value: | |
/// The value of the requested string. This property is always present. | |
/// | |
/// empty: | |
/// A value that specifies whether the requested string wasn't found. | |
/// If its true, the string wasn't found. If its false or undefined, | |
/// the requested string was found. | |
/// | |
/// lang: | |
/// The language of the string, if specified. This property is only present | |
/// for multi-language resources. | |
/// | |
/// </returns> | |
/// </signature> | |
getStringImpl = | |
getStringImpl || | |
(WinJS.Utilities.hasWinRT | |
? WinJS.Resources._getStringWinRT | |
: WinJS.Resources._getStringJS); | |
return getStringImpl(resourceId); | |
}; | |
})(this, WinJS); | |
(function promiseInit(global, undefined) { | |
"use strict"; | |
global.Debug && (global.Debug.setNonUserCodeExceptions = true); | |
var ListenerType = WinJS.Class.mix(WinJS.Class.define(null, { /*empty*/ }, { supportedForProcessing: false }), WinJS.Utilities.eventMixin); | |
var promiseEventListeners = new ListenerType(); | |
// make sure there is a listeners collection so that we can do a more trivial check below | |
promiseEventListeners._listeners = {}; | |
var errorET = "error"; | |
var canceledName = "Canceled"; | |
var tagWithStack = false; | |
var tag = { | |
promise: 0x01, | |
thenPromise: 0x02, | |
errorPromise: 0x04, | |
exceptionPromise: 0x08, | |
completePromise: 0x10, | |
}; | |
tag.all = tag.promise | tag.thenPromise | tag.errorPromise | tag.exceptionPromise | tag.completePromise; | |
// | |
// Global error counter, for each error which enters the system we increment this once and then | |
// the error number travels with the error as it traverses the tree of potential handlers. | |
// | |
// When someone has registered to be told about errors (WinJS.Promise.callonerror) promises | |
// which are in error will get tagged with a ._errorId field. This tagged field is the | |
// contract by which nested promises with errors will be identified as chaining for the | |
// purposes of the callonerror semantics. If a nested promise in error is encountered without | |
// a ._errorId it will be assumed to be foreign and treated as an interop boundary and | |
// a new error id will be minted. | |
// | |
var error_number = 1; | |
// | |
// The state machine has a interesting hiccup in it with regards to notification, in order | |
// to flatten out notification and avoid recursion for synchronous completion we have an | |
// explicit set of *_notify states which are responsible for notifying their entire tree | |
// of children. They can do this because they know that immediate children are always | |
// ThenPromise instances and we can therefore reach into their state to access the | |
// _listeners collection. | |
// | |
// So, what happens is that a Promise will be fulfilled through the _completed or _error | |
// messages at which point it will enter a *_notify state and be responsible for to move | |
// its children into an (as appropriate) success or error state and also notify that child's | |
// listeners of the state transition, until leaf notes are reached. | |
// | |
var state_created, // -> working | |
state_working, // -> error | error_notify | success | success_notify | canceled | waiting | |
state_waiting, // -> error | error_notify | success | success_notify | waiting_canceled | |
state_waiting_canceled, // -> error | error_notify | success | success_notify | canceling | |
state_canceled, // -> error | error_notify | success | success_notify | canceling | |
state_canceling, // -> error_notify | |
state_success_notify, // -> success | |
state_success, // -> . | |
state_error_notify, // -> error | |
state_error; // -> . | |
// Noop function, used in the various states to indicate that they don't support a given | |
// message. Named with the somewhat cute name '_' because it reads really well in the states. | |
function _() { } | |
// Initial state | |
// | |
state_created = { | |
name: "created", | |
enter: function (promise) { | |
promise._setState(state_working); | |
}, | |
cancel: _, | |
done: _, | |
then: _, | |
_completed: _, | |
_error: _, | |
_notify: _, | |
_progress: _, | |
_setCompleteValue: _, | |
_setErrorValue: _ | |
}; | |
// Ready state, waiting for a message (completed/error/progress), able to be canceled | |
// | |
state_working = { | |
name: "working", | |
enter: _, | |
cancel: function (promise) { | |
promise._setState(state_canceled); | |
}, | |
done: done, | |
then: then, | |
_completed: completed, | |
_error: error, | |
_notify: _, | |
_progress: progress, | |
_setCompleteValue: setCompleteValue, | |
_setErrorValue: setErrorValue | |
}; | |
// Waiting state, if a promise is completed with a value which is itself a promise | |
// (has a then() method) it signs up to be informed when that child promise is | |
// fulfilled at which point it will be fulfilled with that value. | |
// | |
state_waiting = { | |
name: "waiting", | |
enter: function (promise) { | |
var waitedUpon = promise._value; | |
var error = function (value) { | |
if (waitedUpon._errorId) { | |
promise._chainedError(value, waitedUpon); | |
} else { | |
// Because this is an interop boundary we want to indicate that this | |
// error has been handled by the promise infrastructure before we | |
// begin a new handling chain. | |
// | |
callonerror(promise, value, detailsForHandledError, waitedUpon, error); | |
promise._error(value); | |
} | |
}; | |
error.handlesOnError = true; | |
waitedUpon.then( | |
promise._completed.bind(promise), | |
error, | |
promise._progress.bind(promise) | |
); | |
}, | |
cancel: function (promise) { | |
promise._setState(state_waiting_canceled); | |
}, | |
done: done, | |
then: then, | |
_completed: completed, | |
_error: error, | |
_notify: _, | |
_progress: progress, | |
_setCompleteValue: setCompleteValue, | |
_setErrorValue: setErrorValue | |
}; | |
// Waiting canceled state, when a promise has been in a waiting state and receives a | |
// request to cancel its pending work it will forward that request to the child promise | |
// and then waits to be informed of the result. This promise moves itself into the | |
// canceling state but understands that the child promise may instead push it to a | |
// different state. | |
// | |
state_waiting_canceled = { | |
name: "waiting_canceled", | |
enter: function (promise) { | |
// Initiate a transition to canceling. Triggering a cancel on the promise | |
// that we are waiting upon may result in a different state transition | |
// before the state machine pump runs again. | |
promise._setState(state_canceling); | |
var waitedUpon = promise._value; | |
if (waitedUpon.cancel) { | |
waitedUpon.cancel(); | |
} | |
}, | |
cancel: _, | |
done: done, | |
then: then, | |
_completed: completed, | |
_error: error, | |
_notify: _, | |
_progress: progress, | |
_setCompleteValue: setCompleteValue, | |
_setErrorValue: setErrorValue | |
}; | |
// Canceled state, moves to the canceling state and then tells the promise to do | |
// whatever it might need to do on cancelation. | |
// | |
state_canceled = { | |
name: "canceled", | |
enter: function (promise) { | |
// Initiate a transition to canceling. The _cancelAction may change the state | |
// before the state machine pump runs again. | |
promise._setState(state_canceling); | |
promise._cancelAction(); | |
}, | |
cancel: _, | |
done: done, | |
then: then, | |
_completed: completed, | |
_error: error, | |
_notify: _, | |
_progress: progress, | |
_setCompleteValue: setCompleteValue, | |
_setErrorValue: setErrorValue | |
}; | |
// Canceling state, commits to the promise moving to an error state with an error | |
// object whose 'name' and 'message' properties contain the string "Canceled" | |
// | |
state_canceling = { | |
name: "canceling", | |
enter: function (promise) { | |
var error = new Error(canceledName); | |
error.name = error.message; | |
promise._value = error; | |
promise._setState(state_error_notify); | |
}, | |
cancel: _, | |
done: _, | |
then: _, | |
_completed: _, | |
_error: _, | |
_notify: _, | |
_progress: _, | |
_setCompleteValue: _, | |
_setErrorValue: _ | |
}; | |
// Success notify state, moves a promise to the success state and notifies all children | |
// | |
state_success_notify = { | |
name: "complete_notify", | |
enter: function (promise) { | |
promise.done = CompletePromise.prototype.done; | |
promise.then = CompletePromise.prototype.then; | |
if (promise._listeners) { | |
var queue = [promise]; | |
var p; | |
while (queue.length) { | |
p = queue.pop(); | |
p._state._notify(p, queue); | |
} | |
} | |
promise._setState(state_success); | |
}, | |
cancel: _, | |
done: null, /*error to get here */ | |
then: null, /*error to get here */ | |
_completed: _, | |
_error: _, | |
_notify: notifySuccess, | |
_progress: _, | |
_setCompleteValue: _, | |
_setErrorValue: _ | |
}; | |
// Success state, moves a promise to the success state and does NOT notify any children. | |
// Some upstream promise is owning the notification pass. | |
// | |
state_success = { | |
name: "success", | |
enter: function (promise) { | |
promise.done = CompletePromise.prototype.done; | |
promise.then = CompletePromise.prototype.then; | |
promise._cleanupAction(); | |
}, | |
cancel: _, | |
done: null, /*error to get here */ | |
then: null, /*error to get here */ | |
_completed: _, | |
_error: _, | |
_notify: notifySuccess, | |
_progress: _, | |
_setCompleteValue: _, | |
_setErrorValue: _ | |
}; | |
// Error notify state, moves a promise to the error state and notifies all children | |
// | |
state_error_notify = { | |
name: "error_notify", | |
enter: function (promise) { | |
promise.done = ErrorPromise.prototype.done; | |
promise.then = ErrorPromise.prototype.then; | |
if (promise._listeners) { | |
var queue = [promise]; | |
var p; | |
while (queue.length) { | |
p = queue.pop(); | |
p._state._notify(p, queue); | |
} | |
} | |
promise._setState(state_error); | |
}, | |
cancel: _, | |
done: null, /*error to get here*/ | |
then: null, /*error to get here*/ | |
_completed: _, | |
_error: _, | |
_notify: notifyError, | |
_progress: _, | |
_setCompleteValue: _, | |
_setErrorValue: _ | |
}; | |
// Error state, moves a promise to the error state and does NOT notify any children. | |
// Some upstream promise is owning the notification pass. | |
// | |
state_error = { | |
name: "error", | |
enter: function (promise) { | |
promise.done = ErrorPromise.prototype.done; | |
promise.then = ErrorPromise.prototype.then; | |
promise._cleanupAction(); | |
}, | |
cancel: _, | |
done: null, /*error to get here*/ | |
then: null, /*error to get here*/ | |
_completed: _, | |
_error: _, | |
_notify: notifyError, | |
_progress: _, | |
_setCompleteValue: _, | |
_setErrorValue: _ | |
}; | |
// | |
// The statemachine implementation follows a very particular pattern, the states are specified | |
// as static stateless bags of functions which are then indirected through the state machine | |
// instance (a Promise). As such all of the functions on each state have the promise instance | |
// passed to them explicitly as a parameter and the Promise instance members do a little | |
// dance where they indirect through the state and insert themselves in the argument list. | |
// | |
// We could instead call directly through the promise states however then every caller | |
// would have to remember to do things like pumping the state machine to catch state transitions. | |
// | |
var PromiseStateMachine = WinJS.Class.define(null, { | |
_listeners: null, | |
_nextState: null, | |
_state: null, | |
_value: null, | |
cancel: function () { | |
/// <signature helpKeyword="WinJS.PromiseStateMachine.cancel"> | |
/// <summary locid="WinJS.PromiseStateMachine.cancel"> | |
/// Attempts to cancel the fulfillment of a promised value. If the promise hasn't | |
/// already been fulfilled and cancellation is supported, the promise enters | |
/// the error state with a value of Error("Canceled"). | |
/// </summary> | |
/// </signature> | |
this._state.cancel(this); | |
this._run(); | |
}, | |
done: function Promise_done(onComplete, onError, onProgress) { | |
/// <signature helpKeyword="WinJS.PromiseStateMachine.done"> | |
/// <summary locid="WinJS.PromiseStateMachine.done"> | |
/// Allows you to specify the work to be done on the fulfillment of the promised value, | |
/// the error handling to be performed if the promise fails to fulfill | |
/// a value, and the handling of progress notifications along the way. | |
/// | |
/// After the handlers have finished executing, this function throws any error that would have been returned | |
/// from then() as a promise in the error state. | |
/// </summary> | |
/// <param name="onComplete" type="Function" locid="WinJS.PromiseStateMachine.done_p:onComplete"> | |
/// The function to be called if the promise is fulfilled successfully with a value. | |
/// The fulfilled value is passed as the single argument. If the value is null, | |
/// the fulfilled value is returned. The value returned | |
/// from the function becomes the fulfilled value of the promise returned by | |
/// then(). If an exception is thrown while executing the function, the promise returned | |
/// by then() moves into the error state. | |
/// </param> | |
/// <param name="onError" type="Function" optional="true" locid="WinJS.PromiseStateMachine.done_p:onError"> | |
/// The function to be called if the promise is fulfilled with an error. The error | |
/// is passed as the single argument. If it is null, the error is forwarded. | |
/// The value returned from the function is the fulfilled value of the promise returned by then(). | |
/// </param> | |
/// <param name="onProgress" type="Function" optional="true" locid="WinJS.PromiseStateMachine.done_p:onProgress"> | |
/// the function to be called if the promise reports progress. Data about the progress | |
/// is passed as the single argument. Promises are not required to support | |
/// progress. | |
/// </param> | |
/// </signature> | |
this._state.done(this, onComplete, onError, onProgress); | |
}, | |
then: function Promise_then(onComplete, onError, onProgress) { | |
/// <signature helpKeyword="WinJS.PromiseStateMachine.then"> | |
/// <summary locid="WinJS.PromiseStateMachine.then"> | |
/// Allows you to specify the work to be done on the fulfillment of the promised value, | |
/// the error handling to be performed if the promise fails to fulfill | |
/// a value, and the handling of progress notifications along the way. | |
/// </summary> | |
/// <param name="onComplete" type="Function" locid="WinJS.PromiseStateMachine.then_p:onComplete"> | |
/// The function to be called if the promise is fulfilled successfully with a value. | |
/// The value is passed as the single argument. If the value is null, the value is returned. | |
/// The value returned from the function becomes the fulfilled value of the promise returned by | |
/// then(). If an exception is thrown while this function is being executed, the promise returned | |
/// by then() moves into the error state. | |
/// </param> | |
/// <param name="onError" type="Function" optional="true" locid="WinJS.PromiseStateMachine.then_p:onError"> | |
/// The function to be called if the promise is fulfilled with an error. The error | |
/// is passed as the single argument. If it is null, the error is forwarded. | |
/// The value returned from the function becomes the fulfilled value of the promise returned by then(). | |
/// </param> | |
/// <param name="onProgress" type="Function" optional="true" locid="WinJS.PromiseStateMachine.then_p:onProgress"> | |
/// The function to be called if the promise reports progress. Data about the progress | |
/// is passed as the single argument. Promises are not required to support | |
/// progress. | |
/// </param> | |
/// <returns type="WinJS.Promise" locid="WinJS.PromiseStateMachine.then_returnValue"> | |
/// The promise whose value is the result of executing the complete or | |
/// error function. | |
/// </returns> | |
/// </signature> | |
return this._state.then(this, onComplete, onError, onProgress); | |
}, | |
_chainedError: function (value, context) { | |
var result = this._state._error(this, value, detailsForChainedError, context); | |
this._run(); | |
return result; | |
}, | |
_completed: function (value) { | |
var result = this._state._completed(this, value); | |
this._run(); | |
return result; | |
}, | |
_error: function (value) { | |
var result = this._state._error(this, value, detailsForError); | |
this._run(); | |
return result; | |
}, | |
_progress: function (value) { | |
this._state._progress(this, value); | |
}, | |
_setState: function (state) { | |
this._nextState = state; | |
}, | |
_setCompleteValue: function (value) { | |
this._state._setCompleteValue(this, value); | |
this._run(); | |
}, | |
_setChainedErrorValue: function (value, context) { | |
var result = this._state._setErrorValue(this, value, detailsForChainedError, context); | |
this._run(); | |
return result; | |
}, | |
_setExceptionValue: function (value) { | |
var result = this._state._setErrorValue(this, value, detailsForException); | |
this._run(); | |
return result; | |
}, | |
_run: function () { | |
while (this._nextState) { | |
this._state = this._nextState; | |
this._nextState = null; | |
this._state.enter(this); | |
} | |
} | |
}, { | |
supportedForProcessing: false | |
}); | |
// | |
// Implementations of shared state machine code. | |
// | |
function completed(promise, value) { | |
var targetState; | |
if (value && typeof value === "object" && typeof value.then === "function") { | |
targetState = state_waiting; | |
} else { | |
targetState = state_success_notify; | |
} | |
promise._value = value; | |
promise._setState(targetState); | |
} | |
function createErrorDetails(exception, error, promise, id, parent, handler) { | |
return { | |
exception: exception, | |
error: error, | |
promise: promise, | |
handler: handler, | |
id: id, | |
parent: parent | |
}; | |
} | |
function detailsForHandledError(promise, errorValue, context, handler) { | |
var exception = context._isException; | |
var errorId = context._errorId; | |
return createErrorDetails( | |
exception ? errorValue : null, | |
exception ? null : errorValue, | |
promise, | |
errorId, | |
context, | |
handler | |
); | |
} | |
function detailsForChainedError(promise, errorValue, context) { | |
var exception = context._isException; | |
var errorId = context._errorId; | |
setErrorInfo(promise, errorId, exception); | |
return createErrorDetails( | |
exception ? errorValue : null, | |
exception ? null : errorValue, | |
promise, | |
errorId, | |
context | |
); | |
} | |
function detailsForError(promise, errorValue) { | |
var errorId = ++error_number; | |
setErrorInfo(promise, errorId); | |
return createErrorDetails( | |
null, | |
errorValue, | |
promise, | |
errorId | |
); | |
} | |
function detailsForException(promise, exceptionValue) { | |
var errorId = ++error_number; | |
setErrorInfo(promise, errorId, true); | |
return createErrorDetails( | |
exceptionValue, | |
null, | |
promise, | |
errorId | |
); | |
} | |
function done(promise, onComplete, onError, onProgress) { | |
pushListener(promise, { c: onComplete, e: onError, p: onProgress }); | |
} | |
function error(promise, value, onerrorDetails, context) { | |
promise._value = value; | |
callonerror(promise, value, onerrorDetails, context); | |
promise._setState(state_error_notify); | |
} | |
function notifySuccess(promise, queue) { | |
var value = promise._value; | |
var listeners = promise._listeners; | |
if (!listeners) { | |
return; | |
} | |
promise._listeners = null; | |
var i, len; | |
for (i = 0, len = Array.isArray(listeners) ? listeners.length : 1; i < len; i++) { | |
var listener = len === 1 ? listeners : listeners[i]; | |
var onComplete = listener.c; | |
var target = listener.promise; | |
if (target) { | |
try { | |
target._setCompleteValue(onComplete ? onComplete(value) : value); | |
} catch (ex) { | |
target._setExceptionValue(ex); | |
} | |
if (target._state !== state_waiting && target._listeners) { | |
queue.push(target); | |
} | |
} else { | |
CompletePromise.prototype.done.call(promise, onComplete); | |
} | |
} | |
} | |
function notifyError(promise, queue) { | |
var value = promise._value; | |
var listeners = promise._listeners; | |
if (!listeners) { | |
return; | |
} | |
promise._listeners = null; | |
var i, len; | |
for (i = 0, len = Array.isArray(listeners) ? listeners.length : 1; i < len; i++) { | |
var listener = len === 1 ? listeners : listeners[i]; | |
var onError = listener.e; | |
var target = listener.promise; | |
if (target) { | |
try { | |
if (onError) { | |
if (!onError.handlesOnError) { | |
callonerror(target, value, detailsForHandledError, promise, onError); | |
} | |
target._setCompleteValue(onError(value)) | |
} else { | |
target._setChainedErrorValue(value, promise); | |
} | |
} catch (ex) { | |
target._setExceptionValue(ex); | |
} | |
if (target._state !== state_waiting && target._listeners) { | |
queue.push(target); | |
} | |
} else { | |
ErrorPromise.prototype.done.call(promise, null, onError); | |
} | |
} | |
} | |
function callonerror(promise, value, onerrorDetailsGenerator, context, handler) { | |
if (promiseEventListeners._listeners[errorET]) { | |
if (value instanceof Error && value.message === canceledName) { | |
return; | |
} | |
promiseEventListeners.dispatchEvent(errorET, onerrorDetailsGenerator(promise, value, context, handler)); | |
} | |
} | |
function progress(promise, value) { | |
var listeners = promise._listeners; | |
if (listeners) { | |
var i, len; | |
for (i = 0, len = Array.isArray(listeners) ? listeners.length : 1; i < len; i++) { | |
var listener = len === 1 ? listeners : listeners[i]; | |
var onProgress = listener.p; | |
if (onProgress) { | |
try { onProgress(value); } catch (ex) { } | |
} | |
if (!(listener.c || listener.e) && listener.promise) { | |
listener.promise._progress(value); | |
} | |
} | |
} | |
} | |
function pushListener(promise, listener) { | |
var listeners = promise._listeners; | |
if (listeners) { | |
// We may have either a single listener (which will never be wrapped in an array) | |
// or 2+ listeners (which will be wrapped). Since we are now adding one more listener | |
// we may have to wrap the single listener before adding the second. | |
listeners = Array.isArray(listeners) ? listeners : [listeners]; | |
listeners.push(listener); | |
} else { | |
listeners = listener; | |
} | |
promise._listeners = listeners; | |
} | |
// The difference beween setCompleteValue()/setErrorValue() and complete()/error() is that setXXXValue() moves | |
// a promise directly to the success/error state without starting another notification pass (because one | |
// is already ongoing). | |
function setErrorInfo(promise, errorId, isException) { | |
promise._isException = isException || false; | |
promise._errorId = errorId; | |
} | |
function setErrorValue(promise, value, onerrorDetails, context) { | |
promise._value = value; | |
callonerror(promise, value, onerrorDetails, context); | |
promise._setState(state_error); | |
} | |
function setCompleteValue(promise, value) { | |
var targetState; | |
if (value && typeof value === "object" && typeof value.then === "function") { | |
targetState = state_waiting; | |
} else { | |
targetState = state_success; | |
} | |
promise._value = value; | |
promise._setState(targetState); | |
} | |
function then(promise, onComplete, onError, onProgress) { | |
var result = new ThenPromise(promise); | |
pushListener(promise, { promise: result, c: onComplete, e: onError, p: onProgress }); | |
return result; | |
} | |
// | |
// Internal implementation detail promise, ThenPromise is created when a promise needs | |
// to be returned from a then() method. | |
// | |
var ThenPromise = WinJS.Class.derive(PromiseStateMachine, | |
function (creator) { | |
if (tagWithStack && (tagWithStack === true || (tagWithStack & tag.thenPromise))) { | |
this._stack = WinJS.Promise._getStack(); | |
} | |
this._creator = creator; | |
this._setState(state_created); | |
this._run(); | |
}, { | |
_creator: null, | |
_cancelAction: function () { if (this._creator) { this._creator.cancel(); } }, | |
_cleanupAction: function () { this._creator = null; } | |
}, { | |
supportedForProcessing: false | |
} | |
); | |
// | |
// Slim promise implementations for already completed promises, these are created | |
// under the hood on synchronous completion paths as well as by WinJS.Promise.wrap | |
// and WinJS.Promise.wrapError. | |
// | |
var ErrorPromise = WinJS.Class.define( | |
function ErrorPromise_ctor(value) { | |
if (tagWithStack && (tagWithStack === true || (tagWithStack & tag.errorPromise))) { | |
this._stack = WinJS.Promise._getStack(); | |
} | |
this._value = value; | |
callonerror(this, value, detailsForError); | |
}, { | |
cancel: function () { | |
/// <signature helpKeyword="WinJS.PromiseStateMachine.cancel"> | |
/// <summary locid="WinJS.PromiseStateMachine.cancel"> | |
/// Attempts to cancel the fulfillment of a promised value. If the promise hasn't | |
/// already been fulfilled and cancellation is supported, the promise enters | |
/// the error state with a value of Error("Canceled"). | |
/// </summary> | |
/// </signature> | |
}, | |
done: function ErrorPromise_done(unused, onError) { | |
/// <signature helpKeyword="WinJS.PromiseStateMachine.done"> | |
/// <summary locid="WinJS.PromiseStateMachine.done"> | |
/// Allows you to specify the work to be done on the fulfillment of the promised value, | |
/// the error handling to be performed if the promise fails to fulfill | |
/// a value, and the handling of progress notifications along the way. | |
/// | |
/// After the handlers have finished executing, this function throws any error that would have been returned | |
/// from then() as a promise in the error state. | |
/// </summary> | |
/// <param name='onComplete' type='Function' locid="WinJS.PromiseStateMachine.done_p:onComplete"> | |
/// The function to be called if the promise is fulfilled successfully with a value. | |
/// The fulfilled value is passed as the single argument. If the value is null, | |
/// the fulfilled value is returned. The value returned | |
/// from the function becomes the fulfilled value of the promise returned by | |
/// then(). If an exception is thrown while executing the function, the promise returned | |
/// by then() moves into the error state. | |
/// </param> | |
/// <param name='onError' type='Function' optional='true' locid="WinJS.PromiseStateMachine.done_p:onError"> | |
/// The function to be called if the promise is fulfilled with an error. The error | |
/// is passed as the single argument. If it is null, the error is forwarded. | |
/// The value returned from the function is the fulfilled value of the promise returned by then(). | |
/// </param> | |
/// <param name='onProgress' type='Function' optional='true' locid="WinJS.PromiseStateMachine.done_p:onProgress"> | |
/// the function to be called if the promise reports progress. Data about the progress | |
/// is passed as the single argument. Promises are not required to support | |
/// progress. | |
/// </param> | |
/// </signature> | |
var value = this._value; | |
if (onError) { | |
try { | |
if (!onError.handlesOnError) { | |
callonerror(null, value, detailsForHandledError, this, onError); | |
} | |
var result = onError(value); | |
if (result && typeof result === "object" && typeof result.done === "function") { | |
// If a promise is returned we need to wait on it. | |
result.done(); | |
} | |
return; | |
} catch (ex) { | |
value = ex; | |
} | |
} | |
if (value instanceof Error && value.message === canceledName) { | |
// suppress cancel | |
return; | |
} | |
// force the exception to be thrown asyncronously to avoid any try/catch blocks | |
// | |
setImmediate(function () { | |
throw value; | |
}); | |
}, | |
then: function ErrorPromise_then(unused, onError) { | |
/// <signature helpKeyword="WinJS.PromiseStateMachine.then"> | |
/// <summary locid="WinJS.PromiseStateMachine.then"> | |
/// Allows you to specify the work to be done on the fulfillment of the promised value, | |
/// the error handling to be performed if the promise fails to fulfill | |
/// a value, and the handling of progress notifications along the way. | |
/// </summary> | |
/// <param name='onComplete' type='Function' locid="WinJS.PromiseStateMachine.then_p:onComplete"> | |
/// The function to be called if the promise is fulfilled successfully with a value. | |
/// The value is passed as the single argument. If the value is null, the value is returned. | |
/// The value returned from the function becomes the fulfilled value of the promise returned by | |
/// then(). If an exception is thrown while this function is being executed, the promise returned | |
/// by then() moves into the error state. | |
/// </param> | |
/// <param name='onError' type='Function' optional='true' locid="WinJS.PromiseStateMachine.then_p:onError"> | |
/// The function to be called if the promise is fulfilled with an error. The error | |
/// is passed as the single argument. If it is null, the error is forwarded. | |
/// The value returned from the function becomes the fulfilled value of the promise returned by then(). | |
/// </param> | |
/// <param name='onProgress' type='Function' optional='true' locid="WinJS.PromiseStateMachine.then_p:onProgress"> | |
/// The function to be called if the promise reports progress. Data about the progress | |
/// is passed as the single argument. Promises are not required to support | |
/// progress. | |
/// </param> | |
/// <returns type="WinJS.Promise" locid="WinJS.PromiseStateMachine.then_returnValue"> | |
/// The promise whose value is the result of executing the complete or | |
/// error function. | |
/// </returns> | |
/// </signature> | |
// If the promise is already in a error state and no error handler is provided | |
// we optimize by simply returning the promise instead of creating a new one. | |
// | |
if (!onError) { return this; } | |
var result; | |
var value = this._value; | |
try { | |
if (!onError.handlesOnError) { | |
callonerror(null, value, detailsForHandledError, this, onError); | |
} | |
result = new CompletePromise(onError(value)); | |
} catch (ex) { | |
// If the value throw from the error handler is the same as the value | |
// provided to the error handler then there is no need for a new promise. | |
// | |
if (ex === value) { | |
result = this; | |
} else { | |
result = new ExceptionPromise(ex); | |
} | |
} | |
return result; | |
} | |
}, { | |
supportedForProcessing: false | |
} | |
); | |
var ExceptionPromise = WinJS.Class.derive(ErrorPromise, | |
function ExceptionPromise_ctor(value) { | |
if (tagWithStack && (tagWithStack === true || (tagWithStack & tag.exceptionPromise))) { | |
this._stack = WinJS.Promise._getStack(); | |
} | |
this._value = value; | |
callonerror(this, value, detailsForException); | |
}, { | |
/* empty */ | |
}, { | |
supportedForProcessing: false | |
} | |
); | |
var CompletePromise = WinJS.Class.define( | |
function CompletePromise_ctor(value) { | |
if (tagWithStack && (tagWithStack === true || (tagWithStack & tag.completePromise))) { | |
this._stack = WinJS.Promise._getStack(); | |
} | |
if (value && typeof value === "object" && typeof value.then === "function") { | |
var result = new ThenPromise(null); | |
result._setCompleteValue(value); | |
return result; | |
} | |
this._value = value; | |
}, { | |
cancel: function () { | |
/// <signature helpKeyword="WinJS.PromiseStateMachine.cancel"> | |
/// <summary locid="WinJS.PromiseStateMachine.cancel"> | |
/// Attempts to cancel the fulfillment of a promised value. If the promise hasn't | |
/// already been fulfilled and cancellation is supported, the promise enters | |
/// the error state with a value of Error("Canceled"). | |
/// </summary> | |
/// </signature> | |
}, | |
done: function CompletePromise_done(onComplete) { | |
/// <signature helpKeyword="WinJS.PromiseStateMachine.done"> | |
/// <summary locid="WinJS.PromiseStateMachine.done"> | |
/// Allows you to specify the work to be done on the fulfillment of the promised value, | |
/// the error handling to be performed if the promise fails to fulfill | |
/// a value, and the handling of progress notifications along the way. | |
/// | |
/// After the handlers have finished executing, this function throws any error that would have been returned | |
/// from then() as a promise in the error state. | |
/// </summary> | |
/// <param name='onComplete' type='Function' locid="WinJS.PromiseStateMachine.done_p:onComplete"> | |
/// The function to be called if the promise is fulfilled successfully with a value. | |
/// The fulfilled value is passed as the single argument. If the value is null, | |
/// the fulfilled value is returned. The value returned | |
/// from the function becomes the fulfilled value of the promise returned by | |
/// then(). If an exception is thrown while executing the function, the promise returned | |
/// by then() moves into the error state. | |
/// </param> | |
/// <param name='onError' type='Function' optional='true' locid="WinJS.PromiseStateMachine.done_p:onError"> | |
/// The function to be called if the promise is fulfilled with an error. The error | |
/// is passed as the single argument. If it is null, the error is forwarded. | |
/// The value returned from the function is the fulfilled value of the promise returned by then(). | |
/// </param> | |
/// <param name='onProgress' type='Function' optional='true' locid="WinJS.PromiseStateMachine.done_p:onProgress"> | |
/// the function to be called if the promise reports progress. Data about the progress | |
/// is passed as the single argument. Promises are not required to support | |
/// progress. | |
/// </param> | |
/// </signature> | |
if (!onComplete) { return; } | |
try { | |
var result = onComplete(this._value); | |
if (result && typeof result === "object" && typeof result.done === "function") { | |
result.done(); | |
} | |
} catch (ex) { | |
// force the exception to be thrown asynchronously to avoid any try/catch blocks | |
setImmediate(function () { | |
throw ex; | |
}); | |
} | |
}, | |
then: function CompletePromise_then(onComplete) { | |
/// <signature helpKeyword="WinJS.PromiseStateMachine.then"> | |
/// <summary locid="WinJS.PromiseStateMachine.then"> | |
/// Allows you to specify the work to be done on the fulfillment of the promised value, | |
/// the error handling to be performed if the promise fails to fulfill | |
/// a value, and the handling of progress notifications along the way. | |
/// </summary> | |
/// <param name='onComplete' type='Function' locid="WinJS.PromiseStateMachine.then_p:onComplete"> | |
/// The function to be called if the promise is fulfilled successfully with a value. | |
/// The value is passed as the single argument. If the value is null, the value is returned. | |
/// The value returned from the function becomes the fulfilled value of the promise returned by | |
/// then(). If an exception is thrown while this function is being executed, the promise returned | |
/// by then() moves into the error state. | |
/// </param> | |
/// <param name='onError' type='Function' optional='true' locid="WinJS.PromiseStateMachine.then_p:onError"> | |
/// The function to be called if the promise is fulfilled with an error. The error | |
/// is passed as the single argument. If it is null, the error is forwarded. | |
/// The value returned from the function becomes the fulfilled value of the promise returned by then(). | |
/// </param> | |
/// <param name='onProgress' type='Function' optional='true' locid="WinJS.PromiseStateMachine.then_p:onProgress"> | |
/// The function to be called if the promise reports progress. Data about the progress | |
/// is passed as the single argument. Promises are not required to support | |
/// progress. | |
/// </param> | |
/// <returns type="WinJS.Promise" locid="WinJS.PromiseStateMachine.then_returnValue"> | |
/// The promise whose value is the result of executing the complete or | |
/// error function. | |
/// </returns> | |
/// </signature> | |
try { | |
// If the value returned from the completion handler is the same as the value | |
// provided to the completion handler then there is no need for a new promise. | |
// | |
var newValue = onComplete ? onComplete(this._value) : this._value; | |
return newValue === this._value ? this : new CompletePromise(newValue); | |
} catch (ex) { | |
return new ExceptionPromise(ex); | |
} | |
} | |
}, { | |
supportedForProcessing: false | |
} | |
); | |
// | |
// Promise is the user-creatable WinJS.Promise object. | |
// | |
function timeout(timeoutMS) { | |
var id; | |
return new WinJS.Promise( | |
function (c) { | |
if (timeoutMS) { | |
id = setTimeout(c, timeoutMS); | |
} else { | |
setImmediate(c); | |
} | |
}, | |
function () { | |
if (id) { | |
clearTimeout(id); | |
} | |
} | |
); | |
} | |
function timeoutWithPromise(timeout, promise) { | |
var cancelPromise = function () { promise.cancel(); } | |
var cancelTimeout = function () { timeout.cancel(); } | |
timeout.then(cancelPromise); | |
promise.then(cancelTimeout, cancelTimeout); | |
return promise; | |
} | |
var staticCanceledPromise; | |
var Promise = WinJS.Class.derive(PromiseStateMachine, | |
function Promise_ctor(init, oncancel) { | |
/// <signature helpKeyword="WinJS.Promise"> | |
/// <summary locid="WinJS.Promise"> | |
/// A promise provides a mechanism to schedule work to be done on a value that | |
/// has not yet been computed. It is a convenient abstraction for managing | |
/// interactions with asynchronous APIs. | |
/// </summary> | |
/// <param name="init" type="Function" locid="WinJS.Promise_p:init"> | |
/// The function that is called during construction of the promise. The function | |
/// is given three arguments (complete, error, progress). Inside this function | |
/// you should add event listeners for the notifications supported by this value. | |
/// </param> | |
/// <param name="oncancel" optional="true" locid="WinJS.Promise_p:oncancel"> | |
/// The function to call if a consumer of this promise wants | |
/// to cancel its undone work. Promises are not required to | |
/// support cancellation. | |
/// </param> | |
/// </signature> | |
if (tagWithStack && (tagWithStack === true || (tagWithStack & tag.promise))) { | |
this._stack = WinJS.Promise._getStack(); | |
} | |
this._oncancel = oncancel; | |
this._setState(state_created); | |
this._run(); | |
try { | |
var complete = this._completed.bind(this); | |
var error = this._error.bind(this); | |
var progress = this._progress.bind(this); | |
init(complete, error, progress); | |
} catch (ex) { | |
this._setExceptionValue(ex); | |
} | |
}, { | |
_oncancel: null, | |
_cancelAction: function () { | |
if (this._oncancel) { | |
try { this._oncancel(); } catch (ex) { } | |
} | |
}, | |
_cleanupAction: function () { this._oncancel = null; } | |
}, { | |
addEventListener: function Promise_addEventListener(eventType, listener, capture) { | |
/// <signature helpKeyword="WinJS.Promise.addEventListener"> | |
/// <summary locid="WinJS.Promise.addEventListener"> | |
/// Adds an event listener to the control. | |
/// </summary> | |
/// <param name="eventType" locid="WinJS.Promise.addEventListener_p:eventType"> | |
/// The type (name) of the event. | |
/// </param> | |
/// <param name="listener" locid="WinJS.Promise.addEventListener_p:listener"> | |
/// The listener to invoke when the event is raised. | |
/// </param> | |
/// <param name="capture" locid="WinJS.Promise.addEventListener_p:capture"> | |
/// Specifies whether or not to initiate capture. | |
/// </param> | |
/// </signature> | |
promiseEventListeners.addEventListener(eventType, listener, capture); | |
}, | |
any: function Promise_any(values) { | |
/// <signature helpKeyword="WinJS.Promise.any"> | |
/// <summary locid="WinJS.Promise.any"> | |
/// Returns a promise that is fulfilled when one of the input promises | |
/// has been fulfilled. | |
/// </summary> | |
/// <param name="values" type="Array" locid="WinJS.Promise.any_p:values"> | |
/// An array that contains promise objects or objects whose property | |
/// values include promise objects. | |
/// </param> | |
/// <returns type="WinJS.Promise" locid="WinJS.Promise.any_returnValue"> | |
/// A promise that on fulfillment yields the value of the input (complete or error). | |
/// </returns> | |
/// </signature> | |
return new Promise( | |
function (complete, error, progress) { | |
var keys = Object.keys(values); | |
var errors = Array.isArray(values) ? [] : {}; | |
if (keys.length === 0) { | |
complete(); | |
} | |
var canceled = 0; | |
keys.forEach(function (key) { | |
Promise.as(values[key]).then( | |
function () { complete({ key: key, value: values[key] }); }, | |
function (e) { | |
if (e instanceof Error && e.name === canceledName) { | |
if ((++canceled) === keys.length) { | |
complete(WinJS.Promise.cancel); | |
} | |
return; | |
} | |
error({ key: key, value: values[key] }); | |
} | |
); | |
}); | |
}, | |
function () { | |
var keys = Object.keys(values); | |
keys.forEach(function (key) { | |
var promise = Promise.as(values[key]); | |
if (typeof promise.cancel === "function") { | |
promise.cancel(); | |
} | |
}); | |
} | |
); | |
}, | |
as: function Promise_as(value) { | |
/// <signature helpKeyword="WinJS.Promise.as"> | |
/// <summary locid="WinJS.Promise.as"> | |
/// Returns a promise. If the object is already a promise it is returned; | |
/// otherwise the object is wrapped in a promise. | |
/// </summary> | |
/// <param name="value" locid="WinJS.Promise.as_p:value"> | |
/// The value to be treated as a promise. | |
/// </param> | |
/// <returns type="WinJS.Promise" locid="WinJS.Promise.as_returnValue"> | |
/// A promise. | |
/// </returns> | |
/// </signature> | |
if (value && typeof value === "object" && typeof value.then === "function") { | |
return value; | |
} | |
return new CompletePromise(value); | |
}, | |
/// <field type="WinJS.Promise" helpKeyword="WinJS.Promise.cancel" locid="WinJS.Promise.cancel"> | |
/// Canceled promise value, can be returned from a promise completion handler | |
/// to indicate cancelation of the promise chain. | |
/// </field> | |
cancel: { | |
get: function () { | |
return (staticCanceledPromise = staticCanceledPromise || new ErrorPromise(new WinJS.ErrorFromName(canceledName))); | |
} | |
}, | |
dispatchEvent: function Promise_dispatchEvent(eventType, details) { | |
/// <signature helpKeyword="WinJS.Promise.dispatchEvent"> | |
/// <summary locid="WinJS.Promise.dispatchEvent"> | |
/// Raises an event of the specified type and properties. | |
/// </summary> | |
/// <param name="eventType" locid="WinJS.Promise.dispatchEvent_p:eventType"> | |
/// The type (name) of the event. | |
/// </param> | |
/// <param name="details" locid="WinJS.Promise.dispatchEvent_p:details"> | |
/// The set of additional properties to be attached to the event object. | |
/// </param> | |
/// <returns type="Boolean" locid="WinJS.Promise.dispatchEvent_returnValue"> | |
/// Specifies whether preventDefault was called on the event. | |
/// </returns> | |
/// </signature> | |
return promiseEventListeners.dispatchEvent(eventType, details); | |
}, | |
is: function Promise_is(value) { | |
/// <signature helpKeyword="WinJS.Promise.is"> | |
/// <summary locid="WinJS.Promise.is"> | |
/// Determines whether a value fulfills the promise contract. | |
/// </summary> | |
/// <param name="value" locid="WinJS.Promise.is_p:value"> | |
/// A value that may be a promise. | |
/// </param> | |
/// <returns type="Boolean" locid="WinJS.Promise.is_returnValue"> | |
/// true if the specified value is a promise, otherwise false. | |
/// </returns> | |
/// </signature> | |
return value && typeof value === "object" && typeof value.then === "function"; | |
}, | |
join: function Promise_join(values) { | |
/// <signature helpKeyword="WinJS.Promise.join"> | |
/// <summary locid="WinJS.Promise.join"> | |
/// Creates a promise that is fulfilled when all the values are fulfilled. | |
/// </summary> | |
/// <param name="values" type="Object" locid="WinJS.Promise.join_p:values"> | |
/// An object whose fields contain values, some of which may be promises. | |
/// </param> | |
/// <returns type="WinJS.Promise" locid="WinJS.Promise.join_returnValue"> | |
/// A promise whose value is an object with the same field names as those of the object in the values parameter, where | |
/// each field value is the fulfilled value of a promise. | |
/// </returns> | |
/// </signature> | |
return new Promise( | |
function (complete, error, progress) { | |
var keys = Object.keys(values); | |
var errors = Array.isArray(values) ? [] : {}; | |
var results = Array.isArray(values) ? [] : {}; | |
var undefineds = 0; | |
var pending = keys.length; | |
var argDone = function (key) { | |
if ((--pending) === 0) { | |
var errorCount = Object.keys(errors).length; | |
if (errorCount === 0) { | |
complete(results); | |
} else { | |
var canceledCount = 0; | |
keys.forEach(function (key) { | |
var e = errors[key]; | |
if (e instanceof Error && e.name === canceledName) { | |
canceledCount++; | |
} | |
}); | |
if (canceledCount === errorCount) { | |
complete(WinJS.Promise.cancel); | |
} else { | |
error(errors); | |
} | |
} | |
} else { | |
progress({ Key: key, Done: true }); | |
} | |
}; | |
keys.forEach(function (key) { | |
var value = values[key]; | |
if (value === undefined) { | |
undefineds++; | |
} else { | |
Promise.then(value, | |
function (value) { results[key] = value; argDone(key); }, | |
function (value) { errors[key] = value; argDone(key); } | |
); | |
} | |
}); | |
pending -= undefineds; | |
if (pending === 0) { | |
complete(results); | |
return; | |
} | |
}, | |
function () { | |
Object.keys(values).forEach(function (key) { | |
var promise = Promise.as(values[key]); | |
if (typeof promise.cancel === "function") { | |
promise.cancel(); | |
} | |
}); | |
} | |
); | |
}, | |
removeEventListener: function Promise_removeEventListener(eventType, listener, capture) { | |
/// <signature helpKeyword="WinJS.Promise.removeEventListener"> | |
/// <summary locid="WinJS.Promise.removeEventListener"> | |
/// Removes an event listener from the control. | |
/// </summary> | |
/// <param name='eventType' locid="WinJS.Promise.removeEventListener_eventType"> | |
/// The type (name) of the event. | |
/// </param> | |
/// <param name='listener' locid="WinJS.Promise.removeEventListener_listener"> | |
/// The listener to remove. | |
/// </param> | |
/// <param name='capture' locid="WinJS.Promise.removeEventListener_capture"> | |
/// Specifies whether or not to initiate capture. | |
/// </param> | |
/// </signature> | |
promiseEventListeners.removeEventListener(eventType, listener, capture); | |
}, | |
supportedForProcessing: false, | |
then: function Promise_then(value, onComplete, onError, onProgress) { | |
/// <signature helpKeyword="WinJS.Promise.then"> | |
/// <summary locid="WinJS.Promise.then"> | |
/// A static version of the promise instance method then(). | |
/// </summary> | |
/// <param name="value" locid="WinJS.Promise.then_p:value"> | |
/// the value to be treated as a promise. | |
/// </param> | |
/// <param name="onComplete" type="Function" locid="WinJS.Promise.then_p:complete"> | |
/// The function to be called if the promise is fulfilled with a value. | |
/// If it is null, the promise simply | |
/// returns the value. The value is passed as the single argument. | |
/// </param> | |
/// <param name="onError" type="Function" optional="true" locid="WinJS.Promise.then_p:error"> | |
/// The function to be called if the promise is fulfilled with an error. The error | |
/// is passed as the single argument. | |
/// </param> | |
/// <param name="onProgress" type="Function" optional="true" locid="WinJS.Promise.then_p:progress"> | |
/// The function to be called if the promise reports progress. Data about the progress | |
/// is passed as the single argument. Promises are not required to support | |
/// progress. | |
/// </param> | |
/// <returns type="WinJS.Promise" locid="WinJS.Promise.then_returnValue"> | |
/// A promise whose value is the result of executing the provided complete function. | |
/// </returns> | |
/// </signature> | |
return Promise.as(value).then(onComplete, onError, onProgress); | |
}, | |
thenEach: function Promise_thenEach(values, onComplete, onError, onProgress) { | |
/// <signature helpKeyword="WinJS.Promise.thenEach"> | |
/// <summary locid="WinJS.Promise.thenEach"> | |
/// Performs an operation on all the input promises and returns a promise | |
/// that has the shape of the input and contains the result of the operation | |
/// that has been performed on each input. | |
/// </summary> | |
/// <param name="values" locid="WinJS.Promise.thenEach_p:values"> | |
/// A set of values (which could be either an array or an object) of which some or all are promises. | |
/// </param> | |
/// <param name="onComplete" type="Function" locid="WinJS.Promise.thenEach_p:complete"> | |
/// The function to be called if the promise is fulfilled with a value. | |
/// If the value is null, the promise returns the value. | |
/// The value is passed as the single argument. | |
/// </param> | |
/// <param name="onError" type="Function" optional="true" locid="WinJS.Promise.thenEach_p:error"> | |
/// The function to be called if the promise is fulfilled with an error. The error | |
/// is passed as the single argument. | |
/// </param> | |
/// <param name="onProgress" type="Function" optional="true" locid="WinJS.Promise.thenEach_p:progress"> | |
/// The function to be called if the promise reports progress. Data about the progress | |
/// is passed as the single argument. Promises are not required to support | |
/// progress. | |
/// </param> | |
/// <returns type="WinJS.Promise" locid="WinJS.Promise.thenEach_returnValue"> | |
/// A promise that is the result of calling Promise.join on the values parameter. | |
/// </returns> | |
/// </signature> | |
var result = Array.isArray(values) ? [] : {}; | |
Object.keys(values).forEach(function (key) { | |
result[key] = Promise.as(values[key]).then(onComplete, onError, onProgress); | |
}); | |
return Promise.join(result); | |
}, | |
timeout: function Promise_timeout(time, promise) { | |
/// <signature helpKeyword="WinJS.Promise.timeout"> | |
/// <summary locid="WinJS.Promise.timeout"> | |
/// Creates a promise that is fulfilled after a timeout. | |
/// </summary> | |
/// <param name="timeout" type="Number" optional="true" locid="WinJS.Promise.timeout_p:timeout"> | |
/// The timeout period in milliseconds. If this value is zero or not specified | |
/// setImmediate is called, otherwise setTimeout is called. | |
/// </param> | |
/// <param name="promise" type="Promise" optional="true" locid="WinJS.Promise.timeout_p:promise"> | |
/// A promise that will be canceled if it doesn't complete before the | |
/// timeout has expired. | |
/// </param> | |
/// <returns type="WinJS.Promise" locid="WinJS.Promise.timeout_returnValue"> | |
/// A promise that is completed asynchronously after the specified timeout. | |
/// </returns> | |
/// </signature> | |
var to = timeout(time); | |
return promise ? timeoutWithPromise(to, promise) : to; | |
}, | |
wrap: function Promise_wrap(value) { | |
/// <signature helpKeyword="WinJS.Promise.wrap"> | |
/// <summary locid="WinJS.Promise.wrap"> | |
/// Wraps a non-promise value in a promise. You can use this function if you need | |
/// to pass a value to a function that requires a promise. | |
/// </summary> | |
/// <param name="value" locid="WinJS.Promise.wrap_p:value"> | |
/// Some non-promise value to be wrapped in a promise. | |
/// </param> | |
/// <returns type="WinJS.Promise" locid="WinJS.Promise.wrap_returnValue"> | |
/// A promise that is successfully fulfilled with the specified value | |
/// </returns> | |
/// </signature> | |
return new CompletePromise(value); | |
}, | |
wrapError: function Promise_wrapError(error) { | |
/// <signature helpKeyword="WinJS.Promise.wrapError"> | |
/// <summary locid="WinJS.Promise.wrapError"> | |
/// Wraps a non-promise error value in a promise. You can use this function if you need | |
/// to pass an error to a function that requires a promise. | |
/// </summary> | |
/// <param name="error" locid="WinJS.Promise.wrapError_p:error"> | |
/// A non-promise error value to be wrapped in a promise. | |
/// </param> | |
/// <returns type="WinJS.Promise" locid="WinJS.Promise.wrapError_returnValue"> | |
/// A promise that is in an error state with the specified value. | |
/// </returns> | |
/// </signature> | |
return new ErrorPromise(error); | |
}, | |
_veryExpensiveTagWithStack: { | |
get: function () { return tagWithStack; }, | |
set: function (value) { tagWithStack = value; } | |
}, | |
_veryExpensiveTagWithStack_tag: tag, | |
_getStack: function () { | |
if (Debug.debuggerEnabled) { | |
try { throw new Error(); } catch (e) { return e.stack; } | |
} | |
}, | |
} | |
); | |
Object.defineProperties(Promise, WinJS.Utilities.createEventProperties(errorET)); | |
var SignalPromise = WinJS.Class.derive(PromiseStateMachine, | |
function (cancel) { | |
this._oncancel = cancel; | |
this._setState(state_created); | |
this._run(); | |
}, { | |
_cancelAction: function () { this._oncancel && this._oncancel(); }, | |
_cleanupAction: function () { this._oncancel = null; } | |
}, { | |
supportedForProcessing: false | |
} | |
); | |
var Signal = WinJS.Class.define( | |
function Signal_ctor(oncancel) { | |
this._promise = new SignalPromise(oncancel); | |
}, { | |
promise: { | |
get: function () { return this._promise; } | |
}, | |
cancel: function Signal_cancel() { | |
this._promise.cancel(); | |
}, | |
complete: function Signal_complete(value) { | |
this._promise._completed(value); | |
}, | |
error: function Signal_error(value) { | |
this._promise._error(value); | |
}, | |
progress: function Signal_progress(value) { | |
this._promise._progress(value); | |
} | |
}, { | |
supportedForProcessing: false, | |
} | |
); | |
// Publish WinJS.Promise | |
// | |
WinJS.Namespace.define("WinJS", { | |
Promise: Promise, | |
_Signal: Signal | |
}); | |
}(this)); | |
(function errorsInit(global, WinJS) { | |
"use strict"; | |
WinJS.Namespace.define("WinJS", { | |
// ErrorFromName establishes a simple pattern for returning error codes. | |
// | |
ErrorFromName: WinJS.Class.derive(Error, function (name, message) { | |
/// <signature helpKeyword="WinJS.ErrorFromName"> | |
/// <summary locid="WinJS.ErrorFromName"> | |
/// Creates an Error object with the specified name and message properties. | |
/// </summary> | |
/// <param name="name" type="String" locid="WinJS.ErrorFromName_p:name">The name of this error. The name is meant to be consumed programmatically and should not be localized.</param> | |
/// <param name="message" type="String" optional="true" locid="WinJS.ErrorFromName_p:message">The message for this error. The message is meant to be consumed by humans and should be localized.</param> | |
/// <returns type="Error" locid="WinJS.ErrorFromName_returnValue">Error instance with .name and .message properties populated</returns> | |
/// </signature> | |
this.name = name; | |
this.message = message || name; | |
}, { | |
/* empty */ | |
}, { | |
supportedForProcessing: false, | |
}) | |
}); | |
})(this, WinJS); | |
(function xhrInit() { | |
"use strict"; | |
WinJS.Namespace.define("WinJS", { | |
xhr: function (options) { | |
/// <signature helpKeyword="WinJS.xhr"> | |
/// <summary locid="WinJS.xhr"> | |
/// Wraps calls to XMLHttpRequest in a promise. | |
/// </summary> | |
/// <param name="options" type="Object" locid="WinJS.xhr_p:options"> | |
/// The options that are applied to the XMLHttpRequest object. They are: type, | |
/// url, user, password, headers, responseType, data, and customRequestInitializer. | |
/// </param> | |
/// <returns type="WinJS.Promise" locid="WinJS.xhr_returnValue"> | |
/// A promise that returns the XMLHttpRequest object when it completes. | |
/// </returns> | |
/// </signature> | |
var req; | |
return new WinJS.Promise( | |
function (c, e, p) { | |
/// <returns value="c(new XMLHttpRequest())" locid="WinJS.xhr.constructor._returnValue" /> | |
req = new XMLHttpRequest(); | |
req.onreadystatechange = function () { | |
if (req._canceled) { return; } | |
if (req.readyState === 4) { | |
if (req.status >= 200 && req.status < 300) { | |
c(req); | |
} else { | |
e(req); | |
} | |
req.onreadystatechange = function () { }; | |
} else { | |
p(req); | |
} | |
}; | |
req.open( | |
options.type || "GET", | |
options.url, | |
// Promise based XHR does not support sync. | |
// | |
true, | |
options.user, | |
options.password | |
); | |
req.responseType = options.responseType || ""; | |
Object.keys(options.headers || {}).forEach(function (k) { | |
req.setRequestHeader(k, options.headers[k]); | |
}); | |
if (options.customRequestInitializer) { | |
options.customRequestInitializer(req); | |
} | |
req.send(options.data); | |
}, | |
function () { | |
req._canceled = true; | |
req.abort(); | |
} | |
); | |
} | |
}); | |
})(); | |
(function safeHTMLInit(global, undefined) { | |
"use strict"; | |
var setInnerHTML, | |
setInnerHTMLUnsafe, | |
setOuterHTML, | |
setOuterHTMLUnsafe, | |
insertAdjacentHTML, | |
insertAdjacentHTMLUnsafe; | |
var strings = { | |
get nonStaticHTML() { return WinJS.Resources._getWinJSString("base/nonStaticHTML").value; }, | |
}; | |
setInnerHTML = setInnerHTMLUnsafe = function (element, text) { | |
/// <signature helpKeyword="WinJS.Utilities.setInnerHTML"> | |
/// <summary locid="WinJS.Utilities.setInnerHTML"> | |
/// Sets the innerHTML property of the specified element to the specified text. | |
/// </summary> | |
/// <param name="element" type="HTMLElement" locid="WinJS.Utilities.setInnerHTML_p:element"> | |
/// The element on which the innerHTML property is to be set. | |
/// </param> | |
/// <param name="text" type="String" locid="WinJS.Utilities.setInnerHTML_p:text"> | |
/// The value to be set to the innerHTML property. | |
/// </param> | |
/// </signature> | |
element.innerHTML = text; | |
}; | |
setOuterHTML = setOuterHTMLUnsafe = function (element, text) { | |
/// <signature helpKeyword="WinJS.Utilities.setOuterHTML"> | |
/// <summary locid="WinJS.Utilities.setOuterHTML"> | |
/// Sets the outerHTML property of the specified element to the specified text. | |
/// </summary> | |
/// <param name="element" type="HTMLElement" locid="WinJS.Utilities.setOuterHTML_p:element"> | |
/// The element on which the outerHTML property is to be set. | |
/// </param> | |
/// <param name="text" type="String" locid="WinJS.Utilities.setOuterHTML_p:text"> | |
/// The value to be set to the outerHTML property. | |
/// </param> | |
/// </signature> | |
element.outerHTML = text; | |
}; | |
insertAdjacentHTML = insertAdjacentHTMLUnsafe = function (element, position, text) { | |
/// <signature helpKeyword="WinJS.Utilities.insertAdjacentHTML"> | |
/// <summary locid="WinJS.Utilities.insertAdjacentHTML"> | |
/// Calls insertAdjacentHTML on the specified element. | |
/// </summary> | |
/// <param name="element" type="HTMLElement" locid="WinJS.Utilities.insertAdjacentHTML_p:element"> | |
/// The element on which insertAdjacentHTML is to be called. | |
/// </param> | |
/// <param name="position" type="String" locid="WinJS.Utilities.insertAdjacentHTML_p:position"> | |
/// The position relative to the element at which to insert the HTML. | |
/// </param> | |
/// <param name="text" type="String" locid="WinJS.Utilities.insertAdjacentHTML_p:text"> | |
/// The value to be provided to insertAdjacentHTML. | |
/// </param> | |
/// </signature> | |
element.insertAdjacentHTML(position, text); | |
}; | |
var msApp = global.MSApp; | |
if (msApp) { | |
setInnerHTMLUnsafe = function (element, text) { | |
/// <signature helpKeyword="WinJS.Utilities.setInnerHTMLUnsafe"> | |
/// <summary locid="WinJS.Utilities.setInnerHTMLUnsafe"> | |
/// Sets the innerHTML property of the specified element to the specified text. | |
/// </summary> | |
/// <param name='element' type='HTMLElement' locid="WinJS.Utilities.setInnerHTMLUnsafe_p:element"> | |
/// The element on which the innerHTML property is to be set. | |
/// </param> | |
/// <param name='text' type="String" locid="WinJS.Utilities.setInnerHTMLUnsafe_p:text"> | |
/// The value to be set to the innerHTML property. | |
/// </param> | |
/// </signature> | |
msApp.execUnsafeLocalFunction(function () { | |
element.innerHTML = text; | |
}); | |
}; | |
setOuterHTMLUnsafe = function (element, text) { | |
/// <signature helpKeyword="WinJS.Utilities.setOuterHTMLUnsafe"> | |
/// <summary locid="WinJS.Utilities.setOuterHTMLUnsafe"> | |
/// Sets the outerHTML property of the specified element to the specified text | |
/// in the context of msWWA.execUnsafeLocalFunction. | |
/// </summary> | |
/// <param name="element" type="HTMLElement" locid="WinJS.Utilities.setOuterHTMLUnsafe_p:element"> | |
/// The element on which the outerHTML property is to be set. | |
/// </param> | |
/// <param name="text" type="String" locid="WinJS.Utilities.setOuterHTMLUnsafe_p:text"> | |
/// The value to be set to the outerHTML property. | |
/// </param> | |
/// </signature> | |
msApp.execUnsafeLocalFunction(function () { | |
element.outerHTML = text; | |
}); | |
}; | |
insertAdjacentHTMLUnsafe = function (element, position, text) { | |
/// <signature helpKeyword="WinJS.Utilities.insertAdjacentHTMLUnsafe"> | |
/// <summary locid="WinJS.Utilities.insertAdjacentHTMLUnsafe"> | |
/// Calls insertAdjacentHTML on the specified element in the context | |
/// of msWWA.execUnsafeLocalFunction. | |
/// </summary> | |
/// <param name="element" type="HTMLElement" locid="WinJS.Utilities.insertAdjacentHTMLUnsafe_p:element"> | |
/// The element on which insertAdjacentHTML is to be called. | |
/// </param> | |
/// <param name="position" type="String" locid="WinJS.Utilities.insertAdjacentHTMLUnsafe_p:position"> | |
/// The position relative to the element at which to insert the HTML. | |
/// </param> | |
/// <param name="text" type="String" locid="WinJS.Utilities.insertAdjacentHTMLUnsafe_p:text"> | |
/// Value to be provided to insertAdjacentHTML. | |
/// </param> | |
/// </signature> | |
msApp.execUnsafeLocalFunction(function () { | |
element.insertAdjacentHTML(position, text); | |
}); | |
}; | |
} | |
else if (global.msIsStaticHTML) { | |
var check = function (str) { | |
if (!global.msIsStaticHTML(str)) { | |
throw new WinJS.ErrorFromName("WinJS.Utitilies.NonStaticHTML", strings.nonStaticHTML); | |
} | |
} | |
// If we ever get isStaticHTML we can attempt to recreate the behavior we have in the local | |
// compartment, in the mean-time all we can do is sanitize the input. | |
// | |
setInnerHTML = function (element, text) { | |
/// <signature helpKeyword="WinJS.Utilities.setInnerHTML"> | |
/// <summary locid="WinJS.Utilities.msIsStaticHTML.setInnerHTML"> | |
/// Sets the innerHTML property of a element to the specified text | |
/// if it passes a msIsStaticHTML check. | |
/// </summary> | |
/// <param name="element" type="HTMLElement" locid="WinJS.Utilities.msIsStaticHTML.setInnerHTML_p:element"> | |
/// The element on which the innerHTML property is to be set. | |
/// </param> | |
/// <param name="text" type="String" locid="WinJS.Utilities.msIsStaticHTML.setInnerHTML_p:text"> | |
/// The value to be set to the innerHTML property. | |
/// </param> | |
/// </signature> | |
check(text); | |
element.innerHTML = text; | |
}; | |
setOuterHTML = function (element, text) { | |
/// <signature helpKeyword="WinJS.Utilities.setOuterHTML"> | |
/// <summary locid="WinJS.Utilities.msIsStaticHTML.setOuterHTML"> | |
/// Sets the outerHTML property of a element to the specified text | |
/// if it passes a msIsStaticHTML check. | |
/// </summary> | |
/// <param name="element" type="HTMLElement" locid="WinJS.Utilities.msIsStaticHTML.setOuterHTML_p:element"> | |
/// The element on which the outerHTML property is to be set. | |
/// </param> | |
/// <param name="text" type="String" locid="WinJS.Utilities.msIsStaticHTML.setOuterHTML_p:text"> | |
/// The value to be set to the outerHTML property. | |
/// </param> | |
/// </signature> | |
check(text); | |
element.outerHTML = text; | |
}; | |
insertAdjacentHTML = function (element, position, text) { | |
/// <signature helpKeyword="WinJS.Utilities.insertAdjacentHTML"> | |
/// <summary locid="WinJS.Utilities.msIsStaticHTML.insertAdjacentHTML"> | |
/// Calls insertAdjacentHTML on the element if it passes | |
/// a msIsStaticHTML check. | |
/// </summary> | |
/// <param name="element" type="HTMLElement" locid="WinJS.Utilities.msIsStaticHTML.insertAdjacentHTML_p:element"> | |
/// The element on which insertAdjacentHTML is to be called. | |
/// </param> | |
/// <param name="position" type="String" locid="WinJS.Utilities.msIsStaticHTML.insertAdjacentHTML_p:position"> | |
/// The position relative to the element at which to insert the HTML. | |
/// </param> | |
/// <param name="text" type="String" locid="WinJS.Utilities.msIsStaticHTML.insertAdjacentHTML_p:text"> | |
/// The value to be provided to insertAdjacentHTML. | |
/// </param> | |
/// </signature> | |
check(text); | |
element.insertAdjacentHTML(position, text); | |
}; | |
} | |
WinJS.Namespace.define("WinJS.Utilities", { | |
setInnerHTML: setInnerHTML, | |
setInnerHTMLUnsafe: setInnerHTMLUnsafe, | |
setOuterHTML: setOuterHTML, | |
setOuterHTMLUnsafe: setOuterHTMLUnsafe, | |
insertAdjacentHTML: insertAdjacentHTML, | |
insertAdjacentHTMLUnsafe: insertAdjacentHTMLUnsafe | |
}); | |
}(this)); | |
(function getWinJSStringInit() { | |
"use strict"; | |
var appxVersion = "Microsoft.WinJS.1.0"; | |
var developerPrefix = "Developer."; | |
if (appxVersion.indexOf(developerPrefix) === 0) { | |
appxVersion = appxVersion.substring(developerPrefix.length); | |
} | |
WinJS.Namespace.define("WinJS.Resources", { | |
_getWinJSString: function (id) { | |
return WinJS.Resources.getString("ms-resource://" + appxVersion + "/" + id); | |
} | |
}); | |
}(this)); | |
(function controlInit(global, WinJS, undefined) { | |
"use strict"; | |
// not supported in WebWorker | |
if (!global.document) { | |
return; | |
} | |
var DOMEventMixin = { | |
_domElement: null, | |
addEventListener: function (type, listener, useCapture) { | |
/// <signature helpKeyword="WinJS.UI.DOMEventMixin.addEventListener"> | |
/// <summary locid="WinJS.UI.DOMEventMixin.addEventListener"> | |
/// Adds an event listener to the control. | |
/// </summary> | |
/// <param name="type" type="String" locid="WinJS.UI.DOMEventMixin.addEventListener_p:type"> | |
/// The type (name) of the event. | |
/// </param> | |
/// <param name="listener" type="Function" locid="WinJS.UI.DOMEventMixin.addEventListener_p:listener"> | |
/// The listener to invoke when the event gets raised. | |
/// </param> | |
/// <param name="useCapture" type="Boolean" locid="WinJS.UI.DOMEventMixin.addEventListener_p:useCapture"> | |
/// true to initiate capture; otherwise, false. | |
/// </param> | |
/// </signature> | |
(this.element || this._domElement).addEventListener(type, listener, useCapture || false); | |
}, | |
dispatchEvent: function (type, eventProperties) { | |
/// <signature helpKeyword="WinJS.UI.DOMEventMixin.dispatchEvent"> | |
/// <summary locid="WinJS.UI.DOMEventMixin.dispatchEvent"> | |
/// Raises an event of the specified type, adding the specified additional properties. | |
/// </summary> | |
/// <param name="type" type="String" locid="WinJS.UI.DOMEventMixin.dispatchEvent_p:type"> | |
/// The type (name) of the event. | |
/// </param> | |
/// <param name="eventProperties" type="Object" locid="WinJS.UI.DOMEventMixin.dispatchEvent_p:eventProperties"> | |
/// The set of additional properties to be attached to the event object when the event is raised. | |
/// </param> | |
/// <returns type="Boolean" locid="WinJS.UI.DOMEventMixin.dispatchEvent_returnValue"> | |
/// true if preventDefault was called on the event, otherwise false. | |
/// </returns> | |
/// </signature> | |
var eventValue = document.createEvent("Event"); | |
eventValue.initEvent(type, false, false); | |
eventValue.detail = eventProperties; | |
if (typeof eventProperties === "object") { | |
Object.keys(eventProperties).forEach(function (key) { | |
eventValue[key] = eventProperties[key]; | |
}); | |
} | |
return (this.element || this._domElement).dispatchEvent(eventValue); | |
}, | |
removeEventListener: function (type, listener, useCapture) { | |
/// <signature helpKeyword="WinJS.UI.DOMEventMixin.removeEventListener"> | |
/// <summary locid="WinJS.UI.DOMEventMixin.removeEventListener"> | |
/// Removes an event listener from the control. | |
/// </summary> | |
/// <param name="type" type="String" locid="WinJS.UI.DOMEventMixin.removeEventListener_p:type"> | |
/// The type (name) of the event. | |
/// </param> | |
/// <param name="listener" type="Function" locid="WinJS.UI.DOMEventMixin.removeEventListener_p:listener"> | |
/// The listener to remove. | |
/// </param> | |
/// <param name="useCapture" type="Boolean" locid="WinJS.UI.DOMEventMixin.removeEventListener_p:useCapture"> | |
/// true to initiate capture; otherwise, false. | |
/// </param> | |
/// </signature> | |
(this.element || this._domElement).removeEventListener(type, listener, useCapture || false); | |
} | |
}; | |
function setOptions(control, options) { | |
/// <signature helpKeyword="WinJS.UI.DOMEventMixin.setOptions"> | |
/// <summary locid="WinJS.UI.DOMEventMixin.setOptions"> | |
/// Adds the set of declaratively specified options (properties and events) to the specified control. | |
/// If name of the options property begins with "on", the property value is a function and the control | |
/// supports addEventListener. The setOptions method calls the addEventListener method on the control. | |
/// </summary> | |
/// <param name="control" type="Object" domElement="false" locid="WinJS.UI.DOMEventMixin.setOptions_p:control"> | |
/// The control on which the properties and events are to be applied. | |
/// </param> | |
/// <param name="options" type="Object" domElement="false" locid="WinJS.UI.DOMEventMixin.setOptions_p:options"> | |
/// The set of options that are specified declaratively. | |
/// </param> | |
/// </signature> | |
_setOptions(control, options); | |
}; | |
function _setOptions(control, options, eventsOnly) { | |
if (typeof options === "object") { | |
var keys = Object.keys(options); | |
for (var i = 0, len = keys.length; i < len; i++) { | |
var key = keys[i]; | |
var value = options[key]; | |
if (key.length > 2) { | |
var ch1 = key[0]; | |
var ch2 = key[1]; | |
if ((ch1 === 'o' || ch1 === 'O') && (ch2 === 'n' || ch2 === 'N')) { | |
if (typeof value === "function") { | |
if (control.addEventListener) { | |
control.addEventListener(key.substr(2), value); | |
continue; | |
} | |
} | |
} | |
} | |
if (!eventsOnly) { | |
control[key] = value; | |
} | |
} | |
} | |
}; | |
WinJS.Namespace.define("WinJS.UI", { | |
DOMEventMixin: DOMEventMixin, | |
setOptions: setOptions, | |
_setOptions: _setOptions | |
}); | |
})(this, WinJS); | |
(function declarativeControlsInit(global, WinJS, undefined) { | |
"use strict"; | |
// not supported in WebWorker | |
if (!global.document) { | |
return; | |
} | |
var strings = { | |
get errorActivatingControl() { return WinJS.Resources._getWinJSString("base/errorActivatingControl").value; }, | |
}; | |
var markSupportedForProcessing = WinJS.Utilities.markSupportedForProcessing; | |
var requireSupportedForProcessing = WinJS.Utilities.requireSupportedForProcessing; | |
var processedAllCalled = false; | |
function createSelect(element) { | |
var result = function select(selector) { | |
/// <signature helpKeyword="WinJS.UI.select.createSelect"> | |
/// <summary locid="WinJS.UI.select.createSelect"> | |
/// Walks the DOM tree from the given element to the root of the document, whenever | |
/// a selector scope is encountered select performs a lookup within that scope for | |
/// the given selector string. The first matching element is returned. | |
/// </summary> | |
/// <param name="selector" type="String" locid="WinJS.UI.select.createSelect_p:selector">The selector string.</param> | |
/// <returns type="HTMLElement" domElement="true" locid="WinJS.UI.select.createSelect_returnValue">The target element, if found.</returns> | |
/// </signature> | |
var current = element; | |
var selected; | |
while (current) { | |
if (current.msParentSelectorScope) { | |
var scope = current.parentNode; | |
if (scope) { | |
// In order to be inclusive of the scope in the lookup we do a QSA across | |
// the parent of the scope and see if this scope is in the list. | |
var scopeParent = scope.parentNode; | |
if (scopeParent && -1 !== Array.prototype.indexOf.call(scopeParent.querySelectorAll(selector), scope)) { | |
selected = scope; | |
} | |
if (selected = selected || scope.querySelector(selector)) { | |
break; | |
} | |
} | |
} | |
current = current.parentNode; | |
} | |
return selected || document.querySelector(selector); | |
} | |
return markSupportedForProcessing(result); | |
} | |
function activate(element, handler) { | |
return new WinJS.Promise(function activate2(complete, error) { | |
try { | |
var options; | |
var optionsAttribute = element.getAttribute("data-win-options"); | |
if (optionsAttribute) { | |
options = WinJS.UI.optionsParser(optionsAttribute, global, { | |
select: createSelect(element) | |
}); | |
} | |
var ctl; | |
var count = 1; | |
// handler is required to call complete if it takes that parameter | |
// | |
if (handler.length > 2) { | |
count++; | |
} | |
var checkComplete = function checkComplete() { | |
count--; | |
if (count === 0) { | |
element.winControl = element.winControl || ctl; | |
complete(ctl); | |
} | |
}; | |
// async exceptions from the handler get dropped on the floor... | |
// | |
ctl = new handler(element, options, checkComplete); | |
checkComplete(); | |
} | |
catch (err) { | |
WinJS.log && WinJS.log(WinJS.Resources._formatString(strings.errorActivatingControl, err && err.message), "winjs controls", "error"); | |
error(err); | |
} | |
}); | |
}; | |
function processAllImpl(rootElement) { | |
return new WinJS.Promise(function processAllImpl2(complete, error) { | |
msWriteProfilerMark("WinJS.UI:processAll,StartTM"); | |
rootElement = rootElement || document.body; | |
var pending = 0; | |
var selector = "[data-win-control]"; | |
var allElements = rootElement.querySelectorAll(selector); | |
var elements = []; | |
if (getControlHandler(rootElement)) { | |
elements.push(rootElement); | |
} | |
for (var i = 0, len = allElements.length; i < len; i++) { | |
elements.push(allElements[i]); | |
} | |
// bail early if there is nothing to process | |
// | |
if (elements.length === 0) { complete(rootElement); return; } | |
var checkAllComplete = function () { | |
pending = pending - 1; | |
if (pending < 0) { | |
msWriteProfilerMark("WinJS.UI:processAll,StopTM"); | |
complete(rootElement); | |
} | |
} | |
// First go through and determine which elements to activate | |
// | |
var controls = new Array(elements.length); | |
for (var i = 0, len = elements.length; i < len; i++) { | |
var element = elements[i]; | |
var control; | |
var instance = element.winControl; | |
if (instance) { | |
control = instance.constructor; | |
// already activated, don't need to add to controls array | |
} | |
else { | |
controls[i] = control = getControlHandler(element); | |
} | |
if (control && control.isDeclarativeControlContainer) { | |
i += element.querySelectorAll(selector).length; | |
} | |
} | |
// Now go through and activate those | |
// | |
msWriteProfilerMark("WinJS.UI:processAllActivateControls,StartTM"); | |
for (var i = 0, len = elements.length; i < len; i++) { | |
var ctl = controls[i]; | |
if (ctl) { | |
pending++; | |
activate(elements[i], ctl).then(checkAllComplete, error); | |
} | |
} | |
msWriteProfilerMark("WinJS.UI:processAllActivateControls,StopTM"); | |
checkAllComplete(); | |
}); | |
}; | |
function getControlHandler(element) { | |
if (element.getAttribute) { | |
var evaluator = element.getAttribute("data-win-control"); | |
if (evaluator) { | |
return WinJS.Utilities._getMemberFiltered(evaluator.trim(), global, requireSupportedForProcessing); | |
} | |
} | |
}; | |
WinJS.Namespace.define("WinJS.UI", { | |
scopedSelect: function (selector, element) { | |
/// <signature helpKeyword="WinJS.UI.scopedSelect"> | |
/// <summary locid="WinJS.UI.scopedSelect"> | |
/// Walks the DOM tree from the given element to the root of the document, whenever | |
/// a selector scope is encountered select performs a lookup within that scope for | |
/// the given selector string. The first matching element is returned. | |
/// </summary> | |
/// <param name="selector" type="String" locid="WinJS.UI.scopedSelect_p:selector">The selector string.</param> | |
/// <returns type="HTMLElement" domElement="true" locid="WinJS.UI.scopedSelect_returnValue">The target element, if found.</returns> | |
/// </signature> | |
return createSelect(element)(selector); | |
}, | |
processAll: function (rootElement) { | |
/// <signature helpKeyword="WinJS.UI.processAll"> | |
/// <summary locid="WinJS.UI.processAll"> | |
/// Applies declarative control binding to all elements, starting at the specified root element. | |
/// </summary> | |
/// <param name="rootElement" type="Object" domElement="true" locid="WinJS.UI.processAll_p:rootElement"> | |
/// The element at which to start applying the binding. If this parameter is not specified, the binding is applied to the entire document. | |
/// </param> | |
/// <returns type="WinJS.Promise" locid="WinJS.UI.processAll_returnValue"> | |
/// A promise that is fulfilled when binding has been applied to all the controls. | |
/// </returns> | |
/// </signature> | |
if (!processedAllCalled) { | |
return WinJS.Utilities.ready().then(function () { | |
processedAllCalled = true; | |
return processAllImpl(rootElement); | |
}); | |
} | |
else { | |
return processAllImpl(rootElement); | |
} | |
}, | |
process: function (element) { | |
/// <signature helpKeyword="WinJS.UI.process"> | |
/// <summary locid="WinJS.UI.process"> | |
/// Applies declarative control binding to the specified element. | |
/// </summary> | |
/// <param name="element" type="Object" domElement="true" locid="WinJS.UI.process_p:element"> | |
/// The element to bind. | |
/// </param> | |
/// <returns type="WinJS.Promise" locid="WinJS.UI.process_returnValue"> | |
/// A promise that is fulfilled after the control is activated. The value of the | |
/// promise is the control that is attached to element. | |
/// </returns> | |
/// </signature> | |
if (element && element.winControl) { | |
return WinJS.Promise.as(element.winControl); | |
} | |
var handler = getControlHandler(element); | |
if (!handler) { | |
return WinJS.Promise.as(); // undefined, no handler | |
} | |
else { | |
return activate(element, handler); | |
} | |
} | |
}); | |
})(this, WinJS); | |
(function elementListUtilities(global, WinJS, undefined) { | |
"use strict"; | |
// not supported in WebWorker | |
if (!global.document) { | |
return; | |
} | |
var QueryCollection = WinJS.Class.derive(Array, function (items) { | |
/// <signature helpKeyword="WinJS.Utilities.QueryCollection"> | |
/// <summary locid="WinJS.Utilities.QueryCollection"> | |
/// Represents the result of a query selector, and provides | |
/// various operations that perform actions over the elements of | |
/// the collection. | |
/// </summary> | |
/// <param name="items" locid="WinJS.Utilities.QueryCollection_p:items"> | |
/// The items resulting from the query. | |
/// </param> | |
/// </signature> | |
if (items) { | |
this.include(items); | |
} | |
}, { | |
forEach: function (callbackFn, thisArg) { | |
/// <signature helpKeyword="WinJS.Utilities.QueryCollection.forEach"> | |
/// <summary locid="WinJS.Utilities.QueryCollection.forEach"> | |
/// Performs an action on each item in the QueryCollection | |
/// </summary> | |
/// <param name="callbackFn" type="function(value, Number index, traversedObject)" locid="WinJS.Utilities.QueryCollection.forEach_p:callbackFn"> | |
/// Action to perform on each item. | |
/// </param> | |
/// <param name="thisArg" isOptional="true" type="function(value, Number index, traversedObject)" locid="WinJS.Utilities.QueryCollection.forEach_p:thisArg"> | |
/// Argument to bind to callbackFn | |
/// </param> | |
/// <returns type="WinJS.Utilities.QueryCollection" locid="WinJS.Utilities.QueryCollection.forEach_returnValue"> | |
/// Returns the QueryCollection | |
/// </returns> | |
/// </signature> | |
Array.prototype.forEach.apply(this, [callbackFn, thisArg]); | |
return this; | |
}, | |
get: function (index) { | |
/// <signature helpKeyword="WinJS.Utilities.QueryCollection.get"> | |
/// <summary locid="WinJS.Utilities.QueryCollection.get"> | |
/// Gets an item from the QueryCollection. | |
/// </summary> | |
/// <param name="index" type="Number" locid="WinJS.Utilities.QueryCollection.get_p:index"> | |
/// The index of the item to return. | |
/// </param> | |
/// <returns type="Object" locid="WinJS.Utilities.QueryCollection.get_returnValue"> | |
/// A single item from the collection. | |
/// </returns> | |
/// </signature> | |
return this[index]; | |
}, | |
setAttribute: function (name, value) { | |
/// <signature helpKeyword="WinJS.Utilities.QueryCollection.setAttribute"> | |
/// <summary locid="WinJS.Utilities.QueryCollection.setAttribute"> | |
/// Sets an attribute value on all the items in the collection. | |
/// </summary> | |
/// <param name="name" type="String" locid="WinJS.Utilities.QueryCollection.setAttribute_p:name"> | |
/// The name of the attribute to be set. | |
/// </param> | |
/// <param name="value" type="String" locid="WinJS.Utilities.QueryCollection.setAttribute_p:value"> | |
/// The value of the attribute to be set. | |
/// </param> | |
/// <returns type="WinJS.Utilities.QueryCollection" locid="WinJS.Utilities.QueryCollection.setAttribute_returnValue"> | |
/// This QueryCollection object. | |
/// </returns> | |
/// </signature> | |
this.forEach(function (item) { | |
item.setAttribute(name, value); | |
}); | |
return this; | |
}, | |
getAttribute: function (name) { | |
/// <signature helpKeyword="WinJS.Utilities.QueryCollection.getAttribute"> | |
/// <summary locid="WinJS.Utilities.QueryCollection.getAttribute"> | |
/// Gets an attribute value from the first element in the collection. | |
/// </summary> | |
/// <param name="name" type="String" locid="WinJS.Utilities.QueryCollection.getAttribute_p:name"> | |
/// The name of the attribute. | |
/// </param> | |
/// <returns type="String" locid="WinJS.Utilities.QueryCollection.getAttribute_returnValue"> | |
/// The value of the attribute. | |
/// </returns> | |
/// </signature> | |
if (this.length > 0) { | |
return this[0].getAttribute(name); | |
} | |
}, | |
addClass: function (name) { | |
/// <signature helpKeyword="WinJS.Utilities.QueryCollection.addClass"> | |
/// <summary locid="WinJS.Utilities.QueryCollection.addClass"> | |
/// Adds the specified class to all the elements in the collection. | |
/// </summary> | |
/// <param name="name" type="String" locid="WinJS.Utilities.QueryCollection.addClass_p:name"> | |
/// The name of the class to add. | |
/// </param> | |
/// <returns type="WinJS.Utilities.QueryCollection" locid="WinJS.Utilities.QueryCollection.addClass_returnValue"> | |
/// This QueryCollection object. | |
/// </returns> | |
/// </signature> | |
this.forEach(function (item) { | |
WinJS.Utilities.addClass(item, name); | |
}); | |
return this; | |
}, | |
hasClass: function (name) { | |
/// <signature helpKeyword="WinJS.Utilities.QueryCollection.hasClass"> | |
/// <summary locid="WinJS.Utilities.QueryCollection.hasClass"> | |
/// Determines whether the specified class exists on the first element of the collection. | |
/// </summary> | |
/// <param name="name" type="String" locid="WinJS.Utilities.QueryCollection.hasClass_p:name"> | |
/// The name of the class. | |
/// </param> | |
/// <returns type="Boolean" locid="WinJS.Utilities.QueryCollection.hasClass_returnValue"> | |
/// true if the element has the specified class; otherwise, false. | |
/// </returns> | |
/// </signature> | |
if (this.length > 0) { | |
return WinJS.Utilities.hasClass(this[0], name); | |
} | |
return false; | |
}, | |
removeClass: function (name) { | |
/// <signature helpKeyword="WinJS.Utilities.QueryCollection.removeClass"> | |
/// <summary locid="WinJS.Utilities.QueryCollection.removeClass"> | |
/// Removes the specified class from all the elements in the collection. | |
/// </summary> | |
/// <param name="name" type="String" locid="WinJS.Utilities.QueryCollection.removeClass_p:name"> | |
/// The name of the class to be removed. | |
/// </param> | |
/// <returns type="WinJS.Utilities.QueryCollection" locid="WinJS.Utilities.QueryCollection.removeClass_returnValue"> | |
/// This QueryCollection object. | |
/// </returns> | |
/// </signature> | |
this.forEach(function (item) { | |
WinJS.Utilities.removeClass(item, name); | |
}); | |
return this; | |
}, | |
toggleClass: function (name) { | |
/// <signature helpKeyword="WinJS.Utilities.QueryCollection.toggleClass">> | |
/// <summary locid="WinJS.Utilities.QueryCollection.toggleClass"> | |
/// Toggles (adds or removes) the specified class on all the elements in the collection. | |
/// If the class is present, it is removed; if it is absent, it is added. | |
/// </summary> | |
/// <param name="name" type="String" locid="WinJS.Utilities.QueryCollection.toggleClass_p:name"> | |
/// The name of the class to be toggled. | |
/// </param> | |
/// <returns type="WinJS.Utilities.QueryCollection" locid="WinJS.Utilities.QueryCollection.toggleClass_returnValue"> | |
/// This QueryCollection object. | |
/// </returns> | |
/// </signature> | |
this.forEach(function (item) { | |
WinJS.Utilities.toggleClass(item, name); | |
}); | |
return this; | |
}, | |
listen: function (eventType, listener, capture) { | |
/// <signature helpKeyword="WinJS.Utilities.QueryCollection.listen"> | |
/// <summary locid="WinJS.Utilities.QueryCollection.listen"> | |
/// Registers the listener for the specified event on all the elements in the collection. | |
/// </summary> | |
/// <param name="eventType" type="String" locid="WinJS.Utilities.QueryCollection.listen_p:eventType"> | |
/// The name of the event. | |
/// </param> | |
/// <param name="listener" type="Function" locid="WinJS.Utilities.QueryCollection.listen_p:listener"> | |
/// The event handler function to be called when the event occurs. | |
/// </param> | |
/// <param name="capture" type="Boolean" locid="WinJS.Utilities.QueryCollection.listen_p:capture"> | |
/// true if capture == true is to be passed to addEventListener; otherwise, false. | |
/// </param> | |
/// <returns type="WinJS.Utilities.QueryCollection" locid="WinJS.Utilities.QueryCollection.listen_returnValue"> | |
/// This QueryCollection object. | |
/// </returns> | |
/// </signature> | |
this.forEach(function (item) { | |
item.addEventListener(eventType, listener, capture); | |
}); | |
return this; | |
}, | |
removeEventListener: function (eventType, listener, capture) { | |
/// <signature helpKeyword="WinJS.Utilities.QueryCollection.removeEventListener"> | |
/// <summary locid="WinJS.Utilities.QueryCollection.removeEventListener"> | |
/// Unregisters the listener for the specified event on all the elements in the collection. | |
/// </summary> | |
/// <param name="eventType" type="String" locid="WinJS.Utilities.QueryCollection.removeEventListener_p:eventType"> | |
/// The name of the event. | |
/// </param> | |
/// <param name="listener" type="Function" locid="WinJS.Utilities.QueryCollection.removeEventListener_p:listener"> | |
/// The event handler function. | |
/// </param> | |
/// <param name="capture" type="Boolean" locid="WinJS.Utilities.QueryCollection.removeEventListener_p:capture"> | |
/// true if capture == true; otherwise, false. | |
/// </param> | |
/// <returns type="WinJS.Utilities.QueryCollection" locid="WinJS.Utilities.QueryCollection.removeEventListener_returnValue"> | |
/// This QueryCollection object. | |
/// </returns> | |
/// </signature> | |
this.forEach(function (item) { | |
item.removeEventListener(eventType, listener, capture); | |
}); | |
return this; | |
}, | |
setStyle: function (name, value) { | |
/// <signature helpKeyword="WinJS.Utilities.QueryCollection.setStyle"> | |
/// <summary locid="WinJS.Utilities.QueryCollection.setStyle"> | |
/// Sets the specified style property for all the elements in the collection. | |
/// </summary> | |
/// <param name="name" type="String" locid="WinJS.Utilities.QueryCollection.setStyle_p:name"> | |
/// The name of the style property. | |
/// </param> | |
/// <param name="value" type="String" locid="WinJS.Utilities.QueryCollection.setStyle_p:value"> | |
/// The value for the property. | |
/// </param> | |
/// <returns type="WinJS.Utilities.QueryCollection" locid="WinJS.Utilities.QueryCollection.setStyle_returnValue"> | |
/// This QueryCollection object. | |
/// </returns> | |
/// </signature> | |
this.forEach(function (item) { | |
item.style[name] = value; | |
}); | |
return this; | |
}, | |
clearStyle: function (name) { | |
/// <signature helpKeyword="WinJS.Utilities.QueryCollection.clearStyle"> | |
/// <summary locid="WinJS.Utilities.QueryCollection.clearStyle"> | |
/// Clears the specified style property for all the elements in the collection. | |
/// </summary> | |
/// <param name="name" type="String" locid="WinJS.Utilities.QueryCollection.clearStyle_p:name"> | |
/// The name of the style property to be cleared. | |
/// </param> | |
/// <returns type="WinJS.Utilities.QueryCollection" locid="WinJS.Utilities.QueryCollection.clearStyle_returnValue"> | |
/// This QueryCollection object. | |
/// </returns> | |
/// </signature> | |
this.forEach(function (item) { | |
item.style[name] = ""; | |
}); | |
return this; | |
}, | |
query: function (query) { | |
/// <signature helpKeyword="WinJS.Utilities.QueryCollection.query"> | |
/// <summary locid="WinJS.Utilities.QueryCollection.query"> | |