chore: move core modules into core directory

BREAKING CHANGE:
    This change moves the http module into angular2/, so its import
    path is now angular2/http instead of http/http.

    Many other modules have also been moved around inside of angular2,
    but the public API paths have not changed as of this commit.
This commit is contained in:
Jeff Cross
2015-08-20 14:28:09 -07:00
parent 56e88058f1
commit 38a5a2a955
260 changed files with 0 additions and 0 deletions

View File

@ -0,0 +1,468 @@
library angular.core.facade.dom;
import 'dart:html';
import 'dom_adapter.dart' show setRootDomAdapter;
import 'generic_browser_adapter.dart' show GenericBrowserDomAdapter;
import '../facade/browser.dart';
import 'dart:js' as js;
// 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();
final _keyCodeToKeyMap = const {
8: 'Backspace',
9: 'Tab',
12: 'Clear',
13: 'Enter',
16: 'Shift',
17: 'Control',
18: 'Alt',
19: 'Pause',
20: 'CapsLock',
27: 'Escape',
32: ' ',
33: 'PageUp',
34: 'PageDown',
35: 'End',
36: 'Home',
37: 'ArrowLeft',
38: 'ArrowUp',
39: 'ArrowRight',
40: 'ArrowDown',
45: 'Insert',
46: 'Delete',
65: 'a',
66: 'b',
67: 'c',
68: 'd',
69: 'e',
70: 'f',
71: 'g',
72: 'h',
73: 'i',
74: 'j',
75: 'k',
76: 'l',
77: 'm',
78: 'n',
79: 'o',
80: 'p',
81: 'q',
82: 'r',
83: 's',
84: 't',
85: 'u',
86: 'v',
87: 'w',
88: 'x',
89: 'y',
90: 'z',
91: 'OS',
93: 'ContextMenu',
96: '0',
97: '1',
98: '2',
99: '3',
100: '4',
101: '5',
102: '6',
103: '7',
104: '8',
105: '9',
106: '*',
107: '+',
109: '-',
110: '.',
111: '/',
112: 'F1',
113: 'F2',
114: 'F3',
115: 'F4',
116: 'F5',
117: 'F6',
118: 'F7',
119: 'F8',
120: 'F9',
121: 'F10',
122: 'F11',
123: 'F12',
144: 'NumLock',
145: 'ScrollLock'
};
final bool _supportsTemplateElement = () {
try {
return new TemplateElement().content != null;
} catch(_) {
return false;
}
}();
class BrowserDomAdapter extends GenericBrowserDomAdapter {
js.JsFunction _setProperty;
js.JsFunction _getProperty;
js.JsFunction _hasProperty;
Map<String, bool> _hasPropertyCache;
BrowserDomAdapter() {
_hasPropertyCache = new Map();
_setProperty = js.context.callMethod(
'eval', ['(function(el, prop, value) { el[prop] = value; })']);
_getProperty = js.context
.callMethod('eval', ['(function(el, prop) { return el[prop]; })']);
_hasProperty = js.context
.callMethod('eval', ['(function(el, prop) { return prop in el; })']);
}
static void makeCurrent() {
setRootDomAdapter(new BrowserDomAdapter());
}
bool hasProperty(Element element, String name) {
// Always return true as the serverside version html_adapter.dart does so.
// TODO: change this once we have schema support.
// Note: This nees to kept in sync with html_adapter.dart!
return true;
}
void setProperty(Element element, String name, Object value) {
var cacheKey = "${element.tagName}.${name}";
var hasProperty = this._hasPropertyCache[cacheKey];
if (hasProperty == null) {
hasProperty = this._hasProperty.apply([element, name]);
this._hasPropertyCache[cacheKey] = hasProperty;
}
if (hasProperty) {
_setProperty.apply([element, name, value]);
}
}
getProperty(Element element, String name) =>
_getProperty.apply([element, name]);
invoke(Element element, String methodName, List args) =>
this.getProperty(element, methodName).apply(args, thisArg: element);
// TODO(tbosch): move this into a separate environment class once we have it
logError(error) {
window.console.error(error);
}
log(error) {
window.console.log(error);
}
logGroup(error) {
window.console.group(error);
}
logGroupEnd() {
window.console.groupEnd();
}
@override
Map<String, String> get attrToPropMap => const <String, String>{
'class': 'className',
'innerHtml': 'innerHTML',
'readonly': 'readOnly',
'tabindex': 'tabIndex',
};
Element 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);
}
Function onAndCancel(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.
var subscription = element.on[event].listen(callback);
return subscription.cancel;
}
void dispatchEvent(EventTarget el, Event evt) {
el.dispatchEvent(evt);
}
MouseEvent createMouseEvent(String eventType) =>
new MouseEvent(eventType, canBubble: true);
Event createEvent(String eventType) => new Event(eventType, canBubble: true);
void preventDefault(Event evt) {
evt.preventDefault();
}
bool isPrevented(Event evt) {
return evt.defaultPrevented;
}
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) => _supportsTemplateElement ? el.content : el;
Node firstChild(el) => el.firstChild;
Node nextSibling(Node el) => el.nextNode;
Element parentElement(Node el) => el.parent;
List<Node> 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(el, Node node) {
node.remove();
}
void replaceChild(Node el, Node newNode, Node oldNode) {
oldNode.replaceWith(newNode);
}
ChildNode remove(ChildNode el) {
return el..remove();
}
void insertBefore(Node el, node) {
el.parentNode.insertBefore(node, el);
}
void insertAllBefore(Node el, Iterable<Node> 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(el) => el.value;
void setValue(el, String value) {
el.value = value;
}
bool getChecked(InputElement el) => el.checked;
void setChecked(InputElement el, bool isChecked) {
el.checked = isChecked;
}
Comment createComment(String text) {
return new Comment(text);
}
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);
}
Text 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;
Element getHost(Element el) => (el as ShadowRoot).host;
clone(Node node) => node.clone(true);
List<Node> getElementsByClassName(Element element, String name) =>
element.getElementsByClassName(name);
List<Node> getElementsByTagName(Element element, String name) =>
element.querySelectorAll(name);
List<String> 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);
void setStyle(Element element, String stylename, String stylevalue) {
element.style.setProperty(stylename, stylevalue);
}
void removeStyle(Element element, String stylename) {
element.style.removeProperty(stylename);
}
String getStyle(Element element, String stylename) {
return element.style.getPropertyValue(stylename);
}
String tagName(Element element) => element.tagName;
Map<String, String> attributeMap(Element element) {
return new Map.from(element.attributes);
}
bool hasAttribute(Element element, String attribute) =>
element.attributes.containsKey(attribute);
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;
Rectangle getBoundingClientRect(el) => el.getBoundingClientRect();
String getTitle() => document.title;
void setTitle(String newTitle) {
document.title = newTitle;
}
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;
}
bool isShadowRoot(Node node) {
return node is ShadowRoot;
}
Node importIntoDoc(Node node) {
return document.importNode(node, true);
}
Node adoptNode(Node node) {
return document.adoptNode(node);
}
bool isPageRule(CssRule rule) => rule is CssPageRule;
bool isStyleRule(CssRule rule) => rule is CssStyleRule;
bool isMediaRule(CssRule rule) => rule is CssMediaRule;
bool isKeyframesRule(CssRule rule) => rule is CssKeyframesRule;
String getHref(AnchorElement element) {
return element.href;
}
String getEventKey(KeyboardEvent event) {
int keyCode = event.keyCode;
return _keyCodeToKeyMap.containsKey(keyCode)
? _keyCodeToKeyMap[keyCode]
: 'Unidentified';
}
getGlobalEventTarget(String target) {
if (target == "window") {
return window;
} else if (target == "document") {
return document;
} else if (target == "body") {
return document.body;
}
}
getHistory() {
return window.history;
}
getLocation() {
return window.location;
}
getBaseHref() {
var href = getBaseElementHref();
if (href == null) {
return null;
}
var baseUri = Uri.parse(href);
return baseUri.path[0] == '/' ? baseUri.path : ('/' + baseUri.path);
}
resetBaseElement() {
baseElement = null;
}
String getUserAgent() {
return window.navigator.userAgent;
}
void setData(Element element, String name, String value) {
element.dataset[name] = value;
}
String getData(Element element, String name) {
return element.dataset[name];
}
// TODO(tbosch): move this into a separate environment class once we have it
setGlobalVar(String name, value) {
js.context[name] = value;
}
}
var baseElement = null;
String getBaseElementHref() {
if (baseElement == null) {
baseElement = document.querySelector('base');
if (baseElement == null) {
return null;
}
}
return baseElement.getAttribute('href');
}

