feat(compiler): DOM adapters + html5lib implementation; misc fixes

This commit is contained in:
Yegor Jbanov
2015-02-27 14:50:06 -08:00
parent ab42664e76
commit 757eae8ad3
79 changed files with 1223 additions and 643 deletions
+21
View File
@@ -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 []);
}
}
+10
View File
@@ -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;
+1 -1
View File
@@ -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;
-210
View File
@@ -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<Node> 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<Node> 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<Node> getElementsByClassName(Element element, String name) =>
element.getElementsByClassName(name);
static List<Node> getElementsByTagName(Element element, String name) =>
element.querySelectorAll(name);
static List<String> 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<String, String> 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;
}
-250
View File
@@ -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<childNodes.length; i++) {
res[i] = childNodes[i];
}
return res;
}
static clearNodes(el) {
el.innerHTML = "";
}
static appendChild(el, node) {
el.appendChild(node);
}
static removeChild(el, node) {
el.removeChild(node);
}
static remove(el: Element): Element {
var parent = el.parentNode;
parent.removeChild(el);
return el;
}
static insertBefore(el, node) {
el.parentNode.insertBefore(node, el);
}
static insertAllBefore(el, nodes) {
ListWrapper.forEach(nodes, (n) => {
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;
}
}