From 3f6e6820db627fcb9ee950d316d842e287757dac Mon Sep 17 00:00:00 2001 From: hpinkos Date: Mon, 19 Mar 2018 14:16:10 -0400 Subject: [PATCH] html credits --- CHANGES.md | 4 + LICENSE.md | 28 + Source/Assets/Images/bing_maps_credit.png | Bin 0 -> 18831 bytes Source/Assets/Images/cesium_credit.png | Bin 0 -> 4242 bytes Source/Assets/Images/google_earth_credit.png | Bin 0 -> 7703 bytes Source/Core/BingMapsApi.js | 5 +- Source/Core/CesiumTerrainProvider.js | 9 +- Source/Core/Credit.js | 204 ++- Source/Core/GoogleEarthEnterpriseMetadata.js | 2 +- .../GoogleEarthEnterpriseTerrainProvider.js | 2 +- Source/Core/IonResource.js | 9 +- Source/Core/MapboxApi.js | 5 +- Source/Core/VRTheWorldTerrainProvider.js | 2 +- .../Scene/ArcGisMapServerImageryProvider.js | 2 +- Source/Scene/BingMapsImageryProvider.js | 14 +- Source/Scene/CreditDisplay.js | 181 +- .../GoogleEarthEnterpriseImageryProvider.js | 2 +- .../GoogleEarthEnterpriseMapsProvider.js | 10 +- Source/Scene/IonImageryProvider.js | 9 +- Source/Scene/MapboxImageryProvider.js | 27 +- Source/Scene/SingleTileImageryProvider.js | 2 +- Source/Scene/UrlTemplateImageryProvider.js | 2 +- .../Scene/WebMapTileServiceImageryProvider.js | 8 +- .../createOpenStreetMapImageryProvider.js | 4 +- Source/ThirdParty/xss.js | 1613 +++++++++++++++++ Source/Widgets/CesiumWidget/CesiumWidget.js | 2 - Specs/Core/CesiumTerrainProviderSpec.js | 4 +- Specs/Scene/CreditDisplaySpec.js | 487 +---- Specs/Scene/MapboxImageryProviderSpec.js | 4 +- 29 files changed, 1976 insertions(+), 665 deletions(-) create mode 100644 Source/Assets/Images/bing_maps_credit.png create mode 100644 Source/Assets/Images/cesium_credit.png create mode 100644 Source/Assets/Images/google_earth_credit.png create mode 100644 Source/ThirdParty/xss.js diff --git a/CHANGES.md b/CHANGES.md index c0f2c80ef5ce..397b924b117c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,9 @@ Change Log ##### Deprecated :hourglass_flowing_sand: * `ClippingPlaneCollection` is now supported in Internet Explorer, so `ClippingPlaneCollection.isSupported` has been deprecated and will be removed in Cesium 1.45. * `ClippingPlaneCollection` should now be used with `ClippingPlane` objects instead of `Plane`. Use of `Plane` objects has been deprecated and will be removed in Cesium 1.45. +* `Credit` now takes an `html` and `showOnScreen` parameters instead of an `options` object. Use of the `options` parameter is deprecated and will be removed in Cesium 1.46. +* `Credit.text`, `Credit.imageUrl` and `Credit.link` properties have all been deprecated and will be removed in Cesium 1.46. Use `Credit.html` to retrieve the credit content. +* `Credit.hasImage` and `Credit.hasLink` functions have been deprecated and will be removed in Cesium 1.46. ##### Additions :tada: * Added support for glTF models with [Draco geometry compression](https://github.com/fanzhanggoogle/glTF/blob/KHR_mesh_compression/extensions/Khronos/KHR_draco_mesh_compression/README.md). @@ -20,6 +23,7 @@ Change Log * sourceType specifies the type of data source if the URL doesn't have a known file extension. * flyTo=false optionally disables the automatic flyTo after loading the data source. * Added a multi-part CZML example to Sandcastle. [#6320](https://github.com/AnalyticalGraphicsInc/cesium/pull/6320) +* `Credit` has been modified to take an HTML string as the credit content [#6331](https://github.com/AnalyticalGraphicsInc/cesium/pull/6331) ##### Fixes :wrench: * Fixed support of glTF-supplied tangent vectors. [#6302](https://github.com/AnalyticalGraphicsInc/cesium/pull/6302) diff --git a/LICENSE.md b/LICENSE.md index 31245d76d8e4..4c062b3fc734 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -686,6 +686,34 @@ https://github.com/google/draco >License for the specific language governing permissions and limitations under >the License. +### JSXSS + +https://github.com/leizongmin/js-xss + +> Copyright (c) 2012-2017 Zongmin Lei(雷宗民) +> http://ucdok.com +> +> The MIT License +> +> 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. + Tests ===== diff --git a/Source/Assets/Images/bing_maps_credit.png b/Source/Assets/Images/bing_maps_credit.png new file mode 100644 index 0000000000000000000000000000000000000000..15109db3cd4937eddafbb1400e5cd778cc4cb7e6 GIT binary patch literal 18831 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 z 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 literal 0 HcmV?d00001 diff --git a/Source/Assets/Images/google_earth_credit.png b/Source/Assets/Images/google_earth_credit.png new file mode 100644 index 0000000000000000000000000000000000000000..a7622d822d38c661a56b32be271b815691b6df7f GIT binary patch literal 7703 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 Rvh4r>002ovPDHLkV1jBLV0Hii literal 0 HcmV?d00001 diff --git a/Source/Core/BingMapsApi.js b/Source/Core/BingMapsApi.js index fbca04299f50..6d6032d28297 100644 --- a/Source/Core/BingMapsApi.js +++ b/Source/Core/BingMapsApi.js @@ -52,10 +52,7 @@ define([ } if (!defined(errorCredit)) { - errorCredit = new Credit({ - text : errorString, - showOnScreen : true - }); + errorCredit = new Credit(errorString, true); } return errorCredit; diff --git a/Source/Core/CesiumTerrainProvider.js b/Source/Core/CesiumTerrainProvider.js index cdd7644fe905..97760891cde1 100644 --- a/Source/Core/CesiumTerrainProvider.js +++ b/Source/Core/CesiumTerrainProvider.js @@ -131,7 +131,7 @@ define([ var credit = options.credit; if (typeof credit === 'string') { - credit = new Credit({text: credit}); + credit = new Credit(credit); } this._credit = credit; @@ -163,12 +163,11 @@ define([ var uri = new Uri(metadataResource.url); if (uri.authority === 'assets.agi.com') { - var deprecationText = 'The STK World Terrain tileset is deprecated and will be available until September 1, 2018'; + var deprecationText = 'The STK World Terrain tileset is deprecated and will be available until September 1, 2018.'; var deprecationLinkText = 'Check out the new high-resolution Cesium World Terrain'; var deprecationLink = 'https://cesium.com/blog/2018/03/01/introducing-cesium-world-terrain/'; that._tileCredits = [ - new Credit({ text: deprecationText, showOnScreen: true }), - new Credit({ text: deprecationLinkText, link: deprecationLink, showOnScreen: true }) + new Credit('' + deprecationText + ' ' + deprecationLinkText + '', true) ]; deprecationWarning('assets.agi.com', deprecationText + ' ' + deprecationLinkText + ' ' + deprecationLink); } else { @@ -327,7 +326,7 @@ define([ } } - var layerJsonCredit = new Credit({ text: attribution }); + var layerJsonCredit = new Credit(attribution); if (defined(that._tileCredits)) { that._tileCredits.push(layerJsonCredit); diff --git a/Source/Core/Credit.js b/Source/Core/Credit.js index 596339ef4d70..5e4bff76dc4b 100644 --- a/Source/Core/Credit.js +++ b/Source/Core/Credit.js @@ -1,62 +1,39 @@ define([ - './defaultValue', - './defined', - './defineProperties', - './DeveloperError' - ], function( - defaultValue, - defined, - defineProperties, - DeveloperError) { + './defaultValue', + './defined', + './defineProperties', + './deprecationWarning', + './DeveloperError', + '../ThirdParty/xss' +], function( + defaultValue, + defined, + defineProperties, + deprecationWarning, + DeveloperError, + xss) { 'use strict'; var nextCreditId = 0; var creditToId = {}; + function createDomNode(html) { + var span = document.createElement('span'); + span.innerHTML = html; + + return span; + } + function getElement(credit) { - var element = document.createElement('span'); - var text = credit.text; - var link = credit.link; - var a; - if (credit._hasImage) { - var content = document.createElement('img'); - content.src = credit.imageUrl; - if (defined(text)) { - content.alt = text; - content.title = text; - } - if (credit._hasLink) { - a = document.createElement('a'); - a.appendChild(content); - a.href = link; - a.target = '_blank'; - element.appendChild(a); - } else { - element.appendChild(content); - } - element.className = 'cesium-credit-image'; - } else { - if (credit._hasLink) { - a = document.createElement('a'); - a.textContent = text; - a.href = link; - a.target = '_blank'; - element.appendChild(a); - } else { - element.textContent = text; - } - element.className = 'cesium-credit-text'; - } - return element; + var html = credit.html; + html = xss(html); + return createDomNode(html); } /** * A credit contains data pertaining to how to display attributions/credits for certain content on the screen. - * @param {Object} [options] An object with the following properties - * @param {String} [options.text] The text to be displayed on the screen if no imageUrl is specified. - * @param {String} [options.imageUrl] The source location for an image - * @param {String} [options.link] A URL location for which the credit will be hyperlinked - * @param {Boolean} [options.showOnScreen=false] If true, the credit will be visible in the main credit container. Otherwise, it will appear in a popover + * @param {String} html An string representing an html code snippet (can be text only) + * @param {Boolean} [showOnScreen=false] If true, the credit will be visible in the main credit container. Otherwise, it will appear in a popover * * @alias Credit * @constructor @@ -71,38 +48,74 @@ define([ * link : 'https://cesiumjs.org/' * }); */ - function Credit(options) { - options = defaultValue(options, defaultValue.EMPTY_OBJECT); + function Credit(html, showOnScreen) { + var id; + var key; + if (typeof html !== 'string') { + var options = defaultValue(html, defaultValue.EMPTY_OBJECT); + deprecationWarning('Credit options', 'The options parameter has been deprecated and will be removed in Cesium 1.46. Instead, pass in an HTML string (or a string of text)'); + showOnScreen = defaultValue(options.showOnScreen, showOnScreen); + var text = options.text; + var imageUrl = options.imageUrl; + var link = options.link; - var text = options.text; - var imageUrl = options.imageUrl; - var link = options.link; - var showOnScreen = defaultValue(options.showOnScreen, false); + var hasLink = (defined(link)); + var hasImage = (defined(imageUrl)); + var hasText = (defined(text)); - var hasLink = (defined(link)); - var hasImage = (defined(imageUrl)); - var hasText = (defined(text)); + //>>includeStart('debug', pragmas.debug); + if (!hasText && !hasImage && !hasLink) { + throw new DeveloperError('options.text, options.imageUrl, or options.link is required.'); + } + //>>includeEnd('debug'); - //>>includeStart('debug', pragmas.debug); - if (!hasText && !hasImage && !hasLink) { - throw new DeveloperError('options.text, options.imageUrl, or options.link is required.'); - } - //>>includeEnd('debug'); + if (!hasText && !hasImage) { + text = link; + } - if (!hasText && !hasImage) { - text = link; - } + this._text = text; + this._imageUrl = imageUrl; + this._link = link; + this._hasLink = hasLink; + this._hasImage = hasImage; - this._text = text; - this._imageUrl = imageUrl; - this._link = link; - this._hasLink = hasLink; - this._hasImage = hasImage; - this._showOnScreen = showOnScreen; + var element = document.createElement('span'); + var a; + if (hasImage) { + var content = document.createElement('img'); + content.src = imageUrl; + if (defined(text)) { + content.alt = text; + content.title = text; + } + if (hasLink) { + a = document.createElement('a'); + a.appendChild(content); + a.href = link; + a.target = '_blank'; + element.appendChild(a); + } else { + element.appendChild(content); + } + element.className = 'cesium-credit-image'; + } else { + if (hasLink) { + a = document.createElement('a'); + a.textContent = text; + a.href = link; + a.target = '_blank'; + element.appendChild(a); + } else { + element.textContent = text; + } + element.className = 'cesium-credit-text'; + } - // Credits are immutable so generate an id to use to optimize equal() - var id; - var key = JSON.stringify([text, imageUrl, link]); + html = '' + element.innerHTML + ''; + key = JSON.stringify([text, imageUrl, link]); + } else { + key = html; + } if (defined(creditToId[key])) { id = creditToId[key]; @@ -111,12 +124,27 @@ define([ creditToId[key] = id; } - this._id = id; + showOnScreen = defaultValue(showOnScreen, false); + // Credits are immutable so generate an id to use to optimize equal() + this._id = id; + this._html = html; + this._showOnScreen = showOnScreen; this._element = undefined; } defineProperties(Credit.prototype, { + /** + * The credit content + * @memberof Credit.prototype + * @type {String} + * @readonly + */ + html : { + get : function() { + return this._html; + } + }, /** * The credit text * @memberof Credit.prototype @@ -125,6 +153,7 @@ define([ */ text : { get : function() { + deprecationWarning('Credit.text', 'Credit.text is deprecated and will be removed in Cesium 1.46. Instead, use Credit.html to get the credit content.'); return this._text; } }, @@ -137,6 +166,7 @@ define([ */ imageUrl : { get : function() { + deprecationWarning('Credit.imageUrl', 'Credit.imageUrl is deprecated and will be removed in Cesium 1.46. Instead, use Credit.html to get the credit content.'); return this._imageUrl; } }, @@ -149,6 +179,7 @@ define([ */ link : { get : function() { + deprecationWarning('Credit.link', 'Credit.link is deprecated and will be removed in Cesium 1.46. Instead, use Credit.html to get the credit content.'); return this._link; } }, @@ -200,6 +231,7 @@ define([ * @returns {Boolean} */ Credit.prototype.hasImage = function() { + deprecationWarning('Credit.hasImage', 'Credit.hasImage is deprecated and will be removed in Cesium 1.46.'); return this._hasImage; }; @@ -209,6 +241,7 @@ define([ * @returns {Boolean} */ Credit.prototype.hasLink = function() { + deprecationWarning('Credit.hasLink', 'Credit.hasLink is deprecated and will be removed in Cesium 1.46.'); return this._hasLink; }; @@ -236,5 +269,26 @@ define([ return Credit.equals(this, credit); }; + /** + * @private + * @param attribution + * @return {Credit} + */ + Credit.getIonCredit = function(attribution) { + var credit; + var showOnScreen = defined(attribution.collapsible) && !attribution.collapsible; + if (defined(attribution.html)) { + credit = new Credit(attribution.html, showOnScreen); + } else { + credit = new Credit({ + text: attribution.text, + link: attribution.url, + imageUrl: attribution.image + }, showOnScreen); + } + credit._isIon = true; + return credit; + }; + return Credit; }); diff --git a/Source/Core/GoogleEarthEnterpriseMetadata.js b/Source/Core/GoogleEarthEnterpriseMetadata.js index 1ad3392796f7..2d6b5e7fd66b 100644 --- a/Source/Core/GoogleEarthEnterpriseMetadata.js +++ b/Source/Core/GoogleEarthEnterpriseMetadata.js @@ -546,7 +546,7 @@ define([ var provider = providerInfo[i]; var copyrightString = provider.copyrightString; if (defined(copyrightString)) { - providers[provider.providerId] = new Credit({text: copyrightString.value}); + providers[provider.providerId] = new Credit(copyrightString.value); } } }) diff --git a/Source/Core/GoogleEarthEnterpriseTerrainProvider.js b/Source/Core/GoogleEarthEnterpriseTerrainProvider.js index bb0cc9f0e299..40fcffa7e54a 100644 --- a/Source/Core/GoogleEarthEnterpriseTerrainProvider.js +++ b/Source/Core/GoogleEarthEnterpriseTerrainProvider.js @@ -150,7 +150,7 @@ define([ var credit = options.credit; if (typeof credit === 'string') { - credit = new Credit({text: credit}); + credit = new Credit(credit); } this._credit = credit; diff --git a/Source/Core/IonResource.js b/Source/Core/IonResource.js index 329ddba62b3a..d814869f6131 100644 --- a/Source/Core/IonResource.js +++ b/Source/Core/IonResource.js @@ -130,14 +130,7 @@ define([ return this._credits; } - this._credits = this._ionEndpoint.attributions.map(function(attribution) { - return new Credit({ - text: attribution.text, - link: attribution.url, - imageUrl: attribution.image, - showOnScreen: defined(attribution.collapsible) && !attribution.collapsible - }); - }); + this._credits = this._ionEndpoint.attributions.map(Credit.getIonCredit); return this._credits; } diff --git a/Source/Core/MapboxApi.js b/Source/Core/MapboxApi.js index 1ca3b34368ba..59b600f021ff 100644 --- a/Source/Core/MapboxApi.js +++ b/Source/Core/MapboxApi.js @@ -47,10 +47,7 @@ define([ } if (!defined(errorCredit)) { - errorCredit = new Credit({ - text : errorString, - showOnScreen : true - }); + errorCredit = new Credit(errorString, true); } return errorCredit; diff --git a/Source/Core/VRTheWorldTerrainProvider.js b/Source/Core/VRTheWorldTerrainProvider.js index 21570b0b5961..a416dae9ead4 100644 --- a/Source/Core/VRTheWorldTerrainProvider.js +++ b/Source/Core/VRTheWorldTerrainProvider.js @@ -98,7 +98,7 @@ define([ var credit = options.credit; if (typeof credit === 'string') { - credit = new Credit({text: credit}); + credit = new Credit(credit); } this._credit = credit; diff --git a/Source/Scene/ArcGisMapServerImageryProvider.js b/Source/Scene/ArcGisMapServerImageryProvider.js index d5123ec76a33..7644ed4fe608 100644 --- a/Source/Scene/ArcGisMapServerImageryProvider.js +++ b/Source/Scene/ArcGisMapServerImageryProvider.js @@ -216,7 +216,7 @@ define([ } if (defined(data.copyrightText) && data.copyrightText.length > 0) { - that._credit = new Credit({text: data.copyrightText}); + that._credit = new Credit(data.copyrightText); } that._ready = true; diff --git a/Source/Scene/BingMapsImageryProvider.js b/Source/Scene/BingMapsImageryProvider.js index 7588ffcd01e3..ef450efe5d6c 100644 --- a/Source/Scene/BingMapsImageryProvider.js +++ b/Source/Scene/BingMapsImageryProvider.js @@ -1,5 +1,6 @@ define([ '../Core/BingMapsApi', + '../Core/buildModuleUrl', '../Core/Cartesian2', '../Core/Credit', '../Core/defaultValue', @@ -20,6 +21,7 @@ define([ './ImageryProvider' ], function( BingMapsApi, + buildModuleUrl, Cartesian2, Credit, defaultValue, @@ -118,11 +120,7 @@ define([ this._culture = defaultValue(options.culture, ''); this._tileDiscardPolicy = options.tileDiscardPolicy; this._proxy = options.proxy; - this._credit = new Credit({ - text: 'Bing Imagery', - imageUrl: BingMapsImageryProvider._logoData, - link: 'http://www.bing.com' - }); + this._credit = new Credit(''); /** * The default {@link ImageryLayer#gamma} to use for imagery layers created for this provider. @@ -200,9 +198,7 @@ define([ for (var attributionIndex = 0, attributionLength = attributionList.length; attributionIndex < attributionLength; ++attributionIndex) { var attribution = attributionList[attributionIndex]; - attribution.credit = new Credit({ - text: attribution.attribution - }); + attribution.credit = new Credit(attribution.attribution); var coverageAreas = attribution.coverageAreas; @@ -574,7 +570,7 @@ define([ return undefined; }; - BingMapsImageryProvider._logoData = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD0AAAAaCAYAAAAEy1RnAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAB3RJTUUH3gIDEgcPTMnXOQAAClZJREFUWMPdWGtsFNcV/u689uH1+sXaONhlWQzBENtxiUFBpBSLd60IpXHSNig4URtSYQUkRJNSi0igViVVVBJBaBsiAgKRQJSG8AgEHCCWU4iBCprY2MSgXfOI16y9D3s9Mzsztz9yB12WNU2i9Ecy0tHOzN4793zn3POdcy7BnRfJ8I7iB3SRDPeEExswLz8Y0DZIAYDIRGAgLQAm+7Xle31J3L3Anp1MZPY+BUBjorN332vgYhpgV1FRUd6TTz45ubq6OtDV1SXpuu5g//Oept9wNwlMyAi8IXDjyF245TsDTdivDMATCATGNDU1/WbhwoWPTZs2bWx1dXWhx+Oxrl+/PqTrus5t9W8KWEzjinTAYhro/xuBStwiIgBnJBLxKIoy1u/3V/r9/krDMMz3339/Z3t7e38ikUgCMDLEt8W+Q0cAI3McYTDDmZxh7DESG5Ni43jg9Gsa+X+OsxWxPSJTSj3JZFK5ZRVJErOzs8e6XC4fgGwALhbzDgAKU1hK28KEA6PMmTMn56233qpevnz5PQDcbJ7EzVUAuMrLy3MBeABkcWOEDELSyFe4y7iMoHkriZZlKYZh8ASHZDKpJJPJHAC5APIA5APIAeBlCjo5TwlpXnbOmTPHP3fu3KZVq1atZKBcDJQ9x7V48WJfc3Pzhp6enj+tXLnyR8w4MjdG4gyVDk7KICMClzKlLUrpbQMNw5AkScppbGz8cWdn57WjR4/2caw+DEBlYjO8wX1foZQWuN3uKZIklQD4G+fhlG0Yl8uVm5WVVW6app6dne0D0G8vnxbjJntHubCUOK/badZICyWanrJuAaeUknTQpmlKkUhEWbx48U8LCwtHhUKha+fPn+85fPhwV0tLyzUACSZx9jvMFhIByNFoVDEMw/qKB5HPvJfkUqBr9+7deklJyZ/j8bi5ffv2OAslieMLsG+m2DybT2QuzEQOsF5SUqJfvXo1yc2l6Xn6rgSRSCSEc+fOhVeuXLmwoqJixvTp0wcWLFgQ7unpudHR0dF97ty5z/fu3XseQJh5adjeerquy5ZlCalUivh8Pt8HH3ywzOPxyD09PZ81NjZ+2NnZaQEQx40b54vFYqaqquEVK1b4a2tr/WvWrDn18ssv144fP36SqqoD69ev371nz57rDLwAwHHkyJGfjRs3rtowDOv06dOnu7q6rs6bN2/s7Nmz9zIjDKenWoFZKg/AlMLCwl82Nzf/m3LX22+/fXb06NF/ALC8u7u7m6ZdkUhksL29/UpLS0vzunXrVgAoBzAaQBGAiY2NjUui0ei1RCLRFwwG/9PX19cVi8WCqqoOdHd3HysrK6sDMCccDl8IBoOtiqIsOnbs2D+i0eiV3t7ez8Ph8GeRSKRT07TB/v7+i1OnTp0HYBqABzs7O/+paVo0Fot1RyKRi/F4/Gp/f39XIpHoZnoUMn6wU+ZtRDaymwmxZFk2AWjvvvvuJ/F4PMn/n5+fn1VeXu6fOXNmbU1NzUOM4Bz8QqIoyg6HwxuLxfq3bdu2a+vWrW/09/dfKy0tffDVV199BEC20+n0ud3uQgBup9Pp83g8JYqieE+ePPnxxo0bt33xxRen8/Ly7n3hhRcWASh47bXX5pWVldWFw+GuXbt27XjzzTd3BoPBDq/XG1AUZRRHmAKPVfqaoKkgCCkA+oYNG84Eg0FHTU1N5ezZs8eWlJQ4CSF8/LvZYhJPQoQQpFKpwcrKyo1su9HBwUF99erVv588eXINgOOmacIwDEopdaZSKUIpxYkTJz6sr68/BMBav379RcMwZk2aNOl+AP+qq6t7xDTNVEVFxR+j0WgSAJk4ceKlTz/9tNzpdHpZvIvpjVW6pykhhBJCbkvwgiAQQogEQL558ybdtGlTsLm5OWJZdxZmlmWll5OUEEJN0zSGhob6GcOrALSzZ8/2apqWcLlc2axGACNRkRAimqaph0Kh68xIwwB0y7IMSZKcABz5+fkl8Xj8y2g0apOb5na7rYGBgS/JV54Q0qpAAoBKaS0jBWClg1ZVFeFw2AlgVF1dXeDpp5+eWVFRUVpcXOzgvQwAbrcbDJhdudlGpKZpGtx6JCcnRxIEQbQsS2PjbjM+AMvlchnMSBaXkr7ymCCIhmEYfMoVRVESBEHI0CaTTNubssUsQRBuubCtra33pZdeCk6YMCGwZs2aipqaGn9paWmuJEl3JP0bN258eeTIkRMABrm0YomiaImiKGVlZeWxLecAgBkzZvgdDkfWjRs3ggA0bpfpoiiahBCqKEqKAy2yULMA6MlkMp6Xl3cP1x2SWCwmFhQU+CmlFhfHNFOevpX4LcvSJUkyAeDQoUOh119//fpTTz01Zf78+UWBQCBHUZQ7yE/TNGPfvn0n33vvvSP79+//BECMeZsCMGRZNgRBgNPpHHXx4sVVDQ0Nf1+wYMGYJ554YikAevDgwUMA4oIgQJZlSggZdDqdBiGEZGdn6ww0tQlJURTT4/EMHz9+/MCjjz7622AwuHbZsmVbiouLvWvXrm1wOp3ZqVRqaKQTIInf1gAMl8ulU0q1CxcuBGOxmL5u3bryQCDgycrKEjORXGtra8eOHTsOHz169OyVK1cuA+hlRYrGlNRkWR7UNO2mYRiaz+cb3dLS8gYhhOi6Hj116tSOVatWHQNALcsaME0zLghClBDSZ9+zQsZ2SoJS2udwOKLPPffcvsrKyrJAIPDQ/v37txiGofX19V3r7e29UlBQMHqEVpjwnrYA6PF4PK6q6s2qqqqpZWVlitvtljOB7enpiWzbtu3wgQMHTre1tV0E0MeKkkGuIhMAqHv37u30er3Px+NxlyiKygMPPOAnhFiXLl0Kbd68uYPNsXbu3Lk6mUwaqqr2btmyZUdtbe3hd955pwvAEFNcO3jw4K/b2tqiqqpGIpGI4/HHH/9rQ0PDCa/XOyoSidDLly8PNTU1PcZ4QuNK1ju6NYHFRAGASXPnzv1Fa2vrxzTDpapqateuXR/Nnz+/SVGUhwFMBzCBFSLZLF75DsrJGpXRAH4EIABgPIBxAEoBFAPwARjFif1sNzZ25+VlOhaxufcCqAFQC+BhAPVLliz5XSqVUkOhUAuAKWnFyR3dlsw+fg+A+8eMGfPzTZs2bY9GozEb8JkzZ9qXLl36l+Li4l8B+AmAyQDGsGrOzfXNPGPawG2l85jksmcPm+vihH+2W1iF3bvZPN+sWbPuGx4eDrW3t+85fvz41o6OjmZN04Y0TYvV19cvYIbN5QqUjG2mwj5YAqDK4XDMe+aZZ55vbW09+sorr2yuqqpqYFatAuBn3uB7XzJCY297XeaUd2RoGzOJmHb6IjFj5D777LP3DQwMfDw8PBxSVbUvkUj0hEKhj1588cXH2O7zMSPdplumoxveMx5Zlj3jx4/39vb26gMDA4MsvgYZo+p8Pr7LqQX5Ds/U7d0jFxUVZS1atKg4Nzc317Isp67rZldXV6y5ufkmI78hFtcmrx8ZweMit6XsUs4+6kmlgbW+peLf9gyMZNCR374G0y/FxEzX8b/8+bkXEBxKFwAAAABJRU5ErkJggg=='; + BingMapsImageryProvider._logoData = buildModuleUrl('Assets/Images/bing_maps_credit.png'); /** * Converts a tiles (x, y, level) position into a quadkey used to request an image diff --git a/Source/Scene/CreditDisplay.js b/Source/Scene/CreditDisplay.js index 9eb709c98c11..d513f937f8c6 100644 --- a/Source/Scene/CreditDisplay.js +++ b/Source/Scene/CreditDisplay.js @@ -1,10 +1,12 @@ define([ + '../Core/buildModuleUrl', '../Core/Check', '../Core/Credit', '../Core/defaultValue', '../Core/defined', '../Core/destroyObject' ], function( + buildModuleUrl, Check, Credit, defaultValue, @@ -28,16 +30,36 @@ define([ return false; } - function displayTextCredits(creditDisplay, textCredits) { + function swapCesiumCredit(creditDisplay) { + // We don't want to clutter the screen with the Cesium logo and the Cesium ion + // logo at the same time. Since the ion logo is required, we just replace the + // Cesium logo or add the logo if the Cesium one was removed. + var previousCredit = creditDisplay._previousCesiumCredit; + var currentCredit = creditDisplay._currentCesiumCredit; + if (Credit.equals(currentCredit, previousCredit)) { + return; + } + + if (defined(previousCredit)) { + creditDisplay._cesiumCreditContainer.removeChild(previousCredit.element); + } + if (defined(currentCredit)) { + creditDisplay._cesiumCreditContainer.appendChild(currentCredit.element); + } + + creditDisplay._previousCesiumCredit = currentCredit; + } + + function displayCredits(creditDisplay, credits) { var i; var index; var credit; - var displayedTextCredits = creditDisplay._displayedCredits.textCredits; - var container = creditDisplay._textContainer; - for (i = 0; i < textCredits.length; i++) { - credit = textCredits[i]; + var displayedCredits = creditDisplay._displayedCredits.screenCredits; + var container = creditDisplay._screenContainer; + for (i = 0; i < credits.length; i++) { + credit = credits[i]; if (defined(credit)) { - index = displayedTextCredits.indexOf(credit); + index = displayedCredits.indexOf(credit); if (index === -1) { var element = credit.element; if (container.hasChildNodes()) { @@ -48,26 +70,7 @@ define([ } container.appendChild(element); } else { - displayedTextCredits.splice(index, 1); - } - } - } - } - - function displayImageCredits(creditDisplay, imageCredits) { - var i; - var index; - var credit; - var displayedImageCredits = creditDisplay._displayedCredits.imageCredits; - var container = creditDisplay._imageContainer; - for (i = 0; i < imageCredits.length; i++) { - credit = imageCredits[i]; - if (defined(credit)) { - index = displayedImageCredits.indexOf(credit); - if (index === -1) { - container.appendChild(credit.element); - } else { - displayedImageCredits.splice(index, 1); + displayedCredits.splice(index, 1); } } } @@ -100,12 +103,8 @@ define([ var container = credit.showOnScreen ? element.parentNode : element.parentNode.parentNode; - if (credit.hasImage() || !credit.showOnScreen) { - if (credit.showOnScreen) { - container.removeChild(element); - } else { - container.removeChild(element.parentNode); - } + if (!credit.showOnScreen) { + container.removeChild(element.parentNode); return; } @@ -122,20 +121,13 @@ define([ function removeUnusedCredits(creditDisplay) { var i; var credit; - var displayedTextCredits = creditDisplay._displayedCredits.textCredits; + var displayedTextCredits = creditDisplay._displayedCredits.screenCredits; for (i = 0; i < displayedTextCredits.length; i++) { credit = displayedTextCredits[i]; if (defined(credit)) { removeCreditDomElement(credit); } } - var displayedImageCredits = creditDisplay._displayedCredits.imageCredits; - for (i = 0; i < displayedImageCredits.length; i++) { - credit = displayedImageCredits[i]; - if (defined(credit)) { - removeCreditDomElement(credit); - } - } } function removeUnusedLightboxCredits(creditDisplay) { @@ -205,11 +197,11 @@ define([ margin : 'auto' }); - style += addStyle('.cesium-credit-lightbox > ul > li > span > a, .cesium-credit-lightbox > ul > li > span > a:visited', { + style += addStyle('.cesium-credit-lightbox > ul > li > span a, .cesium-credit-lightbox > ul > li > span a:visited', { color: textColor }); - style += addStyle('.cesium-credit-lightbox > ul > li > span > a:hover', { + style += addStyle('.cesium-credit-lightbox > ul > li > span a:hover', { color: highlightColor }); @@ -270,12 +262,8 @@ define([ head.insertBefore(css, head.firstChild); } - var cesiumCredit = new Credit({ - text: 'CesiumJS', - imageUrl: 'data:image/png;base64,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', - link: 'https://cesiumjs.org/', - showOnScreen: true - }); + var cesiumLogo = buildModuleUrl('Assets/Images/cesium_credit.png'); + var cesiumCredit = new Credit('', true); /** * The credit display is responsible for displaying credits on screen. @@ -328,13 +316,12 @@ define([ var creditList = document.createElement('ul'); lightboxCredits.appendChild(creditList); - var imageContainer = document.createElement('span'); - imageContainer.className = 'cesium-credit-imageContainer'; - container.appendChild(imageContainer); + var cesiumCreditContainer = document.createElement('span'); + container.appendChild(cesiumCreditContainer); - var textContainer = document.createElement('span'); - textContainer.className = 'cesium-credit-textContainer'; - container.appendChild(textContainer); + var screenContainer = document.createElement('span'); + screenContainer.className = 'cesium-credit-textContainer'; + container.appendChild(screenContainer); var expandLink = document.createElement('a'); expandLink.className = 'cesium-credit-expand-link'; @@ -345,8 +332,8 @@ define([ appendCss(); this._delimiter = defaultValue(delimiter, ' • '); - this._textContainer = textContainer; - this._imageContainer = imageContainer; + this._screenContainer = screenContainer; + this._cesiumCreditContainer = cesiumCreditContainer; this._lastViewportHeight = undefined; this._lastViewportWidth = undefined; this._lightboxCredits = lightboxCredits; @@ -355,17 +342,16 @@ define([ this._hideLightbox = hideLightbox; this._expandLink = expandLink; this._expanded = false; - this._defaultImageCredits = []; - this._defaultTextCredits = []; + this._defaultCredits = []; + this._previousCesiumCredit = undefined; + this._currentCesiumCredit = CreditDisplay.cesiumCredit; this._displayedCredits = { - imageCredits : [], - textCredits : [], + screenCredits : [], lightboxCredits : [] }; this._currentFrameCredits = { - imageCredits : [], - textCredits : [], + screenCredits : [], lightboxCredits : [] }; @@ -388,23 +374,14 @@ define([ Check.defined('credit', credit); //>>includeEnd('debug'); - var imageCredits = this._currentFrameCredits.imageCredits; + var screenCredits = this._currentFrameCredits.screenCredits; - if (credit.text === 'Cesium ion') { - // We don't want to clutter the screen with the Cesium logo and the Cesium ion - // logo at the same time. Since the ion logo is required, we just replace the - // Cesium logo or add the logo if the Cesium one was removed. - if (defined(imageCredits[cesiumCredit.id])) { - imageCredits[cesiumCredit.id] = credit; - } else { - imageCredits[credit.id] = credit; - } + if (credit._isIon) { + this._currentCesiumCredit = credit; } else if (!credit.showOnScreen) { this._currentFrameCredits.lightboxCredits[credit.id] = credit; - } else if (credit.hasImage()) { - imageCredits[credit.id] = credit; } else { - this._currentFrameCredits.textCredits[credit.id] = credit; + screenCredits[credit.id] = credit; } }; @@ -418,16 +395,9 @@ define([ Check.defined('credit', credit); //>>includeEnd('debug'); - if (credit.hasImage()) { - var imageCredits = this._defaultImageCredits; - if (!contains(imageCredits, credit)) { - imageCredits.push(credit); - } - } else { - var textCredits = this._defaultTextCredits; - if (!contains(textCredits, credit)) { - textCredits.push(credit); - } + var credits = this._defaultCredits; + if (!contains(credits, credit)) { + credits.push(credit); } }; @@ -441,17 +411,9 @@ define([ Check.defined('credit', credit); //>>includeEnd('debug'); - var index; - if (credit.hasImage()) { - index = this._defaultImageCredits.indexOf(credit); - if (index !== -1) { - this._defaultImageCredits.splice(index, 1); - } - } else { - index = this._defaultTextCredits.indexOf(credit); - if (index !== -1) { - this._defaultTextCredits.splice(index, 1); - } + var index = this._defaultCredits.indexOf(credit); + if (index !== -1) { + this._defaultCredits.splice(index, 1); } }; @@ -486,36 +448,27 @@ define([ * Resets the credit display to a beginning of frame state, clearing out current credits. */ CreditDisplay.prototype.beginFrame = function() { - this._currentFrameCredits.imageCredits.length = 0; - this._currentFrameCredits.textCredits.length = 0; + this._currentFrameCredits.screenCredits.length = 0; this._currentFrameCredits.lightboxCredits.length = 0; - - var cesiumCredit = CreditDisplay.cesiumCredit; - if (defined(cesiumCredit)) { - this._currentFrameCredits.imageCredits[cesiumCredit.id] = cesiumCredit; - } + this._currentCesiumCredit = CreditDisplay.cesiumCredit; }; /** * Sets the credit display to the end of frame state, displaying credits from the last frame in the credit container. */ CreditDisplay.prototype.endFrame = function() { - displayImageCredits(this, this._defaultImageCredits); - displayTextCredits(this, this._defaultTextCredits); - - displayImageCredits(this, this._currentFrameCredits.imageCredits); - displayTextCredits(this, this._currentFrameCredits.textCredits); + displayCredits(this, this._defaultCredits); + displayCredits(this, this._currentFrameCredits.screenCredits); - var displayedTextCredits = this._defaultTextCredits.concat(this._currentFrameCredits.textCredits); - var displayedImageCredits = this._defaultImageCredits.concat(this._currentFrameCredits.imageCredits); + var displayedScreenCredits = this._defaultCredits.concat(this._currentFrameCredits.screenCredits); var showLightboxLink = this._currentFrameCredits.lightboxCredits.length > 0; this._expandLink.style.display = showLightboxLink ? 'inline' : 'none'; removeUnusedCredits(this); + swapCesiumCredit(this); - this._displayedCredits.textCredits = displayedTextCredits; - this._displayedCredits.imageCredits = displayedImageCredits; + this._displayedCredits.screenCredits = displayedScreenCredits; this._creditsToUpdate = this._currentFrameCredits.lightboxCredits.slice(); }; @@ -533,8 +486,8 @@ define([ CreditDisplay.prototype.destroy = function() { this._lightbox.removeEventListener('click', this._hideLightbox, false); - this.container.removeChild(this._textContainer); - this.container.removeChild(this._imageContainer); + this.container.removeChild(this._cesiumCreditContainer); + this.container.removeChild(this._screenContainer); this.container.removeChild(this._expandLink); this.viewport.removeChild(this._lightbox); diff --git a/Source/Scene/GoogleEarthEnterpriseImageryProvider.js b/Source/Scene/GoogleEarthEnterpriseImageryProvider.js index e3602588038d..25e99b644153 100644 --- a/Source/Scene/GoogleEarthEnterpriseImageryProvider.js +++ b/Source/Scene/GoogleEarthEnterpriseImageryProvider.js @@ -133,7 +133,7 @@ define([ var credit = options.credit; if (typeof credit === 'string') { - credit = new Credit({text: credit}); + credit = new Credit(credit); } this._credit = credit; diff --git a/Source/Scene/GoogleEarthEnterpriseMapsProvider.js b/Source/Scene/GoogleEarthEnterpriseMapsProvider.js index 7e48643fae7b..3a961721987a 100644 --- a/Source/Scene/GoogleEarthEnterpriseMapsProvider.js +++ b/Source/Scene/GoogleEarthEnterpriseMapsProvider.js @@ -1,4 +1,5 @@ define([ + '../Core/buildModuleUrl', '../Core/Credit', '../Core/defaultValue', '../Core/defined', @@ -15,6 +16,7 @@ define([ '../ThirdParty/when', './ImageryProvider' ], function( + buildModuleUrl, Credit, defaultValue, defined, @@ -134,11 +136,7 @@ define([ this._tileDiscardPolicy = options.tileDiscardPolicy; this._channel = options.channel; this._requestType = 'ImageryMaps'; - this._credit = new Credit({ - text: 'Google Imagery', - imageUrl: GoogleEarthEnterpriseMapsProvider._logoData, - link: 'http://www.google.com/enterprise/mapsearth/products/earthenterprise.html' - }); + this._credit = new Credit(''); /** * The default {@link ImageryLayer#gamma} to use for imagery layers created for this provider. @@ -607,7 +605,7 @@ define([ return undefined; }; - GoogleEarthEnterpriseMapsProvider._logoData = 'data:image/png;base64,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'; + GoogleEarthEnterpriseMapsProvider._logoData = buildModuleUrl('Assets/Images/google_earth_credit.png'); return GoogleEarthEnterpriseMapsProvider; }); diff --git a/Source/Scene/IonImageryProvider.js b/Source/Scene/IonImageryProvider.js index 1dca249c0ca5..48205d1dea2d 100644 --- a/Source/Scene/IonImageryProvider.js +++ b/Source/Scene/IonImageryProvider.js @@ -185,14 +185,7 @@ define([ imageryProvider = factory(endpoint.options); } - that._tileCredits = endpoint.attributions.map(function(attribution) { - return new Credit({ - text: attribution.text, - link: attribution.url, - imageUrl: attribution.image, - showOnScreen: defined(attribution.collapsible) && !attribution.collapsible - }); - }); + that._tileCredits = endpoint.attributions.map(Credit.getIonCredit); return imageryProvider; }) diff --git a/Source/Scene/MapboxImageryProvider.js b/Source/Scene/MapboxImageryProvider.js index ac46c2693cd6..a6826f7e9728 100644 --- a/Source/Scene/MapboxImageryProvider.js +++ b/Source/Scene/MapboxImageryProvider.js @@ -21,14 +21,7 @@ define([ 'use strict'; var trailingSlashRegex = /\/$/; - var defaultCredit1 = new Credit({ - text:'© Mapbox © OpenStreetMap', - link: 'https://www.mapbox.com/about/maps/' - }); - var defaultCredit2 = [new Credit({ - text: 'Improve this map', - link: 'https://www.mapbox.com/map-feedback/' - })]; + var defaultCredit = new Credit('© Mapbox © OpenStreetMap Improve this map'); /** * Provides tiled imagery hosted by Mapbox. @@ -104,19 +97,20 @@ define([ access_token: accessToken }); + var credit; if (defined(options.credit)) { - var credit = options.credit; + credit = options.credit; if (typeof credit === 'string') { - credit = new Credit({text: credit}); + credit = new Credit(credit); } - defaultCredit1 = credit; - defaultCredit2.length = 0; + } else { + credit = defaultCredit; } this._resource = resource; this._imageryProvider = new UrlTemplateImageryProvider({ url: resource, - credit: defaultCredit1, + credit: credit, ellipsoid: options.ellipsoid, minimumLevel: options.minimumLevel, maximumLevel: options.maximumLevel, @@ -326,11 +320,9 @@ define([ * @exception {DeveloperError} getTileCredits must not be called before the imagery provider is ready. */ MapboxImageryProvider.prototype.getTileCredits = function(x, y, level) { - var credits = defaultCredit2.slice(); if (defined(this._accessTokenErrorCredit)) { - credits.push(this._accessTokenErrorCredit); + return [this._accessTokenErrorCredit]; } - return credits; }; /** @@ -374,5 +366,8 @@ define([ return this._imageryProvider.pickFeatures(x, y, level, longitude, latitude); }; + // Exposed for tests + MapboxImageryProvider._defaultCredit = defaultCredit; + return MapboxImageryProvider; }); diff --git a/Source/Scene/SingleTileImageryProvider.js b/Source/Scene/SingleTileImageryProvider.js index 2a2e676e9201..1ad86c008ebf 100644 --- a/Source/Scene/SingleTileImageryProvider.js +++ b/Source/Scene/SingleTileImageryProvider.js @@ -87,7 +87,7 @@ define([ var credit = options.credit; if (typeof credit === 'string') { - credit = new Credit({text: credit}); + credit = new Credit(credit); } this._credit = credit; diff --git a/Source/Scene/UrlTemplateImageryProvider.js b/Source/Scene/UrlTemplateImageryProvider.js index 029a097934d3..f325eade8085 100644 --- a/Source/Scene/UrlTemplateImageryProvider.js +++ b/Source/Scene/UrlTemplateImageryProvider.js @@ -620,7 +620,7 @@ define([ var credit = properties.credit; if (typeof credit === 'string') { - credit = new Credit({text: credit}); + credit = new Credit(credit); } that._credit = credit; diff --git a/Source/Scene/WebMapTileServiceImageryProvider.js b/Source/Scene/WebMapTileServiceImageryProvider.js index 0ec60896e918..6378d84595f6 100644 --- a/Source/Scene/WebMapTileServiceImageryProvider.js +++ b/Source/Scene/WebMapTileServiceImageryProvider.js @@ -87,7 +87,7 @@ define([ * tileMatrixSetID : 'default028mm', * // tileMatrixLabels : ['default028mm:0', 'default028mm:1', 'default028mm:2' ...], * maximumLevel: 19, - * credit : new Cesium.Credit({ text : 'U. S. Geological Survey' }) + * credit : new Cesium.Credit('U. S. Geological Survey') * }); * viewer.imageryLayers.addImageryProvider(shadedRelief1); * @@ -100,7 +100,7 @@ define([ * format : 'image/jpeg', * tileMatrixSetID : 'default028mm', * maximumLevel: 19, - * credit : new Cesium.Credit({ text : 'U. S. Geological Survey' }) + * credit : new Cesium.Credit('U. S. Geological Survey') * }); * viewer.imageryLayers.addImageryProvider(shadedRelief2); * @@ -123,7 +123,7 @@ define([ * format : 'image/png', * clock: clock, * times: times, - * credit : new Cesium.Credit({ text : 'NASA Global Imagery Browse Services for EOSDIS' }) + * credit : new Cesium.Credit('NASA Global Imagery Browse Services for EOSDIS') * }); * viewer.imageryLayers.addImageryProvider(weather); * @@ -234,7 +234,7 @@ define([ this._errorEvent = new Event(); var credit = options.credit; - this._credit = typeof credit === 'string' ? new Credit({text: credit}) : credit; + this._credit = typeof credit === 'string' ? new Credit(credit) : credit; this._subdomains = options.subdomains; if (isArray(this._subdomains)) { diff --git a/Source/Scene/createOpenStreetMapImageryProvider.js b/Source/Scene/createOpenStreetMapImageryProvider.js index 62ca813375e0..da0a604ad770 100644 --- a/Source/Scene/createOpenStreetMapImageryProvider.js +++ b/Source/Scene/createOpenStreetMapImageryProvider.js @@ -22,7 +22,7 @@ define([ UrlTemplateImageryProvider) { 'use strict'; - var defaultCredit = new Credit({text: 'MapQuest, Open Street Map and contributors, CC-BY-SA'}); + var defaultCredit = new Credit('MapQuest, Open Street Map and contributors, CC-BY-SA'); /** * Creates a {@link UrlTemplateImageryProvider} instance that provides tiled imagery hosted by OpenStreetMap @@ -101,7 +101,7 @@ define([ var credit = defaultValue(options.credit, defaultCredit); if (typeof credit === 'string') { - credit = new Credit({text: credit}); + credit = new Credit(credit); } return new UrlTemplateImageryProvider({ diff --git a/Source/ThirdParty/xss.js b/Source/ThirdParty/xss.js new file mode 100644 index 000000000000..24871d6276b4 --- /dev/null +++ b/Source/ThirdParty/xss.js @@ -0,0 +1,1613 @@ +/** +* @license +* Copyright (c) 2012-2017 Zongmin Lei(雷宗民) +* http://ucdok.com +* The MIT License +*/ + +// Built using: browserify lib/index.js --standalone xss > xss.js +// From: git@github.com:leizongmin/js-xss.git tag: v0.3.5 + +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.xss = f()}})(function(){var define,module,exports;return (function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o + */ + +var FilterCSS = require('cssfilter').FilterCSS; +var getDefaultCSSWhiteList = require('cssfilter').getDefaultWhiteList; +var _ = require('./util'); + +// 默认白名单 +function getDefaultWhiteList () { + return { + a: ['target', 'href', 'title'], + abbr: ['title'], + address: [], + area: ['shape', 'coords', 'href', 'alt'], + article: [], + aside: [], + audio: ['autoplay', 'controls', 'loop', 'preload', 'src'], + b: [], + bdi: ['dir'], + bdo: ['dir'], + big: [], + blockquote: ['cite'], + br: [], + caption: [], + center: [], + cite: [], + code: [], + col: ['align', 'valign', 'span', 'width'], + colgroup: ['align', 'valign', 'span', 'width'], + dd: [], + del: ['datetime'], + details: ['open'], + div: [], + dl: [], + dt: [], + em: [], + font: ['color', 'size', 'face'], + footer: [], + h1: [], + h2: [], + h3: [], + h4: [], + h5: [], + h6: [], + header: [], + hr: [], + i: [], + img: ['src', 'alt', 'title', 'width', 'height'], + ins: ['datetime'], + li: [], + mark: [], + nav: [], + ol: [], + p: [], + pre: [], + s: [], + section:[], + small: [], + span: [], + sub: [], + sup: [], + strong: [], + table: ['width', 'border', 'align', 'valign'], + tbody: ['align', 'valign'], + td: ['width', 'rowspan', 'colspan', 'align', 'valign'], + tfoot: ['align', 'valign'], + th: ['width', 'rowspan', 'colspan', 'align', 'valign'], + thead: ['align', 'valign'], + tr: ['rowspan', 'align', 'valign'], + tt: [], + u: [], + ul: [], + video: ['autoplay', 'controls', 'loop', 'preload', 'src', 'height', 'width'] + }; +} + +// 默认CSS Filter +var defaultCSSFilter = new FilterCSS(); + +/** + * 匹配到标签时的处理方法 + * + * @param {String} tag + * @param {String} html + * @param {Object} options + * @return {String} + */ +function onTag (tag, html, options) { + // do nothing +} + +/** + * 匹配到不在白名单上的标签时的处理方法 + * + * @param {String} tag + * @param {String} html + * @param {Object} options + * @return {String} + */ +function onIgnoreTag (tag, html, options) { + // do nothing +} + +/** + * 匹配到标签属性时的处理方法 + * + * @param {String} tag + * @param {String} name + * @param {String} value + * @return {String} + */ +function onTagAttr (tag, name, value) { + // do nothing +} + +/** + * 匹配到不在白名单上的标签属性时的处理方法 + * + * @param {String} tag + * @param {String} name + * @param {String} value + * @return {String} + */ +function onIgnoreTagAttr (tag, name, value) { + // do nothing +} + +/** + * HTML转义 + * + * @param {String} html + */ +function escapeHtml (html) { + return html.replace(REGEXP_LT, '<').replace(REGEXP_GT, '>'); +} + +/** + * 安全的标签属性值 + * + * @param {String} tag + * @param {String} name + * @param {String} value + * @param {Object} cssFilter + * @return {String} + */ +function safeAttrValue (tag, name, value, cssFilter) { + // 转换为友好的属性值,再做判断 + value = friendlyAttrValue(value); + + if (name === 'href' || name === 'src') { + // 过滤 href 和 src 属性 + // 仅允许 http:// | https:// | mailto: | / | # 开头的地址 + value = _.trim(value); + if (value === '#') return '#'; + if (!(value.substr(0, 7) === 'http://' || + value.substr(0, 8) === 'https://' || + value.substr(0, 7) === 'mailto:' || + value.substr(0, 4) === 'tel:' || + value[0] === '#' || + value[0] === '/')) { + return ''; + } + } else if (name === 'background') { + // 过滤 background 属性 (这个xss漏洞较老了,可能已经不适用) + // javascript: + REGEXP_DEFAULT_ON_TAG_ATTR_4.lastIndex = 0; + if (REGEXP_DEFAULT_ON_TAG_ATTR_4.test(value)) { + return ''; + } + } else if (name === 'style') { + // /*注释*/ + /*REGEXP_DEFAULT_ON_TAG_ATTR_3.lastIndex = 0; + if (REGEXP_DEFAULT_ON_TAG_ATTR_3.test(value)) { + return ''; + }*/ + // expression() + REGEXP_DEFAULT_ON_TAG_ATTR_7.lastIndex = 0; + if (REGEXP_DEFAULT_ON_TAG_ATTR_7.test(value)) { + return ''; + } + // url() + REGEXP_DEFAULT_ON_TAG_ATTR_8.lastIndex = 0; + if (REGEXP_DEFAULT_ON_TAG_ATTR_8.test(value)) { + REGEXP_DEFAULT_ON_TAG_ATTR_4.lastIndex = 0; + if (REGEXP_DEFAULT_ON_TAG_ATTR_4.test(value)) { + return ''; + } + } + if (cssFilter !== false) { + cssFilter = cssFilter || defaultCSSFilter; + value = cssFilter.process(value); + } + } + + // 输出时需要转义<>" + value = escapeAttrValue(value); + return value; +} + +// 正则表达式 +var REGEXP_LT = //g; +var REGEXP_QUOTE = /"/g; +var REGEXP_QUOTE_2 = /"/g; +var REGEXP_ATTR_VALUE_1 = /&#([a-zA-Z0-9]*);?/img; +var REGEXP_ATTR_VALUE_COLON = /:?/img; +var REGEXP_ATTR_VALUE_NEWLINE = /&newline;?/img; +var REGEXP_DEFAULT_ON_TAG_ATTR_3 = /\/\*|\*\//mg; +var REGEXP_DEFAULT_ON_TAG_ATTR_4 = /((j\s*a\s*v\s*a|v\s*b|l\s*i\s*v\s*e)\s*s\s*c\s*r\s*i\s*p\s*t\s*|m\s*o\s*c\s*h\s*a)\:/ig; +var REGEXP_DEFAULT_ON_TAG_ATTR_5 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:/ig; +var REGEXP_DEFAULT_ON_TAG_ATTR_6 = /^[\s"'`]*(d\s*a\s*t\s*a\s*)\:\s*image\//ig; +var REGEXP_DEFAULT_ON_TAG_ATTR_7 = /e\s*x\s*p\s*r\s*e\s*s\s*s\s*i\s*o\s*n\s*\(.*/ig; +var REGEXP_DEFAULT_ON_TAG_ATTR_8 = /u\s*r\s*l\s*\(.*/ig; + +/** + * 对双引号进行转义 + * + * @param {String} str + * @return {String} str + */ +function escapeQuote (str) { + return str.replace(REGEXP_QUOTE, '"'); +} + +/** + * 对双引号进行转义 + * + * @param {String} str + * @return {String} str + */ +function unescapeQuote (str) { + return str.replace(REGEXP_QUOTE_2, '"'); +} + +/** + * 对html实体编码进行转义 + * + * @param {String} str + * @return {String} + */ +function escapeHtmlEntities (str) { + return str.replace(REGEXP_ATTR_VALUE_1, function replaceUnicode (str, code) { + return (code[0] === 'x' || code[0] === 'X') + ? String.fromCharCode(parseInt(code.substr(1), 16)) + : String.fromCharCode(parseInt(code, 10)); + }); +} + +/** + * 对html5新增的危险实体编码进行转义 + * + * @param {String} str + * @return {String} + */ +function escapeDangerHtml5Entities (str) { + return str.replace(REGEXP_ATTR_VALUE_COLON, ':') + .replace(REGEXP_ATTR_VALUE_NEWLINE, ' '); +} + +/** + * 清除不可见字符 + * + * @param {String} str + * @return {String} + */ +function clearNonPrintableCharacter (str) { + var str2 = ''; + for (var i = 0, len = str.length; i < len; i++) { + str2 += str.charCodeAt(i) < 32 ? ' ' : str.charAt(i); + } + return _.trim(str2); +} + +/** + * 将标签的属性值转换成一般字符,便于分析 + * + * @param {String} str + * @return {String} + */ +function friendlyAttrValue (str) { + str = unescapeQuote(str); // 双引号 + str = escapeHtmlEntities(str); // 转换HTML实体编码 + str = escapeDangerHtml5Entities(str); // 转换危险的HTML5新增实体编码 + str = clearNonPrintableCharacter(str); // 清除不可见字符 + return str; +} + +/** + * 转义用于输出的标签属性值 + * + * @param {String} str + * @return {String} + */ +function escapeAttrValue (str) { + str = escapeQuote(str); + str = escapeHtml(str); + return str; +} + +/** + * 去掉不在白名单中的标签onIgnoreTag处理方法 + */ +function onIgnoreTagStripAll () { + return ''; +} + +/** + * 删除标签体 + * + * @param {array} tags 要删除的标签列表 + * @param {function} next 对不在列表中的标签的处理函数,可选 + */ +function StripTagBody (tags, next) { + if (typeof(next) !== 'function') { + next = function () {}; + } + + var isRemoveAllTag = !Array.isArray(tags); + function isRemoveTag (tag) { + if (isRemoveAllTag) return true; + return (_.indexOf(tags, tag) !== -1); + } + + var removeList = []; // 要删除的位置范围列表 + var posStart = false; // 当前标签开始位置 + + return { + onIgnoreTag: function (tag, html, options) { + if (isRemoveTag(tag)) { + if (options.isClosing) { + var ret = '[/removed]'; + var end = options.position + ret.length; + removeList.push([posStart !== false ? posStart : options.position, end]); + posStart = false; + return ret; + } else { + if (!posStart) { + posStart = options.position; + } + return '[removed]'; + } + } else { + return next(tag, html, options); + } + }, + remove: function (html) { + var rethtml = ''; + var lastPos = 0; + _.forEach(removeList, function (pos) { + rethtml += html.slice(lastPos, pos[0]); + lastPos = pos[1]; + }); + rethtml += html.slice(lastPos); + return rethtml; + } + }; +} + +/** + * 去除备注标签 + * + * @param {String} html + * @return {String} + */ +function stripCommentTag (html) { + return html.replace(STRIP_COMMENT_TAG_REGEXP, ''); +} +var STRIP_COMMENT_TAG_REGEXP = //g; + +/** + * 去除不可见字符 + * + * @param {String} html + * @return {String} + */ +function stripBlankChar (html) { + var chars = html.split(''); + chars = chars.filter(function (char) { + var c = char.charCodeAt(0); + if (c === 127) return false; + if (c <= 31) { + if (c === 10 || c === 13) return true; + return false; + } + return true; + }); + return chars.join(''); +} + + +exports.whiteList = getDefaultWhiteList(); +exports.getDefaultWhiteList = getDefaultWhiteList; +exports.onTag = onTag; +exports.onIgnoreTag = onIgnoreTag; +exports.onTagAttr = onTagAttr; +exports.onIgnoreTagAttr = onIgnoreTagAttr; +exports.safeAttrValue = safeAttrValue; +exports.escapeHtml = escapeHtml; +exports.escapeQuote = escapeQuote; +exports.unescapeQuote = unescapeQuote; +exports.escapeHtmlEntities = escapeHtmlEntities; +exports.escapeDangerHtml5Entities = escapeDangerHtml5Entities; +exports.clearNonPrintableCharacter = clearNonPrintableCharacter; +exports.friendlyAttrValue = friendlyAttrValue; +exports.escapeAttrValue = escapeAttrValue; +exports.onIgnoreTagStripAll = onIgnoreTagStripAll; +exports.StripTagBody = StripTagBody; +exports.stripCommentTag = stripCommentTag; +exports.stripBlankChar = stripBlankChar; +exports.cssFilter = defaultCSSFilter; +exports.getDefaultCSSWhiteList = getDefaultCSSWhiteList; + +},{"./util":4,"cssfilter":8}],2:[function(require,module,exports){ +/** + * 模块入口 + * + * @author 老雷 + */ + +var DEFAULT = require('./default'); +var parser = require('./parser'); +var FilterXSS = require('./xss'); + + +/** + * XSS过滤 + * + * @param {String} html 要过滤的HTML代码 + * @param {Object} options 选项:whiteList, onTag, onTagAttr, onIgnoreTag, onIgnoreTagAttr, safeAttrValue, escapeHtml + * @return {String} + */ +function filterXSS (html, options) { + var xss = new FilterXSS(options); + return xss.process(html); +} + + +// 输出 +exports = module.exports = filterXSS; +exports.FilterXSS = FilterXSS; +for (var i in DEFAULT) exports[i] = DEFAULT[i]; +for (var i in parser) exports[i] = parser[i]; + + +// 在浏览器端使用 +if (typeof window !== 'undefined') { + window.filterXSS = module.exports; +} + +},{"./default":1,"./parser":3,"./xss":5}],3:[function(require,module,exports){ +/** + * 简单 HTML Parser + * + * @author 老雷 + */ + +var _ = require('./util'); + +/** + * 获取标签的名称 + * + * @param {String} html 如:'' + * @return {String} + */ +function getTagName (html) { + var i = _.spaceIndex(html); + if (i === -1) { + var tagName = html.slice(1, -1); + } else { + var tagName = html.slice(1, i + 1); + } + tagName = _.trim(tagName).toLowerCase(); + if (tagName.slice(0, 1) === '/') tagName = tagName.slice(1); + if (tagName.slice(-1) === '/') tagName = tagName.slice(0, -1); + return tagName; +} + +/** + * 是否为闭合标签 + * + * @param {String} html 如:'' + * @return {Boolean} + */ +function isClosing (html) { + return (html.slice(0, 2) === '') { + rethtml += escapeHtml(html.slice(lastPos, tagStart)); + currentHtml = html.slice(tagStart, currentPos + 1); + currentTagName = getTagName(currentHtml); + rethtml += onTag(tagStart, + rethtml.length, + currentTagName, + currentHtml, + isClosing(currentHtml)); + lastPos = currentPos + 1; + tagStart = false; + continue; + } + // HTML标签内的引号仅当前一个字符是等于号时才有效 + if ((c === '"' || c === "'") && html.charAt(currentPos - 1) === '=') { + quoteStart = c; + continue; + } + } else { + if (c === quoteStart) { + quoteStart = false; + continue; + } + } + } + } + if (lastPos < html.length) { + rethtml += escapeHtml(html.substr(lastPos)); + } + + return rethtml; +} + +// 不符合属性名称规则的正则表达式 +var REGEXP_ATTR_NAME = /[^a-zA-Z0-9_:\.\-]/img; + +/** + * 分析标签HTML代码,调用相应的函数处理,返回HTML + * + * @param {String} html 如标签'' 则为 'href="#" target="_blank"' + * @param {Function} onAttr 处理属性值的函数 + * 函数格式: function (name, value) + * @return {String} + */ +function parseAttr (html, onAttr) { + 'user strict'; + + var lastPos = 0; // 当前位置 + var retAttrs = []; // 待返回的属性列表 + var tmpName = false; // 临时属性名称 + var len = html.length; // HTML代码长度 + + function addAttr (name, value) { + name = _.trim(name); + name = name.replace(REGEXP_ATTR_NAME, '').toLowerCase(); + if (name.length < 1) return; + var ret = onAttr(name, value || ''); + if (ret) retAttrs.push(ret); + }; + + // 逐个分析字符 + for (var i = 0; i < len; i++) { + var c = html.charAt(i); + var v, j; + if (tmpName === false && c === '=') { + tmpName = html.slice(lastPos, i); + lastPos = i + 1; + continue; + } + if (tmpName !== false) { + // HTML标签内的引号仅当前一个字符是等于号时才有效 + if (i === lastPos && (c === '"' || c === "'") && html.charAt(i - 1) === '=') { + j = html.indexOf(c, i + 1); + if (j === -1) { + break; + } else { + v = _.trim(html.slice(lastPos + 1, j)); + addAttr(tmpName, v); + tmpName = false; + i = j; + lastPos = i + 1; + continue; + } + } + } + if (/\s|\n|\t/.test(c)) { + html = html.replace(/\s|\n|\t/g, ' '); + if (tmpName === false) { + j = findNextEqual(html, i); + if (j === -1) { + v = _.trim(html.slice(lastPos, i)); + addAttr(v); + tmpName = false; + lastPos = i + 1; + continue; + } else { + i = j - 1; + continue; + } + } else { + j = findBeforeEqual(html, i - 1); + if (j === -1) { + v = _.trim(html.slice(lastPos, i)); + v = stripQuoteWrap(v); + addAttr(tmpName, v); + tmpName = false; + lastPos = i + 1; + continue; + } else { + continue; + } + } + } + } + + if (lastPos < html.length) { + if (tmpName === false) { + addAttr(html.slice(lastPos)); + } else { + addAttr(tmpName, stripQuoteWrap(_.trim(html.slice(lastPos)))); + } + } + + return _.trim(retAttrs.join(' ')); +} + +function findNextEqual (str, i) { + for (; i < str.length; i++) { + var c = str[i]; + if (c === ' ') continue; + if (c === '=') return i; + return -1; + } +} + +function findBeforeEqual (str, i) { + for (; i > 0; i--) { + var c = str[i]; + if (c === ' ') continue; + if (c === '=') return i; + return -1; + } +} + +function isQuoteWrapString (text) { + if ((text[0] === '"' && text[text.length - 1] === '"') || + (text[0] === '\'' && text[text.length - 1] === '\'')) { + return true; + } else { + return false; + } +}; + +function stripQuoteWrap (text) { + if (isQuoteWrapString(text)) { + return text.substr(1, text.length - 2); + } else { + return text; + } +}; + + +exports.parseTag = parseTag; +exports.parseAttr = parseAttr; + +},{"./util":4}],4:[function(require,module,exports){ +module.exports = { + indexOf: function (arr, item) { + var i, j; + if (Array.prototype.indexOf) { + return arr.indexOf(item); + } + for (i = 0, j = arr.length; i < j; i++) { + if (arr[i] === item) { + return i; + } + } + return -1; + }, + forEach: function (arr, fn, scope) { + var i, j; + if (Array.prototype.forEach) { + return arr.forEach(fn, scope); + } + for (i = 0, j = arr.length; i < j; i++) { + fn.call(scope, arr[i], i, arr); + } + }, + trim: function (str) { + if (String.prototype.trim) { + return str.trim(); + } + return str.replace(/(^\s*)|(\s*$)/g, ''); + }, + spaceIndex: function (str) { + var reg = /\s|\n|\t/; + var match = reg.exec(str); + return match ? match.index : -1; + } +}; + +},{}],5:[function(require,module,exports){ +/** + * 过滤XSS + * + * @author 老雷 + */ + +var FilterCSS = require('cssfilter').FilterCSS; +var DEFAULT = require('./default'); +var parser = require('./parser'); +var parseTag = parser.parseTag; +var parseAttr = parser.parseAttr; +var _ = require('./util'); + + +/** + * 返回值是否为空 + * + * @param {Object} obj + * @return {Boolean} + */ +function isNull (obj) { + return (obj === undefined || obj === null); +} + +/** + * 取标签内的属性列表字符串 + * + * @param {String} html + * @return {Object} + * - {String} html + * - {Boolean} closing + */ +function getAttrs (html) { + var i = _.spaceIndex(html); + if (i === -1) { + return { + html: '', + closing: (html[html.length - 2] === '/') + }; + } + html = _.trim(html.slice(i + 1, -1)); + var isClosing = (html[html.length - 1] === '/'); + if (isClosing) html = _.trim(html.slice(0, -1)); + return { + html: html, + closing: isClosing + }; +} + +/** + * 浅拷贝对象 + * + * @param {Object} obj + * @return {Object} + */ +function shallowCopyObject (obj) { + var ret = {}; + for (var i in obj) { + ret[i] = obj[i]; + } + return ret; +} + +/** + * XSS过滤对象 + * + * @param {Object} options + * 选项:whiteList, onTag, onTagAttr, onIgnoreTag, + * onIgnoreTagAttr, safeAttrValue, escapeHtml + * stripIgnoreTagBody, allowCommentTag, stripBlankChar + * css{whiteList, onAttr, onIgnoreAttr} css=false表示禁用cssfilter + */ +function FilterXSS (options) { + options = shallowCopyObject(options || {}); + + if (options.stripIgnoreTag) { + if (options.onIgnoreTag) { + console.error('Notes: cannot use these two options "stripIgnoreTag" and "onIgnoreTag" at the same time'); + } + options.onIgnoreTag = DEFAULT.onIgnoreTagStripAll; + } + + options.whiteList = options.whiteList || DEFAULT.whiteList; + options.onTag = options.onTag || DEFAULT.onTag; + options.onTagAttr = options.onTagAttr || DEFAULT.onTagAttr; + options.onIgnoreTag = options.onIgnoreTag || DEFAULT.onIgnoreTag; + options.onIgnoreTagAttr = options.onIgnoreTagAttr || DEFAULT.onIgnoreTagAttr; + options.safeAttrValue = options.safeAttrValue || DEFAULT.safeAttrValue; + options.escapeHtml = options.escapeHtml || DEFAULT.escapeHtml; + this.options = options; + + if (options.css === false) { + this.cssFilter = false; + } else { + options.css = options.css || {}; + this.cssFilter = new FilterCSS(options.css); + } +} + +/** + * 开始处理 + * + * @param {String} html + * @return {String} + */ +FilterXSS.prototype.process = function (html) { + // 兼容各种奇葩输入 + html = html || ''; + html = html.toString(); + if (!html) return ''; + + var me = this; + var options = me.options; + var whiteList = options.whiteList; + var onTag = options.onTag; + var onIgnoreTag = options.onIgnoreTag; + var onTagAttr = options.onTagAttr; + var onIgnoreTagAttr = options.onIgnoreTagAttr; + var safeAttrValue = options.safeAttrValue; + var escapeHtml = options.escapeHtml; + var cssFilter = me.cssFilter; + + // 是否清除不可见字符 + if (options.stripBlankChar) { + html = DEFAULT.stripBlankChar(html); + } + + // 是否禁止备注标签 + if (!options.allowCommentTag) { + html = DEFAULT.stripCommentTag(html); + } + + // 如果开启了stripIgnoreTagBody + var stripIgnoreTagBody = false; + if (options.stripIgnoreTagBody) { + var stripIgnoreTagBody = DEFAULT.StripTagBody(options.stripIgnoreTagBody, onIgnoreTag); + onIgnoreTag = stripIgnoreTagBody.onIgnoreTag; + } + + var retHtml = parseTag(html, function (sourcePosition, position, tag, html, isClosing) { + var info = { + sourcePosition: sourcePosition, + position: position, + isClosing: isClosing, + isWhite: (tag in whiteList) + }; + + // 调用onTag处理 + var ret = onTag(tag, html, info); + if (!isNull(ret)) return ret; + + // 默认标签处理方法 + if (info.isWhite) { + // 白名单标签,解析标签属性 + // 如果是闭合标签,则不需要解析属性 + if (info.isClosing) { + return ''; + } + + var attrs = getAttrs(html); + var whiteAttrList = whiteList[tag]; + var attrsHtml = parseAttr(attrs.html, function (name, value) { + + // 调用onTagAttr处理 + var isWhiteAttr = (_.indexOf(whiteAttrList, name) !== -1); + var ret = onTagAttr(tag, name, value, isWhiteAttr); + if (!isNull(ret)) return ret; + + // 默认的属性处理方法 + if (isWhiteAttr) { + // 白名单属性,调用safeAttrValue过滤属性值 + value = safeAttrValue(tag, name, value, cssFilter); + if (value) { + return name + '="' + value + '"'; + } else { + return name; + } + } else { + // 非白名单属性,调用onIgnoreTagAttr处理 + var ret = onIgnoreTagAttr(tag, name, value, isWhiteAttr); + if (!isNull(ret)) return ret; + return; + } + }); + + // 构造新的标签代码 + var html = '<' + tag; + if (attrsHtml) html += ' ' + attrsHtml; + if (attrs.closing) html += ' /'; + html += '>'; + return html; + + } else { + // 非白名单标签,调用onIgnoreTag处理 + var ret = onIgnoreTag(tag, html, info); + if (!isNull(ret)) return ret; + return escapeHtml(html); + } + + }, escapeHtml); + + // 如果开启了stripIgnoreTagBody,需要对结果再进行处理 + if (stripIgnoreTagBody) { + retHtml = stripIgnoreTagBody.remove(retHtml); + } + + return retHtml; +}; + + +module.exports = FilterXSS; + +},{"./default":1,"./parser":3,"./util":4,"cssfilter":8}],6:[function(require,module,exports){ +/** + * cssfilter + * + * @author 老雷 + */ + +var DEFAULT = require('./default'); +var parseStyle = require('./parser'); +var _ = require('./util'); + + +/** + * 返回值是否为空 + * + * @param {Object} obj + * @return {Boolean} + */ +function isNull (obj) { + return (obj === undefined || obj === null); +} + +/** + * 浅拷贝对象 + * + * @param {Object} obj + * @return {Object} + */ +function shallowCopyObject (obj) { + var ret = {}; + for (var i in obj) { + ret[i] = obj[i]; + } + return ret; +} + +/** + * 创建CSS过滤器 + * + * @param {Object} options + * - {Object} whiteList + * - {Function} onAttr + * - {Function} onIgnoreAttr + * - {Function} safeAttrValue + */ +function FilterCSS (options) { + options = shallowCopyObject(options || {}); + options.whiteList = options.whiteList || DEFAULT.whiteList; + options.onAttr = options.onAttr || DEFAULT.onAttr; + options.onIgnoreAttr = options.onIgnoreAttr || DEFAULT.onIgnoreAttr; + options.safeAttrValue = options.safeAttrValue || DEFAULT.safeAttrValue; + this.options = options; +} + +FilterCSS.prototype.process = function (css) { + // 兼容各种奇葩输入 + css = css || ''; + css = css.toString(); + if (!css) return ''; + + var me = this; + var options = me.options; + var whiteList = options.whiteList; + var onAttr = options.onAttr; + var onIgnoreAttr = options.onIgnoreAttr; + var safeAttrValue = options.safeAttrValue; + + var retCSS = parseStyle(css, function (sourcePosition, position, name, value, source) { + + var check = whiteList[name]; + var isWhite = false; + if (check === true) isWhite = check; + else if (typeof check === 'function') isWhite = check(value); + else if (check instanceof RegExp) isWhite = check.test(value); + if (isWhite !== true) isWhite = false; + + // 如果过滤后 value 为空则直接忽略 + value = safeAttrValue(name, value); + if (!value) return; + + var opts = { + position: position, + sourcePosition: sourcePosition, + source: source, + isWhite: isWhite + }; + + if (isWhite) { + + var ret = onAttr(name, value, opts); + if (isNull(ret)) { + return name + ':' + value; + } else { + return ret; + } + + } else { + + var ret = onIgnoreAttr(name, value, opts); + if (!isNull(ret)) { + return ret; + } + + } + }); + + return retCSS; +}; + + +module.exports = FilterCSS; + +},{"./default":7,"./parser":9,"./util":10}],7:[function(require,module,exports){ +/** + * cssfilter + * + * @author 老雷 + */ + +function getDefaultWhiteList () { + // 白名单值说明: + // true: 允许该属性 + // Function: function (val) { } 返回true表示允许该属性,其他值均表示不允许 + // RegExp: regexp.test(val) 返回true表示允许该属性,其他值均表示不允许 + // 除上面列出的值外均表示不允许 + var whiteList = {}; + + whiteList['align-content'] = false; // default: auto + whiteList['align-items'] = false; // default: auto + whiteList['align-self'] = false; // default: auto + whiteList['alignment-adjust'] = false; // default: auto + whiteList['alignment-baseline'] = false; // default: baseline + whiteList['all'] = false; // default: depending on individual properties + whiteList['anchor-point'] = false; // default: none + whiteList['animation'] = false; // default: depending on individual properties + whiteList['animation-delay'] = false; // default: 0 + whiteList['animation-direction'] = false; // default: normal + whiteList['animation-duration'] = false; // default: 0 + whiteList['animation-fill-mode'] = false; // default: none + whiteList['animation-iteration-count'] = false; // default: 1 + whiteList['animation-name'] = false; // default: none + whiteList['animation-play-state'] = false; // default: running + whiteList['animation-timing-function'] = false; // default: ease + whiteList['azimuth'] = false; // default: center + whiteList['backface-visibility'] = false; // default: visible + whiteList['background'] = true; // default: depending on individual properties + whiteList['background-attachment'] = true; // default: scroll + whiteList['background-clip'] = true; // default: border-box + whiteList['background-color'] = true; // default: transparent + whiteList['background-image'] = true; // default: none + whiteList['background-origin'] = true; // default: padding-box + whiteList['background-position'] = true; // default: 0% 0% + whiteList['background-repeat'] = true; // default: repeat + whiteList['background-size'] = true; // default: auto + whiteList['baseline-shift'] = false; // default: baseline + whiteList['binding'] = false; // default: none + whiteList['bleed'] = false; // default: 6pt + whiteList['bookmark-label'] = false; // default: content() + whiteList['bookmark-level'] = false; // default: none + whiteList['bookmark-state'] = false; // default: open + whiteList['border'] = true; // default: depending on individual properties + whiteList['border-bottom'] = true; // default: depending on individual properties + whiteList['border-bottom-color'] = true; // default: current color + whiteList['border-bottom-left-radius'] = true; // default: 0 + whiteList['border-bottom-right-radius'] = true; // default: 0 + whiteList['border-bottom-style'] = true; // default: none + whiteList['border-bottom-width'] = true; // default: medium + whiteList['border-collapse'] = true; // default: separate + whiteList['border-color'] = true; // default: depending on individual properties + whiteList['border-image'] = true; // default: none + whiteList['border-image-outset'] = true; // default: 0 + whiteList['border-image-repeat'] = true; // default: stretch + whiteList['border-image-slice'] = true; // default: 100% + whiteList['border-image-source'] = true; // default: none + whiteList['border-image-width'] = true; // default: 1 + whiteList['border-left'] = true; // default: depending on individual properties + whiteList['border-left-color'] = true; // default: current color + whiteList['border-left-style'] = true; // default: none + whiteList['border-left-width'] = true; // default: medium + whiteList['border-radius'] = true; // default: 0 + whiteList['border-right'] = true; // default: depending on individual properties + whiteList['border-right-color'] = true; // default: current color + whiteList['border-right-style'] = true; // default: none + whiteList['border-right-width'] = true; // default: medium + whiteList['border-spacing'] = true; // default: 0 + whiteList['border-style'] = true; // default: depending on individual properties + whiteList['border-top'] = true; // default: depending on individual properties + whiteList['border-top-color'] = true; // default: current color + whiteList['border-top-left-radius'] = true; // default: 0 + whiteList['border-top-right-radius'] = true; // default: 0 + whiteList['border-top-style'] = true; // default: none + whiteList['border-top-width'] = true; // default: medium + whiteList['border-width'] = true; // default: depending on individual properties + whiteList['bottom'] = false; // default: auto + whiteList['box-decoration-break'] = true; // default: slice + whiteList['box-shadow'] = true; // default: none + whiteList['box-sizing'] = true; // default: content-box + whiteList['box-snap'] = true; // default: none + whiteList['box-suppress'] = true; // default: show + whiteList['break-after'] = true; // default: auto + whiteList['break-before'] = true; // default: auto + whiteList['break-inside'] = true; // default: auto + whiteList['caption-side'] = false; // default: top + whiteList['chains'] = false; // default: none + whiteList['clear'] = true; // default: none + whiteList['clip'] = false; // default: auto + whiteList['clip-path'] = false; // default: none + whiteList['clip-rule'] = false; // default: nonzero + whiteList['color'] = true; // default: implementation dependent + whiteList['color-interpolation-filters'] = true; // default: auto + whiteList['column-count'] = false; // default: auto + whiteList['column-fill'] = false; // default: balance + whiteList['column-gap'] = false; // default: normal + whiteList['column-rule'] = false; // default: depending on individual properties + whiteList['column-rule-color'] = false; // default: current color + whiteList['column-rule-style'] = false; // default: medium + whiteList['column-rule-width'] = false; // default: medium + whiteList['column-span'] = false; // default: none + whiteList['column-width'] = false; // default: auto + whiteList['columns'] = false; // default: depending on individual properties + whiteList['contain'] = false; // default: none + whiteList['content'] = false; // default: normal + whiteList['counter-increment'] = false; // default: none + whiteList['counter-reset'] = false; // default: none + whiteList['counter-set'] = false; // default: none + whiteList['crop'] = false; // default: auto + whiteList['cue'] = false; // default: depending on individual properties + whiteList['cue-after'] = false; // default: none + whiteList['cue-before'] = false; // default: none + whiteList['cursor'] = false; // default: auto + whiteList['direction'] = false; // default: ltr + whiteList['display'] = true; // default: depending on individual properties + whiteList['display-inside'] = true; // default: auto + whiteList['display-list'] = true; // default: none + whiteList['display-outside'] = true; // default: inline-level + whiteList['dominant-baseline'] = false; // default: auto + whiteList['elevation'] = false; // default: level + whiteList['empty-cells'] = false; // default: show + whiteList['filter'] = false; // default: none + whiteList['flex'] = false; // default: depending on individual properties + whiteList['flex-basis'] = false; // default: auto + whiteList['flex-direction'] = false; // default: row + whiteList['flex-flow'] = false; // default: depending on individual properties + whiteList['flex-grow'] = false; // default: 0 + whiteList['flex-shrink'] = false; // default: 1 + whiteList['flex-wrap'] = false; // default: nowrap + whiteList['float'] = false; // default: none + whiteList['float-offset'] = false; // default: 0 0 + whiteList['flood-color'] = false; // default: black + whiteList['flood-opacity'] = false; // default: 1 + whiteList['flow-from'] = false; // default: none + whiteList['flow-into'] = false; // default: none + whiteList['font'] = true; // default: depending on individual properties + whiteList['font-family'] = true; // default: implementation dependent + whiteList['font-feature-settings'] = true; // default: normal + whiteList['font-kerning'] = true; // default: auto + whiteList['font-language-override'] = true; // default: normal + whiteList['font-size'] = true; // default: medium + whiteList['font-size-adjust'] = true; // default: none + whiteList['font-stretch'] = true; // default: normal + whiteList['font-style'] = true; // default: normal + whiteList['font-synthesis'] = true; // default: weight style + whiteList['font-variant'] = true; // default: normal + whiteList['font-variant-alternates'] = true; // default: normal + whiteList['font-variant-caps'] = true; // default: normal + whiteList['font-variant-east-asian'] = true; // default: normal + whiteList['font-variant-ligatures'] = true; // default: normal + whiteList['font-variant-numeric'] = true; // default: normal + whiteList['font-variant-position'] = true; // default: normal + whiteList['font-weight'] = true; // default: normal + whiteList['grid'] = false; // default: depending on individual properties + whiteList['grid-area'] = false; // default: depending on individual properties + whiteList['grid-auto-columns'] = false; // default: auto + whiteList['grid-auto-flow'] = false; // default: none + whiteList['grid-auto-rows'] = false; // default: auto + whiteList['grid-column'] = false; // default: depending on individual properties + whiteList['grid-column-end'] = false; // default: auto + whiteList['grid-column-start'] = false; // default: auto + whiteList['grid-row'] = false; // default: depending on individual properties + whiteList['grid-row-end'] = false; // default: auto + whiteList['grid-row-start'] = false; // default: auto + whiteList['grid-template'] = false; // default: depending on individual properties + whiteList['grid-template-areas'] = false; // default: none + whiteList['grid-template-columns'] = false; // default: none + whiteList['grid-template-rows'] = false; // default: none + whiteList['hanging-punctuation'] = false; // default: none + whiteList['height'] = true; // default: auto + whiteList['hyphens'] = false; // default: manual + whiteList['icon'] = false; // default: auto + whiteList['image-orientation'] = false; // default: auto + whiteList['image-resolution'] = false; // default: normal + whiteList['ime-mode'] = false; // default: auto + whiteList['initial-letters'] = false; // default: normal + whiteList['inline-box-align'] = false; // default: last + whiteList['justify-content'] = false; // default: auto + whiteList['justify-items'] = false; // default: auto + whiteList['justify-self'] = false; // default: auto + whiteList['left'] = false; // default: auto + whiteList['letter-spacing'] = true; // default: normal + whiteList['lighting-color'] = true; // default: white + whiteList['line-box-contain'] = false; // default: block inline replaced + whiteList['line-break'] = false; // default: auto + whiteList['line-grid'] = false; // default: match-parent + whiteList['line-height'] = false; // default: normal + whiteList['line-snap'] = false; // default: none + whiteList['line-stacking'] = false; // default: depending on individual properties + whiteList['line-stacking-ruby'] = false; // default: exclude-ruby + whiteList['line-stacking-shift'] = false; // default: consider-shifts + whiteList['line-stacking-strategy'] = false; // default: inline-line-height + whiteList['list-style'] = true; // default: depending on individual properties + whiteList['list-style-image'] = true; // default: none + whiteList['list-style-position'] = true; // default: outside + whiteList['list-style-type'] = true; // default: disc + whiteList['margin'] = true; // default: depending on individual properties + whiteList['margin-bottom'] = true; // default: 0 + whiteList['margin-left'] = true; // default: 0 + whiteList['margin-right'] = true; // default: 0 + whiteList['margin-top'] = true; // default: 0 + whiteList['marker-offset'] = false; // default: auto + whiteList['marker-side'] = false; // default: list-item + whiteList['marks'] = false; // default: none + whiteList['mask'] = false; // default: border-box + whiteList['mask-box'] = false; // default: see individual properties + whiteList['mask-box-outset'] = false; // default: 0 + whiteList['mask-box-repeat'] = false; // default: stretch + whiteList['mask-box-slice'] = false; // default: 0 fill + whiteList['mask-box-source'] = false; // default: none + whiteList['mask-box-width'] = false; // default: auto + whiteList['mask-clip'] = false; // default: border-box + whiteList['mask-image'] = false; // default: none + whiteList['mask-origin'] = false; // default: border-box + whiteList['mask-position'] = false; // default: center + whiteList['mask-repeat'] = false; // default: no-repeat + whiteList['mask-size'] = false; // default: border-box + whiteList['mask-source-type'] = false; // default: auto + whiteList['mask-type'] = false; // default: luminance + whiteList['max-height'] = true; // default: none + whiteList['max-lines'] = false; // default: none + whiteList['max-width'] = true; // default: none + whiteList['min-height'] = true; // default: 0 + whiteList['min-width'] = true; // default: 0 + whiteList['move-to'] = false; // default: normal + whiteList['nav-down'] = false; // default: auto + whiteList['nav-index'] = false; // default: auto + whiteList['nav-left'] = false; // default: auto + whiteList['nav-right'] = false; // default: auto + whiteList['nav-up'] = false; // default: auto + whiteList['object-fit'] = false; // default: fill + whiteList['object-position'] = false; // default: 50% 50% + whiteList['opacity'] = false; // default: 1 + whiteList['order'] = false; // default: 0 + whiteList['orphans'] = false; // default: 2 + whiteList['outline'] = false; // default: depending on individual properties + whiteList['outline-color'] = false; // default: invert + whiteList['outline-offset'] = false; // default: 0 + whiteList['outline-style'] = false; // default: none + whiteList['outline-width'] = false; // default: medium + whiteList['overflow'] = false; // default: depending on individual properties + whiteList['overflow-wrap'] = false; // default: normal + whiteList['overflow-x'] = false; // default: visible + whiteList['overflow-y'] = false; // default: visible + whiteList['padding'] = true; // default: depending on individual properties + whiteList['padding-bottom'] = true; // default: 0 + whiteList['padding-left'] = true; // default: 0 + whiteList['padding-right'] = true; // default: 0 + whiteList['padding-top'] = true; // default: 0 + whiteList['page'] = false; // default: auto + whiteList['page-break-after'] = false; // default: auto + whiteList['page-break-before'] = false; // default: auto + whiteList['page-break-inside'] = false; // default: auto + whiteList['page-policy'] = false; // default: start + whiteList['pause'] = false; // default: implementation dependent + whiteList['pause-after'] = false; // default: implementation dependent + whiteList['pause-before'] = false; // default: implementation dependent + whiteList['perspective'] = false; // default: none + whiteList['perspective-origin'] = false; // default: 50% 50% + whiteList['pitch'] = false; // default: medium + whiteList['pitch-range'] = false; // default: 50 + whiteList['play-during'] = false; // default: auto + whiteList['position'] = false; // default: static + whiteList['presentation-level'] = false; // default: 0 + whiteList['quotes'] = false; // default: text + whiteList['region-fragment'] = false; // default: auto + whiteList['resize'] = false; // default: none + whiteList['rest'] = false; // default: depending on individual properties + whiteList['rest-after'] = false; // default: none + whiteList['rest-before'] = false; // default: none + whiteList['richness'] = false; // default: 50 + whiteList['right'] = false; // default: auto + whiteList['rotation'] = false; // default: 0 + whiteList['rotation-point'] = false; // default: 50% 50% + whiteList['ruby-align'] = false; // default: auto + whiteList['ruby-merge'] = false; // default: separate + whiteList['ruby-position'] = false; // default: before + whiteList['shape-image-threshold'] = false; // default: 0.0 + whiteList['shape-outside'] = false; // default: none + whiteList['shape-margin'] = false; // default: 0 + whiteList['size'] = false; // default: auto + whiteList['speak'] = false; // default: auto + whiteList['speak-as'] = false; // default: normal + whiteList['speak-header'] = false; // default: once + whiteList['speak-numeral'] = false; // default: continuous + whiteList['speak-punctuation'] = false; // default: none + whiteList['speech-rate'] = false; // default: medium + whiteList['stress'] = false; // default: 50 + whiteList['string-set'] = false; // default: none + whiteList['tab-size'] = false; // default: 8 + whiteList['table-layout'] = false; // default: auto + whiteList['text-align'] = true; // default: start + whiteList['text-align-last'] = true; // default: auto + whiteList['text-combine-upright'] = true; // default: none + whiteList['text-decoration'] = true; // default: none + whiteList['text-decoration-color'] = true; // default: currentColor + whiteList['text-decoration-line'] = true; // default: none + whiteList['text-decoration-skip'] = true; // default: objects + whiteList['text-decoration-style'] = true; // default: solid + whiteList['text-emphasis'] = true; // default: depending on individual properties + whiteList['text-emphasis-color'] = true; // default: currentColor + whiteList['text-emphasis-position'] = true; // default: over right + whiteList['text-emphasis-style'] = true; // default: none + whiteList['text-height'] = true; // default: auto + whiteList['text-indent'] = true; // default: 0 + whiteList['text-justify'] = true; // default: auto + whiteList['text-orientation'] = true; // default: mixed + whiteList['text-overflow'] = true; // default: clip + whiteList['text-shadow'] = true; // default: none + whiteList['text-space-collapse'] = true; // default: collapse + whiteList['text-transform'] = true; // default: none + whiteList['text-underline-position'] = true; // default: auto + whiteList['text-wrap'] = true; // default: normal + whiteList['top'] = false; // default: auto + whiteList['transform'] = false; // default: none + whiteList['transform-origin'] = false; // default: 50% 50% 0 + whiteList['transform-style'] = false; // default: flat + whiteList['transition'] = false; // default: depending on individual properties + whiteList['transition-delay'] = false; // default: 0s + whiteList['transition-duration'] = false; // default: 0s + whiteList['transition-property'] = false; // default: all + whiteList['transition-timing-function'] = false; // default: ease + whiteList['unicode-bidi'] = false; // default: normal + whiteList['vertical-align'] = false; // default: baseline + whiteList['visibility'] = false; // default: visible + whiteList['voice-balance'] = false; // default: center + whiteList['voice-duration'] = false; // default: auto + whiteList['voice-family'] = false; // default: implementation dependent + whiteList['voice-pitch'] = false; // default: medium + whiteList['voice-range'] = false; // default: medium + whiteList['voice-rate'] = false; // default: normal + whiteList['voice-stress'] = false; // default: normal + whiteList['voice-volume'] = false; // default: medium + whiteList['volume'] = false; // default: medium + whiteList['white-space'] = false; // default: normal + whiteList['widows'] = false; // default: 2 + whiteList['width'] = true; // default: auto + whiteList['will-change'] = false; // default: auto + whiteList['word-break'] = true; // default: normal + whiteList['word-spacing'] = true; // default: normal + whiteList['word-wrap'] = true; // default: normal + whiteList['wrap-flow'] = false; // default: auto + whiteList['wrap-through'] = false; // default: wrap + whiteList['writing-mode'] = false; // default: horizontal-tb + whiteList['z-index'] = false; // default: auto + + return whiteList; +} + + +/** + * 匹配到白名单上的一个属性时 + * + * @param {String} name + * @param {String} value + * @param {Object} options + * @return {String} + */ +function onAttr (name, value, options) { + // do nothing +} + +/** + * 匹配到不在白名单上的一个属性时 + * + * @param {String} name + * @param {String} value + * @param {Object} options + * @return {String} + */ +function onIgnoreAttr (name, value, options) { + // do nothing +} + +var REGEXP_URL_JAVASCRIPT = /javascript\s*\:/img; + +/** + * 过滤属性值 + * + * @param {String} name + * @param {String} value + * @return {String} + */ +function safeAttrValue(name, value) { + if (REGEXP_URL_JAVASCRIPT.test(value)) return ''; + return value; +} + + +exports.whiteList = getDefaultWhiteList(); +exports.getDefaultWhiteList = getDefaultWhiteList; +exports.onAttr = onAttr; +exports.onIgnoreAttr = onIgnoreAttr; +exports.safeAttrValue = safeAttrValue; + +},{}],8:[function(require,module,exports){ +/** + * cssfilter + * + * @author 老雷 + */ + +var DEFAULT = require('./default'); +var FilterCSS = require('./css'); + + +/** + * XSS过滤 + * + * @param {String} css 要过滤的CSS代码 + * @param {Object} options 选项:whiteList, onAttr, onIgnoreAttr + * @return {String} + */ +function filterCSS (html, options) { + var xss = new FilterCSS(options); + return xss.process(html); +} + + +// 输出 +exports = module.exports = filterCSS; +exports.FilterCSS = FilterCSS; +for (var i in DEFAULT) exports[i] = DEFAULT[i]; + +// 在浏览器端使用 +if (typeof window !== 'undefined') { + window.filterCSS = module.exports; +} + +},{"./css":6,"./default":7}],9:[function(require,module,exports){ +/** + * cssfilter + * + * @author 老雷 + */ + +var _ = require('./util'); + + +/** + * 解析style + * + * @param {String} css + * @param {Function} onAttr 处理属性的函数 + * 参数格式: function (sourcePosition, position, name, value, source) + * @return {String} + */ +function parseStyle (css, onAttr) { + css = _.trimRight(css); + if (css[css.length - 1] !== ';') css += ';'; + var cssLength = css.length; + var isParenthesisOpen = false; + var lastPos = 0; + var i = 0; + var retCSS = ''; + + function addNewAttr () { + // 如果没有正常的闭合圆括号,则直接忽略当前属性 + if (!isParenthesisOpen) { + var source = _.trim(css.slice(lastPos, i)); + var j = source.indexOf(':'); + if (j !== -1) { + var name = _.trim(source.slice(0, j)); + var value = _.trim(source.slice(j + 1)); + // 必须有属性名称 + if (name) { + var ret = onAttr(lastPos, retCSS.length, name, value, source); + if (ret) retCSS += ret + '; '; + } + } + } + lastPos = i + 1; + } + + for (; i < cssLength; i++) { + var c = css[i]; + if (c === '/' && css[i + 1] === '*') { + // 备注开始 + var j = css.indexOf('*/', i + 2); + // 如果没有正常的备注结束,则后面的部分全部跳过 + if (j === -1) break; + // 直接将当前位置调到备注结尾,并且初始化状态 + i = j + 1; + lastPos = i + 1; + isParenthesisOpen = false; + } else if (c === '(') { + isParenthesisOpen = true; + } else if (c === ')') { + isParenthesisOpen = false; + } else if (c === ';') { + if (isParenthesisOpen) { + // 在圆括号里面,忽略 + } else { + addNewAttr(); + } + } else if (c === '\n') { + addNewAttr(); + } + } + + return _.trim(retCSS); +} + +module.exports = parseStyle; + +},{"./util":10}],10:[function(require,module,exports){ +module.exports = { + indexOf: function (arr, item) { + var i, j; + if (Array.prototype.indexOf) { + return arr.indexOf(item); + } + for (i = 0, j = arr.length; i < j; i++) { + if (arr[i] === item) { + return i; + } + } + return -1; + }, + forEach: function (arr, fn, scope) { + var i, j; + if (Array.prototype.forEach) { + return arr.forEach(fn, scope); + } + for (i = 0, j = arr.length; i < j; i++) { + fn.call(scope, arr[i], i, arr); + } + }, + trim: function (str) { + if (String.prototype.trim) { + return str.trim(); + } + return str.replace(/(^\s*)|(\s*$)/g, ''); + }, + trimRight: function (str) { + if (String.prototype.trimRight) { + return str.trimRight(); + } + return str.replace(/(\s*$)/g, ''); + } +}; + +},{}]},{},[2])(2) +}); diff --git a/Source/Widgets/CesiumWidget/CesiumWidget.js b/Source/Widgets/CesiumWidget/CesiumWidget.js index 5039775c771a..4439fc514b5a 100644 --- a/Source/Widgets/CesiumWidget/CesiumWidget.js +++ b/Source/Widgets/CesiumWidget/CesiumWidget.js @@ -2,7 +2,6 @@ define([ '../../Core/buildModuleUrl', '../../Core/Cartesian3', '../../Core/Clock', - '../../Core/Credit', '../../Core/defaultValue', '../../Core/defined', '../../Core/defineProperties', @@ -27,7 +26,6 @@ define([ buildModuleUrl, Cartesian3, Clock, - Credit, defaultValue, defined, defineProperties, diff --git a/Specs/Core/CesiumTerrainProviderSpec.js b/Specs/Core/CesiumTerrainProviderSpec.js index 73a52c045821..009cb3508b59 100644 --- a/Specs/Core/CesiumTerrainProviderSpec.js +++ b/Specs/Core/CesiumTerrainProviderSpec.js @@ -314,7 +314,7 @@ defineSuite([ return pollToPromise(function() { return provider.ready; }).then(function() { - expect(provider._tileCredits[0].text).toBe('This is a child tileset! This amazing data is courtesy The Amazing Data Source!'); + expect(provider._tileCredits[0].html).toBe('This is a child tileset! This amazing data is courtesy The Amazing Data Source!'); expect(provider.requestVertexNormals).toBe(true); expect(provider.requestWaterMask).toBe(true); expect(provider.hasVertexNormals).toBe(false); // Neither tileset has them @@ -455,7 +455,7 @@ defineSuite([ return pollToPromise(function() { return provider.ready; }).then(function() { - expect(provider._tileCredits[0].text).toBe('This amazing data is courtesy The Amazing Data Source!'); + expect(provider._tileCredits[0].html).toBe('This amazing data is courtesy The Amazing Data Source!'); }); }); diff --git a/Specs/Scene/CreditDisplaySpec.js b/Specs/Scene/CreditDisplaySpec.js index 6ab00dfc6f6e..4893462db55e 100644 --- a/Specs/Scene/CreditDisplaySpec.js +++ b/Specs/Scene/CreditDisplaySpec.js @@ -9,12 +9,6 @@ defineSuite([ 'use strict'; var container; - var imageContainer = 'cesium-credit-imageContainer'; - var textContainer = 'cesium-credit-textContainer'; - var text = 'cesium-credit-text'; - var image = 'cesium-credit-image'; - var imgSrc = 'imagesrc'; - var delimiter = 'cesium-credit-delimiter'; var creditDisplay; var defaultCredit; @@ -36,7 +30,6 @@ defineSuite([ // credit at the beginning of every frame function beginFrame(creditDisplay) { creditDisplay.beginFrame(); - creditDisplay._currentFrameCredits.imageCredits.length = 0; } it('credit display throws with no container', function() { @@ -67,125 +60,47 @@ defineSuite([ }); it('credits have unique ids', function() { - var credit1 = new Credit({ - text: 'credit1', - imageUrl: imgSrc, - link: 'http://cesiumjs.org/' - }); - var credit2 = new Credit({ - text: 'credit2', - imageUrl: imgSrc, - link: 'http://cesiumjs.org/' - }); + var credit1 = new Credit('credit1'); + var credit2 = new Credit('credit2'); expect(credit1.id).not.toEqual(credit2.id); - var credit1a = new Credit({ - text: 'credit1', - imageUrl: imgSrc, - link: 'http://cesiumjs.org/' - }); - expect(credit1.id).toEqual(credit1a.id); - }); - - it('credit display displays text credit', function() { - creditDisplay = new CreditDisplay(container); - var credit = new Credit({ - text: 'credit1', - showOnScreen: true - }); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit); - creditDisplay.endFrame(); - expect(container.childNodes.length).toEqual(3); - var child0 = container.childNodes[0]; - var child1 = container.childNodes[1]; - expect(child0.className).toEqual(imageContainer); - expect(child1.className).toEqual(textContainer); - expect(child0.childNodes.length).toEqual(0); - expect(child1.childNodes.length).toEqual(1); - expect(child1.childNodes[0].className).toEqual(text); - expect(child1.childNodes[0].innerHTML).toEqual('credit1'); - }); - - it('credit display displays image credit', function() { - creditDisplay = new CreditDisplay(container); - var credit = new Credit({ - imageUrl: imgSrc, - showOnScreen: true - }); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit); - creditDisplay.endFrame(); - - var child0 = container.childNodes[0]; - var child1 = container.childNodes[1]; - expect(child0.className).toEqual(imageContainer); - expect(child1.className).toEqual(textContainer); - expect(child0.childNodes.length).toEqual(1); - expect(child1.childNodes.length).toEqual(0); - var child00 = child0.childNodes[0]; - expect(child00.className).toEqual(image); - expect(child00.childNodes.length).toEqual(1); - expect(child00.childNodes[0].src).toContain(imgSrc); + var credit3 = new Credit('credit1'); + expect(credit1.id).toEqual(credit3.id); }); - it('credit display displays hyperlink credit', function() { + it('credit display displays a credit', function() { creditDisplay = new CreditDisplay(container); - var link = 'http://cesiumjs.org/'; - var credit = new Credit({ - link: link, - showOnScreen: true - }); + var credit = new Credit('CesiumJS.org', true); beginFrame(creditDisplay); creditDisplay.addCredit(credit); creditDisplay.endFrame(); - var child0 = container.childNodes[0]; - var child1 = container.childNodes[1]; - expect(child0.className).toEqual(imageContainer); - expect(child1.className).toEqual(textContainer); - expect(child0.childNodes.length).toEqual(0); - expect(child1.childNodes.length).toEqual(1); - var child10 = child1.childNodes[0]; - expect(child10.className).toEqual(text); + var creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(1); + var child10 = creditContainer.childNodes[0]; expect(child10.childNodes.length).toEqual(1); - expect(child10.childNodes[0].href).toEqual(link); - expect(child10.childNodes[0].innerHTML).toEqual(link); }); it('credit display updates html when credits change', function() { - var credit1 = new Credit({ - text: 'credit1', - showOnScreen: true - }); - var credit2 = new Credit({ - imageUrl: imgSrc, - showOnScreen: true - }); + var credit1 = new Credit('credit1', true); + var credit2 = new Credit('credit2', true); creditDisplay = new CreditDisplay(container); beginFrame(creditDisplay); creditDisplay.addCredit(credit1); creditDisplay.endFrame(); var innerHTML = container.innerHTML; - var child0 = container.childNodes[0]; - var child1 = container.childNodes[1]; - expect(child0.childNodes.length).toEqual(0); - expect(child1.childNodes.length).toEqual(1); - expect(child1.childNodes[0].innerHTML).toEqual('credit1'); + var creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(1); + expect(creditContainer.childNodes[0].innerHTML).toEqual('credit1'); beginFrame(creditDisplay); creditDisplay.addCredit(credit2); creditDisplay.endFrame(); expect(container.innerHTML).not.toEqual(innerHTML); innerHTML = container.innerHTML; - child0 = container.childNodes[0]; - child1 = container.childNodes[1]; - expect(child0.childNodes.length).toEqual(1); - expect(child1.childNodes.length).toEqual(0); - var child00 = child0.childNodes[0]; - expect(child00.childNodes.length).toEqual(1); - expect(child00.childNodes[0].src).toContain(imgSrc); + expect(creditContainer.childNodes.length).toEqual(1); + expect(creditContainer.childNodes[0].innerHTML).toEqual('credit2'); beginFrame(creditDisplay); creditDisplay.addCredit(credit1); @@ -193,162 +108,78 @@ defineSuite([ creditDisplay.endFrame(); expect(container.innerHTML).not.toEqual(innerHTML); innerHTML = container.innerHTML; - expect(container.childNodes[0].childNodes.length).toEqual(1); - expect(container.childNodes[1].childNodes.length).toEqual(1); + expect(creditContainer.childNodes.length).toEqual(3); beginFrame(creditDisplay); creditDisplay.endFrame(); expect(container.innerHTML).not.toEqual(innerHTML); - expect(container.childNodes[0].childNodes.length).toEqual(0); - expect(container.childNodes[1].childNodes.length).toEqual(0); + expect(creditContainer.childNodes.length).toEqual(0); }); - it('credit display uses delimeter for text credits', function() { - var credit1 = new Credit({ - text: 'credit1', - showOnScreen: true - }); - var credit2 = new Credit({ - text: 'credit2', - showOnScreen: true - }); + it('credit display uses delimeter', function() { + var credit1 = new Credit('credit1', true); + var credit2 = new Credit('credit2', true); + var delimiter = ', '; creditDisplay = new CreditDisplay(container, ', '); beginFrame(creditDisplay); creditDisplay.addCredit(credit1); creditDisplay.addCredit(credit2); creditDisplay.endFrame(); - var child0 = container.childNodes[0]; - var child1 = container.childNodes[1]; - expect(child0.className).toEqual(imageContainer); - expect(child1.className).toEqual(textContainer); - expect(child0.childNodes.length).toEqual(0); - expect(child1.childNodes.length).toEqual(3); - expect(child1.childNodes[0].className).toEqual(text); - expect(child1.childNodes[0].innerHTML).toEqual('credit1'); - expect(child1.childNodes[1].className).toEqual(delimiter); - expect(child1.childNodes[1].innerHTML).toEqual(', '); - expect(child1.childNodes[2].className).toEqual(text); - expect(child1.childNodes[2].innerHTML).toEqual('credit2'); + var creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(3); + expect(creditContainer.childNodes[0].innerHTML).toEqual('credit1'); + expect(creditContainer.childNodes[1].innerHTML).toEqual(delimiter); + expect(creditContainer.childNodes[2].innerHTML).toEqual('credit2'); }); it('credit display manages delimeters correctly for text credits', function() { - var credit1 = new Credit({ - text: 'credit1', - showOnScreen: true - }); - var credit2 = new Credit({ - text: 'credit2', - showOnScreen: true - }); - var credit3 = new Credit({ - text: 'credit3', - showOnScreen: true - }); - - creditDisplay = new CreditDisplay(container, ', '); + var credit1 = new Credit('credit1', true); + var credit2 = new Credit('credit2', true); + var credit3 = new Credit('credit3', true); + var delimiter = ', '; + creditDisplay = new CreditDisplay(container, delimiter); beginFrame(creditDisplay); creditDisplay.addCredit(credit1); creditDisplay.addCredit(credit2); creditDisplay.addCredit(credit3); creditDisplay.endFrame(); - var child0 = container.childNodes[0]; - var child1 = container.childNodes[1]; - expect(child0.className).toEqual(imageContainer); - expect(child1.className).toEqual(textContainer); - expect(child0.childNodes.length).toEqual(0); - expect(child1.childNodes.length).toEqual(5); - expect(child1.childNodes[0].className).toEqual(text); - expect(child1.childNodes[1].className).toEqual(delimiter); - expect(child1.childNodes[2].className).toEqual(text); - expect(child1.childNodes[3].className).toEqual(delimiter); - expect(child1.childNodes[4].className).toEqual(text); + var creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(5); + expect(creditContainer.childNodes[0]).toEqual(credit1.element); + expect(creditContainer.childNodes[1].innerHTML).toEqual(delimiter); + expect(creditContainer.childNodes[2]).toEqual(credit2.element); + expect(creditContainer.childNodes[3].innerHTML).toEqual(delimiter); + expect(creditContainer.childNodes[4]).toEqual(credit3.element); beginFrame(creditDisplay); creditDisplay.addCredit(credit2); creditDisplay.addCredit(credit3); creditDisplay.endFrame(); - child1 = container.childNodes[1]; - expect(child1.className).toEqual(textContainer); - expect(child1.childNodes.length).toEqual(3); - expect(child1.childNodes[0].className).toEqual(text); - expect(child1.childNodes[1].className).toEqual(delimiter); - expect(child1.childNodes[2].className).toEqual(text); + expect(creditContainer.childNodes.length).toEqual(3); + expect(creditContainer.childNodes[0]).toEqual(credit2.element); + expect(creditContainer.childNodes[1].innerHTML).toEqual(delimiter); + expect(creditContainer.childNodes[2]).toEqual(credit3.element); beginFrame(creditDisplay); creditDisplay.addCredit(credit2); creditDisplay.endFrame(); - child1 = container.childNodes[1]; - expect(child1.className).toEqual(textContainer); - expect(child1.childNodes.length).toEqual(1); - expect(child1.childNodes[0].className).toEqual(text); + expect(creditContainer.childNodes.length).toEqual(1); + expect(creditContainer.childNodes[0]).toEqual(credit2.element); beginFrame(creditDisplay); creditDisplay.addCredit(credit2); creditDisplay.addCredit(credit3); creditDisplay.endFrame(); - child1 = container.childNodes[1]; - expect(child1.className).toEqual(textContainer); - expect(child1.childNodes.length).toEqual(3); - expect(child1.childNodes[0].className).toEqual(text); - expect(child1.childNodes[1].className).toEqual(delimiter); - expect(child1.childNodes[2].className).toEqual(text); - }); - - it('credit display uses text as title for image credit', function() { - var credit1 = new Credit({ - text: 'credit text', - imageUrl: imgSrc, - showOnScreen: true - }); - creditDisplay = new CreditDisplay(container); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.endFrame(); - - var child0 = container.childNodes[0]; - expect(child0.className).toEqual(imageContainer); - expect(child0.childNodes.length).toEqual(1); - var child00 = child0.childNodes[0]; - expect(child00.className).toEqual(image); - expect(child00.childNodes.length).toEqual(1); - expect(child00.childNodes[0].src).toContain(imgSrc); - expect(child00.childNodes[0].alt).toEqual('credit text'); - expect(child00.childNodes[0].title).toEqual('credit text'); - }); - - it('credit display creates image credit with hyperlink', function() { - var credit1 = new Credit({ - imageUrl: imgSrc, - link: 'link.com', - showOnScreen: true - }); - creditDisplay = new CreditDisplay(container); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.endFrame(); - - var child0 = container.childNodes[0]; - expect(child0.className).toEqual(imageContainer); - expect(child0.childNodes.length).toEqual(1); - var child00 = child0.childNodes[0]; - expect(child00.className).toEqual(image); - expect(child00.childNodes.length).toEqual(1); - var child000 = child00.childNodes[0]; - expect(child000.href).toContain('link.com'); - expect(child000.childNodes.length).toEqual(1); - expect(child000.childNodes[0].src).toContain(imgSrc); + expect(creditContainer.childNodes.length).toEqual(3); + expect(creditContainer.childNodes[0]).toEqual(credit2.element); + expect(creditContainer.childNodes[1].innerHTML).toEqual(delimiter); + expect(creditContainer.childNodes[2]).toEqual(credit3.element); }); it('credit display displays default credit', function() { - var defaultCredit = new Credit({ - text: 'default credit', - showOnScreen: true - }); - var credit1 = new Credit({ - text: 'credit1', - showOnScreen: true - }); + var defaultCredit = new Credit('default credit', true); + var credit1 = new Credit('credit1', true); creditDisplay = new CreditDisplay(container, ', '); creditDisplay.addDefaultCredit(defaultCredit); @@ -356,180 +187,57 @@ defineSuite([ creditDisplay.addCredit(credit1); creditDisplay.endFrame(); - var child1 = container.childNodes[1]; - expect(child1.className).toEqual(textContainer); - expect(child1.childNodes.length).toEqual(3); - expect(child1.childNodes[0].className).toEqual(text); - expect(child1.childNodes[0].innerHTML).toEqual('default credit'); - expect(child1.childNodes[1].className).toEqual(delimiter); - expect(child1.childNodes[1].innerHTML).toEqual(', '); - expect(child1.childNodes[2].className).toEqual(text); - expect(child1.childNodes[2].innerHTML).toEqual('credit1'); + var creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(3); + expect(creditContainer.childNodes[0]).toEqual(defaultCredit.element); + expect(creditContainer.childNodes[1].innerHTML).toEqual(', '); + expect(creditContainer.childNodes[2]).toEqual(credit1.element); beginFrame(creditDisplay); creditDisplay.endFrame(); - child1 = container.childNodes[1]; - expect(child1.className).toEqual(textContainer); - expect(child1.childNodes.length).toEqual(1); - expect(child1.childNodes[0].className).toEqual(text); - expect(child1.childNodes[0].innerHTML).toEqual('default credit'); + expect(creditContainer.childNodes.length).toEqual(1); + expect(creditContainer.childNodes[0]).toEqual(defaultCredit.element); }); it('credit display displays credits when default is removed', function() { - var defaultCredit = new Credit({ - text: 'defaultCredit', - showOnScreen: true - }); - var credit1 = new Credit({ - text: 'credit1', - showOnScreen: true - }); + var defaultCredit = new Credit('default credit', true); + var credit1 = new Credit('credit1', true); creditDisplay = new CreditDisplay(container, ', '); creditDisplay.addDefaultCredit(defaultCredit); beginFrame(creditDisplay); creditDisplay.addCredit(credit1); creditDisplay.endFrame(); - var child1 = container.childNodes[1]; - expect(child1.className).toEqual(textContainer); - expect(child1.childNodes.length).toEqual(3); - expect(child1.childNodes[0].className).toEqual(text); - expect(child1.childNodes[0].innerHTML).toEqual('defaultCredit'); - expect(child1.childNodes[1].className).toEqual(delimiter); - expect(child1.childNodes[1].innerHTML).toEqual(', '); - expect(child1.childNodes[2].className).toEqual(text); - expect(child1.childNodes[2].innerHTML).toEqual('credit1'); + var creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(3); + expect(creditContainer.childNodes[0]).toEqual(defaultCredit.element); + expect(creditContainer.childNodes[1].innerHTML).toEqual(', '); + expect(creditContainer.childNodes[2]).toEqual(credit1.element); creditDisplay.removeDefaultCredit(defaultCredit); beginFrame(creditDisplay); creditDisplay.addCredit(credit1); creditDisplay.endFrame(); - child1 = container.childNodes[1]; - expect(child1.className).toEqual(textContainer); - expect(child1.childNodes.length).toEqual(1); - expect(child1.childNodes[0].className).toEqual(text); - expect(child1.childNodes[0].innerHTML).toEqual('credit1'); + expect(creditContainer.childNodes.length).toEqual(1); + expect(creditContainer.childNodes[0]).toEqual(credit1.element); }); - it('credit display displays default image credit', function() { - var defaultCredit = new Credit({ - imageUrl: imgSrc, - showOnScreen: true - }); - var credit1 = new Credit({ - text: 'credit1', - showOnScreen: true - }); - creditDisplay = new CreditDisplay(container, ', '); - creditDisplay.addDefaultCredit(defaultCredit); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.endFrame(); - var child0 = container.childNodes[0]; - var child1 = container.childNodes[1]; - expect(child0.className).toEqual(imageContainer); - expect(child1.className).toEqual(textContainer); - expect(child0.childNodes.length).toEqual(1); - expect(child1.childNodes.length).toEqual(1); - - beginFrame(creditDisplay); - creditDisplay.endFrame(); - child0 = container.childNodes[0]; - child1 = container.childNodes[1]; - expect(child0.className).toEqual(imageContainer); - expect(child1.className).toEqual(textContainer); - expect(child0.childNodes.length).toEqual(1); - expect(child1.childNodes.length).toEqual(0); - }); - - it('credit display displays credits when default image is removed', function() { - var defaultCredit = new Credit({ - imageUrl: imgSrc, - showOnScreen: true - }); - var credit1 = new Credit({ - text: 'credit1', - showOnScreen: true - }); - - creditDisplay = new CreditDisplay(container, ', '); - creditDisplay.addDefaultCredit(defaultCredit); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.endFrame(); - var child0 = container.childNodes[0]; - var child1 = container.childNodes[1]; - expect(child0.className).toEqual(imageContainer); - expect(child1.className).toEqual(textContainer); - expect(child0.childNodes.length).toEqual(1); - expect(child1.childNodes.length).toEqual(1); - - creditDisplay.removeDefaultCredit(defaultCredit); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.endFrame(); - child0 = container.childNodes[0]; - child1 = container.childNodes[1]; - expect(child0.className).toEqual(imageContainer); - expect(child1.className).toEqual(textContainer); - expect(child0.childNodes.length).toEqual(0); - expect(child1.childNodes.length).toEqual(1); - }); - - it('credit display only displays one if two image credits are equal', function() { - var credit1 = new Credit({ - imageUrl: imgSrc, - showOnScreen: true - }); - var credit2 = new Credit({ - imageUrl: imgSrc, - showOnScreen: true - }); + it('credit display only displays one if two credits are equal', function() { + var credit1 = new Credit('credit1', true); + var credit2 = new Credit('credit1', true); creditDisplay = new CreditDisplay(container); beginFrame(creditDisplay); creditDisplay.addCredit(credit1); creditDisplay.addCredit(credit2); creditDisplay.endFrame(); - var child0 = container.childNodes[0]; - var child1 = container.childNodes[1]; - expect(child0.className).toEqual(imageContainer); - expect(child1.className).toEqual(textContainer); - expect(child0.childNodes.length).toEqual(1); - expect(child1.childNodes.length).toEqual(0); - var child00 = child0.childNodes[0]; - expect(child00.className).toEqual(image); - expect(child00.childNodes.length).toEqual(1); - expect(child00.childNodes[0].src).toContain(imgSrc); - - }); - - it('credit display only displays one if two text credits are equal', function() { - var credit1 = new Credit({ - text: 'credit1', - showOnScreen: true - }); - var credit2 = new Credit({ - text: 'credit1', - showOnScreen: true - }); - creditDisplay = new CreditDisplay(container); - beginFrame(creditDisplay); - creditDisplay.addCredit(credit1); - creditDisplay.addCredit(credit2); - creditDisplay.endFrame(); - var child0 = container.childNodes[0]; - var child1 = container.childNodes[1]; - expect(child0.className).toEqual(imageContainer); - expect(child1.className).toEqual(textContainer); - expect(child0.childNodes.length).toEqual(0); - expect(child1.childNodes.length).toEqual(1); - expect(child1.childNodes[0].className).toEqual(text); - expect(child1.childNodes[0].innerHTML).toEqual('credit1'); + var creditContainer = container.childNodes[1]; + expect(creditContainer.childNodes.length).toEqual(1); + expect(creditContainer.childNodes[0].innerHTML).toEqual('credit1'); }); it('displays credits in a lightbox', function() { - var credit1 = new Credit({text: 'credit1'}); - var credit2 = new Credit({imageUrl: imgSrc}); + var credit1 = new Credit('credit1'); + var credit2 = new Credit(''); creditDisplay = new CreditDisplay(container); var creditList = creditDisplay._creditList; @@ -576,8 +284,8 @@ defineSuite([ }); it('only renders lightbox credits when lightbox is visible', function() { - var credit1 = new Credit({text: 'credit1'}); - var credit2 = new Credit({imageUrl: imgSrc}); + var credit1 = new Credit('credit1'); + var credit2 = new Credit(''); creditDisplay = new CreditDisplay(container); var creditList = creditDisplay._creditList; @@ -604,8 +312,8 @@ defineSuite([ }); it('updates lightbox when a new frames are not rendered', function() { - var credit1 = new Credit({text: 'credit1'}); - var credit2 = new Credit({imageUrl: imgSrc}); + var credit1 = new Credit('credit1'); + var credit2 = new Credit(''); creditDisplay = new CreditDisplay(container); var creditList = creditDisplay._creditList; @@ -637,43 +345,28 @@ defineSuite([ it('works if Cesium credit removed', function() { creditDisplay = new CreditDisplay(container); + var cesiumCredit = CreditDisplay.cesiumCredit; CreditDisplay.cesiumCredit = undefined; creditDisplay.beginFrame(); - expect(creditDisplay._currentFrameCredits.imageCredits.length).toEqual(0); creditDisplay.endFrame(); + expect(creditDisplay._cesiumCreditContainer.childNodes.length).toBe(0); + CreditDisplay.cesiumCredit = cesiumCredit; }); it('works if Cesium credit replaced', function() { - var credit = new Credit({ text: '' }); - CreditDisplay.cesiumCredit = credit; - creditDisplay = new CreditDisplay(container); - creditDisplay.beginFrame(); - expect(creditDisplay._currentFrameCredits.imageCredits[credit.id]).toBe(credit); - creditDisplay.endFrame(); - }); - - it('replaces Cesium credit if ion asset detected', function() { - var ionCredit = new Credit({ text: 'Cesium ion' }); + var ionCredit = Credit.getIonCredit({ + html: 'Cesium ion', + collapsible: false + }); creditDisplay = new CreditDisplay(container); creditDisplay.beginFrame(); - - expect(creditDisplay._currentFrameCredits.imageCredits[CreditDisplay.cesiumCredit.id]).toBe(CreditDisplay.cesiumCredit); creditDisplay.addCredit(ionCredit); - expect(creditDisplay._currentFrameCredits.imageCredits[CreditDisplay.cesiumCredit.id]).toBe(ionCredit); creditDisplay.endFrame(); - }); - - it('adds ion credit detected if Cesium credit replaced', function() { - var ionCredit = new Credit({ text: 'Cesium ion' }); - CreditDisplay.cesiumCredit = new Credit({ text: 'not Cesium' }); - creditDisplay = new CreditDisplay(container); + expect(creditDisplay._cesiumCreditContainer.childNodes.length).toBe(1); + expect(creditDisplay._cesiumCreditContainer.childNodes[0]).toBe(ionCredit._element); creditDisplay.beginFrame(); - - expect(creditDisplay._currentFrameCredits.imageCredits[CreditDisplay.cesiumCredit.id]).toBe(CreditDisplay.cesiumCredit); - - creditDisplay.addCredit(ionCredit); - - expect(creditDisplay._currentFrameCredits.imageCredits[ionCredit.id]).toBe(ionCredit); creditDisplay.endFrame(); + expect(creditDisplay._cesiumCreditContainer.childNodes.length).toBe(1); + expect(creditDisplay._cesiumCreditContainer.childNodes[0]).toBe(CreditDisplay.cesiumCredit.element); }); }); diff --git a/Specs/Scene/MapboxImageryProviderSpec.js b/Specs/Scene/MapboxImageryProviderSpec.js index 4270f8d2d957..504ab5eec00a 100644 --- a/Specs/Scene/MapboxImageryProviderSpec.js +++ b/Specs/Scene/MapboxImageryProviderSpec.js @@ -242,7 +242,7 @@ defineSuite([ url : 'made/up/mapbox/server/', mapId: 'test-id' }); - expect(provider.credit.text).toEqual('© Mapbox © OpenStreetMap'); + expect(provider.credit.html).toBe(MapboxImageryProvider._defaultCredit); }); it('turns the supplied credit into a logo', function() { @@ -252,7 +252,7 @@ defineSuite([ mapId: 'test-id', credit: creditText }); - expect(providerWithCredit.credit.text).toEqual(creditText); + expect(providerWithCredit.credit.html).toEqual(creditText); }); it('raises error event when image cannot be loaded', function() {