View File

@ -0,0 +1,340 @@
import {List, MapWrapper, ListWrapper} from 'angular2/src/facade/collection';
import {isBlank, isPresent, global} from 'angular2/src/facade/lang';
import {setRootDomAdapter} from './dom_adapter';
import {GenericBrowserDomAdapter} from './generic_browser_adapter';
var _attrToPropMap = {
'class': 'className',
'innerHtml': 'innerHTML',
'readonly': 'readOnly',
'tabindex': 'tabIndex'
};
const DOM_KEY_LOCATION_NUMPAD = 3;
// Map to convert some key or keyIdentifier values to what will be returned by getEventKey
var _keyMap = {
// The following values are here for cross-browser compatibility and to match the W3C standard
// cf http://www.w3.org/TR/DOM-Level-3-Events-key/
'\b': 'Backspace',
'\t': 'Tab',
'\x7F': 'Delete',
'\x1B': 'Escape',
'Del': 'Delete',
'Esc': 'Escape',
'Left': 'ArrowLeft',
'Right': 'ArrowRight',
'Up': 'ArrowUp',
'Down': 'ArrowDown',
'Menu': 'ContextMenu',
'Scroll': 'ScrollLock',
'Win': 'OS'
};
// There is a bug in Chrome for numeric keypad keys:
// https://code.google.com/p/chromium/issues/detail?id=155654
// 1, 2, 3 ... are reported as A, B, C ...
var _chromeNumKeyPadMap = {
'A': '1',
'B': '2',
'C': '3',
'D': '4',
'E': '5',
'F': '6',
'G': '7',
'H': '8',
'I': '9',
'J': '*',
'K': '+',
'M': '-',
'N': '.',
'O': '/',
'\x60': '0',
'\x90': 'NumLock'
};
/* tslint:disable:requireParameterType */
export class BrowserDomAdapter extends GenericBrowserDomAdapter {
static makeCurrent() { setRootDomAdapter(new BrowserDomAdapter()); }
hasProperty(element, name: string): boolean { return name in element; }
setProperty(el: /*element*/ any, name: string, value: any) { el[name] = value; }
getProperty(el: /*element*/ any, name: string): any { return el[name]; }
invoke(el: /*element*/ any, methodName: string, args: List<any>): any {
el[methodName].apply(el, args);
}
// TODO(tbosch): move this into a separate environment class once we have it
logError(error) { window.console.error(error); }
log(error) { window.console.log(error); }
logGroup(error) {
if (window.console.group) {
window.console.group(error);
} else {
window.console.log(error);
}
}
logGroupEnd() {
if (window.console.groupEnd) {
window.console.groupEnd();
}
}
get attrToPropMap(): any { return _attrToPropMap; }
query(selector: string): any { return document.querySelector(selector); }
querySelector(el, selector: string): HTMLElement { return el.querySelector(selector); }
querySelectorAll(el, selector: string): List<any> { return el.querySelectorAll(selector); }
on(el, evt, listener) { el.addEventListener(evt, listener, false); }
onAndCancel(el, evt, listener): Function {
el.addEventListener(evt, listener, false);
// Needed to follow Dart's subscription semantic, until fix of
// https://code.google.com/p/dart/issues/detail?id=17406
return () => { el.removeEventListener(evt, listener, false); };
}
dispatchEvent(el, evt) { el.dispatchEvent(evt); }
createMouseEvent(eventType: string): MouseEvent {
var evt: MouseEvent = document.createEvent('MouseEvent');
evt.initEvent(eventType, true, true);
return evt;
}
createEvent(eventType): Event {
var evt: Event = document.createEvent('Event');
evt.initEvent(eventType, true, true);
return evt;
}
preventDefault(evt: Event) {
evt.preventDefault();
evt.returnValue = false;
}
isPrevented(evt: Event): boolean {
return evt.defaultPrevented || isPresent(evt.returnValue) && !evt.returnValue;
}
getInnerHTML(el): string { return el.innerHTML; }
getOuterHTML(el): string { return el.outerHTML; }
nodeName(node: Node): string { return node.nodeName; }
nodeValue(node: Node): string { return node.nodeValue; }
type(node: HTMLInputElement): string { return node.type; }
content(node: Node): Node {
if (this.hasProperty(node, "content")) {
return (<any>node).content;
} else {
return node;
}
}
firstChild(el): Node { return el.firstChild; }
nextSibling(el): Node { return el.nextSibling; }
parentElement(el): Node { return el.parentNode; }
childNodes(el): List<Node> { return el.childNodes; }
childNodesAsList(el): List<any> {
var childNodes = el.childNodes;
var res = ListWrapper.createFixedSize(childNodes.length);
for (var i = 0; i < childNodes.length; i++) {
res[i] = childNodes[i];
}
return res;
}
clearNodes(el) {
while (el.firstChild) {
el.removeChild(el.firstChild);
}
}
appendChild(el, node) { el.appendChild(node); }
removeChild(el, node) { el.removeChild(node); }
replaceChild(el: Node, newChild, oldChild) { el.replaceChild(newChild, oldChild); }
remove(node): Node {
node.parentNode.removeChild(node);
return node;
}
insertBefore(el, node) { el.parentNode.insertBefore(node, el); }
insertAllBefore(el, nodes) {
ListWrapper.forEach(nodes, (n) => { el.parentNode.insertBefore(n, el); });
}
insertAfter(el, node) { el.parentNode.insertBefore(node, el.nextSibling); }
setInnerHTML(el, value) { el.innerHTML = value; }
getText(el): string { return el.textContent; }
// TODO(vicb): removed Element type because it does not support StyleElement
setText(el, value: string) { el.textContent = value; }
getValue(el): string { return el.value; }
setValue(el, value: string) { el.value = value; }
getChecked(el): boolean { return el.checked; }
setChecked(el, value: boolean) { el.checked = value; }
createComment(text: string): Comment { return document.createComment(text); }
createTemplate(html): HTMLElement {
var t = document.createElement('template');
t.innerHTML = html;
return t;
}
createElement(tagName, doc = document): HTMLElement { return doc.createElement(tagName); }
createTextNode(text: string, doc = document): Text { return doc.createTextNode(text); }
createScriptTag(attrName: string, attrValue: string, doc = document): HTMLScriptElement {
var el = <HTMLScriptElement>doc.createElement('SCRIPT');
el.setAttribute(attrName, attrValue);
return el;
}
createStyleElement(css: string, doc = document): HTMLStyleElement {
var style = <HTMLStyleElement>doc.createElement('style');
this.appendChild(style, this.createTextNode(css));
return style;
}
createShadowRoot(el: HTMLElement): DocumentFragment { return (<any>el).createShadowRoot(); }
getShadowRoot(el: HTMLElement): DocumentFragment { return (<any>el).shadowRoot; }
getHost(el: HTMLElement): HTMLElement { return (<any>el).host; }
clone(node: Node): Node { return node.cloneNode(true); }
getElementsByClassName(element, name: string): List<HTMLElement> {
return element.getElementsByClassName(name);
}
getElementsByTagName(element, name: string): List<HTMLElement> {
return element.getElementsByTagName(name);
}
classList(element): List<any> {
return <List<any>>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): boolean { 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): string { return element.style[stylename]; }
tagName(element): string { return element.tagName; }
attributeMap(element): Map<string, string> {
var res = new Map();
var elAttrs = element.attributes;
for (var i = 0; i < elAttrs.length; i++) {
var attrib = elAttrs[i];
res.set(attrib.name, attrib.value);
}
return res;
}
hasAttribute(element, attribute: string): boolean { return element.hasAttribute(attribute); }
getAttribute(element, attribute: string): string { return element.getAttribute(attribute); }
setAttribute(element, name: string, value: string) { element.setAttribute(name, value); }
removeAttribute(element, attribute: string) { element.removeAttribute(attribute); }
templateAwareRoot(el): any { return this.isTemplateElement(el) ? this.content(el) : el; }
createHtmlDocument(): HTMLDocument {
return document.implementation.createHTMLDocument('fakeTitle');
}
defaultDoc(): HTMLDocument { return document; }
getBoundingClientRect(el): any {
try {
return el.getBoundingClientRect();
} catch (e) {
return {top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0};
}
}
getTitle(): string { return document.title; }
setTitle(newTitle: string) { document.title = newTitle || ''; }
elementMatches(n, selector: string): boolean {
var matches = false;
if (n instanceof HTMLElement) {
if (n.matches) {
matches = n.matches(selector);
} else if (n.msMatchesSelector) {
matches = n.msMatchesSelector(selector);
} else if (n.webkitMatchesSelector) {
matches = n.webkitMatchesSelector(selector);
}
}
return matches;
}
isTemplateElement(el: any): boolean {
return el instanceof HTMLElement && el.nodeName == "TEMPLATE";
}
isTextNode(node: Node): boolean { return node.nodeType === Node.TEXT_NODE; }
isCommentNode(node: Node): boolean { return node.nodeType === Node.COMMENT_NODE; }
isElementNode(node: Node): boolean { return node.nodeType === Node.ELEMENT_NODE; }
hasShadowRoot(node): boolean { return node instanceof HTMLElement && isPresent(node.shadowRoot); }
isShadowRoot(node): boolean { return node instanceof DocumentFragment; }
importIntoDoc(node: Node): any {
var toImport = node;
if (this.isTemplateElement(node)) {
toImport = this.content(node);
}
return document.importNode(toImport, true);
}
adoptNode(node: Node): any { return document.adoptNode(node); }
isPageRule(rule): boolean { return rule.type === CSSRule.PAGE_RULE; }
isStyleRule(rule): boolean { return rule.type === CSSRule.STYLE_RULE; }
isMediaRule(rule): boolean { return rule.type === CSSRule.MEDIA_RULE; }
isKeyframesRule(rule): boolean { return rule.type === CSSRule.KEYFRAMES_RULE; }
getHref(el: Element): string { return (<any>el).href; }
getEventKey(event): string {
var key = event.key;
if (isBlank(key)) {
key = event.keyIdentifier;
// keyIdentifier is defined in the old draft of DOM Level 3 Events implemented by Chrome and
// Safari
// cf
// http://www.w3.org/TR/2007/WD-DOM-Level-3-Events-20071221/events.html#Events-KeyboardEvents-Interfaces
if (isBlank(key)) {
return 'Unidentified';
}
if (key.startsWith('U+')) {
key = String.fromCharCode(parseInt(key.substring(2), 16));
if (event.location === DOM_KEY_LOCATION_NUMPAD && _chromeNumKeyPadMap.hasOwnProperty(key)) {
// There is a bug in Chrome for numeric keypad keys:
// https://code.google.com/p/chromium/issues/detail?id=155654
// 1, 2, 3 ... are reported as A, B, C ...
key = _chromeNumKeyPadMap[key];
}
}
}
if (_keyMap.hasOwnProperty(key)) {
key = _keyMap[key];
}
return key;
}
getGlobalEventTarget(target: string): EventTarget {
if (target == "window") {
return window;
} else if (target == "document") {
return document;
} else if (target == "body") {
return document.body;
}
}
getHistory(): History { return window.history; }
getLocation(): Location { return window.location; }
getBaseHref(): string {
var href = getBaseElementHref();
if (isBlank(href)) {
return null;
}
return relativePath(href);
}
resetBaseElement(): void { baseElement = null; }
getUserAgent(): string { return window.navigator.userAgent; }
setData(element, name: string, value: string) {
this.setAttribute(element, 'data-' + name, value);
}
getData(element, name: string): string { return this.getAttribute(element, 'data-' + name); }
// TODO(tbosch): move this into a separate environment class once we have it
setGlobalVar(name: string, value: any) { global[name] = value; }
}
var baseElement = null;
function getBaseElementHref(): string {
if (isBlank(baseElement)) {
baseElement = document.querySelector('base');
if (isBlank(baseElement)) {
return null;
}
}
return baseElement.getAttribute('href');
}
// based on urlUtils.js in AngularJS 1
var urlParsingNode = null;
function relativePath(url): string {
if (isBlank(urlParsingNode)) {
urlParsingNode = document.createElement("a");
}
urlParsingNode.setAttribute('href', url);
return (urlParsingNode.pathname.charAt(0) === '/') ? urlParsingNode.pathname :
'/' + urlParsingNode.pathname;
}

