From 757eae8ad31b03903e4f3c05d1cedfdf41d2ec4b Mon Sep 17 00:00:00 2001 From: Yegor Jbanov Date: Fri, 27 Feb 2015 14:50:06 -0800 Subject: [PATCH] feat(compiler): DOM adapters + html5lib implementation; misc fixes --- gulpfile.js | 16 +- modules/angular2/e2e_test/test_util.es6 | 4 +- modules/angular2/pubspec.yaml | 1 + modules/angular2/src/core/application.js | 4 +- .../angular2/src/core/compiler/compiler.js | 3 +- .../core/compiler/pipeline/compile_element.js | 8 +- .../compiler/pipeline/compile_pipeline.js | 4 +- .../compiler/pipeline/directive_parser.js | 2 +- .../pipeline/element_binder_builder.js | 31 ++- .../pipeline/element_binding_marker.js | 2 +- .../src/core/compiler/pipeline/resolve_css.js | 2 +- .../pipeline/text_interpolation_parser.js | 2 +- .../core/compiler/pipeline/view_splitter.js | 6 +- .../shadow_dom_emulation/content_tag.js | 38 +-- .../shadow_dom_emulation/light_dom.js | 10 +- .../shadow_dom_emulation/shadow_css.js | 18 +- .../src/core/compiler/shadow_dom_strategy.js | 38 +-- .../src/core/compiler/template_loader.js | 2 +- .../src/core/compiler/url_resolver.js | 4 +- modules/angular2/src/core/compiler/view.js | 18 +- .../src/core/compiler/view_container.js | 8 +- modules/angular2/src/core/dom/element.js | 6 +- .../angular2/src/core/events/event_manager.js | 8 +- .../src/core/events/hammer_gestures.dart | 1 - .../src/core/events/hammer_gestures.es6 | 3 +- modules/angular2/src/dom/browser_adapter.dart | 194 ++++++++++++++ modules/angular2/src/dom/browser_adapter.es6 | 247 +++++++++++++++++ modules/angular2/src/dom/dom_adapter.js | 231 ++++++++++++++++ .../angular2/src/dom/html5lib_adapter.dart | 229 ++++++++++++++++ modules/angular2/src/facade/browser.dart | 21 ++ modules/angular2/src/facade/browser.es6 | 10 + modules/angular2/src/facade/collection.dart | 2 +- modules/angular2/src/facade/dom.dart | 210 --------------- modules/angular2/src/facade/dom.es6 | 250 ------------------ modules/angular2/src/forms/directives.js | 2 +- .../angular2/src/test_lib/benchmark_util.js | 5 +- modules/angular2/src/test_lib/test_lib.dart | 36 ++- modules/angular2/src/test_lib/test_lib.es6 | 7 +- modules/angular2/src/test_lib/utils.js | 2 +- .../change_detection/change_detection_spec.js | 1 - .../change_detection/parser/lexer_spec.js | 1 - .../angular2/test/core/application_spec.js | 2 +- .../core/compiler/compiler_browser_spec.js | 9 + ...piler_spec.js => compiler_common_tests.js} | 4 +- .../compiler_html5lib.server.spec.dart | 9 + .../test/core/compiler/integration_spec.js | 2 +- .../pipeline/element_binder_builder_spec.js | 2 +- .../pipeline/element_binding_marker_spec.js | 2 +- .../core/compiler/pipeline/pipeline_spec.js | 2 +- .../proto_element_injector_builder_spec.js | 12 +- .../compiler/pipeline/resolve_css_spec.js | 2 +- .../compiler/pipeline/shim_shadow_dom_spec.js | 6 +- .../compiler/pipeline/view_splitter_spec.js | 2 +- .../compiler/shadow_dom/content_tag_spec.js | 2 +- .../compiler/shadow_dom/light_dom_spec.js | 2 +- .../shadow_dom_emulation_integration_spec.js | 5 +- .../core/compiler/shadow_dom_strategy_spec.js | 2 +- .../core/compiler/template_loader_spec.js | 3 - .../test/core/compiler/view_container_spec.js | 4 +- .../angular2/test/core/compiler/view_spec.js | 2 +- .../test/core/events/event_manager_spec.js | 5 +- modules/angular2/test/di/key_spec.js | 1 - .../angular2/test/directives/foreach_spec.js | 2 +- modules/angular2/test/directives/if_spec.js | 2 +- .../test/directives/non_bindable_spec.js | 2 +- .../angular2/test/directives/switch_spec.js | 2 +- .../dom/html5lib_adapter.server.spec.dart | 20 ++ .../change_detection_benchmark.js | 2 + .../src/compiler/compiler_benchmark.js | 5 +- .../src/compiler/selector_benchmark.js | 2 + modules/benchmarks/src/di/di_benchmark.js | 2 + .../element_injector_benchmark.js | 2 + .../src/naive_infinite_scroll/app.js | 5 +- .../src/naive_infinite_scroll/index.js | 2 +- .../src/naive_infinite_scroll/scroll_area.js | 2 +- .../src/naive_infinite_scroll/scroll_item.js | 2 +- modules/benchmarks/src/tree/tree_benchmark.js | 13 +- test-main.dart | 2 + test-main.js | 32 ++- 79 files changed, 1223 insertions(+), 643 deletions(-) create mode 100644 modules/angular2/src/dom/browser_adapter.dart create mode 100644 modules/angular2/src/dom/browser_adapter.es6 create mode 100644 modules/angular2/src/dom/dom_adapter.js create mode 100644 modules/angular2/src/dom/html5lib_adapter.dart create mode 100644 modules/angular2/src/facade/browser.dart create mode 100644 modules/angular2/src/facade/browser.es6 delete mode 100644 modules/angular2/src/facade/dom.dart delete mode 100644 modules/angular2/src/facade/dom.es6 create mode 100644 modules/angular2/test/core/compiler/compiler_browser_spec.js rename modules/angular2/test/core/compiler/{compiler_spec.js => compiler_common_tests.js} (99%) create mode 100644 modules/angular2/test/core/compiler/compiler_html5lib.server.spec.dart create mode 100644 modules/angular2/test/dom/html5lib_adapter.server.spec.dart diff --git a/gulpfile.js b/gulpfile.js index a905633e82..157ac1e687 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -618,19 +618,31 @@ gulp.task('tests/transform.dart', function() { .pipe(gulp.dest('dist/dart/angular2/test/transform')); }); + + // ----------------- // orchestrated targets -gulp.task('build.dart', function(done) { + +// Builds all Dart packages, but does not compile them +gulp.task('build/packages.dart', function(done) { runSequence( ['build/transpile.dart', 'build/html.dart', 'build/copy.dart', 'build/multicopy.dart'], 'tests/transform.dart', 'build/format.dart', 'build/pubspec.dart', + done + ); +}); + +// Builds and compiles all Dart packages +gulp.task('build.dart', function(done) { + runSequence( + 'build/packages.dart', + 'build/analyze.dart', 'build/pubbuild.dart', // Note: pubbuild.dart will clear the dart2js folder, so we need to copy // our files after this :-( 'build/multicopy.js.dart2js', - 'build/analyze.dart', done ); }); diff --git a/modules/angular2/e2e_test/test_util.es6 b/modules/angular2/e2e_test/test_util.es6 index 75fb1eecae..ee463e0129 100644 --- a/modules/angular2/e2e_test/test_util.es6 +++ b/modules/angular2/e2e_test/test_util.es6 @@ -17,12 +17,10 @@ function verifyNoBrowserErrors() { browser.executeScript('1+1'); browser.manage().logs().get('browser').then(function(browserLog) { var filteredLog = browserLog.filter(function(logEntry) { + console.log('>> ' + require('util').inspect(logEntry)); return logEntry.level.value > webdriver.logging.Level.WARNING.value; }); expect(filteredLog.length).toEqual(0); - if (filteredLog.length) { - console.log('browser console errors: ' + require('util').inspect(filteredLog)); - } }); } diff --git a/modules/angular2/pubspec.yaml b/modules/angular2/pubspec.yaml index cc1f540a65..661597cd75 100644 --- a/modules/angular2/pubspec.yaml +++ b/modules/angular2/pubspec.yaml @@ -13,6 +13,7 @@ dependencies: barback: '^0.15.2+2' code_transformers: '^0.2.5' dart_style: '^0.1.3' + html5lib: '^0.12.0' stack_trace: '^1.1.1' dev_dependencies: guinness: "^0.1.16" diff --git a/modules/angular2/src/core/application.js b/modules/angular2/src/core/application.js index 1b3ad43e04..49467422f4 100644 --- a/modules/angular2/src/core/application.js +++ b/modules/angular2/src/core/application.js @@ -1,6 +1,7 @@ import {Injector, bind, OpaqueToken} from 'angular2/di'; import {Type, FIELD, isBlank, isPresent, BaseException, assertionsEnabled, print} from 'angular2/src/facade/lang'; -import {DOM, Element} from 'angular2/src/facade/dom'; +import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Compiler, CompilerCache} from './compiler/compiler'; import {ProtoView} from './compiler/view'; import {Reflector, reflector} from 'angular2/src/reflection/reflection'; @@ -117,6 +118,7 @@ function _createVmZone(givenReporter:Function): VmTurnZone { // Multiple calls to this method are allowed. Each application would only share // _rootInjector, which is not user-configurable by design, thus safe to share. export function bootstrap(appComponentType: Type, bindings: List=null, givenBootstrapErrorReporter: Function=null): Promise { + BrowserDomAdapter.makeCurrent(); var bootstrapProcess = PromiseWrapper.completer(); var zone = _createVmZone(givenBootstrapErrorReporter); diff --git a/modules/angular2/src/core/compiler/compiler.js b/modules/angular2/src/core/compiler/compiler.js index d9f3361239..09a046f6c7 100644 --- a/modules/angular2/src/core/compiler/compiler.js +++ b/modules/angular2/src/core/compiler/compiler.js @@ -1,7 +1,6 @@ import {Type, isBlank, isPresent, BaseException, normalizeBlank, stringify} from 'angular2/src/facade/lang'; import {Promise, PromiseWrapper} from 'angular2/src/facade/async'; import {List, ListWrapper, Map, MapWrapper} from 'angular2/src/facade/collection'; -import {DOM, Element} from 'angular2/src/facade/dom'; import {ChangeDetection, Parser} from 'angular2/change_detection'; @@ -149,7 +148,7 @@ export class Compiler { } // TODO(vicb): union type return ProtoView or Promise - _compileTemplate(template: Template, tplElement: Element, component: Type) { + _compileTemplate(template: Template, tplElement, component: Type) { var pipeline = new CompilePipeline(this.createSteps(component, template)); var compilationCtxtDescription = stringify(this._reader.read(component).type); var compileElements; diff --git a/modules/angular2/src/core/compiler/pipeline/compile_element.js b/modules/angular2/src/core/compiler/pipeline/compile_element.js index 1939b192fd..fd3adfb814 100644 --- a/modules/angular2/src/core/compiler/pipeline/compile_element.js +++ b/modules/angular2/src/core/compiler/pipeline/compile_element.js @@ -1,5 +1,5 @@ import {List, Map, ListWrapper, MapWrapper} from 'angular2/src/facade/collection'; -import {Element, DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {int, isBlank, isPresent, Type, StringJoiner, assertionsEnabled} from 'angular2/src/facade/lang'; import {DirectiveMetadata} from '../directive_metadata'; import {Decorator, Component, Viewport} from '../../annotations/annotations'; @@ -15,7 +15,7 @@ import {AST} from 'angular2/change_detection'; * by the CompileSteps starting out with the pure HTMLElement. */ export class CompileElement { - element:Element; + element; _attrs:Map; _classList:List; textNodeBindings:Map; @@ -40,7 +40,7 @@ export class CompileElement { ignoreBindings: boolean; elementDescription: string; // e.g. '
' : used to provide context in case of error - constructor(element:Element, compilationUnit = '') { + constructor(element, compilationUnit = '') { this.element = element; this._attrs = null; this._classList = null; @@ -177,7 +177,7 @@ export class CompileElement { // return an HTML representation of an element start tag - without its content // this is used to give contextual information in case of errors -function getElementDescription(domElement:Element):string { +function getElementDescription(domElement):string { var buf = new StringJoiner(); var atts = DOM.attributeMap(domElement); diff --git a/modules/angular2/src/core/compiler/pipeline/compile_pipeline.js b/modules/angular2/src/core/compiler/pipeline/compile_pipeline.js index bbe0442336..377643c492 100644 --- a/modules/angular2/src/core/compiler/pipeline/compile_pipeline.js +++ b/modules/angular2/src/core/compiler/pipeline/compile_pipeline.js @@ -1,6 +1,6 @@ import {isPresent} from 'angular2/src/facade/lang'; import {List, ListWrapper} from 'angular2/src/facade/collection'; -import {Element, DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {CompileElement} from './compile_element'; import {CompileControl} from './compile_control'; import {CompileStep} from './compile_step'; @@ -15,7 +15,7 @@ export class CompilePipeline { this._control = new CompileControl(steps); } - process(rootElement:Element, compilationCtxtDescription:string = ''):List { + process(rootElement, compilationCtxtDescription:string = ''):List { var results = ListWrapper.create(); this._process(results, null, new CompileElement(rootElement, compilationCtxtDescription), compilationCtxtDescription); return results; diff --git a/modules/angular2/src/core/compiler/pipeline/directive_parser.js b/modules/angular2/src/core/compiler/pipeline/directive_parser.js index f27c9c650b..cf093dee1d 100644 --- a/modules/angular2/src/core/compiler/pipeline/directive_parser.js +++ b/modules/angular2/src/core/compiler/pipeline/directive_parser.js @@ -1,6 +1,6 @@ import {isPresent, isBlank, BaseException, assertionsEnabled, RegExpWrapper} from 'angular2/src/facade/lang'; import {List, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {SelectorMatcher} from '../selector'; import {CssSelector} from '../selector'; diff --git a/modules/angular2/src/core/compiler/pipeline/element_binder_builder.js b/modules/angular2/src/core/compiler/pipeline/element_binder_builder.js index ab8c815c67..1cc496c058 100644 --- a/modules/angular2/src/core/compiler/pipeline/element_binder_builder.js +++ b/modules/angular2/src/core/compiler/pipeline/element_binder_builder.js @@ -1,5 +1,5 @@ import {int, isPresent, isBlank, Type, BaseException, StringWrapper, RegExpWrapper, isString, stringify} from 'angular2/src/facade/lang'; -import {Element, DOM, attrToPropMap} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {ListWrapper, List, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection'; import {reflector} from 'angular2/src/reflection/reflection'; @@ -21,7 +21,7 @@ function ariaSetterFactory(attrName:string) { var setterFn = StringMapWrapper.get(ariaSettersCache, attrName); if (isBlank(setterFn)) { - setterFn = function(element:Element, value) { + setterFn = function(element, value) { if (isPresent(value)) { DOM.setAttribute(element, attrName, stringify(value)); } else { @@ -42,7 +42,7 @@ function classSetterFactory(className:string) { var setterFn = StringMapWrapper.get(classSettersCache, className); if (isBlank(setterFn)) { - setterFn = function(element:Element, value) { + setterFn = function(element, value) { if (value) { DOM.addClass(element, className); } else { @@ -64,7 +64,7 @@ function styleSetterFactory(styleName:string, stylesuffix:string) { var setterFn = StringMapWrapper.get(styleSettersCache, cacheKey); if (isBlank(setterFn)) { - setterFn = function(element:Element, value) { + setterFn = function(element, value) { var valAsStr; if (isPresent(value)) { valAsStr = stringify(value); @@ -80,7 +80,7 @@ function styleSetterFactory(styleName:string, stylesuffix:string) { } const ROLE_ATTR = 'role'; -function roleSetter(element:Element, value) { +function roleSetter(element, value) { if (isString(value)) { DOM.setAttribute(element, ROLE_ATTR, value); } else { @@ -92,18 +92,25 @@ function roleSetter(element:Element, value) { } // special mapping for cases where attribute name doesn't match property name -var attrToProp = StringMapWrapper.merge({ - "inner-html": "innerHTML", - "readonly": "readOnly", - "tabindex": "tabIndex", -}, attrToPropMap); +var _lazyAttrToProp; + +function attrToProp() { + if (!isPresent(_lazyAttrToProp)) { + _lazyAttrToProp = StringMapWrapper.merge({ + "inner-html": "innerHTML", + "readonly": "readOnly", + "tabindex": "tabIndex", + }, DOM.attrToPropMap); + } + return _lazyAttrToProp; +} // tells if an attribute is handled by the ElementBinderBuilder step export function isSpecialProperty(propName:string) { return StringWrapper.startsWith(propName, ARIA_PREFIX) || StringWrapper.startsWith(propName, CLASS_PREFIX) || StringWrapper.startsWith(propName, STYLE_PREFIX) - || StringMapWrapper.contains(attrToProp, propName); + || StringMapWrapper.contains(attrToProp(), propName); } /** @@ -250,7 +257,7 @@ export class ElementBinderBuilder extends CompileStep { } _resolvePropertyName(attrName:string) { - var mappedPropName = StringMapWrapper.get(attrToProp, attrName); + var mappedPropName = StringMapWrapper.get(attrToProp(), attrName); return isPresent(mappedPropName) ? mappedPropName : attrName; } } diff --git a/modules/angular2/src/core/compiler/pipeline/element_binding_marker.js b/modules/angular2/src/core/compiler/pipeline/element_binding_marker.js index cca926faca..8cf51bd4d4 100644 --- a/modules/angular2/src/core/compiler/pipeline/element_binding_marker.js +++ b/modules/angular2/src/core/compiler/pipeline/element_binding_marker.js @@ -1,6 +1,6 @@ import {isPresent} from 'angular2/src/facade/lang'; import {MapWrapper} from 'angular2/src/facade/collection'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {CompileStep} from './compile_step'; import {CompileElement} from './compile_element'; diff --git a/modules/angular2/src/core/compiler/pipeline/resolve_css.js b/modules/angular2/src/core/compiler/pipeline/resolve_css.js index 7daa7f718f..544166c0c9 100644 --- a/modules/angular2/src/core/compiler/pipeline/resolve_css.js +++ b/modules/angular2/src/core/compiler/pipeline/resolve_css.js @@ -5,7 +5,7 @@ import {CompileControl} from './compile_control'; import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata'; import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Type} from 'angular2/src/facade/lang'; import {PromiseWrapper} from 'angular2/src/facade/async'; import {ListWrapper} from 'angular2/src/facade/collection'; diff --git a/modules/angular2/src/core/compiler/pipeline/text_interpolation_parser.js b/modules/angular2/src/core/compiler/pipeline/text_interpolation_parser.js index 9d2f6a0ba4..a3283bbfe5 100644 --- a/modules/angular2/src/core/compiler/pipeline/text_interpolation_parser.js +++ b/modules/angular2/src/core/compiler/pipeline/text_interpolation_parser.js @@ -1,5 +1,5 @@ import {RegExpWrapper, StringWrapper, isPresent} from 'angular2/src/facade/lang'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Parser} from 'angular2/change_detection'; diff --git a/modules/angular2/src/core/compiler/pipeline/view_splitter.js b/modules/angular2/src/core/compiler/pipeline/view_splitter.js index bd0e5054db..68d7a273f4 100644 --- a/modules/angular2/src/core/compiler/pipeline/view_splitter.js +++ b/modules/angular2/src/core/compiler/pipeline/view_splitter.js @@ -1,5 +1,5 @@ import {isBlank, isPresent, BaseException} from 'angular2/src/facade/lang'; -import {DOM, TemplateElement} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {MapWrapper, ListWrapper} from 'angular2/src/facade/collection'; import {Parser} from 'angular2/change_detection'; @@ -64,8 +64,8 @@ export class ViewSplitter extends CompileStep { if (DOM.isTemplateElement(current.element)) { if (!current.isViewRoot) { var viewRoot = new CompileElement(DOM.createTemplate('')); - var currentElement:TemplateElement = current.element; - var viewRootElement:TemplateElement = viewRoot.element; + var currentElement = current.element; + var viewRootElement = viewRoot.element; this._moveChildNodes(DOM.content(currentElement), DOM.content(viewRootElement)); // viewRoot doesn't appear in the original template, so we associate // the current element description to get a more meaningful message in case of error diff --git a/modules/angular2/src/core/compiler/shadow_dom_emulation/content_tag.js b/modules/angular2/src/core/compiler/shadow_dom_emulation/content_tag.js index 1f712624eb..62b9f44a05 100644 --- a/modules/angular2/src/core/compiler/shadow_dom_emulation/content_tag.js +++ b/modules/angular2/src/core/compiler/shadow_dom_emulation/content_tag.js @@ -1,16 +1,14 @@ import {Decorator} from '../../annotations/annotations'; import {SourceLightDom, DestinationLightDom, LightDom} from './light_dom'; import {Inject} from 'angular2/di'; -import {Element, Node, DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {isPresent} from 'angular2/src/facade/lang'; import {List, ListWrapper} from 'angular2/src/facade/collection'; import {NgElement} from 'angular2/src/core/dom/element'; -var _scriptTemplate = DOM.createScriptTag('type', 'ng/content') - class ContentStrategy { - nodes: List; - insert(nodes:List){} + nodes:List; + insert(nodes:List){} } /** @@ -19,34 +17,42 @@ class ContentStrategy { * and thus does not affect redistribution. */ class RenderedContent extends ContentStrategy { - beginScript:Element; - endScript:Element; + static _lazyScriptTemplate; + beginScript; + endScript; - constructor(contentEl:Element) { + constructor(contentEl) { super(); this._replaceContentElementWithScriptTags(contentEl); this.nodes = []; } + _scriptTemplate() { + if (!isPresent(RenderedContent._lazyScriptTemplate)) { + RenderedContent._lazyScriptTemplate = DOM.createScriptTag('type', 'ng/content'); + } + return RenderedContent._lazyScriptTemplate; + } + // Inserts the nodes in between the start and end scripts. // Previous content is removed. - insert(nodes:List) { + insert(nodes:List) { this.nodes = nodes; DOM.insertAllBefore(this.endScript, nodes); this._removeNodesUntil(ListWrapper.isEmpty(nodes) ? this.endScript : nodes[0]); } // Replaces the content tag with a pair of script tags - _replaceContentElementWithScriptTags(contentEl:Element) { - this.beginScript = DOM.clone(_scriptTemplate); - this.endScript = DOM.clone(_scriptTemplate); + _replaceContentElementWithScriptTags(contentEl) { + this.beginScript = DOM.clone(this._scriptTemplate()); + this.endScript = DOM.clone(this._scriptTemplate()); DOM.insertBefore(contentEl, this.beginScript); DOM.insertBefore(contentEl, this.endScript); DOM.removeChild(DOM.parentElement(contentEl), contentEl); } - _removeNodesUntil(node:Node) { + _removeNodesUntil(node) { var p = DOM.parentElement(this.beginScript); for (var next = DOM.nextSibling(this.beginScript); next !== node; @@ -70,7 +76,7 @@ class IntermediateContent extends ContentStrategy { this.nodes = []; } - insert(nodes:List) { + insert(nodes:List) { this.nodes = nodes; this.destinationLightDom.redistribute(); } @@ -91,11 +97,11 @@ export class Content { new RenderedContent(contentEl.domElement); } - nodes():List { + nodes():List { return this._strategy.nodes; } - insert(nodes:List) { + insert(nodes:List) { this._strategy.insert(nodes); } } diff --git a/modules/angular2/src/core/compiler/shadow_dom_emulation/light_dom.js b/modules/angular2/src/core/compiler/shadow_dom_emulation/light_dom.js index 9de9d0157e..6d07233a33 100644 --- a/modules/angular2/src/core/compiler/shadow_dom_emulation/light_dom.js +++ b/modules/angular2/src/core/compiler/shadow_dom_emulation/light_dom.js @@ -1,4 +1,4 @@ -import {Element, Node, DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {List, ListWrapper} from 'angular2/src/facade/collection'; import {isBlank, isPresent} from 'angular2/src/facade/lang'; @@ -12,7 +12,7 @@ export class DestinationLightDom {} class _Root { - node:Node; + node; injector:ElementInjector; constructor(node, injector) { @@ -29,10 +29,10 @@ export class LightDom { // The shadow DOM shadowDomView:View; // The nodes of the light DOM - nodes:List; + nodes:List; roots:List<_Root>; - constructor(lightDomView:View, shadowDomView:View, element:Element) { + constructor(lightDomView:View, shadowDomView:View, element) { this.lightDomView = lightDomView; this.shadowDomView = shadowDomView; this.nodes = DOM.childNodesAsList(element); @@ -113,7 +113,7 @@ export class LightDom { } // Projects the light DOM into the shadow DOM -function redistributeNodes(contents:List, nodes:List) { +function redistributeNodes(contents:List, nodes:List) { for (var i = 0; i < contents.length; ++i) { var content = contents[i]; var select = content.select; diff --git a/modules/angular2/src/core/compiler/shadow_dom_emulation/shadow_css.js b/modules/angular2/src/core/compiler/shadow_dom_emulation/shadow_css.js index 57f18fe5a1..64ed04e690 100644 --- a/modules/angular2/src/core/compiler/shadow_dom_emulation/shadow_css.js +++ b/modules/angular2/src/core/compiler/shadow_dom_emulation/shadow_css.js @@ -1,10 +1,4 @@ -import { - StyleElement, - DOM, - CssRule, - CssKeyframesRule, - CSSRuleWrapper -} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {List, ListWrapper} from 'angular2/src/facade/collection'; import { StringWrapper, @@ -153,7 +147,7 @@ export class ShadowCss { * Shim a style element with the given selector. Returns cssText that can * be included in the document via WebComponents.ShadowCSS.addCssToDocument(css). */ - shimStyle(style: StyleElement, selector: string, hostSelector: string = ''): string { + shimStyle(style, selector: string, hostSelector: string = ''): string { var cssText = DOM.getText(style); return this.shimCssText(cssText, selector, hostSelector); } @@ -353,11 +347,11 @@ export class ShadowCss { if (isPresent(cssRules)) { for (var i = 0; i < cssRules.length; i++) { var rule = cssRules[i]; - if (CSSRuleWrapper.isStyleRule(rule) || CSSRuleWrapper.isPageRule(rule)) { + if (DOM.isStyleRule(rule) || DOM.isPageRule(rule)) { cssText += this._scopeSelector(rule.selectorText, scopeSelector, hostSelector, this.strictStyling) + ' {\n'; cssText += this._propertiesFromRule(rule) + '\n}\n\n'; - } else if (CSSRuleWrapper.isMediaRule(rule)) { + } else if (DOM.isMediaRule(rule)) { cssText += '@media ' + rule.media.mediaText + ' {\n'; cssText += this._scopeRules(rule.cssRules, scopeSelector, hostSelector); cssText += '\n}\n\n'; @@ -372,7 +366,7 @@ export class ShadowCss { cssText += rule.cssText + '\n\n'; } } catch(x) { - if (CSSRuleWrapper.isKeyframesRule(rule) && isPresent(rule.cssRules)) { + if (DOM.isKeyframesRule(rule) && isPresent(rule.cssRules)) { cssText += this._ieSafeCssTextFromKeyFrameRule(rule); } } @@ -382,7 +376,7 @@ export class ShadowCss { return cssText; } - _ieSafeCssTextFromKeyFrameRule(rule: CssKeyframesRule): string { + _ieSafeCssTextFromKeyFrameRule(rule): string { var cssText = '@keyframes ' + rule.name + ' {'; for (var i = 0; i < rule.cssRules.length; i++) { var r = rule.cssRules[i]; diff --git a/modules/angular2/src/core/compiler/shadow_dom_strategy.js b/modules/angular2/src/core/compiler/shadow_dom_strategy.js index 925e82b219..07bbb93de2 100644 --- a/modules/angular2/src/core/compiler/shadow_dom_strategy.js +++ b/modules/angular2/src/core/compiler/shadow_dom_strategy.js @@ -1,5 +1,5 @@ import {Type, isBlank, isPresent, int} from 'angular2/src/facade/lang'; -import {DOM, Element, StyleElement} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {List, ListWrapper, MapWrapper, Map} from 'angular2/src/facade/collection'; import {PromiseWrapper} from 'angular2/src/facade/async'; @@ -13,14 +13,14 @@ import {StyleInliner} from './style_inliner'; import {StyleUrlResolver} from './style_url_resolver'; export class ShadowDomStrategy { - attachTemplate(el:Element, view:View) {} - constructLightDom(lightDomView:View, shadowDomView:View, el:Element) {} + attachTemplate(el, view:View) {} + constructLightDom(lightDomView:View, shadowDomView:View, el) {} polyfillDirectives():List { return null; } // TODO(vicb): union types: return either a string or a Promise transformStyleText(cssText: string, baseUrl: string, component: Type) {} - handleStyleElement(styleEl: StyleElement) {}; - shimContentElement(component: Type, element: Element) {} - shimHostElement(component: Type, element: Element) {} + handleStyleElement(styleEl) {}; + shimContentElement(component: Type, element) {} + shimHostElement(component: Type, element) {} } /** @@ -34,21 +34,21 @@ export class ShadowDomStrategy { */ export class EmulatedUnscopedShadowDomStrategy extends ShadowDomStrategy { _styleUrlResolver: StyleUrlResolver; - _lastInsertedStyle: StyleElement; - _styleHost: Element; + _lastInsertedStyle; + _styleHost; - constructor(styleUrlResolver: StyleUrlResolver, styleHost: Element) { + constructor(styleUrlResolver: StyleUrlResolver, styleHost) { super(); this._styleUrlResolver = styleUrlResolver; this._styleHost = styleHost; } - attachTemplate(el:Element, view:View){ + attachTemplate(el, view:View){ DOM.clearNodes(el); _moveViewNodesIntoParent(el, view); } - constructLightDom(lightDomView:View, shadowDomView:View, el:Element){ + constructLightDom(lightDomView:View, shadowDomView:View, el) { return new LightDom(lightDomView, shadowDomView, el); } @@ -60,7 +60,7 @@ export class EmulatedUnscopedShadowDomStrategy extends ShadowDomStrategy { return this._styleUrlResolver.resolveUrls(cssText, baseUrl); } - handleStyleElement(styleEl: StyleElement) { + handleStyleElement(styleEl) { DOM.remove(styleEl); var cssText = DOM.getText(styleEl); @@ -73,7 +73,7 @@ export class EmulatedUnscopedShadowDomStrategy extends ShadowDomStrategy { } }; - _insertStyleElement(host: Element, style: StyleElement) { + _insertStyleElement(host, style) { if (isBlank(this._lastInsertedStyle)) { var firstChild = DOM.firstChild(host); if (isPresent(firstChild)) { @@ -103,7 +103,7 @@ export class EmulatedUnscopedShadowDomStrategy extends ShadowDomStrategy { export class EmulatedScopedShadowDomStrategy extends EmulatedUnscopedShadowDomStrategy { _styleInliner: StyleInliner; - constructor(styleInliner: StyleInliner, styleUrlResolver: StyleUrlResolver, styleHost: Element) { + constructor(styleInliner: StyleInliner, styleUrlResolver: StyleUrlResolver, styleHost) { super(styleUrlResolver, styleHost); this._styleInliner = styleInliner; } @@ -118,18 +118,18 @@ export class EmulatedScopedShadowDomStrategy extends EmulatedUnscopedShadowDomSt } } - handleStyleElement(styleEl: StyleElement) { + handleStyleElement(styleEl) { DOM.remove(styleEl); this._insertStyleElement(this._styleHost, styleEl); }; - shimContentElement(component: Type, element: Element) { + shimContentElement(component: Type, element) { var id = _getComponentId(component); var attrName = _getContentAttribute(id); DOM.setAttribute(element, attrName, ''); } - shimHostElement(component: Type, element: Element) { + shimHostElement(component: Type, element) { var id = _getComponentId(component); var attrName = _getHostAttribute(id); DOM.setAttribute(element, attrName, ''); @@ -150,11 +150,11 @@ export class NativeShadowDomStrategy extends ShadowDomStrategy { this._styleUrlResolver = styleUrlResolver; } - attachTemplate(el:Element, view:View){ + attachTemplate(el, view:View){ _moveViewNodesIntoParent(DOM.createShadowRoot(el), view); } - constructLightDom(lightDomView:View, shadowDomView:View, el:Element){ + constructLightDom(lightDomView:View, shadowDomView:View, el) { return null; } diff --git a/modules/angular2/src/core/compiler/template_loader.js b/modules/angular2/src/core/compiler/template_loader.js index 2c8417d275..bfcd0d895a 100644 --- a/modules/angular2/src/core/compiler/template_loader.js +++ b/modules/angular2/src/core/compiler/template_loader.js @@ -1,6 +1,6 @@ import {isBlank, isPresent, BaseException, stringify} from 'angular2/src/facade/lang'; -import {DOM, Element} from 'angular2/src/facade/dom'; import {Map, MapWrapper, StringMapWrapper, StringMap} from 'angular2/src/facade/collection'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {XHR} from './xhr/xhr'; diff --git a/modules/angular2/src/core/compiler/url_resolver.js b/modules/angular2/src/core/compiler/url_resolver.js index a9cc11a238..df1b67c5bc 100644 --- a/modules/angular2/src/core/compiler/url_resolver.js +++ b/modules/angular2/src/core/compiler/url_resolver.js @@ -1,8 +1,8 @@ import {isPresent, isBlank, RegExpWrapper, BaseException} from 'angular2/src/facade/lang'; -import {DOM, AnchorElement} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; export class UrlResolver { - static a: AnchorElement; + static a; constructor() { if (isBlank(UrlResolver.a)) { diff --git a/modules/angular2/src/core/compiler/view.js b/modules/angular2/src/core/compiler/view.js index fa4b13728e..ba61bf0279 100644 --- a/modules/angular2/src/core/compiler/view.js +++ b/modules/angular2/src/core/compiler/view.js @@ -1,4 +1,4 @@ -import {DOM, Element, Node, Text, DocumentFragment} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Promise} from 'angular2/src/facade/async'; import {ListWrapper, MapWrapper, StringMapWrapper, List} from 'angular2/src/facade/collection'; import {AST, ContextWithVariableBindings, ChangeDispatcher, ProtoChangeDetector, ChangeDetector, ChangeRecord} @@ -33,12 +33,12 @@ export class View { /// This list matches the _nodes list. It is sparse, since only Elements have ElementInjector rootElementInjectors:List; elementInjectors:List; - bindElements:List; - textNodes:List; + bindElements:List; + textNodes:List; changeDetector:ChangeDetector; /// When the view is part of render tree, the DocumentFragment is empty, which is why we need /// to keep track of the nodes. - nodes:List; + nodes:List; componentChildViews: List; viewContainers: List; preBuiltObjects: List; @@ -46,7 +46,7 @@ export class View { context: any; contextWithLocals:ContextWithVariableBindings; - constructor(proto:ProtoView, nodes:List, protoChangeDetector:ProtoChangeDetector, protoContextLocals:Map) { + constructor(proto:ProtoView, nodes:List, protoChangeDetector:ProtoChangeDetector, protoContextLocals:Map) { this.proto = proto; this.nodes = nodes; this.changeDetector = protoChangeDetector.instantiate(this); @@ -262,7 +262,7 @@ export class View { } export class ProtoView { - element:Element; + element; elementBinders:List; protoChangeDetector:ProtoChangeDetector; variableBindings: Map; @@ -277,7 +277,7 @@ export class ProtoView { stylePromises: List; constructor( - template:Element, + template, protoChangeDetector:ProtoChangeDetector, shadowDomStrategy: ShadowDomStrategy) { this.element = template; @@ -558,8 +558,8 @@ export class ElementBindingMemento { this._setter = setter; } - invoke(record:ChangeRecord, bindElements:List) { - var element:Element = bindElements[this._elementIndex]; + invoke(record:ChangeRecord, bindElements:List) { + var element = bindElements[this._elementIndex]; this._setter(element, record.currentValue); } } diff --git a/modules/angular2/src/core/compiler/view_container.js b/modules/angular2/src/core/compiler/view_container.js index 785f787e1a..ac9365c6f6 100644 --- a/modules/angular2/src/core/compiler/view_container.js +++ b/modules/angular2/src/core/compiler/view_container.js @@ -1,5 +1,5 @@ import * as viewModule from './view'; -import {DOM, Node, Element} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {ListWrapper, MapWrapper, List} from 'angular2/src/facade/collection'; import {BaseException} from 'angular2/src/facade/lang'; import {Injector} from 'angular2/di'; @@ -9,7 +9,7 @@ import {EventManager} from 'angular2/src/core/events/event_manager'; export class ViewContainer { parentView: viewModule.View; - templateElement: Element; + templateElement; defaultProtoView: viewModule.ProtoView; _views: List; _lightDom: any; @@ -18,7 +18,7 @@ export class ViewContainer { appInjector: Injector; hostElementInjector: eiModule.ElementInjector; - constructor(parentView: viewModule.View, templateElement: Element, defaultProtoView: viewModule.ProtoView, + constructor(parentView: viewModule.View, templateElement, defaultProtoView: viewModule.ProtoView, elementInjector: eiModule.ElementInjector, eventManager: EventManager, lightDom = null) { this.parentView = parentView; this.templateElement = templateElement; @@ -124,7 +124,7 @@ export class ViewContainer { return this._views; } - nodes():List { + nodes():List { var r = []; for (var i = 0; i < this._views.length; ++i) { r = ListWrapper.concat(r, this._views[i].nodes); diff --git a/modules/angular2/src/core/dom/element.js b/modules/angular2/src/core/dom/element.js index c5457d78fd..82d57bc8da 100644 --- a/modules/angular2/src/core/dom/element.js +++ b/modules/angular2/src/core/dom/element.js @@ -1,9 +1,9 @@ -import {DOM, Element} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {normalizeBlank} from 'angular2/src/facade/lang'; export class NgElement { - domElement:Element; - constructor(domElement:Element) { + domElement; + constructor(domElement) { this.domElement = domElement; } diff --git a/modules/angular2/src/core/events/event_manager.js b/modules/angular2/src/core/events/event_manager.js index 58fe234c05..78d5854c7b 100644 --- a/modules/angular2/src/core/events/event_manager.js +++ b/modules/angular2/src/core/events/event_manager.js @@ -1,5 +1,5 @@ import {isBlank, BaseException, isPresent, StringWrapper} from 'angular2/src/facade/lang'; -import {DOM, Element} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {List, ListWrapper, MapWrapper} from 'angular2/src/facade/collection'; import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone'; @@ -17,7 +17,7 @@ export class EventManager { } } - addEventListener(element: Element, eventName: string, handler: Function) { + addEventListener(element, eventName: string, handler: Function) { var shouldSupportBubble = eventName[0] == BUBBLE_SYMBOL; if (shouldSupportBubble) { eventName = StringWrapper.substring(eventName, 1); @@ -54,7 +54,7 @@ export class EventManagerPlugin { return false; } - addEventListener(element: Element, eventName: string, handler: Function, + addEventListener(element, eventName: string, handler: Function, shouldSupportBubble: boolean) { throw "not implemented"; } @@ -69,7 +69,7 @@ export class DomEventsPlugin extends EventManagerPlugin { return true; } - addEventListener(element: Element, eventName: string, handler: Function, + addEventListener(element, eventName: string, handler: Function, shouldSupportBubble: boolean) { var outsideHandler = shouldSupportBubble ? DomEventsPlugin.bubbleCallback(element, handler, this.manager._zone) : diff --git a/modules/angular2/src/core/events/hammer_gestures.dart b/modules/angular2/src/core/events/hammer_gestures.dart index 89c07e728c..edb2332b30 100644 --- a/modules/angular2/src/core/events/hammer_gestures.dart +++ b/modules/angular2/src/core/events/hammer_gestures.dart @@ -2,7 +2,6 @@ library angular.events; import 'dart:html'; import './hammer_common.dart'; -import '../../facade/dom.dart' show Element; import '../../facade/lang.dart' show BaseException; import 'dart:js' as js; diff --git a/modules/angular2/src/core/events/hammer_gestures.es6 b/modules/angular2/src/core/events/hammer_gestures.es6 index 87c6cc2a1a..b5baabcbc5 100644 --- a/modules/angular2/src/core/events/hammer_gestures.es6 +++ b/modules/angular2/src/core/events/hammer_gestures.es6 @@ -1,5 +1,4 @@ import {HammerGesturesPluginCommon} from './hammer_common'; -import {Element} from 'angular2/src/facade/dom'; import {isPresent, BaseException} from 'angular2/src/facade/lang'; export class HammerGesturesPlugin extends HammerGesturesPluginCommon { @@ -17,7 +16,7 @@ export class HammerGesturesPlugin extends HammerGesturesPluginCommon { return true; } - addEventListener(element:Element, eventName:string, handler:Function, shouldSupportBubble: boolean) { + addEventListener(element, eventName:string, handler:Function, shouldSupportBubble: boolean) { if (shouldSupportBubble) throw new BaseException('Hammer.js plugin does not support bubbling gestures.'); var zone = this.manager.getZone(); eventName = eventName.toLowerCase(); diff --git a/modules/angular2/src/dom/browser_adapter.dart b/modules/angular2/src/dom/browser_adapter.dart new file mode 100644 index 0000000000..aead6a1327 --- /dev/null +++ b/modules/angular2/src/dom/browser_adapter.dart @@ -0,0 +1,194 @@ +library angular.core.facade.dom; + +import 'dart:html'; +import 'dart:js' show JsObject; +import 'dom_adapter.dart' show setRootDomAdapter, DomAdapter; +import '../facade/browser.dart'; + +// WARNING: Do not expose outside this class. Parsing HTML using this +// sanitizer is a security risk. +class _IdentitySanitizer implements NodeTreeSanitizer { + void sanitizeTree(Node node) {} +} + +final _identitySanitizer = new _IdentitySanitizer(); + +class BrowserDomAdapter extends DomAdapter { + static void makeCurrent() { + setRootDomAdapter(new BrowserDomAdapter()); + } + + // override JS logic of attribute to property mapping + @override + final attrToPropMap = const { + "inner-html": "innerHtml" + }; + + query(String selector) => document.querySelector(selector); + + Element querySelector(el, String selector) => + el.querySelector(selector); + + ElementList querySelectorAll(el, String selector) => + el.querySelectorAll(selector); + + void on(EventTarget element, String event, callback(arg)) { + // due to https://code.google.com/p/dart/issues/detail?id=17406 + // addEventListener misses zones so we use element.on. + element.on[event].listen(callback); + } + void dispatchEvent(EventTarget el, Event evt) { + el.dispatchEvent(evt); + } + MouseEvent createMouseEvent(String eventType) => + new MouseEvent(eventType, canBubble: true); + createEvent(eventType) => + new Event(eventType, canBubble: true); + String getInnerHTML(Element el) => el.innerHtml; + String getOuterHTML(Element el) => el.outerHtml; + void setInnerHTML(Element el, String value) { + el.innerHtml = value; + } + String nodeName(Node el) => el.nodeName; + String nodeValue(Node el) => el.nodeValue; + String type(InputElement el) => el.type; + Node content(TemplateElement el) => el.content; + Node firstChild(el) => el.firstChild; + Node nextSibling(Node el) => el.nextNode; + Element parentElement(Node el) => el.parent; + List childNodes(Node el) => el.childNodes; + List childNodesAsList(Node el) => childNodes(el).toList(); + void clearNodes(Node el) { + el.nodes = const []; + } + void appendChild(Node el, Node node) { + el.append(node); + } + void removeChild(Element el, Node node) { + node.remove(); + } + Element remove(Element el) { + return el..remove(); + } + insertBefore(Node el, node) { + el.parentNode.insertBefore(node, el); + } + void insertAllBefore(Node el, Iterable nodes) { + el.parentNode.insertAllBefore(nodes, el); + } + void insertAfter(Node el, Node node) { + el.parentNode.insertBefore(node, el.nextNode); + } + String getText(Node el) => el.text; + void setText(Node el, String value) { + el.text = value; + } + String getValue(InputElement el) => el.value; + void setValue(InputElement el, String value) { + el.value = value; + } + bool getChecked(InputElement el) => el.checked; + void setChecked(InputElement el, bool isChecked) { + el.checked = isChecked; + } + TemplateElement createTemplate(String html) { + var t = new TemplateElement(); + // We do not sanitize because templates are part of the application code + // not user code. + t.setInnerHtml(html, treeSanitizer: _identitySanitizer); + return t; + } + Element createElement(String tagName, [HtmlDocument doc = null]) { + if (doc == null) doc = document; + return doc.createElement(tagName); + } + createTextNode(String text, [HtmlDocument doc = null]) { + return new Text(text); + } + createScriptTag(String attrName, String attrValue, + [HtmlDocument doc = null]) { + if (doc == null) doc = document; + var el = doc.createElement("SCRIPT"); + el.setAttribute(attrName, attrValue); + return el; + } + StyleElement createStyleElement(String css, [HtmlDocument doc = null]) { + if (doc == null) doc = document; + var el = doc.createElement("STYLE"); + el.text = css; + return el; + } + ShadowRoot createShadowRoot(Element el) => el.createShadowRoot(); + ShadowRoot getShadowRoot(Element el) => el.shadowRoot; + clone(Node node) => node.clone(true); + bool hasProperty(Element element, String name) => + new JsObject.fromBrowserObject(element).hasProperty(name); + List getElementsByClassName(Element element, String name) => + element.getElementsByClassName(name); + List getElementsByTagName(Element element, String name) => + element.querySelectorAll(name); + List classList(Element element) => element.classes.toList(); + void addClass(Element element, String classname) { + element.classes.add(classname); + } + void removeClass(Element element, String classname) { + element.classes.remove(classname); + } + bool hasClass(Element element, String classname) => + element.classes.contains(classname); + + setStyle(Element element, String stylename, String stylevalue) { + element.style.setProperty(stylename, stylevalue); + } + removeStyle(Element element, String stylename) { + element.style.removeProperty(stylename); + } + getStyle(Element element, String stylename) { + return element.style.getPropertyValue(stylename); + } + + String tagName(Element element) => element.tagName; + + Map attributeMap(Element element) => + element.attributes; + + String getAttribute(Element element, String attribute) => + element.getAttribute(attribute); + + void setAttribute(Element element, String name, String value) { + element.setAttribute(name, value); + } + + void removeAttribute(Element element, String name) { + //there is no removeAttribute method as of now in Dart: + //https://code.google.com/p/dart/issues/detail?id=19934 + element.attributes.remove(name); + } + + Node templateAwareRoot(Element el) => + el is TemplateElement ? el.content : el; + + HtmlDocument createHtmlDocument() => + document.implementation.createHtmlDocument('fakeTitle'); + + HtmlDocument defaultDoc() => document; + bool elementMatches(n, String selector) => + n is Element && n.matches(selector); + bool isTemplateElement(Element el) => + el is TemplateElement; + bool isTextNode(Node node) => + node.nodeType == Node.TEXT_NODE; + bool isCommentNode(Node node) => node.nodeType == Node.COMMENT_NODE; + bool isElementNode(Node node) => + node.nodeType == Node.ELEMENT_NODE; + bool hasShadowRoot(Node node) { + return node is Element && node.shadowRoot != null; + } + Node importIntoDoc(Node node) { + return document.importNode(node, true); + } + isPageRule(CssRule rule) => rule is CssPageRule; + isStyleRule(CssRule rule) => rule is CssStyleRule; + isMediaRule(CssRule rule) => rule is CssMediaRule; + isKeyframesRule(CssRule rule) => rule is CssKeyframesRule; +} diff --git a/modules/angular2/src/dom/browser_adapter.es6 b/modules/angular2/src/dom/browser_adapter.es6 new file mode 100644 index 0000000000..cc18096b11 --- /dev/null +++ b/modules/angular2/src/dom/browser_adapter.es6 @@ -0,0 +1,247 @@ +import {List, MapWrapper, ListWrapper} from 'angular2/src/facade/collection'; +import {isPresent} from 'angular2/src/facade/lang'; +import {DomAdapter, setRootDomAdapter} from './dom_adapter'; + +var EMPTY_MAP = MapWrapper.create(); + +export class BrowserDomAdapter extends DomAdapter { + static makeCurrent() { + setRootDomAdapter(new BrowserDomAdapter()); + } + + get attrToPropMap():Map { + return EMPTY_MAP + } + + query(selector) { + return document.querySelector(selector); + } + querySelector(el, selector:string):Node { + return el.querySelector(selector); + } + querySelectorAll(el, selector:string):NodeList { + return el.querySelectorAll(selector); + } + on(el, evt, listener) { + el.addEventListener(evt, listener, false); + } + dispatchEvent(el, evt) { + el.dispatchEvent(evt); + } + createMouseEvent(eventType) { + var evt = new MouseEvent(eventType); + evt.initEvent(eventType, true, true); + return evt; + } + createEvent(eventType) { + return new Event(eventType, true); + } + getInnerHTML(el) { + return el.innerHTML; + } + getOuterHTML(el) { + return el.outerHTML; + } + nodeName(node:Node):string { + return node.nodeName; + } + nodeValue(node:Node):string { + return node.nodeValue; + } + type(node:string) { + return node.type; + } + content(node:HTMLTemplateElement):Node { + return node.content; + } + firstChild(el):Node { + return el.firstChild; + } + nextSibling(el):Node { + return el.nextSibling; + } + parentElement(el) { + return el.parentElement; + } + childNodes(el):NodeList { + return el.childNodes; + } + childNodesAsList(el):List { + var childNodes = el.childNodes; + var res = ListWrapper.createFixedSize(childNodes.length); + for (var i=0; i { + el.parentNode.insertBefore(n, el); + }); + } + insertAfter(el, node) { + el.parentNode.insertBefore(node, el.nextSibling); + } + setInnerHTML(el, value) { + el.innerHTML = value; + } + getText(el) { + return el.textContent; + } + // TODO(vicb): removed Element type because it does not support StyleElement + setText(el, value:string) { + el.textContent = value; + } + getValue(el) { + return el.value; + } + setValue(el, value:string) { + el.value = value; + } + getChecked(el) { + return el.checked; + } + setChecked(el, value:boolean) { + el.checked = value; + } + createTemplate(html) { + var t = document.createElement('template'); + t.innerHTML = html; + return t; + } + createElement(tagName, doc=document) { + return doc.createElement(tagName); + } + createTextNode(text: string, doc=document) { + return doc.createTextNode(text); + } + createScriptTag(attrName:string, attrValue:string, doc=document) { + var el = doc.createElement("SCRIPT"); + el.setAttribute(attrName, attrValue); + return el; + } + createStyleElement(css:string, doc=document):HTMLStyleElement { + var style = doc.createElement('STYLE'); + style.innerText = css; + return style; + } + createShadowRoot(el:HTMLElement): ShadowRoot { + return el.createShadowRoot(); + } + getShadowRoot(el:HTMLElement): ShadowRoot { + return el.shadowRoot; + } + clone(node:Node) { + return node.cloneNode(true); + } + hasProperty(element, name:string) { + return name in element; + } + getElementsByClassName(element, name:string) { + return element.getElementsByClassName(name); + } + getElementsByTagName(element, name:string) { + return element.getElementsByTagName(name); + } + classList(element):List { + return Array.prototype.slice.call(element.classList, 0); + } + addClass(element, classname:string) { + element.classList.add(classname); + } + removeClass(element, classname:string) { + element.classList.remove(classname); + } + hasClass(element, classname:string) { + return element.classList.contains(classname); + } + setStyle(element, stylename:string, stylevalue:string) { + element.style[stylename] = stylevalue; + } + removeStyle(element, stylename:string) { + element.style[stylename] = null; + } + getStyle(element, stylename:string) { + return element.style[stylename]; + } + tagName(element):string { + return element.tagName; + } + attributeMap(element) { + var res = MapWrapper.create(); + var elAttrs = element.attributes; + for (var i = 0; i < elAttrs.length; i++) { + var attrib = elAttrs[i]; + MapWrapper.set(res, attrib.name, attrib.value); + } + return res; + } + getAttribute(element, attribute:string) { + return element.getAttribute(attribute); + } + setAttribute(element, name:string, value:string) { + element.setAttribute(name, value); + } + removeAttribute(element, attribute:string) { + return element.removeAttribute(attribute); + } + templateAwareRoot(el) { + return el instanceof HTMLTemplateElement ? el.content : el; + } + createHtmlDocument() { + return document.implementation.createHTMLDocument(); + } + defaultDoc() { + return document; + } + elementMatches(n, selector:string):boolean { + return n instanceof HTMLElement && n.matches(selector); + } + isTemplateElement(el:any):boolean { + return el instanceof HTMLTemplateElement; + } + isTextNode(node:Node):boolean { + return node.nodeType === Node.TEXT_NODE; + } + isCommentNode(node:Node):boolean { + return node.nodeType === Node.TEXT_NODE; + } + isElementNode(node:Node):boolean { + return node.nodeType === Node.ELEMENT_NODE; + } + hasShadowRoot(node):boolean { + return node instanceof HTMLElement && isPresent(node.shadowRoot); + } + importIntoDoc(node:Node) { + return document.importNode(node, true); + } + isPageRule(rule) { + return rule.type === CSSRule.PAGE_RULE; + } + isStyleRule(rule) { + return rule.type === CSSRule.STYLE_RULE; + } + isMediaRule(rule) { + return rule.type === CSSRule.MEDIA_RULE; + } + isKeyframesRule(rule) { + return rule.type === CSSRule.KEYFRAMES_RULE; + } +} diff --git a/modules/angular2/src/dom/dom_adapter.js b/modules/angular2/src/dom/dom_adapter.js new file mode 100644 index 0000000000..bf4adb9729 --- /dev/null +++ b/modules/angular2/src/dom/dom_adapter.js @@ -0,0 +1,231 @@ +import {ABSTRACT, BaseException} from 'angular2/src/facade/lang'; + +export var DOM:DomAdapter; + +export function setRootDomAdapter(adapter:DomAdapter) { + DOM = adapter; +} + +function _abstract() { + return new BaseException('This method is abstract'); +} + +/** + * Provides DOM operations in an environment-agnostic way. + */ +@ABSTRACT() +export class DomAdapter { + get attrToPropMap():Map { + throw _abstract(); + } + parse(templateHtml:string) { + throw _abstract(); + } + query(selector) { + throw _abstract(); + } + querySelector(el, selector:string) { + throw _abstract(); + } + querySelectorAll(el, selector:string):List { + throw _abstract(); + } + on(el, evt, listener) { + throw _abstract(); + } + dispatchEvent(el, evt) { + throw _abstract(); + } + createMouseEvent(eventType) { + throw _abstract(); + } + createEvent(eventType) { + throw _abstract(); + } + getInnerHTML(el) { + throw _abstract(); + } + getOuterHTML(el) { + throw _abstract(); + } + nodeName(node):string { + throw _abstract(); + } + nodeValue(node):string { + throw _abstract(); + } + type(node):string { + throw _abstract(); + } + content(node) { + throw _abstract(); + } + firstChild(el) { + throw _abstract(); + } + nextSibling(el) { + throw _abstract(); + } + parentElement(el) { + throw _abstract(); + } + childNodes(el):List { + throw _abstract(); + } + childNodesAsList(el):List { + throw _abstract(); + } + clearNodes(el) { + throw _abstract(); + } + appendChild(el, node) { + throw _abstract(); + } + removeChild(el, node) { + throw _abstract(); + } + remove(el) { + throw _abstract(); + } + insertBefore(el, node) { + throw _abstract(); + } + insertAllBefore(el, nodes) { + throw _abstract(); + } + insertAfter(el, node) { + throw _abstract(); + } + setInnerHTML(el, value) { + throw _abstract(); + } + getText(el) { + throw _abstract(); + } + setText(el, value:string) { + throw _abstract(); + } + getValue(el) { + throw _abstract(); + } + setValue(el, value:string) { + throw _abstract(); + } + getChecked(el) { + throw _abstract(); + } + setChecked(el, value:boolean) { + throw _abstract(); + } + createTemplate(html) { + throw _abstract(); + } + createElement(tagName, doc = null) { + throw _abstract(); + } + createTextNode(text: string, doc = null) { + throw _abstract(); + } + createScriptTag(attrName:string, attrValue:string, doc = null) { + throw _abstract(); + } + createStyleElement(css:string, doc = null) { + throw _abstract(); + } + createShadowRoot(el) { + throw _abstract(); + } + getShadowRoot(el) { + throw _abstract(); + } + clone(node) { + throw _abstract(); + } + hasProperty(element, name:string) { + throw _abstract(); + } + getElementsByClassName(element, name:string) { + throw _abstract(); + } + getElementsByTagName(element, name:string) { + throw _abstract(); + } + classList(element):List { + throw _abstract(); + } + addClass(element, classname:string) { + throw _abstract(); + } + removeClass(element, classname:string) { + throw _abstract(); + } + hasClass(element, classname:string) { + throw _abstract(); + } + setStyle(element, stylename:string, stylevalue:string) { + throw _abstract(); + } + removeStyle(element, stylename:string) { + throw _abstract(); + } + getStyle(element, stylename:string) { + throw _abstract(); + } + tagName(element):string { + throw _abstract(); + } + attributeMap(element) { + throw _abstract(); + } + getAttribute(element, attribute:string) { + throw _abstract(); + } + setAttribute(element, name:string, value:string) { + throw _abstract(); + } + removeAttribute(element, attribute:string) { + throw _abstract(); + } + templateAwareRoot(el) { + throw _abstract(); + } + createHtmlDocument() { + throw _abstract(); + } + defaultDoc() { + throw _abstract(); + } + elementMatches(n, selector:string):boolean { + throw _abstract(); + } + isTemplateElement(el:any):boolean { + throw _abstract(); + } + isTextNode(node):boolean { + throw _abstract(); + } + isCommentNode(node):boolean { + throw _abstract(); + } + isElementNode(node):boolean { + throw _abstract(); + } + hasShadowRoot(node):boolean { + throw _abstract(); + } + importIntoDoc(node) { + throw _abstract(); + } + isPageRule(rule) { + throw _abstract(); + } + isStyleRule(rule) { + throw _abstract(); + } + isMediaRule(rule) { + throw _abstract(); + } + isKeyframesRule(rule) { + throw _abstract(); + } +} diff --git a/modules/angular2/src/dom/html5lib_adapter.dart b/modules/angular2/src/dom/html5lib_adapter.dart new file mode 100644 index 0000000000..0e36f51315 --- /dev/null +++ b/modules/angular2/src/dom/html5lib_adapter.dart @@ -0,0 +1,229 @@ +library angular2.dom.html5adapter; + +import 'dom_adapter.dart'; +import 'package:html5lib/parser.dart' as parser; +import 'package:html5lib/dom.dart'; + +class Html5LibDomAdapter implements DomAdapter { + static void makeCurrent() { + setRootDomAdapter(new Html5LibDomAdapter()); + } + + Element parse(String templateHtml) => parser.parse(templateHtml).firstChild; + query(selector) { + throw 'not implemented'; + } + querySelector(el, String selector) { + throw 'not implemented'; + } + List querySelectorAll(el, String selector) { + throw 'not implemented'; + } + on(el, evt, listener) { + throw 'not implemented'; + } + dispatchEvent(el, evt) { + throw 'not implemented'; + } + createMouseEvent(eventType) { + throw 'not implemented'; + } + createEvent(eventType) { + throw 'not implemented'; + } + getInnerHTML(el) { + return el.innerHtml; + } + getOuterHTML(el) { + throw 'not implemented'; + } + String nodeName(node) { + throw 'not implemented'; + } + String nodeValue(node) { + throw 'not implemented'; + } + String type(node) { + throw 'not implemented'; + } + content(TemplateElement node) { + throw 'not implemented'; + } + + firstChild(el) => el is NodeList + ? el.first + : el.firstChild; + + nextSibling(el) { + final parentNode = el.parentNode; + if (parentNode == null) return null; + final siblings = parentNode.nodes; + final index = siblings.indexOf(el); + if (index < siblings.length - 1) { + return siblings[index + 1]; + } + return null; + } + + parentElement(el) { + throw 'not implemented'; + } + List childNodes(el) { + throw 'not implemented'; + } + List childNodesAsList(el) { + throw 'not implemented'; + } + clearNodes(el) { + throw 'not implemented'; + } + appendChild(el, node) { + throw 'not implemented'; + } + removeChild(el, node) { + throw 'not implemented'; + } + remove(el) { + throw 'not implemented'; + } + insertBefore(el, node) { + throw 'not implemented'; + } + insertAllBefore(el, nodes) { + throw 'not implemented'; + } + insertAfter(el, node) { + throw 'not implemented'; + } + setInnerHTML(el, value) { + throw 'not implemented'; + } + getText(el) { + throw 'not implemented'; + } + setText(el, String value) { + throw 'not implemented'; + } + getValue(el) { + throw 'not implemented'; + } + setValue(el, String value) { + throw 'not implemented'; + } + getChecked(el) { + throw 'not implemented'; + } + setChecked(el, bool value) { + throw 'not implemented'; + } + createTemplate(html) { + return createElement('template') + ..innerHtml = html; + } + createElement(tagName, [doc]) { + return new Element.tag(tagName); + } + createTextNode(String text, [doc]) { + throw 'not implemented'; + } + createScriptTag(String attrName, String attrValue, [doc]) { + throw 'not implemented'; + } + createStyleElement(String css, [doc]) { + throw 'not implemented'; + } + clone(node) { + throw 'not implemented'; + } + hasProperty(element, String name) { + throw 'not implemented'; + } + getElementsByClassName(element, String name) { + throw 'not implemented'; + } + getElementsByTagName(element, String name) { + throw 'not implemented'; + } + List classList(element) { + throw 'not implemented'; + } + addClass(element, String classname) { + throw 'not implemented'; + } + removeClass(element, String classname) { + throw 'not implemented'; + } + + hasClass(element, String classname) => + element.classes.contains(classname); + + setStyle(element, String stylename, String stylevalue) { + throw 'not implemented'; + } + removeStyle(element, String stylename) { + throw 'not implemented'; + } + getStyle(element, String stylename) { + throw 'not implemented'; + } + + String tagName(element) => element.localName; + + attributeMap(element) => element.attributes; + getAttribute(element, String attribute) { + throw 'not implemented'; + } + setAttribute(element, String name, String value) { + throw 'not implemented'; + } + removeAttribute(element, String attribute) { + throw 'not implemented'; + } + + templateAwareRoot(el) => isTemplateElement(el) + ? el.nodes + : el; + + createHtmlDocument() { + throw 'not implemented'; + } + + defaultDoc() { + throw 'not implemented'; + } + + bool elementMatches(n, String selector) { + throw 'not implemented'; + } + + bool isTemplateElement(Element el) { + return el != null && el.localName.toLowerCase() == 'template'; + } + bool isTextNode(node) { + throw 'not implemented'; + } + bool isCommentNode(node) { + throw 'not implemented'; + } + + bool isElementNode(node) => node is Element; + + bool hasShadowRoot(node) { + throw 'not implemented'; + } + importIntoDoc(node) { + throw 'not implemented'; + } + isPageRule(rule) { + throw 'not implemented'; + } + isStyleRule(rule) { + throw 'not implemented'; + } + isMediaRule(rule) { + throw 'not implemented'; + } + isKeyframesRule(rule) { + throw 'not implemented'; + } +} diff --git a/modules/angular2/src/facade/browser.dart b/modules/angular2/src/facade/browser.dart new file mode 100644 index 0000000000..3c84a5a289 --- /dev/null +++ b/modules/angular2/src/facade/browser.dart @@ -0,0 +1,21 @@ +/** + * Dart version of browser APIs. This library depends on 'dart:html' and + * therefore can only run in the browser. + */ + +import 'dart:js' show context; + +export 'dart:html' show + document, + location, + window, + Element, + Node; + +final _gc = context['gc']; + +void gc() { + if (_gc != null) { + _gc.apply(const []); + } +} diff --git a/modules/angular2/src/facade/browser.es6 b/modules/angular2/src/facade/browser.es6 new file mode 100644 index 0000000000..0ee9380ce8 --- /dev/null +++ b/modules/angular2/src/facade/browser.es6 @@ -0,0 +1,10 @@ +/** + * JS version of browser APIs. This library can only run in the browser. + */ + +var win = window; + +export {win as window}; +export var document = window.document; +export var location = window.location; +export var gc = window.gc ? () => window.gc() : () => null; diff --git a/modules/angular2/src/facade/collection.dart b/modules/angular2/src/facade/collection.dart index 0e0ed6abb0..478451d823 100644 --- a/modules/angular2/src/facade/collection.dart +++ b/modules/angular2/src/facade/collection.dart @@ -67,7 +67,7 @@ class StringMapWrapper { static void forEach(Map m, fn(v, k)) { m.forEach((k, v) => fn(v, k)); } - static HashMap merge(HashMap a, HashMap b) { + static HashMap merge(Map a, Map b) { var m = new HashMap.from(a); b.forEach((k, v) => m[k] = v); return m; diff --git a/modules/angular2/src/facade/dom.dart b/modules/angular2/src/facade/dom.dart deleted file mode 100644 index 380eb059e9..0000000000 --- a/modules/angular2/src/facade/dom.dart +++ /dev/null @@ -1,210 +0,0 @@ -library angular.core.facade.dom; - -import 'dart:html'; -import 'dart:js' show JsObject, context; - -export 'dart:html' show - CssRule, - CssKeyframesRule, - document, - DocumentFragment, - Element, - location, - Node, - ShadowRoot, - StyleElement, - TemplateElement, - InputElement, - AnchorElement, - Text, - window, - attrToPropMap; - -// TODO(tbosch): Is there a builtin one? Why is Dart -// removing unknown elements by default? -class IdentitySanitizer implements NodeTreeSanitizer { - void sanitizeTree(Node node) {} -} - -final _window = context['window']; -final _gc = context['gc']; - -void gc() { - if (_gc != null) { - _gc.apply(const []); - } -} - -final identitySanitizer = new IdentitySanitizer(); - -// override JS logic of attribute to property mapping -var attrToPropMap = { - "inner-html": "innerHtml" -}; - -class DOM { - static query(String selector) => document.querySelector(selector); - - static Element querySelector(el, String selector) => - el.querySelector(selector); - - static ElementList querySelectorAll(el, String selector) => - el.querySelectorAll(selector); - - static void on(EventTarget element, String event, callback(arg)) { - // due to https://code.google.com/p/dart/issues/detail?id=17406 - // addEventListener misses zones so we use element.on. - element.on[event].listen(callback); - } - static void dispatchEvent(EventTarget el, Event evt) { - el.dispatchEvent(evt); - } - static MouseEvent createMouseEvent(String eventType) => - new MouseEvent(eventType, canBubble: true); - static createEvent(eventType) => - new Event(eventType, canBubble: true); - static String getInnerHTML(Element el) => el.innerHtml; - static String getOuterHTML(Element el) => el.outerHtml; - static void setInnerHTML(Element el, String value) { - el.innerHtml = value; - } - static String nodeName(Node el) => el.nodeName; - static String nodeValue(Node el) => el.nodeValue; - static String type(InputElement el) => el.type; - static Node content(TemplateElement el) => el.content; - static Node firstChild(el) => el.firstChild; - static Node nextSibling(Node el) => el.nextNode; - static Element parentElement(Node el) => el.parent; - static List childNodes(Node el) => el.childNodes; - static List childNodesAsList(Node el) => childNodes(el).toList(); - static void clearNodes(Node el) { - el.nodes = const []; - } - static void appendChild(Node el, Node node) { - el.append(node); - } - static void removeChild(Element el, Node node) { - node.remove(); - } - static Element remove(Element el) { - return el..remove(); - } - static insertBefore(Node el, node) { - el.parentNode.insertBefore(node, el); - } - static void insertAllBefore(Node el, Iterable nodes) { - el.parentNode.insertAllBefore(nodes, el); - } - static void insertAfter(Node el, Node node) { - el.parentNode.insertBefore(node, el.nextNode); - } - static String getText(Node el) => el.text; - static void setText(Node el, String value) { - el.text = value; - } - static String getValue(InputElement el) => el.value; - static void setValue(InputElement el, String value) { - el.value = value; - } - static bool getChecked(InputElement el) => el.checked; - static void setChecked(InputElement el, bool isChecked) { - el.checked = isChecked; - } - static TemplateElement createTemplate(String html) { - var t = new TemplateElement(); - t.setInnerHtml(html, treeSanitizer: identitySanitizer); - return t; - } - static Element createElement(String tagName, [HtmlDocument doc = null]) { - if (doc == null) doc = document; - return doc.createElement(tagName); - } - static createTextNode(String text, [HtmlDocument doc = null]) { - return new Text(text); - } - static createScriptTag(String attrName, String attrValue, - [HtmlDocument doc = null]) { - if (doc == null) doc = document; - var el = doc.createElement("SCRIPT"); - el.setAttribute(attrName, attrValue); - return el; - } - static StyleElement createStyleElement(String css, [HtmlDocument doc = null]) { - if (doc == null) doc = document; - var el = doc.createElement("STYLE"); - el.text = css; - return el; - } - static ShadowRoot createShadowRoot(Element el) => el.createShadowRoot(); - static ShadowRoot getShadowRoot(Element el) => el.shadowRoot; - static clone(Node node) => node.clone(true); - static bool hasProperty(Element element, String name) => - new JsObject.fromBrowserObject(element).hasProperty(name); - static List getElementsByClassName(Element element, String name) => - element.getElementsByClassName(name); - static List getElementsByTagName(Element element, String name) => - element.querySelectorAll(name); - static List classList(Element element) => element.classes.toList(); - static void addClass(Element element, String classname) { - element.classes.add(classname); - } - static void removeClass(Element element, String classname) { - element.classes.remove(classname); - } - static bool hasClass(Element element, String classname) => - element.classes.contains(classname); - - static void setStyle(Element element, String stylename, String stylevalue) { - element.style.setProperty(stylename, stylevalue); - } - static void removeStyle(Element element, String stylename) { - element.style.removeProperty(stylename); - } - static String getStyle(Element element, String stylename) { - return element.style.getPropertyValue(stylename); - } - - static String tagName(Element element) => element.tagName; - - static Map attributeMap(Element element) => - element.attributes; - - static String getAttribute(Element element, String attribute) => - element.getAttribute(attribute); - - static void setAttribute(Element element, String name, String value) { - element.setAttribute(name, value); - } - - static void removeAttribute(Element element, String name) { - //there is no removeAttribute method as of now in Dart: - //https://code.google.com/p/dart/issues/detail?id=19934 - element.attributes.remove(name); - } - - static Node templateAwareRoot(Element el) => - el is TemplateElement ? el.content : el; - - static HtmlDocument createHtmlDocument() => - document.implementation.createHtmlDocument('fakeTitle'); - - static HtmlDocument defaultDoc() => document; - static bool elementMatches(n, String selector) => - n is Element && n.matches(selector); - static bool isTemplateElement(Element el) => - el is TemplateElement; - static bool isTextNode(Node node) => - node.nodeType == Node.TEXT_NODE; - static bool isElementNode(Node node) => - node.nodeType == Node.ELEMENT_NODE; - static Node importIntoDoc(Node node) { - return document.importNode(node, true); - } -} - -class CSSRuleWrapper { - static bool isPageRule(CssRule rule) => rule is CssPageRule; - static bool isStyleRule(CssRule rule) => rule is CssStyleRule; - static bool isMediaRule(CssRule rule) => rule is CssMediaRule; - static bool isKeyframesRule(CssRule rule) => rule is CssKeyframesRule; -} diff --git a/modules/angular2/src/facade/dom.es6 b/modules/angular2/src/facade/dom.es6 deleted file mode 100644 index ffd6d0aca0..0000000000 --- a/modules/angular2/src/facade/dom.es6 +++ /dev/null @@ -1,250 +0,0 @@ -import {List, MapWrapper, ListWrapper} from 'angular2/src/facade/collection'; - -export var window = frames.window; -export var DocumentFragment = window.DocumentFragment; -export var Node = window.Node; -export var NodeList = window.NodeList; -export var Text = window.Text; -export var Element = window.HTMLElement; -export var AnchorElement = window.HTMLAnchorElement; -export var TemplateElement = window.HTMLTemplateElement; -export var StyleElement = window.HTMLStyleElement; -export var ShadowRoot = window.ShadowRoot; -export var document = window.document; -export var location = window.location; -export var gc = window.gc ? () => window.gc() : () => null; -export var CssRule = window.CSSRule; -export var CssKeyframesRule = window.CSSKeyframesRule; - -export var attrToPropMap = {}; - -export class DOM { - static query(selector) { - return document.querySelector(selector); - } - static querySelector(el, selector:string):Node { - return el.querySelector(selector); - } - static querySelectorAll(el, selector:string):NodeList { - return el.querySelectorAll(selector); - } - static on(el, evt, listener) { - el.addEventListener(evt, listener, false); - } - static dispatchEvent(el, evt) { - el.dispatchEvent(evt); - } - static createMouseEvent(eventType) { - var evt = new MouseEvent(eventType); - evt.initEvent(eventType, true, true); - return evt; - } - static createEvent(eventType) { - return new Event(eventType, true); - } - static getInnerHTML(el) { - return el.innerHTML; - } - static getOuterHTML(el) { - return el.outerHTML; - } - static nodeName(node:Node):string { - return node.nodeName; - } - static nodeValue(node:Node):string { - return node.nodeValue; - } - static type(node:Element):string { - return node.type; - } - static content(node:TemplateElement):Node { - return node.content; - } - static firstChild(el):Node { - return el.firstChild; - } - static nextSibling(el):Node { - return el.nextSibling; - } - static parentElement(el) { - return el.parentElement; - } - static childNodes(el):NodeList { - return el.childNodes; - } - static childNodesAsList(el):List { - var childNodes = el.childNodes; - var res = ListWrapper.createFixedSize(childNodes.length); - for (var i=0; i { - el.parentNode.insertBefore(n, el); - }); - } - static insertAfter(el, node) { - el.parentNode.insertBefore(node, el.nextSibling); - } - static setInnerHTML(el, value) { - el.innerHTML = value; - } - static getText(el: Element) { - return el.textContent; - } - // TODO(vicb): removed Element type because it does not support StyleElement - static setText(el, value:string) { - el.textContent = value; - } - static getValue(el: Element) { - return el.value; - } - static setValue(el: Element, value:string) { - el.value = value; - } - static getChecked(el: Element) { - return el.checked; - } - static setChecked(el: Element, value:boolean) { - el.checked = value; - } - static createTemplate(html) { - var t = document.createElement('template'); - t.innerHTML = html; - return t; - } - static createElement(tagName, doc=document) { - return doc.createElement(tagName); - } - static createTextNode(text: string, doc=document) { - return doc.createTextNode(text); - } - static createScriptTag(attrName:string, attrValue:string, doc=document) { - var el = doc.createElement("SCRIPT"); - el.setAttribute(attrName, attrValue); - return el; - } - static createStyleElement(css:string, doc=document):StyleElement { - var style = doc.createElement('STYLE'); - style.innerText = css; - return style; - } - static createShadowRoot(el: Element): ShadowRoot { - return el.createShadowRoot(); - } - static getShadowRoot(el: Element): ShadowRoot { - return el.shadowRoot; - } - static clone(node:Node) { - return node.cloneNode(true); - } - static hasProperty(element:Element, name:string) { - return name in element; - } - static getElementsByClassName(element:Element, name:string) { - return element.getElementsByClassName(name); - } - static getElementsByTagName(element:Element, name:string) { - return element.getElementsByTagName(name); - } - static classList(element:Element):List { - return Array.prototype.slice.call(element.classList, 0); - } - static addClass(element:Element, classname:string) { - element.classList.add(classname); - } - static removeClass(element:Element, classname:string) { - element.classList.remove(classname); - } - static hasClass(element:Element, classname:string) { - return element.classList.contains(classname); - } - static setStyle(element:Element, stylename:string, stylevalue:string) { - element.style[stylename] = stylevalue; - } - static removeStyle(element:Element, stylename:string) { - element.style[stylename] = null; - } - static getStyle(element:Element, stylename:string) { - return element.style[stylename]; - } - static tagName(element:Element):string { - return element.tagName; - } - static attributeMap(element:Element) { - var res = MapWrapper.create(); - var elAttrs = element.attributes; - for (var i = 0; i < elAttrs.length; i++) { - var attrib = elAttrs[i]; - MapWrapper.set(res, attrib.name, attrib.value); - } - return res; - } - static getAttribute(element:Element, attribute:string) { - return element.getAttribute(attribute); - } - static setAttribute(element:Element, name:string, value:string) { - element.setAttribute(name, value); - } - static removeAttribute(element:Element, attribute:string) { - return element.removeAttribute(attribute); - } - static templateAwareRoot(el:Element):Node { - return el instanceof TemplateElement ? el.content : el; - } - static createHtmlDocument() { - return document.implementation.createHTMLDocument(); - } - static defaultDoc() { - return document; - } - static elementMatches(n, selector:string):boolean { - return n instanceof Element && n.matches(selector); - } - static isTemplateElement(el:any):boolean { - return el instanceof TemplateElement; - } - static isTextNode(node:Node):boolean { - return node.nodeType === Node.TEXT_NODE; - } - static isElementNode(node:Node):boolean { - return node.nodeType === Node.ELEMENT_NODE; - } - static importIntoDoc(node:Node) { - return document.importNode(node, true); - } -} - -export class CSSRuleWrapper { - static isPageRule(rule) { - return rule.type === CSSRule.PAGE_RULE; - } - static isStyleRule(rule) { - return rule.type === CSSRule.STYLE_RULE; - } - static isMediaRule(rule) { - return rule.type === CSSRule.MEDIA_RULE; - } - static isKeyframesRule(rule) { - return rule.type === CSSRule.KEYFRAMES_RULE; - } -} diff --git a/modules/angular2/src/forms/directives.js b/modules/angular2/src/forms/directives.js index 66c4d4ad89..b833937f91 100644 --- a/modules/angular2/src/forms/directives.js +++ b/modules/angular2/src/forms/directives.js @@ -1,5 +1,5 @@ import {Template, Component, Decorator, NgElement, Ancestor, onChange} from 'angular2/core'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {isBlank, isPresent, CONST} from 'angular2/src/facade/lang'; import {StringMapWrapper, ListWrapper} from 'angular2/src/facade/collection'; import {ControlGroup, Control} from './model'; diff --git a/modules/angular2/src/test_lib/benchmark_util.js b/modules/angular2/src/test_lib/benchmark_util.js index 6aba8fee4d..778f85f8bb 100644 --- a/modules/angular2/src/test_lib/benchmark_util.js +++ b/modules/angular2/src/test_lib/benchmark_util.js @@ -1,6 +1,9 @@ -import {DOM, document, location} from 'angular2/src/facade/dom'; +import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter'; +import {document} from 'angular2/src/facade/browser'; import {NumberWrapper, BaseException, isBlank} from 'angular2/src/facade/lang'; +var DOM = new BrowserDomAdapter(); + export function getIntParameter(name:string) { return NumberWrapper.parseInt(getStringParameter(name), 10); } diff --git a/modules/angular2/src/test_lib/test_lib.dart b/modules/angular2/src/test_lib/test_lib.dart index 75bf52c559..68b81ad007 100644 --- a/modules/angular2/src/test_lib/test_lib.dart +++ b/modules/angular2/src/test_lib/test_lib.dart @@ -1,13 +1,14 @@ library test_lib.test_lib; -import 'package:guinness/guinness_html.dart' as gns; -export 'package:guinness/guinness_html.dart' hide Expect, expect, NotExpect, beforeEach, it, iit; +import 'package:guinness/guinness.dart' as gns; +export 'package:guinness/guinness.dart' hide Expect, expect, NotExpect, beforeEach, it, iit; import 'package:unittest/unittest.dart' hide expect; import 'dart:mirrors'; import 'dart:async'; import 'package:angular2/src/reflection/reflection.dart'; import 'package:angular2/src/reflection/reflection_capabilities.dart'; import 'package:collection/equality.dart'; +import 'package:angular2/src/dom/dom_adapter.dart' show DOM; bool IS_DARTIUM = true; @@ -29,6 +30,7 @@ class Expect extends gns.Expect { void toBePromise() => _expect(actual is Future, equals(true)); void toImplement(expected) => toBeA(expected); void toBeNaN() => _expect(double.NAN.compareTo(actual) == 0, equals(true)); + void toHaveText(expected) => _expect(elementText(actual), expected); Function get _expect => gns.guinness.matchers.expect; } @@ -43,7 +45,6 @@ class NotExpect extends gns.NotExpect { } beforeEach(fn) { - gns.guinnessEnableHtmlMatchers(); gns.beforeEach(_enableReflection(fn)); } @@ -137,3 +138,32 @@ class _FixedObjToData { }); } } + +String elementText(n) { + hasNodes(n) { + var children = DOM.childNodes(n); + return children != null && children.length > 0; + } + + if (n is Iterable) { + return n.map((nn) => elementText(nn)).join(""); + } + + if (DOM.isCommentNode(n)) { + return ''; + } + + if (DOM.isElementNode(n) && DOM.tagName(n) == 'CONTENT') { + return elementText(n.getDistributedNodes()); + } + + if (DOM.hasShadowRoot(n)) { + return elementText(DOM.childNodesAsList(n.shadowRoot)); + } + + if (hasNodes(n)) { + return elementText(DOM.childNodesAsList(n)); + } + + return DOM.getText(n); +} diff --git a/modules/angular2/src/test_lib/test_lib.es6 b/modules/angular2/src/test_lib/test_lib.es6 index 3877f56b51..033bd5d187 100644 --- a/modules/angular2/src/test_lib/test_lib.es6 +++ b/modules/angular2/src/test_lib/test_lib.es6 @@ -1,4 +1,4 @@ -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; export {proxy} from 'rtts_assert/rtts_assert'; export var describe = window.describe; @@ -150,7 +150,6 @@ export class SpyObject { function elementText(n) { - var hasShadowRoot = (n) => n instanceof Element && n.shadowRoot; var hasNodes = (n) => {var children = DOM.childNodes(n); return children && children.length > 0;} if (n instanceof Comment) return ''; @@ -158,8 +157,8 @@ function elementText(n) { if (n instanceof Array) return n.map((nn) => elementText(nn)).join(""); if (n instanceof Element && DOM.tagName(n) == 'CONTENT') return elementText(Array.prototype.slice.apply(n.getDistributedNodes())); - if (hasShadowRoot(n)) return elementText(DOM.childNodesAsList(n.shadowRoot)); + if (DOM.hasShadowRoot(n)) return elementText(DOM.childNodesAsList(n.shadowRoot)); if (hasNodes(n)) return elementText(DOM.childNodesAsList(n)); return n.textContent; -} \ No newline at end of file +} diff --git a/modules/angular2/src/test_lib/utils.js b/modules/angular2/src/test_lib/utils.js index d4deff8744..a436d03998 100644 --- a/modules/angular2/src/test_lib/utils.js +++ b/modules/angular2/src/test_lib/utils.js @@ -1,5 +1,5 @@ import {List, ListWrapper} from 'angular2/src/facade/collection'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {isPresent} from 'angular2/src/facade/lang'; export class Log { diff --git a/modules/angular2/test/change_detection/change_detection_spec.js b/modules/angular2/test/change_detection/change_detection_spec.js index f2bc3f0edd..b3a7d2920c 100644 --- a/modules/angular2/test/change_detection/change_detection_spec.js +++ b/modules/angular2/test/change_detection/change_detection_spec.js @@ -11,7 +11,6 @@ import {ChangeDispatcher, DynamicChangeDetector, ChangeDetectionError, ContextWi import {ChangeDetectionUtil} from 'angular2/src/change_detection/change_detection_util'; - import {JitProtoChangeDetector, DynamicProtoChangeDetector} from 'angular2/src/change_detection/proto_change_detector'; diff --git a/modules/angular2/test/change_detection/parser/lexer_spec.js b/modules/angular2/test/change_detection/parser/lexer_spec.js index 16b2a3fb7f..ae14b18dc0 100644 --- a/modules/angular2/test/change_detection/parser/lexer_spec.js +++ b/modules/angular2/test/change_detection/parser/lexer_spec.js @@ -49,7 +49,6 @@ function expectKeywordToken(token, index, keyword) { expect(token.toString()).toEqual(keyword); } - export function main() { describe('lexer', function() { describe('token', function() { diff --git a/modules/angular2/test/core/application_spec.js b/modules/angular2/test/core/application_spec.js index ae0e27108c..ff84455f14 100644 --- a/modules/angular2/test/core/application_spec.js +++ b/modules/angular2/test/core/application_spec.js @@ -2,7 +2,7 @@ import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach} from ' import {bootstrap, appDocumentToken, appElementToken} from 'angular2/src/core/application'; import {Component} from 'angular2/src/core/annotations/annotations'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {ListWrapper} from 'angular2/src/facade/collection'; import {PromiseWrapper} from 'angular2/src/facade/async'; import {bind, Inject} from 'angular2/di'; diff --git a/modules/angular2/test/core/compiler/compiler_browser_spec.js b/modules/angular2/test/core/compiler/compiler_browser_spec.js new file mode 100644 index 0000000000..963ee1b8d2 --- /dev/null +++ b/modules/angular2/test/core/compiler/compiler_browser_spec.js @@ -0,0 +1,9 @@ +/* + * Runs compiler tests using in-browser DOM adapter. + */ + +import {runCompilerCommonTests} from './compiler_common_tests'; + +export function main() { + runCompilerCommonTests(); +} diff --git a/modules/angular2/test/core/compiler/compiler_spec.js b/modules/angular2/test/core/compiler/compiler_common_tests.js similarity index 99% rename from modules/angular2/test/core/compiler/compiler_spec.js rename to modules/angular2/test/core/compiler/compiler_common_tests.js index 46528dae03..e904b3672a 100644 --- a/modules/angular2/test/core/compiler/compiler_spec.js +++ b/modules/angular2/test/core/compiler/compiler_common_tests.js @@ -1,6 +1,6 @@ import {describe, beforeEach, it, expect, ddescribe, iit, el, IS_DARTIUM} from 'angular2/test_lib'; -import {DOM, Element, TemplateElement} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {List, ListWrapper, Map, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection'; import {Type, isBlank, stringify, isPresent} from 'angular2/src/facade/lang'; import {PromiseWrapper} from 'angular2/src/facade/async'; @@ -22,7 +22,7 @@ import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver'; import {Lexer, Parser, dynamicChangeDetection} from 'angular2/change_detection'; import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy'; -export function main() { +export function runCompilerCommonTests() { describe('compiler', function() { StringMapWrapper.forEach({ '(sync TemplateLoader)': true, diff --git a/modules/angular2/test/core/compiler/compiler_html5lib.server.spec.dart b/modules/angular2/test/core/compiler/compiler_html5lib.server.spec.dart new file mode 100644 index 0000000000..c25f660ae9 --- /dev/null +++ b/modules/angular2/test/core/compiler/compiler_html5lib.server.spec.dart @@ -0,0 +1,9 @@ +library angular2.compiler.html5lib_dom_adapter.test; + +import 'package:angular2/src/dom/html5lib_adapter.dart'; +import 'compiler_common_tests.dart'; + +void main() { + Html5LibDomAdapter.makeCurrent(); + runCompilerCommonTests(); +} diff --git a/modules/angular2/test/core/compiler/integration_spec.js b/modules/angular2/test/core/compiler/integration_spec.js index b645e5b0b8..a31d6e0834 100644 --- a/modules/angular2/test/core/compiler/integration_spec.js +++ b/modules/angular2/test/core/compiler/integration_spec.js @@ -1,6 +1,6 @@ import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'angular2/test_lib'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Type, isPresent, BaseException} from 'angular2/src/facade/lang'; import {assertionsEnabled, isJsObject} from 'angular2/src/facade/lang'; diff --git a/modules/angular2/test/core/compiler/pipeline/element_binder_builder_spec.js b/modules/angular2/test/core/compiler/pipeline/element_binder_builder_spec.js index 1475d1bb06..d7448c3ec6 100644 --- a/modules/angular2/test/core/compiler/pipeline/element_binder_builder_spec.js +++ b/modules/angular2/test/core/compiler/pipeline/element_binder_builder_spec.js @@ -1,6 +1,6 @@ import {describe, beforeEach, it, expect, iit, ddescribe, el} from 'angular2/test_lib'; import {isPresent, normalizeBlank} from 'angular2/src/facade/lang'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection'; import {ElementBinderBuilder} from 'angular2/src/core/compiler/pipeline/element_binder_builder'; diff --git a/modules/angular2/test/core/compiler/pipeline/element_binding_marker_spec.js b/modules/angular2/test/core/compiler/pipeline/element_binding_marker_spec.js index 3e4922ccac..75df86dfd9 100644 --- a/modules/angular2/test/core/compiler/pipeline/element_binding_marker_spec.js +++ b/modules/angular2/test/core/compiler/pipeline/element_binding_marker_spec.js @@ -1,6 +1,6 @@ import {describe, beforeEach, it, expect, iit, ddescribe, el} from 'angular2/test_lib'; import {isPresent} from 'angular2/src/facade/lang'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {MapWrapper} from 'angular2/src/facade/collection'; import {ElementBindingMarker} from 'angular2/src/core/compiler/pipeline/element_binding_marker'; diff --git a/modules/angular2/test/core/compiler/pipeline/pipeline_spec.js b/modules/angular2/test/core/compiler/pipeline/pipeline_spec.js index 4e747e9b04..0e29a4b633 100644 --- a/modules/angular2/test/core/compiler/pipeline/pipeline_spec.js +++ b/modules/angular2/test/core/compiler/pipeline/pipeline_spec.js @@ -1,6 +1,6 @@ import {describe, beforeEach, it, expect, iit, ddescribe, el} from 'angular2/test_lib'; import {ListWrapper, List, MapWrapper} from 'angular2/src/facade/collection'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {isPresent, NumberWrapper, StringWrapper} from 'angular2/src/facade/lang'; import {CompilePipeline} from 'angular2/src/core/compiler/pipeline/compile_pipeline'; diff --git a/modules/angular2/test/core/compiler/pipeline/proto_element_injector_builder_spec.js b/modules/angular2/test/core/compiler/pipeline/proto_element_injector_builder_spec.js index fa4bdb01a4..b4a98a1b28 100644 --- a/modules/angular2/test/core/compiler/pipeline/proto_element_injector_builder_spec.js +++ b/modules/angular2/test/core/compiler/pipeline/proto_element_injector_builder_spec.js @@ -15,16 +15,18 @@ import {ProtoElementInjector} from 'angular2/src/core/compiler/element_injector' export function main() { describe('ProtoElementInjectorBuilder', () => { var protoElementInjectorBuilder, protoView; + // Create consts for an elements with a var- so that we can fake parsing the var into + // the CompileElement's variableBindings without actually doing any parsing. + var ELEMENT_WITH_VAR; + var DIRECTIVE_ELEMENT_WITH_VAR; + beforeEach( () => { + ELEMENT_WITH_VAR = el('
'); + DIRECTIVE_ELEMENT_WITH_VAR = el('
'); protoElementInjectorBuilder = new TestableProtoElementInjectorBuilder(); protoView = new ProtoView(null, null, null); }); - // Create consts for an elements with a var- so that we can fake parsing the var into - // the CompileElement's variableBindings without actually doing any parsing. - var ELEMENT_WITH_VAR = el('
'); - var DIRECTIVE_ELEMENT_WITH_VAR = el('
'); - function createPipeline(directives = null) { if (isBlank(directives)) { directives = []; diff --git a/modules/angular2/test/core/compiler/pipeline/resolve_css_spec.js b/modules/angular2/test/core/compiler/pipeline/resolve_css_spec.js index 1eaf5254b9..2d1dafe6f6 100644 --- a/modules/angular2/test/core/compiler/pipeline/resolve_css_spec.js +++ b/modules/angular2/test/core/compiler/pipeline/resolve_css_spec.js @@ -22,7 +22,7 @@ import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy' import {ProtoView} from 'angular2/src/core/compiler/view'; import {IMPLEMENTS, Type, stringify} from 'angular2/src/facade/lang'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {PromiseWrapper} from 'angular2/src/facade/async'; export function main() { diff --git a/modules/angular2/test/core/compiler/pipeline/shim_shadow_dom_spec.js b/modules/angular2/test/core/compiler/pipeline/shim_shadow_dom_spec.js index 6018d21016..f1cfe489a4 100644 --- a/modules/angular2/test/core/compiler/pipeline/shim_shadow_dom_spec.js +++ b/modules/angular2/test/core/compiler/pipeline/shim_shadow_dom_spec.js @@ -11,7 +11,7 @@ import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata'; import {ShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy'; import {Type, isBlank, stringify} from 'angular2/src/facade/lang'; -import {DOM, Element} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; export function main() { describe('ShimShadowDom', () => { @@ -62,12 +62,12 @@ class FakeStrategy extends ShadowDomStrategy { super(); } - shimContentElement(component: Type, element: Element) { + shimContentElement(component: Type, element) { var attrName = stringify(component) + '-content'; DOM.setAttribute(element, attrName, ''); } - shimHostElement(component: Type, element: Element) { + shimHostElement(component: Type, element) { var attrName = stringify(component) + '-host'; DOM.setAttribute(element, attrName, ''); } diff --git a/modules/angular2/test/core/compiler/pipeline/view_splitter_spec.js b/modules/angular2/test/core/compiler/pipeline/view_splitter_spec.js index e4872899f0..a93441c20b 100644 --- a/modules/angular2/test/core/compiler/pipeline/view_splitter_spec.js +++ b/modules/angular2/test/core/compiler/pipeline/view_splitter_spec.js @@ -3,7 +3,7 @@ import {MapWrapper} from 'angular2/src/facade/collection'; import {ViewSplitter} from 'angular2/src/core/compiler/pipeline/view_splitter'; import {CompilePipeline} from 'angular2/src/core/compiler/pipeline/compile_pipeline'; -import {DOM, TemplateElement} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Lexer, Parser} from 'angular2/change_detection'; diff --git a/modules/angular2/test/core/compiler/shadow_dom/content_tag_spec.js b/modules/angular2/test/core/compiler/shadow_dom/content_tag_spec.js index 5a81698d7b..5c0a62c099 100644 --- a/modules/angular2/test/core/compiler/shadow_dom/content_tag_spec.js +++ b/modules/angular2/test/core/compiler/shadow_dom/content_tag_spec.js @@ -1,6 +1,6 @@ import {describe, beforeEach, it, expect, ddescribe, iit, SpyObject, el, proxy} from 'angular2/test_lib'; import {IMPLEMENTS} from 'angular2/src/facade/lang'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Content} from 'angular2/src/core/compiler/shadow_dom_emulation/content_tag'; import {NgElement} from 'angular2/src/core/dom/element'; import {LightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom'; diff --git a/modules/angular2/test/core/compiler/shadow_dom/light_dom_spec.js b/modules/angular2/test/core/compiler/shadow_dom/light_dom_spec.js index 5c2381daf0..ab6dbdc582 100644 --- a/modules/angular2/test/core/compiler/shadow_dom/light_dom_spec.js +++ b/modules/angular2/test/core/compiler/shadow_dom/light_dom_spec.js @@ -1,7 +1,7 @@ import {describe, beforeEach, it, expect, ddescribe, iit, SpyObject, el, proxy} from 'angular2/test_lib'; import {IMPLEMENTS, isBlank} from 'angular2/src/facade/lang'; import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Content} from 'angular2/src/core/compiler/shadow_dom_emulation/content_tag'; import {LightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom'; import {View} from 'angular2/src/core/compiler/view'; diff --git a/modules/angular2/test/core/compiler/shadow_dom/shadow_dom_emulation_integration_spec.js b/modules/angular2/test/core/compiler/shadow_dom/shadow_dom_emulation_integration_spec.js index 5bed6536f6..f6bb8ff52d 100644 --- a/modules/angular2/test/core/compiler/shadow_dom/shadow_dom_emulation_integration_spec.js +++ b/modules/angular2/test/core/compiler/shadow_dom/shadow_dom_emulation_integration_spec.js @@ -2,7 +2,7 @@ import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'angular import {StringMapWrapper, List} from 'angular2/src/facade/collection'; import {Type} from 'angular2/src/facade/lang'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Injector} from 'angular2/di'; import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'angular2/change_detection'; @@ -29,7 +29,10 @@ import {Template} from 'angular2/src/core/annotations/template'; import {ViewContainer} from 'angular2/src/core/compiler/view_container'; +import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter'; + export function main() { + BrowserDomAdapter.makeCurrent(); describe('integration tests', function() { var urlResolver = new UrlResolver(); var styleUrlResolver = new StyleUrlResolver(urlResolver); diff --git a/modules/angular2/test/core/compiler/shadow_dom_strategy_spec.js b/modules/angular2/test/core/compiler/shadow_dom_strategy_spec.js index 40fab0c814..3895905d6d 100644 --- a/modules/angular2/test/core/compiler/shadow_dom_strategy_spec.js +++ b/modules/angular2/test/core/compiler/shadow_dom_strategy_spec.js @@ -13,7 +13,7 @@ import {ProtoView} from 'angular2/src/core/compiler/view'; import {XHR} from 'angular2/src/core/compiler/xhr/xhr'; import {isPresent, isBlank} from 'angular2/src/facade/lang'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Map, MapWrapper} from 'angular2/src/facade/collection'; import {PromiseWrapper, Promise} from 'angular2/src/facade/async'; diff --git a/modules/angular2/test/core/compiler/template_loader_spec.js b/modules/angular2/test/core/compiler/template_loader_spec.js index 0dac934bfd..dc1cf5e120 100644 --- a/modules/angular2/test/core/compiler/template_loader_spec.js +++ b/modules/angular2/test/core/compiler/template_loader_spec.js @@ -1,12 +1,9 @@ import {describe, it, expect, beforeEach, ddescribe, iit, xit, el} from 'angular2/test_lib'; - import {TemplateLoader} from 'angular2/src/core/compiler/template_loader'; import {UrlResolver} from 'angular2/src/core/compiler/url_resolver'; import {Template} from 'angular2/src/core/annotations/template'; - import {PromiseWrapper} from 'angular2/src/facade/async'; - import {XHRMock} from 'angular2/src/mock/xhr_mock'; export function main() { diff --git a/modules/angular2/test/core/compiler/view_container_spec.js b/modules/angular2/test/core/compiler/view_container_spec.js index a51dec2a96..1861ee74f5 100644 --- a/modules/angular2/test/core/compiler/view_container_spec.js +++ b/modules/angular2/test/core/compiler/view_container_spec.js @@ -2,7 +2,7 @@ import {describe, xit, it, expect, beforeEach, ddescribe, iit, el, proxy} from ' import {View, ProtoView} from 'angular2/src/core/compiler/view'; import {ViewContainer} from 'angular2/src/core/compiler/view_container'; import {IMPLEMENTS} from 'angular2/src/facade/lang'; -import {DOM, Node} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection'; import {Injector} from 'angular2/di'; import {ProtoElementInjector, ElementInjector} from 'angular2/src/core/compiler/element_injector'; @@ -33,7 +33,7 @@ class AttachableChangeDetector { @IMPLEMENTS(View) class HydrateAwareFakeView { isHydrated: boolean; - nodes: List; + nodes: List; changeDetector: ChangeDetector; rootElementInjectors; constructor(isHydrated) { diff --git a/modules/angular2/test/core/compiler/view_spec.js b/modules/angular2/test/core/compiler/view_spec.js index 978ef67721..0443b7675c 100644 --- a/modules/angular2/test/core/compiler/view_spec.js +++ b/modules/angular2/test/core/compiler/view_spec.js @@ -8,7 +8,7 @@ import {Lexer, Parser, DynamicProtoChangeDetector, ChangeDetector} from 'angular2/change_detection'; import {EventEmitter} from 'angular2/src/core/annotations/events'; import {List, MapWrapper} from 'angular2/src/facade/collection'; -import {DOM, Element} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {int, IMPLEMENTS} from 'angular2/src/facade/lang'; import {Injector} from 'angular2/di'; import {View} from 'angular2/src/core/compiler/view'; diff --git a/modules/angular2/test/core/events/event_manager_spec.js b/modules/angular2/test/core/events/event_manager_spec.js index 9c85b7e568..fef9a6f9f2 100644 --- a/modules/angular2/test/core/events/event_manager_spec.js +++ b/modules/angular2/test/core/events/event_manager_spec.js @@ -2,7 +2,8 @@ import {describe, ddescribe, it, iit, xit, xdescribe, expect, beforeEach, el} fr import {EventManager, EventManagerPlugin, DomEventsPlugin} from 'angular2/src/core/events/event_manager'; import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone'; import {List, ListWrapper, Map, MapWrapper} from 'angular2/src/facade/collection'; -import {DOM, Element, document} from 'angular2/src/facade/dom'; +import {document} from 'angular2/src/facade/browser'; +import {DOM} from 'angular2/src/dom/dom_adapter'; export function main() { var domEventPlugin; @@ -100,7 +101,7 @@ class FakeEventManagerPlugin extends EventManagerPlugin { return ListWrapper.contains(this._supports, eventName); } - addEventListener(element: Element, eventName: string, handler: Function, shouldSupportBubble: boolean) { + addEventListener(element, eventName: string, handler: Function, shouldSupportBubble: boolean) { MapWrapper.set(shouldSupportBubble ? this._bubbleEventHandlers : this._nonBubbleEventHandlers, eventName, handler); } diff --git a/modules/angular2/test/di/key_spec.js b/modules/angular2/test/di/key_spec.js index 5182ea7beb..1ecf54cad4 100644 --- a/modules/angular2/test/di/key_spec.js +++ b/modules/angular2/test/di/key_spec.js @@ -2,7 +2,6 @@ import {describe, iit, it, expect, beforeEach} from 'angular2/test_lib'; import {Key, KeyRegistry} from 'angular2/di'; export function main() { - describe("key", function () { var registry; diff --git a/modules/angular2/test/directives/foreach_spec.js b/modules/angular2/test/directives/foreach_spec.js index d17fadfef9..18e678707b 100644 --- a/modules/angular2/test/directives/foreach_spec.js +++ b/modules/angular2/test/directives/foreach_spec.js @@ -1,6 +1,6 @@ import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'angular2/test_lib'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {ListWrapper} from 'angular2/src/facade/collection'; import {Injector} from 'angular2/di'; diff --git a/modules/angular2/test/directives/if_spec.js b/modules/angular2/test/directives/if_spec.js index 37297af517..0992f247c0 100644 --- a/modules/angular2/test/directives/if_spec.js +++ b/modules/angular2/test/directives/if_spec.js @@ -1,6 +1,6 @@ import {describe, xit, it, expect, beforeEach, ddescribe, iit, el, IS_DARTIUM} from 'angular2/test_lib'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Injector} from 'angular2/di'; import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'angular2/change_detection'; diff --git a/modules/angular2/test/directives/non_bindable_spec.js b/modules/angular2/test/directives/non_bindable_spec.js index 71d51dc2a3..66e2f1508e 100644 --- a/modules/angular2/test/directives/non_bindable_spec.js +++ b/modules/angular2/test/directives/non_bindable_spec.js @@ -1,5 +1,5 @@ import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'angular2/test_lib'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Injector} from 'angular2/di'; import {Lexer, Parser, ChangeDetector, dynamicChangeDetection} from 'angular2/change_detection'; diff --git a/modules/angular2/test/directives/switch_spec.js b/modules/angular2/test/directives/switch_spec.js index e719ecc697..9d8e93e15f 100644 --- a/modules/angular2/test/directives/switch_spec.js +++ b/modules/angular2/test/directives/switch_spec.js @@ -1,5 +1,5 @@ import {describe, xit, it, expect, beforeEach, ddescribe, iit, el} from 'angular2/test_lib'; -import {DOM} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Injector} from 'angular2/di'; import {Lexer, Parser, dynamicChangeDetection} from 'angular2/change_detection'; diff --git a/modules/angular2/test/dom/html5lib_adapter.server.spec.dart b/modules/angular2/test/dom/html5lib_adapter.server.spec.dart new file mode 100644 index 0000000000..ccfad2c969 --- /dev/null +++ b/modules/angular2/test/dom/html5lib_adapter.server.spec.dart @@ -0,0 +1,20 @@ +library angular2.dom.html5lib_adapter.test; + +import 'package:guinness/guinness.dart'; +import 'package:unittest/unittest.dart' hide expect; +import 'package:angular2/src/dom/html5lib_adapter.dart'; + +// A smoke-test of the adapter. It is primarily tested by the compiler. +main() { + describe('Html5Lib DOM Adapter', () { + Html5LibDomAdapter subject; + + beforeEach(() { + subject = new Html5LibDomAdapter(); + }); + + it('should parse HTML', () { + expect(subject.parse('
hi
'), isNotNull); + }); + }); +} diff --git a/modules/benchmarks/src/change_detection/change_detection_benchmark.js b/modules/benchmarks/src/change_detection/change_detection_benchmark.js index 7df4cd7cf5..1fc86c47c5 100644 --- a/modules/benchmarks/src/change_detection/change_detection_benchmark.js +++ b/modules/benchmarks/src/change_detection/change_detection_benchmark.js @@ -2,6 +2,7 @@ import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection'; import {reflector} from 'angular2/src/reflection/reflection'; import {isPresent, isJsObject} from 'angular2/src/facade/lang'; import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util'; +import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter'; import { Lexer, @@ -135,6 +136,7 @@ function setUpChangeDetection(changeDetection:ChangeDetection, iterations) { } export function main () { + BrowserDomAdapter.makeCurrent(); var numberOfChecks = getIntParameter('numberOfChecks'); var numberOfChecksPerDetector = 10; diff --git a/modules/benchmarks/src/compiler/compiler_benchmark.js b/modules/benchmarks/src/compiler/compiler_benchmark.js index 22b2eb4d44..805396310d 100644 --- a/modules/benchmarks/src/compiler/compiler_benchmark.js +++ b/modules/benchmarks/src/compiler/compiler_benchmark.js @@ -1,5 +1,7 @@ -import {DOM, document} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; +import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter'; import {isBlank, Type} from 'angular2/src/facade/lang'; +import {document} from 'angular2/src/facade/browser'; import {MapWrapper} from 'angular2/src/facade/collection'; import {DirectiveMetadata} from 'angular2/src/core/compiler/directive_metadata'; import {NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy'; @@ -80,6 +82,7 @@ function setupReflector() { } export function main() { + BrowserDomAdapter.makeCurrent(); var count = getIntParameter('elements'); setupReflector(); diff --git a/modules/benchmarks/src/compiler/selector_benchmark.js b/modules/benchmarks/src/compiler/selector_benchmark.js index d97a97b8cf..846b1885fe 100644 --- a/modules/benchmarks/src/compiler/selector_benchmark.js +++ b/modules/benchmarks/src/compiler/selector_benchmark.js @@ -3,8 +3,10 @@ import {CssSelector} from "angular2/src/core/compiler/selector"; import {StringWrapper, Math} from 'angular2/src/facade/lang'; import {ListWrapper} from 'angular2/src/facade/collection'; import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util'; +import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter'; export function main() { + BrowserDomAdapter.makeCurrent(); var count = getIntParameter('selectors'); var fixedMatcher; diff --git a/modules/benchmarks/src/di/di_benchmark.js b/modules/benchmarks/src/di/di_benchmark.js index 39b54aa3bc..b57c77cbee 100644 --- a/modules/benchmarks/src/di/di_benchmark.js +++ b/modules/benchmarks/src/di/di_benchmark.js @@ -1,6 +1,7 @@ import {Injector, Key} from "angular2/di"; import {reflector} from 'angular2/src/reflection/reflection'; import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util'; +import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter'; var count = 0; @@ -33,6 +34,7 @@ function setupReflector() { } export function main() { + BrowserDomAdapter.makeCurrent(); var iterations = getIntParameter('iterations'); setupReflector(); diff --git a/modules/benchmarks/src/element_injector/element_injector_benchmark.js b/modules/benchmarks/src/element_injector/element_injector_benchmark.js index a88a17b044..8366ee7cc0 100644 --- a/modules/benchmarks/src/element_injector/element_injector_benchmark.js +++ b/modules/benchmarks/src/element_injector/element_injector_benchmark.js @@ -2,6 +2,7 @@ import {reflector} from 'angular2/src/reflection/reflection'; import {Injector} from 'angular2/di'; import {ProtoElementInjector} from 'angular2/src/core/compiler/element_injector'; import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util'; +import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter'; var count = 0; @@ -24,6 +25,7 @@ function setupReflector() { } export function main() { + BrowserDomAdapter.makeCurrent(); var iterations = getIntParameter('iterations'); setupReflector(); diff --git a/modules/benchmarks/src/naive_infinite_scroll/app.js b/modules/benchmarks/src/naive_infinite_scroll/app.js index 44662e6bca..da0511c4df 100644 --- a/modules/benchmarks/src/naive_infinite_scroll/app.js +++ b/modules/benchmarks/src/naive_infinite_scroll/app.js @@ -7,7 +7,8 @@ import {PromiseWrapper} from 'angular2/src/facade/async'; import {ListWrapper} from 'angular2/src/facade/collection'; import {ScrollAreaComponent} from './scroll_area'; import {If, Foreach} from 'angular2/directives'; -import {DOM, document, Element} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; +import {document} from 'angular2/src/facade/browser'; export class App { scrollAreas:List; @@ -68,7 +69,7 @@ export class App { }, 0); } - _locateFinishedMarker():Element { + _locateFinishedMarker() { return DOM.querySelector(document.body, '#done'); } diff --git a/modules/benchmarks/src/naive_infinite_scroll/index.js b/modules/benchmarks/src/naive_infinite_scroll/index.js index 3b0f9505e0..1bf7c058bb 100644 --- a/modules/benchmarks/src/naive_infinite_scroll/index.js +++ b/modules/benchmarks/src/naive_infinite_scroll/index.js @@ -1,5 +1,5 @@ import {int, isBlank} from 'angular2/src/facade/lang'; -import {Element} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {MapWrapper} from 'angular2/src/facade/collection'; import {Parser, Lexer, ChangeDetector, ChangeDetection} diff --git a/modules/benchmarks/src/naive_infinite_scroll/scroll_area.js b/modules/benchmarks/src/naive_infinite_scroll/scroll_area.js index 7120ec6433..44fdda7575 100644 --- a/modules/benchmarks/src/naive_infinite_scroll/scroll_area.js +++ b/modules/benchmarks/src/naive_infinite_scroll/scroll_area.js @@ -5,7 +5,7 @@ import {Component, Viewport, Template, ViewContainer, Compiler} from 'angular2/angular2'; import {PromiseWrapper} from 'angular2/src/facade/async'; import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection'; -import {Element} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Math} from 'angular2/src/facade/math'; import {Offering, ITEMS, ITEM_HEIGHT, VISIBLE_ITEMS, VIEW_PORT_HEIGHT, diff --git a/modules/benchmarks/src/naive_infinite_scroll/scroll_item.js b/modules/benchmarks/src/naive_infinite_scroll/scroll_item.js index 5a8e840950..751a72d3c5 100644 --- a/modules/benchmarks/src/naive_infinite_scroll/scroll_item.js +++ b/modules/benchmarks/src/naive_infinite_scroll/scroll_item.js @@ -4,7 +4,7 @@ import {Component, Viewport, Template, ViewContainer, Compiler} from 'angular2/angular2'; import {PromiseWrapper} from 'angular2/src/facade/async'; import {ListWrapper, MapWrapper} from 'angular2/src/facade/collection'; -import {Element} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {Math} from 'angular2/src/facade/math'; import {CompanyNameComponent, OpportunityNameComponent, OfferingNameComponent, StageButtonsComponent, AccountCellComponent, diff --git a/modules/benchmarks/src/tree/tree_benchmark.js b/modules/benchmarks/src/tree/tree_benchmark.js index 11ece23295..2602d24691 100644 --- a/modules/benchmarks/src/tree/tree_benchmark.js +++ b/modules/benchmarks/src/tree/tree_benchmark.js @@ -16,14 +16,16 @@ import {ComponentUrlMapper} from 'angular2/src/core/compiler/component_url_mappe import {StyleInliner} from 'angular2/src/core/compiler/style_inliner'; import {reflector} from 'angular2/src/reflection/reflection'; -import {DOM, document, window, Element, gc} from 'angular2/src/facade/dom'; +import {DOM} from 'angular2/src/dom/dom_adapter'; import {isPresent} from 'angular2/src/facade/lang'; +import {window, document, gc} from 'angular2/src/facade/browser'; import {getIntParameter, bindAction} from 'angular2/src/test_lib/benchmark_util'; import {XHR} from 'angular2/src/core/compiler/xhr/xhr'; import {XHRImpl} from 'angular2/src/core/compiler/xhr/xhr_impl'; import {If} from 'angular2/directives'; +import {BrowserDomAdapter} from 'angular2/src/dom/browser_adapter'; function setupReflector() { // TODO: Put the general calls to reflector.register... in a shared file @@ -188,9 +190,10 @@ function setupReflector() { } export function main() { - var maxDepth = getIntParameter('depth'); + BrowserDomAdapter.makeCurrent(); + var maxDepth = getIntParameter('depth'); - setupReflector(); + setupReflector(); var app; var lifeCycle; @@ -310,7 +313,7 @@ var BASELINE_IF_TEMPLATE = DOM.createTemplate( // http://jsperf.com/nextsibling-vs-childnodes class BaseLineTreeComponent { - element:Element; + element; value:BaseLineInterpolation; left:BaseLineIf; right:BaseLineIf; @@ -352,7 +355,7 @@ class BaseLineInterpolation { class BaseLineIf { condition:boolean; component:BaseLineTreeComponent; - anchor:Element; + anchor; constructor(anchor) { this.anchor = anchor; this.condition = false; diff --git a/test-main.dart b/test-main.dart index a1e5fc567b..33d0de13fa 100644 --- a/test-main.dart +++ b/test-main.dart @@ -1,7 +1,9 @@ import 'package:guinness/guinness.dart'; import 'package:unittest/unittest.dart' as unit; +import 'package:angular2/src/dom/browser_adapter.dart'; main() { + BrowserDomAdapter.makeCurrent(); unit.filterStacks = true; unit.formatStacks = false; unit.unittestConfiguration.timeout = new Duration(milliseconds: 100); diff --git a/test-main.js b/test-main.js index b3fd43dae3..caeeebc0f7 100644 --- a/test-main.js +++ b/test-main.js @@ -17,21 +17,25 @@ System.paths = { 'transpiler/*': '../tools/transpiler/*.js' } - // Import all the specs, execute their `main()` method and kick off Karma (Jasmine). -Promise.all( - Object.keys(window.__karma__.files) // All files served by Karma. - .filter(onlySpecFiles) - .map(window.file2moduleName) // Normalize paths to module names. - .map(function(path) { - return System.import(path).then(function(module) { - if (module.hasOwnProperty('main')) { - module.main() - } else { - throw new Error('Module ' + path + ' does not implement main() method.'); - } - }); - })).then(function() { +System.import('angular2/src/dom/browser_adapter').then(function(browser_adapter) { + browser_adapter.BrowserDomAdapter.makeCurrent(); +}).then(function() { + return Promise.all( + Object.keys(window.__karma__.files) // All files served by Karma. + .filter(onlySpecFiles) + .map(window.file2moduleName) // Normalize paths to module names. + .map(function(path) { + return System.import(path).then(function(module) { + if (module.hasOwnProperty('main')) { + module.main() + } else { + throw new Error('Module ' + path + ' does not implement main() method.'); + } + }); + })) +}) +.then(function() { __karma__.start(); }, function(error) { console.error(error.stack || error)