123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407 |
- /**
- * @license Copyright (c) CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.html or http://ckeditor.com/license
- */
- CKEDITOR.plugins.add("wordcount", {
- lang: "ar,ca,da,de,el,en,es,fi,fr,he,hr,it,jp,nl,no,pl,pt,pt-br,ru,sv,tr,zh-cn", // %REMOVE_LINE_CORE%
- version: 1.15,
- requires: 'htmlwriter,notification,undo',
- init: function (editor) {
- var defaultFormat = "",
- intervalId,
- lastWordCount = -1,
- lastCharCount = -1,
- limitReachedNotified = false,
- limitRestoredNotified = false,
- snapShot = editor.getSnapshot();
- var dispatchEvent = function (type, currentLength, maxLength) {
- if (typeof document.dispatchEvent == 'undefined') {
- return;
- }
- type = 'ckeditor.wordcount.' + type;
- var cEvent;
- var eventInitDict = {
- bubbles: false,
- cancelable: true,
- detail: {
- currentLength: currentLength,
- maxLength: maxLength
- }
- };
- try {
- cEvent = new CustomEvent(type, eventInitDict);
- } catch (o_O) {
- cEvent = document.createEvent('CustomEvent');
- cEvent.initCustomEvent(
- type,
- eventInitDict.bubbles,
- eventInitDict.cancelable,
- eventInitDict.detail
- );
- }
- document.dispatchEvent(cEvent);
- };
- // Default Config
- var defaultConfig = {
- showParagraphs: true,
- showWordCount: true,
- showCharCount: false,
- countSpacesAsChars: false,
- countHTML: false,
- hardLimit: true,
- //MAXLENGTH Properties
- maxWordCount: -1,
- maxCharCount: -1,
- // Filter
- filter: null,
- //DisAllowed functions
- wordCountGreaterThanMaxLengthEvent: function (currentLength, maxLength) {
- dispatchEvent('wordCountGreaterThanMaxLengthEvent', currentLength, maxLength);
- },
- charCountGreaterThanMaxLengthEvent: function (currentLength, maxLength) {
- dispatchEvent('charCountGreaterThanMaxLengthEvent', currentLength, maxLength);
- },
- //Allowed Functions
- wordCountLessThanMaxLengthEvent: function (currentLength, maxLength) {
- dispatchEvent('wordCountLessThanMaxLengthEvent', currentLength, maxLength);
- },
- charCountLessThanMaxLengthEvent: function (currentLength, maxLength) {
- dispatchEvent('charCountLessThanMaxLengthEvent', currentLength, maxLength);
- }
- };
- // Get Config & Lang
- var config = CKEDITOR.tools.extend(defaultConfig, editor.config.wordcount || {}, true);
- if (config.showParagraphs) {
- defaultFormat += editor.lang.wordcount.Paragraphs + " %paragraphs%";
- }
- if (config.showParagraphs && (config.showWordCount || config.showCharCount)) {
- defaultFormat += ", ";
- }
- if (config.showWordCount) {
- defaultFormat += editor.lang.wordcount.WordCount + " %wordCount%";
- if (config.maxWordCount > -1) {
- defaultFormat += "/" + config.maxWordCount;
- }
- }
- if (config.showCharCount && config.showWordCount) {
- defaultFormat += ", ";
- }
- if (config.showCharCount) {
- var charLabel = editor.lang.wordcount[config.countHTML ? "CharCountWithHTML" : "CharCount"];
- defaultFormat += charLabel + " %charCount%";
- if (config.maxCharCount > -1) {
- defaultFormat += "/" + config.maxCharCount;
- }
- }
- var format = defaultFormat;
- if (config.loadCss === undefined || config.loadCss) {
- CKEDITOR.document.appendStyleSheet(this.path + "css/wordcount.css");
- }
- function counterId(editorInstance) {
- return "cke_wordcount_" + editorInstance.name;
- }
- function counterElement(editorInstance) {
- return document.getElementById(counterId(editorInstance));
- }
- function strip(html) {
- var tmp = document.createElement("div");
- // Add filter before strip
- html = filter(html);
- tmp.innerHTML = html;
- if (tmp.textContent == "" && typeof tmp.innerText == "undefined") {
- return "";
- }
- return tmp.textContent || tmp.innerText;
- }
- /**
- * Implement filter to add or remove before counting
- * @param html
- * @returns string
- */
- function filter(html) {
- if(config.filter instanceof CKEDITOR.htmlParser.filter) {
- var fragment = CKEDITOR.htmlParser.fragment.fromHtml(html),
- writer = new CKEDITOR.htmlParser.basicWriter();
- config.filter.applyTo( fragment );
- fragment.writeHtml( writer );
- return writer.getHtml();
- }
- return html;
- }
- function countCharacters(text, editorInstance) {
- if (config.countHTML) {
- return (filter(text).length);
- } else {
- var normalizedText;
- // strip body tags
- if (editor.config.fullPage) {
- var i = text.search(new RegExp("<body>", "i"));
- if (i != -1) {
- var j = text.search(new RegExp("</body>", "i"));
- text = text.substring(i + 6, j);
- }
- }
- normalizedText = text;
- if (!config.countSpacesAsChars) {
- normalizedText = text.
- replace(/\s/g, "").
- replace(/ /g, "");
- }
- normalizedText = normalizedText.
- replace(/(\r\n|\n|\r)/gm, "").
- replace(/ /gi, " ");
- normalizedText = strip(normalizedText).replace(/^([\t\r\n]*)$/, "");
- return(normalizedText.length);
- }
- }
- function countParagraphs(text) {
- return (text.replace(/ /g, " ").replace(/(<([^>]+)>)/ig, "").replace(/^\s*$[\n\r]{1,}/gm, "++").split("++").length);
- }
- function countWords(text) {
- var normalizedText = text.
- replace(/(\r\n|\n|\r)/gm, " ").
- replace(/^\s+|\s+$/g, "").
- replace(" ", " ");
- normalizedText = strip(normalizedText);
- var words = normalizedText.split(/\s+/);
- for (var wordIndex = words.length - 1; wordIndex >= 0; wordIndex--) {
- if (words[wordIndex].match(/^([\s\t\r\n]*)$/)) {
- words.splice(wordIndex, 1);
- }
- }
- return (words.length);
- }
- function limitReached(editorInstance, notify) {
- limitReachedNotified = true;
- limitRestoredNotified = false;
- if (config.hardLimit) {
- editorInstance.loadSnapshot(snapShot);
- // lock editor
- editorInstance.config.Locked = 1;
- }
- if (!notify) {
- counterElement(editorInstance).className = "cke_path_item cke_wordcountLimitReached";
- editorInstance.fire("limitReached", {}, editor);
- }
- }
- function limitRestored(editorInstance) {
- limitRestoredNotified = true;
- limitReachedNotified = false;
- editorInstance.config.Locked = 0;
- snapShot = editor.getSnapshot();
- counterElement(editorInstance).className = "cke_path_item";
- }
- function updateCounter(editorInstance) {
- var paragraphs = 0,
- wordCount = 0,
- charCount = 0,
- text;
- if (text = editorInstance.getData()) {
- if (config.showCharCount) {
- charCount = countCharacters(text, editorInstance);
- }
- if (config.showParagraphs) {
- paragraphs = countParagraphs(text);
- }
- if (config.showWordCount) {
- wordCount = countWords(text);
- }
- }
- var html = format.replace("%wordCount%", wordCount).replace("%charCount%", charCount).replace("%paragraphs%", paragraphs);
- (editorInstance.config.wordcount || (editorInstance.config.wordcount = {})).wordCount = wordCount;
- (editorInstance.config.wordcount || (editorInstance.config.wordcount = {})).charCount = charCount;
- if (CKEDITOR.env.gecko) {
- counterElement(editorInstance).innerHTML = html;
- } else {
- counterElement(editorInstance).innerText = html;
- }
- if (charCount == lastCharCount && wordCount == lastWordCount) {
- return true;
- }
- //If the limit is already over, allow the deletion of characters/words. Otherwise,
- //the user would have to delete at one go the number of offending characters
- var deltaWord = wordCount - lastWordCount;
- var deltaChar = charCount - lastCharCount;
- lastWordCount = wordCount;
- lastCharCount = charCount;
- if (lastWordCount == -1) {
- lastWordCount = wordCount;
- }
- if (lastCharCount == -1) {
- lastCharCount = charCount;
- }
- // Check for word limit and/or char limit
- if ((config.maxWordCount > -1 && wordCount > config.maxWordCount && deltaWord > 0) ||
- (config.maxCharCount > -1 && charCount > config.maxCharCount && deltaChar > 0)) {
- limitReached(editorInstance, limitReachedNotified);
- } else if ((config.maxWordCount == -1 || wordCount < config.maxWordCount) &&
- (config.maxCharCount == -1 || charCount < config.maxCharCount)) {
- limitRestored(editorInstance);
- } else {
- snapShot = editorInstance.getSnapshot();
- }
- // Fire Custom Events
- if (config.charCountGreaterThanMaxLengthEvent && config.charCountLessThanMaxLengthEvent) {
- if (charCount > config.maxCharCount && config.maxCharCount > -1) {
- config.charCountGreaterThanMaxLengthEvent(charCount, config.maxCharCount);
- } else {
- config.charCountLessThanMaxLengthEvent(charCount, config.maxCharCount);
- }
- }
- if (config.wordCountGreaterThanMaxLengthEvent && config.wordCountLessThanMaxLengthEvent) {
- if (wordCount > config.maxWordCount && config.maxWordCount > -1) {
- config.wordCountGreaterThanMaxLengthEvent(wordCount, config.maxWordCount);
- } else {
- config.wordCountLessThanMaxLengthEvent(wordCount, config.maxWordCount);
- }
- }
- return true;
- }
- editor.on("key", function (event) {
- if (editor.mode === "source") {
- updateCounter(event.editor);
- }
- }, editor, null, 100);
- editor.on("change", function (event) {
- updateCounter(event.editor);
- }, editor, null, 100);
- editor.on("uiSpace", function (event) {
- if (editor.elementMode === CKEDITOR.ELEMENT_MODE_INLINE) {
- if (event.data.space == "top") {
- event.data.html += "<div class=\"cke_wordcount\" style=\"\"" +
- " title=\"" +
- editor.lang.wordcount.title +
- "\"" +
- "><span id=\"" +
- counterId(event.editor) +
- "\" class=\"cke_path_item\"> </span></div>";
- }
- } else {
- if (event.data.space == "bottom") {
- event.data.html += "<div class=\"cke_wordcount\" style=\"\"" +
- " title=\"" +
- editor.lang.wordcount.title +
- "\"" +
- "><span id=\"" +
- counterId(event.editor) +
- "\" class=\"cke_path_item\"> </span></div>";
- }
- }
- }, editor, null, 100);
- editor.on("dataReady", function (event) {
- updateCounter(event.editor);
- }, editor, null, 100);
- editor.on("paste", function(event) {
- if (config.maxWordCount > 0 || config.maxCharCount > 0) {
- // Check if pasted content is above the limits
- var wordCount = -1,
- charCount = -1,
- text = event.editor.getData() + event.data.dataValue;
- if (config.showCharCount) {
- charCount = countCharacters(text, event.editor);
- }
- if (config.showWordCount) {
- wordCount = countWords(text);
- }
- var notification = new CKEDITOR.plugins.notification(event.editor, { message: event.editor.lang.wordcount.pasteWarning, type: 'warning' });
- if (config.maxCharCount > 0 && charCount > config.maxCharCount && config.hardLimit) {
- notification.show();
- event.cancel();
- }
- if (config.maxWordCount > 0 && wordCount > config.maxWordCount && config.hardLimit) {
- notification.show();
- event.cancel();
- }
- }
- }, editor, null, 100);
- editor.on("afterPaste", function (event) {
- updateCounter(event.editor);
- }, editor, null, 100);
- editor.on("blur", function () {
- if (intervalId) {
- window.clearInterval(intervalId);
- }
- }, editor, null, 300);
- }
- });
|