blob: ab285ae47078f6892e1c0e26bc48b7d5089adb88 [file] [log] [blame]
// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
/**
* Custom DOM elements.
*
* This library provides access to the Polymer project's
* [Custom Elements]
* (http://www.polymer-project.org/platform/custom-elements.html)
* API, which lets you define your own elements. With custom elements, you
* associate code with custom tag names, and then use those custom tag names
* as you would any standard tag. For more information, see the
* [Polymer.dart homepage](https://www.dartlang.org/polymer-dart/) and its
* [custom element example]
* (https://www.dartlang.org/polymer-dart/#custom-elements).
*/
library custom_element;
import 'dart:async';
import 'dart:html';
import 'src/custom_tag_name.dart';
/**
* *Deprecated* -- do not use. Extend [HtmlElement] and use
* [document.register] instead. If running on a browser without native
* document.register, you can add the polyfill script to your page:
*
* <script src="packages/custom_element/custom-elements.debug.js"></script>
*
* You can also use "custom-elements.min.js" for the minified version.
*/
// This is only used by Dart Web UI.
class CustomElement implements Element {
/** The web component element wrapped by this class. */
Element _host;
List _shadowRoots;
/**
* Shadow roots generated by dwc for each custom element, indexed by the
* custom element tag name.
*/
Map<String, dynamic> _generatedRoots = {};
/**
* Temporary property until components extend [Element]. An element can
* only be associated with one host, and it is an error to use a web component
* without an associated host element.
*/
Element get host {
if (_host == null) throw new StateError('host element has not been set.');
return _host;
}
set host(Element value) {
if (value == null) {
throw new ArgumentError('host must not be null.');
}
// TODO(jmesserly): xtag used to return "null" if unset, now it checks for
// "this". Temporarily allow both.
var xtag = value.xtag;
if (xtag != null && xtag != value) {
throw new ArgumentError('host must not have its xtag property set.');
}
if (_host != null) {
throw new StateError('host can only be set once.');
}
value.xtag = this;
_host = value;
}
/**
* **Note**: This is an implementation helper and should not need to be called
* from your code.
*
* Creates the [ShadowRoot] backing this component.
*/
createShadowRoot([String componentName]) {
var root = host.createShadowRoot();
if (componentName != null) {
_generatedRoots[componentName] = root;
}
return root;
}
getShadowRoot(String componentName) => _generatedRoots[componentName];
/**
* Invoked when this component gets created.
* Note that [root] will be a [ShadowRoot] if the browser supports Shadow DOM.
*/
void created() {}
// Added for analyzer warnings
@deprecated
void createdCallback() {}
/** Invoked when this component gets inserted in the DOM tree. */
void inserted() {}
@deprecated
void enteredView() {}
/** Invoked when this component is removed from the DOM tree. */
void removed() {}
@deprecated
void leftView() {}
/** Invoked when any attribute of the component is modified. */
void attributeChanged(String name, String oldValue, String newValue) =>
host.attributeChanged(name, oldValue, newValue);
// TODO(efortuna): Update these when we decide what to do with these
// properties.
@deprecated
String getAttribute(String name) =>
host.getAttribute(name);
@deprecated
String getAttributeNS(String namespaceUri, String localName) =>
host.getAttributeNS(namespaceUri, localName);
@deprecated
String setAttributeNS(
String namespaceUri, String localName, String value) {
host.setAttributeNS(namespaceUri, localName, value);
}
@deprecated
void setAttribute(String name, String value) =>
host.setAttribute(name, value);
@deprecated
List<Node> get childNodes => host.childNodes;
// TODO(jmesserly): this forwarding is temporary until Dart supports
// subclassing Elements.
// TODO(jmesserly): we were missing the setter for title, are other things
// missing setters?
List<Node> get nodes => host.nodes;
set nodes(Iterable<Node> value) { host.nodes = value; }
/**
* Replaces this node with another node.
*/
Node replaceWith(Node otherNode) { host.replaceWith(otherNode); }
/**
* Removes this node from the DOM.
*/
void remove() => host.remove();
Node get nextNode => host.nextNode;
String get nodeName => host.nodeName;
Document get ownerDocument => host.ownerDocument;
Node get previousNode => host.previousNode;
String get text => host.text;
set text(String v) { host.text = v; }
bool contains(Node other) => host.contains(other);
bool hasChildNodes() => host.hasChildNodes();
Node insertBefore(Node newChild, Node refChild) =>
host.insertBefore(newChild, refChild);
Node insertAllBefore(Iterable<Node> newChild, Node refChild) =>
host.insertAllBefore(newChild, refChild);
Map<String, String> get attributes => host.attributes;
set attributes(Map<String, String> value) {
host.attributes = value;
}
List<Element> get elements => host.children;
set elements(List<Element> value) {
host.children = value;
}
List<Element> get children => host.children;
set children(List<Element> value) {
host.children = value;
}
Set<String> get classes => host.classes;
set classes(Iterable<String> value) {
host.classes = value;
}
CssRect get contentEdge => host.contentEdge;
CssRect get paddingEdge => host.paddingEdge;
CssRect get borderEdge => host.borderEdge;
CssRect get marginEdge => host.marginEdge;
Point get documentOffset => host.documentOffset;
Point offsetTo(Element parent) => host.offsetTo(parent);
Map<String, String> getNamespacedAttributes(String namespace) =>
host.getNamespacedAttributes(namespace);
CssStyleDeclaration getComputedStyle([String pseudoElement])
=> host.getComputedStyle(pseudoElement);
Element clone(bool deep) => host.clone(deep);
Element get parent => host.parent;
Node get parentNode => host.parentNode;
String get nodeValue => host.nodeValue;
Events get on => host.on;
String get contentEditable => host.contentEditable;
set contentEditable(String v) { host.contentEditable = v; }
String get dir => host.dir;
set dir(String v) { host.dir = v; }
bool get draggable => host.draggable;
set draggable(bool v) { host.draggable = v; }
bool get hidden => host.hidden;
set hidden(bool v) { host.hidden = v; }
String get id => host.id;
set id(String v) { host.id = v; }
String get innerHtml => host.innerHtml;
void set innerHtml(String v) {
host.innerHtml = v;
}
void setInnerHtml(String html,
{NodeValidator validator, NodeTreeSanitizer treeSanitizer}) {
host.setInnerHtml(html, validator: validator, treeSanitizer: treeSanitizer);
}
DocumentFragment createFragment(String html,
{NodeValidator validator, NodeTreeSanitizer treeSanitizer}) =>
host.createFragment(html,
validator: validator, treeSanitizer: treeSanitizer);
InputMethodContext get inputMethodContext => host.inputMethodContext;
bool get isContentEditable => host.isContentEditable;
String get lang => host.lang;
set lang(String v) { host.lang = v; }
String get outerHtml => host.outerHtml;
bool get spellcheck => host.spellcheck;
set spellcheck(bool v) { host.spellcheck = v; }
int get tabIndex => host.tabIndex;
set tabIndex(int i) { host.tabIndex = i; }
String get title => host.title;
set title(String value) { host.title = value; }
bool get translate => host.translate;
set translate(bool v) { host.translate = v; }
String get dropzone => host.dropzone;
set dropzone(String v) { host.dropzone = v; }
void click() { host.click(); }
List<Node> getDestinationInsertionPoints() =>
host.getDestinationInsertionPoints();
Element insertAdjacentElement(String where, Element element) =>
host.insertAdjacentElement(where, element);
void insertAdjacentHtml(String where, String html) {
host.insertAdjacentHtml(where, html);
}
void insertAdjacentText(String where, String text) {
host.insertAdjacentText(where, text);
}
Map<String, String> get dataset => host.dataset;
set dataset(Map<String, String> value) {
host.dataset = value;
}
Element get nextElementSibling => host.nextElementSibling;
Element get offsetParent => host.offsetParent;
Element get previousElementSibling => host.previousElementSibling;
CssStyleDeclaration get style => host.style;
String get tagName => host.tagName;
String get pseudo => host.pseudo;
void set pseudo(String value) {
host.pseudo = value;
}
// Note: we are not polyfilling the shadow root here. This will be fixed when
// we migrate to the JS Shadow DOM polyfills. You can still use getShadowRoot
// to retrieve a node that behaves as the shadow root when Shadow DOM is not
// enabled.
ShadowRoot get shadowRoot => host.shadowRoot;
void blur() { host.blur(); }
void focus() { host.focus(); }
void scrollByLines(int lines) {
host.scrollByLines(lines);
}
void scrollByPages(int pages) {
host.scrollByPages(pages);
}
void scrollIntoView([ScrollAlignment alignment]) {
host.scrollIntoView(alignment);
}
bool matches(String selectors) => host.matches(selectors);
bool matchesWithAncestors(String selectors) =>
host.matchesWithAncestors(selectors);
@deprecated
void requestFullScreen(int flags) { requestFullscreen(); }
void requestFullscreen() { host.requestFullscreen(); }
void requestPointerLock() { host.requestPointerLock(); }
Element querySelector(String selectors) => host.querySelector(selectors);
ElementList querySelectorAll(String selectors) =>
host.querySelectorAll(selectors);
@deprecated
Element query(String selectors) => host.querySelector(selectors);
@deprecated
ElementList queryAll(String selectors) => host.querySelectorAll(selectors);
String get className => host.className;
set className(String value) { host.className = value; }
@deprecated
int get clientHeight => client.height;
@deprecated
int get clientLeft => client.left;
@deprecated
int get clientTop => client.top;
@deprecated
int get clientWidth => client.width;
Rectangle get client => host.client;
@deprecated
int get offsetHeight => offset.height;
@deprecated
int get offsetLeft => offset.left;
@deprecated
int get offsetTop => offset.top;
@deprecated
int get offsetWidth => offset.width;
Rectangle get offset => host.offset;
int get scrollHeight => host.scrollHeight;
int get scrollLeft => host.scrollLeft;
int get scrollTop => host.scrollTop;
set scrollLeft(int value) { host.scrollLeft = value; }
set scrollTop(int value) { host.scrollTop = value; }
int get scrollWidth => host.scrollWidth;
Rectangle getBoundingClientRect() => host.getBoundingClientRect();
List<Rectangle> getClientRects() => host.getClientRects();
List<Node> getElementsByClassName(String name) =>
host.getElementsByClassName(name);
Node get firstChild => host.firstChild;
Node get lastChild => host.lastChild;
String get localName => host.localName;
String get namespaceUri => host.namespaceUri;
int get nodeType => host.nodeType;
void addEventListener(String type, EventListener listener,
[bool useCapture]) {
host.addEventListener(type, listener, useCapture);
}
bool dispatchEvent(Event event) => host.dispatchEvent(event);
void removeEventListener(String type, EventListener listener,
[bool useCapture]) {
host.removeEventListener(type, listener, useCapture);
}
get xtag => host.xtag;
set xtag(value) { host.xtag = value; }
Node append(Node e) => host.append(e);
void appendText(String text) => host.appendText(text);
void appendHtml(String html) => host.appendHtml(html);
String get regionOverset => host.regionOverset;
List<Range> getRegionFlowRanges() => host.getRegionFlowRanges();
// TODO(jmesserly): rename "created" to "onCreated".
void onCreated() => created();
Stream<Event> get onAbort => host.onAbort;
Stream<Event> get onBeforeCopy => host.onBeforeCopy;
Stream<Event> get onBeforeCut => host.onBeforeCut;
Stream<Event> get onBeforePaste => host.onBeforePaste;
Stream<Event> get onBlur => host.onBlur;
Stream<Event> get onChange => host.onChange;
Stream<MouseEvent> get onClick => host.onClick;
Stream<MouseEvent> get onContextMenu => host.onContextMenu;
Stream<Event> get onCopy => host.onCopy;
Stream<Event> get onCut => host.onCut;
Stream<Event> get onDoubleClick => host.onDoubleClick;
Stream<MouseEvent> get onDrag => host.onDrag;
Stream<MouseEvent> get onDragEnd => host.onDragEnd;
Stream<MouseEvent> get onDragEnter => host.onDragEnter;
Stream<MouseEvent> get onDragLeave => host.onDragLeave;
Stream<MouseEvent> get onDragOver => host.onDragOver;
Stream<MouseEvent> get onDragStart => host.onDragStart;
Stream<MouseEvent> get onDrop => host.onDrop;
Stream<Event> get onError => host.onError;
Stream<Event> get onFocus => host.onFocus;
Stream<Event> get onInput => host.onInput;
Stream<Event> get onInvalid => host.onInvalid;
Stream<KeyboardEvent> get onKeyDown => host.onKeyDown;
Stream<KeyboardEvent> get onKeyPress => host.onKeyPress;
Stream<KeyboardEvent> get onKeyUp => host.onKeyUp;
Stream<Event> get onLoad => host.onLoad;
Stream<MouseEvent> get onMouseDown => host.onMouseDown;
Stream<MouseEvent> get onMouseEnter => host.onMouseEnter;
Stream<MouseEvent> get onMouseLeave => host.onMouseLeave;
Stream<MouseEvent> get onMouseMove => host.onMouseMove;
Stream<Event> get onFullscreenChange => host.onFullscreenChange;
Stream<Event> get onFullscreenError => host.onFullscreenError;
Stream<Event> get onPaste => host.onPaste;
Stream<Event> get onReset => host.onReset;
Stream<Event> get onScroll => host.onScroll;
Stream<Event> get onSearch => host.onSearch;
Stream<Event> get onSelect => host.onSelect;
Stream<Event> get onSelectStart => host.onSelectStart;
Stream<Event> get onSubmit => host.onSubmit;
Stream<MouseEvent> get onMouseOut => host.onMouseOut;
Stream<MouseEvent> get onMouseOver => host.onMouseOver;
Stream<MouseEvent> get onMouseUp => host.onMouseUp;
Stream<TouchEvent> get onTouchCancel => host.onTouchCancel;
Stream<TouchEvent> get onTouchEnd => host.onTouchEnd;
Stream<TouchEvent> get onTouchEnter => host.onTouchEnter;
Stream<TouchEvent> get onTouchLeave => host.onTouchLeave;
Stream<TouchEvent> get onTouchMove => host.onTouchMove;
Stream<TouchEvent> get onTouchStart => host.onTouchStart;
Stream<TransitionEvent> get onTransitionEnd => host.onTransitionEnd;
// TODO(sigmund): do the normal forwarding when dartbug.com/7919 is fixed.
Stream<WheelEvent> get onMouseWheel {
throw new UnsupportedError('onMouseWheel is not supported');
}
}