mirror of
https://github.com/wassname/fullcalendar.git
synced 2026-08-17 11:19:14 +08:00
merge from master
This commit is contained in:
@@ -0,0 +1,588 @@
|
||||
/*jshint camelcase:true, plusplus:true, forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true, strict:true, undef:true, unused:true, curly:true, browser:true, devel:true, maxerr:100, white:false, onevar:false */
|
||||
/*global jQuery:true $:true */
|
||||
|
||||
/* jQuery Simulate Drag-n-Drop Plugin 1.3.0
|
||||
* http://github.com/j-ulrich/jquery-simulate-ext
|
||||
*
|
||||
* Copyright (c) 2014 Jochen Ulrich
|
||||
* Licensed under the MIT license (MIT-LICENSE.txt).
|
||||
*/
|
||||
|
||||
;(function($, undefined) {
|
||||
"use strict";
|
||||
|
||||
/* Overwrite the $.fn.simulate function to reduce the jQuery set to the first element for the
|
||||
* drag-n-drop interactions.
|
||||
*/
|
||||
$.fn.simulate = function( type, options ) {
|
||||
switch (type) {
|
||||
case "drag":
|
||||
case "drop":
|
||||
case "drag-n-drop":
|
||||
var ele = this.first();
|
||||
new $.simulate( ele[0], type, options);
|
||||
return ele;
|
||||
default:
|
||||
return this.each(function() {
|
||||
new $.simulate( this, type, options );
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
var now = Date.now || function() { return new Date().getTime(); };
|
||||
|
||||
var rdocument = /\[object (?:HTML)?Document\]/;
|
||||
/**
|
||||
* Tests whether an object is an (HTML) document object.
|
||||
* @param {DOM Element} elem - the object/element to be tested
|
||||
* @returns {Boolean} <code>true</code> if <i>elem</i> is an (HTML) document object.
|
||||
* @private
|
||||
* @author julrich
|
||||
* @since 1.1
|
||||
*/
|
||||
function isDocument( elem ) {
|
||||
return rdocument.test(Object.prototype.toString.call($(elem)[0]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Selects the first match from an array.
|
||||
* @param {Array} array - Array of objects to be be tested
|
||||
* @param {Function} check - Callback function that accepts one argument (which will be one element
|
||||
* from the <i>array</i>) and returns a boolean.
|
||||
* @returns {Boolean|null} the first element in <i>array</i> for which <i>check</i> returns <code>true</code>.
|
||||
* If none of the elements in <i>array</i> passes <i>check</i>, <code>null</code> is returned.
|
||||
* @private
|
||||
* @author julrich
|
||||
* @since 1.1
|
||||
*/
|
||||
function selectFirstMatch(array, check) {
|
||||
var i;
|
||||
if ($.isFunction(check)) {
|
||||
for (i=0; i < array.length; i+=1) {
|
||||
if (check(array[i])) {
|
||||
return array[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
for (i=0; i < array.length; i+=1) {
|
||||
if (array[i]) {
|
||||
return array[i];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Based on the findCenter function from jquery.simulate.js
|
||||
/**
|
||||
* Calculates the position of the center of an DOM element.
|
||||
* @param {DOM Element} elem - the element whose center should be calculated.
|
||||
* @returns {Object} an object with the properties <code>x</code> and <code>y</code>
|
||||
* representing the position of the center of <i>elem</i> in page relative coordinates
|
||||
* (i.e. independent of any scrolling).
|
||||
* @private
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
function findCenter( elem ) {
|
||||
var offset,
|
||||
$elem = $( elem );
|
||||
if ( isDocument($elem[0]) ) {
|
||||
offset = {left: 0, top: 0};
|
||||
}
|
||||
else {
|
||||
offset = $elem.offset();
|
||||
}
|
||||
|
||||
return {
|
||||
x: offset.left + $elem.outerWidth() / 2,
|
||||
y: offset.top + $elem.outerHeight() / 2
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts page relative coordinates into client relative coordinates.
|
||||
* @param {Numeric|Object} x - Either the x coordinate of the page relative coordinates or
|
||||
* an object with the properties <code>pageX</code> and <code>pageY</code> representing page
|
||||
* relative coordinates.
|
||||
* @param {Numeric} [y] - If <i>x</i> is numeric (i.e. the x coordinate of page relative coordinates),
|
||||
* then this is the y coordinate. If <i>x</i> is an object, this parameter is skipped.
|
||||
* @param {DOM Document} [docRel] - Optional DOM document object used to calculate the client relative
|
||||
* coordinates. The page relative coordinates are interpreted as being relative to that document and
|
||||
* the scroll position of that document is used to calculate the client relative coordinates.
|
||||
* By default, <code>document</code> is used.
|
||||
* @returns {Object} an object representing the client relative coordinates corresponding to the
|
||||
* given page relative coordinates. The object either provides the properties <code>x</code> and
|
||||
* <code>y</code> when <i>x</i> and <i>y</i> were given as arguments, or <code>clientX</code>
|
||||
* and <code>clientY</code> when the parameter <i>x</i> was given as an object (see above).
|
||||
* @private
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
function pageToClientPos(x, y, docRel) {
|
||||
var $document;
|
||||
if ( isDocument(y) ) {
|
||||
$document = $(y);
|
||||
} else {
|
||||
$document = $(docRel || document);
|
||||
}
|
||||
|
||||
if (typeof x === "number" && typeof y === "number") {
|
||||
return {
|
||||
x: x - $document.scrollLeft(),
|
||||
y: y - $document.scrollTop()
|
||||
};
|
||||
}
|
||||
else if (typeof x === "object" && x.pageX && x.pageY) {
|
||||
return {
|
||||
clientX: x.pageX - $document.scrollLeft(),
|
||||
clientY: x.pageY - $document.scrollTop()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Browser-independent implementation of <code>document.elementFromPoint()</code>.
|
||||
*
|
||||
* When run for the first time on a scrolled page, this function performs a check on how
|
||||
* <code>document.elementFromPoint()</code> is implemented in the current browser. It stores
|
||||
* the results in two static variables so that the check can be skipped for successive calls.
|
||||
*
|
||||
* @param {Numeric|Object} x - Either the x coordinate of client relative coordinates or an object
|
||||
* with the properties <code>x</code> and <code>y</code> representing client relative coordinates.
|
||||
* @param {Numeric} [y] - If <i>x</i> is numeric (i.e. the x coordinate of client relative coordinates),
|
||||
* this is the y coordinate. If <i>x</i> is an object, this parameter is skipped.
|
||||
* @param {DOM Document} [docRel] - Optional DOM document object
|
||||
* @returns {DOM Element|Null}
|
||||
* @private
|
||||
* @author Nicolas Zeh (Basic idea), julrich
|
||||
* @see http://www.zehnet.de/2010/11/19/document-elementfrompoint-a-jquery-solution/
|
||||
* @since 1.0
|
||||
*/
|
||||
function elementAtPosition(x, y, docRel) {
|
||||
var doc;
|
||||
if ( isDocument(y) ) {
|
||||
doc = y;
|
||||
} else {
|
||||
doc = docRel || document;
|
||||
}
|
||||
|
||||
if(!doc.elementFromPoint) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var clientX = x, clientY = y;
|
||||
if (typeof x === "object" && (x.clientX || x.clientY)) {
|
||||
clientX = x.clientX || 0 ;
|
||||
clientY = x.clientY || 0;
|
||||
}
|
||||
|
||||
if(elementAtPosition.prototype.check)
|
||||
{
|
||||
var sl, ele;
|
||||
if ((sl = $(doc).scrollTop()) >0)
|
||||
{
|
||||
ele = doc.elementFromPoint(0, sl + $(window).height() -1);
|
||||
if ( ele !== null && ele.tagName.toUpperCase() === 'HTML' ) { ele = null; }
|
||||
elementAtPosition.prototype.nativeUsesRelative = ( ele === null );
|
||||
}
|
||||
else if((sl = $(doc).scrollLeft()) >0)
|
||||
{
|
||||
ele = doc.elementFromPoint(sl + $(window).width() -1, 0);
|
||||
if ( ele !== null && ele.tagName.toUpperCase() === 'HTML' ) { ele = null; }
|
||||
elementAtPosition.prototype.nativeUsesRelative = ( ele === null );
|
||||
}
|
||||
elementAtPosition.prototype.check = (sl<=0); // Check was not meaningful because we were at scroll position 0
|
||||
}
|
||||
|
||||
if(!elementAtPosition.prototype.nativeUsesRelative)
|
||||
{
|
||||
clientX += $(doc).scrollLeft();
|
||||
clientY += $(doc).scrollTop();
|
||||
}
|
||||
|
||||
return doc.elementFromPoint(clientX,clientY);
|
||||
}
|
||||
// Default values for the check variables
|
||||
elementAtPosition.prototype.check = true;
|
||||
elementAtPosition.prototype.nativeUsesRelative = true;
|
||||
|
||||
/**
|
||||
* Informs the rest of the world that the drag is finished.
|
||||
* @param {DOM Element} ele - The element which was dragged.
|
||||
* @param {Object} [options] - The drag options.
|
||||
* @fires simulate-drag
|
||||
* @private
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
function dragFinished(ele, options) {
|
||||
var opts = options || {};
|
||||
$(ele).trigger({type: "simulate-drag"});
|
||||
if ($.isFunction(opts.callback)) {
|
||||
opts.callback.apply(ele);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a series of <code>mousemove</code> events for a drag.
|
||||
* @param {Object} self - The simulate object.
|
||||
* @param {DOM Element} ele - The element which is dragged.
|
||||
* @param {Object} start - The start coordinates of the drag, represented using the properties
|
||||
* <code>x</code> and <code>y</code>.
|
||||
* @param {Object} drag - The distance to be dragged, represented using the properties <code>dx</code>
|
||||
* and <code>dy</code>.
|
||||
* @param {Object} options - The drag options. Must have the property <code>interpolation</code>
|
||||
* containing the interpolation options (<code>stepWidth</code>, <code>stepCount</code>, etc.).
|
||||
* @requires eventTarget
|
||||
* @requires now()
|
||||
* @private
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
function interpolatedEvents(self, ele, start, drag, options) {
|
||||
var targetDoc = selectFirstMatch([ele, ele.ownerDocument], isDocument) || document,
|
||||
interpolOptions = options.interpolation,
|
||||
dragDistance = Math.sqrt(Math.pow(drag.dx,2) + Math.pow(drag.dy,2)), // sqrt(a^2 + b^2)
|
||||
stepWidth, stepCount, stepVector;
|
||||
|
||||
if (interpolOptions.stepWidth) {
|
||||
stepWidth = parseInt(interpolOptions.stepWidth, 10);
|
||||
stepCount = Math.floor(dragDistance / stepWidth)-1;
|
||||
var stepScale = stepWidth / dragDistance;
|
||||
stepVector = {x: drag.dx*stepScale, y: drag.dy*stepScale };
|
||||
}
|
||||
else {
|
||||
stepCount = parseInt(interpolOptions.stepCount, 10);
|
||||
stepWidth = dragDistance / (stepCount+1);
|
||||
stepVector = {x: drag.dx/(stepCount+1), y: drag.dy/(stepCount+1)};
|
||||
}
|
||||
|
||||
|
||||
var coords = $.extend({},start);
|
||||
|
||||
/**
|
||||
* Calculates the effective coordinates for one <code>mousemove</code> event and fires the event.
|
||||
* @requires eventTarget
|
||||
* @requires targetDoc
|
||||
* @requires coords
|
||||
* @requires stepVector
|
||||
* @requires interpolOptions
|
||||
* @fires mousemove
|
||||
* @inner
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
function interpolationStep() {
|
||||
coords.x += stepVector.x;
|
||||
coords.y += stepVector.y;
|
||||
var effectiveCoords = {pageX: coords.x, pageY: coords.y};
|
||||
if (interpolOptions.shaky && (interpolOptions.shaky === true || !isNaN(parseInt(interpolOptions.shaky,10)) )) {
|
||||
var amplitude = (interpolOptions.shaky === true)? 1 : parseInt(interpolOptions.shaky,10);
|
||||
effectiveCoords.pageX += Math.floor(Math.random()*(2*amplitude+1)-amplitude);
|
||||
effectiveCoords.pageY += Math.floor(Math.random()*(2*amplitude+1)-amplitude);
|
||||
}
|
||||
var clientCoord = pageToClientPos(effectiveCoords, targetDoc),
|
||||
eventTarget = elementAtPosition(clientCoord, targetDoc) || ele;
|
||||
self.simulateEvent( eventTarget, "mousemove", {pageX: Math.round(effectiveCoords.pageX), pageY: Math.round(effectiveCoords.pageY)});
|
||||
}
|
||||
|
||||
|
||||
var lastTime;
|
||||
|
||||
/**
|
||||
* Performs one interpolation step (i.e. cares about firing the event) and then sleeps for
|
||||
* <code>stepDelay</code> milliseconds.
|
||||
* @requires lastTime
|
||||
* @requires stepDelay
|
||||
* @requires step
|
||||
* @requires ele
|
||||
* @requires eventTarget
|
||||
* @reuiqre targetDoc
|
||||
* @requires start
|
||||
* @requires drag
|
||||
* @requires now()
|
||||
* @inner
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
function stepAndSleep() {
|
||||
var timeElapsed = now() - lastTime; // Work-around for Firefox & IE "bug": setTimeout can fire before the timeout
|
||||
if (timeElapsed >= stepDelay) {
|
||||
if (step < stepCount) {
|
||||
interpolationStep();
|
||||
step += 1;
|
||||
lastTime = now();
|
||||
setTimeout(stepAndSleep, stepDelay);
|
||||
}
|
||||
else {
|
||||
var pageCoord = {pageX: Math.round(start.x+drag.dx), pageY: Math.round(start.y+drag.dy)},
|
||||
clientCoord = pageToClientPos(pageCoord, targetDoc),
|
||||
eventTarget = elementAtPosition(clientCoord, targetDoc) || ele;
|
||||
self.simulateEvent( eventTarget, "mousemove", pageCoord);
|
||||
dragFinished(ele, options);
|
||||
}
|
||||
}
|
||||
else {
|
||||
setTimeout(stepAndSleep, stepDelay - timeElapsed);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ( (!interpolOptions.stepDelay && !interpolOptions.duration) || ((interpolOptions.stepDelay <= 0) && (interpolOptions.duration <= 0)) ) {
|
||||
// Trigger as fast as possible
|
||||
for (var i=0; i < stepCount; i+=1) {
|
||||
interpolationStep();
|
||||
}
|
||||
var pageCoord = {pageX: Math.round(start.x+drag.dx), pageY: Math.round(start.y+drag.dy)},
|
||||
clientCoord = pageToClientPos(pageCoord, targetDoc),
|
||||
eventTarget = elementAtPosition(clientCoord, targetDoc) || ele;
|
||||
self.simulateEvent( eventTarget, "mousemove", pageCoord);
|
||||
dragFinished(ele, options);
|
||||
}
|
||||
else {
|
||||
var stepDelay = parseInt(interpolOptions.stepDelay,10) || Math.ceil(parseInt(interpolOptions.duration,10) / (stepCount+1));
|
||||
var step = 0;
|
||||
|
||||
lastTime = now();
|
||||
setTimeout(stepAndSleep, stepDelay);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {Object|undefined} an object containing information about the currently active drag
|
||||
* or <code>undefined</code> when there is no active drag.
|
||||
* The returned object contains the following properties:
|
||||
* <ul>
|
||||
* <li><code>dragElement</code>: the dragged element</li>
|
||||
* <li><code>dragStart</code>: object with the properties <code>x</code> and <code>y</code>
|
||||
* representing the page relative start coordinates of the drag</li>
|
||||
* <li><code>dragDistance</code>: object with the properties <code>x</code> and <code>y</code>
|
||||
* representing the distance of the drag in x and y direction</li>
|
||||
* </ul>
|
||||
* @public
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
$.simulate.activeDrag = function() {
|
||||
if (!$.simulate._activeDrag) {
|
||||
return undefined;
|
||||
}
|
||||
return $.extend(true,{},$.simulate._activeDrag);
|
||||
};
|
||||
|
||||
$.extend( $.simulate.prototype,
|
||||
|
||||
/**
|
||||
* @lends $.simulate.prototype
|
||||
*/
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Simulates a drag.
|
||||
*
|
||||
* @see https://github.com/j-ulrich/jquery-simulate-ext/blob/master/doc/drag-n-drop.md
|
||||
* @public
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
simulateDrag: function() {
|
||||
var self = this,
|
||||
ele = self.target,
|
||||
options = $.extend({
|
||||
dx: 0,
|
||||
dy: 0,
|
||||
dragTarget: undefined,
|
||||
clickToDrag: false,
|
||||
eventProps: {},
|
||||
interpolation: {
|
||||
stepWidth: 0,
|
||||
stepCount: 0,
|
||||
stepDelay: 0,
|
||||
duration: 0,
|
||||
shaky: false
|
||||
},
|
||||
callback: undefined
|
||||
}, this.options);
|
||||
|
||||
var start,
|
||||
continueDrag = ($.simulate._activeDrag && $.simulate._activeDrag.dragElement === ele);
|
||||
|
||||
if (continueDrag) {
|
||||
start = $.simulate._activeDrag.dragStart;
|
||||
}
|
||||
else {
|
||||
start = findCenter( ele );
|
||||
}
|
||||
|
||||
var x = Math.round( start.x ),
|
||||
y = Math.round( start.y ),
|
||||
coord = { pageX: x, pageY: y },
|
||||
dx,
|
||||
dy;
|
||||
|
||||
if (options.dragTarget) {
|
||||
var end = findCenter(options.dragTarget);
|
||||
dx = Math.round(end.x - start.x);
|
||||
dy = Math.round(end.y - start.y);
|
||||
}
|
||||
else {
|
||||
dx = options.dx || 0;
|
||||
dy = options.dy || 0;
|
||||
}
|
||||
|
||||
if (continueDrag) {
|
||||
// We just continue to move the dragged element
|
||||
$.simulate._activeDrag.dragDistance.x += dx;
|
||||
$.simulate._activeDrag.dragDistance.y += dy;
|
||||
coord = { pageX: Math.round(x + $.simulate._activeDrag.dragDistance.x) , pageY: Math.round(y + $.simulate._activeDrag.dragDistance.y) };
|
||||
}
|
||||
else {
|
||||
if ($.simulate._activeDrag) {
|
||||
// Drop before starting a new drag
|
||||
$($.simulate._activeDrag.dragElement).simulate( "drop" );
|
||||
}
|
||||
|
||||
// We start a new drag
|
||||
$.extend(options.eventProps, coord);
|
||||
self.simulateEvent( ele, "mousedown", options.eventProps );
|
||||
if (options.clickToDrag === true) {
|
||||
self.simulateEvent( ele, "mouseup", options.eventProps );
|
||||
self.simulateEvent( ele, "click", options.eventProps );
|
||||
}
|
||||
$(ele).add(ele.ownerDocument).one('mouseup', function() {
|
||||
$.simulate._activeDrag = undefined;
|
||||
});
|
||||
|
||||
$.extend($.simulate, {
|
||||
_activeDrag: {
|
||||
dragElement: ele,
|
||||
dragStart: { x: x, y: y },
|
||||
dragDistance: { x: dx, y: dy }
|
||||
}
|
||||
});
|
||||
coord = { pageX: Math.round(x + dx), pageY: Math.round(y + dy) };
|
||||
}
|
||||
|
||||
if (dx !== 0 || dy !== 0) {
|
||||
|
||||
if ( options.interpolation && (options.interpolation.stepCount || options.interpolation.stepWidth) ) {
|
||||
interpolatedEvents(self, ele, {x: x, y: y}, {dx: dx, dy: dy}, options);
|
||||
}
|
||||
else {
|
||||
var targetDoc = selectFirstMatch([ele, ele.ownerDocument], isDocument) || document,
|
||||
clientCoord = pageToClientPos(coord, targetDoc),
|
||||
eventTarget = elementAtPosition(clientCoord, targetDoc) || ele;
|
||||
|
||||
$.extend(options.eventProps, coord);
|
||||
self.simulateEvent( eventTarget, "mousemove", options.eventProps );
|
||||
dragFinished(ele, options);
|
||||
}
|
||||
}
|
||||
else {
|
||||
dragFinished(ele, options);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Simulates a drop.
|
||||
*
|
||||
* @see https://github.com/j-ulrich/jquery-simulate-ext/blob/master/doc/drag-n-drop.md
|
||||
* @public
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
simulateDrop: function() {
|
||||
var self = this,
|
||||
ele = this.target,
|
||||
activeDrag = $.simulate._activeDrag,
|
||||
options = $.extend({
|
||||
clickToDrop: false,
|
||||
eventProps: {},
|
||||
callback: undefined
|
||||
}, self.options),
|
||||
moveBeforeDrop = true,
|
||||
center = findCenter( ele ),
|
||||
x = Math.round( center.x ),
|
||||
y = Math.round( center.y ),
|
||||
coord = { pageX: x, pageY: y },
|
||||
targetDoc = ( (activeDrag)? selectFirstMatch([activeDrag.dragElement, activeDrag.dragElement.ownerDocument], isDocument) : selectFirstMatch([ele, ele.ownerDocument], isDocument) ) || document,
|
||||
clientCoord = pageToClientPos(coord, targetDoc),
|
||||
eventTarget = elementAtPosition(clientCoord, targetDoc);
|
||||
|
||||
if (activeDrag && (activeDrag.dragElement === ele || isDocument(ele))) {
|
||||
// We already moved the mouse during the drag so we just simulate the drop on the end position
|
||||
x = Math.round(activeDrag.dragStart.x + activeDrag.dragDistance.x);
|
||||
y = Math.round(activeDrag.dragStart.y + activeDrag.dragDistance.y);
|
||||
coord = { pageX: x, pageY: y };
|
||||
clientCoord = pageToClientPos(coord, targetDoc);
|
||||
eventTarget = elementAtPosition(clientCoord, targetDoc);
|
||||
moveBeforeDrop = false;
|
||||
}
|
||||
|
||||
if (!eventTarget) {
|
||||
eventTarget = (activeDrag)? activeDrag.dragElement : ele;
|
||||
}
|
||||
|
||||
$.extend(options.eventProps, coord);
|
||||
|
||||
if (moveBeforeDrop === true) {
|
||||
// Else we assume the drop should happen on target, so we move there
|
||||
self.simulateEvent( eventTarget, "mousemove", options.eventProps );
|
||||
}
|
||||
|
||||
if (options.clickToDrop) {
|
||||
self.simulateEvent( eventTarget, "mousedown", options.eventProps );
|
||||
}
|
||||
this.simulateEvent( eventTarget, "mouseup", options.eventProps );
|
||||
if (options.clickToDrop) {
|
||||
self.simulateEvent( eventTarget, "click", options.eventProps );
|
||||
}
|
||||
|
||||
$.simulate._activeDrag = undefined;
|
||||
$(eventTarget).trigger({type: "simulate-drop"});
|
||||
if ($.isFunction(options.callback)) {
|
||||
options.callback.apply(eventTarget);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Simulates a drag followed by drop.
|
||||
*
|
||||
* @see https://github.com/j-ulrich/jquery-simulate-ext/blob/master/doc/drag-n-drop.md
|
||||
* @public
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
simulateDragNDrop: function() {
|
||||
var self = this,
|
||||
ele = this.target,
|
||||
options = $.extend({
|
||||
dragTarget: undefined,
|
||||
dropTarget: undefined
|
||||
}, self.options),
|
||||
// If there is a dragTarget or dx/dy, then we drag there and simulate an independent drop on dropTarget or ele
|
||||
dropEle = ((options.dragTarget || options.dx || options.dy)? options.dropTarget : ele) || ele;
|
||||
/*
|
||||
dx = (options.dropTarget)? 0 : (options.dx || 0),
|
||||
dy = (options.dropTarget)? 0 : (options.dy || 0),
|
||||
dragDistance = { dx: dx, dy: dy };
|
||||
|
||||
$.extend(options, dragDistance);
|
||||
*/
|
||||
$(ele).simulate( "drag", $.extend({},options,{
|
||||
// If there is no dragTarget, no dx and no dy, we drag onto the dropTarget directly
|
||||
dragTarget: options.dragTarget || ((options.dx || options.dy)?undefined:options.dropTarget),
|
||||
callback: function() {
|
||||
$(dropEle).simulate( "drop", options );
|
||||
}
|
||||
}));
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,30 @@
|
||||
/*jshint camelcase:true, plusplus:true, forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true, strict:true, undef:true, unused:true, curly:true, browser:true, devel:true, maxerr:100, white:false, onevar:false */
|
||||
/*global jQuery:true $:true */
|
||||
|
||||
/* jQuery Simulate Extended Plugin 1.3.0
|
||||
* http://github.com/j-ulrich/jquery-simulate-ext
|
||||
*
|
||||
* Copyright (c) 2014 Jochen Ulrich
|
||||
* Licensed under the MIT license (MIT-LICENSE.txt).
|
||||
*/
|
||||
|
||||
;(function( $ ) {
|
||||
"use strict";
|
||||
|
||||
/* Overwrite the $.simulate.prototype.mouseEvent function
|
||||
* to convert pageX/Y to clientX/Y
|
||||
*/
|
||||
var originalMouseEvent = $.simulate.prototype.mouseEvent,
|
||||
rdocument = /\[object (?:HTML)?Document\]/;
|
||||
|
||||
$.simulate.prototype.mouseEvent = function(type, options) {
|
||||
if (options.pageX || options.pageY) {
|
||||
var doc = rdocument.test(Object.prototype.toString.call(this.target))? this.target : (this.target.ownerDocument || document);
|
||||
options.clientX = (options.pageX || 0) - $(doc).scrollLeft();
|
||||
options.clientY = (options.pageY || 0) - $(doc).scrollTop();
|
||||
}
|
||||
return originalMouseEvent.apply(this, [type, options]);
|
||||
};
|
||||
|
||||
|
||||
})( jQuery );
|
||||
@@ -0,0 +1,193 @@
|
||||
/*jshint camelcase:true, plusplus:true, forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true, strict:true, undef:true, unused:true, curly:true, browser:true, devel:true, maxerr:100, white:false, onevar:false */
|
||||
/*global jQuery:true $:true */
|
||||
|
||||
/* jQuery Simulate Key-Combo Plugin 1.3.0
|
||||
* http://github.com/j-ulrich/jquery-simulate-ext
|
||||
*
|
||||
* Copyright (c) 2014 Jochen Ulrich
|
||||
* Licensed under the MIT license (MIT-LICENSE.txt).
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* For details about key events, key codes, char codes etc. see http://unixpapa.com/js/key.html
|
||||
*/
|
||||
|
||||
;(function($,undefined) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Key codes of special keys.
|
||||
* @private
|
||||
* @author julrich
|
||||
* @since 1.3.0
|
||||
*/
|
||||
var SpecialKeyCodes = {
|
||||
// Modifier Keys
|
||||
SHIFT: 16,
|
||||
CONTROL: 17,
|
||||
ALTERNATIVE: 18,
|
||||
META: 91,
|
||||
// Arrow Keys
|
||||
LEFT_ARROW: 37,
|
||||
UP_ARROW: 38,
|
||||
RIGHT_ARROW: 39,
|
||||
DOWN_ARROW: 40,
|
||||
// Function Keys
|
||||
F1: 112,
|
||||
F2: 113,
|
||||
F3: 114,
|
||||
F4: 115,
|
||||
F5: 116,
|
||||
F6: 117,
|
||||
F7: 118,
|
||||
F8: 119,
|
||||
F9: 120,
|
||||
F10: 121,
|
||||
F11: 122,
|
||||
F12: 123,
|
||||
// Other
|
||||
ENTER: 13,
|
||||
TABULATOR: 9,
|
||||
ESCAPE: 27,
|
||||
BACKSPACE: 8,
|
||||
INSERT: 45,
|
||||
DELETE: 46,
|
||||
HOME: 36,
|
||||
END: 35,
|
||||
PAGE_UP: 33,
|
||||
PAGE_DOWN: 34,
|
||||
|
||||
};
|
||||
|
||||
// SpecialKeyCode aliases
|
||||
SpecialKeyCodes.CTRL = SpecialKeyCodes.CONTROL;
|
||||
SpecialKeyCodes.ALT = SpecialKeyCodes.ALTERNATIVE;
|
||||
SpecialKeyCodes.COMMAND = SpecialKeyCodes.META;
|
||||
SpecialKeyCodes.TAB = SpecialKeyCodes.TABULATOR;
|
||||
SpecialKeyCodes.ESC = SpecialKeyCodes.ESCAPE;
|
||||
|
||||
|
||||
$.extend( $.simulate.prototype,
|
||||
|
||||
/**
|
||||
* @lends $.simulate.prototype
|
||||
*/
|
||||
{
|
||||
|
||||
|
||||
/**
|
||||
* Simulates simultaneous key presses
|
||||
*
|
||||
* @see https://github.com/j-ulrich/jquery-simulate-ext/blob/master/doc/key-combo.md
|
||||
* @public
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
simulateKeyCombo: function() {
|
||||
var $target = $(this.target),
|
||||
options = $.extend({
|
||||
combo: "",
|
||||
eventProps: {},
|
||||
eventsOnly: false
|
||||
}, this.options),
|
||||
combo = options.combo,
|
||||
comboSplit = combo.split(/(\+)/),
|
||||
plusExpected = false,
|
||||
holdKeys = [],
|
||||
i;
|
||||
|
||||
if (combo.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove empty parts
|
||||
comboSplit = $.grep(comboSplit, function(part) {
|
||||
return (part !== "");
|
||||
});
|
||||
|
||||
for (i=0; i < comboSplit.length; i+=1) {
|
||||
var key = comboSplit[i],
|
||||
keyLowered = key.toLowerCase(),
|
||||
keySpecial = key.toUpperCase().replace('-','_');
|
||||
|
||||
if (plusExpected) {
|
||||
if (key !== "+") {
|
||||
throw 'Syntax error: expected "+"';
|
||||
}
|
||||
else {
|
||||
plusExpected = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var keyCode;
|
||||
if ( key.length > 1) {
|
||||
// Assume a special key
|
||||
keyCode = SpecialKeyCodes[keySpecial];
|
||||
|
||||
if (keyCode === undefined) {
|
||||
throw 'Syntax error: unknown special key "'+key+'" (forgot "+" between keys?)';
|
||||
}
|
||||
|
||||
switch (keyCode) {
|
||||
case SpecialKeyCodes.CONTROL:
|
||||
case SpecialKeyCodes.ALT:
|
||||
case SpecialKeyCodes.SHIFT:
|
||||
case SpecialKeyCodes.META:
|
||||
options.eventProps[keyLowered+"Key"] = true;
|
||||
break;
|
||||
}
|
||||
holdKeys.unshift(keyCode);
|
||||
options.eventProps.keyCode = keyCode;
|
||||
options.eventProps.which = keyCode;
|
||||
options.eventProps.charCode = 0;
|
||||
$target.simulate("keydown", options.eventProps);
|
||||
|
||||
}
|
||||
else {
|
||||
// "Normal" key
|
||||
keyCode = $.simulate.prototype.simulateKeySequence.prototype.charToKeyCode(key);
|
||||
holdKeys.unshift(keyCode);
|
||||
options.eventProps.keyCode = keyCode;
|
||||
options.eventProps.which = keyCode;
|
||||
options.eventProps.charCode = undefined;
|
||||
$target.simulate("keydown", options.eventProps);
|
||||
if (options.eventProps.shiftKey) {
|
||||
key = key.toUpperCase();
|
||||
}
|
||||
options.eventProps.keyCode = key.charCodeAt(0);
|
||||
options.eventProps.charCode = options.eventProps.keyCode;
|
||||
options.eventProps.which = options.eventProps.keyCode;
|
||||
$target.simulate("keypress", options.eventProps);
|
||||
if (options.eventsOnly !== true && !options.eventProps.ctrlKey && !options.eventProps.altKey && !options.eventProps.metaKey) {
|
||||
$target.simulate('key-sequence', {sequence: key, triggerKeyEvents: false});
|
||||
}
|
||||
}
|
||||
|
||||
plusExpected = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!plusExpected) {
|
||||
throw 'Syntax error: expected key (trailing "+"?)';
|
||||
}
|
||||
|
||||
// Release keys
|
||||
options.eventProps.charCode = undefined;
|
||||
for (i=0; i < holdKeys.length; i+=1) {
|
||||
options.eventProps.keyCode = holdKeys[i];
|
||||
options.eventProps.which = holdKeys[i];
|
||||
switch (options.eventProps.keyCode) {
|
||||
case SpecialKeyCodes.ALT: options.eventProps.altKey = false; break;
|
||||
case SpecialKeyCodes.SHIFT: options.eventProps.shiftKey = false; break;
|
||||
case SpecialKeyCodes.CONTROL: options.eventProps.ctrlKey = false; break;
|
||||
case SpecialKeyCodes.META: options.eventProps.metaKey = false; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
$target.simulate("keyup", options.eventProps);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}(jQuery));
|
||||
@@ -0,0 +1,444 @@
|
||||
/*jshint camelcase:true, plusplus:true, forin:true, noarg:true, noempty:true, eqeqeq:true, bitwise:true, strict:true, undef:true, unused:true, curly:true, browser:true, devel:true, maxerr:100, white:false, onevar:false */
|
||||
/*global jQuery:true $:true bililiteRange:true */
|
||||
|
||||
/* jQuery Simulate Key-Sequence Plugin 1.3.0
|
||||
* http://github.com/j-ulrich/jquery-simulate-ext
|
||||
*
|
||||
* Copyright (c) 2014 Jochen Ulrich
|
||||
* Licensed under the MIT license (MIT-LICENSE.txt).
|
||||
*
|
||||
* The plugin is an extension and modification of the jQuery sendkeys plugin by Daniel Wachsstock.
|
||||
* Therefore, the original copyright notice and license follow below.
|
||||
*/
|
||||
|
||||
// insert characters in a textarea or text input field
|
||||
// special characters are enclosed in {}; use {{} for the { character itself
|
||||
// documentation: http://bililite.com/blog/2008/08/20/the-fnsendkeys-plugin/
|
||||
// Version: 2.0
|
||||
// Copyright (c) 2010 Daniel Wachsstock
|
||||
// MIT license:
|
||||
// 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.
|
||||
|
||||
;(function($, undefined){
|
||||
"use strict";
|
||||
|
||||
$.simulate.prototype.quirks = $.simulate.prototype.quirks || {};
|
||||
|
||||
$.extend($.simulate.prototype.quirks,
|
||||
|
||||
/**
|
||||
* @lends $.simulate.prototype.quirks
|
||||
*/
|
||||
{
|
||||
/**
|
||||
* When simulating with delay in non-input elements,
|
||||
* all spaces are simulated at the end of the sequence instead
|
||||
* of the correct position.
|
||||
* @see {@link https://github.com/j-ulrich/jquery-simulate-ext/issues/6|issues #6}
|
||||
*/
|
||||
delayedSpacesInNonInputGlitchToEnd: undefined
|
||||
|
||||
});
|
||||
|
||||
$.extend($.simulate.prototype,
|
||||
|
||||
/**
|
||||
* @lends $.simulate.prototype
|
||||
*/
|
||||
{
|
||||
|
||||
/**
|
||||
* Simulates sequencial key strokes.
|
||||
*
|
||||
* @see https://github.com/j-ulrich/jquery-simulate-ext/blob/master/doc/key-sequence.md
|
||||
* @public
|
||||
* @author Daniel Wachsstock, julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
simulateKeySequence: function() {
|
||||
var target = this.target,
|
||||
$target = $(target),
|
||||
opts = $.extend({
|
||||
sequence: "",
|
||||
triggerKeyEvents: true,
|
||||
eventProps: {},
|
||||
delay: 0,
|
||||
callback: undefined
|
||||
}, this.options),
|
||||
sequence = opts.sequence;
|
||||
|
||||
opts.delay = parseInt(opts.delay,10);
|
||||
|
||||
var localkeys = {};
|
||||
|
||||
// Fix for #6 (https://github.com/j-ulrich/jquery-simulate-ext/issues/6)
|
||||
if ($.simulate.prototype.quirks.delayedSpacesInNonInputGlitchToEnd && !$target.is('input,textarea')) {
|
||||
$.extend(localkeys, {
|
||||
' ': function(rng, s, opts) {
|
||||
var internalOpts = $.extend({}, opts, {
|
||||
triggerKeyEvents: false,
|
||||
delay: 0,
|
||||
callback: undefined
|
||||
});
|
||||
$.simulate.prototype.simulateKeySequence.defaults.simplechar(rng, '\xA0', internalOpts);
|
||||
$.simulate.prototype.simulateKeySequence.defaults['{leftarrow}'](rng, s, internalOpts);
|
||||
$.simulate.prototype.simulateKeySequence.defaults.simplechar(rng, s, opts);
|
||||
$.simulate.prototype.simulateKeySequence.defaults['{del}'](rng, s, internalOpts);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$.extend(localkeys, opts, $target.data('simulate-keySequence')); // allow for element-specific key functions
|
||||
|
||||
// most elements to not keep track of their selection when they lose focus, so we have to do it for them
|
||||
var rng = $.data (target, 'simulate-keySequence.selection');
|
||||
if (!rng){
|
||||
rng = bililiteRange(target).bounds('selection');
|
||||
$.data(target, 'simulate-keySequence.selection', rng);
|
||||
$target.bind('mouseup.simulate-keySequence', function(){
|
||||
// we have to update the saved range. The routines here update the bounds with each press, but actual keypresses and mouseclicks do not
|
||||
$.data(target, 'simulate-keySequence.selection').bounds('selection');
|
||||
}).bind('keyup.simulate-keySequence', function(evt){
|
||||
// restore the selection if we got here with a tab (a click should select what was clicked on)
|
||||
if (evt.which === 9){
|
||||
// there's a flash of selection when we restore the focus, but I don't know how to avoid that.
|
||||
$.data(target, 'simulate-keySequence.selection').select();
|
||||
}else{
|
||||
$.data(target, 'simulate-keySequence.selection').bounds('selection');
|
||||
}
|
||||
});
|
||||
}
|
||||
$target.focus();
|
||||
if (typeof sequence === 'undefined') { // no string, so we just set up the event handlers
|
||||
return;
|
||||
}
|
||||
sequence = sequence.replace(/\n/g, '{enter}'); // turn line feeds into explicit break insertions
|
||||
|
||||
/**
|
||||
* Informs the rest of the world that the sequences is finished.
|
||||
* @fires simulate-keySequence
|
||||
* @requires target
|
||||
* @requires sequence
|
||||
* @requires opts
|
||||
* @inner
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
function sequenceFinished() {
|
||||
$target.trigger({type: 'simulate-keySequence', sequence: sequence});
|
||||
if ($.isFunction(opts.callback)) {
|
||||
opts.callback.apply(target, [{
|
||||
sequence: sequence
|
||||
}]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulates the key stroke for one character (or special sequence) and sleeps for
|
||||
* <code>opts.delay</code> milliseconds.
|
||||
* @requires lastTime
|
||||
* @requires now()
|
||||
* @requires tokenRegExp
|
||||
* @requires opts
|
||||
* @requires rng
|
||||
* @inner
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
function processNextToken() {
|
||||
var timeElapsed = now() - lastTime; // Work-around for Firefox "bug": setTimeout can fire before the timeout
|
||||
if (timeElapsed >= opts.delay) {
|
||||
var match = tokenRegExp.exec(sequence);
|
||||
if ( match !== null ) {
|
||||
var s = match[0];
|
||||
(localkeys[s] || $.simulate.prototype.simulateKeySequence.defaults[s] || $.simulate.prototype.simulateKeySequence.defaults.simplechar)(rng, s, opts);
|
||||
setTimeout(processNextToken, opts.delay);
|
||||
}
|
||||
else {
|
||||
sequenceFinished();
|
||||
}
|
||||
lastTime = now();
|
||||
}
|
||||
else {
|
||||
setTimeout(processNextToken, opts.delay - timeElapsed);
|
||||
}
|
||||
}
|
||||
|
||||
if (!opts.delay || opts.delay <= 0) {
|
||||
// Run as fast as possible
|
||||
sequence.replace(/\{[^}]*\}|[^{]+/g, function(s){
|
||||
(localkeys[s] || $.simulate.prototype.simulateKeySequence.defaults[s] || $.simulate.prototype.simulateKeySequence.defaults.simplechar)(rng, s, opts);
|
||||
});
|
||||
sequenceFinished();
|
||||
}
|
||||
else {
|
||||
var tokenRegExp = /\{[^}]*\}|[^{]/g; // This matches curly bracket expressions or single characters
|
||||
var now = Date.now || function() { return new Date().getTime(); },
|
||||
lastTime = now();
|
||||
|
||||
processNextToken();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
$.extend($.simulate.prototype.simulateKeySequence.prototype,
|
||||
|
||||
/**
|
||||
* @lends $.simulate.prototype.simulateKeySequence.prototype
|
||||
*/
|
||||
{
|
||||
|
||||
/**
|
||||
* Maps special character char codes to IE key codes (covers IE and Webkit)
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
IEKeyCodeTable: {
|
||||
33: 49, // ! -> 1
|
||||
64: 50, // @ -> 2
|
||||
35: 51, // # -> 3
|
||||
36: 52, // $ -> 4
|
||||
37: 53, // % -> 5
|
||||
94: 54, // ^ -> 6
|
||||
38: 55, // & -> 7
|
||||
42: 56, // * -> 8
|
||||
40: 57, // ( -> 9
|
||||
41: 48, // ) -> 0
|
||||
|
||||
59: 186, // ; -> 186
|
||||
58: 186, // : -> 186
|
||||
61: 187, // = -> 187
|
||||
43: 187, // + -> 187
|
||||
44: 188, // , -> 188
|
||||
60: 188, // < -> 188
|
||||
45: 189, // - -> 189
|
||||
95: 189, // _ -> 189
|
||||
46: 190, // . -> 190
|
||||
62: 190, // > -> 190
|
||||
47: 191, // / -> 191
|
||||
63: 191, // ? -> 191
|
||||
96: 192, // ` -> 192
|
||||
126: 192, // ~ -> 192
|
||||
91: 219, // [ -> 219
|
||||
123: 219, // { -> 219
|
||||
92: 220, // \ -> 220
|
||||
124: 220, // | -> 220
|
||||
93: 221, // ] -> 221
|
||||
125: 221, // } -> 221
|
||||
39: 222, // ' -> 222
|
||||
34: 222 // " -> 222
|
||||
},
|
||||
|
||||
/**
|
||||
* Tries to convert character codes to key codes.
|
||||
* @param {Numeric} character - A character code
|
||||
* @returns {Numeric} The key code corresponding to the given character code,
|
||||
* based on the key code table of InternetExplorer. If no corresponding key code
|
||||
* could be found (which will be the case for all special characters except the common
|
||||
* ones), the character code itself is returned. However, <code>keyCode === charCode</code>
|
||||
* does not imply that no key code was found because some key codes are identical to the
|
||||
* character codes (e.g. for uppercase characters).
|
||||
* @requires $.simulate.prototype.simulateKeySequence.prototype.IEKeyCodeTable
|
||||
* @see $.simulate.prototype.simulateKeySequence.prototype.IEKeyCodeTable
|
||||
* @author julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
charToKeyCode: function(character) {
|
||||
var specialKeyCodeTable = $.simulate.prototype.simulateKeySequence.prototype.IEKeyCodeTable;
|
||||
var charCode = character.charCodeAt(0);
|
||||
|
||||
if (charCode >= 64 && charCode <= 90 || charCode >= 48 && charCode <= 57) {
|
||||
// A-Z and 0-9
|
||||
return charCode;
|
||||
}
|
||||
else if (charCode >= 97 && charCode <= 122) {
|
||||
// a-z -> A-Z
|
||||
return character.toUpperCase().charCodeAt(0);
|
||||
}
|
||||
else if (specialKeyCodeTable[charCode] !== undefined) {
|
||||
return specialKeyCodeTable[charCode];
|
||||
}
|
||||
else {
|
||||
return charCode;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// add the functions publicly so they can be overridden
|
||||
$.simulate.prototype.simulateKeySequence.defaults = {
|
||||
|
||||
/**
|
||||
* Simulates key strokes of "normal" characters (i.e. non-special sequences).
|
||||
* @param {Object} rng - bililiteRange object of the simulation target element.
|
||||
* @param {String} s - String of (simple) characters to be simulated.
|
||||
* @param {Object} opts - The key-sequence options.
|
||||
* @author Daniel Wachsstock, julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
simplechar: function (rng, s, opts){
|
||||
rng.text(s, 'end');
|
||||
if (opts.triggerKeyEvents) {
|
||||
for (var i =0; i < s.length; i += 1){
|
||||
var charCode = s.charCodeAt(i);
|
||||
var keyCode = $.simulate.prototype.simulateKeySequence.prototype.charToKeyCode(s.charAt(i));
|
||||
// a bit of cheating: rng._el is the element associated with rng.
|
||||
$(rng._el).simulate('keydown', $.extend({}, opts.eventProps, {keyCode: keyCode}));
|
||||
$(rng._el).simulate('keypress', $.extend({}, opts.eventProps,{keyCode: charCode, which: charCode, charCode: charCode}));
|
||||
$(rng._el).simulate('keyup', $.extend({}, opts.eventProps, {keyCode: keyCode}));
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Simulates key strokes of a curly opening bracket.
|
||||
* @param {Object} rng - bililiteRange object of the simulation target element.
|
||||
* @param {String} s - Ignored.
|
||||
* @param {Object} opts - The key-sequence options.
|
||||
* @author Daniel Wachsstock, julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
'{{}': function (rng, s, opts){
|
||||
$.simulate.prototype.simulateKeySequence.defaults.simplechar(rng, '{', opts);
|
||||
},
|
||||
|
||||
/**
|
||||
* Simulates hitting the enter button.
|
||||
* @param {Object} rng - bililiteRange object of the simulation target element.
|
||||
* @param {String} s - Ignored.
|
||||
* @param {Object} opts - The key-sequence options.
|
||||
* @author Daniel Wachsstock, julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
'{enter}': function (rng, s, opts){
|
||||
rng.insertEOL();
|
||||
rng.select();
|
||||
if (opts.triggerKeyEvents === true) {
|
||||
$(rng._el).simulate('keydown', $.extend({}, opts.eventProps, {keyCode: 13}));
|
||||
$(rng._el).simulate('keypress', $.extend({}, opts.eventProps, {keyCode: 13, which: 13, charCode: 13}));
|
||||
$(rng._el).simulate('keyup', $.extend({}, opts.eventProps, {keyCode: 13}));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Simulates hitting the backspace button.
|
||||
* @param {Object} rng - bililiteRange object of the simulation target element.
|
||||
* @param {String} s - Ignored.
|
||||
* @param {Object} opts - The key-sequence options.
|
||||
* @author Daniel Wachsstock, julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
'{backspace}': function (rng, s, opts){
|
||||
var b = rng.bounds();
|
||||
if (b[0] === b[1]) { rng.bounds([b[0]-1, b[0]]); } // no characters selected; it's just an insertion point. Remove the previous character
|
||||
rng.text('', 'end'); // delete the characters and update the selection
|
||||
if (opts.triggerKeyEvents === true) {
|
||||
$(rng._el).simulate('keydown', $.extend({}, opts.eventProps, {keyCode: 8}));
|
||||
$(rng._el).simulate('keyup', $.extend({}, opts.eventProps, {keyCode: 8}));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Simulates hitting the delete button.
|
||||
* @param {Object} rng - bililiteRange object of the simulation target element.
|
||||
* @param {String} s - Ignored.
|
||||
* @param {Object} opts - The key-sequence options.
|
||||
* @author Daniel Wachsstock, julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
'{del}': function (rng, s, opts){
|
||||
var b = rng.bounds();
|
||||
if (b[0] === b[1]) { rng.bounds([b[0], b[0]+1]); } // no characters selected; it's just an insertion point. Remove the next character
|
||||
rng.text('', 'end'); // delete the characters and update the selection
|
||||
if (opts.triggerKeyEvents === true) {
|
||||
$(rng._el).simulate('keydown', $.extend({}, opts.eventProps, {keyCode: 46}));
|
||||
$(rng._el).simulate('keyup', $.extend({}, opts.eventProps, {keyCode: 46}));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Simulates hitting the right arrow button.
|
||||
* @param {Object} rng - bililiteRange object of the simulation target element.
|
||||
* @param {String} s - Ignored.
|
||||
* @param {Object} opts - The key-sequence options.
|
||||
* @author Daniel Wachsstock, julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
'{rightarrow}': function (rng, s, opts){
|
||||
var b = rng.bounds();
|
||||
if (b[0] === b[1]) { b[1] += 1; } // no characters selected; it's just an insertion point. Move to the right
|
||||
rng.bounds([b[1], b[1]]).select();
|
||||
if (opts.triggerKeyEvents === true) {
|
||||
$(rng._el).simulate('keydown', $.extend({}, opts.eventProps, {keyCode: 39}));
|
||||
$(rng._el).simulate('keyup', $.extend({}, opts.eventProps, {keyCode: 39}));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Simulates hitting the left arrow button.
|
||||
* @param {Object} rng - bililiteRange object of the simulation target element.
|
||||
* @param {String} s - Ignored.
|
||||
* @param {Object} opts - The key-sequence options.
|
||||
* @author Daniel Wachsstock, julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
'{leftarrow}': function (rng, s, opts){
|
||||
var b = rng.bounds();
|
||||
if (b[0] === b[1]) { b[0] -= 1; } // no characters selected; it's just an insertion point. Move to the left
|
||||
rng.bounds([b[0], b[0]]).select();
|
||||
if (opts.triggerKeyEvents === true) {
|
||||
$(rng._el).simulate('keydown', $.extend({}, opts.eventProps, {keyCode: 37}));
|
||||
$(rng._el).simulate('keyup', $.extend({}, opts.eventProps, {keyCode: 37}));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects all characters in the target element.
|
||||
* @param {Object} rng - bililiteRange object of the simulation target element.
|
||||
* @author Daniel Wachsstock, julrich
|
||||
* @since 1.0
|
||||
*/
|
||||
'{selectall}' : function (rng){
|
||||
rng.bounds('all').select();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//####### Quirk detection #######
|
||||
if ($.simulate.ext_disableQuirkDetection !== true) { // Fixes issue #9 (https://github.com/j-ulrich/jquery-simulate-ext/issues/9)
|
||||
$(document).ready(function() {
|
||||
// delayedSpacesInNonInputGlitchToEnd
|
||||
// See issues #6 (https://github.com/j-ulrich/jquery-simulate-ext/issues/6)
|
||||
/* Append a div to the document (bililiteRange needs the element to be in the document), simulate
|
||||
* a delayed sequence containing a space in the middle and check if the space moves to the end.
|
||||
*/
|
||||
var $testDiv = $('<div/>').css({height: 1, width: 1, position: 'absolute', left: -1000, top: -1000}).appendTo('body');
|
||||
$testDiv.simulate('key-sequence', {sequence: '\xA0 \xA0', delay:1, callback: function() {
|
||||
$.simulate.prototype.quirks.delayedSpacesInNonInputGlitchToEnd = ($testDiv.text() === '\xA0\xA0 ');
|
||||
$testDiv.remove();
|
||||
}});
|
||||
});
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
Reference in New Issue
Block a user