twreporter-react
Version:
React-Redux site for The Reporter Foundation in Taiwan
1,411 lines (1,222 loc) • 202 kB
JavaScript
// 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;
})();
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));
/** 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 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;
}());
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);
})();
/**
* Represents a notification to an observer.
*/
var Notification = Rx.Notification = (function () {
function Notification(kind, hasValue) {
this.hasValue = hasValue == null ? false : hasValue;
this.kind = kind;
}
/**
* Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result.
*
* @memberOf Notification
* @param {Any} observerOrOnNext Delegate to invoke for an OnNext notification or Observer to invoke the notification on..
* @param {Function} onError Delegate to invoke for an OnError notification.
* @param {Function} onCompleted Delegate to invoke for an OnCompleted notification.
* @returns {Any} Result produced by the observation.
*/
Notification.prototype.accept = function (observerOrOnNext, onError, onCompleted) {
return observerOrOnNext && typeof observerOrOnNext === 'object' ?
this._acceptObservable(observerOrOnNext) :
this._accept(observerOrOnNext, onError, onCompleted);
};
/**
* Returns an observable sequence with a single notification.
*
* @memberOf Notifications
* @param {Scheduler} [scheduler] Scheduler to send out the notification calls on.
* @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription.
*/
Notification.prototype.toObservable = function (scheduler) {
var notification = this;
isScheduler(scheduler) || (scheduler = immediateScheduler);
return new AnonymousObservable(function (observer) {
return scheduler.schedule(function () {
notification._acceptObservable(observer);
notification.kind === 'N' && observer.onCompleted();
});
});
};
return