2 * TinyMCE version 6.8.3 (2024-02-08)
8 var global$4 = tinymce.util.Tools.resolve('tinymce.PluginManager');
10 const hasProto = (v, constructor, predicate) => {
12 if (predicate(v, constructor.prototype)) {
15 return ((_a = v.constructor) === null || _a === void 0 ? void 0 : _a.name) === constructor.name;
22 } else if (t === 'object' && Array.isArray(x)) {
24 } else if (t === 'object' && hasProto(x, String, (o, proto) => proto.isPrototypeOf(o))) {
30 const isType = type => value => typeOf(value) === type;
31 const isSimpleType = type => value => typeof value === type;
32 const isString = isType('string');
33 const isObject = isType('object');
34 const isArray = isType('array');
35 const isFunction = isSimpleType('function');
37 var global$3 = tinymce.util.Tools.resolve('tinymce.dom.DOMUtils');
39 var global$2 = tinymce.util.Tools.resolve('tinymce.EditorManager');
41 var global$1 = tinymce.util.Tools.resolve('tinymce.Env');
43 var global = tinymce.util.Tools.resolve('tinymce.util.Tools');
45 const option = name => editor => editor.options.get(name);
46 const register = editor => {
47 const registerOption = editor.options.register;
48 const filterProcessor = value => isString(value) || isFunction(value) || isObject(value);
49 registerOption('importcss_merge_classes', {
53 registerOption('importcss_exclusive', {
57 registerOption('importcss_selector_converter', { processor: 'function' });
58 registerOption('importcss_selector_filter', { processor: filterProcessor });
59 registerOption('importcss_file_filter', { processor: filterProcessor });
60 registerOption('importcss_groups', { processor: 'object[]' });
61 registerOption('importcss_append', {
66 const shouldMergeClasses = option('importcss_merge_classes');
67 const shouldImportExclusive = option('importcss_exclusive');
68 const getSelectorConverter = option('importcss_selector_converter');
69 const getSelectorFilter = option('importcss_selector_filter');
70 const getCssGroups = option('importcss_groups');
71 const shouldAppend = option('importcss_append');
72 const getFileFilter = option('importcss_file_filter');
73 const getSkin = option('skin');
74 const getSkinUrl = option('skin_url');
76 const nativePush = Array.prototype.push;
77 const map = (xs, f) => {
78 const len = xs.length;
79 const r = new Array(len);
80 for (let i = 0; i < len; i++) {
86 const flatten = xs => {
88 for (let i = 0, len = xs.length; i < len; ++i) {
89 if (!isArray(xs[i])) {
90 throw new Error('Arr.flatten item ' + i + ' was not an array, input: ' + xs);
92 nativePush.apply(r, xs[i]);
96 const bind = (xs, f) => flatten(map(xs, f));
98 const generate = () => {
99 const ungroupedOrder = [];
100 const groupOrder = [];
102 const addItemToGroup = (groupTitle, itemInfo) => {
103 if (groups[groupTitle]) {
104 groups[groupTitle].push(itemInfo);
106 groupOrder.push(groupTitle);
107 groups[groupTitle] = [itemInfo];
110 const addItem = itemInfo => {
111 ungroupedOrder.push(itemInfo);
113 const toFormats = () => {
114 const groupItems = bind(groupOrder, g => {
115 const items = groups[g];
116 return items.length === 0 ? [] : [{
121 return groupItems.concat(ungroupedOrder);
130 const internalEditorStyle = /^\.(?:ephox|tiny-pageembed|mce)(?:[.-]+\w+)+$/;
131 const removeCacheSuffix = url => {
132 const cacheSuffix = global$1.cacheSuffix;
134 url = url.replace('?' + cacheSuffix, '').replace('&' + cacheSuffix, '');
138 const isSkinContentCss = (editor, href) => {
139 const skin = getSkin(editor);
141 const skinUrlBase = getSkinUrl(editor);
142 const skinUrl = skinUrlBase ? editor.documentBaseURI.toAbsolute(skinUrlBase) : global$2.baseURL + '/skins/ui/' + skin;
143 const contentSkinUrlPart = global$2.baseURL + '/skins/content/';
144 return href === skinUrl + '/content' + (editor.inline ? '.inline' : '') + '.min.css' || href.indexOf(contentSkinUrlPart) !== -1;
148 const compileFilter = filter => {
149 if (isString(filter)) {
151 return value.indexOf(filter) !== -1;
153 } else if (filter instanceof RegExp) {
155 return filter.test(value);
160 const isCssImportRule = rule => rule.styleSheet;
161 const isCssPageRule = rule => rule.selectorText;
162 const getSelectors = (editor, doc, fileFilter) => {
163 const selectors = [];
164 const contentCSSUrls = {};
165 const append = (styleSheet, imported) => {
166 let href = styleSheet.href;
168 href = removeCacheSuffix(href);
169 if (!href || fileFilter && !fileFilter(href, imported) || isSkinContentCss(editor, href)) {
172 global.each(styleSheet.imports, styleSheet => {
173 append(styleSheet, true);
176 rules = styleSheet.cssRules || styleSheet.rules;
179 global.each(rules, cssRule => {
180 if (isCssImportRule(cssRule) && cssRule.styleSheet) {
181 append(cssRule.styleSheet, true);
182 } else if (isCssPageRule(cssRule)) {
183 global.each(cssRule.selectorText.split(','), selector => {
184 selectors.push(global.trim(selector));
189 global.each(editor.contentCSS, url => {
190 contentCSSUrls[url] = true;
193 fileFilter = (href, imported) => {
194 return imported || contentCSSUrls[href];
198 global.each(doc.styleSheets, styleSheet => {
205 const defaultConvertSelectorToFormat = (editor, selectorText) => {
207 const selector = /^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(selectorText);
211 const elementName = selector[1];
212 const classes = selector[2].substr(1).split('.').join(' ');
213 const inlineSelectorElements = global.makeMap('a,img');
215 format = { title: selectorText };
216 if (editor.schema.getTextBlockElements()[elementName]) {
217 format.block = elementName;
218 } else if (editor.schema.getBlockElements()[elementName] || inlineSelectorElements[elementName.toLowerCase()]) {
219 format.selector = elementName;
221 format.inline = elementName;
223 } else if (selector[2]) {
226 title: selectorText.substr(1),
230 if (shouldMergeClasses(editor)) {
231 format.classes = classes;
233 format.attributes = { class: classes };
237 const getGroupsBySelector = (groups, selector) => {
238 return global.grep(groups, group => {
239 return !group.filter || group.filter(selector);
242 const compileUserDefinedGroups = groups => {
243 return global.map(groups, group => {
244 return global.extend({}, group, {
247 filter: compileFilter(group.filter)
251 const isExclusiveMode = (editor, group) => {
252 return group === null || shouldImportExclusive(editor);
254 const isUniqueSelector = (editor, selector, group, globallyUniqueSelectors) => {
255 return !(isExclusiveMode(editor, group) ? selector in globallyUniqueSelectors : selector in group.selectors);
257 const markUniqueSelector = (editor, selector, group, globallyUniqueSelectors) => {
258 if (isExclusiveMode(editor, group)) {
259 globallyUniqueSelectors[selector] = true;
261 group.selectors[selector] = true;
264 const convertSelectorToFormat = (editor, plugin, selector, group) => {
265 let selectorConverter;
266 const converter = getSelectorConverter(editor);
267 if (group && group.selector_converter) {
268 selectorConverter = group.selector_converter;
269 } else if (converter) {
270 selectorConverter = converter;
272 selectorConverter = () => {
273 return defaultConvertSelectorToFormat(editor, selector);
276 return selectorConverter.call(plugin, selector, group);
278 const setup = editor => {
279 editor.on('init', () => {
280 const model = generate();
281 const globallyUniqueSelectors = {};
282 const selectorFilter = compileFilter(getSelectorFilter(editor));
283 const groups = compileUserDefinedGroups(getCssGroups(editor));
284 const processSelector = (selector, group) => {
285 if (isUniqueSelector(editor, selector, group, globallyUniqueSelectors)) {
286 markUniqueSelector(editor, selector, group, globallyUniqueSelectors);
287 const format = convertSelectorToFormat(editor, editor.plugins.importcss, selector, group);
289 const formatName = format.name || global$3.DOM.uniqueId();
290 editor.formatter.register(formatName, format);
299 global.each(getSelectors(editor, editor.getDoc(), compileFilter(getFileFilter(editor))), selector => {
300 if (!internalEditorStyle.test(selector)) {
301 if (!selectorFilter || selectorFilter(selector)) {
302 const selectorGroups = getGroupsBySelector(groups, selector);
303 if (selectorGroups.length > 0) {
304 global.each(selectorGroups, group => {
305 const menuItem = processSelector(selector, group);
307 model.addItemToGroup(group.title, menuItem);
311 const menuItem = processSelector(selector, null);
313 model.addItem(menuItem);
319 const items = model.toFormats();
320 editor.dispatch('addStyleModifications', {
322 replace: !shouldAppend(editor)
327 const get = editor => {
328 const convertSelectorToFormat = selectorText => {
329 return defaultConvertSelectorToFormat(editor, selectorText);
331 return { convertSelectorToFormat };
335 global$4.add('importcss', editor => {