-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
HTML Credits #6331
Conversation
@hpinkos, thanks for the pull request! Maintainers, we have a signed CLA from @hpinkos, so you can review this at any time.
I am a bot who helps you make Cesium awesome! Contributions to my configuration are welcome. 🌍 🌎 🌏 |
Source/ThirdParty/xss.js
Outdated
value.substr(0, 8) === 'https://' || | ||
value.substr(0, 7) === 'mailto:' || | ||
value.substr(0, 4) === 'tel:' || | ||
value.substr(0, 11) === 'data:image/' || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added this line and wanted to point out this change.
We have a few image credits like the Cesium and Bing credits that use <img src="data:image/png;base64,....."/>
. xss
was removing this. There wasn't a way to whitelist it through the API so I added a line to allow it. I couldn't find any reason why a data URI would lead to a security vulnerability, but I wanted to double check.
I added a comment to the top of the file so anyone updating this in the future knows that this file was altered from the original source.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer we not modify this, both because it's third-party code and because even if we don't think there are security implications, there may be. I don't know why we embed the Cesium and Bing credits anyway, they can just be external images like everything else.
If you are postive there are no security implications, then open an issue/PR in the xss respository and have it merged into the upstream project first.
@mramato can you review when you have some time? thanks! |
text: 'Improve this map', | ||
link: 'https://www.mapbox.com/map-feedback/' | ||
})]; | ||
var defaultCredit = new Credit('<a href="https://www.mapbox.com/about/maps/" target="_blank">© Mapbox © OpenStreetMap</a> <a href="https://www.mapbox.com/map-feedback/">Improve this map</a>'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we just use ©
for the copyright symbol now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also incorrect, see https://www.mapbox.com/help/how-attribution-works/#text-attribution
Source/Core/CesiumTerrainProvider.js
Outdated
@@ -167,8 +167,8 @@ define([ | |||
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, true), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was only two credits because of non-HTML credit limitations. You can merge it into a single one now.
Source/Core/Credit.js
Outdated
var key; | ||
if (typeof html !== 'string') { | ||
var options = defaultValue(html, defaultValue.EMPTY_OBJECT); | ||
deprecationWarning('Credit options', 'The options paramater has been deprecated and will be removed in Cesium 1.46. Instead, pass in an html string (or a string of text)'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nit, but html
-> HTML
Source/Core/Credit.js
Outdated
@@ -137,6 +170,7 @@ define([ | |||
*/ | |||
imageUrl : { | |||
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.'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copy paste typos in deprecation errors throughout
Source/Core/Credit.js
Outdated
|
||
function getElement(credit) { | ||
var html = credit.html; | ||
html = xss(html); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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
Source/Core/Credit.js
Outdated
} | ||
element.className = 'cesium-credit-text'; | ||
function createDomNode(html) { | ||
var div = document.createElement('span'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this can't be a span
because a span technically can't have child elements.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a span technically can't have child elements
Are you sure? I couldn't find any sources that say that. I use a span
because it's inherently inline
, where a div
is a block element. Plus we were putting everything into a span
already and it's worked fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a good answer on the subject with links back to the spec https://stackoverflow.com/a/11314736
span
can only have "phrasing elements", so I was only half-right but using a div is still the correct way to go. If it's trivial to use an inline div, then we should, but we could probably get away with a span element if we had to.
The Bing key warning message can now be improved since we can have inline links and other styling. EDIT: Perhaps add a little bold or other larger print. |
Source/Core/Credit.js
Outdated
var div = document.createElement('span'); | ||
div.innerHTML = html; | ||
|
||
if (div.children.length === 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is bad, I'm not sure you need it at all but if you're trying to avoid an extra wrapper then it should be childNodes
not children
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can test with This entire credit should be <b>visible</b>
key = JSON.stringify([text, imageUrl, link]); | ||
} else { | ||
key = html; | ||
} | ||
|
||
if (defined(creditToId[key])) { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
Looks like there is some missing test coverage, particular in the deprecated code. It's probably also a good idea to expose It also looks like a |
Thanks @hpinkos! This will be a big improvement. That's it for my initial review, but I actually didn't review Credit.js or CreditDisplay.js too closely yet, once all my initial feedback is addressed I'll give this another look. Thanks again! |
@mramato ready for another look. I addressed all of your comments. |
Source/Core/CesiumTerrainProvider.js
Outdated
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) |
There was a problem hiding this comment.
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)
Source/Core/Credit.js
Outdated
DeveloperError) { | ||
'use strict'; | ||
|
||
var nextCreditId = 0; | ||
var creditToId = {}; | ||
|
||
function createDomNode(html) { | ||
var span = document.createElement('span'); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
@mramato I think this is ready now
|
One last bug. Switching to Sentinel-2 (or any of the 3 ion imagery assets in the BaseLayerPicker) does not show the correct credit. The ion logo isn't there and the other attribution gets shown on screen instead of in the lightbox. |
I also tweaked the Bing/Mapbox signup credits to make them more obvious. |
@mramato fixed |
Whoops, broke one of the tests. One sec |
@mramato ready |
Sorry, found one more issue. The ion Sandcastle examples are triggering deprecation warnings: http://localhost:8080/Apps/Sandcastle/index.html?src=Blue%20Marble.html&label=ion%20Assets EDIT: Actually, anything using ion assets. |
@mramato that will be fixed when we change the attributions being sent from the ion server. I'm wasn't sure if it's something we should work around here. |
Makes sense, since we're putting that change in by tomorrow, I'll just hold off on merging this (but otherwise looks ready). |
@hpinkos one more thing, loading ion demos, such as http://localhost:8080/Apps/Sandcastle/index.html?src=Sentinel-2.html&label=ion%20Assets results in the logo being push up above |
@mramato that's a problem with the credit being sent from the ion server. I submitted a fix for it. I guess we should wait to merge this until that goes through. |
@mramato this is ready now |
Thanks! |
Other web mapping platforms like Leaflet and OpenLayers define attributions as HTML strings. This changes our
Credit
to do the same. HTML allows for much more flexibility than only exposing options for setting the text, image source and URL link. For example, will allow users to create credits like"My source is from some website with some license", something that is frequently needed for proper attribution, but not currently supported with our
Credit
.Summary of changes:
Credit
to accept an html string instead of anoption
objectCredit
no longer differentiates between 'text' credits and 'image' credits, modifiedCreditDisplay
to add all credits to the same credit containerCreditDisplay._cesiumCreditContainer
to add the Cesium credit