blob: a1692d260b85ec0bd9d940d287a0f807cdc1c8b2 [file] [log] [blame]
// 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.
library web_components.build.import_inliner;
import 'dart:async';
import 'package:html5lib/dom.dart' show Document, Element, Node;
abstract class ImportReader {
Future<Document> readImport(Element import);
}
class ImportInliner {
final ImportReader _importReader;
ImportInliner(this._importReader);
// TODO(jakemac): Dedupe imports based on location
// TODO(jakemac): Normalize paths in attributes when inlining
Future<Document> inlineImports(Document document,
[Element importsWrapper, bool inPlace = true]) {
if (importsWrapper == null) {
importsWrapper = new Element.html('<div style="display:none;"></div>');
}
// Copy document if not editing in place.
if (!inPlace) document = document.clone(true);
var imports = document.querySelectorAll('link[rel="import"]');
var done = Future.wait(imports.map(
(import) => _inlineImport(document, importsWrapper, import)));
return done.then((_) {
// Insert the importsWrapper element at top of body if we had any imports.
if (importsWrapper.hasChildNodes()) {
document.body.insertBefore(importsWrapper, document.body.firstChild);
}
return document;
});
}
Future _inlineImport(Document document, Element importsWrapper,
Element import) {
return _importReader.readImport(import).then((importedDocument) {
// Create copies of the imports we find, don't modify them in place.
return inlineImports(importedDocument, importsWrapper, false).then((_) {
for (var node in importedDocument.body.nodes) {
importsWrapper.append(node.clone(true));
}
import.remove();
});
});
}
}