View File

@ -0,0 +1,135 @@
import {BaseException, isBlank} from 'angular2/src/facade/lang';
export var DOM: DomAdapter;
export function setRootDomAdapter(adapter: DomAdapter) {
if (isBlank(DOM)) {
DOM = adapter;
}
}
function _abstract() {
return new BaseException('This method is abstract');
}
/* tslint:disable:requireParameterType */
/**
* Provides DOM operations in an environment-agnostic way.
*/
export class DomAdapter {
hasProperty(element, name: string): boolean { throw _abstract(); }
setProperty(el: Element, name: string, value: any) { throw _abstract(); }
getProperty(el: Element, name: string): any { throw _abstract(); }
invoke(el: Element, methodName: string, args: List<any>): any { throw _abstract(); }
logError(error) { throw _abstract(); }
log(error) { throw _abstract(); }
logGroup(error) { throw _abstract(); }
logGroupEnd() { throw _abstract(); }
/**
* Maps attribute names to their corresponding property names for cases
* where attribute name doesn't match property name.
*/
get attrToPropMap(): StringMap<string, string> { throw _abstract(); }
parse(templateHtml: string) { throw _abstract(); }
query(selector: string): any { throw _abstract(); }
querySelector(el, selector: string): HTMLElement { throw _abstract(); }
querySelectorAll(el, selector: string): List<any> { throw _abstract(); }
on(el, evt, listener) { throw _abstract(); }
onAndCancel(el, evt, listener): Function { throw _abstract(); }
dispatchEvent(el, evt) { throw _abstract(); }
createMouseEvent(eventType): any { throw _abstract(); }
createEvent(eventType: string): any { throw _abstract(); }
preventDefault(evt) { throw _abstract(); }
isPrevented(evt): boolean { throw _abstract(); }
getInnerHTML(el): string { throw _abstract(); }
getOuterHTML(el): string { throw _abstract(); }
nodeName(node): string { throw _abstract(); }
nodeValue(node): string { throw _abstract(); }
type(node): string { throw _abstract(); }
content(node): any { throw _abstract(); }
firstChild(el): Node { throw _abstract(); }
nextSibling(el): Node { throw _abstract(); }
parentElement(el): Node { throw _abstract(); }
childNodes(el): List<Node> { throw _abstract(); }
childNodesAsList(el): List<Node> { throw _abstract(); }
clearNodes(el) { throw _abstract(); }
appendChild(el, node) { throw _abstract(); }
removeChild(el, node) { throw _abstract(); }
replaceChild(el, newNode, oldNode) { throw _abstract(); }
remove(el): Node { throw _abstract(); }
insertBefore(el, node) { throw _abstract(); }
insertAllBefore(el, nodes) { throw _abstract(); }
insertAfter(el, node) { throw _abstract(); }
setInnerHTML(el, value) { throw _abstract(); }
getText(el): string { throw _abstract(); }
setText(el, value: string) { throw _abstract(); }
getValue(el): string { throw _abstract(); }
setValue(el, value: string) { throw _abstract(); }
getChecked(el): boolean { throw _abstract(); }
setChecked(el, value: boolean) { throw _abstract(); }
createComment(text: string): any { throw _abstract(); }
createTemplate(html): HTMLElement { throw _abstract(); }
createElement(tagName, doc = null): HTMLElement { throw _abstract(); }
createTextNode(text: string, doc = null): Text { throw _abstract(); }
createScriptTag(attrName: string, attrValue: string, doc = null): HTMLElement {
throw _abstract();
}
createStyleElement(css: string, doc = null): HTMLStyleElement { throw _abstract(); }
createShadowRoot(el): any { throw _abstract(); }
getShadowRoot(el): any { throw _abstract(); }
getHost(el): any { throw _abstract(); }
getDistributedNodes(el): List<Node> { throw _abstract(); }
clone /*<T extends Node>*/ (node: Node /*T*/): Node /*T*/ { throw _abstract(); }
getElementsByClassName(element, name: string): List<HTMLElement> { throw _abstract(); }
getElementsByTagName(element, name: string): List<HTMLElement> { throw _abstract(); }
classList(element): List<any> { throw _abstract(); }
addClass(element, classname: string) { throw _abstract(); }
removeClass(element, classname: string) { throw _abstract(); }
hasClass(element, classname: string): boolean { throw _abstract(); }
setStyle(element, stylename: string, stylevalue: string) { throw _abstract(); }
removeStyle(element, stylename: string) { throw _abstract(); }
getStyle(element, stylename: string): string { throw _abstract(); }
tagName(element): string { throw _abstract(); }
attributeMap(element): Map<string, string> { throw _abstract(); }
hasAttribute(element, attribute: string): boolean { throw _abstract(); }
getAttribute(element, attribute: string): string { throw _abstract(); }
setAttribute(element, name: string, value: string) { throw _abstract(); }
removeAttribute(element, attribute: string) { throw _abstract(); }
templateAwareRoot(el) { throw _abstract(); }
createHtmlDocument(): HTMLDocument { throw _abstract(); }
defaultDoc(): HTMLDocument { throw _abstract(); }
getBoundingClientRect(el) { throw _abstract(); }
getTitle(): string { throw _abstract(); }
setTitle(newTitle: string) { 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(); }
isShadowRoot(node): boolean { throw _abstract(); }
importIntoDoc /*<T extends Node>*/ (node: Node /*T*/): Node /*T*/ { throw _abstract(); }
adoptNode /*<T extends Node>*/ (node: Node /*T*/): Node /*T*/ { throw _abstract(); }
isPageRule(rule): boolean { throw _abstract(); }
isStyleRule(rule): boolean { throw _abstract(); }
isMediaRule(rule): boolean { throw _abstract(); }
isKeyframesRule(rule): boolean { throw _abstract(); }
getHref(element): string { throw _abstract(); }
getEventKey(event): string { throw _abstract(); }
resolveAndSetHref(element, baseUrl: string, href: string) { throw _abstract(); }
cssToRules(css: string): List<any> { throw _abstract(); }
supportsDOMEvents(): boolean { throw _abstract(); }
supportsNativeShadowDOM(): boolean { throw _abstract(); }
getGlobalEventTarget(target: string): any { throw _abstract(); }
getHistory(): History { throw _abstract(); }
getLocation(): Location { throw _abstract(); }
getBaseHref(): string { throw _abstract(); }
resetBaseElement(): void { throw _abstract(); }
getUserAgent(): string { throw _abstract(); }
setData(element, name: string, value: string) { throw _abstract(); }
getData(element, name: string): string { throw _abstract(); }
setGlobalVar(name: string, value: any) { throw _abstract(); }
}

