diff --git a/.gitignore b/.gitignore index f6345d5..68b9e27 100644 --- a/.gitignore +++ b/.gitignore @@ -1,188 +1,2 @@ -advhr/css/advhr.css -advhr/editor_plugin.js -advhr/editor_plugin_src.js -advhr/js/rule.js -advhr/langs/en_dlg.js -advhr/rule.htm -advimage/css/advimage.css -advimage/editor_plugin.js -advimage/editor_plugin_src.js -advimage/image.htm -advimage/img/sample.gif -advimage/js/image.js -advimage/langs/en_dlg.js -advlink/css/advlink.css -advlink/editor_plugin.js -advlink/editor_plugin_src.js -advlink/js/advlink.js -advlink/langs/en_dlg.js -advlink/link.htm -advlist/editor_plugin.js -advlist/editor_plugin_src.js -autolink/editor_plugin.js -autolink/editor_plugin_src.js -autoresize/editor_plugin.js -autoresize/editor_plugin_src.js -autosave/editor_plugin.js -autosave/editor_plugin_src.js -bbcode/editor_plugin.js -bbcode/editor_plugin_src.js -contextmenu/editor_plugin.js -contextmenu/editor_plugin_src.js -directionality/editor_plugin.js -directionality/editor_plugin_src.js -emotions/editor_plugin.js -emotions/editor_plugin_src.js -emotions/emotions.htm -emotions/img/smiley-cool.gif -emotions/img/smiley-cry.gif -emotions/img/smiley-embarassed.gif -emotions/img/smiley-foot-in-mouth.gif -emotions/img/smiley-frown.gif -emotions/img/smiley-innocent.gif -emotions/img/smiley-kiss.gif -emotions/img/smiley-laughing.gif -emotions/img/smiley-money-mouth.gif -emotions/img/smiley-sealed.gif -emotions/img/smiley-smile.gif -emotions/img/smiley-surprised.gif -emotions/img/smiley-tongue-out.gif -emotions/img/smiley-undecided.gif -emotions/img/smiley-wink.gif -emotions/img/smiley-yell.gif -emotions/js/emotions.js -emotions/langs/en_dlg.js -example/dialog.htm -example/editor_plugin.js -example/editor_plugin_src.js -example/img/example.gif -example/js/dialog.js -example/langs/en.js -example/langs/en_dlg.js -example_dependency/editor_plugin.js -example_dependency/editor_plugin_src.js -fullpage/css/fullpage.css -fullpage/editor_plugin.js -fullpage/editor_plugin_src.js -fullpage/fullpage.htm -fullpage/js/fullpage.js -fullpage/langs/en_dlg.js -fullscreen/editor_plugin.js -fullscreen/editor_plugin_src.js -fullscreen/fullscreen.htm -iespell/editor_plugin.js -iespell/editor_plugin_src.js -inlinepopups/editor_plugin.js -inlinepopups/editor_plugin_src.js -inlinepopups/skins/clearlooks2/img/alert.gif -inlinepopups/skins/clearlooks2/img/button.gif -inlinepopups/skins/clearlooks2/img/buttons.gif -inlinepopups/skins/clearlooks2/img/confirm.gif -inlinepopups/skins/clearlooks2/img/corners.gif -inlinepopups/skins/clearlooks2/img/horizontal.gif -inlinepopups/skins/clearlooks2/img/vertical.gif -inlinepopups/skins/clearlooks2/window.css -inlinepopups/template.htm -insertdatetime/editor_plugin.js -insertdatetime/editor_plugin_src.js -layer/editor_plugin.js -layer/editor_plugin_src.js -legacyoutput/editor_plugin.js -legacyoutput/editor_plugin_src.js -lists/editor_plugin.js -lists/editor_plugin_src.js -media/css/media.css -media/editor_plugin.js -media/editor_plugin_src.js -media/js/embed.js -media/js/media.js -media/langs/en_dlg.js -media/media.htm -media/moxieplayer.swf -nonbreaking/editor_plugin.js -nonbreaking/editor_plugin_src.js -noneditable/editor_plugin.js -noneditable/editor_plugin_src.js -pagebreak/editor_plugin.js -pagebreak/editor_plugin_src.js -paste/editor_plugin.js -paste/editor_plugin_src.js -paste/js/pastetext.js -paste/js/pasteword.js -paste/langs/en_dlg.js -paste/pastetext.htm -paste/pasteword.htm -preview/editor_plugin.js -preview/editor_plugin_src.js -preview/example.html -preview/jscripts/embed.js -preview/preview.html -print/editor_plugin.js -print/editor_plugin_src.js -save/editor_plugin.js -save/editor_plugin_src.js -searchreplace/css/searchreplace.css -searchreplace/editor_plugin.js -searchreplace/editor_plugin_src.js -searchreplace/js/searchreplace.js -searchreplace/langs/en_dlg.js -searchreplace/searchreplace.htm -spellchecker/css/content.css -spellchecker/editor_plugin.js -spellchecker/editor_plugin_src.js -spellchecker/img/wline.gif -style/css/props.css -style/editor_plugin.js -style/editor_plugin_src.js -style/js/props.js -style/langs/en_dlg.js -style/props.htm -style/readme.txt -tabfocus/editor_plugin.js -tabfocus/editor_plugin_src.js -table/cell.htm -table/css/cell.css -table/css/row.css -table/css/table.css -table/editor_plugin.js -table/editor_plugin_src.js -table/js/cell.js -table/js/merge_cells.js -table/js/row.js -table/js/table.js -table/langs/en_dlg.js -table/merge_cells.htm -table/row.htm -table/table.htm -template/blank.htm -template/css/template.css -template/editor_plugin.js -template/editor_plugin_src.js -template/js/template.js -template/langs/en_dlg.js -template/template.htm -visualblocks/css/visualblocks.css -visualblocks/editor_plugin.js -visualblocks/editor_plugin_src.js -visualchars/editor_plugin.js -visualchars/editor_plugin_src.js -wordcount/editor_plugin.js -wordcount/editor_plugin_src.js -xhtmlxtras/abbr.htm -xhtmlxtras/acronym.htm -xhtmlxtras/attributes.htm -xhtmlxtras/cite.htm -xhtmlxtras/css/attributes.css -xhtmlxtras/css/popup.css -xhtmlxtras/del.htm -xhtmlxtras/editor_plugin.js -xhtmlxtras/editor_plugin_src.js -xhtmlxtras/ins.htm -xhtmlxtras/js/abbr.js -xhtmlxtras/js/acronym.js -xhtmlxtras/js/attributes.js -xhtmlxtras/js/cite.js -xhtmlxtras/js/del.js -xhtmlxtras/js/element_common.js -xhtmlxtras/js/ins.js -xhtmlxtras/langs/en_dlg.js +node_modules/ +bower_components/ diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 0000000..47a7310 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,120 @@ +{ + // -------------------------------------------------------------------- + // JSHint Configuration, Strict Edition + // -------------------------------------------------------------------- + // + // This is a options template for [JSHint][1], using [JSHint example][2] + // and [Ory Band's example][3] as basis and setting config values to + // be most strict: + // + // * set all enforcing options to true + // * set all relaxing options to false + // * set all environment options to false, except the browser value + // * set all JSLint legacy options to false + // + // [1]: http://www.jshint.com/ + // [2]: https://github.com/jshint/node-jshint/blob/master/example/config.json + // [3]: https://github.com/oryband/dotfiles/blob/master/jshintrc + // + // @author http://michael.haschke.biz/ + // @license http://unlicense.org/ + + // == Enforcing Options =============================================== + // + // These options tell JSHint to be more strict towards your code. Use + // them if you want to allow only a safe subset of JavaScript, very + // useful when your codebase is shared with a big number of developers + // with different skill levels. + + "bitwise" : false, // Prohibit bitwise operators (&, |, ^, etc.). + "curly" : true, // Require {} for every new block or scope. + "eqeqeq" : true, // Require triple equals i.e. `===`. + "forin" : true, // Tolerate `for in` loops without `hasOwnPrototype`. + "immed" : true, // Require immediate invocations to be wrapped in parens e.g. `( function(){}() );` + "latedef" : true, // Prohibit variable use before definition. + "newcap" : true, // Require capitalization of all constructor functions e.g. `new F()`. + "noarg" : true, // Prohibit use of `arguments.caller` and `arguments.callee`. + "noempty" : true, // Prohibit use of empty blocks. + "nonew" : true, // Prohibit use of constructors for side-effects. + "plusplus" : false, // Prohibit use of `++` & `--`. + "regexp" : true, // Prohibit `.` and `[^...]` in regular expressions. + "undef" : true, // Require all non-global variables be declared before they are used. + "strict" : true, // Require `use strict` pragma in every file. + "trailing" : true, // Prohibit trailing whitespaces. + "quotmark" : true, + + // == Relaxing Options ================================================ + // + // These options allow you to suppress certain types of warnings. Use + // them only if you are absolutely positive that you know what you are + // doing. + + "asi" : false, // Tolerate Automatic Semicolon Insertion (no semicolons). + "boss" : false, // Tolerate assignments inside if, for & while. Usually conditions & loops are for comparison, not assignments. + "debug" : false, // Allow debugger statements e.g. browser breakpoints. + "eqnull" : false, // Tolerate use of `== null`. + "es5" : false, // Allow EcmaScript 5 syntax. + "esnext" : false, // Allow ES.next specific features such as `const` and `let`. + "evil" : false, // Tolerate use of `eval`. + "expr" : false, // Tolerate `ExpressionStatement` as Programs. + "funcscope" : false, // Tolerate declarations of variables inside of control structures while accessing them later from the outside. + "globalstrict" : false, // Allow global "use strict" (also enables 'strict'). + "iterator" : false, // Allow usage of __iterator__ property. + "lastsemic" : false, // Tolerat missing semicolons when the it is omitted for the last statement in a one-line block. + "laxbreak" : false, // Tolerate unsafe line breaks e.g. `return [\n] x` without semicolons. + "laxcomma" : false, // Suppress warnings about comma-first coding style. + "loopfunc" : false, // Allow functions to be defined within loops. + "multistr" : false, // Tolerate multi-line strings. + "onecase" : false, // Tolerate switches with just one case. + "proto" : false, // Tolerate __proto__ property. This property is deprecated. + "regexdash" : false, // Tolerate unescaped last dash i.e. `[-...]`. + "scripturl" : false, // Tolerate script-targeted URLs. + "smarttabs" : false, // Tolerate mixed tabs and spaces when the latter are used for alignmnent only. + "shadow" : false, // Allows re-define variables later in code e.g. `var x=1; x=2;`. + "sub" : false, // Tolerate all forms of subscript notation besides dot notation e.g. `dict['key']` instead of `dict.key`. + "supernew" : false, // Tolerate `new function () { ... };` and `new Object;`. + "validthis" : false, // Tolerate strict violations when the code is running in strict mode and you use this in a non-constructor function. + + // == Environments ==================================================== + // + // These options pre-define global variables that are exposed by + // popular JavaScript libraries and runtime environments—such as + // browser or node.js. + + "browser" : true, // Standard browser globals e.g. `window`, `document`. + "couch" : false, // Enable globals exposed by CouchDB. + "devel" : false, // Allow development statements e.g. `console.log();`. + "dojo" : false, // Enable globals exposed by Dojo Toolkit. + "jquery" : false, // Enable globals exposed by jQuery JavaScript library. + "mootools" : false, // Enable globals exposed by MooTools JavaScript framework. + "node" : false, // Enable globals available when code is running inside of the NodeJS runtime environment. + "nonstandard" : false, // Define non-standard but widely adopted globals such as escape and unescape. + "prototypejs" : false, // Enable globals exposed by Prototype JavaScript framework. + "rhino" : false, // Enable globals available when your code is running inside of the Rhino runtime environment. + "wsh" : false, // Enable globals available when your code is running as a script for the Windows Script Host. + + // == JSLint Legacy =================================================== + // + // These options are legacy from JSLint. Aside from bug fixes they will + // not be improved in any way and might be removed at any point. + + "nomen" : false, // Prohibit use of initial or trailing underbars in names. + "onevar" : false, // Allow only one `var` statement per function. + "passfail" : false, // Stop on first error. + "white" : false, // Check against strict whitespace and indentation rules. + + // == Undocumented Options ============================================ + // + // While I've found these options in [example1][2] and [example2][3] + // they are not described in the [JSHint Options documentation][4]. + // + // [4]: http://www.jshint.com/options/ + + "maxerr" : 100, // Maximum errors before stopping. + "predef" : [ // Extra globals. + //"exampleVar", + //"anotherCoolGlobal", + //"iLoveDouglas" + ], + "indent" : 4 // Specify indentation spacing +} \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..5cce176 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - "5.7" +branches: + only: + - master \ No newline at end of file diff --git a/README.md b/README.md index 6e43e3b..6261d64 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ -#tinyMCE mention +# tinyMCE mention + +[![Travis](https://travis-ci.org/StevenDevooght/tinyMCE-mention.svg?branch=master)](https://travis-ci.org/StevenDevooght/tinyMCE-mention) Mentions plugin for tinyMCE WYSIWYG editor. -![preview](http://www.cognistreamer.com/shared/github/tinyMCE-mentions.png) +![preview](https://static.cognistreamer.com/mention-plugin/mention-4.0.0.png) -##Browser compatibility +## Browser compatibility * IE7+ * Chrome @@ -12,14 +14,22 @@ Mentions plugin for tinyMCE WYSIWYG editor. * Firefox * Opera -##Dependencies +## Dependencies -* [tinyMCE](http://www.tinymce.com/) (v3.5.x) +* [tinyMCE](http://www.tinymce.com/) * [jQuery](http://jquery.com/) -##Usage +> NOTE: Use v3.x if you're using tinyMCE v3.5.x, use v4.x if you're using tinyMCE v4.x + +## Usage + +Install using bower. -Copy the source of the plugin to the plugins directory of your tinyMCE installation. +``` +bower install tinymce-mention +``` + +Or copy the source of the plugin to the plugins directory of your tinyMCE installation. Add the mention plugin to your tinyMCE configuration. ```javascript @@ -40,13 +50,13 @@ mentions: { }, ``` -##Configuration +## Configuration -###source (required) +### source (required) The source parameter can be configured as an array or a function. -####array +#### array ```javascript source: [ @@ -57,43 +67,58 @@ source: [ ] ``` -####function +#### function ```javascript -source: function(query, process) { - //Do your ajax call - $.getJSON('ajax/test.json', function(data) { - //call process to show the result - process(data) +source: function (query, process, delimiter) { + // Do your ajax call + // When using multiple delimiters you can alter the query depending on the delimiter used + if (delimiter === '@') { + $.getJSON('ajax/users.json', function (data) { + //call process to show the result + process(data) + }); } } ``` -###queryBy +### queryBy The name of the property used to do the lookup in the `source`. **Default**: `'name'`. -###delimiter +### delimiter + +Character that will trigger the mention plugin. Can be configured as a character or an array of characters. -Character that will trigger the mention plugin. +#### character + +```javascript +delimiter: '@' +``` + +#### array + +```javascript +delimiter: ['@', '#'] +``` **Default**: `'@'`. -###delay +### delay Delay of the lookup in milliseconds when typing a new character. **Default**: `500`. -###items +### items Maximum number of items displayed in the dropdown. **Default**: `10` -###matcher +### matcher Checks for a match in the source collection. @@ -106,7 +131,7 @@ matcher: function(item) { } ``` -###highlighter +### highlighter Highlights the part of the query in the matched result. @@ -119,7 +144,14 @@ highlighter: function(text) { } ``` -###insert +### insertFrom +Key used in the default `insert` implementation. + +**Default**: `queryBy` value + +> NOTE: key can be any property defined in`source` option. + +### insert Callback to set the content you want to insert in tinyMCE. @@ -131,7 +163,7 @@ insert: function(item) { > NOTE: item parameter has all properties defined in the `source` option. -###render +### render Callback to set the HTML of an item in the autocomplete dropdown. @@ -145,7 +177,7 @@ render: function(item) { > NOTE: item parameter has all properties defined in the `source` option. -###renderDropdown +### renderDropdown Callback to set the wrapper HTML for the autocomplete dropdown. @@ -156,7 +188,7 @@ renderDropdown: function() { } ``` -##License +## License MIT licensed diff --git a/bower.json b/bower.json new file mode 100644 index 0000000..05cb386 --- /dev/null +++ b/bower.json @@ -0,0 +1,32 @@ +{ + "name": "tinymce-mention", + "version": "4.0.0", + "description": "Mention/Autocomplete plugin for tinyMCE WYSIWYG editor.", + "main": "mention/plugin.min.js", + "keywords": [ + "tinyMCE", + "autocomplete", + "mention" + ], + "authors": [ + "Steven Devooght" + ], + "license": "MIT", + "homepage": "http://cognistreamer.github.io/tinyMCE-mention", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests", + "gulpfile.js", + "package.json" + ], + "dependencies": { + "tinymce-dist": "~4", + "jquery": "~3" + }, + "devDependencies": { + "qunit": "~1.21.0" + } +} diff --git a/css/autocomplete.css b/css/autocomplete.css index d6a949c..177a1c5 100644 --- a/css/autocomplete.css +++ b/css/autocomplete.css @@ -4,7 +4,6 @@ left: 0px; display: block; z-index: 1000; - display: none; float: left; min-width: 160px; padding: 5px 0; @@ -49,6 +48,11 @@ left: 10px; } +.rte-autocomplete > li.loading { + background: url("https://www.ajaxload.info/cache/FF/FF/FF/00/00/00/1-0.gif") center no-repeat; + height: 16px; +} + .rte-autocomplete > li > a { display: block; padding: 3px 20px; @@ -84,5 +88,5 @@ background-image: linear-gradient(to bottom,#08c,#0077b3); background-repeat: repeat-x; outline: 0; - filter: progid:DXImageTransform.Microsof; -} \ No newline at end of file + filter: progid:DXImageTransform.Microsoft; +} diff --git a/examples/commonjs/.gitignore b/examples/commonjs/.gitignore new file mode 100644 index 0000000..849ddff --- /dev/null +++ b/examples/commonjs/.gitignore @@ -0,0 +1 @@ +dist/ diff --git a/examples/commonjs/index.html b/examples/commonjs/index.html new file mode 100644 index 0000000..ddd183e --- /dev/null +++ b/examples/commonjs/index.html @@ -0,0 +1,16 @@ + + + + tinyMCE-mention + + + + + + + + + + + \ No newline at end of file diff --git a/examples/commonjs/main.js b/examples/commonjs/main.js new file mode 100644 index 0000000..526155e --- /dev/null +++ b/examples/commonjs/main.js @@ -0,0 +1,18 @@ +var tinymce = require('tinymce/tinymce'); + +require('tinymce/themes/modern/theme'); +require('tinymce-mention'); + +tinymce.init({ + selector: '#rte', + skin: false, + plugins: ['mention'], + mentions: { + source: [ + { name: 'Tyra Porcelli' }, + { name: 'Brigid Reddish' }, + { name: 'Ashely Buckler' }, + { name: 'Teddy Whelan' } + ] + } +}); \ No newline at end of file diff --git a/examples/commonjs/package.json b/examples/commonjs/package.json new file mode 100644 index 0000000..069c7e2 --- /dev/null +++ b/examples/commonjs/package.json @@ -0,0 +1,26 @@ +{ + "name": "tinyMCE-mention-webpack", + "version": "4.0.0", + "repository": { + "type": "git", + "url": "https://github.com/CogniStreamer/tinyMCE-mention.git" + }, + "description": "Mention/Autocomplete plugin for tinyMCE WYSIWYG editor", + "author": "Steven Devooght", + "bugs": { + "url": "https://github.com/CogniStreamer/tinyMCE-mention/issues" + }, + "private": true, + "engines": { + "node": ">=0.10.26" + }, + "dependencies": { + "tinymce": "^4.3.13", + "tinymce-mention": "^4.0.1" + }, + "devDependencies": { + "exports-loader": "^0.6.3", + "imports-loader": "^0.6.5", + "webpack": "^1.13.1" + } +} diff --git a/examples/commonjs/webpack.config.js b/examples/commonjs/webpack.config.js new file mode 100644 index 0000000..e2cb077 --- /dev/null +++ b/examples/commonjs/webpack.config.js @@ -0,0 +1,27 @@ +var webpack = require('webpack'); +var path = require('path'); + +module.exports = { + entry: './main.js', + output: { + filename: './dist/bundle.js' + }, + resolve: { + alias: { + 'jquery': path.join(__dirname, 'node_modules/jquery/dist/jquery') + } + }, + module: { + loaders: [ + { + test: require.resolve('tinymce/tinymce'), + loaders: [ + 'imports?this=>window', + 'exports?window.tinymce' + ] + } + ] + }, + debug: true, + watch: false +}; \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..8a649ef --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,22 @@ +var gulp = require('gulp'), + bower = require('gulp-bower'), + jshint = require('gulp-jshint'), + qunit = require('gulp-qunit'); + +gulp.task('lint', function () { + return gulp.src(['./mention/plugin.js', './tests/test_mention.js']) + .pipe(jshint()) + .pipe(jshint.reporter('default')) + .pipe(jshint.reporter('fail')); +}); + +gulp.task('bower', function () { + return bower(); +}); + +gulp.task('test', ['bower'], function () { + return gulp.src('./tests/test_runner.html') + .pipe(qunit({ timeout: 10 })); +}); + +gulp.task('default', ['lint']); \ No newline at end of file diff --git a/mention/editor_plugin.js b/mention/editor_plugin.js deleted file mode 100644 index b43d373..0000000 --- a/mention/editor_plugin.js +++ /dev/null @@ -1 +0,0 @@ -(function(e,t){"use strict";var n=function(e,n){this.editor=e;this.options=t.extend({},{source:[],delay:500,queryBy:"name",items:10},n);this.matcher=this.options.matcher||this.matcher;this.renderDropdown=this.options.renderDropdown||this.renderDropdown;this.render=this.options.render||this.render;this.insert=this.options.insert||this.insert;this.highlighter=this.options.highlighter||this.highlighter;this.query="";this.hasFocus=true;this.renderInput();this.bindEvents()};n.prototype={constructor:n,renderInput:function(){var e=''+''+this.options.delimiter+""+''+"";this.editor.execCommand("mceInsertContent",false,e);this.editor.focus();this.editor.selection.select(this.editor.selection.dom.select("span#autocomplete-searchtext span")[0]);this.editor.selection.collapse(0)},bindEvents:function(){this.editor.onKeyUp.addToTop(this.editorKeyUpProxy=t.proxy(this.rteKeyUp,this));this.editor.onKeyDown.addToTop(this.editorKeyDownProxy=t.proxy(this.rteKeyDown,this));this.editor.onClick.addToTop(this.editorClickProxy=t.proxy(this.rteClicked,this));t(this.editor.getWin()).on("scroll",this.rteScroll=t.proxy(function(){this.cleanUp(true)},this));t("body").on("click",this.bodyClickProxy=t.proxy(this.rteLostFocus,this))},unbindEvents:function(){this.editor.onKeyUp.remove(this.editorKeyUpProxy);this.editor.onKeyDown.remove(this.editorKeyDownProxy);this.editor.onClick.remove(this.editorClickProxy);t(this.editor.getWin()).off("scroll",this.rteScroll);t("body").off("click",this.bodyClickProxy)},rteKeyUp:function(e,t){switch(t.which||t.keyCode){case 40:case 38:case 16:case 17:case 18:break;case 8:if(this.query===""){this.cleanUp(true)}else{this.lookup()}break;case 9:case 13:var n=this.$dropdown!==undefined?this.$dropdown.find("li.active"):[];if(n.length){this.select(n.data());this.cleanUp(false)}else{this.cleanUp(true)}break;case 27:this.cleanUp(true);break;default:this.lookup()}},rteKeyDown:function(e,t){switch(t.which||t.keyCode){case 9:case 13:case 27:t.preventDefault();break;case 8:return false;case 38:t.preventDefault();if(this.$dropdown!==undefined){this.highlightPreviousResult()}break;case 40:t.preventDefault();if(this.$dropdown!==undefined){this.highlightNextResult()}break}t.stopPropagation()},rteClicked:function(e,n){var r=t(n.target);if(this.hasFocus&&r.parent().attr("id")!=="autocomplete-searchtext"){this.cleanUp(true)}},rteLostFocus:function(e,t){if(this.hasFocus){this.cleanUp(true)}},lookup:function(){this.query=t.trim(t(this.editor.getBody()).find("#autocomplete-searchtext").text()).replace("","");clearTimeout(this.searchTimeout);this.searchTimeout=setTimeout(t.proxy(function(){var e=t.isFunction(this.options.source)?this.options.source(this.query,t.proxy(this.process,this)):this.options.source;if(e){this.process(e)}},this),this.options.delay)},matcher:function(e){return~e[this.options.queryBy].toLowerCase().indexOf(this.query.toLowerCase())},sorter:function(e){var t=[],n=[],r=[],i;while((i=e.shift())!==undefined){if(!i[this.options.queryBy].toLowerCase().indexOf(this.query.toLowerCase()))t.push(i);else if(~i[this.options.queryBy].indexOf(this.query))n.push(i);else r.push(i)}return t.concat(n,r)},highlighter:function(e){return e.replace(new RegExp("("+this.query+")","ig"),function(e,t){return""+t+""})},show:function(){var e=t(this.editor.getContainer()).offset(),n=t(this.editor.getContainer()).find(".mceToolbar").first(),r=t(this.editor.dom.select("span#autocomplete")).position(),i=e.top+n.innerHeight()+r.top+t(this.editor.selection.getNode()).innerHeight()-t(this.editor.getDoc()).scrollTop()+5,s=e.left+r.left;this.$dropdown=t(this.renderDropdown()).css({top:i,left:s});t("body").append(this.$dropdown);this.$dropdown.on("click",t.proxy(this.autoCompleteClick,this))},process:function(e){if(!this.hasFocus){return}if(this.$dropdown===undefined){this.show()}var n=this,r=[],i=t.grep(e,function(e){return n.matcher(e)});i=n.sorter(i);i=i.slice(0,this.options.items);t.each(i,function(e,s){var o=t(n.render(s));o.html(o.html().replace(o.text(),n.highlighter(o.text())));t.each(i[e],function(e,t){o.attr("data-"+e,t)});r.push(o[0].outerHTML)});if(r.length){this.$dropdown.html(r.join("")).show()}else{this.$dropdown.hide()}},renderDropdown:function(){return''},render:function(e){return"
  • "+''+e.name+""+"
  • "},autoCompleteClick:function(e){var n=t(e.target).closest("li").data();if(!t.isEmptyObject(n)){this.select(n);this.cleanUp(false)}e.stopPropagation();e.preventDefault()},highlightPreviousResult:function(){var e=this.$dropdown.find("li.active").index(),t=e===0?this.$dropdown.find("li").length-1:e-=1;this.$dropdown.find("li").removeClass("active").eq(t).addClass("active")},highlightNextResult:function(){var e=this.$dropdown.find("li.active").index(),t=e===this.$dropdown.find("li").length-1?0:e+=1;this.$dropdown.find("li").removeClass("active").eq(t).addClass("active")},select:function(e){var t=this.editor.dom.select("span#autocomplete")[0];this.editor.dom.remove(t);this.editor.execCommand("mceInsertContent",false,this.insert(e)+" ")},insert:function(e){return""+e.name+""},cleanUp:function(e){this.unbindEvents();this.hasFocus=false;if(this.$dropdown!==undefined){this.$dropdown.remove();delete this.$dropdown}if(e){var n=this.query,r=t(this.editor.dom.select("span#autocomplete")),i=t("

    "+this.options.delimiter+n+"

    ")[0].firstChild,s=t(this.editor.selection.getNode()).offset().top===r.offset().top+(r.outerHeight()-r.height())/2;this.editor.dom.replace(i,r[0]);if(s){this.editor.selection.select(i);this.editor.selection.collapse()}}}};e.create("tinymce.plugins.Mention",{init:function(e,r){function o(){var n=t(e.selection.getNode().outerHTML),r=n.text(),i=r.substr(r.length-1,1);return!!t.trim(i).length?false:true}var i,s=e.getParam("mentions");s.delimiter=s.delimiter||"@";e.onKeyPress.add(function(e,t){if(String.fromCharCode(t.which||t.keyCode)===s.delimiter&&o()){if(i===undefined||i.hasFocus!==undefined&&!i.hasFocus){t.preventDefault();i=new n(e,s)}}})},getInfo:function(){return{longname:"mention",author:"Steven Devooght",version:e.majorVersion+"."+e.minorVersion}}});e.PluginManager.add("mention",e.plugins.Mention)})(tinymce,jQuery) \ No newline at end of file diff --git a/mention/editor_plugin_src.js b/mention/plugin.js similarity index 56% rename from mention/editor_plugin_src.js rename to mention/plugin.js index c3c908d..38dbb13 100644 --- a/mention/editor_plugin_src.js +++ b/mention/plugin.js @@ -1,7 +1,36 @@ -;(function (tinymce, $) { +/*global tinymce, module, require, define, global, self */ + +;(function (f) { + 'use strict'; + + // CommonJS + if (typeof exports === 'object' && typeof module !== 'undefined') { + module.exports = f(require('jquery')); + + // RequireJS + } else if (typeof define === 'function' && define.amd) { + define(['jquery'], f); + + // + + + + + + + + +
    +
    + + + + + \ No newline at end of file