@glimmer/runtime
Version:
Minimal runtime needed to render Glimmer templates
113 lines (91 loc) • 11.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.requiresSanitization = requiresSanitization;
exports.sanitizeAttributeValue = sanitizeAttributeValue;
var _normalize = require("../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);
}
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;
};
}
function sanitizeAttributeValue(element, attribute, value) {
var tagName = null;
if (value === null || value === undefined) {
return value;
}
if ((0, _normalize.isSafeString)(value)) {
return value.toHTML();
}
if (!element) {
tagName = null;
} else {
tagName = element.tagName.toUpperCase();
}
var str = (0, _normalize.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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL0BnbGltbWVyL3J1bnRpbWUvbGliL2RvbS9zYW5pdGl6ZWQtdmFsdWVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7O0FBRUE7O0FBRUEsSUFBTSxZQUFZLEdBQUcsQ0FBQSxhQUFBLEVBQXJCLFdBQXFCLENBQXJCO0FBRUEsSUFBTSxPQUFPLEdBQUcsQ0FBQSxHQUFBLEVBQUEsTUFBQSxFQUFBLE1BQUEsRUFBQSxLQUFBLEVBQUEsUUFBQSxFQUFBLE1BQUEsRUFBaEIsTUFBZ0IsQ0FBaEI7QUFFQSxJQUFNLGlCQUFpQixHQUFHLENBQTFCLE9BQTBCLENBQTFCO0FBRUEsSUFBTSxhQUFhLEdBQUcsQ0FBQSxNQUFBLEVBQUEsS0FBQSxFQUFBLFlBQUEsRUFBdEIsUUFBc0IsQ0FBdEI7QUFFQSxJQUFNLHVCQUF1QixHQUFHLENBQWhDLEtBQWdDLENBQWhDOztBQUVBLFNBQUEsR0FBQSxDQUFBLEtBQUEsRUFBQSxJQUFBLEVBQStDO0FBQzdDLFNBQU8sS0FBSyxDQUFMLE9BQUEsQ0FBQSxJQUFBLE1BQXdCLENBQS9CLENBQUE7QUFDRDs7QUFFRCxTQUFBLFFBQUEsQ0FBQSxPQUFBLEVBQUEsU0FBQSxFQUE0RDtBQUMxRCxTQUFPLENBQUMsT0FBTyxLQUFQLElBQUEsSUFBb0IsR0FBRyxDQUFBLE9BQUEsRUFBeEIsT0FBd0IsQ0FBeEIsS0FBK0MsR0FBRyxDQUFBLGFBQUEsRUFBekQsU0FBeUQsQ0FBekQ7QUFDRDs7QUFFRCxTQUFBLFlBQUEsQ0FBQSxPQUFBLEVBQUEsU0FBQSxFQUFnRTtBQUM5RCxNQUFJLE9BQU8sS0FBWCxJQUFBLEVBQXNCLE9BQUEsS0FBQTtBQUN0QixTQUFPLEdBQUcsQ0FBQSxpQkFBQSxFQUFILE9BQUcsQ0FBSCxJQUFtQyxHQUFHLENBQUEsdUJBQUEsRUFBN0MsU0FBNkMsQ0FBN0M7QUFDRDs7QUFFSyxTQUFBLG9CQUFBLENBQUEsT0FBQSxFQUFBLFNBQUEsRUFBaUU7QUFDckUsU0FBTyxRQUFRLENBQUEsT0FBQSxFQUFSLFNBQVEsQ0FBUixJQUFnQyxZQUFZLENBQUEsT0FBQSxFQUFuRCxTQUFtRCxDQUFuRDtBQUNEOztBQVVELElBQUEsY0FBQTs7QUFFQSxJQUNFLE9BQUEsR0FBQSxLQUFBLFFBQUEsSUFDQSxHQUFHLEtBREgsSUFBQSxJQUVBO0FBQ0E7QUFDQSxPQUFTLEdBQXVCLENBQWhDLEtBQUEsS0FMRixVQUFBLEVBTUU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUksT0FBTyxHQUFYLEdBQUE7O0FBRUEsRUFBQSxjQUFjLEdBQUksU0FBQSxjQUFBLENBQUQsR0FBQyxFQUFlO0FBQy9CLFFBQUksUUFBUSxHQUFaLElBQUE7O0FBRUEsUUFBSSxPQUFBLEdBQUEsS0FBSixRQUFBLEVBQTZCO0FBQzNCLE1BQUEsUUFBUSxHQUFHLE9BQU8sQ0FBUCxLQUFBLENBQUEsR0FBQSxFQUFYLFFBQUE7QUFDRDs7QUFFRCxXQUFPLFFBQVEsS0FBUixJQUFBLEdBQUEsR0FBQSxHQUFQLFFBQUE7QUFQRixHQUFBO0FBaEJGLENBQUEsTUF5Qk8sSUFBSSxPQUFBLEdBQUEsS0FBSixVQUFBLEVBQStCO0FBQ3BDLEVBQUEsY0FBYyxHQUFJLFNBQUEsY0FBQSxDQUFELElBQUMsRUFBZ0I7QUFDaEMsUUFBSTtBQUNGLFVBQUksR0FBRyxHQUFHLElBQUEsR0FBQSxDQUFWLElBQVUsQ0FBVjtBQUVBLGFBQU8sR0FBRyxDQUFWLFFBQUE7QUFIRixLQUFBLENBSUUsT0FBQSxLQUFBLEVBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGFBQUEsR0FBQTtBQUNEO0FBWEgsR0FBQTtBQURLLENBQUEsTUFjQTtBQUNMO0FBQ0EsTUFBSSxXQUFXLEdBQUcsUUFBUSxDQUFSLGFBQUEsQ0FBbEIsR0FBa0IsQ0FBbEI7O0FBRUEsRUFBQSxjQUFjLEdBQUksU0FBQSxjQUFBLENBQUQsR0FBQyxFQUFlO0FBQy9CLElBQUEsV0FBVyxDQUFYLElBQUEsR0FBQSxHQUFBO0FBQ0EsV0FBTyxXQUFXLENBQWxCLFFBQUE7QUFGRixHQUFBO0FBSUQ7O0FBRUssU0FBQSxzQkFBQSxDQUFBLE9BQUEsRUFBQSxTQUFBLEVBQUEsS0FBQSxFQUdVO0FBRWQsTUFBSSxPQUFPLEdBQVgsSUFBQTs7QUFFQSxNQUFJLEtBQUssS0FBTCxJQUFBLElBQWtCLEtBQUssS0FBM0IsU0FBQSxFQUEyQztBQUN6QyxXQUFBLEtBQUE7QUFDRDs7QUFFRCxNQUFJLDZCQUFKLEtBQUksQ0FBSixFQUF5QjtBQUN2QixXQUFPLEtBQUssQ0FBWixNQUFPLEVBQVA7QUFDRDs7QUFFRCxNQUFJLENBQUosT0FBQSxFQUFjO0FBQ1osSUFBQSxPQUFPLEdBQVAsSUFBQTtBQURGLEdBQUEsTUFFTztBQUNMLElBQUEsT0FBTyxHQUFHLE9BQU8sQ0FBUCxPQUFBLENBQVYsV0FBVSxFQUFWO0FBQ0Q7O0FBRUQsTUFBSSxHQUFHLEdBQUcscUNBQVYsS0FBVSxDQUFWOztBQUVBLE1BQUksUUFBUSxDQUFBLE9BQUEsRUFBWixTQUFZLENBQVosRUFBa0M7QUFDaEMsUUFBSSxRQUFRLEdBQUcsY0FBYyxDQUE3QixHQUE2QixDQUE3Qjs7QUFDQSxRQUFJLEdBQUcsQ0FBQSxZQUFBLEVBQVAsUUFBTyxDQUFQLEVBQWlDO0FBQy9CLGFBQUEsWUFBQSxHQUFBO0FBQ0Q7QUFDRjs7QUFFRCxNQUFJLFlBQVksQ0FBQSxPQUFBLEVBQWhCLFNBQWdCLENBQWhCLEVBQXNDO0FBQ3BDLFdBQUEsWUFBQSxHQUFBO0FBQ0Q7O0FBRUQsU0FBQSxHQUFBO0FBQ0QiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPcHRpb24gfSBmcm9tICdAZ2xpbW1lci9pbnRlcmZhY2VzJztcbmltcG9ydCB7IFNpbXBsZUVsZW1lbnQgfSBmcm9tICdAc2ltcGxlLWRvbS9pbnRlcmZhY2UnO1xuaW1wb3J0IHsgaXNTYWZlU3RyaW5nLCBub3JtYWxpemVTdHJpbmdWYWx1ZSB9IGZyb20gJy4uL2RvbS9ub3JtYWxpemUnO1xuXG5jb25zdCBiYWRQcm90b2NvbHMgPSBbJ2phdmFzY3JpcHQ6JywgJ3Zic2NyaXB0OiddO1xuXG5jb25zdCBiYWRUYWdzID0gWydBJywgJ0JPRFknLCAnTElOSycsICdJTUcnLCAnSUZSQU1FJywgJ0JBU0UnLCAnRk9STSddO1xuXG5jb25zdCBiYWRUYWdzRm9yRGF0YVVSSSA9IFsnRU1CRUQnXTtcblxuY29uc3QgYmFkQXR0cmlidXRlcyA9IFsnaHJlZicsICdzcmMnLCAnYmFja2dyb3VuZCcsICdhY3Rpb24nXTtcblxuY29uc3QgYmFkQXR0cmlidXRlc0ZvckRhdGFVUkkgPSBbJ3NyYyddO1xuXG5mdW5jdGlvbiBoYXMoYXJyYXk6IEFycmF5PHN0cmluZz4sIGl0ZW06IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gYXJyYXkuaW5kZXhPZihpdGVtKSAhPT0gLTE7XG59XG5cbmZ1bmN0aW9uIGNoZWNrVVJJKHRhZ05hbWU6IE9wdGlvbjxzdHJpbmc+LCBhdHRyaWJ1dGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gKHRhZ05hbWUgPT09IG51bGwgfHwgaGFzKGJhZFRhZ3MsIHRhZ05hbWUpKSAmJiBoYXMoYmFkQXR0cmlidXRlcywgYXR0cmlidXRlKTtcbn1cblxuZnVuY3Rpb24gY2hlY2tEYXRhVVJJKHRhZ05hbWU6IE9wdGlvbjxzdHJpbmc+LCBhdHRyaWJ1dGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBpZiAodGFnTmFtZSA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gaGFzKGJhZFRhZ3NGb3JEYXRhVVJJLCB0YWdOYW1lKSAmJiBoYXMoYmFkQXR0cmlidXRlc0ZvckRhdGFVUkksIGF0dHJpYnV0ZSk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlc1Nhbml0aXphdGlvbih0YWdOYW1lOiBzdHJpbmcsIGF0dHJpYnV0ZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBjaGVja1VSSSh0YWdOYW1lLCBhdHRyaWJ1dGUpIHx8IGNoZWNrRGF0YVVSSSh0YWdOYW1lLCBhdHRyaWJ1dGUpO1xufVxuXG5pbnRlcmZhY2UgTm9kZVVybFBhcnNlUmVzdWx0IHtcbiAgcHJvdG9jb2w6IHN0cmluZyB8IG51bGw7XG59XG5cbmludGVyZmFjZSBOb2RlVXJsTW9kdWxlIHtcbiAgcGFyc2UodXJsOiBzdHJpbmcpOiBOb2RlVXJsUGFyc2VSZXN1bHQ7XG59XG5cbmxldCBwcm90b2NvbEZvclVybDogKHVybDogc3RyaW5nKSA9PiBzdHJpbmc7XG5cbmlmIChcbiAgdHlwZW9mIFVSTCA9PT0gJ29iamVjdCcgJiZcbiAgVVJMICE9PSBudWxsICYmXG4gIC8vIHRoaXMgaXMgc3VwZXIgYW5ub3lpbmcsIFRTIHRoaW5rcyB0aGF0IFVSTCAqKm11c3QqKiBiZSBhIGZ1bmN0aW9uIHNvIGBVUkwucGFyc2VgIGNoZWNrXG4gIC8vIHRoaW5rcyBpdCBpcyBgbmV2ZXJgIHdpdGhvdXQgdGhpcyBgYXMgdW5rbm93biBhcyBhbnlgXG4gIHR5cGVvZiAoKFVSTCBhcyB1bmtub3duKSBhcyBhbnkpLnBhcnNlID09PSAnZnVuY3Rpb24nXG4pIHtcbiAgLy8gSW4gRW1iZXItbGFuZCB0aGUgYGZhc3Rib290YCBwYWNrYWdlIHNldHMgdGhlIGBVUkxgIGdsb2JhbCB0byBgcmVxdWlyZSgndXJsJylgXG4gIC8vIHVsdGltYXRlbHksIHRoaXMgc2hvdWxkIGJlIGNoYW5nZWQgKHNvIHRoYXQgd2UgY2FuIGVpdGhlciByZWx5IG9uIHRoZSBuYXR1cmFsIGBVUkxgIGdsb2JhbFxuICAvLyB0aGF0IGV4aXN0cykgYnV0IGZvciBub3cgd2UgaGF2ZSB0byBkZXRlY3QgdGhlIHNwZWNpZmljIGBGYXN0Qm9vdGAgY2FzZSBmaXJzdFxuICAvL1xuICAvLyBhIGZ1dHVyZSB2ZXJzaW9uIG9mIGBmYXN0Ym9vdGAgd2lsbCBkZXRlY3QgaWYgdGhpcyBsZWdhY3kgVVJMIHNldHVwIGlzIHJlcXVpcmVkIChieVxuICAvLyBpbnNwZWN0aW5nIEVtYmVyIHZlcnNpb24pIGFuZCBpZiBuZXcgZW5vdWdoLCBpdCB3aWxsIGF2b2lkIHNoYWRvd2luZyB0aGUgYFVSTGAgZ2xvYmFsXG4gIC8vIGNvbnN0cnVjdG9yIHdpdGggYHJlcXVpcmUoJ3VybCcpYC5cbiAgbGV0IG5vZGVVUkwgPSBVUkwgYXMgTm9kZVVybE1vZHVsZTtcblxuICBwcm90b2NvbEZvclVybCA9ICh1cmw6IHN0cmluZykgPT4ge1xuICAgIGxldCBwcm90b2NvbCA9IG51bGw7XG5cbiAgICBpZiAodHlwZW9mIHVybCA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHByb3RvY29sID0gbm9kZVVSTC5wYXJzZSh1cmwpLnByb3RvY29sO1xuICAgIH1cblxuICAgIHJldHVybiBwcm90b2NvbCA9PT0gbnVsbCA/ICc6JyA6IHByb3RvY29sO1xuICB9O1xufSBlbHNlIGlmICh0eXBlb2YgVVJMID09PSAnZnVuY3Rpb24nKSB7XG4gIHByb3RvY29sRm9yVXJsID0gKF91cmw6IHN0cmluZykgPT4ge1xuICAgIHRyeSB7XG4gICAgICBsZXQgdXJsID0gbmV3IFVSTChfdXJsKTtcblxuICAgICAgcmV0dXJuIHVybC5wcm90b2NvbDtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gYW55IG5vbi1mdWxseSBxdWFsaWZpZWQgdXJsIHN0cmluZyB3aWxsIHRyaWdnZXIgYW4gZXJyb3IgKGJlY2F1c2UgdGhlcmUgaXMgbm9cbiAgICAgIC8vIGJhc2VVUkkgdGhhdCB3ZSBjYW4gcHJvdmlkZTsgaW4gdGhhdCBjYXNlIHdlICoqa25vdyoqIHRoYXQgdGhlIHByb3RvY29sIGlzXG4gICAgICAvLyBcInNhZmVcIiBiZWNhdXNlIGl0IGlzbid0IHNwZWNpZmljYWxseSBvbmUgb2YgdGhlIGBiYWRQcm90b2NvbHNgIGxpc3RlZCBhYm92ZVxuICAgICAgLy8gKGFuZCB0aG9zZSBwcm90b2NvbHMgY2FuIG5ldmVyIGJlIHRoZSBkZWZhdWx0IGJhc2VVUkkpXG4gICAgICByZXR1cm4gJzonO1xuICAgIH1cbiAgfTtcbn0gZWxzZSB7XG4gIC8vIGZhbGxiYWNrIGZvciBJRTExIHN1cHBvcnRcbiAgbGV0IHBhcnNpbmdOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xuXG4gIHByb3RvY29sRm9yVXJsID0gKHVybDogc3RyaW5nKSA9PiB7XG4gICAgcGFyc2luZ05vZGUuaHJlZiA9IHVybDtcbiAgICByZXR1cm4gcGFyc2luZ05vZGUucHJvdG9jb2w7XG4gIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzYW5pdGl6ZUF0dHJpYnV0ZVZhbHVlKFxuICBlbGVtZW50OiBTaW1wbGVFbGVtZW50LFxuICBhdHRyaWJ1dGU6IHN0cmluZyxcbiAgdmFsdWU6IHVua25vd25cbik6IHVua25vd24ge1xuICBsZXQgdGFnTmFtZTogT3B0aW9uPHN0cmluZz4gPSBudWxsO1xuXG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgaWYgKGlzU2FmZVN0cmluZyh2YWx1ZSkpIHtcbiAgICByZXR1cm4gdmFsdWUudG9IVE1MKCk7XG4gIH1cblxuICBpZiAoIWVsZW1lbnQpIHtcbiAgICB0YWdOYW1lID0gbnVsbDtcbiAgfSBlbHNlIHtcbiAgICB0YWdOYW1lID0gZWxlbWVudC50YWdOYW1lLnRvVXBwZXJDYXNlKCk7XG4gIH1cblxuICBsZXQgc3RyID0gbm9ybWFsaXplU3RyaW5nVmFsdWUodmFsdWUpO1xuXG4gIGlmIChjaGVja1VSSSh0YWdOYW1lLCBhdHRyaWJ1dGUpKSB7XG4gICAgbGV0IHByb3RvY29sID0gcHJvdG9jb2xGb3JVcmwoc3RyKTtcbiAgICBpZiAoaGFzKGJhZFByb3RvY29scywgcHJvdG9jb2wpKSB7XG4gICAgICByZXR1cm4gYHVuc2FmZToke3N0cn1gO1xuICAgIH1cbiAgfVxuXG4gIGlmIChjaGVja0RhdGFVUkkodGFnTmFtZSwgYXR0cmlidXRlKSkge1xuICAgIHJldHVybiBgdW5zYWZlOiR7c3RyfWA7XG4gIH1cblxuICByZXR1cm4gc3RyO1xufVxuIl0sInNvdXJjZVJvb3QiOiIifQ==