init
This commit is contained in:
27
public/tinymce/src/plugins/visualchars/main/ts/Plugin.ts
Normal file
27
public/tinymce/src/plugins/visualchars/main/ts/Plugin.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
import { Cell } from '@ephox/katamari';
|
||||
import PluginManager from 'tinymce/core/api/PluginManager';
|
||||
import Api from './api/Api';
|
||||
import Commands from './api/Commands';
|
||||
import Keyboard from './core/Keyboard';
|
||||
import Bindings from './core/Bindings';
|
||||
import * as Buttons from './ui/Buttons';
|
||||
|
||||
PluginManager.add('visualchars', function (editor) {
|
||||
const toggleState = Cell(false);
|
||||
|
||||
Commands.register(editor, toggleState);
|
||||
Buttons.register(editor);
|
||||
Keyboard.setup(editor, toggleState);
|
||||
Bindings.setup(editor, toggleState);
|
||||
|
||||
return Api.get(toggleState);
|
||||
});
|
||||
|
||||
export default function () {}
|
||||
20
public/tinymce/src/plugins/visualchars/main/ts/api/Api.ts
Normal file
20
public/tinymce/src/plugins/visualchars/main/ts/api/Api.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
const get = function (toggleState) {
|
||||
const isEnabled = function () {
|
||||
return toggleState.get();
|
||||
};
|
||||
|
||||
return {
|
||||
isEnabled
|
||||
};
|
||||
};
|
||||
|
||||
export default {
|
||||
get
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
import Actions from '../core/Actions';
|
||||
|
||||
const register = function (editor, toggleState) {
|
||||
editor.addCommand('mceVisualChars', function () {
|
||||
Actions.toggleVisualChars(editor, toggleState);
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
register
|
||||
};
|
||||
14
public/tinymce/src/plugins/visualchars/main/ts/api/Events.ts
Normal file
14
public/tinymce/src/plugins/visualchars/main/ts/api/Events.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
const fireVisualChars = function (editor, state) {
|
||||
return editor.fire('VisualChars', { state });
|
||||
};
|
||||
|
||||
export default {
|
||||
fireVisualChars
|
||||
};
|
||||
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
import { Editor } from 'tinymce/core/api/Editor';
|
||||
|
||||
const isEnabledByDefault = (editor: Editor) => {
|
||||
return editor.getParam('visualchars_default_state', false);
|
||||
};
|
||||
|
||||
export default {
|
||||
isEnabledByDefault
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
import Events from '../api/Events';
|
||||
import VisualChars from './VisualChars';
|
||||
|
||||
const toggleVisualChars = function (editor, toggleState) {
|
||||
const body = editor.getBody();
|
||||
const selection = editor.selection;
|
||||
let bookmark;
|
||||
|
||||
toggleState.set(!toggleState.get());
|
||||
Events.fireVisualChars(editor, toggleState.get());
|
||||
|
||||
bookmark = selection.getBookmark();
|
||||
|
||||
if (toggleState.get() === true) {
|
||||
VisualChars.show(editor, body);
|
||||
} else {
|
||||
VisualChars.hide(editor, body);
|
||||
}
|
||||
|
||||
selection.moveToBookmark(bookmark);
|
||||
};
|
||||
|
||||
export default {
|
||||
toggleVisualChars
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
import { Editor } from 'tinymce/core/api/Editor';
|
||||
import Settings from '../api/Settings';
|
||||
import Actions from './Actions';
|
||||
|
||||
const setup = (editor: Editor, toggleState) => {
|
||||
editor.on('init', () => {
|
||||
// should be false when enabled, so toggling will change it to true
|
||||
const valueForToggling = !Settings.isEnabledByDefault(editor);
|
||||
toggleState.set(valueForToggling);
|
||||
Actions.toggleVisualChars(editor, toggleState);
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
setup
|
||||
};
|
||||
43
public/tinymce/src/plugins/visualchars/main/ts/core/Data.ts
Normal file
43
public/tinymce/src/plugins/visualchars/main/ts/core/Data.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
const charMap = {
|
||||
'\u00a0': 'nbsp',
|
||||
'\u00ad': 'shy'
|
||||
};
|
||||
|
||||
const charMapToRegExp = function (charMap, global?) {
|
||||
let key, regExp = '';
|
||||
|
||||
for (key in charMap) {
|
||||
regExp += key;
|
||||
}
|
||||
|
||||
return new RegExp('[' + regExp + ']', global ? 'g' : '');
|
||||
};
|
||||
|
||||
const charMapToSelector = function (charMap) {
|
||||
let key, selector = '';
|
||||
|
||||
for (key in charMap) {
|
||||
if (selector) {
|
||||
selector += ',';
|
||||
}
|
||||
selector += 'span.mce-' + charMap[key];
|
||||
}
|
||||
|
||||
return selector;
|
||||
};
|
||||
|
||||
export default {
|
||||
charMap,
|
||||
regExp: charMapToRegExp(charMap),
|
||||
regExpGlobal: charMapToRegExp(charMap, true),
|
||||
selector: charMapToSelector(charMap),
|
||||
charMapToRegExp,
|
||||
charMapToSelector
|
||||
};
|
||||
16
public/tinymce/src/plugins/visualchars/main/ts/core/Html.ts
Normal file
16
public/tinymce/src/plugins/visualchars/main/ts/core/Html.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
import Data from './Data';
|
||||
|
||||
const wrapCharWithSpan = function (value) {
|
||||
return '<span data-mce-bogus="1" class="mce-' + Data.charMap[value] + '">' + value + '</span>';
|
||||
};
|
||||
|
||||
export default {
|
||||
wrapCharWithSpan
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
import Delay from 'tinymce/core/api/util/Delay';
|
||||
import VisualChars from './VisualChars';
|
||||
|
||||
const setup = function (editor, toggleState) {
|
||||
const debouncedToggle = Delay.debounce(function () {
|
||||
VisualChars.toggle(editor);
|
||||
}, 300);
|
||||
|
||||
if (editor.settings.forced_root_block !== false) {
|
||||
editor.on('keydown', function (e) {
|
||||
if (toggleState.get() === true) {
|
||||
e.keyCode === 13 ? VisualChars.toggle(editor) : debouncedToggle();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
setup
|
||||
};
|
||||
52
public/tinymce/src/plugins/visualchars/main/ts/core/Nodes.ts
Normal file
52
public/tinymce/src/plugins/visualchars/main/ts/core/Nodes.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
import { Arr } from '@ephox/katamari';
|
||||
import { Element, Node } from '@ephox/sugar';
|
||||
import Data from './Data';
|
||||
import Html from './Html';
|
||||
|
||||
const isMatch = function (n) {
|
||||
return Node.isText(n) &&
|
||||
Node.value(n) !== undefined &&
|
||||
Data.regExp.test(Node.value(n));
|
||||
};
|
||||
|
||||
// inlined sugars PredicateFilter.descendants for file size
|
||||
const filterDescendants = function (scope, predicate) {
|
||||
let result = [];
|
||||
const dom = scope.dom();
|
||||
const children = Arr.map(dom.childNodes, Element.fromDom);
|
||||
|
||||
Arr.each(children, function (x) {
|
||||
if (predicate(x)) {
|
||||
result = result.concat([ x ]);
|
||||
}
|
||||
result = result.concat(filterDescendants(x, predicate));
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
const findParentElm = function (elm, rootElm) {
|
||||
while (elm.parentNode) {
|
||||
if (elm.parentNode === rootElm) {
|
||||
return elm;
|
||||
}
|
||||
elm = elm.parentNode;
|
||||
}
|
||||
};
|
||||
|
||||
const replaceWithSpans = function (html) {
|
||||
return html.replace(Data.regExpGlobal, Html.wrapCharWithSpan);
|
||||
};
|
||||
|
||||
export default {
|
||||
isMatch,
|
||||
filterDescendants,
|
||||
findParentElm,
|
||||
replaceWithSpans
|
||||
};
|
||||
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
import Data from './Data';
|
||||
import Nodes from './Nodes';
|
||||
import { Arr } from '@ephox/katamari';
|
||||
import { Element, Node } from '@ephox/sugar';
|
||||
|
||||
const show = function (editor, rootElm) {
|
||||
let node, div;
|
||||
const nodeList = Nodes.filterDescendants(Element.fromDom(rootElm), Nodes.isMatch);
|
||||
|
||||
Arr.each(nodeList, function (n) {
|
||||
const withSpans = Nodes.replaceWithSpans(Node.value(n));
|
||||
|
||||
div = editor.dom.create('div', null, withSpans);
|
||||
while ((node = div.lastChild)) {
|
||||
editor.dom.insertAfter(node, n.dom());
|
||||
}
|
||||
|
||||
editor.dom.remove(n.dom());
|
||||
});
|
||||
};
|
||||
|
||||
const hide = function (editor, body) {
|
||||
const nodeList = editor.dom.select(Data.selector, body);
|
||||
|
||||
Arr.each(nodeList, function (node) {
|
||||
editor.dom.remove(node, 1);
|
||||
});
|
||||
};
|
||||
|
||||
const toggle = function (editor) {
|
||||
const body = editor.getBody();
|
||||
const bookmark = editor.selection.getBookmark();
|
||||
let parentNode = Nodes.findParentElm(editor.selection.getNode(), body);
|
||||
|
||||
// if user does select all the parentNode will be undefined
|
||||
parentNode = parentNode !== undefined ? parentNode : body;
|
||||
|
||||
hide(editor, parentNode);
|
||||
show(editor, parentNode);
|
||||
|
||||
editor.selection.moveToBookmark(bookmark);
|
||||
};
|
||||
|
||||
export default {
|
||||
show,
|
||||
hide,
|
||||
toggle
|
||||
};
|
||||
38
public/tinymce/src/plugins/visualchars/main/ts/ui/Buttons.ts
Normal file
38
public/tinymce/src/plugins/visualchars/main/ts/ui/Buttons.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) Tiny Technologies, Inc. All rights reserved.
|
||||
* Licensed under the LGPL or a commercial license.
|
||||
* For LGPL see License.txt in the project root for license information.
|
||||
* For commercial licenses see https://www.tiny.cloud/
|
||||
*/
|
||||
|
||||
const toggleActiveState = function (editor) {
|
||||
return function (e) {
|
||||
const ctrl = e.control;
|
||||
|
||||
editor.on('VisualChars', function (e) {
|
||||
ctrl.active(e.state);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
const register = function (editor) {
|
||||
editor.addButton('visualchars', {
|
||||
active: false,
|
||||
title: 'Show invisible characters',
|
||||
cmd: 'mceVisualChars',
|
||||
onPostRender: toggleActiveState(editor)
|
||||
});
|
||||
|
||||
editor.addMenuItem('visualchars', {
|
||||
text: 'Show invisible characters',
|
||||
cmd: 'mceVisualChars',
|
||||
onPostRender: toggleActiveState(editor),
|
||||
selectable: true,
|
||||
context: 'view',
|
||||
prependToContext: true
|
||||
});
|
||||
};
|
||||
|
||||
export {
|
||||
register
|
||||
};
|
||||
Reference in New Issue
Block a user