UNPKG

jodit

Version:

Jodit is an awesome and useful wysiwyg editor with filebrowser

160 lines (159 loc) 5.6 kB
/*! * Jodit Editor (https://xdsoft.net/jodit/) * Released under MIT see LICENSE.txt in the project root for license information. * Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net */ import { globalDocument } from "../../../constants.js"; import { Dom } from "../../../dom/dom.js"; import { getContainer } from "../../../global.js"; import { isBoolean, isNumber, isPlainObject, isString } from "../../../helpers/checker/index.js"; import { normalizeCssValue } from "../../../helpers/normalize/normalize-css-value.js"; import { size } from "../../../helpers/size/object-size.js"; import { kebabCase } from "../../../helpers/string/kebab-case.js"; import { assert, attr } from "../../../helpers/utils/index.js"; import { css } from "../../../helpers/utils/css.js"; import { dataBind } from "../../../helpers/utils/data-bind.js"; import { _PREFIX, CHANGE, UNSET, UNWRAP } from "../constants.js"; const tak = 'toggleAttributes'; /** * Toggles attributes * @private */ export function toggleAttributes(commitStyle, elm, jodit, mode, dry = false) { if (!dry && commitStyle.isApplied(elm, tak)) { return mode; } !dry && commitStyle.setApplied(elm, tak); const { attributes } = commitStyle.options; if (attributes && size(attributes) > 0) { Object.keys(attributes).forEach((key) => { const value = attributes[key]; switch (key) { case 'style': { mode = toggleStyle(commitStyle, jodit, value, elm, dry, mode); break; } case 'className': case 'class': mode = toggleClass(jodit, value, elm, mode, dry); break; default: mode = toggleAttribute(jodit, value, elm, key, dry, mode); } }); } return mode; } function toggleStyle(commitStyle, jodit, style, elm, dry, mode) { assert(isPlainObject(style) && size(style), 'Style must be an object'); Object.keys(style).forEach((rule) => { const inlineValue = elm.style.getPropertyValue(kebabCase(rule)); const newValue = style[rule]; if (inlineValue === '' && newValue == null) { return; } if (getNativeCSSValue(jodit, elm, rule) === normalizeCssValue(rule, newValue)) { if (!inlineValue) { return; } !dry && css(elm, rule, null); mode = UNSET; mode = removeExtraStyleAttribute(commitStyle, elm, mode); return; } mode = CHANGE; if (!dry) { css(elm, rule, newValue); mode = removeExtraStyleAttribute(commitStyle, elm, mode); } }); return mode; } function toggleClass(jodit, value, elm, mode, dry) { assert(isString(value), 'Class name must be a string'); const hook = jodit.e.fire.bind(jodit.e, `${_PREFIX}AfterToggleAttribute`); if (elm.classList.contains(value.toString())) { mode = UNSET; if (!dry) { elm.classList.remove(value); if (elm.classList.length === 0) { attr(elm, 'class', null); hook(mode, elm, 'class', null); } } } else { mode = CHANGE; if (!dry) { elm.classList.add(value); hook(mode, elm, 'class', value); } } return mode; } function toggleAttribute(jodit, value, elm, key, dry, mode) { assert(isString(value) || isNumber(value) || isBoolean(value) || value == null, 'Attribute value must be a string or number or boolean or null'); const hook = jodit.e.fire.bind(jodit.e, `${_PREFIX}AfterToggleAttribute`); if (attr(elm, key) === value) { !dry && attr(elm, key, null); mode = UNSET; !dry && hook(mode, elm, key, value); return mode; } mode = CHANGE; if (!dry) { attr(elm, key, value); hook(mode, elm, key, value); } return mode; } /** * If the element has an empty style attribute, it removes the attribute, * and if it is default, it removes the element itself */ function removeExtraStyleAttribute(commitStyle, elm, mode) { if (!attr(elm, 'style')) { attr(elm, 'style', null); if (elm.tagName.toLowerCase() === commitStyle.defaultTag) { Dom.unwrap(elm); mode = UNWRAP; } } return mode; } /** * Creates an iframe into which elements will be inserted to test their default styles in the browser */ function getShadowRoot(jodit) { var _a; if (dataBind(jodit, 'shadowRoot') !== undefined) { return dataBind(jodit, 'shadowRoot'); } const container = getContainer(jodit); const iframe = globalDocument.createElement('iframe'); css(iframe, { width: 0, height: 0, position: 'absolute', border: 0 }); iframe.src = 'about:blank'; container.appendChild(iframe); const doc = (_a = iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.document; const shadowRoot = !doc ? jodit.od.body : doc.body; dataBind(jodit, 'shadowRoot', shadowRoot); return shadowRoot; } /** * `strong -> fontWeight 700` */ function getNativeCSSValue(jodit, elm, key) { const newElm = jodit.create.element(elm.tagName.toLowerCase()); newElm.style.cssText = elm.style.cssText; const root = getShadowRoot(jodit); root.appendChild(newElm); const result = css(newElm, key); Dom.safeRemove(newElm); return result; }