Added compiled JavaScript to repository for GitHub pages
This feels like a mistake...
This commit is contained in:
parent
3d5a2fb322
commit
dc226b1f25
468 changed files with 212152 additions and 2 deletions
1665
resources/public/js/compiled/out/goog/array/array.js
Normal file
1665
resources/public/js/compiled/out/goog/array/array.js
Normal file
File diff suppressed because it is too large
Load diff
369
resources/public/js/compiled/out/goog/asserts/asserts.js
Normal file
369
resources/public/js/compiled/out/goog/asserts/asserts.js
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities to check the preconditions, postconditions and
|
||||
* invariants runtime.
|
||||
*
|
||||
* Methods in this package should be given special treatment by the compiler
|
||||
* for type-inference. For example, <code>goog.asserts.assert(foo)</code>
|
||||
* will restrict <code>foo</code> to a truthy value.
|
||||
*
|
||||
* The compiler has an option to disable asserts. So code like:
|
||||
* <code>
|
||||
* var x = goog.asserts.assert(foo()); goog.asserts.assert(bar());
|
||||
* </code>
|
||||
* will be transformed into:
|
||||
* <code>
|
||||
* var x = foo();
|
||||
* </code>
|
||||
* The compiler will leave in foo() (because its return value is used),
|
||||
* but it will remove bar() because it assumes it does not have side-effects.
|
||||
*
|
||||
* @author agrieve@google.com (Andrew Grieve)
|
||||
*/
|
||||
|
||||
goog.provide('goog.asserts');
|
||||
goog.provide('goog.asserts.AssertionError');
|
||||
|
||||
goog.require('goog.debug.Error');
|
||||
goog.require('goog.dom.NodeType');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether to strip out asserts or to leave them in.
|
||||
*/
|
||||
goog.define('goog.asserts.ENABLE_ASSERTS', goog.DEBUG);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Error object for failed assertions.
|
||||
* @param {string} messagePattern The pattern that was used to form message.
|
||||
* @param {!Array<*>} messageArgs The items to substitute into the pattern.
|
||||
* @constructor
|
||||
* @extends {goog.debug.Error}
|
||||
* @final
|
||||
*/
|
||||
goog.asserts.AssertionError = function(messagePattern, messageArgs) {
|
||||
messageArgs.unshift(messagePattern);
|
||||
goog.debug.Error.call(this, goog.string.subs.apply(null, messageArgs));
|
||||
// Remove the messagePattern afterwards to avoid permanently modifying the
|
||||
// passed in array.
|
||||
messageArgs.shift();
|
||||
|
||||
/**
|
||||
* The message pattern used to format the error message. Error handlers can
|
||||
* use this to uniquely identify the assertion.
|
||||
* @type {string}
|
||||
*/
|
||||
this.messagePattern = messagePattern;
|
||||
};
|
||||
goog.inherits(goog.asserts.AssertionError, goog.debug.Error);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.asserts.AssertionError.prototype.name = 'AssertionError';
|
||||
|
||||
|
||||
/**
|
||||
* The default error handler.
|
||||
* @param {!goog.asserts.AssertionError} e The exception to be handled.
|
||||
*/
|
||||
goog.asserts.DEFAULT_ERROR_HANDLER = function(e) {
|
||||
throw e;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The handler responsible for throwing or logging assertion errors.
|
||||
* @private {function(!goog.asserts.AssertionError)}
|
||||
*/
|
||||
goog.asserts.errorHandler_ = goog.asserts.DEFAULT_ERROR_HANDLER;
|
||||
|
||||
|
||||
/**
|
||||
* Throws an exception with the given message and "Assertion failed" prefixed
|
||||
* onto it.
|
||||
* @param {string} defaultMessage The message to use if givenMessage is empty.
|
||||
* @param {Array<*>} defaultArgs The substitution arguments for defaultMessage.
|
||||
* @param {string|undefined} givenMessage Message supplied by the caller.
|
||||
* @param {Array<*>} givenArgs The substitution arguments for givenMessage.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a number.
|
||||
* @private
|
||||
*/
|
||||
goog.asserts.doAssertFailure_ = function(
|
||||
defaultMessage, defaultArgs, givenMessage, givenArgs) {
|
||||
var message = 'Assertion failed';
|
||||
if (givenMessage) {
|
||||
message += ': ' + givenMessage;
|
||||
var args = givenArgs;
|
||||
} else if (defaultMessage) {
|
||||
message += ': ' + defaultMessage;
|
||||
args = defaultArgs;
|
||||
}
|
||||
// The '' + works around an Opera 10 bug in the unit tests. Without it,
|
||||
// a stack trace is added to var message above. With this, a stack trace is
|
||||
// not added until this line (it causes the extra garbage to be added after
|
||||
// the assertion message instead of in the middle of it).
|
||||
var e = new goog.asserts.AssertionError('' + message, args || []);
|
||||
goog.asserts.errorHandler_(e);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets a custom error handler that can be used to customize the behavior of
|
||||
* assertion failures, for example by turning all assertion failures into log
|
||||
* messages.
|
||||
* @param {function(!goog.asserts.AssertionError)} errorHandler
|
||||
*/
|
||||
goog.asserts.setErrorHandler = function(errorHandler) {
|
||||
if (goog.asserts.ENABLE_ASSERTS) {
|
||||
goog.asserts.errorHandler_ = errorHandler;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the condition evaluates to true if goog.asserts.ENABLE_ASSERTS is
|
||||
* true.
|
||||
* @template T
|
||||
* @param {T} condition The condition to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {T} The value of the condition.
|
||||
* @throws {goog.asserts.AssertionError} When the condition evaluates to false.
|
||||
*/
|
||||
goog.asserts.assert = function(condition, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !condition) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'', null, opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return condition;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fails if goog.asserts.ENABLE_ASSERTS is true. This function is useful in case
|
||||
* when we want to add a check in the unreachable area like switch-case
|
||||
* statement:
|
||||
*
|
||||
* <pre>
|
||||
* switch(type) {
|
||||
* case FOO: doSomething(); break;
|
||||
* case BAR: doSomethingElse(); break;
|
||||
* default: goog.asserts.fail('Unrecognized type: ' + type);
|
||||
* // We have only 2 types - "default:" section is unreachable code.
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @throws {goog.asserts.AssertionError} Failure.
|
||||
*/
|
||||
goog.asserts.fail = function(opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS) {
|
||||
goog.asserts.errorHandler_(
|
||||
new goog.asserts.AssertionError(
|
||||
'Failure' + (opt_message ? ': ' + opt_message : ''),
|
||||
Array.prototype.slice.call(arguments, 1)));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a number if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {number} The value, guaranteed to be a number when asserts enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a number.
|
||||
*/
|
||||
goog.asserts.assertNumber = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected number but got %s: %s.', [goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {number} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a string if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {string} The value, guaranteed to be a string when asserts enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a string.
|
||||
*/
|
||||
goog.asserts.assertString = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isString(value)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected string but got %s: %s.', [goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {string} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a function if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {!Function} The value, guaranteed to be a function when asserts
|
||||
* enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a function.
|
||||
*/
|
||||
goog.asserts.assertFunction = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected function but got %s: %s.', [goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {!Function} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is an Object if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {!Object} The value, guaranteed to be a non-null object.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not an object.
|
||||
*/
|
||||
goog.asserts.assertObject = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected object but got %s: %s.', [goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {!Object} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is an Array if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {!Array<?>} The value, guaranteed to be a non-null array.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not an array.
|
||||
*/
|
||||
goog.asserts.assertArray = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isArray(value)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected array but got %s: %s.', [goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {!Array<?>} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a boolean if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {boolean} The value, guaranteed to be a boolean when asserts are
|
||||
* enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a boolean.
|
||||
*/
|
||||
goog.asserts.assertBoolean = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected boolean but got %s: %s.', [goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {boolean} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a DOM Element if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {!Element} The value, likely to be a DOM Element when asserts are
|
||||
* enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not an Element.
|
||||
*/
|
||||
goog.asserts.assertElement = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS &&
|
||||
(!goog.isObject(value) || value.nodeType != goog.dom.NodeType.ELEMENT)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected Element but got %s: %s.', [goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {!Element} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is an instance of the user-defined type if
|
||||
* goog.asserts.ENABLE_ASSERTS is true.
|
||||
*
|
||||
* The compiler may tighten the type returned by this function.
|
||||
*
|
||||
* @param {?} value The value to check.
|
||||
* @param {function(new: T, ...)} type A user-defined constructor.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not an instance of
|
||||
* type.
|
||||
* @return {T}
|
||||
* @template T
|
||||
*/
|
||||
goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) {
|
||||
goog.asserts.doAssertFailure_(
|
||||
'Expected instanceof %s but got %s.',
|
||||
[goog.asserts.getType_(type), goog.asserts.getType_(value)],
|
||||
opt_message, Array.prototype.slice.call(arguments, 3));
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks that no enumerable keys are present in Object.prototype. Such keys
|
||||
* would break most code that use {@code for (var ... in ...)} loops.
|
||||
*/
|
||||
goog.asserts.assertObjectPrototypeIsIntact = function() {
|
||||
for (var key in Object.prototype) {
|
||||
goog.asserts.fail(key + ' should not be enumerable in Object.prototype.');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the type of a value. If a constructor is passed, and a suitable
|
||||
* string cannot be found, 'unknown type name' will be returned.
|
||||
* @param {*} value A constructor, object, or primitive.
|
||||
* @return {string} The best display name for the value, or 'unknown type name'.
|
||||
* @private
|
||||
*/
|
||||
goog.asserts.getType_ = function(value) {
|
||||
if (value instanceof Function) {
|
||||
return value.displayName || value.name || 'unknown type name';
|
||||
} else if (value instanceof Object) {
|
||||
return value.constructor.displayName || value.constructor.name ||
|
||||
Object.prototype.toString.call(value);
|
||||
} else {
|
||||
return value === null ? 'null' : typeof value;
|
||||
}
|
||||
};
|
||||
83
resources/public/js/compiled/out/goog/async/freelist.js
Normal file
83
resources/public/js/compiled/out/goog/async/freelist.js
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright 2015 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Simple freelist.
|
||||
*
|
||||
* An anterative to goog.structs.SimplePool, it imposes the requirement that the
|
||||
* objects in the list contain a "next" property that can be used to maintain
|
||||
* the pool.
|
||||
*/
|
||||
|
||||
goog.provide('goog.async.FreeList');
|
||||
|
||||
|
||||
/**
|
||||
* @template ITEM
|
||||
*/
|
||||
goog.async.FreeList = goog.defineClass(null, {
|
||||
/**
|
||||
* @param {function():ITEM} create
|
||||
* @param {function(ITEM):void} reset
|
||||
* @param {number} limit
|
||||
*/
|
||||
constructor: function(create, reset, limit) {
|
||||
/** @private @const {number} */
|
||||
this.limit_ = limit;
|
||||
/** @private @const {function()} */
|
||||
this.create_ = create;
|
||||
/** @private @const {function(ITEM):void} */
|
||||
this.reset_ = reset;
|
||||
|
||||
/** @private {number} */
|
||||
this.occupants_ = 0;
|
||||
/** @private {ITEM} */
|
||||
this.head_ = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {ITEM}
|
||||
*/
|
||||
get: function() {
|
||||
var item;
|
||||
if (this.occupants_ > 0) {
|
||||
this.occupants_--;
|
||||
item = this.head_;
|
||||
this.head_ = item.next;
|
||||
item.next = null;
|
||||
} else {
|
||||
item = this.create_();
|
||||
}
|
||||
return item;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {ITEM} item An item available for possible future reuse.
|
||||
*/
|
||||
put: function(item) {
|
||||
this.reset_(item);
|
||||
if (this.occupants_ < this.limit_) {
|
||||
this.occupants_++;
|
||||
item.next = this.head_;
|
||||
this.head_ = item;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Visible for testing.
|
||||
* @package
|
||||
* @return {number}
|
||||
*/
|
||||
occupants: function() { return this.occupants_; }
|
||||
});
|
||||
262
resources/public/js/compiled/out/goog/async/nexttick.js
Normal file
262
resources/public/js/compiled/out/goog/async/nexttick.js
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Provides a function to schedule running a function as soon
|
||||
* as possible after the current JS execution stops and yields to the event
|
||||
* loop.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.async.nextTick');
|
||||
goog.provide('goog.async.throwException');
|
||||
|
||||
goog.require('goog.debug.entryPointRegistry');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.functions');
|
||||
goog.require('goog.labs.userAgent.browser');
|
||||
goog.require('goog.labs.userAgent.engine');
|
||||
|
||||
|
||||
/**
|
||||
* Throw an item without interrupting the current execution context. For
|
||||
* example, if processing a group of items in a loop, sometimes it is useful
|
||||
* to report an error while still allowing the rest of the batch to be
|
||||
* processed.
|
||||
* @param {*} exception
|
||||
*/
|
||||
goog.async.throwException = function(exception) {
|
||||
// Each throw needs to be in its own context.
|
||||
goog.global.setTimeout(function() { throw exception; }, 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fires the provided callbacks as soon as possible after the current JS
|
||||
* execution context. setTimeout(…, 0) takes at least 4ms when called from
|
||||
* within another setTimeout(…, 0) for legacy reasons.
|
||||
*
|
||||
* This will not schedule the callback as a microtask (i.e. a task that can
|
||||
* preempt user input or networking callbacks). It is meant to emulate what
|
||||
* setTimeout(_, 0) would do if it were not throttled. If you desire microtask
|
||||
* behavior, use {@see goog.Promise} instead.
|
||||
*
|
||||
* @param {function(this:SCOPE)} callback Callback function to fire as soon as
|
||||
* possible.
|
||||
* @param {SCOPE=} opt_context Object in whose scope to call the listener.
|
||||
* @param {boolean=} opt_useSetImmediate Avoid the IE workaround that
|
||||
* ensures correctness at the cost of speed. See comments for details.
|
||||
* @template SCOPE
|
||||
*/
|
||||
goog.async.nextTick = function(callback, opt_context, opt_useSetImmediate) {
|
||||
var cb = callback;
|
||||
if (opt_context) {
|
||||
cb = goog.bind(callback, opt_context);
|
||||
}
|
||||
cb = goog.async.nextTick.wrapCallback_(cb);
|
||||
// Note we do allow callers to also request setImmediate if they are willing
|
||||
// to accept the possible tradeoffs of incorrectness in exchange for speed.
|
||||
// The IE fallback of readystate change is much slower. See useSetImmediate_
|
||||
// for details.
|
||||
if (goog.isFunction(goog.global.setImmediate) &&
|
||||
(opt_useSetImmediate || goog.async.nextTick.useSetImmediate_())) {
|
||||
goog.global.setImmediate(cb);
|
||||
return;
|
||||
}
|
||||
|
||||
// Look for and cache the custom fallback version of setImmediate.
|
||||
if (!goog.async.nextTick.setImmediate_) {
|
||||
goog.async.nextTick.setImmediate_ =
|
||||
goog.async.nextTick.getSetImmediateEmulator_();
|
||||
}
|
||||
goog.async.nextTick.setImmediate_(cb);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether should use setImmediate implementation currently on window.
|
||||
*
|
||||
* window.setImmediate was introduced and currently only supported by IE10+,
|
||||
* but due to a bug in the implementation it is not guaranteed that
|
||||
* setImmediate is faster than setTimeout nor that setImmediate N is before
|
||||
* setImmediate N+1. That is why we do not use the native version if
|
||||
* available. We do, however, call setImmediate if it is a non-native function
|
||||
* because that indicates that it has been replaced by goog.testing.MockClock
|
||||
* which we do want to support.
|
||||
* See
|
||||
* http://connect.microsoft.com/IE/feedback/details/801823/setimmediate-and-messagechannel-are-broken-in-ie10
|
||||
*
|
||||
* @return {boolean} Whether to use the implementation of setImmediate defined
|
||||
* on Window.
|
||||
* @private
|
||||
*/
|
||||
goog.async.nextTick.useSetImmediate_ = function() {
|
||||
// Not a browser environment.
|
||||
if (!goog.global.Window || !goog.global.Window.prototype) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// MS Edge has window.setImmediate natively, but it's not on Window.prototype.
|
||||
// Also, there's no clean way to detect if the goog.global.setImmediate has
|
||||
// been replaced by mockClock as its replacement also shows up as "[native
|
||||
// code]" when using toString. Therefore, just always use
|
||||
// goog.global.setImmediate for Edge. It's unclear if it suffers the same
|
||||
// issues as IE10/11, but based on
|
||||
// https://dev.modern.ie/testdrive/demos/setimmediatesorting/
|
||||
// it seems they've been working to ensure it's WAI.
|
||||
if (goog.labs.userAgent.browser.isEdge() ||
|
||||
goog.global.Window.prototype.setImmediate != goog.global.setImmediate) {
|
||||
// Something redefined setImmediate in which case we decide to use it (This
|
||||
// is so that we use the mockClock setImmediate).
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Cache for the setImmediate implementation.
|
||||
* @type {function(function())}
|
||||
* @private
|
||||
*/
|
||||
goog.async.nextTick.setImmediate_;
|
||||
|
||||
|
||||
/**
|
||||
* Determines the best possible implementation to run a function as soon as
|
||||
* the JS event loop is idle.
|
||||
* @return {function(function())} The "setImmediate" implementation.
|
||||
* @private
|
||||
*/
|
||||
goog.async.nextTick.getSetImmediateEmulator_ = function() {
|
||||
// Create a private message channel and use it to postMessage empty messages
|
||||
// to ourselves.
|
||||
var Channel = goog.global['MessageChannel'];
|
||||
// If MessageChannel is not available and we are in a browser, implement
|
||||
// an iframe based polyfill in browsers that have postMessage and
|
||||
// document.addEventListener. The latter excludes IE8 because it has a
|
||||
// synchronous postMessage implementation.
|
||||
if (typeof Channel === 'undefined' && typeof window !== 'undefined' &&
|
||||
window.postMessage && window.addEventListener &&
|
||||
// Presto (The old pre-blink Opera engine) has problems with iframes
|
||||
// and contentWindow.
|
||||
!goog.labs.userAgent.engine.isPresto()) {
|
||||
/** @constructor */
|
||||
Channel = function() {
|
||||
// Make an empty, invisible iframe.
|
||||
var iframe = /** @type {!HTMLIFrameElement} */ (
|
||||
document.createElement(goog.dom.TagName.IFRAME));
|
||||
iframe.style.display = 'none';
|
||||
iframe.src = '';
|
||||
document.documentElement.appendChild(iframe);
|
||||
var win = iframe.contentWindow;
|
||||
var doc = win.document;
|
||||
doc.open();
|
||||
doc.write('');
|
||||
doc.close();
|
||||
// Do not post anything sensitive over this channel, as the workaround for
|
||||
// pages with file: origin could allow that information to be modified or
|
||||
// intercepted.
|
||||
var message = 'callImmediate' + Math.random();
|
||||
// The same origin policy rejects attempts to postMessage from file: urls
|
||||
// unless the origin is '*'.
|
||||
// TODO(b/16335441): Use '*' origin for data: and other similar protocols.
|
||||
var origin = win.location.protocol == 'file:' ?
|
||||
'*' :
|
||||
win.location.protocol + '//' + win.location.host;
|
||||
var onmessage = goog.bind(function(e) {
|
||||
// Validate origin and message to make sure that this message was
|
||||
// intended for us. If the origin is set to '*' (see above) only the
|
||||
// message needs to match since, for example, '*' != 'file://'. Allowing
|
||||
// the wildcard is ok, as we are not concerned with security here.
|
||||
if ((origin != '*' && e.origin != origin) || e.data != message) {
|
||||
return;
|
||||
}
|
||||
this['port1'].onmessage();
|
||||
}, this);
|
||||
win.addEventListener('message', onmessage, false);
|
||||
this['port1'] = {};
|
||||
this['port2'] = {
|
||||
postMessage: function() { win.postMessage(message, origin); }
|
||||
};
|
||||
};
|
||||
}
|
||||
if (typeof Channel !== 'undefined' && (!goog.labs.userAgent.browser.isIE())) {
|
||||
// Exclude all of IE due to
|
||||
// http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-internet-explorer-10/
|
||||
// which allows starving postMessage with a busy setTimeout loop.
|
||||
// This currently affects IE10 and IE11 which would otherwise be able
|
||||
// to use the postMessage based fallbacks.
|
||||
var channel = new Channel();
|
||||
// Use a fifo linked list to call callbacks in the right order.
|
||||
var head = {};
|
||||
var tail = head;
|
||||
channel['port1'].onmessage = function() {
|
||||
if (goog.isDef(head.next)) {
|
||||
head = head.next;
|
||||
var cb = head.cb;
|
||||
head.cb = null;
|
||||
cb();
|
||||
}
|
||||
};
|
||||
return function(cb) {
|
||||
tail.next = {cb: cb};
|
||||
tail = tail.next;
|
||||
channel['port2'].postMessage(0);
|
||||
};
|
||||
}
|
||||
// Implementation for IE6 to IE10: Script elements fire an asynchronous
|
||||
// onreadystatechange event when inserted into the DOM.
|
||||
if (typeof document !== 'undefined' &&
|
||||
'onreadystatechange' in document.createElement(goog.dom.TagName.SCRIPT)) {
|
||||
return function(cb) {
|
||||
var script = document.createElement(goog.dom.TagName.SCRIPT);
|
||||
script.onreadystatechange = function() {
|
||||
// Clean up and call the callback.
|
||||
script.onreadystatechange = null;
|
||||
script.parentNode.removeChild(script);
|
||||
script = null;
|
||||
cb();
|
||||
cb = null;
|
||||
};
|
||||
document.documentElement.appendChild(script);
|
||||
};
|
||||
}
|
||||
// Fall back to setTimeout with 0. In browsers this creates a delay of 5ms
|
||||
// or more.
|
||||
// NOTE(user): This fallback is used for IE11.
|
||||
return function(cb) { goog.global.setTimeout(cb, 0); };
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper function that is overrided to protect callbacks with entry point
|
||||
* monitor if the application monitors entry points.
|
||||
* @param {function()} callback Callback function to fire as soon as possible.
|
||||
* @return {function()} The wrapped callback.
|
||||
* @private
|
||||
*/
|
||||
goog.async.nextTick.wrapCallback_ = goog.functions.identity;
|
||||
|
||||
|
||||
// Register the callback function as an entry point, so that it can be
|
||||
// monitored for exception handling, etc. This has to be done in this file
|
||||
// since it requires special code to handle all browsers.
|
||||
goog.debug.entryPointRegistry.register(
|
||||
/**
|
||||
* @param {function(!Function): !Function} transformer The transforming
|
||||
* function.
|
||||
*/
|
||||
function(transformer) { goog.async.nextTick.wrapCallback_ = transformer; });
|
||||
133
resources/public/js/compiled/out/goog/async/run.js
Normal file
133
resources/public/js/compiled/out/goog/async/run.js
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.async.run');
|
||||
|
||||
goog.require('goog.async.WorkQueue');
|
||||
goog.require('goog.async.nextTick');
|
||||
goog.require('goog.async.throwException');
|
||||
|
||||
|
||||
/**
|
||||
* Fires the provided callback just before the current callstack unwinds, or as
|
||||
* soon as possible after the current JS execution context.
|
||||
* @param {function(this:THIS)} callback
|
||||
* @param {THIS=} opt_context Object to use as the "this value" when calling
|
||||
* the provided function.
|
||||
* @template THIS
|
||||
*/
|
||||
goog.async.run = function(callback, opt_context) {
|
||||
if (!goog.async.run.schedule_) {
|
||||
goog.async.run.initializeRunner_();
|
||||
}
|
||||
if (!goog.async.run.workQueueScheduled_) {
|
||||
// Nothing is currently scheduled, schedule it now.
|
||||
goog.async.run.schedule_();
|
||||
goog.async.run.workQueueScheduled_ = true;
|
||||
}
|
||||
|
||||
goog.async.run.workQueue_.add(callback, opt_context);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the function to use to process the work queue.
|
||||
* @private
|
||||
*/
|
||||
goog.async.run.initializeRunner_ = function() {
|
||||
// If native Promises are available in the browser, just schedule the callback
|
||||
// on a fulfilled promise, which is specified to be async, but as fast as
|
||||
// possible.
|
||||
if (goog.global.Promise && goog.global.Promise.resolve) {
|
||||
var promise = goog.global.Promise.resolve(undefined);
|
||||
goog.async.run.schedule_ = function() {
|
||||
promise.then(goog.async.run.processWorkQueue);
|
||||
};
|
||||
} else {
|
||||
goog.async.run.schedule_ = function() {
|
||||
goog.async.nextTick(goog.async.run.processWorkQueue);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Forces goog.async.run to use nextTick instead of Promise.
|
||||
*
|
||||
* This should only be done in unit tests. It's useful because MockClock
|
||||
* replaces nextTick, but not the browser Promise implementation, so it allows
|
||||
* Promise-based code to be tested with MockClock.
|
||||
*
|
||||
* However, we also want to run promises if the MockClock is no longer in
|
||||
* control so we schedule a backup "setTimeout" to the unmocked timeout if
|
||||
* provided.
|
||||
*
|
||||
* @param {function(function())=} opt_realSetTimeout
|
||||
*/
|
||||
goog.async.run.forceNextTick = function(opt_realSetTimeout) {
|
||||
goog.async.run.schedule_ = function() {
|
||||
goog.async.nextTick(goog.async.run.processWorkQueue);
|
||||
if (opt_realSetTimeout) {
|
||||
opt_realSetTimeout(goog.async.run.processWorkQueue);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The function used to schedule work asynchronousely.
|
||||
* @private {function()}
|
||||
*/
|
||||
goog.async.run.schedule_;
|
||||
|
||||
|
||||
/** @private {boolean} */
|
||||
goog.async.run.workQueueScheduled_ = false;
|
||||
|
||||
|
||||
/** @private {!goog.async.WorkQueue} */
|
||||
goog.async.run.workQueue_ = new goog.async.WorkQueue();
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Reset the work queue. Only available for tests in debug mode.
|
||||
*/
|
||||
goog.async.run.resetQueue = function() {
|
||||
goog.async.run.workQueueScheduled_ = false;
|
||||
goog.async.run.workQueue_ = new goog.async.WorkQueue();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run any pending goog.async.run work items. This function is not intended
|
||||
* for general use, but for use by entry point handlers to run items ahead of
|
||||
* goog.async.nextTick.
|
||||
*/
|
||||
goog.async.run.processWorkQueue = function() {
|
||||
// NOTE: additional work queue items may be added while processing.
|
||||
var item = null;
|
||||
while (item = goog.async.run.workQueue_.remove()) {
|
||||
try {
|
||||
item.fn.call(item.scope);
|
||||
} catch (e) {
|
||||
goog.async.throwException(e);
|
||||
}
|
||||
goog.async.run.workQueue_.returnUnused(item);
|
||||
}
|
||||
|
||||
// There are no more work items, allow processing to be scheduled again.
|
||||
goog.async.run.workQueueScheduled_ = false;
|
||||
};
|
||||
138
resources/public/js/compiled/out/goog/async/workqueue.js
Normal file
138
resources/public/js/compiled/out/goog/async/workqueue.js
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
// Copyright 2015 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.async.WorkItem');
|
||||
goog.provide('goog.async.WorkQueue');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.async.FreeList');
|
||||
|
||||
|
||||
// TODO(johnlenz): generalize the WorkQueue if this is used by more
|
||||
// than goog.async.run.
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A low GC workqueue. The key elements of this design:
|
||||
* - avoids the need for goog.bind or equivalent by carrying scope
|
||||
* - avoids the need for array reallocation by using a linked list
|
||||
* - minimizes work entry objects allocation by recycling objects
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
*/
|
||||
goog.async.WorkQueue = function() {
|
||||
this.workHead_ = null;
|
||||
this.workTail_ = null;
|
||||
};
|
||||
|
||||
|
||||
/** @define {number} The maximum number of entries to keep for recycling. */
|
||||
goog.define('goog.async.WorkQueue.DEFAULT_MAX_UNUSED', 100);
|
||||
|
||||
|
||||
/** @const @private {goog.async.FreeList<goog.async.WorkItem>} */
|
||||
goog.async.WorkQueue.freelist_ = new goog.async.FreeList(
|
||||
function() { return new goog.async.WorkItem(); },
|
||||
function(item) { item.reset(); }, goog.async.WorkQueue.DEFAULT_MAX_UNUSED);
|
||||
|
||||
|
||||
/**
|
||||
* @param {function()} fn
|
||||
* @param {Object|null|undefined} scope
|
||||
*/
|
||||
goog.async.WorkQueue.prototype.add = function(fn, scope) {
|
||||
var item = this.getUnusedItem_();
|
||||
item.set(fn, scope);
|
||||
|
||||
if (this.workTail_) {
|
||||
this.workTail_.next = item;
|
||||
this.workTail_ = item;
|
||||
} else {
|
||||
goog.asserts.assert(!this.workHead_);
|
||||
this.workHead_ = item;
|
||||
this.workTail_ = item;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.async.WorkItem}
|
||||
*/
|
||||
goog.async.WorkQueue.prototype.remove = function() {
|
||||
var item = null;
|
||||
|
||||
if (this.workHead_) {
|
||||
item = this.workHead_;
|
||||
this.workHead_ = this.workHead_.next;
|
||||
if (!this.workHead_) {
|
||||
this.workTail_ = null;
|
||||
}
|
||||
item.next = null;
|
||||
}
|
||||
return item;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.async.WorkItem} item
|
||||
*/
|
||||
goog.async.WorkQueue.prototype.returnUnused = function(item) {
|
||||
goog.async.WorkQueue.freelist_.put(item);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.async.WorkItem}
|
||||
* @private
|
||||
*/
|
||||
goog.async.WorkQueue.prototype.getUnusedItem_ = function() {
|
||||
return goog.async.WorkQueue.freelist_.get();
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
*/
|
||||
goog.async.WorkItem = function() {
|
||||
/** @type {?function()} */
|
||||
this.fn = null;
|
||||
/** @type {Object|null|undefined} */
|
||||
this.scope = null;
|
||||
/** @type {?goog.async.WorkItem} */
|
||||
this.next = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {function()} fn
|
||||
* @param {Object|null|undefined} scope
|
||||
*/
|
||||
goog.async.WorkItem.prototype.set = function(fn, scope) {
|
||||
this.fn = fn;
|
||||
this.scope = scope;
|
||||
this.next = null;
|
||||
};
|
||||
|
||||
|
||||
/** Reset the work item so they don't prevent GC before reuse */
|
||||
goog.async.WorkItem.prototype.reset = function() {
|
||||
this.fn = null;
|
||||
this.scope = null;
|
||||
this.next = null;
|
||||
};
|
||||
2727
resources/public/js/compiled/out/goog/base.js
Normal file
2727
resources/public/js/compiled/out/goog/base.js
Normal file
File diff suppressed because it is too large
Load diff
1746
resources/public/js/compiled/out/goog/date/date.js
Normal file
1746
resources/public/js/compiled/out/goog/date/date.js
Normal file
File diff suppressed because it is too large
Load diff
27
resources/public/js/compiled/out/goog/date/datelike.js
Normal file
27
resources/public/js/compiled/out/goog/date/datelike.js
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Typedefs for working with dates.
|
||||
*
|
||||
* @author nicksantos@google.com (Nick Santos)
|
||||
*/
|
||||
|
||||
goog.provide('goog.date.DateLike');
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {(Date|goog.date.Date)}
|
||||
*/
|
||||
goog.date.DateLike;
|
||||
150
resources/public/js/compiled/out/goog/date/duration.js
Normal file
150
resources/public/js/compiled/out/goog/date/duration.js
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Functions for formatting duration values. Such as "3 days"
|
||||
* "3 hours", "14 minutes", "2 hours 45 minutes".
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.date.duration');
|
||||
|
||||
goog.require('goog.i18n.DateTimeFormat');
|
||||
goog.require('goog.i18n.MessageFormat');
|
||||
|
||||
|
||||
/**
|
||||
* Number of milliseconds in a minute.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.date.duration.MINUTE_MS_ = 60000;
|
||||
|
||||
|
||||
/**
|
||||
* Number of milliseconds in an hour.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.date.duration.HOUR_MS_ = 3600000;
|
||||
|
||||
|
||||
/**
|
||||
* Number of milliseconds in a day.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.date.duration.DAY_MS_ = 86400000;
|
||||
|
||||
|
||||
/**
|
||||
* Accepts a duration in milliseconds and outputs an absolute duration time in
|
||||
* form of "1 day", "2 hours", "20 minutes", "2 days 1 hour 15 minutes" etc.
|
||||
* @param {number} durationMs Duration in milliseconds.
|
||||
* @return {string} The formatted duration.
|
||||
*/
|
||||
goog.date.duration.format = function(durationMs) {
|
||||
var ms = Math.abs(durationMs);
|
||||
|
||||
// Handle durations shorter than 1 minute.
|
||||
if (ms < goog.date.duration.MINUTE_MS_) {
|
||||
/**
|
||||
* @desc Duration time of zero minutes.
|
||||
*/
|
||||
var MSG_ZERO_MINUTES = goog.getMsg('0 minutes');
|
||||
return MSG_ZERO_MINUTES;
|
||||
}
|
||||
|
||||
var days = Math.floor(ms / goog.date.duration.DAY_MS_);
|
||||
ms %= goog.date.duration.DAY_MS_;
|
||||
|
||||
var hours = Math.floor(ms / goog.date.duration.HOUR_MS_);
|
||||
ms %= goog.date.duration.HOUR_MS_;
|
||||
|
||||
var minutes = Math.floor(ms / goog.date.duration.MINUTE_MS_);
|
||||
|
||||
// Localized number representations.
|
||||
var daysText = goog.i18n.DateTimeFormat.localizeNumbers(days);
|
||||
var hoursText = goog.i18n.DateTimeFormat.localizeNumbers(hours);
|
||||
var minutesText = goog.i18n.DateTimeFormat.localizeNumbers(minutes);
|
||||
|
||||
// We need a space after the days if there are hours or minutes to come.
|
||||
var daysSeparator = days * (hours + minutes) ? ' ' : '';
|
||||
// We need a space after the hours if there are minutes to come.
|
||||
var hoursSeparator = hours * minutes ? ' ' : '';
|
||||
|
||||
/**
|
||||
* @desc The days part of the duration message: 1 day, 5 days.
|
||||
*/
|
||||
var MSG_DURATION_DAYS = goog.getMsg(
|
||||
'{COUNT, plural, ' +
|
||||
'=0 {}' +
|
||||
'=1 {{TEXT} day}' +
|
||||
'other {{TEXT} days}}');
|
||||
/**
|
||||
* @desc The hours part of the duration message: 1 hour, 5 hours.
|
||||
*/
|
||||
var MSG_DURATION_HOURS = goog.getMsg(
|
||||
'{COUNT, plural, ' +
|
||||
'=0 {}' +
|
||||
'=1 {{TEXT} hour}' +
|
||||
'other {{TEXT} hours}}');
|
||||
/**
|
||||
* @desc The minutes part of the duration message: 1 minute, 5 minutes.
|
||||
*/
|
||||
var MSG_DURATION_MINUTES = goog.getMsg(
|
||||
'{COUNT, plural, ' +
|
||||
'=0 {}' +
|
||||
'=1 {{TEXT} minute}' +
|
||||
'other {{TEXT} minutes}}');
|
||||
|
||||
var daysPart = goog.date.duration.getDurationMessagePart_(
|
||||
MSG_DURATION_DAYS, days, daysText);
|
||||
var hoursPart = goog.date.duration.getDurationMessagePart_(
|
||||
MSG_DURATION_HOURS, hours, hoursText);
|
||||
var minutesPart = goog.date.duration.getDurationMessagePart_(
|
||||
MSG_DURATION_MINUTES, minutes, minutesText);
|
||||
|
||||
/**
|
||||
* @desc Duration time text concatenated from the individual time unit message
|
||||
* parts. The separator will be a space (e.g. '1 day 2 hours 24 minutes') or
|
||||
* nothing in case one/two of the duration parts is empty (
|
||||
* e.g. '1 hour 30 minutes', '3 days 15 minutes', '2 hours').
|
||||
*/
|
||||
var MSG_CONCATENATED_DURATION_TEXT = goog.getMsg(
|
||||
'{$daysPart}{$daysSeparator}{$hoursPart}{$hoursSeparator}{$minutesPart}',
|
||||
{
|
||||
'daysPart': daysPart,
|
||||
'daysSeparator': daysSeparator,
|
||||
'hoursPart': hoursPart,
|
||||
'hoursSeparator': hoursSeparator,
|
||||
'minutesPart': minutesPart
|
||||
});
|
||||
|
||||
return MSG_CONCATENATED_DURATION_TEXT;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets a duration message part for a time unit.
|
||||
* @param {string} pattern The pattern to apply.
|
||||
* @param {number} count The number of units.
|
||||
* @param {string} text The string to use for amount of units in the message.
|
||||
* @return {string} The formatted message part.
|
||||
* @private
|
||||
*/
|
||||
goog.date.duration.getDurationMessagePart_ = function(pattern, count, text) {
|
||||
var formatter = new goog.i18n.MessageFormat(pattern);
|
||||
return formatter.format({'COUNT': count, 'TEXT': text});
|
||||
};
|
||||
190
resources/public/js/compiled/out/goog/date/utcdatetime.js
Normal file
190
resources/public/js/compiled/out/goog/date/utcdatetime.js
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Locale independent date/time class.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.date.UtcDateTime');
|
||||
|
||||
goog.require('goog.date');
|
||||
goog.require('goog.date.Date');
|
||||
goog.require('goog.date.DateTime');
|
||||
goog.require('goog.date.Interval');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class representing a date/time in GMT+0 time zone, without daylight saving.
|
||||
* Defaults to current date and time if none is specified. The get... and the
|
||||
* getUTC... methods are equivalent.
|
||||
*
|
||||
* @param {number|goog.date.DateLike=} opt_year Four digit UTC year or a
|
||||
* date-like object. If not set, the created object will contain the
|
||||
* date determined by goog.now().
|
||||
* @param {number=} opt_month UTC month, 0 = Jan, 11 = Dec.
|
||||
* @param {number=} opt_date UTC date of month, 1 - 31.
|
||||
* @param {number=} opt_hours UTC hours, 0 - 23.
|
||||
* @param {number=} opt_minutes UTC minutes, 0 - 59.
|
||||
* @param {number=} opt_seconds UTC seconds, 0 - 59.
|
||||
* @param {number=} opt_milliseconds UTC milliseconds, 0 - 999.
|
||||
* @constructor
|
||||
* @struct
|
||||
* @extends {goog.date.DateTime}
|
||||
*/
|
||||
goog.date.UtcDateTime = function(
|
||||
opt_year, opt_month, opt_date, opt_hours, opt_minutes, opt_seconds,
|
||||
opt_milliseconds) {
|
||||
var timestamp;
|
||||
if (goog.isNumber(opt_year)) {
|
||||
timestamp = Date.UTC(
|
||||
opt_year, opt_month || 0, opt_date || 1, opt_hours || 0,
|
||||
opt_minutes || 0, opt_seconds || 0, opt_milliseconds || 0);
|
||||
} else {
|
||||
timestamp = opt_year ? opt_year.getTime() : goog.now();
|
||||
}
|
||||
this.date = new Date(timestamp);
|
||||
};
|
||||
goog.inherits(goog.date.UtcDateTime, goog.date.DateTime);
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} timestamp Number of milliseconds since Epoch.
|
||||
* @return {!goog.date.UtcDateTime}
|
||||
*/
|
||||
goog.date.UtcDateTime.fromTimestamp = function(timestamp) {
|
||||
var date = new goog.date.UtcDateTime();
|
||||
date.setTime(timestamp);
|
||||
return date;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a DateTime from a UTC datetime string expressed in ISO 8601 format.
|
||||
*
|
||||
* @param {string} formatted A date or datetime expressed in ISO 8601 format.
|
||||
* @return {goog.date.UtcDateTime} Parsed date or null if parse fails.
|
||||
*/
|
||||
goog.date.UtcDateTime.fromIsoString = function(formatted) {
|
||||
var ret = new goog.date.UtcDateTime(2000);
|
||||
return goog.date.setIso8601DateTime(ret, formatted) ? ret : null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clones the UtcDateTime object.
|
||||
*
|
||||
* @return {!goog.date.UtcDateTime} A clone of the datetime object.
|
||||
* @override
|
||||
*/
|
||||
goog.date.UtcDateTime.prototype.clone = function() {
|
||||
var date = new goog.date.UtcDateTime(this.date);
|
||||
date.setFirstDayOfWeek(this.getFirstDayOfWeek());
|
||||
date.setFirstWeekCutOffDay(this.getFirstWeekCutOffDay());
|
||||
return date;
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.add = function(interval) {
|
||||
if (interval.years || interval.months) {
|
||||
var yearsMonths = new goog.date.Interval(interval.years, interval.months);
|
||||
goog.date.Date.prototype.add.call(this, yearsMonths);
|
||||
}
|
||||
var daysAndTimeMillis = 1000 *
|
||||
(interval.seconds +
|
||||
60 * (interval.minutes + 60 * (interval.hours + 24 * interval.days)));
|
||||
this.date = new Date(this.date.getTime() + daysAndTimeMillis);
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.getTimezoneOffset = function() {
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.getFullYear =
|
||||
goog.date.DateTime.prototype.getUTCFullYear;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.getMonth =
|
||||
goog.date.DateTime.prototype.getUTCMonth;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.getDate =
|
||||
goog.date.DateTime.prototype.getUTCDate;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.getHours =
|
||||
goog.date.DateTime.prototype.getUTCHours;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.getMinutes =
|
||||
goog.date.DateTime.prototype.getUTCMinutes;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.getSeconds =
|
||||
goog.date.DateTime.prototype.getUTCSeconds;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.getMilliseconds =
|
||||
goog.date.DateTime.prototype.getUTCMilliseconds;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.getDay = goog.date.DateTime.prototype.getUTCDay;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.setFullYear =
|
||||
goog.date.DateTime.prototype.setUTCFullYear;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.setMonth =
|
||||
goog.date.DateTime.prototype.setUTCMonth;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.setDate =
|
||||
goog.date.DateTime.prototype.setUTCDate;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.setHours =
|
||||
goog.date.DateTime.prototype.setUTCHours;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.setMinutes =
|
||||
goog.date.DateTime.prototype.setUTCMinutes;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.setSeconds =
|
||||
goog.date.DateTime.prototype.setUTCSeconds;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.date.UtcDateTime.prototype.setMilliseconds =
|
||||
goog.date.DateTime.prototype.setUTCMilliseconds;
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
// Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A global registry for entry points into a program,
|
||||
* so that they can be instrumented. Each module should register their
|
||||
* entry points with this registry. Designed to be compiled out
|
||||
* if no instrumentation is requested.
|
||||
*
|
||||
* Entry points may be registered before or after a call to
|
||||
* goog.debug.entryPointRegistry.monitorAll. If an entry point is registered
|
||||
* later, the existing monitor will instrument the new entry point.
|
||||
*
|
||||
* @author nicksantos@google.com (Nick Santos)
|
||||
*/
|
||||
|
||||
goog.provide('goog.debug.EntryPointMonitor');
|
||||
goog.provide('goog.debug.entryPointRegistry');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @interface
|
||||
*/
|
||||
goog.debug.EntryPointMonitor = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Instruments a function.
|
||||
*
|
||||
* @param {!Function} fn A function to instrument.
|
||||
* @return {!Function} The instrumented function.
|
||||
*/
|
||||
goog.debug.EntryPointMonitor.prototype.wrap;
|
||||
|
||||
|
||||
/**
|
||||
* Try to remove an instrumentation wrapper created by this monitor.
|
||||
* If the function passed to unwrap is not a wrapper created by this
|
||||
* monitor, then we will do nothing.
|
||||
*
|
||||
* Notice that some wrappers may not be unwrappable. For example, if other
|
||||
* monitors have applied their own wrappers, then it will be impossible to
|
||||
* unwrap them because their wrappers will have captured our wrapper.
|
||||
*
|
||||
* So it is important that entry points are unwrapped in the reverse
|
||||
* order that they were wrapped.
|
||||
*
|
||||
* @param {!Function} fn A function to unwrap.
|
||||
* @return {!Function} The unwrapped function, or {@code fn} if it was not
|
||||
* a wrapped function created by this monitor.
|
||||
*/
|
||||
goog.debug.EntryPointMonitor.prototype.unwrap;
|
||||
|
||||
|
||||
/**
|
||||
* An array of entry point callbacks.
|
||||
* @type {!Array<function(!Function)>}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.entryPointRegistry.refList_ = [];
|
||||
|
||||
|
||||
/**
|
||||
* Monitors that should wrap all the entry points.
|
||||
* @type {!Array<!goog.debug.EntryPointMonitor>}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.entryPointRegistry.monitors_ = [];
|
||||
|
||||
|
||||
/**
|
||||
* Whether goog.debug.entryPointRegistry.monitorAll has ever been called.
|
||||
* Checking this allows the compiler to optimize out the registrations.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.debug.entryPointRegistry.monitorsMayExist_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* Register an entry point with this module.
|
||||
*
|
||||
* The entry point will be instrumented when a monitor is passed to
|
||||
* goog.debug.entryPointRegistry.monitorAll. If this has already occurred, the
|
||||
* entry point is instrumented immediately.
|
||||
*
|
||||
* @param {function(!Function)} callback A callback function which is called
|
||||
* with a transforming function to instrument the entry point. The callback
|
||||
* is responsible for wrapping the relevant entry point with the
|
||||
* transforming function.
|
||||
*/
|
||||
goog.debug.entryPointRegistry.register = function(callback) {
|
||||
// Don't use push(), so that this can be compiled out.
|
||||
goog.debug.entryPointRegistry
|
||||
.refList_[goog.debug.entryPointRegistry.refList_.length] = callback;
|
||||
// If no one calls monitorAll, this can be compiled out.
|
||||
if (goog.debug.entryPointRegistry.monitorsMayExist_) {
|
||||
var monitors = goog.debug.entryPointRegistry.monitors_;
|
||||
for (var i = 0; i < monitors.length; i++) {
|
||||
callback(goog.bind(monitors[i].wrap, monitors[i]));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Configures a monitor to wrap all entry points.
|
||||
*
|
||||
* Entry points that have already been registered are immediately wrapped by
|
||||
* the monitor. When an entry point is registered in the future, it will also
|
||||
* be wrapped by the monitor when it is registered.
|
||||
*
|
||||
* @param {!goog.debug.EntryPointMonitor} monitor An entry point monitor.
|
||||
*/
|
||||
goog.debug.entryPointRegistry.monitorAll = function(monitor) {
|
||||
goog.debug.entryPointRegistry.monitorsMayExist_ = true;
|
||||
var transformer = goog.bind(monitor.wrap, monitor);
|
||||
for (var i = 0; i < goog.debug.entryPointRegistry.refList_.length; i++) {
|
||||
goog.debug.entryPointRegistry.refList_[i](transformer);
|
||||
}
|
||||
goog.debug.entryPointRegistry.monitors_.push(monitor);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Try to unmonitor all the entry points that have already been registered. If
|
||||
* an entry point is registered in the future, it will not be wrapped by the
|
||||
* monitor when it is registered. Note that this may fail if the entry points
|
||||
* have additional wrapping.
|
||||
*
|
||||
* @param {!goog.debug.EntryPointMonitor} monitor The last monitor to wrap
|
||||
* the entry points.
|
||||
* @throws {Error} If the monitor is not the most recently configured monitor.
|
||||
*/
|
||||
goog.debug.entryPointRegistry.unmonitorAllIfPossible = function(monitor) {
|
||||
var monitors = goog.debug.entryPointRegistry.monitors_;
|
||||
goog.asserts.assert(
|
||||
monitor == monitors[monitors.length - 1],
|
||||
'Only the most recent monitor can be unwrapped.');
|
||||
var transformer = goog.bind(monitor.unwrap, monitor);
|
||||
for (var i = 0; i < goog.debug.entryPointRegistry.refList_.length; i++) {
|
||||
goog.debug.entryPointRegistry.refList_[i](transformer);
|
||||
}
|
||||
monitors.length--;
|
||||
};
|
||||
63
resources/public/js/compiled/out/goog/debug/error.js
Normal file
63
resources/public/js/compiled/out/goog/debug/error.js
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Provides a base class for custom Error objects such that the
|
||||
* stack is correctly maintained.
|
||||
*
|
||||
* You should never need to throw goog.debug.Error(msg) directly, Error(msg) is
|
||||
* sufficient.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.debug.Error');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class for custom error objects.
|
||||
* @param {*=} opt_msg The message associated with the error.
|
||||
* @constructor
|
||||
* @extends {Error}
|
||||
*/
|
||||
goog.debug.Error = function(opt_msg) {
|
||||
|
||||
// Attempt to ensure there is a stack trace.
|
||||
if (Error.captureStackTrace) {
|
||||
Error.captureStackTrace(this, goog.debug.Error);
|
||||
} else {
|
||||
var stack = new Error().stack;
|
||||
if (stack) {
|
||||
this.stack = stack;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt_msg) {
|
||||
this.message = String(opt_msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether to report this error to the server. Setting this to false will
|
||||
* cause the error reporter to not report the error back to the server,
|
||||
* which can be useful if the client knows that the error has already been
|
||||
* logged on the server.
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.reportErrorToServer = true;
|
||||
};
|
||||
goog.inherits(goog.debug.Error, Error);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.debug.Error.prototype.name = 'CustomError';
|
||||
1508
resources/public/js/compiled/out/goog/deps.js
Normal file
1508
resources/public/js/compiled/out/goog/deps.js
Normal file
File diff suppressed because one or more lines are too long
73
resources/public/js/compiled/out/goog/dom/browserfeature.js
Normal file
73
resources/public/js/compiled/out/goog/dom/browserfeature.js
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Browser capability checks for the dom package.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.dom.BrowserFeature');
|
||||
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
* Enum of browser capabilities.
|
||||
* @enum {boolean}
|
||||
*/
|
||||
goog.dom.BrowserFeature = {
|
||||
/**
|
||||
* Whether attributes 'name' and 'type' can be added to an element after it's
|
||||
* created. False in Internet Explorer prior to version 9.
|
||||
*/
|
||||
CAN_ADD_NAME_OR_TYPE_ATTRIBUTES:
|
||||
!goog.userAgent.IE || goog.userAgent.isDocumentModeOrHigher(9),
|
||||
|
||||
/**
|
||||
* Whether we can use element.children to access an element's Element
|
||||
* children. Available since Gecko 1.9.1, IE 9. (IE<9 also includes comment
|
||||
* nodes in the collection.)
|
||||
*/
|
||||
CAN_USE_CHILDREN_ATTRIBUTE: !goog.userAgent.GECKO && !goog.userAgent.IE ||
|
||||
goog.userAgent.IE && goog.userAgent.isDocumentModeOrHigher(9) ||
|
||||
goog.userAgent.GECKO && goog.userAgent.isVersionOrHigher('1.9.1'),
|
||||
|
||||
/**
|
||||
* Opera, Safari 3, and Internet Explorer 9 all support innerText but they
|
||||
* include text nodes in script and style tags. Not document-mode-dependent.
|
||||
*/
|
||||
CAN_USE_INNER_TEXT:
|
||||
(goog.userAgent.IE && !goog.userAgent.isVersionOrHigher('9')),
|
||||
|
||||
/**
|
||||
* MSIE, Opera, and Safari>=4 support element.parentElement to access an
|
||||
* element's parent if it is an Element.
|
||||
*/
|
||||
CAN_USE_PARENT_ELEMENT_PROPERTY:
|
||||
goog.userAgent.IE || goog.userAgent.OPERA || goog.userAgent.WEBKIT,
|
||||
|
||||
/**
|
||||
* Whether NoScope elements need a scoped element written before them in
|
||||
* innerHTML.
|
||||
* MSDN: http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx#1
|
||||
*/
|
||||
INNER_HTML_NEEDS_SCOPED_ELEMENT: goog.userAgent.IE,
|
||||
|
||||
/**
|
||||
* Whether we use legacy IE range API.
|
||||
*/
|
||||
LEGACY_IE_RANGES:
|
||||
goog.userAgent.IE && !goog.userAgent.isDocumentModeOrHigher(9)
|
||||
};
|
||||
157
resources/public/js/compiled/out/goog/dom/dataset.js
Normal file
157
resources/public/js/compiled/out/goog/dom/dataset.js
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities for adding, removing and setting values in
|
||||
* an Element's dataset.
|
||||
* See {@link http://www.w3.org/TR/html5/Overview.html#dom-dataset}.
|
||||
*
|
||||
* @author nicksay@google.com (Alex Nicksay)
|
||||
*/
|
||||
|
||||
goog.provide('goog.dom.dataset');
|
||||
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.userAgent.product');
|
||||
|
||||
|
||||
/**
|
||||
* Whether using the dataset property is allowed. In IE (up to and including
|
||||
* IE 11), setting element.dataset in JS does not propagate values to CSS,
|
||||
* breaking expressions such as `content: attr(data-content)` that would
|
||||
* otherwise work.
|
||||
* See {@link https://github.com/google/closure-library/issues/396}.
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
goog.dom.dataset.ALLOWED_ = !goog.userAgent.product.IE;
|
||||
|
||||
|
||||
/**
|
||||
* The DOM attribute name prefix that must be present for it to be considered
|
||||
* for a dataset.
|
||||
* @type {string}
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
goog.dom.dataset.PREFIX_ = 'data-';
|
||||
|
||||
|
||||
/**
|
||||
* Sets a custom data attribute on an element. The key should be
|
||||
* in camelCase format (e.g "keyName" for the "data-key-name" attribute).
|
||||
* @param {Element} element DOM node to set the custom data attribute on.
|
||||
* @param {string} key Key for the custom data attribute.
|
||||
* @param {string} value Value for the custom data attribute.
|
||||
*/
|
||||
goog.dom.dataset.set = function(element, key, value) {
|
||||
if (goog.dom.dataset.ALLOWED_ && element.dataset) {
|
||||
element.dataset[key] = value;
|
||||
} else {
|
||||
element.setAttribute(
|
||||
goog.dom.dataset.PREFIX_ + goog.string.toSelectorCase(key), value);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets a custom data attribute from an element. The key should be
|
||||
* in camelCase format (e.g "keyName" for the "data-key-name" attribute).
|
||||
* @param {Element} element DOM node to get the custom data attribute from.
|
||||
* @param {string} key Key for the custom data attribute.
|
||||
* @return {?string} The attribute value, if it exists.
|
||||
*/
|
||||
goog.dom.dataset.get = function(element, key) {
|
||||
if (goog.dom.dataset.ALLOWED_ && element.dataset) {
|
||||
// Android browser (non-chrome) returns the empty string for
|
||||
// element.dataset['doesNotExist'].
|
||||
if (!(key in element.dataset)) {
|
||||
return null;
|
||||
}
|
||||
return element.dataset[key];
|
||||
} else {
|
||||
return element.getAttribute(
|
||||
goog.dom.dataset.PREFIX_ + goog.string.toSelectorCase(key));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes a custom data attribute from an element. The key should be
|
||||
* in camelCase format (e.g "keyName" for the "data-key-name" attribute).
|
||||
* @param {Element} element DOM node to get the custom data attribute from.
|
||||
* @param {string} key Key for the custom data attribute.
|
||||
*/
|
||||
goog.dom.dataset.remove = function(element, key) {
|
||||
if (goog.dom.dataset.ALLOWED_ && element.dataset) {
|
||||
// In strict mode Safari will trigger an error when trying to delete a
|
||||
// property which does not exist.
|
||||
if (goog.dom.dataset.has(element, key)) {
|
||||
delete element.dataset[key];
|
||||
}
|
||||
} else {
|
||||
element.removeAttribute(
|
||||
goog.dom.dataset.PREFIX_ + goog.string.toSelectorCase(key));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether custom data attribute exists on an element. The key should be
|
||||
* in camelCase format (e.g "keyName" for the "data-key-name" attribute).
|
||||
*
|
||||
* @param {Element} element DOM node to get the custom data attribute from.
|
||||
* @param {string} key Key for the custom data attribute.
|
||||
* @return {boolean} Whether the attribute exists.
|
||||
*/
|
||||
goog.dom.dataset.has = function(element, key) {
|
||||
if (goog.dom.dataset.ALLOWED_ && element.dataset) {
|
||||
return key in element.dataset;
|
||||
} else if (element.hasAttribute) {
|
||||
return element.hasAttribute(
|
||||
goog.dom.dataset.PREFIX_ + goog.string.toSelectorCase(key));
|
||||
} else {
|
||||
return !!(
|
||||
element.getAttribute(
|
||||
goog.dom.dataset.PREFIX_ + goog.string.toSelectorCase(key)));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets all custom data attributes as a string map. The attribute names will be
|
||||
* camel cased (e.g., data-foo-bar -> dataset['fooBar']). This operation is not
|
||||
* safe for attributes having camel-cased names clashing with already existing
|
||||
* properties (e.g., data-to-string -> dataset['toString']).
|
||||
* @param {!Element} element DOM node to get the data attributes from.
|
||||
* @return {!Object} The string map containing data attributes and their
|
||||
* respective values.
|
||||
*/
|
||||
goog.dom.dataset.getAll = function(element) {
|
||||
if (goog.dom.dataset.ALLOWED_ && element.dataset) {
|
||||
return element.dataset;
|
||||
} else {
|
||||
var dataset = {};
|
||||
var attributes = element.attributes;
|
||||
for (var i = 0; i < attributes.length; ++i) {
|
||||
var attribute = attributes[i];
|
||||
if (goog.string.startsWith(attribute.name, goog.dom.dataset.PREFIX_)) {
|
||||
// We use substr(5), since it's faster than replacing 'data-' with ''.
|
||||
var key = goog.string.toCamelCase(attribute.name.substr(5));
|
||||
dataset[key] = attribute.value;
|
||||
}
|
||||
}
|
||||
return dataset;
|
||||
}
|
||||
};
|
||||
2992
resources/public/js/compiled/out/goog/dom/dom.js
Normal file
2992
resources/public/js/compiled/out/goog/dom/dom.js
Normal file
File diff suppressed because it is too large
Load diff
48
resources/public/js/compiled/out/goog/dom/nodetype.js
Normal file
48
resources/public/js/compiled/out/goog/dom/nodetype.js
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Definition of goog.dom.NodeType.
|
||||
*/
|
||||
|
||||
goog.provide('goog.dom.NodeType');
|
||||
|
||||
|
||||
/**
|
||||
* Constants for the nodeType attribute in the Node interface.
|
||||
*
|
||||
* These constants match those specified in the Node interface. These are
|
||||
* usually present on the Node object in recent browsers, but not in older
|
||||
* browsers (specifically, early IEs) and thus are given here.
|
||||
*
|
||||
* In some browsers (early IEs), these are not defined on the Node object,
|
||||
* so they are provided here.
|
||||
*
|
||||
* See http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247
|
||||
* @enum {number}
|
||||
*/
|
||||
goog.dom.NodeType = {
|
||||
ELEMENT: 1,
|
||||
ATTRIBUTE: 2,
|
||||
TEXT: 3,
|
||||
CDATA_SECTION: 4,
|
||||
ENTITY_REFERENCE: 5,
|
||||
ENTITY: 6,
|
||||
PROCESSING_INSTRUCTION: 7,
|
||||
COMMENT: 8,
|
||||
DOCUMENT: 9,
|
||||
DOCUMENT_TYPE: 10,
|
||||
DOCUMENT_FRAGMENT: 11,
|
||||
NOTATION: 12
|
||||
};
|
||||
372
resources/public/js/compiled/out/goog/dom/safe.js
Normal file
372
resources/public/js/compiled/out/goog/dom/safe.js
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Type-safe wrappers for unsafe DOM APIs.
|
||||
*
|
||||
* This file provides type-safe wrappers for DOM APIs that can result in
|
||||
* cross-site scripting (XSS) vulnerabilities, if the API is supplied with
|
||||
* untrusted (attacker-controlled) input. Instead of plain strings, the type
|
||||
* safe wrappers consume values of types from the goog.html package whose
|
||||
* contract promises that values are safe to use in the corresponding context.
|
||||
*
|
||||
* Hence, a program that exclusively uses the wrappers in this file (i.e., whose
|
||||
* only reference to security-sensitive raw DOM APIs are in this file) is
|
||||
* guaranteed to be free of XSS due to incorrect use of such DOM APIs (modulo
|
||||
* correctness of code that produces values of the respective goog.html types,
|
||||
* and absent code that violates type safety).
|
||||
*
|
||||
* For example, assigning to an element's .innerHTML property a string that is
|
||||
* derived (even partially) from untrusted input typically results in an XSS
|
||||
* vulnerability. The type-safe wrapper goog.html.setInnerHtml consumes a value
|
||||
* of type goog.html.SafeHtml, whose contract states that using its values in a
|
||||
* HTML context will not result in XSS. Hence a program that is free of direct
|
||||
* assignments to any element's innerHTML property (with the exception of the
|
||||
* assignment to .innerHTML in this file) is guaranteed to be free of XSS due to
|
||||
* assignment of untrusted strings to the innerHTML property.
|
||||
*/
|
||||
|
||||
goog.provide('goog.dom.safe');
|
||||
goog.provide('goog.dom.safe.InsertAdjacentHtmlPosition');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.html.SafeHtml');
|
||||
goog.require('goog.html.SafeUrl');
|
||||
goog.require('goog.html.TrustedResourceUrl');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.string.Const');
|
||||
|
||||
|
||||
/** @enum {string} */
|
||||
goog.dom.safe.InsertAdjacentHtmlPosition = {
|
||||
AFTERBEGIN: 'afterbegin',
|
||||
AFTEREND: 'afterend',
|
||||
BEFOREBEGIN: 'beforebegin',
|
||||
BEFOREEND: 'beforeend'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Inserts known-safe HTML into a Node, at the specified position.
|
||||
* @param {!Node} node The node on which to call insertAdjacentHTML.
|
||||
* @param {!goog.dom.safe.InsertAdjacentHtmlPosition} position Position where
|
||||
* to insert the HTML.
|
||||
* @param {!goog.html.SafeHtml} html The known-safe HTML to insert.
|
||||
*/
|
||||
goog.dom.safe.insertAdjacentHtml = function(node, position, html) {
|
||||
node.insertAdjacentHTML(position, goog.html.SafeHtml.unwrap(html));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Assigns known-safe HTML to an element's innerHTML property.
|
||||
* @param {!Element} elem The element whose innerHTML is to be assigned to.
|
||||
* @param {!goog.html.SafeHtml} html The known-safe HTML to assign.
|
||||
*/
|
||||
goog.dom.safe.setInnerHtml = function(elem, html) {
|
||||
elem.innerHTML = goog.html.SafeHtml.unwrap(html);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Assigns known-safe HTML to an element's outerHTML property.
|
||||
* @param {!Element} elem The element whose outerHTML is to be assigned to.
|
||||
* @param {!goog.html.SafeHtml} html The known-safe HTML to assign.
|
||||
*/
|
||||
goog.dom.safe.setOuterHtml = function(elem, html) {
|
||||
elem.outerHTML = goog.html.SafeHtml.unwrap(html);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes known-safe HTML to a document.
|
||||
* @param {!Document} doc The document to be written to.
|
||||
* @param {!goog.html.SafeHtml} html The known-safe HTML to assign.
|
||||
*/
|
||||
goog.dom.safe.documentWrite = function(doc, html) {
|
||||
doc.write(goog.html.SafeHtml.unwrap(html));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to an anchor element's href property.
|
||||
*
|
||||
* If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to
|
||||
* anchor's href property. If url is of type string however, it is first
|
||||
* sanitized using goog.html.SafeUrl.sanitize.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setAnchorHref(anchorEl, url);
|
||||
* which is a safe alternative to
|
||||
* anchorEl.href = url;
|
||||
* The latter can result in XSS vulnerabilities if url is a
|
||||
* user-/attacker-controlled value.
|
||||
*
|
||||
* @param {!HTMLAnchorElement} anchor The anchor element whose href property
|
||||
* is to be assigned to.
|
||||
* @param {string|!goog.html.SafeUrl} url The URL to assign.
|
||||
* @see goog.html.SafeUrl#sanitize
|
||||
*/
|
||||
goog.dom.safe.setAnchorHref = function(anchor, url) {
|
||||
/** @type {!goog.html.SafeUrl} */
|
||||
var safeUrl;
|
||||
if (url instanceof goog.html.SafeUrl) {
|
||||
safeUrl = url;
|
||||
} else {
|
||||
safeUrl = goog.html.SafeUrl.sanitize(url);
|
||||
}
|
||||
anchor.href = goog.html.SafeUrl.unwrap(safeUrl);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to an image element's src property.
|
||||
*
|
||||
* If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to
|
||||
* image's src property. If url is of type string however, it is first
|
||||
* sanitized using goog.html.SafeUrl.sanitize.
|
||||
*
|
||||
* @param {!HTMLImageElement} imageElement The image element whose src property
|
||||
* is to be assigned to.
|
||||
* @param {string|!goog.html.SafeUrl} url The URL to assign.
|
||||
* @see goog.html.SafeUrl#sanitize
|
||||
*/
|
||||
goog.dom.safe.setImageSrc = function(imageElement, url) {
|
||||
/** @type {!goog.html.SafeUrl} */
|
||||
var safeUrl;
|
||||
if (url instanceof goog.html.SafeUrl) {
|
||||
safeUrl = url;
|
||||
} else {
|
||||
safeUrl = goog.html.SafeUrl.sanitize(url);
|
||||
}
|
||||
imageElement.src = goog.html.SafeUrl.unwrap(safeUrl);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to an embed element's src property.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setEmbedSrc(embedEl, url);
|
||||
* which is a safe alternative to
|
||||
* embedEl.src = url;
|
||||
* The latter can result in loading untrusted code unless it is ensured that
|
||||
* the URL refers to a trustworthy resource.
|
||||
*
|
||||
* @param {!HTMLEmbedElement} embed The embed element whose src property
|
||||
* is to be assigned to.
|
||||
* @param {!goog.html.TrustedResourceUrl} url The URL to assign.
|
||||
*/
|
||||
goog.dom.safe.setEmbedSrc = function(embed, url) {
|
||||
embed.src = goog.html.TrustedResourceUrl.unwrap(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to a frame element's src property.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setFrameSrc(frameEl, url);
|
||||
* which is a safe alternative to
|
||||
* frameEl.src = url;
|
||||
* The latter can result in loading untrusted code unless it is ensured that
|
||||
* the URL refers to a trustworthy resource.
|
||||
*
|
||||
* @param {!HTMLFrameElement} frame The frame element whose src property
|
||||
* is to be assigned to.
|
||||
* @param {!goog.html.TrustedResourceUrl} url The URL to assign.
|
||||
*/
|
||||
goog.dom.safe.setFrameSrc = function(frame, url) {
|
||||
frame.src = goog.html.TrustedResourceUrl.unwrap(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to an iframe element's src property.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setIframeSrc(iframeEl, url);
|
||||
* which is a safe alternative to
|
||||
* iframeEl.src = url;
|
||||
* The latter can result in loading untrusted code unless it is ensured that
|
||||
* the URL refers to a trustworthy resource.
|
||||
*
|
||||
* @param {!HTMLIFrameElement} iframe The iframe element whose src property
|
||||
* is to be assigned to.
|
||||
* @param {!goog.html.TrustedResourceUrl} url The URL to assign.
|
||||
*/
|
||||
goog.dom.safe.setIframeSrc = function(iframe, url) {
|
||||
iframe.src = goog.html.TrustedResourceUrl.unwrap(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely sets a link element's href and rel properties. Whether or not
|
||||
* the URL assigned to href has to be a goog.html.TrustedResourceUrl
|
||||
* depends on the value of the rel property. If rel contains "stylesheet"
|
||||
* then a TrustedResourceUrl is required.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setLinkHrefAndRel(linkEl, url, 'stylesheet');
|
||||
* which is a safe alternative to
|
||||
* linkEl.rel = 'stylesheet';
|
||||
* linkEl.href = url;
|
||||
* The latter can result in loading untrusted code unless it is ensured that
|
||||
* the URL refers to a trustworthy resource.
|
||||
*
|
||||
* @param {!HTMLLinkElement} link The link element whose href property
|
||||
* is to be assigned to.
|
||||
* @param {string|!goog.html.SafeUrl|!goog.html.TrustedResourceUrl} url The URL
|
||||
* to assign to the href property. Must be a TrustedResourceUrl if the
|
||||
* value assigned to rel contains "stylesheet". A string value is
|
||||
* sanitized with goog.html.SafeUrl.sanitize.
|
||||
* @param {string} rel The value to assign to the rel property.
|
||||
* @throws {Error} if rel contains "stylesheet" and url is not a
|
||||
* TrustedResourceUrl
|
||||
* @see goog.html.SafeUrl#sanitize
|
||||
*/
|
||||
goog.dom.safe.setLinkHrefAndRel = function(link, url, rel) {
|
||||
link.rel = rel;
|
||||
if (goog.string.caseInsensitiveContains(rel, 'stylesheet')) {
|
||||
goog.asserts.assert(
|
||||
url instanceof goog.html.TrustedResourceUrl,
|
||||
'URL must be TrustedResourceUrl because "rel" contains "stylesheet"');
|
||||
link.href = goog.html.TrustedResourceUrl.unwrap(url);
|
||||
} else if (url instanceof goog.html.TrustedResourceUrl) {
|
||||
link.href = goog.html.TrustedResourceUrl.unwrap(url);
|
||||
} else if (url instanceof goog.html.SafeUrl) {
|
||||
link.href = goog.html.SafeUrl.unwrap(url);
|
||||
} else { // string
|
||||
// SafeUrl.sanitize must return legitimate SafeUrl when passed a string.
|
||||
link.href = goog.html.SafeUrl.sanitize(url).getTypedStringValue();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to an object element's data property.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setObjectData(objectEl, url);
|
||||
* which is a safe alternative to
|
||||
* objectEl.data = url;
|
||||
* The latter can result in loading untrusted code unless setit is ensured that
|
||||
* the URL refers to a trustworthy resource.
|
||||
*
|
||||
* @param {!HTMLObjectElement} object The object element whose data property
|
||||
* is to be assigned to.
|
||||
* @param {!goog.html.TrustedResourceUrl} url The URL to assign.
|
||||
*/
|
||||
goog.dom.safe.setObjectData = function(object, url) {
|
||||
object.data = goog.html.TrustedResourceUrl.unwrap(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to an iframe element's src property.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setScriptSrc(scriptEl, url);
|
||||
* which is a safe alternative to
|
||||
* scriptEl.src = url;
|
||||
* The latter can result in loading untrusted code unless it is ensured that
|
||||
* the URL refers to a trustworthy resource.
|
||||
*
|
||||
* @param {!HTMLScriptElement} script The script element whose src property
|
||||
* is to be assigned to.
|
||||
* @param {!goog.html.TrustedResourceUrl} url The URL to assign.
|
||||
*/
|
||||
goog.dom.safe.setScriptSrc = function(script, url) {
|
||||
script.src = goog.html.TrustedResourceUrl.unwrap(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely assigns a URL to a Location object's href property.
|
||||
*
|
||||
* If url is of type goog.html.SafeUrl, its value is unwrapped and assigned to
|
||||
* loc's href property. If url is of type string however, it is first sanitized
|
||||
* using goog.html.SafeUrl.sanitize.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.setLocationHref(document.location, redirectUrl);
|
||||
* which is a safe alternative to
|
||||
* document.location.href = redirectUrl;
|
||||
* The latter can result in XSS vulnerabilities if redirectUrl is a
|
||||
* user-/attacker-controlled value.
|
||||
*
|
||||
* @param {!Location} loc The Location object whose href property is to be
|
||||
* assigned to.
|
||||
* @param {string|!goog.html.SafeUrl} url The URL to assign.
|
||||
* @see goog.html.SafeUrl#sanitize
|
||||
*/
|
||||
goog.dom.safe.setLocationHref = function(loc, url) {
|
||||
/** @type {!goog.html.SafeUrl} */
|
||||
var safeUrl;
|
||||
if (url instanceof goog.html.SafeUrl) {
|
||||
safeUrl = url;
|
||||
} else {
|
||||
safeUrl = goog.html.SafeUrl.sanitize(url);
|
||||
}
|
||||
loc.href = goog.html.SafeUrl.unwrap(safeUrl);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safely opens a URL in a new window (via window.open).
|
||||
*
|
||||
* If url is of type goog.html.SafeUrl, its value is unwrapped and passed in to
|
||||
* window.open. If url is of type string however, it is first sanitized
|
||||
* using goog.html.SafeUrl.sanitize.
|
||||
*
|
||||
* Note that this function does not prevent leakages via the referer that is
|
||||
* sent by window.open. It is advised to only use this to open 1st party URLs.
|
||||
*
|
||||
* Example usage:
|
||||
* goog.dom.safe.openInWindow(url);
|
||||
* which is a safe alternative to
|
||||
* window.open(url);
|
||||
* The latter can result in XSS vulnerabilities if redirectUrl is a
|
||||
* user-/attacker-controlled value.
|
||||
*
|
||||
* @param {string|!goog.html.SafeUrl} url The URL to open.
|
||||
* @param {Window=} opt_openerWin Window of which to call the .open() method.
|
||||
* Defaults to the global window.
|
||||
* @param {!goog.string.Const=} opt_name Name of the window to open in. Can be
|
||||
* _top, etc as allowed by window.open().
|
||||
* @param {string=} opt_specs Comma-separated list of specifications, same as
|
||||
* in window.open().
|
||||
* @param {boolean=} opt_replace Whether to replace the current entry in browser
|
||||
* history, same as in window.open().
|
||||
* @return {Window} Window the url was opened in.
|
||||
*/
|
||||
goog.dom.safe.openInWindow = function(
|
||||
url, opt_openerWin, opt_name, opt_specs, opt_replace) {
|
||||
/** @type {!goog.html.SafeUrl} */
|
||||
var safeUrl;
|
||||
if (url instanceof goog.html.SafeUrl) {
|
||||
safeUrl = url;
|
||||
} else {
|
||||
safeUrl = goog.html.SafeUrl.sanitize(url);
|
||||
}
|
||||
var win = opt_openerWin || window;
|
||||
return win.open(
|
||||
goog.html.SafeUrl.unwrap(safeUrl),
|
||||
// If opt_name is undefined, simply passing that in to open() causes IE to
|
||||
// reuse the current window instead of opening a new one. Thus we pass ''
|
||||
// in instead, which according to spec opens a new window. See
|
||||
// https://html.spec.whatwg.org/multipage/browsers.html#dom-open .
|
||||
opt_name ? goog.string.Const.unwrap(opt_name) : '', opt_specs,
|
||||
opt_replace);
|
||||
};
|
||||
160
resources/public/js/compiled/out/goog/dom/tagname.js
Normal file
160
resources/public/js/compiled/out/goog/dom/tagname.js
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Defines the goog.dom.TagName enum. This enumerates
|
||||
* all HTML tag names specified in either the the W3C HTML 4.01 index of
|
||||
* elements or the HTML5 draft specification.
|
||||
*
|
||||
* References:
|
||||
* http://www.w3.org/TR/html401/index/elements.html
|
||||
* http://dev.w3.org/html5/spec/section-index.html
|
||||
*
|
||||
*/
|
||||
goog.provide('goog.dom.TagName');
|
||||
|
||||
|
||||
/**
|
||||
* Enum of all html tag names specified by the W3C HTML4.01 and HTML5
|
||||
* specifications.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.dom.TagName = {
|
||||
A: 'A',
|
||||
ABBR: 'ABBR',
|
||||
ACRONYM: 'ACRONYM',
|
||||
ADDRESS: 'ADDRESS',
|
||||
APPLET: 'APPLET',
|
||||
AREA: 'AREA',
|
||||
ARTICLE: 'ARTICLE',
|
||||
ASIDE: 'ASIDE',
|
||||
AUDIO: 'AUDIO',
|
||||
B: 'B',
|
||||
BASE: 'BASE',
|
||||
BASEFONT: 'BASEFONT',
|
||||
BDI: 'BDI',
|
||||
BDO: 'BDO',
|
||||
BIG: 'BIG',
|
||||
BLOCKQUOTE: 'BLOCKQUOTE',
|
||||
BODY: 'BODY',
|
||||
BR: 'BR',
|
||||
BUTTON: 'BUTTON',
|
||||
CANVAS: 'CANVAS',
|
||||
CAPTION: 'CAPTION',
|
||||
CENTER: 'CENTER',
|
||||
CITE: 'CITE',
|
||||
CODE: 'CODE',
|
||||
COL: 'COL',
|
||||
COLGROUP: 'COLGROUP',
|
||||
COMMAND: 'COMMAND',
|
||||
DATA: 'DATA',
|
||||
DATALIST: 'DATALIST',
|
||||
DD: 'DD',
|
||||
DEL: 'DEL',
|
||||
DETAILS: 'DETAILS',
|
||||
DFN: 'DFN',
|
||||
DIALOG: 'DIALOG',
|
||||
DIR: 'DIR',
|
||||
DIV: 'DIV',
|
||||
DL: 'DL',
|
||||
DT: 'DT',
|
||||
EM: 'EM',
|
||||
EMBED: 'EMBED',
|
||||
FIELDSET: 'FIELDSET',
|
||||
FIGCAPTION: 'FIGCAPTION',
|
||||
FIGURE: 'FIGURE',
|
||||
FONT: 'FONT',
|
||||
FOOTER: 'FOOTER',
|
||||
FORM: 'FORM',
|
||||
FRAME: 'FRAME',
|
||||
FRAMESET: 'FRAMESET',
|
||||
H1: 'H1',
|
||||
H2: 'H2',
|
||||
H3: 'H3',
|
||||
H4: 'H4',
|
||||
H5: 'H5',
|
||||
H6: 'H6',
|
||||
HEAD: 'HEAD',
|
||||
HEADER: 'HEADER',
|
||||
HGROUP: 'HGROUP',
|
||||
HR: 'HR',
|
||||
HTML: 'HTML',
|
||||
I: 'I',
|
||||
IFRAME: 'IFRAME',
|
||||
IMG: 'IMG',
|
||||
INPUT: 'INPUT',
|
||||
INS: 'INS',
|
||||
ISINDEX: 'ISINDEX',
|
||||
KBD: 'KBD',
|
||||
KEYGEN: 'KEYGEN',
|
||||
LABEL: 'LABEL',
|
||||
LEGEND: 'LEGEND',
|
||||
LI: 'LI',
|
||||
LINK: 'LINK',
|
||||
MAP: 'MAP',
|
||||
MARK: 'MARK',
|
||||
MATH: 'MATH',
|
||||
MENU: 'MENU',
|
||||
META: 'META',
|
||||
METER: 'METER',
|
||||
NAV: 'NAV',
|
||||
NOFRAMES: 'NOFRAMES',
|
||||
NOSCRIPT: 'NOSCRIPT',
|
||||
OBJECT: 'OBJECT',
|
||||
OL: 'OL',
|
||||
OPTGROUP: 'OPTGROUP',
|
||||
OPTION: 'OPTION',
|
||||
OUTPUT: 'OUTPUT',
|
||||
P: 'P',
|
||||
PARAM: 'PARAM',
|
||||
PRE: 'PRE',
|
||||
PROGRESS: 'PROGRESS',
|
||||
Q: 'Q',
|
||||
RP: 'RP',
|
||||
RT: 'RT',
|
||||
RUBY: 'RUBY',
|
||||
S: 'S',
|
||||
SAMP: 'SAMP',
|
||||
SCRIPT: 'SCRIPT',
|
||||
SECTION: 'SECTION',
|
||||
SELECT: 'SELECT',
|
||||
SMALL: 'SMALL',
|
||||
SOURCE: 'SOURCE',
|
||||
SPAN: 'SPAN',
|
||||
STRIKE: 'STRIKE',
|
||||
STRONG: 'STRONG',
|
||||
STYLE: 'STYLE',
|
||||
SUB: 'SUB',
|
||||
SUMMARY: 'SUMMARY',
|
||||
SUP: 'SUP',
|
||||
SVG: 'SVG',
|
||||
TABLE: 'TABLE',
|
||||
TBODY: 'TBODY',
|
||||
TD: 'TD',
|
||||
TEMPLATE: 'TEMPLATE',
|
||||
TEXTAREA: 'TEXTAREA',
|
||||
TFOOT: 'TFOOT',
|
||||
TH: 'TH',
|
||||
THEAD: 'THEAD',
|
||||
TIME: 'TIME',
|
||||
TITLE: 'TITLE',
|
||||
TR: 'TR',
|
||||
TRACK: 'TRACK',
|
||||
TT: 'TT',
|
||||
U: 'U',
|
||||
UL: 'UL',
|
||||
VAR: 'VAR',
|
||||
VIDEO: 'VIDEO',
|
||||
WBR: 'WBR'
|
||||
};
|
||||
41
resources/public/js/compiled/out/goog/dom/tags.js
Normal file
41
resources/public/js/compiled/out/goog/dom/tags.js
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
// Copyright 2014 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities for HTML element tag names.
|
||||
*/
|
||||
goog.provide('goog.dom.tags');
|
||||
|
||||
goog.require('goog.object');
|
||||
|
||||
|
||||
/**
|
||||
* The void elements specified by
|
||||
* http://www.w3.org/TR/html-markup/syntax.html#void-elements.
|
||||
* @const @private {!Object<string, boolean>}
|
||||
*/
|
||||
goog.dom.tags.VOID_TAGS_ = goog.object.createSet(
|
||||
'area', 'base', 'br', 'col', 'command', 'embed', 'hr', 'img', 'input',
|
||||
'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr');
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether the tag is void (with no contents allowed and no legal end
|
||||
* tag), for example 'br'.
|
||||
* @param {string} tagName The tag name in lower case.
|
||||
* @return {boolean}
|
||||
*/
|
||||
goog.dom.tags.isVoidTag = function(tagName) {
|
||||
return goog.dom.tags.VOID_TAGS_[tagName] === true;
|
||||
};
|
||||
425
resources/public/js/compiled/out/goog/events/keycodes.js
Normal file
425
resources/public/js/compiled/out/goog/events/keycodes.js
Normal file
|
|
@ -0,0 +1,425 @@
|
|||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Constant declarations for common key codes.
|
||||
*
|
||||
* @author eae@google.com (Emil A Eklund)
|
||||
* @see ../demos/keyhandler.html
|
||||
*/
|
||||
|
||||
goog.provide('goog.events.KeyCodes');
|
||||
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
goog.forwardDeclare('goog.events.BrowserEvent');
|
||||
|
||||
|
||||
/**
|
||||
* Key codes for common characters.
|
||||
*
|
||||
* This list is not localized and therefore some of the key codes are not
|
||||
* correct for non US keyboard layouts. See comments below.
|
||||
*
|
||||
* @enum {number}
|
||||
*/
|
||||
goog.events.KeyCodes = {
|
||||
WIN_KEY_FF_LINUX: 0,
|
||||
MAC_ENTER: 3,
|
||||
BACKSPACE: 8,
|
||||
TAB: 9,
|
||||
NUM_CENTER: 12, // NUMLOCK on FF/Safari Mac
|
||||
ENTER: 13,
|
||||
SHIFT: 16,
|
||||
CTRL: 17,
|
||||
ALT: 18,
|
||||
PAUSE: 19,
|
||||
CAPS_LOCK: 20,
|
||||
ESC: 27,
|
||||
SPACE: 32,
|
||||
PAGE_UP: 33, // also NUM_NORTH_EAST
|
||||
PAGE_DOWN: 34, // also NUM_SOUTH_EAST
|
||||
END: 35, // also NUM_SOUTH_WEST
|
||||
HOME: 36, // also NUM_NORTH_WEST
|
||||
LEFT: 37, // also NUM_WEST
|
||||
UP: 38, // also NUM_NORTH
|
||||
RIGHT: 39, // also NUM_EAST
|
||||
DOWN: 40, // also NUM_SOUTH
|
||||
PLUS_SIGN: 43, // NOT numpad plus
|
||||
PRINT_SCREEN: 44,
|
||||
INSERT: 45, // also NUM_INSERT
|
||||
DELETE: 46, // also NUM_DELETE
|
||||
ZERO: 48,
|
||||
ONE: 49,
|
||||
TWO: 50,
|
||||
THREE: 51,
|
||||
FOUR: 52,
|
||||
FIVE: 53,
|
||||
SIX: 54,
|
||||
SEVEN: 55,
|
||||
EIGHT: 56,
|
||||
NINE: 57,
|
||||
FF_SEMICOLON: 59, // Firefox (Gecko) fires this for semicolon instead of 186
|
||||
FF_EQUALS: 61, // Firefox (Gecko) fires this for equals instead of 187
|
||||
FF_DASH: 173, // Firefox (Gecko) fires this for dash instead of 189
|
||||
QUESTION_MARK: 63, // needs localization
|
||||
AT_SIGN: 64,
|
||||
A: 65,
|
||||
B: 66,
|
||||
C: 67,
|
||||
D: 68,
|
||||
E: 69,
|
||||
F: 70,
|
||||
G: 71,
|
||||
H: 72,
|
||||
I: 73,
|
||||
J: 74,
|
||||
K: 75,
|
||||
L: 76,
|
||||
M: 77,
|
||||
N: 78,
|
||||
O: 79,
|
||||
P: 80,
|
||||
Q: 81,
|
||||
R: 82,
|
||||
S: 83,
|
||||
T: 84,
|
||||
U: 85,
|
||||
V: 86,
|
||||
W: 87,
|
||||
X: 88,
|
||||
Y: 89,
|
||||
Z: 90,
|
||||
META: 91, // WIN_KEY_LEFT
|
||||
WIN_KEY_RIGHT: 92,
|
||||
CONTEXT_MENU: 93,
|
||||
NUM_ZERO: 96,
|
||||
NUM_ONE: 97,
|
||||
NUM_TWO: 98,
|
||||
NUM_THREE: 99,
|
||||
NUM_FOUR: 100,
|
||||
NUM_FIVE: 101,
|
||||
NUM_SIX: 102,
|
||||
NUM_SEVEN: 103,
|
||||
NUM_EIGHT: 104,
|
||||
NUM_NINE: 105,
|
||||
NUM_MULTIPLY: 106,
|
||||
NUM_PLUS: 107,
|
||||
NUM_MINUS: 109,
|
||||
NUM_PERIOD: 110,
|
||||
NUM_DIVISION: 111,
|
||||
F1: 112,
|
||||
F2: 113,
|
||||
F3: 114,
|
||||
F4: 115,
|
||||
F5: 116,
|
||||
F6: 117,
|
||||
F7: 118,
|
||||
F8: 119,
|
||||
F9: 120,
|
||||
F10: 121,
|
||||
F11: 122,
|
||||
F12: 123,
|
||||
NUMLOCK: 144,
|
||||
SCROLL_LOCK: 145,
|
||||
|
||||
// OS-specific media keys like volume controls and browser controls.
|
||||
FIRST_MEDIA_KEY: 166,
|
||||
LAST_MEDIA_KEY: 183,
|
||||
|
||||
SEMICOLON: 186, // needs localization
|
||||
DASH: 189, // needs localization
|
||||
EQUALS: 187, // needs localization
|
||||
COMMA: 188, // needs localization
|
||||
PERIOD: 190, // needs localization
|
||||
SLASH: 191, // needs localization
|
||||
APOSTROPHE: 192, // needs localization
|
||||
TILDE: 192, // needs localization
|
||||
SINGLE_QUOTE: 222, // needs localization
|
||||
OPEN_SQUARE_BRACKET: 219, // needs localization
|
||||
BACKSLASH: 220, // needs localization
|
||||
CLOSE_SQUARE_BRACKET: 221, // needs localization
|
||||
WIN_KEY: 224,
|
||||
MAC_FF_META:
|
||||
224, // Firefox (Gecko) fires this for the meta key instead of 91
|
||||
MAC_WK_CMD_LEFT: 91, // WebKit Left Command key fired, same as META
|
||||
MAC_WK_CMD_RIGHT: 93, // WebKit Right Command key fired, different from META
|
||||
WIN_IME: 229,
|
||||
|
||||
// "Reserved for future use". Some programs (e.g. the SlingPlayer 2.4 ActiveX
|
||||
// control) fire this as a hacky way to disable screensavers.
|
||||
VK_NONAME: 252,
|
||||
|
||||
// We've seen users whose machines fire this keycode at regular one
|
||||
// second intervals. The common thread among these users is that
|
||||
// they're all using Dell Inspiron laptops, so we suspect that this
|
||||
// indicates a hardware/bios problem.
|
||||
// http://en.community.dell.com/support-forums/laptop/f/3518/p/19285957/19523128.aspx
|
||||
PHANTOM: 255
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the event contains a text modifying key.
|
||||
* @param {goog.events.BrowserEvent} e A key event.
|
||||
* @return {boolean} Whether it's a text modifying key.
|
||||
*/
|
||||
goog.events.KeyCodes.isTextModifyingKeyEvent = function(e) {
|
||||
if (e.altKey && !e.ctrlKey || e.metaKey ||
|
||||
// Function keys don't generate text
|
||||
e.keyCode >= goog.events.KeyCodes.F1 &&
|
||||
e.keyCode <= goog.events.KeyCodes.F12) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// The following keys are quite harmless, even in combination with
|
||||
// CTRL, ALT or SHIFT.
|
||||
switch (e.keyCode) {
|
||||
case goog.events.KeyCodes.ALT:
|
||||
case goog.events.KeyCodes.CAPS_LOCK:
|
||||
case goog.events.KeyCodes.CONTEXT_MENU:
|
||||
case goog.events.KeyCodes.CTRL:
|
||||
case goog.events.KeyCodes.DOWN:
|
||||
case goog.events.KeyCodes.END:
|
||||
case goog.events.KeyCodes.ESC:
|
||||
case goog.events.KeyCodes.HOME:
|
||||
case goog.events.KeyCodes.INSERT:
|
||||
case goog.events.KeyCodes.LEFT:
|
||||
case goog.events.KeyCodes.MAC_FF_META:
|
||||
case goog.events.KeyCodes.META:
|
||||
case goog.events.KeyCodes.NUMLOCK:
|
||||
case goog.events.KeyCodes.NUM_CENTER:
|
||||
case goog.events.KeyCodes.PAGE_DOWN:
|
||||
case goog.events.KeyCodes.PAGE_UP:
|
||||
case goog.events.KeyCodes.PAUSE:
|
||||
case goog.events.KeyCodes.PHANTOM:
|
||||
case goog.events.KeyCodes.PRINT_SCREEN:
|
||||
case goog.events.KeyCodes.RIGHT:
|
||||
case goog.events.KeyCodes.SCROLL_LOCK:
|
||||
case goog.events.KeyCodes.SHIFT:
|
||||
case goog.events.KeyCodes.UP:
|
||||
case goog.events.KeyCodes.VK_NONAME:
|
||||
case goog.events.KeyCodes.WIN_KEY:
|
||||
case goog.events.KeyCodes.WIN_KEY_RIGHT:
|
||||
return false;
|
||||
case goog.events.KeyCodes.WIN_KEY_FF_LINUX:
|
||||
return !goog.userAgent.GECKO;
|
||||
default:
|
||||
return e.keyCode < goog.events.KeyCodes.FIRST_MEDIA_KEY ||
|
||||
e.keyCode > goog.events.KeyCodes.LAST_MEDIA_KEY;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the key fires a keypress event in the current browser.
|
||||
*
|
||||
* Accoridng to MSDN [1] IE only fires keypress events for the following keys:
|
||||
* - Letters: A - Z (uppercase and lowercase)
|
||||
* - Numerals: 0 - 9
|
||||
* - Symbols: ! @ # $ % ^ & * ( ) _ - + = < [ ] { } , . / ? \ | ' ` " ~
|
||||
* - System: ESC, SPACEBAR, ENTER
|
||||
*
|
||||
* That's not entirely correct though, for instance there's no distinction
|
||||
* between upper and lower case letters.
|
||||
*
|
||||
* [1] http://msdn2.microsoft.com/en-us/library/ms536939(VS.85).aspx)
|
||||
*
|
||||
* Safari is similar to IE, but does not fire keypress for ESC.
|
||||
*
|
||||
* Additionally, IE6 does not fire keydown or keypress events for letters when
|
||||
* the control or alt keys are held down and the shift key is not. IE7 does
|
||||
* fire keydown in these cases, though, but not keypress.
|
||||
*
|
||||
* @param {number} keyCode A key code.
|
||||
* @param {number=} opt_heldKeyCode Key code of a currently-held key.
|
||||
* @param {boolean=} opt_shiftKey Whether the shift key is held down.
|
||||
* @param {boolean=} opt_ctrlKey Whether the control key is held down.
|
||||
* @param {boolean=} opt_altKey Whether the alt key is held down.
|
||||
* @return {boolean} Whether it's a key that fires a keypress event.
|
||||
*/
|
||||
goog.events.KeyCodes.firesKeyPressEvent = function(
|
||||
keyCode, opt_heldKeyCode, opt_shiftKey, opt_ctrlKey, opt_altKey) {
|
||||
if (!goog.userAgent.IE && !goog.userAgent.EDGE &&
|
||||
!(goog.userAgent.WEBKIT && goog.userAgent.isVersionOrHigher('525'))) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (goog.userAgent.MAC && opt_altKey) {
|
||||
return goog.events.KeyCodes.isCharacterKey(keyCode);
|
||||
}
|
||||
|
||||
// Alt but not AltGr which is represented as Alt+Ctrl.
|
||||
if (opt_altKey && !opt_ctrlKey) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Saves Ctrl or Alt + key for IE and WebKit 525+, which won't fire keypress.
|
||||
// Non-IE browsers and WebKit prior to 525 won't get this far so no need to
|
||||
// check the user agent.
|
||||
if (goog.isNumber(opt_heldKeyCode)) {
|
||||
opt_heldKeyCode = goog.events.KeyCodes.normalizeKeyCode(opt_heldKeyCode);
|
||||
}
|
||||
if (!opt_shiftKey &&
|
||||
(opt_heldKeyCode == goog.events.KeyCodes.CTRL ||
|
||||
opt_heldKeyCode == goog.events.KeyCodes.ALT ||
|
||||
goog.userAgent.MAC && opt_heldKeyCode == goog.events.KeyCodes.META)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Some keys with Ctrl/Shift do not issue keypress in WEBKIT.
|
||||
if ((goog.userAgent.WEBKIT || goog.userAgent.EDGE) && opt_ctrlKey &&
|
||||
opt_shiftKey) {
|
||||
switch (keyCode) {
|
||||
case goog.events.KeyCodes.BACKSLASH:
|
||||
case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:
|
||||
case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:
|
||||
case goog.events.KeyCodes.TILDE:
|
||||
case goog.events.KeyCodes.SEMICOLON:
|
||||
case goog.events.KeyCodes.DASH:
|
||||
case goog.events.KeyCodes.EQUALS:
|
||||
case goog.events.KeyCodes.COMMA:
|
||||
case goog.events.KeyCodes.PERIOD:
|
||||
case goog.events.KeyCodes.SLASH:
|
||||
case goog.events.KeyCodes.APOSTROPHE:
|
||||
case goog.events.KeyCodes.SINGLE_QUOTE:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// When Ctrl+<somekey> is held in IE, it only fires a keypress once, but it
|
||||
// continues to fire keydown events as the event repeats.
|
||||
if (goog.userAgent.IE && opt_ctrlKey && opt_heldKeyCode == keyCode) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (keyCode) {
|
||||
case goog.events.KeyCodes.ENTER:
|
||||
return true;
|
||||
case goog.events.KeyCodes.ESC:
|
||||
return !(goog.userAgent.WEBKIT || goog.userAgent.EDGE);
|
||||
}
|
||||
|
||||
return goog.events.KeyCodes.isCharacterKey(keyCode);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the key produces a character.
|
||||
* This does not cover characters on non-US keyboards (Russian, Hebrew, etc.).
|
||||
*
|
||||
* @param {number} keyCode A key code.
|
||||
* @return {boolean} Whether it's a character key.
|
||||
*/
|
||||
goog.events.KeyCodes.isCharacterKey = function(keyCode) {
|
||||
if (keyCode >= goog.events.KeyCodes.ZERO &&
|
||||
keyCode <= goog.events.KeyCodes.NINE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (keyCode >= goog.events.KeyCodes.NUM_ZERO &&
|
||||
keyCode <= goog.events.KeyCodes.NUM_MULTIPLY) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (keyCode >= goog.events.KeyCodes.A && keyCode <= goog.events.KeyCodes.Z) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Safari sends zero key code for non-latin characters.
|
||||
if ((goog.userAgent.WEBKIT || goog.userAgent.EDGE) && keyCode == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (keyCode) {
|
||||
case goog.events.KeyCodes.SPACE:
|
||||
case goog.events.KeyCodes.PLUS_SIGN:
|
||||
case goog.events.KeyCodes.QUESTION_MARK:
|
||||
case goog.events.KeyCodes.AT_SIGN:
|
||||
case goog.events.KeyCodes.NUM_PLUS:
|
||||
case goog.events.KeyCodes.NUM_MINUS:
|
||||
case goog.events.KeyCodes.NUM_PERIOD:
|
||||
case goog.events.KeyCodes.NUM_DIVISION:
|
||||
case goog.events.KeyCodes.SEMICOLON:
|
||||
case goog.events.KeyCodes.FF_SEMICOLON:
|
||||
case goog.events.KeyCodes.DASH:
|
||||
case goog.events.KeyCodes.EQUALS:
|
||||
case goog.events.KeyCodes.FF_EQUALS:
|
||||
case goog.events.KeyCodes.COMMA:
|
||||
case goog.events.KeyCodes.PERIOD:
|
||||
case goog.events.KeyCodes.SLASH:
|
||||
case goog.events.KeyCodes.APOSTROPHE:
|
||||
case goog.events.KeyCodes.SINGLE_QUOTE:
|
||||
case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:
|
||||
case goog.events.KeyCodes.BACKSLASH:
|
||||
case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Normalizes key codes from OS/Browser-specific value to the general one.
|
||||
* @param {number} keyCode The native key code.
|
||||
* @return {number} The normalized key code.
|
||||
*/
|
||||
goog.events.KeyCodes.normalizeKeyCode = function(keyCode) {
|
||||
if (goog.userAgent.GECKO) {
|
||||
return goog.events.KeyCodes.normalizeGeckoKeyCode(keyCode);
|
||||
} else if (goog.userAgent.MAC && goog.userAgent.WEBKIT) {
|
||||
return goog.events.KeyCodes.normalizeMacWebKitKeyCode(keyCode);
|
||||
} else {
|
||||
return keyCode;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Normalizes key codes from their Gecko-specific value to the general one.
|
||||
* @param {number} keyCode The native key code.
|
||||
* @return {number} The normalized key code.
|
||||
*/
|
||||
goog.events.KeyCodes.normalizeGeckoKeyCode = function(keyCode) {
|
||||
switch (keyCode) {
|
||||
case goog.events.KeyCodes.FF_EQUALS:
|
||||
return goog.events.KeyCodes.EQUALS;
|
||||
case goog.events.KeyCodes.FF_SEMICOLON:
|
||||
return goog.events.KeyCodes.SEMICOLON;
|
||||
case goog.events.KeyCodes.FF_DASH:
|
||||
return goog.events.KeyCodes.DASH;
|
||||
case goog.events.KeyCodes.MAC_FF_META:
|
||||
return goog.events.KeyCodes.META;
|
||||
case goog.events.KeyCodes.WIN_KEY_FF_LINUX:
|
||||
return goog.events.KeyCodes.WIN_KEY;
|
||||
default:
|
||||
return keyCode;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Normalizes key codes from their Mac WebKit-specific value to the general one.
|
||||
* @param {number} keyCode The native key code.
|
||||
* @return {number} The normalized key code.
|
||||
*/
|
||||
goog.events.KeyCodes.normalizeMacWebKitKeyCode = function(keyCode) {
|
||||
switch (keyCode) {
|
||||
case goog.events.KeyCodes.MAC_WK_CMD_RIGHT: // 93
|
||||
return goog.events.KeyCodes.META; // 91
|
||||
default:
|
||||
return keyCode;
|
||||
}
|
||||
};
|
||||
110
resources/public/js/compiled/out/goog/fs/url.js
Normal file
110
resources/public/js/compiled/out/goog/fs/url.js
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
// Copyright 2015 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Wrapper for URL and its createObjectUrl and revokeObjectUrl
|
||||
* methods that are part of the HTML5 File API.
|
||||
*/
|
||||
|
||||
goog.provide('goog.fs.url');
|
||||
|
||||
|
||||
/**
|
||||
* Creates a blob URL for a blob object.
|
||||
* Throws an error if the browser does not support Object Urls.
|
||||
*
|
||||
* @param {!Blob} blob The object for which to create the URL.
|
||||
* @return {string} The URL for the object.
|
||||
*/
|
||||
goog.fs.url.createObjectUrl = function(blob) {
|
||||
return goog.fs.url.getUrlObject_().createObjectURL(blob);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Revokes a URL created by {@link goog.fs.url.createObjectUrl}.
|
||||
* Throws an error if the browser does not support Object Urls.
|
||||
*
|
||||
* @param {string} url The URL to revoke.
|
||||
*/
|
||||
goog.fs.url.revokeObjectUrl = function(url) {
|
||||
goog.fs.url.getUrlObject_().revokeObjectURL(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{createObjectURL: (function(!Blob): string),
|
||||
* revokeObjectURL: function(string): void}}
|
||||
*/
|
||||
goog.fs.url.UrlObject_;
|
||||
|
||||
|
||||
/**
|
||||
* Get the object that has the createObjectURL and revokeObjectURL functions for
|
||||
* this browser.
|
||||
*
|
||||
* @return {goog.fs.url.UrlObject_} The object for this browser.
|
||||
* @private
|
||||
*/
|
||||
goog.fs.url.getUrlObject_ = function() {
|
||||
var urlObject = goog.fs.url.findUrlObject_();
|
||||
if (urlObject != null) {
|
||||
return urlObject;
|
||||
} else {
|
||||
throw Error('This browser doesn\'t seem to support blob URLs');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Finds the object that has the createObjectURL and revokeObjectURL functions
|
||||
* for this browser.
|
||||
*
|
||||
* @return {?goog.fs.url.UrlObject_} The object for this browser or null if the
|
||||
* browser does not support Object Urls.
|
||||
* @suppress {unnecessaryCasts} Depending on how the code is compiled, casting
|
||||
* goog.global to UrlObject_ may result in unnecessary cast warning.
|
||||
* However, the cast cannot be removed because with different set of
|
||||
* compiler flags, the cast is indeed necessary. As such, silencing it.
|
||||
* @private
|
||||
*/
|
||||
goog.fs.url.findUrlObject_ = function() {
|
||||
// This is what the spec says to do
|
||||
// http://dev.w3.org/2006/webapi/FileAPI/#dfn-createObjectURL
|
||||
if (goog.isDef(goog.global.URL) &&
|
||||
goog.isDef(goog.global.URL.createObjectURL)) {
|
||||
return /** @type {goog.fs.url.UrlObject_} */ (goog.global.URL);
|
||||
// This is what Chrome does (as of 10.0.648.6 dev)
|
||||
} else if (
|
||||
goog.isDef(goog.global.webkitURL) &&
|
||||
goog.isDef(goog.global.webkitURL.createObjectURL)) {
|
||||
return /** @type {goog.fs.url.UrlObject_} */ (goog.global.webkitURL);
|
||||
// This is what the spec used to say to do
|
||||
} else if (goog.isDef(goog.global.createObjectURL)) {
|
||||
return /** @type {goog.fs.url.UrlObject_} */ (goog.global);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks whether this browser supports Object Urls. If not, calls to
|
||||
* createObjectUrl and revokeObjectUrl will result in an error.
|
||||
*
|
||||
* @return {boolean} True if this browser supports Object Urls.
|
||||
*/
|
||||
goog.fs.url.browserSupportsObjectUrls = function() {
|
||||
return goog.fs.url.findUrlObject_() != null;
|
||||
};
|
||||
456
resources/public/js/compiled/out/goog/functions/functions.js
Normal file
456
resources/public/js/compiled/out/goog/functions/functions.js
Normal file
|
|
@ -0,0 +1,456 @@
|
|||
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities for creating functions. Loosely inspired by the
|
||||
* java classes: http://goo.gl/GM0Hmu and http://goo.gl/6k7nI8.
|
||||
*
|
||||
* @author nicksantos@google.com (Nick Santos)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.functions');
|
||||
|
||||
|
||||
/**
|
||||
* Creates a function that always returns the same value.
|
||||
* @param {T} retValue The value to return.
|
||||
* @return {function():T} The new function.
|
||||
* @template T
|
||||
*/
|
||||
goog.functions.constant = function(retValue) {
|
||||
return function() { return retValue; };
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Always returns false.
|
||||
* @type {function(...): boolean}
|
||||
*/
|
||||
goog.functions.FALSE = goog.functions.constant(false);
|
||||
|
||||
|
||||
/**
|
||||
* Always returns true.
|
||||
* @type {function(...): boolean}
|
||||
*/
|
||||
goog.functions.TRUE = goog.functions.constant(true);
|
||||
|
||||
|
||||
/**
|
||||
* Always returns NULL.
|
||||
* @type {function(...): null}
|
||||
*/
|
||||
goog.functions.NULL = goog.functions.constant(null);
|
||||
|
||||
|
||||
/**
|
||||
* A simple function that returns the first argument of whatever is passed
|
||||
* into it.
|
||||
* @param {T=} opt_returnValue The single value that will be returned.
|
||||
* @param {...*} var_args Optional trailing arguments. These are ignored.
|
||||
* @return {T} The first argument passed in, or undefined if nothing was passed.
|
||||
* @template T
|
||||
*/
|
||||
goog.functions.identity = function(opt_returnValue, var_args) {
|
||||
return opt_returnValue;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a function that always throws an error with the given message.
|
||||
* @param {string} message The error message.
|
||||
* @return {!Function} The error-throwing function.
|
||||
*/
|
||||
goog.functions.error = function(message) {
|
||||
return function() { throw Error(message); };
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a function that throws the given object.
|
||||
* @param {*} err An object to be thrown.
|
||||
* @return {!Function} The error-throwing function.
|
||||
*/
|
||||
goog.functions.fail = function(err) {
|
||||
return function() { throw err; };
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Given a function, create a function that keeps opt_numArgs arguments and
|
||||
* silently discards all additional arguments.
|
||||
* @param {Function} f The original function.
|
||||
* @param {number=} opt_numArgs The number of arguments to keep. Defaults to 0.
|
||||
* @return {!Function} A version of f that only keeps the first opt_numArgs
|
||||
* arguments.
|
||||
*/
|
||||
goog.functions.lock = function(f, opt_numArgs) {
|
||||
opt_numArgs = opt_numArgs || 0;
|
||||
return function() {
|
||||
return f.apply(this, Array.prototype.slice.call(arguments, 0, opt_numArgs));
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a function that returns its nth argument.
|
||||
* @param {number} n The position of the return argument.
|
||||
* @return {!Function} A new function.
|
||||
*/
|
||||
goog.functions.nth = function(n) {
|
||||
return function() { return arguments[n]; };
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Like goog.partial(), except that arguments are added after arguments to the
|
||||
* returned function.
|
||||
*
|
||||
* Usage:
|
||||
* function f(arg1, arg2, arg3, arg4) { ... }
|
||||
* var g = goog.functions.partialRight(f, arg3, arg4);
|
||||
* g(arg1, arg2);
|
||||
*
|
||||
* @param {!Function} fn A function to partially apply.
|
||||
* @param {...*} var_args Additional arguments that are partially applied to fn
|
||||
* at the end.
|
||||
* @return {!Function} A partially-applied form of the function goog.partial()
|
||||
* was invoked as a method of.
|
||||
*/
|
||||
goog.functions.partialRight = function(fn, var_args) {
|
||||
var rightArgs = Array.prototype.slice.call(arguments, 1);
|
||||
return function() {
|
||||
var newArgs = Array.prototype.slice.call(arguments);
|
||||
newArgs.push.apply(newArgs, rightArgs);
|
||||
return fn.apply(this, newArgs);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Given a function, create a new function that swallows its return value
|
||||
* and replaces it with a new one.
|
||||
* @param {Function} f A function.
|
||||
* @param {T} retValue A new return value.
|
||||
* @return {function(...?):T} A new function.
|
||||
* @template T
|
||||
*/
|
||||
goog.functions.withReturnValue = function(f, retValue) {
|
||||
return goog.functions.sequence(f, goog.functions.constant(retValue));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a function that returns whether its argument equals the given value.
|
||||
*
|
||||
* Example:
|
||||
* var key = goog.object.findKey(obj, goog.functions.equalTo('needle'));
|
||||
*
|
||||
* @param {*} value The value to compare to.
|
||||
* @param {boolean=} opt_useLooseComparison Whether to use a loose (==)
|
||||
* comparison rather than a strict (===) one. Defaults to false.
|
||||
* @return {function(*):boolean} The new function.
|
||||
*/
|
||||
goog.functions.equalTo = function(value, opt_useLooseComparison) {
|
||||
return function(other) {
|
||||
return opt_useLooseComparison ? (value == other) : (value === other);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates the composition of the functions passed in.
|
||||
* For example, (goog.functions.compose(f, g))(a) is equivalent to f(g(a)).
|
||||
* @param {function(...?):T} fn The final function.
|
||||
* @param {...Function} var_args A list of functions.
|
||||
* @return {function(...?):T} The composition of all inputs.
|
||||
* @template T
|
||||
*/
|
||||
goog.functions.compose = function(fn, var_args) {
|
||||
var functions = arguments;
|
||||
var length = functions.length;
|
||||
return function() {
|
||||
var result;
|
||||
if (length) {
|
||||
result = functions[length - 1].apply(this, arguments);
|
||||
}
|
||||
|
||||
for (var i = length - 2; i >= 0; i--) {
|
||||
result = functions[i].call(this, result);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a function that calls the functions passed in in sequence, and
|
||||
* returns the value of the last function. For example,
|
||||
* (goog.functions.sequence(f, g))(x) is equivalent to f(x),g(x).
|
||||
* @param {...Function} var_args A list of functions.
|
||||
* @return {!Function} A function that calls all inputs in sequence.
|
||||
*/
|
||||
goog.functions.sequence = function(var_args) {
|
||||
var functions = arguments;
|
||||
var length = functions.length;
|
||||
return function() {
|
||||
var result;
|
||||
for (var i = 0; i < length; i++) {
|
||||
result = functions[i].apply(this, arguments);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a function that returns true if each of its components evaluates
|
||||
* to true. The components are evaluated in order, and the evaluation will be
|
||||
* short-circuited as soon as a function returns false.
|
||||
* For example, (goog.functions.and(f, g))(x) is equivalent to f(x) && g(x).
|
||||
* @param {...Function} var_args A list of functions.
|
||||
* @return {function(...?):boolean} A function that ANDs its component
|
||||
* functions.
|
||||
*/
|
||||
goog.functions.and = function(var_args) {
|
||||
var functions = arguments;
|
||||
var length = functions.length;
|
||||
return function() {
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (!functions[i].apply(this, arguments)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a function that returns true if any of its components evaluates
|
||||
* to true. The components are evaluated in order, and the evaluation will be
|
||||
* short-circuited as soon as a function returns true.
|
||||
* For example, (goog.functions.or(f, g))(x) is equivalent to f(x) || g(x).
|
||||
* @param {...Function} var_args A list of functions.
|
||||
* @return {function(...?):boolean} A function that ORs its component
|
||||
* functions.
|
||||
*/
|
||||
goog.functions.or = function(var_args) {
|
||||
var functions = arguments;
|
||||
var length = functions.length;
|
||||
return function() {
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (functions[i].apply(this, arguments)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a function that returns the Boolean opposite of a provided function.
|
||||
* For example, (goog.functions.not(f))(x) is equivalent to !f(x).
|
||||
* @param {!Function} f The original function.
|
||||
* @return {function(...?):boolean} A function that delegates to f and returns
|
||||
* opposite.
|
||||
*/
|
||||
goog.functions.not = function(f) {
|
||||
return function() { return !f.apply(this, arguments); };
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generic factory function to construct an object given the constructor
|
||||
* and the arguments. Intended to be bound to create object factories.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* var factory = goog.partial(goog.functions.create, Class);
|
||||
*
|
||||
* @param {function(new:T, ...)} constructor The constructor for the Object.
|
||||
* @param {...*} var_args The arguments to be passed to the constructor.
|
||||
* @return {T} A new instance of the class given in {@code constructor}.
|
||||
* @template T
|
||||
*/
|
||||
goog.functions.create = function(constructor, var_args) {
|
||||
/**
|
||||
* @constructor
|
||||
* @final
|
||||
*/
|
||||
var temp = function() {};
|
||||
temp.prototype = constructor.prototype;
|
||||
|
||||
// obj will have constructor's prototype in its chain and
|
||||
// 'obj instanceof constructor' will be true.
|
||||
var obj = new temp();
|
||||
|
||||
// obj is initialized by constructor.
|
||||
// arguments is only array-like so lacks shift(), but can be used with
|
||||
// the Array prototype function.
|
||||
constructor.apply(obj, Array.prototype.slice.call(arguments, 1));
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the return value cache should be used.
|
||||
* This should only be used to disable caches when testing.
|
||||
*/
|
||||
goog.define('goog.functions.CACHE_RETURN_VALUE', true);
|
||||
|
||||
|
||||
/**
|
||||
* Gives a wrapper function that caches the return value of a parameterless
|
||||
* function when first called.
|
||||
*
|
||||
* When called for the first time, the given function is called and its
|
||||
* return value is cached (thus this is only appropriate for idempotent
|
||||
* functions). Subsequent calls will return the cached return value. This
|
||||
* allows the evaluation of expensive functions to be delayed until first used.
|
||||
*
|
||||
* To cache the return values of functions with parameters, see goog.memoize.
|
||||
*
|
||||
* @param {!function():T} fn A function to lazily evaluate.
|
||||
* @return {!function():T} A wrapped version the function.
|
||||
* @template T
|
||||
*/
|
||||
goog.functions.cacheReturnValue = function(fn) {
|
||||
var called = false;
|
||||
var value;
|
||||
|
||||
return function() {
|
||||
if (!goog.functions.CACHE_RETURN_VALUE) {
|
||||
return fn();
|
||||
}
|
||||
|
||||
if (!called) {
|
||||
value = fn();
|
||||
called = true;
|
||||
}
|
||||
|
||||
return value;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Wraps a function to allow it to be called, at most, once. All
|
||||
* additional calls are no-ops.
|
||||
*
|
||||
* This is particularly useful for initialization functions
|
||||
* that should be called, at most, once.
|
||||
*
|
||||
* @param {function():*} f Function to call.
|
||||
* @return {function():undefined} Wrapped function.
|
||||
*/
|
||||
goog.functions.once = function(f) {
|
||||
// Keep a reference to the function that we null out when we're done with
|
||||
// it -- that way, the function can be GC'd when we're done with it.
|
||||
var inner = f;
|
||||
return function() {
|
||||
if (inner) {
|
||||
var tmp = inner;
|
||||
inner = null;
|
||||
tmp();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Wraps a function to allow it to be called, at most, once for each sequence of
|
||||
* calls fired repeatedly so long as they are fired less than a specified
|
||||
* interval apart (in milliseconds). Whether it receives one signal or multiple,
|
||||
* it will always wait until a full interval has elapsed since the last signal
|
||||
* before performing the action, passing the arguments from the last call of the
|
||||
* debouncing decorator into the decorated function.
|
||||
*
|
||||
* This is particularly useful for bulking up repeated user actions (e.g. only
|
||||
* refreshing a view once a user finishes typing rather than updating with every
|
||||
* keystroke). For more stateful debouncing with support for pausing, resuming,
|
||||
* and canceling debounced actions, use {@code goog.async.Debouncer}.
|
||||
*
|
||||
* @param {function(this:SCOPE, ...?)} f Function to call.
|
||||
* @param {number} interval Interval over which to debounce. The function will
|
||||
* only be called after the full interval has elapsed since the last call.
|
||||
* @param {SCOPE=} opt_scope Object in whose scope to call the function.
|
||||
* @return {function(...?): undefined} Wrapped function.
|
||||
* @template SCOPE
|
||||
*/
|
||||
goog.functions.debounce = function(f, interval, opt_scope) {
|
||||
if (opt_scope) {
|
||||
f = goog.bind(f, opt_scope);
|
||||
}
|
||||
var timeout = null;
|
||||
return /** @type {function(...?)} */ (function(var_args) {
|
||||
goog.global.clearTimeout(timeout);
|
||||
var args = arguments;
|
||||
timeout =
|
||||
goog.global.setTimeout(function() { f.apply(null, args); }, interval);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Wraps a function to allow it to be called, at most, once per interval
|
||||
* (specified in milliseconds). If it is called multiple times while it is
|
||||
* waiting, it will only perform the action once at the end of the interval,
|
||||
* passing the arguments from the last call of the throttling decorator into the
|
||||
* decorated function.
|
||||
*
|
||||
* This is particularly useful for limiting repeated user requests (e.g.
|
||||
* preventing a user from spamming a server with frequent view refreshes). For
|
||||
* more stateful throttling with support for pausing, resuming, and canceling
|
||||
* throttled actions, use {@code goog.async.Throttle}.
|
||||
*
|
||||
* @param {function(this:SCOPE, ...?)} f Function to call.
|
||||
* @param {number} interval Interval over which to throttle. The function can
|
||||
* only be called once per interval.
|
||||
* @param {SCOPE=} opt_scope Object in whose scope to call the function.
|
||||
* @return {function(...?): undefined} Wrapped function.
|
||||
* @template SCOPE
|
||||
*/
|
||||
goog.functions.throttle = function(f, interval, opt_scope) {
|
||||
if (opt_scope) {
|
||||
f = goog.bind(f, opt_scope);
|
||||
}
|
||||
var timeout = null;
|
||||
var shouldFire = false;
|
||||
var args = [];
|
||||
|
||||
var handleTimeout = function() {
|
||||
timeout = null;
|
||||
if (shouldFire) {
|
||||
shouldFire = false;
|
||||
fire();
|
||||
}
|
||||
};
|
||||
|
||||
var fire = function() {
|
||||
timeout = goog.global.setTimeout(handleTimeout, interval);
|
||||
f.apply(null, args);
|
||||
};
|
||||
|
||||
return /** @type {function(...?)} */ (function(var_args) {
|
||||
args = arguments;
|
||||
if (!timeout) {
|
||||
fire();
|
||||
} else {
|
||||
shouldFire = true;
|
||||
}
|
||||
});
|
||||
};
|
||||
948
resources/public/js/compiled/out/goog/html/safehtml.js
Normal file
948
resources/public/js/compiled/out/goog/html/safehtml.js
Normal file
|
|
@ -0,0 +1,948 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview The SafeHtml type and its builders.
|
||||
*
|
||||
* TODO(xtof): Link to document stating type contract.
|
||||
*/
|
||||
|
||||
goog.provide('goog.html.SafeHtml');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.dom.tags');
|
||||
goog.require('goog.html.SafeStyle');
|
||||
goog.require('goog.html.SafeStyleSheet');
|
||||
goog.require('goog.html.SafeUrl');
|
||||
goog.require('goog.html.TrustedResourceUrl');
|
||||
goog.require('goog.i18n.bidi.Dir');
|
||||
goog.require('goog.i18n.bidi.DirectionalString');
|
||||
goog.require('goog.labs.userAgent.browser');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.string.Const');
|
||||
goog.require('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A string that is safe to use in HTML context in DOM APIs and HTML documents.
|
||||
*
|
||||
* A SafeHtml is a string-like object that carries the security type contract
|
||||
* that its value as a string will not cause untrusted script execution when
|
||||
* evaluated as HTML in a browser.
|
||||
*
|
||||
* Values of this type are guaranteed to be safe to use in HTML contexts,
|
||||
* such as, assignment to the innerHTML DOM property, or interpolation into
|
||||
* a HTML template in HTML PC_DATA context, in the sense that the use will not
|
||||
* result in a Cross-Site-Scripting vulnerability.
|
||||
*
|
||||
* Instances of this type must be created via the factory methods
|
||||
* ({@code goog.html.SafeHtml.create}, {@code goog.html.SafeHtml.htmlEscape}),
|
||||
* etc and not by invoking its constructor. The constructor intentionally
|
||||
* takes no parameters and the type is immutable; hence only a default instance
|
||||
* corresponding to the empty string can be obtained via constructor invocation.
|
||||
*
|
||||
* @see goog.html.SafeHtml#create
|
||||
* @see goog.html.SafeHtml#htmlEscape
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
* @implements {goog.i18n.bidi.DirectionalString}
|
||||
* @implements {goog.string.TypedString}
|
||||
*/
|
||||
goog.html.SafeHtml = function() {
|
||||
/**
|
||||
* The contained value of this SafeHtml. The field has a purposely ugly
|
||||
* name to make (non-compiled) code that attempts to directly access this
|
||||
* field stand out.
|
||||
* @private {string}
|
||||
*/
|
||||
this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ = '';
|
||||
|
||||
/**
|
||||
* A type marker used to implement additional run-time type checking.
|
||||
* @see goog.html.SafeHtml#unwrap
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
this.SAFE_HTML_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =
|
||||
goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
|
||||
|
||||
/**
|
||||
* This SafeHtml's directionality, or null if unknown.
|
||||
* @private {?goog.i18n.bidi.Dir}
|
||||
*/
|
||||
this.dir_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.SafeHtml.prototype.implementsGoogI18nBidiDirectionalString = true;
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.html.SafeHtml.prototype.getDirection = function() {
|
||||
return this.dir_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.SafeHtml.prototype.implementsGoogStringTypedString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Returns this SafeHtml's value as string.
|
||||
*
|
||||
* IMPORTANT: In code where it is security relevant that an object's type is
|
||||
* indeed {@code SafeHtml}, use {@code goog.html.SafeHtml.unwrap} instead of
|
||||
* this method. If in doubt, assume that it's security relevant. In particular,
|
||||
* note that goog.html functions which return a goog.html type do not guarantee
|
||||
* that the returned instance is of the right type. For example:
|
||||
*
|
||||
* <pre>
|
||||
* var fakeSafeHtml = new String('fake');
|
||||
* fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;
|
||||
* var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);
|
||||
* // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by
|
||||
* // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml
|
||||
* // instanceof goog.html.SafeHtml.
|
||||
* </pre>
|
||||
*
|
||||
* @see goog.html.SafeHtml#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeHtml.prototype.getTypedStringValue = function() {
|
||||
return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_;
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a debug string-representation of this value.
|
||||
*
|
||||
* To obtain the actual string value wrapped in a SafeHtml, use
|
||||
* {@code goog.html.SafeHtml.unwrap}.
|
||||
*
|
||||
* @see goog.html.SafeHtml#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeHtml.prototype.toString = function() {
|
||||
return 'SafeHtml{' + this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ +
|
||||
'}';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a runtime check that the provided object is indeed a SafeHtml
|
||||
* object, and returns its value.
|
||||
* @param {!goog.html.SafeHtml} safeHtml The object to extract from.
|
||||
* @return {string} The SafeHtml object's contained string, unless the run-time
|
||||
* type check fails. In that case, {@code unwrap} returns an innocuous
|
||||
* string, or, if assertions are enabled, throws
|
||||
* {@code goog.asserts.AssertionError}.
|
||||
*/
|
||||
goog.html.SafeHtml.unwrap = function(safeHtml) {
|
||||
// Perform additional run-time type-checking to ensure that safeHtml is indeed
|
||||
// an instance of the expected type. This provides some additional protection
|
||||
// against security bugs due to application code that disables type checks.
|
||||
// Specifically, the following checks are performed:
|
||||
// 1. The object is an instance of the expected type.
|
||||
// 2. The object is not an instance of a subclass.
|
||||
// 3. The object carries a type marker for the expected type. "Faking" an
|
||||
// object requires a reference to the type marker, which has names intended
|
||||
// to stand out in code reviews.
|
||||
if (safeHtml instanceof goog.html.SafeHtml &&
|
||||
safeHtml.constructor === goog.html.SafeHtml &&
|
||||
safeHtml.SAFE_HTML_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===
|
||||
goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
|
||||
return safeHtml.privateDoNotAccessOrElseSafeHtmlWrappedValue_;
|
||||
} else {
|
||||
goog.asserts.fail('expected object of type SafeHtml, got \'' +
|
||||
safeHtml + '\' of type ' + goog.typeOf(safeHtml));
|
||||
return 'type_error:SafeHtml';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Shorthand for union of types that can sensibly be converted to strings
|
||||
* or might already be SafeHtml (as SafeHtml is a goog.string.TypedString).
|
||||
* @private
|
||||
* @typedef {string|number|boolean|!goog.string.TypedString|
|
||||
* !goog.i18n.bidi.DirectionalString}
|
||||
*/
|
||||
goog.html.SafeHtml.TextOrHtml_;
|
||||
|
||||
|
||||
/**
|
||||
* Returns HTML-escaped text as a SafeHtml object.
|
||||
*
|
||||
* If text is of a type that implements
|
||||
* {@code goog.i18n.bidi.DirectionalString}, the directionality of the new
|
||||
* {@code SafeHtml} object is set to {@code text}'s directionality, if known.
|
||||
* Otherwise, the directionality of the resulting SafeHtml is unknown (i.e.,
|
||||
* {@code null}).
|
||||
*
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_} textOrHtml The text to escape. If
|
||||
* the parameter is of type SafeHtml it is returned directly (no escaping
|
||||
* is done).
|
||||
* @return {!goog.html.SafeHtml} The escaped text, wrapped as a SafeHtml.
|
||||
*/
|
||||
goog.html.SafeHtml.htmlEscape = function(textOrHtml) {
|
||||
if (textOrHtml instanceof goog.html.SafeHtml) {
|
||||
return textOrHtml;
|
||||
}
|
||||
var dir = null;
|
||||
if (textOrHtml.implementsGoogI18nBidiDirectionalString) {
|
||||
dir = textOrHtml.getDirection();
|
||||
}
|
||||
var textAsString;
|
||||
if (textOrHtml.implementsGoogStringTypedString) {
|
||||
textAsString = textOrHtml.getTypedStringValue();
|
||||
} else {
|
||||
textAsString = String(textOrHtml);
|
||||
}
|
||||
return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
goog.string.htmlEscape(textAsString), dir);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns HTML-escaped text as a SafeHtml object, with newlines changed to
|
||||
* <br>.
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_} textOrHtml The text to escape. If
|
||||
* the parameter is of type SafeHtml it is returned directly (no escaping
|
||||
* is done).
|
||||
* @return {!goog.html.SafeHtml} The escaped text, wrapped as a SafeHtml.
|
||||
*/
|
||||
goog.html.SafeHtml.htmlEscapePreservingNewlines = function(textOrHtml) {
|
||||
if (textOrHtml instanceof goog.html.SafeHtml) {
|
||||
return textOrHtml;
|
||||
}
|
||||
var html = goog.html.SafeHtml.htmlEscape(textOrHtml);
|
||||
return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
goog.string.newLineToBr(goog.html.SafeHtml.unwrap(html)),
|
||||
html.getDirection());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns HTML-escaped text as a SafeHtml object, with newlines changed to
|
||||
* <br> and escaping whitespace to preserve spatial formatting. Character
|
||||
* entity #160 is used to make it safer for XML.
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_} textOrHtml The text to escape. If
|
||||
* the parameter is of type SafeHtml it is returned directly (no escaping
|
||||
* is done).
|
||||
* @return {!goog.html.SafeHtml} The escaped text, wrapped as a SafeHtml.
|
||||
*/
|
||||
goog.html.SafeHtml.htmlEscapePreservingNewlinesAndSpaces = function(
|
||||
textOrHtml) {
|
||||
if (textOrHtml instanceof goog.html.SafeHtml) {
|
||||
return textOrHtml;
|
||||
}
|
||||
var html = goog.html.SafeHtml.htmlEscape(textOrHtml);
|
||||
return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
goog.string.whitespaceEscape(goog.html.SafeHtml.unwrap(html)),
|
||||
html.getDirection());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Coerces an arbitrary object into a SafeHtml object.
|
||||
*
|
||||
* If {@code textOrHtml} is already of type {@code goog.html.SafeHtml}, the same
|
||||
* object is returned. Otherwise, {@code textOrHtml} is coerced to string, and
|
||||
* HTML-escaped. If {@code textOrHtml} is of a type that implements
|
||||
* {@code goog.i18n.bidi.DirectionalString}, its directionality, if known, is
|
||||
* preserved.
|
||||
*
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_} textOrHtml The text or SafeHtml to
|
||||
* coerce.
|
||||
* @return {!goog.html.SafeHtml} The resulting SafeHtml object.
|
||||
* @deprecated Use goog.html.SafeHtml.htmlEscape.
|
||||
*/
|
||||
goog.html.SafeHtml.from = goog.html.SafeHtml.htmlEscape;
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeHtml.VALID_NAMES_IN_TAG_ = /^[a-zA-Z0-9-]+$/;
|
||||
|
||||
|
||||
/**
|
||||
* Set of attributes containing URL as defined at
|
||||
* http://www.w3.org/TR/html5/index.html#attributes-1.
|
||||
* @private @const {!Object<string,boolean>}
|
||||
*/
|
||||
goog.html.SafeHtml.URL_ATTRIBUTES_ = goog.object.createSet(
|
||||
'action', 'cite', 'data', 'formaction', 'href', 'manifest', 'poster',
|
||||
'src');
|
||||
|
||||
|
||||
/**
|
||||
* Tags which are unsupported via create(). They might be supported via a
|
||||
* tag-specific create method. These are tags which might require a
|
||||
* TrustedResourceUrl in one of their attributes or a restricted type for
|
||||
* their content.
|
||||
* @private @const {!Object<string,boolean>}
|
||||
*/
|
||||
goog.html.SafeHtml.NOT_ALLOWED_TAG_NAMES_ = goog.object.createSet(
|
||||
goog.dom.TagName.APPLET, goog.dom.TagName.BASE, goog.dom.TagName.EMBED,
|
||||
goog.dom.TagName.IFRAME, goog.dom.TagName.LINK, goog.dom.TagName.MATH,
|
||||
goog.dom.TagName.META, goog.dom.TagName.OBJECT, goog.dom.TagName.SCRIPT,
|
||||
goog.dom.TagName.STYLE, goog.dom.TagName.SVG, goog.dom.TagName.TEMPLATE);
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {string|number|goog.string.TypedString|
|
||||
* goog.html.SafeStyle.PropertyMap}
|
||||
*/
|
||||
goog.html.SafeHtml.AttributeValue;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeHtml content consisting of a tag with optional attributes and
|
||||
* optional content.
|
||||
*
|
||||
* For convenience tag names and attribute names are accepted as regular
|
||||
* strings, instead of goog.string.Const. Nevertheless, you should not pass
|
||||
* user-controlled values to these parameters. Note that these parameters are
|
||||
* syntactically validated at runtime, and invalid values will result in
|
||||
* an exception.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* goog.html.SafeHtml.create('br');
|
||||
* goog.html.SafeHtml.create('div', {'class': 'a'});
|
||||
* goog.html.SafeHtml.create('p', {}, 'a');
|
||||
* goog.html.SafeHtml.create('p', {}, goog.html.SafeHtml.create('br'));
|
||||
*
|
||||
* goog.html.SafeHtml.create('span', {
|
||||
* 'style': {'margin': '0'}
|
||||
* });
|
||||
*
|
||||
* To guarantee SafeHtml's type contract is upheld there are restrictions on
|
||||
* attribute values and tag names.
|
||||
*
|
||||
* - For attributes which contain script code (on*), a goog.string.Const is
|
||||
* required.
|
||||
* - For attributes which contain style (style), a goog.html.SafeStyle or a
|
||||
* goog.html.SafeStyle.PropertyMap is required.
|
||||
* - For attributes which are interpreted as URLs (e.g. src, href) a
|
||||
* goog.html.SafeUrl, goog.string.Const or string is required. If a string
|
||||
* is passed, it will be sanitized with SafeUrl.sanitize().
|
||||
* - For tags which can load code or set security relevant page metadata,
|
||||
* more specific goog.html.SafeHtml.create*() functions must be used. Tags
|
||||
* which are not supported by this function are applet, base, embed, iframe,
|
||||
* link, math, object, script, style, svg, and template.
|
||||
*
|
||||
* @param {string} tagName The name of the tag. Only tag names consisting of
|
||||
* [a-zA-Z0-9-] are allowed. Tag names documented above are disallowed.
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* Mapping from attribute names to their values. Only attribute names
|
||||
* consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes
|
||||
* the attribute to be omitted.
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content Content to
|
||||
* HTML-escape and put inside the tag. This must be empty for void tags
|
||||
* like <br>. Array elements are concatenated.
|
||||
* @return {!goog.html.SafeHtml} The SafeHtml content with the tag.
|
||||
* @throws {Error} If invalid tag name, attribute name, or attribute value is
|
||||
* provided.
|
||||
* @throws {goog.asserts.AssertionError} If content for void tag is provided.
|
||||
*/
|
||||
goog.html.SafeHtml.create = function(tagName, opt_attributes, opt_content) {
|
||||
goog.html.SafeHtml.verifyTagName(tagName);
|
||||
return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(
|
||||
tagName, opt_attributes, opt_content);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Verifies if the tag name is valid and if it doesn't change the context.
|
||||
* E.g. STRONG is fine but SCRIPT throws because it changes context. See
|
||||
* goog.html.SafeHtml.create for an explanation of allowed tags.
|
||||
* @param {string} tagName
|
||||
* @throws {Error} If invalid tag name is provided.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeHtml.verifyTagName = function(tagName) {
|
||||
if (!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(tagName)) {
|
||||
throw Error('Invalid tag name <' + tagName + '>.');
|
||||
}
|
||||
if (tagName.toUpperCase() in goog.html.SafeHtml.NOT_ALLOWED_TAG_NAMES_) {
|
||||
throw Error('Tag name <' + tagName + '> is not allowed for SafeHtml.');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeHtml representing an iframe tag.
|
||||
*
|
||||
* This by default restricts the iframe as much as possible by setting the
|
||||
* sandbox attribute to the empty string. If the iframe requires less
|
||||
* restrictions, set the sandbox attribute as tight as possible, but do not rely
|
||||
* on the sandbox as a security feature because it is not supported by older
|
||||
* browsers. If a sandbox is essential to security (e.g. for third-party
|
||||
* frames), use createSandboxIframe which checks for browser support.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe#attr-sandbox
|
||||
*
|
||||
* @param {?goog.html.TrustedResourceUrl=} opt_src The value of the src
|
||||
* attribute. If null or undefined src will not be set.
|
||||
* @param {?goog.html.SafeHtml=} opt_srcdoc The value of the srcdoc attribute.
|
||||
* If null or undefined srcdoc will not be set.
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* Mapping from attribute names to their values. Only attribute names
|
||||
* consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes
|
||||
* the attribute to be omitted.
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content Content to
|
||||
* HTML-escape and put inside the tag. Array elements are concatenated.
|
||||
* @return {!goog.html.SafeHtml} The SafeHtml content with the tag.
|
||||
* @throws {Error} If invalid tag name, attribute name, or attribute value is
|
||||
* provided. If opt_attributes contains the src or srcdoc attributes.
|
||||
*/
|
||||
goog.html.SafeHtml.createIframe = function(
|
||||
opt_src, opt_srcdoc, opt_attributes, opt_content) {
|
||||
if (opt_src) {
|
||||
// Check whether this is really TrustedResourceUrl.
|
||||
goog.html.TrustedResourceUrl.unwrap(opt_src);
|
||||
}
|
||||
|
||||
var fixedAttributes = {};
|
||||
fixedAttributes['src'] = opt_src || null;
|
||||
fixedAttributes['srcdoc'] =
|
||||
opt_srcdoc && goog.html.SafeHtml.unwrap(opt_srcdoc);
|
||||
var defaultAttributes = {'sandbox': ''};
|
||||
var attributes = goog.html.SafeHtml.combineAttributes(
|
||||
fixedAttributes, defaultAttributes, opt_attributes);
|
||||
return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(
|
||||
'iframe', attributes, opt_content);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeHtml representing a sandboxed iframe tag.
|
||||
*
|
||||
* The sandbox attribute is enforced in its most restrictive mode, an empty
|
||||
* string. Consequently, the security requirements for the src and srcdoc
|
||||
* attributes are relaxed compared to SafeHtml.createIframe. This function
|
||||
* will throw on browsers that do not support the sandbox attribute, as
|
||||
* determined by SafeHtml.canUseSandboxIframe.
|
||||
*
|
||||
* The SafeHtml returned by this function can trigger downloads with no
|
||||
* user interaction on Chrome (though only a few, further attempts are blocked).
|
||||
* Firefox and IE will block all downloads from the sandbox.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en/docs/Web/HTML/Element/iframe#attr-sandbox
|
||||
* @see https://lists.w3.org/Archives/Public/public-whatwg-archive/2013Feb/0112.html
|
||||
*
|
||||
* @param {string|!goog.html.SafeUrl=} opt_src The value of the src
|
||||
* attribute. If null or undefined src will not be set.
|
||||
* @param {string=} opt_srcdoc The value of the srcdoc attribute.
|
||||
* If null or undefined srcdoc will not be set. Will not be sanitized.
|
||||
* @param {!Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* Mapping from attribute names to their values. Only attribute names
|
||||
* consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes
|
||||
* the attribute to be omitted.
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content Content to
|
||||
* HTML-escape and put inside the tag. Array elements are concatenated.
|
||||
* @return {!goog.html.SafeHtml} The SafeHtml content with the tag.
|
||||
* @throws {Error} If invalid tag name, attribute name, or attribute value is
|
||||
* provided. If opt_attributes contains the src, srcdoc or sandbox
|
||||
* attributes. If browser does not support the sandbox attribute on iframe.
|
||||
*/
|
||||
goog.html.SafeHtml.createSandboxIframe = function(
|
||||
opt_src, opt_srcdoc, opt_attributes, opt_content) {
|
||||
if (!goog.html.SafeHtml.canUseSandboxIframe()) {
|
||||
throw new Error('The browser does not support sandboxed iframes.');
|
||||
}
|
||||
|
||||
var fixedAttributes = {};
|
||||
if (opt_src) {
|
||||
// Note that sanitize is a no-op on SafeUrl.
|
||||
fixedAttributes['src'] =
|
||||
goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(opt_src));
|
||||
} else {
|
||||
fixedAttributes['src'] = null;
|
||||
}
|
||||
fixedAttributes['srcdoc'] = opt_srcdoc || null;
|
||||
fixedAttributes['sandbox'] = '';
|
||||
var attributes =
|
||||
goog.html.SafeHtml.combineAttributes(fixedAttributes, {}, opt_attributes);
|
||||
return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(
|
||||
'iframe', attributes, opt_content);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the user agent supports sandboxed iframes.
|
||||
* @return {boolean}
|
||||
*/
|
||||
goog.html.SafeHtml.canUseSandboxIframe = function() {
|
||||
return goog.global['HTMLIFrameElement'] &&
|
||||
('sandbox' in goog.global['HTMLIFrameElement'].prototype);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeHtml representing a script tag with the src attribute.
|
||||
* @param {!goog.html.TrustedResourceUrl} src The value of the src
|
||||
* attribute.
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=}
|
||||
* opt_attributes
|
||||
* Mapping from attribute names to their values. Only attribute names
|
||||
* consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined
|
||||
* causes the attribute to be omitted.
|
||||
* @return {!goog.html.SafeHtml} The SafeHtml content with the tag.
|
||||
* @throws {Error} If invalid attribute name or value is provided. If
|
||||
* opt_attributes contains the src attribute.
|
||||
*/
|
||||
goog.html.SafeHtml.createScriptSrc = function(src, opt_attributes) {
|
||||
// Check whether this is really TrustedResourceUrl.
|
||||
goog.html.TrustedResourceUrl.unwrap(src);
|
||||
|
||||
var fixedAttributes = {'src': src};
|
||||
var defaultAttributes = {};
|
||||
var attributes = goog.html.SafeHtml.combineAttributes(
|
||||
fixedAttributes, defaultAttributes, opt_attributes);
|
||||
return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(
|
||||
'script', attributes);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeHtml representing a style tag. The type attribute is set
|
||||
* to "text/css".
|
||||
* @param {!goog.html.SafeStyleSheet|!Array<!goog.html.SafeStyleSheet>}
|
||||
* styleSheet Content to put inside the tag. Array elements are
|
||||
* concatenated.
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* Mapping from attribute names to their values. Only attribute names
|
||||
* consisting of [a-zA-Z0-9-] are allowed. Value of null or undefined causes
|
||||
* the attribute to be omitted.
|
||||
* @return {!goog.html.SafeHtml} The SafeHtml content with the tag.
|
||||
* @throws {Error} If invalid attribute name or attribute value is provided. If
|
||||
* opt_attributes contains the type attribute.
|
||||
*/
|
||||
goog.html.SafeHtml.createStyle = function(styleSheet, opt_attributes) {
|
||||
var fixedAttributes = {'type': 'text/css'};
|
||||
var defaultAttributes = {};
|
||||
var attributes = goog.html.SafeHtml.combineAttributes(
|
||||
fixedAttributes, defaultAttributes, opt_attributes);
|
||||
|
||||
var content = '';
|
||||
styleSheet = goog.array.concat(styleSheet);
|
||||
for (var i = 0; i < styleSheet.length; i++) {
|
||||
content += goog.html.SafeStyleSheet.unwrap(styleSheet[i]);
|
||||
}
|
||||
// Convert to SafeHtml so that it's not HTML-escaped. This is safe because
|
||||
// as part of its contract, SafeStyleSheet should have no dangerous '<'.
|
||||
var htmlContent =
|
||||
goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
content, goog.i18n.bidi.Dir.NEUTRAL);
|
||||
return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(
|
||||
'style', attributes, htmlContent);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeHtml representing a meta refresh tag.
|
||||
* @param {!goog.html.SafeUrl|string} url Where to redirect. If a string is
|
||||
* passed, it will be sanitized with SafeUrl.sanitize().
|
||||
* @param {number=} opt_secs Number of seconds until the page should be
|
||||
* reloaded. Will be set to 0 if unspecified.
|
||||
* @return {!goog.html.SafeHtml} The SafeHtml content with the tag.
|
||||
*/
|
||||
goog.html.SafeHtml.createMetaRefresh = function(url, opt_secs) {
|
||||
|
||||
// Note that sanitize is a no-op on SafeUrl.
|
||||
var unwrappedUrl = goog.html.SafeUrl.unwrap(goog.html.SafeUrl.sanitize(url));
|
||||
|
||||
if (goog.labs.userAgent.browser.isIE() ||
|
||||
goog.labs.userAgent.browser.isEdge()) {
|
||||
// IE/EDGE can't parse the content attribute if the url contains a
|
||||
// semicolon. We can fix this by adding quotes around the url, but then we
|
||||
// can't parse quotes in the URL correctly. Also, it seems that IE/EDGE
|
||||
// did not unescape semicolons in these URLs at some point in the past. We
|
||||
// take a best-effort approach.
|
||||
//
|
||||
// If the URL has semicolons (which may happen in some cases, see
|
||||
// http://www.w3.org/TR/1999/REC-html401-19991224/appendix/notes.html#h-B.2
|
||||
// for instance), wrap it in single quotes to protect the semicolons.
|
||||
// If the URL has semicolons and single quotes, url-encode the single quotes
|
||||
// as well.
|
||||
//
|
||||
// This is imperfect. Notice that both ' and ; are reserved characters in
|
||||
// URIs, so this could do the wrong thing, but at least it will do the wrong
|
||||
// thing in only rare cases.
|
||||
if (goog.string.contains(unwrappedUrl, ';')) {
|
||||
unwrappedUrl = "'" + unwrappedUrl.replace(/'/g, '%27') + "'";
|
||||
}
|
||||
}
|
||||
var attributes = {
|
||||
'http-equiv': 'refresh',
|
||||
'content': (opt_secs || 0) + '; url=' + unwrappedUrl
|
||||
};
|
||||
|
||||
// This function will handle the HTML escaping for attributes.
|
||||
return goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse(
|
||||
'meta', attributes);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} tagName The tag name.
|
||||
* @param {string} name The attribute name.
|
||||
* @param {!goog.html.SafeHtml.AttributeValue} value The attribute value.
|
||||
* @return {string} A "name=value" string.
|
||||
* @throws {Error} If attribute value is unsafe for the given tag and attribute.
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeHtml.getAttrNameAndValue_ = function(tagName, name, value) {
|
||||
// If it's goog.string.Const, allow any valid attribute name.
|
||||
if (value instanceof goog.string.Const) {
|
||||
value = goog.string.Const.unwrap(value);
|
||||
} else if (name.toLowerCase() == 'style') {
|
||||
value = goog.html.SafeHtml.getStyleValue_(value);
|
||||
} else if (/^on/i.test(name)) {
|
||||
// TODO(jakubvrana): Disallow more attributes with a special meaning.
|
||||
throw Error(
|
||||
'Attribute "' + name + '" requires goog.string.Const value, "' + value +
|
||||
'" given.');
|
||||
// URL attributes handled differently accroding to tag.
|
||||
} else if (name.toLowerCase() in goog.html.SafeHtml.URL_ATTRIBUTES_) {
|
||||
if (value instanceof goog.html.TrustedResourceUrl) {
|
||||
value = goog.html.TrustedResourceUrl.unwrap(value);
|
||||
} else if (value instanceof goog.html.SafeUrl) {
|
||||
value = goog.html.SafeUrl.unwrap(value);
|
||||
} else if (goog.isString(value)) {
|
||||
value = goog.html.SafeUrl.sanitize(value).getTypedStringValue();
|
||||
} else {
|
||||
throw Error(
|
||||
'Attribute "' + name + '" on tag "' + tagName +
|
||||
'" requires goog.html.SafeUrl, goog.string.Const, or string,' +
|
||||
' value "' + value + '" given.');
|
||||
}
|
||||
}
|
||||
|
||||
// Accept SafeUrl, TrustedResourceUrl, etc. for attributes which only require
|
||||
// HTML-escaping.
|
||||
if (value.implementsGoogStringTypedString) {
|
||||
// Ok to call getTypedStringValue() since there's no reliance on the type
|
||||
// contract for security here.
|
||||
value = value.getTypedStringValue();
|
||||
}
|
||||
|
||||
goog.asserts.assert(
|
||||
goog.isString(value) || goog.isNumber(value),
|
||||
'String or number value expected, got ' + (typeof value) +
|
||||
' with value: ' + value);
|
||||
return name + '="' + goog.string.htmlEscape(String(value)) + '"';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets value allowed in "style" attribute.
|
||||
* @param {!goog.html.SafeHtml.AttributeValue} value It could be SafeStyle or a
|
||||
* map which will be passed to goog.html.SafeStyle.create.
|
||||
* @return {string} Unwrapped value.
|
||||
* @throws {Error} If string value is given.
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeHtml.getStyleValue_ = function(value) {
|
||||
if (!goog.isObject(value)) {
|
||||
throw Error(
|
||||
'The "style" attribute requires goog.html.SafeStyle or map ' +
|
||||
'of style properties, ' + (typeof value) + ' given: ' + value);
|
||||
}
|
||||
if (!(value instanceof goog.html.SafeStyle)) {
|
||||
// Process the property bag into a style object.
|
||||
value = goog.html.SafeStyle.create(value);
|
||||
}
|
||||
return goog.html.SafeStyle.unwrap(value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeHtml content with known directionality consisting of a tag with
|
||||
* optional attributes and optional content.
|
||||
* @param {!goog.i18n.bidi.Dir} dir Directionality.
|
||||
* @param {string} tagName
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>=} opt_content
|
||||
* @return {!goog.html.SafeHtml} The SafeHtml content with the tag.
|
||||
*/
|
||||
goog.html.SafeHtml.createWithDir = function(
|
||||
dir, tagName, opt_attributes, opt_content) {
|
||||
var html = goog.html.SafeHtml.create(tagName, opt_attributes, opt_content);
|
||||
html.dir_ = dir;
|
||||
return html;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new SafeHtml object by concatenating values.
|
||||
* @param {...(!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>)} var_args Values to concatenate.
|
||||
* @return {!goog.html.SafeHtml}
|
||||
*/
|
||||
goog.html.SafeHtml.concat = function(var_args) {
|
||||
var dir = goog.i18n.bidi.Dir.NEUTRAL;
|
||||
var content = '';
|
||||
|
||||
/**
|
||||
* @param {!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>} argument
|
||||
*/
|
||||
var addArgument = function(argument) {
|
||||
if (goog.isArray(argument)) {
|
||||
goog.array.forEach(argument, addArgument);
|
||||
} else {
|
||||
var html = goog.html.SafeHtml.htmlEscape(argument);
|
||||
content += goog.html.SafeHtml.unwrap(html);
|
||||
var htmlDir = html.getDirection();
|
||||
if (dir == goog.i18n.bidi.Dir.NEUTRAL) {
|
||||
dir = htmlDir;
|
||||
} else if (htmlDir != goog.i18n.bidi.Dir.NEUTRAL && dir != htmlDir) {
|
||||
dir = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
goog.array.forEach(arguments, addArgument);
|
||||
return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
content, dir);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new SafeHtml object with known directionality by concatenating the
|
||||
* values.
|
||||
* @param {!goog.i18n.bidi.Dir} dir Directionality.
|
||||
* @param {...(!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>)} var_args Elements of array
|
||||
* arguments would be processed recursively.
|
||||
* @return {!goog.html.SafeHtml}
|
||||
*/
|
||||
goog.html.SafeHtml.concatWithDir = function(dir, var_args) {
|
||||
var html = goog.html.SafeHtml.concat(goog.array.slice(arguments, 1));
|
||||
html.dir_ = dir;
|
||||
return html;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Type marker for the SafeHtml type, used to implement additional run-time
|
||||
* type checking.
|
||||
* @const {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeHtml.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Package-internal utility method to create SafeHtml instances.
|
||||
*
|
||||
* @param {string} html The string to initialize the SafeHtml object with.
|
||||
* @param {?goog.i18n.bidi.Dir} dir The directionality of the SafeHtml to be
|
||||
* constructed, or null if unknown.
|
||||
* @return {!goog.html.SafeHtml} The initialized SafeHtml object.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse = function(
|
||||
html, dir) {
|
||||
return new goog.html.SafeHtml().initSecurityPrivateDoNotAccessOrElse_(
|
||||
html, dir);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called from createSafeHtmlSecurityPrivateDoNotAccessOrElse(). This
|
||||
* method exists only so that the compiler can dead code eliminate static
|
||||
* fields (like EMPTY) when they're not accessed.
|
||||
* @param {string} html
|
||||
* @param {?goog.i18n.bidi.Dir} dir
|
||||
* @return {!goog.html.SafeHtml}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeHtml.prototype.initSecurityPrivateDoNotAccessOrElse_ = function(
|
||||
html, dir) {
|
||||
this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ = html;
|
||||
this.dir_ = dir;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Like create() but does not restrict which tags can be constructed.
|
||||
*
|
||||
* @param {string} tagName Tag name. Set or validated by caller.
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* @param {(!goog.html.SafeHtml.TextOrHtml_|
|
||||
* !Array<!goog.html.SafeHtml.TextOrHtml_>)=} opt_content
|
||||
* @return {!goog.html.SafeHtml}
|
||||
* @throws {Error} If invalid or unsafe attribute name or value is provided.
|
||||
* @throws {goog.asserts.AssertionError} If content for void tag is provided.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeHtml.createSafeHtmlTagSecurityPrivateDoNotAccessOrElse = function(
|
||||
tagName, opt_attributes, opt_content) {
|
||||
var dir = null;
|
||||
var result = '<' + tagName;
|
||||
result += goog.html.SafeHtml.stringifyAttributes(tagName, opt_attributes);
|
||||
|
||||
var content = opt_content;
|
||||
if (!goog.isDefAndNotNull(content)) {
|
||||
content = [];
|
||||
} else if (!goog.isArray(content)) {
|
||||
content = [content];
|
||||
}
|
||||
|
||||
if (goog.dom.tags.isVoidTag(tagName.toLowerCase())) {
|
||||
goog.asserts.assert(
|
||||
!content.length, 'Void tag <' + tagName + '> does not allow content.');
|
||||
result += '>';
|
||||
} else {
|
||||
var html = goog.html.SafeHtml.concat(content);
|
||||
result += '>' + goog.html.SafeHtml.unwrap(html) + '</' + tagName + '>';
|
||||
dir = html.getDirection();
|
||||
}
|
||||
|
||||
var dirAttribute = opt_attributes && opt_attributes['dir'];
|
||||
if (dirAttribute) {
|
||||
if (/^(ltr|rtl|auto)$/i.test(dirAttribute)) {
|
||||
// If the tag has the "dir" attribute specified then its direction is
|
||||
// neutral because it can be safely used in any context.
|
||||
dir = goog.i18n.bidi.Dir.NEUTRAL;
|
||||
} else {
|
||||
dir = null;
|
||||
}
|
||||
}
|
||||
|
||||
return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
result, dir);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a string with attributes to insert after tagName.
|
||||
* @param {string} tagName
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* @return {string} Returns an empty string if there are no attributes, returns
|
||||
* a string starting with a space otherwise.
|
||||
* @throws {Error} If attribute value is unsafe for the given tag and attribute.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeHtml.stringifyAttributes = function(tagName, opt_attributes) {
|
||||
var result = '';
|
||||
if (opt_attributes) {
|
||||
for (var name in opt_attributes) {
|
||||
if (!goog.html.SafeHtml.VALID_NAMES_IN_TAG_.test(name)) {
|
||||
throw Error('Invalid attribute name "' + name + '".');
|
||||
}
|
||||
var value = opt_attributes[name];
|
||||
if (!goog.isDefAndNotNull(value)) {
|
||||
continue;
|
||||
}
|
||||
result +=
|
||||
' ' + goog.html.SafeHtml.getAttrNameAndValue_(tagName, name, value);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!Object<string, string>} fixedAttributes
|
||||
* @param {!Object<string, string>} defaultAttributes
|
||||
* @param {?Object<string, ?goog.html.SafeHtml.AttributeValue>=} opt_attributes
|
||||
* Optional attributes passed to create*().
|
||||
* @return {!Object<string, ?goog.html.SafeHtml.AttributeValue>}
|
||||
* @throws {Error} If opt_attributes contains an attribute with the same name
|
||||
* as an attribute in fixedAttributes.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeHtml.combineAttributes = function(
|
||||
fixedAttributes, defaultAttributes, opt_attributes) {
|
||||
var combinedAttributes = {};
|
||||
var name;
|
||||
|
||||
for (name in fixedAttributes) {
|
||||
goog.asserts.assert(name.toLowerCase() == name, 'Must be lower case');
|
||||
combinedAttributes[name] = fixedAttributes[name];
|
||||
}
|
||||
for (name in defaultAttributes) {
|
||||
goog.asserts.assert(name.toLowerCase() == name, 'Must be lower case');
|
||||
combinedAttributes[name] = defaultAttributes[name];
|
||||
}
|
||||
|
||||
for (name in opt_attributes) {
|
||||
var nameLower = name.toLowerCase();
|
||||
if (nameLower in fixedAttributes) {
|
||||
throw Error(
|
||||
'Cannot override "' + nameLower + '" attribute, got "' + name +
|
||||
'" with value "' + opt_attributes[name] + '"');
|
||||
}
|
||||
if (nameLower in defaultAttributes) {
|
||||
delete combinedAttributes[nameLower];
|
||||
}
|
||||
combinedAttributes[name] = opt_attributes[name];
|
||||
}
|
||||
|
||||
return combinedAttributes;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A SafeHtml instance corresponding to the HTML doctype: "<!DOCTYPE html>".
|
||||
* @const {!goog.html.SafeHtml}
|
||||
*/
|
||||
goog.html.SafeHtml.DOCTYPE_HTML =
|
||||
goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
'<!DOCTYPE html>', goog.i18n.bidi.Dir.NEUTRAL);
|
||||
|
||||
|
||||
/**
|
||||
* A SafeHtml instance corresponding to the empty string.
|
||||
* @const {!goog.html.SafeHtml}
|
||||
*/
|
||||
goog.html.SafeHtml.EMPTY =
|
||||
goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
'', goog.i18n.bidi.Dir.NEUTRAL);
|
||||
|
||||
|
||||
/**
|
||||
* A SafeHtml instance corresponding to the <br> tag.
|
||||
* @const {!goog.html.SafeHtml}
|
||||
*/
|
||||
goog.html.SafeHtml.BR =
|
||||
goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
'<br>', goog.i18n.bidi.Dir.NEUTRAL);
|
||||
234
resources/public/js/compiled/out/goog/html/safescript.js
Normal file
234
resources/public/js/compiled/out/goog/html/safescript.js
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
// Copyright 2014 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview The SafeScript type and its builders.
|
||||
*
|
||||
* TODO(xtof): Link to document stating type contract.
|
||||
*/
|
||||
|
||||
goog.provide('goog.html.SafeScript');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.string.Const');
|
||||
goog.require('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A string-like object which represents JavaScript code and that carries the
|
||||
* security type contract that its value, as a string, will not cause execution
|
||||
* of unconstrained attacker controlled code (XSS) when evaluated as JavaScript
|
||||
* in a browser.
|
||||
*
|
||||
* Instances of this type must be created via the factory method
|
||||
* {@code goog.html.SafeScript.fromConstant} and not by invoking its
|
||||
* constructor. The constructor intentionally takes no parameters and the type
|
||||
* is immutable; hence only a default instance corresponding to the empty string
|
||||
* can be obtained via constructor invocation.
|
||||
*
|
||||
* A SafeScript's string representation can safely be interpolated as the
|
||||
* content of a script element within HTML. The SafeScript string should not be
|
||||
* escaped before interpolation.
|
||||
*
|
||||
* Note that the SafeScript might contain text that is attacker-controlled but
|
||||
* that text should have been interpolated with appropriate escaping,
|
||||
* sanitization and/or validation into the right location in the script, such
|
||||
* that it is highly constrained in its effect (for example, it had to match a
|
||||
* set of whitelisted words).
|
||||
*
|
||||
* A SafeScript can be constructed via security-reviewed unchecked
|
||||
* conversions. In this case producers of SafeScript must ensure themselves that
|
||||
* the SafeScript does not contain unsafe script. Note in particular that
|
||||
* {@code <} is dangerous, even when inside JavaScript strings, and so should
|
||||
* always be forbidden or JavaScript escaped in user controlled input. For
|
||||
* example, if {@code </script><script>evil</script>"} were
|
||||
* interpolated inside a JavaScript string, it would break out of the context
|
||||
* of the original script element and {@code evil} would execute. Also note
|
||||
* that within an HTML script (raw text) element, HTML character references,
|
||||
* such as "<" are not allowed. See
|
||||
* http://www.w3.org/TR/html5/scripting-1.html#restrictions-for-contents-of-script-elements.
|
||||
*
|
||||
* @see goog.html.SafeScript#fromConstant
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
* @implements {goog.string.TypedString}
|
||||
*/
|
||||
goog.html.SafeScript = function() {
|
||||
/**
|
||||
* The contained value of this SafeScript. The field has a purposely
|
||||
* ugly name to make (non-compiled) code that attempts to directly access this
|
||||
* field stand out.
|
||||
* @private {string}
|
||||
*/
|
||||
this.privateDoNotAccessOrElseSafeScriptWrappedValue_ = '';
|
||||
|
||||
/**
|
||||
* A type marker used to implement additional run-time type checking.
|
||||
* @see goog.html.SafeScript#unwrap
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
this.SAFE_SCRIPT_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =
|
||||
goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.SafeScript.prototype.implementsGoogStringTypedString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Type marker for the SafeScript type, used to implement additional
|
||||
* run-time type checking.
|
||||
* @const {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeScript object from a compile-time constant string.
|
||||
*
|
||||
* @param {!goog.string.Const} script A compile-time-constant string from which
|
||||
* to create a SafeScript.
|
||||
* @return {!goog.html.SafeScript} A SafeScript object initialized to
|
||||
* {@code script}.
|
||||
*/
|
||||
goog.html.SafeScript.fromConstant = function(script) {
|
||||
var scriptString = goog.string.Const.unwrap(script);
|
||||
if (scriptString.length === 0) {
|
||||
return goog.html.SafeScript.EMPTY;
|
||||
}
|
||||
return goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse(
|
||||
scriptString);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this SafeScript's value as a string.
|
||||
*
|
||||
* IMPORTANT: In code where it is security relevant that an object's type is
|
||||
* indeed {@code SafeScript}, use {@code goog.html.SafeScript.unwrap} instead of
|
||||
* this method. If in doubt, assume that it's security relevant. In particular,
|
||||
* note that goog.html functions which return a goog.html type do not guarantee
|
||||
* the returned instance is of the right type. For example:
|
||||
*
|
||||
* <pre>
|
||||
* var fakeSafeHtml = new String('fake');
|
||||
* fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;
|
||||
* var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);
|
||||
* // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by
|
||||
* // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml
|
||||
* // instanceof goog.html.SafeHtml.
|
||||
* </pre>
|
||||
*
|
||||
* @see goog.html.SafeScript#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeScript.prototype.getTypedStringValue = function() {
|
||||
return this.privateDoNotAccessOrElseSafeScriptWrappedValue_;
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a debug string-representation of this value.
|
||||
*
|
||||
* To obtain the actual string value wrapped in a SafeScript, use
|
||||
* {@code goog.html.SafeScript.unwrap}.
|
||||
*
|
||||
* @see goog.html.SafeScript#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeScript.prototype.toString = function() {
|
||||
return 'SafeScript{' +
|
||||
this.privateDoNotAccessOrElseSafeScriptWrappedValue_ + '}';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a runtime check that the provided object is indeed a
|
||||
* SafeScript object, and returns its value.
|
||||
*
|
||||
* @param {!goog.html.SafeScript} safeScript The object to extract from.
|
||||
* @return {string} The safeScript object's contained string, unless
|
||||
* the run-time type check fails. In that case, {@code unwrap} returns an
|
||||
* innocuous string, or, if assertions are enabled, throws
|
||||
* {@code goog.asserts.AssertionError}.
|
||||
*/
|
||||
goog.html.SafeScript.unwrap = function(safeScript) {
|
||||
// Perform additional Run-time type-checking to ensure that
|
||||
// safeScript is indeed an instance of the expected type. This
|
||||
// provides some additional protection against security bugs due to
|
||||
// application code that disables type checks.
|
||||
// Specifically, the following checks are performed:
|
||||
// 1. The object is an instance of the expected type.
|
||||
// 2. The object is not an instance of a subclass.
|
||||
// 3. The object carries a type marker for the expected type. "Faking" an
|
||||
// object requires a reference to the type marker, which has names intended
|
||||
// to stand out in code reviews.
|
||||
if (safeScript instanceof goog.html.SafeScript &&
|
||||
safeScript.constructor === goog.html.SafeScript &&
|
||||
safeScript.SAFE_SCRIPT_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===
|
||||
goog.html.SafeScript.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
|
||||
return safeScript.privateDoNotAccessOrElseSafeScriptWrappedValue_;
|
||||
} else {
|
||||
goog.asserts.fail('expected object of type SafeScript, got \'' +
|
||||
safeScript + '\' of type ' + goog.typeOf(safeScript));
|
||||
return 'type_error:SafeScript';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Package-internal utility method to create SafeScript instances.
|
||||
*
|
||||
* @param {string} script The string to initialize the SafeScript object with.
|
||||
* @return {!goog.html.SafeScript} The initialized SafeScript object.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse =
|
||||
function(script) {
|
||||
return new goog.html.SafeScript().initSecurityPrivateDoNotAccessOrElse_(
|
||||
script);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called from createSafeScriptSecurityPrivateDoNotAccessOrElse(). This
|
||||
* method exists only so that the compiler can dead code eliminate static
|
||||
* fields (like EMPTY) when they're not accessed.
|
||||
* @param {string} script
|
||||
* @return {!goog.html.SafeScript}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeScript.prototype.initSecurityPrivateDoNotAccessOrElse_ = function(
|
||||
script) {
|
||||
this.privateDoNotAccessOrElseSafeScriptWrappedValue_ = script;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A SafeScript instance corresponding to the empty string.
|
||||
* @const {!goog.html.SafeScript}
|
||||
*/
|
||||
goog.html.SafeScript.EMPTY =
|
||||
goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse('');
|
||||
449
resources/public/js/compiled/out/goog/html/safestyle.js
Normal file
449
resources/public/js/compiled/out/goog/html/safestyle.js
Normal file
|
|
@ -0,0 +1,449 @@
|
|||
// Copyright 2014 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview The SafeStyle type and its builders.
|
||||
*
|
||||
* TODO(xtof): Link to document stating type contract.
|
||||
*/
|
||||
|
||||
goog.provide('goog.html.SafeStyle');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.string.Const');
|
||||
goog.require('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A string-like object which represents a sequence of CSS declarations
|
||||
* ({@code propertyName1: propertyvalue1; propertyName2: propertyValue2; ...})
|
||||
* and that carries the security type contract that its value, as a string,
|
||||
* will not cause untrusted script execution (XSS) when evaluated as CSS in a
|
||||
* browser.
|
||||
*
|
||||
* Instances of this type must be created via the factory methods
|
||||
* ({@code goog.html.SafeStyle.create} or
|
||||
* {@code goog.html.SafeStyle.fromConstant}) and not by invoking its
|
||||
* constructor. The constructor intentionally takes no parameters and the type
|
||||
* is immutable; hence only a default instance corresponding to the empty string
|
||||
* can be obtained via constructor invocation.
|
||||
*
|
||||
* A SafeStyle's string representation ({@link #getTypedStringValue()}) can
|
||||
* safely:
|
||||
* <ul>
|
||||
* <li>Be interpolated as the entire content of a *quoted* HTML style
|
||||
* attribute, or before already existing properties. The SafeStyle string
|
||||
* *must be HTML-attribute-escaped* (where " and ' are escaped) before
|
||||
* interpolation.
|
||||
* <li>Be interpolated as the entire content of a {}-wrapped block within a
|
||||
* stylesheet, or before already existing properties. The SafeStyle string
|
||||
* should not be escaped before interpolation. SafeStyle's contract also
|
||||
* guarantees that the string will not be able to introduce new properties
|
||||
* or elide existing ones.
|
||||
* <li>Be assigned to the style property of a DOM node. The SafeStyle string
|
||||
* should not be escaped before being assigned to the property.
|
||||
* </ul>
|
||||
*
|
||||
* A SafeStyle may never contain literal angle brackets. Otherwise, it could
|
||||
* be unsafe to place a SafeStyle into a <style> tag (where it can't
|
||||
* be HTML escaped). For example, if the SafeStyle containing
|
||||
* "{@code font: 'foo <style/><script>evil</script>'}" were
|
||||
* interpolated within a <style> tag, this would then break out of the
|
||||
* style context into HTML.
|
||||
*
|
||||
* A SafeStyle may contain literal single or double quotes, and as such the
|
||||
* entire style string must be escaped when used in a style attribute (if
|
||||
* this were not the case, the string could contain a matching quote that
|
||||
* would escape from the style attribute).
|
||||
*
|
||||
* Values of this type must be composable, i.e. for any two values
|
||||
* {@code style1} and {@code style2} of this type,
|
||||
* {@code goog.html.SafeStyle.unwrap(style1) +
|
||||
* goog.html.SafeStyle.unwrap(style2)} must itself be a value that satisfies
|
||||
* the SafeStyle type constraint. This requirement implies that for any value
|
||||
* {@code style} of this type, {@code goog.html.SafeStyle.unwrap(style)} must
|
||||
* not end in a "property value" or "property name" context. For example,
|
||||
* a value of {@code background:url("} or {@code font-} would not satisfy the
|
||||
* SafeStyle contract. This is because concatenating such strings with a
|
||||
* second value that itself does not contain unsafe CSS can result in an
|
||||
* overall string that does. For example, if {@code javascript:evil())"} is
|
||||
* appended to {@code background:url("}, the resulting string may result in
|
||||
* the execution of a malicious script.
|
||||
*
|
||||
* TODO(user): Consider whether we should implement UTF-8 interchange
|
||||
* validity checks and blacklisting of newlines (including Unicode ones) and
|
||||
* other whitespace characters (\t, \f). Document here if so and also update
|
||||
* SafeStyle.fromConstant().
|
||||
*
|
||||
* The following example values comply with this type's contract:
|
||||
* <ul>
|
||||
* <li><pre>width: 1em;</pre>
|
||||
* <li><pre>height:1em;</pre>
|
||||
* <li><pre>width: 1em;height: 1em;</pre>
|
||||
* <li><pre>background:url('http://url');</pre>
|
||||
* </ul>
|
||||
* In addition, the empty string is safe for use in a CSS attribute.
|
||||
*
|
||||
* The following example values do NOT comply with this type's contract:
|
||||
* <ul>
|
||||
* <li><pre>background: red</pre> (missing a trailing semi-colon)
|
||||
* <li><pre>background:</pre> (missing a value and a trailing semi-colon)
|
||||
* <li><pre>1em</pre> (missing an attribute name, which provides context for
|
||||
* the value)
|
||||
* </ul>
|
||||
*
|
||||
* @see goog.html.SafeStyle#create
|
||||
* @see goog.html.SafeStyle#fromConstant
|
||||
* @see http://www.w3.org/TR/css3-syntax/
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
* @implements {goog.string.TypedString}
|
||||
*/
|
||||
goog.html.SafeStyle = function() {
|
||||
/**
|
||||
* The contained value of this SafeStyle. The field has a purposely
|
||||
* ugly name to make (non-compiled) code that attempts to directly access this
|
||||
* field stand out.
|
||||
* @private {string}
|
||||
*/
|
||||
this.privateDoNotAccessOrElseSafeStyleWrappedValue_ = '';
|
||||
|
||||
/**
|
||||
* A type marker used to implement additional run-time type checking.
|
||||
* @see goog.html.SafeStyle#unwrap
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
this.SAFE_STYLE_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =
|
||||
goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.SafeStyle.prototype.implementsGoogStringTypedString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Type marker for the SafeStyle type, used to implement additional
|
||||
* run-time type checking.
|
||||
* @const {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeStyle object from a compile-time constant string.
|
||||
*
|
||||
* {@code style} should be in the format
|
||||
* {@code name: value; [name: value; ...]} and must not have any < or >
|
||||
* characters in it. This is so that SafeStyle's contract is preserved,
|
||||
* allowing the SafeStyle to correctly be interpreted as a sequence of CSS
|
||||
* declarations and without affecting the syntactic structure of any
|
||||
* surrounding CSS and HTML.
|
||||
*
|
||||
* This method performs basic sanity checks on the format of {@code style}
|
||||
* but does not constrain the format of {@code name} and {@code value}, except
|
||||
* for disallowing tag characters.
|
||||
*
|
||||
* @param {!goog.string.Const} style A compile-time-constant string from which
|
||||
* to create a SafeStyle.
|
||||
* @return {!goog.html.SafeStyle} A SafeStyle object initialized to
|
||||
* {@code style}.
|
||||
*/
|
||||
goog.html.SafeStyle.fromConstant = function(style) {
|
||||
var styleString = goog.string.Const.unwrap(style);
|
||||
if (styleString.length === 0) {
|
||||
return goog.html.SafeStyle.EMPTY;
|
||||
}
|
||||
goog.html.SafeStyle.checkStyle_(styleString);
|
||||
goog.asserts.assert(
|
||||
goog.string.endsWith(styleString, ';'),
|
||||
'Last character of style string is not \';\': ' + styleString);
|
||||
goog.asserts.assert(
|
||||
goog.string.contains(styleString, ':'),
|
||||
'Style string must contain at least one \':\', to ' +
|
||||
'specify a "name: value" pair: ' + styleString);
|
||||
return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(
|
||||
styleString);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the style definition is valid.
|
||||
* @param {string} style
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeStyle.checkStyle_ = function(style) {
|
||||
goog.asserts.assert(
|
||||
!/[<>]/.test(style), 'Forbidden characters in style string: ' + style);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this SafeStyle's value as a string.
|
||||
*
|
||||
* IMPORTANT: In code where it is security relevant that an object's type is
|
||||
* indeed {@code SafeStyle}, use {@code goog.html.SafeStyle.unwrap} instead of
|
||||
* this method. If in doubt, assume that it's security relevant. In particular,
|
||||
* note that goog.html functions which return a goog.html type do not guarantee
|
||||
* the returned instance is of the right type. For example:
|
||||
*
|
||||
* <pre>
|
||||
* var fakeSafeHtml = new String('fake');
|
||||
* fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;
|
||||
* var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);
|
||||
* // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by
|
||||
* // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml
|
||||
* // instanceof goog.html.SafeHtml.
|
||||
* </pre>
|
||||
*
|
||||
* @see goog.html.SafeStyle#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeStyle.prototype.getTypedStringValue = function() {
|
||||
return this.privateDoNotAccessOrElseSafeStyleWrappedValue_;
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a debug string-representation of this value.
|
||||
*
|
||||
* To obtain the actual string value wrapped in a SafeStyle, use
|
||||
* {@code goog.html.SafeStyle.unwrap}.
|
||||
*
|
||||
* @see goog.html.SafeStyle#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeStyle.prototype.toString = function() {
|
||||
return 'SafeStyle{' + this.privateDoNotAccessOrElseSafeStyleWrappedValue_ +
|
||||
'}';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a runtime check that the provided object is indeed a
|
||||
* SafeStyle object, and returns its value.
|
||||
*
|
||||
* @param {!goog.html.SafeStyle} safeStyle The object to extract from.
|
||||
* @return {string} The safeStyle object's contained string, unless
|
||||
* the run-time type check fails. In that case, {@code unwrap} returns an
|
||||
* innocuous string, or, if assertions are enabled, throws
|
||||
* {@code goog.asserts.AssertionError}.
|
||||
*/
|
||||
goog.html.SafeStyle.unwrap = function(safeStyle) {
|
||||
// Perform additional Run-time type-checking to ensure that
|
||||
// safeStyle is indeed an instance of the expected type. This
|
||||
// provides some additional protection against security bugs due to
|
||||
// application code that disables type checks.
|
||||
// Specifically, the following checks are performed:
|
||||
// 1. The object is an instance of the expected type.
|
||||
// 2. The object is not an instance of a subclass.
|
||||
// 3. The object carries a type marker for the expected type. "Faking" an
|
||||
// object requires a reference to the type marker, which has names intended
|
||||
// to stand out in code reviews.
|
||||
if (safeStyle instanceof goog.html.SafeStyle &&
|
||||
safeStyle.constructor === goog.html.SafeStyle &&
|
||||
safeStyle.SAFE_STYLE_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===
|
||||
goog.html.SafeStyle.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
|
||||
return safeStyle.privateDoNotAccessOrElseSafeStyleWrappedValue_;
|
||||
} else {
|
||||
goog.asserts.fail('expected object of type SafeStyle, got \'' +
|
||||
safeStyle + '\' of type ' + goog.typeOf(safeStyle));
|
||||
return 'type_error:SafeStyle';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Package-internal utility method to create SafeStyle instances.
|
||||
*
|
||||
* @param {string} style The string to initialize the SafeStyle object with.
|
||||
* @return {!goog.html.SafeStyle} The initialized SafeStyle object.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse = function(
|
||||
style) {
|
||||
return new goog.html.SafeStyle().initSecurityPrivateDoNotAccessOrElse_(style);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called from createSafeStyleSecurityPrivateDoNotAccessOrElse(). This
|
||||
* method exists only so that the compiler can dead code eliminate static
|
||||
* fields (like EMPTY) when they're not accessed.
|
||||
* @param {string} style
|
||||
* @return {!goog.html.SafeStyle}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeStyle.prototype.initSecurityPrivateDoNotAccessOrElse_ = function(
|
||||
style) {
|
||||
this.privateDoNotAccessOrElseSafeStyleWrappedValue_ = style;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A SafeStyle instance corresponding to the empty string.
|
||||
* @const {!goog.html.SafeStyle}
|
||||
*/
|
||||
goog.html.SafeStyle.EMPTY =
|
||||
goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse('');
|
||||
|
||||
|
||||
/**
|
||||
* The innocuous string generated by goog.html.SafeUrl.create when passed
|
||||
* an unsafe value.
|
||||
* @const {string}
|
||||
*/
|
||||
goog.html.SafeStyle.INNOCUOUS_STRING = 'zClosurez';
|
||||
|
||||
|
||||
/**
|
||||
* Mapping of property names to their values.
|
||||
* @typedef {!Object<string, goog.string.Const|string>}
|
||||
*/
|
||||
goog.html.SafeStyle.PropertyMap;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new SafeStyle object from the properties specified in the map.
|
||||
* @param {goog.html.SafeStyle.PropertyMap} map Mapping of property names to
|
||||
* their values, for example {'margin': '1px'}. Names must consist of
|
||||
* [-_a-zA-Z0-9]. Values might be strings consisting of
|
||||
* [-,.'"%_!# a-zA-Z0-9], where " and ' must be properly balanced.
|
||||
* Other values must be wrapped in goog.string.Const. Null value causes
|
||||
* skipping the property.
|
||||
* @return {!goog.html.SafeStyle}
|
||||
* @throws {Error} If invalid name is provided.
|
||||
* @throws {goog.asserts.AssertionError} If invalid value is provided. With
|
||||
* disabled assertions, invalid value is replaced by
|
||||
* goog.html.SafeStyle.INNOCUOUS_STRING.
|
||||
*/
|
||||
goog.html.SafeStyle.create = function(map) {
|
||||
var style = '';
|
||||
for (var name in map) {
|
||||
if (!/^[-_a-zA-Z0-9]+$/.test(name)) {
|
||||
throw Error('Name allows only [-_a-zA-Z0-9], got: ' + name);
|
||||
}
|
||||
var value = map[name];
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
if (value instanceof goog.string.Const) {
|
||||
value = goog.string.Const.unwrap(value);
|
||||
// These characters can be used to change context and we don't want that
|
||||
// even with const values.
|
||||
goog.asserts.assert(!/[{;}]/.test(value), 'Value does not allow [{;}].');
|
||||
} else if (!goog.html.SafeStyle.VALUE_RE_.test(value)) {
|
||||
goog.asserts.fail(
|
||||
'String value allows only [-,."\'%_!# a-zA-Z0-9], rgb() and ' +
|
||||
'rgba(), got: ' + value);
|
||||
value = goog.html.SafeStyle.INNOCUOUS_STRING;
|
||||
} else if (!goog.html.SafeStyle.hasBalancedQuotes_(value)) {
|
||||
goog.asserts.fail('String value requires balanced quotes, got: ' + value);
|
||||
value = goog.html.SafeStyle.INNOCUOUS_STRING;
|
||||
}
|
||||
style += name + ':' + value + ';';
|
||||
}
|
||||
if (!style) {
|
||||
return goog.html.SafeStyle.EMPTY;
|
||||
}
|
||||
goog.html.SafeStyle.checkStyle_(style);
|
||||
return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(
|
||||
style);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks that quotes (" and ') are properly balanced inside a string. Assumes
|
||||
* that neither escape (\) nor any other character that could result in
|
||||
* breaking out of a string parsing context are allowed;
|
||||
* see http://www.w3.org/TR/css3-syntax/#string-token-diagram.
|
||||
* @param {string} value Untrusted CSS property value.
|
||||
* @return {boolean} True if property value is safe with respect to quote
|
||||
* balancedness.
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeStyle.hasBalancedQuotes_ = function(value) {
|
||||
var outsideSingle = true;
|
||||
var outsideDouble = true;
|
||||
for (var i = 0; i < value.length; i++) {
|
||||
var c = value.charAt(i);
|
||||
if (c == "'" && outsideDouble) {
|
||||
outsideSingle = !outsideSingle;
|
||||
} else if (c == '"' && outsideSingle) {
|
||||
outsideDouble = !outsideDouble;
|
||||
}
|
||||
}
|
||||
return outsideSingle && outsideDouble;
|
||||
};
|
||||
|
||||
|
||||
// Keep in sync with the error string in create().
|
||||
/**
|
||||
* Regular expression for safe values.
|
||||
*
|
||||
* Quotes (" and ') are allowed, but a check must be done elsewhere to ensure
|
||||
* they're balanced.
|
||||
*
|
||||
* ',' allows multiple values to be assigned to the same property
|
||||
* (e.g. background-attachment or font-family) and hence could allow
|
||||
* multiple values to get injected, but that should pose no risk of XSS.
|
||||
*
|
||||
* The rgb() and rgba() expression checks only for XSS safety, not for CSS
|
||||
* validity.
|
||||
* @const {!RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeStyle.VALUE_RE_ =
|
||||
/^([-,."'%_!# a-zA-Z0-9]+|(?:rgb|hsl)a?\([0-9.%, ]+\))$/;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new SafeStyle object by concatenating the values.
|
||||
* @param {...(!goog.html.SafeStyle|!Array<!goog.html.SafeStyle>)} var_args
|
||||
* SafeStyles to concatenate.
|
||||
* @return {!goog.html.SafeStyle}
|
||||
*/
|
||||
goog.html.SafeStyle.concat = function(var_args) {
|
||||
var style = '';
|
||||
|
||||
/**
|
||||
* @param {!goog.html.SafeStyle|!Array<!goog.html.SafeStyle>} argument
|
||||
*/
|
||||
var addArgument = function(argument) {
|
||||
if (goog.isArray(argument)) {
|
||||
goog.array.forEach(argument, addArgument);
|
||||
} else {
|
||||
style += goog.html.SafeStyle.unwrap(argument);
|
||||
}
|
||||
};
|
||||
|
||||
goog.array.forEach(arguments, addArgument);
|
||||
if (!style) {
|
||||
return goog.html.SafeStyle.EMPTY;
|
||||
}
|
||||
return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(
|
||||
style);
|
||||
};
|
||||
278
resources/public/js/compiled/out/goog/html/safestylesheet.js
Normal file
278
resources/public/js/compiled/out/goog/html/safestylesheet.js
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
// Copyright 2014 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview The SafeStyleSheet type and its builders.
|
||||
*
|
||||
* TODO(xtof): Link to document stating type contract.
|
||||
*/
|
||||
|
||||
goog.provide('goog.html.SafeStyleSheet');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.string.Const');
|
||||
goog.require('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A string-like object which represents a CSS style sheet and that carries the
|
||||
* security type contract that its value, as a string, will not cause untrusted
|
||||
* script execution (XSS) when evaluated as CSS in a browser.
|
||||
*
|
||||
* Instances of this type must be created via the factory method
|
||||
* {@code goog.html.SafeStyleSheet.fromConstant} and not by invoking its
|
||||
* constructor. The constructor intentionally takes no parameters and the type
|
||||
* is immutable; hence only a default instance corresponding to the empty string
|
||||
* can be obtained via constructor invocation.
|
||||
*
|
||||
* A SafeStyleSheet's string representation can safely be interpolated as the
|
||||
* content of a style element within HTML. The SafeStyleSheet string should
|
||||
* not be escaped before interpolation.
|
||||
*
|
||||
* Values of this type must be composable, i.e. for any two values
|
||||
* {@code styleSheet1} and {@code styleSheet2} of this type,
|
||||
* {@code goog.html.SafeStyleSheet.unwrap(styleSheet1) +
|
||||
* goog.html.SafeStyleSheet.unwrap(styleSheet2)} must itself be a value that
|
||||
* satisfies the SafeStyleSheet type constraint. This requirement implies that
|
||||
* for any value {@code styleSheet} of this type,
|
||||
* {@code goog.html.SafeStyleSheet.unwrap(styleSheet1)} must end in
|
||||
* "beginning of rule" context.
|
||||
|
||||
* A SafeStyleSheet can be constructed via security-reviewed unchecked
|
||||
* conversions. In this case producers of SafeStyleSheet must ensure themselves
|
||||
* that the SafeStyleSheet does not contain unsafe script. Note in particular
|
||||
* that {@code <} is dangerous, even when inside CSS strings, and so should
|
||||
* always be forbidden or CSS-escaped in user controlled input. For example, if
|
||||
* {@code </style><script>evil</script>"} were interpolated
|
||||
* inside a CSS string, it would break out of the context of the original
|
||||
* style element and {@code evil} would execute. Also note that within an HTML
|
||||
* style (raw text) element, HTML character references, such as
|
||||
* {@code &lt;}, are not allowed. See
|
||||
*
|
||||
http://www.w3.org/TR/html5/scripting-1.html#restrictions-for-contents-of-script-elements
|
||||
* (similar considerations apply to the style element).
|
||||
*
|
||||
* @see goog.html.SafeStyleSheet#fromConstant
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
* @implements {goog.string.TypedString}
|
||||
*/
|
||||
goog.html.SafeStyleSheet = function() {
|
||||
/**
|
||||
* The contained value of this SafeStyleSheet. The field has a purposely
|
||||
* ugly name to make (non-compiled) code that attempts to directly access this
|
||||
* field stand out.
|
||||
* @private {string}
|
||||
*/
|
||||
this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_ = '';
|
||||
|
||||
/**
|
||||
* A type marker used to implement additional run-time type checking.
|
||||
* @see goog.html.SafeStyleSheet#unwrap
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
this.SAFE_STYLE_SHEET_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =
|
||||
goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.SafeStyleSheet.prototype.implementsGoogStringTypedString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Type marker for the SafeStyleSheet type, used to implement additional
|
||||
* run-time type checking.
|
||||
* @const {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new SafeStyleSheet object by concatenating values.
|
||||
* @param {...(!goog.html.SafeStyleSheet|!Array<!goog.html.SafeStyleSheet>)}
|
||||
* var_args Values to concatenate.
|
||||
* @return {!goog.html.SafeStyleSheet}
|
||||
*/
|
||||
goog.html.SafeStyleSheet.concat = function(var_args) {
|
||||
var result = '';
|
||||
|
||||
/**
|
||||
* @param {!goog.html.SafeStyleSheet|!Array<!goog.html.SafeStyleSheet>}
|
||||
* argument
|
||||
*/
|
||||
var addArgument = function(argument) {
|
||||
if (goog.isArray(argument)) {
|
||||
goog.array.forEach(argument, addArgument);
|
||||
} else {
|
||||
result += goog.html.SafeStyleSheet.unwrap(argument);
|
||||
}
|
||||
};
|
||||
|
||||
goog.array.forEach(arguments, addArgument);
|
||||
return goog.html.SafeStyleSheet
|
||||
.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(result);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeStyleSheet object from a compile-time constant string.
|
||||
*
|
||||
* {@code styleSheet} must not have any < characters in it, so that
|
||||
* the syntactic structure of the surrounding HTML is not affected.
|
||||
*
|
||||
* @param {!goog.string.Const} styleSheet A compile-time-constant string from
|
||||
* which to create a SafeStyleSheet.
|
||||
* @return {!goog.html.SafeStyleSheet} A SafeStyleSheet object initialized to
|
||||
* {@code styleSheet}.
|
||||
*/
|
||||
goog.html.SafeStyleSheet.fromConstant = function(styleSheet) {
|
||||
var styleSheetString = goog.string.Const.unwrap(styleSheet);
|
||||
if (styleSheetString.length === 0) {
|
||||
return goog.html.SafeStyleSheet.EMPTY;
|
||||
}
|
||||
// > is a valid character in CSS selectors and there's no strict need to
|
||||
// block it if we already block <.
|
||||
goog.asserts.assert(
|
||||
!goog.string.contains(styleSheetString, '<'),
|
||||
"Forbidden '<' character in style sheet string: " + styleSheetString);
|
||||
return goog.html.SafeStyleSheet
|
||||
.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheetString);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this SafeStyleSheet's value as a string.
|
||||
*
|
||||
* IMPORTANT: In code where it is security relevant that an object's type is
|
||||
* indeed {@code SafeStyleSheet}, use {@code goog.html.SafeStyleSheet.unwrap}
|
||||
* instead of this method. If in doubt, assume that it's security relevant. In
|
||||
* particular, note that goog.html functions which return a goog.html type do
|
||||
* not guarantee the returned instance is of the right type. For example:
|
||||
*
|
||||
* <pre>
|
||||
* var fakeSafeHtml = new String('fake');
|
||||
* fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;
|
||||
* var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);
|
||||
* // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by
|
||||
* // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml
|
||||
* // instanceof goog.html.SafeHtml.
|
||||
* </pre>
|
||||
*
|
||||
* @see goog.html.SafeStyleSheet#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeStyleSheet.prototype.getTypedStringValue = function() {
|
||||
return this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_;
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a debug string-representation of this value.
|
||||
*
|
||||
* To obtain the actual string value wrapped in a SafeStyleSheet, use
|
||||
* {@code goog.html.SafeStyleSheet.unwrap}.
|
||||
*
|
||||
* @see goog.html.SafeStyleSheet#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeStyleSheet.prototype.toString = function() {
|
||||
return 'SafeStyleSheet{' +
|
||||
this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_ + '}';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a runtime check that the provided object is indeed a
|
||||
* SafeStyleSheet object, and returns its value.
|
||||
*
|
||||
* @param {!goog.html.SafeStyleSheet} safeStyleSheet The object to extract from.
|
||||
* @return {string} The safeStyleSheet object's contained string, unless
|
||||
* the run-time type check fails. In that case, {@code unwrap} returns an
|
||||
* innocuous string, or, if assertions are enabled, throws
|
||||
* {@code goog.asserts.AssertionError}.
|
||||
*/
|
||||
goog.html.SafeStyleSheet.unwrap = function(safeStyleSheet) {
|
||||
// Perform additional Run-time type-checking to ensure that
|
||||
// safeStyleSheet is indeed an instance of the expected type. This
|
||||
// provides some additional protection against security bugs due to
|
||||
// application code that disables type checks.
|
||||
// Specifically, the following checks are performed:
|
||||
// 1. The object is an instance of the expected type.
|
||||
// 2. The object is not an instance of a subclass.
|
||||
// 3. The object carries a type marker for the expected type. "Faking" an
|
||||
// object requires a reference to the type marker, which has names intended
|
||||
// to stand out in code reviews.
|
||||
if (safeStyleSheet instanceof goog.html.SafeStyleSheet &&
|
||||
safeStyleSheet.constructor === goog.html.SafeStyleSheet &&
|
||||
safeStyleSheet
|
||||
.SAFE_STYLE_SHEET_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===
|
||||
goog.html.SafeStyleSheet.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
|
||||
return safeStyleSheet.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_;
|
||||
} else {
|
||||
goog.asserts.fail('expected object of type SafeStyleSheet, got \'' +
|
||||
safeStyleSheet + '\' of type ' + goog.typeOf(safeStyleSheet));
|
||||
return 'type_error:SafeStyleSheet';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Package-internal utility method to create SafeStyleSheet instances.
|
||||
*
|
||||
* @param {string} styleSheet The string to initialize the SafeStyleSheet
|
||||
* object with.
|
||||
* @return {!goog.html.SafeStyleSheet} The initialized SafeStyleSheet object.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeStyleSheet.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse =
|
||||
function(styleSheet) {
|
||||
return new goog.html.SafeStyleSheet().initSecurityPrivateDoNotAccessOrElse_(
|
||||
styleSheet);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called from createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(). This
|
||||
* method exists only so that the compiler can dead code eliminate static
|
||||
* fields (like EMPTY) when they're not accessed.
|
||||
* @param {string} styleSheet
|
||||
* @return {!goog.html.SafeStyleSheet}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeStyleSheet.prototype.initSecurityPrivateDoNotAccessOrElse_ =
|
||||
function(styleSheet) {
|
||||
this.privateDoNotAccessOrElseSafeStyleSheetWrappedValue_ = styleSheet;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A SafeStyleSheet instance corresponding to the empty string.
|
||||
* @const {!goog.html.SafeStyleSheet}
|
||||
*/
|
||||
goog.html.SafeStyleSheet.EMPTY =
|
||||
goog.html.SafeStyleSheet
|
||||
.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse('');
|
||||
412
resources/public/js/compiled/out/goog/html/safeurl.js
Normal file
412
resources/public/js/compiled/out/goog/html/safeurl.js
Normal file
|
|
@ -0,0 +1,412 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview The SafeUrl type and its builders.
|
||||
*
|
||||
* TODO(xtof): Link to document stating type contract.
|
||||
*/
|
||||
|
||||
goog.provide('goog.html.SafeUrl');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.fs.url');
|
||||
goog.require('goog.i18n.bidi.Dir');
|
||||
goog.require('goog.i18n.bidi.DirectionalString');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.string.Const');
|
||||
goog.require('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A string that is safe to use in URL context in DOM APIs and HTML documents.
|
||||
*
|
||||
* A SafeUrl is a string-like object that carries the security type contract
|
||||
* that its value as a string will not cause untrusted script execution
|
||||
* when evaluated as a hyperlink URL in a browser.
|
||||
*
|
||||
* Values of this type are guaranteed to be safe to use in URL/hyperlink
|
||||
* contexts, such as, assignment to URL-valued DOM properties, or
|
||||
* interpolation into a HTML template in URL context (e.g., inside a href
|
||||
* attribute), in the sense that the use will not result in a
|
||||
* Cross-Site-Scripting vulnerability.
|
||||
*
|
||||
* Note that, as documented in {@code goog.html.SafeUrl.unwrap}, this type's
|
||||
* contract does not guarantee that instances are safe to interpolate into HTML
|
||||
* without appropriate escaping.
|
||||
*
|
||||
* Note also that this type's contract does not imply any guarantees regarding
|
||||
* the resource the URL refers to. In particular, SafeUrls are <b>not</b>
|
||||
* safe to use in a context where the referred-to resource is interpreted as
|
||||
* trusted code, e.g., as the src of a script tag.
|
||||
*
|
||||
* Instances of this type must be created via the factory methods
|
||||
* ({@code goog.html.SafeUrl.fromConstant}, {@code goog.html.SafeUrl.sanitize}),
|
||||
* etc and not by invoking its constructor. The constructor intentionally
|
||||
* takes no parameters and the type is immutable; hence only a default instance
|
||||
* corresponding to the empty string can be obtained via constructor invocation.
|
||||
*
|
||||
* @see goog.html.SafeUrl#fromConstant
|
||||
* @see goog.html.SafeUrl#from
|
||||
* @see goog.html.SafeUrl#sanitize
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
* @implements {goog.i18n.bidi.DirectionalString}
|
||||
* @implements {goog.string.TypedString}
|
||||
*/
|
||||
goog.html.SafeUrl = function() {
|
||||
/**
|
||||
* The contained value of this SafeUrl. The field has a purposely ugly
|
||||
* name to make (non-compiled) code that attempts to directly access this
|
||||
* field stand out.
|
||||
* @private {string}
|
||||
*/
|
||||
this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ = '';
|
||||
|
||||
/**
|
||||
* A type marker used to implement additional run-time type checking.
|
||||
* @see goog.html.SafeUrl#unwrap
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
this.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =
|
||||
goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The innocuous string generated by goog.html.SafeUrl.sanitize when passed
|
||||
* an unsafe URL.
|
||||
*
|
||||
* about:invalid is registered in
|
||||
* http://www.w3.org/TR/css3-values/#about-invalid.
|
||||
* http://tools.ietf.org/html/rfc6694#section-2.2.1 permits about URLs to
|
||||
* contain a fragment, which is not to be considered when determining if an
|
||||
* about URL is well-known.
|
||||
*
|
||||
* Using about:invalid seems preferable to using a fixed data URL, since
|
||||
* browsers might choose to not report CSP violations on it, as legitimate
|
||||
* CSS function calls to attr() can result in this URL being produced. It is
|
||||
* also a standard URL which matches exactly the semantics we need:
|
||||
* "The about:invalid URI references a non-existent document with a generic
|
||||
* error condition. It can be used when a URI is necessary, but the default
|
||||
* value shouldn't be resolveable as any type of document".
|
||||
*
|
||||
* @const {string}
|
||||
*/
|
||||
goog.html.SafeUrl.INNOCUOUS_STRING = 'about:invalid#zClosurez';
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.SafeUrl.prototype.implementsGoogStringTypedString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Returns this SafeUrl's value a string.
|
||||
*
|
||||
* IMPORTANT: In code where it is security relevant that an object's type is
|
||||
* indeed {@code SafeUrl}, use {@code goog.html.SafeUrl.unwrap} instead of this
|
||||
* method. If in doubt, assume that it's security relevant. In particular, note
|
||||
* that goog.html functions which return a goog.html type do not guarantee that
|
||||
* the returned instance is of the right type. For example:
|
||||
*
|
||||
* <pre>
|
||||
* var fakeSafeHtml = new String('fake');
|
||||
* fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;
|
||||
* var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);
|
||||
* // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by
|
||||
* // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml instanceof
|
||||
* // goog.html.SafeHtml.
|
||||
* </pre>
|
||||
*
|
||||
* IMPORTANT: The guarantees of the SafeUrl type contract only extend to the
|
||||
* behavior of browsers when interpreting URLs. Values of SafeUrl objects MUST
|
||||
* be appropriately escaped before embedding in a HTML document. Note that the
|
||||
* required escaping is context-sensitive (e.g. a different escaping is
|
||||
* required for embedding a URL in a style property within a style
|
||||
* attribute, as opposed to embedding in a href attribute).
|
||||
*
|
||||
* @see goog.html.SafeUrl#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeUrl.prototype.getTypedStringValue = function() {
|
||||
return this.privateDoNotAccessOrElseSafeHtmlWrappedValue_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.SafeUrl.prototype.implementsGoogI18nBidiDirectionalString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Returns this URLs directionality, which is always {@code LTR}.
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeUrl.prototype.getDirection = function() {
|
||||
return goog.i18n.bidi.Dir.LTR;
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a debug string-representation of this value.
|
||||
*
|
||||
* To obtain the actual string value wrapped in a SafeUrl, use
|
||||
* {@code goog.html.SafeUrl.unwrap}.
|
||||
*
|
||||
* @see goog.html.SafeUrl#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.SafeUrl.prototype.toString = function() {
|
||||
return 'SafeUrl{' + this.privateDoNotAccessOrElseSafeHtmlWrappedValue_ +
|
||||
'}';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a runtime check that the provided object is indeed a SafeUrl
|
||||
* object, and returns its value.
|
||||
*
|
||||
* IMPORTANT: The guarantees of the SafeUrl type contract only extend to the
|
||||
* behavior of browsers when interpreting URLs. Values of SafeUrl objects MUST
|
||||
* be appropriately escaped before embedding in a HTML document. Note that the
|
||||
* required escaping is context-sensitive (e.g. a different escaping is
|
||||
* required for embedding a URL in a style property within a style
|
||||
* attribute, as opposed to embedding in a href attribute).
|
||||
*
|
||||
* @param {!goog.html.SafeUrl} safeUrl The object to extract from.
|
||||
* @return {string} The SafeUrl object's contained string, unless the run-time
|
||||
* type check fails. In that case, {@code unwrap} returns an innocuous
|
||||
* string, or, if assertions are enabled, throws
|
||||
* {@code goog.asserts.AssertionError}.
|
||||
*/
|
||||
goog.html.SafeUrl.unwrap = function(safeUrl) {
|
||||
// Perform additional Run-time type-checking to ensure that safeUrl is indeed
|
||||
// an instance of the expected type. This provides some additional protection
|
||||
// against security bugs due to application code that disables type checks.
|
||||
// Specifically, the following checks are performed:
|
||||
// 1. The object is an instance of the expected type.
|
||||
// 2. The object is not an instance of a subclass.
|
||||
// 3. The object carries a type marker for the expected type. "Faking" an
|
||||
// object requires a reference to the type marker, which has names intended
|
||||
// to stand out in code reviews.
|
||||
if (safeUrl instanceof goog.html.SafeUrl &&
|
||||
safeUrl.constructor === goog.html.SafeUrl &&
|
||||
safeUrl.SAFE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===
|
||||
goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
|
||||
return safeUrl.privateDoNotAccessOrElseSafeHtmlWrappedValue_;
|
||||
} else {
|
||||
goog.asserts.fail('expected object of type SafeUrl, got \'' +
|
||||
safeUrl + '\' of type ' + goog.typeOf(safeUrl));
|
||||
return 'type_error:SafeUrl';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeUrl object from a compile-time constant string.
|
||||
*
|
||||
* Compile-time constant strings are inherently program-controlled and hence
|
||||
* trusted.
|
||||
*
|
||||
* @param {!goog.string.Const} url A compile-time-constant string from which to
|
||||
* create a SafeUrl.
|
||||
* @return {!goog.html.SafeUrl} A SafeUrl object initialized to {@code url}.
|
||||
*/
|
||||
goog.html.SafeUrl.fromConstant = function(url) {
|
||||
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(
|
||||
goog.string.Const.unwrap(url));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A pattern that matches Blob or data types that can have SafeUrls created
|
||||
* from URL.createObjectURL(blob) or via a data: URI. Only matches image and
|
||||
* video types, currently.
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
goog.html.SAFE_MIME_TYPE_PATTERN_ =
|
||||
/^(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm))$/i;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeUrl wrapping a blob URL for the given {@code blob}.
|
||||
*
|
||||
* The blob URL is created with {@code URL.createObjectURL}. If the MIME type
|
||||
* for {@code blob} is not of a known safe image or video MIME type, then the
|
||||
* SafeUrl will wrap {@link #INNOCUOUS_STRING}.
|
||||
*
|
||||
* @see http://www.w3.org/TR/FileAPI/#url
|
||||
* @param {!Blob} blob
|
||||
* @return {!goog.html.SafeUrl} The blob URL, or an innocuous string wrapped
|
||||
* as a SafeUrl.
|
||||
*/
|
||||
goog.html.SafeUrl.fromBlob = function(blob) {
|
||||
var url = goog.html.SAFE_MIME_TYPE_PATTERN_.test(blob.type) ?
|
||||
goog.fs.url.createObjectUrl(blob) :
|
||||
goog.html.SafeUrl.INNOCUOUS_STRING;
|
||||
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Matches a base-64 data URL, with the first match group being the MIME type.
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
goog.html.DATA_URL_PATTERN_ = /^data:([^;,]*);base64,[a-z0-9+\/]+=*$/i;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeUrl wrapping a data: URL, after validating it matches a
|
||||
* known-safe image or video MIME type.
|
||||
*
|
||||
* @param {string} dataUrl A valid base64 data URL with one of the whitelisted
|
||||
* image or video MIME types.
|
||||
* @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}
|
||||
* wrapped as a SafeUrl if it does not pass.
|
||||
*/
|
||||
goog.html.SafeUrl.fromDataUrl = function(dataUrl) {
|
||||
// There's a slight risk here that a browser sniffs the content type if it
|
||||
// doesn't know the MIME type and executes HTML within the data: URL. For this
|
||||
// to cause XSS it would also have to execute the HTML in the same origin
|
||||
// of the page with the link. It seems unlikely that both of these will
|
||||
// happen, particularly in not really old IEs.
|
||||
var match = dataUrl.match(goog.html.DATA_URL_PATTERN_);
|
||||
var valid = match && goog.html.SAFE_MIME_TYPE_PATTERN_.test(match[1]);
|
||||
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(
|
||||
valid ? dataUrl : goog.html.SafeUrl.INNOCUOUS_STRING);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeUrl wrapping a tel: URL.
|
||||
*
|
||||
* @param {string} telUrl A tel URL.
|
||||
* @return {!goog.html.SafeUrl} A matching safe URL, or {@link INNOCUOUS_STRING}
|
||||
* wrapped as a SafeUrl if it does not pass.
|
||||
*/
|
||||
goog.html.SafeUrl.fromTelUrl = function(telUrl) {
|
||||
// There's a risk that a tel: URL could immediately place a call once
|
||||
// clicked, without requiring user confirmation. For that reason it is
|
||||
// handled in this separate function.
|
||||
if (!goog.string.caseInsensitiveStartsWith(telUrl, 'tel:')) {
|
||||
telUrl = goog.html.SafeUrl.INNOCUOUS_STRING;
|
||||
}
|
||||
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(
|
||||
telUrl);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A pattern that recognizes a commonly useful subset of URLs that satisfy
|
||||
* the SafeUrl contract.
|
||||
*
|
||||
* This regular expression matches a subset of URLs that will not cause script
|
||||
* execution if used in URL context within a HTML document. Specifically, this
|
||||
* regular expression matches if (comment from here on and regex copied from
|
||||
* Soy's EscapingConventions):
|
||||
* (1) Either a protocol in a whitelist (http, https, mailto or ftp).
|
||||
* (2) or no protocol. A protocol must be followed by a colon. The below
|
||||
* allows that by allowing colons only after one of the characters [/?#].
|
||||
* A colon after a hash (#) must be in the fragment.
|
||||
* Otherwise, a colon after a (?) must be in a query.
|
||||
* Otherwise, a colon after a single solidus (/) must be in a path.
|
||||
* Otherwise, a colon after a double solidus (//) must be in the authority
|
||||
* (before port).
|
||||
*
|
||||
* The pattern disallows &, used in HTML entity declarations before
|
||||
* one of the characters in [/?#]. This disallows HTML entities used in the
|
||||
* protocol name, which should never happen, e.g. "http" for "http".
|
||||
* It also disallows HTML entities in the first path part of a relative path,
|
||||
* e.g. "foo<bar/baz". Our existing escaping functions should not produce
|
||||
* that. More importantly, it disallows masking of a colon,
|
||||
* e.g. "javascript:...".
|
||||
*
|
||||
* @private
|
||||
* @const {!RegExp}
|
||||
*/
|
||||
goog.html.SAFE_URL_PATTERN_ =
|
||||
/^(?:(?:https?|mailto|ftp):|[^&:/?#]*(?:[/?#]|$))/i;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a SafeUrl object from {@code url}. If {@code url} is a
|
||||
* goog.html.SafeUrl then it is simply returned. Otherwise the input string is
|
||||
* validated to match a pattern of commonly used safe URLs.
|
||||
*
|
||||
* {@code url} may be a URL with the http, https, mailto or ftp scheme,
|
||||
* or a relative URL (i.e., a URL without a scheme; specifically, a
|
||||
* scheme-relative, absolute-path-relative, or path-relative URL).
|
||||
*
|
||||
* @see http://url.spec.whatwg.org/#concept-relative-url
|
||||
* @param {string|!goog.string.TypedString} url The URL to validate.
|
||||
* @return {!goog.html.SafeUrl} The validated URL, wrapped as a SafeUrl.
|
||||
*/
|
||||
goog.html.SafeUrl.sanitize = function(url) {
|
||||
if (url instanceof goog.html.SafeUrl) {
|
||||
return url;
|
||||
} else if (url.implementsGoogStringTypedString) {
|
||||
url = url.getTypedStringValue();
|
||||
} else {
|
||||
url = String(url);
|
||||
}
|
||||
if (!goog.html.SAFE_URL_PATTERN_.test(url)) {
|
||||
url = goog.html.SafeUrl.INNOCUOUS_STRING;
|
||||
}
|
||||
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Type marker for the SafeUrl type, used to implement additional run-time
|
||||
* type checking.
|
||||
* @const {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.html.SafeUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Package-internal utility method to create SafeUrl instances.
|
||||
*
|
||||
* @param {string} url The string to initialize the SafeUrl object with.
|
||||
* @return {!goog.html.SafeUrl} The initialized SafeUrl object.
|
||||
* @package
|
||||
*/
|
||||
goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse = function(
|
||||
url) {
|
||||
var safeUrl = new goog.html.SafeUrl();
|
||||
safeUrl.privateDoNotAccessOrElseSafeHtmlWrappedValue_ = url;
|
||||
return safeUrl;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A SafeUrl corresponding to the special about:blank url.
|
||||
* @const {!goog.html.SafeUrl}
|
||||
*/
|
||||
goog.html.SafeUrl.ABOUT_BLANK =
|
||||
goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(
|
||||
'about:blank');
|
||||
244
resources/public/js/compiled/out/goog/html/trustedresourceurl.js
Normal file
244
resources/public/js/compiled/out/goog/html/trustedresourceurl.js
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview The TrustedResourceUrl type and its builders.
|
||||
*
|
||||
* TODO(xtof): Link to document stating type contract.
|
||||
*/
|
||||
|
||||
goog.provide('goog.html.TrustedResourceUrl');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.i18n.bidi.Dir');
|
||||
goog.require('goog.i18n.bidi.DirectionalString');
|
||||
goog.require('goog.string.Const');
|
||||
goog.require('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A URL which is under application control and from which script, CSS, and
|
||||
* other resources that represent executable code, can be fetched.
|
||||
*
|
||||
* Given that the URL can only be constructed from strings under application
|
||||
* control and is used to load resources, bugs resulting in a malformed URL
|
||||
* should not have a security impact and are likely to be easily detectable
|
||||
* during testing. Given the wide number of non-RFC compliant URLs in use,
|
||||
* stricter validation could prevent some applications from being able to use
|
||||
* this type.
|
||||
*
|
||||
* Instances of this type must be created via the factory method,
|
||||
* ({@code goog.html.TrustedResourceUrl.fromConstant}), and not by invoking its
|
||||
* constructor. The constructor intentionally takes no parameters and the type
|
||||
* is immutable; hence only a default instance corresponding to the empty
|
||||
* string can be obtained via constructor invocation.
|
||||
*
|
||||
* @see goog.html.TrustedResourceUrl#fromConstant
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
* @implements {goog.i18n.bidi.DirectionalString}
|
||||
* @implements {goog.string.TypedString}
|
||||
*/
|
||||
goog.html.TrustedResourceUrl = function() {
|
||||
/**
|
||||
* The contained value of this TrustedResourceUrl. The field has a purposely
|
||||
* ugly name to make (non-compiled) code that attempts to directly access this
|
||||
* field stand out.
|
||||
* @private {string}
|
||||
*/
|
||||
this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ = '';
|
||||
|
||||
/**
|
||||
* A type marker used to implement additional run-time type checking.
|
||||
* @see goog.html.TrustedResourceUrl#unwrap
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
this.TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ =
|
||||
goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.prototype.implementsGoogStringTypedString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Returns this TrustedResourceUrl's value as a string.
|
||||
*
|
||||
* IMPORTANT: In code where it is security relevant that an object's type is
|
||||
* indeed {@code TrustedResourceUrl}, use
|
||||
* {@code goog.html.TrustedResourceUrl.unwrap} instead of this method. If in
|
||||
* doubt, assume that it's security relevant. In particular, note that
|
||||
* goog.html functions which return a goog.html type do not guarantee that
|
||||
* the returned instance is of the right type. For example:
|
||||
*
|
||||
* <pre>
|
||||
* var fakeSafeHtml = new String('fake');
|
||||
* fakeSafeHtml.__proto__ = goog.html.SafeHtml.prototype;
|
||||
* var newSafeHtml = goog.html.SafeHtml.htmlEscape(fakeSafeHtml);
|
||||
* // newSafeHtml is just an alias for fakeSafeHtml, it's passed through by
|
||||
* // goog.html.SafeHtml.htmlEscape() as fakeSafeHtml instanceof
|
||||
* // goog.html.SafeHtml.
|
||||
* </pre>
|
||||
*
|
||||
* @see goog.html.TrustedResourceUrl#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.prototype.getTypedStringValue = function() {
|
||||
return this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.prototype.implementsGoogI18nBidiDirectionalString =
|
||||
true;
|
||||
|
||||
|
||||
/**
|
||||
* Returns this URLs directionality, which is always {@code LTR}.
|
||||
* @override
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.prototype.getDirection = function() {
|
||||
return goog.i18n.bidi.Dir.LTR;
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a debug string-representation of this value.
|
||||
*
|
||||
* To obtain the actual string value wrapped in a TrustedResourceUrl, use
|
||||
* {@code goog.html.TrustedResourceUrl.unwrap}.
|
||||
*
|
||||
* @see goog.html.TrustedResourceUrl#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.prototype.toString = function() {
|
||||
return 'TrustedResourceUrl{' +
|
||||
this.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ + '}';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Performs a runtime check that the provided object is indeed a
|
||||
* TrustedResourceUrl object, and returns its value.
|
||||
*
|
||||
* @param {!goog.html.TrustedResourceUrl} trustedResourceUrl The object to
|
||||
* extract from.
|
||||
* @return {string} The trustedResourceUrl object's contained string, unless
|
||||
* the run-time type check fails. In that case, {@code unwrap} returns an
|
||||
* innocuous string, or, if assertions are enabled, throws
|
||||
* {@code goog.asserts.AssertionError}.
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.unwrap = function(trustedResourceUrl) {
|
||||
// Perform additional Run-time type-checking to ensure that
|
||||
// trustedResourceUrl is indeed an instance of the expected type. This
|
||||
// provides some additional protection against security bugs due to
|
||||
// application code that disables type checks.
|
||||
// Specifically, the following checks are performed:
|
||||
// 1. The object is an instance of the expected type.
|
||||
// 2. The object is not an instance of a subclass.
|
||||
// 3. The object carries a type marker for the expected type. "Faking" an
|
||||
// object requires a reference to the type marker, which has names intended
|
||||
// to stand out in code reviews.
|
||||
if (trustedResourceUrl instanceof goog.html.TrustedResourceUrl &&
|
||||
trustedResourceUrl.constructor === goog.html.TrustedResourceUrl &&
|
||||
trustedResourceUrl
|
||||
.TRUSTED_RESOURCE_URL_TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ ===
|
||||
goog.html.TrustedResourceUrl
|
||||
.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_) {
|
||||
return trustedResourceUrl
|
||||
.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_;
|
||||
} else {
|
||||
goog.asserts.fail('expected object of type TrustedResourceUrl, got \'' +
|
||||
trustedResourceUrl + '\' of type ' + goog.typeOf(trustedResourceUrl));
|
||||
return 'type_error:TrustedResourceUrl';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a TrustedResourceUrl object from a compile-time constant string.
|
||||
*
|
||||
* Compile-time constant strings are inherently program-controlled and hence
|
||||
* trusted.
|
||||
*
|
||||
* @param {!goog.string.Const} url A compile-time-constant string from which to
|
||||
* create a TrustedResourceUrl.
|
||||
* @return {!goog.html.TrustedResourceUrl} A TrustedResourceUrl object
|
||||
* initialized to {@code url}.
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.fromConstant = function(url) {
|
||||
return goog.html.TrustedResourceUrl
|
||||
.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(
|
||||
goog.string.Const.unwrap(url));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a TrustedResourceUrl object from a compile-time constant strings.
|
||||
*
|
||||
* Compile-time constant strings are inherently program-controlled and hence
|
||||
* trusted.
|
||||
*
|
||||
* @param {!Array<!goog.string.Const>} parts Compile-time-constant strings from
|
||||
* which to create a TrustedResourceUrl.
|
||||
* @return {!goog.html.TrustedResourceUrl} A TrustedResourceUrl object
|
||||
* initialized to concatenation of {@code parts}.
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.fromConstants = function(parts) {
|
||||
var unwrapped = '';
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
unwrapped += goog.string.Const.unwrap(parts[i]);
|
||||
}
|
||||
return goog.html.TrustedResourceUrl
|
||||
.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(unwrapped);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Type marker for the TrustedResourceUrl type, used to implement additional
|
||||
* run-time type checking.
|
||||
* @const {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.html.TrustedResourceUrl.TYPE_MARKER_GOOG_HTML_SECURITY_PRIVATE_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Package-internal utility method to create TrustedResourceUrl instances.
|
||||
*
|
||||
* @param {string} url The string to initialize the TrustedResourceUrl object
|
||||
* with.
|
||||
* @return {!goog.html.TrustedResourceUrl} The initialized TrustedResourceUrl
|
||||
* object.
|
||||
* @package
|
||||
*/
|
||||
goog.html.TrustedResourceUrl
|
||||
.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse = function(url) {
|
||||
var trustedResourceUrl = new goog.html.TrustedResourceUrl();
|
||||
trustedResourceUrl.privateDoNotAccessOrElseTrustedResourceUrlWrappedValue_ =
|
||||
url;
|
||||
return trustedResourceUrl;
|
||||
};
|
||||
|
|
@ -0,0 +1,232 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Unchecked conversions to create values of goog.html types from
|
||||
* plain strings. Use of these functions could potentially result in instances
|
||||
* of goog.html types that violate their type contracts, and hence result in
|
||||
* security vulnerabilties.
|
||||
*
|
||||
* Therefore, all uses of the methods herein must be carefully security
|
||||
* reviewed. Avoid use of the methods in this file whenever possible; instead
|
||||
* prefer to create instances of goog.html types using inherently safe builders
|
||||
* or template systems.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @visibility {//closure/goog/html:approved_for_unchecked_conversion}
|
||||
* @visibility {//closure/goog/bin/sizetests:__pkg__}
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.html.uncheckedconversions');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.html.SafeHtml');
|
||||
goog.require('goog.html.SafeScript');
|
||||
goog.require('goog.html.SafeStyle');
|
||||
goog.require('goog.html.SafeStyleSheet');
|
||||
goog.require('goog.html.SafeUrl');
|
||||
goog.require('goog.html.TrustedResourceUrl');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.string.Const');
|
||||
|
||||
|
||||
/**
|
||||
* Performs an "unchecked conversion" to SafeHtml from a plain string that is
|
||||
* known to satisfy the SafeHtml type contract.
|
||||
*
|
||||
* IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
|
||||
* that the value of {@code html} satisfies the SafeHtml type contract in all
|
||||
* possible program states.
|
||||
*
|
||||
*
|
||||
* @param {!goog.string.Const} justification A constant string explaining why
|
||||
* this use of this method is safe. May include a security review ticket
|
||||
* number.
|
||||
* @param {string} html A string that is claimed to adhere to the SafeHtml
|
||||
* contract.
|
||||
* @param {?goog.i18n.bidi.Dir=} opt_dir The optional directionality of the
|
||||
* SafeHtml to be constructed. A null or undefined value signifies an
|
||||
* unknown directionality.
|
||||
* @return {!goog.html.SafeHtml} The value of html, wrapped in a SafeHtml
|
||||
* object.
|
||||
* @suppress {visibility} For access to SafeHtml.create... Note that this
|
||||
* use is appropriate since this method is intended to be "package private"
|
||||
* within goog.html. DO NOT call SafeHtml.create... from outside this
|
||||
* package; use appropriate wrappers instead.
|
||||
*/
|
||||
goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract =
|
||||
function(justification, html, opt_dir) {
|
||||
// unwrap() called inside an assert so that justification can be optimized
|
||||
// away in production code.
|
||||
goog.asserts.assertString(
|
||||
goog.string.Const.unwrap(justification), 'must provide justification');
|
||||
goog.asserts.assert(
|
||||
!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
|
||||
'must provide non-empty justification');
|
||||
return goog.html.SafeHtml.createSafeHtmlSecurityPrivateDoNotAccessOrElse(
|
||||
html, opt_dir || null);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs an "unchecked conversion" to SafeScript from a plain string that is
|
||||
* known to satisfy the SafeScript type contract.
|
||||
*
|
||||
* IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
|
||||
* that the value of {@code script} satisfies the SafeScript type contract in
|
||||
* all possible program states.
|
||||
*
|
||||
*
|
||||
* @param {!goog.string.Const} justification A constant string explaining why
|
||||
* this use of this method is safe. May include a security review ticket
|
||||
* number.
|
||||
* @param {string} script The string to wrap as a SafeScript.
|
||||
* @return {!goog.html.SafeScript} The value of {@code script}, wrapped in a
|
||||
* SafeScript object.
|
||||
*/
|
||||
goog.html.uncheckedconversions.safeScriptFromStringKnownToSatisfyTypeContract =
|
||||
function(justification, script) {
|
||||
// unwrap() called inside an assert so that justification can be optimized
|
||||
// away in production code.
|
||||
goog.asserts.assertString(
|
||||
goog.string.Const.unwrap(justification), 'must provide justification');
|
||||
goog.asserts.assert(
|
||||
!goog.string.isEmpty(goog.string.Const.unwrap(justification)),
|
||||
'must provide non-empty justification');
|
||||
return goog.html.SafeScript.createSafeScriptSecurityPrivateDoNotAccessOrElse(
|
||||
script);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs an "unchecked conversion" to SafeStyle from a plain string that is
|
||||
* known to satisfy the SafeStyle type contract.
|
||||
*
|
||||
* IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
|
||||
* that the value of {@code style} satisfies the SafeUrl type contract in all
|
||||
* possible program states.
|
||||
*
|
||||
*
|
||||
* @param {!goog.string.Const} justification A constant string explaining why
|
||||
* this use of this method is safe. May include a security review ticket
|
||||
* number.
|
||||
* @param {string} style The string to wrap as a SafeStyle.
|
||||
* @return {!goog.html.SafeStyle} The value of {@code style}, wrapped in a
|
||||
* SafeStyle object.
|
||||
*/
|
||||
goog.html.uncheckedconversions.safeStyleFromStringKnownToSatisfyTypeContract =
|
||||
function(justification, style) {
|
||||
// unwrap() called inside an assert so that justification can be optimized
|
||||
// away in production code.
|
||||
goog.asserts.assertString(
|
||||
goog.string.Const.unwrap(justification), 'must provide justification');
|
||||
goog.asserts.assert(
|
||||
!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
|
||||
'must provide non-empty justification');
|
||||
return goog.html.SafeStyle.createSafeStyleSecurityPrivateDoNotAccessOrElse(
|
||||
style);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs an "unchecked conversion" to SafeStyleSheet from a plain string
|
||||
* that is known to satisfy the SafeStyleSheet type contract.
|
||||
*
|
||||
* IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
|
||||
* that the value of {@code styleSheet} satisfies the SafeUrl type contract in
|
||||
* all possible program states.
|
||||
*
|
||||
*
|
||||
* @param {!goog.string.Const} justification A constant string explaining why
|
||||
* this use of this method is safe. May include a security review ticket
|
||||
* number.
|
||||
* @param {string} styleSheet The string to wrap as a SafeStyleSheet.
|
||||
* @return {!goog.html.SafeStyleSheet} The value of {@code styleSheet}, wrapped
|
||||
* in a SafeStyleSheet object.
|
||||
*/
|
||||
goog.html.uncheckedconversions
|
||||
.safeStyleSheetFromStringKnownToSatisfyTypeContract = function(
|
||||
justification, styleSheet) {
|
||||
// unwrap() called inside an assert so that justification can be optimized
|
||||
// away in production code.
|
||||
goog.asserts.assertString(
|
||||
goog.string.Const.unwrap(justification), 'must provide justification');
|
||||
goog.asserts.assert(
|
||||
!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
|
||||
'must provide non-empty justification');
|
||||
return goog.html.SafeStyleSheet
|
||||
.createSafeStyleSheetSecurityPrivateDoNotAccessOrElse(styleSheet);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs an "unchecked conversion" to SafeUrl from a plain string that is
|
||||
* known to satisfy the SafeUrl type contract.
|
||||
*
|
||||
* IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
|
||||
* that the value of {@code url} satisfies the SafeUrl type contract in all
|
||||
* possible program states.
|
||||
*
|
||||
*
|
||||
* @param {!goog.string.Const} justification A constant string explaining why
|
||||
* this use of this method is safe. May include a security review ticket
|
||||
* number.
|
||||
* @param {string} url The string to wrap as a SafeUrl.
|
||||
* @return {!goog.html.SafeUrl} The value of {@code url}, wrapped in a SafeUrl
|
||||
* object.
|
||||
*/
|
||||
goog.html.uncheckedconversions.safeUrlFromStringKnownToSatisfyTypeContract =
|
||||
function(justification, url) {
|
||||
// unwrap() called inside an assert so that justification can be optimized
|
||||
// away in production code.
|
||||
goog.asserts.assertString(
|
||||
goog.string.Const.unwrap(justification), 'must provide justification');
|
||||
goog.asserts.assert(
|
||||
!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
|
||||
'must provide non-empty justification');
|
||||
return goog.html.SafeUrl.createSafeUrlSecurityPrivateDoNotAccessOrElse(url);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs an "unchecked conversion" to TrustedResourceUrl from a plain string
|
||||
* that is known to satisfy the TrustedResourceUrl type contract.
|
||||
*
|
||||
* IMPORTANT: Uses of this method must be carefully security-reviewed to ensure
|
||||
* that the value of {@code url} satisfies the TrustedResourceUrl type contract
|
||||
* in all possible program states.
|
||||
*
|
||||
*
|
||||
* @param {!goog.string.Const} justification A constant string explaining why
|
||||
* this use of this method is safe. May include a security review ticket
|
||||
* number.
|
||||
* @param {string} url The string to wrap as a TrustedResourceUrl.
|
||||
* @return {!goog.html.TrustedResourceUrl} The value of {@code url}, wrapped in
|
||||
* a TrustedResourceUrl object.
|
||||
*/
|
||||
goog.html.uncheckedconversions
|
||||
.trustedResourceUrlFromStringKnownToSatisfyTypeContract = function(
|
||||
justification, url) {
|
||||
// unwrap() called inside an assert so that justification can be optimized
|
||||
// away in production code.
|
||||
goog.asserts.assertString(
|
||||
goog.string.Const.unwrap(justification), 'must provide justification');
|
||||
goog.asserts.assert(
|
||||
!goog.string.isEmptyOrWhitespace(goog.string.Const.unwrap(justification)),
|
||||
'must provide non-empty justification');
|
||||
return goog.html.TrustedResourceUrl
|
||||
.createTrustedResourceUrlSecurityPrivateDoNotAccessOrElse(url);
|
||||
};
|
||||
876
resources/public/js/compiled/out/goog/i18n/bidi.js
Normal file
876
resources/public/js/compiled/out/goog/i18n/bidi.js
Normal file
|
|
@ -0,0 +1,876 @@
|
|||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utility functions for supporting Bidi issues.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Namespace for bidi supporting functions.
|
||||
*/
|
||||
goog.provide('goog.i18n.bidi');
|
||||
goog.provide('goog.i18n.bidi.Dir');
|
||||
goog.provide('goog.i18n.bidi.DirectionalString');
|
||||
goog.provide('goog.i18n.bidi.Format');
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} FORCE_RTL forces the {@link goog.i18n.bidi.IS_RTL} constant
|
||||
* to say that the current locale is a RTL locale. This should only be used
|
||||
* if you want to override the default behavior for deciding whether the
|
||||
* current locale is RTL or not.
|
||||
*
|
||||
* {@see goog.i18n.bidi.IS_RTL}
|
||||
*/
|
||||
goog.define('goog.i18n.bidi.FORCE_RTL', false);
|
||||
|
||||
|
||||
/**
|
||||
* Constant that defines whether or not the current locale is a RTL locale.
|
||||
* If {@link goog.i18n.bidi.FORCE_RTL} is not true, this constant will default
|
||||
* to check that {@link goog.LOCALE} is one of a few major RTL locales.
|
||||
*
|
||||
* <p>This is designed to be a maximally efficient compile-time constant. For
|
||||
* example, for the default goog.LOCALE, compiling
|
||||
* "if (goog.i18n.bidi.IS_RTL) alert('rtl') else {}" should produce no code. It
|
||||
* is this design consideration that limits the implementation to only
|
||||
* supporting a few major RTL locales, as opposed to the broader repertoire of
|
||||
* something like goog.i18n.bidi.isRtlLanguage.
|
||||
*
|
||||
* <p>Since this constant refers to the directionality of the locale, it is up
|
||||
* to the caller to determine if this constant should also be used for the
|
||||
* direction of the UI.
|
||||
*
|
||||
* {@see goog.LOCALE}
|
||||
*
|
||||
* @type {boolean}
|
||||
*
|
||||
* TODO(user): write a test that checks that this is a compile-time constant.
|
||||
*/
|
||||
goog.i18n.bidi.IS_RTL = goog.i18n.bidi.FORCE_RTL ||
|
||||
((goog.LOCALE.substring(0, 2).toLowerCase() == 'ar' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'fa' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'he' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'iw' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'ps' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'sd' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'ug' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'ur' ||
|
||||
goog.LOCALE.substring(0, 2).toLowerCase() == 'yi') &&
|
||||
(goog.LOCALE.length == 2 || goog.LOCALE.substring(2, 3) == '-' ||
|
||||
goog.LOCALE.substring(2, 3) == '_')) ||
|
||||
(goog.LOCALE.length >= 3 &&
|
||||
goog.LOCALE.substring(0, 3).toLowerCase() == 'ckb' &&
|
||||
(goog.LOCALE.length == 3 || goog.LOCALE.substring(3, 4) == '-' ||
|
||||
goog.LOCALE.substring(3, 4) == '_'));
|
||||
|
||||
|
||||
/**
|
||||
* Unicode formatting characters and directionality string constants.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.i18n.bidi.Format = {
|
||||
/** Unicode "Left-To-Right Embedding" (LRE) character. */
|
||||
LRE: '\u202A',
|
||||
/** Unicode "Right-To-Left Embedding" (RLE) character. */
|
||||
RLE: '\u202B',
|
||||
/** Unicode "Pop Directional Formatting" (PDF) character. */
|
||||
PDF: '\u202C',
|
||||
/** Unicode "Left-To-Right Mark" (LRM) character. */
|
||||
LRM: '\u200E',
|
||||
/** Unicode "Right-To-Left Mark" (RLM) character. */
|
||||
RLM: '\u200F'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Directionality enum.
|
||||
* @enum {number}
|
||||
*/
|
||||
goog.i18n.bidi.Dir = {
|
||||
/**
|
||||
* Left-to-right.
|
||||
*/
|
||||
LTR: 1,
|
||||
|
||||
/**
|
||||
* Right-to-left.
|
||||
*/
|
||||
RTL: -1,
|
||||
|
||||
/**
|
||||
* Neither left-to-right nor right-to-left.
|
||||
*/
|
||||
NEUTRAL: 0
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 'right' string constant.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.i18n.bidi.RIGHT = 'right';
|
||||
|
||||
|
||||
/**
|
||||
* 'left' string constant.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.i18n.bidi.LEFT = 'left';
|
||||
|
||||
|
||||
/**
|
||||
* 'left' if locale is RTL, 'right' if not.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.i18n.bidi.I18N_RIGHT =
|
||||
goog.i18n.bidi.IS_RTL ? goog.i18n.bidi.LEFT : goog.i18n.bidi.RIGHT;
|
||||
|
||||
|
||||
/**
|
||||
* 'right' if locale is RTL, 'left' if not.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.i18n.bidi.I18N_LEFT =
|
||||
goog.i18n.bidi.IS_RTL ? goog.i18n.bidi.RIGHT : goog.i18n.bidi.LEFT;
|
||||
|
||||
|
||||
/**
|
||||
* Convert a directionality given in various formats to a goog.i18n.bidi.Dir
|
||||
* constant. Useful for interaction with different standards of directionality
|
||||
* representation.
|
||||
*
|
||||
* @param {goog.i18n.bidi.Dir|number|boolean|null} givenDir Directionality given
|
||||
* in one of the following formats:
|
||||
* 1. A goog.i18n.bidi.Dir constant.
|
||||
* 2. A number (positive = LTR, negative = RTL, 0 = neutral).
|
||||
* 3. A boolean (true = RTL, false = LTR).
|
||||
* 4. A null for unknown directionality.
|
||||
* @param {boolean=} opt_noNeutral Whether a givenDir of zero or
|
||||
* goog.i18n.bidi.Dir.NEUTRAL should be treated as null, i.e. unknown, in
|
||||
* order to preserve legacy behavior.
|
||||
* @return {?goog.i18n.bidi.Dir} A goog.i18n.bidi.Dir constant matching the
|
||||
* given directionality. If given null, returns null (i.e. unknown).
|
||||
*/
|
||||
goog.i18n.bidi.toDir = function(givenDir, opt_noNeutral) {
|
||||
if (typeof givenDir == 'number') {
|
||||
// This includes the non-null goog.i18n.bidi.Dir case.
|
||||
return givenDir > 0 ? goog.i18n.bidi.Dir.LTR : givenDir < 0 ?
|
||||
goog.i18n.bidi.Dir.RTL :
|
||||
opt_noNeutral ? null : goog.i18n.bidi.Dir.NEUTRAL;
|
||||
} else if (givenDir == null) {
|
||||
return null;
|
||||
} else {
|
||||
// Must be typeof givenDir == 'boolean'.
|
||||
return givenDir ? goog.i18n.bidi.Dir.RTL : goog.i18n.bidi.Dir.LTR;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A practical pattern to identify strong LTR characters. This pattern is not
|
||||
* theoretically correct according to the Unicode standard. It is simplified for
|
||||
* performance and small code size.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.ltrChars_ =
|
||||
'A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF' +
|
||||
'\u200E\u2C00-\uFB1C\uFE00-\uFE6F\uFEFD-\uFFFF';
|
||||
|
||||
|
||||
/**
|
||||
* A practical pattern to identify strong RTL character. This pattern is not
|
||||
* theoretically correct according to the Unicode standard. It is simplified
|
||||
* for performance and small code size.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rtlChars_ =
|
||||
'\u0591-\u06EF\u06FA-\u07FF\u200F\uFB1D-\uFDFF\uFE70-\uFEFC';
|
||||
|
||||
|
||||
/**
|
||||
* Simplified regular expression for an HTML tag (opening or closing) or an HTML
|
||||
* escape. We might want to skip over such expressions when estimating the text
|
||||
* directionality.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.htmlSkipReg_ = /<[^>]*>|&[^;]+;/g;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the input text with spaces instead of HTML tags or HTML escapes, if
|
||||
* opt_isStripNeeded is true. Else returns the input as is.
|
||||
* Useful for text directionality estimation.
|
||||
* Note: the function should not be used in other contexts; it is not 100%
|
||||
* correct, but rather a good-enough implementation for directionality
|
||||
* estimation purposes.
|
||||
* @param {string} str The given string.
|
||||
* @param {boolean=} opt_isStripNeeded Whether to perform the stripping.
|
||||
* Default: false (to retain consistency with calling functions).
|
||||
* @return {string} The given string cleaned of HTML tags / escapes.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.stripHtmlIfNeeded_ = function(str, opt_isStripNeeded) {
|
||||
return opt_isStripNeeded ? str.replace(goog.i18n.bidi.htmlSkipReg_, '') : str;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression to check for RTL characters.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rtlCharReg_ = new RegExp('[' + goog.i18n.bidi.rtlChars_ + ']');
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression to check for LTR characters.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.ltrCharReg_ = new RegExp('[' + goog.i18n.bidi.ltrChars_ + ']');
|
||||
|
||||
|
||||
/**
|
||||
* Test whether the given string has any RTL characters in it.
|
||||
* @param {string} str The given string that need to be tested.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether the string contains RTL characters.
|
||||
*/
|
||||
goog.i18n.bidi.hasAnyRtl = function(str, opt_isHtml) {
|
||||
return goog.i18n.bidi.rtlCharReg_.test(
|
||||
goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Test whether the given string has any RTL characters in it.
|
||||
* @param {string} str The given string that need to be tested.
|
||||
* @return {boolean} Whether the string contains RTL characters.
|
||||
* @deprecated Use hasAnyRtl.
|
||||
*/
|
||||
goog.i18n.bidi.hasRtlChar = goog.i18n.bidi.hasAnyRtl;
|
||||
|
||||
|
||||
/**
|
||||
* Test whether the given string has any LTR characters in it.
|
||||
* @param {string} str The given string that need to be tested.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether the string contains LTR characters.
|
||||
*/
|
||||
goog.i18n.bidi.hasAnyLtr = function(str, opt_isHtml) {
|
||||
return goog.i18n.bidi.ltrCharReg_.test(
|
||||
goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression pattern to check if the first character in the string
|
||||
* is LTR.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.ltrRe_ = new RegExp('^[' + goog.i18n.bidi.ltrChars_ + ']');
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression pattern to check if the first character in the string
|
||||
* is RTL.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rtlRe_ = new RegExp('^[' + goog.i18n.bidi.rtlChars_ + ']');
|
||||
|
||||
|
||||
/**
|
||||
* Check if the first character in the string is RTL or not.
|
||||
* @param {string} str The given string that need to be tested.
|
||||
* @return {boolean} Whether the first character in str is an RTL char.
|
||||
*/
|
||||
goog.i18n.bidi.isRtlChar = function(str) {
|
||||
return goog.i18n.bidi.rtlRe_.test(str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check if the first character in the string is LTR or not.
|
||||
* @param {string} str The given string that need to be tested.
|
||||
* @return {boolean} Whether the first character in str is an LTR char.
|
||||
*/
|
||||
goog.i18n.bidi.isLtrChar = function(str) {
|
||||
return goog.i18n.bidi.ltrRe_.test(str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check if the first character in the string is neutral or not.
|
||||
* @param {string} str The given string that need to be tested.
|
||||
* @return {boolean} Whether the first character in str is a neutral char.
|
||||
*/
|
||||
goog.i18n.bidi.isNeutralChar = function(str) {
|
||||
return !goog.i18n.bidi.isLtrChar(str) && !goog.i18n.bidi.isRtlChar(str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expressions to check if a piece of text is of LTR directionality
|
||||
* on first character with strong directionality.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.ltrDirCheckRe_ = new RegExp(
|
||||
'^[^' + goog.i18n.bidi.rtlChars_ + ']*[' + goog.i18n.bidi.ltrChars_ + ']');
|
||||
|
||||
|
||||
/**
|
||||
* Regular expressions to check if a piece of text is of RTL directionality
|
||||
* on first character with strong directionality.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rtlDirCheckRe_ = new RegExp(
|
||||
'^[^' + goog.i18n.bidi.ltrChars_ + ']*[' + goog.i18n.bidi.rtlChars_ + ']');
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the first strongly directional character (if any) is RTL.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether RTL directionality is detected using the first
|
||||
* strongly-directional character method.
|
||||
*/
|
||||
goog.i18n.bidi.startsWithRtl = function(str, opt_isHtml) {
|
||||
return goog.i18n.bidi.rtlDirCheckRe_.test(
|
||||
goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the first strongly directional character (if any) is RTL.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether RTL directionality is detected using the first
|
||||
* strongly-directional character method.
|
||||
* @deprecated Use startsWithRtl.
|
||||
*/
|
||||
goog.i18n.bidi.isRtlText = goog.i18n.bidi.startsWithRtl;
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the first strongly directional character (if any) is LTR.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether LTR directionality is detected using the first
|
||||
* strongly-directional character method.
|
||||
*/
|
||||
goog.i18n.bidi.startsWithLtr = function(str, opt_isHtml) {
|
||||
return goog.i18n.bidi.ltrDirCheckRe_.test(
|
||||
goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the first strongly directional character (if any) is LTR.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether LTR directionality is detected using the first
|
||||
* strongly-directional character method.
|
||||
* @deprecated Use startsWithLtr.
|
||||
*/
|
||||
goog.i18n.bidi.isLtrText = goog.i18n.bidi.startsWithLtr;
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression to check if a string looks like something that must
|
||||
* always be LTR even in RTL text, e.g. a URL. When estimating the
|
||||
* directionality of text containing these, we treat these as weakly LTR,
|
||||
* like numbers.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.isRequiredLtrRe_ = /^http:\/\/.*/;
|
||||
|
||||
|
||||
/**
|
||||
* Check whether the input string either contains no strongly directional
|
||||
* characters or looks like a url.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether neutral directionality is detected.
|
||||
*/
|
||||
goog.i18n.bidi.isNeutralText = function(str, opt_isHtml) {
|
||||
str = goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml);
|
||||
return goog.i18n.bidi.isRequiredLtrRe_.test(str) ||
|
||||
!goog.i18n.bidi.hasAnyLtr(str) && !goog.i18n.bidi.hasAnyRtl(str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expressions to check if the last strongly-directional character in a
|
||||
* piece of text is LTR.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.ltrExitDirCheckRe_ = new RegExp(
|
||||
'[' + goog.i18n.bidi.ltrChars_ + '][^' + goog.i18n.bidi.rtlChars_ + ']*$');
|
||||
|
||||
|
||||
/**
|
||||
* Regular expressions to check if the last strongly-directional character in a
|
||||
* piece of text is RTL.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rtlExitDirCheckRe_ = new RegExp(
|
||||
'[' + goog.i18n.bidi.rtlChars_ + '][^' + goog.i18n.bidi.ltrChars_ + ']*$');
|
||||
|
||||
|
||||
/**
|
||||
* Check if the exit directionality a piece of text is LTR, i.e. if the last
|
||||
* strongly-directional character in the string is LTR.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether LTR exit directionality was detected.
|
||||
*/
|
||||
goog.i18n.bidi.endsWithLtr = function(str, opt_isHtml) {
|
||||
return goog.i18n.bidi.ltrExitDirCheckRe_.test(
|
||||
goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check if the exit directionality a piece of text is LTR, i.e. if the last
|
||||
* strongly-directional character in the string is LTR.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether LTR exit directionality was detected.
|
||||
* @deprecated Use endsWithLtr.
|
||||
*/
|
||||
goog.i18n.bidi.isLtrExitText = goog.i18n.bidi.endsWithLtr;
|
||||
|
||||
|
||||
/**
|
||||
* Check if the exit directionality a piece of text is RTL, i.e. if the last
|
||||
* strongly-directional character in the string is RTL.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether RTL exit directionality was detected.
|
||||
*/
|
||||
goog.i18n.bidi.endsWithRtl = function(str, opt_isHtml) {
|
||||
return goog.i18n.bidi.rtlExitDirCheckRe_.test(
|
||||
goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check if the exit directionality a piece of text is RTL, i.e. if the last
|
||||
* strongly-directional character in the string is RTL.
|
||||
* @param {string} str String being checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether RTL exit directionality was detected.
|
||||
* @deprecated Use endsWithRtl.
|
||||
*/
|
||||
goog.i18n.bidi.isRtlExitText = goog.i18n.bidi.endsWithRtl;
|
||||
|
||||
|
||||
/**
|
||||
* A regular expression for matching right-to-left language codes.
|
||||
* See {@link #isRtlLanguage} for the design.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rtlLocalesRe_ = new RegExp(
|
||||
'^(ar|ckb|dv|he|iw|fa|nqo|ps|sd|ug|ur|yi|' +
|
||||
'.*[-_](Arab|Hebr|Thaa|Nkoo|Tfng))' +
|
||||
'(?!.*[-_](Latn|Cyrl)($|-|_))($|-|_)',
|
||||
'i');
|
||||
|
||||
|
||||
/**
|
||||
* Check if a BCP 47 / III language code indicates an RTL language, i.e. either:
|
||||
* - a language code explicitly specifying one of the right-to-left scripts,
|
||||
* e.g. "az-Arab", or<p>
|
||||
* - a language code specifying one of the languages normally written in a
|
||||
* right-to-left script, e.g. "fa" (Farsi), except ones explicitly specifying
|
||||
* Latin or Cyrillic script (which are the usual LTR alternatives).<p>
|
||||
* The list of right-to-left scripts appears in the 100-199 range in
|
||||
* http://www.unicode.org/iso15924/iso15924-num.html, of which Arabic and
|
||||
* Hebrew are by far the most widely used. We also recognize Thaana, N'Ko, and
|
||||
* Tifinagh, which also have significant modern usage. The rest (Syriac,
|
||||
* Samaritan, Mandaic, etc.) seem to have extremely limited or no modern usage
|
||||
* and are not recognized to save on code size.
|
||||
* The languages usually written in a right-to-left script are taken as those
|
||||
* with Suppress-Script: Hebr|Arab|Thaa|Nkoo|Tfng in
|
||||
* http://www.iana.org/assignments/language-subtag-registry,
|
||||
* as well as Central (or Sorani) Kurdish (ckb), Sindhi (sd) and Uyghur (ug).
|
||||
* Other subtags of the language code, e.g. regions like EG (Egypt), are
|
||||
* ignored.
|
||||
* @param {string} lang BCP 47 (a.k.a III) language code.
|
||||
* @return {boolean} Whether the language code is an RTL language.
|
||||
*/
|
||||
goog.i18n.bidi.isRtlLanguage = function(lang) {
|
||||
return goog.i18n.bidi.rtlLocalesRe_.test(lang);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for bracket guard replacement in text.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.bracketGuardTextRe_ =
|
||||
/(\(.*?\)+)|(\[.*?\]+)|(\{.*?\}+)|(<.*?>+)/g;
|
||||
|
||||
|
||||
/**
|
||||
* Apply bracket guard using LRM and RLM. This is to address the problem of
|
||||
* messy bracket display frequently happens in RTL layout.
|
||||
* This function works for plain text, not for HTML. In HTML, the opening
|
||||
* bracket might be in a different context than the closing bracket (such as
|
||||
* an attribute value).
|
||||
* @param {string} s The string that need to be processed.
|
||||
* @param {boolean=} opt_isRtlContext specifies default direction (usually
|
||||
* direction of the UI).
|
||||
* @return {string} The processed string, with all bracket guarded.
|
||||
*/
|
||||
goog.i18n.bidi.guardBracketInText = function(s, opt_isRtlContext) {
|
||||
var useRtl = opt_isRtlContext === undefined ? goog.i18n.bidi.hasAnyRtl(s) :
|
||||
opt_isRtlContext;
|
||||
var mark = useRtl ? goog.i18n.bidi.Format.RLM : goog.i18n.bidi.Format.LRM;
|
||||
return s.replace(goog.i18n.bidi.bracketGuardTextRe_, mark + '$&' + mark);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enforce the html snippet in RTL directionality regardless overall context.
|
||||
* If the html piece was enclosed by tag, dir will be applied to existing
|
||||
* tag, otherwise a span tag will be added as wrapper. For this reason, if
|
||||
* html snippet start with with tag, this tag must enclose the whole piece. If
|
||||
* the tag already has a dir specified, this new one will override existing
|
||||
* one in behavior (tested on FF and IE).
|
||||
* @param {string} html The string that need to be processed.
|
||||
* @return {string} The processed string, with directionality enforced to RTL.
|
||||
*/
|
||||
goog.i18n.bidi.enforceRtlInHtml = function(html) {
|
||||
if (html.charAt(0) == '<') {
|
||||
return html.replace(/<\w+/, '$& dir=rtl');
|
||||
}
|
||||
// '\n' is important for FF so that it won't incorrectly merge span groups
|
||||
return '\n<span dir=rtl>' + html + '</span>';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enforce RTL on both end of the given text piece using unicode BiDi formatting
|
||||
* characters RLE and PDF.
|
||||
* @param {string} text The piece of text that need to be wrapped.
|
||||
* @return {string} The wrapped string after process.
|
||||
*/
|
||||
goog.i18n.bidi.enforceRtlInText = function(text) {
|
||||
return goog.i18n.bidi.Format.RLE + text + goog.i18n.bidi.Format.PDF;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enforce the html snippet in RTL directionality regardless overall context.
|
||||
* If the html piece was enclosed by tag, dir will be applied to existing
|
||||
* tag, otherwise a span tag will be added as wrapper. For this reason, if
|
||||
* html snippet start with with tag, this tag must enclose the whole piece. If
|
||||
* the tag already has a dir specified, this new one will override existing
|
||||
* one in behavior (tested on FF and IE).
|
||||
* @param {string} html The string that need to be processed.
|
||||
* @return {string} The processed string, with directionality enforced to RTL.
|
||||
*/
|
||||
goog.i18n.bidi.enforceLtrInHtml = function(html) {
|
||||
if (html.charAt(0) == '<') {
|
||||
return html.replace(/<\w+/, '$& dir=ltr');
|
||||
}
|
||||
// '\n' is important for FF so that it won't incorrectly merge span groups
|
||||
return '\n<span dir=ltr>' + html + '</span>';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enforce LTR on both end of the given text piece using unicode BiDi formatting
|
||||
* characters LRE and PDF.
|
||||
* @param {string} text The piece of text that need to be wrapped.
|
||||
* @return {string} The wrapped string after process.
|
||||
*/
|
||||
goog.i18n.bidi.enforceLtrInText = function(text) {
|
||||
return goog.i18n.bidi.Format.LRE + text + goog.i18n.bidi.Format.PDF;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression to find dimensions such as "padding: .3 0.4ex 5px 6;"
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.dimensionsRe_ =
|
||||
/:\s*([.\d][.\w]*)\s+([.\d][.\w]*)\s+([.\d][.\w]*)\s+([.\d][.\w]*)/g;
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for left.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.leftRe_ = /left/gi;
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for right.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rightRe_ = /right/gi;
|
||||
|
||||
|
||||
/**
|
||||
* Placeholder regular expression for swapping.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.tempRe_ = /%%%%/g;
|
||||
|
||||
|
||||
/**
|
||||
* Swap location parameters and 'left'/'right' in CSS specification. The
|
||||
* processed string will be suited for RTL layout. Though this function can
|
||||
* cover most cases, there are always exceptions. It is suggested to put
|
||||
* those exceptions in separate group of CSS string.
|
||||
* @param {string} cssStr CSS spefication string.
|
||||
* @return {string} Processed CSS specification string.
|
||||
*/
|
||||
goog.i18n.bidi.mirrorCSS = function(cssStr) {
|
||||
return cssStr
|
||||
.
|
||||
// reverse dimensions
|
||||
replace(goog.i18n.bidi.dimensionsRe_, ':$1 $4 $3 $2')
|
||||
.replace(goog.i18n.bidi.leftRe_, '%%%%')
|
||||
. // swap left and right
|
||||
replace(goog.i18n.bidi.rightRe_, goog.i18n.bidi.LEFT)
|
||||
.replace(goog.i18n.bidi.tempRe_, goog.i18n.bidi.RIGHT);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for hebrew double quote substitution, finding quote
|
||||
* directly after hebrew characters.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.doubleQuoteSubstituteRe_ = /([\u0591-\u05f2])"/g;
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for hebrew single quote substitution, finding quote
|
||||
* directly after hebrew characters.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.singleQuoteSubstituteRe_ = /([\u0591-\u05f2])'/g;
|
||||
|
||||
|
||||
/**
|
||||
* Replace the double and single quote directly after a Hebrew character with
|
||||
* GERESH and GERSHAYIM. In such case, most likely that's user intention.
|
||||
* @param {string} str String that need to be processed.
|
||||
* @return {string} Processed string with double/single quote replaced.
|
||||
*/
|
||||
goog.i18n.bidi.normalizeHebrewQuote = function(str) {
|
||||
return str.replace(goog.i18n.bidi.doubleQuoteSubstituteRe_, '$1\u05f4')
|
||||
.replace(goog.i18n.bidi.singleQuoteSubstituteRe_, '$1\u05f3');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression to split a string into "words" for directionality
|
||||
* estimation based on relative word counts.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.wordSeparatorRe_ = /\s+/;
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression to check if a string contains any numerals. Used to
|
||||
* differentiate between completely neutral strings and those containing
|
||||
* numbers, which are weakly LTR.
|
||||
*
|
||||
* Native Arabic digits (\u0660 - \u0669) are not included because although they
|
||||
* do flow left-to-right inside a number, this is the case even if the overall
|
||||
* directionality is RTL, and a mathematical expression using these digits is
|
||||
* supposed to flow right-to-left overall, including unary plus and minus
|
||||
* appearing to the right of a number, and this does depend on the overall
|
||||
* directionality being RTL. The digits used in Farsi (\u06F0 - \u06F9), on the
|
||||
* other hand, are included, since Farsi math (including unary plus and minus)
|
||||
* does flow left-to-right.
|
||||
*
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.hasNumeralsRe_ = /[\d\u06f0-\u06f9]/;
|
||||
|
||||
|
||||
/**
|
||||
* This constant controls threshold of RTL directionality.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.bidi.rtlDetectionThreshold_ = 0.40;
|
||||
|
||||
|
||||
/**
|
||||
* Estimates the directionality of a string based on relative word counts.
|
||||
* If the number of RTL words is above a certain percentage of the total number
|
||||
* of strongly directional words, returns RTL.
|
||||
* Otherwise, if any words are strongly or weakly LTR, returns LTR.
|
||||
* Otherwise, returns UNKNOWN, which is used to mean "neutral".
|
||||
* Numbers are counted as weakly LTR.
|
||||
* @param {string} str The string to be checked.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {goog.i18n.bidi.Dir} Estimated overall directionality of {@code str}.
|
||||
*/
|
||||
goog.i18n.bidi.estimateDirection = function(str, opt_isHtml) {
|
||||
var rtlCount = 0;
|
||||
var totalCount = 0;
|
||||
var hasWeaklyLtr = false;
|
||||
var tokens = goog.i18n.bidi.stripHtmlIfNeeded_(str, opt_isHtml)
|
||||
.split(goog.i18n.bidi.wordSeparatorRe_);
|
||||
for (var i = 0; i < tokens.length; i++) {
|
||||
var token = tokens[i];
|
||||
if (goog.i18n.bidi.startsWithRtl(token)) {
|
||||
rtlCount++;
|
||||
totalCount++;
|
||||
} else if (goog.i18n.bidi.isRequiredLtrRe_.test(token)) {
|
||||
hasWeaklyLtr = true;
|
||||
} else if (goog.i18n.bidi.hasAnyLtr(token)) {
|
||||
totalCount++;
|
||||
} else if (goog.i18n.bidi.hasNumeralsRe_.test(token)) {
|
||||
hasWeaklyLtr = true;
|
||||
}
|
||||
}
|
||||
|
||||
return totalCount == 0 ?
|
||||
(hasWeaklyLtr ? goog.i18n.bidi.Dir.LTR : goog.i18n.bidi.Dir.NEUTRAL) :
|
||||
(rtlCount / totalCount > goog.i18n.bidi.rtlDetectionThreshold_ ?
|
||||
goog.i18n.bidi.Dir.RTL :
|
||||
goog.i18n.bidi.Dir.LTR);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check the directionality of a piece of text, return true if the piece of
|
||||
* text should be laid out in RTL direction.
|
||||
* @param {string} str The piece of text that need to be detected.
|
||||
* @param {boolean=} opt_isHtml Whether str is HTML / HTML-escaped.
|
||||
* Default: false.
|
||||
* @return {boolean} Whether this piece of text should be laid out in RTL.
|
||||
*/
|
||||
goog.i18n.bidi.detectRtlDirectionality = function(str, opt_isHtml) {
|
||||
return goog.i18n.bidi.estimateDirection(str, opt_isHtml) ==
|
||||
goog.i18n.bidi.Dir.RTL;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets text input element's directionality and text alignment based on a
|
||||
* given directionality. Does nothing if the given directionality is unknown or
|
||||
* neutral.
|
||||
* @param {Element} element Input field element to set directionality to.
|
||||
* @param {goog.i18n.bidi.Dir|number|boolean|null} dir Desired directionality,
|
||||
* given in one of the following formats:
|
||||
* 1. A goog.i18n.bidi.Dir constant.
|
||||
* 2. A number (positive = LRT, negative = RTL, 0 = neutral).
|
||||
* 3. A boolean (true = RTL, false = LTR).
|
||||
* 4. A null for unknown directionality.
|
||||
*/
|
||||
goog.i18n.bidi.setElementDirAndAlign = function(element, dir) {
|
||||
if (element) {
|
||||
dir = goog.i18n.bidi.toDir(dir);
|
||||
if (dir) {
|
||||
element.style.textAlign = dir == goog.i18n.bidi.Dir.RTL ?
|
||||
goog.i18n.bidi.RIGHT :
|
||||
goog.i18n.bidi.LEFT;
|
||||
element.dir = dir == goog.i18n.bidi.Dir.RTL ? 'rtl' : 'ltr';
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets element dir based on estimated directionality of the given text.
|
||||
* @param {!Element} element
|
||||
* @param {string} text
|
||||
*/
|
||||
goog.i18n.bidi.setElementDirByTextDirectionality = function(element, text) {
|
||||
switch (goog.i18n.bidi.estimateDirection(text)) {
|
||||
case (goog.i18n.bidi.Dir.LTR):
|
||||
element.dir = 'ltr';
|
||||
break;
|
||||
case (goog.i18n.bidi.Dir.RTL):
|
||||
element.dir = 'rtl';
|
||||
break;
|
||||
default:
|
||||
// Default for no direction, inherit from document.
|
||||
element.removeAttribute('dir');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Strings that have an (optional) known direction.
|
||||
*
|
||||
* Implementations of this interface are string-like objects that carry an
|
||||
* attached direction, if known.
|
||||
* @interface
|
||||
*/
|
||||
goog.i18n.bidi.DirectionalString = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Interface marker of the DirectionalString interface.
|
||||
*
|
||||
* This property can be used to determine at runtime whether or not an object
|
||||
* implements this interface. All implementations of this interface set this
|
||||
* property to {@code true}.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.i18n.bidi.DirectionalString.prototype
|
||||
.implementsGoogI18nBidiDirectionalString;
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves this object's known direction (if any).
|
||||
* @return {?goog.i18n.bidi.Dir} The known direction. Null if unknown.
|
||||
*/
|
||||
goog.i18n.bidi.DirectionalString.prototype.getDirection;
|
||||
10354
resources/public/js/compiled/out/goog/i18n/compactnumberformatsymbols.js
Normal file
10354
resources/public/js/compiled/out/goog/i18n/compactnumberformatsymbols.js
Normal file
File diff suppressed because it is too large
Load diff
437
resources/public/js/compiled/out/goog/i18n/currency.js
Normal file
437
resources/public/js/compiled/out/goog/i18n/currency.js
Normal file
|
|
@ -0,0 +1,437 @@
|
|||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview A utility to get better currency format pattern.
|
||||
*
|
||||
* This module implements a new currency format representation model. It
|
||||
* provides 3 currency representation forms: global, portable and local. Local
|
||||
* format is the most popular format people use to represent currency in its
|
||||
* circulating country without worrying about how it should be distinguished
|
||||
* from other currencies. Global format is a formal representation in context
|
||||
* of multiple currencies in same page, it is ISO 4217 currency code. Portable
|
||||
* format is a compromise between global and local. It looks similar to how
|
||||
* people would like to see how their currency is being represented in other
|
||||
* media. While at the same time, it should be distinguishable to world's
|
||||
* popular currencies (like USD, EUR) and currencies somewhat relevant in the
|
||||
* area (like CNY in HK, though native currency is HKD). There is no guarantee
|
||||
* of uniqueness.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.i18n.currency');
|
||||
goog.provide('goog.i18n.currency.CurrencyInfo');
|
||||
goog.provide('goog.i18n.currency.CurrencyInfoTier2');
|
||||
|
||||
|
||||
/**
|
||||
* The mask of precision field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.currency.PRECISION_MASK_ = 0x07;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the currency sign should be positioned after the number.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.currency.POSITION_FLAG_ = 0x10;
|
||||
|
||||
|
||||
/**
|
||||
* Whether a space should be inserted between the number and currency sign.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.currency.SPACE_FLAG_ = 0x20;
|
||||
|
||||
|
||||
/**
|
||||
* Whether tier2 was enabled already by calling addTier2Support().
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.currency.tier2Enabled_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* This function will add tier2 currency support. Be default, only tier1
|
||||
* (most popular currencies) are supported. If an application really needs
|
||||
* to support some of the rarely used currencies, it should call this function
|
||||
* before any other functions in this namespace.
|
||||
*/
|
||||
goog.i18n.currency.addTier2Support = function() {
|
||||
// Protection from executing this these again and again.
|
||||
if (!goog.i18n.currency.tier2Enabled_) {
|
||||
for (var key in goog.i18n.currency.CurrencyInfoTier2) {
|
||||
goog.i18n.currency.CurrencyInfo[key] =
|
||||
goog.i18n.currency.CurrencyInfoTier2[key];
|
||||
}
|
||||
goog.i18n.currency.tier2Enabled_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Global currency pattern always uses ISO-4217 currency code as prefix. Local
|
||||
* currency sign is added if it is different from currency code. Each currency
|
||||
* is unique in this form. The negative side is that ISO code looks weird in
|
||||
* some countries as people normally do not use it. Local currency sign
|
||||
* alleviates the problem, but also makes it a little verbose.
|
||||
*
|
||||
* @param {string} currencyCode ISO-4217 3-letter currency code.
|
||||
* @return {string} Global currency pattern string for given currency.
|
||||
*/
|
||||
goog.i18n.currency.getGlobalCurrencyPattern = function(currencyCode) {
|
||||
var info = goog.i18n.currency.CurrencyInfo[currencyCode];
|
||||
var patternNum = info[0];
|
||||
if (currencyCode == info[1]) {
|
||||
return goog.i18n.currency.getCurrencyPattern_(patternNum, info[1]);
|
||||
}
|
||||
return currencyCode + ' ' +
|
||||
goog.i18n.currency.getCurrencyPattern_(patternNum, info[1]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return global currency sign string for those applications
|
||||
* that want to handle currency sign themselves.
|
||||
*
|
||||
* @param {string} currencyCode ISO-4217 3-letter currency code.
|
||||
* @return {string} Global currency sign for given currency.
|
||||
*/
|
||||
goog.i18n.currency.getGlobalCurrencySign = function(currencyCode) {
|
||||
var info = goog.i18n.currency.CurrencyInfo[currencyCode];
|
||||
return (currencyCode == info[1]) ? currencyCode :
|
||||
currencyCode + ' ' + info[1];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Local currency pattern is the most frequently used pattern in currency's
|
||||
* native region. It does not care about how it is distinguished from other
|
||||
* currencies.
|
||||
*
|
||||
* @param {string} currencyCode ISO-4217 3-letter currency code.
|
||||
* @return {string} Local currency pattern string for given currency.
|
||||
*/
|
||||
goog.i18n.currency.getLocalCurrencyPattern = function(currencyCode) {
|
||||
var info = goog.i18n.currency.CurrencyInfo[currencyCode];
|
||||
return goog.i18n.currency.getCurrencyPattern_(info[0], info[1]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns local currency sign string for those applications that need to
|
||||
* handle currency sign separately.
|
||||
*
|
||||
* @param {string} currencyCode ISO-4217 3-letter currency code.
|
||||
* @return {string} Local currency sign for given currency.
|
||||
*/
|
||||
goog.i18n.currency.getLocalCurrencySign = function(currencyCode) {
|
||||
return goog.i18n.currency.CurrencyInfo[currencyCode][1];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Portable currency pattern is a compromise between local and global. It is
|
||||
* not a mere blend or mid-way between the two. Currency sign is chosen so that
|
||||
* it looks familiar to native users. It also has enough information to
|
||||
* distinguish itself from other popular currencies in its native region.
|
||||
* In this pattern, currency sign symbols that has availability problem in
|
||||
* popular fonts are also avoided.
|
||||
*
|
||||
* @param {string} currencyCode ISO-4217 3-letter currency code.
|
||||
* @return {string} Portable currency pattern string for given currency.
|
||||
*/
|
||||
goog.i18n.currency.getPortableCurrencyPattern = function(currencyCode) {
|
||||
var info = goog.i18n.currency.CurrencyInfo[currencyCode];
|
||||
return goog.i18n.currency.getCurrencyPattern_(info[0], info[2]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return portable currency sign string for those applications that need to
|
||||
* handle currency sign themselves.
|
||||
*
|
||||
* @param {string} currencyCode ISO-4217 3-letter currency code.
|
||||
* @return {string} Portable currency sign for given currency.
|
||||
*/
|
||||
goog.i18n.currency.getPortableCurrencySign = function(currencyCode) {
|
||||
return goog.i18n.currency.CurrencyInfo[currencyCode][2];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This function returns the default currency sign position. Some applications
|
||||
* may want to handle currency sign and currency amount separately. This
|
||||
* function can be used in such situations to correctly position the currency
|
||||
* sign relative to the amount.
|
||||
*
|
||||
* To match the behavior of ICU, position is not determined by display locale.
|
||||
*
|
||||
* @param {string} currencyCode ISO-4217 3-letter currency code.
|
||||
* @return {boolean} true if currency should be positioned before amount field.
|
||||
*/
|
||||
goog.i18n.currency.isPrefixSignPosition = function(currencyCode) {
|
||||
return (goog.i18n.currency.CurrencyInfo[currencyCode][0] &
|
||||
goog.i18n.currency.POSITION_FLAG_) == 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This function constructs the currency pattern. Currency sign is provided. The
|
||||
* pattern information is encoded in patternNum.
|
||||
*
|
||||
* @param {number} patternNum Encoded pattern number that has
|
||||
* currency pattern information.
|
||||
* @param {string} sign The currency sign that will be used in pattern.
|
||||
* @return {string} currency pattern string.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.currency.getCurrencyPattern_ = function(patternNum, sign) {
|
||||
var strParts = ['#,##0'];
|
||||
var precision = patternNum & goog.i18n.currency.PRECISION_MASK_;
|
||||
if (precision > 0) {
|
||||
strParts.push('.');
|
||||
for (var i = 0; i < precision; i++) {
|
||||
strParts.push('0');
|
||||
}
|
||||
}
|
||||
if ((patternNum & goog.i18n.currency.POSITION_FLAG_) == 0) {
|
||||
strParts.unshift(
|
||||
(patternNum & goog.i18n.currency.SPACE_FLAG_) ? "' " : "'");
|
||||
strParts.unshift(sign);
|
||||
strParts.unshift("'");
|
||||
} else {
|
||||
strParts.push(
|
||||
(patternNum & goog.i18n.currency.SPACE_FLAG_) ? " '" : "'", sign, "'");
|
||||
}
|
||||
return strParts.join('');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Modify currency pattern string by adjusting precision for given currency.
|
||||
* Standard currency pattern will have 2 digit after decimal point.
|
||||
* Examples:
|
||||
* $#,##0.00 -> $#,##0 (precision == 0)
|
||||
* $#,##0.00 -> $#,##0.0 (precision == 1)
|
||||
* $#,##0.00 -> $#,##0.000 (precision == 3)
|
||||
*
|
||||
* @param {string} pattern currency pattern string.
|
||||
* @param {string} currencyCode 3-letter currency code.
|
||||
* @return {string} modified currency pattern string.
|
||||
*/
|
||||
goog.i18n.currency.adjustPrecision = function(pattern, currencyCode) {
|
||||
var strParts = ['0'];
|
||||
var info = goog.i18n.currency.CurrencyInfo[currencyCode];
|
||||
var precision = info[0] & goog.i18n.currency.PRECISION_MASK_;
|
||||
if (precision > 0) {
|
||||
strParts.push('.');
|
||||
for (var i = 0; i < precision; i++) {
|
||||
strParts.push('0');
|
||||
}
|
||||
}
|
||||
return pattern.replace(/0.00/g, strParts.join(''));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tier 1 currency information.
|
||||
*
|
||||
* The first number in the array is a combination of the precision mask and
|
||||
* other flags. The precision mask indicates how many decimal places to show for
|
||||
* the currency. Valid values are [0..7]. The position flag indicates whether
|
||||
* the currency sign should be positioned after the number. Valid values are 0
|
||||
* (before the number) or 16 (after the number). The space flag indicates
|
||||
* whether a space should be inserted between the currency sign and number.
|
||||
* Valid values are 0 (no space) and 32 (space).
|
||||
*
|
||||
* The number in the array is calculated by adding together the mask and flag
|
||||
* values. For example:
|
||||
*
|
||||
* 0: no precision (0), currency sign first (0), no space (0)
|
||||
* 2: two decimals precision (2), currency sign first (0), no space (0)
|
||||
* 18: two decimals precision (2), currency sign last (16), no space (0)
|
||||
* 50: two decimals precision (2), currency sign last (16), space (32)
|
||||
*
|
||||
* @const {!Object<!Array<?>>}
|
||||
*/
|
||||
goog.i18n.currency.CurrencyInfo = {
|
||||
'AED': [2, 'dh', '\u062f.\u0625.', 'DH'],
|
||||
'ALL': [0, 'Lek', 'Lek'],
|
||||
'AUD': [2, '$', 'AU$'],
|
||||
'BDT': [2, '\u09F3', 'Tk'],
|
||||
'BGN': [2, 'lev', 'lev'],
|
||||
'BRL': [2, 'R$', 'R$'],
|
||||
'CAD': [2, '$', 'C$'],
|
||||
'CDF': [2, 'FrCD', 'CDF'],
|
||||
'CHF': [2, 'CHF', 'CHF'],
|
||||
'CLP': [0, '$', 'CL$'],
|
||||
'CNY': [2, '¥', 'RMB¥'],
|
||||
'COP': [32, '$', 'COL$'],
|
||||
'CRC': [0, '\u20a1', 'CR\u20a1'],
|
||||
'CZK': [50, 'K\u010d', 'K\u010d'],
|
||||
'DKK': [50, 'kr.', 'kr.'],
|
||||
'DOP': [2, 'RD$', 'RD$'],
|
||||
'EGP': [2, '£', 'LE'],
|
||||
'ETB': [2, 'Birr', 'Birr'],
|
||||
'EUR': [2, '€', '€'],
|
||||
'GBP': [2, '£', 'GB£'],
|
||||
'HKD': [2, '$', 'HK$'],
|
||||
'HRK': [2, 'kn', 'kn'],
|
||||
'HUF': [34, 'Ft', 'Ft'],
|
||||
'IDR': [0, 'Rp', 'Rp'],
|
||||
'ILS': [34, '\u20AA', 'IL\u20AA'],
|
||||
'INR': [2, '\u20B9', 'Rs'],
|
||||
'IRR': [0, 'Rial', 'IRR'],
|
||||
'ISK': [0, 'kr', 'kr'],
|
||||
'JMD': [2, '$', 'JA$'],
|
||||
'JPY': [0, '¥', 'JP¥'],
|
||||
'KRW': [0, '\u20A9', 'KR₩'],
|
||||
'LKR': [2, 'Rs', 'SLRs'],
|
||||
'LTL': [2, 'Lt', 'Lt'],
|
||||
'MNT': [0, '\u20AE', 'MN₮'],
|
||||
'MVR': [2, 'Rf', 'MVR'],
|
||||
'MXN': [2, '$', 'Mex$'],
|
||||
'MYR': [2, 'RM', 'RM'],
|
||||
'NOK': [50, 'kr', 'NOkr'],
|
||||
'PAB': [2, 'B/.', 'B/.'],
|
||||
'PEN': [2, 'S/.', 'S/.'],
|
||||
'PHP': [2, '\u20B1', 'Php'],
|
||||
'PKR': [0, 'Rs', 'PKRs.'],
|
||||
'PLN': [50, 'z\u0142', 'z\u0142'],
|
||||
'RON': [2, 'RON', 'RON'],
|
||||
'RSD': [0, 'din', 'RSD'],
|
||||
'RUB': [50, '\u20bd', 'RUB'],
|
||||
'SAR': [2, 'Rial', 'Rial'],
|
||||
'SEK': [50, 'kr', 'kr'],
|
||||
'SGD': [2, '$', 'S$'],
|
||||
'THB': [2, '\u0e3f', 'THB'],
|
||||
'TRY': [2, 'TL', 'YTL'],
|
||||
'TWD': [2, 'NT$', 'NT$'],
|
||||
'TZS': [0, 'TSh', 'TSh'],
|
||||
'UAH': [2, 'грн.', 'UAH'],
|
||||
'USD': [2, '$', 'US$'],
|
||||
'UYU': [2, '$', '$U'],
|
||||
'VND': [48, '\u20AB', 'VN\u20AB'],
|
||||
'YER': [0, 'Rial', 'Rial'],
|
||||
'ZAR': [2, 'R', 'ZAR']
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tier 2 currency information.
|
||||
* @const {!Object<!Array<?>>}
|
||||
*/
|
||||
goog.i18n.currency.CurrencyInfoTier2 = {
|
||||
'AFN': [48, 'Af.', 'AFN'],
|
||||
'AMD': [32, 'Dram', 'dram'],
|
||||
'ANG': [2, 'NAf.', 'ANG'],
|
||||
'AOA': [2, 'Kz', 'Kz'],
|
||||
'ARS': [34, '$', 'AR$'],
|
||||
'AWG': [2, 'Afl.', 'Afl.'],
|
||||
'AZN': [34, '\u20bc', 'AZN'],
|
||||
'BAM': [2, 'KM', 'KM'],
|
||||
'BBD': [2, '$', 'Bds$'],
|
||||
'BHD': [3, 'din', 'din'],
|
||||
'BIF': [0, 'FBu', 'FBu'],
|
||||
'BMD': [2, '$', 'BD$'],
|
||||
'BND': [2, '$', 'B$'],
|
||||
'BOB': [2, 'Bs', 'Bs'],
|
||||
'BSD': [2, '$', 'BS$'],
|
||||
'BTN': [2, 'Nu.', 'Nu.'],
|
||||
'BWP': [2, 'P', 'pula'],
|
||||
'BYR': [48, 'p.', 'BYR'],
|
||||
'BZD': [2, '$', 'BZ$'],
|
||||
'CUC': [1, '$', 'CUC$'],
|
||||
'CUP': [2, '$', 'CU$'],
|
||||
'CVE': [2, 'CVE', 'Esc'],
|
||||
'DJF': [0, 'Fdj', 'Fdj'],
|
||||
'DZD': [2, 'din', 'din'],
|
||||
'ERN': [2, 'Nfk', 'Nfk'],
|
||||
'FJD': [2, '$', 'FJ$'],
|
||||
'FKP': [2, '£', 'FK£'],
|
||||
'GEL': [2, 'GEL', 'GEL'],
|
||||
'GHS': [2, 'GHS', 'GHS'],
|
||||
'GIP': [2, '£', 'GI£'],
|
||||
'GMD': [2, 'GMD', 'GMD'],
|
||||
'GNF': [0, 'FG', 'FG'],
|
||||
'GTQ': [2, 'Q', 'GTQ'],
|
||||
'GYD': [0, '$', 'GY$'],
|
||||
'HNL': [2, 'L', 'HNL'],
|
||||
'HTG': [2, 'HTG', 'HTG'],
|
||||
'IQD': [0, 'din', 'IQD'],
|
||||
'JOD': [3, 'din', 'JOD'],
|
||||
'KES': [2, 'Ksh', 'Ksh'],
|
||||
'KGS': [2, 'KGS', 'KGS'],
|
||||
'KHR': [2, 'Riel', 'KHR'],
|
||||
'KMF': [0, 'CF', 'KMF'],
|
||||
'KPW': [0, '\u20A9KP', 'KPW'],
|
||||
'KWD': [3, 'din', 'KWD'],
|
||||
'KYD': [2, '$', 'KY$'],
|
||||
'KZT': [2, '\u20B8', 'KZT'],
|
||||
'LAK': [0, '\u20AD', '\u20AD'],
|
||||
'LBP': [0, 'L£', 'LBP'],
|
||||
'LRD': [2, '$', 'L$'],
|
||||
'LSL': [2, 'LSL', 'LSL'],
|
||||
'LYD': [3, 'din', 'LD'],
|
||||
'MAD': [2, 'dh', 'MAD'],
|
||||
'MDL': [2, 'MDL', 'MDL'],
|
||||
'MGA': [0, 'Ar', 'MGA'],
|
||||
'MKD': [2, 'din', 'MKD'],
|
||||
'MMK': [0, 'K', 'MMK'],
|
||||
'MOP': [2, 'MOP', 'MOP$'],
|
||||
'MRO': [0, 'MRO', 'MRO'],
|
||||
'MUR': [0, 'MURs', 'MURs'],
|
||||
'MWK': [2, 'MWK', 'MWK'],
|
||||
'MZN': [2, 'MTn', 'MTn'],
|
||||
'NAD': [2, '$', 'N$'],
|
||||
'NGN': [2, '\u20A6', 'NG\u20A6'],
|
||||
'NIO': [2, 'C$', 'C$'],
|
||||
'NPR': [2, 'Rs', 'NPRs'],
|
||||
'NZD': [2, '$', 'NZ$'],
|
||||
'OMR': [3, 'Rial', 'OMR'],
|
||||
'PGK': [2, 'PGK', 'PGK'],
|
||||
'PYG': [16, 'Gs.', 'PYG'],
|
||||
'QAR': [2, 'Rial', 'QR'],
|
||||
'RWF': [0, 'RF', 'RF'],
|
||||
'SBD': [2, '$', 'SI$'],
|
||||
'SCR': [2, 'SCR', 'SCR'],
|
||||
'SDG': [2, 'SDG', 'SDG'],
|
||||
'SHP': [2, '£', 'SH£'],
|
||||
'SLL': [0, 'SLL', 'SLL'],
|
||||
'SOS': [0, 'SOS', 'SOS'],
|
||||
'SRD': [2, '$', 'SR$'],
|
||||
'SSP': [2, '£', 'SSP'],
|
||||
'STD': [0, 'Db', 'Db'],
|
||||
'SYP': [0, '£', 'SY£'],
|
||||
'SZL': [2, 'SZL', 'SZL'],
|
||||
'TJS': [2, 'Som', 'TJS'],
|
||||
'TND': [3, 'din', 'DT'],
|
||||
'TOP': [2, 'T$', 'T$'],
|
||||
'TTD': [2, '$', 'TT$'],
|
||||
'UGX': [0, 'UGX', 'UGX'],
|
||||
'UZS': [0, 'so\u02bcm', 'UZS'],
|
||||
'VEF': [2, 'Bs', 'Bs'],
|
||||
'VUV': [0, 'VUV', 'VUV'],
|
||||
'WST': [2, 'WST', 'WST'],
|
||||
'XAF': [0, 'FCFA', 'FCFA'],
|
||||
'XCD': [2, '$', 'EC$'],
|
||||
'XOF': [0, 'CFA', 'CFA'],
|
||||
'XPF': [0, 'FCFP', 'FCFP'],
|
||||
'ZMW': [0, 'ZMW', 'ZMW'],
|
||||
'ZWD': [0, '$', 'Z$']
|
||||
};
|
||||
882
resources/public/js/compiled/out/goog/i18n/datetimeformat.js
Normal file
882
resources/public/js/compiled/out/goog/i18n/datetimeformat.js
Normal file
|
|
@ -0,0 +1,882 @@
|
|||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Functions for dealing with date/time formatting.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Namespace for i18n date/time formatting functions
|
||||
*/
|
||||
goog.provide('goog.i18n.DateTimeFormat');
|
||||
goog.provide('goog.i18n.DateTimeFormat.Format');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.date');
|
||||
goog.require('goog.i18n.DateTimeSymbols');
|
||||
goog.require('goog.i18n.TimeZone');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* Datetime formatting functions following the pattern specification as defined
|
||||
* in JDK, ICU and CLDR, with minor modification for typical usage in JS.
|
||||
* Pattern specification:
|
||||
* {@link http://userguide.icu-project.org/formatparse/datetime}
|
||||
* <pre>
|
||||
* Symbol Meaning Presentation Example
|
||||
* ------ ------- ------------ -------
|
||||
* G# era designator (Text) AD
|
||||
* y# year (Number) 1996
|
||||
* Y* year (week of year) (Number) 1997
|
||||
* u* extended year (Number) 4601
|
||||
* Q# quarter (Text) Q3 & 3rd quarter
|
||||
* M month in year (Text & Number) July & 07
|
||||
* L month in year (standalone) (Text & Number) July & 07
|
||||
* d day in month (Number) 10
|
||||
* h hour in am/pm (1~12) (Number) 12
|
||||
* H hour in day (0~23) (Number) 0
|
||||
* m minute in hour (Number) 30
|
||||
* s second in minute (Number) 55
|
||||
* S fractional second (Number) 978
|
||||
* E# day of week (Text) Tue & Tuesday
|
||||
* e* day of week (local 1~7) (Number) 2
|
||||
* c# day of week (standalone) (Text & Number) 2 & Tues & Tuesday & T
|
||||
* D* day in year (Number) 189
|
||||
* F* day of week in month (Number) 2 (2nd Wed in July)
|
||||
* w week in year (Number) 27
|
||||
* W* week in month (Number) 2
|
||||
* a am/pm marker (Text) PM
|
||||
* k hour in day (1~24) (Number) 24
|
||||
* K hour in am/pm (0~11) (Number) 0
|
||||
* z time zone (Text) Pacific Standard Time
|
||||
* Z# time zone (RFC 822) (Number) -0800
|
||||
* v# time zone (generic) (Text) America/Los_Angeles
|
||||
* V# time zone (Text) Los Angeles Time
|
||||
* g* Julian day (Number) 2451334
|
||||
* A* milliseconds in day (Number) 69540000
|
||||
* ' escape for text (Delimiter) 'Date='
|
||||
* '' single quote (Literal) 'o''clock'
|
||||
*
|
||||
* Item marked with '*' are not supported yet.
|
||||
* Item marked with '#' works different than java
|
||||
*
|
||||
* The count of pattern letters determine the format.
|
||||
* (Text): 4 or more, use full form, <4, use short or abbreviated form if it
|
||||
* exists. (e.g., "EEEE" produces "Monday", "EEE" produces "Mon")
|
||||
*
|
||||
* (Number): the minimum number of digits. Shorter numbers are zero-padded to
|
||||
* this amount (e.g. if "m" produces "6", "mm" produces "06"). Year is handled
|
||||
* specially; that is, if the count of 'y' is 2, the Year will be truncated to
|
||||
* 2 digits. (e.g., if "yyyy" produces "1997", "yy" produces "97".) Unlike other
|
||||
* fields, fractional seconds are padded on the right with zero.
|
||||
*
|
||||
* :(Text & Number) 3 or over, use text, otherwise use number. (e.g., "M"
|
||||
* produces "1", "MM" produces "01", "MMM" produces "Jan", and "MMMM" produces
|
||||
* "January".)
|
||||
*
|
||||
* Any characters in the pattern that are not in the ranges of ['a'..'z'] and
|
||||
* ['A'..'Z'] will be treated as quoted text. For instance, characters like ':',
|
||||
* '.', ' ', '#' and '@' will appear in the resulting time text even they are
|
||||
* not embraced within single quotes.
|
||||
* </pre>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Construct a DateTimeFormat object based on current locale.
|
||||
* @constructor
|
||||
* @param {string|number} pattern pattern specification or pattern type.
|
||||
* @param {!Object=} opt_dateTimeSymbols Optional symbols to use for this
|
||||
* instance rather than the global symbols.
|
||||
* @final
|
||||
*/
|
||||
goog.i18n.DateTimeFormat = function(pattern, opt_dateTimeSymbols) {
|
||||
goog.asserts.assert(goog.isDef(pattern), 'Pattern must be defined');
|
||||
goog.asserts.assert(
|
||||
goog.isDef(opt_dateTimeSymbols) || goog.isDef(goog.i18n.DateTimeSymbols),
|
||||
'goog.i18n.DateTimeSymbols or explicit symbols must be defined');
|
||||
|
||||
this.patternParts_ = [];
|
||||
|
||||
/**
|
||||
* Data structure that with all the locale info needed for date formatting.
|
||||
* (day/month names, most common patterns, rules for week-end, etc.)
|
||||
* @private {!goog.i18n.DateTimeSymbolsType}
|
||||
*/
|
||||
this.dateTimeSymbols_ = /** @type {!goog.i18n.DateTimeSymbolsType} */ (
|
||||
opt_dateTimeSymbols || goog.i18n.DateTimeSymbols);
|
||||
if (typeof pattern == 'number') {
|
||||
this.applyStandardPattern_(pattern);
|
||||
} else {
|
||||
this.applyPattern_(pattern);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Enum to identify predefined Date/Time format pattern.
|
||||
* @enum {number}
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.Format = {
|
||||
FULL_DATE: 0,
|
||||
LONG_DATE: 1,
|
||||
MEDIUM_DATE: 2,
|
||||
SHORT_DATE: 3,
|
||||
FULL_TIME: 4,
|
||||
LONG_TIME: 5,
|
||||
MEDIUM_TIME: 6,
|
||||
SHORT_TIME: 7,
|
||||
FULL_DATETIME: 8,
|
||||
LONG_DATETIME: 9,
|
||||
MEDIUM_DATETIME: 10,
|
||||
SHORT_DATETIME: 11
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* regular expression pattern for parsing pattern string
|
||||
* @type {Array<RegExp>}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.TOKENS_ = [
|
||||
// quote string
|
||||
/^\'(?:[^\']|\'\')*\'/,
|
||||
// pattern chars
|
||||
/^(?:G+|y+|M+|k+|S+|E+|a+|h+|K+|H+|c+|L+|Q+|d+|m+|s+|v+|V+|w+|z+|Z+)/,
|
||||
// and all the other chars
|
||||
/^[^\'GyMkSEahKHcLQdmsvVwzZ]+/ // and all the other chars
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* These are token types, corresponding to above token definitions.
|
||||
* @enum {number}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.PartTypes_ = {
|
||||
QUOTED_STRING: 0,
|
||||
FIELD: 1,
|
||||
LITERAL: 2
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!goog.date.DateLike} date
|
||||
* @return {number}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.getHours_ = function(date) {
|
||||
return date.getHours ? date.getHours() : 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Apply specified pattern to this formatter object.
|
||||
* @param {string} pattern String specifying how the date should be formatted.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.applyPattern_ = function(pattern) {
|
||||
if (goog.i18n.DateTimeFormat.removeRlmInPatterns_) {
|
||||
// Remove RLM unicode control character from pattern.
|
||||
pattern = pattern.replace(/\u200f/g, '');
|
||||
}
|
||||
// lex the pattern, once for all uses
|
||||
while (pattern) {
|
||||
for (var i = 0; i < goog.i18n.DateTimeFormat.TOKENS_.length; ++i) {
|
||||
var m = pattern.match(goog.i18n.DateTimeFormat.TOKENS_[i]);
|
||||
if (m) {
|
||||
var part = m[0];
|
||||
pattern = pattern.substring(part.length);
|
||||
if (i == goog.i18n.DateTimeFormat.PartTypes_.QUOTED_STRING) {
|
||||
if (part == "''") {
|
||||
part = "'"; // '' -> '
|
||||
} else {
|
||||
part = part.substring(1, part.length - 1); // strip quotes
|
||||
part = part.replace(/\'\'/, "'");
|
||||
}
|
||||
}
|
||||
this.patternParts_.push({text: part, type: i});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Format the given date object according to preset pattern and current locale.
|
||||
* @param {goog.date.DateLike} date The Date object that is being formatted.
|
||||
* @param {goog.i18n.TimeZone=} opt_timeZone optional, if specified, time
|
||||
* related fields will be formatted based on its setting. When this field
|
||||
* is not specified, "undefined" will be pass around and those function
|
||||
* that really need time zone service will create a default one.
|
||||
* @return {string} Formatted string for the given date.
|
||||
* Throws an error if the date is null or if one tries to format a date-only
|
||||
* object (for instance goog.date.Date) using a pattern with time fields.
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.format = function(date, opt_timeZone) {
|
||||
if (!date) throw Error('The date to format must be non-null.');
|
||||
|
||||
// We don't want to write code to calculate each date field because we
|
||||
// want to maximize performance and minimize code size.
|
||||
// JavaScript only provide API to render local time.
|
||||
// Suppose target date is: 16:00 GMT-0400
|
||||
// OS local time is: 12:00 GMT-0800
|
||||
// We want to create a Local Date Object : 16:00 GMT-0800, and fix the
|
||||
// time zone display ourselves.
|
||||
// Thing get a little bit tricky when daylight time transition happens. For
|
||||
// example, suppose OS timeZone is America/Los_Angeles, it is impossible to
|
||||
// represent "2006/4/2 02:30" even for those timeZone that has no transition
|
||||
// at this time. Because 2:00 to 3:00 on that day does not exist in
|
||||
// America/Los_Angeles time zone. To avoid calculating date field through
|
||||
// our own code, we uses 3 Date object instead, one for "Year, month, day",
|
||||
// one for time within that day, and one for timeZone object since it need
|
||||
// the real time to figure out actual time zone offset.
|
||||
var diff = opt_timeZone ?
|
||||
(date.getTimezoneOffset() - opt_timeZone.getOffset(date)) * 60000 :
|
||||
0;
|
||||
var dateForDate = diff ? new Date(date.getTime() + diff) : date;
|
||||
var dateForTime = dateForDate;
|
||||
// When the time manipulation applied above spans the DST on/off hour, this
|
||||
// could alter the time incorrectly by adding or subtracting an additional
|
||||
// hour.
|
||||
// We can mitigate this by:
|
||||
// - Adding the difference in timezone offset to the date. This ensures that
|
||||
// the dateForDate is still within the right day if the extra DST hour
|
||||
// affected the date.
|
||||
// - Move the time one day forward if we applied a timezone offset backwards,
|
||||
// or vice versa. This trick ensures that the time is in the same offset
|
||||
// as the original date, so we remove the additional hour added or
|
||||
// subtracted by the DST switch.
|
||||
if (opt_timeZone &&
|
||||
dateForDate.getTimezoneOffset() != date.getTimezoneOffset()) {
|
||||
var dstDiff =
|
||||
(dateForDate.getTimezoneOffset() - date.getTimezoneOffset()) * 60000;
|
||||
dateForDate = new Date(dateForDate.getTime() + dstDiff);
|
||||
|
||||
diff += diff > 0 ? -goog.date.MS_PER_DAY : goog.date.MS_PER_DAY;
|
||||
dateForTime = new Date(date.getTime() + diff);
|
||||
}
|
||||
|
||||
var out = [];
|
||||
for (var i = 0; i < this.patternParts_.length; ++i) {
|
||||
var text = this.patternParts_[i].text;
|
||||
if (goog.i18n.DateTimeFormat.PartTypes_.FIELD ==
|
||||
this.patternParts_[i].type) {
|
||||
out.push(
|
||||
this.formatField_(
|
||||
text, date, dateForDate, dateForTime, opt_timeZone));
|
||||
} else {
|
||||
out.push(text);
|
||||
}
|
||||
}
|
||||
return out.join('');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Apply a predefined pattern as identified by formatType, which is stored in
|
||||
* locale specific repository.
|
||||
* @param {number} formatType A number that identified the predefined pattern.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.applyStandardPattern_ = function(
|
||||
formatType) {
|
||||
var pattern;
|
||||
if (formatType < 4) {
|
||||
pattern = this.dateTimeSymbols_.DATEFORMATS[formatType];
|
||||
} else if (formatType < 8) {
|
||||
pattern = this.dateTimeSymbols_.TIMEFORMATS[formatType - 4];
|
||||
} else if (formatType < 12) {
|
||||
pattern = this.dateTimeSymbols_.DATETIMEFORMATS[formatType - 8];
|
||||
pattern = pattern.replace(
|
||||
'{1}', this.dateTimeSymbols_.DATEFORMATS[formatType - 8]);
|
||||
pattern = pattern.replace(
|
||||
'{0}', this.dateTimeSymbols_.TIMEFORMATS[formatType - 8]);
|
||||
} else {
|
||||
this.applyStandardPattern_(goog.i18n.DateTimeFormat.Format.MEDIUM_DATETIME);
|
||||
return;
|
||||
}
|
||||
this.applyPattern_(pattern);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Localizes a string potentially containing numbers, replacing ASCII digits
|
||||
* with native digits if specified so by the locale. Leaves other characters.
|
||||
* @param {string} input the string to be localized, using ASCII digits.
|
||||
* @return {string} localized string, potentially using native digits.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.localizeNumbers_ = function(input) {
|
||||
return goog.i18n.DateTimeFormat.localizeNumbers(input, this.dateTimeSymbols_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* If the usage of Ascii digits should be enforced regardless of locale.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.enforceAsciiDigits_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* If RLM unicode characters should be removed from date/time patterns (useful
|
||||
* when enforcing ASCII digits for Arabic). See {@code #setEnforceAsciiDigits}.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.removeRlmInPatterns_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* Sets if the usage of Ascii digits in formatting should be enforced in
|
||||
* formatted date/time even for locales where native digits are indicated.
|
||||
* Also sets whether to remove RLM unicode control characters when using
|
||||
* standard enumerated patterns (they exist e.g. in standard d/M/y for Arabic).
|
||||
* Production code should call this once before any {@code DateTimeFormat}
|
||||
* object is instantiated.
|
||||
* Caveats:
|
||||
* * Enforcing ASCII digits affects all future formatting by new or existing
|
||||
* {@code DateTimeFormat} objects.
|
||||
* * Removal of RLM characters only applies to {@code DateTimeFormat} objects
|
||||
* instantiated after this call.
|
||||
* @param {boolean} enforceAsciiDigits Whether Ascii digits should be enforced.
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.setEnforceAsciiDigits = function(enforceAsciiDigits) {
|
||||
goog.i18n.DateTimeFormat.enforceAsciiDigits_ = enforceAsciiDigits;
|
||||
|
||||
// Also setting removal of RLM chracters when forcing ASCII digits since it's
|
||||
// the right thing to do for Arabic standard patterns. One could add an
|
||||
// optional argument here or to the {@code DateTimeFormat} constructor to
|
||||
// enable an alternative behavior.
|
||||
goog.i18n.DateTimeFormat.removeRlmInPatterns_ = enforceAsciiDigits;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether enforcing ASCII digits for all locales. See
|
||||
* {@code #setEnforceAsciiDigits} for more details.
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.isEnforceAsciiDigits = function() {
|
||||
return goog.i18n.DateTimeFormat.enforceAsciiDigits_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Localizes a string potentially containing numbers, replacing ASCII digits
|
||||
* with native digits if specified so by the locale. Leaves other characters.
|
||||
* @param {number|string} input the string to be localized, using ASCII digits.
|
||||
* @param {!Object=} opt_dateTimeSymbols Optional symbols to use rather than
|
||||
* the global symbols.
|
||||
* @return {string} localized string, potentially using native digits.
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.localizeNumbers = function(
|
||||
input, opt_dateTimeSymbols) {
|
||||
input = String(input);
|
||||
var dateTimeSymbols = opt_dateTimeSymbols || goog.i18n.DateTimeSymbols;
|
||||
if (dateTimeSymbols.ZERODIGIT === undefined ||
|
||||
goog.i18n.DateTimeFormat.enforceAsciiDigits_) {
|
||||
return input;
|
||||
}
|
||||
|
||||
var parts = [];
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
var c = input.charCodeAt(i);
|
||||
parts.push(
|
||||
(0x30 <= c && c <= 0x39) ? // '0' <= c <= '9'
|
||||
String.fromCharCode(dateTimeSymbols.ZERODIGIT + c - 0x30) :
|
||||
input.charAt(i));
|
||||
}
|
||||
return parts.join('');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats Era field according to pattern specified.
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} Formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatEra_ = function(count, date) {
|
||||
var value = date.getFullYear() > 0 ? 1 : 0;
|
||||
return count >= 4 ? this.dateTimeSymbols_.ERANAMES[value] :
|
||||
this.dateTimeSymbols_.ERAS[value];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats Year field according to pattern specified
|
||||
* Javascript Date object seems incapable handling 1BC and
|
||||
* year before. It can show you year 0 which does not exists.
|
||||
* following we just keep consistent with javascript's
|
||||
* toString method. But keep in mind those things should be
|
||||
* unsupported.
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} Formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatYear_ = function(count, date) {
|
||||
var value = date.getFullYear();
|
||||
if (value < 0) {
|
||||
value = -value;
|
||||
}
|
||||
if (count == 2) {
|
||||
// See comment about special casing 'yy' at the start of the file, this
|
||||
// matches ICU and CLDR behaviour. See also:
|
||||
// http://icu-project.org/apiref/icu4j/com/ibm/icu/text/SimpleDateFormat.html
|
||||
// http://www.unicode.org/reports/tr35/tr35-dates.html
|
||||
value = value % 100;
|
||||
}
|
||||
return this.localizeNumbers_(goog.string.padNumber(value, count));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats Month field according to pattern specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} Formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatMonth_ = function(count, date) {
|
||||
var value = date.getMonth();
|
||||
switch (count) {
|
||||
case 5:
|
||||
return this.dateTimeSymbols_.NARROWMONTHS[value];
|
||||
case 4:
|
||||
return this.dateTimeSymbols_.MONTHS[value];
|
||||
case 3:
|
||||
return this.dateTimeSymbols_.SHORTMONTHS[value];
|
||||
default:
|
||||
return this.localizeNumbers_(goog.string.padNumber(value + 1, count));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Validates is the goog.date.DateLike object to format has a time.
|
||||
* DateLike means Date|goog.date.Date, and goog.date.DateTime inherits
|
||||
* from goog.date.Date. But goog.date.Date does not have time related
|
||||
* members (getHours, getMinutes, getSeconds).
|
||||
* Formatting can be done, if there are no time placeholders in the pattern.
|
||||
*
|
||||
* @param {!goog.date.DateLike} date the object to validate.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.validateDateHasTime_ = function(date) {
|
||||
if (date.getHours && date.getSeconds && date.getMinutes) return;
|
||||
// if (date instanceof Date || date instanceof goog.date.DateTime)
|
||||
throw Error(
|
||||
'The date to format has no time (probably a goog.date.Date). ' +
|
||||
'Use Date or goog.date.DateTime, or use a pattern without time fields.');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats (1..24) Hours field according to pattern specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats. This controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} Formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.format24Hours_ = function(count, date) {
|
||||
goog.i18n.DateTimeFormat.validateDateHasTime_(date);
|
||||
var hours = goog.i18n.DateTimeFormat.getHours_(date) || 24;
|
||||
return this.localizeNumbers_(goog.string.padNumber(hours, count));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats Fractional seconds field according to pattern
|
||||
* specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
*
|
||||
* @return {string} Formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatFractionalSeconds_ = function(
|
||||
count, date) {
|
||||
// Fractional seconds left-justify, append 0 for precision beyond 3
|
||||
var value = date.getTime() % 1000 / 1000;
|
||||
return this.localizeNumbers_(
|
||||
value.toFixed(Math.min(3, count)).substr(2) +
|
||||
(count > 3 ? goog.string.padNumber(0, count - 3) : ''));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats Day of week field according to pattern specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} Formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatDayOfWeek_ = function(count, date) {
|
||||
var value = date.getDay();
|
||||
return count >= 4 ? this.dateTimeSymbols_.WEEKDAYS[value] :
|
||||
this.dateTimeSymbols_.SHORTWEEKDAYS[value];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats Am/Pm field according to pattern specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} Formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatAmPm_ = function(count, date) {
|
||||
goog.i18n.DateTimeFormat.validateDateHasTime_(date);
|
||||
var hours = goog.i18n.DateTimeFormat.getHours_(date);
|
||||
return this.dateTimeSymbols_.AMPMS[hours >= 12 && hours < 24 ? 1 : 0];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats (1..12) Hours field according to pattern specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.format1To12Hours_ = function(count, date) {
|
||||
goog.i18n.DateTimeFormat.validateDateHasTime_(date);
|
||||
var hours = goog.i18n.DateTimeFormat.getHours_(date) % 12 || 12;
|
||||
return this.localizeNumbers_(goog.string.padNumber(hours, count));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats (0..11) Hours field according to pattern specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.format0To11Hours_ = function(count, date) {
|
||||
goog.i18n.DateTimeFormat.validateDateHasTime_(date);
|
||||
var hours = goog.i18n.DateTimeFormat.getHours_(date) % 12;
|
||||
return this.localizeNumbers_(goog.string.padNumber(hours, count));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats (0..23) Hours field according to pattern specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.format0To23Hours_ = function(count, date) {
|
||||
goog.i18n.DateTimeFormat.validateDateHasTime_(date);
|
||||
var hours = goog.i18n.DateTimeFormat.getHours_(date);
|
||||
return this.localizeNumbers_(goog.string.padNumber(hours, count));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats Standalone weekday field according to pattern specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatStandaloneDay_ = function(
|
||||
count, date) {
|
||||
var value = date.getDay();
|
||||
switch (count) {
|
||||
case 5:
|
||||
return this.dateTimeSymbols_.STANDALONENARROWWEEKDAYS[value];
|
||||
case 4:
|
||||
return this.dateTimeSymbols_.STANDALONEWEEKDAYS[value];
|
||||
case 3:
|
||||
return this.dateTimeSymbols_.STANDALONESHORTWEEKDAYS[value];
|
||||
default:
|
||||
return this.localizeNumbers_(goog.string.padNumber(value, 1));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats Standalone Month field according to pattern specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatStandaloneMonth_ = function(
|
||||
count, date) {
|
||||
var value = date.getMonth();
|
||||
switch (count) {
|
||||
case 5:
|
||||
return this.dateTimeSymbols_.STANDALONENARROWMONTHS[value];
|
||||
case 4:
|
||||
return this.dateTimeSymbols_.STANDALONEMONTHS[value];
|
||||
case 3:
|
||||
return this.dateTimeSymbols_.STANDALONESHORTMONTHS[value];
|
||||
default:
|
||||
return this.localizeNumbers_(goog.string.padNumber(value + 1, count));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats Quarter field according to pattern specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} Formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatQuarter_ = function(count, date) {
|
||||
var value = Math.floor(date.getMonth() / 3);
|
||||
return count < 4 ? this.dateTimeSymbols_.SHORTQUARTERS[value] :
|
||||
this.dateTimeSymbols_.QUARTERS[value];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats Date field according to pattern specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} Formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatDate_ = function(count, date) {
|
||||
return this.localizeNumbers_(goog.string.padNumber(date.getDate(), count));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats Minutes field according to pattern specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} Formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatMinutes_ = function(count, date) {
|
||||
goog.i18n.DateTimeFormat.validateDateHasTime_(date);
|
||||
return this.localizeNumbers_(
|
||||
goog.string.padNumber(
|
||||
/** @type {!goog.date.DateTime} */ (date).getMinutes(), count));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats Seconds field according to pattern specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} Formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatSeconds_ = function(count, date) {
|
||||
goog.i18n.DateTimeFormat.validateDateHasTime_(date);
|
||||
return this.localizeNumbers_(
|
||||
goog.string.padNumber(
|
||||
/** @type {!goog.date.DateTime} */ (date).getSeconds(), count));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats the week of year field according to pattern specified
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @return {string} Formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatWeekOfYear_ = function(count, date) {
|
||||
|
||||
|
||||
var weekNum = goog.date.getWeekNumber(
|
||||
date.getFullYear(), date.getMonth(), date.getDate(),
|
||||
this.dateTimeSymbols_.FIRSTWEEKCUTOFFDAY,
|
||||
this.dateTimeSymbols_.FIRSTDAYOFWEEK);
|
||||
|
||||
return this.localizeNumbers_(goog.string.padNumber(weekNum, count));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats TimeZone field following RFC
|
||||
*
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date It holds the date object to be formatted.
|
||||
* @param {goog.i18n.TimeZone=} opt_timeZone This holds current time zone info.
|
||||
* @return {string} Formatted string that represent this field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatTimeZoneRFC_ = function(
|
||||
count, date, opt_timeZone) {
|
||||
opt_timeZone = opt_timeZone ||
|
||||
goog.i18n.TimeZone.createTimeZone(date.getTimezoneOffset());
|
||||
|
||||
// RFC 822 formats should be kept in ASCII, but localized GMT formats may need
|
||||
// to use native digits.
|
||||
return count < 4 ? opt_timeZone.getRFCTimeZoneString(date) :
|
||||
this.localizeNumbers_(opt_timeZone.getGMTString(date));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generate GMT timeZone string for given date
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date Whose value being evaluated.
|
||||
* @param {goog.i18n.TimeZone=} opt_timeZone This holds current time zone info.
|
||||
* @return {string} GMT timeZone string.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatTimeZone_ = function(
|
||||
count, date, opt_timeZone) {
|
||||
opt_timeZone = opt_timeZone ||
|
||||
goog.i18n.TimeZone.createTimeZone(date.getTimezoneOffset());
|
||||
return count < 4 ? opt_timeZone.getShortName(date) :
|
||||
opt_timeZone.getLongName(date);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generate GMT timeZone string for given date
|
||||
* @param {!goog.date.DateLike} date Whose value being evaluated.
|
||||
* @param {goog.i18n.TimeZone=} opt_timeZone This holds current time zone info.
|
||||
* @return {string} GMT timeZone string.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatTimeZoneId_ = function(
|
||||
date, opt_timeZone) {
|
||||
opt_timeZone = opt_timeZone ||
|
||||
goog.i18n.TimeZone.createTimeZone(date.getTimezoneOffset());
|
||||
return opt_timeZone.getTimeZoneId();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generate localized, location dependent time zone id
|
||||
* @param {number} count Number of time pattern char repeats, it controls
|
||||
* how a field should be formatted.
|
||||
* @param {!goog.date.DateLike} date Whose value being evaluated.
|
||||
* @param {goog.i18n.TimeZone=} opt_timeZone This holds current time zone info.
|
||||
* @return {string} GMT timeZone string.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatTimeZoneLocationId_ = function(
|
||||
count, date, opt_timeZone) {
|
||||
opt_timeZone = opt_timeZone ||
|
||||
goog.i18n.TimeZone.createTimeZone(date.getTimezoneOffset());
|
||||
return count <= 2 ? opt_timeZone.getTimeZoneId() :
|
||||
opt_timeZone.getGenericLocation(date);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formatting one date field.
|
||||
* @param {string} patternStr The pattern string for the field being formatted.
|
||||
* @param {!goog.date.DateLike} date represents the real date to be formatted.
|
||||
* @param {!goog.date.DateLike} dateForDate used to resolve date fields
|
||||
* for formatting.
|
||||
* @param {!goog.date.DateLike} dateForTime used to resolve time fields
|
||||
* for formatting.
|
||||
* @param {goog.i18n.TimeZone=} opt_timeZone This holds current time zone info.
|
||||
* @return {string} string representation for the given field.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.DateTimeFormat.prototype.formatField_ = function(
|
||||
patternStr, date, dateForDate, dateForTime, opt_timeZone) {
|
||||
var count = patternStr.length;
|
||||
switch (patternStr.charAt(0)) {
|
||||
case 'G':
|
||||
return this.formatEra_(count, dateForDate);
|
||||
case 'y':
|
||||
return this.formatYear_(count, dateForDate);
|
||||
case 'M':
|
||||
return this.formatMonth_(count, dateForDate);
|
||||
case 'k':
|
||||
return this.format24Hours_(count, dateForTime);
|
||||
case 'S':
|
||||
return this.formatFractionalSeconds_(count, dateForTime);
|
||||
case 'E':
|
||||
return this.formatDayOfWeek_(count, dateForDate);
|
||||
case 'a':
|
||||
return this.formatAmPm_(count, dateForTime);
|
||||
case 'h':
|
||||
return this.format1To12Hours_(count, dateForTime);
|
||||
case 'K':
|
||||
return this.format0To11Hours_(count, dateForTime);
|
||||
case 'H':
|
||||
return this.format0To23Hours_(count, dateForTime);
|
||||
case 'c':
|
||||
return this.formatStandaloneDay_(count, dateForDate);
|
||||
case 'L':
|
||||
return this.formatStandaloneMonth_(count, dateForDate);
|
||||
case 'Q':
|
||||
return this.formatQuarter_(count, dateForDate);
|
||||
case 'd':
|
||||
return this.formatDate_(count, dateForDate);
|
||||
case 'm':
|
||||
return this.formatMinutes_(count, dateForTime);
|
||||
case 's':
|
||||
return this.formatSeconds_(count, dateForTime);
|
||||
case 'v':
|
||||
return this.formatTimeZoneId_(date, opt_timeZone);
|
||||
case 'V':
|
||||
return this.formatTimeZoneLocationId_(count, date, opt_timeZone);
|
||||
case 'w':
|
||||
return this.formatWeekOfYear_(count, dateForTime);
|
||||
case 'z':
|
||||
return this.formatTimeZone_(count, date, opt_timeZone);
|
||||
case 'Z':
|
||||
return this.formatTimeZoneRFC_(count, date, opt_timeZone);
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
};
|
||||
4880
resources/public/js/compiled/out/goog/i18n/datetimesymbols.js
Normal file
4880
resources/public/js/compiled/out/goog/i18n/datetimesymbols.js
Normal file
File diff suppressed because it is too large
Load diff
780
resources/public/js/compiled/out/goog/i18n/messageformat.js
Normal file
780
resources/public/js/compiled/out/goog/i18n/messageformat.js
Normal file
|
|
@ -0,0 +1,780 @@
|
|||
// Copyright 2010 The Closure Library Authors. All Rights Reserved
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Message/plural format library with locale support.
|
||||
*
|
||||
* Message format grammar:
|
||||
*
|
||||
* messageFormatPattern := string ( "{" messageFormatElement "}" string )*
|
||||
* messageFormatElement := argumentIndex [ "," elementFormat ]
|
||||
* elementFormat := "plural" "," pluralStyle
|
||||
* | "selectordinal" "," ordinalStyle
|
||||
* | "select" "," selectStyle
|
||||
* pluralStyle := pluralFormatPattern
|
||||
* ordinalStyle := selectFormatPattern
|
||||
* selectStyle := selectFormatPattern
|
||||
* pluralFormatPattern := [ "offset" ":" offsetIndex ] pluralForms*
|
||||
* selectFormatPattern := pluralForms*
|
||||
* pluralForms := stringKey "{" ( "{" messageFormatElement "}"|string )* "}"
|
||||
*
|
||||
* This is a subset of the ICU MessageFormatSyntax:
|
||||
* http://userguide.icu-project.org/formatparse/messages
|
||||
* See also http://go/plurals and http://go/ordinals for internal details.
|
||||
*
|
||||
*
|
||||
* Message example:
|
||||
*
|
||||
* I see {NUM_PEOPLE, plural, offset:1
|
||||
* =0 {no one at all}
|
||||
* =1 {{WHO}}
|
||||
* one {{WHO} and one other person}
|
||||
* other {{WHO} and # other people}}
|
||||
* in {PLACE}.
|
||||
*
|
||||
* Calling format({'NUM_PEOPLE': 2, 'WHO': 'Mark', 'PLACE': 'Athens'}) would
|
||||
* produce "I see Mark and one other person in Athens." as output.
|
||||
*
|
||||
* OR:
|
||||
*
|
||||
* {NUM_FLOOR, selectordinal,
|
||||
* one {Take the elevator to the #st floor.}
|
||||
* two {Take the elevator to the #nd floor.}
|
||||
* few {Take the elevator to the #rd floor.}
|
||||
* other {Take the elevator to the #th floor.}}
|
||||
*
|
||||
* Calling format({'NUM_FLOOR': 22}) would produce
|
||||
* "Take the elevator to the 22nd floor".
|
||||
*
|
||||
* See messageformat_test.html for more examples.
|
||||
*/
|
||||
|
||||
goog.provide('goog.i18n.MessageFormat');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.i18n.NumberFormat');
|
||||
goog.require('goog.i18n.ordinalRules');
|
||||
goog.require('goog.i18n.pluralRules');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor of MessageFormat.
|
||||
* @param {string} pattern The pattern we parse and apply positional parameters
|
||||
* to.
|
||||
* @constructor
|
||||
* @final
|
||||
*/
|
||||
goog.i18n.MessageFormat = function(pattern) {
|
||||
/**
|
||||
* All encountered literals during parse stage. Indices tell us the order of
|
||||
* replacement.
|
||||
* @type {!Array<string>}
|
||||
* @private
|
||||
*/
|
||||
this.literals_ = [];
|
||||
|
||||
/**
|
||||
* Input pattern gets parsed into objects for faster formatting.
|
||||
* @type {!Array<!Object>}
|
||||
* @private
|
||||
*/
|
||||
this.parsedPattern_ = [];
|
||||
|
||||
/**
|
||||
* Locale aware number formatter.
|
||||
* @type {goog.i18n.NumberFormat}
|
||||
* @private
|
||||
*/
|
||||
this.numberFormatter_ =
|
||||
new goog.i18n.NumberFormat(goog.i18n.NumberFormat.Format.DECIMAL);
|
||||
|
||||
this.parsePattern_(pattern);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Literal strings, including '', are replaced with \uFDDF_x_ for
|
||||
* parsing purposes, and recovered during format phase.
|
||||
* \uFDDF is a Unicode nonprinting character, not expected to be found in the
|
||||
* typical message.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.LITERAL_PLACEHOLDER_ = '\uFDDF_';
|
||||
|
||||
|
||||
/**
|
||||
* Marks a string and block during parsing.
|
||||
* @enum {number}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.Element_ = {
|
||||
STRING: 0,
|
||||
BLOCK: 1
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Block type.
|
||||
* @enum {number}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.BlockType_ = {
|
||||
PLURAL: 0,
|
||||
ORDINAL: 1,
|
||||
SELECT: 2,
|
||||
SIMPLE: 3,
|
||||
STRING: 4,
|
||||
UNKNOWN: 5
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Mandatory option in both select and plural form.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.OTHER_ = 'other';
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for looking for string literals.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.REGEX_LITERAL_ = new RegExp("'([{}#].*?)'", 'g');
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for looking for '' in the message.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.REGEX_DOUBLE_APOSTROPHE_ = new RegExp("''", 'g');
|
||||
|
||||
/** @typedef {{ type: goog.i18n.MessageFormat.Element_, value: ? }} */
|
||||
goog.i18n.MessageFormat.TypeVal_;
|
||||
|
||||
/**
|
||||
* Formats a message, treating '#' with special meaning representing
|
||||
* the number (plural_variable - offset).
|
||||
* @param {!Object} namedParameters Parameters that either
|
||||
* influence the formatting or are used as actual data.
|
||||
* I.e. in call to fmt.format({'NUM_PEOPLE': 5, 'NAME': 'Angela'}),
|
||||
* object {'NUM_PEOPLE': 5, 'NAME': 'Angela'} holds positional parameters.
|
||||
* 1st parameter could mean 5 people, which could influence plural format,
|
||||
* and 2nd parameter is just a data to be printed out in proper position.
|
||||
* @return {string} Formatted message.
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.format = function(namedParameters) {
|
||||
return this.format_(namedParameters, false);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats a message, treating '#' as literary character.
|
||||
* @param {!Object} namedParameters Parameters that either
|
||||
* influence the formatting or are used as actual data.
|
||||
* I.e. in call to fmt.format({'NUM_PEOPLE': 5, 'NAME': 'Angela'}),
|
||||
* object {'NUM_PEOPLE': 5, 'NAME': 'Angela'} holds positional parameters.
|
||||
* 1st parameter could mean 5 people, which could influence plural format,
|
||||
* and 2nd parameter is just a data to be printed out in proper position.
|
||||
* @return {string} Formatted message.
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.formatIgnoringPound = function(
|
||||
namedParameters) {
|
||||
return this.format_(namedParameters, true);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats a message.
|
||||
* @param {!Object} namedParameters Parameters that either
|
||||
* influence the formatting or are used as actual data.
|
||||
* I.e. in call to fmt.format({'NUM_PEOPLE': 5, 'NAME': 'Angela'}),
|
||||
* object {'NUM_PEOPLE': 5, 'NAME': 'Angela'} holds positional parameters.
|
||||
* 1st parameter could mean 5 people, which could influence plural format,
|
||||
* and 2nd parameter is just a data to be printed out in proper position.
|
||||
* @param {boolean} ignorePound If true, treat '#' in plural messages as a
|
||||
* literary character, else treat it as an ICU syntax character, resolving
|
||||
* to the number (plural_variable - offset).
|
||||
* @return {string} Formatted message.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.format_ = function(
|
||||
namedParameters, ignorePound) {
|
||||
if (this.parsedPattern_.length == 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var result = [];
|
||||
this.formatBlock_(this.parsedPattern_, namedParameters, ignorePound, result);
|
||||
var message = result.join('');
|
||||
|
||||
if (!ignorePound) {
|
||||
goog.asserts.assert(message.search('#') == -1, 'Not all # were replaced.');
|
||||
}
|
||||
|
||||
while (this.literals_.length > 0) {
|
||||
message = message.replace(
|
||||
this.buildPlaceholder_(this.literals_), this.literals_.pop());
|
||||
}
|
||||
|
||||
return message;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parses generic block and returns a formatted string.
|
||||
* @param {!Array<!goog.i18n.MessageFormat.TypeVal_>} parsedPattern
|
||||
* Holds parsed tree.
|
||||
* @param {!Object} namedParameters Parameters that either influence
|
||||
* the formatting or are used as actual data.
|
||||
* @param {boolean} ignorePound If true, treat '#' in plural messages as a
|
||||
* literary character, else treat it as an ICU syntax character, resolving
|
||||
* to the number (plural_variable - offset).
|
||||
* @param {!Array<!string>} result Each formatting stage appends its product
|
||||
* to the result.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.formatBlock_ = function(
|
||||
parsedPattern, namedParameters, ignorePound, result) {
|
||||
for (var i = 0; i < parsedPattern.length; i++) {
|
||||
switch (parsedPattern[i].type) {
|
||||
case goog.i18n.MessageFormat.BlockType_.STRING:
|
||||
result.push(parsedPattern[i].value);
|
||||
break;
|
||||
case goog.i18n.MessageFormat.BlockType_.SIMPLE:
|
||||
var pattern = parsedPattern[i].value;
|
||||
this.formatSimplePlaceholder_(pattern, namedParameters, result);
|
||||
break;
|
||||
case goog.i18n.MessageFormat.BlockType_.SELECT:
|
||||
var pattern = parsedPattern[i].value;
|
||||
this.formatSelectBlock_(pattern, namedParameters, ignorePound, result);
|
||||
break;
|
||||
case goog.i18n.MessageFormat.BlockType_.PLURAL:
|
||||
var pattern = parsedPattern[i].value;
|
||||
this.formatPluralOrdinalBlock_(
|
||||
pattern, namedParameters, goog.i18n.pluralRules.select, ignorePound,
|
||||
result);
|
||||
break;
|
||||
case goog.i18n.MessageFormat.BlockType_.ORDINAL:
|
||||
var pattern = parsedPattern[i].value;
|
||||
this.formatPluralOrdinalBlock_(
|
||||
pattern, namedParameters, goog.i18n.ordinalRules.select,
|
||||
ignorePound, result);
|
||||
break;
|
||||
default:
|
||||
goog.asserts.fail('Unrecognized block type: ' + parsedPattern[i].type);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats simple placeholder.
|
||||
* @param {!Object} parsedPattern JSON object containing placeholder info.
|
||||
* @param {!Object} namedParameters Parameters that are used as actual data.
|
||||
* @param {!Array<!string>} result Each formatting stage appends its product
|
||||
* to the result.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.formatSimplePlaceholder_ = function(
|
||||
parsedPattern, namedParameters, result) {
|
||||
var value = namedParameters[parsedPattern];
|
||||
if (!goog.isDef(value)) {
|
||||
result.push('Undefined parameter - ' + parsedPattern);
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't push the value yet, it may contain any of # { } in it which
|
||||
// will break formatter. Insert a placeholder and replace at the end.
|
||||
this.literals_.push(value);
|
||||
result.push(this.buildPlaceholder_(this.literals_));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats select block. Only one option is selected.
|
||||
* @param {!{argumentIndex:?}} parsedPattern JSON object containing select
|
||||
* block info.
|
||||
* @param {!Object} namedParameters Parameters that either influence
|
||||
* the formatting or are used as actual data.
|
||||
* @param {boolean} ignorePound If true, treat '#' in plural messages as a
|
||||
* literary character, else treat it as an ICU syntax character, resolving
|
||||
* to the number (plural_variable - offset).
|
||||
* @param {!Array<!string>} result Each formatting stage appends its product
|
||||
* to the result.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.formatSelectBlock_ = function(
|
||||
parsedPattern, namedParameters, ignorePound, result) {
|
||||
var argumentIndex = parsedPattern.argumentIndex;
|
||||
if (!goog.isDef(namedParameters[argumentIndex])) {
|
||||
result.push('Undefined parameter - ' + argumentIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
var option = parsedPattern[namedParameters[argumentIndex]];
|
||||
if (!goog.isDef(option)) {
|
||||
option = parsedPattern[goog.i18n.MessageFormat.OTHER_];
|
||||
goog.asserts.assertArray(
|
||||
option, 'Invalid option or missing other option for select block.');
|
||||
}
|
||||
|
||||
this.formatBlock_(option, namedParameters, ignorePound, result);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Formats plural or selectordinal block. Only one option is selected and all #
|
||||
* are replaced.
|
||||
* @param {!{argumentIndex, argumentOffset}} parsedPattern JSON object
|
||||
* containing plural block info.
|
||||
* @param {!Object} namedParameters Parameters that either influence
|
||||
* the formatting or are used as actual data.
|
||||
* @param {!function(number, number=):string} pluralSelector A select function
|
||||
* from goog.i18n.pluralRules or goog.i18n.ordinalRules which determines
|
||||
* which plural/ordinal form to use based on the input number's cardinality.
|
||||
* @param {boolean} ignorePound If true, treat '#' in plural messages as a
|
||||
* literary character, else treat it as an ICU syntax character, resolving
|
||||
* to the number (plural_variable - offset).
|
||||
* @param {!Array<!string>} result Each formatting stage appends its product
|
||||
* to the result.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.formatPluralOrdinalBlock_ = function(
|
||||
parsedPattern, namedParameters, pluralSelector, ignorePound, result) {
|
||||
var argumentIndex = parsedPattern.argumentIndex;
|
||||
var argumentOffset = parsedPattern.argumentOffset;
|
||||
var pluralValue = +namedParameters[argumentIndex];
|
||||
if (isNaN(pluralValue)) {
|
||||
// TODO(user): Distinguish between undefined and invalid parameters.
|
||||
result.push('Undefined or invalid parameter - ' + argumentIndex);
|
||||
return;
|
||||
}
|
||||
var diff = pluralValue - argumentOffset;
|
||||
|
||||
// Check if there is an exact match.
|
||||
var option = parsedPattern[namedParameters[argumentIndex]];
|
||||
if (!goog.isDef(option)) {
|
||||
goog.asserts.assert(diff >= 0, 'Argument index smaller than offset.');
|
||||
var item;
|
||||
if (this.numberFormatter_.getMinimumFractionDigits) { // number formatter?
|
||||
// If we know the number of fractional digits we can make better decisions
|
||||
// We can decide (for instance) between "1 dollar" and "1.00 dollars".
|
||||
item = pluralSelector(
|
||||
diff, this.numberFormatter_.getMinimumFractionDigits());
|
||||
} else {
|
||||
item = pluralSelector(diff);
|
||||
}
|
||||
goog.asserts.assertString(item, 'Invalid plural key.');
|
||||
|
||||
option = parsedPattern[item];
|
||||
|
||||
// If option is not provided fall back to "other".
|
||||
if (!goog.isDef(option)) {
|
||||
option = parsedPattern[goog.i18n.MessageFormat.OTHER_];
|
||||
}
|
||||
|
||||
goog.asserts.assertArray(
|
||||
option, 'Invalid option or missing other option for plural block.');
|
||||
}
|
||||
|
||||
var pluralResult = [];
|
||||
this.formatBlock_(option, namedParameters, ignorePound, pluralResult);
|
||||
var plural = pluralResult.join('');
|
||||
goog.asserts.assertString(plural, 'Empty block in plural.');
|
||||
if (ignorePound) {
|
||||
result.push(plural);
|
||||
} else {
|
||||
var localeAwareDiff = this.numberFormatter_.format(diff);
|
||||
result.push(plural.replace(/#/g, localeAwareDiff));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parses input pattern into an array, for faster reformatting with
|
||||
* different input parameters.
|
||||
* Parsing is locale independent.
|
||||
* @param {string} pattern MessageFormat pattern to parse.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.parsePattern_ = function(pattern) {
|
||||
if (pattern) {
|
||||
pattern = this.insertPlaceholders_(pattern);
|
||||
|
||||
this.parsedPattern_ = this.parseBlock_(pattern);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Replaces string literals with literal placeholders.
|
||||
* Literals are string of the form '}...', '{...' and '#...' where ... is
|
||||
* set of characters not containing '
|
||||
* Builds a dictionary so we can recover literals during format phase.
|
||||
* @param {string} pattern Pattern to clean up.
|
||||
* @return {string} Pattern with literals replaced with placeholders.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.insertPlaceholders_ = function(pattern) {
|
||||
var literals = this.literals_;
|
||||
var buildPlaceholder = goog.bind(this.buildPlaceholder_, this);
|
||||
|
||||
// First replace '' with single quote placeholder since they can be found
|
||||
// inside other literals.
|
||||
pattern = pattern.replace(
|
||||
goog.i18n.MessageFormat.REGEX_DOUBLE_APOSTROPHE_, function() {
|
||||
literals.push("'");
|
||||
return buildPlaceholder(literals);
|
||||
});
|
||||
|
||||
pattern = pattern.replace(
|
||||
goog.i18n.MessageFormat.REGEX_LITERAL_, function(match, text) {
|
||||
literals.push(text);
|
||||
return buildPlaceholder(literals);
|
||||
});
|
||||
|
||||
return pattern;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Breaks pattern into strings and top level {...} blocks.
|
||||
* @param {string} pattern (sub)Pattern to be broken.
|
||||
* @return {!Array<goog.i18n.MessageFormat.TypeVal_>}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.extractParts_ = function(pattern) {
|
||||
var prevPos = 0;
|
||||
var inBlock = false;
|
||||
var braceStack = [];
|
||||
var results = [];
|
||||
|
||||
var braces = /[{}]/g;
|
||||
braces.lastIndex = 0; // lastIndex doesn't get set to 0 so we have to.
|
||||
var match;
|
||||
|
||||
while (match = braces.exec(pattern)) {
|
||||
var pos = match.index;
|
||||
if (match[0] == '}') {
|
||||
var brace = braceStack.pop();
|
||||
goog.asserts.assert(
|
||||
goog.isDef(brace) && brace == '{', 'No matching { for }.');
|
||||
|
||||
if (braceStack.length == 0) {
|
||||
// End of the block.
|
||||
var part = {};
|
||||
part.type = goog.i18n.MessageFormat.Element_.BLOCK;
|
||||
part.value = pattern.substring(prevPos, pos);
|
||||
results.push(part);
|
||||
prevPos = pos + 1;
|
||||
inBlock = false;
|
||||
}
|
||||
} else {
|
||||
if (braceStack.length == 0) {
|
||||
inBlock = true;
|
||||
var substring = pattern.substring(prevPos, pos);
|
||||
if (substring != '') {
|
||||
results.push({
|
||||
type: goog.i18n.MessageFormat.Element_.STRING,
|
||||
value: substring
|
||||
});
|
||||
}
|
||||
prevPos = pos + 1;
|
||||
}
|
||||
braceStack.push('{');
|
||||
}
|
||||
}
|
||||
|
||||
// Take care of the final string, and check if the braceStack is empty.
|
||||
goog.asserts.assert(
|
||||
braceStack.length == 0, 'There are mismatched { or } in the pattern.');
|
||||
|
||||
var substring = pattern.substring(prevPos);
|
||||
if (substring != '') {
|
||||
results.push(
|
||||
{type: goog.i18n.MessageFormat.Element_.STRING, value: substring});
|
||||
}
|
||||
|
||||
return results;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A regular expression to parse the plural block, extracting the argument
|
||||
* index and offset (if any).
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.PLURAL_BLOCK_RE_ =
|
||||
/^\s*(\w+)\s*,\s*plural\s*,(?:\s*offset:(\d+))?/;
|
||||
|
||||
|
||||
/**
|
||||
* A regular expression to parse the ordinal block, extracting the argument
|
||||
* index.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.ORDINAL_BLOCK_RE_ = /^\s*(\w+)\s*,\s*selectordinal\s*,/;
|
||||
|
||||
|
||||
/**
|
||||
* A regular expression to parse the select block, extracting the argument
|
||||
* index.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.SELECT_BLOCK_RE_ = /^\s*(\w+)\s*,\s*select\s*,/;
|
||||
|
||||
|
||||
/**
|
||||
* Detects which type of a block is the pattern.
|
||||
* @param {string} pattern Content of the block.
|
||||
* @return {goog.i18n.MessageFormat.BlockType_} One of the block types.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.parseBlockType_ = function(pattern) {
|
||||
if (goog.i18n.MessageFormat.PLURAL_BLOCK_RE_.test(pattern)) {
|
||||
return goog.i18n.MessageFormat.BlockType_.PLURAL;
|
||||
}
|
||||
|
||||
if (goog.i18n.MessageFormat.ORDINAL_BLOCK_RE_.test(pattern)) {
|
||||
return goog.i18n.MessageFormat.BlockType_.ORDINAL;
|
||||
}
|
||||
|
||||
if (goog.i18n.MessageFormat.SELECT_BLOCK_RE_.test(pattern)) {
|
||||
return goog.i18n.MessageFormat.BlockType_.SELECT;
|
||||
}
|
||||
|
||||
if (/^\s*\w+\s*/.test(pattern)) {
|
||||
return goog.i18n.MessageFormat.BlockType_.SIMPLE;
|
||||
}
|
||||
|
||||
return goog.i18n.MessageFormat.BlockType_.UNKNOWN;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parses generic block.
|
||||
* @param {string} pattern Content of the block to parse.
|
||||
* @return {!Array<!Object>} Subblocks marked as strings, select...
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.parseBlock_ = function(pattern) {
|
||||
var result = [];
|
||||
var parts = this.extractParts_(pattern);
|
||||
for (var i = 0; i < parts.length; i++) {
|
||||
var block = {};
|
||||
if (goog.i18n.MessageFormat.Element_.STRING == parts[i].type) {
|
||||
block.type = goog.i18n.MessageFormat.BlockType_.STRING;
|
||||
block.value = parts[i].value;
|
||||
} else if (goog.i18n.MessageFormat.Element_.BLOCK == parts[i].type) {
|
||||
var blockType = this.parseBlockType_(parts[i].value);
|
||||
|
||||
switch (blockType) {
|
||||
case goog.i18n.MessageFormat.BlockType_.SELECT:
|
||||
block.type = goog.i18n.MessageFormat.BlockType_.SELECT;
|
||||
block.value = this.parseSelectBlock_(parts[i].value);
|
||||
break;
|
||||
case goog.i18n.MessageFormat.BlockType_.PLURAL:
|
||||
block.type = goog.i18n.MessageFormat.BlockType_.PLURAL;
|
||||
block.value = this.parsePluralBlock_(parts[i].value);
|
||||
break;
|
||||
case goog.i18n.MessageFormat.BlockType_.ORDINAL:
|
||||
block.type = goog.i18n.MessageFormat.BlockType_.ORDINAL;
|
||||
block.value = this.parseOrdinalBlock_(parts[i].value);
|
||||
break;
|
||||
case goog.i18n.MessageFormat.BlockType_.SIMPLE:
|
||||
block.type = goog.i18n.MessageFormat.BlockType_.SIMPLE;
|
||||
block.value = parts[i].value;
|
||||
break;
|
||||
default:
|
||||
goog.asserts.fail(
|
||||
'Unknown block type for pattern: ' + parts[i].value);
|
||||
}
|
||||
} else {
|
||||
goog.asserts.fail('Unknown part of the pattern.');
|
||||
}
|
||||
result.push(block);
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parses a select type of a block and produces JSON object for it.
|
||||
* @param {string} pattern Subpattern that needs to be parsed as select pattern.
|
||||
* @return {!Object} Object with select block info.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.parseSelectBlock_ = function(pattern) {
|
||||
var argumentIndex = '';
|
||||
var replaceRegex = goog.i18n.MessageFormat.SELECT_BLOCK_RE_;
|
||||
pattern = pattern.replace(replaceRegex, function(string, name) {
|
||||
argumentIndex = name;
|
||||
return '';
|
||||
});
|
||||
var result = {};
|
||||
result.argumentIndex = argumentIndex;
|
||||
|
||||
var parts = this.extractParts_(pattern);
|
||||
// Looking for (key block)+ sequence. One of the keys has to be "other".
|
||||
var pos = 0;
|
||||
while (pos < parts.length) {
|
||||
var key = parts[pos].value;
|
||||
goog.asserts.assertString(key, 'Missing select key element.');
|
||||
|
||||
pos++;
|
||||
goog.asserts.assert(
|
||||
pos < parts.length, 'Missing or invalid select value element.');
|
||||
|
||||
if (goog.i18n.MessageFormat.Element_.BLOCK == parts[pos].type) {
|
||||
var value = this.parseBlock_(parts[pos].value);
|
||||
} else {
|
||||
goog.asserts.fail('Expected block type.');
|
||||
}
|
||||
result[key.replace(/\s/g, '')] = value;
|
||||
pos++;
|
||||
}
|
||||
|
||||
goog.asserts.assertArray(
|
||||
result[goog.i18n.MessageFormat.OTHER_],
|
||||
'Missing other key in select statement.');
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parses a plural type of a block and produces JSON object for it.
|
||||
* @param {string} pattern Subpattern that needs to be parsed as plural pattern.
|
||||
* @return {!Object} Object with select block info.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.parsePluralBlock_ = function(pattern) {
|
||||
var argumentIndex = '';
|
||||
var argumentOffset = 0;
|
||||
var replaceRegex = goog.i18n.MessageFormat.PLURAL_BLOCK_RE_;
|
||||
pattern = pattern.replace(replaceRegex, function(string, name, offset) {
|
||||
argumentIndex = name;
|
||||
if (offset) {
|
||||
argumentOffset = parseInt(offset, 10);
|
||||
}
|
||||
return '';
|
||||
});
|
||||
|
||||
var result = {};
|
||||
result.argumentIndex = argumentIndex;
|
||||
result.argumentOffset = argumentOffset;
|
||||
|
||||
var parts = this.extractParts_(pattern);
|
||||
// Looking for (key block)+ sequence.
|
||||
var pos = 0;
|
||||
while (pos < parts.length) {
|
||||
var key = parts[pos].value;
|
||||
goog.asserts.assertString(key, 'Missing plural key element.');
|
||||
|
||||
pos++;
|
||||
goog.asserts.assert(
|
||||
pos < parts.length, 'Missing or invalid plural value element.');
|
||||
|
||||
if (goog.i18n.MessageFormat.Element_.BLOCK == parts[pos].type) {
|
||||
var value = this.parseBlock_(parts[pos].value);
|
||||
} else {
|
||||
goog.asserts.fail('Expected block type.');
|
||||
}
|
||||
result[key.replace(/\s*(?:=)?(\w+)\s*/, '$1')] = value;
|
||||
pos++;
|
||||
}
|
||||
|
||||
goog.asserts.assertArray(
|
||||
result[goog.i18n.MessageFormat.OTHER_],
|
||||
'Missing other key in plural statement.');
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parses an ordinal type of a block and produces JSON object for it.
|
||||
* For example the input string:
|
||||
* '{FOO, selectordinal, one {Message A}other {Message B}}'
|
||||
* Should result in the output object:
|
||||
* {
|
||||
* argumentIndex: 'FOO',
|
||||
* argumentOffest: 0,
|
||||
* one: [ { type: 4, value: 'Message A' } ],
|
||||
* other: [ { type: 4, value: 'Message B' } ]
|
||||
* }
|
||||
* @param {string} pattern Subpattern that needs to be parsed as plural pattern.
|
||||
* @return {!Object} Object with select block info.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.parseOrdinalBlock_ = function(pattern) {
|
||||
var argumentIndex = '';
|
||||
var replaceRegex = goog.i18n.MessageFormat.ORDINAL_BLOCK_RE_;
|
||||
pattern = pattern.replace(replaceRegex, function(string, name) {
|
||||
argumentIndex = name;
|
||||
return '';
|
||||
});
|
||||
|
||||
var result = {};
|
||||
result.argumentIndex = argumentIndex;
|
||||
result.argumentOffset = 0;
|
||||
|
||||
var parts = this.extractParts_(pattern);
|
||||
// Looking for (key block)+ sequence.
|
||||
var pos = 0;
|
||||
while (pos < parts.length) {
|
||||
var key = parts[pos].value;
|
||||
goog.asserts.assertString(key, 'Missing ordinal key element.');
|
||||
|
||||
pos++;
|
||||
goog.asserts.assert(
|
||||
pos < parts.length, 'Missing or invalid ordinal value element.');
|
||||
|
||||
if (goog.i18n.MessageFormat.Element_.BLOCK == parts[pos].type) {
|
||||
var value = this.parseBlock_(parts[pos].value);
|
||||
} else {
|
||||
goog.asserts.fail('Expected block type.');
|
||||
}
|
||||
result[key.replace(/\s*(?:=)?(\w+)\s*/, '$1')] = value;
|
||||
pos++;
|
||||
}
|
||||
|
||||
goog.asserts.assertArray(
|
||||
result[goog.i18n.MessageFormat.OTHER_],
|
||||
'Missing other key in selectordinal statement.');
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Builds a placeholder from the last index of the array.
|
||||
* @param {!Array<string>} literals All literals encountered during parse.
|
||||
* @return {string} \uFDDF_ + last index + _.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.MessageFormat.prototype.buildPlaceholder_ = function(literals) {
|
||||
goog.asserts.assert(literals.length > 0, 'Literal array is empty.');
|
||||
|
||||
var index = (literals.length - 1).toString(10);
|
||||
return goog.i18n.MessageFormat.LITERAL_PLACEHOLDER_ + index + '_';
|
||||
};
|
||||
1483
resources/public/js/compiled/out/goog/i18n/numberformat.js
Normal file
1483
resources/public/js/compiled/out/goog/i18n/numberformat.js
Normal file
File diff suppressed because it is too large
Load diff
4465
resources/public/js/compiled/out/goog/i18n/numberformatsymbols.js
Normal file
4465
resources/public/js/compiled/out/goog/i18n/numberformatsymbols.js
Normal file
File diff suppressed because it is too large
Load diff
783
resources/public/js/compiled/out/goog/i18n/ordinalrules.js
Normal file
783
resources/public/js/compiled/out/goog/i18n/ordinalrules.js
Normal file
|
|
@ -0,0 +1,783 @@
|
|||
// Copyright 2012 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Ordinal rules.
|
||||
*
|
||||
* This file is autogenerated by script:
|
||||
* http://go/generate_pluralrules.py
|
||||
* File generated from CLDR ver. 29
|
||||
*
|
||||
* Before check in, this file could have been manually edited. This is to
|
||||
* incorporate changes before we could fix CLDR. All manual modification must be
|
||||
* documented in this section, and should be removed after those changes land to
|
||||
* CLDR.
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
|
||||
goog.provide('goog.i18n.ordinalRules');
|
||||
/**
|
||||
* Ordinal pattern keyword
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.i18n.ordinalRules.Keyword = {
|
||||
ZERO: 'zero',
|
||||
ONE: 'one',
|
||||
TWO: 'two',
|
||||
FEW: 'few',
|
||||
MANY: 'many',
|
||||
OTHER: 'other'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Default Ordinal select rule.
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision optional, precision.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Default value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.defaultSelect_ = function(n, opt_precision) {
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the fractional part of a number (3.1416 => 1416)
|
||||
* @param {number} n The count of items.
|
||||
* @return {number} The fractional part.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.decimals_ = function(n) {
|
||||
var str = n + '';
|
||||
var result = str.indexOf('.');
|
||||
return (result == -1) ? 0 : str.length - result - 1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates v and f as per CLDR plural rules.
|
||||
* The short names for parameters / return match the CLDR syntax and UTS #35
|
||||
* (http://unicode.org/reports/tr35/tr35-numbers.html#Plural_rules_syntax)
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision optional, precision.
|
||||
* @return {!{v:number, f:number}} The v and f.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.get_vf_ = function(n, opt_precision) {
|
||||
var DEFAULT_DIGITS = 3;
|
||||
|
||||
if (undefined === opt_precision) {
|
||||
var v = Math.min(goog.i18n.ordinalRules.decimals_(n), DEFAULT_DIGITS);
|
||||
} else {
|
||||
var v = opt_precision;
|
||||
}
|
||||
|
||||
var base = Math.pow(10, v);
|
||||
var f = ((n * base) | 0) % base;
|
||||
|
||||
return {v: v, f: f};
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates w and t as per CLDR plural rules.
|
||||
* The short names for parameters / return match the CLDR syntax and UTS #35
|
||||
* (http://unicode.org/reports/tr35/tr35-numbers.html#Plural_rules_syntax)
|
||||
* @param {number} v Calculated previously.
|
||||
* @param {number} f Calculated previously.
|
||||
* @return {!{w:number, t:number}} The w and t.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.get_wt_ = function(v, f) {
|
||||
if (f === 0) {
|
||||
return {w: 0, t: 0};
|
||||
}
|
||||
|
||||
while ((f % 10) === 0) {
|
||||
f /= 10;
|
||||
v--;
|
||||
}
|
||||
|
||||
return {w: v, t: f};
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for cy locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.cySelect_ = function(n, opt_precision) {
|
||||
if (n == 0 || n == 7 || n == 8 || n == 9) {
|
||||
return goog.i18n.ordinalRules.Keyword.ZERO;
|
||||
}
|
||||
if (n == 1) {
|
||||
return goog.i18n.ordinalRules.Keyword.ONE;
|
||||
}
|
||||
if (n == 2) {
|
||||
return goog.i18n.ordinalRules.Keyword.TWO;
|
||||
}
|
||||
if (n == 3 || n == 4) {
|
||||
return goog.i18n.ordinalRules.Keyword.FEW;
|
||||
}
|
||||
if (n == 5 || n == 6) {
|
||||
return goog.i18n.ordinalRules.Keyword.MANY;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for en locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.enSelect_ = function(n, opt_precision) {
|
||||
if (n % 10 == 1 && n % 100 != 11) {
|
||||
return goog.i18n.ordinalRules.Keyword.ONE;
|
||||
}
|
||||
if (n % 10 == 2 && n % 100 != 12) {
|
||||
return goog.i18n.ordinalRules.Keyword.TWO;
|
||||
}
|
||||
if (n % 10 == 3 && n % 100 != 13) {
|
||||
return goog.i18n.ordinalRules.Keyword.FEW;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for uk locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.ukSelect_ = function(n, opt_precision) {
|
||||
if (n % 10 == 3 && n % 100 != 13) {
|
||||
return goog.i18n.ordinalRules.Keyword.FEW;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for it locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.itSelect_ = function(n, opt_precision) {
|
||||
if (n == 11 || n == 8 || n == 80 || n == 800) {
|
||||
return goog.i18n.ordinalRules.Keyword.MANY;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for ne locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.neSelect_ = function(n, opt_precision) {
|
||||
if (n >= 1 && n <= 4) {
|
||||
return goog.i18n.ordinalRules.Keyword.ONE;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for be locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.beSelect_ = function(n, opt_precision) {
|
||||
if ((n % 10 == 2 || n % 10 == 3) && n % 100 != 12 && n % 100 != 13) {
|
||||
return goog.i18n.ordinalRules.Keyword.FEW;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for az locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.azSelect_ = function(n, opt_precision) {
|
||||
var i = n | 0;
|
||||
if ((i % 10 == 1 || i % 10 == 2 || i % 10 == 5 || i % 10 == 7 || i % 10 == 8) || (i % 100 == 20 || i % 100 == 50 || i % 100 == 70 || i % 100 == 80)) {
|
||||
return goog.i18n.ordinalRules.Keyword.ONE;
|
||||
}
|
||||
if ((i % 10 == 3 || i % 10 == 4) || (i % 1000 == 100 || i % 1000 == 200 || i % 1000 == 300 || i % 1000 == 400 || i % 1000 == 500 || i % 1000 == 600 || i % 1000 == 700 || i % 1000 == 800 || i % 1000 == 900)) {
|
||||
return goog.i18n.ordinalRules.Keyword.FEW;
|
||||
}
|
||||
if (i == 0 || i % 10 == 6 || (i % 100 == 40 || i % 100 == 60 || i % 100 == 90)) {
|
||||
return goog.i18n.ordinalRules.Keyword.MANY;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for ka locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.kaSelect_ = function(n, opt_precision) {
|
||||
var i = n | 0;
|
||||
if (i == 1) {
|
||||
return goog.i18n.ordinalRules.Keyword.ONE;
|
||||
}
|
||||
if (i == 0 || (i % 100 >= 2 && i % 100 <= 20 || i % 100 == 40 || i % 100 == 60 || i % 100 == 80)) {
|
||||
return goog.i18n.ordinalRules.Keyword.MANY;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for mr locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.mrSelect_ = function(n, opt_precision) {
|
||||
if (n == 1) {
|
||||
return goog.i18n.ordinalRules.Keyword.ONE;
|
||||
}
|
||||
if (n == 2 || n == 3) {
|
||||
return goog.i18n.ordinalRules.Keyword.TWO;
|
||||
}
|
||||
if (n == 4) {
|
||||
return goog.i18n.ordinalRules.Keyword.FEW;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for sv locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.svSelect_ = function(n, opt_precision) {
|
||||
if ((n % 10 == 1 || n % 10 == 2) && n % 100 != 11 && n % 100 != 12) {
|
||||
return goog.i18n.ordinalRules.Keyword.ONE;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for kk locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.kkSelect_ = function(n, opt_precision) {
|
||||
if (n % 10 == 6 || n % 10 == 9 || n % 10 == 0 && n != 0) {
|
||||
return goog.i18n.ordinalRules.Keyword.MANY;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for mk locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.mkSelect_ = function(n, opt_precision) {
|
||||
var i = n | 0;
|
||||
if (i % 10 == 1 && i % 100 != 11) {
|
||||
return goog.i18n.ordinalRules.Keyword.ONE;
|
||||
}
|
||||
if (i % 10 == 2 && i % 100 != 12) {
|
||||
return goog.i18n.ordinalRules.Keyword.TWO;
|
||||
}
|
||||
if ((i % 10 == 7 || i % 10 == 8) && i % 100 != 17 && i % 100 != 18) {
|
||||
return goog.i18n.ordinalRules.Keyword.MANY;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for hu locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.huSelect_ = function(n, opt_precision) {
|
||||
if (n == 1 || n == 5) {
|
||||
return goog.i18n.ordinalRules.Keyword.ONE;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for fr locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.frSelect_ = function(n, opt_precision) {
|
||||
if (n == 1) {
|
||||
return goog.i18n.ordinalRules.Keyword.ONE;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for sq locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.sqSelect_ = function(n, opt_precision) {
|
||||
if (n == 1) {
|
||||
return goog.i18n.ordinalRules.Keyword.ONE;
|
||||
}
|
||||
if (n % 10 == 4 && n % 100 != 14) {
|
||||
return goog.i18n.ordinalRules.Keyword.MANY;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for ca locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.caSelect_ = function(n, opt_precision) {
|
||||
if (n == 1 || n == 3) {
|
||||
return goog.i18n.ordinalRules.Keyword.ONE;
|
||||
}
|
||||
if (n == 2) {
|
||||
return goog.i18n.ordinalRules.Keyword.TWO;
|
||||
}
|
||||
if (n == 4) {
|
||||
return goog.i18n.ordinalRules.Keyword.FEW;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for gu locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.guSelect_ = function(n, opt_precision) {
|
||||
if (n == 1) {
|
||||
return goog.i18n.ordinalRules.Keyword.ONE;
|
||||
}
|
||||
if (n == 2 || n == 3) {
|
||||
return goog.i18n.ordinalRules.Keyword.TWO;
|
||||
}
|
||||
if (n == 4) {
|
||||
return goog.i18n.ordinalRules.Keyword.FEW;
|
||||
}
|
||||
if (n == 6) {
|
||||
return goog.i18n.ordinalRules.Keyword.MANY;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ordinal select rules for as locale
|
||||
*
|
||||
* @param {number} n The count of items.
|
||||
* @param {number=} opt_precision Precision for number formatting, if not default.
|
||||
* @return {goog.i18n.ordinalRules.Keyword} Locale-specific ordinal value.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.ordinalRules.asSelect_ = function(n, opt_precision) {
|
||||
if (n == 1 || n == 5 || n == 7 || n == 8 || n == 9 || n == 10) {
|
||||
return goog.i18n.ordinalRules.Keyword.ONE;
|
||||
}
|
||||
if (n == 2 || n == 3) {
|
||||
return goog.i18n.ordinalRules.Keyword.TWO;
|
||||
}
|
||||
if (n == 4) {
|
||||
return goog.i18n.ordinalRules.Keyword.FEW;
|
||||
}
|
||||
if (n == 6) {
|
||||
return goog.i18n.ordinalRules.Keyword.MANY;
|
||||
}
|
||||
return goog.i18n.ordinalRules.Keyword.OTHER;
|
||||
};
|
||||
|
||||
/**
|
||||
* Selected Ordinal rules by locale.
|
||||
*/
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.enSelect_;
|
||||
if (goog.LOCALE == 'af') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'am') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ar') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'az') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.azSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'be') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.beSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'bg') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'bn') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.asSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'br') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'bs') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ca') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.caSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'chr') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'cs') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'cy') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.cySelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'da') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'de') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'de_AT' || goog.LOCALE == 'de-AT') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'de_CH' || goog.LOCALE == 'de-CH') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'el') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'en') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.enSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'en_AU' || goog.LOCALE == 'en-AU') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.enSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'en_CA' || goog.LOCALE == 'en-CA') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.enSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'en_GB' || goog.LOCALE == 'en-GB') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.enSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'en_IE' || goog.LOCALE == 'en-IE') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.enSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'en_IN' || goog.LOCALE == 'en-IN') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.enSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'en_SG' || goog.LOCALE == 'en-SG') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.enSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'en_US' || goog.LOCALE == 'en-US') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.enSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'en_ZA' || goog.LOCALE == 'en-ZA') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.enSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'es') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'es_419' || goog.LOCALE == 'es-419') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'es_ES' || goog.LOCALE == 'es-ES') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'es_MX' || goog.LOCALE == 'es-MX') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'es_US' || goog.LOCALE == 'es-US') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'et') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'eu') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'fa') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'fi') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'fil') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.frSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'fr') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.frSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'fr_CA' || goog.LOCALE == 'fr-CA') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.frSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ga') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.frSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'gl') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'gsw') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'gu') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.guSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'haw') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'he') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'hi') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.guSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'hr') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'hu') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.huSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'hy') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.frSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'id') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'in') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'is') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'it') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.itSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'iw') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ja') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ka') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.kaSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'kk') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.kkSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'km') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'kn') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ko') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ky') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ln') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'lo') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.frSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'lt') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'lv') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'mk') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.mkSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ml') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'mn') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'mo') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.frSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'mr') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.mrSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ms') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.frSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'mt') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'my') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'nb') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ne') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.neSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'nl') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'no') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'no_NO' || goog.LOCALE == 'no-NO') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'or') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'pa') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'pl') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'pt') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'pt_BR' || goog.LOCALE == 'pt-BR') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'pt_PT' || goog.LOCALE == 'pt-PT') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ro') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.frSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ru') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'sh') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'si') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'sk') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'sl') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'sq') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.sqSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'sr') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'sr_Latn' || goog.LOCALE == 'sr-Latn') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'sv') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.svSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'sw') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ta') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'te') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'th') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'tl') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.frSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'tr') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'uk') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.ukSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'ur') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'uz') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'vi') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.frSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'zh') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'zh_CN' || goog.LOCALE == 'zh-CN') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'zh_HK' || goog.LOCALE == 'zh-HK') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'zh_TW' || goog.LOCALE == 'zh-TW') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
if (goog.LOCALE == 'zu') {
|
||||
goog.i18n.ordinalRules.select = goog.i18n.ordinalRules.defaultSelect_;
|
||||
}
|
||||
1140
resources/public/js/compiled/out/goog/i18n/pluralrules.js
Normal file
1140
resources/public/js/compiled/out/goog/i18n/pluralrules.js
Normal file
File diff suppressed because it is too large
Load diff
422
resources/public/js/compiled/out/goog/i18n/timezone.js
Normal file
422
resources/public/js/compiled/out/goog/i18n/timezone.js
Normal file
|
|
@ -0,0 +1,422 @@
|
|||
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Functions to provide timezone information for use with
|
||||
* date/time format.
|
||||
*/
|
||||
|
||||
goog.provide('goog.i18n.TimeZone');
|
||||
|
||||
goog.require('goog.array');
|
||||
/** @suppress {extraRequire} goog.date.DateLike represents a Date or a
|
||||
* goog.Date object. It is a parameter in the following methods:
|
||||
* - getDaylightAdjustment
|
||||
* - getGMTString
|
||||
* - getLongName
|
||||
* - getOffset
|
||||
* - getRFCTimeZoneString
|
||||
* - getShortName
|
||||
* - isDaylightTime
|
||||
* - getLongNameGMT
|
||||
* - getGenericLocation
|
||||
* Lint warns that this require is unnecessary but the closure compiler needs
|
||||
* it in order to accept a Date or a goog.Date object as a goog.date.DateLike
|
||||
* parameter in any of these methods. */
|
||||
goog.require('goog.date.DateLike');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* TimeZone class implemented a time zone resolution and name information
|
||||
* source for client applications. The time zone object is initiated from
|
||||
* a time zone information object. Application can initiate a time zone
|
||||
* statically, or it may choose to initiate from a data obtained from server.
|
||||
* Each time zone information array is small, but the whole set of data
|
||||
* is too much for client application to download. If end user is allowed to
|
||||
* change time zone setting, dynamic retrieval should be the method to use.
|
||||
* In case only time zone offset is known, there is a decent fallback
|
||||
* that only use the time zone offset to create a TimeZone object.
|
||||
* A whole set of time zone information array was available under
|
||||
* http://go/js_locale_data. It is generated based on CLDR/ICU and
|
||||
* Olson time zone data base, and will be updated timely.
|
||||
*
|
||||
* @constructor
|
||||
* @final
|
||||
*/
|
||||
goog.i18n.TimeZone = function() {
|
||||
/**
|
||||
* The standard time zone id.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
this.timeZoneId_;
|
||||
|
||||
|
||||
/**
|
||||
* The standard, non-daylight time zone offset, in minutes WEST of UTC.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.standardOffset_;
|
||||
|
||||
|
||||
/**
|
||||
* An array of strings that can have 2 or 4 elements. The first two elements
|
||||
* are the long and short names for standard time in this time zone, and the
|
||||
* last two elements (if present) are the long and short names for daylight
|
||||
* time in this time zone.
|
||||
* @type {Array<string>}
|
||||
* @private
|
||||
*/
|
||||
this.tzNames_;
|
||||
|
||||
|
||||
/**
|
||||
* An object of 2 to 4 elements. The STD_* are always available, while the
|
||||
* DST_* are only available when daylight saving time is available for this
|
||||
* time zone.
|
||||
* <ul>
|
||||
* <li>STD_LONG_NAME_GMT: long GMT name for standard time</li>
|
||||
* <li>STD_GENERIC_LOCATION: generic location for standard time</li>
|
||||
* <li>DST_LONG_NAME_GMT: long GMT for daylight saving time</li>
|
||||
* <li>DST_GENERIC_LOCATION: generic location for daylight saving time</li>
|
||||
* </ul>
|
||||
* @type { { STD_LONG_NAME_GMT:string, STD_GENERIC_LOCATION:string } |
|
||||
* { STD_LONG_NAME_GMT:string, STD_GENERIC_LOCATION:string,
|
||||
* DST_LONG_NAME_GMT:string, DST_GENERIC_LOCATION:string }
|
||||
* }
|
||||
* @private
|
||||
*/
|
||||
this.tzNamesExt_;
|
||||
|
||||
|
||||
/**
|
||||
* This array specifies the Daylight Saving Time transitions for this time
|
||||
* zone. This is a flat array of numbers which are interpreted in pairs:
|
||||
* [time1, adjustment1, time2, adjustment2, ...] where each time is a DST
|
||||
* transition point given as a number of hours since 00:00 UTC, January 1,
|
||||
* 1970, and each adjustment is the adjustment to apply for times after the
|
||||
* DST transition, given as minutes EAST of UTC.
|
||||
* @type {Array<number>}
|
||||
* @private
|
||||
*/
|
||||
this.transitions_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The number of milliseconds in an hour.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.TimeZone.MILLISECONDS_PER_HOUR_ = 3600 * 1000;
|
||||
|
||||
|
||||
/**
|
||||
* Indices into the array of time zone names.
|
||||
* @enum {number}
|
||||
*/
|
||||
goog.i18n.TimeZone.NameType = {
|
||||
STD_SHORT_NAME: 0,
|
||||
STD_LONG_NAME: 1,
|
||||
DLT_SHORT_NAME: 2,
|
||||
DLT_LONG_NAME: 3
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This factory method creates a time zone instance. It takes either an object
|
||||
* containing complete time zone information, or a single number representing a
|
||||
* constant time zone offset. If the latter form is used, DST functionality is
|
||||
* not available.
|
||||
*
|
||||
* @param {number|Object} timeZoneData If this parameter is a number, it should
|
||||
* indicate minutes WEST of UTC to be used as a constant time zone offset.
|
||||
* Otherwise, it should be an object with these four fields:
|
||||
* <ul>
|
||||
* <li>id: A string ID for the time zone.
|
||||
* <li>std_offset: The standard time zone offset in minutes EAST of UTC.
|
||||
* <li>names: An array of four names (standard short name, standard long
|
||||
* name, daylight short name, daylight long, name)
|
||||
* <li>names_ext: A hash of four fields (standard long name gmt, daylight
|
||||
* long name gmt, standard generic location, daylight generic
|
||||
* location)
|
||||
* <li>transitions: An array of numbers which are interpreted in pairs:
|
||||
* [time1, adjustment1, time2, adjustment2, ...] where each time is
|
||||
* a DST transition point given as a number of hours since 00:00 UTC,
|
||||
* January 1, 1970, and each adjustment is the adjustment to apply
|
||||
* for times after the DST transition, given as minutes EAST of UTC.
|
||||
* </ul>
|
||||
* @return {!goog.i18n.TimeZone} A goog.i18n.TimeZone object for the given
|
||||
* time zone data.
|
||||
*/
|
||||
goog.i18n.TimeZone.createTimeZone = function(timeZoneData) {
|
||||
if (typeof timeZoneData == 'number') {
|
||||
return goog.i18n.TimeZone.createSimpleTimeZone_(timeZoneData);
|
||||
}
|
||||
var tz = new goog.i18n.TimeZone();
|
||||
tz.timeZoneId_ = timeZoneData['id'];
|
||||
tz.standardOffset_ = -timeZoneData['std_offset'];
|
||||
tz.tzNames_ = timeZoneData['names'];
|
||||
tz.tzNamesExt_ = timeZoneData['names_ext'];
|
||||
tz.transitions_ = timeZoneData['transitions'];
|
||||
return tz;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* This factory method creates a time zone object with a constant offset.
|
||||
* @param {number} timeZoneOffsetInMinutes Offset in minutes WEST of UTC.
|
||||
* @return {!goog.i18n.TimeZone} A time zone object with the given constant
|
||||
* offset. Note that the time zone ID of this object will use the POSIX
|
||||
* convention, which has a reversed sign ("Etc/GMT+8" means UTC-8 or PST).
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.TimeZone.createSimpleTimeZone_ = function(timeZoneOffsetInMinutes) {
|
||||
var tz = new goog.i18n.TimeZone();
|
||||
tz.standardOffset_ = timeZoneOffsetInMinutes;
|
||||
tz.timeZoneId_ =
|
||||
goog.i18n.TimeZone.composePosixTimeZoneID_(timeZoneOffsetInMinutes);
|
||||
var str = goog.i18n.TimeZone.composeUTCString_(timeZoneOffsetInMinutes);
|
||||
var strGMT = goog.i18n.TimeZone.composeGMTString_(timeZoneOffsetInMinutes);
|
||||
tz.tzNames_ = [str, str];
|
||||
tz.tzNamesExt_ = {STD_LONG_NAME_GMT: strGMT, STD_GENERIC_LOCATION: strGMT};
|
||||
tz.transitions_ = [];
|
||||
return tz;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generate a GMT-relative string for a constant time zone offset.
|
||||
* @param {number} offset The time zone offset in minutes WEST of UTC.
|
||||
* @return {string} The GMT string for this offset, which will indicate
|
||||
* hours EAST of UTC.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.TimeZone.composeGMTString_ = function(offset) {
|
||||
var parts = ['GMT'];
|
||||
parts.push(offset <= 0 ? '+' : '-');
|
||||
offset = Math.abs(offset);
|
||||
parts.push(
|
||||
goog.string.padNumber(Math.floor(offset / 60) % 100, 2), ':',
|
||||
goog.string.padNumber(offset % 60, 2));
|
||||
return parts.join('');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generate a POSIX time zone ID for a constant time zone offset.
|
||||
* @param {number} offset The time zone offset in minutes WEST of UTC.
|
||||
* @return {string} The POSIX time zone ID for this offset, which will indicate
|
||||
* hours WEST of UTC.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.TimeZone.composePosixTimeZoneID_ = function(offset) {
|
||||
if (offset == 0) {
|
||||
return 'Etc/GMT';
|
||||
}
|
||||
var parts = ['Etc/GMT', offset < 0 ? '-' : '+'];
|
||||
offset = Math.abs(offset);
|
||||
parts.push(Math.floor(offset / 60) % 100);
|
||||
offset = offset % 60;
|
||||
if (offset != 0) {
|
||||
parts.push(':', goog.string.padNumber(offset, 2));
|
||||
}
|
||||
return parts.join('');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generate a UTC-relative string for a constant time zone offset.
|
||||
* @param {number} offset The time zone offset in minutes WEST of UTC.
|
||||
* @return {string} The UTC string for this offset, which will indicate
|
||||
* hours EAST of UTC.
|
||||
* @private
|
||||
*/
|
||||
goog.i18n.TimeZone.composeUTCString_ = function(offset) {
|
||||
if (offset == 0) {
|
||||
return 'UTC';
|
||||
}
|
||||
var parts = ['UTC', offset < 0 ? '+' : '-'];
|
||||
offset = Math.abs(offset);
|
||||
parts.push(Math.floor(offset / 60) % 100);
|
||||
offset = offset % 60;
|
||||
if (offset != 0) {
|
||||
parts.push(':', offset);
|
||||
}
|
||||
return parts.join('');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Convert the contents of time zone object to a timeZoneData object, suitable
|
||||
* for passing to goog.i18n.TimeZone.createTimeZone.
|
||||
* @return {!Object} A timeZoneData object (see the documentation for
|
||||
* goog.i18n.TimeZone.createTimeZone).
|
||||
*/
|
||||
goog.i18n.TimeZone.prototype.getTimeZoneData = function() {
|
||||
return {
|
||||
'id': this.timeZoneId_,
|
||||
'std_offset': -this.standardOffset_, // note createTimeZone flips the sign
|
||||
'names': goog.array.clone(this.tzNames_), // avoid aliasing the array
|
||||
'names_ext': goog.object.clone(this.tzNamesExt_), // avoid aliasing
|
||||
'transitions': goog.array.clone(this.transitions_) // avoid aliasing
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return the DST adjustment to the time zone offset for a given time.
|
||||
* While Daylight Saving Time is in effect, this number is positive.
|
||||
* Otherwise, it is zero.
|
||||
* @param {goog.date.DateLike} date The time to check.
|
||||
* @return {number} The DST adjustment in minutes EAST of UTC.
|
||||
*/
|
||||
goog.i18n.TimeZone.prototype.getDaylightAdjustment = function(date) {
|
||||
var timeInMs = Date.UTC(
|
||||
date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(),
|
||||
date.getUTCHours(), date.getUTCMinutes());
|
||||
var timeInHours = timeInMs / goog.i18n.TimeZone.MILLISECONDS_PER_HOUR_;
|
||||
var index = 0;
|
||||
while (index < this.transitions_.length &&
|
||||
timeInHours >= this.transitions_[index]) {
|
||||
index += 2;
|
||||
}
|
||||
return (index == 0) ? 0 : this.transitions_[index - 1];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return the GMT representation of this time zone object.
|
||||
* @param {goog.date.DateLike} date The date for which time to retrieve
|
||||
* GMT string.
|
||||
* @return {string} GMT representation string.
|
||||
*/
|
||||
goog.i18n.TimeZone.prototype.getGMTString = function(date) {
|
||||
return goog.i18n.TimeZone.composeGMTString_(this.getOffset(date));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the long time zone name for a given date/time.
|
||||
* @param {goog.date.DateLike} date The time for which to retrieve
|
||||
* the long time zone name.
|
||||
* @return {string} The long time zone name.
|
||||
*/
|
||||
goog.i18n.TimeZone.prototype.getLongName = function(date) {
|
||||
return this.tzNames_[this.isDaylightTime(date) ?
|
||||
goog.i18n.TimeZone.NameType.DLT_LONG_NAME :
|
||||
goog.i18n.TimeZone.NameType.STD_LONG_NAME];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the time zone offset in minutes WEST of UTC for a given date/time.
|
||||
* @param {goog.date.DateLike} date The time for which to retrieve
|
||||
* the time zone offset.
|
||||
* @return {number} The time zone offset in minutes WEST of UTC.
|
||||
*/
|
||||
goog.i18n.TimeZone.prototype.getOffset = function(date) {
|
||||
return this.standardOffset_ - this.getDaylightAdjustment(date);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the RFC representation of the time zone for a given date/time.
|
||||
* @param {goog.date.DateLike} date The time for which to retrieve the
|
||||
* RFC time zone string.
|
||||
* @return {string} The RFC time zone string.
|
||||
*/
|
||||
goog.i18n.TimeZone.prototype.getRFCTimeZoneString = function(date) {
|
||||
var offset = -this.getOffset(date);
|
||||
var parts = [offset < 0 ? '-' : '+'];
|
||||
offset = Math.abs(offset);
|
||||
parts.push(
|
||||
goog.string.padNumber(Math.floor(offset / 60) % 100, 2),
|
||||
goog.string.padNumber(offset % 60, 2));
|
||||
return parts.join('');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the short time zone name for given date/time.
|
||||
* @param {goog.date.DateLike} date The time for which to retrieve
|
||||
* the short time zone name.
|
||||
* @return {string} The short time zone name.
|
||||
*/
|
||||
goog.i18n.TimeZone.prototype.getShortName = function(date) {
|
||||
return this.tzNames_[this.isDaylightTime(date) ?
|
||||
goog.i18n.TimeZone.NameType.DLT_SHORT_NAME :
|
||||
goog.i18n.TimeZone.NameType.STD_SHORT_NAME];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Return the time zone ID for this time zone.
|
||||
* @return {string} The time zone ID.
|
||||
*/
|
||||
goog.i18n.TimeZone.prototype.getTimeZoneId = function() {
|
||||
return this.timeZoneId_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check if Daylight Saving Time is in effect at a given time in this time zone.
|
||||
* @param {goog.date.DateLike} date The time to check.
|
||||
* @return {boolean} True if Daylight Saving Time is in effect.
|
||||
*/
|
||||
goog.i18n.TimeZone.prototype.isDaylightTime = function(date) {
|
||||
return this.getDaylightAdjustment(date) > 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the long GMT time zone name for a given date/time.
|
||||
* @param {!goog.date.DateLike} date The time for which to retrieve
|
||||
* the long GMT time zone name.
|
||||
* @return {string} The long GMT time zone name.
|
||||
*/
|
||||
goog.i18n.TimeZone.prototype.getLongNameGMT = function(date) {
|
||||
if (this.isDaylightTime(date)) {
|
||||
return (goog.isDef(this.tzNamesExt_.DST_LONG_NAME_GMT)) ?
|
||||
this.tzNamesExt_.DST_LONG_NAME_GMT :
|
||||
this.tzNamesExt_['DST_LONG_NAME_GMT'];
|
||||
} else {
|
||||
return (goog.isDef(this.tzNamesExt_.STD_LONG_NAME_GMT)) ?
|
||||
this.tzNamesExt_.STD_LONG_NAME_GMT :
|
||||
this.tzNamesExt_['STD_LONG_NAME_GMT'];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get the generic location time zone name for a given date/time.
|
||||
* @param {!goog.date.DateLike} date The time for which to retrieve
|
||||
* the generic location time zone name.
|
||||
* @return {string} The generic location time zone name.
|
||||
*/
|
||||
goog.i18n.TimeZone.prototype.getGenericLocation = function(date) {
|
||||
if (this.isDaylightTime(date)) {
|
||||
return (goog.isDef(this.tzNamesExt_.DST_GENERIC_LOCATION)) ?
|
||||
this.tzNamesExt_.DST_GENERIC_LOCATION :
|
||||
this.tzNamesExt_['DST_GENERIC_LOCATION'];
|
||||
} else {
|
||||
return (goog.isDef(this.tzNamesExt_.STD_GENERIC_LOCATION)) ?
|
||||
this.tzNamesExt_.STD_GENERIC_LOCATION :
|
||||
this.tzNamesExt_['STD_GENERIC_LOCATION'];
|
||||
}
|
||||
};
|
||||
1284
resources/public/js/compiled/out/goog/iter/iter.js
Normal file
1284
resources/public/js/compiled/out/goog/iter/iter.js
Normal file
File diff suppressed because it is too large
Load diff
338
resources/public/js/compiled/out/goog/labs/useragent/browser.js
Normal file
338
resources/public/js/compiled/out/goog/labs/useragent/browser.js
Normal file
|
|
@ -0,0 +1,338 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Closure user agent detection (Browser).
|
||||
* @see <a href="http://www.useragentstring.com/">User agent strings</a>
|
||||
* For more information on rendering engine, platform, or device see the other
|
||||
* sub-namespaces in goog.labs.userAgent, goog.labs.userAgent.platform,
|
||||
* goog.labs.userAgent.device respectively.)
|
||||
*
|
||||
* @author martone@google.com (Andy Martone)
|
||||
*/
|
||||
|
||||
goog.provide('goog.labs.userAgent.browser');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.labs.userAgent.util');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
// TODO(nnaze): Refactor to remove excessive exclusion logic in matching
|
||||
// functions.
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Opera. Note: Chromium
|
||||
* based Opera (Opera 15+) is detected as Chrome to avoid unnecessary
|
||||
* special casing.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchOpera_ = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Opera');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is IE.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchIE_ = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Trident') ||
|
||||
goog.labs.userAgent.util.matchUserAgent('MSIE');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Edge.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchEdge_ = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Edge');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Firefox.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchFirefox_ = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Firefox');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Safari.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchSafari_ = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Safari') &&
|
||||
!(goog.labs.userAgent.browser.matchChrome_() ||
|
||||
goog.labs.userAgent.browser.matchCoast_() ||
|
||||
goog.labs.userAgent.browser.matchOpera_() ||
|
||||
goog.labs.userAgent.browser.matchEdge_() ||
|
||||
goog.labs.userAgent.browser.isSilk() ||
|
||||
goog.labs.userAgent.util.matchUserAgent('Android'));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based
|
||||
* iOS browser).
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchCoast_ = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Coast');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is iOS Webview.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchIosWebview_ = function() {
|
||||
// iOS Webview does not show up as Chrome or Safari. Also check for Opera's
|
||||
// WebKit-based iOS browser, Coast.
|
||||
return (goog.labs.userAgent.util.matchUserAgent('iPad') ||
|
||||
goog.labs.userAgent.util.matchUserAgent('iPhone')) &&
|
||||
!goog.labs.userAgent.browser.matchSafari_() &&
|
||||
!goog.labs.userAgent.browser.matchChrome_() &&
|
||||
!goog.labs.userAgent.browser.matchCoast_() &&
|
||||
goog.labs.userAgent.util.matchUserAgent('AppleWebKit');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Chrome.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchChrome_ = function() {
|
||||
return (goog.labs.userAgent.util.matchUserAgent('Chrome') ||
|
||||
goog.labs.userAgent.util.matchUserAgent('CriOS')) &&
|
||||
!goog.labs.userAgent.browser.matchEdge_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is the Android browser.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.matchAndroidBrowser_ = function() {
|
||||
// Android can appear in the user agent string for Chrome on Android.
|
||||
// This is not the Android standalone browser if it does.
|
||||
return goog.labs.userAgent.util.matchUserAgent('Android') &&
|
||||
!(goog.labs.userAgent.browser.isChrome() ||
|
||||
goog.labs.userAgent.browser.isFirefox() ||
|
||||
goog.labs.userAgent.browser.isOpera() ||
|
||||
goog.labs.userAgent.browser.isSilk());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Opera.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isOpera = goog.labs.userAgent.browser.matchOpera_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is IE.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isIE = goog.labs.userAgent.browser.matchIE_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Edge.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isEdge = goog.labs.userAgent.browser.matchEdge_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Firefox.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isFirefox =
|
||||
goog.labs.userAgent.browser.matchFirefox_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Safari.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isSafari = goog.labs.userAgent.browser.matchSafari_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Coast (Opera's Webkit-based
|
||||
* iOS browser).
|
||||
*/
|
||||
goog.labs.userAgent.browser.isCoast = goog.labs.userAgent.browser.matchCoast_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is iOS Webview.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isIosWebview =
|
||||
goog.labs.userAgent.browser.matchIosWebview_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is Chrome.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isChrome = goog.labs.userAgent.browser.matchChrome_;
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user's browser is the Android browser.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isAndroidBrowser =
|
||||
goog.labs.userAgent.browser.matchAndroidBrowser_;
|
||||
|
||||
|
||||
/**
|
||||
* For more information, see:
|
||||
* http://docs.aws.amazon.com/silk/latest/developerguide/user-agent.html
|
||||
* @return {boolean} Whether the user's browser is Silk.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isSilk = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Silk');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The browser version or empty string if version cannot be
|
||||
* determined. Note that for Internet Explorer, this returns the version of
|
||||
* the browser, not the version of the rendering engine. (IE 8 in
|
||||
* compatibility mode will return 8.0 rather than 7.0. To determine the
|
||||
* rendering engine version, look at document.documentMode instead. See
|
||||
* http://msdn.microsoft.com/en-us/library/cc196988(v=vs.85).aspx for more
|
||||
* details.)
|
||||
*/
|
||||
goog.labs.userAgent.browser.getVersion = function() {
|
||||
var userAgentString = goog.labs.userAgent.util.getUserAgent();
|
||||
// Special case IE since IE's version is inside the parenthesis and
|
||||
// without the '/'.
|
||||
if (goog.labs.userAgent.browser.isIE()) {
|
||||
return goog.labs.userAgent.browser.getIEVersion_(userAgentString);
|
||||
}
|
||||
|
||||
var versionTuples =
|
||||
goog.labs.userAgent.util.extractVersionTuples(userAgentString);
|
||||
|
||||
// Construct a map for easy lookup.
|
||||
var versionMap = {};
|
||||
goog.array.forEach(versionTuples, function(tuple) {
|
||||
// Note that the tuple is of length three, but we only care about the
|
||||
// first two.
|
||||
var key = tuple[0];
|
||||
var value = tuple[1];
|
||||
versionMap[key] = value;
|
||||
});
|
||||
|
||||
var versionMapHasKey = goog.partial(goog.object.containsKey, versionMap);
|
||||
|
||||
// Gives the value with the first key it finds, otherwise empty string.
|
||||
function lookUpValueWithKeys(keys) {
|
||||
var key = goog.array.find(keys, versionMapHasKey);
|
||||
return versionMap[key] || '';
|
||||
}
|
||||
|
||||
// Check Opera before Chrome since Opera 15+ has "Chrome" in the string.
|
||||
// See
|
||||
// http://my.opera.com/ODIN/blog/2013/07/15/opera-user-agent-strings-opera-15-and-beyond
|
||||
if (goog.labs.userAgent.browser.isOpera()) {
|
||||
// Opera 10 has Version/10.0 but Opera/9.8, so look for "Version" first.
|
||||
// Opera uses 'OPR' for more recent UAs.
|
||||
return lookUpValueWithKeys(['Version', 'Opera']);
|
||||
}
|
||||
|
||||
// Check Edge before Chrome since it has Chrome in the string.
|
||||
if (goog.labs.userAgent.browser.isEdge()) {
|
||||
return lookUpValueWithKeys(['Edge']);
|
||||
}
|
||||
|
||||
if (goog.labs.userAgent.browser.isChrome()) {
|
||||
return lookUpValueWithKeys(['Chrome', 'CriOS']);
|
||||
}
|
||||
|
||||
// Usually products browser versions are in the third tuple after "Mozilla"
|
||||
// and the engine.
|
||||
var tuple = versionTuples[2];
|
||||
return tuple && tuple[1] || '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string|number} version The version to check.
|
||||
* @return {boolean} Whether the browser version is higher or the same as the
|
||||
* given version.
|
||||
*/
|
||||
goog.labs.userAgent.browser.isVersionOrHigher = function(version) {
|
||||
return goog.string.compareVersions(
|
||||
goog.labs.userAgent.browser.getVersion(), version) >= 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determines IE version. More information:
|
||||
* http://msdn.microsoft.com/en-us/library/ie/bg182625(v=vs.85).aspx#uaString
|
||||
* http://msdn.microsoft.com/en-us/library/hh869301(v=vs.85).aspx
|
||||
* http://blogs.msdn.com/b/ie/archive/2010/03/23/introducing-ie9-s-user-agent-string.aspx
|
||||
* http://blogs.msdn.com/b/ie/archive/2009/01/09/the-internet-explorer-8-user-agent-string-updated-edition.aspx
|
||||
*
|
||||
* @param {string} userAgent the User-Agent.
|
||||
* @return {string}
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.browser.getIEVersion_ = function(userAgent) {
|
||||
// IE11 may identify itself as MSIE 9.0 or MSIE 10.0 due to an IE 11 upgrade
|
||||
// bug. Example UA:
|
||||
// Mozilla/5.0 (MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0; rv:11.0)
|
||||
// like Gecko.
|
||||
// See http://www.whatismybrowser.com/developers/unknown-user-agent-fragments.
|
||||
var rv = /rv: *([\d\.]*)/.exec(userAgent);
|
||||
if (rv && rv[1]) {
|
||||
return rv[1];
|
||||
}
|
||||
|
||||
var version = '';
|
||||
var msie = /MSIE +([\d\.]+)/.exec(userAgent);
|
||||
if (msie && msie[1]) {
|
||||
// IE in compatibility mode usually identifies itself as MSIE 7.0; in this
|
||||
// case, use the Trident version to determine the version of IE. For more
|
||||
// details, see the links above.
|
||||
var tridentVersion = /Trident\/(\d.\d)/.exec(userAgent);
|
||||
if (msie[1] == '7.0') {
|
||||
if (tridentVersion && tridentVersion[1]) {
|
||||
switch (tridentVersion[1]) {
|
||||
case '4.0':
|
||||
version = '8.0';
|
||||
break;
|
||||
case '5.0':
|
||||
version = '9.0';
|
||||
break;
|
||||
case '6.0':
|
||||
version = '10.0';
|
||||
break;
|
||||
case '7.0':
|
||||
version = '11.0';
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
version = '7.0';
|
||||
}
|
||||
} else {
|
||||
version = msie[1];
|
||||
}
|
||||
}
|
||||
return version;
|
||||
};
|
||||
156
resources/public/js/compiled/out/goog/labs/useragent/engine.js
Normal file
156
resources/public/js/compiled/out/goog/labs/useragent/engine.js
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Closure user agent detection.
|
||||
* @see http://en.wikipedia.org/wiki/User_agent
|
||||
* For more information on browser brand, platform, or device see the other
|
||||
* sub-namespaces in goog.labs.userAgent (browser, platform, and device).
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.labs.userAgent.engine');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.labs.userAgent.util');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the rendering engine is Presto.
|
||||
*/
|
||||
goog.labs.userAgent.engine.isPresto = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Presto');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the rendering engine is Trident.
|
||||
*/
|
||||
goog.labs.userAgent.engine.isTrident = function() {
|
||||
// IE only started including the Trident token in IE8.
|
||||
return goog.labs.userAgent.util.matchUserAgent('Trident') ||
|
||||
goog.labs.userAgent.util.matchUserAgent('MSIE');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the rendering engine is Edge.
|
||||
*/
|
||||
goog.labs.userAgent.engine.isEdge = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Edge');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the rendering engine is WebKit.
|
||||
*/
|
||||
goog.labs.userAgent.engine.isWebKit = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgentIgnoreCase('WebKit') &&
|
||||
!goog.labs.userAgent.engine.isEdge();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the rendering engine is Gecko.
|
||||
*/
|
||||
goog.labs.userAgent.engine.isGecko = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Gecko') &&
|
||||
!goog.labs.userAgent.engine.isWebKit() &&
|
||||
!goog.labs.userAgent.engine.isTrident() &&
|
||||
!goog.labs.userAgent.engine.isEdge();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The rendering engine's version or empty string if version
|
||||
* can't be determined.
|
||||
*/
|
||||
goog.labs.userAgent.engine.getVersion = function() {
|
||||
var userAgentString = goog.labs.userAgent.util.getUserAgent();
|
||||
if (userAgentString) {
|
||||
var tuples = goog.labs.userAgent.util.extractVersionTuples(userAgentString);
|
||||
|
||||
var engineTuple = goog.labs.userAgent.engine.getEngineTuple_(tuples);
|
||||
if (engineTuple) {
|
||||
// In Gecko, the version string is either in the browser info or the
|
||||
// Firefox version. See Gecko user agent string reference:
|
||||
// http://goo.gl/mULqa
|
||||
if (engineTuple[0] == 'Gecko') {
|
||||
return goog.labs.userAgent.engine.getVersionForKey_(tuples, 'Firefox');
|
||||
}
|
||||
|
||||
return engineTuple[1];
|
||||
}
|
||||
|
||||
// MSIE has only one version identifier, and the Trident version is
|
||||
// specified in the parenthetical. IE Edge is covered in the engine tuple
|
||||
// detection.
|
||||
var browserTuple = tuples[0];
|
||||
var info;
|
||||
if (browserTuple && (info = browserTuple[2])) {
|
||||
var match = /Trident\/([^\s;]+)/.exec(info);
|
||||
if (match) {
|
||||
return match[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!Array<!Array<string>>} tuples Extracted version tuples.
|
||||
* @return {!Array<string>|undefined} The engine tuple or undefined if not
|
||||
* found.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.engine.getEngineTuple_ = function(tuples) {
|
||||
if (!goog.labs.userAgent.engine.isEdge()) {
|
||||
return tuples[1];
|
||||
}
|
||||
for (var i = 0; i < tuples.length; i++) {
|
||||
var tuple = tuples[i];
|
||||
if (tuple[0] == 'Edge') {
|
||||
return tuple;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string|number} version The version to check.
|
||||
* @return {boolean} Whether the rendering engine version is higher or the same
|
||||
* as the given version.
|
||||
*/
|
||||
goog.labs.userAgent.engine.isVersionOrHigher = function(version) {
|
||||
return goog.string.compareVersions(
|
||||
goog.labs.userAgent.engine.getVersion(), version) >= 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!Array<!Array<string>>} tuples Version tuples.
|
||||
* @param {string} key The key to look for.
|
||||
* @return {string} The version string of the given key, if present.
|
||||
* Otherwise, the empty string.
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.engine.getVersionForKey_ = function(tuples, key) {
|
||||
// TODO(nnaze): Move to util if useful elsewhere.
|
||||
|
||||
var pair = goog.array.find(tuples, function(pair) { return key == pair[0]; });
|
||||
|
||||
return pair && pair[1] || '';
|
||||
};
|
||||
160
resources/public/js/compiled/out/goog/labs/useragent/platform.js
Normal file
160
resources/public/js/compiled/out/goog/labs/useragent/platform.js
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Closure user agent platform detection.
|
||||
* @see <a href="http://www.useragentstring.com/">User agent strings</a>
|
||||
* For more information on browser brand, rendering engine, or device see the
|
||||
* other sub-namespaces in goog.labs.userAgent (browser, engine, and device
|
||||
* respectively).
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.labs.userAgent.platform');
|
||||
|
||||
goog.require('goog.labs.userAgent.util');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is Android.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isAndroid = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Android');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is iPod.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isIpod = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('iPod');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is iPhone.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isIphone = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('iPhone') &&
|
||||
!goog.labs.userAgent.util.matchUserAgent('iPod') &&
|
||||
!goog.labs.userAgent.util.matchUserAgent('iPad');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is iPad.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isIpad = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('iPad');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is iOS.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isIos = function() {
|
||||
return goog.labs.userAgent.platform.isIphone() ||
|
||||
goog.labs.userAgent.platform.isIpad() ||
|
||||
goog.labs.userAgent.platform.isIpod();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is Mac.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isMacintosh = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Macintosh');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Note: ChromeOS is not considered to be Linux as it does not report itself
|
||||
* as Linux in the user agent string.
|
||||
* @return {boolean} Whether the platform is Linux.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isLinux = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Linux');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is Windows.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isWindows = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('Windows');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the platform is ChromeOS.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isChromeOS = function() {
|
||||
return goog.labs.userAgent.util.matchUserAgent('CrOS');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The version of the platform. We only determine the version for Windows,
|
||||
* Mac, and Chrome OS. It doesn't make much sense on Linux. For Windows, we only
|
||||
* look at the NT version. Non-NT-based versions (e.g. 95, 98, etc.) are given
|
||||
* version 0.0.
|
||||
*
|
||||
* @return {string} The platform version or empty string if version cannot be
|
||||
* determined.
|
||||
*/
|
||||
goog.labs.userAgent.platform.getVersion = function() {
|
||||
var userAgentString = goog.labs.userAgent.util.getUserAgent();
|
||||
var version = '', re;
|
||||
if (goog.labs.userAgent.platform.isWindows()) {
|
||||
re = /Windows (?:NT|Phone) ([0-9.]+)/;
|
||||
var match = re.exec(userAgentString);
|
||||
if (match) {
|
||||
version = match[1];
|
||||
} else {
|
||||
version = '0.0';
|
||||
}
|
||||
} else if (goog.labs.userAgent.platform.isIos()) {
|
||||
re = /(?:iPhone|iPod|iPad|CPU)\s+OS\s+(\S+)/;
|
||||
var match = re.exec(userAgentString);
|
||||
// Report the version as x.y.z and not x_y_z
|
||||
version = match && match[1].replace(/_/g, '.');
|
||||
} else if (goog.labs.userAgent.platform.isMacintosh()) {
|
||||
re = /Mac OS X ([0-9_.]+)/;
|
||||
var match = re.exec(userAgentString);
|
||||
// Note: some old versions of Camino do not report an OSX version.
|
||||
// Default to 10.
|
||||
version = match ? match[1].replace(/_/g, '.') : '10';
|
||||
} else if (goog.labs.userAgent.platform.isAndroid()) {
|
||||
re = /Android\s+([^\);]+)(\)|;)/;
|
||||
var match = re.exec(userAgentString);
|
||||
version = match && match[1];
|
||||
} else if (goog.labs.userAgent.platform.isChromeOS()) {
|
||||
re = /(?:CrOS\s+(?:i686|x86_64)\s+([0-9.]+))/;
|
||||
var match = re.exec(userAgentString);
|
||||
version = match && match[1];
|
||||
}
|
||||
return version || '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string|number} version The version to check.
|
||||
* @return {boolean} Whether the browser version is higher or the same as the
|
||||
* given version.
|
||||
*/
|
||||
goog.labs.userAgent.platform.isVersionOrHigher = function(version) {
|
||||
return goog.string.compareVersions(
|
||||
goog.labs.userAgent.platform.getVersion(), version) >= 0;
|
||||
};
|
||||
147
resources/public/js/compiled/out/goog/labs/useragent/util.js
Normal file
147
resources/public/js/compiled/out/goog/labs/useragent/util.js
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities used by goog.labs.userAgent tools. These functions
|
||||
* should not be used outside of goog.labs.userAgent.*.
|
||||
*
|
||||
*
|
||||
* @author nnaze@google.com (Nathan Naze)
|
||||
*/
|
||||
|
||||
goog.provide('goog.labs.userAgent.util');
|
||||
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* Gets the native userAgent string from navigator if it exists.
|
||||
* If navigator or navigator.userAgent string is missing, returns an empty
|
||||
* string.
|
||||
* @return {string}
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.util.getNativeUserAgentString_ = function() {
|
||||
var navigator = goog.labs.userAgent.util.getNavigator_();
|
||||
if (navigator) {
|
||||
var userAgent = navigator.userAgent;
|
||||
if (userAgent) {
|
||||
return userAgent;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Getter for the native navigator.
|
||||
* This is a separate function so it can be stubbed out in testing.
|
||||
* @return {Navigator}
|
||||
* @private
|
||||
*/
|
||||
goog.labs.userAgent.util.getNavigator_ = function() {
|
||||
return goog.global.navigator;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A possible override for applications which wish to not check
|
||||
* navigator.userAgent but use a specified value for detection instead.
|
||||
* @private {string}
|
||||
*/
|
||||
goog.labs.userAgent.util.userAgent_ =
|
||||
goog.labs.userAgent.util.getNativeUserAgentString_();
|
||||
|
||||
|
||||
/**
|
||||
* Applications may override browser detection on the built in
|
||||
* navigator.userAgent object by setting this string. Set to null to use the
|
||||
* browser object instead.
|
||||
* @param {?string=} opt_userAgent The User-Agent override.
|
||||
*/
|
||||
goog.labs.userAgent.util.setUserAgent = function(opt_userAgent) {
|
||||
goog.labs.userAgent.util.userAgent_ =
|
||||
opt_userAgent || goog.labs.userAgent.util.getNativeUserAgentString_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The user agent string.
|
||||
*/
|
||||
goog.labs.userAgent.util.getUserAgent = function() {
|
||||
return goog.labs.userAgent.util.userAgent_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @return {boolean} Whether the user agent contains the given string, ignoring
|
||||
* case.
|
||||
*/
|
||||
goog.labs.userAgent.util.matchUserAgent = function(str) {
|
||||
var userAgent = goog.labs.userAgent.util.getUserAgent();
|
||||
return goog.string.contains(userAgent, str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} str
|
||||
* @return {boolean} Whether the user agent contains the given string.
|
||||
*/
|
||||
goog.labs.userAgent.util.matchUserAgentIgnoreCase = function(str) {
|
||||
var userAgent = goog.labs.userAgent.util.getUserAgent();
|
||||
return goog.string.caseInsensitiveContains(userAgent, str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parses the user agent into tuples for each section.
|
||||
* @param {string} userAgent
|
||||
* @return {!Array<!Array<string>>} Tuples of key, version, and the contents
|
||||
* of the parenthetical.
|
||||
*/
|
||||
goog.labs.userAgent.util.extractVersionTuples = function(userAgent) {
|
||||
// Matches each section of a user agent string.
|
||||
// Example UA:
|
||||
// Mozilla/5.0 (iPad; U; CPU OS 3_2_1 like Mac OS X; en-us)
|
||||
// AppleWebKit/531.21.10 (KHTML, like Gecko) Mobile/7B405
|
||||
// This has three version tuples: Mozilla, AppleWebKit, and Mobile.
|
||||
|
||||
var versionRegExp = new RegExp(
|
||||
// Key. Note that a key may have a space.
|
||||
// (i.e. 'Mobile Safari' in 'Mobile Safari/5.0')
|
||||
'(\\w[\\w ]+)' +
|
||||
|
||||
'/' + // slash
|
||||
'([^\\s]+)' + // version (i.e. '5.0b')
|
||||
'\\s*' + // whitespace
|
||||
'(?:\\((.*?)\\))?', // parenthetical info. parentheses not matched.
|
||||
'g');
|
||||
|
||||
var data = [];
|
||||
var match;
|
||||
|
||||
// Iterate and collect the version tuples. Each iteration will be the
|
||||
// next regex match.
|
||||
while (match = versionRegExp.exec(userAgent)) {
|
||||
data.push([
|
||||
match[1], // key
|
||||
match[2], // value
|
||||
// || undefined as this is not undefined in IE7 and IE8
|
||||
match[3] || undefined // info
|
||||
]);
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
||||
268
resources/public/js/compiled/out/goog/math/coordinate.js
Normal file
268
resources/public/js/compiled/out/goog/math/coordinate.js
Normal file
|
|
@ -0,0 +1,268 @@
|
|||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A utility class for representing two-dimensional positions.
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.math.Coordinate');
|
||||
|
||||
goog.require('goog.math');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class for representing coordinates and positions.
|
||||
* @param {number=} opt_x Left, defaults to 0.
|
||||
* @param {number=} opt_y Top, defaults to 0.
|
||||
* @struct
|
||||
* @constructor
|
||||
*/
|
||||
goog.math.Coordinate = function(opt_x, opt_y) {
|
||||
/**
|
||||
* X-value
|
||||
* @type {number}
|
||||
*/
|
||||
this.x = goog.isDef(opt_x) ? opt_x : 0;
|
||||
|
||||
/**
|
||||
* Y-value
|
||||
* @type {number}
|
||||
*/
|
||||
this.y = goog.isDef(opt_y) ? opt_y : 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a new copy of the coordinate.
|
||||
* @return {!goog.math.Coordinate} A clone of this coordinate.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.clone = function() {
|
||||
return new goog.math.Coordinate(this.x, this.y);
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a nice string representing the coordinate.
|
||||
* @return {string} In the form (50, 73).
|
||||
* @override
|
||||
*/
|
||||
goog.math.Coordinate.prototype.toString = function() {
|
||||
return '(' + this.x + ', ' + this.y + ')';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compares coordinates for equality.
|
||||
* @param {goog.math.Coordinate} a A Coordinate.
|
||||
* @param {goog.math.Coordinate} b A Coordinate.
|
||||
* @return {boolean} True iff the coordinates are equal, or if both are null.
|
||||
*/
|
||||
goog.math.Coordinate.equals = function(a, b) {
|
||||
if (a == b) {
|
||||
return true;
|
||||
}
|
||||
if (!a || !b) {
|
||||
return false;
|
||||
}
|
||||
return a.x == b.x && a.y == b.y;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the distance between two coordinates.
|
||||
* @param {!goog.math.Coordinate} a A Coordinate.
|
||||
* @param {!goog.math.Coordinate} b A Coordinate.
|
||||
* @return {number} The distance between {@code a} and {@code b}.
|
||||
*/
|
||||
goog.math.Coordinate.distance = function(a, b) {
|
||||
var dx = a.x - b.x;
|
||||
var dy = a.y - b.y;
|
||||
return Math.sqrt(dx * dx + dy * dy);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the magnitude of a coordinate.
|
||||
* @param {!goog.math.Coordinate} a A Coordinate.
|
||||
* @return {number} The distance between the origin and {@code a}.
|
||||
*/
|
||||
goog.math.Coordinate.magnitude = function(a) {
|
||||
return Math.sqrt(a.x * a.x + a.y * a.y);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the angle from the origin to a coordinate.
|
||||
* @param {!goog.math.Coordinate} a A Coordinate.
|
||||
* @return {number} The angle, in degrees, clockwise from the positive X
|
||||
* axis to {@code a}.
|
||||
*/
|
||||
goog.math.Coordinate.azimuth = function(a) {
|
||||
return goog.math.angle(0, 0, a.x, a.y);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the squared distance between two coordinates. Squared distances can
|
||||
* be used for comparisons when the actual value is not required.
|
||||
*
|
||||
* Performance note: eliminating the square root is an optimization often used
|
||||
* in lower-level languages, but the speed difference is not nearly as
|
||||
* pronounced in JavaScript (only a few percent.)
|
||||
*
|
||||
* @param {!goog.math.Coordinate} a A Coordinate.
|
||||
* @param {!goog.math.Coordinate} b A Coordinate.
|
||||
* @return {number} The squared distance between {@code a} and {@code b}.
|
||||
*/
|
||||
goog.math.Coordinate.squaredDistance = function(a, b) {
|
||||
var dx = a.x - b.x;
|
||||
var dy = a.y - b.y;
|
||||
return dx * dx + dy * dy;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the difference between two coordinates as a new
|
||||
* goog.math.Coordinate.
|
||||
* @param {!goog.math.Coordinate} a A Coordinate.
|
||||
* @param {!goog.math.Coordinate} b A Coordinate.
|
||||
* @return {!goog.math.Coordinate} A Coordinate representing the difference
|
||||
* between {@code a} and {@code b}.
|
||||
*/
|
||||
goog.math.Coordinate.difference = function(a, b) {
|
||||
return new goog.math.Coordinate(a.x - b.x, a.y - b.y);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the sum of two coordinates as a new goog.math.Coordinate.
|
||||
* @param {!goog.math.Coordinate} a A Coordinate.
|
||||
* @param {!goog.math.Coordinate} b A Coordinate.
|
||||
* @return {!goog.math.Coordinate} A Coordinate representing the sum of the two
|
||||
* coordinates.
|
||||
*/
|
||||
goog.math.Coordinate.sum = function(a, b) {
|
||||
return new goog.math.Coordinate(a.x + b.x, a.y + b.y);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rounds the x and y fields to the next larger integer values.
|
||||
* @return {!goog.math.Coordinate} This coordinate with ceil'd fields.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.ceil = function() {
|
||||
this.x = Math.ceil(this.x);
|
||||
this.y = Math.ceil(this.y);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rounds the x and y fields to the next smaller integer values.
|
||||
* @return {!goog.math.Coordinate} This coordinate with floored fields.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.floor = function() {
|
||||
this.x = Math.floor(this.x);
|
||||
this.y = Math.floor(this.y);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rounds the x and y fields to the nearest integer values.
|
||||
* @return {!goog.math.Coordinate} This coordinate with rounded fields.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.round = function() {
|
||||
this.x = Math.round(this.x);
|
||||
this.y = Math.round(this.y);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Translates this box by the given offsets. If a {@code goog.math.Coordinate}
|
||||
* is given, then the x and y values are translated by the coordinate's x and y.
|
||||
* Otherwise, x and y are translated by {@code tx} and {@code opt_ty}
|
||||
* respectively.
|
||||
* @param {number|goog.math.Coordinate} tx The value to translate x by or the
|
||||
* the coordinate to translate this coordinate by.
|
||||
* @param {number=} opt_ty The value to translate y by.
|
||||
* @return {!goog.math.Coordinate} This coordinate after translating.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.translate = function(tx, opt_ty) {
|
||||
if (tx instanceof goog.math.Coordinate) {
|
||||
this.x += tx.x;
|
||||
this.y += tx.y;
|
||||
} else {
|
||||
this.x += Number(tx);
|
||||
if (goog.isNumber(opt_ty)) {
|
||||
this.y += opt_ty;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Scales this coordinate by the given scale factors. The x and y values are
|
||||
* scaled by {@code sx} and {@code opt_sy} respectively. If {@code opt_sy}
|
||||
* is not given, then {@code sx} is used for both x and y.
|
||||
* @param {number} sx The scale factor to use for the x dimension.
|
||||
* @param {number=} opt_sy The scale factor to use for the y dimension.
|
||||
* @return {!goog.math.Coordinate} This coordinate after scaling.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.scale = function(sx, opt_sy) {
|
||||
var sy = goog.isNumber(opt_sy) ? opt_sy : sx;
|
||||
this.x *= sx;
|
||||
this.y *= sy;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rotates this coordinate clockwise about the origin (or, optionally, the given
|
||||
* center) by the given angle, in radians.
|
||||
* @param {number} radians The angle by which to rotate this coordinate
|
||||
* clockwise about the given center, in radians.
|
||||
* @param {!goog.math.Coordinate=} opt_center The center of rotation. Defaults
|
||||
* to (0, 0) if not given.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.rotateRadians = function(radians, opt_center) {
|
||||
var center = opt_center || new goog.math.Coordinate(0, 0);
|
||||
|
||||
var x = this.x;
|
||||
var y = this.y;
|
||||
var cos = Math.cos(radians);
|
||||
var sin = Math.sin(radians);
|
||||
|
||||
this.x = (x - center.x) * cos - (y - center.y) * sin + center.x;
|
||||
this.y = (x - center.x) * sin + (y - center.y) * cos + center.y;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rotates this coordinate clockwise about the origin (or, optionally, the given
|
||||
* center) by the given angle, in degrees.
|
||||
* @param {number} degrees The angle by which to rotate this coordinate
|
||||
* clockwise about the given center, in degrees.
|
||||
* @param {!goog.math.Coordinate=} opt_center The center of rotation. Defaults
|
||||
* to (0, 0) if not given.
|
||||
*/
|
||||
goog.math.Coordinate.prototype.rotateDegrees = function(degrees, opt_center) {
|
||||
this.rotateRadians(goog.math.toRadians(degrees), opt_center);
|
||||
};
|
||||
807
resources/public/js/compiled/out/goog/math/integer.js
Normal file
807
resources/public/js/compiled/out/goog/math/integer.js
Normal file
|
|
@ -0,0 +1,807 @@
|
|||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Defines an Integer class for representing (potentially)
|
||||
* infinite length two's-complement integer values.
|
||||
*
|
||||
* For the specific case of 64-bit integers, use goog.math.Long, which is more
|
||||
* efficient.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.math.Integer');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a two's-complement integer an array containing bits of the
|
||||
* integer in 32-bit (signed) pieces, given in little-endian order (i.e.,
|
||||
* lowest-order bits in the first piece), and the sign of -1 or 0.
|
||||
*
|
||||
* See the from* functions below for other convenient ways of constructing
|
||||
* Integers.
|
||||
*
|
||||
* The internal representation of an integer is an array of 32-bit signed
|
||||
* pieces, along with a sign (0 or -1) that indicates the contents of all the
|
||||
* other 32-bit pieces out to infinity. We use 32-bit pieces because these are
|
||||
* the size of integers on which Javascript performs bit-operations. For
|
||||
* operations like addition and multiplication, we split each number into 16-bit
|
||||
* pieces, which can easily be multiplied within Javascript's floating-point
|
||||
* representation without overflow or change in sign.
|
||||
*
|
||||
* @struct
|
||||
* @constructor
|
||||
* @param {Array<number>} bits Array containing the bits of the number.
|
||||
* @param {number} sign The sign of the number: -1 for negative and 0 positive.
|
||||
* @final
|
||||
*/
|
||||
goog.math.Integer = function(bits, sign) {
|
||||
/**
|
||||
* @type {!Array<number>}
|
||||
* @private
|
||||
*/
|
||||
this.bits_ = [];
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.sign_ = sign;
|
||||
|
||||
// Copy the 32-bit signed integer values passed in. We prune out those at the
|
||||
// top that equal the sign since they are redundant.
|
||||
var top = true;
|
||||
for (var i = bits.length - 1; i >= 0; i--) {
|
||||
var val = bits[i] | 0;
|
||||
if (!top || val != sign) {
|
||||
this.bits_[i] = val;
|
||||
top = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the
|
||||
// from* methods on which they depend.
|
||||
|
||||
|
||||
/**
|
||||
* A cache of the Integer representations of small integer values.
|
||||
* @type {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Integer.IntCache_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an Integer representing the given (32-bit) integer value.
|
||||
* @param {number} value A 32-bit integer value.
|
||||
* @return {!goog.math.Integer} The corresponding Integer value.
|
||||
*/
|
||||
goog.math.Integer.fromInt = function(value) {
|
||||
if (-128 <= value && value < 128) {
|
||||
var cachedObj = goog.math.Integer.IntCache_[value];
|
||||
if (cachedObj) {
|
||||
return cachedObj;
|
||||
}
|
||||
}
|
||||
|
||||
var obj = new goog.math.Integer([value | 0], value < 0 ? -1 : 0);
|
||||
if (-128 <= value && value < 128) {
|
||||
goog.math.Integer.IntCache_[value] = obj;
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an Integer representing the given value, provided that it is a finite
|
||||
* number. Otherwise, zero is returned.
|
||||
* @param {number} value The value in question.
|
||||
* @return {!goog.math.Integer} The corresponding Integer value.
|
||||
*/
|
||||
goog.math.Integer.fromNumber = function(value) {
|
||||
if (isNaN(value) || !isFinite(value)) {
|
||||
return goog.math.Integer.ZERO;
|
||||
} else if (value < 0) {
|
||||
return goog.math.Integer.fromNumber(-value).negate();
|
||||
} else {
|
||||
var bits = [];
|
||||
var pow = 1;
|
||||
for (var i = 0; value >= pow; i++) {
|
||||
bits[i] = (value / pow) | 0;
|
||||
pow *= goog.math.Integer.TWO_PWR_32_DBL_;
|
||||
}
|
||||
return new goog.math.Integer(bits, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Integer representing the value that comes by concatenating the
|
||||
* given entries, each is assumed to be 32 signed bits, given in little-endian
|
||||
* order (lowest order bits in the lowest index), and sign-extending the highest
|
||||
* order 32-bit value.
|
||||
* @param {Array<number>} bits The bits of the number, in 32-bit signed pieces,
|
||||
* in little-endian order.
|
||||
* @return {!goog.math.Integer} The corresponding Integer value.
|
||||
*/
|
||||
goog.math.Integer.fromBits = function(bits) {
|
||||
var high = bits[bits.length - 1];
|
||||
return new goog.math.Integer(bits, high & (1 << 31) ? -1 : 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an Integer representation of the given string, written using the
|
||||
* given radix.
|
||||
* @param {string} str The textual representation of the Integer.
|
||||
* @param {number=} opt_radix The radix in which the text is written.
|
||||
* @return {!goog.math.Integer} The corresponding Integer value.
|
||||
*/
|
||||
goog.math.Integer.fromString = function(str, opt_radix) {
|
||||
if (str.length == 0) {
|
||||
throw Error('number format error: empty string');
|
||||
}
|
||||
|
||||
var radix = opt_radix || 10;
|
||||
if (radix < 2 || 36 < radix) {
|
||||
throw Error('radix out of range: ' + radix);
|
||||
}
|
||||
|
||||
if (str.charAt(0) == '-') {
|
||||
return goog.math.Integer.fromString(str.substring(1), radix).negate();
|
||||
} else if (str.indexOf('-') >= 0) {
|
||||
throw Error('number format error: interior "-" character');
|
||||
}
|
||||
|
||||
// Do several (8) digits each time through the loop, so as to
|
||||
// minimize the calls to the very expensive emulated div.
|
||||
var radixToPower = goog.math.Integer.fromNumber(Math.pow(radix, 8));
|
||||
|
||||
var result = goog.math.Integer.ZERO;
|
||||
for (var i = 0; i < str.length; i += 8) {
|
||||
var size = Math.min(8, str.length - i);
|
||||
var value = parseInt(str.substring(i, i + size), radix);
|
||||
if (size < 8) {
|
||||
var power = goog.math.Integer.fromNumber(Math.pow(radix, size));
|
||||
result = result.multiply(power).add(goog.math.Integer.fromNumber(value));
|
||||
} else {
|
||||
result = result.multiply(radixToPower);
|
||||
result = result.add(goog.math.Integer.fromNumber(value));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A number used repeatedly in calculations. This must appear before the first
|
||||
* call to the from* functions below.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Integer.TWO_PWR_32_DBL_ = (1 << 16) * (1 << 16);
|
||||
|
||||
|
||||
/** @type {!goog.math.Integer} */
|
||||
goog.math.Integer.ZERO = goog.math.Integer.fromInt(0);
|
||||
|
||||
|
||||
/** @type {!goog.math.Integer} */
|
||||
goog.math.Integer.ONE = goog.math.Integer.fromInt(1);
|
||||
|
||||
|
||||
/**
|
||||
* @type {!goog.math.Integer}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Integer.TWO_PWR_24_ = goog.math.Integer.fromInt(1 << 24);
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value, assuming it is a 32-bit integer.
|
||||
* @return {number} The corresponding int value.
|
||||
*/
|
||||
goog.math.Integer.prototype.toInt = function() {
|
||||
return this.bits_.length > 0 ? this.bits_[0] : this.sign_;
|
||||
};
|
||||
|
||||
|
||||
/** @return {number} The closest floating-point representation to this value. */
|
||||
goog.math.Integer.prototype.toNumber = function() {
|
||||
if (this.isNegative()) {
|
||||
return -this.negate().toNumber();
|
||||
} else {
|
||||
var val = 0;
|
||||
var pow = 1;
|
||||
for (var i = 0; i < this.bits_.length; i++) {
|
||||
val += this.getBitsUnsigned(i) * pow;
|
||||
pow *= goog.math.Integer.TWO_PWR_32_DBL_;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number=} opt_radix The radix in which the text should be written.
|
||||
* @return {string} The textual representation of this value.
|
||||
* @override
|
||||
*/
|
||||
goog.math.Integer.prototype.toString = function(opt_radix) {
|
||||
var radix = opt_radix || 10;
|
||||
if (radix < 2 || 36 < radix) {
|
||||
throw Error('radix out of range: ' + radix);
|
||||
}
|
||||
|
||||
if (this.isZero()) {
|
||||
return '0';
|
||||
} else if (this.isNegative()) {
|
||||
return '-' + this.negate().toString(radix);
|
||||
}
|
||||
|
||||
// Do several (6) digits each time through the loop, so as to
|
||||
// minimize the calls to the very expensive emulated div.
|
||||
var radixToPower = goog.math.Integer.fromNumber(Math.pow(radix, 6));
|
||||
|
||||
var rem = this;
|
||||
var result = '';
|
||||
while (true) {
|
||||
var remDiv = rem.divide(radixToPower);
|
||||
// The right shifting fixes negative values in the case when
|
||||
// intval >= 2^31; for more details see
|
||||
// https://github.com/google/closure-library/pull/498
|
||||
var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt() >>> 0;
|
||||
var digits = intval.toString(radix);
|
||||
|
||||
rem = remDiv;
|
||||
if (rem.isZero()) {
|
||||
return digits + result;
|
||||
} else {
|
||||
while (digits.length < 6) {
|
||||
digits = '0' + digits;
|
||||
}
|
||||
result = '' + digits + result;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the index-th 32-bit (signed) piece of the Integer according to
|
||||
* little-endian order (i.e., index 0 contains the smallest bits).
|
||||
* @param {number} index The index in question.
|
||||
* @return {number} The requested 32-bits as a signed number.
|
||||
*/
|
||||
goog.math.Integer.prototype.getBits = function(index) {
|
||||
if (index < 0) {
|
||||
return 0; // Allowing this simplifies bit shifting operations below...
|
||||
} else if (index < this.bits_.length) {
|
||||
return this.bits_[index];
|
||||
} else {
|
||||
return this.sign_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the index-th 32-bit piece as an unsigned number.
|
||||
* @param {number} index The index in question.
|
||||
* @return {number} The requested 32-bits as an unsigned number.
|
||||
*/
|
||||
goog.math.Integer.prototype.getBitsUnsigned = function(index) {
|
||||
var val = this.getBits(index);
|
||||
return val >= 0 ? val : goog.math.Integer.TWO_PWR_32_DBL_ + val;
|
||||
};
|
||||
|
||||
|
||||
/** @return {number} The sign bit of this number, -1 or 0. */
|
||||
goog.math.Integer.prototype.getSign = function() {
|
||||
return this.sign_;
|
||||
};
|
||||
|
||||
|
||||
/** @return {boolean} Whether this value is zero. */
|
||||
goog.math.Integer.prototype.isZero = function() {
|
||||
if (this.sign_ != 0) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < this.bits_.length; i++) {
|
||||
if (this.bits_[i] != 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/** @return {boolean} Whether this value is negative. */
|
||||
goog.math.Integer.prototype.isNegative = function() {
|
||||
return this.sign_ == -1;
|
||||
};
|
||||
|
||||
|
||||
/** @return {boolean} Whether this value is odd. */
|
||||
goog.math.Integer.prototype.isOdd = function() {
|
||||
return (this.bits_.length == 0) && (this.sign_ == -1) ||
|
||||
(this.bits_.length > 0) && ((this.bits_[0] & 1) != 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Integer} other Integer to compare against.
|
||||
* @return {boolean} Whether this Integer equals the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.equals = function(other) {
|
||||
if (this.sign_ != other.sign_) {
|
||||
return false;
|
||||
}
|
||||
var len = Math.max(this.bits_.length, other.bits_.length);
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (this.getBits(i) != other.getBits(i)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Integer} other Integer to compare against.
|
||||
* @return {boolean} Whether this Integer does not equal the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.notEquals = function(other) {
|
||||
return !this.equals(other);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Integer} other Integer to compare against.
|
||||
* @return {boolean} Whether this Integer is greater than the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.greaterThan = function(other) {
|
||||
return this.compare(other) > 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Integer} other Integer to compare against.
|
||||
* @return {boolean} Whether this Integer is greater than or equal to the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.greaterThanOrEqual = function(other) {
|
||||
return this.compare(other) >= 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Integer} other Integer to compare against.
|
||||
* @return {boolean} Whether this Integer is less than the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.lessThan = function(other) {
|
||||
return this.compare(other) < 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Integer} other Integer to compare against.
|
||||
* @return {boolean} Whether this Integer is less than or equal to the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.lessThanOrEqual = function(other) {
|
||||
return this.compare(other) <= 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compares this Integer with the given one.
|
||||
* @param {goog.math.Integer} other Integer to compare against.
|
||||
* @return {number} 0 if they are the same, 1 if the this is greater, and -1
|
||||
* if the given one is greater.
|
||||
*/
|
||||
goog.math.Integer.prototype.compare = function(other) {
|
||||
var diff = this.subtract(other);
|
||||
if (diff.isNegative()) {
|
||||
return -1;
|
||||
} else if (diff.isZero()) {
|
||||
return 0;
|
||||
} else {
|
||||
return +1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an integer with only the first numBits bits of this value, sign
|
||||
* extended from the final bit.
|
||||
* @param {number} numBits The number of bits by which to shift.
|
||||
* @return {!goog.math.Integer} The shorted integer value.
|
||||
*/
|
||||
goog.math.Integer.prototype.shorten = function(numBits) {
|
||||
var arr_index = (numBits - 1) >> 5;
|
||||
var bit_index = (numBits - 1) % 32;
|
||||
var bits = [];
|
||||
for (var i = 0; i < arr_index; i++) {
|
||||
bits[i] = this.getBits(i);
|
||||
}
|
||||
var sigBits = bit_index == 31 ? 0xFFFFFFFF : (1 << (bit_index + 1)) - 1;
|
||||
var val = this.getBits(arr_index) & sigBits;
|
||||
if (val & (1 << bit_index)) {
|
||||
val |= 0xFFFFFFFF - sigBits;
|
||||
bits[arr_index] = val;
|
||||
return new goog.math.Integer(bits, -1);
|
||||
} else {
|
||||
bits[arr_index] = val;
|
||||
return new goog.math.Integer(bits, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @return {!goog.math.Integer} The negation of this value. */
|
||||
goog.math.Integer.prototype.negate = function() {
|
||||
return this.not().add(goog.math.Integer.ONE);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the sum of this and the given Integer.
|
||||
* @param {goog.math.Integer} other The Integer to add to this.
|
||||
* @return {!goog.math.Integer} The Integer result.
|
||||
*/
|
||||
goog.math.Integer.prototype.add = function(other) {
|
||||
var len = Math.max(this.bits_.length, other.bits_.length);
|
||||
var arr = [];
|
||||
var carry = 0;
|
||||
|
||||
for (var i = 0; i <= len; i++) {
|
||||
var a1 = this.getBits(i) >>> 16;
|
||||
var a0 = this.getBits(i) & 0xFFFF;
|
||||
|
||||
var b1 = other.getBits(i) >>> 16;
|
||||
var b0 = other.getBits(i) & 0xFFFF;
|
||||
|
||||
var c0 = carry + a0 + b0;
|
||||
var c1 = (c0 >>> 16) + a1 + b1;
|
||||
carry = c1 >>> 16;
|
||||
c0 &= 0xFFFF;
|
||||
c1 &= 0xFFFF;
|
||||
arr[i] = (c1 << 16) | c0;
|
||||
}
|
||||
return goog.math.Integer.fromBits(arr);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the difference of this and the given Integer.
|
||||
* @param {goog.math.Integer} other The Integer to subtract from this.
|
||||
* @return {!goog.math.Integer} The Integer result.
|
||||
*/
|
||||
goog.math.Integer.prototype.subtract = function(other) {
|
||||
return this.add(other.negate());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the product of this and the given Integer.
|
||||
* @param {goog.math.Integer} other The Integer to multiply against this.
|
||||
* @return {!goog.math.Integer} The product of this and the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.multiply = function(other) {
|
||||
if (this.isZero()) {
|
||||
return goog.math.Integer.ZERO;
|
||||
} else if (other.isZero()) {
|
||||
return goog.math.Integer.ZERO;
|
||||
}
|
||||
|
||||
if (this.isNegative()) {
|
||||
if (other.isNegative()) {
|
||||
return this.negate().multiply(other.negate());
|
||||
} else {
|
||||
return this.negate().multiply(other).negate();
|
||||
}
|
||||
} else if (other.isNegative()) {
|
||||
return this.multiply(other.negate()).negate();
|
||||
}
|
||||
|
||||
// If both numbers are small, use float multiplication
|
||||
if (this.lessThan(goog.math.Integer.TWO_PWR_24_) &&
|
||||
other.lessThan(goog.math.Integer.TWO_PWR_24_)) {
|
||||
return goog.math.Integer.fromNumber(this.toNumber() * other.toNumber());
|
||||
}
|
||||
|
||||
// Fill in an array of 16-bit products.
|
||||
var len = this.bits_.length + other.bits_.length;
|
||||
var arr = [];
|
||||
for (var i = 0; i < 2 * len; i++) {
|
||||
arr[i] = 0;
|
||||
}
|
||||
for (var i = 0; i < this.bits_.length; i++) {
|
||||
for (var j = 0; j < other.bits_.length; j++) {
|
||||
var a1 = this.getBits(i) >>> 16;
|
||||
var a0 = this.getBits(i) & 0xFFFF;
|
||||
|
||||
var b1 = other.getBits(j) >>> 16;
|
||||
var b0 = other.getBits(j) & 0xFFFF;
|
||||
|
||||
arr[2 * i + 2 * j] += a0 * b0;
|
||||
goog.math.Integer.carry16_(arr, 2 * i + 2 * j);
|
||||
arr[2 * i + 2 * j + 1] += a1 * b0;
|
||||
goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 1);
|
||||
arr[2 * i + 2 * j + 1] += a0 * b1;
|
||||
goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 1);
|
||||
arr[2 * i + 2 * j + 2] += a1 * b1;
|
||||
goog.math.Integer.carry16_(arr, 2 * i + 2 * j + 2);
|
||||
}
|
||||
}
|
||||
|
||||
// Combine the 16-bit values into 32-bit values.
|
||||
for (var i = 0; i < len; i++) {
|
||||
arr[i] = (arr[2 * i + 1] << 16) | arr[2 * i];
|
||||
}
|
||||
for (var i = len; i < 2 * len; i++) {
|
||||
arr[i] = 0;
|
||||
}
|
||||
return new goog.math.Integer(arr, 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Carries any overflow from the given index into later entries.
|
||||
* @param {Array<number>} bits Array of 16-bit values in little-endian order.
|
||||
* @param {number} index The index in question.
|
||||
* @private
|
||||
*/
|
||||
goog.math.Integer.carry16_ = function(bits, index) {
|
||||
while ((bits[index] & 0xFFFF) != bits[index]) {
|
||||
bits[index + 1] += bits[index] >>> 16;
|
||||
bits[index] &= 0xFFFF;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns "this" Integer divided by the given one. Both "this" and the given
|
||||
* Integer MUST be positive.
|
||||
*
|
||||
* This method is only needed for very large numbers (>10^308),
|
||||
* for which the original division algorithm gets into an infinite
|
||||
* loop (see https://github.com/google/closure-library/issues/500).
|
||||
*
|
||||
* The algorithm has some possible performance enhancements (or
|
||||
* could be rewritten entirely), it's just an initial solution for
|
||||
* the issue linked above.
|
||||
*
|
||||
* @param {!goog.math.Integer} other The Integer to divide "this" by.
|
||||
* @return {!goog.math.Integer} "this" value divided by the given one.
|
||||
* @private
|
||||
*/
|
||||
goog.math.Integer.prototype.slowDivide_ = function(other) {
|
||||
if (this.isNegative() || other.isNegative()) {
|
||||
throw Error('slowDivide_ only works with positive integers.');
|
||||
}
|
||||
|
||||
var twoPower = goog.math.Integer.ONE;
|
||||
var multiple = other;
|
||||
|
||||
// First we have to figure out what the highest bit of the result
|
||||
// is, so we increase "twoPower" and "multiple" until "multiple"
|
||||
// exceeds "this".
|
||||
while (multiple.lessThanOrEqual(this)) {
|
||||
twoPower = twoPower.shiftLeft(1);
|
||||
multiple = multiple.shiftLeft(1);
|
||||
}
|
||||
|
||||
// Rewind by one power of two, giving us the highest bit of the
|
||||
// result.
|
||||
var res = twoPower.shiftRight(1);
|
||||
var total = multiple.shiftRight(1);
|
||||
|
||||
// Now we starting decreasing "multiple" and "twoPower" to find the
|
||||
// rest of the bits of the result.
|
||||
var total2;
|
||||
multiple = multiple.shiftRight(2);
|
||||
twoPower = twoPower.shiftRight(2);
|
||||
while (!multiple.isZero()) {
|
||||
// whenever we can add "multiple" to the total and not exceed
|
||||
// "this", that means we've found a 1 bit. Else we've found a 0
|
||||
// and don't need to add to the result.
|
||||
total2 = total.add(multiple);
|
||||
if (total2.lessThanOrEqual(this)) {
|
||||
res = res.add(twoPower);
|
||||
total = total2;
|
||||
}
|
||||
multiple = multiple.shiftRight(1);
|
||||
twoPower = twoPower.shiftRight(1);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Integer divided by the given one.
|
||||
* @param {!goog.math.Integer} other The Integer to divide this by.
|
||||
* @return {!goog.math.Integer} This value divided by the given one.
|
||||
*/
|
||||
goog.math.Integer.prototype.divide = function(other) {
|
||||
if (other.isZero()) {
|
||||
throw Error('division by zero');
|
||||
} else if (this.isZero()) {
|
||||
return goog.math.Integer.ZERO;
|
||||
}
|
||||
|
||||
if (this.isNegative()) {
|
||||
if (other.isNegative()) {
|
||||
return this.negate().divide(other.negate());
|
||||
} else {
|
||||
return this.negate().divide(other).negate();
|
||||
}
|
||||
} else if (other.isNegative()) {
|
||||
return this.divide(other.negate()).negate();
|
||||
}
|
||||
|
||||
// Have to degrade to slowDivide for Very Large Numbers, because
|
||||
// they're out of range for the floating-point approximation
|
||||
// technique used below.
|
||||
if (this.bits_.length > 30) {
|
||||
return this.slowDivide_(other);
|
||||
}
|
||||
|
||||
// Repeat the following until the remainder is less than other: find a
|
||||
// floating-point that approximates remainder / other *from below*, add this
|
||||
// into the result, and subtract it from the remainder. It is critical that
|
||||
// the approximate value is less than or equal to the real value so that the
|
||||
// remainder never becomes negative.
|
||||
var res = goog.math.Integer.ZERO;
|
||||
var rem = this;
|
||||
while (rem.greaterThanOrEqual(other)) {
|
||||
// Approximate the result of division. This may be a little greater or
|
||||
// smaller than the actual value.
|
||||
var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber()));
|
||||
|
||||
// We will tweak the approximate result by changing it in the 48-th digit or
|
||||
// the smallest non-fractional digit, whichever is larger.
|
||||
var log2 = Math.ceil(Math.log(approx) / Math.LN2);
|
||||
var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48);
|
||||
|
||||
// Decrease the approximation until it is smaller than the remainder. Note
|
||||
// that if it is too large, the product overflows and is negative.
|
||||
var approxRes = goog.math.Integer.fromNumber(approx);
|
||||
var approxRem = approxRes.multiply(other);
|
||||
while (approxRem.isNegative() || approxRem.greaterThan(rem)) {
|
||||
approx -= delta;
|
||||
approxRes = goog.math.Integer.fromNumber(approx);
|
||||
approxRem = approxRes.multiply(other);
|
||||
}
|
||||
|
||||
// We know the answer can't be zero... and actually, zero would cause
|
||||
// infinite recursion since we would make no progress.
|
||||
if (approxRes.isZero()) {
|
||||
approxRes = goog.math.Integer.ONE;
|
||||
}
|
||||
|
||||
res = res.add(approxRes);
|
||||
rem = rem.subtract(approxRem);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Integer modulo the given one.
|
||||
* @param {!goog.math.Integer} other The Integer by which to mod.
|
||||
* @return {!goog.math.Integer} This value modulo the given one.
|
||||
*/
|
||||
goog.math.Integer.prototype.modulo = function(other) {
|
||||
return this.subtract(this.divide(other).multiply(other));
|
||||
};
|
||||
|
||||
|
||||
/** @return {!goog.math.Integer} The bitwise-NOT of this value. */
|
||||
goog.math.Integer.prototype.not = function() {
|
||||
var len = this.bits_.length;
|
||||
var arr = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
arr[i] = ~this.bits_[i];
|
||||
}
|
||||
return new goog.math.Integer(arr, ~this.sign_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the bitwise-AND of this Integer and the given one.
|
||||
* @param {goog.math.Integer} other The Integer to AND with this.
|
||||
* @return {!goog.math.Integer} The bitwise-AND of this and the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.and = function(other) {
|
||||
var len = Math.max(this.bits_.length, other.bits_.length);
|
||||
var arr = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
arr[i] = this.getBits(i) & other.getBits(i);
|
||||
}
|
||||
return new goog.math.Integer(arr, this.sign_ & other.sign_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the bitwise-OR of this Integer and the given one.
|
||||
* @param {goog.math.Integer} other The Integer to OR with this.
|
||||
* @return {!goog.math.Integer} The bitwise-OR of this and the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.or = function(other) {
|
||||
var len = Math.max(this.bits_.length, other.bits_.length);
|
||||
var arr = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
arr[i] = this.getBits(i) | other.getBits(i);
|
||||
}
|
||||
return new goog.math.Integer(arr, this.sign_ | other.sign_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the bitwise-XOR of this Integer and the given one.
|
||||
* @param {goog.math.Integer} other The Integer to XOR with this.
|
||||
* @return {!goog.math.Integer} The bitwise-XOR of this and the other.
|
||||
*/
|
||||
goog.math.Integer.prototype.xor = function(other) {
|
||||
var len = Math.max(this.bits_.length, other.bits_.length);
|
||||
var arr = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
arr[i] = this.getBits(i) ^ other.getBits(i);
|
||||
}
|
||||
return new goog.math.Integer(arr, this.sign_ ^ other.sign_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this value with bits shifted to the left by the given amount.
|
||||
* @param {number} numBits The number of bits by which to shift.
|
||||
* @return {!goog.math.Integer} This shifted to the left by the given amount.
|
||||
*/
|
||||
goog.math.Integer.prototype.shiftLeft = function(numBits) {
|
||||
var arr_delta = numBits >> 5;
|
||||
var bit_delta = numBits % 32;
|
||||
var len = this.bits_.length + arr_delta + (bit_delta > 0 ? 1 : 0);
|
||||
var arr = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (bit_delta > 0) {
|
||||
arr[i] = (this.getBits(i - arr_delta) << bit_delta) |
|
||||
(this.getBits(i - arr_delta - 1) >>> (32 - bit_delta));
|
||||
} else {
|
||||
arr[i] = this.getBits(i - arr_delta);
|
||||
}
|
||||
}
|
||||
return new goog.math.Integer(arr, this.sign_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this value with bits shifted to the right by the given amount.
|
||||
* @param {number} numBits The number of bits by which to shift.
|
||||
* @return {!goog.math.Integer} This shifted to the right by the given amount.
|
||||
*/
|
||||
goog.math.Integer.prototype.shiftRight = function(numBits) {
|
||||
var arr_delta = numBits >> 5;
|
||||
var bit_delta = numBits % 32;
|
||||
var len = this.bits_.length - arr_delta;
|
||||
var arr = [];
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (bit_delta > 0) {
|
||||
arr[i] = (this.getBits(i + arr_delta) >>> bit_delta) |
|
||||
(this.getBits(i + arr_delta + 1) << (32 - bit_delta));
|
||||
} else {
|
||||
arr[i] = this.getBits(i + arr_delta);
|
||||
}
|
||||
}
|
||||
return new goog.math.Integer(arr, this.sign_);
|
||||
};
|
||||
843
resources/public/js/compiled/out/goog/math/long.js
Normal file
843
resources/public/js/compiled/out/goog/math/long.js
Normal file
|
|
@ -0,0 +1,843 @@
|
|||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Defines a Long class for representing a 64-bit two's-complement
|
||||
* integer value, which faithfully simulates the behavior of a Java "long". This
|
||||
* implementation is derived from LongLib in GWT.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.math.Long');
|
||||
|
||||
goog.require('goog.reflect');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a 64-bit two's-complement integer, given its low and high 32-bit
|
||||
* values as *signed* integers. See the from* functions below for more
|
||||
* convenient ways of constructing Longs.
|
||||
*
|
||||
* The internal representation of a long is the two given signed, 32-bit values.
|
||||
* We use 32-bit pieces because these are the size of integers on which
|
||||
* Javascript performs bit-operations. For operations like addition and
|
||||
* multiplication, we split each number into 16-bit pieces, which can easily be
|
||||
* multiplied within Javascript's floating-point representation without overflow
|
||||
* or change in sign.
|
||||
*
|
||||
* In the algorithms below, we frequently reduce the negative case to the
|
||||
* positive case by negating the input(s) and then post-processing the result.
|
||||
* Note that we must ALWAYS check specially whether those values are MIN_VALUE
|
||||
* (-2^63) because -MIN_VALUE == MIN_VALUE (since 2^63 cannot be represented as
|
||||
* a positive number, it overflows back into a negative). Not handling this
|
||||
* case would often result in infinite recursion.
|
||||
*
|
||||
* @param {number} low The low (signed) 32 bits of the long.
|
||||
* @param {number} high The high (signed) 32 bits of the long.
|
||||
* @struct
|
||||
* @constructor
|
||||
* @final
|
||||
*/
|
||||
goog.math.Long = function(low, high) {
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.low_ = low | 0; // force into 32 signed bits.
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.high_ = high | 0; // force into 32 signed bits.
|
||||
};
|
||||
|
||||
|
||||
// NOTE: Common constant values ZERO, ONE, NEG_ONE, etc. are defined below the
|
||||
// from* methods on which they depend.
|
||||
|
||||
|
||||
/**
|
||||
* A cache of the Long representations of small integer values.
|
||||
* @type {!Object<number, !goog.math.Long>}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Long.IntCache_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* A cache of the Long representations of common values.
|
||||
* @type {!Object<goog.math.Long.ValueCacheId_, !goog.math.Long>}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Long.valueCache_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Long representing the given (32-bit) integer value.
|
||||
* @param {number} value The 32-bit integer in question.
|
||||
* @return {!goog.math.Long} The corresponding Long value.
|
||||
*/
|
||||
goog.math.Long.fromInt = function(value) {
|
||||
if (-128 <= value && value < 128) {
|
||||
return goog.reflect.cache(goog.math.Long.IntCache_, value, function(val) {
|
||||
return new goog.math.Long(val | 0, val < 0 ? -1 : 0);
|
||||
});
|
||||
} else {
|
||||
return new goog.math.Long(value | 0, value < 0 ? -1 : 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Long representing the given value.
|
||||
* NaN will be returned as zero. Infinity is converted to max value and
|
||||
* -Infinity to min value.
|
||||
* @param {number} value The number in question.
|
||||
* @return {!goog.math.Long} The corresponding Long value.
|
||||
*/
|
||||
goog.math.Long.fromNumber = function(value) {
|
||||
if (isNaN(value)) {
|
||||
return goog.math.Long.getZero();
|
||||
} else if (value <= -goog.math.Long.TWO_PWR_63_DBL_) {
|
||||
return goog.math.Long.getMinValue();
|
||||
} else if (value + 1 >= goog.math.Long.TWO_PWR_63_DBL_) {
|
||||
return goog.math.Long.getMaxValue();
|
||||
} else if (value < 0) {
|
||||
return goog.math.Long.fromNumber(-value).negate();
|
||||
} else {
|
||||
return new goog.math.Long(
|
||||
(value % goog.math.Long.TWO_PWR_32_DBL_) | 0,
|
||||
(value / goog.math.Long.TWO_PWR_32_DBL_) | 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Long representing the 64-bit integer that comes by concatenating
|
||||
* the given high and low bits. Each is assumed to use 32 bits.
|
||||
* @param {number} lowBits The low 32-bits.
|
||||
* @param {number} highBits The high 32-bits.
|
||||
* @return {!goog.math.Long} The corresponding Long value.
|
||||
*/
|
||||
goog.math.Long.fromBits = function(lowBits, highBits) {
|
||||
return new goog.math.Long(lowBits, highBits);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a Long representation of the given string, written using the given
|
||||
* radix.
|
||||
* @param {string} str The textual representation of the Long.
|
||||
* @param {number=} opt_radix The radix in which the text is written.
|
||||
* @return {!goog.math.Long} The corresponding Long value.
|
||||
*/
|
||||
goog.math.Long.fromString = function(str, opt_radix) {
|
||||
if (str.length == 0) {
|
||||
throw Error('number format error: empty string');
|
||||
}
|
||||
|
||||
var radix = opt_radix || 10;
|
||||
if (radix < 2 || 36 < radix) {
|
||||
throw Error('radix out of range: ' + radix);
|
||||
}
|
||||
|
||||
if (str.charAt(0) == '-') {
|
||||
return goog.math.Long.fromString(str.substring(1), radix).negate();
|
||||
} else if (str.indexOf('-') >= 0) {
|
||||
throw Error('number format error: interior "-" character: ' + str);
|
||||
}
|
||||
|
||||
// Do several (8) digits each time through the loop, so as to
|
||||
// minimize the calls to the very expensive emulated div.
|
||||
var radixToPower = goog.math.Long.fromNumber(Math.pow(radix, 8));
|
||||
|
||||
var result = goog.math.Long.getZero();
|
||||
for (var i = 0; i < str.length; i += 8) {
|
||||
var size = Math.min(8, str.length - i);
|
||||
var value = parseInt(str.substring(i, i + size), radix);
|
||||
if (size < 8) {
|
||||
var power = goog.math.Long.fromNumber(Math.pow(radix, size));
|
||||
result = result.multiply(power).add(goog.math.Long.fromNumber(value));
|
||||
} else {
|
||||
result = result.multiply(radixToPower);
|
||||
result = result.add(goog.math.Long.fromNumber(value));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
// NOTE: the compiler should inline these constant values below and then remove
|
||||
// these variables, so there should be no runtime penalty for these.
|
||||
|
||||
|
||||
/**
|
||||
* Number used repeated below in calculations. This must appear before the
|
||||
* first call to any from* function below.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Long.TWO_PWR_16_DBL_ = 1 << 16;
|
||||
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Long.TWO_PWR_32_DBL_ =
|
||||
goog.math.Long.TWO_PWR_16_DBL_ * goog.math.Long.TWO_PWR_16_DBL_;
|
||||
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Long.TWO_PWR_64_DBL_ =
|
||||
goog.math.Long.TWO_PWR_32_DBL_ * goog.math.Long.TWO_PWR_32_DBL_;
|
||||
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.math.Long.TWO_PWR_63_DBL_ = goog.math.Long.TWO_PWR_64_DBL_ / 2;
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.math.Long}
|
||||
* @public
|
||||
*/
|
||||
goog.math.Long.getZero = function() {
|
||||
return goog.reflect.cache(
|
||||
goog.math.Long.valueCache_, goog.math.Long.ValueCacheId_.ZERO,
|
||||
function() { return goog.math.Long.fromInt(0); });
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.math.Long}
|
||||
* @public
|
||||
*/
|
||||
goog.math.Long.getOne = function() {
|
||||
return goog.reflect.cache(
|
||||
goog.math.Long.valueCache_, goog.math.Long.ValueCacheId_.ONE,
|
||||
function() { return goog.math.Long.fromInt(1); });
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.math.Long}
|
||||
* @public
|
||||
*/
|
||||
goog.math.Long.getNegOne = function() {
|
||||
return goog.reflect.cache(
|
||||
goog.math.Long.valueCache_, goog.math.Long.ValueCacheId_.NEG_ONE,
|
||||
function() { return goog.math.Long.fromInt(-1); });
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.math.Long}
|
||||
* @public
|
||||
*/
|
||||
goog.math.Long.getMaxValue = function() {
|
||||
return goog.reflect.cache(
|
||||
goog.math.Long.valueCache_, goog.math.Long.ValueCacheId_.MAX_VALUE,
|
||||
function() {
|
||||
return goog.math.Long.fromBits(0xFFFFFFFF | 0, 0x7FFFFFFF | 0);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.math.Long}
|
||||
* @public
|
||||
*/
|
||||
goog.math.Long.getMinValue = function() {
|
||||
return goog.reflect.cache(
|
||||
goog.math.Long.valueCache_, goog.math.Long.ValueCacheId_.MIN_VALUE,
|
||||
function() { return goog.math.Long.fromBits(0, 0x80000000 | 0); });
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.math.Long}
|
||||
* @public
|
||||
*/
|
||||
goog.math.Long.getTwoPwr24 = function() {
|
||||
return goog.reflect.cache(
|
||||
goog.math.Long.valueCache_, goog.math.Long.ValueCacheId_.TWO_PWR_24,
|
||||
function() { return goog.math.Long.fromInt(1 << 24); });
|
||||
};
|
||||
|
||||
|
||||
/** @return {number} The value, assuming it is a 32-bit integer. */
|
||||
goog.math.Long.prototype.toInt = function() {
|
||||
return this.low_;
|
||||
};
|
||||
|
||||
|
||||
/** @return {number} The closest floating-point representation to this value. */
|
||||
goog.math.Long.prototype.toNumber = function() {
|
||||
return this.high_ * goog.math.Long.TWO_PWR_32_DBL_ +
|
||||
this.getLowBitsUnsigned();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number=} opt_radix The radix in which the text should be written.
|
||||
* @return {string} The textual representation of this value.
|
||||
* @override
|
||||
*/
|
||||
goog.math.Long.prototype.toString = function(opt_radix) {
|
||||
var radix = opt_radix || 10;
|
||||
if (radix < 2 || 36 < radix) {
|
||||
throw Error('radix out of range: ' + radix);
|
||||
}
|
||||
|
||||
if (this.isZero()) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
if (this.isNegative()) {
|
||||
if (this.equals(goog.math.Long.getMinValue())) {
|
||||
// We need to change the Long value before it can be negated, so we remove
|
||||
// the bottom-most digit in this base and then recurse to do the rest.
|
||||
var radixLong = goog.math.Long.fromNumber(radix);
|
||||
var div = this.div(radixLong);
|
||||
var rem = div.multiply(radixLong).subtract(this);
|
||||
return div.toString(radix) + rem.toInt().toString(radix);
|
||||
} else {
|
||||
return '-' + this.negate().toString(radix);
|
||||
}
|
||||
}
|
||||
|
||||
// Do several (6) digits each time through the loop, so as to
|
||||
// minimize the calls to the very expensive emulated div.
|
||||
var radixToPower = goog.math.Long.fromNumber(Math.pow(radix, 6));
|
||||
|
||||
var rem = this;
|
||||
var result = '';
|
||||
while (true) {
|
||||
var remDiv = rem.div(radixToPower);
|
||||
// The right shifting fixes negative values in the case when
|
||||
// intval >= 2^31; for more details see
|
||||
// https://github.com/google/closure-library/pull/498
|
||||
var intval = rem.subtract(remDiv.multiply(radixToPower)).toInt() >>> 0;
|
||||
var digits = intval.toString(radix);
|
||||
|
||||
rem = remDiv;
|
||||
if (rem.isZero()) {
|
||||
return digits + result;
|
||||
} else {
|
||||
while (digits.length < 6) {
|
||||
digits = '0' + digits;
|
||||
}
|
||||
result = '' + digits + result;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @return {number} The high 32-bits as a signed value. */
|
||||
goog.math.Long.prototype.getHighBits = function() {
|
||||
return this.high_;
|
||||
};
|
||||
|
||||
|
||||
/** @return {number} The low 32-bits as a signed value. */
|
||||
goog.math.Long.prototype.getLowBits = function() {
|
||||
return this.low_;
|
||||
};
|
||||
|
||||
|
||||
/** @return {number} The low 32-bits as an unsigned value. */
|
||||
goog.math.Long.prototype.getLowBitsUnsigned = function() {
|
||||
return (this.low_ >= 0) ? this.low_ :
|
||||
goog.math.Long.TWO_PWR_32_DBL_ + this.low_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Returns the number of bits needed to represent the absolute
|
||||
* value of this Long.
|
||||
*/
|
||||
goog.math.Long.prototype.getNumBitsAbs = function() {
|
||||
if (this.isNegative()) {
|
||||
if (this.equals(goog.math.Long.getMinValue())) {
|
||||
return 64;
|
||||
} else {
|
||||
return this.negate().getNumBitsAbs();
|
||||
}
|
||||
} else {
|
||||
var val = this.high_ != 0 ? this.high_ : this.low_;
|
||||
for (var bit = 31; bit > 0; bit--) {
|
||||
if ((val & (1 << bit)) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this.high_ != 0 ? bit + 33 : bit + 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @return {boolean} Whether this value is zero. */
|
||||
goog.math.Long.prototype.isZero = function() {
|
||||
return this.high_ == 0 && this.low_ == 0;
|
||||
};
|
||||
|
||||
|
||||
/** @return {boolean} Whether this value is negative. */
|
||||
goog.math.Long.prototype.isNegative = function() {
|
||||
return this.high_ < 0;
|
||||
};
|
||||
|
||||
|
||||
/** @return {boolean} Whether this value is odd. */
|
||||
goog.math.Long.prototype.isOdd = function() {
|
||||
return (this.low_ & 1) == 1;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Long} other Long to compare against.
|
||||
* @return {boolean} Whether this Long equals the other.
|
||||
*/
|
||||
goog.math.Long.prototype.equals = function(other) {
|
||||
return (this.high_ == other.high_) && (this.low_ == other.low_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Long} other Long to compare against.
|
||||
* @return {boolean} Whether this Long does not equal the other.
|
||||
*/
|
||||
goog.math.Long.prototype.notEquals = function(other) {
|
||||
return (this.high_ != other.high_) || (this.low_ != other.low_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Long} other Long to compare against.
|
||||
* @return {boolean} Whether this Long is less than the other.
|
||||
*/
|
||||
goog.math.Long.prototype.lessThan = function(other) {
|
||||
return this.compare(other) < 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Long} other Long to compare against.
|
||||
* @return {boolean} Whether this Long is less than or equal to the other.
|
||||
*/
|
||||
goog.math.Long.prototype.lessThanOrEqual = function(other) {
|
||||
return this.compare(other) <= 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Long} other Long to compare against.
|
||||
* @return {boolean} Whether this Long is greater than the other.
|
||||
*/
|
||||
goog.math.Long.prototype.greaterThan = function(other) {
|
||||
return this.compare(other) > 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.math.Long} other Long to compare against.
|
||||
* @return {boolean} Whether this Long is greater than or equal to the other.
|
||||
*/
|
||||
goog.math.Long.prototype.greaterThanOrEqual = function(other) {
|
||||
return this.compare(other) >= 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compares this Long with the given one.
|
||||
* @param {goog.math.Long} other Long to compare against.
|
||||
* @return {number} 0 if they are the same, 1 if the this is greater, and -1
|
||||
* if the given one is greater.
|
||||
*/
|
||||
goog.math.Long.prototype.compare = function(other) {
|
||||
if (this.equals(other)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var thisNeg = this.isNegative();
|
||||
var otherNeg = other.isNegative();
|
||||
if (thisNeg && !otherNeg) {
|
||||
return -1;
|
||||
}
|
||||
if (!thisNeg && otherNeg) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// at this point, the signs are the same, so subtraction will not overflow
|
||||
if (this.subtract(other).isNegative()) {
|
||||
return -1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @return {!goog.math.Long} The negation of this value. */
|
||||
goog.math.Long.prototype.negate = function() {
|
||||
if (this.equals(goog.math.Long.getMinValue())) {
|
||||
return goog.math.Long.getMinValue();
|
||||
} else {
|
||||
return this.not().add(goog.math.Long.getOne());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the sum of this and the given Long.
|
||||
* @param {goog.math.Long} other Long to add to this one.
|
||||
* @return {!goog.math.Long} The sum of this and the given Long.
|
||||
*/
|
||||
goog.math.Long.prototype.add = function(other) {
|
||||
// Divide each number into 4 chunks of 16 bits, and then sum the chunks.
|
||||
|
||||
var a48 = this.high_ >>> 16;
|
||||
var a32 = this.high_ & 0xFFFF;
|
||||
var a16 = this.low_ >>> 16;
|
||||
var a00 = this.low_ & 0xFFFF;
|
||||
|
||||
var b48 = other.high_ >>> 16;
|
||||
var b32 = other.high_ & 0xFFFF;
|
||||
var b16 = other.low_ >>> 16;
|
||||
var b00 = other.low_ & 0xFFFF;
|
||||
|
||||
var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
|
||||
c00 += a00 + b00;
|
||||
c16 += c00 >>> 16;
|
||||
c00 &= 0xFFFF;
|
||||
c16 += a16 + b16;
|
||||
c32 += c16 >>> 16;
|
||||
c16 &= 0xFFFF;
|
||||
c32 += a32 + b32;
|
||||
c48 += c32 >>> 16;
|
||||
c32 &= 0xFFFF;
|
||||
c48 += a48 + b48;
|
||||
c48 &= 0xFFFF;
|
||||
return goog.math.Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the difference of this and the given Long.
|
||||
* @param {goog.math.Long} other Long to subtract from this.
|
||||
* @return {!goog.math.Long} The difference of this and the given Long.
|
||||
*/
|
||||
goog.math.Long.prototype.subtract = function(other) {
|
||||
return this.add(other.negate());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the product of this and the given long.
|
||||
* @param {goog.math.Long} other Long to multiply with this.
|
||||
* @return {!goog.math.Long} The product of this and the other.
|
||||
*/
|
||||
goog.math.Long.prototype.multiply = function(other) {
|
||||
if (this.isZero()) {
|
||||
return goog.math.Long.getZero();
|
||||
} else if (other.isZero()) {
|
||||
return goog.math.Long.getZero();
|
||||
}
|
||||
|
||||
if (this.equals(goog.math.Long.getMinValue())) {
|
||||
return other.isOdd() ? goog.math.Long.getMinValue() :
|
||||
goog.math.Long.getZero();
|
||||
} else if (other.equals(goog.math.Long.getMinValue())) {
|
||||
return this.isOdd() ? goog.math.Long.getMinValue() :
|
||||
goog.math.Long.getZero();
|
||||
}
|
||||
|
||||
if (this.isNegative()) {
|
||||
if (other.isNegative()) {
|
||||
return this.negate().multiply(other.negate());
|
||||
} else {
|
||||
return this.negate().multiply(other).negate();
|
||||
}
|
||||
} else if (other.isNegative()) {
|
||||
return this.multiply(other.negate()).negate();
|
||||
}
|
||||
|
||||
// If both longs are small, use float multiplication
|
||||
if (this.lessThan(goog.math.Long.getTwoPwr24()) &&
|
||||
other.lessThan(goog.math.Long.getTwoPwr24())) {
|
||||
return goog.math.Long.fromNumber(this.toNumber() * other.toNumber());
|
||||
}
|
||||
|
||||
// Divide each long into 4 chunks of 16 bits, and then add up 4x4 products.
|
||||
// We can skip products that would overflow.
|
||||
|
||||
var a48 = this.high_ >>> 16;
|
||||
var a32 = this.high_ & 0xFFFF;
|
||||
var a16 = this.low_ >>> 16;
|
||||
var a00 = this.low_ & 0xFFFF;
|
||||
|
||||
var b48 = other.high_ >>> 16;
|
||||
var b32 = other.high_ & 0xFFFF;
|
||||
var b16 = other.low_ >>> 16;
|
||||
var b00 = other.low_ & 0xFFFF;
|
||||
|
||||
var c48 = 0, c32 = 0, c16 = 0, c00 = 0;
|
||||
c00 += a00 * b00;
|
||||
c16 += c00 >>> 16;
|
||||
c00 &= 0xFFFF;
|
||||
c16 += a16 * b00;
|
||||
c32 += c16 >>> 16;
|
||||
c16 &= 0xFFFF;
|
||||
c16 += a00 * b16;
|
||||
c32 += c16 >>> 16;
|
||||
c16 &= 0xFFFF;
|
||||
c32 += a32 * b00;
|
||||
c48 += c32 >>> 16;
|
||||
c32 &= 0xFFFF;
|
||||
c32 += a16 * b16;
|
||||
c48 += c32 >>> 16;
|
||||
c32 &= 0xFFFF;
|
||||
c32 += a00 * b32;
|
||||
c48 += c32 >>> 16;
|
||||
c32 &= 0xFFFF;
|
||||
c48 += a48 * b00 + a32 * b16 + a16 * b32 + a00 * b48;
|
||||
c48 &= 0xFFFF;
|
||||
return goog.math.Long.fromBits((c16 << 16) | c00, (c48 << 16) | c32);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Long divided by the given one.
|
||||
* @param {goog.math.Long} other Long by which to divide.
|
||||
* @return {!goog.math.Long} This Long divided by the given one.
|
||||
*/
|
||||
goog.math.Long.prototype.div = function(other) {
|
||||
if (other.isZero()) {
|
||||
throw Error('division by zero');
|
||||
} else if (this.isZero()) {
|
||||
return goog.math.Long.getZero();
|
||||
}
|
||||
|
||||
if (this.equals(goog.math.Long.getMinValue())) {
|
||||
if (other.equals(goog.math.Long.getOne()) ||
|
||||
other.equals(goog.math.Long.getNegOne())) {
|
||||
return goog.math.Long.getMinValue(); // recall -MIN_VALUE == MIN_VALUE
|
||||
} else if (other.equals(goog.math.Long.getMinValue())) {
|
||||
return goog.math.Long.getOne();
|
||||
} else {
|
||||
// At this point, we have |other| >= 2, so |this/other| < |MIN_VALUE|.
|
||||
var halfThis = this.shiftRight(1);
|
||||
var approx = halfThis.div(other).shiftLeft(1);
|
||||
if (approx.equals(goog.math.Long.getZero())) {
|
||||
return other.isNegative() ? goog.math.Long.getOne() :
|
||||
goog.math.Long.getNegOne();
|
||||
} else {
|
||||
var rem = this.subtract(other.multiply(approx));
|
||||
var result = approx.add(rem.div(other));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
} else if (other.equals(goog.math.Long.getMinValue())) {
|
||||
return goog.math.Long.getZero();
|
||||
}
|
||||
|
||||
if (this.isNegative()) {
|
||||
if (other.isNegative()) {
|
||||
return this.negate().div(other.negate());
|
||||
} else {
|
||||
return this.negate().div(other).negate();
|
||||
}
|
||||
} else if (other.isNegative()) {
|
||||
return this.div(other.negate()).negate();
|
||||
}
|
||||
|
||||
// Repeat the following until the remainder is less than other: find a
|
||||
// floating-point that approximates remainder / other *from below*, add this
|
||||
// into the result, and subtract it from the remainder. It is critical that
|
||||
// the approximate value is less than or equal to the real value so that the
|
||||
// remainder never becomes negative.
|
||||
var res = goog.math.Long.getZero();
|
||||
var rem = this;
|
||||
while (rem.greaterThanOrEqual(other)) {
|
||||
// Approximate the result of division. This may be a little greater or
|
||||
// smaller than the actual value.
|
||||
var approx = Math.max(1, Math.floor(rem.toNumber() / other.toNumber()));
|
||||
|
||||
// We will tweak the approximate result by changing it in the 48-th digit or
|
||||
// the smallest non-fractional digit, whichever is larger.
|
||||
var log2 = Math.ceil(Math.log(approx) / Math.LN2);
|
||||
var delta = (log2 <= 48) ? 1 : Math.pow(2, log2 - 48);
|
||||
|
||||
// Decrease the approximation until it is smaller than the remainder. Note
|
||||
// that if it is too large, the product overflows and is negative.
|
||||
var approxRes = goog.math.Long.fromNumber(approx);
|
||||
var approxRem = approxRes.multiply(other);
|
||||
while (approxRem.isNegative() || approxRem.greaterThan(rem)) {
|
||||
approx -= delta;
|
||||
approxRes = goog.math.Long.fromNumber(approx);
|
||||
approxRem = approxRes.multiply(other);
|
||||
}
|
||||
|
||||
// We know the answer can't be zero... and actually, zero would cause
|
||||
// infinite recursion since we would make no progress.
|
||||
if (approxRes.isZero()) {
|
||||
approxRes = goog.math.Long.getOne();
|
||||
}
|
||||
|
||||
res = res.add(approxRes);
|
||||
rem = rem.subtract(approxRem);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Long modulo the given one.
|
||||
* @param {goog.math.Long} other Long by which to mod.
|
||||
* @return {!goog.math.Long} This Long modulo the given one.
|
||||
*/
|
||||
goog.math.Long.prototype.modulo = function(other) {
|
||||
return this.subtract(this.div(other).multiply(other));
|
||||
};
|
||||
|
||||
|
||||
/** @return {!goog.math.Long} The bitwise-NOT of this value. */
|
||||
goog.math.Long.prototype.not = function() {
|
||||
return goog.math.Long.fromBits(~this.low_, ~this.high_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the bitwise-AND of this Long and the given one.
|
||||
* @param {goog.math.Long} other The Long with which to AND.
|
||||
* @return {!goog.math.Long} The bitwise-AND of this and the other.
|
||||
*/
|
||||
goog.math.Long.prototype.and = function(other) {
|
||||
return goog.math.Long.fromBits(
|
||||
this.low_ & other.low_, this.high_ & other.high_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the bitwise-OR of this Long and the given one.
|
||||
* @param {goog.math.Long} other The Long with which to OR.
|
||||
* @return {!goog.math.Long} The bitwise-OR of this and the other.
|
||||
*/
|
||||
goog.math.Long.prototype.or = function(other) {
|
||||
return goog.math.Long.fromBits(
|
||||
this.low_ | other.low_, this.high_ | other.high_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the bitwise-XOR of this Long and the given one.
|
||||
* @param {goog.math.Long} other The Long with which to XOR.
|
||||
* @return {!goog.math.Long} The bitwise-XOR of this and the other.
|
||||
*/
|
||||
goog.math.Long.prototype.xor = function(other) {
|
||||
return goog.math.Long.fromBits(
|
||||
this.low_ ^ other.low_, this.high_ ^ other.high_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Long with bits shifted to the left by the given amount.
|
||||
* @param {number} numBits The number of bits by which to shift.
|
||||
* @return {!goog.math.Long} This shifted to the left by the given amount.
|
||||
*/
|
||||
goog.math.Long.prototype.shiftLeft = function(numBits) {
|
||||
numBits &= 63;
|
||||
if (numBits == 0) {
|
||||
return this;
|
||||
} else {
|
||||
var low = this.low_;
|
||||
if (numBits < 32) {
|
||||
var high = this.high_;
|
||||
return goog.math.Long.fromBits(
|
||||
low << numBits, (high << numBits) | (low >>> (32 - numBits)));
|
||||
} else {
|
||||
return goog.math.Long.fromBits(0, low << (numBits - 32));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Long with bits shifted to the right by the given amount.
|
||||
* The new leading bits match the current sign bit.
|
||||
* @param {number} numBits The number of bits by which to shift.
|
||||
* @return {!goog.math.Long} This shifted to the right by the given amount.
|
||||
*/
|
||||
goog.math.Long.prototype.shiftRight = function(numBits) {
|
||||
numBits &= 63;
|
||||
if (numBits == 0) {
|
||||
return this;
|
||||
} else {
|
||||
var high = this.high_;
|
||||
if (numBits < 32) {
|
||||
var low = this.low_;
|
||||
return goog.math.Long.fromBits(
|
||||
(low >>> numBits) | (high << (32 - numBits)), high >> numBits);
|
||||
} else {
|
||||
return goog.math.Long.fromBits(
|
||||
high >> (numBits - 32), high >= 0 ? 0 : -1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Long with bits shifted to the right by the given amount, with
|
||||
* zeros placed into the new leading bits.
|
||||
* @param {number} numBits The number of bits by which to shift.
|
||||
* @return {!goog.math.Long} This shifted to the right by the given amount, with
|
||||
* zeros placed into the new leading bits.
|
||||
*/
|
||||
goog.math.Long.prototype.shiftRightUnsigned = function(numBits) {
|
||||
numBits &= 63;
|
||||
if (numBits == 0) {
|
||||
return this;
|
||||
} else {
|
||||
var high = this.high_;
|
||||
if (numBits < 32) {
|
||||
var low = this.low_;
|
||||
return goog.math.Long.fromBits(
|
||||
(low >>> numBits) | (high << (32 - numBits)), high >>> numBits);
|
||||
} else if (numBits == 32) {
|
||||
return goog.math.Long.fromBits(high, 0);
|
||||
} else {
|
||||
return goog.math.Long.fromBits(high >>> (numBits - 32), 0);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {number} Ids of commonly requested Long instances.
|
||||
* @private
|
||||
*/
|
||||
goog.math.Long.ValueCacheId_ = {
|
||||
MAX_VALUE: 1,
|
||||
MIN_VALUE: 2,
|
||||
ZERO: 3,
|
||||
ONE: 4,
|
||||
NEG_ONE: 5,
|
||||
TWO_PWR_24: 6
|
||||
};
|
||||
447
resources/public/js/compiled/out/goog/math/math.js
Normal file
447
resources/public/js/compiled/out/goog/math/math.js
Normal file
|
|
@ -0,0 +1,447 @@
|
|||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Additional mathematical functions.
|
||||
*/
|
||||
|
||||
goog.provide('goog.math');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
|
||||
|
||||
/**
|
||||
* Returns a random integer greater than or equal to 0 and less than {@code a}.
|
||||
* @param {number} a The upper bound for the random integer (exclusive).
|
||||
* @return {number} A random integer N such that 0 <= N < a.
|
||||
*/
|
||||
goog.math.randomInt = function(a) {
|
||||
return Math.floor(Math.random() * a);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a random number greater than or equal to {@code a} and less than
|
||||
* {@code b}.
|
||||
* @param {number} a The lower bound for the random number (inclusive).
|
||||
* @param {number} b The upper bound for the random number (exclusive).
|
||||
* @return {number} A random number N such that a <= N < b.
|
||||
*/
|
||||
goog.math.uniformRandom = function(a, b) {
|
||||
return a + Math.random() * (b - a);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Takes a number and clamps it to within the provided bounds.
|
||||
* @param {number} value The input number.
|
||||
* @param {number} min The minimum value to return.
|
||||
* @param {number} max The maximum value to return.
|
||||
* @return {number} The input number if it is within bounds, or the nearest
|
||||
* number within the bounds.
|
||||
*/
|
||||
goog.math.clamp = function(value, min, max) {
|
||||
return Math.min(Math.max(value, min), max);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The % operator in JavaScript returns the remainder of a / b, but differs from
|
||||
* some other languages in that the result will have the same sign as the
|
||||
* dividend. For example, -1 % 8 == -1, whereas in some other languages
|
||||
* (such as Python) the result would be 7. This function emulates the more
|
||||
* correct modulo behavior, which is useful for certain applications such as
|
||||
* calculating an offset index in a circular list.
|
||||
*
|
||||
* @param {number} a The dividend.
|
||||
* @param {number} b The divisor.
|
||||
* @return {number} a % b where the result is between 0 and b (either 0 <= x < b
|
||||
* or b < x <= 0, depending on the sign of b).
|
||||
*/
|
||||
goog.math.modulo = function(a, b) {
|
||||
var r = a % b;
|
||||
// If r and b differ in sign, add b to wrap the result to the correct sign.
|
||||
return (r * b < 0) ? r + b : r;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs linear interpolation between values a and b. Returns the value
|
||||
* between a and b proportional to x (when x is between 0 and 1. When x is
|
||||
* outside this range, the return value is a linear extrapolation).
|
||||
* @param {number} a A number.
|
||||
* @param {number} b A number.
|
||||
* @param {number} x The proportion between a and b.
|
||||
* @return {number} The interpolated value between a and b.
|
||||
*/
|
||||
goog.math.lerp = function(a, b, x) {
|
||||
return a + x * (b - a);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tests whether the two values are equal to each other, within a certain
|
||||
* tolerance to adjust for floating point errors.
|
||||
* @param {number} a A number.
|
||||
* @param {number} b A number.
|
||||
* @param {number=} opt_tolerance Optional tolerance range. Defaults
|
||||
* to 0.000001. If specified, should be greater than 0.
|
||||
* @return {boolean} Whether {@code a} and {@code b} are nearly equal.
|
||||
*/
|
||||
goog.math.nearlyEquals = function(a, b, opt_tolerance) {
|
||||
return Math.abs(a - b) <= (opt_tolerance || 0.000001);
|
||||
};
|
||||
|
||||
|
||||
// TODO(user): Rename to normalizeAngle, retaining old name as deprecated
|
||||
// alias.
|
||||
/**
|
||||
* Normalizes an angle to be in range [0-360). Angles outside this range will
|
||||
* be normalized to be the equivalent angle with that range.
|
||||
* @param {number} angle Angle in degrees.
|
||||
* @return {number} Standardized angle.
|
||||
*/
|
||||
goog.math.standardAngle = function(angle) {
|
||||
return goog.math.modulo(angle, 360);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Normalizes an angle to be in range [0-2*PI). Angles outside this range will
|
||||
* be normalized to be the equivalent angle with that range.
|
||||
* @param {number} angle Angle in radians.
|
||||
* @return {number} Standardized angle.
|
||||
*/
|
||||
goog.math.standardAngleInRadians = function(angle) {
|
||||
return goog.math.modulo(angle, 2 * Math.PI);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts degrees to radians.
|
||||
* @param {number} angleDegrees Angle in degrees.
|
||||
* @return {number} Angle in radians.
|
||||
*/
|
||||
goog.math.toRadians = function(angleDegrees) {
|
||||
return angleDegrees * Math.PI / 180;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts radians to degrees.
|
||||
* @param {number} angleRadians Angle in radians.
|
||||
* @return {number} Angle in degrees.
|
||||
*/
|
||||
goog.math.toDegrees = function(angleRadians) {
|
||||
return angleRadians * 180 / Math.PI;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* For a given angle and radius, finds the X portion of the offset.
|
||||
* @param {number} degrees Angle in degrees (zero points in +X direction).
|
||||
* @param {number} radius Radius.
|
||||
* @return {number} The x-distance for the angle and radius.
|
||||
*/
|
||||
goog.math.angleDx = function(degrees, radius) {
|
||||
return radius * Math.cos(goog.math.toRadians(degrees));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* For a given angle and radius, finds the Y portion of the offset.
|
||||
* @param {number} degrees Angle in degrees (zero points in +X direction).
|
||||
* @param {number} radius Radius.
|
||||
* @return {number} The y-distance for the angle and radius.
|
||||
*/
|
||||
goog.math.angleDy = function(degrees, radius) {
|
||||
return radius * Math.sin(goog.math.toRadians(degrees));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Computes the angle between two points (x1,y1) and (x2,y2).
|
||||
* Angle zero points in the +X direction, 90 degrees points in the +Y
|
||||
* direction (down) and from there we grow clockwise towards 360 degrees.
|
||||
* @param {number} x1 x of first point.
|
||||
* @param {number} y1 y of first point.
|
||||
* @param {number} x2 x of second point.
|
||||
* @param {number} y2 y of second point.
|
||||
* @return {number} Standardized angle in degrees of the vector from
|
||||
* x1,y1 to x2,y2.
|
||||
*/
|
||||
goog.math.angle = function(x1, y1, x2, y2) {
|
||||
return goog.math.standardAngle(
|
||||
goog.math.toDegrees(Math.atan2(y2 - y1, x2 - x1)));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Computes the difference between startAngle and endAngle (angles in degrees).
|
||||
* @param {number} startAngle Start angle in degrees.
|
||||
* @param {number} endAngle End angle in degrees.
|
||||
* @return {number} The number of degrees that when added to
|
||||
* startAngle will result in endAngle. Positive numbers mean that the
|
||||
* direction is clockwise. Negative numbers indicate a counter-clockwise
|
||||
* direction.
|
||||
* The shortest route (clockwise vs counter-clockwise) between the angles
|
||||
* is used.
|
||||
* When the difference is 180 degrees, the function returns 180 (not -180)
|
||||
* angleDifference(30, 40) is 10, and angleDifference(40, 30) is -10.
|
||||
* angleDifference(350, 10) is 20, and angleDifference(10, 350) is -20.
|
||||
*/
|
||||
goog.math.angleDifference = function(startAngle, endAngle) {
|
||||
var d =
|
||||
goog.math.standardAngle(endAngle) - goog.math.standardAngle(startAngle);
|
||||
if (d > 180) {
|
||||
d = d - 360;
|
||||
} else if (d <= -180) {
|
||||
d = 360 + d;
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the sign of a number as per the "sign" or "signum" function.
|
||||
* @param {number} x The number to take the sign of.
|
||||
* @return {number} -1 when negative, 1 when positive, 0 when 0. Preserves
|
||||
* signed zeros and NaN.
|
||||
*/
|
||||
goog.math.sign = Math.sign || function(x) {
|
||||
if (x > 0) {
|
||||
return 1;
|
||||
}
|
||||
if (x < 0) {
|
||||
return -1;
|
||||
}
|
||||
return x; // Preserves signed zeros and NaN.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* JavaScript implementation of Longest Common Subsequence problem.
|
||||
* http://en.wikipedia.org/wiki/Longest_common_subsequence
|
||||
*
|
||||
* Returns the longest possible array that is subarray of both of given arrays.
|
||||
*
|
||||
* @param {IArrayLike<S>} array1 First array of objects.
|
||||
* @param {IArrayLike<T>} array2 Second array of objects.
|
||||
* @param {Function=} opt_compareFn Function that acts as a custom comparator
|
||||
* for the array ojects. Function should return true if objects are equal,
|
||||
* otherwise false.
|
||||
* @param {Function=} opt_collectorFn Function used to decide what to return
|
||||
* as a result subsequence. It accepts 2 arguments: index of common element
|
||||
* in the first array and index in the second. The default function returns
|
||||
* element from the first array.
|
||||
* @return {!Array<S|T>} A list of objects that are common to both arrays
|
||||
* such that there is no common subsequence with size greater than the
|
||||
* length of the list.
|
||||
* @template S,T
|
||||
*/
|
||||
goog.math.longestCommonSubsequence = function(
|
||||
array1, array2, opt_compareFn, opt_collectorFn) {
|
||||
|
||||
var compare = opt_compareFn || function(a, b) { return a == b; };
|
||||
|
||||
var collect = opt_collectorFn || function(i1, i2) { return array1[i1]; };
|
||||
|
||||
var length1 = array1.length;
|
||||
var length2 = array2.length;
|
||||
|
||||
var arr = [];
|
||||
for (var i = 0; i < length1 + 1; i++) {
|
||||
arr[i] = [];
|
||||
arr[i][0] = 0;
|
||||
}
|
||||
|
||||
for (var j = 0; j < length2 + 1; j++) {
|
||||
arr[0][j] = 0;
|
||||
}
|
||||
|
||||
for (i = 1; i <= length1; i++) {
|
||||
for (j = 1; j <= length2; j++) {
|
||||
if (compare(array1[i - 1], array2[j - 1])) {
|
||||
arr[i][j] = arr[i - 1][j - 1] + 1;
|
||||
} else {
|
||||
arr[i][j] = Math.max(arr[i - 1][j], arr[i][j - 1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Backtracking
|
||||
var result = [];
|
||||
var i = length1, j = length2;
|
||||
while (i > 0 && j > 0) {
|
||||
if (compare(array1[i - 1], array2[j - 1])) {
|
||||
result.unshift(collect(i - 1, j - 1));
|
||||
i--;
|
||||
j--;
|
||||
} else {
|
||||
if (arr[i - 1][j] > arr[i][j - 1]) {
|
||||
i--;
|
||||
} else {
|
||||
j--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the sum of the arguments.
|
||||
* @param {...number} var_args Numbers to add.
|
||||
* @return {number} The sum of the arguments (0 if no arguments were provided,
|
||||
* {@code NaN} if any of the arguments is not a valid number).
|
||||
*/
|
||||
goog.math.sum = function(var_args) {
|
||||
return /** @type {number} */ (
|
||||
goog.array.reduce(
|
||||
arguments, function(sum, value) { return sum + value; }, 0));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the arithmetic mean of the arguments.
|
||||
* @param {...number} var_args Numbers to average.
|
||||
* @return {number} The average of the arguments ({@code NaN} if no arguments
|
||||
* were provided or any of the arguments is not a valid number).
|
||||
*/
|
||||
goog.math.average = function(var_args) {
|
||||
return goog.math.sum.apply(null, arguments) / arguments.length;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the unbiased sample variance of the arguments. For a definition,
|
||||
* see e.g. http://en.wikipedia.org/wiki/Variance
|
||||
* @param {...number} var_args Number samples to analyze.
|
||||
* @return {number} The unbiased sample variance of the arguments (0 if fewer
|
||||
* than two samples were provided, or {@code NaN} if any of the samples is
|
||||
* not a valid number).
|
||||
*/
|
||||
goog.math.sampleVariance = function(var_args) {
|
||||
var sampleSize = arguments.length;
|
||||
if (sampleSize < 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var mean = goog.math.average.apply(null, arguments);
|
||||
var variance =
|
||||
goog.math.sum.apply(null, goog.array.map(arguments, function(val) {
|
||||
return Math.pow(val - mean, 2);
|
||||
})) / (sampleSize - 1);
|
||||
|
||||
return variance;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the sample standard deviation of the arguments. For a definition of
|
||||
* sample standard deviation, see e.g.
|
||||
* http://en.wikipedia.org/wiki/Standard_deviation
|
||||
* @param {...number} var_args Number samples to analyze.
|
||||
* @return {number} The sample standard deviation of the arguments (0 if fewer
|
||||
* than two samples were provided, or {@code NaN} if any of the samples is
|
||||
* not a valid number).
|
||||
*/
|
||||
goog.math.standardDeviation = function(var_args) {
|
||||
return Math.sqrt(goog.math.sampleVariance.apply(null, arguments));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the supplied number represents an integer, i.e. that is has
|
||||
* no fractional component. No range-checking is performed on the number.
|
||||
* @param {number} num The number to test.
|
||||
* @return {boolean} Whether {@code num} is an integer.
|
||||
*/
|
||||
goog.math.isInt = function(num) {
|
||||
return isFinite(num) && num % 1 == 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the supplied number is finite and not NaN.
|
||||
* @param {number} num The number to test.
|
||||
* @return {boolean} Whether {@code num} is a finite number.
|
||||
*/
|
||||
goog.math.isFiniteNumber = function(num) {
|
||||
return isFinite(num) && !isNaN(num);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} num The number to test.
|
||||
* @return {boolean} Whether it is negative zero.
|
||||
*/
|
||||
goog.math.isNegativeZero = function(num) {
|
||||
return num == 0 && 1 / num < 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the precise value of floor(log10(num)).
|
||||
* Simpler implementations didn't work because of floating point rounding
|
||||
* errors. For example
|
||||
* <ul>
|
||||
* <li>Math.floor(Math.log(num) / Math.LN10) is off by one for num == 1e+3.
|
||||
* <li>Math.floor(Math.log(num) * Math.LOG10E) is off by one for num == 1e+15.
|
||||
* <li>Math.floor(Math.log10(num)) is off by one for num == 1e+15 - 1.
|
||||
* </ul>
|
||||
* @param {number} num A floating point number.
|
||||
* @return {number} Its logarithm to base 10 rounded down to the nearest
|
||||
* integer if num > 0. -Infinity if num == 0. NaN if num < 0.
|
||||
*/
|
||||
goog.math.log10Floor = function(num) {
|
||||
if (num > 0) {
|
||||
var x = Math.round(Math.log(num) * Math.LOG10E);
|
||||
return x - (parseFloat('1e' + x) > num ? 1 : 0);
|
||||
}
|
||||
return num == 0 ? -Infinity : NaN;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A tweaked variant of {@code Math.floor} which tolerates if the passed number
|
||||
* is infinitesimally smaller than the closest integer. It often happens with
|
||||
* the results of floating point calculations because of the finite precision
|
||||
* of the intermediate results. For example {@code Math.floor(Math.log(1000) /
|
||||
* Math.LN10) == 2}, not 3 as one would expect.
|
||||
* @param {number} num A number.
|
||||
* @param {number=} opt_epsilon An infinitesimally small positive number, the
|
||||
* rounding error to tolerate.
|
||||
* @return {number} The largest integer less than or equal to {@code num}.
|
||||
*/
|
||||
goog.math.safeFloor = function(num, opt_epsilon) {
|
||||
goog.asserts.assert(!goog.isDef(opt_epsilon) || opt_epsilon > 0);
|
||||
return Math.floor(num + (opt_epsilon || 2e-15));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A tweaked variant of {@code Math.ceil}. See {@code goog.math.safeFloor} for
|
||||
* details.
|
||||
* @param {number} num A number.
|
||||
* @param {number=} opt_epsilon An infinitesimally small positive number, the
|
||||
* rounding error to tolerate.
|
||||
* @return {number} The smallest integer greater than or equal to {@code num}.
|
||||
*/
|
||||
goog.math.safeCeil = function(num, opt_epsilon) {
|
||||
goog.asserts.assert(!goog.isDef(opt_epsilon) || opt_epsilon > 0);
|
||||
return Math.ceil(num - (opt_epsilon || 2e-15));
|
||||
};
|
||||
227
resources/public/js/compiled/out/goog/math/size.js
Normal file
227
resources/public/js/compiled/out/goog/math/size.js
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A utility class for representing two-dimensional sizes.
|
||||
* @author brenneman@google.com (Shawn Brenneman)
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.math.Size');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class for representing sizes consisting of a width and height. Undefined
|
||||
* width and height support is deprecated and results in compiler warning.
|
||||
* @param {number} width Width.
|
||||
* @param {number} height Height.
|
||||
* @struct
|
||||
* @constructor
|
||||
*/
|
||||
goog.math.Size = function(width, height) {
|
||||
/**
|
||||
* Width
|
||||
* @type {number}
|
||||
*/
|
||||
this.width = width;
|
||||
|
||||
/**
|
||||
* Height
|
||||
* @type {number}
|
||||
*/
|
||||
this.height = height;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compares sizes for equality.
|
||||
* @param {goog.math.Size} a A Size.
|
||||
* @param {goog.math.Size} b A Size.
|
||||
* @return {boolean} True iff the sizes have equal widths and equal
|
||||
* heights, or if both are null.
|
||||
*/
|
||||
goog.math.Size.equals = function(a, b) {
|
||||
if (a == b) {
|
||||
return true;
|
||||
}
|
||||
if (!a || !b) {
|
||||
return false;
|
||||
}
|
||||
return a.width == b.width && a.height == b.height;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!goog.math.Size} A new copy of the Size.
|
||||
*/
|
||||
goog.math.Size.prototype.clone = function() {
|
||||
return new goog.math.Size(this.width, this.height);
|
||||
};
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Returns a nice string representing size.
|
||||
* @return {string} In the form (50 x 73).
|
||||
* @override
|
||||
*/
|
||||
goog.math.Size.prototype.toString = function() {
|
||||
return '(' + this.width + ' x ' + this.height + ')';
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The longer of the two dimensions in the size.
|
||||
*/
|
||||
goog.math.Size.prototype.getLongest = function() {
|
||||
return Math.max(this.width, this.height);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The shorter of the two dimensions in the size.
|
||||
*/
|
||||
goog.math.Size.prototype.getShortest = function() {
|
||||
return Math.min(this.width, this.height);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The area of the size (width * height).
|
||||
*/
|
||||
goog.math.Size.prototype.area = function() {
|
||||
return this.width * this.height;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The perimeter of the size (width + height) * 2.
|
||||
*/
|
||||
goog.math.Size.prototype.perimeter = function() {
|
||||
return (this.width + this.height) * 2;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The ratio of the size's width to its height.
|
||||
*/
|
||||
goog.math.Size.prototype.aspectRatio = function() {
|
||||
return this.width / this.height;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} True if the size has zero area, false if both dimensions
|
||||
* are non-zero numbers.
|
||||
*/
|
||||
goog.math.Size.prototype.isEmpty = function() {
|
||||
return !this.area();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the width and height parameters upward to integer values.
|
||||
* @return {!goog.math.Size} This size with ceil'd components.
|
||||
*/
|
||||
goog.math.Size.prototype.ceil = function() {
|
||||
this.width = Math.ceil(this.width);
|
||||
this.height = Math.ceil(this.height);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!goog.math.Size} target The target size.
|
||||
* @return {boolean} True if this Size is the same size or smaller than the
|
||||
* target size in both dimensions.
|
||||
*/
|
||||
goog.math.Size.prototype.fitsInside = function(target) {
|
||||
return this.width <= target.width && this.height <= target.height;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clamps the width and height parameters downward to integer values.
|
||||
* @return {!goog.math.Size} This size with floored components.
|
||||
*/
|
||||
goog.math.Size.prototype.floor = function() {
|
||||
this.width = Math.floor(this.width);
|
||||
this.height = Math.floor(this.height);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Rounds the width and height parameters to integer values.
|
||||
* @return {!goog.math.Size} This size with rounded components.
|
||||
*/
|
||||
goog.math.Size.prototype.round = function() {
|
||||
this.width = Math.round(this.width);
|
||||
this.height = Math.round(this.height);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Scales this size by the given scale factors. The width and height are scaled
|
||||
* by {@code sx} and {@code opt_sy} respectively. If {@code opt_sy} is not
|
||||
* given, then {@code sx} is used for both the width and height.
|
||||
* @param {number} sx The scale factor to use for the width.
|
||||
* @param {number=} opt_sy The scale factor to use for the height.
|
||||
* @return {!goog.math.Size} This Size object after scaling.
|
||||
*/
|
||||
goog.math.Size.prototype.scale = function(sx, opt_sy) {
|
||||
var sy = goog.isNumber(opt_sy) ? opt_sy : sx;
|
||||
this.width *= sx;
|
||||
this.height *= sy;
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Uniformly scales the size to perfectly cover the dimensions of a given size.
|
||||
* If the size is already larger than the target, it will be scaled down to the
|
||||
* minimum size at which it still covers the entire target. The original aspect
|
||||
* ratio will be preserved.
|
||||
*
|
||||
* This function assumes that both Sizes contain strictly positive dimensions.
|
||||
* @param {!goog.math.Size} target The target size.
|
||||
* @return {!goog.math.Size} This Size object, after optional scaling.
|
||||
*/
|
||||
goog.math.Size.prototype.scaleToCover = function(target) {
|
||||
var s = this.aspectRatio() <= target.aspectRatio() ?
|
||||
target.width / this.width :
|
||||
target.height / this.height;
|
||||
|
||||
return this.scale(s);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Uniformly scales the size to fit inside the dimensions of a given size. The
|
||||
* original aspect ratio will be preserved.
|
||||
*
|
||||
* This function assumes that both Sizes contain strictly positive dimensions.
|
||||
* @param {!goog.math.Size} target The target size.
|
||||
* @return {!goog.math.Size} This Size object, after optional scaling.
|
||||
*/
|
||||
goog.math.Size.prototype.scaleToFit = function(target) {
|
||||
var s = this.aspectRatio() > target.aspectRatio() ?
|
||||
target.width / this.width :
|
||||
target.height / this.height;
|
||||
|
||||
return this.scale(s);
|
||||
};
|
||||
946
resources/public/js/compiled/out/goog/mochikit/async/deferred.js
Normal file
946
resources/public/js/compiled/out/goog/mochikit/async/deferred.js
Normal file
|
|
@ -0,0 +1,946 @@
|
|||
// Copyright 2007 Bob Ippolito. All Rights Reserved.
|
||||
// Modifications Copyright 2009 The Closure Library Authors. All Rights
|
||||
// Reserved.
|
||||
|
||||
/**
|
||||
* @license Portions of this code are from MochiKit, received by
|
||||
* The Closure Authors under the MIT license. All other code is Copyright
|
||||
* 2005-2009 The Closure Authors. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @fileoverview Classes for tracking asynchronous operations and handling the
|
||||
* results. The Deferred object here is patterned after the Deferred object in
|
||||
* the Twisted python networking framework.
|
||||
*
|
||||
* See: http://twistedmatrix.com/projects/core/documentation/howto/defer.html
|
||||
*
|
||||
* Based on the Dojo code which in turn is based on the MochiKit code.
|
||||
*
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @author brenneman@google.com (Shawn Brenneman)
|
||||
*/
|
||||
|
||||
goog.provide('goog.async.Deferred');
|
||||
goog.provide('goog.async.Deferred.AlreadyCalledError');
|
||||
goog.provide('goog.async.Deferred.CanceledError');
|
||||
|
||||
goog.require('goog.Promise');
|
||||
goog.require('goog.Thenable');
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.debug.Error');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A Deferred represents the result of an asynchronous operation. A Deferred
|
||||
* instance has no result when it is created, and is "fired" (given an initial
|
||||
* result) by calling {@code callback} or {@code errback}.
|
||||
*
|
||||
* Once fired, the result is passed through a sequence of callback functions
|
||||
* registered with {@code addCallback} or {@code addErrback}. The functions may
|
||||
* mutate the result before it is passed to the next function in the sequence.
|
||||
*
|
||||
* Callbacks and errbacks may be added at any time, including after the Deferred
|
||||
* has been "fired". If there are no pending actions in the execution sequence
|
||||
* of a fired Deferred, any new callback functions will be called with the last
|
||||
* computed result. Adding a callback function is the only way to access the
|
||||
* result of the Deferred.
|
||||
*
|
||||
* If a Deferred operation is canceled, an optional user-provided cancellation
|
||||
* function is invoked which may perform any special cleanup, followed by firing
|
||||
* the Deferred's errback sequence with a {@code CanceledError}. If the
|
||||
* Deferred has already fired, cancellation is ignored.
|
||||
*
|
||||
* Deferreds may be templated to a specific type they produce using generics
|
||||
* with syntax such as:
|
||||
*
|
||||
* /** @type {goog.async.Deferred<string>} *\
|
||||
* var d = new goog.async.Deferred();
|
||||
* // Compiler can infer that foo is a string.
|
||||
* d.addCallback(function(foo) {...});
|
||||
* d.callback('string'); // Checked to be passed a string
|
||||
*
|
||||
* Since deferreds are often used to produce different values across a chain,
|
||||
* the type information is not propagated across chains, but rather only
|
||||
* associated with specifically cast objects.
|
||||
*
|
||||
* @param {Function=} opt_onCancelFunction A function that will be called if the
|
||||
* Deferred is canceled. If provided, this function runs before the
|
||||
* Deferred is fired with a {@code CanceledError}.
|
||||
* @param {Object=} opt_defaultScope The default object context to call
|
||||
* callbacks and errbacks in.
|
||||
* @constructor
|
||||
* @implements {goog.Thenable<VALUE>}
|
||||
* @template VALUE
|
||||
*/
|
||||
goog.async.Deferred = function(opt_onCancelFunction, opt_defaultScope) {
|
||||
/**
|
||||
* Entries in the sequence are arrays containing a callback, an errback, and
|
||||
* an optional scope. The callback or errback in an entry may be null.
|
||||
* @type {!Array<!Array>}
|
||||
* @private
|
||||
*/
|
||||
this.sequence_ = [];
|
||||
|
||||
/**
|
||||
* Optional function that will be called if the Deferred is canceled.
|
||||
* @type {Function|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.onCancelFunction_ = opt_onCancelFunction;
|
||||
|
||||
/**
|
||||
* The default scope to execute callbacks and errbacks in.
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
this.defaultScope_ = opt_defaultScope || null;
|
||||
|
||||
/**
|
||||
* Whether the Deferred has been fired.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.fired_ = false;
|
||||
|
||||
/**
|
||||
* Whether the last result in the execution sequence was an error.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.hadError_ = false;
|
||||
|
||||
/**
|
||||
* The current Deferred result, updated as callbacks and errbacks are
|
||||
* executed.
|
||||
* @type {*}
|
||||
* @private
|
||||
*/
|
||||
this.result_ = undefined;
|
||||
|
||||
/**
|
||||
* Whether the Deferred is blocked waiting on another Deferred to fire. If a
|
||||
* callback or errback returns a Deferred as a result, the execution sequence
|
||||
* is blocked until that Deferred result becomes available.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.blocked_ = false;
|
||||
|
||||
/**
|
||||
* Whether this Deferred is blocking execution of another Deferred. If this
|
||||
* instance was returned as a result in another Deferred's execution
|
||||
* sequence,that other Deferred becomes blocked until this instance's
|
||||
* execution sequence completes. No additional callbacks may be added to a
|
||||
* Deferred once it is blocking another instance.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.blocking_ = false;
|
||||
|
||||
/**
|
||||
* Whether the Deferred has been canceled without having a custom cancel
|
||||
* function.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
this.silentlyCanceled_ = false;
|
||||
|
||||
/**
|
||||
* If an error is thrown during Deferred execution with no errback to catch
|
||||
* it, the error is rethrown after a timeout. Reporting the error after a
|
||||
* timeout allows execution to continue in the calling context (empty when
|
||||
* no error is scheduled).
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.unhandledErrorId_ = 0;
|
||||
|
||||
/**
|
||||
* If this Deferred was created by branch(), this will be the "parent"
|
||||
* Deferred.
|
||||
* @type {goog.async.Deferred}
|
||||
* @private
|
||||
*/
|
||||
this.parent_ = null;
|
||||
|
||||
/**
|
||||
* The number of Deferred objects that have been branched off this one. This
|
||||
* will be decremented whenever a branch is fired or canceled.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.branches_ = 0;
|
||||
|
||||
if (goog.async.Deferred.LONG_STACK_TRACES) {
|
||||
/**
|
||||
* Holds the stack trace at time of deferred creation if the JS engine
|
||||
* provides the Error.captureStackTrace API.
|
||||
* @private {?string}
|
||||
*/
|
||||
this.constructorStack_ = null;
|
||||
if (Error.captureStackTrace) {
|
||||
var target = { stack: '' };
|
||||
Error.captureStackTrace(target, goog.async.Deferred);
|
||||
// Check if Error.captureStackTrace worked. It fails in gjstest.
|
||||
if (typeof target.stack == 'string') {
|
||||
// Remove first line and force stringify to prevent memory leak due to
|
||||
// holding on to actual stack frames.
|
||||
this.constructorStack_ = target.stack.replace(/^[^\n]*\n/, '');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether unhandled errors should always get rethrown to the
|
||||
* global scope. Defaults to the value of goog.DEBUG.
|
||||
*/
|
||||
goog.define('goog.async.Deferred.STRICT_ERRORS', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether to attempt to make stack traces long. Defaults to
|
||||
* the value of goog.DEBUG.
|
||||
*/
|
||||
goog.define('goog.async.Deferred.LONG_STACK_TRACES', false);
|
||||
|
||||
|
||||
/**
|
||||
* Cancels a Deferred that has not yet been fired, or is blocked on another
|
||||
* deferred operation. If this Deferred is waiting for a blocking Deferred to
|
||||
* fire, the blocking Deferred will also be canceled.
|
||||
*
|
||||
* If this Deferred was created by calling branch() on a parent Deferred with
|
||||
* opt_propagateCancel set to true, the parent may also be canceled. If
|
||||
* opt_deepCancel is set, cancel() will be called on the parent (as well as any
|
||||
* other ancestors if the parent is also a branch). If one or more branches were
|
||||
* created with opt_propagateCancel set to true, the parent will be canceled if
|
||||
* cancel() is called on all of those branches.
|
||||
*
|
||||
* @param {boolean=} opt_deepCancel If true, cancels this Deferred's parent even
|
||||
* if cancel() hasn't been called on some of the parent's branches. Has no
|
||||
* effect on a branch without opt_propagateCancel set to true.
|
||||
*/
|
||||
goog.async.Deferred.prototype.cancel = function(opt_deepCancel) {
|
||||
if (!this.hasFired()) {
|
||||
if (this.parent_) {
|
||||
// Get rid of the parent reference before potentially running the parent's
|
||||
// canceler function to ensure that this cancellation isn't
|
||||
// double-counted.
|
||||
var parent = this.parent_;
|
||||
delete this.parent_;
|
||||
if (opt_deepCancel) {
|
||||
parent.cancel(opt_deepCancel);
|
||||
} else {
|
||||
parent.branchCancel_();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.onCancelFunction_) {
|
||||
// Call in user-specified scope.
|
||||
this.onCancelFunction_.call(this.defaultScope_, this);
|
||||
} else {
|
||||
this.silentlyCanceled_ = true;
|
||||
}
|
||||
if (!this.hasFired()) {
|
||||
this.errback(new goog.async.Deferred.CanceledError(this));
|
||||
}
|
||||
} else if (this.result_ instanceof goog.async.Deferred) {
|
||||
this.result_.cancel();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle a single branch being canceled. Once all branches are canceled, this
|
||||
* Deferred will be canceled as well.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
goog.async.Deferred.prototype.branchCancel_ = function() {
|
||||
this.branches_--;
|
||||
if (this.branches_ <= 0) {
|
||||
this.cancel();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called after a blocking Deferred fires. Unblocks this Deferred and resumes
|
||||
* its execution sequence.
|
||||
*
|
||||
* @param {boolean} isSuccess Whether the result is a success or an error.
|
||||
* @param {*} res The result of the blocking Deferred.
|
||||
* @private
|
||||
*/
|
||||
goog.async.Deferred.prototype.continue_ = function(isSuccess, res) {
|
||||
this.blocked_ = false;
|
||||
this.updateResult_(isSuccess, res);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Updates the current result based on the success or failure of the last action
|
||||
* in the execution sequence.
|
||||
*
|
||||
* @param {boolean} isSuccess Whether the new result is a success or an error.
|
||||
* @param {*} res The result.
|
||||
* @private
|
||||
*/
|
||||
goog.async.Deferred.prototype.updateResult_ = function(isSuccess, res) {
|
||||
this.fired_ = true;
|
||||
this.result_ = res;
|
||||
this.hadError_ = !isSuccess;
|
||||
this.fire_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Verifies that the Deferred has not yet been fired.
|
||||
*
|
||||
* @private
|
||||
* @throws {Error} If this has already been fired.
|
||||
*/
|
||||
goog.async.Deferred.prototype.check_ = function() {
|
||||
if (this.hasFired()) {
|
||||
if (!this.silentlyCanceled_) {
|
||||
throw new goog.async.Deferred.AlreadyCalledError(this);
|
||||
}
|
||||
this.silentlyCanceled_ = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fire the execution sequence for this Deferred by passing the starting result
|
||||
* to the first registered callback.
|
||||
* @param {VALUE=} opt_result The starting result.
|
||||
*/
|
||||
goog.async.Deferred.prototype.callback = function(opt_result) {
|
||||
this.check_();
|
||||
this.assertNotDeferred_(opt_result);
|
||||
this.updateResult_(true /* isSuccess */, opt_result);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fire the execution sequence for this Deferred by passing the starting error
|
||||
* result to the first registered errback.
|
||||
* @param {*=} opt_result The starting error.
|
||||
*/
|
||||
goog.async.Deferred.prototype.errback = function(opt_result) {
|
||||
this.check_();
|
||||
this.assertNotDeferred_(opt_result);
|
||||
this.makeStackTraceLong_(opt_result);
|
||||
this.updateResult_(false /* isSuccess */, opt_result);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Attempt to make the error's stack trace be long in that it contains the
|
||||
* stack trace from the point where the deferred was created on top of the
|
||||
* current stack trace to give additional context.
|
||||
* @param {*} error
|
||||
* @private
|
||||
*/
|
||||
goog.async.Deferred.prototype.makeStackTraceLong_ = function(error) {
|
||||
if (!goog.async.Deferred.LONG_STACK_TRACES) {
|
||||
return;
|
||||
}
|
||||
if (this.constructorStack_ && goog.isObject(error) && error.stack &&
|
||||
// Stack looks like it was system generated. See
|
||||
// https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
|
||||
(/^[^\n]+(\n [^\n]+)+/).test(error.stack)) {
|
||||
error.stack = error.stack + '\nDEFERRED OPERATION:\n' +
|
||||
this.constructorStack_;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Asserts that an object is not a Deferred.
|
||||
* @param {*} obj The object to test.
|
||||
* @throws {Error} Throws an exception if the object is a Deferred.
|
||||
* @private
|
||||
*/
|
||||
goog.async.Deferred.prototype.assertNotDeferred_ = function(obj) {
|
||||
goog.asserts.assert(
|
||||
!(obj instanceof goog.async.Deferred),
|
||||
'An execution sequence may not be initiated with a blocking Deferred.');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Register a callback function to be called with a successful result. If no
|
||||
* value is returned by the callback function, the result value is unchanged. If
|
||||
* a new value is returned, it becomes the Deferred result and will be passed to
|
||||
* the next callback in the execution sequence.
|
||||
*
|
||||
* If the function throws an error, the error becomes the new result and will be
|
||||
* passed to the next errback in the execution chain.
|
||||
*
|
||||
* If the function returns a Deferred, the execution sequence will be blocked
|
||||
* until that Deferred fires. Its result will be passed to the next callback (or
|
||||
* errback if it is an error result) in this Deferred's execution sequence.
|
||||
*
|
||||
* @param {!function(this:T,VALUE):?} cb The function to be called with a
|
||||
* successful result.
|
||||
* @param {T=} opt_scope An optional scope to call the callback in.
|
||||
* @return {!goog.async.Deferred} This Deferred.
|
||||
* @template T
|
||||
*/
|
||||
goog.async.Deferred.prototype.addCallback = function(cb, opt_scope) {
|
||||
return this.addCallbacks(cb, null, opt_scope);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Register a callback function to be called with an error result. If no value
|
||||
* is returned by the function, the error result is unchanged. If a new error
|
||||
* value is returned or thrown, that error becomes the Deferred result and will
|
||||
* be passed to the next errback in the execution sequence.
|
||||
*
|
||||
* If the errback function handles the error by returning a non-error value,
|
||||
* that result will be passed to the next normal callback in the sequence.
|
||||
*
|
||||
* If the function returns a Deferred, the execution sequence will be blocked
|
||||
* until that Deferred fires. Its result will be passed to the next callback (or
|
||||
* errback if it is an error result) in this Deferred's execution sequence.
|
||||
*
|
||||
* @param {!function(this:T,?):?} eb The function to be called on an
|
||||
* unsuccessful result.
|
||||
* @param {T=} opt_scope An optional scope to call the errback in.
|
||||
* @return {!goog.async.Deferred<VALUE>} This Deferred.
|
||||
* @template T
|
||||
*/
|
||||
goog.async.Deferred.prototype.addErrback = function(eb, opt_scope) {
|
||||
return this.addCallbacks(null, eb, opt_scope);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Registers one function as both a callback and errback.
|
||||
*
|
||||
* @param {!function(this:T,?):?} f The function to be called on any result.
|
||||
* @param {T=} opt_scope An optional scope to call the function in.
|
||||
* @return {!goog.async.Deferred} This Deferred.
|
||||
* @template T
|
||||
*/
|
||||
goog.async.Deferred.prototype.addBoth = function(f, opt_scope) {
|
||||
return this.addCallbacks(f, f, opt_scope);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Like addBoth, but propagates uncaught exceptions in the errback.
|
||||
*
|
||||
* @param {function(this:T,?):?} f The function to be called on any result.
|
||||
* @param {T=} opt_scope An optional scope to call the function in.
|
||||
* @return {!goog.async.Deferred<VALUE>} This Deferred.
|
||||
* @template T
|
||||
*/
|
||||
goog.async.Deferred.prototype.addFinally = function(f, opt_scope) {
|
||||
var self = this;
|
||||
return this.addCallbacks(f, function(err) {
|
||||
var result = f.call(self, err);
|
||||
if (!goog.isDef(result)) {
|
||||
throw err;
|
||||
}
|
||||
return result;
|
||||
}, opt_scope);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Registers a callback function and an errback function at the same position
|
||||
* in the execution sequence. Only one of these functions will execute,
|
||||
* depending on the error state during the execution sequence.
|
||||
*
|
||||
* NOTE: This is not equivalent to {@code def.addCallback().addErrback()}! If
|
||||
* the callback is invoked, the errback will be skipped, and vice versa.
|
||||
*
|
||||
* @param {?(function(this:T,VALUE):?)} cb The function to be called on a
|
||||
* successful result.
|
||||
* @param {?(function(this:T,?):?)} eb The function to be called on an
|
||||
* unsuccessful result.
|
||||
* @param {T=} opt_scope An optional scope to call the functions in.
|
||||
* @return {!goog.async.Deferred} This Deferred.
|
||||
* @template T
|
||||
*/
|
||||
goog.async.Deferred.prototype.addCallbacks = function(cb, eb, opt_scope) {
|
||||
goog.asserts.assert(!this.blocking_, 'Blocking Deferreds can not be re-used');
|
||||
this.sequence_.push([cb, eb, opt_scope]);
|
||||
if (this.hasFired()) {
|
||||
this.fire_();
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Implements {@see goog.Thenable} for seamless integration with
|
||||
* {@see goog.Promise}.
|
||||
* Deferred results are mutable and may represent multiple values over
|
||||
* their lifetime. Calling {@code then} on a Deferred returns a Promise
|
||||
* with the result of the Deferred at that point in its callback chain.
|
||||
* Note that if the Deferred result is never mutated, and only
|
||||
* {@code then} calls are made, the Deferred will behave like a Promise.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
goog.async.Deferred.prototype.then = function(opt_onFulfilled, opt_onRejected,
|
||||
opt_context) {
|
||||
var resolve, reject;
|
||||
var promise = new goog.Promise(function(res, rej) {
|
||||
// Copying resolvers to outer scope, so that they are available when the
|
||||
// deferred callback fires (which may be synchronous).
|
||||
resolve = res;
|
||||
reject = rej;
|
||||
});
|
||||
this.addCallbacks(resolve, function(reason) {
|
||||
if (reason instanceof goog.async.Deferred.CanceledError) {
|
||||
promise.cancel();
|
||||
} else {
|
||||
reject(reason);
|
||||
}
|
||||
});
|
||||
return promise.then(opt_onFulfilled, opt_onRejected, opt_context);
|
||||
};
|
||||
goog.Thenable.addImplementation(goog.async.Deferred);
|
||||
|
||||
|
||||
/**
|
||||
* Links another Deferred to the end of this Deferred's execution sequence. The
|
||||
* result of this execution sequence will be passed as the starting result for
|
||||
* the chained Deferred, invoking either its first callback or errback.
|
||||
*
|
||||
* @param {!goog.async.Deferred} otherDeferred The Deferred to chain.
|
||||
* @return {!goog.async.Deferred} This Deferred.
|
||||
*/
|
||||
goog.async.Deferred.prototype.chainDeferred = function(otherDeferred) {
|
||||
this.addCallbacks(
|
||||
otherDeferred.callback, otherDeferred.errback, otherDeferred);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Makes this Deferred wait for another Deferred's execution sequence to
|
||||
* complete before continuing.
|
||||
*
|
||||
* This is equivalent to adding a callback that returns {@code otherDeferred},
|
||||
* but doesn't prevent additional callbacks from being added to
|
||||
* {@code otherDeferred}.
|
||||
*
|
||||
* @param {!goog.async.Deferred|!goog.Thenable} otherDeferred The Deferred
|
||||
* to wait for.
|
||||
* @return {!goog.async.Deferred} This Deferred.
|
||||
*/
|
||||
goog.async.Deferred.prototype.awaitDeferred = function(otherDeferred) {
|
||||
if (!(otherDeferred instanceof goog.async.Deferred)) {
|
||||
// The Thenable case.
|
||||
return this.addCallback(function() {
|
||||
return otherDeferred;
|
||||
});
|
||||
}
|
||||
return this.addCallback(goog.bind(otherDeferred.branch, otherDeferred));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a branch off this Deferred's execution sequence, and returns it as a
|
||||
* new Deferred. The branched Deferred's starting result will be shared with the
|
||||
* parent at the point of the branch, even if further callbacks are added to the
|
||||
* parent.
|
||||
*
|
||||
* All branches at the same stage in the execution sequence will receive the
|
||||
* same starting value.
|
||||
*
|
||||
* @param {boolean=} opt_propagateCancel If cancel() is called on every child
|
||||
* branch created with opt_propagateCancel, the parent will be canceled as
|
||||
* well.
|
||||
* @return {!goog.async.Deferred<VALUE>} A Deferred that will be started with
|
||||
* the computed result from this stage in the execution sequence.
|
||||
*/
|
||||
goog.async.Deferred.prototype.branch = function(opt_propagateCancel) {
|
||||
var d = new goog.async.Deferred();
|
||||
this.chainDeferred(d);
|
||||
if (opt_propagateCancel) {
|
||||
d.parent_ = this;
|
||||
this.branches_++;
|
||||
}
|
||||
return d;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the execution sequence has been started on this
|
||||
* Deferred by invoking {@code callback} or {@code errback}.
|
||||
*/
|
||||
goog.async.Deferred.prototype.hasFired = function() {
|
||||
return this.fired_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {*} res The latest result in the execution sequence.
|
||||
* @return {boolean} Whether the current result is an error that should cause
|
||||
* the next errback to fire. May be overridden by subclasses to handle
|
||||
* special error types.
|
||||
* @protected
|
||||
*/
|
||||
goog.async.Deferred.prototype.isError = function(res) {
|
||||
return res instanceof Error;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether an errback exists in the remaining sequence.
|
||||
* @private
|
||||
*/
|
||||
goog.async.Deferred.prototype.hasErrback_ = function() {
|
||||
return goog.array.some(this.sequence_, function(sequenceRow) {
|
||||
// The errback is the second element in the array.
|
||||
return goog.isFunction(sequenceRow[1]);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Exhausts the execution sequence while a result is available. The result may
|
||||
* be modified by callbacks or errbacks, and execution will block if the
|
||||
* returned result is an incomplete Deferred.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
goog.async.Deferred.prototype.fire_ = function() {
|
||||
if (this.unhandledErrorId_ && this.hasFired() && this.hasErrback_()) {
|
||||
// It is possible to add errbacks after the Deferred has fired. If a new
|
||||
// errback is added immediately after the Deferred encountered an unhandled
|
||||
// error, but before that error is rethrown, the error is unscheduled.
|
||||
goog.async.Deferred.unscheduleError_(this.unhandledErrorId_);
|
||||
this.unhandledErrorId_ = 0;
|
||||
}
|
||||
|
||||
if (this.parent_) {
|
||||
this.parent_.branches_--;
|
||||
delete this.parent_;
|
||||
}
|
||||
|
||||
var res = this.result_;
|
||||
var unhandledException = false;
|
||||
var isNewlyBlocked = false;
|
||||
|
||||
while (this.sequence_.length && !this.blocked_) {
|
||||
var sequenceEntry = this.sequence_.shift();
|
||||
|
||||
var callback = sequenceEntry[0];
|
||||
var errback = sequenceEntry[1];
|
||||
var scope = sequenceEntry[2];
|
||||
|
||||
var f = this.hadError_ ? errback : callback;
|
||||
if (f) {
|
||||
/** @preserveTry */
|
||||
try {
|
||||
var ret = f.call(scope || this.defaultScope_, res);
|
||||
|
||||
// If no result, then use previous result.
|
||||
if (goog.isDef(ret)) {
|
||||
// Bubble up the error as long as the return value hasn't changed.
|
||||
this.hadError_ = this.hadError_ && (ret == res || this.isError(ret));
|
||||
this.result_ = res = ret;
|
||||
}
|
||||
|
||||
if (goog.Thenable.isImplementedBy(res) ||
|
||||
(typeof goog.global['Promise'] === 'function' &&
|
||||
res instanceof goog.global['Promise'])) {
|
||||
isNewlyBlocked = true;
|
||||
this.blocked_ = true;
|
||||
}
|
||||
|
||||
} catch (ex) {
|
||||
res = ex;
|
||||
this.hadError_ = true;
|
||||
this.makeStackTraceLong_(res);
|
||||
|
||||
if (!this.hasErrback_()) {
|
||||
// If an error is thrown with no additional errbacks in the queue,
|
||||
// prepare to rethrow the error.
|
||||
unhandledException = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.result_ = res;
|
||||
|
||||
if (isNewlyBlocked) {
|
||||
var onCallback = goog.bind(this.continue_, this, true /* isSuccess */);
|
||||
var onErrback = goog.bind(this.continue_, this, false /* isSuccess */);
|
||||
|
||||
if (res instanceof goog.async.Deferred) {
|
||||
res.addCallbacks(onCallback, onErrback);
|
||||
res.blocking_ = true;
|
||||
} else {
|
||||
res.then(onCallback, onErrback);
|
||||
}
|
||||
} else if (goog.async.Deferred.STRICT_ERRORS && this.isError(res) &&
|
||||
!(res instanceof goog.async.Deferred.CanceledError)) {
|
||||
this.hadError_ = true;
|
||||
unhandledException = true;
|
||||
}
|
||||
|
||||
if (unhandledException) {
|
||||
// Rethrow the unhandled error after a timeout. Execution will continue, but
|
||||
// the error will be seen by global handlers and the user. The throw will
|
||||
// be canceled if another errback is appended before the timeout executes.
|
||||
// The error's original stack trace is preserved where available.
|
||||
this.unhandledErrorId_ = goog.async.Deferred.scheduleError_(res);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a Deferred that has an initial result.
|
||||
*
|
||||
* @param {*=} opt_result The result.
|
||||
* @return {!goog.async.Deferred} The new Deferred.
|
||||
*/
|
||||
goog.async.Deferred.succeed = function(opt_result) {
|
||||
var d = new goog.async.Deferred();
|
||||
d.callback(opt_result);
|
||||
return d;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a Deferred that fires when the given promise resolves.
|
||||
* Use only during migration to Promises.
|
||||
*
|
||||
* @param {!goog.Promise<T>} promise
|
||||
* @return {!goog.async.Deferred<T>} The new Deferred.
|
||||
* @template T
|
||||
*/
|
||||
goog.async.Deferred.fromPromise = function(promise) {
|
||||
var d = new goog.async.Deferred();
|
||||
d.callback();
|
||||
d.addCallback(function() {
|
||||
return promise;
|
||||
});
|
||||
return d;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a Deferred that has an initial error result.
|
||||
*
|
||||
* @param {*} res The error result.
|
||||
* @return {!goog.async.Deferred} The new Deferred.
|
||||
*/
|
||||
goog.async.Deferred.fail = function(res) {
|
||||
var d = new goog.async.Deferred();
|
||||
d.errback(res);
|
||||
return d;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a Deferred that has already been canceled.
|
||||
*
|
||||
* @return {!goog.async.Deferred} The new Deferred.
|
||||
*/
|
||||
goog.async.Deferred.canceled = function() {
|
||||
var d = new goog.async.Deferred();
|
||||
d.cancel();
|
||||
return d;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Normalizes values that may or may not be Deferreds.
|
||||
*
|
||||
* If the input value is a Deferred, the Deferred is branched (so the original
|
||||
* execution sequence is not modified) and the input callback added to the new
|
||||
* branch. The branch is returned to the caller.
|
||||
*
|
||||
* If the input value is not a Deferred, the callback will be executed
|
||||
* immediately and an already firing Deferred will be returned to the caller.
|
||||
*
|
||||
* In the following (contrived) example, if <code>isImmediate</code> is true
|
||||
* then 3 is alerted immediately, otherwise 6 is alerted after a 2-second delay.
|
||||
*
|
||||
* <pre>
|
||||
* var value;
|
||||
* if (isImmediate) {
|
||||
* value = 3;
|
||||
* } else {
|
||||
* value = new goog.async.Deferred();
|
||||
* setTimeout(function() { value.callback(6); }, 2000);
|
||||
* }
|
||||
*
|
||||
* var d = goog.async.Deferred.when(value, alert);
|
||||
* </pre>
|
||||
*
|
||||
* @param {*} value Deferred or normal value to pass to the callback.
|
||||
* @param {!function(this:T, ?):?} callback The callback to execute.
|
||||
* @param {T=} opt_scope An optional scope to call the callback in.
|
||||
* @return {!goog.async.Deferred} A new Deferred that will call the input
|
||||
* callback with the input value.
|
||||
* @template T
|
||||
*/
|
||||
goog.async.Deferred.when = function(value, callback, opt_scope) {
|
||||
if (value instanceof goog.async.Deferred) {
|
||||
return value.branch(true).addCallback(callback, opt_scope);
|
||||
} else {
|
||||
return goog.async.Deferred.succeed(value).addCallback(callback, opt_scope);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* An error sub class that is used when a Deferred has already been called.
|
||||
* @param {!goog.async.Deferred} deferred The Deferred.
|
||||
*
|
||||
* @constructor
|
||||
* @extends {goog.debug.Error}
|
||||
*/
|
||||
goog.async.Deferred.AlreadyCalledError = function(deferred) {
|
||||
goog.debug.Error.call(this);
|
||||
|
||||
/**
|
||||
* The Deferred that raised this error.
|
||||
* @type {goog.async.Deferred}
|
||||
*/
|
||||
this.deferred = deferred;
|
||||
};
|
||||
goog.inherits(goog.async.Deferred.AlreadyCalledError, goog.debug.Error);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.async.Deferred.AlreadyCalledError.prototype.message =
|
||||
'Deferred has already fired';
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.async.Deferred.AlreadyCalledError.prototype.name = 'AlreadyCalledError';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* An error sub class that is used when a Deferred is canceled.
|
||||
*
|
||||
* @param {!goog.async.Deferred} deferred The Deferred object.
|
||||
* @constructor
|
||||
* @extends {goog.debug.Error}
|
||||
*/
|
||||
goog.async.Deferred.CanceledError = function(deferred) {
|
||||
goog.debug.Error.call(this);
|
||||
|
||||
/**
|
||||
* The Deferred that raised this error.
|
||||
* @type {goog.async.Deferred}
|
||||
*/
|
||||
this.deferred = deferred;
|
||||
};
|
||||
goog.inherits(goog.async.Deferred.CanceledError, goog.debug.Error);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.async.Deferred.CanceledError.prototype.message = 'Deferred was canceled';
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.async.Deferred.CanceledError.prototype.name = 'CanceledError';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper around errors that are scheduled to be thrown by failing deferreds
|
||||
* after a timeout.
|
||||
*
|
||||
* @param {*} error Error from a failing deferred.
|
||||
* @constructor
|
||||
* @final
|
||||
* @private
|
||||
* @struct
|
||||
*/
|
||||
goog.async.Deferred.Error_ = function(error) {
|
||||
/** @const @private {number} */
|
||||
this.id_ = goog.global.setTimeout(goog.bind(this.throwError, this), 0);
|
||||
|
||||
/** @const @private {*} */
|
||||
this.error_ = error;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Actually throws the error and removes it from the list of pending
|
||||
* deferred errors.
|
||||
*/
|
||||
goog.async.Deferred.Error_.prototype.throwError = function() {
|
||||
goog.asserts.assert(goog.async.Deferred.errorMap_[this.id_],
|
||||
'Cannot throw an error that is not scheduled.');
|
||||
delete goog.async.Deferred.errorMap_[this.id_];
|
||||
throw this.error_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Resets the error throw timer.
|
||||
*/
|
||||
goog.async.Deferred.Error_.prototype.resetTimer = function() {
|
||||
goog.global.clearTimeout(this.id_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Map of unhandled errors scheduled to be rethrown in a future timestep.
|
||||
* @private {!Object<(number|string), goog.async.Deferred.Error_>}
|
||||
*/
|
||||
goog.async.Deferred.errorMap_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Schedules an error to be thrown after a delay.
|
||||
* @param {*} error Error from a failing deferred.
|
||||
* @return {number} Id of the error.
|
||||
* @private
|
||||
*/
|
||||
goog.async.Deferred.scheduleError_ = function(error) {
|
||||
var deferredError = new goog.async.Deferred.Error_(error);
|
||||
goog.async.Deferred.errorMap_[deferredError.id_] = deferredError;
|
||||
return deferredError.id_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Unschedules an error from being thrown.
|
||||
* @param {number} id Id of the deferred error to unschedule.
|
||||
* @private
|
||||
*/
|
||||
goog.async.Deferred.unscheduleError_ = function(id) {
|
||||
var error = goog.async.Deferred.errorMap_[id];
|
||||
if (error) {
|
||||
error.resetTimer();
|
||||
delete goog.async.Deferred.errorMap_[id];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Asserts that there are no pending deferred errors. If there are any
|
||||
* scheduled errors, one will be thrown immediately to make this function fail.
|
||||
*/
|
||||
goog.async.Deferred.assertNoErrors = function() {
|
||||
var map = goog.async.Deferred.errorMap_;
|
||||
for (var key in map) {
|
||||
var error = map[key];
|
||||
error.resetTimer();
|
||||
error.throwError();
|
||||
}
|
||||
};
|
||||
389
resources/public/js/compiled/out/goog/net/jsloader.js
Normal file
389
resources/public/js/compiled/out/goog/net/jsloader.js
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A utility to load JavaScript files via DOM script tags.
|
||||
* Refactored from goog.net.Jsonp. Works cross-domain.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.net.jsloader');
|
||||
goog.provide('goog.net.jsloader.Error');
|
||||
goog.provide('goog.net.jsloader.ErrorCode');
|
||||
goog.provide('goog.net.jsloader.Options');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.async.Deferred');
|
||||
goog.require('goog.debug.Error');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.object');
|
||||
|
||||
|
||||
/**
|
||||
* The name of the property of goog.global under which the JavaScript
|
||||
* verification object is stored by the loaded script.
|
||||
* @private {string}
|
||||
*/
|
||||
goog.net.jsloader.GLOBAL_VERIFY_OBJS_ = 'closure_verification';
|
||||
|
||||
|
||||
/**
|
||||
* The default length of time, in milliseconds, we are prepared to wait for a
|
||||
* load request to complete.
|
||||
* @type {number}
|
||||
*/
|
||||
goog.net.jsloader.DEFAULT_TIMEOUT = 5000;
|
||||
|
||||
|
||||
/**
|
||||
* Optional parameters for goog.net.jsloader.send.
|
||||
* timeout: The length of time, in milliseconds, we are prepared to wait
|
||||
* for a load request to complete, or 0 or negative for no timeout. Default
|
||||
* is 5 seconds.
|
||||
* document: The HTML document under which to load the JavaScript. Default is
|
||||
* the current document.
|
||||
* cleanupWhenDone: If true clean up the script tag after script completes to
|
||||
* load. This is important if you just want to read data from the JavaScript
|
||||
* and then throw it away. Default is false.
|
||||
* attributes: Additional attributes to set on the script tag.
|
||||
*
|
||||
* @typedef {{
|
||||
* timeout: (number|undefined),
|
||||
* document: (HTMLDocument|undefined),
|
||||
* cleanupWhenDone: (boolean|undefined),
|
||||
* attributes: (!Object<string, string>|undefined)
|
||||
* }}
|
||||
*/
|
||||
goog.net.jsloader.Options;
|
||||
|
||||
|
||||
/**
|
||||
* Scripts (URIs) waiting to be loaded.
|
||||
* @private {!Array<string>}
|
||||
*/
|
||||
goog.net.jsloader.scriptsToLoad_ = [];
|
||||
|
||||
|
||||
/**
|
||||
* The deferred result of loading the URIs in scriptsToLoad_.
|
||||
* We need to return this to a caller that wants to load URIs while
|
||||
* a deferred is already working on them.
|
||||
* @private {!goog.async.Deferred<null>}
|
||||
*/
|
||||
goog.net.jsloader.scriptLoadingDeferred_;
|
||||
|
||||
|
||||
/**
|
||||
* Loads and evaluates the JavaScript files at the specified URIs, guaranteeing
|
||||
* the order of script loads.
|
||||
*
|
||||
* Because we have to load the scripts in serial (load script 1, exec script 1,
|
||||
* load script 2, exec script 2, and so on), this will be slower than doing
|
||||
* the network fetches in parallel.
|
||||
*
|
||||
* If you need to load a large number of scripts but dependency order doesn't
|
||||
* matter, you should just call goog.net.jsloader.load N times.
|
||||
*
|
||||
* If you need to load a large number of scripts on the same domain,
|
||||
* you may want to use goog.module.ModuleLoader.
|
||||
*
|
||||
* @param {Array<string>} uris The URIs to load.
|
||||
* @param {goog.net.jsloader.Options=} opt_options Optional parameters. See
|
||||
* goog.net.jsloader.options documentation for details.
|
||||
* @return {!goog.async.Deferred} The deferred result, that may be used to add
|
||||
* callbacks
|
||||
*/
|
||||
goog.net.jsloader.loadMany = function(uris, opt_options) {
|
||||
// Loading the scripts in serial introduces asynchronosity into the flow.
|
||||
// Therefore, there are race conditions where client A can kick off the load
|
||||
// sequence for client B, even though client A's scripts haven't all been
|
||||
// loaded yet.
|
||||
//
|
||||
// To work around this issue, all module loads share a queue.
|
||||
if (!uris.length) {
|
||||
return goog.async.Deferred.succeed(null);
|
||||
}
|
||||
|
||||
var isAnotherModuleLoading = goog.net.jsloader.scriptsToLoad_.length;
|
||||
goog.array.extend(goog.net.jsloader.scriptsToLoad_, uris);
|
||||
if (isAnotherModuleLoading) {
|
||||
// jsloader is still loading some other scripts.
|
||||
// In order to prevent the race condition noted above, we just add
|
||||
// these URIs to the end of the scripts' queue and return the deferred
|
||||
// result of the ongoing script load, so the caller knows when they
|
||||
// finish loading.
|
||||
return goog.net.jsloader.scriptLoadingDeferred_;
|
||||
}
|
||||
|
||||
uris = goog.net.jsloader.scriptsToLoad_;
|
||||
var popAndLoadNextScript = function() {
|
||||
var uri = uris.shift();
|
||||
var deferred = goog.net.jsloader.load(uri, opt_options);
|
||||
if (uris.length) {
|
||||
deferred.addBoth(popAndLoadNextScript);
|
||||
}
|
||||
return deferred;
|
||||
};
|
||||
goog.net.jsloader.scriptLoadingDeferred_ = popAndLoadNextScript();
|
||||
return goog.net.jsloader.scriptLoadingDeferred_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Loads and evaluates a JavaScript file.
|
||||
* When the script loads, a user callback is called.
|
||||
* It is the client's responsibility to verify that the script ran successfully.
|
||||
*
|
||||
* @param {string} uri The URI of the JavaScript.
|
||||
* @param {goog.net.jsloader.Options=} opt_options Optional parameters. See
|
||||
* goog.net.jsloader.Options documentation for details.
|
||||
* @return {!goog.async.Deferred} The deferred result, that may be used to add
|
||||
* callbacks and/or cancel the transmission.
|
||||
* The error callback will be called with a single goog.net.jsloader.Error
|
||||
* parameter.
|
||||
*/
|
||||
goog.net.jsloader.load = function(uri, opt_options) {
|
||||
var options = opt_options || {};
|
||||
var doc = options.document || document;
|
||||
|
||||
var script = goog.dom.createElement(goog.dom.TagName.SCRIPT);
|
||||
var request = {script_: script, timeout_: undefined};
|
||||
var deferred = new goog.async.Deferred(goog.net.jsloader.cancel_, request);
|
||||
|
||||
// Set a timeout.
|
||||
var timeout = null;
|
||||
var timeoutDuration = goog.isDefAndNotNull(options.timeout) ?
|
||||
options.timeout :
|
||||
goog.net.jsloader.DEFAULT_TIMEOUT;
|
||||
if (timeoutDuration > 0) {
|
||||
timeout = window.setTimeout(function() {
|
||||
goog.net.jsloader.cleanup_(script, true);
|
||||
deferred.errback(
|
||||
new goog.net.jsloader.Error(
|
||||
goog.net.jsloader.ErrorCode.TIMEOUT,
|
||||
'Timeout reached for loading script ' + uri));
|
||||
}, timeoutDuration);
|
||||
request.timeout_ = timeout;
|
||||
}
|
||||
|
||||
// Hang the user callback to be called when the script completes to load.
|
||||
// NOTE(user): This callback will be called in IE even upon error. In any
|
||||
// case it is the client's responsibility to verify that the script ran
|
||||
// successfully.
|
||||
script.onload = script.onreadystatechange = function() {
|
||||
if (!script.readyState || script.readyState == 'loaded' ||
|
||||
script.readyState == 'complete') {
|
||||
var removeScriptNode = options.cleanupWhenDone || false;
|
||||
goog.net.jsloader.cleanup_(script, removeScriptNode, timeout);
|
||||
deferred.callback(null);
|
||||
}
|
||||
};
|
||||
|
||||
// Add an error callback.
|
||||
// NOTE(user): Not supported in IE.
|
||||
script.onerror = function() {
|
||||
goog.net.jsloader.cleanup_(script, true, timeout);
|
||||
deferred.errback(
|
||||
new goog.net.jsloader.Error(
|
||||
goog.net.jsloader.ErrorCode.LOAD_ERROR,
|
||||
'Error while loading script ' + uri));
|
||||
};
|
||||
|
||||
var properties = options.attributes || {};
|
||||
goog.object.extend(properties, {
|
||||
'type': 'text/javascript',
|
||||
'charset': 'UTF-8',
|
||||
// NOTE(user): Safari never loads the script if we don't set
|
||||
// the src attribute before appending.
|
||||
'src': uri
|
||||
});
|
||||
goog.dom.setProperties(script, properties);
|
||||
var scriptParent = goog.net.jsloader.getScriptParentElement_(doc);
|
||||
scriptParent.appendChild(script);
|
||||
|
||||
return deferred;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Loads a JavaScript file and verifies it was evaluated successfully, using a
|
||||
* verification object.
|
||||
* The verification object is set by the loaded JavaScript at the end of the
|
||||
* script.
|
||||
* We verify this object was set and return its value in the success callback.
|
||||
* If the object is not defined we trigger an error callback.
|
||||
*
|
||||
* @param {string} uri The URI of the JavaScript.
|
||||
* @param {string} verificationObjName The name of the verification object that
|
||||
* the loaded script should set.
|
||||
* @param {goog.net.jsloader.Options} options Optional parameters. See
|
||||
* goog.net.jsloader.Options documentation for details.
|
||||
* @return {!goog.async.Deferred} The deferred result, that may be used to add
|
||||
* callbacks and/or cancel the transmission.
|
||||
* The success callback will be called with a single parameter containing
|
||||
* the value of the verification object.
|
||||
* The error callback will be called with a single goog.net.jsloader.Error
|
||||
* parameter.
|
||||
*/
|
||||
goog.net.jsloader.loadAndVerify = function(uri, verificationObjName, options) {
|
||||
// Define the global objects variable.
|
||||
if (!goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_]) {
|
||||
goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_] = {};
|
||||
}
|
||||
var verifyObjs = goog.global[goog.net.jsloader.GLOBAL_VERIFY_OBJS_];
|
||||
|
||||
// Verify that the expected object does not exist yet.
|
||||
if (goog.isDef(verifyObjs[verificationObjName])) {
|
||||
// TODO(user): Error or reset variable?
|
||||
return goog.async.Deferred.fail(
|
||||
new goog.net.jsloader.Error(
|
||||
goog.net.jsloader.ErrorCode.VERIFY_OBJECT_ALREADY_EXISTS,
|
||||
'Verification object ' + verificationObjName +
|
||||
' already defined.'));
|
||||
}
|
||||
|
||||
// Send request to load the JavaScript.
|
||||
var sendDeferred = goog.net.jsloader.load(uri, options);
|
||||
|
||||
// Create a deferred object wrapping the send result.
|
||||
var deferred =
|
||||
new goog.async.Deferred(goog.bind(sendDeferred.cancel, sendDeferred));
|
||||
|
||||
// Call user back with object that was set by the script.
|
||||
sendDeferred.addCallback(function() {
|
||||
var result = verifyObjs[verificationObjName];
|
||||
if (goog.isDef(result)) {
|
||||
deferred.callback(result);
|
||||
delete verifyObjs[verificationObjName];
|
||||
} else {
|
||||
// Error: script was not loaded properly.
|
||||
deferred.errback(
|
||||
new goog.net.jsloader.Error(
|
||||
goog.net.jsloader.ErrorCode.VERIFY_ERROR, 'Script ' + uri +
|
||||
' loaded, but verification object ' + verificationObjName +
|
||||
' was not defined.'));
|
||||
}
|
||||
});
|
||||
|
||||
// Pass error to new deferred object.
|
||||
sendDeferred.addErrback(function(error) {
|
||||
if (goog.isDef(verifyObjs[verificationObjName])) {
|
||||
delete verifyObjs[verificationObjName];
|
||||
}
|
||||
deferred.errback(error);
|
||||
});
|
||||
|
||||
return deferred;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the DOM element under which we should add new script elements.
|
||||
* How? Take the first head element, and if not found take doc.documentElement,
|
||||
* which always exists.
|
||||
*
|
||||
* @param {!HTMLDocument} doc The relevant document.
|
||||
* @return {!Element} The script parent element.
|
||||
* @private
|
||||
*/
|
||||
goog.net.jsloader.getScriptParentElement_ = function(doc) {
|
||||
var headElements = doc.getElementsByTagName(goog.dom.TagName.HEAD);
|
||||
if (!headElements || goog.array.isEmpty(headElements)) {
|
||||
return doc.documentElement;
|
||||
} else {
|
||||
return headElements[0];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Cancels a given request.
|
||||
* @this {{script_: Element, timeout_: number}} The request context.
|
||||
* @private
|
||||
*/
|
||||
goog.net.jsloader.cancel_ = function() {
|
||||
var request = this;
|
||||
if (request && request.script_) {
|
||||
var scriptNode = request.script_;
|
||||
if (scriptNode && scriptNode.tagName == goog.dom.TagName.SCRIPT) {
|
||||
goog.net.jsloader.cleanup_(scriptNode, true, request.timeout_);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes the script node and the timeout.
|
||||
*
|
||||
* @param {Node} scriptNode The node to be cleaned up.
|
||||
* @param {boolean} removeScriptNode If true completely remove the script node.
|
||||
* @param {?number=} opt_timeout The timeout handler to cleanup.
|
||||
* @private
|
||||
*/
|
||||
goog.net.jsloader.cleanup_ = function(
|
||||
scriptNode, removeScriptNode, opt_timeout) {
|
||||
if (goog.isDefAndNotNull(opt_timeout)) {
|
||||
goog.global.clearTimeout(opt_timeout);
|
||||
}
|
||||
|
||||
scriptNode.onload = goog.nullFunction;
|
||||
scriptNode.onerror = goog.nullFunction;
|
||||
scriptNode.onreadystatechange = goog.nullFunction;
|
||||
|
||||
// Do this after a delay (removing the script node of a running script can
|
||||
// confuse older IEs).
|
||||
if (removeScriptNode) {
|
||||
window.setTimeout(function() { goog.dom.removeNode(scriptNode); }, 0);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Possible error codes for jsloader.
|
||||
* @enum {number}
|
||||
*/
|
||||
goog.net.jsloader.ErrorCode = {
|
||||
LOAD_ERROR: 0,
|
||||
TIMEOUT: 1,
|
||||
VERIFY_ERROR: 2,
|
||||
VERIFY_OBJECT_ALREADY_EXISTS: 3
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A jsloader error.
|
||||
*
|
||||
* @param {goog.net.jsloader.ErrorCode} code The error code.
|
||||
* @param {string=} opt_message Additional message.
|
||||
* @constructor
|
||||
* @extends {goog.debug.Error}
|
||||
* @final
|
||||
*/
|
||||
goog.net.jsloader.Error = function(code, opt_message) {
|
||||
var msg = 'Jsloader error (code #' + code + ')';
|
||||
if (opt_message) {
|
||||
msg += ': ' + opt_message;
|
||||
}
|
||||
goog.net.jsloader.Error.base(this, 'constructor', msg);
|
||||
|
||||
/**
|
||||
* The code for this error.
|
||||
*
|
||||
* @type {goog.net.jsloader.ErrorCode}
|
||||
*/
|
||||
this.code = code;
|
||||
};
|
||||
goog.inherits(goog.net.jsloader.Error, goog.debug.Error);
|
||||
705
resources/public/js/compiled/out/goog/object/object.js
Normal file
705
resources/public/js/compiled/out/goog/object/object.js
Normal file
|
|
@ -0,0 +1,705 @@
|
|||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities for manipulating objects/maps/hashes.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*/
|
||||
|
||||
goog.provide('goog.object');
|
||||
|
||||
|
||||
/**
|
||||
* Whether two values are not observably distinguishable. This
|
||||
* correctly detects that 0 is not the same as -0 and two NaNs are
|
||||
* practically equivalent.
|
||||
*
|
||||
* The implementation is as suggested by harmony:egal proposal.
|
||||
*
|
||||
* @param {*} v The first value to compare.
|
||||
* @param {*} v2 The second value to compare.
|
||||
* @return {boolean} Whether two values are not observably distinguishable.
|
||||
* @see http://wiki.ecmascript.org/doku.php?id=harmony:egal
|
||||
*/
|
||||
goog.object.is = function(v, v2) {
|
||||
if (v === v2) {
|
||||
// 0 === -0, but they are not identical.
|
||||
// We need the cast because the compiler requires that v2 is a
|
||||
// number (although 1/v2 works with non-number). We cast to ? to
|
||||
// stop the compiler from type-checking this statement.
|
||||
return v !== 0 || 1 / v === 1 / /** @type {?} */ (v2);
|
||||
}
|
||||
|
||||
// NaN is non-reflexive: NaN !== NaN, although they are identical.
|
||||
return v !== v && v2 !== v2;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls a function for each element in an object/map/hash.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object over which to iterate.
|
||||
* @param {function(this:T,V,?,Object<K,V>):?} f The function to call
|
||||
* for every element. This function takes 3 arguments (the value, the
|
||||
* key and the object) and the return value is ignored.
|
||||
* @param {T=} opt_obj This is used as the 'this' object within f.
|
||||
* @template T,K,V
|
||||
*/
|
||||
goog.object.forEach = function(obj, f, opt_obj) {
|
||||
for (var key in obj) {
|
||||
f.call(/** @type {?} */ (opt_obj), obj[key], key, obj);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls a function for each element in an object/map/hash. If that call returns
|
||||
* true, adds the element to a new object.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object over which to iterate.
|
||||
* @param {function(this:T,V,?,Object<K,V>):boolean} f The function to call
|
||||
* for every element. This
|
||||
* function takes 3 arguments (the value, the key and the object)
|
||||
* and should return a boolean. If the return value is true the
|
||||
* element is added to the result object. If it is false the
|
||||
* element is not included.
|
||||
* @param {T=} opt_obj This is used as the 'this' object within f.
|
||||
* @return {!Object<K,V>} a new object in which only elements that passed the
|
||||
* test are present.
|
||||
* @template T,K,V
|
||||
*/
|
||||
goog.object.filter = function(obj, f, opt_obj) {
|
||||
var res = {};
|
||||
for (var key in obj) {
|
||||
if (f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) {
|
||||
res[key] = obj[key];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* For every element in an object/map/hash calls a function and inserts the
|
||||
* result into a new object.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object over which to iterate.
|
||||
* @param {function(this:T,V,?,Object<K,V>):R} f The function to call
|
||||
* for every element. This function
|
||||
* takes 3 arguments (the value, the key and the object)
|
||||
* and should return something. The result will be inserted
|
||||
* into a new object.
|
||||
* @param {T=} opt_obj This is used as the 'this' object within f.
|
||||
* @return {!Object<K,R>} a new object with the results from f.
|
||||
* @template T,K,V,R
|
||||
*/
|
||||
goog.object.map = function(obj, f, opt_obj) {
|
||||
var res = {};
|
||||
for (var key in obj) {
|
||||
res[key] = f.call(/** @type {?} */ (opt_obj), obj[key], key, obj);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls a function for each element in an object/map/hash. If any
|
||||
* call returns true, returns true (without checking the rest). If
|
||||
* all calls return false, returns false.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object to check.
|
||||
* @param {function(this:T,V,?,Object<K,V>):boolean} f The function to
|
||||
* call for every element. This function
|
||||
* takes 3 arguments (the value, the key and the object) and should
|
||||
* return a boolean.
|
||||
* @param {T=} opt_obj This is used as the 'this' object within f.
|
||||
* @return {boolean} true if any element passes the test.
|
||||
* @template T,K,V
|
||||
*/
|
||||
goog.object.some = function(obj, f, opt_obj) {
|
||||
for (var key in obj) {
|
||||
if (f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls a function for each element in an object/map/hash. If
|
||||
* all calls return true, returns true. If any call returns false, returns
|
||||
* false at this point and does not continue to check the remaining elements.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object to check.
|
||||
* @param {?function(this:T,V,?,Object<K,V>):boolean} f The function to
|
||||
* call for every element. This function
|
||||
* takes 3 arguments (the value, the key and the object) and should
|
||||
* return a boolean.
|
||||
* @param {T=} opt_obj This is used as the 'this' object within f.
|
||||
* @return {boolean} false if any element fails the test.
|
||||
* @template T,K,V
|
||||
*/
|
||||
goog.object.every = function(obj, f, opt_obj) {
|
||||
for (var key in obj) {
|
||||
if (!f.call(/** @type {?} */ (opt_obj), obj[key], key, obj)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of key-value pairs in the object map.
|
||||
*
|
||||
* @param {Object} obj The object for which to get the number of key-value
|
||||
* pairs.
|
||||
* @return {number} The number of key-value pairs in the object map.
|
||||
*/
|
||||
goog.object.getCount = function(obj) {
|
||||
var rv = 0;
|
||||
for (var key in obj) {
|
||||
rv++;
|
||||
}
|
||||
return rv;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns one key from the object map, if any exists.
|
||||
* For map literals the returned key will be the first one in most of the
|
||||
* browsers (a know exception is Konqueror).
|
||||
*
|
||||
* @param {Object} obj The object to pick a key from.
|
||||
* @return {string|undefined} The key or undefined if the object is empty.
|
||||
*/
|
||||
goog.object.getAnyKey = function(obj) {
|
||||
for (var key in obj) {
|
||||
return key;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns one value from the object map, if any exists.
|
||||
* For map literals the returned value will be the first one in most of the
|
||||
* browsers (a know exception is Konqueror).
|
||||
*
|
||||
* @param {Object<K,V>} obj The object to pick a value from.
|
||||
* @return {V|undefined} The value or undefined if the object is empty.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.getAnyValue = function(obj) {
|
||||
for (var key in obj) {
|
||||
return obj[key];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the object/hash/map contains the given object as a value.
|
||||
* An alias for goog.object.containsValue(obj, val).
|
||||
*
|
||||
* @param {Object<K,V>} obj The object in which to look for val.
|
||||
* @param {V} val The object for which to check.
|
||||
* @return {boolean} true if val is present.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.contains = function(obj, val) {
|
||||
return goog.object.containsValue(obj, val);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the values of the object/map/hash.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object from which to get the values.
|
||||
* @return {!Array<V>} The values in the object/map/hash.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.getValues = function(obj) {
|
||||
var res = [];
|
||||
var i = 0;
|
||||
for (var key in obj) {
|
||||
res[i++] = obj[key];
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the keys of the object/map/hash.
|
||||
*
|
||||
* @param {Object} obj The object from which to get the keys.
|
||||
* @return {!Array<string>} Array of property keys.
|
||||
*/
|
||||
goog.object.getKeys = function(obj) {
|
||||
var res = [];
|
||||
var i = 0;
|
||||
for (var key in obj) {
|
||||
res[i++] = key;
|
||||
}
|
||||
return res;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Get a value from an object multiple levels deep. This is useful for
|
||||
* pulling values from deeply nested objects, such as JSON responses.
|
||||
* Example usage: getValueByKeys(jsonObj, 'foo', 'entries', 3)
|
||||
*
|
||||
* @param {!Object} obj An object to get the value from. Can be array-like.
|
||||
* @param {...(string|number|!IArrayLike<number|string>)}
|
||||
* var_args A number of keys
|
||||
* (as strings, or numbers, for array-like objects). Can also be
|
||||
* specified as a single array of keys.
|
||||
* @return {*} The resulting value. If, at any point, the value for a key
|
||||
* is undefined, returns undefined.
|
||||
*/
|
||||
goog.object.getValueByKeys = function(obj, var_args) {
|
||||
var isArrayLike = goog.isArrayLike(var_args);
|
||||
var keys = isArrayLike ? var_args : arguments;
|
||||
|
||||
// Start with the 2nd parameter for the variable parameters syntax.
|
||||
for (var i = isArrayLike ? 0 : 1; i < keys.length; i++) {
|
||||
obj = obj[keys[i]];
|
||||
if (!goog.isDef(obj)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the object/map/hash contains the given key.
|
||||
*
|
||||
* @param {Object} obj The object in which to look for key.
|
||||
* @param {?} key The key for which to check.
|
||||
* @return {boolean} true If the map contains the key.
|
||||
*/
|
||||
goog.object.containsKey = function(obj, key) {
|
||||
return obj !== null && key in obj;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the object/map/hash contains the given value. This is O(n).
|
||||
*
|
||||
* @param {Object<K,V>} obj The object in which to look for val.
|
||||
* @param {V} val The value for which to check.
|
||||
* @return {boolean} true If the map contains the value.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.containsValue = function(obj, val) {
|
||||
for (var key in obj) {
|
||||
if (obj[key] == val) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Searches an object for an element that satisfies the given condition and
|
||||
* returns its key.
|
||||
* @param {Object<K,V>} obj The object to search in.
|
||||
* @param {function(this:T,V,string,Object<K,V>):boolean} f The
|
||||
* function to call for every element. Takes 3 arguments (the value,
|
||||
* the key and the object) and should return a boolean.
|
||||
* @param {T=} opt_this An optional "this" context for the function.
|
||||
* @return {string|undefined} The key of an element for which the function
|
||||
* returns true or undefined if no such element is found.
|
||||
* @template T,K,V
|
||||
*/
|
||||
goog.object.findKey = function(obj, f, opt_this) {
|
||||
for (var key in obj) {
|
||||
if (f.call(/** @type {?} */ (opt_this), obj[key], key, obj)) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Searches an object for an element that satisfies the given condition and
|
||||
* returns its value.
|
||||
* @param {Object<K,V>} obj The object to search in.
|
||||
* @param {function(this:T,V,string,Object<K,V>):boolean} f The function
|
||||
* to call for every element. Takes 3 arguments (the value, the key
|
||||
* and the object) and should return a boolean.
|
||||
* @param {T=} opt_this An optional "this" context for the function.
|
||||
* @return {V} The value of an element for which the function returns true or
|
||||
* undefined if no such element is found.
|
||||
* @template T,K,V
|
||||
*/
|
||||
goog.object.findValue = function(obj, f, opt_this) {
|
||||
var key = goog.object.findKey(obj, f, opt_this);
|
||||
return key && obj[key];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the object/map/hash is empty.
|
||||
*
|
||||
* @param {Object} obj The object to test.
|
||||
* @return {boolean} true if obj is empty.
|
||||
*/
|
||||
goog.object.isEmpty = function(obj) {
|
||||
for (var key in obj) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes all key value pairs from the object/map/hash.
|
||||
*
|
||||
* @param {Object} obj The object to clear.
|
||||
*/
|
||||
goog.object.clear = function(obj) {
|
||||
for (var i in obj) {
|
||||
delete obj[i];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes a key-value pair based on the key.
|
||||
*
|
||||
* @param {Object} obj The object from which to remove the key.
|
||||
* @param {?} key The key to remove.
|
||||
* @return {boolean} Whether an element was removed.
|
||||
*/
|
||||
goog.object.remove = function(obj, key) {
|
||||
var rv;
|
||||
if (rv = key in /** @type {!Object} */ (obj)) {
|
||||
delete obj[key];
|
||||
}
|
||||
return rv;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a key-value pair to the object. Throws an exception if the key is
|
||||
* already in use. Use set if you want to change an existing pair.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object to which to add the key-value pair.
|
||||
* @param {string} key The key to add.
|
||||
* @param {V} val The value to add.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.add = function(obj, key, val) {
|
||||
if (obj !== null && key in obj) {
|
||||
throw Error('The object already contains the key "' + key + '"');
|
||||
}
|
||||
goog.object.set(obj, key, val);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value for the given key.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object from which to get the value.
|
||||
* @param {string} key The key for which to get the value.
|
||||
* @param {R=} opt_val The value to return if no item is found for the given
|
||||
* key (default is undefined).
|
||||
* @return {V|R|undefined} The value for the given key.
|
||||
* @template K,V,R
|
||||
*/
|
||||
goog.object.get = function(obj, key, opt_val) {
|
||||
if (obj !== null && key in obj) {
|
||||
return obj[key];
|
||||
}
|
||||
return opt_val;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a key-value pair to the object/map/hash.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object to which to add the key-value pair.
|
||||
* @param {string} key The key to add.
|
||||
* @param {V} value The value to add.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.set = function(obj, key, value) {
|
||||
obj[key] = value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a key-value pair to the object/map/hash if it doesn't exist yet.
|
||||
*
|
||||
* @param {Object<K,V>} obj The object to which to add the key-value pair.
|
||||
* @param {string} key The key to add.
|
||||
* @param {V} value The value to add if the key wasn't present.
|
||||
* @return {V} The value of the entry at the end of the function.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.setIfUndefined = function(obj, key, value) {
|
||||
return key in /** @type {!Object} */ (obj) ? obj[key] : (obj[key] = value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets a key and value to an object if the key is not set. The value will be
|
||||
* the return value of the given function. If the key already exists, the
|
||||
* object will not be changed and the function will not be called (the function
|
||||
* will be lazily evaluated -- only called if necessary).
|
||||
*
|
||||
* This function is particularly useful for use with a map used a as a cache.
|
||||
*
|
||||
* @param {!Object<K,V>} obj The object to which to add the key-value pair.
|
||||
* @param {string} key The key to add.
|
||||
* @param {function():V} f The value to add if the key wasn't present.
|
||||
* @return {V} The value of the entry at the end of the function.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.setWithReturnValueIfNotSet = function(obj, key, f) {
|
||||
if (key in obj) {
|
||||
return obj[key];
|
||||
}
|
||||
|
||||
var val = f();
|
||||
obj[key] = val;
|
||||
return val;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compares two objects for equality using === on the values.
|
||||
*
|
||||
* @param {!Object<K,V>} a
|
||||
* @param {!Object<K,V>} b
|
||||
* @return {boolean}
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.equals = function(a, b) {
|
||||
for (var k in a) {
|
||||
if (!(k in b) || a[k] !== b[k]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (var k in b) {
|
||||
if (!(k in a)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a shallow clone of the object.
|
||||
*
|
||||
* @param {Object<K,V>} obj Object to clone.
|
||||
* @return {!Object<K,V>} Clone of the input object.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.clone = function(obj) {
|
||||
// We cannot use the prototype trick because a lot of methods depend on where
|
||||
// the actual key is set.
|
||||
|
||||
var res = {};
|
||||
for (var key in obj) {
|
||||
res[key] = obj[key];
|
||||
}
|
||||
return res;
|
||||
// We could also use goog.mixin but I wanted this to be independent from that.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clones a value. The input may be an Object, Array, or basic type. Objects and
|
||||
* arrays will be cloned recursively.
|
||||
*
|
||||
* WARNINGS:
|
||||
* <code>goog.object.unsafeClone</code> does not detect reference loops. Objects
|
||||
* that refer to themselves will cause infinite recursion.
|
||||
*
|
||||
* <code>goog.object.unsafeClone</code> is unaware of unique identifiers, and
|
||||
* copies UIDs created by <code>getUid</code> into cloned results.
|
||||
*
|
||||
* @param {*} obj The value to clone.
|
||||
* @return {*} A clone of the input value.
|
||||
*/
|
||||
goog.object.unsafeClone = function(obj) {
|
||||
var type = goog.typeOf(obj);
|
||||
if (type == 'object' || type == 'array') {
|
||||
if (goog.isFunction(obj.clone)) {
|
||||
return obj.clone();
|
||||
}
|
||||
var clone = type == 'array' ? [] : {};
|
||||
for (var key in obj) {
|
||||
clone[key] = goog.object.unsafeClone(obj[key]);
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a new object in which all the keys and values are interchanged
|
||||
* (keys become values and values become keys). If multiple keys map to the
|
||||
* same value, the chosen transposed value is implementation-dependent.
|
||||
*
|
||||
* @param {Object} obj The object to transpose.
|
||||
* @return {!Object} The transposed object.
|
||||
*/
|
||||
goog.object.transpose = function(obj) {
|
||||
var transposed = {};
|
||||
for (var key in obj) {
|
||||
transposed[obj[key]] = key;
|
||||
}
|
||||
return transposed;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The names of the fields that are defined on Object.prototype.
|
||||
* @type {Array<string>}
|
||||
* @private
|
||||
*/
|
||||
goog.object.PROTOTYPE_FIELDS_ = [
|
||||
'constructor', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable',
|
||||
'toLocaleString', 'toString', 'valueOf'
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Extends an object with another object.
|
||||
* This operates 'in-place'; it does not create a new Object.
|
||||
*
|
||||
* Example:
|
||||
* var o = {};
|
||||
* goog.object.extend(o, {a: 0, b: 1});
|
||||
* o; // {a: 0, b: 1}
|
||||
* goog.object.extend(o, {b: 2, c: 3});
|
||||
* o; // {a: 0, b: 2, c: 3}
|
||||
*
|
||||
* @param {Object} target The object to modify. Existing properties will be
|
||||
* overwritten if they are also present in one of the objects in
|
||||
* {@code var_args}.
|
||||
* @param {...Object} var_args The objects from which values will be copied.
|
||||
*/
|
||||
goog.object.extend = function(target, var_args) {
|
||||
var key, source;
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
source = arguments[i];
|
||||
for (key in source) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
|
||||
// For IE the for-in-loop does not contain any properties that are not
|
||||
// enumerable on the prototype object (for example isPrototypeOf from
|
||||
// Object.prototype) and it will also not include 'replace' on objects that
|
||||
// extend String and change 'replace' (not that it is common for anyone to
|
||||
// extend anything except Object).
|
||||
|
||||
for (var j = 0; j < goog.object.PROTOTYPE_FIELDS_.length; j++) {
|
||||
key = goog.object.PROTOTYPE_FIELDS_[j];
|
||||
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
||||
target[key] = source[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new object built from the key-value pairs provided as arguments.
|
||||
* @param {...*} var_args If only one argument is provided and it is an array
|
||||
* then this is used as the arguments, otherwise even arguments are used as
|
||||
* the property names and odd arguments are used as the property values.
|
||||
* @return {!Object} The new object.
|
||||
* @throws {Error} If there are uneven number of arguments or there is only one
|
||||
* non array argument.
|
||||
*/
|
||||
goog.object.create = function(var_args) {
|
||||
var argLength = arguments.length;
|
||||
if (argLength == 1 && goog.isArray(arguments[0])) {
|
||||
return goog.object.create.apply(null, arguments[0]);
|
||||
}
|
||||
|
||||
if (argLength % 2) {
|
||||
throw Error('Uneven number of arguments');
|
||||
}
|
||||
|
||||
var rv = {};
|
||||
for (var i = 0; i < argLength; i += 2) {
|
||||
rv[arguments[i]] = arguments[i + 1];
|
||||
}
|
||||
return rv;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new object where the property names come from the arguments but
|
||||
* the value is always set to true
|
||||
* @param {...*} var_args If only one argument is provided and it is an array
|
||||
* then this is used as the arguments, otherwise the arguments are used
|
||||
* as the property names.
|
||||
* @return {!Object} The new object.
|
||||
*/
|
||||
goog.object.createSet = function(var_args) {
|
||||
var argLength = arguments.length;
|
||||
if (argLength == 1 && goog.isArray(arguments[0])) {
|
||||
return goog.object.createSet.apply(null, arguments[0]);
|
||||
}
|
||||
|
||||
var rv = {};
|
||||
for (var i = 0; i < argLength; i++) {
|
||||
rv[arguments[i]] = true;
|
||||
}
|
||||
return rv;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates an immutable view of the underlying object, if the browser
|
||||
* supports immutable objects.
|
||||
*
|
||||
* In default mode, writes to this view will fail silently. In strict mode,
|
||||
* they will throw an error.
|
||||
*
|
||||
* @param {!Object<K,V>} obj An object.
|
||||
* @return {!Object<K,V>} An immutable view of that object, or the
|
||||
* original object if this browser does not support immutables.
|
||||
* @template K,V
|
||||
*/
|
||||
goog.object.createImmutableView = function(obj) {
|
||||
var result = obj;
|
||||
if (Object.isFrozen && !Object.isFrozen(obj)) {
|
||||
result = Object.create(obj);
|
||||
Object.freeze(result);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!Object} obj An object.
|
||||
* @return {boolean} Whether this is an immutable view of the object.
|
||||
*/
|
||||
goog.object.isImmutableView = function(obj) {
|
||||
return !!Object.isFrozen && Object.isFrozen(obj);
|
||||
};
|
||||
1336
resources/public/js/compiled/out/goog/promise/promise.js
Normal file
1336
resources/public/js/compiled/out/goog/promise/promise.js
Normal file
File diff suppressed because it is too large
Load diff
48
resources/public/js/compiled/out/goog/promise/resolver.js
Normal file
48
resources/public/js/compiled/out/goog/promise/resolver.js
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.promise.Resolver');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Resolver interface for promises. The resolver is a convenience interface that
|
||||
* bundles the promise and its associated resolve and reject functions together,
|
||||
* for cases where the resolver needs to be persisted internally.
|
||||
*
|
||||
* @interface
|
||||
* @template TYPE
|
||||
*/
|
||||
goog.promise.Resolver = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* The promise that created this resolver.
|
||||
* @type {!goog.Promise<TYPE>}
|
||||
*/
|
||||
goog.promise.Resolver.prototype.promise;
|
||||
|
||||
|
||||
/**
|
||||
* Resolves this resolver with the specified value.
|
||||
* @type {function((TYPE|goog.Promise<TYPE>|Thenable)=)}
|
||||
*/
|
||||
goog.promise.Resolver.prototype.resolve;
|
||||
|
||||
|
||||
/**
|
||||
* Rejects this resolver with the specified reason.
|
||||
* @type {function(*=): void}
|
||||
*/
|
||||
goog.promise.Resolver.prototype.reject;
|
||||
126
resources/public/js/compiled/out/goog/promise/thenable.js
Normal file
126
resources/public/js/compiled/out/goog/promise/thenable.js
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.Thenable');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Provides a more strict interface for Thenables in terms of
|
||||
* http://promisesaplus.com for interop with {@see goog.Promise}.
|
||||
*
|
||||
* @interface
|
||||
* @extends {IThenable<TYPE>}
|
||||
* @template TYPE
|
||||
*/
|
||||
goog.Thenable = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Adds callbacks that will operate on the result of the Thenable, returning a
|
||||
* new child Promise.
|
||||
*
|
||||
* If the Thenable is fulfilled, the {@code onFulfilled} callback will be
|
||||
* invoked with the fulfillment value as argument, and the child Promise will
|
||||
* be fulfilled with the return value of the callback. If the callback throws
|
||||
* an exception, the child Promise will be rejected with the thrown value
|
||||
* instead.
|
||||
*
|
||||
* If the Thenable is rejected, the {@code onRejected} callback will be invoked
|
||||
* with the rejection reason as argument, and the child Promise will be rejected
|
||||
* with the return value of the callback or thrown value.
|
||||
*
|
||||
* @param {?(function(this:THIS, TYPE): VALUE)=} opt_onFulfilled A
|
||||
* function that will be invoked with the fulfillment value if the Promise
|
||||
* is fulfilled.
|
||||
* @param {?(function(this:THIS, *): *)=} opt_onRejected A function that will
|
||||
* be invoked with the rejection reason if the Promise is rejected.
|
||||
* @param {THIS=} opt_context An optional context object that will be the
|
||||
* execution context for the callbacks. By default, functions are executed
|
||||
* with the default this.
|
||||
*
|
||||
* @return {RESULT} A new Promise that will receive the result
|
||||
* of the fulfillment or rejection callback.
|
||||
* @template VALUE
|
||||
* @template THIS
|
||||
*
|
||||
* When a Promise (or thenable) is returned from the fulfilled callback,
|
||||
* the result is the payload of that promise, not the promise itself.
|
||||
*
|
||||
* @template RESULT := type('goog.Promise',
|
||||
* cond(isUnknown(VALUE), unknown(),
|
||||
* mapunion(VALUE, (V) =>
|
||||
* cond(isTemplatized(V) && sub(rawTypeOf(V), 'IThenable'),
|
||||
* templateTypeOf(V, 0),
|
||||
* cond(sub(V, 'Thenable'),
|
||||
* unknown(),
|
||||
* V)))))
|
||||
* =:
|
||||
*
|
||||
*/
|
||||
goog.Thenable.prototype.then = function(
|
||||
opt_onFulfilled, opt_onRejected, opt_context) {};
|
||||
|
||||
|
||||
/**
|
||||
* An expando property to indicate that an object implements
|
||||
* {@code goog.Thenable}.
|
||||
*
|
||||
* {@see addImplementation}.
|
||||
*
|
||||
* @const
|
||||
*/
|
||||
goog.Thenable.IMPLEMENTED_BY_PROP = '$goog_Thenable';
|
||||
|
||||
|
||||
/**
|
||||
* Marks a given class (constructor) as an implementation of Thenable, so
|
||||
* that we can query that fact at runtime. The class must have already
|
||||
* implemented the interface.
|
||||
* Exports a 'then' method on the constructor prototype, so that the objects
|
||||
* also implement the extern {@see goog.Thenable} interface for interop with
|
||||
* other Promise implementations.
|
||||
* @param {function(new:goog.Thenable,...?)} ctor The class constructor. The
|
||||
* corresponding class must have already implemented the interface.
|
||||
*/
|
||||
goog.Thenable.addImplementation = function(ctor) {
|
||||
goog.exportProperty(ctor.prototype, 'then', ctor.prototype.then);
|
||||
if (COMPILED) {
|
||||
ctor.prototype[goog.Thenable.IMPLEMENTED_BY_PROP] = true;
|
||||
} else {
|
||||
// Avoids dictionary access in uncompiled mode.
|
||||
ctor.prototype.$goog_Thenable = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {?} object
|
||||
* @return {boolean} Whether a given instance implements {@code goog.Thenable}.
|
||||
* The class/superclass of the instance must call {@code addImplementation}.
|
||||
*/
|
||||
goog.Thenable.isImplementedBy = function(object) {
|
||||
if (!object) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
if (COMPILED) {
|
||||
return !!object[goog.Thenable.IMPLEMENTED_BY_PROP];
|
||||
}
|
||||
return !!object.$goog_Thenable;
|
||||
} catch (e) {
|
||||
// Property access seems to be forbidden.
|
||||
return false;
|
||||
}
|
||||
};
|
||||
138
resources/public/js/compiled/out/goog/reflect/reflect.js
Normal file
138
resources/public/js/compiled/out/goog/reflect/reflect.js
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
// Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Useful compiler idioms.
|
||||
*
|
||||
* @author johnlenz@google.com (John Lenz)
|
||||
*/
|
||||
|
||||
goog.provide('goog.reflect');
|
||||
|
||||
|
||||
/**
|
||||
* Syntax for object literal casts.
|
||||
* @see http://go/jscompiler-renaming
|
||||
* @see https://goo.gl/CRs09P
|
||||
*
|
||||
* Use this if you have an object literal whose keys need to have the same names
|
||||
* as the properties of some class even after they are renamed by the compiler.
|
||||
*
|
||||
* @param {!Function} type Type to cast to.
|
||||
* @param {Object} object Object literal to cast.
|
||||
* @return {Object} The object literal.
|
||||
*/
|
||||
goog.reflect.object = function(type, object) {
|
||||
return object;
|
||||
};
|
||||
|
||||
/**
|
||||
* Syntax for renaming property strings.
|
||||
* @see http://go/jscompiler-renaming
|
||||
* @see https://goo.gl/CRs09P
|
||||
*
|
||||
* Use this if you have an need to access a property as a string, but want
|
||||
* to also have the property renamed by the compiler. In contrast to
|
||||
* goog.reflect.object, this method takes an instance of an object.
|
||||
*
|
||||
* Properties must be simple names (not qualified names).
|
||||
*
|
||||
* @param {string} prop Name of the property
|
||||
* @param {!Object} object Instance of the object whose type will be used
|
||||
* for renaming
|
||||
* @return {string} The renamed property.
|
||||
*/
|
||||
goog.reflect.objectProperty = function(prop, object) {
|
||||
return prop;
|
||||
};
|
||||
|
||||
/**
|
||||
* To assert to the compiler that an operation is needed when it would
|
||||
* otherwise be stripped. For example:
|
||||
* <code>
|
||||
* // Force a layout
|
||||
* goog.reflect.sinkValue(dialog.offsetHeight);
|
||||
* </code>
|
||||
* @param {T} x
|
||||
* @return {T}
|
||||
* @template T
|
||||
*/
|
||||
goog.reflect.sinkValue = function(x) {
|
||||
goog.reflect.sinkValue[' '](x);
|
||||
return x;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The compiler should optimize this function away iff no one ever uses
|
||||
* goog.reflect.sinkValue.
|
||||
*/
|
||||
goog.reflect.sinkValue[' '] = goog.nullFunction;
|
||||
|
||||
|
||||
/**
|
||||
* Check if a property can be accessed without throwing an exception.
|
||||
* @param {Object} obj The owner of the property.
|
||||
* @param {string} prop The property name.
|
||||
* @return {boolean} Whether the property is accessible. Will also return true
|
||||
* if obj is null.
|
||||
*/
|
||||
goog.reflect.canAccessProperty = function(obj, prop) {
|
||||
/** @preserveTry */
|
||||
try {
|
||||
goog.reflect.sinkValue(obj[prop]);
|
||||
return true;
|
||||
} catch (e) {
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves a value from a cache given a key. The compiler provides special
|
||||
* consideration for this call such that it is generally considered side-effect
|
||||
* free. However, if the {@code opt_keyFn} or {@code valueFn} have side-effects
|
||||
* then the entire call is considered to have side-effects.
|
||||
*
|
||||
* Conventionally storing the value on the cache would be considered a
|
||||
* side-effect and preclude unused calls from being pruned, ie. even if
|
||||
* the value was never used, it would still always be stored in the cache.
|
||||
*
|
||||
* Providing a side-effect free {@code valueFn} and {@code opt_keyFn}
|
||||
* allows unused calls to {@code goog.cache} to be pruned.
|
||||
*
|
||||
* @param {!Object<K, V>} cacheObj The object that contains the cached values.
|
||||
* @param {?} key The key to lookup in the cache. If it is not string or number
|
||||
* then a {@code opt_keyFn} should be provided. The key is also used as the
|
||||
* parameter to the {@code valueFn}.
|
||||
* @param {!function(?):V} valueFn The value provider to use to calculate the
|
||||
* value to store in the cache. This function should be side-effect free
|
||||
* to take advantage of the optimization.
|
||||
* @param {function(?):K=} opt_keyFn The key provider to determine the cache
|
||||
* map key. This should be used if the given key is not a string or number.
|
||||
* If not provided then the given key is used. This function should be
|
||||
* side-effect free to take advantage of the optimization.
|
||||
* @return {V} The cached or calculated value.
|
||||
* @template K
|
||||
* @template V
|
||||
*/
|
||||
goog.reflect.cache = function(cacheObj, key, valueFn, opt_keyFn) {
|
||||
var storedKey = opt_keyFn ? opt_keyFn(key) : key;
|
||||
|
||||
if (Object.prototype.hasOwnProperty.call(cacheObj, storedKey)) {
|
||||
return cacheObj[storedKey];
|
||||
}
|
||||
|
||||
return (cacheObj[storedKey] = valueFn(key));
|
||||
};
|
||||
182
resources/public/js/compiled/out/goog/string/const.js
Normal file
182
resources/public/js/compiled/out/goog/string/const.js
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.string.Const');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for compile-time-constant strings.
|
||||
*
|
||||
* Const is a wrapper for strings that can only be created from program
|
||||
* constants (i.e., string literals). This property relies on a custom Closure
|
||||
* compiler check that {@code goog.string.Const.from} is only invoked on
|
||||
* compile-time-constant expressions.
|
||||
*
|
||||
* Const is useful in APIs whose correct and secure use requires that certain
|
||||
* arguments are not attacker controlled: Compile-time constants are inherently
|
||||
* under the control of the application and not under control of external
|
||||
* attackers, and hence are safe to use in such contexts.
|
||||
*
|
||||
* Instances of this type must be created via its factory method
|
||||
* {@code goog.string.Const.from} and not by invoking its constructor. The
|
||||
* constructor intentionally takes no parameters and the type is immutable;
|
||||
* hence only a default instance corresponding to the empty string can be
|
||||
* obtained via constructor invocation.
|
||||
*
|
||||
* @see goog.string.Const#from
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
* @implements {goog.string.TypedString}
|
||||
*/
|
||||
goog.string.Const = function() {
|
||||
/**
|
||||
* The wrapped value of this Const object. The field has a purposely ugly
|
||||
* name to make (non-compiled) code that attempts to directly access this
|
||||
* field stand out.
|
||||
* @private {string}
|
||||
*/
|
||||
this.stringConstValueWithSecurityContract__googStringSecurityPrivate_ = '';
|
||||
|
||||
/**
|
||||
* A type marker used to implement additional run-time type checking.
|
||||
* @see goog.string.Const#unwrap
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
this.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_ =
|
||||
goog.string.Const.TYPE_MARKER_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @const
|
||||
*/
|
||||
goog.string.Const.prototype.implementsGoogStringTypedString = true;
|
||||
|
||||
|
||||
/**
|
||||
* Returns this Const's value a string.
|
||||
*
|
||||
* IMPORTANT: In code where it is security-relevant that an object's type is
|
||||
* indeed {@code goog.string.Const}, use {@code goog.string.Const.unwrap}
|
||||
* instead of this method.
|
||||
*
|
||||
* @see goog.string.Const#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.string.Const.prototype.getTypedStringValue = function() {
|
||||
return this.stringConstValueWithSecurityContract__googStringSecurityPrivate_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a debug-string representation of this value.
|
||||
*
|
||||
* To obtain the actual string value wrapped inside an object of this type,
|
||||
* use {@code goog.string.Const.unwrap}.
|
||||
*
|
||||
* @see goog.string.Const#unwrap
|
||||
* @override
|
||||
*/
|
||||
goog.string.Const.prototype.toString = function() {
|
||||
return 'Const{' +
|
||||
this.stringConstValueWithSecurityContract__googStringSecurityPrivate_ +
|
||||
'}';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Performs a runtime check that the provided object is indeed an instance
|
||||
* of {@code goog.string.Const}, and returns its value.
|
||||
* @param {!goog.string.Const} stringConst The object to extract from.
|
||||
* @return {string} The Const object's contained string, unless the run-time
|
||||
* type check fails. In that case, {@code unwrap} returns an innocuous
|
||||
* string, or, if assertions are enabled, throws
|
||||
* {@code goog.asserts.AssertionError}.
|
||||
*/
|
||||
goog.string.Const.unwrap = function(stringConst) {
|
||||
// Perform additional run-time type-checking to ensure that stringConst is
|
||||
// indeed an instance of the expected type. This provides some additional
|
||||
// protection against security bugs due to application code that disables type
|
||||
// checks.
|
||||
if (stringConst instanceof goog.string.Const &&
|
||||
stringConst.constructor === goog.string.Const &&
|
||||
stringConst.STRING_CONST_TYPE_MARKER__GOOG_STRING_SECURITY_PRIVATE_ ===
|
||||
goog.string.Const.TYPE_MARKER_) {
|
||||
return stringConst
|
||||
.stringConstValueWithSecurityContract__googStringSecurityPrivate_;
|
||||
} else {
|
||||
goog.asserts.fail(
|
||||
'expected object of type Const, got \'' + stringConst + '\'');
|
||||
return 'type_error:Const';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Creates a Const object from a compile-time constant string.
|
||||
*
|
||||
* It is illegal to invoke this function on an expression whose
|
||||
* compile-time-contant value cannot be determined by the Closure compiler.
|
||||
*
|
||||
* Correct invocations include,
|
||||
* <pre>
|
||||
* var s = goog.string.Const.from('hello');
|
||||
* var t = goog.string.Const.from('hello' + 'world');
|
||||
* </pre>
|
||||
*
|
||||
* In contrast, the following are illegal:
|
||||
* <pre>
|
||||
* var s = goog.string.Const.from(getHello());
|
||||
* var t = goog.string.Const.from('hello' + world);
|
||||
* </pre>
|
||||
*
|
||||
* TODO(xtof): Compile-time checks that this function is only called
|
||||
* with compile-time constant expressions.
|
||||
*
|
||||
* @param {string} s A constant string from which to create a Const.
|
||||
* @return {!goog.string.Const} A Const object initialized to stringConst.
|
||||
*/
|
||||
goog.string.Const.from = function(s) {
|
||||
return goog.string.Const.create__googStringSecurityPrivate_(s);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Type marker for the Const type, used to implement additional run-time
|
||||
* type checking.
|
||||
* @const {!Object}
|
||||
* @private
|
||||
*/
|
||||
goog.string.Const.TYPE_MARKER_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Utility method to create Const instances.
|
||||
* @param {string} s The string to initialize the Const object with.
|
||||
* @return {!goog.string.Const} The initialized Const object.
|
||||
* @private
|
||||
*/
|
||||
goog.string.Const.create__googStringSecurityPrivate_ = function(s) {
|
||||
var stringConst = new goog.string.Const();
|
||||
stringConst.stringConstValueWithSecurityContract__googStringSecurityPrivate_ =
|
||||
s;
|
||||
return stringConst;
|
||||
};
|
||||
1631
resources/public/js/compiled/out/goog/string/string.js
Normal file
1631
resources/public/js/compiled/out/goog/string/string.js
Normal file
File diff suppressed because it is too large
Load diff
103
resources/public/js/compiled/out/goog/string/stringbuffer.js
Normal file
103
resources/public/js/compiled/out/goog/string/stringbuffer.js
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utility for fast string concatenation.
|
||||
*/
|
||||
|
||||
goog.provide('goog.string.StringBuffer');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Utility class to facilitate string concatenation.
|
||||
*
|
||||
* @param {*=} opt_a1 Optional first initial item to append.
|
||||
* @param {...*} var_args Other initial items to
|
||||
* append, e.g., new goog.string.StringBuffer('foo', 'bar').
|
||||
* @constructor
|
||||
*/
|
||||
goog.string.StringBuffer = function(opt_a1, var_args) {
|
||||
if (opt_a1 != null) {
|
||||
this.append.apply(this, arguments);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Internal buffer for the string to be concatenated.
|
||||
* @type {string}
|
||||
* @private
|
||||
*/
|
||||
goog.string.StringBuffer.prototype.buffer_ = '';
|
||||
|
||||
|
||||
/**
|
||||
* Sets the contents of the string buffer object, replacing what's currently
|
||||
* there.
|
||||
*
|
||||
* @param {*} s String to set.
|
||||
*/
|
||||
goog.string.StringBuffer.prototype.set = function(s) {
|
||||
this.buffer_ = '' + s;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Appends one or more items to the buffer.
|
||||
*
|
||||
* Calling this with null, undefined, or empty arguments is an error.
|
||||
*
|
||||
* @param {*} a1 Required first string.
|
||||
* @param {*=} opt_a2 Optional second string.
|
||||
* @param {...?} var_args Other items to append,
|
||||
* e.g., sb.append('foo', 'bar', 'baz').
|
||||
* @return {!goog.string.StringBuffer} This same StringBuffer object.
|
||||
* @suppress {duplicate}
|
||||
*/
|
||||
goog.string.StringBuffer.prototype.append = function(a1, opt_a2, var_args) {
|
||||
// Use a1 directly to avoid arguments instantiation for single-arg case.
|
||||
this.buffer_ += String(a1);
|
||||
if (opt_a2 != null) { // second argument is undefined (null == undefined)
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
this.buffer_ += arguments[i];
|
||||
}
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the internal buffer.
|
||||
*/
|
||||
goog.string.StringBuffer.prototype.clear = function() {
|
||||
this.buffer_ = '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} the length of the current contents of the buffer.
|
||||
*/
|
||||
goog.string.StringBuffer.prototype.getLength = function() {
|
||||
return this.buffer_.length;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The concatenated string.
|
||||
* @override
|
||||
*/
|
||||
goog.string.StringBuffer.prototype.toString = function() {
|
||||
return this.buffer_;
|
||||
};
|
||||
221
resources/public/js/compiled/out/goog/string/stringformat.js
Normal file
221
resources/public/js/compiled/out/goog/string/stringformat.js
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Implementation of sprintf-like, python-%-operator-like,
|
||||
* .NET-String.Format-like functionality. Uses JS string's replace method to
|
||||
* extract format specifiers and sends those specifiers to a handler function,
|
||||
* which then, based on conversion type part of the specifier, calls the
|
||||
* appropriate function to handle the specific conversion.
|
||||
* For specific functionality implemented, look at formatRe below, or look
|
||||
* at the tests.
|
||||
*/
|
||||
|
||||
goog.provide('goog.string.format');
|
||||
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* Performs sprintf-like conversion, i.e. puts the values in a template.
|
||||
* DO NOT use it instead of built-in conversions in simple cases such as
|
||||
* 'Cost: %.2f' as it would introduce unnecessary latency opposed to
|
||||
* 'Cost: ' + cost.toFixed(2).
|
||||
* @param {string} formatString Template string containing % specifiers.
|
||||
* @param {...string|number} var_args Values formatString is to be filled with.
|
||||
* @return {string} Formatted string.
|
||||
*/
|
||||
goog.string.format = function(formatString, var_args) {
|
||||
|
||||
// Convert the arguments to an array (MDC recommended way).
|
||||
var args = Array.prototype.slice.call(arguments);
|
||||
|
||||
// Try to get the template.
|
||||
var template = args.shift();
|
||||
if (typeof template == 'undefined') {
|
||||
throw Error('[goog.string.format] Template required');
|
||||
}
|
||||
|
||||
// This re is used for matching, it also defines what is supported.
|
||||
var formatRe = /%([0\-\ \+]*)(\d+)?(\.(\d+))?([%sfdiu])/g;
|
||||
|
||||
/**
|
||||
* Chooses which conversion function to call based on type conversion
|
||||
* specifier.
|
||||
* @param {string} match Contains the re matched string.
|
||||
* @param {string} flags Formatting flags.
|
||||
* @param {string} width Replacement string minimum width.
|
||||
* @param {string} dotp Matched precision including a dot.
|
||||
* @param {string} precision Specifies floating point precision.
|
||||
* @param {string} type Type conversion specifier.
|
||||
* @param {string} offset Matching location in the original string.
|
||||
* @param {string} wholeString Has the actualString being searched.
|
||||
* @return {string} Formatted parameter.
|
||||
*/
|
||||
function replacerDemuxer(
|
||||
match, flags, width, dotp, precision, type, offset, wholeString) {
|
||||
// The % is too simple and doesn't take an argument.
|
||||
if (type == '%') {
|
||||
return '%';
|
||||
}
|
||||
|
||||
// Try to get the actual value from parent function.
|
||||
var value = args.shift();
|
||||
|
||||
// If we didn't get any arguments, fail.
|
||||
if (typeof value == 'undefined') {
|
||||
throw Error('[goog.string.format] Not enough arguments');
|
||||
}
|
||||
|
||||
// Patch the value argument to the beginning of our type specific call.
|
||||
arguments[0] = value;
|
||||
|
||||
return goog.string.format.demuxes_[type].apply(null, arguments);
|
||||
}
|
||||
|
||||
return template.replace(formatRe, replacerDemuxer);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Contains various conversion functions (to be filled in later on).
|
||||
* @private {!Object}
|
||||
*/
|
||||
goog.string.format.demuxes_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Processes %s conversion specifier.
|
||||
* @param {string} value Contains the formatRe matched string.
|
||||
* @param {string} flags Formatting flags.
|
||||
* @param {string} width Replacement string minimum width.
|
||||
* @param {string} dotp Matched precision including a dot.
|
||||
* @param {string} precision Specifies floating point precision.
|
||||
* @param {string} type Type conversion specifier.
|
||||
* @param {string} offset Matching location in the original string.
|
||||
* @param {string} wholeString Has the actualString being searched.
|
||||
* @return {string} Replacement string.
|
||||
*/
|
||||
goog.string.format.demuxes_['s'] = function(
|
||||
value, flags, width, dotp, precision, type, offset, wholeString) {
|
||||
var replacement = value;
|
||||
// If no padding is necessary we're done.
|
||||
// The check for '' is necessary because Firefox incorrectly provides the
|
||||
// empty string instead of undefined for non-participating capture groups,
|
||||
// and isNaN('') == false.
|
||||
if (isNaN(width) || width == '' || replacement.length >= Number(width)) {
|
||||
return replacement;
|
||||
}
|
||||
|
||||
// Otherwise we should find out where to put spaces.
|
||||
if (flags.indexOf('-', 0) > -1) {
|
||||
replacement = replacement +
|
||||
goog.string.repeat(' ', Number(width) - replacement.length);
|
||||
} else {
|
||||
replacement = goog.string.repeat(' ', Number(width) - replacement.length) +
|
||||
replacement;
|
||||
}
|
||||
return replacement;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Processes %f conversion specifier.
|
||||
* @param {string} value Contains the formatRe matched string.
|
||||
* @param {string} flags Formatting flags.
|
||||
* @param {string} width Replacement string minimum width.
|
||||
* @param {string} dotp Matched precision including a dot.
|
||||
* @param {string} precision Specifies floating point precision.
|
||||
* @param {string} type Type conversion specifier.
|
||||
* @param {string} offset Matching location in the original string.
|
||||
* @param {string} wholeString Has the actualString being searched.
|
||||
* @return {string} Replacement string.
|
||||
*/
|
||||
goog.string.format.demuxes_['f'] = function(
|
||||
value, flags, width, dotp, precision, type, offset, wholeString) {
|
||||
|
||||
var replacement = value.toString();
|
||||
|
||||
// The check for '' is necessary because Firefox incorrectly provides the
|
||||
// empty string instead of undefined for non-participating capture groups,
|
||||
// and isNaN('') == false.
|
||||
if (!(isNaN(precision) || precision == '')) {
|
||||
replacement = parseFloat(value).toFixed(precision);
|
||||
}
|
||||
|
||||
// Generates sign string that will be attached to the replacement.
|
||||
var sign;
|
||||
if (Number(value) < 0) {
|
||||
sign = '-';
|
||||
} else if (flags.indexOf('+') >= 0) {
|
||||
sign = '+';
|
||||
} else if (flags.indexOf(' ') >= 0) {
|
||||
sign = ' ';
|
||||
} else {
|
||||
sign = '';
|
||||
}
|
||||
|
||||
if (Number(value) >= 0) {
|
||||
replacement = sign + replacement;
|
||||
}
|
||||
|
||||
// If no padding is necessary we're done.
|
||||
if (isNaN(width) || replacement.length >= Number(width)) {
|
||||
return replacement;
|
||||
}
|
||||
|
||||
// We need a clean signless replacement to start with
|
||||
replacement = isNaN(precision) ? Math.abs(Number(value)).toString() :
|
||||
Math.abs(Number(value)).toFixed(precision);
|
||||
|
||||
var padCount = Number(width) - replacement.length - sign.length;
|
||||
|
||||
// Find out which side to pad, and if it's left side, then which character to
|
||||
// pad, and set the sign on the left and padding in the middle.
|
||||
if (flags.indexOf('-', 0) >= 0) {
|
||||
replacement = sign + replacement + goog.string.repeat(' ', padCount);
|
||||
} else {
|
||||
// Decides which character to pad.
|
||||
var paddingChar = (flags.indexOf('0', 0) >= 0) ? '0' : ' ';
|
||||
replacement =
|
||||
sign + goog.string.repeat(paddingChar, padCount) + replacement;
|
||||
}
|
||||
|
||||
return replacement;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Processes %d conversion specifier.
|
||||
* @param {string} value Contains the formatRe matched string.
|
||||
* @param {string} flags Formatting flags.
|
||||
* @param {string} width Replacement string minimum width.
|
||||
* @param {string} dotp Matched precision including a dot.
|
||||
* @param {string} precision Specifies floating point precision.
|
||||
* @param {string} type Type conversion specifier.
|
||||
* @param {string} offset Matching location in the original string.
|
||||
* @param {string} wholeString Has the actualString being searched.
|
||||
* @return {string} Replacement string.
|
||||
*/
|
||||
goog.string.format.demuxes_['d'] = function(
|
||||
value, flags, width, dotp, precision, type, offset, wholeString) {
|
||||
return goog.string.format.demuxes_['f'](
|
||||
parseInt(value, 10) /* value */, flags, width, dotp, 0 /* precision */,
|
||||
type, offset, wholeString);
|
||||
};
|
||||
|
||||
|
||||
// These are additional aliases, for integer conversion.
|
||||
goog.string.format.demuxes_['i'] = goog.string.format.demuxes_['d'];
|
||||
goog.string.format.demuxes_['u'] = goog.string.format.demuxes_['d'];
|
||||
48
resources/public/js/compiled/out/goog/string/typedstring.js
Normal file
48
resources/public/js/compiled/out/goog/string/typedstring.js
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.string.TypedString');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for strings that conform to a data type or language.
|
||||
*
|
||||
* Implementations of this interface are wrappers for strings, and typically
|
||||
* associate a type contract with the wrapped string. Concrete implementations
|
||||
* of this interface may choose to implement additional run-time type checking,
|
||||
* see for example {@code goog.html.SafeHtml}. If available, client code that
|
||||
* needs to ensure type membership of an object should use the type's function
|
||||
* to assert type membership, such as {@code goog.html.SafeHtml.unwrap}.
|
||||
* @interface
|
||||
*/
|
||||
goog.string.TypedString = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Interface marker of the TypedString interface.
|
||||
*
|
||||
* This property can be used to determine at runtime whether or not an object
|
||||
* implements this interface. All implementations of this interface set this
|
||||
* property to {@code true}.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.string.TypedString.prototype.implementsGoogStringTypedString;
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves this wrapped string's value.
|
||||
* @return {!string} The wrapped string's value.
|
||||
*/
|
||||
goog.string.TypedString.prototype.getTypedStringValue;
|
||||
457
resources/public/js/compiled/out/goog/structs/map.js
Normal file
457
resources/public/js/compiled/out/goog/structs/map.js
Normal file
|
|
@ -0,0 +1,457 @@
|
|||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Datastructure: Hash Map.
|
||||
*
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*
|
||||
* This file contains an implementation of a Map structure. It implements a lot
|
||||
* of the methods used in goog.structs so those functions work on hashes. This
|
||||
* is best suited for complex key types. For simple keys such as numbers and
|
||||
* strings consider using the lighter-weight utilities in goog.object.
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.structs.Map');
|
||||
|
||||
goog.require('goog.iter.Iterator');
|
||||
goog.require('goog.iter.StopIteration');
|
||||
goog.require('goog.object');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class for Hash Map datastructure.
|
||||
* @param {*=} opt_map Map or Object to initialize the map with.
|
||||
* @param {...*} var_args If 2 or more arguments are present then they
|
||||
* will be used as key-value pairs.
|
||||
* @constructor
|
||||
* @template K, V
|
||||
*/
|
||||
goog.structs.Map = function(opt_map, var_args) {
|
||||
|
||||
/**
|
||||
* Underlying JS object used to implement the map.
|
||||
* @private {!Object}
|
||||
*/
|
||||
this.map_ = {};
|
||||
|
||||
/**
|
||||
* An array of keys. This is necessary for two reasons:
|
||||
* 1. Iterating the keys using for (var key in this.map_) allocates an
|
||||
* object for every key in IE which is really bad for IE6 GC perf.
|
||||
* 2. Without a side data structure, we would need to escape all the keys
|
||||
* as that would be the only way we could tell during iteration if the
|
||||
* key was an internal key or a property of the object.
|
||||
*
|
||||
* This array can contain deleted keys so it's necessary to check the map
|
||||
* as well to see if the key is still in the map (this doesn't require a
|
||||
* memory allocation in IE).
|
||||
* @private {!Array<string>}
|
||||
*/
|
||||
this.keys_ = [];
|
||||
|
||||
/**
|
||||
* The number of key value pairs in the map.
|
||||
* @private {number}
|
||||
*/
|
||||
this.count_ = 0;
|
||||
|
||||
/**
|
||||
* Version used to detect changes while iterating.
|
||||
* @private {number}
|
||||
*/
|
||||
this.version_ = 0;
|
||||
|
||||
var argLength = arguments.length;
|
||||
|
||||
if (argLength > 1) {
|
||||
if (argLength % 2) {
|
||||
throw Error('Uneven number of arguments');
|
||||
}
|
||||
for (var i = 0; i < argLength; i += 2) {
|
||||
this.set(arguments[i], arguments[i + 1]);
|
||||
}
|
||||
} else if (opt_map) {
|
||||
this.addAll(/** @type {Object} */ (opt_map));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} The number of key-value pairs in the map.
|
||||
*/
|
||||
goog.structs.Map.prototype.getCount = function() {
|
||||
return this.count_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the values of the map.
|
||||
* @return {!Array<V>} The values in the map.
|
||||
*/
|
||||
goog.structs.Map.prototype.getValues = function() {
|
||||
this.cleanupKeysArray_();
|
||||
|
||||
var rv = [];
|
||||
for (var i = 0; i < this.keys_.length; i++) {
|
||||
var key = this.keys_[i];
|
||||
rv.push(this.map_[key]);
|
||||
}
|
||||
return rv;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the keys of the map.
|
||||
* @return {!Array<string>} Array of string values.
|
||||
*/
|
||||
goog.structs.Map.prototype.getKeys = function() {
|
||||
this.cleanupKeysArray_();
|
||||
return /** @type {!Array<string>} */ (this.keys_.concat());
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the map contains the given key.
|
||||
* @param {*} key The key to check for.
|
||||
* @return {boolean} Whether the map contains the key.
|
||||
*/
|
||||
goog.structs.Map.prototype.containsKey = function(key) {
|
||||
return goog.structs.Map.hasKey_(this.map_, key);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the map contains the given value. This is O(n).
|
||||
* @param {V} val The value to check for.
|
||||
* @return {boolean} Whether the map contains the value.
|
||||
*/
|
||||
goog.structs.Map.prototype.containsValue = function(val) {
|
||||
for (var i = 0; i < this.keys_.length; i++) {
|
||||
var key = this.keys_[i];
|
||||
if (goog.structs.Map.hasKey_(this.map_, key) && this.map_[key] == val) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether this map is equal to the argument map.
|
||||
* @param {goog.structs.Map} otherMap The map against which to test equality.
|
||||
* @param {function(V, V): boolean=} opt_equalityFn Optional equality function
|
||||
* to test equality of values. If not specified, this will test whether
|
||||
* the values contained in each map are identical objects.
|
||||
* @return {boolean} Whether the maps are equal.
|
||||
*/
|
||||
goog.structs.Map.prototype.equals = function(otherMap, opt_equalityFn) {
|
||||
if (this === otherMap) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.count_ != otherMap.getCount()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var equalityFn = opt_equalityFn || goog.structs.Map.defaultEquals;
|
||||
|
||||
this.cleanupKeysArray_();
|
||||
for (var key, i = 0; key = this.keys_[i]; i++) {
|
||||
if (!equalityFn(this.get(key), otherMap.get(key))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Default equality test for values.
|
||||
* @param {*} a The first value.
|
||||
* @param {*} b The second value.
|
||||
* @return {boolean} Whether a and b reference the same object.
|
||||
*/
|
||||
goog.structs.Map.defaultEquals = function(a, b) {
|
||||
return a === b;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the map is empty.
|
||||
*/
|
||||
goog.structs.Map.prototype.isEmpty = function() {
|
||||
return this.count_ == 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes all key-value pairs from the map.
|
||||
*/
|
||||
goog.structs.Map.prototype.clear = function() {
|
||||
this.map_ = {};
|
||||
this.keys_.length = 0;
|
||||
this.count_ = 0;
|
||||
this.version_ = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes a key-value pair based on the key. This is O(logN) amortized due to
|
||||
* updating the keys array whenever the count becomes half the size of the keys
|
||||
* in the keys array.
|
||||
* @param {*} key The key to remove.
|
||||
* @return {boolean} Whether object was removed.
|
||||
*/
|
||||
goog.structs.Map.prototype.remove = function(key) {
|
||||
if (goog.structs.Map.hasKey_(this.map_, key)) {
|
||||
delete this.map_[key];
|
||||
this.count_--;
|
||||
this.version_++;
|
||||
|
||||
// clean up the keys array if the threshold is hit
|
||||
if (this.keys_.length > 2 * this.count_) {
|
||||
this.cleanupKeysArray_();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Cleans up the temp keys array by removing entries that are no longer in the
|
||||
* map.
|
||||
* @private
|
||||
*/
|
||||
goog.structs.Map.prototype.cleanupKeysArray_ = function() {
|
||||
if (this.count_ != this.keys_.length) {
|
||||
// First remove keys that are no longer in the map.
|
||||
var srcIndex = 0;
|
||||
var destIndex = 0;
|
||||
while (srcIndex < this.keys_.length) {
|
||||
var key = this.keys_[srcIndex];
|
||||
if (goog.structs.Map.hasKey_(this.map_, key)) {
|
||||
this.keys_[destIndex++] = key;
|
||||
}
|
||||
srcIndex++;
|
||||
}
|
||||
this.keys_.length = destIndex;
|
||||
}
|
||||
|
||||
if (this.count_ != this.keys_.length) {
|
||||
// If the count still isn't correct, that means we have duplicates. This can
|
||||
// happen when the same key is added and removed multiple times. Now we have
|
||||
// to allocate one extra Object to remove the duplicates. This could have
|
||||
// been done in the first pass, but in the common case, we can avoid
|
||||
// allocating an extra object by only doing this when necessary.
|
||||
var seen = {};
|
||||
var srcIndex = 0;
|
||||
var destIndex = 0;
|
||||
while (srcIndex < this.keys_.length) {
|
||||
var key = this.keys_[srcIndex];
|
||||
if (!(goog.structs.Map.hasKey_(seen, key))) {
|
||||
this.keys_[destIndex++] = key;
|
||||
seen[key] = 1;
|
||||
}
|
||||
srcIndex++;
|
||||
}
|
||||
this.keys_.length = destIndex;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value for the given key. If the key is not found and the default
|
||||
* value is not given this will return {@code undefined}.
|
||||
* @param {*} key The key to get the value for.
|
||||
* @param {DEFAULT=} opt_val The value to return if no item is found for the
|
||||
* given key, defaults to undefined.
|
||||
* @return {V|DEFAULT} The value for the given key.
|
||||
* @template DEFAULT
|
||||
*/
|
||||
goog.structs.Map.prototype.get = function(key, opt_val) {
|
||||
if (goog.structs.Map.hasKey_(this.map_, key)) {
|
||||
return this.map_[key];
|
||||
}
|
||||
return opt_val;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds a key-value pair to the map.
|
||||
* @param {*} key The key.
|
||||
* @param {V} value The value to add.
|
||||
* @return {*} Some subclasses return a value.
|
||||
*/
|
||||
goog.structs.Map.prototype.set = function(key, value) {
|
||||
if (!(goog.structs.Map.hasKey_(this.map_, key))) {
|
||||
this.count_++;
|
||||
// TODO(johnlenz): This class lies, it claims to return an array of string
|
||||
// keys, but instead returns the original object used.
|
||||
this.keys_.push(/** @type {?} */ (key));
|
||||
// Only change the version if we add a new key.
|
||||
this.version_++;
|
||||
}
|
||||
this.map_[key] = value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds multiple key-value pairs from another goog.structs.Map or Object.
|
||||
* @param {Object} map Object containing the data to add.
|
||||
*/
|
||||
goog.structs.Map.prototype.addAll = function(map) {
|
||||
var keys, values;
|
||||
if (map instanceof goog.structs.Map) {
|
||||
keys = map.getKeys();
|
||||
values = map.getValues();
|
||||
} else {
|
||||
keys = goog.object.getKeys(map);
|
||||
values = goog.object.getValues(map);
|
||||
}
|
||||
// we could use goog.array.forEach here but I don't want to introduce that
|
||||
// dependency just for this.
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
this.set(keys[i], values[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls the given function on each entry in the map.
|
||||
* @param {function(this:T, V, K, goog.structs.Map<K,V>)} f
|
||||
* @param {T=} opt_obj The value of "this" inside f.
|
||||
* @template T
|
||||
*/
|
||||
goog.structs.Map.prototype.forEach = function(f, opt_obj) {
|
||||
var keys = this.getKeys();
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
var value = this.get(key);
|
||||
f.call(opt_obj, value, key, this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clones a map and returns a new map.
|
||||
* @return {!goog.structs.Map} A new map with the same key-value pairs.
|
||||
*/
|
||||
goog.structs.Map.prototype.clone = function() {
|
||||
return new goog.structs.Map(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns a new map in which all the keys and values are interchanged
|
||||
* (keys become values and values become keys). If multiple keys map to the
|
||||
* same value, the chosen transposed value is implementation-dependent.
|
||||
*
|
||||
* It acts very similarly to {goog.object.transpose(Object)}.
|
||||
*
|
||||
* @return {!goog.structs.Map} The transposed map.
|
||||
*/
|
||||
goog.structs.Map.prototype.transpose = function() {
|
||||
var transposed = new goog.structs.Map();
|
||||
for (var i = 0; i < this.keys_.length; i++) {
|
||||
var key = this.keys_[i];
|
||||
var value = this.map_[key];
|
||||
transposed.set(value, key);
|
||||
}
|
||||
|
||||
return transposed;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {!Object} Object representation of the map.
|
||||
*/
|
||||
goog.structs.Map.prototype.toObject = function() {
|
||||
this.cleanupKeysArray_();
|
||||
var obj = {};
|
||||
for (var i = 0; i < this.keys_.length; i++) {
|
||||
var key = this.keys_[i];
|
||||
obj[key] = this.map_[key];
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an iterator that iterates over the keys in the map. Removal of keys
|
||||
* while iterating might have undesired side effects.
|
||||
* @return {!goog.iter.Iterator} An iterator over the keys in the map.
|
||||
*/
|
||||
goog.structs.Map.prototype.getKeyIterator = function() {
|
||||
return this.__iterator__(true);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an iterator that iterates over the values in the map. Removal of
|
||||
* keys while iterating might have undesired side effects.
|
||||
* @return {!goog.iter.Iterator} An iterator over the values in the map.
|
||||
*/
|
||||
goog.structs.Map.prototype.getValueIterator = function() {
|
||||
return this.__iterator__(false);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an iterator that iterates over the values or the keys in the map.
|
||||
* This throws an exception if the map was mutated since the iterator was
|
||||
* created.
|
||||
* @param {boolean=} opt_keys True to iterate over the keys. False to iterate
|
||||
* over the values. The default value is false.
|
||||
* @return {!goog.iter.Iterator} An iterator over the values or keys in the map.
|
||||
*/
|
||||
goog.structs.Map.prototype.__iterator__ = function(opt_keys) {
|
||||
// Clean up keys to minimize the risk of iterating over dead keys.
|
||||
this.cleanupKeysArray_();
|
||||
|
||||
var i = 0;
|
||||
var version = this.version_;
|
||||
var selfObj = this;
|
||||
|
||||
var newIter = new goog.iter.Iterator;
|
||||
newIter.next = function() {
|
||||
if (version != selfObj.version_) {
|
||||
throw Error('The map has changed since the iterator was created');
|
||||
}
|
||||
if (i >= selfObj.keys_.length) {
|
||||
throw goog.iter.StopIteration;
|
||||
}
|
||||
var key = selfObj.keys_[i++];
|
||||
return opt_keys ? key : selfObj.map_[key];
|
||||
};
|
||||
return newIter;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Safe way to test for hasOwnProperty. It even allows testing for
|
||||
* 'hasOwnProperty'.
|
||||
* @param {Object} obj The object to test for presence of the given key.
|
||||
* @param {*} key The key to check for.
|
||||
* @return {boolean} Whether the object has the key.
|
||||
* @private
|
||||
*/
|
||||
goog.structs.Map.hasKey_ = function(obj, key) {
|
||||
return Object.prototype.hasOwnProperty.call(obj, key);
|
||||
};
|
||||
355
resources/public/js/compiled/out/goog/structs/structs.js
Normal file
355
resources/public/js/compiled/out/goog/structs/structs.js
Normal file
|
|
@ -0,0 +1,355 @@
|
|||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Generics method for collection-like classes and objects.
|
||||
*
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
*
|
||||
* This file contains functions to work with collections. It supports using
|
||||
* Map, Set, Array and Object and other classes that implement collection-like
|
||||
* methods.
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.structs');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.object');
|
||||
|
||||
|
||||
// We treat an object as a dictionary if it has getKeys or it is an object that
|
||||
// isn't arrayLike.
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of values in the collection-like object.
|
||||
* @param {Object} col The collection-like object.
|
||||
* @return {number} The number of values in the collection-like object.
|
||||
*/
|
||||
goog.structs.getCount = function(col) {
|
||||
if (col.getCount && typeof col.getCount == 'function') {
|
||||
return col.getCount();
|
||||
}
|
||||
if (goog.isArrayLike(col) || goog.isString(col)) {
|
||||
return col.length;
|
||||
}
|
||||
return goog.object.getCount(col);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the values of the collection-like object.
|
||||
* @param {Object} col The collection-like object.
|
||||
* @return {!Array<?>} The values in the collection-like object.
|
||||
*/
|
||||
goog.structs.getValues = function(col) {
|
||||
if (col.getValues && typeof col.getValues == 'function') {
|
||||
return col.getValues();
|
||||
}
|
||||
if (goog.isString(col)) {
|
||||
return col.split('');
|
||||
}
|
||||
if (goog.isArrayLike(col)) {
|
||||
var rv = [];
|
||||
var l = col.length;
|
||||
for (var i = 0; i < l; i++) {
|
||||
rv.push(col[i]);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
return goog.object.getValues(col);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the keys of the collection. Some collections have no notion of
|
||||
* keys/indexes and this function will return undefined in those cases.
|
||||
* @param {Object} col The collection-like object.
|
||||
* @return {!Array|undefined} The keys in the collection.
|
||||
*/
|
||||
goog.structs.getKeys = function(col) {
|
||||
if (col.getKeys && typeof col.getKeys == 'function') {
|
||||
return col.getKeys();
|
||||
}
|
||||
// if we have getValues but no getKeys we know this is a key-less collection
|
||||
if (col.getValues && typeof col.getValues == 'function') {
|
||||
return undefined;
|
||||
}
|
||||
if (goog.isArrayLike(col) || goog.isString(col)) {
|
||||
var rv = [];
|
||||
var l = col.length;
|
||||
for (var i = 0; i < l; i++) {
|
||||
rv.push(i);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
return goog.object.getKeys(col);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the collection contains the given value. This is O(n) and uses
|
||||
* equals (==) to test the existence.
|
||||
* @param {Object} col The collection-like object.
|
||||
* @param {*} val The value to check for.
|
||||
* @return {boolean} True if the map contains the value.
|
||||
*/
|
||||
goog.structs.contains = function(col, val) {
|
||||
if (col.contains && typeof col.contains == 'function') {
|
||||
return col.contains(val);
|
||||
}
|
||||
if (col.containsValue && typeof col.containsValue == 'function') {
|
||||
return col.containsValue(val);
|
||||
}
|
||||
if (goog.isArrayLike(col) || goog.isString(col)) {
|
||||
return goog.array.contains(/** @type {!Array<?>} */ (col), val);
|
||||
}
|
||||
return goog.object.containsValue(col, val);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the collection is empty.
|
||||
* @param {Object} col The collection-like object.
|
||||
* @return {boolean} True if empty.
|
||||
*/
|
||||
goog.structs.isEmpty = function(col) {
|
||||
if (col.isEmpty && typeof col.isEmpty == 'function') {
|
||||
return col.isEmpty();
|
||||
}
|
||||
|
||||
// We do not use goog.string.isEmptyOrWhitespace because here we treat the
|
||||
// string as
|
||||
// collection and as such even whitespace matters
|
||||
|
||||
if (goog.isArrayLike(col) || goog.isString(col)) {
|
||||
return goog.array.isEmpty(/** @type {!Array<?>} */ (col));
|
||||
}
|
||||
return goog.object.isEmpty(col);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes all the elements from the collection.
|
||||
* @param {Object} col The collection-like object.
|
||||
*/
|
||||
goog.structs.clear = function(col) {
|
||||
// NOTE(arv): This should not contain strings because strings are immutable
|
||||
if (col.clear && typeof col.clear == 'function') {
|
||||
col.clear();
|
||||
} else if (goog.isArrayLike(col)) {
|
||||
goog.array.clear(/** @type {IArrayLike<?>} */ (col));
|
||||
} else {
|
||||
goog.object.clear(col);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls a function for each value in a collection. The function takes
|
||||
* three arguments; the value, the key and the collection.
|
||||
*
|
||||
* NOTE: This will be deprecated soon! Please use a more specific method if
|
||||
* possible, e.g. goog.array.forEach, goog.object.forEach, etc.
|
||||
*
|
||||
* @param {S} col The collection-like object.
|
||||
* @param {function(this:T,?,?,S):?} f The function to call for every value.
|
||||
* This function takes
|
||||
* 3 arguments (the value, the key or undefined if the collection has no
|
||||
* notion of keys, and the collection) and the return value is irrelevant.
|
||||
* @param {T=} opt_obj The object to be used as the value of 'this'
|
||||
* within {@code f}.
|
||||
* @template T,S
|
||||
*/
|
||||
goog.structs.forEach = function(col, f, opt_obj) {
|
||||
if (col.forEach && typeof col.forEach == 'function') {
|
||||
col.forEach(f, opt_obj);
|
||||
} else if (goog.isArrayLike(col) || goog.isString(col)) {
|
||||
goog.array.forEach(/** @type {!Array<?>} */ (col), f, opt_obj);
|
||||
} else {
|
||||
var keys = goog.structs.getKeys(col);
|
||||
var values = goog.structs.getValues(col);
|
||||
var l = values.length;
|
||||
for (var i = 0; i < l; i++) {
|
||||
f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls a function for every value in the collection. When a call returns true,
|
||||
* adds the value to a new collection (Array is returned by default).
|
||||
*
|
||||
* @param {S} col The collection-like object.
|
||||
* @param {function(this:T,?,?,S):boolean} f The function to call for every
|
||||
* value. This function takes
|
||||
* 3 arguments (the value, the key or undefined if the collection has no
|
||||
* notion of keys, and the collection) and should return a Boolean. If the
|
||||
* return value is true the value is added to the result collection. If it
|
||||
* is false the value is not included.
|
||||
* @param {T=} opt_obj The object to be used as the value of 'this'
|
||||
* within {@code f}.
|
||||
* @return {!Object|!Array<?>} A new collection where the passed values are
|
||||
* present. If col is a key-less collection an array is returned. If col
|
||||
* has keys and values a plain old JS object is returned.
|
||||
* @template T,S
|
||||
*/
|
||||
goog.structs.filter = function(col, f, opt_obj) {
|
||||
if (typeof col.filter == 'function') {
|
||||
return col.filter(f, opt_obj);
|
||||
}
|
||||
if (goog.isArrayLike(col) || goog.isString(col)) {
|
||||
return goog.array.filter(/** @type {!Array<?>} */ (col), f, opt_obj);
|
||||
}
|
||||
|
||||
var rv;
|
||||
var keys = goog.structs.getKeys(col);
|
||||
var values = goog.structs.getValues(col);
|
||||
var l = values.length;
|
||||
if (keys) {
|
||||
rv = {};
|
||||
for (var i = 0; i < l; i++) {
|
||||
if (f.call(/** @type {?} */ (opt_obj), values[i], keys[i], col)) {
|
||||
rv[keys[i]] = values[i];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We should not use goog.array.filter here since we want to make sure that
|
||||
// the index is undefined as well as make sure that col is passed to the
|
||||
// function.
|
||||
rv = [];
|
||||
for (var i = 0; i < l; i++) {
|
||||
if (f.call(opt_obj, values[i], undefined, col)) {
|
||||
rv.push(values[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls a function for every value in the collection and adds the result into a
|
||||
* new collection (defaults to creating a new Array).
|
||||
*
|
||||
* @param {S} col The collection-like object.
|
||||
* @param {function(this:T,?,?,S):V} f The function to call for every value.
|
||||
* This function takes 3 arguments (the value, the key or undefined if the
|
||||
* collection has no notion of keys, and the collection) and should return
|
||||
* something. The result will be used as the value in the new collection.
|
||||
* @param {T=} opt_obj The object to be used as the value of 'this'
|
||||
* within {@code f}.
|
||||
* @return {!Object<V>|!Array<V>} A new collection with the new values. If
|
||||
* col is a key-less collection an array is returned. If col has keys and
|
||||
* values a plain old JS object is returned.
|
||||
* @template T,S,V
|
||||
*/
|
||||
goog.structs.map = function(col, f, opt_obj) {
|
||||
if (typeof col.map == 'function') {
|
||||
return col.map(f, opt_obj);
|
||||
}
|
||||
if (goog.isArrayLike(col) || goog.isString(col)) {
|
||||
return goog.array.map(/** @type {!Array<?>} */ (col), f, opt_obj);
|
||||
}
|
||||
|
||||
var rv;
|
||||
var keys = goog.structs.getKeys(col);
|
||||
var values = goog.structs.getValues(col);
|
||||
var l = values.length;
|
||||
if (keys) {
|
||||
rv = {};
|
||||
for (var i = 0; i < l; i++) {
|
||||
rv[keys[i]] = f.call(/** @type {?} */ (opt_obj), values[i], keys[i], col);
|
||||
}
|
||||
} else {
|
||||
// We should not use goog.array.map here since we want to make sure that
|
||||
// the index is undefined as well as make sure that col is passed to the
|
||||
// function.
|
||||
rv = [];
|
||||
for (var i = 0; i < l; i++) {
|
||||
rv[i] = f.call(/** @type {?} */ (opt_obj), values[i], undefined, col);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls f for each value in a collection. If any call returns true this returns
|
||||
* true (without checking the rest). If all returns false this returns false.
|
||||
*
|
||||
* @param {S} col The collection-like object.
|
||||
* @param {function(this:T,?,?,S):boolean} f The function to call for every
|
||||
* value. This function takes 3 arguments (the value, the key or undefined
|
||||
* if the collection has no notion of keys, and the collection) and should
|
||||
* return a boolean.
|
||||
* @param {T=} opt_obj The object to be used as the value of 'this'
|
||||
* within {@code f}.
|
||||
* @return {boolean} True if any value passes the test.
|
||||
* @template T,S
|
||||
*/
|
||||
goog.structs.some = function(col, f, opt_obj) {
|
||||
if (typeof col.some == 'function') {
|
||||
return col.some(f, opt_obj);
|
||||
}
|
||||
if (goog.isArrayLike(col) || goog.isString(col)) {
|
||||
return goog.array.some(/** @type {!Array<?>} */ (col), f, opt_obj);
|
||||
}
|
||||
var keys = goog.structs.getKeys(col);
|
||||
var values = goog.structs.getValues(col);
|
||||
var l = values.length;
|
||||
for (var i = 0; i < l; i++) {
|
||||
if (f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls f for each value in a collection. If all calls return true this return
|
||||
* true this returns true. If any returns false this returns false at this point
|
||||
* and does not continue to check the remaining values.
|
||||
*
|
||||
* @param {S} col The collection-like object.
|
||||
* @param {function(this:T,?,?,S):boolean} f The function to call for every
|
||||
* value. This function takes 3 arguments (the value, the key or
|
||||
* undefined if the collection has no notion of keys, and the collection)
|
||||
* and should return a boolean.
|
||||
* @param {T=} opt_obj The object to be used as the value of 'this'
|
||||
* within {@code f}.
|
||||
* @return {boolean} True if all key-value pairs pass the test.
|
||||
* @template T,S
|
||||
*/
|
||||
goog.structs.every = function(col, f, opt_obj) {
|
||||
if (typeof col.every == 'function') {
|
||||
return col.every(f, opt_obj);
|
||||
}
|
||||
if (goog.isArrayLike(col) || goog.isString(col)) {
|
||||
return goog.array.every(/** @type {!Array<?>} */ (col), f, opt_obj);
|
||||
}
|
||||
var keys = goog.structs.getKeys(col);
|
||||
var values = goog.structs.getValues(col);
|
||||
var l = values.length;
|
||||
for (var i = 0; i < l; i++) {
|
||||
if (!f.call(/** @type {?} */ (opt_obj), values[i], keys && keys[i], col)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
};
|
||||
1526
resources/public/js/compiled/out/goog/uri/uri.js
Normal file
1526
resources/public/js/compiled/out/goog/uri/uri.js
Normal file
File diff suppressed because it is too large
Load diff
1069
resources/public/js/compiled/out/goog/uri/utils.js
Normal file
1069
resources/public/js/compiled/out/goog/uri/utils.js
Normal file
File diff suppressed because it is too large
Load diff
181
resources/public/js/compiled/out/goog/useragent/product.js
Normal file
181
resources/public/js/compiled/out/goog/useragent/product.js
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Detects the specific browser and not just the rendering engine.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.userAgent.product');
|
||||
|
||||
goog.require('goog.labs.userAgent.browser');
|
||||
goog.require('goog.labs.userAgent.platform');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the code is running on the Firefox web browser.
|
||||
*/
|
||||
goog.define('goog.userAgent.product.ASSUME_FIREFOX', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the product is an
|
||||
* iPhone.
|
||||
*/
|
||||
goog.define('goog.userAgent.product.ASSUME_IPHONE', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the product is an
|
||||
* iPad.
|
||||
*/
|
||||
goog.define('goog.userAgent.product.ASSUME_IPAD', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the product is an
|
||||
* AOSP browser or WebView inside a pre KitKat Android phone or tablet.
|
||||
*/
|
||||
goog.define('goog.userAgent.product.ASSUME_ANDROID', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the code is running on the Chrome web browser on
|
||||
* any platform or AOSP browser or WebView in a KitKat+ Android phone or tablet.
|
||||
*/
|
||||
goog.define('goog.userAgent.product.ASSUME_CHROME', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the code is running on the Safari web browser.
|
||||
*/
|
||||
goog.define('goog.userAgent.product.ASSUME_SAFARI', false);
|
||||
|
||||
|
||||
/**
|
||||
* Whether we know the product type at compile-time.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.product.PRODUCT_KNOWN_ = goog.userAgent.ASSUME_IE ||
|
||||
goog.userAgent.ASSUME_EDGE || goog.userAgent.ASSUME_OPERA ||
|
||||
goog.userAgent.product.ASSUME_FIREFOX ||
|
||||
goog.userAgent.product.ASSUME_IPHONE ||
|
||||
goog.userAgent.product.ASSUME_IPAD ||
|
||||
goog.userAgent.product.ASSUME_ANDROID ||
|
||||
goog.userAgent.product.ASSUME_CHROME ||
|
||||
goog.userAgent.product.ASSUME_SAFARI;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the code is running on the Opera web browser.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.product.OPERA = goog.userAgent.OPERA;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the code is running on an IE web browser.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.product.IE = goog.userAgent.IE;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the code is running on an Edge web browser.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.product.EDGE = goog.userAgent.EDGE;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the code is running on the Firefox web browser.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.product.FIREFOX = goog.userAgent.product.PRODUCT_KNOWN_ ?
|
||||
goog.userAgent.product.ASSUME_FIREFOX :
|
||||
goog.labs.userAgent.browser.isFirefox();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is an iPhone or iPod (as in iPod touch).
|
||||
* @return {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.product.isIphoneOrIpod_ = function() {
|
||||
return goog.labs.userAgent.platform.isIphone() ||
|
||||
goog.labs.userAgent.platform.isIpod();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the code is running on an iPhone or iPod touch.
|
||||
*
|
||||
* iPod touch is considered an iPhone for legacy reasons.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.product.IPHONE = goog.userAgent.product.PRODUCT_KNOWN_ ?
|
||||
goog.userAgent.product.ASSUME_IPHONE :
|
||||
goog.userAgent.product.isIphoneOrIpod_();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the code is running on an iPad.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.product.IPAD = goog.userAgent.product.PRODUCT_KNOWN_ ?
|
||||
goog.userAgent.product.ASSUME_IPAD :
|
||||
goog.labs.userAgent.platform.isIpad();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the code is running on AOSP browser or WebView inside
|
||||
* a pre KitKat Android phone or tablet.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.product.ANDROID = goog.userAgent.product.PRODUCT_KNOWN_ ?
|
||||
goog.userAgent.product.ASSUME_ANDROID :
|
||||
goog.labs.userAgent.browser.isAndroidBrowser();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the code is running on the Chrome web browser on any platform
|
||||
* or AOSP browser or WebView in a KitKat+ Android phone or tablet.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.product.CHROME = goog.userAgent.product.PRODUCT_KNOWN_ ?
|
||||
goog.userAgent.product.ASSUME_CHROME :
|
||||
goog.labs.userAgent.browser.isChrome();
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the browser is Safari on desktop.
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.product.isSafariDesktop_ = function() {
|
||||
return goog.labs.userAgent.browser.isSafari() &&
|
||||
!goog.labs.userAgent.platform.isIos();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the code is running on the desktop Safari web browser.
|
||||
* Note: the legacy behavior here is only true for Safari not running
|
||||
* on iOS.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.product.SAFARI = goog.userAgent.product.PRODUCT_KNOWN_ ?
|
||||
goog.userAgent.product.ASSUME_SAFARI :
|
||||
goog.userAgent.product.isSafariDesktop_();
|
||||
568
resources/public/js/compiled/out/goog/useragent/useragent.js
Normal file
568
resources/public/js/compiled/out/goog/useragent/useragent.js
Normal file
|
|
@ -0,0 +1,568 @@
|
|||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Rendering engine detection.
|
||||
* @see <a href="http://www.useragentstring.com/">User agent strings</a>
|
||||
* For information on the browser brand (such as Safari versus Chrome), see
|
||||
* goog.userAgent.product.
|
||||
* @author arv@google.com (Erik Arvidsson)
|
||||
* @see ../demos/useragent.html
|
||||
*/
|
||||
|
||||
goog.provide('goog.userAgent');
|
||||
|
||||
goog.require('goog.labs.userAgent.browser');
|
||||
goog.require('goog.labs.userAgent.engine');
|
||||
goog.require('goog.labs.userAgent.platform');
|
||||
goog.require('goog.labs.userAgent.util');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the browser is IE.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_IE', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the browser is EDGE.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_EDGE', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the browser is GECKO.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_GECKO', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the browser is WEBKIT.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_WEBKIT', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the browser is a
|
||||
* mobile device running WebKit e.g. iPhone or Android.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_MOBILE_WEBKIT', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether we know at compile-time that the browser is OPERA.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_OPERA', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the
|
||||
* {@code goog.userAgent.isVersionOrHigher}
|
||||
* function will return true for any version.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_ANY_VERSION', false);
|
||||
|
||||
|
||||
/**
|
||||
* Whether we know the browser engine at compile-time.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.BROWSER_KNOWN_ = goog.userAgent.ASSUME_IE ||
|
||||
goog.userAgent.ASSUME_EDGE || goog.userAgent.ASSUME_GECKO ||
|
||||
goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.ASSUME_WEBKIT ||
|
||||
goog.userAgent.ASSUME_OPERA;
|
||||
|
||||
|
||||
/**
|
||||
* Returns the userAgent string for the current browser.
|
||||
*
|
||||
* @return {string} The userAgent string.
|
||||
*/
|
||||
goog.userAgent.getUserAgentString = function() {
|
||||
return goog.labs.userAgent.util.getUserAgent();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* TODO(nnaze): Change type to "Navigator" and update compilation targets.
|
||||
* @return {Object} The native navigator object.
|
||||
*/
|
||||
goog.userAgent.getNavigator = function() {
|
||||
// Need a local navigator reference instead of using the global one,
|
||||
// to avoid the rare case where they reference different objects.
|
||||
// (in a WorkerPool, for example).
|
||||
return goog.global['navigator'] || null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is Opera.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.OPERA = goog.userAgent.BROWSER_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_OPERA :
|
||||
goog.labs.userAgent.browser.isOpera();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is Internet Explorer.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.IE = goog.userAgent.BROWSER_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_IE :
|
||||
goog.labs.userAgent.browser.isIE();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is Microsoft Edge.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.EDGE = goog.userAgent.BROWSER_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_EDGE :
|
||||
goog.labs.userAgent.engine.isEdge();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is MS Internet Explorer or MS Edge.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.EDGE_OR_IE = goog.userAgent.EDGE || goog.userAgent.IE;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is Gecko. Gecko is the rendering engine used by
|
||||
* Mozilla, Firefox, and others.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.GECKO = goog.userAgent.BROWSER_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_GECKO :
|
||||
goog.labs.userAgent.engine.isGecko();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is WebKit. WebKit is the rendering engine that
|
||||
* Safari, Android and others use.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.WEBKIT = goog.userAgent.BROWSER_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_WEBKIT || goog.userAgent.ASSUME_MOBILE_WEBKIT :
|
||||
goog.labs.userAgent.engine.isWebKit();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on a mobile device.
|
||||
*
|
||||
* This is a separate function so that the logic can be tested.
|
||||
*
|
||||
* TODO(nnaze): Investigate swapping in goog.labs.userAgent.device.isMobile().
|
||||
*
|
||||
* @return {boolean} Whether the user agent is running on a mobile device.
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.isMobile_ = function() {
|
||||
return goog.userAgent.WEBKIT &&
|
||||
goog.labs.userAgent.util.matchUserAgent('Mobile');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on a mobile device.
|
||||
*
|
||||
* TODO(nnaze): Consider deprecating MOBILE when labs.userAgent
|
||||
* is promoted as the gecko/webkit logic is likely inaccurate.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.MOBILE =
|
||||
goog.userAgent.ASSUME_MOBILE_WEBKIT || goog.userAgent.isMobile_();
|
||||
|
||||
|
||||
/**
|
||||
* Used while transitioning code to use WEBKIT instead.
|
||||
* @type {boolean}
|
||||
* @deprecated Use {@link goog.userAgent.product.SAFARI} instead.
|
||||
* TODO(nicksantos): Delete this from goog.userAgent.
|
||||
*/
|
||||
goog.userAgent.SAFARI = goog.userAgent.WEBKIT;
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} the platform (operating system) the user agent is running
|
||||
* on. Default to empty string because navigator.platform may not be defined
|
||||
* (on Rhino, for example).
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.determinePlatform_ = function() {
|
||||
var navigator = goog.userAgent.getNavigator();
|
||||
return navigator && navigator.platform || '';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The platform (operating system) the user agent is running on. Default to
|
||||
* empty string because navigator.platform may not be defined (on Rhino, for
|
||||
* example).
|
||||
* @type {string}
|
||||
*/
|
||||
goog.userAgent.PLATFORM = goog.userAgent.determinePlatform_();
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on a Macintosh operating
|
||||
* system.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_MAC', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on a Windows operating
|
||||
* system.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_WINDOWS', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on a Linux operating
|
||||
* system.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_LINUX', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on a X11 windowing
|
||||
* system.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_X11', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on Android.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_ANDROID', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on an iPhone.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_IPHONE', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on an iPad.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_IPAD', false);
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether the user agent is running on an iPod.
|
||||
*/
|
||||
goog.define('goog.userAgent.ASSUME_IPOD', false);
|
||||
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.PLATFORM_KNOWN_ = goog.userAgent.ASSUME_MAC ||
|
||||
goog.userAgent.ASSUME_WINDOWS || goog.userAgent.ASSUME_LINUX ||
|
||||
goog.userAgent.ASSUME_X11 || goog.userAgent.ASSUME_ANDROID ||
|
||||
goog.userAgent.ASSUME_IPHONE || goog.userAgent.ASSUME_IPAD ||
|
||||
goog.userAgent.ASSUME_IPOD;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on a Macintosh operating system.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.MAC = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_MAC :
|
||||
goog.labs.userAgent.platform.isMacintosh();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on a Windows operating system.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.WINDOWS = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_WINDOWS :
|
||||
goog.labs.userAgent.platform.isWindows();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is Linux per the legacy behavior of
|
||||
* goog.userAgent.LINUX, which considered ChromeOS to also be
|
||||
* Linux.
|
||||
* @return {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.isLegacyLinux_ = function() {
|
||||
return goog.labs.userAgent.platform.isLinux() ||
|
||||
goog.labs.userAgent.platform.isChromeOS();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on a Linux operating system.
|
||||
*
|
||||
* Note that goog.userAgent.LINUX considers ChromeOS to be Linux,
|
||||
* while goog.labs.userAgent.platform considers ChromeOS and
|
||||
* Linux to be different OSes.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.LINUX = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_LINUX :
|
||||
goog.userAgent.isLegacyLinux_();
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} Whether the user agent is an X11 windowing system.
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.isX11_ = function() {
|
||||
var navigator = goog.userAgent.getNavigator();
|
||||
return !!navigator &&
|
||||
goog.string.contains(navigator['appVersion'] || '', 'X11');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on a X11 windowing system.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.X11 = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_X11 :
|
||||
goog.userAgent.isX11_();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on Android.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.ANDROID = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_ANDROID :
|
||||
goog.labs.userAgent.platform.isAndroid();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on an iPhone.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.IPHONE = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_IPHONE :
|
||||
goog.labs.userAgent.platform.isIphone();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on an iPad.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.IPAD = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_IPAD :
|
||||
goog.labs.userAgent.platform.isIpad();
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent is running on an iPod.
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.userAgent.IPOD = goog.userAgent.PLATFORM_KNOWN_ ?
|
||||
goog.userAgent.ASSUME_IPOD :
|
||||
goog.labs.userAgent.platform.isIpod();
|
||||
|
||||
|
||||
/**
|
||||
* @return {string} The string that describes the version number of the user
|
||||
* agent.
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.determineVersion_ = function() {
|
||||
// All browsers have different ways to detect the version and they all have
|
||||
// different naming schemes.
|
||||
// version is a string rather than a number because it may contain 'b', 'a',
|
||||
// and so on.
|
||||
var version = '';
|
||||
var arr = goog.userAgent.getVersionRegexResult_();
|
||||
if (arr) {
|
||||
version = arr ? arr[1] : '';
|
||||
}
|
||||
|
||||
if (goog.userAgent.IE) {
|
||||
// IE9 can be in document mode 9 but be reporting an inconsistent user agent
|
||||
// version. If it is identifying as a version lower than 9 we take the
|
||||
// documentMode as the version instead. IE8 has similar behavior.
|
||||
// It is recommended to set the X-UA-Compatible header to ensure that IE9
|
||||
// uses documentMode 9.
|
||||
var docMode = goog.userAgent.getDocumentMode_();
|
||||
if (docMode != null && docMode > parseFloat(version)) {
|
||||
return String(docMode);
|
||||
}
|
||||
}
|
||||
|
||||
return version;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {?Array|undefined} The version regex matches from parsing the user
|
||||
* agent string. These regex statements must be executed inline so they can
|
||||
* be compiled out by the closure compiler with the rest of the useragent
|
||||
* detection logic when ASSUME_* is specified.
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.getVersionRegexResult_ = function() {
|
||||
var userAgent = goog.userAgent.getUserAgentString();
|
||||
if (goog.userAgent.GECKO) {
|
||||
return /rv\:([^\);]+)(\)|;)/.exec(userAgent);
|
||||
}
|
||||
if (goog.userAgent.EDGE) {
|
||||
return /Edge\/([\d\.]+)/.exec(userAgent);
|
||||
}
|
||||
if (goog.userAgent.IE) {
|
||||
return /\b(?:MSIE|rv)[: ]([^\);]+)(\)|;)/.exec(userAgent);
|
||||
}
|
||||
if (goog.userAgent.WEBKIT) {
|
||||
// WebKit/125.4
|
||||
return /WebKit\/(\S+)/.exec(userAgent);
|
||||
}
|
||||
if (goog.userAgent.OPERA) {
|
||||
// If none of the above browsers were detected but the browser is Opera, the
|
||||
// only string that is of interest is 'Version/<number>'.
|
||||
return /(?:Version)[ \/]?(\S+)/.exec(userAgent);
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number|undefined} Returns the document mode (for testing).
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.getDocumentMode_ = function() {
|
||||
// NOTE(user): goog.userAgent may be used in context where there is no DOM.
|
||||
var doc = goog.global['document'];
|
||||
return doc ? doc['documentMode'] : undefined;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The version of the user agent. This is a string because it might contain
|
||||
* 'b' (as in beta) as well as multiple dots.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.userAgent.VERSION = goog.userAgent.determineVersion_();
|
||||
|
||||
|
||||
/**
|
||||
* Compares two version numbers.
|
||||
*
|
||||
* @param {string} v1 Version of first item.
|
||||
* @param {string} v2 Version of second item.
|
||||
*
|
||||
* @return {number} 1 if first argument is higher
|
||||
* 0 if arguments are equal
|
||||
* -1 if second argument is higher.
|
||||
* @deprecated Use goog.string.compareVersions.
|
||||
*/
|
||||
goog.userAgent.compare = function(v1, v2) {
|
||||
return goog.string.compareVersions(v1, v2);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Cache for {@link goog.userAgent.isVersionOrHigher}.
|
||||
* Calls to compareVersions are surprisingly expensive and, as a browser's
|
||||
* version number is unlikely to change during a session, we cache the results.
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
goog.userAgent.isVersionOrHigherCache_ = {};
|
||||
|
||||
|
||||
/**
|
||||
* Whether the user agent version is higher or the same as the given version.
|
||||
* NOTE: When checking the version numbers for Firefox and Safari, be sure to
|
||||
* use the engine's version, not the browser's version number. For example,
|
||||
* Firefox 3.0 corresponds to Gecko 1.9 and Safari 3.0 to Webkit 522.11.
|
||||
* Opera and Internet Explorer versions match the product release number.<br>
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Safari_version_history">
|
||||
* Webkit</a>
|
||||
* @see <a href="http://en.wikipedia.org/wiki/Gecko_engine">Gecko</a>
|
||||
*
|
||||
* @param {string|number} version The version to check.
|
||||
* @return {boolean} Whether the user agent version is higher or the same as
|
||||
* the given version.
|
||||
*/
|
||||
goog.userAgent.isVersionOrHigher = function(version) {
|
||||
return goog.userAgent.ASSUME_ANY_VERSION ||
|
||||
goog.userAgent.isVersionOrHigherCache_[version] ||
|
||||
(goog.userAgent.isVersionOrHigherCache_[version] =
|
||||
goog.string.compareVersions(goog.userAgent.VERSION, version) >= 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deprecated alias to {@code goog.userAgent.isVersionOrHigher}.
|
||||
* @param {string|number} version The version to check.
|
||||
* @return {boolean} Whether the user agent version is higher or the same as
|
||||
* the given version.
|
||||
* @deprecated Use goog.userAgent.isVersionOrHigher().
|
||||
*/
|
||||
goog.userAgent.isVersion = goog.userAgent.isVersionOrHigher;
|
||||
|
||||
|
||||
/**
|
||||
* Whether the IE effective document mode is higher or the same as the given
|
||||
* document mode version.
|
||||
* NOTE: Only for IE, return false for another browser.
|
||||
*
|
||||
* @param {number} documentMode The document mode version to check.
|
||||
* @return {boolean} Whether the IE effective document mode is higher or the
|
||||
* same as the given version.
|
||||
*/
|
||||
goog.userAgent.isDocumentModeOrHigher = function(documentMode) {
|
||||
return Number(goog.userAgent.DOCUMENT_MODE) >= documentMode;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Deprecated alias to {@code goog.userAgent.isDocumentModeOrHigher}.
|
||||
* @param {number} version The version to check.
|
||||
* @return {boolean} Whether the IE effective document mode is higher or the
|
||||
* same as the given version.
|
||||
* @deprecated Use goog.userAgent.isDocumentModeOrHigher().
|
||||
*/
|
||||
goog.userAgent.isDocumentMode = goog.userAgent.isDocumentModeOrHigher;
|
||||
|
||||
|
||||
/**
|
||||
* For IE version < 7, documentMode is undefined, so attempt to use the
|
||||
* CSS1Compat property to see if we are in standards mode. If we are in
|
||||
* standards mode, treat the browser version as the document mode. Otherwise,
|
||||
* IE is emulating version 5.
|
||||
* @type {number|undefined}
|
||||
* @const
|
||||
*/
|
||||
goog.userAgent.DOCUMENT_MODE = (function() {
|
||||
var doc = goog.global['document'];
|
||||
var mode = goog.userAgent.getDocumentMode_();
|
||||
if (!doc || !goog.userAgent.IE) {
|
||||
return undefined;
|
||||
}
|
||||
return mode || (doc['compatMode'] == 'CSS1Compat' ?
|
||||
parseInt(goog.userAgent.VERSION, 10) :
|
||||
5);
|
||||
})();
|
||||
Loading…
Add table
Add a link
Reference in a new issue