UNPKG

twreporter-react

Version:

React-Redux site for The Reporter Foundation in Taiwan

1,417 lines (1,223 loc) 178 kB
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. ;(function (undefined) { var objectTypes = { 'boolean': false, 'function': true, 'object': true, 'number': false, 'string': false, 'undefined': false }; var root = (objectTypes[typeof window] && window) || this, freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports, freeModule = objectTypes[typeof module] && module && !module.nodeType && module, moduleExports = freeModule && freeModule.exports === freeExports && freeExports, freeGlobal = objectTypes[typeof global] && global; if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { root = freeGlobal; } var Rx = { internals: {}, config: { Promise: root.Promise, }, helpers: { } }; // Defaults var noop = Rx.helpers.noop = function () { }, notDefined = Rx.helpers.notDefined = function (x) { return typeof x === 'undefined'; }, isScheduler = Rx.helpers.isScheduler = function (x) { return x instanceof Rx.Scheduler; }, identity = Rx.helpers.identity = function (x) { return x; }, pluck = Rx.helpers.pluck = function (property) { return function (x) { return x[property]; }; }, just = Rx.helpers.just = function (value) { return function () { return value; }; }, defaultNow = Rx.helpers.defaultNow = Date.now, defaultComparer = Rx.helpers.defaultComparer = function (x, y) { return isEqual(x, y); }, defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); }, defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); }, defaultError = Rx.helpers.defaultError = function (err) { throw err; }, isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.then === 'function'; }, asArray = Rx.helpers.asArray = function () { return Array.prototype.slice.call(arguments); }, not = Rx.helpers.not = function (a) { return !a; }, isFunction = Rx.helpers.isFunction = (function () { var isFn = function (value) { return typeof value == 'function' || false; } // fallback for older versions of Chrome and Safari if (isFn(/x/)) { isFn = function(value) { return typeof value == 'function' && toString.call(value) == '[object Function]'; }; } return isFn; }()); // Errors var sequenceContainsNoElements = 'Sequence contains no elements.'; var argumentOutOfRange = 'Argument out of range'; var objectDisposed = 'Object has been disposed'; function checkDisposed() { if (this.isDisposed) { throw new Error(objectDisposed); } } Rx.config.longStackSupport = false; var hasStacks = false; try { throw new Error(); } catch (e) { hasStacks = !!e.stack; } // All code after this point will be filtered from stack traces reported by RxJS var rStartingLine = captureLine(), rFileName; var STACK_JUMP_SEPARATOR = "From previous event:"; function makeStackTraceLong(error, observable) { // If possible, transform the error stack trace by removing Node and RxJS // cruft, then concatenating with the stack trace of `observable`. if (hasStacks && observable.stack && typeof error === "object" && error !== null && error.stack && error.stack.indexOf(STACK_JUMP_SEPARATOR) === -1 ) { var stacks = []; for (var o = observable; !!o; o = o.source) { if (o.stack) { stacks.unshift(o.stack); } } stacks.unshift(error.stack); var concatedStacks = stacks.join("\n" + STACK_JUMP_SEPARATOR + "\n"); error.stack = filterStackString(concatedStacks); } } function filterStackString(stackString) { var lines = stackString.split("\n"), desiredLines = []; for (var i = 0, len = lines.length; i < len; i++) { var line = lines[i]; if (!isInternalFrame(line) && !isNodeFrame(line) && line) { desiredLines.push(line); } } return desiredLines.join("\n"); } function isInternalFrame(stackLine) { var fileNameAndLineNumber = getFileNameAndLineNumber(stackLine); if (!fileNameAndLineNumber) { return false; } var fileName = fileNameAndLineNumber[0], lineNumber = fileNameAndLineNumber[1]; return fileName === rFileName && lineNumber >= rStartingLine && lineNumber <= rEndingLine; } function isNodeFrame(stackLine) { return stackLine.indexOf("(module.js:") !== -1 || stackLine.indexOf("(node.js:") !== -1; } function captureLine() { if (!hasStacks) { return; } try { throw new Error(); } catch (e) { var lines = e.stack.split("\n"); var firstLine = lines[0].indexOf("@") > 0 ? lines[1] : lines[2]; var fileNameAndLineNumber = getFileNameAndLineNumber(firstLine); if (!fileNameAndLineNumber) { return; } rFileName = fileNameAndLineNumber[0]; return fileNameAndLineNumber[1]; } } function getFileNameAndLineNumber(stackLine) { // Named functions: "at functionName (filename:lineNumber:columnNumber)" var attempt1 = /at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine); if (attempt1) { return [attempt1[1], Number(attempt1[2])]; } // Anonymous functions: "at filename:lineNumber:columnNumber" var attempt2 = /at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine); if (attempt2) { return [attempt2[1], Number(attempt2[2])]; } // Firefox style: "function@filename:lineNumber or @filename:lineNumber" var attempt3 = /.*@(.+):(\d+)$/.exec(stackLine); if (attempt3) { return [attempt3[1], Number(attempt3[2])]; } } // Shim in iterator support var $iterator$ = (typeof Symbol === 'function' && Symbol.iterator) || '_es6shim_iterator_'; // Bug for mozilla version if (root.Set && typeof new root.Set()['@@iterator'] === 'function') { $iterator$ = '@@iterator'; } var doneEnumerator = Rx.doneEnumerator = { done: true, value: undefined }; var isIterable = Rx.helpers.isIterable = function (o) { return o[$iterator$] !== undefined; } var isArrayLike = Rx.helpers.isArrayLike = function (o) { return o && o.length !== undefined; } Rx.helpers.iterator = $iterator$; var bindCallback = Rx.internals.bindCallback = function (func, thisArg, argCount) { if (typeof thisArg === 'undefined') { return func; } switch(argCount) { case 0: return function() { return func.call(thisArg) }; case 1: return function(arg) { return func.call(thisArg, arg); } case 2: return function(value, index) { return func.call(thisArg, value, index); }; case 3: return function(value, index, collection) { return func.call(thisArg, value, index, collection); }; } return function() { return func.apply(thisArg, arguments); }; }; /** Used to determine if values are of the language type Object */ var dontEnums = ['toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'], dontEnumsLength = dontEnums.length; /** `Object#toString` result shortcuts */ var argsClass = '[object Arguments]', arrayClass = '[object Array]', boolClass = '[object Boolean]', dateClass = '[object Date]', errorClass = '[object Error]', funcClass = '[object Function]', numberClass = '[object Number]', objectClass = '[object Object]', regexpClass = '[object RegExp]', stringClass = '[object String]'; var toString = Object.prototype.toString, hasOwnProperty = Object.prototype.hasOwnProperty, supportsArgsClass = toString.call(arguments) == argsClass, // For less <IE9 && FF<4 supportNodeClass, errorProto = Error.prototype, objectProto = Object.prototype, stringProto = String.prototype, propertyIsEnumerable = objectProto.propertyIsEnumerable; try { supportNodeClass = !(toString.call(document) == objectClass && !({ 'toString': 0 } + '')); } catch (e) { supportNodeClass = true; } var nonEnumProps = {}; nonEnumProps[arrayClass] = nonEnumProps[dateClass] = nonEnumProps[numberClass] = { 'constructor': true, 'toLocaleString': true, 'toString': true, 'valueOf': true }; nonEnumProps[boolClass] = nonEnumProps[stringClass] = { 'constructor': true, 'toString': true, 'valueOf': true }; nonEnumProps[errorClass] = nonEnumProps[funcClass] = nonEnumProps[regexpClass] = { 'constructor': true, 'toString': true }; nonEnumProps[objectClass] = { 'constructor': true }; var support = {}; (function () { var ctor = function() { this.x = 1; }, props = []; ctor.prototype = { 'valueOf': 1, 'y': 1 }; for (var key in new ctor) { props.push(key); } for (key in arguments) { } // Detect if `name` or `message` properties of `Error.prototype` are enumerable by default. support.enumErrorProps = propertyIsEnumerable.call(errorProto, 'message') || propertyIsEnumerable.call(errorProto, 'name'); // Detect if `prototype` properties are enumerable by default. support.enumPrototypes = propertyIsEnumerable.call(ctor, 'prototype'); // Detect if `arguments` object indexes are non-enumerable support.nonEnumArgs = key != 0; // Detect if properties shadowing those on `Object.prototype` are non-enumerable. support.nonEnumShadows = !/valueOf/.test(props); }(1)); var isObject = Rx.internals.isObject = function(value) { var type = typeof value; return value && (type == 'function' || type == 'object') || false; }; function keysIn(object) { var result = []; if (!isObject(object)) { return result; } if (support.nonEnumArgs && object.length && isArguments(object)) { object = slice.call(object); } var skipProto = support.enumPrototypes && typeof object == 'function', skipErrorProps = support.enumErrorProps && (object === errorProto || object instanceof Error); for (var key in object) { if (!(skipProto && key == 'prototype') && !(skipErrorProps && (key == 'message' || key == 'name'))) { result.push(key); } } if (support.nonEnumShadows && object !== objectProto) { var ctor = object.constructor, index = -1, length = dontEnumsLength; if (object === (ctor && ctor.prototype)) { var className = object === stringProto ? stringClass : object === errorProto ? errorClass : toString.call(object), nonEnum = nonEnumProps[className]; } while (++index < length) { key = dontEnums[index]; if (!(nonEnum && nonEnum[key]) && hasOwnProperty.call(object, key)) { result.push(key); } } } return result; } function internalFor(object, callback, keysFunc) { var index = -1, props = keysFunc(object), length = props.length; while (++index < length) { var key = props[index]; if (callback(object[key], key, object) === false) { break; } } return object; } function internalForIn(object, callback) { return internalFor(object, callback, keysIn); } function isNode(value) { // IE < 9 presents DOM nodes as `Object` objects except they have `toString` // methods that are `typeof` "string" and still can coerce nodes to strings return typeof value.toString != 'function' && typeof (value + '') == 'string'; } var isArguments = function(value) { return (value && typeof value == 'object') ? toString.call(value) == argsClass : false; } // fallback for browsers that can't detect `arguments` objects by [[Class]] if (!supportsArgsClass) { isArguments = function(value) { return (value && typeof value == 'object') ? hasOwnProperty.call(value, 'callee') : false; }; } var isEqual = Rx.internals.isEqual = function (x, y) { return deepEquals(x, y, [], []); }; /** @private * Used for deep comparison **/ function deepEquals(a, b, stackA, stackB) { // exit early for identical values if (a === b) { // treat `+0` vs. `-0` as not equal return a !== 0 || (1 / a == 1 / b); } var type = typeof a, otherType = typeof b; // exit early for unlike primitive values if (a === a && (a == null || b == null || (type != 'function' && type != 'object' && otherType != 'function' && otherType != 'object'))) { return false; } // compare [[Class]] names var className = toString.call(a), otherClass = toString.call(b); if (className == argsClass) { className = objectClass; } if (otherClass == argsClass) { otherClass = objectClass; } if (className != otherClass) { return false; } switch (className) { case boolClass: case dateClass: // coerce dates and booleans to numbers, dates to milliseconds and booleans // to `1` or `0` treating invalid dates coerced to `NaN` as not equal return +a == +b; case numberClass: // treat `NaN` vs. `NaN` as equal return (a != +a) ? b != +b : // but treat `-0` vs. `+0` as not equal (a == 0 ? (1 / a == 1 / b) : a == +b); case regexpClass: case stringClass: // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) // treat string primitives and their corresponding object instances as equal return a == String(b); } var isArr = className == arrayClass; if (!isArr) { // exit for functions and DOM nodes if (className != objectClass || (!support.nodeClass && (isNode(a) || isNode(b)))) { return false; } // in older versions of Opera, `arguments` objects have `Array` constructors var ctorA = !support.argsObject && isArguments(a) ? Object : a.constructor, ctorB = !support.argsObject && isArguments(b) ? Object : b.constructor; // non `Object` object instances with different constructors are not equal if (ctorA != ctorB && !(hasOwnProperty.call(a, 'constructor') && hasOwnProperty.call(b, 'constructor')) && !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && ('constructor' in a && 'constructor' in b) ) { return false; } } // assume cyclic structures are equal // the algorithm for detecting cyclic structures is adapted from ES 5.1 // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) var initedStack = !stackA; stackA || (stackA = []); stackB || (stackB = []); var length = stackA.length; while (length--) { if (stackA[length] == a) { return stackB[length] == b; } } var size = 0; var result = true; // add `a` and `b` to the stack of traversed objects stackA.push(a); stackB.push(b); // recursively compare objects and arrays (susceptible to call stack limits) if (isArr) { // compare lengths to determine if a deep comparison is necessary length = a.length; size = b.length; result = size == length; if (result) { // deep compare the contents, ignoring non-numeric properties while (size--) { var index = length, value = b[size]; if (!(result = deepEquals(a[size], value, stackA, stackB))) { break; } } } } else { // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` // which, in this case, is more costly internalForIn(b, function(value, key, b) { if (hasOwnProperty.call(b, key)) { // count the number of properties. size++; // deep compare each property value. return (result = hasOwnProperty.call(a, key) && deepEquals(a[key], value, stackA, stackB)); } }); if (result) { // ensure both objects have the same number of properties internalForIn(a, function(value, key, a) { if (hasOwnProperty.call(a, key)) { // `size` will be `-1` if `a` has more properties than `b` return (result = --size > -1); } }); } } stackA.pop(); stackB.pop(); return result; } var slice = Array.prototype.slice; function argsOrArray(args, idx) { return args.length === 1 && Array.isArray(args[idx]) ? args[idx] : slice.call(args); } var hasProp = {}.hasOwnProperty; var inherits = this.inherits = Rx.internals.inherits = function (child, parent) { function __() { this.constructor = child; } __.prototype = parent.prototype; child.prototype = new __(); }; var addProperties = Rx.internals.addProperties = function (obj) { var sources = slice.call(arguments, 1); for (var i = 0, len = sources.length; i < len; i++) { var source = sources[i]; for (var prop in source) { obj[prop] = source[prop]; } } }; // Rx Utils var addRef = Rx.internals.addRef = function (xs, r) { return new AnonymousObservable(function (observer) { return new CompositeDisposable(r.getDisposable(), xs.subscribe(observer)); }); }; function arrayInitialize(count, factory) { var a = new Array(count); for (var i = 0; i < count; i++) { a[i] = factory(); } return a; } // Collections function IndexedItem(id, value) { this.id = id; this.value = value; } IndexedItem.prototype.compareTo = function (other) { var c = this.value.compareTo(other.value); c === 0 && (c = this.id - other.id); return c; }; // Priority Queue for Scheduling var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) { this.items = new Array(capacity); this.length = 0; }; var priorityProto = PriorityQueue.prototype; priorityProto.isHigherPriority = function (left, right) { return this.items[left].compareTo(this.items[right]) < 0; }; priorityProto.percolate = function (index) { if (index >= this.length || index < 0) { return; } var parent = index - 1 >> 1; if (parent < 0 || parent === index) { return; } if (this.isHigherPriority(index, parent)) { var temp = this.items[index]; this.items[index] = this.items[parent]; this.items[parent] = temp; this.percolate(parent); } }; priorityProto.heapify = function (index) { +index || (index = 0); if (index >= this.length || index < 0) { return; } var left = 2 * index + 1, right = 2 * index + 2, first = index; if (left < this.length && this.isHigherPriority(left, first)) { first = left; } if (right < this.length && this.isHigherPriority(right, first)) { first = right; } if (first !== index) { var temp = this.items[index]; this.items[index] = this.items[first]; this.items[first] = temp; this.heapify(first); } }; priorityProto.peek = function () { return this.items[0].value; }; priorityProto.removeAt = function (index) { this.items[index] = this.items[--this.length]; delete this.items[this.length]; this.heapify(); }; priorityProto.dequeue = function () { var result = this.peek(); this.removeAt(0); return result; }; priorityProto.enqueue = function (item) { var index = this.length++; this.items[index] = new IndexedItem(PriorityQueue.count++, item); this.percolate(index); }; priorityProto.remove = function (item) { for (var i = 0; i < this.length; i++) { if (this.items[i].value === item) { this.removeAt(i); return true; } } return false; }; PriorityQueue.count = 0; /** * Represents a group of disposable resources that are disposed together. * @constructor */ var CompositeDisposable = Rx.CompositeDisposable = function () { this.disposables = argsOrArray(arguments, 0); this.isDisposed = false; this.length = this.disposables.length; }; var CompositeDisposablePrototype = CompositeDisposable.prototype; /** * Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed. * @param {Mixed} item Disposable to add. */ CompositeDisposablePrototype.add = function (item) { if (this.isDisposed) { item.dispose(); } else { this.disposables.push(item); this.length++; } }; /** * Removes and disposes the first occurrence of a disposable from the CompositeDisposable. * @param {Mixed} item Disposable to remove. * @returns {Boolean} true if found; false otherwise. */ CompositeDisposablePrototype.remove = function (item) { var shouldDispose = false; if (!this.isDisposed) { var idx = this.disposables.indexOf(item); if (idx !== -1) { shouldDispose = true; this.disposables.splice(idx, 1); this.length--; item.dispose(); } } return shouldDispose; }; /** * Disposes all disposables in the group and removes them from the group. */ CompositeDisposablePrototype.dispose = function () { if (!this.isDisposed) { this.isDisposed = true; var currentDisposables = this.disposables.slice(0); this.disposables = []; this.length = 0; for (var i = 0, len = currentDisposables.length; i < len; i++) { currentDisposables[i].dispose(); } } }; /** * Converts the existing CompositeDisposable to an array of disposables * @returns {Array} An array of disposable objects. */ CompositeDisposablePrototype.toArray = function () { return this.disposables.slice(0); }; /** * Provides a set of static methods for creating Disposables. * * @constructor * @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once. */ var Disposable = Rx.Disposable = function (action) { this.isDisposed = false; this.action = action || noop; }; /** Performs the task of cleaning up resources. */ Disposable.prototype.dispose = function () { if (!this.isDisposed) { this.action(); this.isDisposed = true; } }; /** * Creates a disposable object that invokes the specified action when disposed. * @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once. * @return {Disposable} The disposable object that runs the given action upon disposal. */ var disposableCreate = Disposable.create = function (action) { return new Disposable(action); }; /** * Gets the disposable that does nothing when disposed. */ var disposableEmpty = Disposable.empty = { dispose: noop }; var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = (function () { function BooleanDisposable () { this.isDisposed = false; this.current = null; } var booleanDisposablePrototype = BooleanDisposable.prototype; /** * Gets the underlying disposable. * @return The underlying disposable. */ booleanDisposablePrototype.getDisposable = function () { return this.current; }; /** * Sets the underlying disposable. * @param {Disposable} value The new underlying disposable. */ booleanDisposablePrototype.setDisposable = function (value) { var shouldDispose = this.isDisposed, old; if (!shouldDispose) { old = this.current; this.current = value; } old && old.dispose(); shouldDispose && value && value.dispose(); }; /** * Disposes the underlying disposable as well as all future replacements. */ booleanDisposablePrototype.dispose = function () { var old; if (!this.isDisposed) { this.isDisposed = true; old = this.current; this.current = null; } old && old.dispose(); }; return BooleanDisposable; }()); var SerialDisposable = Rx.SerialDisposable = SingleAssignmentDisposable; /** * Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed. */ var RefCountDisposable = Rx.RefCountDisposable = (function () { function InnerDisposable(disposable) { this.disposable = disposable; this.disposable.count++; this.isInnerDisposed = false; } InnerDisposable.prototype.dispose = function () { if (!this.disposable.isDisposed) { if (!this.isInnerDisposed) { this.isInnerDisposed = true; this.disposable.count--; if (this.disposable.count === 0 && this.disposable.isPrimaryDisposed) { this.disposable.isDisposed = true; this.disposable.underlyingDisposable.dispose(); } } } }; /** * Initializes a new instance of the RefCountDisposable with the specified disposable. * @constructor * @param {Disposable} disposable Underlying disposable. */ function RefCountDisposable(disposable) { this.underlyingDisposable = disposable; this.isDisposed = false; this.isPrimaryDisposed = false; this.count = 0; } /** * Disposes the underlying disposable only when all dependent disposables have been disposed */ RefCountDisposable.prototype.dispose = function () { if (!this.isDisposed) { if (!this.isPrimaryDisposed) { this.isPrimaryDisposed = true; if (this.count === 0) { this.isDisposed = true; this.underlyingDisposable.dispose(); } } } }; /** * Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable. * @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime. */ RefCountDisposable.prototype.getDisposable = function () { return this.isDisposed ? disposableEmpty : new InnerDisposable(this); }; return RefCountDisposable; })(); function ScheduledDisposable(scheduler, disposable) { this.scheduler = scheduler; this.disposable = disposable; this.isDisposed = false; } ScheduledDisposable.prototype.dispose = function () { var parent = this; this.scheduler.schedule(function () { if (!parent.isDisposed) { parent.isDisposed = true; parent.disposable.dispose(); } }); }; var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) { this.scheduler = scheduler; this.state = state; this.action = action; this.dueTime = dueTime; this.comparer = comparer || defaultSubComparer; this.disposable = new SingleAssignmentDisposable(); } ScheduledItem.prototype.invoke = function () { this.disposable.setDisposable(this.invokeCore()); }; ScheduledItem.prototype.compareTo = function (other) { return this.comparer(this.dueTime, other.dueTime); }; ScheduledItem.prototype.isCancelled = function () { return this.disposable.isDisposed; }; ScheduledItem.prototype.invokeCore = function () { return this.action(this.scheduler, this.state); }; /** Provides a set of static properties to access commonly used schedulers. */ var Scheduler = Rx.Scheduler = (function () { function Scheduler(now, schedule, scheduleRelative, scheduleAbsolute) { this.now = now; this._schedule = schedule; this._scheduleRelative = scheduleRelative; this._scheduleAbsolute = scheduleAbsolute; } function invokeAction(scheduler, action) { action(); return disposableEmpty; } var schedulerProto = Scheduler.prototype; /** * Schedules an action to be executed. * @param {Function} action Action to execute. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). */ schedulerProto.schedule = function (action) { return this._schedule(action, invokeAction); }; /** * Schedules an action to be executed. * @param state State passed to the action to be executed. * @param {Function} action Action to be executed. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). */ schedulerProto.scheduleWithState = function (state, action) { return this._schedule(state, action); }; /** * Schedules an action to be executed after the specified relative due time. * @param {Function} action Action to execute. * @param {Number} dueTime Relative time after which to execute the action. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). */ schedulerProto.scheduleWithRelative = function (dueTime, action) { return this._scheduleRelative(action, dueTime, invokeAction); }; /** * Schedules an action to be executed after dueTime. * @param state State passed to the action to be executed. * @param {Function} action Action to be executed. * @param {Number} dueTime Relative time after which to execute the action. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). */ schedulerProto.scheduleWithRelativeAndState = function (state, dueTime, action) { return this._scheduleRelative(state, dueTime, action); }; /** * Schedules an action to be executed at the specified absolute due time. * @param {Function} action Action to execute. * @param {Number} dueTime Absolute time at which to execute the action. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). */ schedulerProto.scheduleWithAbsolute = function (dueTime, action) { return this._scheduleAbsolute(action, dueTime, invokeAction); }; /** * Schedules an action to be executed at dueTime. * @param {Mixed} state State passed to the action to be executed. * @param {Function} action Action to be executed. * @param {Number}dueTime Absolute time at which to execute the action. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). */ schedulerProto.scheduleWithAbsoluteAndState = function (state, dueTime, action) { return this._scheduleAbsolute(state, dueTime, action); }; /** Gets the current time according to the local machine's system clock. */ Scheduler.now = defaultNow; /** * Normalizes the specified TimeSpan value to a positive value. * @param {Number} timeSpan The time span value to normalize. * @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0 */ Scheduler.normalize = function (timeSpan) { timeSpan < 0 && (timeSpan = 0); return timeSpan; }; return Scheduler; }()); var normalizeTime = Scheduler.normalize; (function (schedulerProto) { function invokeRecImmediate(scheduler, pair) { var state = pair.first, action = pair.second, group = new CompositeDisposable(), recursiveAction = function (state1) { action(state1, function (state2) { var isAdded = false, isDone = false, d = scheduler.scheduleWithState(state2, function (scheduler1, state3) { if (isAdded) { group.remove(d); } else { isDone = true; } recursiveAction(state3); return disposableEmpty; }); if (!isDone) { group.add(d); isAdded = true; } }); }; recursiveAction(state); return group; } function invokeRecDate(scheduler, pair, method) { var state = pair.first, action = pair.second, group = new CompositeDisposable(), recursiveAction = function (state1) { action(state1, function (state2, dueTime1) { var isAdded = false, isDone = false, d = scheduler[method].call(scheduler, state2, dueTime1, function (scheduler1, state3) { if (isAdded) { group.remove(d); } else { isDone = true; } recursiveAction(state3); return disposableEmpty; }); if (!isDone) { group.add(d); isAdded = true; } }); }; recursiveAction(state); return group; } function scheduleInnerRecursive(action, self) { action(function(dt) { self(action, dt); }); } /** * Schedules an action to be executed recursively. * @param {Function} action Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). */ schedulerProto.scheduleRecursive = function (action) { return this.scheduleRecursiveWithState(action, function (_action, self) { _action(function () { self(_action); }); }); }; /** * Schedules an action to be executed recursively. * @param {Mixed} state State passed to the action to be executed. * @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). */ schedulerProto.scheduleRecursiveWithState = function (state, action) { return this.scheduleWithState({ first: state, second: action }, invokeRecImmediate); }; /** * Schedules an action to be executed recursively after a specified relative due time. * @param {Function} action Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action at the specified relative time. * @param {Number}dueTime Relative time after which to execute the action for the first time. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). */ schedulerProto.scheduleRecursiveWithRelative = function (dueTime, action) { return this.scheduleRecursiveWithRelativeAndState(action, dueTime, scheduleInnerRecursive); }; /** * Schedules an action to be executed recursively after a specified relative due time. * @param {Mixed} state State passed to the action to be executed. * @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state. * @param {Number}dueTime Relative time after which to execute the action for the first time. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). */ schedulerProto.scheduleRecursiveWithRelativeAndState = function (state, dueTime, action) { return this._scheduleRelative({ first: state, second: action }, dueTime, function (s, p) { return invokeRecDate(s, p, 'scheduleWithRelativeAndState'); }); }; /** * Schedules an action to be executed recursively at a specified absolute due time. * @param {Function} action Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action at the specified absolute time. * @param {Number}dueTime Absolute time at which to execute the action for the first time. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). */ schedulerProto.scheduleRecursiveWithAbsolute = function (dueTime, action) { return this.scheduleRecursiveWithAbsoluteAndState(action, dueTime, scheduleInnerRecursive); }; /** * Schedules an action to be executed recursively at a specified absolute due time. * @param {Mixed} state State passed to the action to be executed. * @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state. * @param {Number}dueTime Absolute time at which to execute the action for the first time. * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). */ schedulerProto.scheduleRecursiveWithAbsoluteAndState = function (state, dueTime, action) { return this._scheduleAbsolute({ first: state, second: action }, dueTime, function (s, p) { return invokeRecDate(s, p, 'scheduleWithAbsoluteAndState'); }); }; }(Scheduler.prototype)); (function (schedulerProto) { /** * Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation. * @param {Number} period Period for running the work periodically. * @param {Function} action Action to be executed. * @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort). */ Scheduler.prototype.schedulePeriodic = function (period, action) { return this.schedulePeriodicWithState(null, period, action); }; /** * Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation. * @param {Mixed} state Initial state passed to the action upon the first iteration. * @param {Number} period Period for running the work periodically. * @param {Function} action Action to be executed, potentially updating the state. * @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort). */ Scheduler.prototype.schedulePeriodicWithState = function(state, period, action) { if (typeof root.setInterval === 'undefined') { throw new Error('Periodic scheduling not supported.'); } var s = state; var id = root.setInterval(function () { s = action(s); }, period); return disposableCreate(function () { root.clearInterval(id); }); }; }(Scheduler.prototype)); (function (schedulerProto) { /** * Returns a scheduler that wraps the original scheduler, adding exception handling for scheduled actions. * @param {Function} handler Handler that's run if an exception is caught. The exception will be rethrown if the handler returns false. * @returns {Scheduler} Wrapper around the original scheduler, enforcing exception handling. */ schedulerProto.catchError = schedulerProto['catch'] = function (handler) { return new CatchScheduler(this, handler); }; }(Scheduler.prototype)); var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () { function tick(command, recurse) { recurse(0, this._period); try { this._state = this._action(this._state); } catch (e) { this._cancel.dispose(); throw e; } } function SchedulePeriodicRecursive(scheduler, state, period, action) { this._scheduler = scheduler; this._state = state; this._period = period; this._action = action; } SchedulePeriodicRecursive.prototype.start = function () { var d = new SingleAssignmentDisposable(); this._cancel = d; d.setDisposable(this._scheduler.scheduleRecursiveWithRelativeAndState(0, this._period, tick.bind(this))); return d; }; return SchedulePeriodicRecursive; }()); /** Gets a scheduler that schedules work immediately on the current thread. */ var immediateScheduler = Scheduler.immediate = (function () { function scheduleNow(state, action) { return action(this, state); } function scheduleRelative(state, dueTime, action) { var dt = this.now() + normalizeTime(dueTime); while (dt - this.now() > 0) { } return action(this, state); } function scheduleAbsolute(state, dueTime, action) { return this.scheduleWithRelativeAndState(state, dueTime - this.now(), action); } return new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute); }()); /** * Gets a scheduler that schedules work as soon as possible on the current thread. */ var currentThreadScheduler = Scheduler.currentThread = (function () { var queue; function runTrampoline (q) { var item; while (q.length > 0) { item = q.dequeue(); if (!item.isCancelled()) { // Note, do not schedule blocking work! while (item.dueTime - Scheduler.now() > 0) { } if (!item.isCancelled()) { item.invoke(); } } } } function scheduleNow(state, action) { return this.scheduleWithRelativeAndState(state, 0, action); } function scheduleRelative(state, dueTime, action) { var dt = this.now() + Scheduler.normalize(dueTime), si = new ScheduledItem(this, state, action, dt); if (!queue) { queue = new PriorityQueue(4); queue.enqueue(si); try { runTrampoline(queue); } catch (e) { throw e; } finally { queue = null; } } else { queue.enqueue(si); } return si.disposable; } function scheduleAbsolute(state, dueTime, action) { return this.scheduleWithRelativeAndState(state, dueTime - this.now(), action); } var currentScheduler = new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute); currentScheduler.scheduleRequired = function () { return !queue; }; currentScheduler.ensureTrampoline = function (action) { if (!queue) { this.schedule(action); } else { action(); } }; return currentScheduler; }()); var scheduleMethod, clearMethod = noop; var localTimer = (function () { var localSetTimeout, localClearTimeout = noop; if ('WScript' in this) { localSetTimeout = function (fn, time) { WScript.Sleep(time); fn(); }; } else if (!!root.setTimeout) { localSetTimeout = root.setTimeout; localClearTimeout = root.clearTimeout; } else { throw new Error('No concurrency detected!'); } return { setTimeout: localSetTimeout, clearTimeout: localClearTimeout }; }()); var localSetTimeout = localTimer.setTimeout, localClearTimeout = localTimer.clearTimeout; (function () { var reNative = RegExp('^' + String(toString) .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') .replace(/toString| for [^\]]+/g, '.*?') + '$' ); var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' && !reNative.test(setImmediate) && setImmediate, clearImmediate = typeof (clearImmediate = freeGlobal && moduleExports && freeGlobal.clearImmediate) == 'function' && !reNative.test(clearImmediate) && clearImmediate; function postMessageSupported () { // Ensure not in a worker if (!root.postMessage || root.importScripts) { return false; } var isAsync = false, oldHandler = root.onmessage; // Test for async root.onmessage = function () { isAsync = true; }; root.postMessage('', '*'); root.onmessage = oldHandler; return isAsync; } // Use in order, setImmediate, nextTick, postMessage, MessageChannel, script readystatechanged, setTimeout if (typeof setImmediate === 'function') { scheduleMethod = setImmediate; clearMethod = clearImmediate; } else if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') { scheduleMethod = process.nextTick; } else if (postMessageSupported()) { var MSG_PREFIX = 'ms.rx.schedule' + Math.random(), tasks = {}, taskId = 0; var onGlobalPostMessage = function (event) { // Only if we're a match to avoid any other global events if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) { var handleId = event.data.substring(MSG_PREFIX.length), action = tasks[handleId]; action(); delete tasks[handleId]; } } if (root.addEventListener) { root.addEventListener('message', onGlobalPostMessage, false); } else { root.attachEvent('onmessage', onGlobalPostMessage, false); } scheduleMethod = function (action) { var currentId = taskId++; tasks[currentId] = action; root.postMessage(MSG_PREFIX + currentId, '*'); }; } else if (!!root.MessageChannel) { var channel = new root.MessageChannel(), channelTasks = {}, channelTaskId = 0; channel.port1.onmessage = function (event) { var id = event.data, action = channelTasks[id]; action(); delete channelTasks[id]; }; scheduleMethod = function (action) { var id = channelTaskId++; channelTasks[id] = action; channel.port2.postMessage(id); }; } else if ('document' in root && 'onreadystatechange' in root.document.createElement('script')) { scheduleMethod = function (action) { var scriptElement = root.document.createElement('script'); scriptElement.onreadystatechange = function () { action(); scriptElement.onreadystatechange = null; scriptElement.parentNode.removeChild(scriptElement); scriptElement = null; }; root.document.documentElement.appendChild(scriptElement); }; } else { scheduleMethod = function (action) { return localSetTimeout(action, 0); }; clearMethod = localClearTimeout; } }()); /** * Gets a scheduler that schedules work via a timed callback based upon platform. */ var timeoutScheduler = Scheduler.timeout = (function () { function scheduleNow(state, action) { var scheduler = this, disposable = new SingleAssignmentDisposable(); var id = scheduleMethod(function () { if (!disposable.isDisposed) { disposable.setDisposable(action(scheduler, state)); } }); return new CompositeDisposable(disposable, disposableCreate(function () { clearMethod(id); })); } function scheduleRelative(state, dueTime, action) { var scheduler = this, dt = Scheduler.normalize(dueTime); if (dt === 0) { return scheduler.scheduleWithState(state, action); } var disposable = new SingleAssignmentDisposable(); var id = localSetTimeout(function () { if (!disposable.isDisposed) { disposable.setDisposable(action(scheduler, state)); } }, dt); return new CompositeDisposable(disposable, disposableCreate(function () { localClearTimeout(id); })); } function scheduleAbsolute(state, dueTime, action) { return this.scheduleWithRelativeAndState(state, dueTime - this.now(), action); } return new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute); })(); var CatchScheduler = (function (__super__) { function scheduleNow(state, action) { return this._scheduler.scheduleWithState(state, this._wrap(action)); } function scheduleRelative(state, dueTime, action) { return this._scheduler.scheduleWithRelativeAndState(state, dueTime, this._wrap(action)); } function scheduleAbsolute(state, dueTime, action) { return this._scheduler.scheduleWithAbsoluteAndState(state, dueTime, this._wrap(action)); } inherits(CatchScheduler, __super__); function CatchScheduler(scheduler, handler) { this._scheduler = scheduler; this._handler = handler; this._recursiveOriginal = null; this._recursiveWrapper = null; __super__.call(this, this._scheduler.now.bind(t