summaryrefslogtreecommitdiffstats
path: root/apps/comments/js/vendor/At.js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/comments/js/vendor/At.js')
-rw-r--r--apps/comments/js/vendor/At.js/CHANGELOG.md314
-rw-r--r--apps/comments/js/vendor/At.js/CONTRIBUTING.md37
-rw-r--r--apps/comments/js/vendor/At.js/LICENSE-MIT22
-rw-r--r--apps/comments/js/vendor/At.js/README.md67
-rw-r--r--apps/comments/js/vendor/At.js/dist/css/jquery.atwho.css72
-rw-r--r--apps/comments/js/vendor/At.js/dist/css/jquery.atwho.min.css1
-rw-r--r--apps/comments/js/vendor/At.js/dist/js/jquery.atwho.js1212
-rw-r--r--apps/comments/js/vendor/At.js/examples/cross_document/dataFrame.html30
-rw-r--r--apps/comments/js/vendor/At.js/examples/cross_document/index.html90
-rw-r--r--apps/comments/js/vendor/At.js/examples/cross_document/viewFrame.html10
-rw-r--r--apps/comments/js/vendor/At.js/examples/hashtags.html61
-rw-r--r--apps/comments/js/vendor/At.js/examples/medium-editor.html44
-rw-r--r--apps/comments/js/vendor/At.js/examples/style.css57
-rw-r--r--apps/comments/js/vendor/At.js/examples/tinyMCE.html53
-rw-r--r--apps/comments/js/vendor/At.js/examples/ueditor.html45
-rw-r--r--apps/comments/js/vendor/At.js/gulpfile.js103
-rw-r--r--apps/comments/js/vendor/At.js/index.html205
-rw-r--r--apps/comments/js/vendor/At.js/specRunner.html31
-rw-r--r--apps/comments/js/vendor/At.js/src/api.coffee59
-rw-r--r--apps/comments/js/vendor/At.js/src/app.coffee158
-rw-r--r--apps/comments/js/vendor/At.js/src/controller.coffee142
-rw-r--r--apps/comments/js/vendor/At.js/src/default.coffee147
-rw-r--r--apps/comments/js/vendor/At.js/src/editableController.coffee174
-rw-r--r--apps/comments/js/vendor/At.js/src/jquery.atwho.css72
-rw-r--r--apps/comments/js/vendor/At.js/src/model.coffee59
-rw-r--r--apps/comments/js/vendor/At.js/src/textareaController.coffee51
-rw-r--r--apps/comments/js/vendor/At.js/src/view.coffee136
-rw-r--r--apps/comments/js/vendor/At.js/umd.template.js17
28 files changed, 0 insertions, 3469 deletions
diff --git a/apps/comments/js/vendor/At.js/CHANGELOG.md b/apps/comments/js/vendor/At.js/CHANGELOG.md
deleted file mode 100644
index bfc24588475..00000000000
--- a/apps/comments/js/vendor/At.js/CHANGELOG.md
+++ /dev/null
@@ -1,314 +0,0 @@
-### v1.5.0
-
-add `headerTpl` settings
-
-* 7a41d93 - #375 from vcekov/fix_scroll_position - Valentin Cekov
-* ecbf34f - #373 from vcekov/val/fix_key_navigation_interefence_with_mouse - Valentin Cekov
-* b68cf84 - #364 from WorktileTech/master - Harold.Luo
-* f836f04 - #372 from vcekov/fix_caret_for_space_after_@ - Harold.Luo
-* 06cf6bb - Properly set caret position after failed match - Valentin Cekov
-* c9ed2e2 - support header template. - htz
-
-### v1.4.0
-
-#### Contenteditable
-
-Pressing `Backspace` will turn the inserted element back to the origin query 'moment'.
-
-* 84edc9f - skip inserted element when moving left or right - ichord
-* 25a61d3 - the jQuery npm package is now called jquery. Fixes #338 - Mick Staugaard
-* 03ed71f - Merge pull request #351 from mociepka/master - Harold.Luo
-* ae00dc3 - Point main script in package json - Michał Ociepka
-* c5f31f5 - Merge branch 'dev' into HEAD - ichord
-* c399397 - fix contenteditable cursor bug when typing "a" into query - ichord
-* 7f4295a - fix previous replacements get clobbered when re-intering the inserted element - ichord
-* f00fabd - Merge pull request #354 from lvegerano/master - Harold.Luo
-* a42065e - Adds guard to event and dist file - Luis Vegerano
-* e4aaa30 - Add option to disable loopUp on click - Luis Vegerano
-* c9b7609 - Fix bug where callbacks would run before reaching minLen. Fixes #329. - Mike Leone
-* f8692dc - Add support for minLen. Connects to issue #316. - Mike Leone
-* fd7d298 - FIX: the value of `isSelecting` - ichord
-* c374c93 - FIX: IME typing error - ichord
-
-### v1.3.0
-
-* 7f2189d - fix #294 inserts "" suffix in contenteditable
-* bae95d9 - add `tabSelectsMatch` setting to make tab selection optional
-* e966aba - Merge pull request #298 from kkirsche/patch-1 - Harold.Luo
-* 9f78239 - Remove moot `version` property from bower.json - Kevin Kirsche
-
-### v1.2.0
-
-db09ac7 -> 886613f
-
-* 886613f - add `$.fn.atwho.debug = false` to trigger debug mode
-* 6567af9 - Enable default events when nothing is highlighted - Teemu
-* 752ad4a - Add scrollDuration option. - Takuru
-* bf17d43 - add parameter to allow for a spacebar in the middle of a search so that you can match a first + last name, for example - Feather Knee
-* a1d5fe7 - add `reposition` API - ichord
-* 9bcb06e - add "onInsert", "onDispaly" arguments to `tplEval` - ichord
-* db09ac7 - add `hide` api - ichord
-
-### v1.1.0
-
-* lisafeather/displyTplCallBack - #259
-* ADD: `editableAtwhoQueryAttrs` options
-* Added setting for 'spaceSelectsMatch' (default false/off)
-
-### v1.0.0
-
-**The naming convention are using camel case**.
-It means that every callback and setting's name are switched from underscope_naming to CamelNaming.
-Sorry about this.
-
-Future version's naming will follow the rules of http://semver.org constantly.
-
-#### Options:
-
-* Replaced `tpl` with `displayTpl`: display template of dropdown menu items.
- In previous versions, At.js will fetch the value of `data-value` to insert; It stops doing it.
- Please use the `insertTpl` option to manage the content to insert instead.
- The default value is `"<li>${name}</li>"`
-* The `insertTpl` option will be used in *textarea* as well.
- The default value is `"${atwho-at}${name}"`
-
-#### Callbacks:
-
-* Added `afterMatchFailed` callback to *contentEditable*
- It will be invoked after fail to match any query and stopping matching.
- Open *examples/hashtas.html* to examine how it work.
-* Removed `inserting_wrapper` callback to *contentEditable*
-
-#### Internal changes:
-
-* refactor the `Controller`
- Introduced `EditableController` class to control actions of `contenteditable` element.
- Introduced `TextareaController` class to control actions of `textarea` element.
- Both of them are inherit from the `Controller` class.
-
-* Refactored contentEditable mode
- Inserted content are wrapped in a span: `<span class=".atwho-inserted"/>`
- Querying content are wrapped in a span: `<span class=".atwho-query"/>`
-
-* Bring back auto-discovery to iframe.
-* Fix wrong offset in iframe
-* Replaced `iframeStandalone` with `iframeAdRoot`
-* All processed events are preventing default and stopping propagation.
-
-### v0.5.2
-
-* e1f6566 - fix error that doesn't display mention list on new line
-* 8fe3a54 - can insert multiple node from `inserting_wrapper`
-* 4080151 - scroll to top after showing
-* 01555f8 - scroll long dropdown list
-* 1b8999d - Add spm support
-* f2b8e9c - change name in package.json
-* b61bfdc - search on click
-* b1efd09 - Fixes error with selecting always first item on the list on iOS WebView when using https://github.com/ftlabs/fastclick
-* 7ed2890 - Allow accented characters in matcher
-
-### v0.5.1
-
-* 219de3d - fix Goes off screen / gets cropped if there isn't enough room
-* 1100c5b - No longer inherits text colour from document
-* ce60958 - on more boolean argument for `setIframe` api to work cross-document issues #199
-
-### v0.5.0
-
-* 593893c - refactor inserting of contenteditable
- Adding `inserting_wrapper` for customize wrapping inserting content.
- Not to insert item as a block in Firefox. check out issue #109.
- Removing `getInsertedItems`, `getInsertedIDs` API. You have to collect them on your own.
-* 4d3fb8f - have to set IFRAME manually
-* 1f13a16 - change space_after to suffix
-* b099ebb - fix caret position error after inserting
-* 2c47d7a - fix #178 hide view while clicking somewhere else
-
-### v0.4.12
-
-* eeafab1 - fix error: will always call hidden atwho event
-* b0f6ceb - Highlighter finds the first occurrence
-* da256db - Adds possibility of having empty prefix (at keyword) in controllers
-* b884225 - add `space_after` option
-* 65d6273 - Passes esc/tab/return keyup events through to emitted hide event
-
-### v0.4.11
-
-* bf938db - add `delay` setting, support delay searching
-* a0b5a6f - fix bug: terminate if query out of max_len
-* 01d6d5b - add css min file
-
-### v0.4.10
-
-* update jquery dependence version
-
-### v0.4.9
-
-* f317bd7 not lowercase query, add `highlight_first` option
-
-### v0.4.8
-
-* 79bbef4 destroy atwho view container dom
-* 0372d65 update bower and component keywords
-* 52a41f5 add optional `before_repostion` callback
-* cc1c239 Fixes #143 - ichord
-
-### v0.4.7
-
-* resolved #133, #135, #137.
-* add `beforeDestroy` event
-* wouldn't concat `caret.js` into `dist/js/jquery.atwho.js` any more.
-* seperate `jquery.atwho.coffee` into pieces.
-* seperate testing.
-
-### v0.4.6
-
-* 2d9ab23 fix `wrong document` error in IE iframe
-
-### v0.4.5
-
-* 664a765 support iframe
-
-### v0.4.4
-
-* 9ac7e75 - improve contentEditable for IE 8
-
- It's still some bugs in IE 8, just DON'T use it
- I don't want to spend more time on IE 8.
- So it would be the ending fixup. And i will still leave related code for
- a while maybe in case anyone want to help to improve it.
- Just encourge your users to upgrate the browers or just switch to a
- batter one please !!
-
-* a8371b3 - move project page to master from gh-pages.
-* 24b6225 - fix bugs #122
-* 645e030 - update Caret.js to v0.0.5
-
-### v0.4.3
-
-* e8e7561 update `Caret.js` to `v0.0.4`
-
-### v0.4.2
-
-* 4169b74 - binding data storage to the inputor. issues #121
-* 11d053f - reduse querying twice. issues#112
-
-### v0.4.1
-
-* b7721be - fix bug at view id was not been assign. close issues #99
-* 407f069 - fix bug: Can not autofocus after click the at-list in FireFox. #95
-* 917f033 - fix bug: click do not work in div-contenteditable. close issues #93
-
-### v0.4.0
-
-* update `Caret.js` to `v0.0.2`
-* `contenteditable` support !!
-* change content of default item template `tpl`
-* new rule to insert the `at` : will always remove the `at` from inputor but will add it back from `tpl` in default.
- so, if you are using your own `tpl` and want to show the `at` char, you have to do it yourself.
-* add `insert_tpl` setting for `contenteditable`.
- it will insert `data-value` of li element that eval from `tpl` in default.
-* new APIs for `contenteditable`: `getInsertedItemsWithIDs`, `getInsertedItems`, `getInsertedIDs`
-
-### 2013-08-07 - v0.3.2
-
-* bower
-* remove `Caret.js` codes and add it as bower dependencies
-* remove `display_flag` settings.
-* add `start_with_space` settings, default `true`
-* change `super_call` function to `call_default`
-
-### 2013-04-28
-
-* release new api `load`, `run`
-* add `alias` setting for `load` data or as the view's id
-* matching key with a space before it
-* register key in settings `{at: "@", data: []}` instead of being a argument
-* `max_len` setting for max length to search
-* change the default matcher regrex rule: occur at start of line or after whitespace
-* will not sort the datay without valid query string
-
-### 2013-04-23
-
-* group all data handlers as `Model` class.
-* All callbacks's context would be current `Controller`
-
-### 2013-04-05
-
-* `data` setting will be used to load data either local or remote. If it's String as URL it will preload data from remote by launch a ajax request (every times At.js call `reg` to update settings)
-
-* remove default `remote_filter` from callbacks list.
-* add `get_data` and `save_data` function to contoller. They are used to get and save whole data for At.js
-* `save_data` will invoke `data_refactor` everytime
-
-* will filter local data which is set in `settings` first and if it get nothing then call `remote_filter` if it's exists in callbacks list that is set by user.
-
-### 2013-04
-
-* remove ability of changing common setting after inputor binded
-* can fix list view after matched query in IE now.
-* separated core function (get offset of inputor) as a jquery plugins.
-
-### v0.2.0 - 2012-12
-
-**No more testing in IEs browsers.**
-
-#### Note
-The name `atWho` was changed to `atwho`.
-
-#### New features
-
-* Customer data handlers(matcher, filter, sorter) and template renders(highlight, template eval) by a group of configurable callbacks.
-* Support **AMD**
-
-#### Removed features
-
-* Filter by local data and remote (by ajax) data at the same time.
-* Caching
-* Mouse event
-
-#### Changed settings
-
-`-` mean removed option
-`+` mean new added option
-The one that start without `-` or `+` mean not change.
-
-* `-` data: [],
-* `+` data: null,
-
-* `-` choose: "data-value",
-* `+` search_key: "name",
-
-* `-` callback: null,
-* `+` callbacks: DEFAULT_CALLBACKS,
-
-* `+` display_timeout: 300,
-
-* `-` tpl: _DEFAULT_TPL
-* `+` tpl: DEFAULT_TPL
-
-* `-` cache: false
-
-Not change settings
-
-* cache: true,
-* limit: 5,
-* display_flag: true,
-
-### v0.1.7
-
-同步 `jquery-atwho-rails` gem 的版本号
-这会是 `v0.1` 的固定版本. 不再有新功能更新.
-
-###v0.1.2 2012-3-23
-* box showing above instead of bottom when it get close to the bottom of window
-* coffeescript here is.
-* every registered character able to have thire own options such as template(`tpl`)
-* every inputor (textarea, input) able to have their own registered character and different behavior
- even the same character to other inputor
-
-###v0.1.0
-* 可以監聽多個字符
- multiple char listening.
-* 顯示缺省列表.
- show default list.
diff --git a/apps/comments/js/vendor/At.js/CONTRIBUTING.md b/apps/comments/js/vendor/At.js/CONTRIBUTING.md
deleted file mode 100644
index 629943f377e..00000000000
--- a/apps/comments/js/vendor/At.js/CONTRIBUTING.md
+++ /dev/null
@@ -1,37 +0,0 @@
-## Contributing
-
-### Code style
-
-**Two** space indent
-
-### Modifying the code
-First, ensure that you have the latest [Node.js](http://nodejs.org/) and [npm](http://npmjs.org/) installed.
-
-Test that gulp is installed globally by running `grunt -v` at the command-line. If gulp isn't installed globally, run `npm install -g gulp` to install the latest version.
-
-* Fork and clone the repo.
-* Run `npm install` and `bower install` to install all dev dependencies (including grunt).
-* Modify the `*.coffee` file.
-* Run `gulp` to build this project.
-
-Assuming that you don't see any red, you're ready to go. Just be sure to run `gulp` after making any changes, to ensure that nothing is broken.
-
-### Submitting pull requests
-
-1. Create a new branch, please don't work in your `master` branch directly.
-1. Add failing tests for the change you want to make. Run `gulp` to see the tests fail.
-1. Fix stuff.
-1. Run `gulp` to see if the tests pass. Repeat steps 2-4 until done.
-1. Open `_SpecRunner.html` unit test file(s) in actual browser to ensure tests pass everywhere.
-1. Update the documentation to reflect any changes.
-1. Push to your fork and submit a pull request.
-
-### notes
-
-Please don't edit files in the `dist` subdirectory and *.js files in `src` as they are generated via gulp.
-You'll find source code in the `src` subdirectory!
-use `bower install` or `component install` to install dependencies first.
-
-
-### PhantomJS
-While gulp can run the included unit tests via [PhantomJS](http://phantomjs.org/), this shouldn't be considered a substitute for the real thing. Please be sure to test the `_SpecRunner.html` unit test file(s) in _actual_ browsers.
diff --git a/apps/comments/js/vendor/At.js/LICENSE-MIT b/apps/comments/js/vendor/At.js/LICENSE-MIT
deleted file mode 100644
index 36cd1c12272..00000000000
--- a/apps/comments/js/vendor/At.js/LICENSE-MIT
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2013 chord.luo@gmail.com
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
diff --git a/apps/comments/js/vendor/At.js/README.md b/apps/comments/js/vendor/At.js/README.md
deleted file mode 100644
index 551820afbb8..00000000000
--- a/apps/comments/js/vendor/At.js/README.md
+++ /dev/null
@@ -1,67 +0,0 @@
-**An autocompletion library to autocomplete mentions, smileys etc. just like on Github!**
-[![Build Status](https://travis-ci.org/ichord/At.js.png)](https://travis-ci.org/ichord/At.js)
-
-#### Notice
-
-At.js now **depends on** [Caret.js](https://github.com/ichord/Caret.js).
-Please read [**CHANGELOG.md**](CHANGELOG.md) for more details if you are going to update to new version.
-
-### Demo
-http://ichord.github.com/At.js
-
-### Documentation
-https://github.com/ichord/At.js/wiki
-
-### Compatibility
-
-* `textarea` - Chrome, Safari, Firefox, IE7+ (maybe IE6)
-* `contentEditable` - Chrome, Safari, Firefox, IE9+
-
-### Features Preview
-
-* Support IE 7+ for **textarea**.
-* Supports HTML5 [**contentEditable**](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Content_Editable) elements (NOT including IE 8)
-* Can listen to any character and not just '@'. Can set up multiple listeners for different characters with different behavior and data
-* Listener events can be bound to multiple inputors.
-* Format returned data using templates
-* Keyboard controls in addition to mouse
- - `Tab` or `Enter` keys select the value
- - `Up` and `Down` navigate between values (and `Ctrl-P` and `Ctrl-N` also)
- - `Right` and `left` will re-search the keyword.
-* Custom data handlers and template renderers using a group of configurable callbacks
-* Supports AMD
-
-### Requirements
-
-* jQuery >= 1.7.0.
-* [Caret.js](https://github.com/ichord/Caret.js)
- (You can use `Component` or `Bower` to install it.)
-
-### Integrating with your Application
-
-Simply include the following files in your HTML and you are good to go.
-
-```html
-<link href="css/jquery.atwho.css" rel="stylesheet">
-<script src="http://code.jquery.com/jquery.js"></script>
-<script src="js/jquery.caret.js"></script>
-<script src="js/jquery.atwho.js"></script>
-```
-
-```javascript
-$('#inputor').atwho({
- at: "@",
- data:['Peter', 'Tom', 'Anne']
-})
-```
-
-#### Bower & Component
-For installing using Bower you can use `jquery.atwho` and for Component please use `ichord/At.js`.
-
-#### Rails
-You can include At.js in your `Rails` application using the gem [jquery-atwho-rails](https://github.com/ichord/jquery-atwho-rails).
-
-### Core Team Members
-
-* [@ichord](https://twitter.com/_ichord) (twitter)
-
diff --git a/apps/comments/js/vendor/At.js/dist/css/jquery.atwho.css b/apps/comments/js/vendor/At.js/dist/css/jquery.atwho.css
deleted file mode 100644
index dad94ed9641..00000000000
--- a/apps/comments/js/vendor/At.js/dist/css/jquery.atwho.css
+++ /dev/null
@@ -1,72 +0,0 @@
-.atwho-view {
- position:absolute;
- top: 0;
- left: 0;
- display: none;
- margin-top: 18px;
- background: white;
- color: black;
- border: 1px solid #DDD;
- border-radius: 3px;
- box-shadow: 0 0 5px rgba(0,0,0,0.1);
- min-width: 120px;
- z-index: 11110 !important;
-}
-
-.atwho-view .atwho-header {
- padding: 5px;
- margin: 5px;
- cursor: pointer;
- border-bottom: solid 1px #eaeff1;
- color: #6f8092;
- font-size: 11px;
- font-weight: bold;
-}
-
-.atwho-view .atwho-header .small {
- color: #6f8092;
- float: right;
- padding-top: 2px;
- margin-right: -5px;
- font-size: 12px;
- font-weight: normal;
-}
-
-.atwho-view .atwho-header:hover {
- cursor: default;
-}
-
-.atwho-view .cur {
- background: #3366FF;
- color: white;
-}
-.atwho-view .cur small {
- color: white;
-}
-.atwho-view strong {
- color: #3366FF;
-}
-.atwho-view .cur strong {
- color: white;
- font:bold;
-}
-.atwho-view ul {
- /* width: 100px; */
- list-style:none;
- padding:0;
- margin:auto;
- max-height: 200px;
- overflow-y: auto;
-}
-.atwho-view ul li {
- display: block;
- padding: 5px 10px;
- border-bottom: 1px solid #DDD;
- cursor: pointer;
- /* border-top: 1px solid #C8C8C8; */
-}
-.atwho-view small {
- font-size: smaller;
- color: #777;
- font-weight: normal;
-}
diff --git a/apps/comments/js/vendor/At.js/dist/css/jquery.atwho.min.css b/apps/comments/js/vendor/At.js/dist/css/jquery.atwho.min.css
deleted file mode 100644
index f770dc73b3f..00000000000
--- a/apps/comments/js/vendor/At.js/dist/css/jquery.atwho.min.css
+++ /dev/null
@@ -1 +0,0 @@
-.atwho-view{position:absolute;top:0;left:0;display:none;margin-top:18px;background:#fff;color:#000;border:1px solid #DDD;border-radius:3px;box-shadow:0 0 5px rgba(0,0,0,.1);min-width:120px;z-index:11110!important}.atwho-view .atwho-header{padding:5px;margin:5px;cursor:pointer;border-bottom:solid 1px #eaeff1;color:#6f8092;font-size:11px;font-weight:700}.atwho-view .atwho-header .small{color:#6f8092;float:right;padding-top:2px;margin-right:-5px;font-size:12px;font-weight:400}.atwho-view .atwho-header:hover{cursor:default}.atwho-view .cur{background:#36F;color:#fff}.atwho-view .cur small{color:#fff}.atwho-view strong{color:#36F}.atwho-view .cur strong{color:#fff;font:700}.atwho-view ul{list-style:none;padding:0;margin:auto;max-height:200px;overflow-y:auto}.atwho-view ul li{display:block;padding:5px 10px;border-bottom:1px solid #DDD;cursor:pointer}.atwho-view small{font-size:smaller;color:#777;font-weight:400} \ No newline at end of file
diff --git a/apps/comments/js/vendor/At.js/dist/js/jquery.atwho.js b/apps/comments/js/vendor/At.js/dist/js/jquery.atwho.js
deleted file mode 100644
index 795b6c67dcd..00000000000
--- a/apps/comments/js/vendor/At.js/dist/js/jquery.atwho.js
+++ /dev/null
@@ -1,1212 +0,0 @@
-/**
- * at.js - 1.5.4
- * Copyright (c) 2017 chord.luo <chord.luo@gmail.com>;
- * Homepage: http://ichord.github.com/At.js
- * License: MIT
- */
-(function (root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module unless amdModuleId is set
- define(["jquery"], function (a0) {
- return (factory(a0));
- });
- } else if (typeof exports === 'object') {
- // Node. Does not work with strict CommonJS, but
- // only CommonJS-like environments that support module.exports,
- // like Node.
- module.exports = factory(require("jquery"));
- } else {
- factory(jQuery);
- }
-}(this, function ($) {
-var DEFAULT_CALLBACKS, KEY_CODE;
-
-KEY_CODE = {
- ESC: 27,
- TAB: 9,
- ENTER: 13,
- CTRL: 17,
- A: 65,
- P: 80,
- N: 78,
- LEFT: 37,
- UP: 38,
- RIGHT: 39,
- DOWN: 40,
- BACKSPACE: 8,
- SPACE: 32
-};
-
-DEFAULT_CALLBACKS = {
- beforeSave: function(data) {
- return Controller.arrayToDefaultHash(data);
- },
- matcher: function(flag, subtext, should_startWithSpace, acceptSpaceBar) {
- var _a, _y, match, regexp, space;
- flag = flag.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
- if (should_startWithSpace) {
- flag = '(?:^|\\s)' + flag;
- }
- _a = decodeURI("%C3%80");
- _y = decodeURI("%C3%BF");
- space = acceptSpaceBar ? "\ " : "";
- regexp = new RegExp(flag + "([A-Za-z" + _a + "-" + _y + "0-9_" + space + "\'\.\+\-]*)$|" + flag + "([^\\x00-\\xff]*)$", 'gi');
- match = regexp.exec(subtext);
- if (match) {
- return match[2] || match[1];
- } else {
- return null;
- }
- },
- filter: function(query, data, searchKey) {
- var _results, i, item, len;
- _results = [];
- for (i = 0, len = data.length; i < len; i++) {
- item = data[i];
- if (~new String(item[searchKey]).toLowerCase().indexOf(query.toLowerCase())) {
- _results.push(item);
- }
- }
- return _results;
- },
- remoteFilter: null,
- sorter: function(query, items, searchKey) {
- var _results, i, item, len;
- if (!query) {
- return items;
- }
- _results = [];
- for (i = 0, len = items.length; i < len; i++) {
- item = items[i];
- item.atwho_order = new String(item[searchKey]).toLowerCase().indexOf(query.toLowerCase());
- if (item.atwho_order > -1) {
- _results.push(item);
- }
- }
- return _results.sort(function(a, b) {
- return a.atwho_order - b.atwho_order;
- });
- },
- tplEval: function(tpl, map) {
- var error, error1, template;
- template = tpl;
- try {
- if (typeof tpl !== 'string') {
- template = tpl(map);
- }
- return template.replace(/\$\{([^\}]*)\}/g, function(tag, key, pos) {
- return map[key];
- });
- } catch (error1) {
- error = error1;
- return "";
- }
- },
- highlighter: function(li, query) {
- var regexp;
- if (!query) {
- return li;
- }
- regexp = new RegExp(">\\s*([^\<]*?)(" + query.replace("+", "\\+") + ")([^\<]*)\\s*<", 'ig');
- return li.replace(regexp, function(str, $1, $2, $3) {
- return '> ' + $1 + '<strong>' + $2 + '</strong>' + $3 + ' <';
- });
- },
- beforeInsert: function(value, $li, e) {
- return value;
- },
- beforeReposition: function(offset) {
- return offset;
- },
- afterMatchFailed: function(at, el) {}
-};
-
-var App;
-
-App = (function() {
- function App(inputor) {
- this.currentFlag = null;
- this.controllers = {};
- this.aliasMaps = {};
- this.$inputor = $(inputor);
- this.setupRootElement();
- this.listen();
- }
-
- App.prototype.createContainer = function(doc) {
- var ref;
- if ((ref = this.$el) != null) {
- ref.remove();
- }
- return $(doc.body).append(this.$el = $("<div class='atwho-container'></div>"));
- };
-
- App.prototype.setupRootElement = function(iframe, asRoot) {
- var error, error1;
- if (asRoot == null) {
- asRoot = false;
- }
- if (iframe) {
- this.window = iframe.contentWindow;
- this.document = iframe.contentDocument || this.window.document;
- this.iframe = iframe;
- } else {
- this.document = this.$inputor[0].ownerDocument;
- this.window = this.document.defaultView || this.document.parentWindow;
- try {
- this.iframe = this.window.frameElement;
- } catch (error1) {
- error = error1;
- this.iframe = null;
- if ($.fn.atwho.debug) {
- throw new Error("iframe auto-discovery is failed.\nPlease use `setIframe` to set the target iframe manually.\n" + error);
- }
- }
- }
- return this.createContainer((this.iframeAsRoot = asRoot) ? this.document : document);
- };
-
- App.prototype.controller = function(at) {
- var c, current, currentFlag, ref;
- if (this.aliasMaps[at]) {
- current = this.controllers[this.aliasMaps[at]];
- } else {
- ref = this.controllers;
- for (currentFlag in ref) {
- c = ref[currentFlag];
- if (currentFlag === at) {
- current = c;
- break;
- }
- }
- }
- if (current) {
- return current;
- } else {
- return this.controllers[this.currentFlag];
- }
- };
-
- App.prototype.setContextFor = function(at) {
- this.currentFlag = at;
- return this;
- };
-
- App.prototype.reg = function(flag, setting) {
- var base, controller;
- controller = (base = this.controllers)[flag] || (base[flag] = this.$inputor.is('[contentEditable]') ? new EditableController(this, flag) : new TextareaController(this, flag));
- if (setting.alias) {
- this.aliasMaps[setting.alias] = flag;
- }
- controller.init(setting);
- return this;
- };
-
- App.prototype.listen = function() {
- return this.$inputor.on('compositionstart', (function(_this) {
- return function(e) {
- var ref;
- if ((ref = _this.controller()) != null) {
- ref.view.hide();
- }
- _this.isComposing = true;
- return null;
- };
- })(this)).on('compositionend', (function(_this) {
- return function(e) {
- _this.isComposing = false;
- setTimeout(function(e) {
- return _this.dispatch(e);
- });
- return null;
- };
- })(this)).on('keyup.atwhoInner', (function(_this) {
- return function(e) {
- return _this.onKeyup(e);
- };
- })(this)).on('keydown.atwhoInner', (function(_this) {
- return function(e) {
- return _this.onKeydown(e);
- };
- })(this)).on('blur.atwhoInner', (function(_this) {
- return function(e) {
- var c;
- if (c = _this.controller()) {
- c.expectedQueryCBId = null;
- return c.view.hide(e, c.getOpt("displayTimeout"));
- }
- };
- })(this)).on('click.atwhoInner', (function(_this) {
- return function(e) {
- return _this.dispatch(e);
- };
- })(this)).on('scroll.atwhoInner', (function(_this) {
- return function() {
- var lastScrollTop;
- lastScrollTop = _this.$inputor.scrollTop();
- return function(e) {
- var currentScrollTop, ref;
- currentScrollTop = e.target.scrollTop;
- if (lastScrollTop !== currentScrollTop) {
- if ((ref = _this.controller()) != null) {
- ref.view.hide(e);
- }
- }
- lastScrollTop = currentScrollTop;
- return true;
- };
- };
- })(this)());
- };
-
- App.prototype.shutdown = function() {
- var _, c, ref;
- ref = this.controllers;
- for (_ in ref) {
- c = ref[_];
- c.destroy();
- delete this.controllers[_];
- }
- this.$inputor.off('.atwhoInner');
- return this.$el.remove();
- };
-
- App.prototype.dispatch = function(e) {
- var _, c, ref, results;
- ref = this.controllers;
- results = [];
- for (_ in ref) {
- c = ref[_];
- results.push(c.lookUp(e));
- }
- return results;
- };
-
- App.prototype.onKeyup = function(e) {
- var ref;
- switch (e.keyCode) {
- case KEY_CODE.ESC:
- e.preventDefault();
- if ((ref = this.controller()) != null) {
- ref.view.hide();
- }
- break;
- case KEY_CODE.DOWN:
- case KEY_CODE.UP:
- case KEY_CODE.CTRL:
- case KEY_CODE.ENTER:
- $.noop();
- break;
- case KEY_CODE.P:
- case KEY_CODE.N:
- if (!e.ctrlKey) {
- this.dispatch(e);
- }
- break;
- default:
- this.dispatch(e);
- }
- };
-
- App.prototype.onKeydown = function(e) {
- var ref, view;
- view = (ref = this.controller()) != null ? ref.view : void 0;
- if (!(view && view.visible())) {
- return;
- }
- switch (e.keyCode) {
- case KEY_CODE.ESC:
- e.preventDefault();
- view.hide(e);
- break;
- case KEY_CODE.UP:
- e.preventDefault();
- view.prev();
- break;
- case KEY_CODE.DOWN:
- e.preventDefault();
- view.next();
- break;
- case KEY_CODE.P:
- if (!e.ctrlKey) {
- return;
- }
- e.preventDefault();
- view.prev();
- break;
- case KEY_CODE.N:
- if (!e.ctrlKey) {
- return;
- }
- e.preventDefault();
- view.next();
- break;
- case KEY_CODE.TAB:
- case KEY_CODE.ENTER:
- case KEY_CODE.SPACE:
- if (!view.visible()) {
- return;
- }
- if (!this.controller().getOpt('spaceSelectsMatch') && e.keyCode === KEY_CODE.SPACE) {
- return;
- }
- if (!this.controller().getOpt('tabSelectsMatch') && e.keyCode === KEY_CODE.TAB) {
- return;
- }
- if (view.highlighted()) {
- e.preventDefault();
- view.choose(e);
- } else {
- view.hide(e);
- }
- break;
- default:
- $.noop();
- }
- };
-
- return App;
-
-})();
-
-var Controller,
- slice = [].slice;
-
-Controller = (function() {
- Controller.prototype.uid = function() {
- return (Math.random().toString(16) + "000000000").substr(2, 8) + (new Date().getTime());
- };
-
- function Controller(app, at1) {
- this.app = app;
- this.at = at1;
- this.$inputor = this.app.$inputor;
- this.id = this.$inputor[0].id || this.uid();
- this.expectedQueryCBId = null;
- this.setting = null;
- this.query = null;
- this.pos = 0;
- this.range = null;
- if ((this.$el = $("#atwho-ground-" + this.id, this.app.$el)).length === 0) {
- this.app.$el.append(this.$el = $("<div id='atwho-ground-" + this.id + "'></div>"));
- }
- this.model = new Model(this);
- this.view = new View(this);
- }
-
- Controller.prototype.init = function(setting) {
- this.setting = $.extend({}, this.setting || $.fn.atwho["default"], setting);
- this.view.init();
- return this.model.reload(this.setting.data);
- };
-
- Controller.prototype.destroy = function() {
- this.trigger('beforeDestroy');
- this.model.destroy();
- this.view.destroy();
- return this.$el.remove();
- };
-
- Controller.prototype.callDefault = function() {
- var args, error, error1, funcName;
- funcName = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
- try {
- return DEFAULT_CALLBACKS[funcName].apply(this, args);
- } catch (error1) {
- error = error1;
- return $.error(error + " Or maybe At.js doesn't have function " + funcName);
- }
- };
-
- Controller.prototype.trigger = function(name, data) {
- var alias, eventName;
- if (data == null) {
- data = [];
- }
- data.push(this);
- alias = this.getOpt('alias');
- eventName = alias ? name + "-" + alias + ".atwho" : name + ".atwho";
- return this.$inputor.trigger(eventName, data);
- };
-
- Controller.prototype.callbacks = function(funcName) {
- return this.getOpt("callbacks")[funcName] || DEFAULT_CALLBACKS[funcName];
- };
-
- Controller.prototype.getOpt = function(at, default_value) {
- var e, error1;
- try {
- return this.setting[at];
- } catch (error1) {
- e = error1;
- return null;
- }
- };
-
- Controller.prototype.insertContentFor = function($li) {
- var data, tpl;
- tpl = this.getOpt('insertTpl');
- data = $.extend({}, $li.data('item-data'), {
- 'atwho-at': this.at
- });
- return this.callbacks("tplEval").call(this, tpl, data, "onInsert");
- };
-
- Controller.prototype.renderView = function(data) {
- var searchKey;
- searchKey = this.getOpt("searchKey");
- data = this.callbacks("sorter").call(this, this.query.text, data.slice(0, 1001), searchKey);
- return this.view.render(data.slice(0, this.getOpt('limit')));
- };
-
- Controller.arrayToDefaultHash = function(data) {
- var i, item, len, results;
- if (!$.isArray(data)) {
- return data;
- }
- results = [];
- for (i = 0, len = data.length; i < len; i++) {
- item = data[i];
- if ($.isPlainObject(item)) {
- results.push(item);
- } else {
- results.push({
- name: item
- });
- }
- }
- return results;
- };
-
- Controller.prototype.lookUp = function(e) {
- var query, wait;
- if (e && e.type === 'click' && !this.getOpt('lookUpOnClick')) {
- return;
- }
- if (this.getOpt('suspendOnComposing') && this.app.isComposing) {
- return;
- }
- query = this.catchQuery(e);
- if (!query) {
- this.expectedQueryCBId = null;
- return query;
- }
- this.app.setContextFor(this.at);
- if (wait = this.getOpt('delay')) {
- this._delayLookUp(query, wait);
- } else {
- this._lookUp(query);
- }
- return query;
- };
-
- Controller.prototype._delayLookUp = function(query, wait) {
- var now, remaining;
- now = Date.now ? Date.now() : new Date().getTime();
- this.previousCallTime || (this.previousCallTime = now);
- remaining = wait - (now - this.previousCallTime);
- if ((0 < remaining && remaining < wait)) {
- this.previousCallTime = now;
- this._stopDelayedCall();
- return this.delayedCallTimeout = setTimeout((function(_this) {
- return function() {
- _this.previousCallTime = 0;
- _this.delayedCallTimeout = null;
- return _this._lookUp(query);
- };
- })(this), wait);
- } else {
- this._stopDelayedCall();
- if (this.previousCallTime !== now) {
- this.previousCallTime = 0;
- }
- return this._lookUp(query);
- }
- };
-
- Controller.prototype._stopDelayedCall = function() {
- if (this.delayedCallTimeout) {
- clearTimeout(this.delayedCallTimeout);
- return this.delayedCallTimeout = null;
- }
- };
-
- Controller.prototype._generateQueryCBId = function() {
- return {};
- };
-
- Controller.prototype._lookUp = function(query) {
- var _callback;
- _callback = function(queryCBId, data) {
- if (queryCBId !== this.expectedQueryCBId) {
- return;
- }
- if (data && data.length > 0) {
- return this.renderView(this.constructor.arrayToDefaultHash(data));
- } else {
- return this.view.hide();
- }
- };
- this.expectedQueryCBId = this._generateQueryCBId();
- return this.model.query(query.text, $.proxy(_callback, this, this.expectedQueryCBId));
- };
-
- return Controller;
-
-})();
-
-var TextareaController,
- extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
- hasProp = {}.hasOwnProperty;
-
-TextareaController = (function(superClass) {
- extend(TextareaController, superClass);
-
- function TextareaController() {
- return TextareaController.__super__.constructor.apply(this, arguments);
- }
-
- TextareaController.prototype.catchQuery = function() {
- var caretPos, content, end, isString, query, start, subtext;
- content = this.$inputor.val();
- caretPos = this.$inputor.caret('pos', {
- iframe: this.app.iframe
- });
- subtext = content.slice(0, caretPos);
- query = this.callbacks("matcher").call(this, this.at, subtext, this.getOpt('startWithSpace'), this.getOpt("acceptSpaceBar"));
- isString = typeof query === 'string';
- if (isString && query.length < this.getOpt('minLen', 0)) {
- return;
- }
- if (isString && query.length <= this.getOpt('maxLen', 20)) {
- start = caretPos - query.length;
- end = start + query.length;
- this.pos = start;
- query = {
- 'text': query,
- 'headPos': start,
- 'endPos': end
- };
- this.trigger("matched", [this.at, query.text]);
- } else {
- query = null;
- this.view.hide();
- }
- return this.query = query;
- };
-
- TextareaController.prototype.rect = function() {
- var c, iframeOffset, scaleBottom;
- if (!(c = this.$inputor.caret('offset', this.pos - 1, {
- iframe: this.app.iframe
- }))) {
- return;
- }
- if (this.app.iframe && !this.app.iframeAsRoot) {
- iframeOffset = $(this.app.iframe).offset();
- c.left += iframeOffset.left;
- c.top += iframeOffset.top;
- }
- scaleBottom = this.app.document.selection ? 0 : 2;
- return {
- left: c.left,
- top: c.top,
- bottom: c.top + c.height + scaleBottom
- };
- };
-
- TextareaController.prototype.insert = function(content, $li) {
- var $inputor, source, startStr, suffix, text;
- $inputor = this.$inputor;
- source = $inputor.val();
- startStr = source.slice(0, Math.max(this.query.headPos - this.at.length, 0));
- suffix = (suffix = this.getOpt('suffix')) === "" ? suffix : suffix || " ";
- content += suffix;
- text = "" + startStr + content + (source.slice(this.query['endPos'] || 0));
- $inputor.val(text);
- $inputor.caret('pos', startStr.length + content.length, {
- iframe: this.app.iframe
- });
- if (!$inputor.is(':focus')) {
- $inputor.focus();
- }
- return $inputor.change();
- };
-
- return TextareaController;
-
-})(Controller);
-
-var EditableController,
- extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
- hasProp = {}.hasOwnProperty;
-
-EditableController = (function(superClass) {
- extend(EditableController, superClass);
-
- function EditableController() {
- return EditableController.__super__.constructor.apply(this, arguments);
- }
-
- EditableController.prototype._getRange = function() {
- var sel;
- sel = this.app.window.getSelection();
- if (sel.rangeCount > 0) {
- return sel.getRangeAt(0);
- }
- };
-
- EditableController.prototype._setRange = function(position, node, range) {
- if (range == null) {
- range = this._getRange();
- }
- if (!(range && node)) {
- return;
- }
- node = $(node)[0];
- if (position === 'after') {
- range.setEndAfter(node);
- range.setStartAfter(node);
- } else {
- range.setEndBefore(node);
- range.setStartBefore(node);
- }
- range.collapse(false);
- return this._clearRange(range);
- };
-
- EditableController.prototype._clearRange = function(range) {
- var sel;
- if (range == null) {
- range = this._getRange();
- }
- sel = this.app.window.getSelection();
- if (this.ctrl_a_pressed == null) {
- sel.removeAllRanges();
- return sel.addRange(range);
- }
- };
-
- EditableController.prototype._movingEvent = function(e) {
- var ref;
- return e.type === 'click' || ((ref = e.which) === KEY_CODE.RIGHT || ref === KEY_CODE.LEFT || ref === KEY_CODE.UP || ref === KEY_CODE.DOWN);
- };
-
- EditableController.prototype._unwrap = function(node) {
- var next;
- node = $(node).unwrap().get(0);
- if ((next = node.nextSibling) && next.nodeValue) {
- node.nodeValue += next.nodeValue;
- $(next).remove();
- }
- return node;
- };
-
- EditableController.prototype.catchQuery = function(e) {
- var $inserted, $query, _range, index, inserted, isString, lastNode, matched, offset, query, query_content, range;
- if (!(range = this._getRange())) {
- return;
- }
- if (!range.collapsed) {
- return;
- }
- if (e.which === KEY_CODE.ENTER) {
- ($query = $(range.startContainer).closest('.atwho-query')).contents().unwrap();
- if ($query.is(':empty')) {
- $query.remove();
- }
- ($query = $(".atwho-query", this.app.document)).text($query.text()).contents().last().unwrap();
- this._clearRange();
- return;
- }
- if (/firefox/i.test(navigator.userAgent)) {
- if ($(range.startContainer).is(this.$inputor)) {
- this._clearRange();
- return;
- }
- if (e.which === KEY_CODE.BACKSPACE && range.startContainer.nodeType === document.ELEMENT_NODE && (offset = range.startOffset - 1) >= 0) {
- _range = range.cloneRange();
- _range.setStart(range.startContainer, offset);
- if ($(_range.cloneContents()).contents().last().is('.atwho-inserted')) {
- inserted = $(range.startContainer).contents().get(offset);
- this._setRange('after', $(inserted).contents().last());
- }
- } else if (e.which === KEY_CODE.LEFT && range.startContainer.nodeType === document.TEXT_NODE) {
- $inserted = $(range.startContainer.previousSibling);
- if ($inserted.is('.atwho-inserted') && range.startOffset === 0) {
- this._setRange('after', $inserted.contents().last());
- }
- }
- }
- $(range.startContainer).closest('.atwho-inserted').addClass('atwho-query').siblings().removeClass('atwho-query');
- if (($query = $(".atwho-query", this.app.document)).length > 0 && $query.is(':empty') && $query.text().length === 0) {
- $query.remove();
- }
- if (!this._movingEvent(e)) {
- $query.removeClass('atwho-inserted');
- }
- if ($query.length > 0) {
- switch (e.which) {
- case KEY_CODE.LEFT:
- this._setRange('before', $query.get(0), range);
- $query.removeClass('atwho-query');
- return;
- case KEY_CODE.RIGHT:
- this._setRange('after', $query.get(0).nextSibling, range);
- $query.removeClass('atwho-query');
- return;
- }
- }
- if ($query.length > 0 && (query_content = $query.attr('data-atwho-at-query'))) {
- $query.empty().html(query_content).attr('data-atwho-at-query', null);
- this._setRange('after', $query.get(0), range);
- }
- _range = range.cloneRange();
- _range.setStart(range.startContainer, 0);
- matched = this.callbacks("matcher").call(this, this.at, _range.toString(), this.getOpt('startWithSpace'), this.getOpt("acceptSpaceBar"));
- isString = typeof matched === 'string';
- if ($query.length === 0 && isString && (index = range.startOffset - this.at.length - matched.length) >= 0) {
- range.setStart(range.startContainer, index);
- $query = $('<span/>', this.app.document).attr(this.getOpt("editableAtwhoQueryAttrs")).addClass('atwho-query');
- range.surroundContents($query.get(0));
- lastNode = $query.contents().last().get(0);
- if (lastNode) {
- if (/firefox/i.test(navigator.userAgent)) {
- range.setStart(lastNode, lastNode.length);
- range.setEnd(lastNode, lastNode.length);
- this._clearRange(range);
- } else {
- this._setRange('after', lastNode, range);
- }
- }
- }
- if (isString && matched.length < this.getOpt('minLen', 0)) {
- return;
- }
- if (isString && matched.length <= this.getOpt('maxLen', 20)) {
- query = {
- text: matched,
- el: $query
- };
- this.trigger("matched", [this.at, query.text]);
- return this.query = query;
- } else {
- this.view.hide();
- this.query = {
- el: $query
- };
- if ($query.text().indexOf(this.at) >= 0) {
- if (this._movingEvent(e) && $query.hasClass('atwho-inserted')) {
- $query.removeClass('atwho-query');
- } else if (false !== this.callbacks('afterMatchFailed').call(this, this.at, $query)) {
- this._setRange("after", this._unwrap($query.text($query.text()).contents().first()));
- }
- }
- return null;
- }
- };
-
- EditableController.prototype.rect = function() {
- var $iframe, iframeOffset, rect;
- rect = this.query.el.offset();
- if (!(rect && this.query.el[0].getClientRects().length)) {
- return;
- }
- if (this.app.iframe && !this.app.iframeAsRoot) {
- iframeOffset = ($iframe = $(this.app.iframe)).offset();
- rect.left += iframeOffset.left - this.$inputor.scrollLeft();
- rect.top += iframeOffset.top - this.$inputor.scrollTop();
- }
- rect.bottom = rect.top + this.query.el.height();
- return rect;
- };
-
- EditableController.prototype.insert = function(content, $li) {
- var data, overrides, range, suffix, suffixNode;
- if (!this.$inputor.is(':focus')) {
- this.$inputor.focus();
- }
- overrides = this.getOpt('functionOverrides');
- if (overrides.insert) {
- return overrides.insert.call(this, content, $li);
- }
- suffix = (suffix = this.getOpt('suffix')) === "" ? suffix : suffix || "\u00A0";
- data = $li.data('item-data');
- this.query.el.removeClass('atwho-query').addClass('atwho-inserted').html(content).attr('data-atwho-at-query', "" + data['atwho-at'] + this.query.text).attr('contenteditable', "false");
- if (range = this._getRange()) {
- if (this.query.el.length) {
- range.setEndAfter(this.query.el[0]);
- }
- range.collapse(false);
- range.insertNode(suffixNode = this.app.document.createTextNode("" + suffix));
- this._setRange('after', suffixNode, range);
- }
- if (!this.$inputor.is(':focus')) {
- this.$inputor.focus();
- }
- return this.$inputor.change();
- };
-
- return EditableController;
-
-})(Controller);
-
-var Model;
-
-Model = (function() {
- function Model(context) {
- this.context = context;
- this.at = this.context.at;
- this.storage = this.context.$inputor;
- }
-
- Model.prototype.destroy = function() {
- return this.storage.data(this.at, null);
- };
-
- Model.prototype.saved = function() {
- return this.fetch() > 0;
- };
-
- Model.prototype.query = function(query, callback) {
- var _remoteFilter, data, searchKey;
- data = this.fetch();
- searchKey = this.context.getOpt("searchKey");
- data = this.context.callbacks('filter').call(this.context, query, data, searchKey) || [];
- _remoteFilter = this.context.callbacks('remoteFilter');
- if (data.length > 0 || (!_remoteFilter && data.length === 0)) {
- return callback(data);
- } else {
- return _remoteFilter.call(this.context, query, callback);
- }
- };
-
- Model.prototype.fetch = function() {
- return this.storage.data(this.at) || [];
- };
-
- Model.prototype.save = function(data) {
- return this.storage.data(this.at, this.context.callbacks("beforeSave").call(this.context, data || []));
- };
-
- Model.prototype.load = function(data) {
- if (!(this.saved() || !data)) {
- return this._load(data);
- }
- };
-
- Model.prototype.reload = function(data) {
- return this._load(data);
- };
-
- Model.prototype._load = function(data) {
- if (typeof data === "string") {
- return $.ajax(data, {
- dataType: "json"
- }).done((function(_this) {
- return function(data) {
- return _this.save(data);
- };
- })(this));
- } else {
- return this.save(data);
- }
- };
-
- return Model;
-
-})();
-
-var View;
-
-View = (function() {
- function View(context) {
- this.context = context;
- this.$el = $("<div class='atwho-view'><ul class='atwho-view-ul'></ul></div>");
- this.$elUl = this.$el.children();
- this.timeoutID = null;
- this.context.$el.append(this.$el);
- this.bindEvent();
- }
-
- View.prototype.init = function() {
- var header_tpl, id;
- id = this.context.getOpt("alias") || this.context.at.charCodeAt(0);
- header_tpl = this.context.getOpt("headerTpl");
- if (header_tpl && this.$el.children().length === 1) {
- this.$el.prepend(header_tpl);
- }
- return this.$el.attr({
- 'id': "at-view-" + id
- });
- };
-
- View.prototype.destroy = function() {
- return this.$el.remove();
- };
-
- View.prototype.bindEvent = function() {
- var $menu, lastCoordX, lastCoordY;
- $menu = this.$el.find('ul');
- lastCoordX = 0;
- lastCoordY = 0;
- return $menu.on('mousemove.atwho-view', 'li', (function(_this) {
- return function(e) {
- var $cur;
- if (lastCoordX === e.clientX && lastCoordY === e.clientY) {
- return;
- }
- lastCoordX = e.clientX;
- lastCoordY = e.clientY;
- $cur = $(e.currentTarget);
- if ($cur.hasClass('cur')) {
- return;
- }
- $menu.find('.cur').removeClass('cur');
- return $cur.addClass('cur');
- };
- })(this)).on('click.atwho-view', 'li', (function(_this) {
- return function(e) {
- $menu.find('.cur').removeClass('cur');
- $(e.currentTarget).addClass('cur');
- _this.choose(e);
- return e.preventDefault();
- };
- })(this));
- };
-
- View.prototype.visible = function() {
- return $.expr.filters.visible(this.$el[0]);
- };
-
- View.prototype.highlighted = function() {
- return this.$el.find(".cur").length > 0;
- };
-
- View.prototype.choose = function(e) {
- var $li, content;
- if (($li = this.$el.find(".cur")).length) {
- content = this.context.insertContentFor($li);
- this.context._stopDelayedCall();
- this.context.insert(this.context.callbacks("beforeInsert").call(this.context, content, $li, e), $li);
- this.context.trigger("inserted", [$li, e]);
- this.hide(e);
- }
- if (this.context.getOpt("hideWithoutSuffix")) {
- return this.stopShowing = true;
- }
- };
-
- View.prototype.reposition = function(rect) {
- var _window, offset, overflowOffset, ref;
- _window = this.context.app.iframeAsRoot ? this.context.app.window : window;
- if (rect.bottom + this.$el.height() - $(_window).scrollTop() > $(_window).height()) {
- rect.bottom = rect.top - this.$el.height();
- }
- if (rect.left > (overflowOffset = $(_window).width() - this.$el.width() - 5)) {
- rect.left = overflowOffset;
- }
- offset = {
- left: rect.left,
- top: rect.bottom
- };
- if ((ref = this.context.callbacks("beforeReposition")) != null) {
- ref.call(this.context, offset);
- }
- this.$el.offset(offset);
- return this.context.trigger("reposition", [offset]);
- };
-
- View.prototype.next = function() {
- var cur, next, nextEl, offset;
- cur = this.$el.find('.cur').removeClass('cur');
- next = cur.next();
- if (!next.length) {
- next = this.$el.find('li:first');
- }
- next.addClass('cur');
- nextEl = next[0];
- offset = nextEl.offsetTop + nextEl.offsetHeight + (nextEl.nextSibling ? nextEl.nextSibling.offsetHeight : 0);
- return this.scrollTop(Math.max(0, offset - this.$el.height()));
- };
-
- View.prototype.prev = function() {
- var cur, offset, prev, prevEl;
- cur = this.$el.find('.cur').removeClass('cur');
- prev = cur.prev();
- if (!prev.length) {
- prev = this.$el.find('li:last');
- }
- prev.addClass('cur');
- prevEl = prev[0];
- offset = prevEl.offsetTop + prevEl.offsetHeight + (prevEl.nextSibling ? prevEl.nextSibling.offsetHeight : 0);
- return this.scrollTop(Math.max(0, offset - this.$el.height()));
- };
-
- View.prototype.scrollTop = function(scrollTop) {
- var scrollDuration;
- scrollDuration = this.context.getOpt('scrollDuration');
- if (scrollDuration) {
- return this.$elUl.animate({
- scrollTop: scrollTop
- }, scrollDuration);
- } else {
- return this.$elUl.scrollTop(scrollTop);
- }
- };
-
- View.prototype.show = function() {
- var rect;
- if (this.stopShowing) {
- this.stopShowing = false;
- return;
- }
- if (!this.visible()) {
- this.$el.show();
- this.$el.scrollTop(0);
- this.context.trigger('shown');
- }
- if (rect = this.context.rect()) {
- return this.reposition(rect);
- }
- };
-
- View.prototype.hide = function(e, time) {
- var callback;
- if (!this.visible()) {
- return;
- }
- if (isNaN(time)) {
- this.$el.hide();
- return this.context.trigger('hidden', [e]);
- } else {
- callback = (function(_this) {
- return function() {
- return _this.hide();
- };
- })(this);
- clearTimeout(this.timeoutID);
- return this.timeoutID = setTimeout(callback, time);
- }
- };
-
- View.prototype.render = function(list) {
- var $li, $ul, i, item, len, li, tpl;
- if (!($.isArray(list) && list.length > 0)) {
- this.hide();
- return;
- }
- this.$el.find('ul').empty();
- $ul = this.$el.find('ul');
- tpl = this.context.getOpt('displayTpl');
- for (i = 0, len = list.length; i < len; i++) {
- item = list[i];
- item = $.extend({}, item, {
- 'atwho-at': this.context.at
- });
- li = this.context.callbacks("tplEval").call(this.context, tpl, item, "onDisplay");
- $li = $(this.context.callbacks("highlighter").call(this.context, li, this.context.query.text));
- $li.data("item-data", item);
- $ul.append($li);
- }
- this.show();
- if (this.context.getOpt('highlightFirst')) {
- return $ul.find("li:first").addClass("cur");
- }
- };
-
- return View;
-
-})();
-
-var Api;
-
-Api = {
- load: function(at, data) {
- var c;
- if (c = this.controller(at)) {
- return c.model.load(data);
- }
- },
- isSelecting: function() {
- var ref;
- return !!((ref = this.controller()) != null ? ref.view.visible() : void 0);
- },
- hide: function() {
- var ref;
- return (ref = this.controller()) != null ? ref.view.hide() : void 0;
- },
- reposition: function() {
- var c;
- if (c = this.controller()) {
- return c.view.reposition(c.rect());
- }
- },
- setIframe: function(iframe, asRoot) {
- this.setupRootElement(iframe, asRoot);
- return null;
- },
- run: function() {
- return this.dispatch();
- },
- destroy: function() {
- this.shutdown();
- return this.$inputor.data('atwho', null);
- }
-};
-
-$.fn.atwho = function(method) {
- var _args, result;
- _args = arguments;
- result = null;
- this.filter('textarea, input, [contenteditable=""], [contenteditable=true]').each(function() {
- var $this, app;
- if (!(app = ($this = $(this)).data("atwho"))) {
- $this.data('atwho', (app = new App(this)));
- }
- if (typeof method === 'object' || !method) {
- return app.reg(method.at, method);
- } else if (Api[method] && app) {
- return result = Api[method].apply(app, Array.prototype.slice.call(_args, 1));
- } else {
- return $.error("Method " + method + " does not exist on jQuery.atwho");
- }
- });
- if (result != null) {
- return result;
- } else {
- return this;
- }
-};
-
-$.fn.atwho["default"] = {
- at: void 0,
- alias: void 0,
- data: null,
- displayTpl: "<li>${name}</li>",
- insertTpl: "${atwho-at}${name}",
- headerTpl: null,
- callbacks: DEFAULT_CALLBACKS,
- functionOverrides: {},
- searchKey: "name",
- suffix: void 0,
- hideWithoutSuffix: false,
- startWithSpace: true,
- acceptSpaceBar: false,
- highlightFirst: true,
- limit: 5,
- maxLen: 20,
- minLen: 0,
- displayTimeout: 300,
- delay: null,
- spaceSelectsMatch: false,
- tabSelectsMatch: true,
- editableAtwhoQueryAttrs: {},
- scrollDuration: 150,
- suspendOnComposing: true,
- lookUpOnClick: true
-};
-
-$.fn.atwho.debug = false;
-
-}));
diff --git a/apps/comments/js/vendor/At.js/examples/cross_document/dataFrame.html b/apps/comments/js/vendor/At.js/examples/cross_document/dataFrame.html
deleted file mode 100644
index 4a1adabeccd..00000000000
--- a/apps/comments/js/vendor/At.js/examples/cross_document/dataFrame.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <title>Data Iframe</title>
- <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
- <script type="text/javascript" src="http://ichord.github.io/Caret.js/src/jquery.caret.js"></script>
- <script type="text/javascript" src="../../dist/js/jquery.atwho.js"></script>
- <script type="text/javascript">
- $(function(){
- var names = ["Jacob","Isabella","Ethan","Emma","Michael","Olivia","Alexander","Sophia","William","Ava","Joshua","Emily","Daniel","Madison","Jayden","Abigail","Noah","Chloe","你好","你你你"];
-
- var names = $.map(names,function(value,i) {
- return {'id':i,'name':value,'email':value+"@email.com"};
- });
-
- viewFrame = parent.frames.viewFrame
- var at_config = {
- at: "@",
- data: names,
- displayTpl: "<li>${name} <small>${email}</small></li>"
- }
- $(viewFrame.document.body)
- .atwho('setIframe', viewFrame.frameElement, true)
- .atwho(at_config);
- });
- </script>
-</head>
-<body>
-</body>
-</html>
diff --git a/apps/comments/js/vendor/At.js/examples/cross_document/index.html b/apps/comments/js/vendor/At.js/examples/cross_document/index.html
deleted file mode 100644
index 05428b3ee08..00000000000
--- a/apps/comments/js/vendor/At.js/examples/cross_document/index.html
+++ /dev/null
@@ -1,90 +0,0 @@
-<!DOCTYPE HTML>
-<html lang="en">
-<head>
- <meta http-equiv="x-ua-compatible" content="IE=Edge"/>
- <title>At.js</title>
- <style type="text/css">
- html, body {
- background:#F9F9F9;
- padding: 0;
- margin: 0;
- font: 14px/1.6 "Lucida Grande", "Helvetica", sans-serif;
- color: #333;
- }
- h1,h2,h3,h4 {
- font-family: 'PT Sans', sans-serif;
- line-height: 40px;
- color: inherit;
- font-weight: bold;
- margin: 10px 0;
- text-rendering: optimizelegibility;
- }
- h2,h3 {
- color: gray;
- }
- strong {
- color: #424242;
- }
-
- a {
- color: #4183C4;
- text-decoration: none;
- }
- a:hover {
- text-decoration: underline;
- }
- .wrapper {
- width: 750px;
- padding: 20px;
- margin: 0 auto;
- }
- header {
- margin-top:70px;
- margin-bottom: 50px;
- }
- header h1 {
- text-align: center;
- font-size: 75px;
- }
- h1 i {
- color: rgb(182, 180, 180);
- font-style: normal;
- font-weight: normal;
- }
-
- .inputor {
- height: 260px;
- width: 90%;
- border: 1px solid #dadada;
- border-radius: 4px;
- padding: 5px 8px;
- outline: 0 none;
- margin: 10px 0;
- background: white;
- font-size: inherit;
- overflow-y: scroll;
- }
- .inputor:focus {
- border: 1px solid rgb(6, 150, 247);
- }
-
- footer {
- margin: 30px 0;
- }
-
- </style>
-
-</head>
-<body>
- <div class="container wrapper">
- <header>
- <h1>At<i>.js</i></h1>
- </header>
- <div id="main">
- <h2>Cross-Document</h2>
- <iframe name="dataFrame" src="dataFrame.html" style="display:none;"></iframe>
- <iframe name="viewFrame" class="inputor" src="viewFrame.html"></iframe>
- </div>
- </div>
-</body>
-</html>
diff --git a/apps/comments/js/vendor/At.js/examples/cross_document/viewFrame.html b/apps/comments/js/vendor/At.js/examples/cross_document/viewFrame.html
deleted file mode 100644
index 84ee67d8a20..00000000000
--- a/apps/comments/js/vendor/At.js/examples/cross_document/viewFrame.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
- <title>View Iframe</title>
- <link rel="stylesheet" href="../../dist/css/jquery.atwho.css" />
-</head>
-<body contenteditable=true style="height: 100%;">
- <p>hello!</p>
-</body>
-</html>
diff --git a/apps/comments/js/vendor/At.js/examples/hashtags.html b/apps/comments/js/vendor/At.js/examples/hashtags.html
deleted file mode 100644
index 3894ceea993..00000000000
--- a/apps/comments/js/vendor/At.js/examples/hashtags.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<!DOCTYPE HTML>
-<html lang="en">
-<head>
- <meta http-equiv="x-ua-compatible" content="IE=Edge"/>
- <title>At.js</title>
- <link rel="stylesheet" href="../dist/css/jquery.atwho.css" />
- <link rel="stylesheet" href="./style.css" />
- <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
- <script type="text/javascript" src="http://ichord.github.io/Caret.js/src/jquery.caret.js"></script>
- <!-- // <script type="text/javascript" src="../bower_components/jquery/dist/jquery.js"></script> -->
- <!-- // <script type="text/javascript" src="../bower_components/Caret.js/dist/jquery.caret.js"></script> -->
- <script type="text/javascript" src="../dist/js/jquery.atwho.js"></script>
- <script type="text/javascript">
- $(function(){
- var jeremy = decodeURI("J%C3%A9r%C3%A9my") // Jérémy
- var tags = ["Jacob","Isabella","Ethan","Emma","Michael","Olivia","Alexander","Sophia","William","Ava","Joshua","Emily","Daniel","Madison","Jayden","Abigail","Noah","Chloe","你好","你你你", jeremy];
- $('#editable').atwho({
- at: "#",
- data: tags,
- limit: 200,
- callbacks: {
- afterMatchFailed: function(at, el) {
- // 32 is spacebar
- if (at == '#') {
- tags.push(el.text().trim().slice(1));
- this.model.save(tags);
- this.insert(el.text().trim());
- return false;
- }
- }
- }
- });
- });
- </script>
- <style type="text/css">
- /*override atwho's style*/
- .atwho-inserted {
- color: #4183C4;
- }
- .atwho-query {
- color: #4183C4;
- }
- </style>
-</head>
-<body>
- <div class="container wrapper">
- <header>
- <h3>Type `#` to autocomplete tags</h3>
- </header>
- <div id="main">
- <div id="editable" class="inputor" contentEditable="true"></div>
- <footer>
- <h2>
- -> <a class="github" href="https://github.com/ichord/At.js">Fork me on GitHub!</a>
- </h2>
- </footer>
-
- </div>
- </div>
-</body>
-</html>
diff --git a/apps/comments/js/vendor/At.js/examples/medium-editor.html b/apps/comments/js/vendor/At.js/examples/medium-editor.html
deleted file mode 100644
index f1cedf9b06d..00000000000
--- a/apps/comments/js/vendor/At.js/examples/medium-editor.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE HTML>
-<html lang="en">
-<head>
- <meta http-equiv="x-ua-compatible" content="IE=Edge"/>
- <title>At.js</title>
- <link rel="stylesheet" href="../dist/css/jquery.atwho.css" />
- <link rel="stylesheet" type="text/css" href="http://dfimg.com/medium-editor/dist/css/medium-editor.css">
- <link rel="stylesheet" type="text/css" href="http://dfimg.com/medium-editor/dist/css/themes/default.css">
- <link rel="stylesheet" href="./style.css" />
- <!-- // <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> -->
- <!-- // <script type="text/javascript" src="http://ichord.github.io/Caret.js/src/jquery.caret.js"></script> -->
- <script type="text/javascript" src="../bower_components/jquery/dist/jquery.js"></script>
- <script type="text/javascript" src="../bower_components/Caret.js/dist/jquery.caret.js"></script>
- <script type="text/javascript" src="../dist/js/jquery.atwho.js"></script>
- <script src="http://dfimg.com/medium-editor/dist/js/medium-editor.js"></script>
-
- <script type="text/javascript">
- $(function(){
- var jeremy = decodeURI("J%C3%A9r%C3%A9my") // Jérémy
- var names = ["Jacob","Isabella","Ethan","Emma","Michael","Olivia","Alexander","Sophia","William","Ava","Joshua","Emily","Daniel","Madison","Jayden","Abigail","Noah","Chloe","你好","你你你", jeremy];
- var editor = new MediumEditor('#editor');
- $('#editor').atwho({at: "@", data: names});
- });
- </script>
-</head>
-
-<body>
- <div class="container wrapper">
- <header>
- <h3>Example for medium-editor</h3>
- </header>
- <div id="main">
- <div id="editor" contentEditable>Easy! You should check out MoxieManager!</div>
- <footer>
- <h2>
- -> <a class="github" href="https://github.com/ichord/At.js">Fork me on GitHub!</a>
- </h2>
- </footer>
-
- </div>
- </div>
-</body>
-
-</html>
diff --git a/apps/comments/js/vendor/At.js/examples/style.css b/apps/comments/js/vendor/At.js/examples/style.css
deleted file mode 100644
index 9e78ffbf748..00000000000
--- a/apps/comments/js/vendor/At.js/examples/style.css
+++ /dev/null
@@ -1,57 +0,0 @@
-html, body {
- background:#F9F9F9;
- padding: 0;
- margin: 0;
- font: 14px/1.6 "Lucida Grande", "Helvetica", sans-serif;
- color: #333;
-}
-h1,h2,h3,h4 {
- font-family: 'PT Sans', sans-serif;
- line-height: 40px;
- color: inherit;
- font-weight: bold;
- margin: 10px 0;
- text-rendering: optimizelegibility;
-}
-h2,h3 {
- color: gray;
-}
-strong {
- color: #424242;
-}
-
-a {
- color: #4183C4;
- text-decoration: none;
-}
-a:hover {
- text-decoration: underline;
-}
-.wrapper {
- width: 750px;
- padding: 20px;
- margin: 0 auto;
-}
-header {
- margin-top:30px;
-}
-
-.inputor {
- height: 160px;
- width: 90%;
- border: 1px solid #dadada;
- border-radius: 4px;
- padding: 5px 8px;
- outline: 0 none;
- margin: 10px 0;
- background: white;
- font-size: inherit;
- overflow-y: scroll;
-}
-.inputor:focus {
- border: 1px solid rgb(6, 150, 247);
-}
-
-footer {
- margin: 30px 0;
-}
diff --git a/apps/comments/js/vendor/At.js/examples/tinyMCE.html b/apps/comments/js/vendor/At.js/examples/tinyMCE.html
deleted file mode 100644
index fca68152981..00000000000
--- a/apps/comments/js/vendor/At.js/examples/tinyMCE.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!DOCTYPE HTML>
-<html lang="en">
-<head>
- <meta http-equiv="x-ua-compatible" content="IE=Edge"/>
- <title>At.js</title>
- <link rel="stylesheet" href="../dist/css/jquery.atwho.css" />
- <link rel="stylesheet" href="./style.css" />
- <!-- // <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> -->
- <!-- // <script type="text/javascript" src="http://ichord.github.io/Caret.js/src/jquery.caret.js"></script> -->
- <script type="text/javascript" src="../bower_components/jquery/dist/jquery.js"></script>
- <script type="text/javascript" src="../bower_components/Caret.js/dist/jquery.caret.js"></script>
- <script type="text/javascript" src="../dist/js/jquery.atwho.js"></script>
- <script src="http://tinymce.cachefly.net/4.1/tinymce.min.js"></script>
-
- <script type="text/javascript">
- $(function(){
- var jeremy = decodeURI("J%C3%A9r%C3%A9my") // Jérémy
- var names = ["Jacob","Isabella","Ethan","Emma","Michael","Olivia","Alexander","Sophia","William","Ava","Joshua","Emily","Daniel","Madison","Jayden","Abigail","Noah","Chloe","你好","你你你", jeremy];
- tinymce.init({
- selector: "#editor",
- init_instance_callback: function(editor) {
- $(editor.contentDocument.activeElement).atwho({at: "@", data: names});
- },
- setup: function(editor) {
- editor.on('keydown', function(e) {
- if(e.keyCode == 13 && $(editor.contentDocument.activeElement).atwho('isSelecting'))
- return false
- })
- }
- });
-
- });
- </script>
-</head>
-
-<body>
- <div class="container wrapper">
- <header>
- <h3>Example for tinyMCE editor</h3>
- </header>
- <div id="main">
- <textarea id="editor">Easy! You should check out MoxieManager!</textarea>
- <footer>
- <h2>
- -> <a class="github" href="https://github.com/ichord/At.js">Fork me on GitHub!</a>
- </h2>
- </footer>
-
- </div>
- </div>
-</body>
-
-</html>
diff --git a/apps/comments/js/vendor/At.js/examples/ueditor.html b/apps/comments/js/vendor/At.js/examples/ueditor.html
deleted file mode 100644
index 34de7c92922..00000000000
--- a/apps/comments/js/vendor/At.js/examples/ueditor.html
+++ /dev/null
@@ -1,45 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
- <link rel="stylesheet" href="http://ueditor.baidu.com/ueditor/themes/default/css/ueditor.css" />
- <link rel="stylesheet" href="../dist/css/jquery.atwho.css" />
-
- <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
- <script type="text/javascript" src="http://ichord.github.io/Caret.js/src/jquery.caret.js"></script>
- <script type="text/javascript" src="../dist/js/jquery.atwho.js"></script>
-
- <title>ueditor</title>
-</head>
-<body>
- <script id="container" name="content" type="text/plain">
- test
- </script>
- <script src="http://ueditor.baidu.com/ueditor/ueditor.config.js"></script>
- <script src="http://ueditor.baidu.com/ueditor/ueditor.all.js"></script>
-
- <script type="text/javascript">
- var ue = UE.getEditor('container');
- $(function(){
- var at_config = {
- at: "@",
- data:['Peter', 'Tom', 'Anne', 'zhangsan', 'lisi', 'wangwu', 'laoliu', 'libai', 'dupu', 'xiaozhou'],
- limit: 20
- }
-
- var ue = UE.getEditor('container',{
- contextMenu:[],
- //focus时自动清空初始化时的内容
- autoClearinitialContent:true,
- //关闭字数统计
- wordCount:false,
- //关闭elementPath
- elementPathEnabled:false,
- });
- ue.addListener('ready', function(editor){
- $(this.document.body).atwho(at_config);
- });
- });
- </script>
-</body>
-</html>
diff --git a/apps/comments/js/vendor/At.js/gulpfile.js b/apps/comments/js/vendor/At.js/gulpfile.js
deleted file mode 100644
index e9699eab8d7..00000000000
--- a/apps/comments/js/vendor/At.js/gulpfile.js
+++ /dev/null
@@ -1,103 +0,0 @@
-var gulp = require('gulp'),
- coffee = require('gulp-coffee'),
- concat = require('gulp-concat'),
- umd = require('gulp-umd'),
- uglify = require('gulp-uglify'),
- rename = require("gulp-rename"),
- cssmin = require('gulp-cssmin'),
- jasmine = require('gulp-jasmine-phantom'),
- bump = require('gulp-bump'),
- header = require('gulp-header'),
- debug = require('gulp-debug'),
- util = require('gulp-util');
-
-var name = 'jquery.atwho';
-
-gulp.task('coffee', function() {
- gulp.src('src/*.coffee')
- .pipe(coffee({bare: true}).on('error', util.log))
- .pipe(gulp.dest('./build/js'));
-});
-
-gulp.task('concat', function() {
- fileList = [
- 'build/js/default.js',
- 'build/js/app.js',
- 'build/js/controller.js',
- 'build/js/textareaController.js',
- 'build/js/editableController.js',
- 'build/js/model.js',
- 'build/js/view.js',
- 'build/js/api.js'
- ]
- gulp.src(fileList)
- .pipe(concat(name + ".js"))
- .pipe(gulp.dest('build'));
-});
-
-gulp.task('umd', function() {
- gulp.src('build/' + name + ".js")
- .pipe(umd({template: "umd.template.js"}))
- .pipe(gulp.dest('build/js'));
-});
-
-gulp.task('bump', function() {
- gulp.src(['bower.json', 'component.json', 'package.json'])
- .pipe(bump({version: "1.5.4"}))
- .pipe(gulp.dest('./'));
-});
-
-gulp.task("mark", function() {
- var pkg = require('./package.json');
- var banner = ['/**',
- ' * <%= pkg.name %> - <%= pkg.version %>',
- ' * Copyright (c) <%= year %> <%= pkg.author.name %> <<%= pkg.author.email %>>;',
- ' * Homepage: <%= pkg.homepage %>',
- ' * License: <%= pkg.license %>',
- ' */',
- ''].join('\n');
-
- gulp.src('build/js/' + name + '.js')
- .pipe(header(banner, { pkg : pkg, year: (new Date).getFullYear()}))
- .pipe(gulp.dest('dist/js/'))
-});
-
-gulp.task('compress', function() {
- gulp.src('dist/js/' + name + '.js')
- .pipe(uglify())
- .pipe(rename({suffix: '.min'}))
- .pipe(gulp.dest('dist/js'));
-
- gulp.src('src/jquery.atwho.css').pipe(gulp.dest('dist/css'))
- gulp.src('dist/css/' + name + '.css')
- .pipe(cssmin())
- .pipe(rename({suffix: '.min'}))
- .pipe(gulp.dest('dist/css'));
-});
-
-gulp.task('test', function () {
- gulp.src('spec/**/*.coffee')
- .pipe(coffee({bare: true}).on('error', util.log))
- .pipe(debug({title: "compiled specs"}))
- .pipe(gulp.dest('spec/build'))
-
- gulp.src('spec/build/javascripts/*.spec.js')
- .pipe(jasmine({
- integration: true,
- specHtml: "specRunner.html"
- /* TODO: have to add css to spec
- vendor: [
- 'bower_components/jquery/dist/jquery.js',
- 'bower_components/Caret.js/dist/jquery.caret.js',
- 'dist/js/jquery.atwho.js',
- 'node_modules/jasmine-jquery/lib/*.js',
- 'node_modules/jasmine-ajax/lib/*.js',
- 'spec/helpers/*.js',
- 'spec/build/spec_helper.js'
- ],
- */
- }));
-});
-
-gulp.task('compile', ['coffee', 'umd', 'concat']);
-gulp.task('default', ['compile', 'bump', 'mark', 'compress']);
diff --git a/apps/comments/js/vendor/At.js/index.html b/apps/comments/js/vendor/At.js/index.html
deleted file mode 100644
index a2654e0b8e5..00000000000
--- a/apps/comments/js/vendor/At.js/index.html
+++ /dev/null
@@ -1,205 +0,0 @@
-<!DOCTYPE HTML>
-<html lang="en">
-<head>
- <meta http-equiv="x-ua-compatible" content="IE=Edge"/>
- <title>At.js</title>
- <link rel="stylesheet" href="dist/css/jquery.atwho.css" />
- <script type="text/javascript" src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
- <script type="text/javascript" src="https://ichord.github.io/Caret.js/src/jquery.caret.js"></script>
- <!-- <script type="text/javascript" src="bower_components/jquery/dist/jquery.js"></script> -->
- <!-- <script type="text/javascript" src="bower_components/Caret.js/dist/jquery.caret.js"></script> -->
- <script type="text/javascript" src="dist/js/jquery.atwho.js"></script>
- <script type="text/javascript">
- $(function(){
- $.fn.atwho.debug = true
- var emojis = [
- "smile", "iphone", "girl", "smiley", "heart", "kiss", "copyright", "coffee",
- "a", "ab", "airplane", "alien", "ambulance", "angel", "anger", "angry",
- "arrow_forward", "arrow_left", "arrow_lower_left", "arrow_lower_right",
- "arrow_right", "arrow_up", "arrow_upper_left", "arrow_upper_right",
- "art", "astonished", "atm", "b", "baby", "baby_chick", "baby_symbol",
- "balloon", "bamboo", "bank", "barber", "baseball", "basketball", "bath",
- "bear", "beer", "beers", "beginner", "bell", "bento", "bike", "bikini",
- "bird", "birthday", "black_square", "blue_car", "blue_heart", "blush",
- "boar", "boat", "bomb", "book", "boot", "bouquet", "bow", "bowtie",
- "boy", "bread", "briefcase", "broken_heart", "bug", "bulb",
- "person_with_blond_hair", "phone", "pig", "pill", "pisces", "plus1",
- "point_down", "point_left", "point_right", "point_up", "point_up_2",
- "police_car", "poop", "post_office", "postbox", "pray", "princess",
- "punch", "purple_heart", "question", "rabbit", "racehorse", "radio",
- "up", "us", "v", "vhs", "vibration_mode", "virgo", "vs", "walking",
- "warning", "watermelon", "wave", "wc", "wedding", "whale", "wheelchair",
- "white_square", "wind_chime", "wink", "wink2", "wolf", "woman",
- "womans_hat", "womens", "x", "yellow_heart", "zap", "zzz", "+1",
- "-1"
- ]
- var jeremy = decodeURI("J%C3%A9r%C3%A9my") // Jérémy
- var names = ["Jacob","Isabella","Ethan","Emma","Michael","Olivia","Alexander","Sophia","William","Ava","Joshua","Emily","Daniel","Madison","Jayden","Abigail","Noah","Chloe","你好","你你你", jeremy, "가"];
-
- var names = $.map(names,function(value,i) {
- return {'id':i,'name':value,'email':value+"@email.com"};
- });
- var emojis = $.map(emojis, function(value, i) {return {key: value, name:value}});
-
- var at_config = {
- at: "@",
- data: names,
- headerTpl: '<div class="atwho-header">Member List<small>↑&nbsp;↓&nbsp;</small></div>',
- insertTpl: '${name}',
- displayTpl: "<li>${name} <small>${email}</small></li>",
- limit: 200
- }
- var emoji_config = {
- at: ":",
- data: emojis,
- displayTpl: "<li>${name} <img src='https://assets-cdn.github.com/images/icons/emoji/${key}.png' height='20' width='20' /></li>",
- insertTpl: ':${key}:',
- delay: 400
- }
- $inputor = $('#inputor').atwho(at_config).atwho(emoji_config);
- $inputor.caret('pos', 47);
- $inputor.focus().atwho('run');
-
- emoji_config.insertTpl = "<img src='https://assets-cdn.github.com/images/icons/emoji/${name}.png' height='20' width='20' />"
- $('#editable').atwho(at_config).atwho(emoji_config);
-
- ifr = $('#iframe1')[0]
- doc = ifr.contentDocument || iframe.contentWindow.document
- if ((ifrBody = doc.body) == null) {
- // For IE
- doc.write("<body></body>")
- ifrBody = doc.body
- }
- ifrBody.contentEditable = true
- ifrBody.id = 'ifrBody'
- ifrBody.innerHTML = 'For <strong>WYSIWYG</strong> which using <strong>iframe</strong> such as <strong>ckeditor</strong>'
- $(ifrBody).atwho('setIframe', ifr).atwho(at_config)
- });
-
- </script>
- <!--link href='http://fonts.googleapis.com/css?family=Dosis:400,700|Bubblegum+Sans|Overlock:400,900|PT+Sans:400,700|PT+Sans+Narrow:400,700|Magra|Asap:400,700|Share:400,700&subset=latin,latin-ext' rel='stylesheet' type='text/css' -->
- <link href='http://fonts.googleapis.com/css?family=PT+Sans:400,700' rel='stylesheet' type='text/css'>
-
- <style type="text/css">
- html, body {
- background:#F9F9F9;
- padding: 0;
- margin: 0;
- font: 14px/1.6 "Lucida Grande", "Helvetica", sans-serif;
- color: #333;
- }
- h1,h2,h3,h4 {
- font-family: 'PT Sans', sans-serif;
- line-height: 40px;
- color: inherit;
- font-weight: bold;
- margin: 10px 0;
- text-rendering: optimizelegibility;
- }
- h2,h3 {
- color: gray;
- }
- strong {
- color: #424242;
- }
-
- a {
- color: #4183C4;
- text-decoration: none;
- }
- a:hover {
- text-decoration: underline;
- }
- .wrapper {
- width: 750px;
- padding: 20px;
- margin: 0 auto;
- }
- header {
- margin-top:70px;
- margin-bottom: 50px;
- }
- header h1 {
- text-align: center;
- font-size: 75px;
- }
- h1 i {
- color: rgb(182, 180, 180);
- font-style: normal;
- font-weight: normal;
- }
-
- .inputor {
- height: 160px;
- width: 90%;
- border: 1px solid #dadada;
- border-radius: 4px;
- padding: 5px 8px;
- outline: 0 none;
- margin: 10px 0;
- background: white;
- font-size: inherit;
- overflow-y: scroll;
- }
- .inputor:focus {
- border: 1px solid rgb(6, 150, 247);
- }
-
- ul.doc {
- list-style:none;
- }
- ul.doc li {
- display:inline-block;
- margin: 0 10px;
- }
-
- footer {
- margin: 30px 0;
- }
-
- .github {
- text-align: center;
- }
-
- </style>
-
-</head>
-<body>
- <div class="container wrapper">
- <!-- <a id="github" href="https://github.com/ichord/At.js" target="_blank"><img style="position: absolute; top: 0; right: 0; border: 0; z-index:999" src="http://s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png" alt="Fork me on GitHub"></a> -->
-
- <header>
- <h1>At<i>.js</i></h1>
- </header>
- <div id="main">
- <div>
- <textarea id="inputor" class="inputor">At.js, a github-like autocomplete library :s</textarea>
- </div>
-
- <div id="editable" class="inputor" contentEditable="true">
- <p>
- <b>And!!</b> it support <b style="font-size: 20px">ContentEditable</b> mode too!!
- <img src="https://assets-cdn.github.com/images/icons/emoji/smile.png" height="20" width="20">
- <img src="https://assets-cdn.github.com/images/icons/emoji/smiley.png" height="20" width="20">
- <img src="https://assets-cdn.github.com/images/icons/emoji/coffee.png" height="20" width="20">
- </p>
- <p>
- <b>Try here now!</b><img src="https://assets-cdn.github.com/images/icons/emoji/point_right.png" height="20" width="20">
- <b>:h</b>
- </p>
- </div>
-
- <div class="inputor" style="overflow: hidden">
- <iframe src="" id="iframe1" style="width: 100%; height: 100%; border: 0px;"></iframe>
- </div>
-
- <footer>
- <h2>
- -> <a class="github" href="https://github.com/ichord/At.js">Fork me on GitHub!</a>
- </h2>
- </footer>
-
- </div>
- </div>
-</body>
-</html>
diff --git a/apps/comments/js/vendor/At.js/specRunner.html b/apps/comments/js/vendor/At.js/specRunner.html
deleted file mode 100644
index d0a5e63e8b8..00000000000
--- a/apps/comments/js/vendor/At.js/specRunner.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
- <link rel="stylesheet" type="text/css" href="node_modules/gulp-jasmine-phantom/vendor/jasmine-2.0/jasmine.css" />
- <link rel="stylesheet" type="text/css" href="dist/css/jquery.atwho.css" />
- <script type="text/javascript" src="node_modules/gulp-jasmine-phantom/vendor/jasmine-2.0/jasmine.js"></script>
- <script type="text/javascript" src="node_modules/gulp-jasmine-phantom/vendor/jasmine-2.0/jasmine-html.js"></script>
- <script type="text/javascript" src="node_modules/gulp-jasmine-phantom/vendor/jasmine-2.0/console.js"></script>
- <script type="text/javascript" src="node_modules/gulp-jasmine-phantom/vendor/jasmine-2.0/boot.js"></script>
- <script type="text/javascript" src="bower_components/jquery/dist/jquery.js"></script>
- <script type="text/javascript" src="bower_components/Caret.js/dist/jquery.caret.js"></script>
- <script type="text/javascript" src="dist/js/jquery.atwho.js"></script>
- <script type="text/javascript" src="node_modules/jasmine-jquery/lib/jasmine-jquery.js"></script>
- <script type="text/javascript" src="node_modules/jasmine-ajax/lib/mock-ajax.js"></script>
- <script type="text/javascript" src="spec/helpers/noConflict.js"></script>
- <script type="text/javascript" src="spec/build/spec_helper.js"></script>
- <script type="text/javascript" src="spec/build/javascripts/apis.spec.js"></script>
- <script type="text/javascript" src="spec/build/javascripts/content_editable.spec.js"></script>
- <script type="text/javascript" src="spec/build/javascripts/custom_callbacks.spec.js"></script>
- <script type="text/javascript" src="spec/build/javascripts/default_callbacks.spec.js"></script>
- <script type="text/javascript" src="spec/build/javascripts/events.spec.js"></script>
- <script type="text/javascript" src="spec/build/javascripts/iframe.spec.js"></script>
- <script type="text/javascript" src="spec/build/javascripts/settings.spec.js"></script>
- <script type="text/javascript" src="spec/build/javascripts/view.spec.js"></script>
-
-<script type"text/javascript" src="node_modules/gulp-jasmine-phantom/lib/specRunner.js"></script>
-</head>
-<body>
-
-</body>
-</html>
diff --git a/apps/comments/js/vendor/At.js/src/api.coffee b/apps/comments/js/vendor/At.js/src/api.coffee
deleted file mode 100644
index 2e208d3e659..00000000000
--- a/apps/comments/js/vendor/At.js/src/api.coffee
+++ /dev/null
@@ -1,59 +0,0 @@
-Api =
- # load a flag's data
- #
- # @params at[String] the flag
- # @params data [Array] data to storage.
- load: (at, data) -> c.model.load data if c = this.controller(at)
- isSelecting: () -> !!this.controller()?.view.visible()
- hide: () -> this.controller()?.view.hide()
- reposition: () ->
- if c = this.controller()
- c.view.reposition(c.rect())
- setIframe: (iframe, asRoot) -> this.setupRootElement(iframe, asRoot); null;
- run: -> this.dispatch()
- destroy: ->
- this.shutdown()
- @$inputor.data('atwho', null)
-
-$.fn.atwho = (method) ->
- _args = arguments
- result = null
- this.filter('textarea, input, [contenteditable=""], [contenteditable=true]').each ->
- if not app = ($this = $ this).data "atwho"
- $this.data 'atwho', (app = new App this)
- if typeof method is 'object' || !method
- app.reg method.at, method
- else if Api[method] and app
- result = Api[method].apply app, Array::slice.call(_args, 1)
- else
- $.error "Method #{method} does not exist on jQuery.atwho"
- if result? then result else this
-
-$.fn.atwho.default =
- at: undefined
- alias: undefined
- data: null
- displayTpl: "<li>${name}</li>"
- insertTpl: "${atwho-at}${name}"
- headerTpl: null
- callbacks: DEFAULT_CALLBACKS
- functionOverrides: {}
- searchKey: "name"
- suffix: undefined
- hideWithoutSuffix: no
- startWithSpace: yes
- acceptSpaceBar: false
- highlightFirst: yes
- limit: 5
- maxLen: 20
- minLen: 0
- displayTimeout: 300
- delay: null
- spaceSelectsMatch: no
- tabSelectsMatch: yes
- editableAtwhoQueryAttrs: {}
- scrollDuration: 150
- suspendOnComposing: true
- lookUpOnClick: true
-
-$.fn.atwho.debug = false
diff --git a/apps/comments/js/vendor/At.js/src/app.coffee b/apps/comments/js/vendor/At.js/src/app.coffee
deleted file mode 100644
index fd601b51613..00000000000
--- a/apps/comments/js/vendor/At.js/src/app.coffee
+++ /dev/null
@@ -1,158 +0,0 @@
-# At.js central contoller(searching, matching, evaluating and rendering.)
-class App
-
- # @param inputor [HTML DOM Object] `input` or `textarea`
- constructor: (inputor) ->
- @currentFlag = null
- @controllers = {}
- @aliasMaps = {}
- @$inputor = $(inputor)
- this.setupRootElement()
- this.listen()
-
- createContainer: (doc) ->
- @$el?.remove()
- $ doc.body
- .append @$el = $ "<div class='atwho-container'></div>"
-
- setupRootElement: (iframe, asRoot=false) ->
- if iframe
- @window = iframe.contentWindow
- @document = iframe.contentDocument || @window.document
- @iframe = iframe
- else
- @document = @$inputor[0].ownerDocument
- @window = @document.defaultView || @document.parentWindow
- try
- @iframe = @window.frameElement
- catch error
- @iframe = null
- if $.fn.atwho.debug
- throw new Error """
- iframe auto-discovery is failed.
- Please use `setIframe` to set the target iframe manually.
- #{error}
- """
- this.createContainer if @iframeAsRoot = asRoot then @document else document
-
- controller: (at) ->
- if @aliasMaps[at]
- current = @controllers[@aliasMaps[at]]
- else
- for currentFlag, c of @controllers
- if currentFlag is at
- current = c
- break
-
- if current then current else @controllers[@currentFlag]
-
- setContextFor: (at) ->
- @currentFlag = at
- this
-
- # At.js can register multiple at char (flag) to every inputor such as "@" and ":"
- # Along with their own `settings` so that it works differently.
- # After register, we still can update their `settings` such as updating `data`
- #
- # @param flag [String] at char (flag)
- # @param settings [Hash] the settings
- reg: (flag, setting) ->
- controller = @controllers[flag] ||=
- if @$inputor.is '[contentEditable]'
- new EditableController this, flag
- else
- new TextareaController this, flag
- # TODO: it will produce rubbish alias map, reduse this.
- @aliasMaps[setting.alias] = flag if setting.alias
- controller.init setting
- this
-
- # binding jQuery events of `inputor`'s
- listen: ->
- @$inputor
- .on 'compositionstart', (e) =>
- this.controller()?.view.hide()
- @isComposing = true
- null
- .on 'compositionend', (e) =>
- @isComposing = false
- setTimeout((e) => @dispatch(e))
- null
- .on 'keyup.atwhoInner', (e) =>
- this.onKeyup(e)
- .on 'keydown.atwhoInner', (e) =>
- this.onKeydown(e)
- .on 'blur.atwhoInner', (e) =>
- if c = this.controller()
- c.expectedQueryCBId = null
- c.view.hide(e,c.getOpt("displayTimeout"))
- .on 'click.atwhoInner', (e) =>
- this.dispatch e
- .on 'scroll.atwhoInner', do =>
- # make returned handler handle the very first call properly
- lastScrollTop = @$inputor.scrollTop()
- (e) =>
- currentScrollTop = e.target.scrollTop
- if lastScrollTop != currentScrollTop
- @controller()?.view.hide(e)
- lastScrollTop = currentScrollTop
- true # ensure we don't stop bubbling
-
- shutdown: ->
- for _, c of @controllers
- c.destroy()
- delete @controllers[_]
- @$inputor.off '.atwhoInner'
- @$el.remove()
-
- dispatch: (e) ->
- c.lookUp(e) for _, c of @controllers
-
- onKeyup: (e) ->
- switch e.keyCode
- when KEY_CODE.ESC
- e.preventDefault()
- this.controller()?.view.hide()
- when KEY_CODE.DOWN, KEY_CODE.UP, KEY_CODE.CTRL, KEY_CODE.ENTER
- $.noop()
- when KEY_CODE.P, KEY_CODE.N
- this.dispatch e if not e.ctrlKey
- else
- this.dispatch e
- # coffeescript will return everywhere!!
- return
-
- onKeydown: (e) ->
- # return if not (view = this.controller().view).visible()
- view = this.controller()?.view
- return if not (view and view.visible())
- switch e.keyCode
- when KEY_CODE.ESC
- e.preventDefault()
- view.hide(e)
- when KEY_CODE.UP
- e.preventDefault()
- view.prev()
- when KEY_CODE.DOWN
- e.preventDefault()
- view.next()
- when KEY_CODE.P
- return if not e.ctrlKey
- e.preventDefault()
- view.prev()
- when KEY_CODE.N
- return if not e.ctrlKey
- e.preventDefault()
- view.next()
- when KEY_CODE.TAB, KEY_CODE.ENTER, KEY_CODE.SPACE
- return if not view.visible()
- return if not this.controller().getOpt('spaceSelectsMatch') and e.keyCode == KEY_CODE.SPACE
- return if not this.controller().getOpt('tabSelectsMatch') and e.keyCode == KEY_CODE.TAB
- if view.highlighted()
- e.preventDefault()
- view.choose(e)
- else
- view.hide(e)
- else
- $.noop()
- return
diff --git a/apps/comments/js/vendor/At.js/src/controller.coffee b/apps/comments/js/vendor/At.js/src/controller.coffee
deleted file mode 100644
index 22e263b002d..00000000000
--- a/apps/comments/js/vendor/At.js/src/controller.coffee
+++ /dev/null
@@ -1,142 +0,0 @@
-class Controller
- uid: ->
- (Math.random().toString(16)+"000000000").substr(2,8) + (new Date().getTime())
-
- constructor: (@app, @at) ->
- @$inputor = @app.$inputor
- @id = @$inputor[0].id || this.uid()
- @expectedQueryCBId = null
-
- @setting = null
- @query = null
- @pos = 0
- @range = null
- if (@$el = $("#atwho-ground-#{@id}", @app.$el)).length == 0
- @app.$el.append @$el = $("<div id='atwho-ground-#{@id}'></div>")
-
- @model = new Model(this)
- @view = new View(this)
-
- init: (setting) ->
- @setting = $.extend {}, @setting || $.fn.atwho.default, setting
- @view.init()
- @model.reload @setting.data
-
- destroy: ->
- this.trigger 'beforeDestroy'
- @model.destroy()
- @view.destroy()
- @$el.remove()
-
- callDefault: (funcName, args...) ->
- try
- DEFAULT_CALLBACKS[funcName].apply this, args
- catch error
- $.error "#{error} Or maybe At.js doesn't have function #{funcName}"
-
- # Delegate custom `jQueryEvent` to the inputor
- # This function will add `atwho` as namespace to every jQuery event
- # and pass current context as the last param to it.
- #
- # @example
- # this.trigger "roll_n_rock", [1,2,3,4]
- #
- # $inputor.on "rool_n_rock", (e, one, two, three, four) ->
- # console.log one, two, three, four
- #
- # @param name [String] Event name
- # @param data [Array] data to callback
- trigger: (name, data=[]) ->
- data.push this
- alias = this.getOpt('alias')
- eventName = if alias then "#{name}-#{alias}.atwho" else "#{name}.atwho"
- @$inputor.trigger eventName, data
-
- # Get callback either in settings which was set by plugin user or in default callbacks list.
- #
- # @param funcName [String] callback's name
- # @return [Function] The callback.
- callbacks: (funcName)->
- this.getOpt("callbacks")[funcName] || DEFAULT_CALLBACKS[funcName]
-
- # Because different registered at chars have different settings.
- # so we should give their own for them.
- #
- # @param at [String] setting's at name
- # @param default_value [?] return this if nothing is returned from current settings.
- # @return [?] setting's value
- getOpt: (at, default_value) ->
- try
- @setting[at]
- catch e
- null
-
- insertContentFor: ($li) ->
- tpl = this.getOpt('insertTpl')
- data = $.extend {}, $li.data('item-data'), {'atwho-at': @at}
- this.callbacks("tplEval").call(this, tpl, data, "onInsert")
-
- # Render list view
- #
- # @param data [Array] The data
- renderView: (data) ->
- searchKey = this.getOpt("searchKey")
- data = this.callbacks("sorter").call(this, @query.text, data[0..1000] , searchKey)
- @view.render data[0...this.getOpt('limit')]
-
- @arrayToDefaultHash: (data) ->
- return data if not $.isArray data
- for item in data
- if $.isPlainObject item then item else name:item
-
- # Searching!
- lookUp: (e) ->
- return if e && e.type == 'click' && !@getOpt('lookUpOnClick')
- return if @getOpt('suspendOnComposing') and @app.isComposing
- query = @catchQuery e
- if not query
- @expectedQueryCBId = null
- return query
- @app.setContextFor @at
- if wait = this.getOpt('delay')
- @_delayLookUp query, wait
- else
- @_lookUp query
- query
-
- _delayLookUp: (query, wait) ->
- now = if Date.now then Date.now() else new Date().getTime()
- @previousCallTime ||= now
- remaining = wait - (now - @previousCallTime)
- if 0 < remaining < wait
- @previousCallTime = now
- @_stopDelayedCall()
- @delayedCallTimeout = setTimeout(=>
- @previousCallTime = 0
- @delayedCallTimeout = null
- @_lookUp query
- , wait)
- else
- @_stopDelayedCall()
- @previousCallTime = 0 if @previousCallTime isnt now
- @_lookUp query
-
- _stopDelayedCall: ->
- if @delayedCallTimeout
- clearTimeout @delayedCallTimeout
- @delayedCallTimeout = null
-
- _generateQueryCBId: ->
- return {};
-
- _lookUp: (query) ->
- _callback = (queryCBId, data) ->
- # ensure only the latest instance of this function perform actions
- if queryCBId isnt @expectedQueryCBId
- return
- if data and data.length > 0
- this.renderView @constructor.arrayToDefaultHash data
- else
- @view.hide()
- @expectedQueryCBId = @_generateQueryCBId()
- @model.query query.text, $.proxy(_callback, this, @expectedQueryCBId)
diff --git a/apps/comments/js/vendor/At.js/src/default.coffee b/apps/comments/js/vendor/At.js/src/default.coffee
deleted file mode 100644
index f8c64a9fe18..00000000000
--- a/apps/comments/js/vendor/At.js/src/default.coffee
+++ /dev/null
@@ -1,147 +0,0 @@
-KEY_CODE =
- ESC: 27
- TAB: 9
- ENTER: 13
- CTRL: 17
- A: 65
- P: 80
- N: 78
- LEFT: 37
- UP:38
- RIGHT: 39
- DOWN: 40
- BACKSPACE: 8
- SPACE: 32
-
-# Functions set for handling and rendering the data.
-# Others developers can override these methods to tweak At.js such as matcher.
-# We can override them in `callbacks` settings.
-#
-# @mixin
-#
-# The context of these functions is `$.atwho.Controller` object and they are called in this sequences:
-#
-# [beforeSave, matcher, filter, remoteFilter, sorter, tplEvl, highlighter, beforeInsert, afterMatchFailed]
-#
-DEFAULT_CALLBACKS =
-
- # It would be called to restructure the data before At.js invokes `Model#save` to save data
- # By default, At.js will convert it to a Hash Array.
- #
- # @param data [Array] data to refacotor.
- # @return [Array] Data after refactor.
- beforeSave: (data) ->
- Controller.arrayToDefaultHash data
-
- # It would be called to match the `flag`.
- # It will match at start of line or after whitespace
- #
- # @param flag [String] current `flag` ("@", etc)
- # @param subtext [String] Text from start to current caret position.
- # @param should_startWithSpace [boolean] accept white space as beginning of match.
- # @param acceptSpaceBar [boolean] accept a space bar in the center of match,
- # so you can match a first and last name, for ex.
- #
- # @return [String | null] Matched result.
- matcher: (flag, subtext, should_startWithSpace, acceptSpaceBar) ->
- # escape RegExp
- flag = flag.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&")
- flag = '(?:^|\\s)' + flag if should_startWithSpace
-
- # À
- _a = decodeURI("%C3%80")
- # ÿ
- _y = decodeURI("%C3%BF")
- space = if acceptSpaceBar then "\ " else ""
- regexp = new RegExp "#{flag}([A-Za-z#{_a}-#{_y}0-9_#{space}\'\.\+\-]*)$|#{flag}([^\\x00-\\xff]*)$",'gi'
- match = regexp.exec subtext
- if match then match[2] || match[1] else null
-
- # ---------------------
-
- # Filter data by matched string.
- #
- # @param query [String] Matched string.
- # @param data [Array] data list
- # @param searchKey [String] at char for searching.
- #
- # @return [Array] result data.
- filter: (query, data, searchKey) ->
- # !!null #=> false; !!undefined #=> false; !!'' #=> false;
- _results = []
- for item in data
- _results.push item if ~new String(item[searchKey]).toLowerCase().indexOf query.toLowerCase()
- _results
-
- # If a function is given, At.js will invoke it if local filter can not find any data
- #
- # @param params [String] matched query
- # @param callback [Function] callback to render page.
- remoteFilter: null
- # remoteFilter: (query, callback) ->
- # $.ajax url,
- # data: params
- # success: (data) ->
- # callback(data)
-
- # Sorter data of course.
- #
- # @param query [String] matched string
- # @param items [Array] data that was refactored
- # @param searchKey [String] at char to search
- #
- # @return [Array] sorted data
- sorter: (query, items, searchKey) ->
- return items unless query
-
- _results = []
- for item in items
- item.atwho_order = new String(item[searchKey]).toLowerCase().indexOf query.toLowerCase()
- _results.push item if item.atwho_order > -1
-
- _results.sort (a,b) -> a.atwho_order - b.atwho_order
-
- # Evaluate the template either as a string or as a function
- # this allows someone to pass in a set of data that needs a
- # different template for different data results
- #
- # @param tpl [function] the template function or string
- # @param map [Hash] Data map to eval.
- tplEval: (tpl, map) ->
- template = tpl
- try
- template = tpl(map) unless typeof tpl == 'string'
- template.replace /\$\{([^\}]*)\}/g, (tag, key, pos) -> map[key]
- catch error
- ""
-
-
- # Highlight the `matched query` string.
- #
- # @param li [String] HTML String after eval.
- # @param query [String] matched query.
- #
- # @return [String] highlighted string.
- highlighter: (li, query) ->
- return li if not query
- regexp = new RegExp(">\\s*([^\<]*?)(" + query.replace("+","\\+") + ")([^\<]*)\\s*<", 'ig')
- li.replace regexp, (str, $1, $2, $3) -> '> '+$1+'<strong>' + $2 + '</strong>'+$3+' <'
-
- # What to do before inserting item's value into inputor.
- #
- # @param value [String] content to insert
- # @param $li [jQuery Object] the chosen item
- # @param e [event Object] from the user selection (keyDown or click)
- beforeInsert: (value, $li, e) ->
- value
-
- # You can adjust the menu's offset here.
- #
- # @param offset [Hash] offset will be applied to menu
- # beforeReposition: (offset) ->
- # offset.left += 10
- # offset.top += 10
- # offset
- beforeReposition: (offset) -> offset
-
- afterMatchFailed: (at, el) ->
diff --git a/apps/comments/js/vendor/At.js/src/editableController.coffee b/apps/comments/js/vendor/At.js/src/editableController.coffee
deleted file mode 100644
index d6fcaeb7995..00000000000
--- a/apps/comments/js/vendor/At.js/src/editableController.coffee
+++ /dev/null
@@ -1,174 +0,0 @@
-class EditableController extends Controller
-
- _getRange: ->
- sel = @app.window.getSelection()
- sel.getRangeAt(0) if sel.rangeCount > 0
-
- _setRange: (position, node, range=@_getRange()) ->
- return unless range and node
- node = $(node)[0]
- if position == 'after'
- range.setEndAfter node
- range.setStartAfter node
- else
- range.setEndBefore node
- range.setStartBefore node
- range.collapse false
- @_clearRange range
-
- _clearRange: (range=@_getRange()) ->
- sel = @app.window.getSelection()
- #ctrl+a remove defaults using the flag
- if !@ctrl_a_pressed?
- sel.removeAllRanges()
- sel.addRange range
-
- _movingEvent: (e) ->
- e.type == 'click' or e.which in [KEY_CODE.RIGHT, KEY_CODE.LEFT, KEY_CODE.UP, KEY_CODE.DOWN]
-
- _unwrap: (node) ->
- node = $(node).unwrap().get 0
- if (next = node.nextSibling) and next.nodeValue
- node.nodeValue += next.nodeValue
- $(next).remove()
- node
-
- catchQuery: (e) ->
- return unless range = @_getRange()
- return unless range.collapsed
-
- if e.which == KEY_CODE.ENTER
- ($query = $(range.startContainer).closest '.atwho-query')
- .contents().unwrap()
- $query.remove() if $query.is ':empty'
- ($query = $ ".atwho-query", @app.document)
- .text $query.text()
- .contents().last().unwrap()
- @_clearRange()
- return
-
- # absorb range
- # The range at the end of an element is not inside in firefox but not others browsers including IE.
- # To normolize them, we have to move the range inside the element while deleting content or moving caret right after .atwho-inserted
- if /firefox/i.test(navigator.userAgent)
- if $(range.startContainer).is @$inputor
- @_clearRange()
- return
- if e.which == KEY_CODE.BACKSPACE and range.startContainer.nodeType == document.ELEMENT_NODE \
- and (offset = range.startOffset - 1) >= 0
- _range = range.cloneRange()
- _range.setStart range.startContainer, offset
- if $(_range.cloneContents()).contents().last().is '.atwho-inserted'
- inserted = $(range.startContainer).contents().get(offset)
- @_setRange 'after', $(inserted).contents().last()
- else if e.which == KEY_CODE.LEFT and range.startContainer.nodeType == document.TEXT_NODE
- $inserted = $ range.startContainer.previousSibling
- if $inserted.is('.atwho-inserted') and range.startOffset == 0
- @_setRange 'after', $inserted.contents().last()
-
- # modifying inserted element
- $(range.startContainer)
- .closest '.atwho-inserted'
- .addClass 'atwho-query'
- .siblings().removeClass 'atwho-query'
-
- if ($query = $ ".atwho-query", @app.document).length > 0 \
- and $query.is(':empty') and $query.text().length == 0
- $query.remove()
-
- if not @_movingEvent e
- $query.removeClass 'atwho-inserted'
-
- if $query.length > 0
- switch e.which
- when KEY_CODE.LEFT
- @_setRange 'before', $query.get(0), range
- $query.removeClass 'atwho-query'
- return
- when KEY_CODE.RIGHT
- @_setRange 'after', $query.get(0).nextSibling, range
- $query.removeClass 'atwho-query'
- return
-
- # matching
- if $query.length > 0 and query_content = $query.attr('data-atwho-at-query')
- $query.empty().html(query_content).attr('data-atwho-at-query', null)
- @_setRange 'after', $query.get(0), range
- _range = range.cloneRange()
- _range.setStart range.startContainer, 0
- matched = @callbacks("matcher").call(this, @at, _range.toString(), @getOpt('startWithSpace'), @getOpt("acceptSpaceBar"))
- isString = typeof matched is 'string'
-
- # wrapping query with .atwho-query
- if $query.length == 0 and isString \
- and (index = range.startOffset - @at.length - matched.length) >= 0
- range.setStart range.startContainer, index
- $query = $ '<span/>', @app.document
- .attr @getOpt "editableAtwhoQueryAttrs"
- .addClass 'atwho-query'
- range.surroundContents $query.get 0
- lastNode = $query.contents().last().get(0)
- if lastNode
- if /firefox/i.test navigator.userAgent
- range.setStart lastNode, lastNode.length
- range.setEnd lastNode, lastNode.length
- @_clearRange range
- else
- @_setRange 'after', lastNode, range
-
- return if isString and matched.length < @getOpt('minLen', 0)
-
- # handle the matched result
- if isString and matched.length <= @getOpt('maxLen', 20)
- query = text: matched, el: $query
- @trigger "matched", [@at, query.text]
- @query = query
- else
- @view.hide()
- @query = el: $query
- if $query.text().indexOf(this.at) >= 0
- if @_movingEvent(e) and $query.hasClass 'atwho-inserted'
- $query.removeClass('atwho-query')
- else if false != @callbacks('afterMatchFailed').call this, @at, $query
- @_setRange "after", @_unwrap $query.text($query.text()).contents().first()
- null
-
- # Get offset of current at char(`flag`)
- #
- # @return [Hash] the offset which look likes this: {top: y, left: x, bottom: bottom}
- rect: ->
- rect = @query.el.offset()
- # do not use {top: 0, left: 0} from jQuery when element is hidden
- # happens every other time the menu is displayed on click in contenteditable
- return unless rect and @query.el[0].getClientRects().length
- if @app.iframe and not @app.iframeAsRoot
- iframeOffset = ($iframe = $ @app.iframe).offset()
- rect.left += iframeOffset.left - @$inputor.scrollLeft()
- rect.top += iframeOffset.top - @$inputor.scrollTop()
- rect.bottom = rect.top + @query.el.height()
- rect
-
- # Insert value of `data-value` attribute of chosen item into inputor
- #
- # @param content [String] string to insert
- insert: (content, $li) ->
- @$inputor.focus() unless @$inputor.is ':focus'
- overrides = @getOpt 'functionOverrides'
- if overrides.insert
- return overrides.insert.call this, content, $li
- suffix = if (suffix = @getOpt 'suffix') == "" then suffix else suffix or "\u00A0"
- data = $li.data('item-data')
- @query.el
- .removeClass 'atwho-query'
- .addClass 'atwho-inserted'
- .html content
- .attr 'data-atwho-at-query', "" + data['atwho-at'] + @query.text
- .attr 'contenteditable', "false"
- if range = @_getRange()
- if @query.el.length
- range.setEndAfter @query.el[0]
- range.collapse false
- range.insertNode suffixNode = @app.document.createTextNode "" + suffix
- @_setRange 'after', suffixNode, range
- @$inputor.focus() unless @$inputor.is ':focus'
- @$inputor.change()
diff --git a/apps/comments/js/vendor/At.js/src/jquery.atwho.css b/apps/comments/js/vendor/At.js/src/jquery.atwho.css
deleted file mode 100644
index dad94ed9641..00000000000
--- a/apps/comments/js/vendor/At.js/src/jquery.atwho.css
+++ /dev/null
@@ -1,72 +0,0 @@
-.atwho-view {
- position:absolute;
- top: 0;
- left: 0;
- display: none;
- margin-top: 18px;
- background: white;
- color: black;
- border: 1px solid #DDD;
- border-radius: 3px;
- box-shadow: 0 0 5px rgba(0,0,0,0.1);
- min-width: 120px;
- z-index: 11110 !important;
-}
-
-.atwho-view .atwho-header {
- padding: 5px;
- margin: 5px;
- cursor: pointer;
- border-bottom: solid 1px #eaeff1;
- color: #6f8092;
- font-size: 11px;
- font-weight: bold;
-}
-
-.atwho-view .atwho-header .small {
- color: #6f8092;
- float: right;
- padding-top: 2px;
- margin-right: -5px;
- font-size: 12px;
- font-weight: normal;
-}
-
-.atwho-view .atwho-header:hover {
- cursor: default;
-}
-
-.atwho-view .cur {
- background: #3366FF;
- color: white;
-}
-.atwho-view .cur small {
- color: white;
-}
-.atwho-view strong {
- color: #3366FF;
-}
-.atwho-view .cur strong {
- color: white;
- font:bold;
-}
-.atwho-view ul {
- /* width: 100px; */
- list-style:none;
- padding:0;
- margin:auto;
- max-height: 200px;
- overflow-y: auto;
-}
-.atwho-view ul li {
- display: block;
- padding: 5px 10px;
- border-bottom: 1px solid #DDD;
- cursor: pointer;
- /* border-top: 1px solid #C8C8C8; */
-}
-.atwho-view small {
- font-size: smaller;
- color: #777;
- font-weight: normal;
-}
diff --git a/apps/comments/js/vendor/At.js/src/model.coffee b/apps/comments/js/vendor/At.js/src/model.coffee
deleted file mode 100644
index 7d09fa7943f..00000000000
--- a/apps/comments/js/vendor/At.js/src/model.coffee
+++ /dev/null
@@ -1,59 +0,0 @@
-# Class to process data
-class Model
-
- constructor: (@context) ->
- @at = @context.at
- # NOTE: bind data storage to inputor maybe App class can handle it.
- @storage = @context.$inputor
-
- destroy: ->
- @storage.data(@at, null)
-
- saved: ->
- this.fetch() > 0
-
- # fetch data from storage by query.
- # will invoke `callback` to return data
- #
- # @param query [String] catched string for searching
- # @param callback [Function] for receiving data
- query: (query, callback) ->
- data = this.fetch()
- searchKey = @context.getOpt("searchKey")
- data = @context.callbacks('filter').call(@context, query, data, searchKey) || []
- _remoteFilter = @context.callbacks('remoteFilter')
- if data.length > 0 or (!_remoteFilter and data.length == 0)
- callback data
- else
- _remoteFilter.call(@context, query, callback)
-
- # get or set current data which would be shown on the list view.
- #
- # @param data [Array] set data
- # @return [Array|undefined] current data that are showing on the list view.
- fetch: ->
- @storage.data(@at) || []
-
- # save special flag's data to storage
- #
- # @param data [Array] data to save
- save: (data) ->
- @storage.data @at, @context.callbacks("beforeSave").call(@context, data || [])
-
- # load data. It wouldn't load for a second time if it has been loaded.
- #
- # @param data [Array] data to load
- load: (data) ->
- this._load(data) unless this.saved() or not data
-
- reload: (data) ->
- this._load(data)
-
- # load data from local or remote with callback
- #
- # @param data [Array|String] data to load.
- _load: (data) ->
- if typeof data is "string"
- $.ajax(data, dataType: "json").done (data) => this.save(data)
- else
- this.save data
diff --git a/apps/comments/js/vendor/At.js/src/textareaController.coffee b/apps/comments/js/vendor/At.js/src/textareaController.coffee
deleted file mode 100644
index 95f94bf8dcc..00000000000
--- a/apps/comments/js/vendor/At.js/src/textareaController.coffee
+++ /dev/null
@@ -1,51 +0,0 @@
-class TextareaController extends Controller
- # Catch query string behind the at char
- #
- # @return [Hash] Info of the query. Look likes this: {'text': "hello", 'headPos': 0, 'endPos': 0}
- catchQuery: ->
- content = @$inputor.val()
- caretPos = @$inputor.caret('pos', {iframe: @app.iframe})
- subtext = content.slice(0, caretPos)
- query = this.callbacks("matcher").call(this, @at, subtext, this.getOpt('startWithSpace'), @getOpt("acceptSpaceBar"))
- isString = typeof query is 'string'
-
- return if isString and query.length < this.getOpt('minLen', 0)
-
- if isString and query.length <= this.getOpt('maxLen', 20)
- start = caretPos - query.length
- end = start + query.length
- @pos = start
- query = {'text': query, 'headPos': start, 'endPos': end}
- this.trigger "matched", [@at, query.text]
- else
- query = null
- @view.hide()
-
- @query = query
-
- # Get offset of current at char(`flag`)
- #
- # @return [Hash] the offset which look likes this: {top: y, left: x, bottom: bottom}
- rect: ->
- return if not c = @$inputor.caret('offset', @pos - 1, {iframe: @app.iframe})
- if @app.iframe and not @app.iframeAsRoot
- iframeOffset = $(@app.iframe).offset()
- c.left += iframeOffset.left
- c.top += iframeOffset.top
- scaleBottom = if @app.document.selection then 0 else 2
- {left: c.left, top: c.top, bottom: c.top + c.height + scaleBottom}
-
- # Insert value of `data-value` attribute of chosen item into inputor
- #
- # @param content [String] string to insert
- insert: (content, $li) ->
- $inputor = @$inputor
- source = $inputor.val()
- startStr = source.slice 0, Math.max(@query.headPos - @at.length, 0)
- suffix = if (suffix = @getOpt 'suffix') == "" then suffix else suffix or " "
- content += suffix
- text = "#{startStr}#{content}#{source.slice @query['endPos'] || 0}"
- $inputor.val text
- $inputor.caret('pos', startStr.length + content.length, {iframe: @app.iframe})
- $inputor.focus() unless $inputor.is ':focus'
- $inputor.change()
diff --git a/apps/comments/js/vendor/At.js/src/view.coffee b/apps/comments/js/vendor/At.js/src/view.coffee
deleted file mode 100644
index 08785d73736..00000000000
--- a/apps/comments/js/vendor/At.js/src/view.coffee
+++ /dev/null
@@ -1,136 +0,0 @@
-# View class to control how At.js's view showing.
-# All classes share the same DOM view.
-class View
-
- # @param controller [Object] The Controller.
- constructor: (@context) ->
- @$el = $("<div class='atwho-view'><ul class='atwho-view-ul'></ul></div>")
- @$elUl = @$el.children();
- @timeoutID = null
- # create HTML DOM of list view if it does not exist
- @context.$el.append(@$el)
- this.bindEvent()
-
- init: ->
- id = @context.getOpt("alias") || @context.at.charCodeAt(0)
- header_tpl = this.context.getOpt("headerTpl")
- if (header_tpl && this.$el.children().length == 1)
- this.$el.prepend(header_tpl)
- @$el.attr('id': "at-view-#{id}")
-
- destroy: ->
- @$el.remove()
-
- bindEvent: ->
- $menu = @$el.find('ul')
- lastCoordX = 0
- lastCoordY = 0
- $menu.on 'mousemove.atwho-view','li', (e) =>
- # If the mouse hasn't actually moved then exit.
- return if lastCoordX == e.clientX and lastCoordY == e.clientY
- lastCoordX = e.clientX
- lastCoordY = e.clientY
- $cur = $(e.currentTarget)
- return if $cur.hasClass('cur')
- $menu.find('.cur').removeClass 'cur'
- $cur.addClass 'cur'
- .on 'click.atwho-view', 'li', (e) =>
- $menu.find('.cur').removeClass 'cur'
- $(e.currentTarget).addClass 'cur'
- this.choose(e)
- e.preventDefault()
-
- # Check if view is visible
- #
- # @return [Boolean]
- visible: ->
- $.expr.filters.visible(@$el[0])
-
- highlighted: ->
- @$el.find(".cur").length > 0
-
- choose: (e) ->
- if ($li = @$el.find ".cur").length
- content = @context.insertContentFor $li
-
- @context._stopDelayedCall()
- @context.insert @context.callbacks("beforeInsert").call(@context, content, $li, e), $li
- @context.trigger "inserted", [$li, e]
- this.hide(e)
- @stopShowing = yes if @context.getOpt("hideWithoutSuffix")
-
- reposition: (rect) ->
- _window = if @context.app.iframeAsRoot then @context.app.window else window
- if rect.bottom + @$el.height() - $(_window).scrollTop() > $(_window).height()
- rect.bottom = rect.top - @$el.height()
- if rect.left > overflowOffset = $(_window).width() - @$el.width() - 5
- rect.left = overflowOffset
- offset = {left:rect.left, top:rect.bottom}
- @context.callbacks("beforeReposition")?.call(@context, offset)
- @$el.offset offset
- @context.trigger "reposition", [offset]
-
- next: ->
- cur = @$el.find('.cur').removeClass('cur')
- next = cur.next()
- next = @$el.find('li:first') if not next.length
- next.addClass 'cur'
- nextEl = next[0]
- offset = nextEl.offsetTop + nextEl.offsetHeight + (if nextEl.nextSibling then nextEl.nextSibling.offsetHeight else 0)
- @scrollTop Math.max(0, offset - this.$el.height())
-
- prev: ->
- cur = @$el.find('.cur').removeClass('cur')
- prev = cur.prev()
- prev = @$el.find('li:last') if not prev.length
- prev.addClass 'cur'
- prevEl = prev[0]
- offset = prevEl.offsetTop + prevEl.offsetHeight + (if prevEl.nextSibling then prevEl.nextSibling.offsetHeight else 0)
- @scrollTop Math.max(0, offset - this.$el.height())
-
- scrollTop: (scrollTop) ->
- scrollDuration = @context.getOpt('scrollDuration')
- if scrollDuration
- @$elUl.animate {scrollTop: scrollTop}, scrollDuration
- else
- @$elUl.scrollTop(scrollTop)
-
- show: ->
- if @stopShowing
- @stopShowing = false
- return
- if not this.visible()
- @$el.show()
- @$el.scrollTop 0
- @context.trigger 'shown'
- this.reposition(rect) if rect = @context.rect()
-
- hide: (e, time) ->
- return if not this.visible()
- if isNaN(time)
- @$el.hide()
- @context.trigger 'hidden', [e]
- else
- callback = => this.hide()
- clearTimeout @timeoutID
- @timeoutID = setTimeout callback, time
-
- # render list view
- render: (list) ->
- if not ($.isArray(list) and list.length > 0)
- this.hide()
- return
-
- @$el.find('ul').empty()
- $ul = @$el.find('ul')
- tpl = @context.getOpt('displayTpl')
-
- for item in list
- item = $.extend {}, item, {'atwho-at': @context.at}
- li = @context.callbacks("tplEval").call(@context, tpl, item, "onDisplay")
- $li = $ @context.callbacks("highlighter").call(@context, li, @context.query.text)
- $li.data("item-data", item)
- $ul.append $li
-
- this.show()
- $ul.find("li:first").addClass "cur" if @context.getOpt('highlightFirst')
diff --git a/apps/comments/js/vendor/At.js/umd.template.js b/apps/comments/js/vendor/At.js/umd.template.js
deleted file mode 100644
index 9df3d0b5d65..00000000000
--- a/apps/comments/js/vendor/At.js/umd.template.js
+++ /dev/null
@@ -1,17 +0,0 @@
-(function (root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module unless amdModuleId is set
- define(["jquery"], function (a0) {
- return (factory(a0));
- });
- } else if (typeof exports === 'object') {
- // Node. Does not work with strict CommonJS, but
- // only CommonJS-like environments that support module.exports,
- // like Node.
- module.exports = factory(require("jquery"));
- } else {
- factory(jQuery);
- }
-}(this, function ($) {
-<%= contents %>
-}));