return this.loader.request(uri).then(function(content) { if (content) { content = this.pathResolver.rewriteURL(uri, href, content); if (media) { content = '@media ' + media + ' {' + content + '}'; } var style = dom5.constructors.element('style'); dom5.setTextContent(style, '\n' + content + '\n'); if (isPolymerExternalStyle) { // a polymer expternal style <link type="css" rel="import"> must be // in a <dom-module> to be processed var ownerDomModule = dom5.nodeWalkPrior(tag, dom5.predicates.hasTagName('dom-module')); if (ownerDomModule) { var domTemplate = dom5.query(ownerDomModule, dom5.predicates.hasTagName('template')); if (!domTemplate) { // create a <template>, which has a fragment as childNodes[0] domTemplate = dom5.constructors.element('template'); domTemplate.childNodes.push(dom5.constructors.fragment()); dom5.append(ownerDomModule, domTemplate); } dom5.remove(tag); // put the style at the top of the dom-module's template this.prepend(domTemplate.childNodes[0], style); } } else { dom5.replace(tag, style); } } }.bind(this));
function getDomModuleStyles(module) { // TODO: support `.styleModules = ['module-id', ...]` ? const styles = dom5.queryAll(module, styleMatch); if (!styles.length) { return []; } let template = dom5.query(module, pred.hasTagName('template')); if (!template) { template = dom5.constructors.element('template'); const content = dom5.constructors.fragment(); styles.forEach(s => dom5.append(content, s)); dom5.append(template, content); dom5.append(module, template); } else { styles.forEach(s => { let templateContent = template.childNodes[0]; if (!templateContent) { templateContent = dom5.constructors.fragment(); dom5.append(template, templateContent); } const parent = dom5.nodeWalkPrior(s, n => n === templateContent || n === module ); if (parent !== templateContent) { dom5.append(templateContent, s); } }) } return styles; }
/* * Collect styles from dom-module * In addition, make sure those styles are inside a template */ function getAndFixDomModuleStyles(domModule) { // TODO: support `.styleModules = ['module-id', ...]` ? const styles = getStyles(domModule); if (!styles.length) { return []; } let template = dom5.query(domModule, pred.hasTagName('template')); if (!template) { template = dom5.constructors.element('template'); const content = dom5.constructors.fragment(); styles.forEach(s => dom5.append(content, s)); dom5.append(template, content); dom5.append(domModule, template); } else { styles.forEach((s) => { let templateContent = template.content; // ensure element styles are inside the template element const parent = dom5.nodeWalkAncestors(s, (n) => n === templateContent || n === domModule ); if (parent !== templateContent) { prepend(templateContent, s); } }) } return styles; }
hide: function(node) { var hidden = dom5.constructors.element('div'); dom5.setAttribute(hidden, 'hidden', ''); dom5.setAttribute(hidden, 'by-vulcanize', ''); this.removeElementAndNewline(node, hidden); dom5.append(hidden, node); },
function shadyShim(ast, style, elements) { const scope = scopeMap.get(style); const element = getModuleElement(scope, elements); // only shim if module is a full polymer element, not just a style module if (!scope || !element) { return; } const ext = getTypeExtends(element); Polymer.StyleTransformer.css(ast, scope, ext); const module = domModuleCache[scope]; const head = findHead(module); dom5.setAttribute(style, 'scope', scope); const insertionPoint = afterLastInsertion(); dom5.insertBefore(head, insertionPoint || head.childNodes[0], style); // leave comment breadcrumb for css property shim to insert new styles const comment = dom5.constructors.comment(); dom5.setTextContent(comment, ` Shady DOM styles for ${scope} `) dom5.insertBefore(head, style, comment); lastShadyInsertionPoint = style; const template = dom5.query(module, pred.hasTagName('template')); // apply scoping to template if (template) { const elements = dom5.queryAll(template, notStyleMatch); elements.forEach(el => addClass(el, scope)); } }
return this.loader.request(resolvedSrc).then(function (content) { _this4._content[resolvedSrc] = content; var scriptText = dom5.constructors.text(content); dom5.append(script, scriptText); dom5.removeAttribute(script, 'src'); script.__hydrolysisInlined = src; return _this4._processScript(script, resolvedSrc); }).catch(function (err) {
return Options.loader.request(uri).then(function(content) { if (content) { content = pathResolver.rewriteURL(uri, href, content); var style = dom5.constructors.element('style'); dom5.setTextContent(style, '\n' + content + '\n'); dom5.replace(tag, style); } });
cssLinks.forEach(function(link) { var linkHref = dom5.getAttribute(link, 'href'); var uri = url.resolve(href, linkHref); var content = this._content[uri]; var style = dom5.constructors.element('style'); dom5.setTextContent(style, '\n' + content + '\n'); dom5.replace(link, style); }.bind(this));
scripts.forEach(function(script) { var scriptHref = dom5.getAttribute(script, 'src'); var uri = url.resolve(href, scriptHref); var content = this._content[uri]; var inlined = dom5.constructors.element('script'); dom5.setTextContent(inlined, '\n' + content + '\n'); dom5.replace(script, inlined); }.bind(this));
}).then(function(tree) { var flatDoc = this.flatten(tree, true); // make sure there's a <meta charset> in the page to force UTF-8 var meta = dom5.query(flatDoc, matchers.meta); var head = dom5.query(flatDoc, matchers.head); for (var i = 0; i < this.addedImports.length; i++) { var newImport = dom5.constructors.element('link'); dom5.setAttribute(newImport, 'rel', 'import'); dom5.setAttribute(newImport, 'href', this.addedImports[i]); this.prepend(head, newImport); } if (!meta) { meta = dom5.constructors.element('meta'); dom5.setAttribute(meta, 'charset', 'UTF-8'); this.prepend(head, meta); } return {doc: flatDoc, href: tree.href}; }.bind(this));
}).then(function(tree) { // hide bodies of imports from rendering var bodyFragment = dom5.constructors.element('div'); dom5.setAttribute(bodyFragment, 'hidden', ''); dom5.setAttribute(bodyFragment, 'by-vulcanize', ''); var flatDoc = flatten(tree, bodyFragment, tree.href); var body = dom5.query(flatDoc, matchers.body); if (bodyFragment.childNodes.length) { prepend(body, bodyFragment); } // make sure there's a <meta charset> in the page to force UTF-8 var meta = dom5.query(flatDoc, matchers.meta); if (!meta) { meta = dom5.constructors.element('meta'); dom5.setAttribute(meta, 'charset', 'UTF-8'); var head = dom5.query(flatDoc, matchers.head); prepend(head, meta); } return flatDoc; });
function markPolymerElement(polymerElement, useNativeShadow, analysis) { const document = getInlinedTemplateDocument(polymerElement, analysis); if (!document) { return; } const template = document.ast; // add a comment of the form `<!--css-build:shadow-->` to the template as the first child const buildComment = dom5.constructors.comment(`css-build:${useNativeShadow ? 'shadow' : 'shady'}`); prepend(template, buildComment); if (!useNativeShadow) { shadyScopeElementsInTemplate(template, polymerElement.tagName); } }
styles.forEach(s => { let templateContent = template.childNodes[0]; if (!templateContent) { templateContent = dom5.constructors.fragment(); dom5.append(template, templateContent); } const parent = dom5.nodeWalkPrior(s, n => n === templateContent || n === module ); if (parent !== templateContent) { dom5.append(templateContent, s); } })
function injectFrameScript(sourceDocument) { let fs = buildFrameScript(); let scriptTag = dom5.constructors.element('script'); dom5.setAttribute(scriptTag, 'designer-exclude', ''); dom5.setTextContent(scriptTag, fs); let head = dom5.query(sourceDocument, dom5.predicates.hasTagName('head')); if (head) { // inject into <head> if (head.childNodes) { let firstChild = head.childNodes[0]; dom5.insertBefore(head, firstChild, scriptTag); } else { dom5.append(head, scriptTag); } } else { // add to top of doc, below doctype let firstNonDoctype = dom5.nodeWalk(doc, (n) => n.nodeName !== '#documentType'); dom5.insertBefore(sourceDocument, firstNonDoctype, scriptTag); } }
flatten: function flatten(tree, isMainDoc) { var doc = tree.html.ast; var imports = tree.imports; var head = dom5.query(doc, matchers.head); var body = dom5.query(doc, matchers.body); var importNodes = tree.html.import; // early check for old polymer versions if (this.hasOldPolymer(doc)) { throw new Error(constants.OLD_POLYMER + ' File: ' + this.pathResolver.urlToPath(tree.href)); } this.fixFakeExternalScripts(doc); this.pathResolver.acid(doc, tree.href); var moveTarget; if (isMainDoc) { // hide bodies of imports from rendering in main document moveTarget = dom5.constructors.element('div'); dom5.setAttribute(moveTarget, 'hidden', ''); dom5.setAttribute(moveTarget, 'by-vulcanize', ''); } else { moveTarget = dom5.constructors.fragment(); } head.childNodes.filter(this.moveToBodyMatcher).forEach(function(n) { this.removeElementAndNewline(n); dom5.append(moveTarget, n); }, this); this.prepend(body, moveTarget); if (imports) { for (var i = 0, im, thisImport; i < imports.length; i++) { im = imports[i]; thisImport = importNodes[i]; if (this.isDuplicateImport(im) || this.isStrippedImport(im)) { this.removeElementAndNewline(thisImport); continue; } if (this.isExcludedImport(im)) { continue; } if (this.isTemplated(thisImport)) { continue; } var bodyFragment = dom5.constructors.fragment(); var importDoc = this.flatten(im); // rewrite urls this.pathResolver.resolvePaths(importDoc, im.href, tree.href); var importHead = dom5.query(importDoc, matchers.head); var importBody = dom5.query(importDoc, matchers.body); // merge head and body tags for imports into main document var importHeadChildren = importHead.childNodes; var importBodyChildren = importBody.childNodes; // make sure @license comments from import document make it into the import var importHtml = importHead.parentNode; var licenseComments = importDoc.childNodes.concat(importHtml.childNodes).filter(this.isLicenseComment); // move children of <head> and <body> into importer's <body> var reparentFn = this.reparent(bodyFragment); importHeadChildren.forEach(reparentFn); importBodyChildren.forEach(reparentFn); bodyFragment.childNodes = bodyFragment.childNodes.concat( licenseComments, importHeadChildren, importBodyChildren ); // hide imports in main document, unless already hidden if (isMainDoc && !this.ancestorWalk(thisImport, moveTarget)) { this.hide(thisImport); } this.removeElementAndNewline(thisImport, bodyFragment); } } // If hidden node is empty, remove it if (isMainDoc && moveTarget.childNodes.length === 0) { dom5.remove(moveTarget); } return doc; },
flatten: function flatten(tree, isMainDoc) { var doc = tree.html.ast; var imports = tree.imports; var head = dom5.query(doc, matchers.head); var body = dom5.query(doc, matchers.body); var importNodes = tree.html.import; // early check for old polymer versions if (this.hasOldPolymer(doc)) { throw new Error(constants.OLD_POLYMER + ' File: ' + this.pathResolver.urlToPath(tree.href)); } this.fixFakeExternalScripts(doc); this.pathResolver.acid(doc, tree.href); var moveTarget = dom5.constructors.fragment(); var moveToBody = dom5.queryAll(head, dom5.predicates.AND( dom5.predicates.OR( dom5.predicates.hasTagName('script'), dom5.predicates.hasTagName('link') ), dom5.predicates.NOT( matchers.polymerExternalStyle ) ) ); moveToBody.forEach(function(m) { // don't move nodes if inside a <template> content document if (!dom5.nodeWalkPrior(m, dom5.isDocumentFragment)) { dom5.append(moveTarget, m); } }); this.prepend(body, moveTarget); if (imports) { for (var i = 0, im, thisImport; i < imports.length; i++) { im = imports[i]; thisImport = importNodes[i]; if (this.isDuplicateImport(im) || this.isStrippedImport(im)) { this.removeImportAndNewline(thisImport); continue; } if (this.isExcludedImport(im)) { continue; } var bodyFragment = dom5.constructors.fragment(); var importDoc = this.flatten(im); // rewrite urls this.pathResolver.resolvePaths(importDoc, im.href, tree.href); var importHead = dom5.query(importDoc, matchers.head); var importBody = dom5.query(importDoc, matchers.body); // merge head and body tags for imports into main document var importHeadChildren = importHead.childNodes; var importBodyChildren = importBody.childNodes; // make sure @license comments from import document make it into head var importHtml = importHead.parentNode; var licenseComments = importDoc.childNodes.concat(importHtml.childNodes).filter(this.isLicenseComment); // put license comments at the top of <head> importHeadChildren = licenseComments.concat(importHeadChildren); // move children of <head> and <body> into importer's <body> var reparentFn = this.reparent(bodyFragment); importHeadChildren.forEach(reparentFn); importBodyChildren.forEach(reparentFn); bodyFragment.childNodes = bodyFragment.childNodes.concat( importHeadChildren, importBodyChildren ); // hide bodies of imports from rendering in main document if (isMainDoc) { this.hide(thisImport); } this.removeImportAndNewline(thisImport, bodyFragment); } } return doc; },
return Options.loader.request(uri).then(function(content) { var style = dom5.constructors.element('style'); dom5.setTextContent(style, '\n' + content + '\n'); dom5.replace(tag, style); });