View File

@ -0,0 +1,40 @@
import {List, ListWrapper} from 'angular2/src/facade/collection';
import {isPresent, isFunction} from 'angular2/src/facade/lang';
import {DomAdapter} from './dom_adapter';
/**
* Provides DOM operations in any browser environment.
*/
export class GenericBrowserDomAdapter extends DomAdapter {
getDistributedNodes(el: HTMLElement): List<Node> { return (<any>el).getDistributedNodes(); }
resolveAndSetHref(el: HTMLAnchorElement, baseUrl: string, href: string) {
el.href = href == null ? baseUrl : baseUrl + '/../' + href;
}
cssToRules(css: string): List<any> {
var style = this.createStyleElement(css);
this.appendChild(this.defaultDoc().head, style);
var rules = [];
if (isPresent(style.sheet)) {
// TODO(sorvell): Firefox throws when accessing the rules of a stylesheet
// with an @import
// https://bugzilla.mozilla.org/show_bug.cgi?id=625013
try {
var rawRules = (<any>style.sheet).cssRules;
rules = ListWrapper.createFixedSize(rawRules.length);
for (var i = 0; i < rawRules.length; i++) {
rules[i] = rawRules[i];
}
} catch (e) {
//
}
} else {
// console.warn('sheet not found', style);
}
this.remove(style);
return rules;
}
supportsDOMEvents(): boolean { return true; }
supportsNativeShadowDOM(): boolean {
return isFunction((<any>this.defaultDoc().body).createShadowRoot);
}
}

View File

