mirror of
https://github.com/e107inc/e107.git
synced 2025-02-22 07:47:10 +01:00
303 lines
12 KiB
JavaScript
303 lines
12 KiB
JavaScript
tinymce.PluginManager.add('smileys', function (editor, url) {
|
||
/*var defaultSmileys = [
|
||
[
|
||
{ shortcut: '(^^^)', url: url + '/img/shark.gif', title: 'shark' },
|
||
{ shortcut: 'O:)', url: url + '/img/angel.png', title: 'angel' },
|
||
{ shortcut: 'o.O', url: url + '/img/confused.png', title: 'confused' },
|
||
{ shortcut: '3:)', url: url + '/img/devil.png', title: 'devil' },
|
||
{ shortcut: ':-O', url: url + '/img/gasp.png', title: 'gasp' },
|
||
{ shortcut: '8-)', url: url + '/img/glasses.png', title: 'glasses' },
|
||
{ shortcut: ':-D', url: url + '/img/grin.png', title: 'grin' }
|
||
],
|
||
[
|
||
{ shortcut: ':-)', url: url + '/img/smile.png', title: 'smile' },
|
||
{ shortcut: ":'(", url: url + '/img/cry.png', title: 'cry' },
|
||
{ shortcut: '<3', url: url + '/img/heart.png', title: 'heart' },
|
||
{ shortcut: '^_^', url: url + '/img/kiki.png', title: 'kiki' },
|
||
{ shortcut: ':-*', url: url + '/img/kiss.png', title: 'kiss' },
|
||
{ shortcut: ':v', url: url + '/img/pacman.png', title: 'pacman' },
|
||
{ shortcut: '<(<28>)', url: url + '/img/penguin.gif', title: 'penguin' }
|
||
],
|
||
[
|
||
{ shortcut: ':|]', url: url + '/img/robot.gif', title: 'robot' },
|
||
{ shortcut: '-_-', url: url + '/img/squint.png', title: 'squint' },
|
||
{ shortcut: '8-|', url: url + '/img/sunglasses.png', title: 'sunglasses' },
|
||
{ shortcut: ':-P', url: url + '/img/tongue.png', title: 'tongue' },
|
||
{ shortcut: ':/', url: url + '/img/unsure.png', title: 'unsure' },
|
||
{ shortcut: '>:O', url: url + '/img/upset.png', title: 'upset' },
|
||
{ shortcut: '>:(', url: url + '/img/grumpy.png', title: 'grumpy' }
|
||
]
|
||
];*/
|
||
|
||
var defaultSmileys = [];
|
||
|
||
var smileys = editor.settings.smileys || defaultSmileys, fullSmileysList = editor.settings.extended_smileys ? smileys.concat(editor.settings.extended_smileys) : smileys;
|
||
|
||
function getHtml() {
|
||
var smileysHtml;
|
||
|
||
smileysHtml = '<table role="presentation" class="mce-grid">';
|
||
|
||
tinymce.each(fullSmileysList, function (row) {
|
||
smileysHtml += '<tr>';
|
||
|
||
tinymce.each(row, function (icon) {
|
||
smileysHtml += '<td><a href="#" data-mce-url="' + icon.url + '" tabindex="-1" title="' + icon.title + '"><img src="' +
|
||
icon.url + '" style="width: 16px; height: 16px"></a></td>';
|
||
});
|
||
|
||
smileysHtml += '</tr>';
|
||
});
|
||
|
||
smileysHtml += '</table>';
|
||
|
||
return smileysHtml;
|
||
}
|
||
|
||
function concatArray(array) {
|
||
var each = tinymce.each, result = [];
|
||
each(array, function (item) {
|
||
result = result.concat(item);
|
||
});
|
||
return result.length > 0 ? result : array;
|
||
}
|
||
|
||
function findAndReplaceDOMText(regex, node, replacementNode, captureGroup, schema) {
|
||
var m, matches = [], text, count = 0, doc;
|
||
var blockElementsMap, hiddenTextElementsMap, shortEndedElementsMap;
|
||
|
||
doc = node.ownerDocument;
|
||
blockElementsMap = schema.getBlockElements(); // H1-H6, P, TD etc
|
||
hiddenTextElementsMap = schema.getWhiteSpaceElements(); // TEXTAREA, PRE, STYLE, SCRIPT
|
||
shortEndedElementsMap = schema.getShortEndedElements(); // BR, IMG, INPUT
|
||
|
||
function getMatchIndexes(m, captureGroup) {
|
||
captureGroup = captureGroup || 0;
|
||
|
||
var index = m.index;
|
||
|
||
if (captureGroup > 0) {
|
||
var cg = m[captureGroup];
|
||
index += m[0].indexOf(cg);
|
||
m[0] = cg;
|
||
}
|
||
|
||
return [index, index + m[0].length, [m[0]]];
|
||
}
|
||
|
||
function getText(node) {
|
||
var txt;
|
||
|
||
if (node.nodeType === 3) {
|
||
return node.data;
|
||
}
|
||
|
||
if (hiddenTextElementsMap[node.nodeName] && !blockElementsMap[node.nodeName]) {
|
||
return '';
|
||
}
|
||
|
||
txt = '';
|
||
|
||
if (blockElementsMap[node.nodeName] || shortEndedElementsMap[node.nodeName]) {
|
||
txt += '\n';
|
||
}
|
||
|
||
if ((node = node.firstChild)) {
|
||
do {
|
||
txt += getText(node);
|
||
} while ((node = node.nextSibling));
|
||
}
|
||
|
||
return txt;
|
||
}
|
||
|
||
function stepThroughMatches(node, matches, replaceFn) {
|
||
var startNode, endNode, startNodeIndex,
|
||
endNodeIndex, innerNodes = [], atIndex = 0, curNode = node,
|
||
matchLocation = matches.shift(), matchIndex = 0;
|
||
|
||
out: while (true) {
|
||
if (blockElementsMap[curNode.nodeName] || shortEndedElementsMap[curNode.nodeName]) {
|
||
atIndex++;
|
||
}
|
||
|
||
if (curNode.nodeType === 3) {
|
||
if (!endNode && curNode.length + atIndex >= matchLocation[1]) {
|
||
// We've found the ending
|
||
endNode = curNode;
|
||
endNodeIndex = matchLocation[1] - atIndex;
|
||
} else if (startNode) {
|
||
// Intersecting node
|
||
innerNodes.push(curNode);
|
||
}
|
||
|
||
if (!startNode && curNode.length + atIndex > matchLocation[0]) {
|
||
// We've found the match start
|
||
startNode = curNode;
|
||
startNodeIndex = matchLocation[0] - atIndex;
|
||
}
|
||
|
||
atIndex += curNode.length;
|
||
}
|
||
|
||
if (startNode && endNode) {
|
||
curNode = replaceFn({
|
||
startNode: startNode,
|
||
startNodeIndex: startNodeIndex,
|
||
endNode: endNode,
|
||
endNodeIndex: endNodeIndex,
|
||
innerNodes: innerNodes,
|
||
match: matchLocation[2],
|
||
matchIndex: matchIndex
|
||
});
|
||
|
||
// replaceFn has to return the node that replaced the endNode
|
||
// and then we step back so we can continue from the end of the
|
||
// match:
|
||
atIndex -= (endNode.length - endNodeIndex);
|
||
startNode = null;
|
||
endNode = null;
|
||
innerNodes = [];
|
||
matchLocation = matches.shift();
|
||
matchIndex++;
|
||
|
||
if (!matchLocation) {
|
||
break; // no more matches
|
||
}
|
||
} else if ((!hiddenTextElementsMap[curNode.nodeName] || blockElementsMap[curNode.nodeName]) && curNode.firstChild) {
|
||
// Move down
|
||
curNode = curNode.firstChild;
|
||
continue;
|
||
} else if (curNode.nextSibling) {
|
||
// Move forward:
|
||
curNode = curNode.nextSibling;
|
||
continue;
|
||
}
|
||
|
||
// Move forward or up:
|
||
while (true) {
|
||
if (curNode.nextSibling) {
|
||
curNode = curNode.nextSibling;
|
||
break;
|
||
} else if (curNode.parentNode !== node) {
|
||
curNode = curNode.parentNode;
|
||
} else {
|
||
break out;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Generates the actual replaceFn which splits up text nodes
|
||
* and inserts the replacement element.
|
||
*/
|
||
function genReplacer(nodeName) {
|
||
var makeReplacementNode;
|
||
|
||
if (typeof nodeName != 'function') {
|
||
var stencilNode = nodeName.nodeType ? nodeName : doc.createElement(nodeName);
|
||
|
||
makeReplacementNode = function () {
|
||
var clone = stencilNode.cloneNode(false);
|
||
return clone;
|
||
};
|
||
} else {
|
||
makeReplacementNode = nodeName;
|
||
}
|
||
|
||
return function replace(range) {
|
||
var before, after, parentNode, startNode = range.startNode,
|
||
endNode = range.endNode;
|
||
|
||
if (startNode === endNode) {
|
||
var node = startNode;
|
||
|
||
parentNode = node.parentNode;
|
||
if (range.startNodeIndex > 0) {
|
||
// Add `before` text node (before the match)
|
||
before = doc.createTextNode(node.data.substring(0, range.startNodeIndex));
|
||
parentNode.insertBefore(before, node);
|
||
}
|
||
|
||
// Create the replacement node:
|
||
var el = makeReplacementNode();
|
||
parentNode.insertBefore(el, node);
|
||
if (range.endNodeIndex < node.length) {
|
||
// Add `after` text node (after the match)
|
||
after = doc.createTextNode(node.data.substring(range.endNodeIndex));
|
||
parentNode.insertBefore(after, node);
|
||
}
|
||
|
||
node.parentNode.removeChild(node);
|
||
|
||
return el;
|
||
}
|
||
};
|
||
}
|
||
|
||
text = getText(node);
|
||
if (!text) {
|
||
return;
|
||
}
|
||
while ((m = regex.exec(text))) {
|
||
matches.push(getMatchIndexes(m, captureGroup));
|
||
}
|
||
|
||
if (matches.length) {
|
||
count = matches.length;
|
||
stepThroughMatches(node, matches, genReplacer(replacementNode));
|
||
}
|
||
|
||
return count;
|
||
}
|
||
|
||
function replaceAllMatches(smiley) {
|
||
var each = tinymce.each, node = editor.selection.getNode(), marker, text;
|
||
if (typeof (smiley.shortcut) === 'string') {
|
||
text = smiley.shortcut.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
|
||
|
||
marker = editor.dom.create('img', { "src": smiley.url, "title": smiley.title });
|
||
|
||
return findAndReplaceDOMText(new RegExp(text, 'gi'), node, marker, false, editor.schema);
|
||
}
|
||
else if (Array.isArray(smiley.shortcut)) {
|
||
each(smiley.shortcut, function(item) {
|
||
|
||
marker = editor.dom.create('img', { "src": smiley.url, "title": smiley.title });
|
||
|
||
return findAndReplaceDOMText(new RegExp(item.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), 'gi'), node, marker, false, editor.schema);
|
||
});
|
||
}
|
||
}
|
||
|
||
editor.on("keyup", function (e) {
|
||
if (!!editor.settings.auto_convert_smileys) {
|
||
var each = tinymce.each, selection = editor.selection, node = selection.getNode();
|
||
if (node) {
|
||
each(concatArray(fullSmileysList), function (smiley) {
|
||
replaceAllMatches(smiley);
|
||
});
|
||
}
|
||
}
|
||
});
|
||
|
||
editor.addButton('smileys', {
|
||
type: 'panelbutton',
|
||
icon: 'emoticons',
|
||
panel: {
|
||
autohide: true,
|
||
html: getHtml,
|
||
onclick: function (e) {
|
||
var linkElm = editor.dom.getParent(e.target, 'a');
|
||
|
||
if (linkElm) {
|
||
editor.insertContent('<img src="' + linkElm.getAttribute('data-mce-url') + '" title="' + linkElm.getAttribute('title') + '" />');
|
||
this.hide();
|
||
}
|
||
}
|
||
},
|
||
tooltip: 'Smileys'
|
||
});
|
||
});
|