Improved/fixed use of text modules.
This commit is contained in:
parent
f672a93001
commit
bb1c476db1
1 changed files with 87 additions and 60 deletions
|
@ -22,8 +22,8 @@
|
||||||
this._name = pluginName
|
this._name = pluginName
|
||||||
|
|
||||||
this.collection = []
|
this.collection = []
|
||||||
this.active = false
|
this.active = false
|
||||||
this.buffer = ''
|
this.buffer = ''
|
||||||
|
|
||||||
// check if ce exists
|
// check if ce exists
|
||||||
if ( $.data(element, 'plugin_ce') ) {
|
if ( $.data(element, 'plugin_ce') ) {
|
||||||
|
@ -52,18 +52,22 @@
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
var id = _this.$widget.find('.dropdown-menu li.active a').data('id')
|
var id = _this.$widget.find('.dropdown-menu li.active a').data('id')
|
||||||
_this.take(id)
|
_this.take(id)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// arrow keys
|
// arrow keys left/right
|
||||||
if ( e.keyCode === 37 || e.keyCode === 38 || e.keyCode === 39 || e.keyCode === 40 ) {
|
if ( e.keyCode === 37 || e.keyCode === 39 ) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// up
|
// up
|
||||||
if ( e.keyCode === 38 ) {
|
if ( e.keyCode === 38 ) {
|
||||||
|
e.preventDefault()
|
||||||
if ( !_this.$widget.find('.dropdown-menu li.active')[0] ) {
|
if ( !_this.$widget.find('.dropdown-menu li.active')[0] ) {
|
||||||
var top = _this.$widget.find('.dropdown-menu li').last().addClass('active').position().top
|
var top = _this.$widget.find('.dropdown-menu li').last().addClass('active').position().top
|
||||||
_this.$widget.find('.dropdown-menu').scrollTop( top );
|
_this.$widget.find('.dropdown-menu').scrollTop( top );
|
||||||
|
return
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var prev = _this.$widget.find('.dropdown-menu li.active').removeClass('active').prev()
|
var prev = _this.$widget.find('.dropdown-menu li.active').removeClass('active').prev()
|
||||||
|
@ -72,15 +76,17 @@
|
||||||
top = prev.addClass('active').position().top
|
top = prev.addClass('active').position().top
|
||||||
}
|
}
|
||||||
_this.$widget.find('.dropdown-menu').scrollTop( top );
|
_this.$widget.find('.dropdown-menu').scrollTop( top );
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// down
|
// down
|
||||||
if ( e.keyCode === 40 ) {
|
if ( e.keyCode === 40 ) {
|
||||||
|
e.preventDefault()
|
||||||
if ( !_this.$widget.find('.dropdown-menu li.active')[0] ) {
|
if ( !_this.$widget.find('.dropdown-menu li.active')[0] ) {
|
||||||
var top = _this.$widget.find('.dropdown-menu li').first().addClass('active').position().top
|
var top = _this.$widget.find('.dropdown-menu li').first().addClass('active').position().top
|
||||||
_this.$widget.find('.dropdown-menu').scrollTop( top );
|
_this.$widget.find('.dropdown-menu').scrollTop( top );
|
||||||
|
return
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
var next = _this.$widget.find('.dropdown-menu li.active').removeClass('active').next()
|
var next = _this.$widget.find('.dropdown-menu li.active').removeClass('active').next()
|
||||||
|
@ -89,6 +95,7 @@
|
||||||
top = next.addClass('active').position().top
|
top = next.addClass('active').position().top
|
||||||
}
|
}
|
||||||
_this.$widget.find('.dropdown-menu').scrollTop( top );
|
_this.$widget.find('.dropdown-menu').scrollTop( top );
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,9 +107,15 @@
|
||||||
|
|
||||||
// backspace
|
// backspace
|
||||||
if ( e.keyCode === 8 && _this.buffer ) {
|
if ( e.keyCode === 8 && _this.buffer ) {
|
||||||
|
|
||||||
|
// backspace + buffer === :: -> close textmodule
|
||||||
if ( _this.buffer === '::' ) {
|
if ( _this.buffer === '::' ) {
|
||||||
_this.close()
|
_this.close()
|
||||||
|
e.preventDefault()
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reduce buffer and show new result
|
||||||
var length = _this.buffer.length
|
var length = _this.buffer.length
|
||||||
_this.buffer = _this.buffer.substr( 0, length-1 )
|
_this.buffer = _this.buffer.substr( 0, length-1 )
|
||||||
console.log('BS backspace', _this.buffer)
|
console.log('BS backspace', _this.buffer)
|
||||||
|
@ -115,22 +128,26 @@
|
||||||
console.log('BUFF', _this.buffer, e.keyCode, String.fromCharCode(e.which) )
|
console.log('BUFF', _this.buffer, e.keyCode, String.fromCharCode(e.which) )
|
||||||
|
|
||||||
// shift
|
// shift
|
||||||
if ( e.keyCode === 16 ) {
|
if ( e.keyCode === 16 ) return
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// enter
|
// enter
|
||||||
if ( e.keyCode === 13 ) {
|
if ( e.keyCode === 13 ) return
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// arrow keys
|
// arrow keys
|
||||||
if ( e.keyCode === 37 || e.keyCode === 38 || e.keyCode === 39 || e.keyCode === 40 ) {
|
if ( e.keyCode === 37 || e.keyCode === 38 || e.keyCode === 39 || e.keyCode === 40 ) return
|
||||||
return
|
|
||||||
|
// observer other second key
|
||||||
|
if ( _this.buffer === ':' && String.fromCharCode(e.which) !== ':' ) {
|
||||||
|
_this.buffer = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// enter :
|
// oberserve second :
|
||||||
if ( String.fromCharCode(e.which) === ':' ) {
|
if ( _this.buffer === ':' && String.fromCharCode(e.which) === ':' ) {
|
||||||
|
_this.buffer = _this.buffer + ':'
|
||||||
|
}
|
||||||
|
|
||||||
|
// oberserve first :
|
||||||
|
if ( !_this.buffer && String.fromCharCode(e.which) === ':' ) {
|
||||||
_this.buffer = _this.buffer + ':'
|
_this.buffer = _this.buffer + ':'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,57 +189,37 @@
|
||||||
this.$widget = this.$element.next()
|
this.$widget = this.$element.next()
|
||||||
}
|
}
|
||||||
|
|
||||||
// update widget position
|
// set height of widget
|
||||||
|
Plugin.prototype.movePosition = function() {
|
||||||
|
var height = this.$element.height() + 20
|
||||||
|
var widgetHeight = this.$widget.find('ul').height() //+ 60 // + height
|
||||||
|
var top = -( widgetHeight + height ) + this._position.top
|
||||||
|
this.$widget.css('top', top)
|
||||||
|
this.$widget.css('left', this._position.left)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set position of widget
|
||||||
Plugin.prototype.updatePosition = function() {
|
Plugin.prototype.updatePosition = function() {
|
||||||
this.$widget.find('.dropdown-menu').scrollTop( 300 );
|
this.$widget.find('.dropdown-menu').scrollTop( 300 );
|
||||||
if ( !this.$element.is(':visible') ) return
|
if ( !this.$element.is(':visible') ) return
|
||||||
|
|
||||||
// get cursor position
|
// get cursor position
|
||||||
var marker = '<span id="js-cursor-position"></span>'
|
var marker = '<span id="js-cursor-position"></span>'
|
||||||
|
var range = this.getFirstRange();
|
||||||
// IE9 and non-IE
|
var clone = range.cloneRange()
|
||||||
sel = window.getSelection();
|
clone.pasteHtml(marker)
|
||||||
if (sel.getRangeAt && sel.rangeCount) {
|
this._position = $('#js-cursor-position').position()
|
||||||
range = sel.getRangeAt(0);
|
|
||||||
range.deleteContents();
|
|
||||||
|
|
||||||
// Range.createContextualFragment() would be useful here but is
|
|
||||||
// only relatively recently standardized and is not supported in
|
|
||||||
// some browsers (IE9, for one)
|
|
||||||
var el = document.createElement("div");
|
|
||||||
el.innerHTML = marker;
|
|
||||||
var frag = document.createDocumentFragment(), node, lastNode;
|
|
||||||
while ( (node = el.firstChild) ) {
|
|
||||||
lastNode = frag.appendChild(node);
|
|
||||||
}
|
|
||||||
range.insertNode(frag);
|
|
||||||
|
|
||||||
// Preserve the selection
|
|
||||||
if (lastNode) {
|
|
||||||
range = range.cloneRange();
|
|
||||||
range.setStartAfter(lastNode);
|
|
||||||
range.collapse(true);
|
|
||||||
sel.removeAllRanges();
|
|
||||||
sel.addRange(range);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
position = $('#js-cursor-position').position()
|
|
||||||
$('#js-cursor-position').remove()
|
$('#js-cursor-position').remove()
|
||||||
if (!position) return
|
if (!this._position) return
|
||||||
|
|
||||||
// set position of widget
|
// set position of widget
|
||||||
var height = this.$element.height()
|
this.movePosition()
|
||||||
var widgetHeight = this.$widget.find('ul').height() //+ 60 // + height
|
|
||||||
var top = -( widgetHeight + height ) + position.top
|
|
||||||
this.$widget.css('top', top)
|
|
||||||
this.$widget.css('left', position.left)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// open widget
|
// open widget
|
||||||
Plugin.prototype.open = function() {
|
Plugin.prototype.open = function() {
|
||||||
this.active = true
|
this.active = true
|
||||||
this.updatePosition()
|
this.updatePosition()
|
||||||
|
|
||||||
b = $.proxy(function() {
|
b = $.proxy(function() {
|
||||||
this.$widget.addClass('open')
|
this.$widget.addClass('open')
|
||||||
}, this)
|
}, this)
|
||||||
|
@ -231,9 +228,11 @@
|
||||||
|
|
||||||
// close widget
|
// close widget
|
||||||
Plugin.prototype.close = function() {
|
Plugin.prototype.close = function() {
|
||||||
this.active = false
|
|
||||||
this.cutInput()
|
|
||||||
this.$widget.removeClass('open')
|
this.$widget.removeClass('open')
|
||||||
|
if ( this.active ) {
|
||||||
|
this.cutInput(true)
|
||||||
|
}
|
||||||
|
this.active = false
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if widget is active/open
|
// check if widget is active/open
|
||||||
|
@ -255,11 +254,15 @@
|
||||||
|
|
||||||
// cut some content
|
// cut some content
|
||||||
Plugin.prototype.cut = function(string) {
|
Plugin.prototype.cut = function(string) {
|
||||||
|
var range = this.getFirstRange();
|
||||||
|
if (!range) return
|
||||||
|
/*
|
||||||
var sel = window.getSelection()
|
var sel = window.getSelection()
|
||||||
if ( !sel || sel.rangeCount < 1) {
|
if ( !sel || sel.rangeCount < 1) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var range = sel.getRangeAt(0)
|
var range = sel.getRangeAt(0)
|
||||||
|
*/
|
||||||
var clone = range.cloneRange()
|
var clone = range.cloneRange()
|
||||||
|
|
||||||
// improve error handling
|
// improve error handling
|
||||||
|
@ -267,9 +270,34 @@
|
||||||
if (start < 0) {
|
if (start < 0) {
|
||||||
start = 0
|
start = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for chrome, remove also leading space, add it later - otherwice space will be tropped
|
||||||
|
if (start) {
|
||||||
|
clone.setStart(range.startContainer, start-1)
|
||||||
|
clone.setEnd(range.startContainer, start)
|
||||||
|
var spacerChar = clone.toString()
|
||||||
|
if ( spacerChar === ' ' ) {
|
||||||
|
start = start - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//console.log('CUT FOR', string, "-"+clone.toString()+"-", start, range.startOffset)
|
||||||
clone.setStart(range.startContainer, start)
|
clone.setStart(range.startContainer, start)
|
||||||
clone.setEnd(range.startContainer, range.startOffset)
|
clone.setEnd(range.startContainer, range.startOffset)
|
||||||
clone.deleteContents()
|
clone.deleteContents()
|
||||||
|
|
||||||
|
// for chrome, insert space again
|
||||||
|
if (start) {
|
||||||
|
if ( spacerChar === ' ' ) {
|
||||||
|
string = " "
|
||||||
|
if (document.selection) { // IE
|
||||||
|
var range = document.selection.createRange()
|
||||||
|
range.pasteHTML(string)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
document.execCommand('insertHTML', false, string)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// select text module and insert into text
|
// select text module and insert into text
|
||||||
|
@ -291,15 +319,15 @@
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Plugin.prototype.getFirstRange = function() {
|
||||||
|
var sel = rangy.getSelection();
|
||||||
|
return sel.rangeCount ? sel.getRangeAt(0) : null;
|
||||||
|
}
|
||||||
|
|
||||||
// cut out search string from text
|
// cut out search string from text
|
||||||
Plugin.prototype.cutInput = function() {
|
Plugin.prototype.cutInput = function() {
|
||||||
if (!this.buffer) return
|
if (!this.buffer) return
|
||||||
if (!this.$element.text()) return
|
if (!this.$element.text()) return
|
||||||
var sel = window.getSelection()
|
|
||||||
if ( !sel || sel.rangeCount < 1) {
|
|
||||||
this.buffer = ''
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.cut(this.buffer)
|
this.cut(this.buffer)
|
||||||
this.buffer = ''
|
this.buffer = ''
|
||||||
}
|
}
|
||||||
|
@ -340,10 +368,9 @@
|
||||||
_this.take(id)
|
_this.take(id)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
this.updatePosition()
|
this.movePosition()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$.fn[pluginName] = function ( options ) {
|
$.fn[pluginName] = function ( options ) {
|
||||||
return this.each(function () {
|
return this.each(function () {
|
||||||
if (!$.data(this, 'plugin_' + pluginName)) {
|
if (!$.data(this, 'plugin_' + pluginName)) {
|
||||||
|
|
Loading…
Reference in a new issue