2015-03-01 16:17:36 -05:00
|
|
|
var parse5 = require('parse5');
|
|
|
|
var parser = new parse5.Parser(parse5.TreeAdapters.htmlparser2);
|
|
|
|
var serializer = new parse5.Serializer(parse5.TreeAdapters.htmlparser2);
|
|
|
|
var treeAdapter = parser.treeAdapter;
|
|
|
|
|
2015-03-19 06:35:48 -04:00
|
|
|
var cssParse = require('css').parse;
|
2015-03-01 16:17:36 -05:00
|
|
|
|
|
|
|
var url = require('url');
|
|
|
|
|
|
|
|
import {List, MapWrapper, ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
|
|
|
import {DomAdapter, setRootDomAdapter} from './dom_adapter';
|
2015-05-28 17:56:40 -04:00
|
|
|
import {BaseException, isPresent, isBlank, global} from 'angular2/src/facade/lang';
|
2015-04-02 17:40:49 -04:00
|
|
|
import {SelectorMatcher, CssSelector} from 'angular2/src/render/dom/compiler/selector';
|
2015-03-01 16:17:36 -05:00
|
|
|
|
|
|
|
var _attrToPropMap = {
|
2015-03-12 12:28:35 -04:00
|
|
|
'innerHtml': 'innerHTML',
|
2015-03-01 16:17:36 -05:00
|
|
|
'readonly': 'readOnly',
|
|
|
|
'tabindex': 'tabIndex',
|
|
|
|
};
|
|
|
|
var defDoc = null;
|
|
|
|
|
|
|
|
function _notImplemented(methodName) {
|
|
|
|
return new BaseException('This method is not implemented in Parse5DomAdapter: ' + methodName);
|
|
|
|
}
|
|
|
|
|
|
|
|
export class Parse5DomAdapter extends DomAdapter {
|
|
|
|
static makeCurrent() {
|
|
|
|
setRootDomAdapter(new Parse5DomAdapter());
|
|
|
|
}
|
|
|
|
|
2015-04-30 14:25:50 -04:00
|
|
|
logError(error) {
|
|
|
|
console.error(error);
|
|
|
|
}
|
|
|
|
|
2015-03-01 16:17:36 -05:00
|
|
|
get attrToPropMap() {
|
|
|
|
return _attrToPropMap;
|
|
|
|
}
|
|
|
|
|
|
|
|
query(selector) {
|
|
|
|
throw _notImplemented('query');
|
|
|
|
}
|
|
|
|
querySelector(el, selector:string) {
|
2015-03-09 12:41:49 -04:00
|
|
|
return this.querySelectorAll(el, selector)[0];
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
querySelectorAll(el, selector:string) {
|
|
|
|
var res = ListWrapper.create();
|
2015-03-09 12:41:49 -04:00
|
|
|
var _recursive = (result, node, selector, matcher) => {
|
|
|
|
if (this.elementMatches(node, selector, matcher)) {
|
2015-03-01 16:17:36 -05:00
|
|
|
ListWrapper.push(result, node);
|
|
|
|
}
|
|
|
|
var cNodes = node.childNodes;
|
|
|
|
if (cNodes && cNodes.length > 0) {
|
|
|
|
for (var i = 0; i < cNodes.length; i++) {
|
2015-03-09 12:41:49 -04:00
|
|
|
_recursive(result, cNodes[i], selector, matcher);
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2015-03-09 12:41:49 -04:00
|
|
|
var matcher = new SelectorMatcher();
|
2015-03-19 12:01:42 -04:00
|
|
|
matcher.addSelectables(CssSelector.parse(selector));
|
2015-03-09 12:41:49 -04:00
|
|
|
_recursive(res, el, selector, matcher);
|
2015-03-01 16:17:36 -05:00
|
|
|
return res;
|
|
|
|
}
|
2015-03-09 12:41:49 -04:00
|
|
|
elementMatches(node, selector:string, matcher = null):boolean {
|
|
|
|
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();
|
2015-03-19 12:01:42 -04:00
|
|
|
matcher.addSelectables(CssSelector.parse(selector));
|
2015-03-09 12:41:49 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
2015-03-01 16:17:36 -05:00
|
|
|
on(el, evt, listener) {
|
2015-04-21 13:30:55 -04:00
|
|
|
var listenersMap = el._eventListenersMap;
|
|
|
|
if (isBlank(listenersMap)) {
|
|
|
|
var listenersMap = StringMapWrapper.create();
|
|
|
|
el._eventListenersMap = listenersMap;
|
|
|
|
}
|
|
|
|
var listeners = StringMapWrapper.get(listenersMap, evt);
|
|
|
|
if (isBlank(listeners)) {
|
|
|
|
listeners = ListWrapper.create();
|
|
|
|
}
|
|
|
|
ListWrapper.push(listeners, listener);
|
|
|
|
StringMapWrapper.set(listenersMap, evt, listeners);
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2015-04-02 09:56:58 -04:00
|
|
|
onAndCancel(el, evt, listener): Function {
|
2015-04-21 13:30:55 -04:00
|
|
|
this.on(el, evt, listener);
|
|
|
|
return () => {ListWrapper.remove(StringMapWrapper.get(el._eventListenersMap, evt), listener);};
|
2015-04-02 09:56:58 -04:00
|
|
|
}
|
2015-03-01 16:17:36 -05:00
|
|
|
dispatchEvent(el, evt) {
|
2015-04-21 13:30:55 -04:00
|
|
|
if (isBlank(evt.target)) {
|
|
|
|
evt.target = el;
|
|
|
|
}
|
|
|
|
if (isPresent(el._eventListenersMap)) {
|
|
|
|
var listeners = 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);
|
|
|
|
}
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
createMouseEvent(eventType) {
|
2015-04-21 13:30:55 -04:00
|
|
|
return this.createEvent(eventType);
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
createEvent(eventType) {
|
2015-05-06 21:30:37 -04:00
|
|
|
var evt = {
|
|
|
|
type: eventType,
|
|
|
|
defaultPrevented: false,
|
|
|
|
preventDefault: () => {evt.defaultPrevented = true}
|
|
|
|
};
|
|
|
|
return evt;
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
2015-05-21 05:32:29 -04:00
|
|
|
preventDefault(evt) {
|
|
|
|
evt.returnValue = false;
|
|
|
|
}
|
2015-03-01 16:17:36 -05:00
|
|
|
getInnerHTML(el) {
|
|
|
|
return serializer.serialize(this.templateAwareRoot(el));
|
|
|
|
}
|
|
|
|
getOuterHTML(el) {
|
|
|
|
serializer.html = '';
|
|
|
|
serializer._serializeElement(el);
|
|
|
|
return serializer.html;
|
|
|
|
}
|
|
|
|
nodeName(node):string {
|
|
|
|
return node.tagName;
|
|
|
|
}
|
|
|
|
nodeValue(node):string {
|
|
|
|
return node.nodeValue;
|
|
|
|
}
|
|
|
|
type(node:string) {
|
|
|
|
throw _notImplemented('type');
|
|
|
|
}
|
|
|
|
content(node) {
|
|
|
|
return node.childNodes[0];
|
|
|
|
}
|
|
|
|
firstChild(el) {
|
|
|
|
return el.firstChild;
|
|
|
|
}
|
|
|
|
nextSibling(el) {
|
|
|
|
return el.nextSibling;
|
|
|
|
}
|
|
|
|
parentElement(el) {
|
|
|
|
return el.parent;
|
|
|
|
}
|
|
|
|
childNodes(el) {
|
|
|
|
return el.childNodes;
|
|
|
|
}
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
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) {
|
|
|
|
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) {
|
|
|
|
if (this.isTextNode(el)) {
|
|
|
|
return el.data;
|
|
|
|
} else if (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)) {
|
2015-03-12 12:28:35 -04:00
|
|
|
el.data = value;
|
2015-03-01 16:17:36 -05:00
|
|
|
} else {
|
|
|
|
this.clearNodes(el);
|
|
|
|
treeAdapter.insertText(el, 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 template = treeAdapter.createElement("template", 'http://www.w3.org/1999/xhtml', []);
|
|
|
|
var content = parser.parseFragment(html);
|
|
|
|
treeAdapter.appendChild(template, content);
|
|
|
|
return template;
|
|
|
|
}
|
|
|
|
createElement(tagName) {
|
|
|
|
return treeAdapter.createElement(tagName, 'http://www.w3.org/1999/xhtml', []);
|
|
|
|
}
|
|
|
|
createTextNode(text: string) {
|
|
|
|
throw _notImplemented('createTextNode');
|
|
|
|
}
|
|
|
|
createScriptTag(attrName:string, attrValue:string) {
|
|
|
|
return treeAdapter.createElement("script", 'http://www.w3.org/1999/xhtml', [{name: attrName, value: attrValue}]);
|
|
|
|
}
|
|
|
|
createStyleElement(css:string) {
|
|
|
|
var style = this.createElement('style');
|
|
|
|
this.setText(style, css);
|
|
|
|
return style;
|
|
|
|
}
|
|
|
|
createShadowRoot(el) {
|
|
|
|
el.shadowRoot = treeAdapter.createDocumentFragment();
|
|
|
|
el.shadowRoot.parent = el;
|
|
|
|
return el.shadowRoot;
|
|
|
|
}
|
|
|
|
getShadowRoot(el) {
|
|
|
|
return el.shadowRoot;
|
|
|
|
}
|
2015-03-23 19:46:18 -04:00
|
|
|
getHost(el) {
|
|
|
|
return el.host;
|
|
|
|
}
|
2015-03-19 06:35:48 -04:00
|
|
|
getDistributedNodes(el) {
|
|
|
|
throw _notImplemented('getDistributedNodes');
|
|
|
|
}
|
2015-03-01 16:17:36 -05:00
|
|
|
clone(node) {
|
|
|
|
var temp = treeAdapter.createElement("template", null, []);
|
|
|
|
treeAdapter.appendChild(temp, node);
|
|
|
|
var serialized = serializer.serialize(temp);
|
|
|
|
var newParser = new parse5.Parser(parse5.TreeAdapters.htmlparser2);
|
|
|
|
return newParser.parseFragment(serialized).childNodes[0];
|
|
|
|
}
|
|
|
|
hasProperty(element, name:string) {
|
|
|
|
return _HTMLElementPropertyList.indexOf(name) > -1;
|
|
|
|
}
|
|
|
|
getElementsByClassName(element, name:string) {
|
|
|
|
return this.querySelectorAll(element, "." + name);
|
|
|
|
}
|
|
|
|
getElementsByTagName(element, name:string) {
|
|
|
|
throw _notImplemented('getElementsByTagName');
|
|
|
|
}
|
|
|
|
classList(element):List {
|
|
|
|
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) {
|
|
|
|
ListWrapper.push(classList, 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) {
|
|
|
|
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) {
|
2015-03-12 12:28:35 -04:00
|
|
|
styleAttrValue += key + ":" + styleMap[key] + ";";
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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) {
|
|
|
|
var styleMap = this._readStyleAttribute(element);
|
|
|
|
return styleMap.hasOwnProperty(stylename) ? styleMap[stylename] : "";
|
|
|
|
}
|
|
|
|
tagName(element):string {
|
|
|
|
return element.tagName == "style" ? "STYLE" : element.tagName;
|
|
|
|
}
|
|
|
|
attributeMap(element) {
|
|
|
|
var res = MapWrapper.create();
|
|
|
|
var elAttrs = treeAdapter.getAttrList(element);
|
|
|
|
for (var i = 0; i < elAttrs.length; i++) {
|
|
|
|
var attrib = elAttrs[i];
|
|
|
|
MapWrapper.set(res, attrib.name, attrib.value);
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
2015-05-01 07:41:56 -04:00
|
|
|
hasAttribute(element, attribute:string) {
|
|
|
|
return element.attribs && element.attribs.hasOwnProperty(attribute);
|
|
|
|
}
|
2015-03-01 16:17:36 -05:00
|
|
|
getAttribute(element, attribute:string) {
|
2015-03-09 12:41:49 -04:00
|
|
|
return element.attribs && element.attribs.hasOwnProperty(attribute)? element.attribs[attribute]: null;
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
setAttribute(element, attribute:string, value:string) {
|
|
|
|
if (attribute) {
|
|
|
|
element.attribs[attribute] = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
removeAttribute(element, attribute:string) {
|
|
|
|
if (attribute) {
|
|
|
|
delete element.attribs[attribute];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
templateAwareRoot(el) {
|
|
|
|
return this.isTemplateElement(el) ? this.content(el) : el;
|
|
|
|
}
|
|
|
|
createHtmlDocument() {
|
2015-04-16 12:44:34 -04:00
|
|
|
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);
|
2015-04-21 13:30:55 -04:00
|
|
|
StringMapWrapper.set(newDoc, "_window", StringMapWrapper.create());
|
2015-04-16 12:44:34 -04:00
|
|
|
return newDoc;
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
defaultDoc() {
|
|
|
|
if (defDoc === null) {
|
2015-04-16 12:44:34 -04:00
|
|
|
defDoc = this.createHtmlDocument();
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
return defDoc;
|
|
|
|
}
|
2015-04-06 15:45:54 -04:00
|
|
|
getBoundingClientRect(el) {
|
|
|
|
return {left: 0, top: 0, width: 0, height: 0};
|
|
|
|
}
|
2015-03-17 08:51:20 -04:00
|
|
|
getTitle() {
|
|
|
|
return this.defaultDoc().title || "";
|
|
|
|
}
|
|
|
|
setTitle(newTitle:string) {
|
|
|
|
this.defaultDoc().title = newTitle;
|
|
|
|
}
|
2015-03-01 16:17:36 -05:00
|
|
|
isTemplateElement(el:any):boolean {
|
|
|
|
return this.isElementNode(el) && this.tagName(el) === "template";
|
|
|
|
}
|
|
|
|
isTextNode(node):boolean {
|
|
|
|
return treeAdapter.isTextNode(node);
|
|
|
|
}
|
|
|
|
isCommentNode(node):boolean {
|
2015-03-19 06:35:48 -04:00
|
|
|
return treeAdapter.isCommentNode(node);
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
isElementNode(node):boolean {
|
|
|
|
return node ? treeAdapter.isElementNode(node) : false;
|
|
|
|
}
|
|
|
|
hasShadowRoot(node):boolean {
|
|
|
|
return isPresent(node.shadowRoot);
|
|
|
|
}
|
2015-03-23 19:46:18 -04:00
|
|
|
isShadowRoot(node): boolean {
|
|
|
|
return this.getShadowRoot(node) == node;
|
|
|
|
}
|
2015-03-01 16:17:36 -05:00
|
|
|
importIntoDoc(node) {
|
|
|
|
return this.clone(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 = ListWrapper.create();
|
|
|
|
for (var i = 0; i < parsedRules.length; i++) {
|
|
|
|
var parsedRule = parsedRules[i];
|
|
|
|
var rule = {cssText: css};
|
|
|
|
rule.style = {content: "", cssText: ""};
|
|
|
|
if (parsedRule.type == "rule") {
|
|
|
|
rule.type = 1;
|
|
|
|
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];
|
|
|
|
rule.style[declaration.property] = declaration.value;
|
|
|
|
rule.style.cssText += declaration.property + ": " + declaration.value + ";";
|
2015-03-12 12:28:35 -04:00
|
|
|
}
|
2015-03-01 16:17:36 -05:00
|
|
|
} else if (parsedRule.type == "media") {
|
|
|
|
rule.type = 4;
|
|
|
|
rule.media = {mediaText: parsedRule.media};
|
|
|
|
if (parsedRule.rules) {
|
|
|
|
rule.cssRules = this._buildRules(parsedRule.rules);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ListWrapper.push(rules, rule);
|
|
|
|
}
|
|
|
|
return rules;
|
|
|
|
}
|
|
|
|
cssToRules(css:string): List {
|
|
|
|
css = css.replace(/url\(\'(.+)\'\)/g, 'url($1)');
|
|
|
|
var rules = ListWrapper.create();
|
|
|
|
var parsedCSS = cssParse(css, {silent: true});
|
|
|
|
if (parsedCSS.stylesheet && parsedCSS.stylesheet.rules) {
|
|
|
|
rules = this._buildRules(parsedCSS.stylesheet.rules, css);
|
|
|
|
}
|
|
|
|
return rules;
|
|
|
|
}
|
2015-03-19 06:35:48 -04:00
|
|
|
supportsDOMEvents(): boolean {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
supportsNativeShadowDOM(): boolean {
|
|
|
|
return false;
|
|
|
|
}
|
2015-04-21 13:30:55 -04:00
|
|
|
getGlobalEventTarget(target:string) {
|
|
|
|
if (target == "window") {
|
|
|
|
return this.defaultDoc()._window;
|
|
|
|
} else if (target == "document") {
|
|
|
|
return this.defaultDoc();
|
|
|
|
} else if (target == "body") {
|
|
|
|
return this.defaultDoc().body;
|
|
|
|
}
|
|
|
|
}
|
2015-05-05 17:50:53 -04:00
|
|
|
getHistory() {
|
|
|
|
throw 'not implemented';
|
|
|
|
}
|
|
|
|
getLocation() {
|
|
|
|
throw 'not implemented';
|
|
|
|
}
|
2015-05-21 05:54:31 -04:00
|
|
|
getUserAgent() {
|
|
|
|
return "Fake user agent";
|
|
|
|
}
|
2015-05-28 17:56:40 -04:00
|
|
|
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;
|
|
|
|
}
|
2015-03-01 16:17:36 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//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"];
|