Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(521)

Unified Diff: packages/polymer/lib/src/build/html_finalizer.dart

Issue 2312183003: Removed Polymer from Observatory deps (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: packages/polymer/lib/src/build/html_finalizer.dart
diff --git a/packages/polymer/lib/src/build/html_finalizer.dart b/packages/polymer/lib/src/build/html_finalizer.dart
deleted file mode 100644
index d476894b07cc78c583a89397804bb2d7e5b67b18..0000000000000000000000000000000000000000
--- a/packages/polymer/lib/src/build/html_finalizer.dart
+++ /dev/null
@@ -1,333 +0,0 @@
-// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Transfomer that finalizes an html file for deployment:
-/// - Extracts inline js scripts in csp mode.
-/// - Inlines css files into the document.
-/// - Validates polymer-element templates.
-library polymer.src.build.html_finalizer;
-
-import 'dart:async';
-import 'dart:collection' show LinkedHashSet;
-
-import 'package:barback/barback.dart';
-import 'package:code_transformers/assets.dart';
-import 'package:code_transformers/messages/build_logger.dart';
-import 'package:path/path.dart' as path;
-import 'package:html/dom.dart'
- show Document, DocumentFragment, Element, Node;
-import 'package:html/dom_parsing.dart' show TreeVisitor;
-import 'package:source_span/source_span.dart';
-
-import 'common.dart';
-import 'messages.dart';
-
-/// Inlines css files and extracts inline js scripts into files if in csp mode.
-// TODO(jakemac): Move to a different package. Will need to break out the
-// binding-specific logic when this happens (add it to the linter?).
-class _HtmlFinalizer extends PolymerTransformer {
- final TransformOptions options;
- final Transform transform;
- final BuildLogger logger;
- final AssetId docId;
- final seen = new Set<AssetId>();
- final scriptIds = new LinkedHashSet<AssetId>();
- final inlinedStylesheetIds = new Set<AssetId>();
- final extractedFiles = new Set<AssetId>();
-
- /// The number of extracted inline Dart scripts. Used as a counter to give
- /// unique-ish filenames.
- int inlineScriptCounter = 0;
-
- _HtmlFinalizer(TransformOptions options, Transform transform)
- : options = options,
- transform = transform,
- logger = new BuildLogger(transform,
- convertErrorsToWarnings: !options.releaseMode,
- detailsUri: 'http://goo.gl/5HPeuP'),
- docId = transform.primaryInput.id;
-
- Future apply() {
- seen.add(docId);
-
- Document document;
- bool changed = false;
-
- return readPrimaryAsHtml(transform, logger).then((doc) {
- document = doc;
- new _UrlAttributeValidator(docId, logger).visit(document);
-
- changed = _extractScripts(document) || changed;
-
- return _inlineCss(document);
- }).then((cssInlined) {
- changed = changed || cssInlined;
-
- var output = transform.primaryInput;
- if (changed) output = new Asset.fromString(docId, document.outerHtml);
- transform.addOutput(output);
-
- // Write out the logs collected by our [BuildLogger].
- if (options.injectBuildLogsInOutput) {
- return logger.writeOutput();
- }
- });
- }
-
- /// Inlines any css files found into document. Returns a [bool] indicating
- /// whether or not the document was modified.
- Future<bool> _inlineCss(Document document) {
- bool changed = false;
-
- // Note: we need to preserve the import order in the generated output.
- var tags = document.querySelectorAll('link[rel="stylesheet"]');
- return Future.forEach(tags, (Element tag) {
- var href = tag.attributes['href'];
- var id = uriToAssetId(docId, href, logger, tag.sourceSpan,
- errorOnAbsolute: false);
- if (id == null) return null;
- if (!options.shouldInlineStylesheet(id)) return null;
-
- changed = true;
- if (inlinedStylesheetIds.contains(id) &&
- !options.stylesheetInliningIsOverridden(id)) {
- logger.warning(CSS_FILE_INLINED_MULTIPLE_TIMES.create({'url': id.path}),
- span: tag.sourceSpan);
- }
- inlinedStylesheetIds.add(id);
- return _inlineStylesheet(id, tag);
- }).then((_) => changed);
- }
-
- /// Inlines a single css file by replacing [link] with an inline style tag.
- Future _inlineStylesheet(AssetId id, Element link) {
- return transform.readInputAsString(id).catchError((error) {
- // TODO(jakemac): Move this warning to the linter once we can make it run
- // always (see http://dartbug.com/17199). Then hide this error and replace
- // with a comment pointing to the linter error (so we don't double warn).
- logger.warning(INLINE_STYLE_FAIL.create({'error': error}),
- span: link.sourceSpan);
- }).then((css) {
- if (css == null) return null;
- css = new _UrlNormalizer(transform, id, logger).visitCss(css);
- var styleElement = new Element.tag('style')..text = css;
- // Copy over the extra attributes from the link tag to the style tag.
- // This adds support for no-shim, shim-shadowdom, etc.
- link.attributes.forEach((key, value) {
- if (!IGNORED_LINKED_STYLE_ATTRS.contains(key)) {
- styleElement.attributes[key] = value;
- }
- });
- link.replaceWith(styleElement);
- });
- }
-
- /// Splits inline js scripts into their own files in csp mode.
- bool _extractScripts(Document doc) {
- if (!options.contentSecurityPolicy) return false;
-
- bool changed = false;
- for (var script in doc.querySelectorAll('script')) {
- var src = script.attributes['src'];
- if (src != null) continue;
-
- var type = script.attributes['type'];
- if (type == TYPE_DART) continue;
-
- var extension = 'js';
- final filename = path.url.basename(docId.path);
- final count = inlineScriptCounter++;
- var code = script.text;
- // TODO(sigmund): ensure this path is unique (dartbug.com/12618).
- script.attributes['src'] = src = '$filename.$count.$extension';
- script.text = '';
- changed = true;
-
- var newId = docId.addExtension('.$count.$extension');
- extractedFiles.add(newId);
- transform.addOutput(new Asset.fromString(newId, code));
- }
- return changed;
- }
-}
-
-/// Finalizes a single html document for deployment.
-class HtmlFinalizer extends Transformer {
- final TransformOptions options;
-
- HtmlFinalizer(this.options);
-
- /// Only run on entry point .html files.
- bool isPrimary(AssetId id) => options.isHtmlEntryPoint(id);
-
- Future apply(Transform transform) =>
- new _HtmlFinalizer(options, transform).apply();
-}
-
-const TYPE_DART = 'application/dart';
-const TYPE_JS = 'text/javascript';
-
-/// Internally adjusts urls in the html that we are about to inline.
-class _UrlNormalizer {
- final Transform transform;
-
- /// Asset where the original content (and original url) was found.
- final AssetId sourceId;
-
- /// Path to the top level folder relative to the transform primaryInput.
- /// This should just be some arbitrary # of ../'s.
- final String topLevelPath;
-
- /// Whether or not the normalizer has changed something in the tree.
- bool changed = false;
-
- final BuildLogger logger;
-
- _UrlNormalizer(transform, this.sourceId, this.logger)
- : transform = transform,
- topLevelPath = '../' *
- (path.url.split(transform.primaryInput.id.path).length - 2);
-
- static final _URL = new RegExp(r'url\(([^)]*)\)', multiLine: true);
- static final _QUOTE = new RegExp('["\']', multiLine: true);
-
- /// Visit the CSS text and replace any relative URLs so we can inline it.
- // Ported from:
- // https://github.com/Polymer/vulcanize/blob/c14f63696797cda18dc3d372b78aa3378acc691f/lib/vulcan.js#L149
- // TODO(jmesserly): use csslib here instead? Parsing with RegEx is sadness.
- // Maybe it's reliable enough for finding URLs in CSS? I'm not sure.
- String visitCss(String cssText) {
- var url = spanUrlFor(sourceId, transform, logger);
- var src = new SourceFile(cssText, url: url);
- return cssText.replaceAllMapped(_URL, (match) {
- // Extract the URL, without any surrounding quotes.
- var span = src.span(match.start, match.end);
- var href = match[1].replaceAll(_QUOTE, '');
- href = _newUrl(href, span);
- return 'url($href)';
- });
- }
-
- String _newUrl(String href, SourceSpan span) {
- var uri = Uri.parse(href);
- if (uri.isAbsolute) return href;
- if (!uri.scheme.isEmpty) return href;
- if (!uri.host.isEmpty) return href;
- if (uri.path.isEmpty) return href; // Implies standalone ? or # in URI.
- if (path.isAbsolute(href)) return href;
-
- var id = uriToAssetId(sourceId, href, logger, span);
- if (id == null) return href;
- var primaryId = transform.primaryInput.id;
-
- if (id.path.startsWith('lib/')) {
- return '${topLevelPath}packages/${id.package}/${id.path.substring(4)}';
- }
-
- if (id.path.startsWith('asset/')) {
- return '${topLevelPath}assets/${id.package}/${id.path.substring(6)}';
- }
-
- if (primaryId.package != id.package) {
- // Technically we shouldn't get there
- logger.error(INTERNAL_ERROR_DONT_KNOW_HOW_TO_IMPORT
- .create({'target': id, 'source': primaryId, 'extra': ''}),
- span: span);
- return href;
- }
-
- var builder = path.url;
- return builder.relative(builder.join('/', id.path),
- from: builder.join('/', builder.dirname(primaryId.path)));
- }
-}
-
-/// Validates url-like attributes and throws warnings as appropriate.
-/// TODO(jakemac): Move to the linter.
-class _UrlAttributeValidator extends TreeVisitor {
- /// Asset where the original content (and original url) was found.
- final AssetId sourceId;
-
- final BuildLogger logger;
-
- _UrlAttributeValidator(this.sourceId, this.logger);
-
- visit(Node node) {
- return super.visit(node);
- }
-
- visitElement(Element node) {
- // TODO(jakemac): Support custom elements that extend html elements which
- // have url-like attributes. This probably means keeping a list of which
- // html elements support each url-like attribute.
- if (!isCustomTagName(node.localName)) {
- node.attributes.forEach((name, value) {
- if (_urlAttributes.contains(name)) {
- if (!name.startsWith('_') && value.contains(_BINDING_REGEX)) {
- logger.warning(USE_UNDERSCORE_PREFIX.create({'name': name}),
- span: node.sourceSpan, asset: sourceId);
- } else if (name.startsWith('_') && !value.contains(_BINDING_REGEX)) {
- logger.warning(
- DONT_USE_UNDERSCORE_PREFIX.create({'name': name.substring(1)}),
- span: node.sourceSpan, asset: sourceId);
- }
- }
- });
- }
- return super.visitElement(node);
- }
-}
-
-/// HTML attributes that expect a URL value.
-/// <http://dev.w3.org/html5/spec/section-index.html#attributes-1>
-///
-/// Every one of these attributes is a URL in every context where it is used in
-/// the DOM. The comments show every DOM element where an attribute can be used.
-///
-/// The _* version of each attribute is also supported, see http://goo.gl/5av8cU
-const _urlAttributes = const [
- // in form
- 'action',
- '_action',
- // in body
- 'background',
- '_background',
- // in blockquote, del, ins, q
- 'cite',
- '_cite',
- // in object
- 'data',
- '_data',
- // in button, input
- 'formaction',
- '_formaction',
- // in a, area, link, base, command
- 'href',
- '_href',
- // in command
- 'icon',
- '_icon',
- // in html
- 'manifest',
- '_manifest',
- // in video
- 'poster',
- '_poster',
- // in audio, embed, iframe, img, input, script, source, track, video
- 'src',
- '_src',
-];
-
-/// When inlining <link rel="stylesheet"> tags copy over all attributes to the
-/// style tag except these ones.
-const IGNORED_LINKED_STYLE_ATTRS = const [
- 'charset',
- 'href',
- 'href-lang',
- 'rel',
- 'rev'
-];
-
-/// Global RegExp objects.
-final _BINDING_REGEX = new RegExp(r'(({{.*}})|(\[\[.*\]\]))');
« no previous file with comments | « packages/polymer/lib/src/build/generated/messages.html ('k') | packages/polymer/lib/src/build/index_page_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698