diff --git a/.settings/.jsdtscope b/.settings/.jsdtscope index 9b81d1916813..1c2e32de9e23 100644 --- a/.settings/.jsdtscope +++ b/.settings/.jsdtscope @@ -1,6 +1,6 @@ - + diff --git a/.settings/com.eclipsesource.jshint.ui.prefs b/.settings/com.eclipsesource.jshint.ui.prefs index cbcc2c89d885..001a9b6c2b7d 100644 --- a/.settings/com.eclipsesource.jshint.ui.prefs +++ b/.settings/com.eclipsesource.jshint.ui.prefs @@ -1,5 +1,5 @@ eclipse.preferences.version=1 -excluded=Apps/Sandcastle/Cesium-hint.js\:Source/ThirdParty/Chain.js\:Source/ThirdParty/Tween.js\:Source/ThirdParty/when.js\:Source/Workers/cesiumWorkerBootstrapper.js\:ThirdParty//* +excluded=Apps/Sandcastle/Cesium-hint.js\:Source/ThirdParty/Chain.js\:Source/ThirdParty/Tween.js\:Source/ThirdParty/Uri.js\:Source/ThirdParty/sprintf.js\:Source/ThirdParty/when.js\:Source/Workers/cesiumWorkerBootstrapper.js\:ThirdParty//* included=//*.js options=bitwise \: false,\r\ncamelcase \: false,\r\ncurly \: true,\r\neqeqeq \: true,\r\nforin \: true,\r\nimmed \: false,\r\nlatedef \: true,\r\nnewcap \: true,\r\nnoarg \: true,\r\nnoempty \: false,\r\nnonew \: true,\r\nplusplus \: false,\r\nquotmark \: false,\r\nregexp \: false,\r\nundef \: true,\r\nunused \: false,\r\nstrict \: true,\r\ntrailing \: true,\r\nasi \: false,\r\nboss \: false,\r\ndebug \: false,\r\neqnull \: false,\r\nes5 \: false,\r\nesnext \: false,\r\nevil \: false,\r\nexpr \: false,\r\nfuncscope \: false,\r\nglobalstrict \: false,\r\niterator \: false,\r\nlastsemic \: false,\r\nlaxbreak \: false,\r\nlaxcomma \: false,\r\nloopfunc \: false,\r\nmultistr \: false,\r\nonecase \: false,\r\nproto \: false,\r\nregexdash \: false,\r\nscripturl \: false,\r\nsmarttabs \: false,\r\nshadow \: false,\r\nsub \: false,\r\nsupernew \: false,\r\nvalidthis \: false,\r\nbrowser \: true projectSpecificOptions=true diff --git a/Apps/CesiumViewer/CesiumViewer.profile.js b/Apps/CesiumViewer/CesiumViewer.profile.js index 90e9be0b4996..0972ccaf2228 100755 --- a/Apps/CesiumViewer/CesiumViewer.profile.js +++ b/Apps/CesiumViewer/CesiumViewer.profile.js @@ -13,7 +13,8 @@ var profile = { 'dojo/dojo' : { include : ['dojo/dojo', 'CesiumViewer/CesiumViewer', 'CesiumViewer/boot'], boot : true, - customBase : true + customBase : true, + copyright : 'Source/copyrightHeader.js' } }, diff --git a/LICENSE.md b/LICENSE.md index fe5791838e68..afe0f5906d49 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -43,7 +43,7 @@ http://hg.grauw.nl/grauw-lib > > 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. -### when +### when.js https://github.com/cujojs/when @@ -128,48 +128,6 @@ https://github.com/Pomax/fontmetrics.js > > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -### Microsoft - -http://msdn.microsoft.com/en-us/library/bb259689.aspx - -http://msdn.microsoft.com/en-us/cc300389.aspx#O - -> Copyright (c) 2006-2009 Microsoft Corporation. All rights reserved. -> -> MICROSOFT LIMITED PUBLIC LICENSE -> -> This license governs use of code marked as "sample" or "example" available on this web site without a license agreement, as provided under the section above titled "NOTICE SPECIFIC TO SOFTWARE AVAILABLE ON THIS WEB SITE." If you use such code (the "software"), you accept this license. If you do not accept the license, do not use the software. -> -> 1. Definitions -> -> The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. -> -> A "contribution" is the original software, or any additions or changes to the software. -> -> A "contributor" is any person that distributes its contribution under this license. -> -> "Licensed patents" are a contributor's patent claims that read directly on its contribution. -> -> 2. Grant of Rights -> -> (A) Copyright Grant - Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. -> -> (B) Patent Grant - Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. -> -> 3. Conditions and Limitations -> -> (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. -> -> (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. -> -> (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. -> -> (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. -> -> (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. -> -> (F) Platform Limitation - The licenses granted in sections 2(A) and 2(B) extend only to the software or derivative works that you create that run on a Microsoft Windows operating system product. - ### almond https://github.com/jrburke/almond diff --git a/Source/Shaders/Noise.glsl b/Source/Shaders/Noise.glsl index 4d60f09c1f06..76181f301470 100644 --- a/Source/Shaders/Noise.glsl +++ b/Source/Shaders/Noise.glsl @@ -1,7 +1,8 @@ #ifndef czm_NOISE #define czm_NOISE 1 -/*! +/** + * @license * Description : Array and textureless GLSL 2D/3D/4D simplex * noise functions. * Author : Ian McEwan, Ashima Arts. @@ -285,7 +286,8 @@ float czm_snoise(vec4 v) /////////////////////////////////////////////////////////////////////////////// -/*! +/** + * @license * Cellular noise ("Worley noise") in 2D in GLSL. * Copyright (c) Stefan Gustavson 2011-04-19. All rights reserved. * This code is released under the conditions of the MIT license. diff --git a/Source/Shaders/SkyAtmosphereFS.glsl b/Source/Shaders/SkyAtmosphereFS.glsl index 2e494a95cce0..851d77484196 100644 --- a/Source/Shaders/SkyAtmosphereFS.glsl +++ b/Source/Shaders/SkyAtmosphereFS.glsl @@ -1,4 +1,5 @@ -/*! +/** + * @license * Copyright (c) 2000-2005, Sean O'Neil (s_p_oneil@hotmail.com) * All rights reserved. * diff --git a/Source/Shaders/SkyAtmosphereVS.glsl b/Source/Shaders/SkyAtmosphereVS.glsl index be4ed8174195..153004f848f9 100644 --- a/Source/Shaders/SkyAtmosphereVS.glsl +++ b/Source/Shaders/SkyAtmosphereVS.glsl @@ -1,4 +1,5 @@ -/*! +/** + * @license * Copyright (c) 2000-2005, Sean O'Neil (s_p_oneil@hotmail.com) * All rights reserved. * diff --git a/Source/ThirdParty/Tween.js b/Source/ThirdParty/Tween.js index d11cdc12dca8..bf0892744893 100644 --- a/Source/ThirdParty/Tween.js +++ b/Source/ThirdParty/Tween.js @@ -1,3 +1,30 @@ +/** +@license +tween.js - https://github.com/sole/tween.js + +Copyright (c) 2010-2012 Tween.js authors. + +Easing equations Copyright (c) 2001 Robert Penner http://robertpenner.com/easing/ + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + /** * @author sole / http://soledadpenades.com * @author mrdoob / http://mrdoob.com diff --git a/Source/ThirdParty/Uri.js b/Source/ThirdParty/Uri.js index 5b95b00adcd8..a2cdb3d806e3 100644 --- a/Source/ThirdParty/Uri.js +++ b/Source/ThirdParty/Uri.js @@ -1,7 +1,8 @@ /** + * @license * @fileOverview * - * Grauw Uri utilities + * Grauw URI utilities * * See: http://hg.grauw.nl/grauw-lib/file/tip/src/uri.js * @@ -21,264 +22,261 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * Modifications made by Cesium to fit into our build system as well as fix warnings. */ /*global define*/ define(function() { - "use strict"; - /*global unescape*/ - // Regular expression from RFC 3986 appendix B - var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); + /** + * Constructs a URI object. + * @constructor + * @class Implementation of URI parsing and base URI resolving algorithm in RFC 3986. + * @param {string|URI} uri A string or URI object to create the object from. + */ + function URI(uri) { + if (uri instanceof URI) { // copy constructor + this.scheme = uri.scheme; + this.authority = uri.authority; + this.path = uri.path; + this.query = uri.query; + this.fragment = uri.fragment; + } else if (uri) { // uri is URI string or cast to string + var c = parseRegex.exec(uri); + this.scheme = c[1]; + this.authority = c[2]; + this.path = c[3]; + this.query = c[4]; + this.fragment = c[5]; + } + }; - var caseRegex = /%[0-9a-z]{2}/gi; - var percentRegex = /[a-zA-Z0-9\-\._~]/; - var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; + // Initial values on the prototype + URI.prototype.scheme = null; + URI.prototype.authority = null; + URI.prototype.path = ''; + URI.prototype.query = null; + URI.prototype.fragment = null; - /** - * Constructs a Uri object. - * @constructor - * @class Implementation of Uri parsing and base Uri resolving algorithm in RFC 3986. - * @param {string|Uri} uri A string or Uri object to create the object from. - */ - function Uri(uri) { - if (uri instanceof Uri) { // copy constructor - this.scheme = uri.scheme; - this.authority = uri.authority; - this.path = uri.path; - this.query = uri.query; - this.fragment = uri.fragment; - } else if (uri) { // uri is Uri string or cast to string - var c = parseRegex.exec(uri); - this.scheme = c[1]; - this.authority = c[2]; - this.path = c[3]; - this.query = c[4]; - this.fragment = c[5]; - } - } + // Regular expression from RFC 3986 appendix B + var parseRegex = new RegExp('^(?:([^:/?#]+):)?(?://([^/?#]*))?([^?#]*)(?:\\?([^#]*))?(?:#(.*))?$'); - // Initial values on the prototype - Uri.prototype.scheme = null; - Uri.prototype.authority = null; - Uri.prototype.path = ''; - Uri.prototype.query = null; - Uri.prototype.fragment = null; + /** + * Returns the scheme part of the URI. + * In "http://example.com:80/a/b?x#y" this is "http". + * @return + */ + URI.prototype.getScheme = function() { + return this.scheme; + }; - /** - * Returns the scheme part of the Uri. - * In "http://example.com:80/a/b?x#y" this is "http". - */ - Uri.prototype.getScheme = function() { - return this.scheme; - }; + /** + * Returns the authority part of the URI. + * In "http://example.com:80/a/b?x#y" this is "example.com:80". + * @return + */ + URI.prototype.getAuthority = function() { + return this.authority; + }; - /** - * Returns the authority part of the Uri. - * In "http://example.com:80/a/b?x#y" this is "example.com:80". - */ - Uri.prototype.getAuthority = function() { - return this.authority; - }; + /** + * Returns the path part of the URI. + * In "http://example.com:80/a/b?x#y" this is "/a/b". + * In "mailto:mike@example.com" this is "mike@example.com". + * @return + */ + URI.prototype.getPath = function() { + return this.path; + }; - /** - * Returns the path part of the Uri. - * In "http://example.com:80/a/b?x#y" this is "/a/b". - * In "mailto:mike@example.com" this is "mike@example.com". - */ - Uri.prototype.getPath = function() { - return this.path; - }; + /** + * Returns the query part of the URI. + * In "http://example.com:80/a/b?x#y" this is "x". + * @return + */ + URI.prototype.getQuery = function() { + return this.query; + }; - /** - * Returns the query part of the Uri. - * In "http://example.com:80/a/b?x#y" this is "x". - */ - Uri.prototype.getQuery = function() { - return this.query; - }; + /** + * Returns the fragment part of the URI. + * In "http://example.com:80/a/b?x#y" this is "y". + * @return + */ + URI.prototype.getFragment = function() { + return this.fragment; + }; - /** - * Returns the fragment part of the Uri. - * In "http://example.com:80/a/b?x#y" this is "y". - */ - Uri.prototype.getFragment = function() { - return this.fragment; - }; + /** + * Tests whether the URI is an absolute URI. + * See RFC 3986 section 4.3. + */ + URI.prototype.isAbsolute = function() { + return !!this.scheme && !this.fragment; + }; - /** - * Tests whether the Uri is an absolute Uri. - * See RFC 3986 section 4.3. - */ - Uri.prototype.isAbsolute = function() { - return !!this.scheme && !this.fragment; - }; + ///** + //* Extensive validation of the URI against the ABNF in RFC 3986 + //*/ + //URI.prototype.validate - /** - * Tests whether the Uri is a same-document reference. - * See RFC 3986 section 4.4. - * - * To perform more thorough comparison, you can normalise the Uri objects. - */ - Uri.prototype.isSameDocumentAs = function(uri) { - return uri.scheme === this.scheme && uri.authority === this.authority && uri.path === this.path && uri.query === this.query; - }; + /** + * Tests whether the URI is a same-document reference. + * See RFC 3986 section 4.4. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.isSameDocumentAs = function(uri) { + return uri.scheme == this.scheme && + uri.authority == this.authority && + uri.path == this.path && + uri.query == this.query; + }; - /** - * Simple String Comparison of two Uris. - * See RFC 3986 section 6.2.1. - * - * To perform more thorough comparison, you can normalise the Uri objects. - */ - Uri.prototype.equals = function(uri) { - return this.isSameDocumentAs(uri) && uri.fragment === this.fragment; - }; + /** + * Simple String Comparison of two URIs. + * See RFC 3986 section 6.2.1. + * + * To perform more thorough comparison, you can normalise the URI objects. + */ + URI.prototype.equals = function(uri) { + return this.isSameDocumentAs(uri) && uri.fragment == this.fragment; + }; - /** - * Normalizes the Uri using syntax-based normalization. - * This includes case normalization, percent-encoding normalization and path segment normalization. - * XXX: Percent-encoding normalization does not escape characters that need to be escaped. - * (Although that would not be a valid Uri in the first place.) - * See RFC 3986 section 6.2.2. - */ - Uri.prototype.normalize = function() { - this.removeDotSegments(); - if (this.scheme) { - this.scheme = this.scheme.toLowerCase(); - } - if (this.authority) { - this.authority = this.authority.replace(authorityRegex, replaceAuthority).replace(caseRegex, replaceCase); - } - if (this.path) { - this.path = this.path.replace(caseRegex, replaceCase); - } - if (this.query) { - this.query = this.query.replace(caseRegex, replaceCase); - } - if (this.fragment) { - this.fragment = this.fragment.replace(caseRegex, replaceCase); - } - }; + /** + * Normalizes the URI using syntax-based normalization. + * This includes case normalization, percent-encoding normalization and path segment normalization. + * XXX: Percent-encoding normalization does not escape characters that need to be escaped. + * (Although that would not be a valid URI in the first place. See validate().) + * See RFC 3986 section 6.2.2. + */ + URI.prototype.normalize = function() { + this.removeDotSegments(); + if (this.scheme) + this.scheme = this.scheme.toLowerCase(); + if (this.authority) + this.authority = this.authority.replace(authorityRegex, replaceAuthority). + replace(caseRegex, replaceCase); + if (this.path) + this.path = this.path.replace(caseRegex, replaceCase); + if (this.query) + this.query = this.query.replace(caseRegex, replaceCase); + if (this.fragment) + this.fragment = this.fragment.replace(caseRegex, replaceCase); + }; - function replaceCase(str) { - var dec = unescape(str); - return percentRegex.test(dec) ? dec : str.toUpperCase(); - } + var caseRegex = /%[0-9a-z]{2}/gi; + var percentRegex = /[a-zA-Z0-9\-\._~]/; + var authorityRegex = /(.*@)?([^@:]*)(:.*)?/; - function replaceAuthority(str, p1, p2, p3) { - return (p1 || '') + p2.toLowerCase() + (p3 || ''); - } + function replaceCase(str) { + var dec = unescape(str); + return percentRegex.test(dec) ? dec : str.toUpperCase(); + } - /** - * Resolve a relative Uri (this) against a base Uri. - * The base Uri must be an absolute Uri. - * See RFC 3986 section 5.2 - */ - Uri.prototype.resolve = function(baseUri) { - var uri = new Uri(); - if (this.scheme) { - uri.scheme = this.scheme; - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.scheme = baseUri.scheme; - if (this.authority) { - uri.authority = this.authority; - uri.path = this.path; - uri.query = this.query; - } else { - uri.authority = baseUri.authority; - if (this.path === '') { - uri.path = baseUri.path; - uri.query = this.query || baseUri.query; - } else { - if (this.path.charAt(0) === '/') { - uri.path = this.path; - uri.removeDotSegments(); - } else { - if (baseUri.authority && baseUri.path === '') { - uri.path = '/' + this.path; - } else { - uri.path = baseUri.path.substring(0, baseUri.path.lastIndexOf('/') + 1) + this.path; - } - uri.removeDotSegments(); - } - uri.query = this.query; - } - } - } - uri.fragment = this.fragment; - return uri; - }; + function replaceAuthority(str, p1, p2, p3) { + return (p1 || '') + p2.toLowerCase() + (p3 || ''); + } - /** - * Remove dot segments from path. - * See RFC 3986 section 5.2.4 - * @private - */ - Uri.prototype.removeDotSegments = function() { - var input = this.path.split('/'), output = [], segment, absPath = input[0] === ''; - if (absPath) { - input.shift(); - } - if (input[0] === '') { - input.shift(); - } - while (input.length) { - segment = input.shift(); - if (segment === '..') { - output.pop(); - } else if (segment !== '.') { - output.push(segment); - } - } - if (segment === '.' || segment === '..') { - output.push(''); - } - if (absPath) { - output.unshift(''); - } - this.path = output.join('/'); - }; + /** + * Resolve a relative URI (this) against a base URI. + * The base URI must be an absolute URI. + * See RFC 3986 section 5.2 + */ + URI.prototype.resolve = function(baseURI) { + var uri = new URI(); + if (this.scheme) { + uri.scheme = this.scheme; + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.scheme = baseURI.scheme; + if (this.authority) { + uri.authority = this.authority; + uri.path = this.path; + uri.query = this.query; + } else { + uri.authority = baseURI.authority; + if (this.path == '') { + uri.path = baseURI.path; + uri.query = this.query || baseURI.query; + } else { + if (this.path.charAt(0) == '/') { + uri.path = this.path; + uri.removeDotSegments(); + } else { + if (baseURI.authority && baseURI.path == '') { + uri.path = '/' + this.path; + } else { + uri.path = baseURI.path.substring(0, baseURI.path.lastIndexOf('/') + 1) + this.path; + } + uri.removeDotSegments(); + } + uri.query = this.query; + } + } + } + uri.fragment = this.fragment; + return uri; + }; - var cache = {}; + /** + * Remove dot segments from path. + * See RFC 3986 section 5.2.4 + * @private + */ + URI.prototype.removeDotSegments = function() { + var input = this.path.split('/'), + output = [], + segment, + absPath = input[0] == ''; + if (absPath) + input.shift(); + var sFirst = input[0] == '' ? input.shift() : null; + while (input.length) { + segment = input.shift(); + if (segment == '..') { + output.pop(); + } else if (segment != '.') { + output.push(segment); + } + } + if (segment == '.' || segment == '..') + output.push(''); + if (absPath) + output.unshift(''); + this.path = output.join('/'); + }; - /** - * Resolves a relative Uri against an absolute base Uri. - * Convenience method. - * @param {String} uri the relative Uri to resolve - * @param {String} baseUri the base Uri (must be absolute) to resolve against - */ - Uri.resolve = function(sUri, sBaseUri) { - var uri = cache[sUri]; - if (typeof uri === 'undefined') { - cache[sUri] = new Uri(sUri); - } - var baseUri = cache[sBaseUri] || (cache[sBaseUri] = new Uri(sBaseUri)); - return uri.resolve(baseUri).toString(); - }; + /** + * Resolves a relative URI against an absolute base URI. + * Convenience method. + * @param {String} uri the relative URI to resolve + * @param {String} baseURI the base URI (must be absolute) to resolve against + */ + URI.resolve = function(sURI, sBaseURI) { + var uri = cache[sURI] || (cache[sURI] = new URI(sURI)); + var baseURI = cache[sBaseURI] || (cache[sBaseURI] = new URI(sBaseURI)); + return uri.resolve(baseURI).toString(); + }; - /** - * Serializes the Uri to a string. - */ - Uri.prototype.toString = function() { - var result = ''; - if (this.scheme) { - result += this.scheme + ':'; - } - if (this.authority) { - result += '//' + this.authority; - } - result += this.path; - if (this.query) { - result += '?' + this.query; - } - if (this.fragment) { - result += '#' + this.fragment; - } - return result; - }; + var cache = {}; - return Uri; + /** + * Serialises the URI to a string. + */ + URI.prototype.toString = function() { + var result = ''; + if (this.scheme) + result += this.scheme + ':'; + if (this.authority) + result += '//' + this.authority; + result += this.path; + if (this.query) + result += '?' + this.query; + if (this.fragment) + result += '#' + this.fragment; + return result; + }; + +return URI; }); diff --git a/Source/ThirdParty/measureText.js b/Source/ThirdParty/measureText.js index 3ecb6cf49c9e..61f1db806e11 100644 --- a/Source/ThirdParty/measureText.js +++ b/Source/ThirdParty/measureText.js @@ -1,17 +1,20 @@ -/*! +/** + @license + fontmetrics.js - https://github.com/Pomax/fontmetrics.js + This library rewrites the Canvas2D "measureText" function so that it returns a more complete metrics object. This library is licensed under the MIT (Expat) license, the text for which is included below. - ----------------------------------------------------------------------------- +** ----------------------------------------------------------------------------- CHANGELOG: 2012-01-21 - Whitespace handling added by Joe Turner (https://github.com/oampo) - ----------------------------------------------------------------------------- +** ----------------------------------------------------------------------------- Copyright (C) 2011 by Mike "Pomax" Kamermans @@ -32,63 +35,64 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ +**/ /*global define*/ define(function() { - "use strict"; -// var NAME = "FontMetrics Library"; -// var VERSION = "1-2012.0121.1300"; + /*jshint strict:false*/ +/* + var NAME = "FontMetrics Library" + var VERSION = "1-2012.0121.1300"; // if there is no getComputedStyle, this library won't work. -// if(!document.defaultView.getComputedStyle) { -// throw("ERROR: 'document.defaultView.getComputedStyle' not found. This library only works in browsers that can report computed CSS values."); -// } + if(!document.defaultView.getComputedStyle) { + throw("ERROR: 'document.defaultView.getComputedStyle' not found. This library only works in browsers that can report computed CSS values."); + } // store the old text metrics function on the Canvas2D prototype - //CanvasRenderingContext2D.prototype.measureTextWidth = CanvasRenderingContext2D.prototype.measureText; - + CanvasRenderingContext2D.prototype.measureTextWidth = CanvasRenderingContext2D.prototype.measureText; +*/ /** * shortcut function for getting computed CSS values */ var getCSSValue = function(element, property) { return document.defaultView.getComputedStyle(element,null).getPropertyValue(property); }; - +/* // debug function -// var show = function(canvas, ctx, xstart, w, h, metrics) -// { -// document.body.appendChild(canvas); -// ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)'; -// -// ctx.beginPath(); -// ctx.moveTo(xstart,0); -// ctx.lineTo(xstart,h); -// ctx.closePath(); -// ctx.stroke(); -// -// ctx.beginPath(); -// ctx.moveTo(xstart+metrics.bounds.maxx,0); -// ctx.lineTo(xstart+metrics.bounds.maxx,h); -// ctx.closePath(); -// ctx.stroke(); -// -// ctx.beginPath(); -// ctx.moveTo(0,h/2-metrics.ascent); -// ctx.lineTo(w,h/2-metrics.ascent); -// ctx.closePath(); -// ctx.stroke(); -// -// ctx.beginPath(); -// ctx.moveTo(0,h/2+metrics.descent); -// ctx.lineTo(w,h/2+metrics.descent); -// ctx.closePath(); -// ctx.stroke(); -// } - + var show = function(canvas, ctx, xstart, w, h, metrics) + { + document.body.appendChild(canvas); + ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)'; + + ctx.beginPath(); + ctx.moveTo(xstart,0); + ctx.lineTo(xstart,h); + ctx.closePath(); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(xstart+metrics.bounds.maxx,0); + ctx.lineTo(xstart+metrics.bounds.maxx,h); + ctx.closePath(); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(0,h/2-metrics.ascent); + ctx.lineTo(w,h/2-metrics.ascent); + ctx.closePath(); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(0,h/2+metrics.descent); + ctx.lineTo(w,h/2+metrics.descent); + ctx.closePath(); + ctx.stroke(); + } +*/ /** * The new text metrics function */ - return function(context2D, textstring) { + var measureText = function(context2D, textstring) { var metrics = context2D.measureText(textstring), fontFamily = getCSSValue(context2D.canvas,"font-family"), fontSize = getCSSValue(context2D.canvas,"font-size").replace("px",""), @@ -188,4 +192,6 @@ define(function() { } return metrics; }; + + return measureText; }); \ No newline at end of file diff --git a/Source/ThirdParty/sprintf.js b/Source/ThirdParty/sprintf.js index 9fa622c351ed..d7a19990b4d9 100644 --- a/Source/ThirdParty/sprintf.js +++ b/Source/ThirdParty/sprintf.js @@ -1,9 +1,8 @@ /** - * sprintf.js from the php.js project: https://github.com/kvz/phpjs - * Pulled directly from https://github.com/kvz/phpjs/blob/master/functions/strings/sprintf.js - * and then tweaked for Cesium. - */ -/*! +@license +sprintf.js from the php.js project - https://github.com/kvz/phpjs +Directly from https://github.com/kvz/phpjs/blob/master/functions/strings/sprintf.js + php.js is copyright 2012 Kevin van Zonneveld. Portions copyright Brett Zamir (http://brett-zamir.me), Kevin van Zonneveld @@ -128,181 +127,193 @@ OTHER DEALINGS IN THE SOFTWARE. /*global define*/ define(function() { - "use strict"; - // http://kevin.vanzonneveld.net - // + original by: Ash Searle (http://hexmen.com/blog/) - // + namespaced by: Michael White (http://getsprink.com) - // + tweaked by: Jack - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + input by: Paulo Freitas - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + input by: Brett Zamir (http://brett-zamir.me) - // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) - // + improved by: Dj - // + improved by: Allidylls - // * example 1: sprintf("%01.2f", 123.1); - // * returns 1: 123.10 - // * example 2: sprintf("[%10s]", 'monkey'); - // * returns 2: '[ monkey]' - // * example 3: sprintf("[%'#10s]", 'monkey'); - // * returns 3: '[####monkey]' - // * example 4: sprintf("%d", 123456789012345); - // * returns 4: '123456789012345' - var regex = /%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g; +function sprintf () { + // http://kevin.vanzonneveld.net + // + original by: Ash Searle (http://hexmen.com/blog/) + // + namespaced by: Michael White (http://getsprink.com) + // + tweaked by: Jack + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + input by: Paulo Freitas + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + input by: Brett Zamir (http://brett-zamir.me) + // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) + // + improved by: Dj + // + improved by: Allidylls + // * example 1: sprintf("%01.2f", 123.1); + // * returns 1: 123.10 + // * example 2: sprintf("[%10s]", 'monkey'); + // * returns 2: '[ monkey]' + // * example 3: sprintf("[%'#10s]", 'monkey'); + // * returns 3: '[####monkey]' + // * example 4: sprintf("%d", 123456789012345); + // * returns 4: '123456789012345' + var regex = /%%|%(\d+\$)?([-+\'#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuideEfFgG])/g; + var a = arguments, + i = 0, + format = a[i++]; - var pad = function(str, len, chr, leftJustify) { - if (!chr) { - chr = ' '; - } - var padding = (str.length >= len) ? '' : new Array(1 + len - str.length >>> 0).join(chr); - return leftJustify ? str + padding : padding + str; - }; + // pad() + var pad = function (str, len, chr, leftJustify) { + if (!chr) { + chr = ' '; + } + var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr); + return leftJustify ? str + padding : padding + str; + }; - var justify = function(value, prefix, leftJustify, minWidth, zeroPad, customPadChar) { - var diff = minWidth - value.length; - if (diff > 0) { - if (leftJustify || !zeroPad) { - value = pad(value, minWidth, customPadChar, leftJustify); - } else { - value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length); - } - } - return value; - }; + // justify() + var justify = function (value, prefix, leftJustify, minWidth, zeroPad, customPadChar) { + var diff = minWidth - value.length; + if (diff > 0) { + if (leftJustify || !zeroPad) { + value = pad(value, minWidth, customPadChar, leftJustify); + } else { + value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length); + } + } + return value; + }; - // formatString() - var formatString = function(value, leftJustify, minWidth, precision, zeroPad, customPadChar) { - if (precision !== null) { - value = value.slice(0, precision); - } - return justify(value, '', leftJustify, minWidth, zeroPad, customPadChar); - }; + // formatBaseX() + var formatBaseX = function (value, base, prefix, leftJustify, minWidth, precision, zeroPad) { + // Note: casts negative numbers to positive ones + var number = value >>> 0; + prefix = prefix && number && { + '2': '0b', + '8': '0', + '16': '0x' + }[base] || ''; + value = prefix + pad(number.toString(base), precision || 0, '0', false); + return justify(value, prefix, leftJustify, minWidth, zeroPad); + }; - var formatBaseX = function(value, base, prefix, leftJustify, minWidth, precision, zeroPad) { - // Note: casts negative numbers to positive ones - var number = value >>> 0; - prefix = prefix && number && { - '2' : '0b', - '8' : '0', - '16' : '0x' - }[base] || ''; - value = prefix + pad(number.toString(base), precision || 0, '0', false); - return justify(value, prefix, leftJustify, minWidth, zeroPad); - }; + // formatString() + var formatString = function (value, leftJustify, minWidth, precision, zeroPad, customPadChar) { + if (precision != null) { + value = value.slice(0, precision); + } + return justify(value, '', leftJustify, minWidth, zeroPad, customPadChar); + }; - function sprintf() { - var a = arguments, i = 0, format = a[i++]; - return format.replace(regex, function(substring, valueIndex, flags, minWidth, _, precision, type) { - var number; - var prefix; - var method; - var textTransform; - var value; + // doFormat() + var doFormat = function (substring, valueIndex, flags, minWidth, _, precision, type) { + var number; + var prefix; + var method; + var textTransform; + var value; - if (substring === '%%') { - return '%'; - } + if (substring == '%%') { + return '%'; + } - // parse flags - var leftJustify = false, positivePrefix = '', zeroPad = false, prefixBaseX = false, customPadChar = ' '; - var flagsl = flags.length; - for ( var j = 0; flags && j < flagsl; j++) { - switch (flags.charAt(j)) { - case ' ': - positivePrefix = ' '; - break; - case '+': - positivePrefix = '+'; - break; - case '-': - leftJustify = true; - break; - case "'": - customPadChar = flags.charAt(j + 1); - break; - case '0': - zeroPad = true; - break; - case '#': - prefixBaseX = true; - break; - } - } + // parse flags + var leftJustify = false, + positivePrefix = '', + zeroPad = false, + prefixBaseX = false, + customPadChar = ' '; + var flagsl = flags.length; + for (var j = 0; flags && j < flagsl; j++) { + switch (flags.charAt(j)) { + case ' ': + positivePrefix = ' '; + break; + case '+': + positivePrefix = '+'; + break; + case '-': + leftJustify = true; + break; + case "'": + customPadChar = flags.charAt(j + 1); + break; + case '0': + zeroPad = true; + break; + case '#': + prefixBaseX = true; + break; + } + } - // parameters may be null, undefined, empty-string or real valued - // we want to ignore null, undefined and empty-string values - if (!minWidth) { - minWidth = 0; - } else if (minWidth === '*') { - minWidth = +a[i++]; - } else if (minWidth.charAt(0) === '*') { - minWidth = +a[minWidth.slice(1, -1)]; - } else { - minWidth = +minWidth; - } + // parameters may be null, undefined, empty-string or real valued + // we want to ignore null, undefined and empty-string values + if (!minWidth) { + minWidth = 0; + } else if (minWidth == '*') { + minWidth = +a[i++]; + } else if (minWidth.charAt(0) == '*') { + minWidth = +a[minWidth.slice(1, -1)]; + } else { + minWidth = +minWidth; + } - // Note: undocumented perl feature: - if (minWidth < 0) { - minWidth = -minWidth; - leftJustify = true; - } + // Note: undocumented perl feature: + if (minWidth < 0) { + minWidth = -minWidth; + leftJustify = true; + } - if (!isFinite(minWidth)) { - throw new Error('sprintf: (minimum-)width must be finite'); - } + if (!isFinite(minWidth)) { + throw new Error('sprintf: (minimum-)width must be finite'); + } - if (!precision) { - precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type === 'd') ? 0 : undefined; - } else if (precision === '*') { - precision = +a[i++]; - } else if (precision.charAt(0) === '*') { - precision = +a[precision.slice(1, -1)]; - } else { - precision = +precision; - } + if (!precision) { + precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : undefined; + } else if (precision == '*') { + precision = +a[i++]; + } else if (precision.charAt(0) == '*') { + precision = +a[precision.slice(1, -1)]; + } else { + precision = +precision; + } - // grab value using valueIndex if required? - value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++]; + // grab value using valueIndex if required? + value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++]; - switch (type) { - case 's': - return formatString(String(value), leftJustify, minWidth, precision, zeroPad, customPadChar); - case 'c': - return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad); - case 'b': - return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad); - case 'o': - return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad); - case 'x': - return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad); - case 'X': - return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad).toUpperCase(); - case 'u': - return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad); - case 'i': - case 'd': - number = +value || 0; - number = Math.round(number - number % 1); // Plain Math.round doesn't just truncate - prefix = number < 0 ? '-' : positivePrefix; - value = prefix + pad(String(Math.abs(number)), precision, '0', false); - return justify(value, prefix, leftJustify, minWidth, zeroPad); - case 'e': - case 'E': - case 'f': // Should handle locales (as per setlocale) - case 'F': - case 'g': - case 'G': - number = +value; - prefix = number < 0 ? '-' : positivePrefix; - method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())]; - textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2]; - value = prefix + Math.abs(number)[method](precision); - return justify(value, prefix, leftJustify, minWidth, zeroPad)[textTransform](); - default: - return substring; - } - }); + switch (type) { + case 's': + return formatString(String(value), leftJustify, minWidth, precision, zeroPad, customPadChar); + case 'c': + return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad); + case 'b': + return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad); + case 'o': + return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad); + case 'x': + return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad); + case 'X': + return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad).toUpperCase(); + case 'u': + return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad); + case 'i': + case 'd': + number = +value || 0; + number = Math.round(number - number % 1); // Plain Math.round doesn't just truncate + prefix = number < 0 ? '-' : positivePrefix; + value = prefix + pad(String(Math.abs(number)), precision, '0', false); + return justify(value, prefix, leftJustify, minWidth, zeroPad); + case 'e': + case 'E': + case 'f': // Should handle locales (as per setlocale) + case 'F': + case 'g': + case 'G': + number = +value; + prefix = number < 0 ? '-' : positivePrefix; + method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())]; + textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2]; + value = prefix + Math.abs(number)[method](precision); + return justify(value, prefix, leftJustify, minWidth, zeroPad)[textTransform](); + default: + return substring; } - return sprintf; + }; + + return format.replace(regex, doFormat); +} + +return sprintf; }); \ No newline at end of file diff --git a/Source/ThirdParty/when.js b/Source/ThirdParty/when.js index 297a62479943..9f115a15ced9 100755 --- a/Source/ThirdParty/when.js +++ b/Source/ThirdParty/when.js @@ -1,6 +1,9 @@ -/** @license MIT License (c) copyright B Cavalier & J Hann */ - /** + @license + when.js - https://github.com/cujojs/when + + MIT License (c) copyright B Cavalier & J Hann + * A lightweight CommonJS Promises/A and when() implementation * when is part of the cujo.js family of libraries (http://cujojs.com/) * @@ -12,734 +15,734 @@ (function(define) { 'use strict'; define(function () { - var reduceArray, slice, undef; - - // - // Public API - // - - when.defer = defer; // Create a deferred - when.resolve = resolve; // Create a resolved promise - when.reject = reject; // Create a rejected promise - - when.join = join; // Join 2 or more promises - - when.all = all; // Resolve a list of promises - when.map = map; // Array.map() for promises - when.reduce = reduce; // Array.reduce() for promises - - when.any = any; // One-winner race - when.some = some; // Multi-winner race - - when.chain = chain; // Make a promise trigger another resolver - - when.isPromise = isPromise; // Determine if a thing is a promise - - /** - * Register an observer for a promise or immediate value. - * - * @param {*} promiseOrValue - * @param {function?} [onFulfilled] callback to be called when promiseOrValue is - * successfully fulfilled. If promiseOrValue is an immediate value, callback - * will be invoked immediately. - * @param {function?} [onRejected] callback to be called when promiseOrValue is - * rejected. - * @param {function?} [onProgress] callback to be called when progress updates - * are issued for promiseOrValue. - * @returns {Promise} a new {@link Promise} that will complete with the return - * value of callback or errback or the completion value of promiseOrValue if - * callback and/or errback is not supplied. - */ - function when(promiseOrValue, onFulfilled, onRejected, onProgress) { - // Get a trusted promise for the input promiseOrValue, and then - // register promise handlers - return resolve(promiseOrValue).then(onFulfilled, onRejected, onProgress); - } - - /** - * Returns promiseOrValue if promiseOrValue is a {@link Promise}, a new Promise if - * promiseOrValue is a foreign promise, or a new, already-fulfilled {@link Promise} - * whose value is promiseOrValue if promiseOrValue is an immediate value. - * - * @param {*} promiseOrValue - * @returns Guaranteed to return a trusted Promise. If promiseOrValue is a when.js {@link Promise} - * returns promiseOrValue, otherwise, returns a new, already-resolved, when.js {@link Promise} - * whose resolution value is: - * * the resolution value of promiseOrValue if it's a foreign promise, or - * * promiseOrValue if it's a value - */ - function resolve(promiseOrValue) { - var promise, deferred; - - if(promiseOrValue instanceof Promise) { - // It's a when.js promise, so we trust it - promise = promiseOrValue; - - } else { - // It's not a when.js promise. See if it's a foreign promise or a value. - if(isPromise(promiseOrValue)) { - // It's a thenable, but we don't know where it came from, so don't trust - // its implementation entirely. Introduce a trusted middleman when.js promise - deferred = defer(); - - // IMPORTANT: This is the only place when.js should ever call .then() on an - // untrusted promise. Don't expose the return value to the untrusted promise - promiseOrValue.then( - function(value) { deferred.resolve(value); }, - function(reason) { deferred.reject(reason); }, - function(update) { deferred.progress(update); } - ); - - promise = deferred.promise; - - } else { - // It's a value, not a promise. Create a resolved promise for it. - promise = fulfilled(promiseOrValue); - } - } - - return promise; - } - - /** - * Returns a rejected promise for the supplied promiseOrValue. The returned - * promise will be rejected with: - * - promiseOrValue, if it is a value, or - * - if promiseOrValue is a promise - * - promiseOrValue's value after it is fulfilled - * - promiseOrValue's reason after it is rejected - * @param {*} promiseOrValue the rejected value of the returned {@link Promise} - * @return {Promise} rejected {@link Promise} - */ - function reject(promiseOrValue) { - return when(promiseOrValue, rejected); - } - - /** - * Trusted Promise constructor. A Promise created from this constructor is - * a trusted when.js promise. Any other duck-typed promise is considered - * untrusted. - * @constructor - * @name Promise - */ - function Promise(then) { - this.then = then; - } - - Promise.prototype = { - /** - * Register a callback that will be called when a promise is - * fulfilled or rejected. Optionally also register a progress handler. - * Shortcut for .then(onFulfilledOrRejected, onFulfilledOrRejected, onProgress) - * @param {function?} [onFulfilledOrRejected] - * @param {function?} [onProgress] - * @return {Promise} - */ - always: function(onFulfilledOrRejected, onProgress) { - return this.then(onFulfilledOrRejected, onFulfilledOrRejected, onProgress); - }, - - /** - * Register a rejection handler. Shortcut for .then(undefined, onRejected) - * @param {function?} onRejected - * @return {Promise} - */ - otherwise: function(onRejected) { - return this.then(undef, onRejected); - }, - - /** - * Shortcut for .then(function() { return value; }) - * @param {*} value - * @return {Promise} a promise that: - * - is fulfilled if value is not a promise, or - * - if value is a promise, will fulfill with its value, or reject - * with its reason. - */ - yield: function(value) { - return this.then(function() { - return value; - }); - }, - - /** - * Assumes that this promise will fulfill with an array, and arranges - * for the onFulfilled to be called with the array as its argument list - * i.e. onFulfilled.spread(undefined, array). - * @param {function} onFulfilled function to receive spread arguments - * @return {Promise} - */ - spread: function(onFulfilled) { - return this.then(function(array) { - // array may contain promises, so resolve its contents. - return all(array, function(array) { - return onFulfilled.apply(undef, array); - }); - }); - } - }; - - /** - * Create an already-resolved promise for the supplied value - * @private - * - * @param {*} value - * @return {Promise} fulfilled promise - */ - function fulfilled(value) { - var p = new Promise(function(onFulfilled) { - // TODO: Promises/A+ check typeof onFulfilled - try { - return resolve(onFulfilled ? onFulfilled(value) : value); - } catch(e) { - return rejected(e); - } - }); - - return p; - } - - /** - * Create an already-rejected {@link Promise} with the supplied - * rejection reason. - * @private - * - * @param {*} reason - * @return {Promise} rejected promise - */ - function rejected(reason) { - var p = new Promise(function(_, onRejected) { - // TODO: Promises/A+ check typeof onRejected - try { - return onRejected ? resolve(onRejected(reason)) : rejected(reason); - } catch(e) { - return rejected(e); - } - }); - - return p; - } - - /** - * Creates a new, Deferred with fully isolated resolver and promise parts, - * either or both of which may be given out safely to consumers. - * The Deferred itself has the full API: resolve, reject, progress, and - * then. The resolver has resolve, reject, and progress. The promise - * only has then. - * - * @return {Deferred} - */ - function defer() { - var deferred, promise, handlers, progressHandlers, - _then, _progress, _resolve; - - /** - * The promise for the new deferred - * @type {Promise} - */ - promise = new Promise(then); - - /** - * The full Deferred object, with {@link Promise} and {@link Resolver} parts - * @class Deferred - * @name Deferred - */ - deferred = { - then: then, // DEPRECATED: use deferred.promise.then - resolve: promiseResolve, - reject: promiseReject, - // TODO: Consider renaming progress() to notify() - progress: promiseProgress, - - promise: promise, - - resolver: { - resolve: promiseResolve, - reject: promiseReject, - progress: promiseProgress - } - }; - - handlers = []; - progressHandlers = []; - - /** - * Pre-resolution then() that adds the supplied callback, errback, and progback - * functions to the registered listeners - * @private - * - * @param {function?} [onFulfilled] resolution handler - * @param {function?} [onRejected] rejection handler - * @param {function?} [onProgress] progress handler - */ - _then = function(onFulfilled, onRejected, onProgress) { - // TODO: Promises/A+ check typeof onFulfilled, onRejected, onProgress - var deferred, progressHandler; - - deferred = defer(); - - progressHandler = typeof onProgress === 'function' - ? function(update) { - try { - // Allow progress handler to transform progress event - deferred.progress(onProgress(update)); - } catch(e) { - // Use caught value as progress - deferred.progress(e); - } - } - : function(update) { deferred.progress(update); }; - - handlers.push(function(promise) { - promise.then(onFulfilled, onRejected) - .then(deferred.resolve, deferred.reject, progressHandler); - }); - - progressHandlers.push(progressHandler); - - return deferred.promise; - }; - - /** - * Issue a progress event, notifying all progress listeners - * @private - * @param {*} update progress event payload to pass to all listeners - */ - _progress = function(update) { - processQueue(progressHandlers, update); - return update; - }; - - /** - * Transition from pre-resolution state to post-resolution state, notifying - * all listeners of the resolution or rejection - * @private - * @param {*} value the value of this deferred - */ - _resolve = function(value) { - value = resolve(value); - - // Replace _then with one that directly notifies with the result. - _then = value.then; - // Replace _resolve so that this Deferred can only be resolved once - _resolve = resolve; - // Make _progress a noop, to disallow progress for the resolved promise. - _progress = noop; - - // Notify handlers - processQueue(handlers, value); - - // Free progressHandlers array since we'll never issue progress events - progressHandlers = handlers = undef; - - return value; - }; - - return deferred; - - /** - * Wrapper to allow _then to be replaced safely - * @param {function?} [onFulfilled] resolution handler - * @param {function?} [onRejected] rejection handler - * @param {function?} [onProgress] progress handler - * @return {Promise} new promise - */ - function then(onFulfilled, onRejected, onProgress) { - // TODO: Promises/A+ check typeof onFulfilled, onRejected, onProgress - return _then(onFulfilled, onRejected, onProgress); - } - - /** - * Wrapper to allow _resolve to be replaced - */ - function promiseResolve(val) { - return _resolve(val); - } - - /** - * Wrapper to allow _reject to be replaced - */ - function promiseReject(err) { - return _resolve(rejected(err)); - } - - /** - * Wrapper to allow _progress to be replaced - */ - function promiseProgress(update) { - return _progress(update); - } - } - - /** - * Determines if promiseOrValue is a promise or not. Uses the feature - * test from http://wiki.commonjs.org/wiki/Promises/A to determine if - * promiseOrValue is a promise. - * - * @param {*} promiseOrValue anything - * @returns {boolean} true if promiseOrValue is a {@link Promise} - */ - function isPromise(promiseOrValue) { - return promiseOrValue && typeof promiseOrValue.then === 'function'; - } - - /** - * Initiates a competitive race, returning a promise that will resolve when - * howMany of the supplied promisesOrValues have resolved, or will reject when - * it becomes impossible for howMany to resolve, for example, when - * (promisesOrValues.length - howMany) + 1 input promises reject. - * - * @param {Array} promisesOrValues array of anything, may contain a mix - * of promises and values - * @param howMany {number} number of promisesOrValues to resolve - * @param {function?} [onFulfilled] resolution handler - * @param {function?} [onRejected] rejection handler - * @param {function?} [onProgress] progress handler - * @returns {Promise} promise that will resolve to an array of howMany values that - * resolved first, or will reject with an array of (promisesOrValues.length - howMany) + 1 - * rejection reasons. - */ - function some(promisesOrValues, howMany, onFulfilled, onRejected, onProgress) { - - checkCallbacks(2, arguments); - - return when(promisesOrValues, function(promisesOrValues) { - - var toResolve, toReject, values, reasons, deferred, fulfillOne, rejectOne, progress, len, i; - - len = promisesOrValues.length >>> 0; - - toResolve = Math.max(0, Math.min(howMany, len)); - values = []; - - toReject = (len - toResolve) + 1; - reasons = []; - - deferred = defer(); - - // No items in the input, resolve immediately - if (!toResolve) { - deferred.resolve(values); - - } else { - progress = deferred.progress; - - rejectOne = function(reason) { - reasons.push(reason); - if(!--toReject) { - fulfillOne = rejectOne = noop; - deferred.reject(reasons); - } - }; - - fulfillOne = function(val) { - // This orders the values based on promise resolution order - // Another strategy would be to use the original position of - // the corresponding promise. - values.push(val); - - if (!--toResolve) { - fulfillOne = rejectOne = noop; - deferred.resolve(values); - } - }; - - for(i = 0; i < len; ++i) { - if(i in promisesOrValues) { - when(promisesOrValues[i], fulfiller, rejecter, progress); - } - } - } - - return deferred.then(onFulfilled, onRejected, onProgress); - - function rejecter(reason) { - rejectOne(reason); - } - - function fulfiller(val) { - fulfillOne(val); - } - - }); - } - - /** - * Initiates a competitive race, returning a promise that will resolve when - * any one of the supplied promisesOrValues has resolved or will reject when - * *all* promisesOrValues have rejected. - * - * @param {Array|Promise} promisesOrValues array of anything, may contain a mix - * of {@link Promise}s and values - * @param {function?} [onFulfilled] resolution handler - * @param {function?} [onRejected] rejection handler - * @param {function?} [onProgress] progress handler - * @returns {Promise} promise that will resolve to the value that resolved first, or - * will reject with an array of all rejected inputs. - */ - function any(promisesOrValues, onFulfilled, onRejected, onProgress) { - - function unwrapSingleResult(val) { - return onFulfilled ? onFulfilled(val[0]) : val[0]; - } - - return some(promisesOrValues, 1, unwrapSingleResult, onRejected, onProgress); - } - - /** - * Return a promise that will resolve only once all the supplied promisesOrValues - * have resolved. The resolution value of the returned promise will be an array - * containing the resolution values of each of the promisesOrValues. - * @memberOf when - * - * @param {Array|Promise} promisesOrValues array of anything, may contain a mix - * of {@link Promise}s and values - * @param {function?} [onFulfilled] resolution handler - * @param {function?} [onRejected] rejection handler - * @param {function?} [onProgress] progress handler - * @returns {Promise} - */ - function all(promisesOrValues, onFulfilled, onRejected, onProgress) { - checkCallbacks(1, arguments); - return map(promisesOrValues, identity).then(onFulfilled, onRejected, onProgress); - } - - /** - * Joins multiple promises into a single returned promise. - * @return {Promise} a promise that will fulfill when *all* the input promises - * have fulfilled, or will reject when *any one* of the input promises rejects. - */ - function join(/* ...promises */) { - return map(arguments, identity); - } - - /** - * Traditional map function, similar to `Array.prototype.map()`, but allows - * input to contain {@link Promise}s and/or values, and mapFunc may return - * either a value or a {@link Promise} - * - * @param {Array|Promise} promise array of anything, may contain a mix - * of {@link Promise}s and values - * @param {function} mapFunc mapping function mapFunc(value) which may return - * either a {@link Promise} or value - * @returns {Promise} a {@link Promise} that will resolve to an array containing - * the mapped output values. - */ - function map(promise, mapFunc) { - return when(promise, function(array) { - var results, len, toResolve, resolve, i, d; - - // Since we know the resulting length, we can preallocate the results - // array to avoid array expansions. - toResolve = len = array.length >>> 0; - results = []; - d = defer(); - - if(!toResolve) { - d.resolve(results); - } else { - - resolve = function resolveOne(item, i) { - when(item, mapFunc).then(function(mapped) { - results[i] = mapped; - - if(!--toResolve) { - d.resolve(results); - } - }, d.reject); - }; - - // Since mapFunc may be async, get all invocations of it into flight - for(i = 0; i < len; i++) { - if(i in array) { - resolve(array[i], i); - } else { - --toResolve; - } - } - - } - - return d.promise; - - }); - } - - /** - * Traditional reduce function, similar to `Array.prototype.reduce()`, but - * input may contain promises and/or values, and reduceFunc - * may return either a value or a promise, *and* initialValue may - * be a promise for the starting value. - * - * @param {Array|Promise} promise array or promise for an array of anything, - * may contain a mix of promises and values. - * @param {function} reduceFunc reduce function reduce(currentValue, nextValue, index, total), - * where total is the total number of items being reduced, and will be the same - * in each call to reduceFunc. - * @returns {Promise} that will resolve to the final reduced value - */ - function reduce(promise, reduceFunc /*, initialValue */) { - var args = slice.call(arguments, 1); - - return when(promise, function(array) { - var total; - - total = array.length; - - // Wrap the supplied reduceFunc with one that handles promises and then - // delegates to the supplied. - args[0] = function (current, val, i) { - return when(current, function (c) { - return when(val, function (value) { - return reduceFunc(c, value, i, total); - }); - }); - }; - - return reduceArray.apply(array, args); - }); - } - - /** - * Ensure that resolution of promiseOrValue will trigger resolver with the - * value or reason of promiseOrValue, or instead with resolveValue if it is provided. - * - * @param promiseOrValue - * @param {Object} resolver - * @param {function} resolver.resolve - * @param {function} resolver.reject - * @param {*} [resolveValue] - * @returns {Promise} - */ - function chain(promiseOrValue, resolver, resolveValue) { - var useResolveValue = arguments.length > 2; - - return when(promiseOrValue, - function(val) { - val = useResolveValue ? resolveValue : val; - resolver.resolve(val); - return val; - }, - function(reason) { - resolver.reject(reason); - return rejected(reason); - }, - resolver.progress - ); - } - - // - // Utility functions - // - - /** - * Apply all functions in queue to value - * @param {Array} queue array of functions to execute - * @param {*} value argument passed to each function - */ - function processQueue(queue, value) { - var handler, i = 0; - - while (handler = queue[i++]) { - handler(value); - } - } - - /** - * Helper that checks arrayOfCallbacks to ensure that each element is either - * a function, or null or undefined. - * @private - * @param {number} start index at which to start checking items in arrayOfCallbacks - * @param {Array} arrayOfCallbacks array to check - * @throws {Error} if any element of arrayOfCallbacks is something other than - * a functions, null, or undefined. - */ - function checkCallbacks(start, arrayOfCallbacks) { - // TODO: Promises/A+ update type checking and docs - var arg, i = arrayOfCallbacks.length; - - while(i > start) { - arg = arrayOfCallbacks[--i]; - - if (arg != null && typeof arg != 'function') { - throw new Error('arg '+i+' must be a function'); - } - } - } - - /** - * No-Op function used in method replacement - * @private - */ - function noop() {} - - slice = [].slice; - - // ES5 reduce implementation if native not available - // See: http://es5.github.com/#x15.4.4.21 as there are many - // specifics and edge cases. - reduceArray = [].reduce || - function(reduceFunc /*, initialValue */) { - /*jshint maxcomplexity: 7*/ - - // ES5 dictates that reduce.length === 1 - - // This implementation deviates from ES5 spec in the following ways: - // 1. It does not check if reduceFunc is a Callable - - var arr, args, reduced, len, i; - - i = 0; - // This generates a jshint warning, despite being valid - // "Missing 'new' prefix when invoking a constructor." - // See https://github.com/jshint/jshint/issues/392 - arr = Object(this); - len = arr.length >>> 0; - args = arguments; - - // If no initialValue, use first item of array (we know length !== 0 here) - // and adjust i to start at second item - if(args.length <= 1) { - // Skip to the first real element in the array - for(;;) { - if(i in arr) { - reduced = arr[i++]; - break; - } - - // If we reached the end of the array without finding any real - // elements, it's a TypeError - if(++i >= len) { - throw new TypeError(); - } - } - } else { - // If initialValue provided, use it - reduced = args[1]; - } - - // Do the actual reduce - for(;i < len; ++i) { - // Skip holes - if(i in arr) { - reduced = reduceFunc(reduced, arr[i], i, arr); - } - } - - return reduced; - }; - - function identity(x) { - return x; - } - - return when; + var reduceArray, slice, undef; + + // + // Public API + // + + when.defer = defer; // Create a deferred + when.resolve = resolve; // Create a resolved promise + when.reject = reject; // Create a rejected promise + + when.join = join; // Join 2 or more promises + + when.all = all; // Resolve a list of promises + when.map = map; // Array.map() for promises + when.reduce = reduce; // Array.reduce() for promises + + when.any = any; // One-winner race + when.some = some; // Multi-winner race + + when.chain = chain; // Make a promise trigger another resolver + + when.isPromise = isPromise; // Determine if a thing is a promise + + /** + * Register an observer for a promise or immediate value. + * + * @param {*} promiseOrValue + * @param {function?} [onFulfilled] callback to be called when promiseOrValue is + * successfully fulfilled. If promiseOrValue is an immediate value, callback + * will be invoked immediately. + * @param {function?} [onRejected] callback to be called when promiseOrValue is + * rejected. + * @param {function?} [onProgress] callback to be called when progress updates + * are issued for promiseOrValue. + * @returns {Promise} a new {@link Promise} that will complete with the return + * value of callback or errback or the completion value of promiseOrValue if + * callback and/or errback is not supplied. + */ + function when(promiseOrValue, onFulfilled, onRejected, onProgress) { + // Get a trusted promise for the input promiseOrValue, and then + // register promise handlers + return resolve(promiseOrValue).then(onFulfilled, onRejected, onProgress); + } + + /** + * Returns promiseOrValue if promiseOrValue is a {@link Promise}, a new Promise if + * promiseOrValue is a foreign promise, or a new, already-fulfilled {@link Promise} + * whose value is promiseOrValue if promiseOrValue is an immediate value. + * + * @param {*} promiseOrValue + * @returns Guaranteed to return a trusted Promise. If promiseOrValue is a when.js {@link Promise} + * returns promiseOrValue, otherwise, returns a new, already-resolved, when.js {@link Promise} + * whose resolution value is: + * * the resolution value of promiseOrValue if it's a foreign promise, or + * * promiseOrValue if it's a value + */ + function resolve(promiseOrValue) { + var promise, deferred; + + if(promiseOrValue instanceof Promise) { + // It's a when.js promise, so we trust it + promise = promiseOrValue; + + } else { + // It's not a when.js promise. See if it's a foreign promise or a value. + if(isPromise(promiseOrValue)) { + // It's a thenable, but we don't know where it came from, so don't trust + // its implementation entirely. Introduce a trusted middleman when.js promise + deferred = defer(); + + // IMPORTANT: This is the only place when.js should ever call .then() on an + // untrusted promise. Don't expose the return value to the untrusted promise + promiseOrValue.then( + function(value) { deferred.resolve(value); }, + function(reason) { deferred.reject(reason); }, + function(update) { deferred.progress(update); } + ); + + promise = deferred.promise; + + } else { + // It's a value, not a promise. Create a resolved promise for it. + promise = fulfilled(promiseOrValue); + } + } + + return promise; + } + + /** + * Returns a rejected promise for the supplied promiseOrValue. The returned + * promise will be rejected with: + * - promiseOrValue, if it is a value, or + * - if promiseOrValue is a promise + * - promiseOrValue's value after it is fulfilled + * - promiseOrValue's reason after it is rejected + * @param {*} promiseOrValue the rejected value of the returned {@link Promise} + * @return {Promise} rejected {@link Promise} + */ + function reject(promiseOrValue) { + return when(promiseOrValue, rejected); + } + + /** + * Trusted Promise constructor. A Promise created from this constructor is + * a trusted when.js promise. Any other duck-typed promise is considered + * untrusted. + * @constructor + * @name Promise + */ + function Promise(then) { + this.then = then; + } + + Promise.prototype = { + /** + * Register a callback that will be called when a promise is + * fulfilled or rejected. Optionally also register a progress handler. + * Shortcut for .then(onFulfilledOrRejected, onFulfilledOrRejected, onProgress) + * @param {function?} [onFulfilledOrRejected] + * @param {function?} [onProgress] + * @return {Promise} + */ + always: function(onFulfilledOrRejected, onProgress) { + return this.then(onFulfilledOrRejected, onFulfilledOrRejected, onProgress); + }, + + /** + * Register a rejection handler. Shortcut for .then(undefined, onRejected) + * @param {function?} onRejected + * @return {Promise} + */ + otherwise: function(onRejected) { + return this.then(undef, onRejected); + }, + + /** + * Shortcut for .then(function() { return value; }) + * @param {*} value + * @return {Promise} a promise that: + * - is fulfilled if value is not a promise, or + * - if value is a promise, will fulfill with its value, or reject + * with its reason. + */ + yield: function(value) { + return this.then(function() { + return value; + }); + }, + + /** + * Assumes that this promise will fulfill with an array, and arranges + * for the onFulfilled to be called with the array as its argument list + * i.e. onFulfilled.spread(undefined, array). + * @param {function} onFulfilled function to receive spread arguments + * @return {Promise} + */ + spread: function(onFulfilled) { + return this.then(function(array) { + // array may contain promises, so resolve its contents. + return all(array, function(array) { + return onFulfilled.apply(undef, array); + }); + }); + } + }; + + /** + * Create an already-resolved promise for the supplied value + * @private + * + * @param {*} value + * @return {Promise} fulfilled promise + */ + function fulfilled(value) { + var p = new Promise(function(onFulfilled) { + // TODO: Promises/A+ check typeof onFulfilled + try { + return resolve(onFulfilled ? onFulfilled(value) : value); + } catch(e) { + return rejected(e); + } + }); + + return p; + } + + /** + * Create an already-rejected {@link Promise} with the supplied + * rejection reason. + * @private + * + * @param {*} reason + * @return {Promise} rejected promise + */ + function rejected(reason) { + var p = new Promise(function(_, onRejected) { + // TODO: Promises/A+ check typeof onRejected + try { + return onRejected ? resolve(onRejected(reason)) : rejected(reason); + } catch(e) { + return rejected(e); + } + }); + + return p; + } + + /** + * Creates a new, Deferred with fully isolated resolver and promise parts, + * either or both of which may be given out safely to consumers. + * The Deferred itself has the full API: resolve, reject, progress, and + * then. The resolver has resolve, reject, and progress. The promise + * only has then. + * + * @return {Deferred} + */ + function defer() { + var deferred, promise, handlers, progressHandlers, + _then, _progress, _resolve; + + /** + * The promise for the new deferred + * @type {Promise} + */ + promise = new Promise(then); + + /** + * The full Deferred object, with {@link Promise} and {@link Resolver} parts + * @class Deferred + * @name Deferred + */ + deferred = { + then: then, // DEPRECATED: use deferred.promise.then + resolve: promiseResolve, + reject: promiseReject, + // TODO: Consider renaming progress() to notify() + progress: promiseProgress, + + promise: promise, + + resolver: { + resolve: promiseResolve, + reject: promiseReject, + progress: promiseProgress + } + }; + + handlers = []; + progressHandlers = []; + + /** + * Pre-resolution then() that adds the supplied callback, errback, and progback + * functions to the registered listeners + * @private + * + * @param {function?} [onFulfilled] resolution handler + * @param {function?} [onRejected] rejection handler + * @param {function?} [onProgress] progress handler + */ + _then = function(onFulfilled, onRejected, onProgress) { + // TODO: Promises/A+ check typeof onFulfilled, onRejected, onProgress + var deferred, progressHandler; + + deferred = defer(); + + progressHandler = typeof onProgress === 'function' + ? function(update) { + try { + // Allow progress handler to transform progress event + deferred.progress(onProgress(update)); + } catch(e) { + // Use caught value as progress + deferred.progress(e); + } + } + : function(update) { deferred.progress(update); }; + + handlers.push(function(promise) { + promise.then(onFulfilled, onRejected) + .then(deferred.resolve, deferred.reject, progressHandler); + }); + + progressHandlers.push(progressHandler); + + return deferred.promise; + }; + + /** + * Issue a progress event, notifying all progress listeners + * @private + * @param {*} update progress event payload to pass to all listeners + */ + _progress = function(update) { + processQueue(progressHandlers, update); + return update; + }; + + /** + * Transition from pre-resolution state to post-resolution state, notifying + * all listeners of the resolution or rejection + * @private + * @param {*} value the value of this deferred + */ + _resolve = function(value) { + value = resolve(value); + + // Replace _then with one that directly notifies with the result. + _then = value.then; + // Replace _resolve so that this Deferred can only be resolved once + _resolve = resolve; + // Make _progress a noop, to disallow progress for the resolved promise. + _progress = noop; + + // Notify handlers + processQueue(handlers, value); + + // Free progressHandlers array since we'll never issue progress events + progressHandlers = handlers = undef; + + return value; + }; + + return deferred; + + /** + * Wrapper to allow _then to be replaced safely + * @param {function?} [onFulfilled] resolution handler + * @param {function?} [onRejected] rejection handler + * @param {function?} [onProgress] progress handler + * @return {Promise} new promise + */ + function then(onFulfilled, onRejected, onProgress) { + // TODO: Promises/A+ check typeof onFulfilled, onRejected, onProgress + return _then(onFulfilled, onRejected, onProgress); + } + + /** + * Wrapper to allow _resolve to be replaced + */ + function promiseResolve(val) { + return _resolve(val); + } + + /** + * Wrapper to allow _reject to be replaced + */ + function promiseReject(err) { + return _resolve(rejected(err)); + } + + /** + * Wrapper to allow _progress to be replaced + */ + function promiseProgress(update) { + return _progress(update); + } + } + + /** + * Determines if promiseOrValue is a promise or not. Uses the feature + * test from http://wiki.commonjs.org/wiki/Promises/A to determine if + * promiseOrValue is a promise. + * + * @param {*} promiseOrValue anything + * @returns {boolean} true if promiseOrValue is a {@link Promise} + */ + function isPromise(promiseOrValue) { + return promiseOrValue && typeof promiseOrValue.then === 'function'; + } + + /** + * Initiates a competitive race, returning a promise that will resolve when + * howMany of the supplied promisesOrValues have resolved, or will reject when + * it becomes impossible for howMany to resolve, for example, when + * (promisesOrValues.length - howMany) + 1 input promises reject. + * + * @param {Array} promisesOrValues array of anything, may contain a mix + * of promises and values + * @param howMany {number} number of promisesOrValues to resolve + * @param {function?} [onFulfilled] resolution handler + * @param {function?} [onRejected] rejection handler + * @param {function?} [onProgress] progress handler + * @returns {Promise} promise that will resolve to an array of howMany values that + * resolved first, or will reject with an array of (promisesOrValues.length - howMany) + 1 + * rejection reasons. + */ + function some(promisesOrValues, howMany, onFulfilled, onRejected, onProgress) { + + checkCallbacks(2, arguments); + + return when(promisesOrValues, function(promisesOrValues) { + + var toResolve, toReject, values, reasons, deferred, fulfillOne, rejectOne, progress, len, i; + + len = promisesOrValues.length >>> 0; + + toResolve = Math.max(0, Math.min(howMany, len)); + values = []; + + toReject = (len - toResolve) + 1; + reasons = []; + + deferred = defer(); + + // No items in the input, resolve immediately + if (!toResolve) { + deferred.resolve(values); + + } else { + progress = deferred.progress; + + rejectOne = function(reason) { + reasons.push(reason); + if(!--toReject) { + fulfillOne = rejectOne = noop; + deferred.reject(reasons); + } + }; + + fulfillOne = function(val) { + // This orders the values based on promise resolution order + // Another strategy would be to use the original position of + // the corresponding promise. + values.push(val); + + if (!--toResolve) { + fulfillOne = rejectOne = noop; + deferred.resolve(values); + } + }; + + for(i = 0; i < len; ++i) { + if(i in promisesOrValues) { + when(promisesOrValues[i], fulfiller, rejecter, progress); + } + } + } + + return deferred.then(onFulfilled, onRejected, onProgress); + + function rejecter(reason) { + rejectOne(reason); + } + + function fulfiller(val) { + fulfillOne(val); + } + + }); + } + + /** + * Initiates a competitive race, returning a promise that will resolve when + * any one of the supplied promisesOrValues has resolved or will reject when + * *all* promisesOrValues have rejected. + * + * @param {Array|Promise} promisesOrValues array of anything, may contain a mix + * of {@link Promise}s and values + * @param {function?} [onFulfilled] resolution handler + * @param {function?} [onRejected] rejection handler + * @param {function?} [onProgress] progress handler + * @returns {Promise} promise that will resolve to the value that resolved first, or + * will reject with an array of all rejected inputs. + */ + function any(promisesOrValues, onFulfilled, onRejected, onProgress) { + + function unwrapSingleResult(val) { + return onFulfilled ? onFulfilled(val[0]) : val[0]; + } + + return some(promisesOrValues, 1, unwrapSingleResult, onRejected, onProgress); + } + + /** + * Return a promise that will resolve only once all the supplied promisesOrValues + * have resolved. The resolution value of the returned promise will be an array + * containing the resolution values of each of the promisesOrValues. + * @memberOf when + * + * @param {Array|Promise} promisesOrValues array of anything, may contain a mix + * of {@link Promise}s and values + * @param {function?} [onFulfilled] resolution handler + * @param {function?} [onRejected] rejection handler + * @param {function?} [onProgress] progress handler + * @returns {Promise} + */ + function all(promisesOrValues, onFulfilled, onRejected, onProgress) { + checkCallbacks(1, arguments); + return map(promisesOrValues, identity).then(onFulfilled, onRejected, onProgress); + } + + /** + * Joins multiple promises into a single returned promise. + * @return {Promise} a promise that will fulfill when *all* the input promises + * have fulfilled, or will reject when *any one* of the input promises rejects. + */ + function join(/* ...promises */) { + return map(arguments, identity); + } + + /** + * Traditional map function, similar to `Array.prototype.map()`, but allows + * input to contain {@link Promise}s and/or values, and mapFunc may return + * either a value or a {@link Promise} + * + * @param {Array|Promise} promise array of anything, may contain a mix + * of {@link Promise}s and values + * @param {function} mapFunc mapping function mapFunc(value) which may return + * either a {@link Promise} or value + * @returns {Promise} a {@link Promise} that will resolve to an array containing + * the mapped output values. + */ + function map(promise, mapFunc) { + return when(promise, function(array) { + var results, len, toResolve, resolve, i, d; + + // Since we know the resulting length, we can preallocate the results + // array to avoid array expansions. + toResolve = len = array.length >>> 0; + results = []; + d = defer(); + + if(!toResolve) { + d.resolve(results); + } else { + + resolve = function resolveOne(item, i) { + when(item, mapFunc).then(function(mapped) { + results[i] = mapped; + + if(!--toResolve) { + d.resolve(results); + } + }, d.reject); + }; + + // Since mapFunc may be async, get all invocations of it into flight + for(i = 0; i < len; i++) { + if(i in array) { + resolve(array[i], i); + } else { + --toResolve; + } + } + + } + + return d.promise; + + }); + } + + /** + * Traditional reduce function, similar to `Array.prototype.reduce()`, but + * input may contain promises and/or values, and reduceFunc + * may return either a value or a promise, *and* initialValue may + * be a promise for the starting value. + * + * @param {Array|Promise} promise array or promise for an array of anything, + * may contain a mix of promises and values. + * @param {function} reduceFunc reduce function reduce(currentValue, nextValue, index, total), + * where total is the total number of items being reduced, and will be the same + * in each call to reduceFunc. + * @returns {Promise} that will resolve to the final reduced value + */ + function reduce(promise, reduceFunc /*, initialValue */) { + var args = slice.call(arguments, 1); + + return when(promise, function(array) { + var total; + + total = array.length; + + // Wrap the supplied reduceFunc with one that handles promises and then + // delegates to the supplied. + args[0] = function (current, val, i) { + return when(current, function (c) { + return when(val, function (value) { + return reduceFunc(c, value, i, total); + }); + }); + }; + + return reduceArray.apply(array, args); + }); + } + + /** + * Ensure that resolution of promiseOrValue will trigger resolver with the + * value or reason of promiseOrValue, or instead with resolveValue if it is provided. + * + * @param promiseOrValue + * @param {Object} resolver + * @param {function} resolver.resolve + * @param {function} resolver.reject + * @param {*} [resolveValue] + * @returns {Promise} + */ + function chain(promiseOrValue, resolver, resolveValue) { + var useResolveValue = arguments.length > 2; + + return when(promiseOrValue, + function(val) { + val = useResolveValue ? resolveValue : val; + resolver.resolve(val); + return val; + }, + function(reason) { + resolver.reject(reason); + return rejected(reason); + }, + resolver.progress + ); + } + + // + // Utility functions + // + + /** + * Apply all functions in queue to value + * @param {Array} queue array of functions to execute + * @param {*} value argument passed to each function + */ + function processQueue(queue, value) { + var handler, i = 0; + + while (handler = queue[i++]) { + handler(value); + } + } + + /** + * Helper that checks arrayOfCallbacks to ensure that each element is either + * a function, or null or undefined. + * @private + * @param {number} start index at which to start checking items in arrayOfCallbacks + * @param {Array} arrayOfCallbacks array to check + * @throws {Error} if any element of arrayOfCallbacks is something other than + * a functions, null, or undefined. + */ + function checkCallbacks(start, arrayOfCallbacks) { + // TODO: Promises/A+ update type checking and docs + var arg, i = arrayOfCallbacks.length; + + while(i > start) { + arg = arrayOfCallbacks[--i]; + + if (arg != null && typeof arg != 'function') { + throw new Error('arg '+i+' must be a function'); + } + } + } + + /** + * No-Op function used in method replacement + * @private + */ + function noop() {} + + slice = [].slice; + + // ES5 reduce implementation if native not available + // See: http://es5.github.com/#x15.4.4.21 as there are many + // specifics and edge cases. + reduceArray = [].reduce || + function(reduceFunc /*, initialValue */) { + /*jshint maxcomplexity: 7*/ + + // ES5 dictates that reduce.length === 1 + + // This implementation deviates from ES5 spec in the following ways: + // 1. It does not check if reduceFunc is a Callable + + var arr, args, reduced, len, i; + + i = 0; + // This generates a jshint warning, despite being valid + // "Missing 'new' prefix when invoking a constructor." + // See https://github.com/jshint/jshint/issues/392 + arr = Object(this); + len = arr.length >>> 0; + args = arguments; + + // If no initialValue, use first item of array (we know length !== 0 here) + // and adjust i to start at second item + if(args.length <= 1) { + // Skip to the first real element in the array + for(;;) { + if(i in arr) { + reduced = arr[i++]; + break; + } + + // If we reached the end of the array without finding any real + // elements, it's a TypeError + if(++i >= len) { + throw new TypeError(); + } + } + } else { + // If initialValue provided, use it + reduced = args[1]; + } + + // Do the actual reduce + for(;i < len; ++i) { + // Skip holes + if(i in arr) { + reduced = reduceFunc(reduced, arr[i], i, arr); + } + } + + return reduced; + }; + + function identity(x) { + return x; + } + + return when; }); })(typeof define == 'function' && define.amd - ? define - : function (factory) { typeof exports === 'object' - ? (module.exports = factory()) - : (this.when = factory()); - } - // Boilerplate for AMD, Node, and browser global + ? define + : function (factory) { typeof exports === 'object' + ? (module.exports = factory()) + : (this.when = factory()); + } + // Boilerplate for AMD, Node, and browser global ); \ No newline at end of file diff --git a/Source/copyrightHeader.js b/Source/copyrightHeader.js index 88652d6fedb6..fc1fead0921a 100755 --- a/Source/copyrightHeader.js +++ b/Source/copyrightHeader.js @@ -1,4 +1,6 @@ -/*! +/** + * Cesium - https://github.com/AnalyticalGraphicsInc/cesium + * * Copyright 2011-2012 Cesium Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,4 +16,7 @@ * limitations under the License. * * Columbus View (Pat. Pend.) + * + * Portions licensed separately. + * See https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md for full licensing details. */ diff --git a/ThirdParty/almond-0.2.3/almond.js b/ThirdParty/almond-0.2.3/almond.js index 3a3e0c40f5b2..9bb339a388a5 100644 --- a/ThirdParty/almond-0.2.3/almond.js +++ b/ThirdParty/almond-0.2.3/almond.js @@ -1,4 +1,5 @@ /** + * @license * almond 0.2.3 Copyright (c) 2011-2012, The Dojo Foundation All Rights Reserved. * Available via the MIT or new BSD license. * see: http://github.com/jrburke/almond for details diff --git a/Tools/buildTasks/glslToJavaScript.js b/Tools/buildTasks/glslToJavaScript.js index 5f2d835fba09..a5159f9ffb71 100755 --- a/Tools/buildTasks/glslToJavaScript.js +++ b/Tools/buildTasks/glslToJavaScript.js @@ -46,7 +46,7 @@ for ( var i = 0, len = glslFilesets.size(); i < len; ++i) { contents = contents.replace(/\r\n/gm, '\n'); var copyrightComments = ''; - var extractedCopyrightComments = contents.match(/\/\*\!(?:.|\n)*?\*\//gm); + var extractedCopyrightComments = contents.match(/\/\*\*(?:[^*\/]|\*(?!\/)|\n)*?@license(?:.|\n)*?\*\//gm); if (extractedCopyrightComments) { copyrightComments = extractedCopyrightComments.join('\n') + '\n'; }