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

Side by Side Diff: lib/src/dependency_graph.dart

Issue 1145893008: fixes #182, avoid injecting a duplicate link rel=stylesheet (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 5 years, 6 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 unified diff | Download patch
« no previous file with comments | « lib/src/codegen/html_codegen.dart ('k') | test/codegen/expect/sunflower/sunflower.html » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 /// Tracks the shape of the import/export graph and dependencies between files. 5 /// Tracks the shape of the import/export graph and dependencies between files.
6 library dev_compiler.src.dependency_graph; 6 library dev_compiler.src.dependency_graph;
7 7
8 import 'dart:collection' show HashSet; 8 import 'dart:collection' show HashSet, HashMap;
9 9
10 import 'package:analyzer/analyzer.dart' show parseDirectives; 10 import 'package:analyzer/analyzer.dart' show parseDirectives;
11 import 'package:analyzer/src/generated/ast.dart' 11 import 'package:analyzer/src/generated/ast.dart'
12 show 12 show
13 AstNode, 13 AstNode,
14 CompilationUnit, 14 CompilationUnit,
15 ExportDirective, 15 ExportDirective,
16 Identifier, 16 Identifier,
17 ImportDirective, 17 ImportDirective,
18 LibraryDirective, 18 LibraryDirective,
19 PartDirective, 19 PartDirective,
20 PartOfDirective; 20 PartOfDirective;
21 import 'package:analyzer/src/generated/engine.dart' 21 import 'package:analyzer/src/generated/engine.dart'
22 show ParseDartTask, AnalysisContext; 22 show ParseDartTask, AnalysisContext;
23 import 'package:analyzer/src/generated/source.dart' show Source, SourceKind; 23 import 'package:analyzer/src/generated/source.dart' show Source, SourceKind;
24 import 'package:html/dom.dart' show Document, Node; 24 import 'package:html/dom.dart' show Document, Node, Element;
25 import 'package:html/parser.dart' as html; 25 import 'package:html/parser.dart' as html;
26 import 'package:logging/logging.dart' show Logger, Level; 26 import 'package:logging/logging.dart' show Logger, Level;
27 import 'package:path/path.dart' as path; 27 import 'package:path/path.dart' as path;
28 28
29 import 'info.dart'; 29 import 'info.dart';
30 import 'options.dart'; 30 import 'options.dart';
31 import 'report.dart'; 31 import 'report.dart';
32 32
33 /// Holds references to all source nodes in the import graph. This is mainly 33 /// Holds references to all source nodes in the import graph. This is mainly
34 /// used as a level of indirection to ensure that each source has a canonical 34 /// used as a level of indirection to ensure that each source has a canonical
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 @override 160 @override
161 Iterable<SourceNode> get allDeps => 161 Iterable<SourceNode> get allDeps =>
162 [scripts, resources, runtimeDeps].expand((e) => e); 162 [scripts, resources, runtimeDeps].expand((e) => e);
163 163
164 @override 164 @override
165 Iterable<SourceNode> get depsWithoutParts => allDeps; 165 Iterable<SourceNode> get depsWithoutParts => allDeps;
166 166
167 /// Parsed document, updated whenever [update] is invoked. 167 /// Parsed document, updated whenever [update] is invoked.
168 Document document; 168 Document document;
169 169
170 /// Tracks resource files referenced from HTML nodes, e.g.
171 /// `<link rel=stylesheet href=...>` and `<img src=...>`
172 final htmlResourceNodes = new HashMap<Element, ResourceSourceNode>();
173
170 HtmlSourceNode(SourceGraph graph, Uri uri, Source source) 174 HtmlSourceNode(SourceGraph graph, Uri uri, Source source)
171 : runtimeDeps = graph.runtimeDeps, 175 : runtimeDeps = graph.runtimeDeps,
172 super(graph, uri, source); 176 super(graph, uri, source);
173 177
174 @override 178 @override
175 void update() { 179 void update() {
176 super.update(); 180 super.update();
177 if (needsRebuild) { 181 if (needsRebuild) {
178 graph._reporter.clearHtml(uri); 182 graph._reporter.clearHtml(uri);
179 document = html.parse(contents, generateSpans: true); 183 document = html.parse(contents, generateSpans: true);
(...skipping 12 matching lines...) Expand all
192 _reportError(graph, 'Script file $src not found', script); 196 _reportError(graph, 'Script file $src not found', script);
193 } 197 }
194 if (node != null) newScripts.add(node); 198 if (node != null) newScripts.add(node);
195 } 199 }
196 200
197 if (!_same(newScripts, scripts)) { 201 if (!_same(newScripts, scripts)) {
198 structureChanged = true; 202 structureChanged = true;
199 scripts = newScripts; 203 scripts = newScripts;
200 } 204 }
201 205
206 // TODO(jmesserly): simplify the design here. Ideally we wouldn't need
207 // to track user-defined CSS, images, etc. Also we don't have a clear
208 // way to distinguish runtime injected resources, like messages.css, from
209 // user-defined files.
210 htmlResourceNodes.clear();
202 var newResources = new Set<SourceNode>(); 211 var newResources = new Set<SourceNode>();
203 for (var resource in graph.resources) { 212 for (var resource in graph.resources) {
204 newResources.add(graph.nodeFromUri(uri.resolve(resource))); 213 newResources.add(graph.nodeFromUri(uri.resolve(resource)));
205 } 214 }
206 for (var tag in document.querySelectorAll('link[rel="stylesheet"]')) { 215 for (var tag in document.querySelectorAll('link[rel="stylesheet"]')) {
207 newResources 216 var res = graph.nodeFromUri(uri.resolve(tag.attributes['href']));
208 .add(graph.nodeFromUri(uri.resolve(tag.attributes['href']))); 217 htmlResourceNodes[tag] = res;
218 newResources.add(res);
209 } 219 }
210 for (var tag in document.querySelectorAll('img')) { 220 for (var tag in document.querySelectorAll('img[src]')) {
211 newResources.add(graph.nodeFromUri(uri.resolve(tag.attributes['src']))); 221 var res = graph.nodeFromUri(uri.resolve(tag.attributes['src']));
222 htmlResourceNodes[tag] = res;
223 newResources.add(res);
212 } 224 }
213 if (!_same(newResources, resources)) { 225 if (!_same(newResources, resources)) {
214 structureChanged = true; 226 structureChanged = true;
215 resources = newResources; 227 resources = newResources;
216 } 228 }
217 } 229 }
218 } 230 }
219 231
220 void _reportError(SourceGraph graph, String message, Node node) { 232 void _reportError(SourceGraph graph, String message, Node node) {
221 graph._reporter.enterHtml(_source.uri); 233 graph._reporter.enterHtml(_source.uri);
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
516 'dart._interceptors', 528 'dart._interceptors',
517 'dart._native_typed_data', 529 'dart._native_typed_data',
518 */ 530 */
519 ]; 531 ];
520 532
521 /// Runtime files added to applications when running in server mode. 533 /// Runtime files added to applications when running in server mode.
522 final runtimeFilesForServerMode = new List<String>.from(defaultRuntimeFiles) 534 final runtimeFilesForServerMode = new List<String>.from(defaultRuntimeFiles)
523 ..addAll(const ['messages_widget.js', 'messages.css']); 535 ..addAll(const ['messages_widget.js', 'messages.css']);
524 536
525 final _log = new Logger('dev_compiler.dependency_graph'); 537 final _log = new Logger('dev_compiler.dependency_graph');
OLDNEW
« no previous file with comments | « lib/src/codegen/html_codegen.dart ('k') | test/codegen/expect/sunflower/sunflower.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698