mirror of https://github.com/artf/grapesjs.git
nocodeframeworkdrag-and-dropsite-buildersite-generatortemplate-builderui-builderweb-builderweb-builder-frameworkwebsite-builderno-codepage-builder
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
3.0 KiB
118 lines
3.0 KiB
// DOM helpers
|
|
import { each, isUndefined, isString } from 'underscore';
|
|
|
|
const KEY_TAG = 'tag';
|
|
const KEY_ATTR = 'attributes';
|
|
const KEY_CHILD = 'children';
|
|
|
|
export const motionsEv =
|
|
'transitionend oTransitionEnd transitionend webkitTransitionEnd';
|
|
|
|
export const isDoc = el => el && el.nodeType === 9;
|
|
|
|
export const removeEl = el => {
|
|
const parent = el && el.parentNode;
|
|
parent && parent.removeChild(el);
|
|
};
|
|
|
|
export const find = (el, query) => el.querySelectorAll(query);
|
|
|
|
export const attrUp = (el, attrs = {}) =>
|
|
el &&
|
|
el.setAttribute &&
|
|
each(attrs, (value, key) => el.setAttribute(key, value));
|
|
|
|
export const isVisible = el => {
|
|
return (
|
|
el && !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length)
|
|
);
|
|
};
|
|
|
|
export const empty = node => {
|
|
while (node.firstChild) node.removeChild(node.firstChild);
|
|
};
|
|
|
|
export const replaceWith = (oldEl, newEl) => {
|
|
oldEl.parentNode.replaceChild(newEl, oldEl);
|
|
};
|
|
|
|
export const appendAtIndex = (parent, child, index) => {
|
|
const { childNodes } = parent;
|
|
const total = childNodes.length;
|
|
const at = isUndefined(index) ? total : index;
|
|
|
|
if (isString(child)) {
|
|
parent.insertAdjacentHTML('beforeEnd', child);
|
|
child = parent.lastChild;
|
|
parent.removeChild(child);
|
|
}
|
|
|
|
if (at >= total) {
|
|
parent.appendChild(child);
|
|
} else {
|
|
parent.insertBefore(child, childNodes[at]);
|
|
}
|
|
};
|
|
|
|
export const append = (parent, child) => appendAtIndex(parent, child);
|
|
|
|
export const createEl = (tag, attrs = '', child) => {
|
|
const el = document.createElement(tag);
|
|
attrs && each(attrs, (value, key) => el.setAttribute(key, value));
|
|
|
|
if (child) {
|
|
if (isString(child)) el.innerHTML = child;
|
|
else el.appendChild(child);
|
|
}
|
|
|
|
return el;
|
|
};
|
|
|
|
export const createText = str => document.createTextNode(str);
|
|
|
|
// Unfortunately just creating `KeyboardEvent(e.type, e)` is not enough,
|
|
// the keyCode/which will be always `0`. Even if it's an old/deprecated
|
|
// property keymaster (and many others) still use it... using `defineProperty`
|
|
// hack seems the only way
|
|
export const createCustomEvent = (e, cls) => {
|
|
let oEvent;
|
|
const { type } = e;
|
|
try {
|
|
oEvent = new window[cls](type, e);
|
|
} catch (err) {
|
|
oEvent = document.createEvent(cls);
|
|
oEvent.initEvent(type, true, true);
|
|
}
|
|
oEvent._parentEvent = e;
|
|
if (type.indexOf('key') === 0) {
|
|
oEvent.keyCodeVal = e.keyCode;
|
|
['keyCode', 'which'].forEach(prop => {
|
|
Object.defineProperty(oEvent, prop, {
|
|
get() {
|
|
return this.keyCodeVal;
|
|
}
|
|
});
|
|
});
|
|
}
|
|
return oEvent;
|
|
};
|
|
|
|
/**
|
|
* Append an array of vNodes to an element
|
|
* @param {HTMLElement} node HTML element
|
|
* @param {Array} vNodes Array of node objects
|
|
*/
|
|
export const appendVNodes = (node, vNodes = []) => {
|
|
const vNodesArr = Array.isArray(vNodes) ? vNodes : [vNodes];
|
|
vNodesArr.forEach(vnode => {
|
|
const tag = vnode[KEY_TAG] || 'div';
|
|
const attr = vnode[KEY_ATTR] || {};
|
|
const el = document.createElement(tag);
|
|
|
|
each(attr, (value, key) => {
|
|
el.setAttribute(key, value);
|
|
});
|
|
|
|
node.appendChild(el);
|
|
});
|
|
};
|
|
|