WinJS base.js
/// <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; | |