Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
0785aeb9
Commit
0785aeb9
authored
9 years ago
by
Andy Armstrong
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #10426 from edx/andya/update-draggabilly
Upgrade draggabilly.js to fix Firefox iframe bug
parents
183fce37
18dabc33
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
1680 additions
and
782 deletions
+1680
-782
.jshintrc
+13
-5
cms/static/cms/js/require-config.js
+4
-0
cms/static/coffee/spec/main.coffee
+4
-0
cms/static/js/utils/drag_and_drop.js
+36
-31
cms/static/js_test.yml
+1
-0
common/static/js/vendor/draggabilly.pkgd.js
+1622
-746
No files found.
.jshintrc
View file @
0785aeb9
...
...
@@ -109,13 +109,18 @@
// The parameter "predef" should remain empty for this configuration file
// to remain as general as possible.
"predef": [
// jQuery
library.
// jQuery
globals
"jQuery", "$",
// Underscore.js
library.
// Underscore.js
globals
"_",
// Jasmine library.
// RequireJS globals
"define",
"require",
"RequireJS",
// Jasmine globals
"jasmine",
"describe", "xdescribe",
"it", "xit",
...
...
@@ -126,12 +131,15 @@
"waitsFor",
"runs",
// jQuery-Jasmine
library.
// jQuery-Jasmine
globals
"loadFixtures",
"appendLoadFixtures",
"readFixtures",
"setFixtures",
"appendSetFixtures",
"spyOnEvent"
"spyOnEvent",
// Miscellaneous globals
"JSON"
]
}
This diff is collapsed.
Click to expand it.
cms/static/cms/js/require-config.js
View file @
0785aeb9
...
...
@@ -17,6 +17,7 @@ require.config({
paths
:
{
"domReady"
:
"js/vendor/domReady"
,
"gettext"
:
"/i18n"
,
"json2"
:
"js/vendor/json2"
,
"mustache"
:
"js/vendor/mustache"
,
"codemirror"
:
"js/vendor/codemirror-compressed"
,
"codemirror/stex"
:
"js/vendor/CodeMirror/stex"
,
...
...
@@ -95,6 +96,9 @@ require.config({
]
},
shim
:
{
"json2"
:
{
exports
:
"JSON"
},
"gettext"
:
{
exports
:
"gettext"
},
...
...
This diff is collapsed.
Click to expand it.
cms/static/coffee/spec/main.coffee
View file @
0785aeb9
...
...
@@ -23,6 +23,7 @@ requirejs.config({
"jquery.simulate"
:
"xmodule_js/common_static/js/vendor/jquery.simulate"
,
"datepair"
:
"xmodule_js/common_static/js/vendor/timepicker/datepair"
,
"date"
:
"xmodule_js/common_static/js/vendor/date"
,
"json2"
:
"xmodule_js/common_static/js/vendor/json2"
,
"moment"
:
"xmodule_js/common_static/js/vendor/moment.min"
,
"moment-with-locales"
:
"xmodule_js/common_static/js/vendor/moment-with-locales.min"
,
"text"
:
"xmodule_js/common_static/js/vendor/requirejs/text"
,
...
...
@@ -58,6 +59,9 @@ requirejs.config({
"js/spec/test_utils"
:
"js/spec/test_utils"
,
}
shim
:
{
"json2"
:
{
exports
:
"JSON"
},
"gettext"
:
{
exports
:
"gettext"
},
...
...
This diff is collapsed.
Click to expand it.
cms/static/js/utils/drag_and_drop.js
View file @
0785aeb9
define
([
"jquery"
,
"jquery.ui"
,
"underscore"
,
"gettext"
,
"common/js/components/views/feedback_notification"
,
"draggabilly"
,
"js/utils/module"
],
function
(
$
,
ui
,
_
,
gettext
,
NotificationView
,
Draggabilly
,
ModuleUtils
)
{
define
([
"jquery"
,
"jquery.ui"
,
"underscore"
,
"json2"
,
"gettext"
,
"draggabilly"
,
"js/utils/module"
,
"common/js/components/views/feedback_notification"
],
function
(
$
,
ui
,
_
,
JSON
,
gettext
,
Draggabilly
,
ModuleUtils
,
NotificationView
)
{
'use strict'
;
var
contentDragger
=
{
var
contentDragger
=
{
droppableClasses
:
'drop-target drop-target-prepend drop-target-before drop-target-after'
,
validDropClass
:
"valid-drop"
,
expandOnDropClass
:
"expand-on-drop"
,
...
...
@@ -17,14 +18,15 @@ define(["jquery", "jquery.ui", "underscore", "gettext", "common/js/components/vi
var
eleY
=
ele
.
offset
().
top
;
var
eleYEnd
=
eleY
+
ele
.
outerHeight
();
var
containers
=
$
(
ele
.
data
(
'droppable-class'
));
var
isSibling
=
function
()
{
return
$
(
this
).
data
(
'locator'
)
!==
undefined
&&
!
$
(
this
).
is
(
ele
);
};
for
(
var
i
=
0
;
i
<
containers
.
length
;
i
++
)
{
var
container
=
$
(
containers
[
i
]);
// Exclude the 'new unit' buttons, and make sure we don't
// prepend an element to itself
var
siblings
=
container
.
children
().
filter
(
function
()
{
return
$
(
this
).
data
(
'locator'
)
!==
undefined
&&
!
$
(
this
).
is
(
ele
);
});
var
siblings
=
container
.
children
().
filter
(
isSibling
);
// If the container is collapsed, check to see if the
// element is on top of its parent list -- don't check the
// position of the container
...
...
@@ -37,8 +39,8 @@ define(["jquery", "jquery.ui", "underscore", "gettext", "common/js/components/vi
var
collapseFudge
=
10
;
if
(
Math
.
abs
(
eleY
-
parentListTop
)
<
collapseFudge
||
(
eleY
>
parentListTop
&&
eleYEnd
-
collapseFudge
<=
parentListTop
+
parentList
.
outerHeight
())
)
{
eleYEnd
-
collapseFudge
<=
parentListTop
+
parentList
.
outerHeight
())
)
{
return
{
ele
:
container
,
attachMethod
:
'prepend'
,
...
...
@@ -101,11 +103,12 @@ define(["jquery", "jquery.ui", "underscore", "gettext", "common/js/components/vi
}
else
{
// Dragging up into end of list.
if
(
j
===
siblings
.
length
-
1
&&
yChange
<
0
&&
Math
.
abs
(
eleY
-
siblingYEnd
)
<=
fudge
)
{
if
(
j
===
siblings
.
length
-
1
&&
yChange
<
0
&&
Math
.
abs
(
eleY
-
siblingYEnd
)
<=
fudge
)
{
return
{
ele
:
$sibling
,
attachMethod
:
'after'
};
ele
:
$sibling
,
attachMethod
:
'after'
};
}
// Dragging up or down into beginning of list.
else
if
(
j
===
0
&&
Math
.
abs
(
eleY
-
siblingY
)
<=
fudge
)
{
...
...
@@ -145,8 +148,8 @@ define(["jquery", "jquery.ui", "underscore", "gettext", "common/js/components/vi
// Information about the current drag.
dragState
:
{},
onDragStart
:
function
(
dragg
ie
,
event
,
pointer
)
{
var
ele
=
$
(
dragg
i
e
.
element
);
onDragStart
:
function
(
dragg
able
)
{
var
ele
=
$
(
dragg
abl
e
.
element
);
this
.
dragState
=
{
// Which element will be dropped into/onto on success
dropDestination
:
null
,
...
...
@@ -162,7 +165,9 @@ define(["jquery", "jquery.ui", "underscore", "gettext", "common/js/components/vi
if
(
!
ele
.
hasClass
(
this
.
collapsedClass
))
{
ele
.
addClass
(
this
.
collapsedClass
);
ele
.
find
(
'.expand-collapse'
).
first
().
addClass
(
'expand'
).
removeClass
(
'collapse'
);
// onDragStart gets called again after the collapse, so we can't just store a variable in the dragState.
// onDragStart gets called again after the collapse, so we can't
// just store a variable in the dragState.
ele
.
addClass
(
this
.
expandOnDropClass
);
}
...
...
@@ -171,7 +176,7 @@ define(["jquery", "jquery.ui", "underscore", "gettext", "common/js/components/vi
ele
.
removeClass
(
'was-dragging'
);
},
onDragMove
:
function
(
dragg
i
e
,
event
,
pointer
)
{
onDragMove
:
function
(
dragg
abl
e
,
event
,
pointer
)
{
// Handle scrolling of the browser.
var
scrollAmount
=
0
;
var
dragBuffer
=
10
;
...
...
@@ -186,13 +191,13 @@ define(["jquery", "jquery.ui", "underscore", "gettext", "common/js/components/vi
return
;
}
var
yChange
=
dragg
i
e
.
dragPoint
.
y
-
this
.
dragState
.
lastY
;
var
yChange
=
dragg
abl
e
.
dragPoint
.
y
-
this
.
dragState
.
lastY
;
if
(
yChange
!==
0
)
{
this
.
dragState
.
direction
=
yChange
;
}
this
.
dragState
.
lastY
=
dragg
i
e
.
dragPoint
.
y
;
this
.
dragState
.
lastY
=
dragg
abl
e
.
dragPoint
.
y
;
var
ele
=
$
(
dragg
i
e
.
element
);
var
ele
=
$
(
dragg
abl
e
.
element
);
var
destinationInfo
=
this
.
findDestination
(
ele
,
this
.
dragState
.
direction
);
var
destinationEle
=
destinationInfo
.
ele
;
this
.
dragState
.
parentList
=
destinationInfo
.
parentList
;
...
...
@@ -215,8 +220,8 @@ define(["jquery", "jquery.ui", "underscore", "gettext", "common/js/components/vi
}
},
onDragEnd
:
function
(
dragg
i
e
,
event
,
pointer
)
{
var
ele
=
$
(
dragg
i
e
.
element
);
onDragEnd
:
function
(
dragg
abl
e
,
event
,
pointer
)
{
var
ele
=
$
(
dragg
abl
e
.
element
);
var
destination
=
this
.
dragState
.
dropDestination
;
// Clear dragging state in preparation for the next event.
...
...
@@ -284,7 +289,7 @@ define(["jquery", "jquery.ui", "underscore", "gettext", "common/js/components/vi
// If drop was into a collapsed parent, the parent will have been
// expanded. Views using this class may need to track the
// collapse/expand state, so send it with the refresh callback.
var
collapsed
=
element
.
hasClass
(
this
.
collapsedClass
);
var
collapsed
=
element
.
hasClass
(
contentDragger
.
collapsedClass
);
if
(
_
.
isFunction
(
refresh
))
{
refresh
(
collapsed
);
}
};
...
...
@@ -364,20 +369,20 @@ define(["jquery", "jquery.ui", "underscore", "gettext", "common/js/components/vi
if
(
$
(
element
).
data
(
'droppable-class'
)
!==
options
.
droppableClass
)
{
$
(
element
).
data
({
'droppable-class'
:
options
.
droppableClass
,
'parent-location-selector'
:
options
.
parentLocationSelector
,
'child-selector'
:
options
.
type
,
'refresh'
:
options
.
refresh
,
'ensureChildrenRendered'
:
options
.
ensureChildrenRendered
'droppable-class'
:
options
.
droppableClass
,
'parent-location-selector'
:
options
.
parentLocationSelector
,
'child-selector'
:
options
.
type
,
'refresh'
:
options
.
refresh
,
'ensureChildrenRendered'
:
options
.
ensureChildrenRendered
});
draggable
=
new
Draggabilly
(
element
,
{
handle
:
options
.
handleClass
,
containment
:
'.wrapper-dnd'
});
draggable
.
on
(
'dragStart'
,
_
.
bind
(
contentDragger
.
onDragStart
,
contentDragger
));
draggable
.
on
(
'dragMove'
,
_
.
bind
(
contentDragger
.
onDragMove
,
contentDragger
));
draggable
.
on
(
'dragEnd'
,
_
.
bind
(
contentDragger
.
onDragEnd
,
contentDragger
));
draggable
.
on
(
'dragStart'
,
_
.
bind
(
contentDragger
.
onDragStart
,
contentDragger
,
draggable
));
draggable
.
on
(
'dragMove'
,
_
.
bind
(
contentDragger
.
onDragMove
,
contentDragger
,
draggable
));
draggable
.
on
(
'dragEnd'
,
_
.
bind
(
contentDragger
.
onDragEnd
,
contentDragger
,
draggable
));
}
}
};
...
...
This diff is collapsed.
Click to expand it.
cms/static/js_test.yml
View file @
0785aeb9
...
...
@@ -59,6 +59,7 @@ lib_paths:
-
xmodule_js/common_static/js/vendor/draggabilly.pkgd.js
-
xmodule_js/common_static/js/vendor/date.js
-
xmodule_js/common_static/js/vendor/domReady.js
-
xmodule_js/common_static/js/vendor/json2.js
-
xmodule_js/common_static/js/vendor/URI.min.js
-
xmodule_js/common_static/js/vendor/jquery.smooth-scroll.min.js
-
xmodule_js/common_static/coffee/src/jquery.immediateDescendents.js
...
...
This diff is collapsed.
Click to expand it.
common/static/js/vendor/draggabilly.pkgd.js
View file @
0785aeb9
/*!
* Draggabilly PACKAGED v1.
0.5
* Draggabilly PACKAGED v1.
2.4
* Make that shiz draggable
* http://draggabilly.desandro.com
* MIT license
*/
/**
* Bridget makes jQuery widgets
* v1.1.0
* MIT license
*/
(
function
(
window
)
{
// -------------------------- utils -------------------------- //
var
slice
=
Array
.
prototype
.
slice
;
function
noop
()
{}
// -------------------------- definition -------------------------- //
function
defineBridget
(
$
)
{
// bail if no jQuery
if
(
!
$
)
{
return
;
}
// -------------------------- addOptionMethod -------------------------- //
/**
* adds option method -> $().plugin('option', {...})
* @param {Function} PluginClass - constructor class
*/
function
addOptionMethod
(
PluginClass
)
{
// don't overwrite original option method
if
(
PluginClass
.
prototype
.
option
)
{
return
;
}
// option setter
PluginClass
.
prototype
.
option
=
function
(
opts
)
{
// bail out if not an object
if
(
!
$
.
isPlainObject
(
opts
)
){
return
;
}
this
.
options
=
$
.
extend
(
true
,
this
.
options
,
opts
);
};
}
// -------------------------- plugin bridge -------------------------- //
// helper function for logging errors
// $.error breaks jQuery chaining
var
logError
=
typeof
console
===
'undefined'
?
noop
:
function
(
message
)
{
console
.
error
(
message
);
};
/**
* jQuery plugin bridge, access methods like $elem.plugin('method')
* @param {String} namespace - plugin name
* @param {Function} PluginClass - constructor class
*/
function
bridge
(
namespace
,
PluginClass
)
{
// add to jQuery fn namespace
$
.
fn
[
namespace
]
=
function
(
options
)
{
if
(
typeof
options
===
'string'
)
{
// call plugin method when first argument is a string
// get arguments for method
var
args
=
slice
.
call
(
arguments
,
1
);
for
(
var
i
=
0
,
len
=
this
.
length
;
i
<
len
;
i
++
)
{
var
elem
=
this
[
i
];
var
instance
=
$
.
data
(
elem
,
namespace
);
if
(
!
instance
)
{
logError
(
"cannot call methods on "
+
namespace
+
" prior to initialization; "
+
"attempted to call '"
+
options
+
"'"
);
continue
;
}
if
(
!
$
.
isFunction
(
instance
[
options
]
)
||
options
.
charAt
(
0
)
===
'_'
)
{
logError
(
"no such method '"
+
options
+
"' for "
+
namespace
+
" instance"
);
continue
;
}
// trigger method with arguments
var
returnValue
=
instance
[
options
].
apply
(
instance
,
args
);
// break look and return first value if provided
if
(
returnValue
!==
undefined
)
{
return
returnValue
;
}
}
// return this if no return value
return
this
;
}
else
{
return
this
.
each
(
function
()
{
var
instance
=
$
.
data
(
this
,
namespace
);
if
(
instance
)
{
// apply options & init
instance
.
option
(
options
);
instance
.
_init
();
}
else
{
// initialize new instance
instance
=
new
PluginClass
(
this
,
options
);
$
.
data
(
this
,
namespace
,
instance
);
}
});
}
};
}
// -------------------------- bridget -------------------------- //
/**
* converts a Prototypical class into a proper jQuery plugin
* the class must have a ._init method
* @param {String} namespace - plugin name, used in $().pluginName
* @param {Function} PluginClass - constructor class
*/
$
.
bridget
=
function
(
namespace
,
PluginClass
)
{
addOptionMethod
(
PluginClass
);
bridge
(
namespace
,
PluginClass
);
};
return
$
.
bridget
;
}
// transport
if
(
typeof
define
===
'function'
&&
define
.
amd
)
{
// AMD
define
(
'jquery-bridget/jquery.bridget'
,[
'jquery'
],
defineBridget
);
}
else
if
(
typeof
exports
===
'object'
)
{
defineBridget
(
require
(
'jquery'
)
);
}
else
{
// get jquery from browser global
defineBridget
(
window
.
jQuery
);
}
})(
window
);
/*!
* classie - class helper functions
* classie v1.0.1
* class helper functions
* from bonzo https://github.com/ded/bonzo
* MIT license
*
* classie.has( elem, 'my-class' ) -> true/false
* classie.add( elem, 'my-new-class' )
...
...
@@ -14,161 +157,479 @@
* classie.toggle( elem, 'my-class' )
*/
/*jshint browser: true, strict: true, undef: true */
/*global define: false */
/*jshint browser: true, strict: true, undef: true
, unused: true
*/
/*global define: false
, module: false
*/
(
function
(
window
)
{
'use strict'
;
// class helper functions from bonzo https://github.com/ded/bonzo
function
classReg
(
className
)
{
return
new
RegExp
(
"(^|
\\
s+)"
+
className
+
"(
\\
s+|$)"
);
}
function
classReg
(
className
)
{
return
new
RegExp
(
"(^|
\\
s+)"
+
className
+
"(
\\
s+|$)"
);
}
// classList support for class management
// altho to be fair, the api sucks because it won't accept multiple classes at once
var
hasClass
,
addClass
,
removeClass
;
if
(
'classList'
in
document
.
documentElement
)
{
hasClass
=
function
(
elem
,
c
)
{
return
elem
.
classList
.
contains
(
c
);
};
addClass
=
function
(
elem
,
c
)
{
elem
.
classList
.
add
(
c
);
};
removeClass
=
function
(
elem
,
c
)
{
elem
.
classList
.
remove
(
c
);
};
}
else
{
hasClass
=
function
(
elem
,
c
)
{
return
classReg
(
c
).
test
(
elem
.
className
);
};
addClass
=
function
(
elem
,
c
)
{
if
(
!
hasClass
(
elem
,
c
)
)
{
elem
.
className
=
elem
.
className
+
' '
+
c
;
}
};
removeClass
=
function
(
elem
,
c
)
{
elem
.
className
=
elem
.
className
.
replace
(
classReg
(
c
),
' '
);
};
}
function
toggleClass
(
elem
,
c
)
{
var
fn
=
hasClass
(
elem
,
c
)
?
removeClass
:
addClass
;
fn
(
elem
,
c
);
var
hasClass
,
addClass
,
removeClass
;
if
(
'classList'
in
document
.
documentElement
)
{
hasClass
=
function
(
elem
,
c
)
{
return
elem
.
classList
.
contains
(
c
);
};
addClass
=
function
(
elem
,
c
)
{
elem
.
classList
.
add
(
c
);
};
removeClass
=
function
(
elem
,
c
)
{
elem
.
classList
.
remove
(
c
);
};
}
else
{
hasClass
=
function
(
elem
,
c
)
{
return
classReg
(
c
).
test
(
elem
.
className
);
};
addClass
=
function
(
elem
,
c
)
{
if
(
!
hasClass
(
elem
,
c
)
)
{
elem
.
className
=
elem
.
className
+
' '
+
c
;
}
var
classie
=
{
// full names
hasClass
:
hasClass
,
addClass
:
addClass
,
removeClass
:
removeClass
,
toggleClass
:
toggleClass
,
// short names
has
:
hasClass
,
add
:
addClass
,
remove
:
removeClass
,
toggle
:
toggleClass
};
};
removeClass
=
function
(
elem
,
c
)
{
elem
.
className
=
elem
.
className
.
replace
(
classReg
(
c
),
' '
);
};
}
function
toggleClass
(
elem
,
c
)
{
var
fn
=
hasClass
(
elem
,
c
)
?
removeClass
:
addClass
;
fn
(
elem
,
c
);
}
var
classie
=
{
// full names
hasClass
:
hasClass
,
addClass
:
addClass
,
removeClass
:
removeClass
,
toggleClass
:
toggleClass
,
// short names
has
:
hasClass
,
add
:
addClass
,
remove
:
removeClass
,
toggle
:
toggleClass
};
// transport
if
(
typeof
define
===
'function'
&&
define
.
amd
)
{
// AMD
define
(
"classie"
,
classie
);
}
else
{
// browser global
window
.
classie
=
classie
;
}
if
(
typeof
define
===
'function'
&&
define
.
amd
)
{
// AMD
define
(
'classie/classie'
,
classie
);
}
else
if
(
typeof
exports
===
'object'
)
{
// CommonJS
module
.
exports
=
classie
;
}
else
{
// browser global
window
.
classie
=
classie
;
}
})(
window
);
/*!
*
eventie v1.0.3
*
event binding helper
*
eventie.bind( elem, 'click', myFn )
*
eventie.unbind( elem, 'click', myFn )
*
getStyleProperty v1.0.4
*
original by kangax
*
http://perfectionkills.com/feature-testing-css-properties/
*
MIT license
*/
/*jshint browser: true,
undef: true, unused
: true */
/*global define: false */
/*jshint browser: true,
strict: true, undef
: true */
/*global define: false
, exports: false, module: false
*/
(
function
(
window
)
{
'use strict'
;
var
docElem
=
document
.
documentElement
;
var
bind
=
function
()
{};
var
prefixes
=
'Webkit Moz ms Ms O'
.
split
(
' '
);
var
docElemStyle
=
document
.
documentElement
.
style
;
if
(
docElem
.
addEventListener
)
{
bind
=
function
(
obj
,
type
,
fn
)
{
obj
.
addEventListener
(
type
,
fn
,
false
);
};
}
else
if
(
docElem
.
attachEvent
)
{
bind
=
function
(
obj
,
type
,
fn
)
{
obj
[
type
+
fn
]
=
fn
.
handleEvent
?
function
()
{
var
event
=
window
.
event
;
// add event.target
event
.
target
=
event
.
target
||
event
.
srcElement
;
fn
.
handleEvent
.
call
(
fn
,
event
);
}
:
function
()
{
var
event
=
window
.
event
;
// add event.target
event
.
target
=
event
.
target
||
event
.
srcElement
;
fn
.
call
(
obj
,
event
);
};
obj
.
attachEvent
(
"on"
+
type
,
obj
[
type
+
fn
]
);
};
}
function
getStyleProperty
(
propName
)
{
if
(
!
propName
)
{
return
;
}
var
unbind
=
function
()
{};
// test standard property first
if
(
typeof
docElemStyle
[
propName
]
===
'string'
)
{
return
propName
;
}
if
(
docElem
.
removeEventListener
)
{
unbind
=
function
(
obj
,
type
,
fn
)
{
obj
.
removeEventListener
(
type
,
fn
,
false
);
};
}
else
if
(
docElem
.
detachEvent
)
{
unbind
=
function
(
obj
,
type
,
fn
)
{
obj
.
detachEvent
(
"on"
+
type
,
obj
[
type
+
fn
]
);
try
{
delete
obj
[
type
+
fn
];
}
catch
(
err
)
{
// can't delete window object properties
obj
[
type
+
fn
]
=
undefined
;
}
};
// capitalize
propName
=
propName
.
charAt
(
0
).
toUpperCase
()
+
propName
.
slice
(
1
);
// test vendor specific properties
var
prefixed
;
for
(
var
i
=
0
,
len
=
prefixes
.
length
;
i
<
len
;
i
++
)
{
prefixed
=
prefixes
[
i
]
+
propName
;
if
(
typeof
docElemStyle
[
prefixed
]
===
'string'
)
{
return
prefixed
;
}
}
}
// transport
if
(
typeof
define
===
'function'
&&
define
.
amd
)
{
// AMD
define
(
'get-style-property/get-style-property'
,[],
function
()
{
return
getStyleProperty
;
});
}
else
if
(
typeof
exports
===
'object'
)
{
// CommonJS for Component
module
.
exports
=
getStyleProperty
;
}
else
{
// browser global
window
.
getStyleProperty
=
getStyleProperty
;
}
})(
window
);
/*!
* getSize v1.2.2
* measure size of elements
* MIT license
*/
/*jshint browser: true, strict: true, undef: true, unused: true */
/*global define: false, exports: false, require: false, module: false, console: false */
(
function
(
window
,
undefined
)
{
var
eventie
=
{
bind
:
bind
,
unbind
:
unbind
};
// -------------------------- helpers -------------------------- //
// get a number from a string, not a percentage
function
getStyleSize
(
value
)
{
var
num
=
parseFloat
(
value
);
// not a percent like '100%', and a number
var
isValid
=
value
.
indexOf
(
'%'
)
===
-
1
&&
!
isNaN
(
num
);
return
isValid
&&
num
;
}
function
noop
()
{}
var
logError
=
typeof
console
===
'undefined'
?
noop
:
function
(
message
)
{
console
.
error
(
message
);
};
// -------------------------- measurements -------------------------- //
var
measurements
=
[
'paddingLeft'
,
'paddingRight'
,
'paddingTop'
,
'paddingBottom'
,
'marginLeft'
,
'marginRight'
,
'marginTop'
,
'marginBottom'
,
'borderLeftWidth'
,
'borderRightWidth'
,
'borderTopWidth'
,
'borderBottomWidth'
];
function
getZeroSize
()
{
var
size
=
{
width
:
0
,
height
:
0
,
innerWidth
:
0
,
innerHeight
:
0
,
outerWidth
:
0
,
outerHeight
:
0
};
for
(
var
i
=
0
,
len
=
measurements
.
length
;
i
<
len
;
i
++
)
{
var
measurement
=
measurements
[
i
];
size
[
measurement
]
=
0
;
}
return
size
;
}
function
defineGetSize
(
getStyleProperty
)
{
// -------------------------- setup -------------------------- //
var
isSetup
=
false
;
var
getStyle
,
boxSizingProp
,
isBoxSizeOuter
;
/**
* setup vars and functions
* do it on initial getSize(), rather than on script load
* For Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=548397
*/
function
setup
()
{
// setup once
if
(
isSetup
)
{
return
;
}
isSetup
=
true
;
var
getComputedStyle
=
window
.
getComputedStyle
;
getStyle
=
(
function
()
{
var
getStyleFn
=
getComputedStyle
?
function
(
elem
)
{
return
getComputedStyle
(
elem
,
null
);
}
:
function
(
elem
)
{
return
elem
.
currentStyle
;
};
return
function
getStyle
(
elem
)
{
var
style
=
getStyleFn
(
elem
);
if
(
!
style
)
{
logError
(
'Style returned '
+
style
+
'. Are you running this code in a hidden iframe on Firefox? '
+
'See http://bit.ly/getsizebug1'
);
}
return
style
;
};
})();
// -------------------------- box sizing -------------------------- //
boxSizingProp
=
getStyleProperty
(
'boxSizing'
);
/**
* WebKit measures the outer-width on style.width on border-box elems
* IE & Firefox measures the inner-width
*/
if
(
boxSizingProp
)
{
var
div
=
document
.
createElement
(
'div'
);
div
.
style
.
width
=
'200px'
;
div
.
style
.
padding
=
'1px 2px 3px 4px'
;
div
.
style
.
borderStyle
=
'solid'
;
div
.
style
.
borderWidth
=
'1px 2px 3px 4px'
;
div
.
style
[
boxSizingProp
]
=
'border-box'
;
var
body
=
document
.
body
||
document
.
documentElement
;
body
.
appendChild
(
div
);
var
style
=
getStyle
(
div
);
isBoxSizeOuter
=
getStyleSize
(
style
.
width
)
===
200
;
body
.
removeChild
(
div
);
}
}
// -------------------------- getSize -------------------------- //
function
getSize
(
elem
)
{
setup
();
// use querySeletor if elem is string
if
(
typeof
elem
===
'string'
)
{
elem
=
document
.
querySelector
(
elem
);
}
// do not proceed on non-objects
if
(
!
elem
||
typeof
elem
!==
'object'
||
!
elem
.
nodeType
)
{
return
;
}
var
style
=
getStyle
(
elem
);
// if hidden, everything is 0
if
(
style
.
display
===
'none'
)
{
return
getZeroSize
();
}
var
size
=
{};
size
.
width
=
elem
.
offsetWidth
;
size
.
height
=
elem
.
offsetHeight
;
var
isBorderBox
=
size
.
isBorderBox
=
!!
(
boxSizingProp
&&
style
[
boxSizingProp
]
&&
style
[
boxSizingProp
]
===
'border-box'
);
// get all measurements
for
(
var
i
=
0
,
len
=
measurements
.
length
;
i
<
len
;
i
++
)
{
var
measurement
=
measurements
[
i
];
var
value
=
style
[
measurement
];
value
=
mungeNonPixel
(
elem
,
value
);
var
num
=
parseFloat
(
value
);
// any 'auto', 'medium' value will be 0
size
[
measurement
]
=
!
isNaN
(
num
)
?
num
:
0
;
}
var
paddingWidth
=
size
.
paddingLeft
+
size
.
paddingRight
;
var
paddingHeight
=
size
.
paddingTop
+
size
.
paddingBottom
;
var
marginWidth
=
size
.
marginLeft
+
size
.
marginRight
;
var
marginHeight
=
size
.
marginTop
+
size
.
marginBottom
;
var
borderWidth
=
size
.
borderLeftWidth
+
size
.
borderRightWidth
;
var
borderHeight
=
size
.
borderTopWidth
+
size
.
borderBottomWidth
;
var
isBorderBoxSizeOuter
=
isBorderBox
&&
isBoxSizeOuter
;
// overwrite width and height if we can get it from style
var
styleWidth
=
getStyleSize
(
style
.
width
);
if
(
styleWidth
!==
false
)
{
size
.
width
=
styleWidth
+
// add padding and border unless it's already including it
(
isBorderBoxSizeOuter
?
0
:
paddingWidth
+
borderWidth
);
}
var
styleHeight
=
getStyleSize
(
style
.
height
);
if
(
styleHeight
!==
false
)
{
size
.
height
=
styleHeight
+
// add padding and border unless it's already including it
(
isBorderBoxSizeOuter
?
0
:
paddingHeight
+
borderHeight
);
}
size
.
innerWidth
=
size
.
width
-
(
paddingWidth
+
borderWidth
);
size
.
innerHeight
=
size
.
height
-
(
paddingHeight
+
borderHeight
);
size
.
outerWidth
=
size
.
width
+
marginWidth
;
size
.
outerHeight
=
size
.
height
+
marginHeight
;
return
size
;
}
// IE8 returns percent values, not pixels
// taken from jQuery's curCSS
function
mungeNonPixel
(
elem
,
value
)
{
// IE8 and has percent value
if
(
window
.
getComputedStyle
||
value
.
indexOf
(
'%'
)
===
-
1
)
{
return
value
;
}
var
style
=
elem
.
style
;
// Remember the original values
var
left
=
style
.
left
;
var
rs
=
elem
.
runtimeStyle
;
var
rsLeft
=
rs
&&
rs
.
left
;
// Put in the new values to get a computed value out
if
(
rsLeft
)
{
rs
.
left
=
elem
.
currentStyle
.
left
;
}
style
.
left
=
value
;
value
=
style
.
pixelLeft
;
// Revert the changed values
style
.
left
=
left
;
if
(
rsLeft
)
{
rs
.
left
=
rsLeft
;
}
return
value
;
}
return
getSize
;
}
// transport
if
(
typeof
define
===
'function'
&&
define
.
amd
)
{
// AMD
define
(
"eventie"
,
eventie
);
}
else
{
// browser global
window
.
eventie
=
eventie
;
}
if
(
typeof
define
===
'function'
&&
define
.
amd
)
{
// AMD for RequireJS
define
(
'get-size/get-size'
,[
'get-style-property/get-style-property'
],
defineGetSize
);
}
else
if
(
typeof
exports
===
'object'
)
{
// CommonJS for Component
module
.
exports
=
defineGetSize
(
require
(
'desandro-get-style-property'
)
);
}
else
{
// browser global
window
.
getSize
=
defineGetSize
(
window
.
getStyleProperty
);
}
})(
this
);
})(
window
);
/*!
* EventEmitter v4.2.4 - git.io/ee
* Oliver Caldwell
* eventie v1.0.6
* event binding helper
* eventie.bind( elem, 'click', myFn )
* eventie.unbind( elem, 'click', myFn )
* MIT license
*/
/*jshint browser: true, undef: true, unused: true */
/*global define: false, module: false */
(
function
(
window
)
{
var
docElem
=
document
.
documentElement
;
var
bind
=
function
()
{};
function
getIEEvent
(
obj
)
{
var
event
=
window
.
event
;
// add event.target
event
.
target
=
event
.
target
||
event
.
srcElement
||
obj
;
return
event
;
}
if
(
docElem
.
addEventListener
)
{
bind
=
function
(
obj
,
type
,
fn
)
{
obj
.
addEventListener
(
type
,
fn
,
false
);
};
}
else
if
(
docElem
.
attachEvent
)
{
bind
=
function
(
obj
,
type
,
fn
)
{
obj
[
type
+
fn
]
=
fn
.
handleEvent
?
function
()
{
var
event
=
getIEEvent
(
obj
);
fn
.
handleEvent
.
call
(
fn
,
event
);
}
:
function
()
{
var
event
=
getIEEvent
(
obj
);
fn
.
call
(
obj
,
event
);
};
obj
.
attachEvent
(
"on"
+
type
,
obj
[
type
+
fn
]
);
};
}
var
unbind
=
function
()
{};
if
(
docElem
.
removeEventListener
)
{
unbind
=
function
(
obj
,
type
,
fn
)
{
obj
.
removeEventListener
(
type
,
fn
,
false
);
};
}
else
if
(
docElem
.
detachEvent
)
{
unbind
=
function
(
obj
,
type
,
fn
)
{
obj
.
detachEvent
(
"on"
+
type
,
obj
[
type
+
fn
]
);
try
{
delete
obj
[
type
+
fn
];
}
catch
(
err
)
{
// can't delete window object properties
obj
[
type
+
fn
]
=
undefined
;
}
};
}
var
eventie
=
{
bind
:
bind
,
unbind
:
unbind
};
// ----- module definition ----- //
if
(
typeof
define
===
'function'
&&
define
.
amd
)
{
// AMD
define
(
'eventie/eventie'
,
eventie
);
}
else
if
(
typeof
exports
===
'object'
)
{
// CommonJS
module
.
exports
=
eventie
;
}
else
{
// browser global
window
.
eventie
=
eventie
;
}
})(
window
);
/*!
* EventEmitter v4.2.11 - git.io/ee
* Unlicense - http://unlicense.org/
* Oliver Caldwell - http://oli.me.uk/
* @preserve
*/
(
function
()
{
'use strict'
;
;
(
function
()
{
/**
* Class for managing events.
...
...
@@ -179,12 +640,12 @@
function
EventEmitter
()
{}
// Shortcuts to improve speed and size
// Easy access to the prototype
var
proto
=
EventEmitter
.
prototype
;
var
exports
=
this
;
var
originalGlobalValue
=
exports
.
EventEmitter
;
/**
* Finds the index of the listener for the event in it
'
s storage array.
* Finds the index of the listener for the event in its storage array.
*
* @param {Function[]} listeners Array of listeners to search through.
* @param {Function} listener Method to look for.
...
...
@@ -231,7 +692,7 @@
// Return a concatenated array of all matching events if
// the selector is a regular expression.
if
(
typeof
evt
===
'object'
)
{
if
(
evt
instanceof
RegExp
)
{
response
=
{};
for
(
key
in
events
)
{
if
(
events
.
hasOwnProperty
(
key
)
&&
evt
.
test
(
key
))
{
...
...
@@ -315,7 +776,7 @@
/**
* Semi-alias of addListener. It will add a listener that will be
* automatically removed after it
'
s first execution.
* automatically removed after its first execution.
*
* @param {String|RegExp} evt Name of the event to attach the listener to.
* @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
...
...
@@ -437,7 +898,7 @@
var
single
=
remove
?
this
.
removeListener
:
this
.
addListener
;
var
multiple
=
remove
?
this
.
removeListeners
:
this
.
addListeners
;
// If evt is an object then pass each of it
'
s properties to this method
// If evt is an object then pass each of its properties to this method
if
(
typeof
evt
===
'object'
&&
!
(
evt
instanceof
RegExp
))
{
for
(
i
in
evt
)
{
if
(
evt
.
hasOwnProperty
(
i
)
&&
(
value
=
evt
[
i
]))
{
...
...
@@ -484,7 +945,7 @@
// Remove all listeners for the specified event
delete
events
[
evt
];
}
else
if
(
type
===
'object'
)
{
else
if
(
evt
instanceof
RegExp
)
{
// Remove all events matching the regex.
for
(
key
in
events
)
{
if
(
events
.
hasOwnProperty
(
key
)
&&
evt
.
test
(
key
))
{
...
...
@@ -609,9 +1070,19 @@
return
this
.
_events
||
(
this
.
_events
=
{});
};
/**
* Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
*
* @return {Function} Non conflicting EventEmitter class.
*/
EventEmitter
.
noConflict
=
function
noConflict
()
{
exports
.
EventEmitter
=
originalGlobalValue
;
return
EventEmitter
;
};
// Expose the class either via AMD, CommonJS or the global object
if
(
typeof
define
===
'function'
&&
define
.
amd
)
{
define
(
"EventEmitter"
,
function
()
{
define
(
'eventEmitter/EventEmitter'
,[],
function
()
{
return
EventEmitter
;
});
}
...
...
@@ -619,758 +1090,1164 @@
module
.
exports
=
EventEmitter
;
}
else
{
thi
s
.
EventEmitter
=
EventEmitter
;
export
s
.
EventEmitter
=
EventEmitter
;
}
}.
call
(
this
));
/*!
* getStyleProperty by kangax
* http://perfectionkills.com/feature-testing-css-properties/
* Unipointer v1.1.0
* base class for doing one thing with pointer event
* MIT license
*/
/*jshint browser: true,
strict: true, undef
: true */
/*global
s defin
e: false */
/*jshint browser: true,
undef: true, unused: true, strict
: true */
/*global
define: false, module: false, requir
e: false */
(
function
(
window
)
{
(
function
(
window
,
factory
)
{
// universal module definition
'use strict'
;
if
(
typeof
define
==
'function'
&&
define
.
amd
)
{
// AMD
define
(
'unipointer/unipointer'
,[
'eventEmitter/EventEmitter'
,
'eventie/eventie'
],
function
(
EventEmitter
,
eventie
)
{
return
factory
(
window
,
EventEmitter
,
eventie
);
});
}
else
if
(
typeof
exports
==
'object'
)
{
// CommonJS
module
.
exports
=
factory
(
window
,
require
(
'wolfy87-eventemitter'
),
require
(
'eventie'
)
);
}
else
{
// browser global
window
.
Unipointer
=
factory
(
window
,
window
.
EventEmitter
,
window
.
eventie
);
}
var
prefixes
=
'Webkit Moz ms Ms O'
.
split
(
' '
);
var
docElemStyle
=
document
.
documentElement
.
style
;
}(
window
,
function
factory
(
window
,
EventEmitter
,
eventie
)
{
function
getStyleProperty
(
propName
)
{
if
(
!
propName
)
{
return
;
}
// test standard property first
if
(
typeof
docElemStyle
[
propName
]
===
'string'
)
{
return
propName
;
}
// capitalize
propName
=
propName
.
charAt
(
0
).
toUpperCase
()
+
propName
.
slice
(
1
);
function
noop
()
{}
// test vendor specific properties
var
prefixed
;
for
(
var
i
=
0
,
len
=
prefixes
.
length
;
i
<
len
;
i
++
)
{
prefixed
=
prefixes
[
i
]
+
propName
;
if
(
typeof
docElemStyle
[
prefixed
]
===
'string'
)
{
return
prefixed
;
}
}
}
function
Unipointer
()
{}
// transport
if
(
typeof
define
===
'function'
&&
define
.
amd
)
{
// AMD
define
(
"getStyleProperty"
,
function
()
{
return
getStyleProperty
;
});
}
else
{
// browser global
window
.
getStyleProperty
=
getStyleProperty
;
// inherit EventEmitter
Unipointer
.
prototype
=
new
EventEmitter
();
Unipointer
.
prototype
.
bindStartEvent
=
function
(
elem
)
{
this
.
_bindStartEvent
(
elem
,
true
);
};
Unipointer
.
prototype
.
unbindStartEvent
=
function
(
elem
)
{
this
.
_bindStartEvent
(
elem
,
false
);
};
/**
* works as unbinder, as you can ._bindStart( false ) to unbind
* @param {Boolean} isBind - will unbind if falsey
*/
Unipointer
.
prototype
.
_bindStartEvent
=
function
(
elem
,
isBind
)
{
// munge isBind, default to true
isBind
=
isBind
===
undefined
?
true
:
!!
isBind
;
var
bindMethod
=
isBind
?
'bind'
:
'unbind'
;
if
(
window
.
navigator
.
pointerEnabled
)
{
// W3C Pointer Events, IE11. See https://coderwall.com/p/mfreca
eventie
[
bindMethod
](
elem
,
'pointerdown'
,
this
);
}
else
if
(
window
.
navigator
.
msPointerEnabled
)
{
// IE10 Pointer Events
eventie
[
bindMethod
](
elem
,
'MSPointerDown'
,
this
);
}
else
{
// listen for both, for devices like Chrome Pixel
eventie
[
bindMethod
](
elem
,
'mousedown'
,
this
);
eventie
[
bindMethod
](
elem
,
'touchstart'
,
this
);
}
};
// trigger handler methods for events
Unipointer
.
prototype
.
handleEvent
=
function
(
event
)
{
var
method
=
'on'
+
event
.
type
;
if
(
this
[
method
]
)
{
this
[
method
](
event
);
}
};
// returns the touch that we're keeping track of
Unipointer
.
prototype
.
getTouch
=
function
(
touches
)
{
for
(
var
i
=
0
,
len
=
touches
.
length
;
i
<
len
;
i
++
)
{
var
touch
=
touches
[
i
];
if
(
touch
.
identifier
==
this
.
pointerIdentifier
)
{
return
touch
;
}
}
};
})(
window
);
// ----- start event ----- //
Unipointer
.
prototype
.
onmousedown
=
function
(
event
)
{
// dismiss clicks from right or middle buttons
var
button
=
event
.
button
;
if
(
button
&&
(
button
!==
0
&&
button
!==
1
)
)
{
return
;
}
this
.
_pointerDown
(
event
,
event
);
};
Unipointer
.
prototype
.
ontouchstart
=
function
(
event
)
{
this
.
_pointerDown
(
event
,
event
.
changedTouches
[
0
]
);
};
Unipointer
.
prototype
.
onMSPointerDown
=
Unipointer
.
prototype
.
onpointerdown
=
function
(
event
)
{
this
.
_pointerDown
(
event
,
event
);
};
/**
* getSize v1.1.4
* measure size of elements
* pointer start
* @param {Event} event
* @param {Event or Touch} pointer
*/
Unipointer
.
prototype
.
_pointerDown
=
function
(
event
,
pointer
)
{
// dismiss other pointers
if
(
this
.
isPointerDown
)
{
return
;
}
this
.
isPointerDown
=
true
;
// save pointer identifier to match up touch events
this
.
pointerIdentifier
=
pointer
.
pointerId
!==
undefined
?
// pointerId for pointer events, touch.indentifier for touch events
pointer
.
pointerId
:
pointer
.
identifier
;
this
.
pointerDown
(
event
,
pointer
);
};
Unipointer
.
prototype
.
pointerDown
=
function
(
event
,
pointer
)
{
this
.
_bindPostStartEvents
(
event
);
this
.
emitEvent
(
'pointerDown'
,
[
event
,
pointer
]
);
};
// hash of events to be bound after start event
var
postStartEvents
=
{
mousedown
:
[
'mousemove'
,
'mouseup'
],
touchstart
:
[
'touchmove'
,
'touchend'
,
'touchcancel'
],
pointerdown
:
[
'pointermove'
,
'pointerup'
,
'pointercancel'
],
MSPointerDown
:
[
'MSPointerMove'
,
'MSPointerUp'
,
'MSPointerCancel'
]
};
Unipointer
.
prototype
.
_bindPostStartEvents
=
function
(
event
)
{
if
(
!
event
)
{
return
;
}
// get proper events to match start event
var
events
=
postStartEvents
[
event
.
type
];
// IE8 needs to be bound to document
var
node
=
event
.
preventDefault
?
window
:
document
;
// bind events to node
for
(
var
i
=
0
,
len
=
events
.
length
;
i
<
len
;
i
++
)
{
var
evnt
=
events
[
i
];
eventie
.
bind
(
node
,
evnt
,
this
);
}
// save these arguments
this
.
_boundPointerEvents
=
{
events
:
events
,
node
:
node
};
};
Unipointer
.
prototype
.
_unbindPostStartEvents
=
function
()
{
var
args
=
this
.
_boundPointerEvents
;
// IE8 can trigger dragEnd twice, check for _boundEvents
if
(
!
args
||
!
args
.
events
)
{
return
;
}
for
(
var
i
=
0
,
len
=
args
.
events
.
length
;
i
<
len
;
i
++
)
{
var
event
=
args
.
events
[
i
];
eventie
.
unbind
(
args
.
node
,
event
,
this
);
}
delete
this
.
_boundPointerEvents
;
};
/*jshint browser: true, strict: true, undef: true, unused: true */
/*global define: false */
// ----- move event ----- //
(
function
(
window
,
undefined
)
{
Unipointer
.
prototype
.
onmousemove
=
function
(
event
)
{
this
.
_pointerMove
(
event
,
event
);
};
'use strict'
;
Unipointer
.
prototype
.
onMSPointerMove
=
Unipointer
.
prototype
.
onpointermove
=
function
(
event
)
{
if
(
event
.
pointerId
==
this
.
pointerIdentifier
)
{
this
.
_pointerMove
(
event
,
event
);
}
};
// -------------------------- helpers -------------------------- //
Unipointer
.
prototype
.
ontouchmove
=
function
(
event
)
{
var
touch
=
this
.
getTouch
(
event
.
changedTouches
);
if
(
touch
)
{
this
.
_pointerMove
(
event
,
touch
);
}
};
var
defView
=
document
.
defaultView
;
/**
* pointer move
* @param {Event} event
* @param {Event or Touch} pointer
* @private
*/
Unipointer
.
prototype
.
_pointerMove
=
function
(
event
,
pointer
)
{
this
.
pointerMove
(
event
,
pointer
);
};
var
getStyle
=
defView
&&
defView
.
getComputedStyle
?
function
(
elem
)
{
return
defView
.
getComputedStyle
(
elem
,
null
);
}
:
function
(
elem
)
{
return
elem
.
currentStyle
;
};
// public
Unipointer
.
prototype
.
pointerMove
=
function
(
event
,
pointer
)
{
this
.
emitEvent
(
'pointerMove'
,
[
event
,
pointer
]
);
};
// get a number from a string, not a percentage
function
getStyleSize
(
value
)
{
var
num
=
parseFloat
(
value
);
// not a percent like '100%', and a number
var
isValid
=
value
.
indexOf
(
'%'
)
===
-
1
&&
!
isNaN
(
num
);
return
isValid
&&
num
;
}
// ----- end event ----- //
// -------------------------- measurements -------------------------- //
var
measurements
=
[
'paddingLeft'
,
'paddingRight'
,
'paddingTop'
,
'paddingBottom'
,
'marginLeft'
,
'marginRight'
,
'marginTop'
,
'marginBottom'
,
'borderLeftWidth'
,
'borderRightWidth'
,
'borderTopWidth'
,
'borderBottomWidth'
];
function
getZeroSize
()
{
var
size
=
{
width
:
0
,
height
:
0
,
innerWidth
:
0
,
innerHeight
:
0
,
outerWidth
:
0
,
outerHeight
:
0
};
for
(
var
i
=
0
,
len
=
measurements
.
length
;
i
<
len
;
i
++
)
{
var
measurement
=
measurements
[
i
];
size
[
measurement
]
=
0
;
}
return
size
;
}
Unipointer
.
prototype
.
onmouseup
=
function
(
event
)
{
this
.
_pointerUp
(
event
,
event
);
};
Unipointer
.
prototype
.
onMSPointerUp
=
Unipointer
.
prototype
.
onpointerup
=
function
(
event
)
{
if
(
event
.
pointerId
==
this
.
pointerIdentifier
)
{
this
.
_pointerUp
(
event
,
event
);
}
};
Unipointer
.
prototype
.
ontouchend
=
function
(
event
)
{
var
touch
=
this
.
getTouch
(
event
.
changedTouches
);
if
(
touch
)
{
this
.
_pointerUp
(
event
,
touch
);
}
};
function
defineGetSize
(
getStyleProperty
)
{
/**
* pointer up
* @param {Event} event
* @param {Event or Touch} pointer
* @private
*/
Unipointer
.
prototype
.
_pointerUp
=
function
(
event
,
pointer
)
{
this
.
_pointerDone
();
this
.
pointerUp
(
event
,
pointer
);
};
// public
Unipointer
.
prototype
.
pointerUp
=
function
(
event
,
pointer
)
{
this
.
emitEvent
(
'pointerUp'
,
[
event
,
pointer
]
);
};
// ----- pointer done ----- //
// triggered on pointer up & pointer cancel
Unipointer
.
prototype
.
_pointerDone
=
function
()
{
// reset properties
this
.
isPointerDown
=
false
;
delete
this
.
pointerIdentifier
;
// remove events
this
.
_unbindPostStartEvents
();
this
.
pointerDone
();
};
Unipointer
.
prototype
.
pointerDone
=
noop
;
// ----- pointer cancel ----- //
Unipointer
.
prototype
.
onMSPointerCancel
=
Unipointer
.
prototype
.
onpointercancel
=
function
(
event
)
{
if
(
event
.
pointerId
==
this
.
pointerIdentifier
)
{
this
.
_pointerCancel
(
event
,
event
);
}
};
Unipointer
.
prototype
.
ontouchcancel
=
function
(
event
)
{
var
touch
=
this
.
getTouch
(
event
.
changedTouches
);
if
(
touch
)
{
this
.
_pointerCancel
(
event
,
touch
);
}
};
// -------------------------- box sizing -------------------------- //
/**
* pointer cancel
* @param {Event} event
* @param {Event or Touch} pointer
* @private
*/
Unipointer
.
prototype
.
_pointerCancel
=
function
(
event
,
pointer
)
{
this
.
_pointerDone
();
this
.
pointerCancel
(
event
,
pointer
);
};
var
boxSizingProp
=
getStyleProperty
(
'boxSizing'
);
var
isBoxSizeOuter
;
// public
Unipointer
.
prototype
.
pointerCancel
=
function
(
event
,
pointer
)
{
this
.
emitEvent
(
'pointerCancel'
,
[
event
,
pointer
]
);
};
/**
* WebKit measures the outer-width on style.width on border-box elems
* IE & Firefox measures the inner-width
*/
(
function
()
{
if
(
!
boxSizingProp
)
{
return
;
}
// ----- ----- //
var
div
=
document
.
createElement
(
'div'
);
div
.
style
.
width
=
'200px'
;
div
.
style
.
padding
=
'1px 2px 3px 4px'
;
div
.
style
.
borderStyle
=
'solid'
;
div
.
style
.
borderWidth
=
'1px 2px 3px 4px'
;
div
.
style
[
boxSizingProp
]
=
'border-box'
;
// utility function for getting x/y cooridinates from event, because IE8
Unipointer
.
getPointerPoint
=
function
(
pointer
)
{
return
{
x
:
pointer
.
pageX
!==
undefined
?
pointer
.
pageX
:
pointer
.
clientX
,
y
:
pointer
.
pageY
!==
undefined
?
pointer
.
pageY
:
pointer
.
clientY
};
};
var
body
=
document
.
body
||
document
.
documentElement
;
body
.
appendChild
(
div
);
var
style
=
getStyle
(
div
);
// ----- ----- //
isBoxSizeOuter
=
getStyleSize
(
style
.
width
)
===
200
;
body
.
removeChild
(
div
);
})();
return
Unipointer
;
}));
// -------------------------- getSize -------------------------- //
/*!
* Unidragger v1.1.0
* Draggable base class
* MIT license
*/
function
getSize
(
elem
)
{
// use querySeletor if elem is string
if
(
typeof
elem
===
'string'
)
{
elem
=
document
.
querySelector
(
elem
);
}
/*jshint browser: true, unused: true, undef: true, strict: true */
(
function
(
window
,
factory
)
{
/*global define: false, module: false, require: false */
// universal module definition
if
(
typeof
define
==
'function'
&&
define
.
amd
)
{
// AMD
define
(
'unidragger/unidragger'
,[
'eventie/eventie'
,
'unipointer/unipointer'
],
function
(
eventie
,
Unipointer
)
{
return
factory
(
window
,
eventie
,
Unipointer
);
});
}
else
if
(
typeof
exports
==
'object'
)
{
// CommonJS
module
.
exports
=
factory
(
window
,
require
(
'eventie'
),
require
(
'unipointer'
)
);
}
else
{
// browser global
window
.
Unidragger
=
factory
(
window
,
window
.
eventie
,
window
.
Unipointer
);
}
}(
window
,
function
factory
(
window
,
eventie
,
Unipointer
)
{
// ----- ----- //
function
noop
()
{}
// handle IE8 prevent default
function
preventDefaultEvent
(
event
)
{
if
(
event
.
preventDefault
)
{
event
.
preventDefault
();
}
else
{
event
.
returnValue
=
false
;
}
}
function
getParentLink
(
elem
)
{
while
(
elem
!=
document
.
body
)
{
elem
=
elem
.
parentNode
;
if
(
elem
.
nodeName
==
'A'
)
{
return
elem
;
}
}
}
// do not proceed on non-objects
if
(
!
elem
||
typeof
elem
!==
'object'
||
!
elem
.
nodeType
)
{
return
;
}
// -------------------------- Unidragger -------------------------- //
var
style
=
getStyle
(
elem
);
function
Unidragger
()
{}
// if hidden, everything is 0
if
(
style
.
display
===
'none'
)
{
return
getZeroSize
();
}
// inherit Unipointer & EventEmitter
Unidragger
.
prototype
=
new
Unipointer
();
var
size
=
{};
size
.
width
=
elem
.
offsetWidth
;
size
.
height
=
elem
.
offsetHeight
;
// ----- bind start ----- //
var
isBorderBox
=
size
.
isBorderBox
=
!!
(
boxSizingProp
&&
style
[
boxSizingProp
]
&&
style
[
boxSizingProp
]
===
'border-box'
);
Unidragger
.
prototype
.
bindHandles
=
function
()
{
this
.
_bindHandles
(
true
);
};
// get all measurements
for
(
var
i
=
0
,
len
=
measurements
.
length
;
i
<
len
;
i
++
)
{
var
measurement
=
measurements
[
i
];
var
value
=
style
[
measurement
];
var
num
=
parseFloat
(
value
);
// any 'auto', 'medium' value will be 0
size
[
measurement
]
=
!
isNaN
(
num
)
?
num
:
0
;
}
Unidragger
.
prototype
.
unbindHandles
=
function
()
{
this
.
_bindHandles
(
false
);
};
var
paddingWidth
=
size
.
paddingLeft
+
size
.
paddingRight
;
var
paddingHeight
=
size
.
paddingTop
+
size
.
paddingBottom
;
var
marginWidth
=
size
.
marginLeft
+
size
.
marginRight
;
var
marginHeight
=
size
.
marginTop
+
size
.
marginBottom
;
var
borderWidth
=
size
.
borderLeftWidth
+
size
.
borderRightWidth
;
var
borderHeight
=
size
.
borderTopWidth
+
size
.
borderBottomWidth
;
var
isBorderBoxSizeOuter
=
isBorderBox
&&
isBoxSizeOuter
;
// overwrite width and height if we can get it from style
var
styleWidth
=
getStyleSize
(
style
.
width
);
if
(
styleWidth
!==
false
)
{
size
.
width
=
styleWidth
+
// add padding and border unless it's already including it
(
isBorderBoxSizeOuter
?
0
:
paddingWidth
+
borderWidth
);
}
var
navigator
=
window
.
navigator
;
/**
* works as unbinder, as you can .bindHandles( false ) to unbind
* @param {Boolean} isBind - will unbind if falsey
*/
Unidragger
.
prototype
.
_bindHandles
=
function
(
isBind
)
{
// munge isBind, default to true
isBind
=
isBind
===
undefined
?
true
:
!!
isBind
;
// extra bind logic
var
binderExtra
;
if
(
navigator
.
pointerEnabled
)
{
binderExtra
=
function
(
handle
)
{
// disable scrolling on the element
handle
.
style
.
touchAction
=
isBind
?
'none'
:
''
;
};
}
else
if
(
navigator
.
msPointerEnabled
)
{
binderExtra
=
function
(
handle
)
{
// disable scrolling on the element
handle
.
style
.
msTouchAction
=
isBind
?
'none'
:
''
;
};
}
else
{
binderExtra
=
function
()
{
// TODO re-enable img.ondragstart when unbinding
if
(
isBind
)
{
disableImgOndragstart
(
handle
);
}
};
}
// bind each handle
var
bindMethod
=
isBind
?
'bind'
:
'unbind'
;
for
(
var
i
=
0
,
len
=
this
.
handles
.
length
;
i
<
len
;
i
++
)
{
var
handle
=
this
.
handles
[
i
];
this
.
_bindStartEvent
(
handle
,
isBind
);
binderExtra
(
handle
);
eventie
[
bindMethod
](
handle
,
'click'
,
this
);
}
};
var
styleHeight
=
getStyleSize
(
style
.
height
);
if
(
styleHeight
!==
false
)
{
size
.
height
=
styleHeight
+
// add padding and border unless it's already including it
(
isBorderBoxSizeOuter
?
0
:
paddingHeight
+
borderHeight
);
}
// remove default dragging interaction on all images in IE8
// IE8 does its own drag thing on images, which messes stuff up
size
.
innerWidth
=
size
.
width
-
(
paddingWidth
+
borderWidth
);
size
.
innerHeight
=
size
.
height
-
(
paddingHeight
+
borderHeight
);
function
noDragStart
()
{
return
false
;
}
size
.
outerWidth
=
size
.
width
+
marginWidth
;
size
.
outerHeight
=
size
.
height
+
marginHeigh
t
;
// TODO replace this with a IE8 test
var
isIE8
=
'attachEvent'
in
document
.
documentElemen
t
;
return
size
;
}
// IE8 only
var
disableImgOndragstart
=
!
isIE8
?
noop
:
function
(
handle
)
{
return
getSize
;
if
(
handle
.
nodeName
==
'IMG'
)
{
handle
.
ondragstart
=
noDragStart
;
}
}
var
images
=
handle
.
querySelectorAll
(
'img'
);
for
(
var
i
=
0
,
len
=
images
.
length
;
i
<
len
;
i
++
)
{
var
img
=
images
[
i
];
img
.
ondragstart
=
noDragStart
;
}
};
// transport
if
(
typeof
define
===
'function'
&&
define
.
amd
)
{
// AMD
define
(
"getSize"
,
[
'getStyleProperty'
],
defineGetSize
);
}
else
{
// browser global
window
.
getSize
=
defineGetSize
(
window
.
getStyleProperty
);
}
// ----- start event ----- //
var
allowTouchstartNodes
=
Unidragger
.
allowTouchstartNodes
=
{
INPUT
:
true
,
A
:
true
,
BUTTON
:
true
,
SELECT
:
true
};
/**
* pointer start
* @param {Event} event
* @param {Event or Touch} pointer
*/
Unidragger
.
prototype
.
pointerDown
=
function
(
event
,
pointer
)
{
this
.
_dragPointerDown
(
event
,
pointer
);
// kludge to blur focused inputs in dragger
var
focused
=
document
.
activeElement
;
if
(
focused
&&
focused
.
blur
)
{
focused
.
blur
();
}
// bind move and end events
this
.
_bindPostStartEvents
(
event
);
this
.
emitEvent
(
'pointerDown'
,
[
event
,
pointer
]
);
};
// base pointer down logic
Unidragger
.
prototype
.
_dragPointerDown
=
function
(
event
,
pointer
)
{
// track to see when dragging starts
this
.
pointerDownPoint
=
Unipointer
.
getPointerPoint
(
pointer
);
var
targetNodeName
=
event
.
target
.
nodeName
;
// HACK iOS, allow clicks on buttons, inputs, and links, or children of links
var
isTouchstartNode
=
event
.
type
==
'touchstart'
&&
(
allowTouchstartNodes
[
targetNodeName
]
||
getParentLink
(
event
.
target
)
);
// do not prevent default on touchstart nodes or <select>
if
(
!
isTouchstartNode
&&
targetNodeName
!=
'SELECT'
)
{
preventDefaultEvent
(
event
);
}
};
// ----- move event ----- //
/**
* drag move
* @param {Event} event
* @param {Event or Touch} pointer
*/
Unidragger
.
prototype
.
pointerMove
=
function
(
event
,
pointer
)
{
var
moveVector
=
this
.
_dragPointerMove
(
event
,
pointer
);
this
.
emitEvent
(
'pointerMove'
,
[
event
,
pointer
,
moveVector
]
);
this
.
_dragMove
(
event
,
pointer
,
moveVector
);
};
// base pointer move logic
Unidragger
.
prototype
.
_dragPointerMove
=
function
(
event
,
pointer
)
{
var
movePoint
=
Unipointer
.
getPointerPoint
(
pointer
);
var
moveVector
=
{
x
:
movePoint
.
x
-
this
.
pointerDownPoint
.
x
,
y
:
movePoint
.
y
-
this
.
pointerDownPoint
.
y
};
// start drag if pointer has moved far enough to start drag
if
(
!
this
.
isDragging
&&
this
.
hasDragStarted
(
moveVector
)
)
{
this
.
_dragStart
(
event
,
pointer
);
}
return
moveVector
;
};
// condition if pointer has moved far enough to start drag
Unidragger
.
prototype
.
hasDragStarted
=
function
(
moveVector
)
{
return
Math
.
abs
(
moveVector
.
x
)
>
3
||
Math
.
abs
(
moveVector
.
y
)
>
3
;
};
})(
window
);
// ----- end event ----- //
/**
* pointer up
* @param {Event} event
* @param {Event or Touch} pointer
*/
Unidragger
.
prototype
.
pointerUp
=
function
(
event
,
pointer
)
{
this
.
emitEvent
(
'pointerUp'
,
[
event
,
pointer
]
);
this
.
_dragPointerUp
(
event
,
pointer
);
};
Unidragger
.
prototype
.
_dragPointerUp
=
function
(
event
,
pointer
)
{
if
(
this
.
isDragging
)
{
this
.
_dragEnd
(
event
,
pointer
);
}
else
{
// pointer didn't move enough for drag to start
this
.
_staticClick
(
event
,
pointer
);
}
};
// -------------------------- drag -------------------------- //
// dragStart
Unidragger
.
prototype
.
_dragStart
=
function
(
event
,
pointer
)
{
this
.
isDragging
=
true
;
this
.
dragStartPoint
=
Unidragger
.
getPointerPoint
(
pointer
);
// prevent clicks
this
.
isPreventingClicks
=
true
;
this
.
dragStart
(
event
,
pointer
);
};
Unidragger
.
prototype
.
dragStart
=
function
(
event
,
pointer
)
{
this
.
emitEvent
(
'dragStart'
,
[
event
,
pointer
]
);
};
// dragMove
Unidragger
.
prototype
.
_dragMove
=
function
(
event
,
pointer
,
moveVector
)
{
// do not drag if not dragging yet
if
(
!
this
.
isDragging
)
{
return
;
}
this
.
dragMove
(
event
,
pointer
,
moveVector
);
};
Unidragger
.
prototype
.
dragMove
=
function
(
event
,
pointer
,
moveVector
)
{
this
.
emitEvent
(
'dragMove'
,
[
event
,
pointer
,
moveVector
]
);
};
// dragEnd
Unidragger
.
prototype
.
_dragEnd
=
function
(
event
,
pointer
)
{
// set flags
this
.
isDragging
=
false
;
// re-enable clicking async
var
_this
=
this
;
setTimeout
(
function
()
{
delete
_this
.
isPreventingClicks
;
});
this
.
dragEnd
(
event
,
pointer
);
};
Unidragger
.
prototype
.
dragEnd
=
function
(
event
,
pointer
)
{
this
.
emitEvent
(
'dragEnd'
,
[
event
,
pointer
]
);
};
// ----- onclick ----- //
// handle all clicks and prevent clicks when dragging
Unidragger
.
prototype
.
onclick
=
function
(
event
)
{
if
(
this
.
isPreventingClicks
)
{
preventDefaultEvent
(
event
);
}
};
// ----- staticClick ----- //
// triggered after pointer down & up with no/tiny movement
Unidragger
.
prototype
.
_staticClick
=
function
(
event
,
pointer
)
{
// allow click in text input
if
(
event
.
target
.
nodeName
==
'INPUT'
&&
event
.
target
.
type
==
'text'
)
{
event
.
target
.
focus
();
}
this
.
staticClick
(
event
,
pointer
);
};
Unidragger
.
prototype
.
staticClick
=
function
(
event
,
pointer
)
{
this
.
emitEvent
(
'staticClick'
,
[
event
,
pointer
]
);
};
// ----- ----- //
Unidragger
.
getPointerPoint
=
function
(
pointer
)
{
return
{
x
:
pointer
.
pageX
!==
undefined
?
pointer
.
pageX
:
pointer
.
clientX
,
y
:
pointer
.
pageY
!==
undefined
?
pointer
.
pageY
:
pointer
.
clientY
};
};
// ----- ----- //
Unidragger
.
getPointerPoint
=
Unipointer
.
getPointerPoint
;
return
Unidragger
;
}));
/*!
* Draggabilly v1.
0.5
* Draggabilly v1.
2.4
* Make that shiz draggable
* http://draggabilly.desandro.com
* MIT license
*/
(
function
(
window
)
{
(
function
(
window
,
factory
)
{
if
(
typeof
define
==
'function'
&&
define
.
amd
)
{
// AMD
define
(
[
'classie/classie'
,
'get-style-property/get-style-property'
,
'get-size/get-size'
,
'unidragger/unidragger'
],
function
(
classie
,
getStyleProperty
,
getSize
,
Unidragger
)
{
return
factory
(
window
,
classie
,
getStyleProperty
,
getSize
,
Unidragger
);
});
}
else
if
(
typeof
exports
==
'object'
)
{
// CommonJS
module
.
exports
=
factory
(
window
,
require
(
'desandro-classie'
),
require
(
'desandro-get-style-property'
),
require
(
'get-size'
),
require
(
'unidragger'
)
);
}
else
{
// browser global
window
.
Draggabilly
=
factory
(
window
,
window
.
classie
,
window
.
getStyleProperty
,
window
.
getSize
,
window
.
Unidragger
);
}
}(
window
,
function
factory
(
window
,
classie
,
getStyleProperty
,
getSize
,
Unidragger
)
{
'use strict'
;
// vars
var
document
=
window
.
document
;
var
document
=
window
.
document
;
function
noop
()
{}
// -------------------------- helpers -------------------------- //
// extend objects
function
extend
(
a
,
b
)
{
for
(
var
prop
in
b
)
{
a
[
prop
]
=
b
[
prop
];
}
return
a
;
}
function
noop
()
{}
function
extend
(
a
,
b
)
{
for
(
var
prop
in
b
)
{
a
[
prop
]
=
b
[
prop
];
}
return
a
;
}
// ----- get style ----- //
var
defView
=
document
.
defaultView
;
var
defView
=
document
.
defaultView
;
var
getStyle
=
defView
&&
defView
.
getComputedStyle
?
function
(
elem
)
{
return
defView
.
getComputedStyle
(
elem
,
null
);
}
:
function
(
elem
)
{
return
elem
.
currentStyle
;
};
var
getStyle
=
defView
&&
defView
.
getComputedStyle
?
function
(
elem
)
{
return
defView
.
getComputedStyle
(
elem
,
null
);
}
:
function
(
elem
)
{
return
elem
.
currentStyle
;
};
// http://stackoverflow.com/a/384380/182183
var
isElement
=
(
typeof
HTMLElement
=
==
'object'
)
?
function
isElementDOM2
(
obj
)
{
return
obj
instanceof
HTMLElement
;
}
:
function
isElementQuirky
(
obj
)
{
return
obj
&&
typeof
obj
=
==
'object'
&&
obj
.
nodeType
===
1
&&
typeof
obj
.
nodeName
=
==
'string'
;
};
var
isElement
=
(
typeof
HTMLElement
==
'object'
)
?
function
isElementDOM2
(
obj
)
{
return
obj
instanceof
HTMLElement
;
}
:
function
isElementQuirky
(
obj
)
{
return
obj
&&
typeof
obj
==
'object'
&&
obj
.
nodeType
==
1
&&
typeof
obj
.
nodeName
==
'string'
;
};
// -------------------------- requestAnimationFrame -------------------------- //
// https://gist.github.com/1866474
var
lastTime
=
0
;
var
prefixes
=
'webkit moz ms o'
.
split
(
' '
);
var
lastTime
=
0
;
var
prefixes
=
'webkit moz ms o'
.
split
(
' '
);
// get unprefixed rAF and cAF, if present
var
requestAnimationFrame
=
window
.
requestAnimationFrame
;
var
cancelAnimationFrame
=
window
.
cancelAnimationFrame
;
var
requestAnimationFrame
=
window
.
requestAnimationFrame
;
var
cancelAnimationFrame
=
window
.
cancelAnimationFrame
;
// loop through vendor prefixes and get prefixed rAF and cAF
var
prefix
;
for
(
var
i
=
0
;
i
<
prefixes
.
length
;
i
++
)
{
if
(
requestAnimationFrame
&&
cancelAnimationFrame
)
{
break
;
}
prefix
=
prefixes
[
i
];
requestAnimationFrame
=
requestAnimationFrame
||
window
[
prefix
+
'RequestAnimationFrame'
];
cancelAnimationFrame
=
cancelAnimationFrame
||
window
[
prefix
+
'CancelAnimationFrame'
]
||
window
[
prefix
+
'CancelRequestAnimationFrame'
];
}
var
prefix
;
for
(
var
i
=
0
;
i
<
prefixes
.
length
;
i
++
)
{
if
(
requestAnimationFrame
&&
cancelAnimationFrame
)
{
break
;
}
prefix
=
prefixes
[
i
];
requestAnimationFrame
=
requestAnimationFrame
||
window
[
prefix
+
'RequestAnimationFrame'
];
cancelAnimationFrame
=
cancelAnimationFrame
||
window
[
prefix
+
'CancelAnimationFrame'
]
||
window
[
prefix
+
'CancelRequestAnimationFrame'
];
}
// fallback to setTimeout and clearTimeout if either request/cancel is not supported
if
(
!
requestAnimationFrame
||
!
cancelAnimationFrame
)
{
requestAnimationFrame
=
function
(
callback
)
{
var
currTime
=
new
Date
().
getTime
();
var
timeToCall
=
Math
.
max
(
0
,
16
-
(
currTime
-
lastTime
)
);
var
id
=
window
.
setTimeout
(
function
()
{
callback
(
currTime
+
timeToCall
);
},
timeToCall
);
lastTime
=
currTime
+
timeToCall
;
return
id
;
};
cancelAnimationFrame
=
function
(
id
)
{
window
.
clearTimeout
(
id
);
};
}
// -------------------------- definition -------------------------- //
function
draggabillyDefinition
(
classie
,
EventEmitter
,
eventie
,
getStyleProperty
,
getSize
)
{
if
(
!
requestAnimationFrame
||
!
cancelAnimationFrame
)
{
requestAnimationFrame
=
function
(
callback
)
{
var
currTime
=
new
Date
().
getTime
();
var
timeToCall
=
Math
.
max
(
0
,
16
-
(
currTime
-
lastTime
)
);
var
id
=
window
.
setTimeout
(
function
()
{
callback
(
currTime
+
timeToCall
);
},
timeToCall
);
lastTime
=
currTime
+
timeToCall
;
return
id
;
};
cancelAnimationFrame
=
function
(
id
)
{
window
.
clearTimeout
(
id
);
};
}
// -------------------------- support -------------------------- //
var
transformProperty
=
getStyleProperty
(
'transform'
);
var
transformProperty
=
getStyleProperty
(
'transform'
);
// TODO fix quick & dirty check for 3D support
var
is3d
=
!!
getStyleProperty
(
'perspective'
);
var
is3d
=
!!
getStyleProperty
(
'perspective'
);
// -------------------------- -------------------------- //
var
jQuery
=
window
.
jQuery
;
function
Draggabilly
(
element
,
options
)
{
this
.
element
=
element
;
// -------------------------- -------------------------- //
this
.
options
=
extend
(
{},
this
.
options
);
extend
(
this
.
options
,
options
);
function
Draggabilly
(
element
,
options
)
{
// querySelector if string
this
.
element
=
typeof
element
==
'string'
?
document
.
querySelector
(
element
)
:
element
;
this
.
_create
();
if
(
jQuery
)
{
this
.
$element
=
jQuery
(
this
.
element
);
}
}
// options
this
.
options
=
extend
(
{},
this
.
constructor
.
defaults
);
this
.
option
(
options
);
// inherit EventEmitter methods
extend
(
Draggabilly
.
prototype
,
EventEmitter
.
prototype
);
this
.
_create
();
}
Draggabilly
.
prototype
.
options
=
{
}
;
// inherit Unidragger methods
extend
(
Draggabilly
.
prototype
,
Unidragger
.
prototype
)
;
Draggabilly
.
prototype
.
_create
=
function
()
{
Draggabilly
.
defaults
=
{
};
// properties
this
.
position
=
{};
this
.
_getPosition
();
/**
* set options
* @param {Object} opts
*/
Draggabilly
.
prototype
.
option
=
function
(
opts
)
{
extend
(
this
.
options
,
opts
);
};
this
.
startPoint
=
{
x
:
0
,
y
:
0
};
this
.
dragPoint
=
{
x
:
0
,
y
:
0
};
Draggabilly
.
prototype
.
_create
=
function
()
{
this
.
startPosition
=
extend
(
{},
this
.
position
);
// properties
this
.
position
=
{};
this
.
_getPosition
();
// set relative positioning
var
style
=
getStyle
(
this
.
element
);
if
(
style
.
position
!==
'relative'
&&
style
.
position
!==
'absolute'
)
{
this
.
element
.
style
.
position
=
'relative'
;
}
this
.
startPoint
=
{
x
:
0
,
y
:
0
};
this
.
dragPoint
=
{
x
:
0
,
y
:
0
};
this
.
enable
();
this
.
setHandles
();
this
.
startPosition
=
extend
(
{},
this
.
position
);
};
// set relative positioning
var
style
=
getStyle
(
this
.
element
);
if
(
style
.
position
!=
'relative'
&&
style
.
position
!=
'absolute'
)
{
this
.
element
.
style
.
position
=
'relative'
;
}
/**
* set this.handles and bind start events to 'em
*/
Draggabilly
.
prototype
.
setHandles
=
function
()
{
this
.
handles
=
this
.
options
.
handle
?
this
.
element
.
querySelectorAll
(
this
.
options
.
handle
)
:
[
this
.
element
];
for
(
var
i
=
0
,
len
=
this
.
handles
.
length
;
i
<
len
;
i
++
)
{
var
handle
=
this
.
handles
[
i
];
// bind pointer start event
// listen for both, for devices like Chrome Pixel
// which has touch and mouse events
eventie
.
bind
(
handle
,
'mousedown'
,
this
);
eventie
.
bind
(
handle
,
'touchstart'
,
this
);
disableImgOndragstart
(
handle
);
}
};
this
.
enable
();
this
.
setHandles
();
// remove default dragging interaction on all images in IE8
// IE8 does its own drag thing on images, which messes stuff up
};
function
noDragStart
()
{
return
false
;
}
// TODO replace this with a IE8 test
var
isIE8
=
'attachEvent'
in
document
.
documentElement
;
// IE8 only
var
disableImgOndragstart
=
!
isIE8
?
noop
:
function
(
handle
)
{
/**
* set this.handles and bind start events to 'em
*/
Draggabilly
.
prototype
.
setHandles
=
function
()
{
this
.
handles
=
this
.
options
.
handle
?
this
.
element
.
querySelectorAll
(
this
.
options
.
handle
)
:
[
this
.
element
];
if
(
handle
.
nodeName
===
'IMG'
)
{
handle
.
ondragstart
=
noDragStart
;
}
this
.
bindHandles
();
};
var
images
=
handle
.
querySelectorAll
(
'img'
);
for
(
var
i
=
0
,
len
=
images
.
length
;
i
<
len
;
i
++
)
{
var
img
=
images
[
i
];
img
.
ondragstart
=
noDragStart
;
}
};
/**
* emits events via eventEmitter and jQuery events
* @param {String} type - name of event
* @param {Event} event - original event
* @param {Array} args - extra arguments
*/
Draggabilly
.
prototype
.
dispatchEvent
=
function
(
type
,
event
,
args
)
{
var
emitArgs
=
[
event
].
concat
(
args
);
this
.
emitEvent
(
type
,
emitArgs
);
var
jQuery
=
window
.
jQuery
;
// trigger jQuery event
if
(
jQuery
&&
this
.
$element
)
{
if
(
event
)
{
// create jQuery event
var
$event
=
jQuery
.
Event
(
event
);
$event
.
type
=
type
;
this
.
$element
.
trigger
(
$event
,
args
);
}
else
{
// just trigger with type if no event available
this
.
$element
.
trigger
(
type
,
args
);
}
}
};
// -------------------------- position -------------------------- //
// get left/top position from style
Draggabilly
.
prototype
.
_getPosition
=
function
()
{
// properties
var
style
=
getStyle
(
this
.
element
);
Draggabilly
.
prototype
.
_getPosition
=
function
()
{
// properties
var
style
=
getStyle
(
this
.
element
);
var
x
=
parseInt
(
style
.
left
,
10
);
var
y
=
parseInt
(
style
.
top
,
10
);
var
x
=
parseInt
(
style
.
left
,
10
);
var
y
=
parseInt
(
style
.
top
,
10
);
// clean up 'auto' or other non-integer values
this
.
position
.
x
=
isNaN
(
x
)
?
0
:
x
;
this
.
position
.
y
=
isNaN
(
y
)
?
0
:
y
;
// clean up 'auto' or other non-integer values
this
.
position
.
x
=
isNaN
(
x
)
?
0
:
x
;
this
.
position
.
y
=
isNaN
(
y
)
?
0
:
y
;
this
.
_addTransformPosition
(
style
);
};
this
.
_addTransformPosition
(
style
);
};
// add transform: translate( x, y ) to position
Draggabilly
.
prototype
.
_addTransformPosition
=
function
(
style
)
{
if
(
!
transformProperty
)
{
return
;
}
var
transform
=
style
[
transformProperty
];
// bail out if value is 'none'
if
(
transform
.
indexOf
(
'matrix'
)
!==
0
)
{
return
;
}
// split matrix(1, 0, 0, 1, x, y)
var
matrixValues
=
transform
.
split
(
','
);
// translate X value is in 12th or 4th position
var
xIndex
=
transform
.
indexOf
(
'matrix3d'
)
===
0
?
12
:
4
;
var
translateX
=
parseInt
(
matrixValues
[
xIndex
],
10
);
// translate Y value is in 13th or 5th position
var
translateY
=
parseInt
(
matrixValues
[
xIndex
+
1
],
10
);
this
.
position
.
x
+=
translateX
;
this
.
position
.
y
+=
translateY
;
};
Draggabilly
.
prototype
.
_addTransformPosition
=
function
(
style
)
{
if
(
!
transformProperty
)
{
return
;
}
var
transform
=
style
[
transformProperty
];
// bail out if value is 'none'
if
(
transform
.
indexOf
(
'matrix'
)
!==
0
)
{
return
;
}
// split matrix(1, 0, 0, 1, x, y)
var
matrixValues
=
transform
.
split
(
','
);
// translate X value is in 12th or 4th position
var
xIndex
=
transform
.
indexOf
(
'matrix3d'
)
===
0
?
12
:
4
;
var
translateX
=
parseInt
(
matrixValues
[
xIndex
],
10
);
// translate Y value is in 13th or 5th position
var
translateY
=
parseInt
(
matrixValues
[
xIndex
+
1
],
10
);
this
.
position
.
x
+=
translateX
;
this
.
position
.
y
+=
translateY
;
};
// -------------------------- events -------------------------- //
// trigger handler methods for events
Draggabilly
.
prototype
.
handleEvent
=
function
(
event
)
{
var
method
=
'on'
+
event
.
type
;
if
(
this
[
method
]
)
{
this
[
method
](
event
);
}
};
// returns the touch that we're keeping track of
Draggabilly
.
prototype
.
getTouch
=
function
(
touches
)
{
for
(
var
i
=
0
,
len
=
touches
.
length
;
i
<
len
;
i
++
)
{
var
touch
=
touches
[
i
];
if
(
touch
.
identifier
===
this
.
pointerIdentifier
)
{
return
touch
;
}
}
};
// ----- start event ----- //
Draggabilly
.
prototype
.
onmousedown
=
function
(
event
)
{
this
.
dragStart
(
event
,
event
);
};
Draggabilly
.
prototype
.
ontouchstart
=
function
(
event
)
{
// disregard additional touches
if
(
this
.
isDragging
)
{
return
;
}
this
.
dragStart
(
event
,
event
.
changedTouches
[
0
]
);
};
function
setPointerPoint
(
point
,
pointer
)
{
point
.
x
=
pointer
.
pageX
!==
undefined
?
pointer
.
pageX
:
pointer
.
clientX
;
point
.
y
=
pointer
.
pageY
!==
undefined
?
pointer
.
pageY
:
pointer
.
clientY
;
}
/**
* drag start
* @param {Event} event
* @param {Event or Touch} pointer
*/
Draggabilly
.
prototype
.
dragStart
=
function
(
event
,
pointer
)
{
if
(
!
this
.
isEnabled
)
{
return
;
}
if
(
event
.
preventDefault
)
{
event
.
preventDefault
();
}
else
{
event
.
returnValue
=
false
;
}
var
isTouch
=
event
.
type
===
'touchstart'
;
// save pointer identifier to match up touch events
this
.
pointerIdentifier
=
pointer
.
identifier
;
this
.
_getPosition
();
this
.
measureContainment
();
// point where drag began
setPointerPoint
(
this
.
startPoint
,
pointer
);
// position _when_ drag began
this
.
startPosition
.
x
=
this
.
position
.
x
;
this
.
startPosition
.
y
=
this
.
position
.
y
;
// reset left/top style
this
.
setLeftTop
();
this
.
dragPoint
.
x
=
0
;
this
.
dragPoint
.
y
=
0
;
// bind move and end events
this
.
_bindEvents
({
events
:
isTouch
?
[
'touchmove'
,
'touchend'
,
'touchcancel'
]
:
[
'mousemove'
,
'mouseup'
],
// IE8 needs to be bound to document
node
:
event
.
preventDefault
?
window
:
document
});
classie
.
add
(
this
.
element
,
'is-dragging'
);
// reset isDragging flag
this
.
isDragging
=
true
;
this
.
emitEvent
(
'dragStart'
,
[
this
,
event
,
pointer
]
);
// start animation
this
.
animate
();
};
Draggabilly
.
prototype
.
_bindEvents
=
function
(
args
)
{
for
(
var
i
=
0
,
len
=
args
.
events
.
length
;
i
<
len
;
i
++
)
{
var
event
=
args
.
events
[
i
];
eventie
.
bind
(
args
.
node
,
event
,
this
);
}
// save these arguments
this
.
_boundEvents
=
args
;
};
Draggabilly
.
prototype
.
_unbindEvents
=
function
()
{
var
args
=
this
.
_boundEvents
;
for
(
var
i
=
0
,
len
=
args
.
events
.
length
;
i
<
len
;
i
++
)
{
var
event
=
args
.
events
[
i
];
eventie
.
unbind
(
args
.
node
,
event
,
this
);
}
delete
this
.
_boundEvents
;
};
Draggabilly
.
prototype
.
measureContainment
=
function
()
{
var
containment
=
this
.
options
.
containment
;
if
(
!
containment
)
{
return
;
}
this
.
size
=
getSize
(
this
.
element
);
var
elemRect
=
this
.
element
.
getBoundingClientRect
();
// use element if element
var
container
=
isElement
(
containment
)
?
containment
:
// fallback to querySelector if string
typeof
containment
===
'string'
?
document
.
querySelector
(
containment
)
:
// otherwise just `true`, use the parent
this
.
element
.
parentNode
;
/**
* pointer start
* @param {Event} event
* @param {Event or Touch} pointer
*/
Draggabilly
.
prototype
.
pointerDown
=
function
(
event
,
pointer
)
{
this
.
_dragPointerDown
(
event
,
pointer
);
// kludge to blur focused inputs in dragger
var
focused
=
document
.
activeElement
;
if
(
focused
&&
focused
.
blur
)
{
focused
.
blur
();
}
// bind move and end events
this
.
_bindPostStartEvents
(
event
);
classie
.
add
(
this
.
element
,
'is-pointer-down'
);
this
.
dispatchEvent
(
'pointerDown'
,
event
,
[
pointer
]
);
};
this
.
containerSize
=
getSize
(
container
);
var
containerRect
=
container
.
getBoundingClientRect
();
/**
* drag move
* @param {Event} event
* @param {Event or Touch} pointer
*/
Draggabilly
.
prototype
.
pointerMove
=
function
(
event
,
pointer
)
{
var
moveVector
=
this
.
_dragPointerMove
(
event
,
pointer
);
this
.
dispatchEvent
(
'pointerMove'
,
event
,
[
pointer
,
moveVector
]
);
this
.
_dragMove
(
event
,
pointer
,
moveVector
);
};
this
.
relativeStartPosition
=
{
x
:
elemRect
.
left
-
containerRect
.
left
,
y
:
elemRect
.
top
-
containerRect
.
top
};
};
/**
* drag start
* @param {Event} event
* @param {Event or Touch} pointer
*/
Draggabilly
.
prototype
.
dragStart
=
function
(
event
,
pointer
)
{
if
(
!
this
.
isEnabled
)
{
return
;
}
this
.
_getPosition
();
this
.
measureContainment
();
// position _when_ drag began
this
.
startPosition
.
x
=
this
.
position
.
x
;
this
.
startPosition
.
y
=
this
.
position
.
y
;
// reset left/top style
this
.
setLeftTop
();
this
.
dragPoint
.
x
=
0
;
this
.
dragPoint
.
y
=
0
;
// reset isDragging flag
this
.
isDragging
=
true
;
classie
.
add
(
this
.
element
,
'is-dragging'
);
this
.
dispatchEvent
(
'dragStart'
,
event
,
[
pointer
]
);
// start animation
this
.
animate
();
};
Draggabilly
.
prototype
.
measureContainment
=
function
()
{
var
containment
=
this
.
options
.
containment
;
if
(
!
containment
)
{
return
;
}
this
.
size
=
getSize
(
this
.
element
);
var
elemRect
=
this
.
element
.
getBoundingClientRect
();
// use element if element
var
container
=
isElement
(
containment
)
?
containment
:
// fallback to querySelector if string
typeof
containment
==
'string'
?
document
.
querySelector
(
containment
)
:
// otherwise just `true`, use the parent
this
.
element
.
parentNode
;
this
.
containerSize
=
getSize
(
container
);
var
containerRect
=
container
.
getBoundingClientRect
();
this
.
relativeStartPosition
=
{
x
:
elemRect
.
left
-
containerRect
.
left
,
y
:
elemRect
.
top
-
containerRect
.
top
};
};
// ----- move event ----- //
Draggabilly
.
prototype
.
onmousemove
=
function
(
event
)
{
this
.
dragMove
(
event
,
event
);
};
Draggabilly
.
prototype
.
ontouchmove
=
function
(
event
)
{
var
touch
=
this
.
getTouch
(
event
.
changedTouches
);
if
(
touch
)
{
this
.
dragMove
(
event
,
touch
);
}
};
/**
* drag move
* @param {Event} event
* @param {Event or Touch} pointer
*/
Draggabilly
.
prototype
.
dragMove
=
function
(
event
,
pointer
)
{
setPointerPoint
(
this
.
dragPoint
,
pointer
);
this
.
dragPoint
.
x
-=
this
.
startPoint
.
x
;
this
.
dragPoint
.
y
-=
this
.
startPoint
.
y
;
if
(
this
.
options
.
containment
)
{
var
relX
=
this
.
relativeStartPosition
.
x
;
var
relY
=
this
.
relativeStartPosition
.
y
;
this
.
dragPoint
.
x
=
Math
.
max
(
this
.
dragPoint
.
x
,
-
relX
);
this
.
dragPoint
.
y
=
Math
.
max
(
this
.
dragPoint
.
y
,
-
relY
);
this
.
dragPoint
.
x
=
Math
.
min
(
this
.
dragPoint
.
x
,
this
.
containerSize
.
width
-
relX
-
this
.
size
.
width
);
this
.
dragPoint
.
y
=
Math
.
min
(
this
.
dragPoint
.
y
,
this
.
containerSize
.
height
-
relY
-
this
.
size
.
height
);
}
this
.
position
.
x
=
this
.
startPosition
.
x
+
this
.
dragPoint
.
x
;
this
.
position
.
y
=
this
.
startPosition
.
y
+
this
.
dragPoint
.
y
;
this
.
emitEvent
(
'dragMove'
,
[
this
,
event
,
pointer
]
);
};
/**
* drag move
* @param {Event} event
* @param {Event or Touch} pointer
*/
Draggabilly
.
prototype
.
dragMove
=
function
(
event
,
pointer
,
moveVector
)
{
if
(
!
this
.
isEnabled
)
{
return
;
}
var
dragX
=
moveVector
.
x
;
var
dragY
=
moveVector
.
y
;
var
grid
=
this
.
options
.
grid
;
var
gridX
=
grid
&&
grid
[
0
];
var
gridY
=
grid
&&
grid
[
1
];
dragX
=
applyGrid
(
dragX
,
gridX
);
dragY
=
applyGrid
(
dragY
,
gridY
);
dragX
=
this
.
containDrag
(
'x'
,
dragX
,
gridX
);
dragY
=
this
.
containDrag
(
'y'
,
dragY
,
gridY
);
// constrain to axis
dragX
=
this
.
options
.
axis
==
'y'
?
0
:
dragX
;
dragY
=
this
.
options
.
axis
==
'x'
?
0
:
dragY
;
this
.
position
.
x
=
this
.
startPosition
.
x
+
dragX
;
this
.
position
.
y
=
this
.
startPosition
.
y
+
dragY
;
// set dragPoint properties
this
.
dragPoint
.
x
=
dragX
;
this
.
dragPoint
.
y
=
dragY
;
this
.
dispatchEvent
(
'dragMove'
,
event
,
[
pointer
,
moveVector
]
);
};
function
applyGrid
(
value
,
grid
,
method
)
{
method
=
method
||
'round'
;
return
grid
?
Math
[
method
](
value
/
grid
)
*
grid
:
value
;
}
Draggabilly
.
prototype
.
containDrag
=
function
(
axis
,
drag
,
grid
)
{
if
(
!
this
.
options
.
containment
)
{
return
drag
;
}
var
measure
=
axis
==
'x'
?
'width'
:
'height'
;
var
rel
=
this
.
relativeStartPosition
[
axis
];
var
min
=
applyGrid
(
-
rel
,
grid
,
'ceil'
);
var
max
=
this
.
containerSize
[
measure
]
-
rel
-
this
.
size
[
measure
];
max
=
applyGrid
(
max
,
grid
,
'floor'
);
return
Math
.
min
(
max
,
Math
.
max
(
min
,
drag
)
);
};
// ----- end event ----- //
Draggabilly
.
prototype
.
onmouseup
=
function
(
event
)
{
this
.
dragEnd
(
event
,
event
);
};
Draggabilly
.
prototype
.
ontouchend
=
function
(
event
)
{
var
touch
=
this
.
getTouch
(
event
.
changedTouches
);
if
(
touch
)
{
this
.
dragEnd
(
event
,
touch
);
}
};
/**
* drag end
* @param {Event} event
* @param {Event or Touch} pointer
*/
Draggabilly
.
prototype
.
dragEnd
=
function
(
event
,
pointer
)
{
this
.
isDragging
=
false
;
delete
this
.
pointerIdentifier
;
// use top left position when complete
if
(
transformProperty
)
{
this
.
element
.
style
[
transformProperty
]
=
''
;
this
.
setLeftTop
();
}
// remove events
this
.
_unbindEvents
();
classie
.
remove
(
this
.
element
,
'is-dragging'
);
this
.
emitEvent
(
'dragEnd'
,
[
this
,
event
,
pointer
]
);
};
// ----- cancel event ----- //
/**
* pointer up
* @param {Event} event
* @param {Event or Touch} pointer
*/
Draggabilly
.
prototype
.
pointerUp
=
function
(
event
,
pointer
)
{
classie
.
remove
(
this
.
element
,
'is-pointer-down'
);
this
.
dispatchEvent
(
'pointerUp'
,
event
,
[
pointer
]
);
this
.
_dragPointerUp
(
event
,
pointer
);
};
// coerce to end event
Draggabilly
.
prototype
.
ontouchcancel
=
function
(
event
)
{
var
touch
=
this
.
getTouch
(
event
.
changedTouches
);
this
.
dragEnd
(
event
,
touch
);
};
/**
* drag end
* @param {Event} event
* @param {Event or Touch} pointer
*/
Draggabilly
.
prototype
.
dragEnd
=
function
(
event
,
pointer
)
{
if
(
!
this
.
isEnabled
)
{
return
;
}
this
.
isDragging
=
false
;
// use top left position when complete
if
(
transformProperty
)
{
this
.
element
.
style
[
transformProperty
]
=
''
;
this
.
setLeftTop
();
}
classie
.
remove
(
this
.
element
,
'is-dragging'
);
this
.
dispatchEvent
(
'dragEnd'
,
event
,
[
pointer
]
);
};
// -------------------------- animation -------------------------- //
Draggabilly
.
prototype
.
animate
=
function
()
{
// only render and animate if dragging
if
(
!
this
.
isDragging
)
{
return
;
}
Draggabilly
.
prototype
.
animate
=
function
()
{
// only render and animate if dragging
if
(
!
this
.
isDragging
)
{
return
;
}
this
.
positionDrag
();
this
.
positionDrag
();
var
_this
=
this
;
requestAnimationFrame
(
function
animateFrame
()
{
_this
.
animate
();
});
var
_this
=
this
;
requestAnimationFrame
(
function
animateFrame
()
{
_this
.
animate
();
});
};
};
// transform translate function
var
translate
=
is3d
?
function
(
x
,
y
)
{
return
'translate3d( '
+
x
+
'px, '
+
y
+
'px, 0)'
;
}
:
function
(
x
,
y
)
{
return
'translate( '
+
x
+
'px, '
+
y
+
'px)'
;
};
var
translate
=
is3d
?
function
(
x
,
y
)
{
return
'translate3d( '
+
x
+
'px, '
+
y
+
'px, 0)'
;
}
:
function
(
x
,
y
)
{
return
'translate( '
+
x
+
'px, '
+
y
+
'px)'
;
};
// left/top positioning
Draggabilly
.
prototype
.
setLeftTop
=
function
()
{
this
.
element
.
style
.
left
=
this
.
position
.
x
+
'px'
;
this
.
element
.
style
.
top
=
this
.
position
.
y
+
'px'
;
};
Draggabilly
.
prototype
.
positionDrag
=
transformProperty
?
function
()
{
// position with transform
this
.
element
.
style
[
transformProperty
]
=
translate
(
this
.
dragPoint
.
x
,
this
.
dragPoint
.
y
);
}
:
Draggabilly
.
prototype
.
setLeftTop
;
Draggabilly
.
prototype
.
enable
=
function
()
{
this
.
isEnabled
=
true
;
};
Draggabilly
.
prototype
.
disable
=
function
()
{
this
.
isEnabled
=
false
;
if
(
this
.
isDragging
)
{
this
.
dragEnd
();
}
};
return
Draggabilly
;
}
// end definition
// -------------------------- transport -------------------------- //
if
(
typeof
define
===
'function'
&&
define
.
amd
)
{
// AMD
define
(
'draggabilly'
,
[
'classie'
,
'EventEmitter'
,
'eventie'
,
'getStyleProperty'
,
'getSize'
],
draggabillyDefinition
);
}
else
{
// browser global
window
.
Draggabilly
=
draggabillyDefinition
(
window
.
classie
,
window
.
EventEmitter
,
window
.
eventie
,
window
.
getStyleProperty
,
window
.
getSize
);
}
Draggabilly
.
prototype
.
setLeftTop
=
function
()
{
this
.
element
.
style
.
left
=
this
.
position
.
x
+
'px'
;
this
.
element
.
style
.
top
=
this
.
position
.
y
+
'px'
;
};
Draggabilly
.
prototype
.
positionDrag
=
transformProperty
?
function
()
{
// position with transform
this
.
element
.
style
[
transformProperty
]
=
translate
(
this
.
dragPoint
.
x
,
this
.
dragPoint
.
y
);
}
:
Draggabilly
.
prototype
.
setLeftTop
;
// ----- staticClick ----- //
Draggabilly
.
prototype
.
staticClick
=
function
(
event
,
pointer
)
{
this
.
dispatchEvent
(
'staticClick'
,
event
,
[
pointer
]
);
};
// ----- methods ----- //
Draggabilly
.
prototype
.
enable
=
function
()
{
this
.
isEnabled
=
true
;
};
Draggabilly
.
prototype
.
disable
=
function
()
{
this
.
isEnabled
=
false
;
if
(
this
.
isDragging
)
{
this
.
dragEnd
();
}
};
Draggabilly
.
prototype
.
destroy
=
function
()
{
this
.
disable
();
// reset styles
if
(
transformProperty
)
{
this
.
element
.
style
[
transformProperty
]
=
''
;
}
this
.
element
.
style
.
left
=
''
;
this
.
element
.
style
.
top
=
''
;
this
.
element
.
style
.
position
=
''
;
// unbind handles
this
.
unbindHandles
();
// remove jQuery data
if
(
this
.
$element
)
{
this
.
$element
.
removeData
(
'draggabilly'
);
}
};
// ----- jQuery bridget ----- //
// required for jQuery bridget
Draggabilly
.
prototype
.
_init
=
noop
;
if
(
jQuery
&&
jQuery
.
bridget
)
{
jQuery
.
bridget
(
'draggabilly'
,
Draggabilly
);
}
// ----- ----- //
return
Draggabilly
;
}));
})(
window
);
\ No newline at end of file
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment