aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/preact/src/dom/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/preact/src/dom/index.js')
-rw-r--r--thirdparty/preact/src/dom/index.js100
1 files changed, 100 insertions, 0 deletions
diff --git a/thirdparty/preact/src/dom/index.js b/thirdparty/preact/src/dom/index.js
new file mode 100644
index 000000000..248a3cdc5
--- /dev/null
+++ b/thirdparty/preact/src/dom/index.js
@@ -0,0 +1,100 @@
+import { ATTR_KEY, NON_DIMENSION_PROPS, NON_BUBBLING_EVENTS } from '../constants';
+import options from '../options';
+import { toLowerCase, isString, isFunction, hashToClassName } from '../util';
+
+
+
+
+/** Removes a given DOM Node from its parent. */
+export function removeNode(node) {
+ let p = node.parentNode;
+ if (p) p.removeChild(node);
+}
+
+
+/** Set a named attribute on the given Node, with special behavior for some names and event handlers.
+ * If `value` is `null`, the attribute/handler will be removed.
+ * @param {Element} node An element to mutate
+ * @param {string} name The name/key to set, such as an event or attribute name
+ * @param {any} value An attribute value, such as a function to be used as an event handler
+ * @param {any} previousValue The last value that was set for this name/node pair
+ * @private
+ */
+export function setAccessor(node, name, value, old, isSvg) {
+ node[ATTR_KEY][name] = value;
+
+ if (name==='className') name = 'class';
+
+ if (name==='class' && value && typeof value==='object') {
+ value = hashToClassName(value);
+ }
+
+ if (name==='key' || name==='children' || name==='innerHTML') {
+ // skip these
+ }
+ else if (name==='class' && !isSvg) {
+ node.className = value || '';
+ }
+ else if (name==='style') {
+ if (!value || isString(value) || isString(old)) {
+ node.style.cssText = value || '';
+ }
+ if (value && typeof value==='object') {
+ if (!isString(old)) {
+ for (let i in old) if (!(i in value)) node.style[i] = '';
+ }
+ for (let i in value) {
+ node.style[i] = typeof value[i]==='number' && !NON_DIMENSION_PROPS[i] ? (value[i]+'px') : value[i];
+ }
+ }
+ }
+ else if (name==='dangerouslySetInnerHTML') {
+ if (value) node.innerHTML = value.__html;
+ }
+ else if (name[0]=='o' && name[1]=='n') {
+ let l = node._listeners || (node._listeners = {});
+ name = toLowerCase(name.substring(2));
+ // @TODO: this might be worth it later, un-breaks focus/blur bubbling in IE9:
+ // if (node.attachEvent) name = name=='focus'?'focusin':name=='blur'?'focusout':name;
+ if (value) {
+ if (!l[name]) node.addEventListener(name, eventProxy, !!NON_BUBBLING_EVENTS[name]);
+ }
+ else if (l[name]) {
+ node.removeEventListener(name, eventProxy, !!NON_BUBBLING_EVENTS[name]);
+ }
+ l[name] = value;
+ }
+ else if (name!=='list' && name!=='type' && !isSvg && name in node) {
+ setProperty(node, name, value==null ? '' : value);
+ if (value==null || value===false) node.removeAttribute(name);
+ }
+ else {
+ let ns = isSvg && name.match(/^xlink\:?(.+)/);
+ if (value==null || value===false) {
+ if (ns) node.removeAttributeNS('http://www.w3.org/1999/xlink', toLowerCase(ns[1]));
+ else node.removeAttribute(name);
+ }
+ else if (typeof value!=='object' && !isFunction(value)) {
+ if (ns) node.setAttributeNS('http://www.w3.org/1999/xlink', toLowerCase(ns[1]), value);
+ else node.setAttribute(name, value);
+ }
+ }
+}
+
+
+/** Attempt to set a DOM property to the given value.
+ * IE & FF throw for certain property-value combinations.
+ */
+function setProperty(node, name, value) {
+ try {
+ node[name] = value;
+ } catch (e) { }
+}
+
+
+/** Proxy an event to hooked event handlers
+ * @private
+ */
+function eventProxy(e) {
+ return this._listeners[e.type](options.event && options.event(e) || e);
+}