jodit
Version:
Jodit is an awesome and useful wysiwyg editor with filebrowser
131 lines (130 loc) • 3.85 kB
JavaScript
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Released under MIT see LICENSE.txt in the project root for license information.
* Copyright (c) 2013-2026 Valerii Chupurnov. All rights reserved. https://xdsoft.net
*/
import { IS_ES_NEXT, IS_IE } from "../../constants.js";
import { Dom } from "../../dom/dom.js";
import { toArray } from "../array/to-array.js";
import { isString } from "../checker/is-string.js";
import { camelCase } from "../string/camel-case.js";
import { attr } from "./attr.js";
import { error } from "./error/index.js";
let temp = 1;
const $$temp = () => {
temp++;
return temp;
};
/**
* @deprecated Do not use it in new code
*/
export function $$(selector, root) {
let result;
if (!IS_ES_NEXT &&
/:scope/.test(selector) &&
IS_IE &&
!(root && root.nodeType === Node.DOCUMENT_NODE)) {
const id = root.id, temp_id = id ||
'_selector_id_' + String(Math.random()).slice(2) + $$temp();
selector = selector.replace(/:scope/g, '#' + temp_id);
!id && root.setAttribute('id', temp_id);
result = root.parentNode.querySelectorAll(selector);
if (!id) {
root.removeAttribute('id');
}
}
else {
result = root.querySelectorAll(selector);
}
return [].slice.call(result);
}
/**
* Calculate XPath selector
*/
export const getXPathByElement = (element, root) => {
if (!element || element.nodeType !== Node.ELEMENT_NODE) {
return '';
}
if (!element.parentNode || root === element) {
return '';
}
if (element.id) {
return "//*[@id='" + element.id + "']";
}
const sames = [].filter.call(element.parentNode.childNodes, (x) => x.nodeName === element.nodeName);
return (getXPathByElement(element.parentNode, root) +
'/' +
element.nodeName.toLowerCase() +
(sames.length > 1
? '[' + (toArray(sames).indexOf(element) + 1) + ']'
: ''));
};
/**
* Find all `ref` or `data-ref` elements inside HTMLElement
*/
export const refs = (root) => {
if ('container' in root) {
root = root.container;
}
return $$('[ref],[data-ref]', root).reduce((def, child) => {
const key = attr(child, '-ref');
if (key && isString(key)) {
def[camelCase(key)] = child;
def[key] = child;
}
return def;
}, {});
};
/**
* Calculate full CSS selector
*/
export const cssPath = (el) => {
if (!Dom.isElement(el)) {
return null;
}
const path = [];
let start = el;
while (start && start.nodeType === Node.ELEMENT_NODE) {
let selector = start.nodeName.toLowerCase();
if (start.id) {
selector += '#' + start.id;
path.unshift(selector);
break;
}
else {
let sib = start, nth = 1;
do {
sib = sib.previousElementSibling;
if (sib && sib.nodeName.toLowerCase() === selector) {
nth++;
}
} while (sib);
selector += ':nth-of-type(' + nth + ')';
}
path.unshift(selector);
start = start.parentNode;
}
return path.join(' > ');
};
/**
* Try to find element by selector
*/
export function resolveElement(element, od) {
let resolved = element;
if (isString(element)) {
try {
resolved = od.querySelector(element);
}
catch (_a) {
throw error('String "' + element + '" should be valid HTML selector');
}
}
// Duck checking
if (!resolved ||
typeof resolved !== 'object' ||
!Dom.isElement(resolved) ||
!resolved.cloneNode) {
throw error('Element "' + element + '" should be string or HTMLElement instance');
}
return resolved;
}