mirror of
https://github.com/wintercms/winter.git
synced 2024-06-28 05:33:29 +02:00
189 lines
5.5 KiB
JavaScript
189 lines
5.5 KiB
JavaScript
/*
|
|
* Drag Value plugin
|
|
*
|
|
* Uses native dragging to allow elements to be dragged in to inputs, textareas, etc
|
|
*
|
|
* Data attributes:
|
|
* - data-control="dragvalue" - enables the plugin on an element
|
|
* - data-text-value="text to include" - text value to include when dragging
|
|
* - data-drag-click="false" - allow click event, tries to cache the last active element
|
|
* and insert the text at the current cursor position
|
|
*
|
|
* JavaScript API:
|
|
* $('a#someElement').dragValue({ textValue: 'insert this text' })
|
|
*
|
|
*/
|
|
|
|
+function ($) { "use strict";
|
|
|
|
// DRAG VALUE CLASS DEFINITION
|
|
// ============================
|
|
|
|
var DragValue = function(element, options) {
|
|
this.options = options
|
|
this.$el = $(element)
|
|
|
|
// Init
|
|
this.init()
|
|
}
|
|
|
|
DragValue.DEFAULTS = {
|
|
dragClick: false
|
|
}
|
|
|
|
DragValue.prototype.init = function() {
|
|
this.$el.prop('draggable', true)
|
|
this.textValue = this.$el.data('textValue')
|
|
|
|
this.$el.on('dragstart', $.proxy(this.handleDragStart, this))
|
|
this.$el.on('drop', $.proxy(this.handleDrop, this))
|
|
this.$el.on('dragend', $.proxy(this.handleDragEnd, this))
|
|
|
|
if (this.options.dragClick) {
|
|
this.$el.on('click', $.proxy(this.handleClick, this))
|
|
this.$el.on('mouseover', $.proxy(this.handleMouseOver, this))
|
|
}
|
|
}
|
|
|
|
//
|
|
// Drag events
|
|
//
|
|
|
|
DragValue.prototype.handleDragStart = function(event) {
|
|
var e = event.originalEvent
|
|
e.dataTransfer.effectAllowed = 'all'
|
|
e.dataTransfer.setData('text/plain', this.textValue)
|
|
|
|
this.$el
|
|
.css({ opacity: 0.5 })
|
|
.addClass('dragvalue-dragging')
|
|
}
|
|
|
|
DragValue.prototype.handleDrop = function(event) {
|
|
event.stopPropagation()
|
|
return false
|
|
}
|
|
|
|
DragValue.prototype.handleDragEnd = function(event) {
|
|
this.$el
|
|
.css({ opacity: 1 })
|
|
.removeClass('dragvalue-dragging')
|
|
}
|
|
|
|
//
|
|
// Click events
|
|
//
|
|
|
|
DragValue.prototype.handleMouseOver = function(event) {
|
|
var el = document.activeElement
|
|
if (!el) return
|
|
|
|
if (el.isContentEditable || (
|
|
el.tagName.toLowerCase() == 'input' &&
|
|
el.type == 'text' ||
|
|
el.tagName.toLowerCase() == 'textarea'
|
|
)) {
|
|
this.lastElement = el
|
|
}
|
|
}
|
|
|
|
DragValue.prototype.handleClick = function(event) {
|
|
if (!this.lastElement) return
|
|
|
|
var $el = $(this.lastElement)
|
|
|
|
if ($el.hasClass('ace_text-input'))
|
|
return this.handleClickCodeEditor(event, $el)
|
|
|
|
if (this.lastElement.isContentEditable)
|
|
return this.handleClickContentEditable()
|
|
|
|
this.insertAtCaret(this.lastElement, this.textValue)
|
|
}
|
|
|
|
DragValue.prototype.handleClickCodeEditor = function(event, $el) {
|
|
var $editorArea = $el.closest('[data-control=codeeditor]')
|
|
if (!$editorArea.length) return
|
|
|
|
$editorArea.codeEditor('getEditorObject').insert(this.textValue)
|
|
}
|
|
|
|
DragValue.prototype.handleClickContentEditable = function() {
|
|
var sel, range, html;
|
|
if (window.getSelection) {
|
|
sel = window.getSelection();
|
|
if (sel.getRangeAt && sel.rangeCount) {
|
|
range = sel.getRangeAt(0);
|
|
range.deleteContents();
|
|
range.insertNode( document.createTextNode(this.textValue) );
|
|
}
|
|
}
|
|
else if (document.selection && document.selection.createRange) {
|
|
document.selection.createRange().text = this.textValue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Helpers
|
|
//
|
|
|
|
DragValue.prototype.insertAtCaret = function(el, insertValue) {
|
|
// IE
|
|
if (document.selection) {
|
|
el.focus()
|
|
sel = document.selection.createRange()
|
|
sel.text = insertValue
|
|
el.focus()
|
|
}
|
|
// Real browsers
|
|
else if (el.selectionStart || el.selectionStart == '0') {
|
|
var startPos = el.selectionStart, endPos = el.selectionEnd, scrollTop = el.scrollTop
|
|
el.value = el.value.substring(0, startPos) + insertValue + el.value.substring(endPos, el.value.length)
|
|
el.focus()
|
|
el.selectionStart = startPos + insertValue.length
|
|
el.selectionEnd = startPos + insertValue.length
|
|
el.scrollTop = scrollTop
|
|
}
|
|
else {
|
|
el.value += insertValue
|
|
el.focus()
|
|
}
|
|
}
|
|
|
|
// DRAG VALUE PLUGIN DEFINITION
|
|
// ============================
|
|
|
|
var old = $.fn.dragValue
|
|
|
|
$.fn.dragValue = function (option) {
|
|
var args = Array.prototype.slice.call(arguments, 1), result
|
|
this.each(function () {
|
|
var $this = $(this)
|
|
var data = $this.data('oc.dragvalue')
|
|
var options = $.extend({}, DragValue.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
|
if (!data) $this.data('oc.dragvalue', (data = new DragValue(this, options)))
|
|
if (typeof option == 'string') result = data[option].apply(data, args)
|
|
if (typeof result != 'undefined') return false
|
|
})
|
|
|
|
return result ? result : this
|
|
}
|
|
|
|
$.fn.dragValue.Constructor = DragValue
|
|
|
|
// DRAG VALUE NO CONFLICT
|
|
// =================
|
|
|
|
$.fn.dragValue.noConflict = function () {
|
|
$.fn.dragValue = old
|
|
return this
|
|
}
|
|
|
|
// DRAG VALUE DATA-API
|
|
// ===============
|
|
|
|
$(document).render(function() {
|
|
$('[data-control="dragvalue"]').dragValue()
|
|
});
|
|
|
|
}(window.jQuery); |