Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTML Credits #6331

Merged
merged 11 commits into from
Mar 22, 2018
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,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).
Expand All @@ -23,6 +26,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)
* Added support for ordering in `DataSourceCollection` [#6316](https://github.com/AnalyticalGraphicsInc/cesium/pull/6316)
* All ground geometry from one `DataSource` will render in front of all ground geometry from another `DataSource` in the same collection with a lower index.
* Use `DataSourceCollection.raise`, `DataSourceCollection.lower`, `DataSourceCollection.raiseToTop` and `DataSourceCollection.lowerToBottom` functions to change the ordering of a `DataSource` in the collection.
Expand Down
28 changes: 28 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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(雷宗民) <[email protected]>
> 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
=====

Expand Down
Binary file added Source/Assets/Images/bing_maps_credit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Source/Assets/Images/cesium_credit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Source/Assets/Images/google_earth_credit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 1 addition & 4 deletions Source/Core/BingMapsApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,7 @@ define([
}

if (!defined(errorCredit)) {
errorCredit = new Credit({
text : errorString,
showOnScreen : true
});
errorCredit = new Credit(errorString, true);
}

return errorCredit;
Expand Down
9 changes: 4 additions & 5 deletions Source/Core/CesiumTerrainProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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('<span>' + deprecationText + '</span> <a href="' + deprecationLink + '" target="_blank">' + deprecationLinkText + '</a>', true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should have createDomNode automatically add target='_blank' to all credit links (then we can remove them all from this PR)

];
deprecationWarning('assets.agi.com', deprecationText + ' ' + deprecationLinkText + ' ' + deprecationLink);
} else {
Expand Down Expand Up @@ -327,7 +326,7 @@ define([
}
}

var layerJsonCredit = new Credit({ text: attribution });
var layerJsonCredit = new Credit(attribution);

if (defined(that._tileCredits)) {
that._tileCredits.push(layerJsonCredit);
Expand Down
204 changes: 129 additions & 75 deletions Source/Core/Credit.js
Original file line number Diff line number Diff line change
@@ -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');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we were going to make this a div? Also, this function no longer seems necessary since it's only used in the equally small getElement below.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, getElement can also be moved into the element getter, since the whole thing is trivial.

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are we using for a whitelist here? Because it looks like not even the <b> tag works?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out the fact that <b> tags don't work is because createDomNode doesn't work, not because of xss.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just using the default whitelist https://github.com/leizongmin/js-xss/blob/master/lib/default.js

I'll look into the createDomNode thing

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
Expand All @@ -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 = '<span>' + element.innerHTML + '</span>';
key = JSON.stringify([text, imageUrl, link]);
} else {
key = html;
}

if (defined(creditToId[key])) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we even need creditToId anymore? Can't we just use the html as the id directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

credit.id is a number and is used as the index of the credit in the array of credits in CreditDisplay. So we still need this.

id = creditToId[key];
Expand All @@ -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
Expand All @@ -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;
}
},
Expand All @@ -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;
}
},
Expand All @@ -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;
}
},
Expand Down Expand Up @@ -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;
};

Expand All @@ -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;
};

Expand Down Expand Up @@ -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;
});
2 changes: 1 addition & 1 deletion Source/Core/GoogleEarthEnterpriseMetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
})
Expand Down
Loading