@ -0,0 +1,423 @@
library angular2.dom.htmlAdapter;
import 'dom_adapter.dart';
import 'package:html/parser.dart' as parser;
import 'package:html/dom.dart';
import 'dart:io';
class Html5LibDomAdapter implements DomAdapter {
static void makeCurrent() {
setRootDomAdapter(new Html5LibDomAdapter());
}
hasProperty(element, String name) {
// This is needed for serverside compile to generate the right getters/setters.
// TODO: change this once we have property schema support.
// Attention: Keep this in sync with browser_adapter.dart!
return true;
}
void setProperty(Element element, String name, Object value) =>
throw 'not implemented';
getProperty(Element element, String name) => throw 'not implemented';
invoke(Element element, String methodName, List args) =>
throw 'not implemented';
logError(error) {
stderr.writeln('${error}');
}
log(error) {
stdout.writeln('${error}');
}
logGroup(error) {
stdout.writeln('${error}');
}
logGroupEnd() {}
@override
final attrToPropMap = const {
'innerHtml': 'innerHTML',
'readonly': 'readOnly',
'tabindex': 'tabIndex',
};
@override
getGlobalEventTarget(String target) {
throw 'not implemented';
}
@override
getTitle() {
throw 'not implemented';
}
@override
setTitle(String newTitle) {
throw 'not implemented';
}
@override
String getEventKey(event) {
throw 'not implemented';
}
@override
void replaceChild(el, newNode, oldNode) {
throw 'not implemented';
}
@override
dynamic getBoundingClientRect(el) {
throw 'not implemented';
}
Element parse(String templateHtml) => parser.parse(templateHtml).firstChild;
query(selector) {
throw 'not implemented';
}
querySelector(el, String selector) {
return el.querySelector(selector);
}
List querySelectorAll(el, String selector) {
return el.querySelectorAll(selector);
}
on(el, evt, listener) {
throw 'not implemented';
}
Function onAndCancel(el, evt, listener) {
throw 'not implemented';
}
dispatchEvent(el, evt) {
throw 'not implemented';
}
createMouseEvent(eventType) {
throw 'not implemented';
}
createEvent(eventType) {
throw 'not implemented';
}
preventDefault(evt) {
throw 'not implemented';
}
isPrevented(evt) {
throw 'not implemented';
}
getInnerHTML(el) {
return el.innerHtml;
}
getOuterHTML(el) {
return el.outerHtml;
}
String nodeName(node) {
switch (node.nodeType) {
case Node.ELEMENT_NODE:
return (node as Element).localName;
case Node.TEXT_NODE:
return '#text';
default:
throw 'not implemented for type ${node.nodeType}. '
'See http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-1950641247'
' for node types definitions.';
}
}
String nodeValue(node) => node.data;
String type(node) {
throw 'not implemented';
}
content(node) {
return node;
}
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) {
return el.parent;
}
List childNodes(el) => el.nodes;
List childNodesAsList(el) => el.nodes;
clearNodes(el) {
el.nodes.forEach((e) => e.remove());
}
appendChild(el, node) => el.append(node.remove());
removeChild(el, node) {
throw 'not implemented';
}
remove(el) => el.remove();
insertBefore(el, node) {
if (el.parent == null) throw '$el must have a parent';
el.parent.insertBefore(node, el);
}
insertAllBefore(el, nodes) {
throw 'not implemented';
}
insertAfter(el, node) {
throw 'not implemented';
}
setInnerHTML(el, value) {
el.innerHtml = value;
}
getText(el) {
return el.text;
}
setText(el, String value) => el.text = value;
getValue(el) {
throw 'not implemented';
}
setValue(el, String value) {
throw 'not implemented';
}
getChecked(el) {
throw 'not implemented';
}
setChecked(el, bool value) {
throw 'not implemented';
}
createComment(String text) => new Comment(text);
createTemplate(String html) => 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';
}
createShadowRoot(el) {
throw 'not implemented';
}
getShadowRoot(el) {
throw 'not implemented';
}
getHost(el) {
throw 'not implemented';
}
clone(node) => node.clone(true);
getElementsByClassName(element, String name) {
throw 'not implemented';
}
getElementsByTagName(element, String name) {
throw 'not implemented';
}
List classList(element) => element.classes.toList();
addClass(element, String classname) {
element.classes.add(classname);
}
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) {
// `attributes` keys can be {@link AttributeName}s.
var map = <String, String>{};
element.attributes.forEach((key, value) {
map['$key'] = value;
});
return map;
}
hasAttribute(element, String attribute) {
// `attributes` keys can be {@link AttributeName}s.
return element.attributes.keys.any((key) => '$key' == attribute);
}
getAttribute(element, String attribute) {
// `attributes` keys can be {@link AttributeName}s.
var key = element.attributes.keys.firstWhere((key) => '$key' == attribute,
orElse: () {});
return element.attributes[key];
}
setAttribute(element, String name, String value) {
element.attributes[name] = value;
}
removeAttribute(element, String attribute) {
element.attributes.remove(attribute);
}
templateAwareRoot(el) => 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) => node.nodeType == Node.TEXT_NODE;
bool isCommentNode(node) => node.nodeType == Node.COMMENT_NODE;
bool isElementNode(node) => node.nodeType == Node.ELEMENT_NODE;
bool hasShadowRoot(node) {
throw 'not implemented';
}
bool isShadowRoot(node) {
throw 'not implemented';
}
importIntoDoc(node) {
throw 'not implemented';
}
adoptNode(node) {
throw 'not implemented';
}
bool isPageRule(rule) {
throw 'not implemented';
}
bool isStyleRule(rule) {
throw 'not implemented';
}
bool isMediaRule(rule) {
throw 'not implemented';
}
bool isKeyframesRule(rule) {
throw 'not implemented';
}
String getHref(element) {
throw 'not implemented';
}
void resolveAndSetHref(element, baseUrl, href) {
throw 'not implemented';
}
List cssToRules(String css) {
throw 'not implemented';
}
List getDistributedNodes(Node) {
throw 'not implemented';
}
bool supportsDOMEvents() {
return false;
}
bool supportsNativeShadowDOM() {
return false;
}
getHistory() {
throw 'not implemented';
}
getLocation() {
throw 'not implemented';
}
getBaseHref() {
throw 'not implemented';
}
resetBaseElement() {
throw 'not implemented';
}
String getUserAgent() {
throw 'not implemented';
}
void setData(Element element, String name, String value) {
this.setAttribute(element, 'data-${name}', value);
}
String getData(Element element, String name) {
return this.getAttribute(element, 'data-${name}');
}
// TODO(tbosch): move this into a separate environment class once we have it
setGlobalVar(String name, value) {
// noop on the server
}
}

View File

@ -0,0 +1,3 @@
library angular2.src.dom.parse5_adapter;
// no dart implementation

View File

