feat(shadowdom): turn on ShadowDom Emulated Mode by default.
Closes: #526
This commit is contained in:
parent
1d4ff9bcdc
commit
f1593ebca5
|
@ -14,7 +14,7 @@ import {List, ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
import {Promise, PromiseWrapper} from 'angular2/src/facade/async';
|
||||||
import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone';
|
import {VmTurnZone} from 'angular2/src/core/zone/vm_turn_zone';
|
||||||
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||||
import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
import {ShadowDomStrategy, NativeShadowDomStrategy, EmulatedUnscopedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||||
import {XHR} from 'angular2/src/core/compiler/xhr/xhr';
|
import {XHR} from 'angular2/src/core/compiler/xhr/xhr';
|
||||||
import {XHRImpl} from 'angular2/src/core/compiler/xhr/xhr_impl';
|
import {XHRImpl} from 'angular2/src/core/compiler/xhr/xhr_impl';
|
||||||
import {EventManager, DomEventsPlugin} from 'angular2/src/core/events/event_manager';
|
import {EventManager, DomEventsPlugin} from 'angular2/src/core/events/event_manager';
|
||||||
|
@ -84,7 +84,9 @@ function _injectorBindings(appComponentType): List<Binding> {
|
||||||
var plugins = [new HammerGesturesPlugin(), new DomEventsPlugin()];
|
var plugins = [new HammerGesturesPlugin(), new DomEventsPlugin()];
|
||||||
return new EventManager(plugins, zone);
|
return new EventManager(plugins, zone);
|
||||||
}, [VmTurnZone]),
|
}, [VmTurnZone]),
|
||||||
bind(ShadowDomStrategy).toClass(NativeShadowDomStrategy),
|
bind(ShadowDomStrategy).toFactory(
|
||||||
|
(styleUrlResolver, doc) => new EmulatedUnscopedShadowDomStrategy(styleUrlResolver, doc.head),
|
||||||
|
[StyleUrlResolver, appDocumentToken]),
|
||||||
Compiler,
|
Compiler,
|
||||||
CompilerCache,
|
CompilerCache,
|
||||||
TemplateResolver,
|
TemplateResolver,
|
||||||
|
|
|
@ -36,6 +36,7 @@ export class LightDom {
|
||||||
this.lightDomView = lightDomView;
|
this.lightDomView = lightDomView;
|
||||||
this.shadowDomView = shadowDomView;
|
this.shadowDomView = shadowDomView;
|
||||||
this.nodes = DOM.childNodesAsList(element);
|
this.nodes = DOM.childNodesAsList(element);
|
||||||
|
|
||||||
this.roots = null;
|
this.roots = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ export class EmulatedUnscopedShadowDomStrategy extends ShadowDomStrategy {
|
||||||
this._styleHost = styleHost;
|
this._styleHost = styleHost;
|
||||||
}
|
}
|
||||||
|
|
||||||
attachTemplate(el, view:viewModule.View){
|
attachTemplate(el, view:viewModule.View) {
|
||||||
DOM.clearNodes(el);
|
DOM.clearNodes(el);
|
||||||
_moveViewNodesIntoParent(el, view);
|
_moveViewNodesIntoParent(el, view);
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,9 @@ export class BrowserDomAdapter extends GenericBrowserDomAdapter {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
clearNodes(el) {
|
clearNodes(el) {
|
||||||
el.innerHTML = '';
|
for (var i = 0; i < el.childNodes.length; i++) {
|
||||||
|
this.remove(el.childNodes[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
appendChild(el, node) {
|
appendChild(el, node) {
|
||||||
el.appendChild(node);
|
el.appendChild(node);
|
||||||
|
|
|
@ -18,6 +18,12 @@ class HelloRootCmp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component({selector: 'hello-app'})
|
||||||
|
@Template({inline: 'before: <content></content> after: done'})
|
||||||
|
class HelloRootCmpContent {
|
||||||
|
constructor() { }
|
||||||
|
}
|
||||||
|
|
||||||
@Component({selector: 'hello-app-2'})
|
@Component({selector: 'hello-app-2'})
|
||||||
@Template({inline: '{{greeting}} world, again!'})
|
@Template({inline: '{{greeting}} world, again!'})
|
||||||
class HelloRootCmp2 {
|
class HelloRootCmp2 {
|
||||||
|
@ -48,14 +54,17 @@ class HelloRootCmp4 {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
var fakeDoc, el, el2, testBindings;
|
var fakeDoc, el, el2, testBindings, lightDom;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fakeDoc = DOM.createHtmlDocument();
|
fakeDoc = DOM.createHtmlDocument();
|
||||||
el = DOM.createElement('hello-app', fakeDoc);
|
el = DOM.createElement('hello-app', fakeDoc);
|
||||||
el2 = DOM.createElement('hello-app-2', fakeDoc);
|
el2 = DOM.createElement('hello-app-2', fakeDoc);
|
||||||
|
lightDom = DOM.createElement('light-dom-el', fakeDoc);
|
||||||
DOM.appendChild(fakeDoc.body, el);
|
DOM.appendChild(fakeDoc.body, el);
|
||||||
DOM.appendChild(fakeDoc.body, el2);
|
DOM.appendChild(fakeDoc.body, el2);
|
||||||
|
DOM.appendChild(el, lightDom);
|
||||||
|
DOM.setText(lightDom, 'loading');
|
||||||
testBindings = [bind(appDocumentToken).toValue(fakeDoc)];
|
testBindings = [bind(appDocumentToken).toValue(fakeDoc)];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -93,8 +102,7 @@ export function main() {
|
||||||
it('should display hello world', (done) => {
|
it('should display hello world', (done) => {
|
||||||
var injectorPromise = bootstrap(HelloRootCmp, testBindings);
|
var injectorPromise = bootstrap(HelloRootCmp, testBindings);
|
||||||
injectorPromise.then((injector) => {
|
injectorPromise.then((injector) => {
|
||||||
expect(injector.get(appElementToken)
|
expect(injector.get(appElementToken)).toHaveText('hello world!');
|
||||||
.shadowRoot.childNodes[0].nodeValue).toEqual('hello world!');
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -103,10 +111,8 @@ export function main() {
|
||||||
var injectorPromise1 = bootstrap(HelloRootCmp, testBindings);
|
var injectorPromise1 = bootstrap(HelloRootCmp, testBindings);
|
||||||
var injectorPromise2 = bootstrap(HelloRootCmp2, testBindings);
|
var injectorPromise2 = bootstrap(HelloRootCmp2, testBindings);
|
||||||
PromiseWrapper.all([injectorPromise1, injectorPromise2]).then((injectors) => {
|
PromiseWrapper.all([injectorPromise1, injectorPromise2]).then((injectors) => {
|
||||||
expect(injectors[0].get(appElementToken)
|
expect(injectors[0].get(appElementToken)).toHaveText('hello world!');
|
||||||
.shadowRoot.childNodes[0].nodeValue).toEqual('hello world!');
|
expect(injectors[1].get(appElementToken)).toHaveText('hello world, again!');
|
||||||
expect(injectors[1].get(appElementToken)
|
|
||||||
.shadowRoot.childNodes[0].nodeValue).toEqual('hello world, again!');
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -131,5 +137,13 @@ export function main() {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should support shadow dom content tag", (done) => {
|
||||||
|
var injectorPromise = bootstrap(HelloRootCmpContent, testBindings);
|
||||||
|
injectorPromise.then((injector) => {
|
||||||
|
expect(injector.get(appElementToken)).toHaveText('before: loading after: done');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,11 +9,11 @@ describe('ng2 naive infinite scroll benchmark', function () {
|
||||||
it('should not throw errors', function() {
|
it('should not throw errors', function() {
|
||||||
browser.get(URL);
|
browser.get(URL);
|
||||||
var expectedRowCount = 18;
|
var expectedRowCount = 18;
|
||||||
var expectedCellsPerRow = 11;
|
var expectedCellsPerRow = 28;
|
||||||
var allScrollItems = 'scroll-app /deep/ #testArea /deep/ scroll-item';
|
var allScrollItems = 'scroll-app #testArea scroll-item';
|
||||||
var cells = `${ allScrollItems } /deep/ .row *`;
|
var cells = `${ allScrollItems } .row *`;
|
||||||
var stageButtons =
|
var stageButtons =
|
||||||
`${ allScrollItems } /deep/ .row stage-buttons /deep/ button`;
|
`${ allScrollItems } .row stage-buttons button`;
|
||||||
|
|
||||||
var count = function(selector) {
|
var count = function(selector) {
|
||||||
return browser.executeScript(
|
return browser.executeScript(
|
||||||
|
|
|
@ -6,12 +6,14 @@ import {Parser, Lexer, ChangeDetector, ChangeDetection}
|
||||||
from 'angular2/change_detection';
|
from 'angular2/change_detection';
|
||||||
import {ExceptionHandler} from 'angular2/src/core/exception_handler';
|
import {ExceptionHandler} from 'angular2/src/core/exception_handler';
|
||||||
import {
|
import {
|
||||||
bootstrap, Component, Viewport, Template, ViewContainer, Compiler, onChange
|
bootstrap, Component, Viewport, Template, ViewContainer, Compiler, onChange, NgElement, Decorator
|
||||||
} from 'angular2/angular2';
|
} from 'angular2/angular2';
|
||||||
import {Reflector, reflector} from 'angular2/src/reflection/reflection';
|
import {Reflector, reflector} from 'angular2/src/reflection/reflection';
|
||||||
import {CompilerCache} from 'angular2/src/core/compiler/compiler';
|
import {CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||||
import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
import {ShadowDomStrategy, NativeShadowDomStrategy, EmulatedUnscopedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||||
|
import {Content} from 'angular2/src/core/compiler/shadow_dom_emulation/content_tag';
|
||||||
|
import {DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
|
||||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||||
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||||
|
@ -256,6 +258,12 @@ export function setupReflectorForAngular() {
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
reflector.registerType(EmulatedUnscopedShadowDomStrategy, {
|
||||||
|
"factory": (styleUrlResolver) => new EmulatedUnscopedShadowDomStrategy(styleUrlResolver, null),
|
||||||
|
"parameters": [[StyleUrlResolver]],
|
||||||
|
"annotations": []
|
||||||
|
});
|
||||||
|
|
||||||
reflector.registerType(StyleUrlResolver, {
|
reflector.registerType(StyleUrlResolver, {
|
||||||
"factory": (urlResolver) => new StyleUrlResolver(urlResolver),
|
"factory": (urlResolver) => new StyleUrlResolver(urlResolver),
|
||||||
"parameters": [[UrlResolver]],
|
"parameters": [[UrlResolver]],
|
||||||
|
@ -274,6 +282,12 @@ export function setupReflectorForAngular() {
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
reflector.registerType(Content, {
|
||||||
|
"factory": (lightDom, el) => new Content(lightDom, el),
|
||||||
|
"parameters": [[DestinationLightDom], [NgElement]],
|
||||||
|
"annotations" : [new Decorator({selector: '[content]'})]
|
||||||
|
});
|
||||||
|
|
||||||
reflector.registerType(StyleInliner, {
|
reflector.registerType(StyleInliner, {
|
||||||
"factory": (xhr, styleUrlResolver, urlResolver) =>
|
"factory": (xhr, styleUrlResolver, urlResolver) =>
|
||||||
new StyleInliner(xhr, styleUrlResolver, urlResolver),
|
new StyleInliner(xhr, styleUrlResolver, urlResolver),
|
||||||
|
|
|
@ -2,13 +2,15 @@ import {Parser, Lexer, ChangeDetector, ChangeDetection, jitChangeDetection}
|
||||||
from 'angular2/change_detection';
|
from 'angular2/change_detection';
|
||||||
import {ExceptionHandler} from 'angular2/src/core/exception_handler';
|
import {ExceptionHandler} from 'angular2/src/core/exception_handler';
|
||||||
|
|
||||||
import {bootstrap, Component, Viewport, Template, ViewContainer, Compiler} from 'angular2/angular2';
|
import {bootstrap, Component, Viewport, Template, ViewContainer, Compiler, NgElement, Decorator} from 'angular2/angular2';
|
||||||
|
|
||||||
import {CompilerCache} from 'angular2/src/core/compiler/compiler';
|
import {CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||||
import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
import {ShadowDomStrategy, NativeShadowDomStrategy, EmulatedUnscopedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||||
|
import {Content} from 'angular2/src/core/compiler/shadow_dom_emulation/content_tag';
|
||||||
|
import {DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
|
||||||
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||||
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
import {UrlResolver} from 'angular2/src/core/compiler/url_resolver';
|
||||||
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
import {StyleUrlResolver} from 'angular2/src/core/compiler/style_url_resolver';
|
||||||
|
@ -127,12 +129,24 @@ function setupReflector() {
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
reflector.registerType(EmulatedUnscopedShadowDomStrategy, {
|
||||||
|
"factory": (styleUrlResolver) => new EmulatedUnscopedShadowDomStrategy(styleUrlResolver, null),
|
||||||
|
"parameters": [[StyleUrlResolver]],
|
||||||
|
"annotations": []
|
||||||
|
});
|
||||||
|
|
||||||
reflector.registerType(StyleUrlResolver, {
|
reflector.registerType(StyleUrlResolver, {
|
||||||
"factory": (urlResolver) => new StyleUrlResolver(urlResolver),
|
"factory": (urlResolver) => new StyleUrlResolver(urlResolver),
|
||||||
"parameters": [[UrlResolver]],
|
"parameters": [[UrlResolver]],
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
reflector.registerType(Content, {
|
||||||
|
"factory": (lightDom, el) => new Content(lightDom, el),
|
||||||
|
"parameters": [[DestinationLightDom], [NgElement]],
|
||||||
|
"annotations" : [new Decorator({selector: '[content]'})]
|
||||||
|
});
|
||||||
|
|
||||||
reflector.registerType(UrlResolver, {
|
reflector.registerType(UrlResolver, {
|
||||||
"factory": () => new UrlResolver(),
|
"factory": () => new UrlResolver(),
|
||||||
"parameters": [],
|
"parameters": [],
|
||||||
|
|
|
@ -40,9 +40,9 @@ describe('hello world', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
function getComponentText(selector, innerSelector) {
|
function getComponentText(selector, innerSelector) {
|
||||||
return browser.executeScript('return document.querySelector("'+selector+'").shadowRoot.querySelector("'+innerSelector+'").textContent');
|
return browser.executeScript('return document.querySelector("'+selector+'").querySelector("'+innerSelector+'").textContent');
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickComponentButton(selector, innerSelector) {
|
function clickComponentButton(selector, innerSelector) {
|
||||||
return browser.executeScript('return document.querySelector("'+selector+'").shadowRoot.querySelector("'+innerSelector+'").click()');
|
return browser.executeScript('return document.querySelector("'+selector+'").querySelector("'+innerSelector+'").click()');
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,9 @@ import {LifeCycle} from 'angular2/src/core/life_cycle/life_cycle';
|
||||||
|
|
||||||
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
import {Compiler, CompilerCache} from 'angular2/src/core/compiler/compiler';
|
||||||
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
import {DirectiveMetadataReader} from 'angular2/src/core/compiler/directive_metadata_reader';
|
||||||
import {ShadowDomStrategy, NativeShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
import {ShadowDomStrategy, NativeShadowDomStrategy, EmulatedUnscopedShadowDomStrategy} from 'angular2/src/core/compiler/shadow_dom_strategy';
|
||||||
|
import {Content} from 'angular2/src/core/compiler/shadow_dom_emulation/content_tag';
|
||||||
|
import {DestinationLightDom} from 'angular2/src/core/compiler/shadow_dom_emulation/light_dom';
|
||||||
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
import {TemplateLoader} from 'angular2/src/core/compiler/template_loader';
|
||||||
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
import {TemplateResolver} from 'angular2/src/core/compiler/template_resolver';
|
||||||
import {XHR} from 'angular2/src/core/compiler/xhr/xhr';
|
import {XHR} from 'angular2/src/core/compiler/xhr/xhr';
|
||||||
|
@ -125,6 +127,12 @@ function setup() {
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
reflector.registerType(EmulatedUnscopedShadowDomStrategy, {
|
||||||
|
"factory": (styleUrlResolver) => new EmulatedUnscopedShadowDomStrategy(styleUrlResolver, null),
|
||||||
|
"parameters": [[StyleUrlResolver]],
|
||||||
|
"annotations": []
|
||||||
|
});
|
||||||
|
|
||||||
reflector.registerType(StyleUrlResolver, {
|
reflector.registerType(StyleUrlResolver, {
|
||||||
"factory": (urlResolver) => new StyleUrlResolver(urlResolver),
|
"factory": (urlResolver) => new StyleUrlResolver(urlResolver),
|
||||||
"parameters": [[UrlResolver]],
|
"parameters": [[UrlResolver]],
|
||||||
|
@ -143,6 +151,12 @@ function setup() {
|
||||||
"annotations": []
|
"annotations": []
|
||||||
});
|
});
|
||||||
|
|
||||||
|
reflector.registerType(Content, {
|
||||||
|
"factory": (lightDom, el) => new Content(lightDom, el),
|
||||||
|
"parameters": [[DestinationLightDom], [NgElement]],
|
||||||
|
"annotations" : [new Decorator({selector: '[content]'})]
|
||||||
|
});
|
||||||
|
|
||||||
reflector.registerType(StyleInliner, {
|
reflector.registerType(StyleInliner, {
|
||||||
"factory": (xhr, styleUrlResolver, urlResolver) =>
|
"factory": (xhr, styleUrlResolver, urlResolver) =>
|
||||||
new StyleInliner(xhr, styleUrlResolver, urlResolver),
|
new StyleInliner(xhr, styleUrlResolver, urlResolver),
|
||||||
|
|
Loading…
Reference in New Issue