@glimmer/runtime
Version:
Minimal runtime needed to render Glimmer templates
103 lines (85 loc) • 11.6 kB
JavaScript
import { isSafeString, normalizeStringValue } from '../dom/normalize';
var badProtocols = ['javascript:', 'vbscript:'];
var badTags = ['A', 'BODY', 'LINK', 'IMG', 'IFRAME', 'BASE', 'FORM'];
var badTagsForDataURI = ['EMBED'];
var badAttributes = ['href', 'src', 'background', 'action'];
var badAttributesForDataURI = ['src'];
function has(array, item) {
return array.indexOf(item) !== -1;
}
function checkURI(tagName, attribute) {
return (tagName === null || has(badTags, tagName)) && has(badAttributes, attribute);
}
function checkDataURI(tagName, attribute) {
if (tagName === null) return false;
return has(badTagsForDataURI, tagName) && has(badAttributesForDataURI, attribute);
}
export function requiresSanitization(tagName, attribute) {
return checkURI(tagName, attribute) || checkDataURI(tagName, attribute);
}
var protocolForUrl;
if (typeof URL === 'object' && URL !== null && // this is super annoying, TS thinks that URL **must** be a function so `URL.parse` check
// thinks it is `never` without this `as unknown as any`
typeof URL.parse === 'function') {
// In Ember-land the `fastboot` package sets the `URL` global to `require('url')`
// ultimately, this should be changed (so that we can either rely on the natural `URL` global
// that exists) but for now we have to detect the specific `FastBoot` case first
//
// a future version of `fastboot` will detect if this legacy URL setup is required (by
// inspecting Ember version) and if new enough, it will avoid shadowing the `URL` global
// constructor with `require('url')`.
var nodeURL = URL;
protocolForUrl = function protocolForUrl(url) {
var protocol = null;
if (typeof url === 'string') {
protocol = nodeURL.parse(url).protocol;
}
return protocol === null ? ':' : protocol;
};
} else if (typeof URL === 'function') {
protocolForUrl = function protocolForUrl(_url) {
try {
var url = new URL(_url);
return url.protocol;
} catch (error) {
// any non-fully qualified url string will trigger an error (because there is no
// baseURI that we can provide; in that case we **know** that the protocol is
// "safe" because it isn't specifically one of the `badProtocols` listed above
// (and those protocols can never be the default baseURI)
return ':';
}
};
} else {
// fallback for IE11 support
var parsingNode = document.createElement('a');
protocolForUrl = function protocolForUrl(url) {
parsingNode.href = url;
return parsingNode.protocol;
};
}
export function sanitizeAttributeValue(element, attribute, value) {
var tagName = null;
if (value === null || value === undefined) {
return value;
}
if (isSafeString(value)) {
return value.toHTML();
}
if (!element) {
tagName = null;
} else {
tagName = element.tagName.toUpperCase();
}
var str = normalizeStringValue(value);
if (checkURI(tagName, attribute)) {
var protocol = protocolForUrl(str);
if (has(badProtocols, protocol)) {
return "unsafe:" + str;
}
}
if (checkDataURI(tagName, attribute)) {
return "unsafe:" + str;
}
return str;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL2RvbS9zYW5pdGl6ZWQtdmFsdWVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLFNBQUEsWUFBQSxFQUFBLG9CQUFBLFFBQUEsa0JBQUE7QUFFQSxJQUFNLFlBQVksR0FBRyxDQUFBLGFBQUEsRUFBckIsV0FBcUIsQ0FBckI7QUFFQSxJQUFNLE9BQU8sR0FBRyxDQUFBLEdBQUEsRUFBQSxNQUFBLEVBQUEsTUFBQSxFQUFBLEtBQUEsRUFBQSxRQUFBLEVBQUEsTUFBQSxFQUFoQixNQUFnQixDQUFoQjtBQUVBLElBQU0saUJBQWlCLEdBQUcsQ0FBMUIsT0FBMEIsQ0FBMUI7QUFFQSxJQUFNLGFBQWEsR0FBRyxDQUFBLE1BQUEsRUFBQSxLQUFBLEVBQUEsWUFBQSxFQUF0QixRQUFzQixDQUF0QjtBQUVBLElBQU0sdUJBQXVCLEdBQUcsQ0FBaEMsS0FBZ0MsQ0FBaEM7O0FBRUEsU0FBQSxHQUFBLENBQUEsS0FBQSxFQUFBLElBQUEsRUFBK0M7QUFDN0MsU0FBTyxLQUFLLENBQUwsT0FBQSxDQUFBLElBQUEsTUFBd0IsQ0FBL0IsQ0FBQTtBQUNEOztBQUVELFNBQUEsUUFBQSxDQUFBLE9BQUEsRUFBQSxTQUFBLEVBQTREO0FBQzFELFNBQU8sQ0FBQyxPQUFPLEtBQVAsSUFBQSxJQUFvQixHQUFHLENBQUEsT0FBQSxFQUF4QixPQUF3QixDQUF4QixLQUErQyxHQUFHLENBQUEsYUFBQSxFQUF6RCxTQUF5RCxDQUF6RDtBQUNEOztBQUVELFNBQUEsWUFBQSxDQUFBLE9BQUEsRUFBQSxTQUFBLEVBQWdFO0FBQzlELE1BQUksT0FBTyxLQUFYLElBQUEsRUFBc0IsT0FBQSxLQUFBO0FBQ3RCLFNBQU8sR0FBRyxDQUFBLGlCQUFBLEVBQUgsT0FBRyxDQUFILElBQW1DLEdBQUcsQ0FBQSx1QkFBQSxFQUE3QyxTQUE2QyxDQUE3QztBQUNEOztBQUVELE9BQU0sU0FBQSxvQkFBQSxDQUFBLE9BQUEsRUFBQSxTQUFBLEVBQWlFO0FBQ3JFLFNBQU8sUUFBUSxDQUFBLE9BQUEsRUFBUixTQUFRLENBQVIsSUFBZ0MsWUFBWSxDQUFBLE9BQUEsRUFBbkQsU0FBbUQsQ0FBbkQ7QUFDRDtBQVVELElBQUEsY0FBQTs7QUFFQSxJQUNFLE9BQUEsR0FBQSxLQUFBLFFBQUEsSUFDQSxHQUFHLEtBREgsSUFBQSxJQUVBO0FBQ0E7QUFDQSxPQUFTLEdBQXVCLENBQWhDLEtBQUEsS0FMRixVQUFBLEVBTUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUksT0FBTyxHQUFYLEdBQUE7O0FBRUEsRUFBQSxjQUFjLEdBQUksd0JBQUEsR0FBRCxFQUFnQjtBQUMvQixRQUFJLFFBQVEsR0FBWixJQUFBOztBQUVBLFFBQUksT0FBQSxHQUFBLEtBQUosUUFBQSxFQUE2QjtBQUMzQixNQUFBLFFBQVEsR0FBRyxPQUFPLENBQVAsS0FBQSxDQUFBLEdBQUEsRUFBWCxRQUFBO0FBQ0Q7O0FBRUQsV0FBTyxRQUFRLEtBQVIsSUFBQSxHQUFBLEdBQUEsR0FBUCxRQUFBO0FBUEYsR0FBQTtBQWhCRixDQUFBLE1BeUJPLElBQUksT0FBQSxHQUFBLEtBQUosVUFBQSxFQUErQjtBQUNwQyxFQUFBLGNBQWMsR0FBSSx3QkFBQSxJQUFELEVBQWlCO0FBQ2hDLFFBQUk7QUFDRixVQUFJLEdBQUcsR0FBRyxJQUFBLEdBQUEsQ0FBVixJQUFVLENBQVY7QUFFQSxhQUFPLEdBQUcsQ0FBVixRQUFBO0FBSEYsS0FBQSxDQUlFLE9BQUEsS0FBQSxFQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFBLEdBQUE7QUFDRDtBQVhILEdBQUE7QUFESyxDQUFBLE1BY0E7QUFDTDtBQUNBLE1BQUksV0FBVyxHQUFHLFFBQVEsQ0FBUixhQUFBLENBQWxCLEdBQWtCLENBQWxCOztBQUVBLEVBQUEsY0FBYyxHQUFJLHdCQUFBLEdBQUQsRUFBZ0I7QUFDL0IsSUFBQSxXQUFXLENBQVgsSUFBQSxHQUFBLEdBQUE7QUFDQSxXQUFPLFdBQVcsQ0FBbEIsUUFBQTtBQUZGLEdBQUE7QUFJRDs7QUFFRCxPQUFNLFNBQUEsc0JBQUEsQ0FBQSxPQUFBLEVBQUEsU0FBQSxFQUFBLEtBQUEsRUFHVTtBQUVkLE1BQUksT0FBTyxHQUFYLElBQUE7O0FBRUEsTUFBSSxLQUFLLEtBQUwsSUFBQSxJQUFrQixLQUFLLEtBQTNCLFNBQUEsRUFBMkM7QUFDekMsV0FBQSxLQUFBO0FBQ0Q7O0FBRUQsTUFBSSxZQUFZLENBQWhCLEtBQWdCLENBQWhCLEVBQXlCO0FBQ3ZCLFdBQU8sS0FBSyxDQUFaLE1BQU8sRUFBUDtBQUNEOztBQUVELE1BQUksQ0FBSixPQUFBLEVBQWM7QUFDWixJQUFBLE9BQU8sR0FBUCxJQUFBO0FBREYsR0FBQSxNQUVPO0FBQ0wsSUFBQSxPQUFPLEdBQUcsT0FBTyxDQUFQLE9BQUEsQ0FBVixXQUFVLEVBQVY7QUFDRDs7QUFFRCxNQUFJLEdBQUcsR0FBRyxvQkFBb0IsQ0FBOUIsS0FBOEIsQ0FBOUI7O0FBRUEsTUFBSSxRQUFRLENBQUEsT0FBQSxFQUFaLFNBQVksQ0FBWixFQUFrQztBQUNoQyxRQUFJLFFBQVEsR0FBRyxjQUFjLENBQTdCLEdBQTZCLENBQTdCOztBQUNBLFFBQUksR0FBRyxDQUFBLFlBQUEsRUFBUCxRQUFPLENBQVAsRUFBaUM7QUFDL0IseUJBQUEsR0FBQTtBQUNEO0FBQ0Y7O0FBRUQsTUFBSSxZQUFZLENBQUEsT0FBQSxFQUFoQixTQUFnQixDQUFoQixFQUFzQztBQUNwQyx1QkFBQSxHQUFBO0FBQ0Q7O0FBRUQsU0FBQSxHQUFBO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPcHRpb24gfSBmcm9tICdAZ2xpbW1lci9pbnRlcmZhY2VzJztcbmltcG9ydCB7IFNpbXBsZUVsZW1lbnQgfSBmcm9tICdAc2ltcGxlLWRvbS9pbnRlcmZhY2UnO1xuaW1wb3J0IHsgaXNTYWZlU3RyaW5nLCBub3JtYWxpemVTdHJpbmdWYWx1ZSB9IGZyb20gJy4uL2RvbS9ub3JtYWxpemUnO1xuXG5jb25zdCBiYWRQcm90b2NvbHMgPSBbJ2phdmFzY3JpcHQ6JywgJ3Zic2NyaXB0OiddO1xuXG5jb25zdCBiYWRUYWdzID0gWydBJywgJ0JPRFknLCAnTElOSycsICdJTUcnLCAnSUZSQU1FJywgJ0JBU0UnLCAnRk9STSddO1xuXG5jb25zdCBiYWRUYWdzRm9yRGF0YVVSSSA9IFsnRU1CRUQnXTtcblxuY29uc3QgYmFkQXR0cmlidXRlcyA9IFsnaHJlZicsICdzcmMnLCAnYmFja2dyb3VuZCcsICdhY3Rpb24nXTtcblxuY29uc3QgYmFkQXR0cmlidXRlc0ZvckRhdGFVUkkgPSBbJ3NyYyddO1xuXG5mdW5jdGlvbiBoYXMoYXJyYXk6IEFycmF5PHN0cmluZz4sIGl0ZW06IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gYXJyYXkuaW5kZXhPZihpdGVtKSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGNoZWNrVVJJKHRhZ05hbWU6IE9wdGlvbjxzdHJpbmc+LCBhdHRyaWJ1dGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gKHRhZ05hbWUgPT09IG51bGwgfHwgaGFzKGJhZFRhZ3MsIHRhZ05hbWUpKSAmJiBoYXMoYmFkQXR0cmlidXRlcywgYXR0cmlidXRlKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tEYXRhVVJJKHRhZ05hbWU6IE9wdGlvbjxzdHJpbmc+LCBhdHRyaWJ1dGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBpZiAodGFnTmFtZSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gaGFzKGJhZFRhZ3NGb3JEYXRhVVJJLCB0YWdOYW1lKSAmJiBoYXMoYmFkQXR0cmlidXRlc0ZvckRhdGFVUkksIGF0dHJpYnV0ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlc1Nhbml0aXphdGlvbih0YWdOYW1lOiBzdHJpbmcsIGF0dHJpYnV0ZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBjaGVja1VSSSh0YWdOYW1lLCBhdHRyaWJ1dGUpIHx8IGNoZWNrRGF0YVVSSSh0YWdOYW1lLCBhdHRyaWJ1dGUpO1xufVxuXG5pbnRlcmZhY2UgTm9kZVVybFBhcnNlUmVzdWx0IHtcbiAgcHJvdG9jb2w6IHN0cmluZyB8IG51bGw7XG59XG5cbmludGVyZmFjZSBOb2RlVXJsTW9kdWxlIHtcbiAgcGFyc2UodXJsOiBzdHJpbmcpOiBOb2RlVXJsUGFyc2VSZXN1bHQ7XG59XG5cbmxldCBwcm90b2NvbEZvclVybDogKHVybDogc3RyaW5nKSA9PiBzdHJpbmc7XG5cbmlmIChcbiAgdHlwZW9mIFVSTCA9PT0gJ29iamVjdCcgJiZcbiAgVVJMICE9PSBudWxsICYmXG4gIC8vIHRoaXMgaXMgc3VwZXIgYW5ub3lpbmcsIFRTIHRoaW5rcyB0aGF0IFVSTCAqKm11c3QqKiBiZSBhIGZ1bmN0aW9uIHNvIGBVUkwucGFyc2VgIGNoZWNrXG4gIC8vIHRoaW5rcyBpdCBpcyBgbmV2ZXJgIHdpdGhvdXQgdGhpcyBgYXMgdW5rbm93biBhcyBhbnlgXG4gIHR5cGVvZiAoKFVSTCBhcyB1bmtub3duKSBhcyBhbnkpLnBhcnNlID09PSAnZnVuY3Rpb24nXG4pIHtcbiAgLy8gSW4gRW1iZXItbGFuZCB0aGUgYGZhc3Rib290YCBwYWNrYWdlIHNldHMgdGhlIGBVUkxgIGdsb2JhbCB0byBgcmVxdWlyZSgndXJsJylgXG4gIC8vIHVsdGltYXRlbHksIHRoaXMgc2hvdWxkIGJlIGNoYW5nZWQgKHNvIHRoYXQgd2UgY2FuIGVpdGhlciByZWx5IG9uIHRoZSBuYXR1cmFsIGBVUkxgIGdsb2JhbFxuICAvLyB0aGF0IGV4aXN0cykgYnV0IGZvciBub3cgd2UgaGF2ZSB0byBkZXRlY3QgdGhlIHNwZWNpZmljIGBGYXN0Qm9vdGAgY2FzZSBmaXJzdFxuICAvL1xuICAvLyBhIGZ1dHVyZSB2ZXJzaW9uIG9mIGBmYXN0Ym9vdGAgd2lsbCBkZXRlY3QgaWYgdGhpcyBsZWdhY3kgVVJMIHNldHVwIGlzIHJlcXVpcmVkIChieVxuICAvLyBpbnNwZWN0aW5nIEVtYmVyIHZlcnNpb24pIGFuZCBpZiBuZXcgZW5vdWdoLCBpdCB3aWxsIGF2b2lkIHNoYWRvd2luZyB0aGUgYFVSTGAgZ2xvYmFsXG4gIC8vIGNvbnN0cnVjdG9yIHdpdGggYHJlcXVpcmUoJ3VybCcpYC5cbiAgbGV0IG5vZGVVUkwgPSBVUkwgYXMgTm9kZVVybE1vZHVsZTtcblxuICBwcm90b2NvbEZvclVybCA9ICh1cmw6IHN0cmluZykgPT4ge1xuICAgIGxldCBwcm90b2NvbCA9IG51bGw7XG5cbiAgICBpZiAodHlwZW9mIHVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHByb3RvY29sID0gbm9kZVVSTC5wYXJzZSh1cmwpLnByb3RvY29sO1xuICAgIH1cblxuICAgIHJldHVybiBwcm90b2NvbCA9PT0gbnVsbCA/ICc6JyA6IHByb3RvY29sO1xuICB9O1xufSBlbHNlIGlmICh0eXBlb2YgVVJMID09PSAnZnVuY3Rpb24nKSB7XG4gIHByb3RvY29sRm9yVXJsID0gKF91cmw6IHN0cmluZykgPT4ge1xuICAgIHRyeSB7XG4gICAgICBsZXQgdXJsID0gbmV3IFVSTChfdXJsKTtcblxuICAgICAgcmV0dXJuIHVybC5wcm90b2NvbDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gYW55IG5vbi1mdWxseSBxdWFsaWZpZWQgdXJsIHN0cmluZyB3aWxsIHRyaWdnZXIgYW4gZXJyb3IgKGJlY2F1c2UgdGhlcmUgaXMgbm9cbiAgICAgIC8vIGJhc2VVUkkgdGhhdCB3ZSBjYW4gcHJvdmlkZTsgaW4gdGhhdCBjYXNlIHdlICoqa25vdyoqIHRoYXQgdGhlIHByb3RvY29sIGlzXG4gICAgICAvLyBcInNhZmVcIiBiZWNhdXNlIGl0IGlzbid0IHNwZWNpZmljYWxseSBvbmUgb2YgdGhlIGBiYWRQcm90b2NvbHNgIGxpc3RlZCBhYm92ZVxuICAgICAgLy8gKGFuZCB0aG9zZSBwcm90b2NvbHMgY2FuIG5ldmVyIGJlIHRoZSBkZWZhdWx0IGJhc2VVUkkpXG4gICAgICByZXR1cm4gJzonO1xuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIGZhbGxiYWNrIGZvciBJRTExIHN1cHBvcnRcbiAgbGV0IHBhcnNpbmdOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuXG4gIHByb3RvY29sRm9yVXJsID0gKHVybDogc3RyaW5nKSA9PiB7XG4gICAgcGFyc2luZ05vZGUuaHJlZiA9IHVybDtcbiAgICByZXR1cm4gcGFyc2luZ05vZGUucHJvdG9jb2w7XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzYW5pdGl6ZUF0dHJpYnV0ZVZhbHVlKFxuICBlbGVtZW50OiBTaW1wbGVFbGVtZW50LFxuICBhdHRyaWJ1dGU6IHN0cmluZyxcbiAgdmFsdWU6IHVua25vd25cbik6IHVua25vd24ge1xuICBsZXQgdGFnTmFtZTogT3B0aW9uPHN0cmluZz4gPSBudWxsO1xuXG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgaWYgKGlzU2FmZVN0cmluZyh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWUudG9IVE1MKCk7XG4gIH1cblxuICBpZiAoIWVsZW1lbnQpIHtcbiAgICB0YWdOYW1lID0gbnVsbDtcbiAgfSBlbHNlIHtcbiAgICB0YWdOYW1lID0gZWxlbWVudC50YWdOYW1lLnRvVXBwZXJDYXNlKCk7XG4gIH1cblxuICBsZXQgc3RyID0gbm9ybWFsaXplU3RyaW5nVmFsdWUodmFsdWUpO1xuXG4gIGlmIChjaGVja1VSSSh0YWdOYW1lLCBhdHRyaWJ1dGUpKSB7XG4gICAgbGV0IHByb3RvY29sID0gcHJvdG9jb2xGb3JVcmwoc3RyKTtcbiAgICBpZiAoaGFzKGJhZFByb3RvY29scywgcHJvdG9jb2wpKSB7XG4gICAgICByZXR1cm4gYHVuc2FmZToke3N0cn1gO1xuICAgIH1cbiAgfVxuXG4gIGlmIChjaGVja0RhdGFVUkkodGFnTmFtZSwgYXR0cmlidXRlKSkge1xuICAgIHJldHVybiBgdW5zYWZlOiR7c3RyfWA7XG4gIH1cblxuICByZXR1cm4gc3RyO1xufVxuIl0sInNvdXJjZVJvb3QiOiIifQ==