@ -0,0 +1,730 @@
var parse5 = require('parse5');
var parser = new parse5.Parser(parse5.TreeAdapters.htmlparser2);
var serializer = new parse5.Serializer(parse5.TreeAdapters.htmlparser2);
var treeAdapter = parser.treeAdapter;
var cssParse = require('css').parse;
var url = require('url');
import {List, MapWrapper, ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
import {DomAdapter, setRootDomAdapter} from './dom_adapter';
import {BaseException, isPresent, isBlank, global} from 'angular2/src/facade/lang';
import {SelectorMatcher, CssSelector} from 'angular2/src/render/dom/compiler/selector';
var _attrToPropMap = {
'class': 'className',
'innerHtml': 'innerHTML',
'readonly': 'readOnly',
'tabindex': 'tabIndex',
};
var defDoc = null;
var mapProps = ['attribs', 'x-attribsNamespace', 'x-attribsPrefix'];
function _notImplemented(methodName) {
return new BaseException('This method is not implemented in Parse5DomAdapter: ' + methodName);
}
/* tslint:disable:requireParameterType */
export class Parse5DomAdapter extends DomAdapter {
static makeCurrent() { setRootDomAdapter(new Parse5DomAdapter()); }
hasProperty(element, name: string): boolean {
return _HTMLElementPropertyList.indexOf(name) > -1;
}
// TODO(tbosch): don't even call this method when we run the tests on server side
// by not using the DomRenderer in tests. Keeping this for now to make tests happy...
setProperty(el: /*element*/ any, name: string, value: any) {
if (name === 'innerHTML') {
this.setInnerHTML(el, value);
} else if (name === 'className') {
el.attribs["class"] = el.className = value;
} else {
el[name] = value;
}
}
// TODO(tbosch): don't even call this method when we run the tests on server side
// by not using the DomRenderer in tests. Keeping this for now to make tests happy...
getProperty(el: /*element*/ any, name: string): any { return el[name]; }
logError(error) { console.error(error); }
log(error) { console.log(error); }
logGroup(error) { console.log(error); }
logGroupEnd() {}
get attrToPropMap() { return _attrToPropMap; }
query(selector) { throw _notImplemented('query'); }
querySelector(el, selector: string): any { return this.querySelectorAll(el, selector)[0]; }
querySelectorAll(el, selector: string): List<any> {
var res = [];
var _recursive = (result, node, selector, matcher) => {
var cNodes = node.childNodes;
if (cNodes && cNodes.length > 0) {
for (var i = 0; i < cNodes.length; i++) {
var childNode = cNodes[i];
if (this.elementMatches(childNode, selector, matcher)) {
result.push(childNode);
}
_recursive(result, childNode, selector, matcher);
}
}
};
var matcher = new SelectorMatcher();
matcher.addSelectables(CssSelector.parse(selector));
_recursive(res, el, selector, matcher);
return res;
}
elementMatches(node, selector: string, matcher = null): boolean {
if (this.isElementNode(node) && selector === '*') {
return true;
}
var result = false;
if (selector && selector.charAt(0) == "#") {
result = this.getAttribute(node, 'id') == selector.substring(1);
} else if (selector) {
var result = false;
if (matcher == null) {
matcher = new SelectorMatcher();
matcher.addSelectables(CssSelector.parse(selector));
}
var cssSelector = new CssSelector();
cssSelector.setElement(this.tagName(node));
if (node.attribs) {
for (var attrName in node.attribs) {
cssSelector.addAttribute(attrName, node.attribs[attrName]);
}
}
var classList = this.classList(node);
for (var i = 0; i < classList.length; i++) {
cssSelector.addClassName(classList[i]);
}
matcher.match(cssSelector, function(selector, cb) { result = true; });
}
return result;
}
on(el, evt, listener) {
var listenersMap: StringMap<any, any> = el._eventListenersMap;
if (isBlank(listenersMap)) {
var listenersMap: StringMap<any, any> = StringMapWrapper.create();
el._eventListenersMap = listenersMap;
}
var listeners = StringMapWrapper.get(listenersMap, evt);
if (isBlank(listeners)) {
listeners = [];
}
listeners.push(listener);
StringMapWrapper.set(listenersMap, evt, listeners);
}
onAndCancel(el, evt, listener): Function {
this.on(el, evt, listener);
return () => {
ListWrapper.remove(StringMapWrapper.get<List<any>>(el._eventListenersMap, evt), listener);
};
}
dispatchEvent(el, evt) {
if (isBlank(evt.target)) {
evt.target = el;
}
if (isPresent(el._eventListenersMap)) {
var listeners: any = StringMapWrapper.get(el._eventListenersMap, evt.type);
if (isPresent(listeners)) {
for (var i = 0; i < listeners.length; i++) {
listeners[i](evt);
}
}
}
if (isPresent(el.parent)) {
this.dispatchEvent(el.parent, evt);
}
if (isPresent(el._window)) {
this.dispatchEvent(el._window, evt);
}
}
createMouseEvent(eventType): Event { return this.createEvent(eventType); }
createEvent(eventType: string): Event {
var evt = <Event>{
type: eventType,
defaultPrevented: false,
preventDefault: () => { evt.defaultPrevented = true; }
};
return evt;
}
preventDefault(evt) { evt.returnValue = false; }
isPrevented(evt): boolean { return isPresent(evt.returnValue) && !evt.returnValue; }
getInnerHTML(el): string { return serializer.serialize(this.templateAwareRoot(el)); }
getOuterHTML(el): string {
serializer.html = '';
serializer._serializeElement(el);
return serializer.html;
}
nodeName(node): string { return node.tagName; }
nodeValue(node): string { return node.nodeValue; }
type(node: any): string { throw _notImplemented('type'); }
content(node): string { return node.childNodes[0]; }
firstChild(el): Node { return el.firstChild; }
nextSibling(el): Node { return el.nextSibling; }
parentElement(el): Node { return el.parent; }
childNodes(el): Node[] { return el.childNodes; }
childNodesAsList(el): List<any> {
var childNodes = el.childNodes;
var res = ListWrapper.createFixedSize(childNodes.length);
for (var i = 0; i < childNodes.length; i++) {
res[i] = childNodes[i];
}
return res;
}
clearNodes(el) {
while (el.childNodes.length > 0) {
this.remove(el.childNodes[0]);
}
}
appendChild(el, node) {
this.remove(node);
treeAdapter.appendChild(this.templateAwareRoot(el), node);
}
removeChild(el, node) {
if (ListWrapper.contains(el.childNodes, node)) {
this.remove(node);
}
}
remove(el): HTMLElement {
var parent = el.parent;
if (parent) {
var index = parent.childNodes.indexOf(el);
parent.childNodes.splice(index, 1);
}
var prev = el.previousSibling;
var next = el.nextSibling;
if (prev) {
prev.next = next;
}
if (next) {
next.prev = prev;
}
el.prev = null;
el.next = null;
el.parent = null;
return el;
}
insertBefore(el, node) {
this.remove(node);
treeAdapter.insertBefore(el.parent, node, el);
}
insertAllBefore(el, nodes) {
ListWrapper.forEach(nodes, (n) => { this.insertBefore(el, n); });
}
insertAfter(el, node) {
if (el.nextSibling) {
this.insertBefore(el.nextSibling, node);
} else {
this.appendChild(el.parent, node);
}
}
setInnerHTML(el, value) {
this.clearNodes(el);
var content = parser.parseFragment(value);
for (var i = 0; i < content.childNodes.length; i++) {
treeAdapter.appendChild(el, content.childNodes[i]);
}
}
getText(el): string {
if (this.isTextNode(el)) {
return el.data;
} else if (isBlank(el.childNodes) || el.childNodes.length == 0) {
return "";
} else {
var textContent = "";
for (var i = 0; i < el.childNodes.length; i++) {
textContent += this.getText(el.childNodes[i]);
}
return textContent;
}
}
setText(el, value: string) {
if (this.isTextNode(el)) {
el.data = value;
} else {
this.clearNodes(el);
if (value !== '') treeAdapter.insertText(el, value);
}
}
getValue(el): string { return el.value; }
setValue(el, value: string) { el.value = value; }
getChecked(el): boolean { return el.checked; }
setChecked(el, value: boolean) { el.checked = value; }
createComment(text: string): Comment { return treeAdapter.createCommentNode(text); }
createTemplate(html): HTMLElement {
var template = treeAdapter.createElement("template", 'http://www.w3.org/1999/xhtml', []);
var content = parser.parseFragment(html);
treeAdapter.appendChild(template, content);
return template;
}
createElement(tagName): HTMLElement {
return treeAdapter.createElement(tagName, 'http://www.w3.org/1999/xhtml', []);
}
createTextNode(text: string): Text { throw _notImplemented('createTextNode'); }
createScriptTag(attrName: string, attrValue: string): HTMLElement {
return treeAdapter.createElement("script", 'http://www.w3.org/1999/xhtml',
[{name: attrName, value: attrValue}]);
}
createStyleElement(css: string): HTMLStyleElement {
var style = this.createElement('style');
this.setText(style, css);
return <HTMLStyleElement>style;
}
createShadowRoot(el): HTMLElement {
el.shadowRoot = treeAdapter.createDocumentFragment();
el.shadowRoot.parent = el;
return el.shadowRoot;
}
getShadowRoot(el): Element { return el.shadowRoot; }
getHost(el): string { return el.host; }
getDistributedNodes(el: any): List<Node> { throw _notImplemented('getDistributedNodes'); }
clone(node: Node): Node {
var _recursive = (node) => {
var nodeClone = Object.create(Object.getPrototypeOf(node));
for (var prop in node) {
var desc = Object.getOwnPropertyDescriptor(node, prop);
if (desc && 'value' in desc && typeof desc.value !== 'object') {
nodeClone[prop] = node[prop];
}
}
nodeClone.parent = null;
nodeClone.prev = null;
nodeClone.next = null;
nodeClone.children = null;
mapProps.forEach(mapName => {
if (isPresent(node[mapName])) {
nodeClone[mapName] = {};
for (var prop in node[mapName]) {
nodeClone[mapName][prop] = node[mapName][prop];
}
}
});
var cNodes = node.children;
if (cNodes) {
var cNodesClone = new Array(cNodes.length);
for (var i = 0; i < cNodes.length; i++) {
var childNode = cNodes[i];
var childNodeClone = _recursive(childNode);
cNodesClone[i] = childNodeClone;
if (i > 0) {
childNodeClone.prev = cNodesClone[i - 1];
cNodesClone[i - 1].next = childNodeClone;
}
childNodeClone.parent = nodeClone;
}
nodeClone.children = cNodesClone;
}
return nodeClone;
};
return _recursive(node);
}
getElementsByClassName(element, name: string): List<HTMLElement> {
return this.querySelectorAll(element, "." + name);
}
getElementsByTagName(element: any, name: string): List<HTMLElement> {
throw _notImplemented('getElementsByTagName');
}
classList(element): List<string> {
var classAttrValue = null;
var attributes = element.attribs;
if (attributes && attributes.hasOwnProperty("class")) {
classAttrValue = attributes["class"];
}
return classAttrValue ? classAttrValue.trim().split(/\s+/g) : [];
}
addClass(element, classname: string) {
var classList = this.classList(element);
var index = classList.indexOf(classname);
if (index == -1) {
classList.push(classname);
element.attribs["class"] = element.className = ListWrapper.join(classList, " ");
}
}
removeClass(element, classname: string) {
var classList = this.classList(element);
var index = classList.indexOf(classname);
if (index > -1) {
classList.splice(index, 1);
element.attribs["class"] = element.className = ListWrapper.join(classList, " ");
}
}
hasClass(element, classname: string): boolean {
return ListWrapper.contains(this.classList(element), classname);
}
_readStyleAttribute(element) {
var styleMap = {};
var attributes = element.attribs;
if (attributes && attributes.hasOwnProperty("style")) {
var styleAttrValue = attributes["style"];
var styleList = styleAttrValue.split(/;+/g);
for (var i = 0; i < styleList.length; i++) {
if (styleList[i].length > 0) {
var elems = styleList[i].split(/:+/g);
styleMap[elems[0].trim()] = elems[1].trim();
}
}
}
return styleMap;
}
_writeStyleAttribute(element, styleMap) {
var styleAttrValue = "";
for (var key in styleMap) {
var newValue = styleMap[key];
if (newValue && newValue.length > 0) {
styleAttrValue += key + ":" + styleMap[key] + ";";
}
}
element.attribs["style"] = styleAttrValue;
}
setStyle(element, stylename: string, stylevalue: string) {
var styleMap = this._readStyleAttribute(element);
styleMap[stylename] = stylevalue;
this._writeStyleAttribute(element, styleMap);
}
removeStyle(element, stylename: string) { this.setStyle(element, stylename, null); }
getStyle(element, stylename: string): string {
var styleMap = this._readStyleAttribute(element);
return styleMap.hasOwnProperty(stylename) ? styleMap[stylename] : "";
}
tagName(element): string { return element.tagName == "style" ? "STYLE" : element.tagName; }
attributeMap(element): Map<string, string> {
var res = new Map();
var elAttrs = treeAdapter.getAttrList(element);
for (var i = 0; i < elAttrs.length; i++) {
var attrib = elAttrs[i];
res.set(attrib.name, attrib.value);
}
return res;
}
hasAttribute(element, attribute: string): boolean {
return element.attribs && element.attribs.hasOwnProperty(attribute);
}
getAttribute(element, attribute: string): string {
return element.attribs && element.attribs.hasOwnProperty(attribute) ?
element.attribs[attribute] :
null;
}
setAttribute(element, attribute: string, value: string) {
if (attribute) {
element.attribs[attribute] = value;
}
}
removeAttribute(element, attribute: string) {
if (attribute) {
StringMapWrapper.delete(element.attribs, attribute);
}
}
templateAwareRoot(el): any { return this.isTemplateElement(el) ? this.content(el) : el; }
createHtmlDocument(): Document {
var newDoc = treeAdapter.createDocument();
newDoc.title = "fake title";
var head = treeAdapter.createElement("head", null, []);
var body = treeAdapter.createElement("body", 'http://www.w3.org/1999/xhtml', []);
this.appendChild(newDoc, head);
this.appendChild(newDoc, body);
StringMapWrapper.set(newDoc, "head", head);
StringMapWrapper.set(newDoc, "body", body);
StringMapWrapper.set(newDoc, "_window", StringMapWrapper.create());
return newDoc;
}
defaultDoc(): Document {
if (defDoc === null) {
defDoc = this.createHtmlDocument();
}
return defDoc;
}
getBoundingClientRect(el): any { return {left: 0, top: 0, width: 0, height: 0}; }
getTitle(): string { return this.defaultDoc().title || ""; }
setTitle(newTitle: string) { this.defaultDoc().title = newTitle; }
isTemplateElement(el: any): boolean {
return this.isElementNode(el) && this.tagName(el) === "template";
}
isTextNode(node): boolean { return treeAdapter.isTextNode(node); }
isCommentNode(node): boolean { return treeAdapter.isCommentNode(node); }
isElementNode(node): boolean { return node ? treeAdapter.isElementNode(node) : false; }
hasShadowRoot(node): boolean { return isPresent(node.shadowRoot); }
isShadowRoot(node): boolean { return this.getShadowRoot(node) == node; }
importIntoDoc(node): any { return this.clone(node); }
adoptNode(node): any { return node; }
isPageRule(rule): boolean {
return rule.type === 6; // CSSRule.PAGE_RULE
}
isStyleRule(rule): boolean {
return rule.type === 1; // CSSRule.MEDIA_RULE
}
isMediaRule(rule): boolean {
return rule.type === 4; // CSSRule.MEDIA_RULE
}
isKeyframesRule(rule): boolean {
return rule.type === 7; // CSSRule.KEYFRAMES_RULE
}
getHref(el): string { return el.href; }
resolveAndSetHref(el, baseUrl: string, href: string) {
if (href == null) {
el.href = baseUrl;
} else {
el.href = url.resolve(baseUrl, href);
}
}
_buildRules(parsedRules, css?) {
var rules = [];
for (var i = 0; i < parsedRules.length; i++) {
var parsedRule = parsedRules[i];
var rule: StringMap<string, any> = StringMapWrapper.create();
StringMapWrapper.set(rule, "cssText", css);
StringMapWrapper.set(rule, "style", {content: "", cssText: ""});
if (parsedRule.type == "rule") {
StringMapWrapper.set(rule, "type", 1);
StringMapWrapper.set(rule, "selectorText", parsedRule.selectors.join(", ")
.replace(/\s{2,}/g, " ")
.replace(/\s*~\s*/g, " ~ ")
.replace(/\s*\+\s*/g, " + ")
.replace(/\s*>\s*/g, " > ")
.replace(/\[(\w+)=(\w+)\]/g, '[$1="$2"]'));
if (isBlank(parsedRule.declarations)) {
continue;
}
for (var j = 0; j < parsedRule.declarations.length; j++) {
var declaration = parsedRule.declarations[j];
StringMapWrapper.set(StringMapWrapper.get(rule, "style"), declaration.property,
declaration.value);
StringMapWrapper.get(rule, "style").cssText +=
declaration.property + ": " + declaration.value + ";";
}
} else if (parsedRule.type == "media") {
StringMapWrapper.set(rule, "type", 4);
StringMapWrapper.set(rule, "media", {mediaText: parsedRule.media});
if (parsedRule.rules) {
StringMapWrapper.set(rule, "cssRules", this._buildRules(parsedRule.rules));
}
}
rules.push(rule);
}
return rules;
}
cssToRules(css: string): List<any> {
css = css.replace(/url\(\'(.+)\'\)/g, 'url($1)');
var rules = [];
var parsedCSS = cssParse(css, {silent: true});
if (parsedCSS.stylesheet && parsedCSS.stylesheet.rules) {
rules = this._buildRules(parsedCSS.stylesheet.rules, css);
}
return rules;
}
supportsDOMEvents(): boolean { return false; }
supportsNativeShadowDOM(): boolean { return false; }
getGlobalEventTarget(target: string): any {
if (target == "window") {
return (<any>this.defaultDoc())._window;
} else if (target == "document") {
return this.defaultDoc();
} else if (target == "body") {
return this.defaultDoc().body;
}
}
getBaseHref(): string { throw 'not implemented'; }
resetBaseElement(): void { throw 'not implemented'; }
getHistory(): History { throw 'not implemented'; }
getLocation(): Location { throw 'not implemented'; }
getUserAgent(): string { return "Fake user agent"; }
getData(el, name: string): string { return this.getAttribute(el, 'data-' + name); }
setData(el, name: string, value: string) { this.setAttribute(el, 'data-' + name, value); }
// TODO(tbosch): move this into a separate environment class once we have it
setGlobalVar(name: string, value: any) { global[name] = value; }
}
// TODO: build a proper list, this one is all the keys of a HTMLInputElement
var _HTMLElementPropertyList = [
"webkitEntries",
"incremental",
"webkitdirectory",
"selectionDirection",
"selectionEnd",
"selectionStart",
"labels",
"validationMessage",
"validity",
"willValidate",
"width",
"valueAsNumber",
"valueAsDate",
"value",
"useMap",
"defaultValue",
"type",
"step",
"src",
"size",
"required",
"readOnly",
"placeholder",
"pattern",
"name",
"multiple",
"min",
"minLength",
"maxLength",
"max",
"list",
"indeterminate",
"height",
"formTarget",
"formNoValidate",
"formMethod",
"formEnctype",
"formAction",
"files",
"form",
"disabled",
"dirName",
"checked",
"defaultChecked",
"autofocus",
"autocomplete",
"alt",
"align",
"accept",
"onautocompleteerror",
"onautocomplete",
"onwaiting",
"onvolumechange",
"ontoggle",
"ontimeupdate",
"onsuspend",
"onsubmit",
"onstalled",
"onshow",
"onselect",
"onseeking",
"onseeked",
"onscroll",
"onresize",
"onreset",
"onratechange",
"onprogress",
"onplaying",
"onplay",
"onpause",
"onmousewheel",
"onmouseup",
"onmouseover",
"onmouseout",
"onmousemove",
"onmouseleave",
"onmouseenter",
"onmousedown",
"onloadstart",
"onloadedmetadata",
"onloadeddata",
"onload",
"onkeyup",
"onkeypress",
"onkeydown",
"oninvalid",
"oninput",
"onfocus",
"onerror",
"onended",
"onemptied",
"ondurationchange",
"ondrop",
"ondragstart",
"ondragover",
"ondragleave",
"ondragenter",
"ondragend",
"ondrag",
"ondblclick",
"oncuechange",
"oncontextmenu",
"onclose",
"onclick",
"onchange",
"oncanplaythrough",
"oncanplay",
"oncancel",
"onblur",
"onabort",
"spellcheck",
"isContentEditable",
"contentEditable",
"outerText",
"innerText",
"accessKey",
"hidden",
"webkitdropzone",
"draggable",
"tabIndex",
"dir",
"translate",
"lang",
"title",
"childElementCount",
"lastElementChild",
"firstElementChild",
"children",
"onwebkitfullscreenerror",
"onwebkitfullscreenchange",
"nextElementSibling",
"previousElementSibling",
"onwheel",
"onselectstart",
"onsearch",
"onpaste",
"oncut",
"oncopy",
"onbeforepaste",
"onbeforecut",
"onbeforecopy",
"shadowRoot",
"dataset",
"classList",
"className",
"outerHTML",
"innerHTML",
"scrollHeight",
"scrollWidth",
"scrollTop",
"scrollLeft",
"clientHeight",
"clientWidth",
"clientTop",
"clientLeft",
"offsetParent",
"offsetHeight",
"offsetWidth",
"offsetTop",
"offsetLeft",
"localName",
"prefix",
"namespaceURI",
"id",
"style",
"attributes",
"tagName",
"parentElement",
"textContent",
"baseURI",
"ownerDocument",
"nextSibling",
"previousSibling",
"lastChild",
"firstChild",
"childNodes",
"parentNode",
"nodeType",
"nodeValue",
"nodeName",
"closure_lm_714617",
"__jsaction"
];