diff --git a/Gruntfile.js b/Gruntfile.js index a020010461..d0d7563374 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -53,8 +53,8 @@ module.exports = function (grunt) { api: { files: { "api/js/jsapi.min.js": [ - "api/js/jquery/jquery.js", - "api/js/jquery/jquery-ui.js", + "vendor/bower-asset/jquery/dist/jquery.js", + "vendor/bower-asset/jquery-ui/jquery-ui.js", "api/js/jsapi/jsapi.js", "api/js/egw_json.js", "api/js/jsapi/egw_core.js", @@ -153,7 +153,7 @@ module.exports = function (grunt) { "api/js/etemplate/et2_dataview_interfaces.js", "api/js/etemplate/et2_dataview_view_container.js", "api/js/etemplate/et2_dataview_view_row.js", - "api/js/jquery/TouchSwipe/jquery.touchSwipe.js", + "/vendor/bower-asset/jquery-touchswipe/jquery.touchSwipe.js", "api/js/etemplate/et2_dataview_view_aoi.js", "api/js/etemplate/et2_dataview_controller_selection.js", "api/js/etemplate/et2_dataview_controller.js", @@ -234,7 +234,7 @@ module.exports = function (grunt) { mobile: { files: { "pixelegg/js/fw_mobile.min.js": [ - "api/js/jquery/fastclick/lib/fastclick.js", + "/vendor/bower-asset/fastclick/lib/fastclick.js", "api/js/framework/fw_base.js", "api/js/framework/fw_browser.js", "api/js/jquery/mousewheel/mousewheel.js", @@ -278,7 +278,7 @@ module.exports = function (grunt) { files: { "pixelegg/css/pixelegg.min.css": [ "api/js/jquery/chosen/chosen.css", - "api/js/jquery/jquery-ui/redmond/jquery-ui.css", + "vendor/bower-asset/jquery-ui/themes/redmond/jquery-ui.css", "api/js/jquery/magicsuggest/magicsuggest.css", "api/js/jquery/jpicker/css/jPicker-1.1.6.min.css", "api/js/jquery/jquery-ui-timepicker-addon.css", @@ -293,7 +293,7 @@ module.exports = function (grunt) { ], "pixelegg/css/mobile.min.css": [ "api/js/jquery/chosen/chosen.css", - "api/js/jquery/jquery-ui/redmond/jquery-ui.css", + "vendor/bower-asset/jquery-ui/themes/redmond/jquery-ui.css", "api/js/jquery/magicsuggest/magicsuggest.css", "api/js/jquery/jpicker/css/jPicker-1.1.6.min.css", "api/js/jquery/jquery-ui-timepicker-addon.css", @@ -308,7 +308,7 @@ module.exports = function (grunt) { ], "pixelegg/mobile/fw_mobile.min.css": [ "api/js/jquery/chosen/chosen.css", - "api/js/jquery/jquery-ui/redmond/jquery-ui.css", + "vendor/bower-asset/jquery-ui/themes/redmond/jquery-ui.css", "api/js/jquery/magicsuggest/magicsuggest.css", "api/js/jquery/jpicker/css/jPicker-1.1.6.min.css", "api/js/jquery/jquery-ui-timepicker-addon.css", @@ -327,7 +327,7 @@ module.exports = function (grunt) { files: { "jdots/css/high-contrast.min.css": [ "api/js/jquery/chosen/chosen.css", - "api/js/jquery/jquery-ui/redmond/jquery-ui.css", + "vendor/bower-asset/jquery-ui/themes/redmond/jquery-ui.css", "api/js/jquery/magicsuggest/magicsuggest.css", "api/js/jquery/jpicker/css/jPicker-1.1.6.min.css", "api/js/jquery/jquery-ui-timepicker-addon.css", @@ -346,7 +346,7 @@ module.exports = function (grunt) { ], "jdots/css/jdots.min.css": [ "api/js/jquery/chosen/chosen.css", - "api/js/jquery/jquery-ui/redmond/jquery-ui.css", + "vendor/bower-asset/jquery-ui/themes/redmond/jquery-ui.css", "api/js/jquery/magicsuggest/magicsuggest.css", "api/js/jquery/jpicker/css/jPicker-1.1.6.min.css", "api/js/jquery/jquery-ui-timepicker-addon.css", @@ -364,7 +364,7 @@ module.exports = function (grunt) { ], "jdots/css/orange-green.min.css": [ "api/js/jquery/chosen/chosen.css", - "api/js/jquery/jquery-ui/redmond/jquery-ui.css", + "vendor/bower-asset/jquery-ui/themes/redmond/jquery-ui.css", "api/js/jquery/magicsuggest/magicsuggest.css", "api/js/jquery/jpicker/css/jPicker-1.1.6.min.css", "api/js/jquery/jquery-ui-timepicker-addon.css", diff --git a/api/js/egw_action/egw_action_dragdrop.js b/api/js/egw_action/egw_action_dragdrop.js index 42fc2d5b07..0cf6ab974e 100644 --- a/api/js/egw_action/egw_action_dragdrop.js +++ b/api/js/egw_action/egw_action_dragdrop.js @@ -13,8 +13,8 @@ egw_action; egw_action_common; egw_action_popup; - jquery.jquery; - jquery.jquery-ui; + vendor.bower-asset.jquery.dist.jquery; + /vendor/bower-asset/jquery-ui/jquery-ui.js; */ /** diff --git a/api/js/egw_action/egw_action_popup.js b/api/js/egw_action/egw_action_popup.js index 438063751d..5360a251a5 100644 --- a/api/js/egw_action/egw_action_popup.js +++ b/api/js/egw_action/egw_action_popup.js @@ -10,7 +10,7 @@ */ /*egw:uses - jquery.jquery; + vendor.bower-asset.jquery.dist.jquery; egw_menu; /api/js/jquery/jquery-tap-and-hold/jquery.tapandhold.js; */ @@ -268,7 +268,7 @@ function egwPopupActionImplementation() var contextHandler = function(e) { if(egwIsMobile()) { - if (e.originalEvent.which == 3) + if (e.which == 3) { // Enable onhold trigger till we define a better handler for tree contextmenu // return; diff --git a/api/js/egw_action/egw_keymanager.js b/api/js/egw_action/egw_keymanager.js index 2f3249b1be..e9922adc43 100644 --- a/api/js/egw_action/egw_keymanager.js +++ b/api/js/egw_action/egw_keymanager.js @@ -10,7 +10,7 @@ */ /*egw:uses - jquery.jquery; + vendor.bower-asset.jquery.dist.jquery; egw_action; */ @@ -143,7 +143,7 @@ function _egw_nodeIsInInput(_node) } /** - * Register the onkeypress handler on the document + * Register the onkeypress handler on the document */ jQuery(document).ready(function() { @@ -197,7 +197,7 @@ jQuery(window).on("contextmenu",document, function(event) { */ function egw_shortcutIdx(_keyCode, _shift, _ctrl, _alt) { - return "_" + _keyCode + "_" + + return "_" + _keyCode + "_" + (_shift ? "S" : "") + (_ctrl ? "C" : "") + (_alt ? "A" : ""); @@ -262,7 +262,7 @@ function egw_keyHandler(_keyCode, _shift, _ctrl, _alt) { var result = shortcut.handler.call(shortcut.context, shortcut.shortcut); if(result) return result; } - + // Pass the keypress to the currently focused action object // Get the object manager and fetch the container of the currently diff --git a/api/js/egw_json.js b/api/js/egw_json.js index 00cdedeebe..926bd1cd02 100644 --- a/api/js/egw_json.js +++ b/api/js/egw_json.js @@ -11,7 +11,7 @@ /*egw:uses jsapi.jsapi; // Contains some helper functions - jquery.jquery; // Used for the ajax requests + vendor.bower-asset.jquery.dist.jquery; // Used for the ajax requests */ /* The egw_json_request is the javaScript side implementation of class.egw_json.inc.php.*/ diff --git a/api/js/etemplate/et2_core_baseWidget.js b/api/js/etemplate/et2_core_baseWidget.js index 3e7b1fd334..7c6175d700 100644 --- a/api/js/etemplate/et2_core_baseWidget.js +++ b/api/js/etemplate/et2_core_baseWidget.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; lib/tooltip; et2_core_DOMWidget; */ diff --git a/api/js/etemplate/et2_core_inputWidget.js b/api/js/etemplate/et2_core_inputWidget.js index cd9ea7da19..6c9cfdab1b 100644 --- a/api/js/etemplate/et2_core_inputWidget.js +++ b/api/js/etemplate/et2_core_inputWidget.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_interfaces; et2_core_valueWidget; */ diff --git a/api/js/etemplate/et2_core_valueWidget.js b/api/js/etemplate/et2_core_valueWidget.js index 3b1accee5e..404986cd9a 100644 --- a/api/js/etemplate/et2_core_valueWidget.js +++ b/api/js/etemplate/et2_core_valueWidget.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_baseWidget; */ diff --git a/api/js/etemplate/et2_dataview.js b/api/js/etemplate/et2_dataview.js index 57789dccab..07ceeea7bc 100644 --- a/api/js/etemplate/et2_dataview.js +++ b/api/js/etemplate/et2_dataview.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_common; et2_dataview_model_columns; diff --git a/api/js/etemplate/et2_dataview_view_aoi.js b/api/js/etemplate/et2_dataview_view_aoi.js index a2486bd777..b93595a7d8 100644 --- a/api/js/etemplate/et2_dataview_view_aoi.js +++ b/api/js/etemplate/et2_dataview_view_aoi.js @@ -13,7 +13,7 @@ /*egw:uses egw_action.egw_action_common; egw_action.egw_action; - /api/js/jquery/TouchSwipe/jquery.touchSwipe.js; + /vendor/bower-asset/jquery-touchswipe/jquery.touchSwipe.js; */ /** diff --git a/api/js/etemplate/et2_dataview_view_container.js b/api/js/etemplate/et2_dataview_view_container.js index 2bcdbc1888..e03e395c0c 100644 --- a/api/js/etemplate/et2_dataview_view_container.js +++ b/api/js/etemplate/et2_dataview_view_container.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_dataview_interfaces; */ diff --git a/api/js/etemplate/et2_dataview_view_grid.js b/api/js/etemplate/et2_dataview_view_grid.js index d2b9b6c01e..43a58fc4ea 100644 --- a/api/js/etemplate/et2_dataview_view_grid.js +++ b/api/js/etemplate/et2_dataview_view_grid.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_common; et2_dataview_interfaces; diff --git a/api/js/etemplate/et2_dataview_view_rowProvider.js b/api/js/etemplate/et2_dataview_view_rowProvider.js index ec05855a84..e50e1336b7 100644 --- a/api/js/etemplate/et2_dataview_view_rowProvider.js +++ b/api/js/etemplate/et2_dataview_view_rowProvider.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_inheritance; et2_core_interfaces; et2_core_arrayMgr; diff --git a/api/js/etemplate/et2_dataview_view_spacer.js b/api/js/etemplate/et2_dataview_view_spacer.js index 09d82d7093..2dc1cdf588 100644 --- a/api/js/etemplate/et2_dataview_view_spacer.js +++ b/api/js/etemplate/et2_dataview_view_spacer.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_dataview_view_container; */ diff --git a/api/js/etemplate/et2_dataview_view_tile.js b/api/js/etemplate/et2_dataview_view_tile.js index bbfb04bb30..2360759e06 100644 --- a/api/js/etemplate/et2_dataview_view_tile.js +++ b/api/js/etemplate/et2_dataview_view_tile.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_dataview_interfaces; */ diff --git a/api/js/etemplate/et2_extension_customfields.js b/api/js/etemplate/et2_extension_customfields.js index d51e470003..fc4ea67627 100644 --- a/api/js/etemplate/et2_extension_customfields.js +++ b/api/js/etemplate/et2_extension_customfields.js @@ -12,7 +12,7 @@ /*egw:uses lib/tooltip; - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_xml; et2_core_DOMWidget; et2_core_inputWidget; diff --git a/api/js/etemplate/et2_extension_nextmatch_dynheight.js b/api/js/etemplate/et2_extension_nextmatch_dynheight.js index 9432dcc909..43f470ea21 100644 --- a/api/js/etemplate/et2_extension_nextmatch_dynheight.js +++ b/api/js/etemplate/et2_extension_nextmatch_dynheight.js @@ -11,7 +11,7 @@ */ /*egw:use - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_inheritance; */ diff --git a/api/js/etemplate/et2_extension_nextmatch_rowProvider.js b/api/js/etemplate/et2_extension_nextmatch_rowProvider.js index 311f23b184..f054254464 100644 --- a/api/js/etemplate/et2_extension_nextmatch_rowProvider.js +++ b/api/js/etemplate/et2_extension_nextmatch_rowProvider.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_inheritance; et2_core_interfaces; et2_core_arrayMgr; diff --git a/api/js/etemplate/et2_widget_ajaxSelect.js b/api/js/etemplate/et2_widget_ajaxSelect.js index 737b86c870..53678c6e0a 100644 --- a/api/js/etemplate/et2_widget_ajaxSelect.js +++ b/api/js/etemplate/et2_widget_ajaxSelect.js @@ -12,8 +12,8 @@ */ /*egw:uses - jquery.jquery; - jquery.jquery-ui; + /vendor/bower-asset/jquery/dist/jquery.js; + /vendor/bower-asset/jquery-ui/jquery-ui.js; et2_core_inputWidget; et2_core_valueWidget; */ diff --git a/api/js/etemplate/et2_widget_barcode.js b/api/js/etemplate/et2_widget_barcode.js index d538df3d29..13f4b78e91 100644 --- a/api/js/etemplate/et2_widget_barcode.js +++ b/api/js/etemplate/et2_widget_barcode.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; /api/js/jquery/barcode/jquery-barcode.min.js; et2_core_interfaces; et2_core_baseWidget; diff --git a/api/js/etemplate/et2_widget_box.js b/api/js/etemplate/et2_widget_box.js index e436be6361..77ae28629e 100644 --- a/api/js/etemplate/et2_widget_box.js +++ b/api/js/etemplate/et2_widget_box.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_baseWidget; */ diff --git a/api/js/etemplate/et2_widget_button.js b/api/js/etemplate/et2_widget_button.js index 223d0de82d..10cc16b191 100644 --- a/api/js/etemplate/et2_widget_button.js +++ b/api/js/etemplate/et2_widget_button.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_interfaces; et2_core_baseWidget; */ diff --git a/api/js/etemplate/et2_widget_checkbox.js b/api/js/etemplate/et2_widget_checkbox.js index 7b2d1be474..6041fb02b1 100644 --- a/api/js/etemplate/et2_widget_checkbox.js +++ b/api/js/etemplate/et2_widget_checkbox.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_inputWidget; et2_core_valueWidget; */ diff --git a/api/js/etemplate/et2_widget_color.js b/api/js/etemplate/et2_widget_color.js index 3106829556..7985610d03 100644 --- a/api/js/etemplate/et2_widget_color.js +++ b/api/js/etemplate/et2_widget_color.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_inputWidget; et2_core_valueWidget; /api/js/jquery/jpicker/jpicker-1.1.6.js; diff --git a/api/js/etemplate/et2_widget_date.js b/api/js/etemplate/et2_widget_date.js index 028594984c..902eb03faf 100644 --- a/api/js/etemplate/et2_widget_date.js +++ b/api/js/etemplate/et2_widget_date.js @@ -11,8 +11,8 @@ */ /*egw:uses - jquery.jquery; - jquery.jquery-ui; + /vendor/bower-asset/jquery/dist/jquery.js; + /vendor/bower-asset/jquery-ui/jquery-ui.js; lib/date; et2_core_inputWidget; et2_core_valueWidget; diff --git a/api/js/etemplate/et2_widget_description.js b/api/js/etemplate/et2_widget_description.js index 851a13515e..b12534b110 100644 --- a/api/js/etemplate/et2_widget_description.js +++ b/api/js/etemplate/et2_widget_description.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_baseWidget; expose; */ diff --git a/api/js/etemplate/et2_widget_dialog.js b/api/js/etemplate/et2_widget_dialog.js index c17c03a207..973c95102b 100644 --- a/api/js/etemplate/et2_widget_dialog.js +++ b/api/js/etemplate/et2_widget_dialog.js @@ -11,7 +11,7 @@ /*egw:uses et2_core_widget; - jquery.jquery-ui; + /vendor/bower-asset/jquery-ui/jquery-ui.js; */ /** diff --git a/api/js/etemplate/et2_widget_diff.js b/api/js/etemplate/et2_widget_diff.js index 5f1b7cfbde..4b49182b16 100644 --- a/api/js/etemplate/et2_widget_diff.js +++ b/api/js/etemplate/et2_widget_diff.js @@ -11,8 +11,8 @@ */ /*egw:uses - jquery.jquery; - jquery.jquery-ui; + /vendor/bower-asset/jquery/dist/jquery.js; + /vendor/bower-asset/jquery-ui/jquery-ui.js; lib/jsdifflib/difflib; lib/jsdifflib/diffview; et2_core_valueWidget; diff --git a/api/js/etemplate/et2_widget_dropdown_button.js b/api/js/etemplate/et2_widget_dropdown_button.js index 416acc1328..885bd8a585 100644 --- a/api/js/etemplate/et2_widget_dropdown_button.js +++ b/api/js/etemplate/et2_widget_dropdown_button.js @@ -11,8 +11,8 @@ */ /*egw:uses - jquery.jquery; - jquery.jquery-ui; + /vendor/bower-asset/jquery/dist/jquery.js; + /vendor/bower-asset/jquery-ui/jquery-ui.js; et2_baseWidget; */ diff --git a/api/js/etemplate/et2_widget_grid.js b/api/js/etemplate/et2_widget_grid.js index ab1e91264f..fe07cca919 100644 --- a/api/js/etemplate/et2_widget_grid.js +++ b/api/js/etemplate/et2_widget_grid.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_DOMWidget; et2_core_xml; */ diff --git a/api/js/etemplate/et2_widget_hbox.js b/api/js/etemplate/et2_widget_hbox.js index 71795b7867..f3055b7394 100644 --- a/api/js/etemplate/et2_widget_hbox.js +++ b/api/js/etemplate/et2_widget_hbox.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_baseWidget; */ diff --git a/api/js/etemplate/et2_widget_historylog.js b/api/js/etemplate/et2_widget_historylog.js index 3af6a33151..7fb1c3ea6a 100644 --- a/api/js/etemplate/et2_widget_historylog.js +++ b/api/js/etemplate/et2_widget_historylog.js @@ -11,8 +11,8 @@ */ /*egw:uses - jquery.jquery; - jquery.jquery-ui; + /vendor/bower-asset/jquery/dist/jquery.js; + /vendor/bower-asset/jquery-ui/jquery-ui.js; et2_core_valueWidget; // Include the grid classes diff --git a/api/js/etemplate/et2_widget_html.js b/api/js/etemplate/et2_widget_html.js index d343af36a6..381ef43f2b 100644 --- a/api/js/etemplate/et2_widget_html.js +++ b/api/js/etemplate/et2_widget_html.js @@ -12,7 +12,7 @@ /*egw:uses jsapi.jsapi; // Needed for egw_seperateJavaScript - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_baseWidget; */ diff --git a/api/js/etemplate/et2_widget_htmlarea.js b/api/js/etemplate/et2_widget_htmlarea.js index 0ed01cf55d..9147e2d8a9 100644 --- a/api/js/etemplate/et2_widget_htmlarea.js +++ b/api/js/etemplate/et2_widget_htmlarea.js @@ -12,7 +12,7 @@ /*egw:uses jsapi.jsapi; // Needed for egw_seperateJavaScript - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; ckeditor.ckeditor; ckeditor.config; ckeditor.adapters/jquery; diff --git a/api/js/etemplate/et2_widget_image.js b/api/js/etemplate/et2_widget_image.js index 3a9f2d673b..0fd21afbc0 100644 --- a/api/js/etemplate/et2_widget_image.js +++ b/api/js/etemplate/et2_widget_image.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_interfaces; et2_core_baseWidget; expose; diff --git a/api/js/etemplate/et2_widget_itempicker.js b/api/js/etemplate/et2_widget_itempicker.js index cb34138d8f..dd0f2cdf66 100755 --- a/api/js/etemplate/et2_widget_itempicker.js +++ b/api/js/etemplate/et2_widget_itempicker.js @@ -14,7 +14,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_inputWidget; et2_core_valueWidget; et2_extension_itempicker_actions; diff --git a/api/js/etemplate/et2_widget_link.js b/api/js/etemplate/et2_widget_link.js index f71aadfa71..ce34226902 100644 --- a/api/js/etemplate/et2_widget_link.js +++ b/api/js/etemplate/et2_widget_link.js @@ -11,8 +11,8 @@ */ /*egw:uses - jquery.jquery; - jquery.jquery-ui; + /vendor/bower-asset/jquery/dist/jquery.js; + /vendor/bower-asset/jquery-ui/jquery-ui.js; et2_core_inputWidget; et2_core_valueWidget; diff --git a/api/js/etemplate/et2_widget_portlet.js b/api/js/etemplate/et2_widget_portlet.js index 264f9abacc..895519424e 100644 --- a/api/js/etemplate/et2_widget_portlet.js +++ b/api/js/etemplate/et2_widget_portlet.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_baseWidget; */ diff --git a/api/js/etemplate/et2_widget_progress.js b/api/js/etemplate/et2_widget_progress.js index 37d2990624..d03fcac7bf 100644 --- a/api/js/etemplate/et2_widget_progress.js +++ b/api/js/etemplate/et2_widget_progress.js @@ -10,7 +10,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_interfaces; et2_core_valueWidget; */ diff --git a/api/js/etemplate/et2_widget_radiobox.js b/api/js/etemplate/et2_widget_radiobox.js index 2afd6a558e..5a044f1648 100644 --- a/api/js/etemplate/et2_widget_radiobox.js +++ b/api/js/etemplate/et2_widget_radiobox.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_inputWidget; */ diff --git a/api/js/etemplate/et2_widget_selectbox.js b/api/js/etemplate/et2_widget_selectbox.js index d2aa60d02a..17c00b2620 100644 --- a/api/js/etemplate/et2_widget_selectbox.js +++ b/api/js/etemplate/et2_widget_selectbox.js @@ -12,7 +12,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; /api/js/jquery/chosen/chosen.jquery.js; et2_core_xml; et2_core_DOMWidget; @@ -565,7 +565,7 @@ var et2_selectbox = (function(){ "use strict"; return et2_inputWidget.extend( */ find_multi_option: function(_value) { - return jQuery("input[value='"+ + return jQuery("input[value='"+ (typeof _value === 'string' ? _value.replace(this._escape_value_replace, this._escape_value_with) : _value)+ "']", this.multiOptions ); @@ -836,7 +836,7 @@ var et2_selectbox = (function(){ "use strict"; return et2_inputWidget.extend( return this._super.apply(this, arguments); } }, - + /** * override set disabled for tags as the tags using * chosen dom and need to be treated different diff --git a/api/js/etemplate/et2_widget_split.js b/api/js/etemplate/et2_widget_split.js index e6203c7bf5..6d98fbbdaf 100644 --- a/api/js/etemplate/et2_widget_split.js +++ b/api/js/etemplate/et2_widget_split.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; jquery.splitter; et2_core_baseWidget; */ diff --git a/api/js/etemplate/et2_widget_tabs.js b/api/js/etemplate/et2_widget_tabs.js index bfc796d55f..8086ecec84 100644 --- a/api/js/etemplate/et2_widget_tabs.js +++ b/api/js/etemplate/et2_widget_tabs.js @@ -12,7 +12,7 @@ /*egw:uses jsapi.egw; - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_valueWidget; */ diff --git a/api/js/etemplate/et2_widget_textbox.js b/api/js/etemplate/et2_widget_textbox.js index 655f162191..9ac38db02b 100644 --- a/api/js/etemplate/et2_widget_textbox.js +++ b/api/js/etemplate/et2_widget_textbox.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_inputWidget; et2_core_valueWidget; */ diff --git a/api/js/etemplate/et2_widget_toolbar.js b/api/js/etemplate/et2_widget_toolbar.js index d4d45b1c26..b6da5327a5 100644 --- a/api/js/etemplate/et2_widget_toolbar.js +++ b/api/js/etemplate/et2_widget_toolbar.js @@ -11,8 +11,8 @@ */ /*egw:uses - jquery.jquery; - jquery.jquery-ui; + /vendor/bower-asset/jquery/dist/jquery.js; + /vendor/bower-asset/jquery-ui/jquery-ui.js; et2_DOMWidget; */ diff --git a/api/js/etemplate/et2_widget_vfs.js b/api/js/etemplate/et2_widget_vfs.js index 8052c0bf4f..6cf90130d8 100644 --- a/api/js/etemplate/et2_widget_vfs.js +++ b/api/js/etemplate/et2_widget_vfs.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_inputWidget; et2_core_valueWidget; et2_widget_description; diff --git a/api/js/etemplate/et2_widget_video.js b/api/js/etemplate/et2_widget_video.js index 0539d4e4e8..439051cbf1 100644 --- a/api/js/etemplate/et2_widget_video.js +++ b/api/js/etemplate/et2_widget_video.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; et2_core_interfaces; et2_core_baseWidget; */ diff --git a/api/js/etemplate/expose.js b/api/js/etemplate/expose.js index 81e54d7be8..32abd7c5fa 100644 --- a/api/js/etemplate/expose.js +++ b/api/js/etemplate/expose.js @@ -11,7 +11,7 @@ */ /*egw:uses - jquery.jquery; + /vendor/bower-asset/jquery/dist/jquery.js; /api/js/jquery/blueimp/js/blueimp-gallery.min.js; */ diff --git a/api/js/framework/fw_base.js b/api/js/framework/fw_base.js index e8005c1187..d603fb2f07 100644 --- a/api/js/framework/fw_base.js +++ b/api/js/framework/fw_base.js @@ -8,7 +8,7 @@ */ /*egw:uses - jquery.jquery; + vendor.bower-asset.jquery.dist.jquery; egw_inheritance.js; */ diff --git a/api/js/framework/fw_browser.js b/api/js/framework/fw_browser.js index cb61a1a839..c7a4f34aea 100644 --- a/api/js/framework/fw_browser.js +++ b/api/js/framework/fw_browser.js @@ -7,7 +7,7 @@ */ /*egw:uses - jquery.jquery; + vendor.bower-asset.jquery.dist.jquery; egw_action.egw_action_common; egw_inheritance.js; */ diff --git a/api/js/framework/fw_desktop.js b/api/js/framework/fw_desktop.js index 4cd3c881b9..a2aa7e8dc4 100644 --- a/api/js/framework/fw_desktop.js +++ b/api/js/framework/fw_desktop.js @@ -9,7 +9,7 @@ */ /*egw:uses - jquery.jquery; + vendor.bower-asset.jquery.dist.jquery; framework.fw_base; framework.fw_browser; framework.fw_ui; diff --git a/api/js/framework/fw_ui.js b/api/js/framework/fw_ui.js index 4fdcb6b5e6..402d607692 100644 --- a/api/js/framework/fw_ui.js +++ b/api/js/framework/fw_ui.js @@ -8,7 +8,7 @@ */ /*egw:uses - jquery.jquery; + vendor.bower-asset.jquery.dist.jquery; /api/js/jquery/mousewheel/mousewheel.js; egw_inheritance.js; */ diff --git a/api/js/jquery/TouchSwipe/.gitignore b/api/js/jquery/TouchSwipe/.gitignore deleted file mode 100644 index c8c74ad0d9..0000000000 --- a/api/js/jquery/TouchSwipe/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -Makefile -.DS_Store \ No newline at end of file diff --git a/api/js/jquery/TouchSwipe/README.md b/api/js/jquery/TouchSwipe/README.md deleted file mode 100644 index a1d1a085cb..0000000000 --- a/api/js/jquery/TouchSwipe/README.md +++ /dev/null @@ -1,101 +0,0 @@ -#TouchSwipe 1.6 -A jquery plugin to be used on touch devices such as iPad, iPhone, android etc - -Detects single and multiple finger swipes, pinches and falls back to mouse 'drags' on the desktop. - -Time and distance thresholds can be set to destinguish between swipe gesture and slow drag. - -Allows exclusion of child elements (interactive elements) as well allowing page scrolling or page zooming depending on configuration. - - -### Demos, examples and docs - -[http://labs.rampinteractive.co.uk/touchSwipe](http://labs.rampinteractive.co.uk/touchSwipe) -[http://labs.rampinteractive.co.uk/touchSwipe/docs](http://labs.rampinteractive.co.uk/touchSwipe/docs) - - - -### For port to XUI see: -https://github.com/cowgp/xui-touchSwipe - -### Version History - -* **1.6.6** *2014-06-04* - - Merge of pull requests. - - IE10 touch support - - Only prevent default event handling on valid swipe - - Separate license/changelog comment - - Detect if the swipe is valid at the end of the touch event. - - Pass fingerdata to event handlers. - - Add 'hold' gesture - - Be more tolerant about the tap distance - - Typos and minor fixes -* **1.6.5** *2013-08-24* - - Merged a few pull requests fixing various bugs, added AMD support. -* **1.6.4** *2013-04-04* - - Fixed bug with cancelThreshold introduced in 1.6.3, where swipe status no longer fired start event, and stopped once swiping back. -* **1.6.3** *2013-04-01* - - added doubletap, longtap events and longTapThreshold, doubleTapThreshold property -* **1.6.2** *2013-03-23* - - Added support for events binding with on / off / bind in jQ for all callback names. - - Deprecated the 'click' handler in favour of tap. - - added cancelThreshold property - - added 'option' method to update init options at runtime -* **1.6.1** *2013-02-12* - - Added support for ie8 touch events -* **1.6.0** *2013-01-12* - - Fixed bugs with pinching, mainly when both pinch and swipe enabled, as well as adding time threshold for multifinger gestures, so releasing one finger beofre the other doesnt trigger as single finger gesture. - - made the demo site all static local HTML pages so they can be run locally by a developer - - added jsDoc comments and added documentation for the plugin - - code tidy - - added triggerOnTouchLeave property that will end the event when the user swipes off the element. -* **1.5.1** *2012-11-22* - - Fixed bug with jQuery 1.8 and trailing comma in excludedElements - - Fixed bug with IE and event.preventDefault(); -* **1.5.0** *2012-11-10* - - Added `excludedElements`, a jquery selector that specifies child elements that do NOT trigger swipes. By default, this is one select that removes all form, input select, button and anchor elements. -* **1.4.0** *2012-04-10* - - Added pinch support, `pinchIn`, `pinchOut` and `pinchStatus` -* **1.3.3** *2012-09-08* - - Code tidy prep for minified version -* **1.3.2** *2012-29-07* - - Added `fallbackToMouseEvents` option to NOT capture mouse events on non touch devices. - - Added "all" fingers value to the fingers property, so any combinatin of fingers triggers the swipe, allowing event handlers to check the finger count -* **1.3.1** *2012-05-06* - - Bug fixes - - bind() with false as last argument is no longer supported in jQuery 1.6, also, if you just click, the duration is now returned correctly. -* **1.3.0** *2012-06-06* - - Refactored whole plugin to allow for methods to be executed, as well as exposed defaults for user override. Added `enable`, `disable`, and `destroy` methods -* **1.2.8** *2012-05-06* - - Added the possibility to return a value like null or false in the trigger callback. In that way we can control when the touch start/move should take effect or not (simply by returning in some cases return null; or return false;) This effects the ontouchstart/ontouchmove event. -* **1.2.7** *2012-05-06* - - Changed time threshold to have null default for backwards compatibility. Added duration param passed back in events, and refactored how time is handled. -* **1.2.6** *2012-14-05* - - Added timeThreshold between start and end touch, so user can ignore slow swipes (thanks to Mark Chase). Default is null, all swipes are detected -* **1.2.5** *2011-27-09* - - Added support for testing swipes with mouse on desktop browser (thanks to https://github.com/joelhy) -* **1.2.4** *2011-28-04* - - Changed licence terms to be MIT or GPL inline with jQuery. Added check for support of touch events to stop non compatible browsers erroring. -* **1.2.2** *2011-23-02* - - Fixed bug where scope was not preserved in callback methods. -* **1.2.1** *2011-23-02* - - removed console log! -* **1.2.0** *2011-23-02* - - added `click` handler. This is fired if the user simply clicks and does not swipe. The event object and click target are passed to handler. - - If you use the http://code.google.com/p/jquery-ui-for-ipad-and-iphone/ plugin, you can also assign jQuery mouse events to children of a touchSwipe object. -* **1.1.0** *2011-21-02* - - added `allowPageScroll` property to allow swiping and scrolling of page - - changed handler signatures so one handler can be used for multiple events -* **1.0.1** *2010-12-12* - - removed multibyte comments -* **1.0.0** *2010-12-12* - - feature complete - - - - - - - - - diff --git a/api/js/jquery/TouchSwipe/bower.json b/api/js/jquery/TouchSwipe/bower.json deleted file mode 100644 index f704054298..0000000000 --- a/api/js/jquery/TouchSwipe/bower.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "jquery-touchswipe", - "version": "1.6.6", - "main": "./jquery.touchSwipe.js", - "repository": { - "type": "git", - "url": "git://github.com/mattbryson/TouchSwipe-Jquery-Plugin.git" - } -} diff --git a/api/js/jquery/TouchSwipe/demos/Any_finger_swipe.html b/api/js/jquery/TouchSwipe/demos/Any_finger_swipe.html deleted file mode 100644 index 7257f0b622..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Any_finger_swipe.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - - -

Events: swipe

-

properties: fingers

-

By setting the number of fingers to 'all', any number of fingers will trigger the swipe.

- - -

-			
-			
-			
Swipe me with different combinations of fingers
- - - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Basic_swipe.html b/api/js/jquery/TouchSwipe/demos/Basic_swipe.html deleted file mode 100644 index 94de1b63e6..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Basic_swipe.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - -

events: swipe,swipeLeft, swipeRight, swipeUp, swipeDown

-

By using the swipe handler, you can detect all 4 directions, or use the individual methods swipeLeft, swipeRight, swipeUp, swipeDown

- - -

-			
-			
-			
Swipe me
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Enable_and_destroy.html b/api/js/jquery/TouchSwipe/demos/Enable_and_destroy.html deleted file mode 100644 index 284f61d2d1..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Enable_and_destroy.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - -

methods: enable, disable, destroy

-

By using the enable, disable and destroy methods, you can temporarily disable interaction with a swipe element, or completely destroy it, which requires re instantiation.
-

- - - -
- -
- - - - -
- -
Swipe me
- -

- -
Swipe me - Im not affected by the above...
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Excluded_children.html b/api/js/jquery/TouchSwipe/demos/Excluded_children.html deleted file mode 100644 index 93ef4745cc..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Excluded_children.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - -

property: excludedElements

-

If you want to exclude certain child elements from triggering swipes, you can simply add a .noSwipe class to the element. Then the element and any of its children will no longer trigger the swipe. -

Also, a jQuery selector is used to exclude input elements as well as the .noSwipe elements. By default all button, input, select, textarea and a elements are excluded. - So either add a .noSwipe class the element, or set your own selector in the excludedElements property. -

- -

-	
-			
-			
-			
-
Swipe me, the child elements will not trigger swipes by default

-
- - - -
- -

Im am NOT swipeable because my class is .noSwipe

- -
- - -
-
Swipe me, the child elements will not trigger swipes as they have been explicitly excluded

-
- - - -
- -

Im am NOT swipeable because my im added to the excludedElements array

-
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Finger_swipe.html b/api/js/jquery/TouchSwipe/demos/Finger_swipe.html deleted file mode 100644 index a736c27206..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Finger_swipe.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - - -

property: fingers

-

By setting the number of fingers to 2, you can detect ONLY 2 finger swipes, likewise for 3 fingers.

- - -

-			
-			
-			
Swipe me with 2 fingers
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Handlers_and_events.html b/api/js/jquery/TouchSwipe/demos/Handlers_and_events.html deleted file mode 100644 index f8b7fa1c60..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Handlers_and_events.html +++ /dev/null @@ -1,128 +0,0 @@ - - - - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - - - -

events: tap hold swipe swipeLeft swipeRight swipeUp swipeDown swipeStatus pinch pinchIn pinchOut pinchStatus

- See the docs for more on each event -

You can either assign callback methods as part of the options object, or you can assign - event handlers using the jQuery on/off event registration.

- -

The example below logs both from the callback and the event handlers. The Remove Events button will remove the - event bindings, and then only the callbacks will be logged. Event logs are bold, callbacks are normal.

- - -

-			
-			
-			
- -
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Hold.html b/api/js/jquery/TouchSwipe/demos/Hold.html deleted file mode 100644 index 9786bb1598..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Hold.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - -

events: tap, hold

-

properties: longTapThreshold

-

You can also detect if the user holds their finger down until the longTapthreshold is met
- The hold handler is passed the original event object and the target that was clicked. -

-

If you use the jquery.ui.ipad.js plugin (http://code.google.com/p/jquery-ui-for-ipad-and-iphone/) you can then also pickup - standard jQuery mouse events on children of the touchSwipe object.

- - - -

-			
-			
-			
-
Hold me :)

-
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Image_gallery_example.html b/api/js/jquery/TouchSwipe/demos/Image_gallery_example.html deleted file mode 100644 index fc3535a25c..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Image_gallery_example.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - - - - - - - - - - - - touchSwipe - - - - - - -Fork me on GitHub - -
-

Below is a very simple image gallery to demonstrate how to implement touchSwipe.

- Swipe the images below left and right. Swipe up and down will scroll the page. Uses HTML5 - CSS to animate.

-
- -
-
- - - -
-
-
- - diff --git a/api/js/jquery/TouchSwipe/demos/Options.html b/api/js/jquery/TouchSwipe/demos/Options.html deleted file mode 100644 index 15952aa4e5..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Options.html +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - -

methods: option

-

By using the option method, you can change any of the init option properties at run time.
- - see the docs for more info. - -

- - -

-			
-			
-			
- - - - - - -
Swipe me
- -

- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Page_scrolling.html b/api/js/jquery/TouchSwipe/demos/Page_scrolling.html deleted file mode 100644 index 33aa362e97..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Page_scrolling.html +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - - - -

property: allowPageScroll

-

You can set how page scrolling is handled by the browser when the user is interacting with a touchSwipe object. -
There are 4 possible settings for the allowPageScroll option. These can be strings, or use the plugin constants in $.fn.swipe.pageScroll -

- -
- NOTE: if the general swipe or swipeStatus handlers are specificed, then allowPageScroll will be dissabled by default, as they detect swipes in all directions. - To use scrolling AND the swipe handler, set allowPageScroll to the direction you want the user to be able to scroll. -

- - -
		
-			
-			
-			

- allowPageScroll = "auto" or $.fn.swipe.pageScroll.AUTO -
Swipe Left or Right The swipe will trigger but the page will NOT scroll. -
Swipe Up or Down The page will scroll as there is no up or down swipe handler.
-
Swipe me
- -

- allowPageScroll = "none" or $.fn.swipe.pageScroll.NONE -
Swipe Left The swipe will trigger but the page will NOT scroll. -
Swipe right, Up or Down No swipe handler is defined, so nothihng happens and the page will NOT scroll.
-
Swipe me
- -

- allowPageScroll = "horizontal" or $.fn.swipe.pageScroll.HORIZONTAL -
Swipe left and right are triggered
-
Swipe me
- -

- allowPageScroll = "vertical" or $.fn.swipe.pageScroll.VERTICAL -
- With the general swipe or swipeStatus handlers -
These enable all 4 directions, but here we have set allowPageScroll to "vertical" so the user can scroll up and down, and swipe left and right with the general swipe handler.
-
Note how the vertical swipe is hit and miss. As soon as the page starts scrolling, the user is no longer swiping across the object. -
Swipe me
- -

- allowPageScroll = "vertical" or $.fn.swipe.pageScroll.HORIZONTAL -
- Vertical, but WITH the general swipe or swipeStatus handlers -
These enable all 4 directions, but here we have set allowPageScroll to "vertical" so the user can scroll up and down, and swipe left and right with the general swipe handler.
-
Note how the vertical swipe is hit and miss. As soon as the page starts scrolling, the user is no longer swiping across the object. -
Swipe me
- - - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Page_zoom.html b/api/js/jquery/TouchSwipe/demos/Page_zoom.html deleted file mode 100644 index 914aaa9e65..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Page_zoom.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - -

property: fingers

-

If just one finger is set for swipes, at the meta tag enables user-scaling, then page zooms will bubble up and trigger.

-
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes"/>
- - -
	
-			
-			
-			
I only swipe left, but you can pinch zoom me as I only capture 1 finger
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Pinch.html b/api/js/jquery/TouchSwipe/demos/Pinch.html deleted file mode 100644 index 766f4a70dd..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Pinch.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - -

events: pinchIn, pinchOut

-

You can also trigger pinch events, pinchIn will trigger when a user has completed a pinch in event, and pinchOut will trigger when a user has pinched out.

- - -
	
-			
-			
-			
Pinch me
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Pinch_and_Swipe.html b/api/js/jquery/TouchSwipe/demos/Pinch_and_Swipe.html deleted file mode 100644 index 181759c854..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Pinch_and_Swipe.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - - -

events: pinchStatus, swipeStatus

-

properties: pinchThreshold

-

You can combine both pinch and swipe events. As the user can simultaneously pinch and swipe, both events are tirggered at the same time.
- The pinchThreshold property sets how far the user must pinch before it is considered a pinch. The default is 20px. This is useful when trying to elimate slight pinch movement when the user is actually swiping. -

- -
	
-				
-			
-				
-
Pinch me
-
-
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Pinch_status.html b/api/js/jquery/TouchSwipe/demos/Pinch_status.html deleted file mode 100644 index f483ca0aa1..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Pinch_status.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - - -

events: pinchStatus

-

You can also get the current status of a pinch, which can be used in place of the other pinch methods. The pinchStatus reports phase, direction, distance, duration, fingerCount and pinchZoom.

- - -
	
-					
-			
-			
Pinch me
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Single_swipe.html b/api/js/jquery/TouchSwipe/demos/Single_swipe.html deleted file mode 100644 index b91ea29bb4..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Single_swipe.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - - -

events: swipeLeft, swipeRight, swipeUp, swipeDown, swipe

-

By using just one handler swipeLeft you can detect ONLY left swipes. There are handlers for each direction, as well as the generic swipe handler.

- - -

-			
-			
I only swipe left
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Stop_propegation.html b/api/js/jquery/TouchSwipe/demos/Stop_propegation.html deleted file mode 100644 index 1fd5ec5395..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Stop_propegation.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - -

events: swipeStatus

-

In your event handlers, you can return a value of false if you want to manually cancel the swipe. This will trigger the 'cancel' event.

- - -

-			
-			
-			
Swipe will start, but then cancel as the event handler returns false
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Swipe_status.html b/api/js/jquery/TouchSwipe/demos/Swipe_status.html deleted file mode 100644 index 2948f3af1d..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Swipe_status.html +++ /dev/null @@ -1,81 +0,0 @@ - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - -

event: swipeStatus

-

You can also get the current status of the swipe, which can be used in place of all other methods. The status reports phase, direction, distance, duration and fingerCount. - Below has a 200px threshold and a 5 second time limit -

- - -

-			
-			
-			
Swipe me
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Tap_vs_swipe.html b/api/js/jquery/TouchSwipe/demos/Tap_vs_swipe.html deleted file mode 100644 index 2f5f4fef71..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Tap_vs_swipe.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - -

events: tap, doubleTap, longTap, swipe

-

properties: longTapThreshold, doubleTapThreshold

-

You can also detect if the user simply taps and does not swipe with the tap handler

- The tap, doubleTap and longTap handler are passed the original event object and the target that was clicked. -

- See also the hold event for when a long tap reaches the longTapThreshold -
-

-

If you use the jquery.ui.ipad.js plugin (http://code.google.com/p/jquery-ui-for-ipad-and-iphone/) you can then also pickup - standard jQuery mouse events on children of the touchSwipe object.

- -

You can set the delay between taps which defines a double tap, and the length of a long tap with the doubleTapThreshold and longTapThreshold properties.

- -

Note: If you assign both tap and double tap, you tap events will be delayed by the length of doubleTapThreshold as it waits to see if its a double before trigger the event

- -

tap replaces the old click handler for naming consistency. Since the introduction of event - triggering as well as callbacks, the plugin cannot trigger a click event as it clashes with the jQ click event, - so both the event and callback are called tap. For backwards compatibility, the click callback will still work - but there is no click event. You must use the tap event when binding with on or bind

- - - -

-			
-			
-			
-
Swipe, Tap, Double Tap or Long Tap me

-

Im just a child div

-

Im a child div with my own jQuery click handler

-
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/Thresholds.html b/api/js/jquery/TouchSwipe/demos/Thresholds.html deleted file mode 100644 index 4279cea1c9..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Thresholds.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - - - - - - -

property: threshold

-

By setting the threshold you can set how far the user must swipe before it is considered a swipe.
Swipe at least 200px

- - -

-			
-			
-			
Swipe me for at least 200 px
- -

property: cancelThreshold

-

By setting the cancelThreshold you can set the minimum distance in px that the user needs to swipe back to cancel the current swipe, even if they have passed the main threshold

- - -
			
-			
Swipe me for at least 200 px, then back 10px to cancel
- -

property: maxTimeThreshold

-

By setting the maxTimeThreshold you can set the maximum time the user has to complete the swipe. A swipe LONGER than this is cancelled. This can be useful for ignoring long slow swipes.
Swipe in under 500ms

- - -
			
-			
Swipe me within 1000 ms
- - - -

- - diff --git a/api/js/jquery/TouchSwipe/demos/Trigger_handlers.html b/api/js/jquery/TouchSwipe/demos/Trigger_handlers.html deleted file mode 100644 index 1064d60e6a..0000000000 --- a/api/js/jquery/TouchSwipe/demos/Trigger_handlers.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - - - - - - - - - - - - touchSwipe - - - Fork me on GitHub -
- - - - - - - - - - -

properties: triggerOnTouchEnd, triggerOnTouchLeave

-

With triggerOnTouchEnd you can trigger the swipe end handler either when the user releases (default) or when the user has swiped the distance / time of the thresholds (but is still swiping).

-

With triggerOnTouchLeave you can end the event if the user swipes off the element

- - -

Swipe below, and the swipeEnd handler will trigger when you have swiped 200 px.

- - -
		
-			
-			
Swipe over 200px and the swipe event will fire
- -

-			
-					
-			
Swipe in under 5000ms and the swipe event will fire
- -

-			
-			
-			
Swipe out of this box and the swipe event will end
- -

-			
-			
-			
Time, distance and trigger on END and trigger on Leave set..
- - -
- - diff --git a/api/js/jquery/TouchSwipe/demos/css/main.css b/api/js/jquery/TouchSwipe/demos/css/main.css deleted file mode 100644 index 2b22479986..0000000000 --- a/api/js/jquery/TouchSwipe/demos/css/main.css +++ /dev/null @@ -1,110 +0,0 @@ -.pagination -{ - width:100%; - margin-top:20px; - margin-bottom:20px; -} - -.clear -{ - clear:both; -} - -.pagination a -{ - font-size: 12px; - line-height: 18px; -} - -.container -{ - max-width:768px; - margin-bottom:20px; -} - -.box -{ - margin-top:20px; - margin-bottom:20px; - max-width:768px; - height:300px; - - padding: 10px; - background-color: #EEE; - -webkit-border-radius: 6px; - -moz-border-radius: 6px; - border-radius: 6px; - - text-align:center; - font-weight: 300; - font-size: 20px; - line-height: 36px; - - overflow:hidden; -} - -body -{ - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 13px; - line-height: 18px; - color: #333; -} - -h1 -{ - margin-top:36px; - margin-bottom:5px; -} - -h2 -{ - font-size: 30px; - line-height: 36px; - font-weight: 300; - margin-bottom:0px; - -} - -h3 -{ - margin-top:0px; - font-size: 18px; - line-height: 24px; - font-weight: 300; - color:#999; -} - -h4 -{ - margin-top:0px; - font-size: 12px; - line-height: 24px; - font-weight: 300; - color:#333; -} - -a -{ - text-decoration:none; - color:#333; -} - -p { - margin-top:10px; -} - -.prettyprint { - font-size:10px; -} - -.example_btn { - margin-bottom:10px; -} - -.properties code, -.methods code, -.events code { - cursor: pointer; - text-decoration: underline; -} \ No newline at end of file diff --git a/api/js/jquery/TouchSwipe/demos/index.html b/api/js/jquery/TouchSwipe/demos/index.html deleted file mode 100644 index 7583900884..0000000000 --- a/api/js/jquery/TouchSwipe/demos/index.html +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - - - - - - touchSwipe - - - - - - - Fork me on GitHub -
- - -

Features

- - -

Docs

- - -

Options

- - -

Demos

- - - -
-
- - - - - - - diff --git a/api/js/jquery/TouchSwipe/demos/js/jquery.ui.ipad.js b/api/js/jquery/TouchSwipe/demos/js/jquery.ui.ipad.js deleted file mode 100644 index bbfef077a5..0000000000 --- a/api/js/jquery/TouchSwipe/demos/js/jquery.ui.ipad.js +++ /dev/null @@ -1,223 +0,0 @@ -/** -* jQuery.UI.iPad plugin -* Copyright (c) 2010 Stephen von Takach -* licensed under MIT. -* Date: 27/8/2010 -* -* Project Home: -* http://code.google.com/p/jquery-ui-for-ipad-and-iphone/ -*/ - - -$(function() { - // - // Extend jQuery feature detection - // - $.extend($.support, { - touch: typeof Touch == "object" - }); - - // - // Hook up touch events - // - if ($.support.touch) { - document.addEventListener("touchstart", iPadTouchHandler, false); - document.addEventListener("touchmove", iPadTouchHandler, false); - document.addEventListener("touchend", iPadTouchHandler, false); - document.addEventListener("touchcancel", iPadTouchHandler, false); - } -}); - - -var lastTap = null; // Holds last tapped element (so we can compare for double tap) -var tapValid = false; // Are we still in the .6 second window where a double tap can occur -var tapTimeout = null; // The timeout reference - -function cancelTap() { - tapValid = false; -} - - -var rightClickPending = false; // Is a right click still feasible -var rightClickEvent = null; // the original event -var holdTimeout = null; // timeout reference -var cancelMouseUp = false; // prevents a click from occuring as we want the context menu - - -function cancelHold() { - if (rightClickPending) { - window.clearTimeout(holdTimeout); - rightClickPending = false; - rightClickEvent = null; - } -} - -function startHold(event) { - if (rightClickPending) - return; - - rightClickPending = true; // We could be performing a right click - rightClickEvent = (event.changedTouches)[0]; - holdTimeout = window.setTimeout("doRightClick();", 800); -} - - -function doRightClick() { - rightClickPending = false; - - // - // We need to mouse up (as we were down) - // - var first = rightClickEvent, - simulatedEvent = document.createEvent("MouseEvent"); - simulatedEvent.initMouseEvent("mouseup", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, - false, false, false, false, 0, null); - first.target.dispatchEvent(simulatedEvent); - - // - // emulate a right click - // - simulatedEvent = document.createEvent("MouseEvent"); - simulatedEvent.initMouseEvent("mousedown", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, - false, false, false, false, 2, null); - first.target.dispatchEvent(simulatedEvent); - - // - // Show a context menu - // - simulatedEvent = document.createEvent("MouseEvent"); - simulatedEvent.initMouseEvent("contextmenu", true, true, window, 1, first.screenX + 50, first.screenY + 5, first.clientX + 50, first.clientY + 5, - false, false, false, false, 2, null); - first.target.dispatchEvent(simulatedEvent); - - - // - // Note:: I don't mouse up the right click here however feel free to add if required - // - - - cancelMouseUp = true; - rightClickEvent = null; // Release memory -} - - -// -// mouse over event then mouse down -// -function iPadTouchStart(event) { - var touches = event.changedTouches, - first = touches[0], - type = "mouseover", - simulatedEvent = document.createEvent("MouseEvent"); - // - // Mouse over first - I have live events attached on mouse over - // - simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, - false, false, false, false, 0, null); - first.target.dispatchEvent(simulatedEvent); - - type = "mousedown"; - simulatedEvent = document.createEvent("MouseEvent"); - - simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, - false, false, false, false, 0, null); - first.target.dispatchEvent(simulatedEvent); - - - if (!tapValid) { - lastTap = first.target; - tapValid = true; - tapTimeout = window.setTimeout("cancelTap();", 600); - startHold(event); - } - else { - window.clearTimeout(tapTimeout); - - // - // If a double tap is still a possibility and the elements are the same - // Then perform a double click - // - if (first.target == lastTap) { - lastTap = null; - tapValid = false; - - type = "click"; - simulatedEvent = document.createEvent("MouseEvent"); - - simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, - false, false, false, false, 0/*left*/, null); - first.target.dispatchEvent(simulatedEvent); - - type = "dblclick"; - simulatedEvent = document.createEvent("MouseEvent"); - - simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, - false, false, false, false, 0/*left*/, null); - first.target.dispatchEvent(simulatedEvent); - } - else { - lastTap = first.target; - tapValid = true; - tapTimeout = window.setTimeout("cancelTap();", 600); - startHold(event); - } - } -} - -function iPadTouchHandler(event) { - var type = "", - button = 0; /*left*/ - - if (event.touches.length > 1) - return; - - switch (event.type) { - case "touchstart": - if ($(event.changedTouches[0].target).is("select")) { - return; - } - iPadTouchStart(event); /*We need to trigger two events here to support one touch drag and drop*/ - event.preventDefault(); - return false; - break; - - case "touchmove": - cancelHold(); - type = "mousemove"; - event.preventDefault(); - break; - - case "touchend": - if (cancelMouseUp) { - cancelMouseUp = false; - event.preventDefault(); - return false; - } - cancelHold(); - type = "mouseup"; - break; - - default: - return; - } - - var touches = event.changedTouches, - first = touches[0], - simulatedEvent = document.createEvent("MouseEvent"); - - simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, - false, false, false, false, button, null); - - first.target.dispatchEvent(simulatedEvent); - - if (type == "mouseup" && tapValid && first.target == lastTap) { // This actually emulates the ipads default behaviour (which we prevented) - simulatedEvent = document.createEvent("MouseEvent"); // This check avoids click being emulated on a double tap - - simulatedEvent.initMouseEvent("click", true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, - false, false, false, false, button, null); - - first.target.dispatchEvent(simulatedEvent); - } -} - - diff --git a/api/js/jquery/TouchSwipe/demos/js/main.js b/api/js/jquery/TouchSwipe/demos/js/main.js deleted file mode 100644 index a03764fac6..0000000000 --- a/api/js/jquery/TouchSwipe/demos/js/main.js +++ /dev/null @@ -1,240 +0,0 @@ -String.prototype.trim = function() { - return this.replace(/^\s+|\s+$/g,""); -} -String.prototype.trimLeft = function() { - return this.replace(/^\s+/,""); -} -String.prototype.trimRight = function() { - return this.replace(/\s+$/,""); -} - - -//Demos file list (in order of presentation) -//THe page name is formed from the file name. -var fileList = [ - 'Basic_swipe.html', - 'Single_swipe.html', - 'Any_finger_swipe.html', - 'Finger_swipe.html', - 'Swipe_status.html', - 'Pinch.html', - 'Pinch_status.html', - 'Pinch_and_Swipe.html', - 'Trigger_handlers.html', - 'Stop_propegation.html', - 'Handlers_and_events.html', - 'Tap_vs_swipe.html', - 'Hold.html', - 'Excluded_children.html', - 'Page_zoom.html', - 'Thresholds.html', - 'Enable_and_destroy.html', - 'Page_scrolling.html', - 'Options.html', - 'Image_gallery_example.html' -]; - - -/** - * Builds the demo page - */ -function init() { - buildTitle(); - buildCodeExample(); - buildNavigation(); -} - -/** - * Creates the navigation components - */ -function buildNavigation() { - $('.navigation').each(function( index ) { - $(this).html( getNavigation() ); - }); - - $('.navigation_menu').each(function( index ) { - $(this).html( getNavigationMenu() ); - }) - - $('.navigation_list').each(function( index ) { - $(this).html( getNavigationList() ); - }) - - - $('#menu').change( function() { - location.href=$(this).val(); - }); - - $('#menu li').click( function() { - location.href=$(this).val(); - }); - - $('.example_btn').click( function() { - $(document).scrollTop( $("#test").offset().top ); - }); - - $('.events code').click( function() { - location.href = '../docs/symbols/%24.fn.swipe.html#event:' + $(this).text(); - }); - - $('.properties code').click( function() { - location.href = '../docs/symbols/%24.fn.swipe.defaults.html#' + $(this).text(); - }); - - $('.methods code').click( function() { - location.href = '../docs/symbols/%24.fn.swipe.html#' + $(this).text(); - }); -} - -/** - * Builds the title element - */ -function buildTitle() { - $('.title').each(function( index ) { - $(this).html( getTitle() ); - }) -} - -/** - * Copies the - - - - - - -
- - -
-
-
- -
- -
- -
-

File Index

- - -
- -
-
- No description. -
- -
-
- -
-
-
- -

Documentation generated by JsDoc Toolkit 2.4.0 on Wed Jun 04 2014 13:36:57 GMT+0100 (BST)

-
- -
- - diff --git a/api/js/jquery/TouchSwipe/docs/img/class.png b/api/js/jquery/TouchSwipe/docs/img/class.png deleted file mode 100644 index 7eb9c78a6d..0000000000 Binary files a/api/js/jquery/TouchSwipe/docs/img/class.png and /dev/null differ diff --git a/api/js/jquery/TouchSwipe/docs/img/classicons.png b/api/js/jquery/TouchSwipe/docs/img/classicons.png deleted file mode 100644 index 02f1006f80..0000000000 Binary files a/api/js/jquery/TouchSwipe/docs/img/classicons.png and /dev/null differ diff --git a/api/js/jquery/TouchSwipe/docs/img/event.png b/api/js/jquery/TouchSwipe/docs/img/event.png deleted file mode 100644 index 4e05fd0c2d..0000000000 Binary files a/api/js/jquery/TouchSwipe/docs/img/event.png and /dev/null differ diff --git a/api/js/jquery/TouchSwipe/docs/img/glyphicons-halflings-white.png b/api/js/jquery/TouchSwipe/docs/img/glyphicons-halflings-white.png deleted file mode 100644 index 3bf6484a29..0000000000 Binary files a/api/js/jquery/TouchSwipe/docs/img/glyphicons-halflings-white.png and /dev/null differ diff --git a/api/js/jquery/TouchSwipe/docs/img/glyphicons-halflings.png b/api/js/jquery/TouchSwipe/docs/img/glyphicons-halflings.png deleted file mode 100644 index 79bc568c21..0000000000 Binary files a/api/js/jquery/TouchSwipe/docs/img/glyphicons-halflings.png and /dev/null differ diff --git a/api/js/jquery/TouchSwipe/docs/img/interface.png b/api/js/jquery/TouchSwipe/docs/img/interface.png deleted file mode 100644 index 72b6f8a69f..0000000000 Binary files a/api/js/jquery/TouchSwipe/docs/img/interface.png and /dev/null differ diff --git a/api/js/jquery/TouchSwipe/docs/img/namespace.png b/api/js/jquery/TouchSwipe/docs/img/namespace.png deleted file mode 100644 index 399998ef1b..0000000000 Binary files a/api/js/jquery/TouchSwipe/docs/img/namespace.png and /dev/null differ diff --git a/api/js/jquery/TouchSwipe/docs/index.html b/api/js/jquery/TouchSwipe/docs/index.html deleted file mode 100644 index f685c9259a..0000000000 --- a/api/js/jquery/TouchSwipe/docs/index.html +++ /dev/null @@ -1,386 +0,0 @@ - - - - - - JsDoc Reference - Index - - - - - - - - - - - - - -
- -
- -
-
-
- -
- -
- -
-

Class Index

-
- -
-
- $ - ( ) - - - - - - - -
-
-
-
- See (http://jquery.com/). - code » -
- - - - - - - -
-
-
- -
-
- fn - ( ) - - - - - - - Static -
-
-
-
- See (http://jquery.com/) - code » -
- - - - - - - -
-
-
- -
-
- swipe - ( Mixed method ) - - - - - - - Static -
-
-
-
- Applies TouchSwipe behaviour to one or more jQuery objects. -The TouchSwipe plugin can be instantiated via this method, or methods within -TouchSwipe can be executed via this method as per jQuery plugin architecture. - code » -
- - - - - -
- See - - TouchSwipe - -
- - - -
- - Parameters -
- -
method : Mixed
-
If the current DOMNode is a TouchSwipe object, and method is a TouchSwipe method, then -the method is executed, and any following arguments are passed to the TouchSwipe method. -If method is an object, then the TouchSwipe class is instantiated on the current DOMNode, passing the -configuration properties defined in the object. See TouchSwipe
- -
- - -
- -
-
-
- -
-
- defaults - ( ) - - - - - - - Static -
-
-
-
- The default configuration, and available options to configure touch swipe with. -You can set the default values by updating any of the properties prior to instantiation. - code » -
- - - - - - - -
-
-
- -
-
- directions - ( ) - - - - - - - Static -
-
-
-
- The direction constants that are passed to the event handlers. -These properties are read only, attempting to change them will not alter the values passed to the event handlers. - code » -
- - - - - - - -
-
-
- -
-
- fingers - ( ) - - - - - - - Static -
-
-
-
- Constants representing the number of fingers used in a swipe. These are used to set both the value of fingers in the -options object, as well as the value of the fingers event property. -These properties are read only, attempting to change them will not alter the values passed to the event handlers. - code » -
- - - - - - - - - -
-
-
- -
-
- pageScroll - ( ) - - - - - - - Static -
-
-
-
- The page scroll constants that can be used to set the value of allowPageScroll option -These properties are read only - code » -
- - - - - - - - - -
-
-
- -
-
- phases - ( ) - - - - - - - Static -
-
-
-
- The phases that a touch event goes through. The phase is passed to the event handlers. -These properties are read only, attempting to change them will not alter the values passed to the event handlers. - code » -
- - - - - - - -
-
-
- -
-
- _global_ - ( ) - - - - - - - -
-
-
-
- No description. - -
- - - - - - - -
-
-
- -
-
-
-
- -

Documentation generated by JsDoc Toolkit 2.4.0 on Wed Jun 04 2014 13:36:57 GMT+0100 (BST)

-
-
- - diff --git a/api/js/jquery/TouchSwipe/docs/js/accordion.js b/api/js/jquery/TouchSwipe/docs/js/accordion.js deleted file mode 100644 index fbb9444266..0000000000 --- a/api/js/jquery/TouchSwipe/docs/js/accordion.js +++ /dev/null @@ -1,13 +0,0 @@ -// This script licensed under the MIT. -// http://orgachem.mit-license.org - -/** - * @fileoverview A script for accordion effects. - * @author orga.chem.job@gmail.com (Orga Chem) - */ - -$(function() { - $('.accordion-button').click(function() { - $(this).find('.accordion-content').slideToggle(); - }); -}); diff --git a/api/js/jquery/TouchSwipe/docs/js/jquery-1.7.2.min.js b/api/js/jquery/TouchSwipe/docs/js/jquery-1.7.2.min.js deleted file mode 100644 index 16ad06c5ac..0000000000 --- a/api/js/jquery/TouchSwipe/docs/js/jquery-1.7.2.min.js +++ /dev/null @@ -1,4 +0,0 @@ -/*! jQuery v1.7.2 jquery.com | jquery.org/license */ -(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"":"")+""),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;e=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="
"+""+"
",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="
t
",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="
",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function( -a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&j.push({elem:this,matches:d.slice(e)});for(k=0;k0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f -.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(;d1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]===""&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/api/js/jquery/TouchSwipe/docs/js/prettify.js b/api/js/jquery/TouchSwipe/docs/js/prettify.js deleted file mode 100644 index eef5ad7e6a..0000000000 --- a/api/js/jquery/TouchSwipe/docs/js/prettify.js +++ /dev/null @@ -1,28 +0,0 @@ -var q=null;window.PR_SHOULD_USE_CONTINUATION=!0; -(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a= -[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m), -l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/, -q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/, -q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g, -"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a), -a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e} -for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"], -"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"], -H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"], -J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+ -I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]), -["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css", -/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}), -["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes", -hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p=0){var k=k.match(g),f,b;if(b= -!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p - - - - - JsDoc Reference - $.fn - - - - - - - - - - - - -
- - - - - - -
-
- -
- -
- - -
- -
- -

- - Class $.fn - - - - - - -

- - -
- -
- - -
- - Constructor - - - - - - - - - - - -
- - -

-

Constructor

-
-
-
- fn - ( ) - - - - - - - Static -
-
-
-
- See (http://jquery.com/) - code » -
- - - - - - - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - -
- -

Documentation generated by JsDoc Toolkit 2.4.0 on Wed Jun 04 2014 13:36:56 GMT+0100 (BST)

-
-
- diff --git a/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.defaults.html b/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.defaults.html deleted file mode 100644 index f097f02f6f..0000000000 --- a/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.defaults.html +++ /dev/null @@ -1,910 +0,0 @@ - - - - - - JsDoc Reference - $.fn.swipe.defaults - - - - - - - - - - - - -
- - - - - - -
-
- -
- -
- - -
- -
- -

- - Namespace $.fn.swipe.defaults - - - - - - -

- - -
- -
- - -
- - - - - Instance members - - - - - - - - -
- - -

Namespace

-
-
-
- $.fn.swipe.defaults - - - - - - Static -
-
-
- The default configuration, and available options to configure touch swipe with. -You can set the default values by updating any of the properties prior to instantiation. - - code » - -
-
-
-
- - - - - -

-

Instance members

- - -

Instance PropertiesDefined By

-
- -
-
- (function) - - - - - - - $.fn.swipe.defaults -
-
-
-
- [hold=null] A handler triggered when a user reaches longTapThreshold on the item. See $.fn.swipe.defaults#longTapThreshold - code » -
- - - - - - - -
-
-
- -
-
- allowPageScroll - : string|undefined - (default = 'auto') - - - - - $.fn.swipe.defaults -
-
-
-
- How the browser handles page scrolls when the user is swiping on a touchSwipe object. See $.fn.swipe.pageScroll.

- "auto" : all undefined swipes will cause the page to scroll in that direction.
- "none" : the page will not scroll when user swipes.
- "horizontal" : will force page to scroll on horizontal swipes.
- "vertical" : will force page to scroll on vertical swipes.
- code » -
- - - - - - - -
-
-
- -
-
- cancelThreshold - : int - (default = null) - - - - - $.fn.swipe.defaults -
-
-
-
- The number of pixels that the user must move their finger back from the original swipe direction to cancel the gesture. - code » -
- - - - - - - -
-
-
- -
-
- doubleTap - : function - (default = null) - - - - - $.fn.swipe.defaults -
-
-
-
- A handler triggered when a user double taps on the item. The delay between taps can be set with the doubleTapThreshold property. See $.fn.swipe.defaults#doubleTapThreshold - code » -
- - - - - - - -
-
-
- -
-
- doubleTapThreshold - : int - (default = 200) - - - - - $.fn.swipe.defaults -
-
-
-
- Time in milliseconds between 2 taps to count as a double tap - code » -
- - - - - - - -
-
-
- -
-
- excludedElements - : string - (default = "button, input, select, textarea, a, .noSwipe") - - - - - $.fn.swipe.defaults -
-
-
-
- A jquery selector that specifies child elements that do NOT trigger swipes. By default this excludes all form, input, select, button, anchor and .noSwipe elements. - code » -
- - - - - - - -
-
-
- -
-
- fallbackToMouseEvents - : boolean - (default = true) - - - - - $.fn.swipe.defaults -
-
-
-
- If true mouse events are used when run on a non touch device, false will stop swipes being triggered by mouse events on non tocuh devices. - code » -
- - - - - - - -
-
-
- -
-
- fingerReleaseThreshold - : int - (default = 250) - - - - - $.fn.swipe.defaults -
-
-
-
- Time in milliseconds between releasing multiple fingers. If 2 fingers are down, and are released one after the other, if they are within this threshold, it counts as a simultaneous release. - code » -
- - - - - - - -
-
-
- -
-
- fingers - : int - (default = 1) - - - - - $.fn.swipe.defaults -
-
-
-
- The number of fingers to detect in a swipe. Any swipes that do not meet this requirement will NOT trigger swipe handlers. - code » -
- - - - - - - -
-
-
- -
-
- longTap - : function - (default = null) - - - - - $.fn.swipe.defaults -
-
-
-
- A handler triggered when a user long taps on the item. The delay between start and end can be set with the longTapThreshold property. See $.fn.swipe.defaults#longTapThreshold - code » -
- - - - - - - -
-
-
- -
-
- longTapThreshold - : int - (default = 500) - - - - - $.fn.swipe.defaults -
-
-
-
- Time in milliseconds between tap and release for a long tap - code » -
- - - - - - - -
-
-
- -
-
- maxTimeThreshold - : int - (default = null) - - - - - $.fn.swipe.defaults -
-
-
-
- Time, in milliseconds, between touchStart and touchEnd must NOT exceed in order to be considered a swipe. - code » -
- - - - - - - -
-
-
- -
-
- pinchIn - : function - (default = null) - - - - - $.fn.swipe.defaults -
-
-
-
- A handler triggered for pinch in events. See $.fn.swipe#event:pinchIn - code » -
- - - - - - - -
-
-
- -
-
- pinchOut - : function - (default = null) - - - - - $.fn.swipe.defaults -
-
-
-
- A handler triggered for pinch out events. See $.fn.swipe#event:pinchOut - code » -
- - - - - - - -
-
-
- -
-
- pinchStatus - : function - (default = null) - - - - - $.fn.swipe.defaults -
-
-
-
- A handler triggered for every phase of a pinch. See $.fn.swipe#event:pinchStatus - code » -
- - - - - - - -
-
-
- -
-
- pinchThreshold - : int - (default = 20) - - - - - $.fn.swipe.defaults -
-
-
-
- The number of pixels that the user must pinch their finger by before it is considered a pinch. - code » -
- - - - - - - -
-
-
- -
-
- swipe - : function - (default = null) - - - - - $.fn.swipe.defaults -
-
-
-
- A handler to catch all swipes. See $.fn.swipe#event:swipe - code » -
- - - - - - - -
-
-
- -
-
- swipeDown - : function - (default = null) - - - - - $.fn.swipe.defaults -
-
-
-
- A handler that is triggered for "down" swipes. See $.fn.swipe#event:swipeDown - code » -
- - - - - - - -
-
-
- -
-
- swipeLeft - : function - (default = null) - - - - - $.fn.swipe.defaults -
-
-
-
- A handler that is triggered for "left" swipes. See $.fn.swipe#event:swipeLeft - code » -
- - - - - - - -
-
-
- -
-
- swipeRight - : function - (default = null) - - - - - $.fn.swipe.defaults -
-
-
-
- A handler that is triggered for "right" swipes. See $.fn.swipe#event:swipeRight - code » -
- - - - - - - -
-
-
- -
-
- swipeStatus - : function - (default = null) - - - - - $.fn.swipe.defaults -
-
-
-
- A handler triggered for every phase of the swipe. See $.fn.swipe#event:swipeStatus - code » -
- - - - - - - -
-
-
- -
-
- swipeUp - : function - (default = null) - - - - - $.fn.swipe.defaults -
-
-
-
- A handler that is triggered for "up" swipes. See $.fn.swipe#event:swipeUp - code » -
- - - - - - - -
-
-
- -
-
- tap - : function - (default = null) - - - - - $.fn.swipe.defaults -
-
-
-
- A handler triggered when a user just taps on the item, rather than swipes it. If they do not move, tap is triggered, if they do move, it is not. - code » -
- - - - - - - -
-
-
- -
-
- threshold - : int - (default = 75) - - - - - $.fn.swipe.defaults -
-
-
-
- The number of pixels that the user must move their finger by before it is considered a swipe. - code » -
- - - - - - - -
-
-
- -
-
- triggerOnTouchEnd - : boolean - (default = true) - - - - - $.fn.swipe.defaults -
-
-
-
- If true, the swipe events are triggered when the touch end event is received (user releases finger). If false, it will be triggered on reaching the threshold, and then cancel the touch event automatically. - code » -
- - - - - - - -
-
-
- -
-
- triggerOnTouchLeave - : boolean - (default = false) - - - - - $.fn.swipe.defaults -
-
-
-
- If true, then when the user leaves the swipe object, the swipe will end and trigger appropriate handlers. - code » -
- - - - - - - -
-
-
- -
- - - - - - - - - - - - - - - - - - -
- -

Documentation generated by JsDoc Toolkit 2.4.0 on Wed Jun 04 2014 13:36:57 GMT+0100 (BST)

-
-
- diff --git a/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.directions.html b/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.directions.html deleted file mode 100644 index 47da70378e..0000000000 --- a/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.directions.html +++ /dev/null @@ -1,346 +0,0 @@ - - - - - - JsDoc Reference - $.fn.swipe.directions - - - - - - - - - - - - -
- - - - - - -
-
- -
- -
- - -
- -
- -

- - Namespace $.fn.swipe.directions - - - - - - -

- - -
- -
- - -
- - - - - Instance members - - - - - - - - -
- - -

Namespace

-
-
-
- $.fn.swipe.directions - - - - - - Static -
-
-
- The direction constants that are passed to the event handlers. -These properties are read only, attempting to change them will not alter the values passed to the event handlers. - - code » - -
-
-
-
- - - - - -

-

Instance members

- - -

Instance PropertiesDefined By

-
- -
-
- DOWN - : string - - - - - - $.fn.swipe.directions -
-
-
-
- Constant indicating the down direction. Value is "cancel". - code » -
- - - - - - - -
-
-
- -
-
- IN - : string - - - - - - $.fn.swipe.directions -
-
-
-
- Constant indicating the in direction. Value is "in". - code » -
- - - - - - - -
-
-
- -
-
- LEFT - : string - - - - - - $.fn.swipe.directions -
-
-
-
- Constant indicating the left direction. Value is "left". - code » -
- - - - - - - -
-
-
- -
-
- OUT - : string - - - - - - $.fn.swipe.directions -
-
-
-
- Constant indicating the out direction. Value is "out". - code » -
- - - - - - - -
-
-
- -
-
- RIGHT - : string - - - - - - $.fn.swipe.directions -
-
-
-
- Constant indicating the right direction. Value is "right". - code » -
- - - - - - - -
-
-
- -
-
- UP - : string - - - - - - $.fn.swipe.directions -
-
-
-
- Constant indicating the up direction. Value is "up". - code » -
- - - - - - - -
-
-
- -
- - - - - - - - - - - - - - - - - - -
- -

Documentation generated by JsDoc Toolkit 2.4.0 on Wed Jun 04 2014 13:36:57 GMT+0100 (BST)

-
-
- diff --git a/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.fingers.html b/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.fingers.html deleted file mode 100644 index df5bd5697e..0000000000 --- a/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.fingers.html +++ /dev/null @@ -1,291 +0,0 @@ - - - - - - JsDoc Reference - $.fn.swipe.fingers - - - - - - - - - - - - -
- - - - - - -
-
- -
- -
- - -
- -
- -

- - Namespace $.fn.swipe.fingers - - - - - - -

- - -
- -
- - -
- - - - - Instance members - - - - - - - - -
- - -

Namespace

-
-
-
- $.fn.swipe.fingers - - - - - - Static -
-
-
- Constants representing the number of fingers used in a swipe. These are used to set both the value of fingers in the -options object, as well as the value of the fingers event property. -These properties are read only, attempting to change them will not alter the values passed to the event handlers. - - code » - -
-
-
-
- - - - - -

-

Instance members

- - -

Instance PropertiesDefined By

-
- -
-
- ALL - : string - - - - - - $.fn.swipe.fingers -
-
-
-
- Constant indicating any combination of finger are to be detected. Value is "all". - code » -
- - - - - - - -
-
-
- -
-
- ONE - : string - - - - - - $.fn.swipe.fingers -
-
-
-
- Constant indicating 1 finger is to be detected / was detected. Value is 1. - code » -
- - - - - - - -
-
-
- -
-
- THREE - : string - - - - - - $.fn.swipe.fingers -
-
-
-
- Constant indicating 3 finger are to be detected / were detected. Value is 1. - code » -
- - - - - - - -
-
-
- -
-
- TWO - : string - - - - - - $.fn.swipe.fingers -
-
-
-
- Constant indicating 2 fingers are to be detected / were detected. Value is 1. - code » -
- - - - - - - -
-
-
- -
- - - - - - - - - - - - - - - - - - -
- -

Documentation generated by JsDoc Toolkit 2.4.0 on Wed Jun 04 2014 13:36:57 GMT+0100 (BST)

-
-
- diff --git a/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.html b/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.html deleted file mode 100644 index b74b59264b..0000000000 --- a/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.html +++ /dev/null @@ -1,1402 +0,0 @@ - - - - - - JsDoc Reference - $.fn.swipe - - - - - - - - - - - - -
- - - - - - -
-
- -
- -
- - -
- -
- -

- - Class $.fn.swipe - - - - - - -

- - -
- -
- - -
- - Constructor - - - - - Instance members - - - - - Static members - - - - - - Events - -
- - -

-

Constructor

-
-
-
- swipe - ( Mixed method ) - - - - - - - Static -
-
-
-
- Applies TouchSwipe behaviour to one or more jQuery objects. -The TouchSwipe plugin can be instantiated via this method, or methods within -TouchSwipe can be executed via this method as per jQuery plugin architecture. - code » -
- - - - - -
- See - - TouchSwipe - -
- - - -
- - Parameters -
- -
method : Mixed
-
If the current DOMNode is a TouchSwipe object, and method is a TouchSwipe method, then -the method is executed, and any following arguments are passed to the TouchSwipe method. -If method is an object, then the TouchSwipe class is instantiated on the current DOMNode, passing the -configuration properties defined in the object. See TouchSwipe
- -
- - -
- -
-
-
-
- - - - - -

-

Instance members

- -

Instance MethodsDefined By

-
- -
-
-
- destroy - ( ) - : DOMNode - - - - - $.fn.swipe -
-
-
-
-
- Destroy the swipe plugin completely. To use any swipe methods, you must re initialise the plugin. - code » -
- - -
$("#element").swipe("destroy");
- - - - - - - - -
- - - Returns -
- -
DOMNode
-
The Dom element that was registered with TouchSwipe
- -
- -
- -
-
-
- -
-
-
- disable - ( ) - : DOMNode - - - - - $.fn.swipe -
-
-
-
-
- disables the swipe plugin - code » -
- - -
$("#element").swipe("disable");
- - - - - - - - -
- - - Returns -
- -
DOMNode
-
The Dom element that is now registered with TouchSwipe
- -
- -
- -
-
-
- -
-
-
- enable - ( ) - : DOMNode - - - - - $.fn.swipe -
-
-
-
-
- re-enables the swipe plugin with the previous configuration - code » -
- - -
$("#element").swipe("enable");
- - - - - - - - -
- - - Returns -
- -
DOMNode
-
The Dom element that was registered with TouchSwipe
- -
- -
- -
-
-
- -
-
-
- option - ( String property, [Object value] ) - : Object - - - - - $.fn.swipe -
-
-
-
-
- Allows run time updating of the swipe configuration options. - code » -
- - -
$("#element").swipe("option", "threshold"); // return the threshold
- -
$("#element").swipe("option", "threshold", 100); // set the threshold after init
- - - - - - -
- See - - $.fn.swipe.defaults - -
- - - -
- - Parameters -
- -
property : String
-
The option property to get or set
- -
value : Object
-
The value to set the property to
- -
- - - Returns -
- -
Object
-
If only a property name is passed, then that property value is returned.
- -
- -
- -
-
-
- -
- - - - - - - -

-

Static members

- -

Nested namespacesDefined By

-
- -
-
- - defaults - - - - - - Static - $.fn.swipe -
-
-
-
- The default configuration, and available options to configure touch swipe with. -You can set the default values by updating any of the properties prior to instantiation. - code » -
- - - - - - - -
-
-
- -
-
- - directions - - - - - - Static - $.fn.swipe -
-
-
-
- The direction constants that are passed to the event handlers. -These properties are read only, attempting to change them will not alter the values passed to the event handlers. - code » -
- - - - - - - -
-
-
- -
-
- - fingers - - - - - - Static - $.fn.swipe -
-
-
-
- Constants representing the number of fingers used in a swipe. These are used to set both the value of fingers in the -options object, as well as the value of the fingers event property. -These properties are read only, attempting to change them will not alter the values passed to the event handlers. - code » -
- - - - - - - - - -
-
-
- -
-
- - pageScroll - - - - - - Static - $.fn.swipe -
-
-
-
- The page scroll constants that can be used to set the value of allowPageScroll option -These properties are read only - code » -
- - - - - - - - - -
-
-
- -
-
- - phases - - - - - - Static - $.fn.swipe -
-
-
-
- The phases that a touch event goes through. The phase is passed to the event handlers. -These properties are read only, attempting to change them will not alter the values passed to the event handlers. - code » -
- - - - - - - -
-
-
- -
- - - - - - - - - - - -

-

EventsDefined By

-
- -
-
-
- - click - ( EventObject event, DomObject target ) - - - - - $.fn.swipe -
-
-
-
-
- A click handler triggered when a user simply clicks, rather than swipes on an element. -This is deprecated since version 1.6.2, any assignment to click will be assigned to the tap handler. -You cannot use on to bind to this event as the default jQ click event will be triggered. -Use the tap event instead. - code » -
- - -
- Deprecated - since version 1.6.2, please use $.fn.swipe#tap instead -
- - - - - - -
- - Parameters -
- -
event : EventObject
-
The original event object
- -
target : DomObject
-
The element clicked on.
- -
- - -
- -
-
-
- -
-
-
- - doubleTap - ( EventObject event, DomObject target ) - - - - - $.fn.swipe -
-
-
-
-
- A double tap handler triggered when a user double clicks or taps on an element. -You can set the time delay for a double tap with the $.fn.swipe.defaults#doubleTapThreshold property. -Note: If you set both doubleTap and tap handlers, the tap event will be delayed by the doubleTapThreshold -as the script needs to check if its a double tap. - code » -
- - - - - - - - - -
- - Parameters -
- -
event : EventObject
-
The original event object
- -
target : DomObject
-
The element clicked on.
- -
- - -
- -
-
-
- -
-
-
- - hold - ( EventObject event, DomObject target ) - - - - - $.fn.swipe -
-
-
-
-
- A hold tap handler triggered as soon as the longTapThreshold is reached -You can set the time delay for a long tap with the $.fn.swipe.defaults#longTapThreshold property. - code » -
- - - - - - - - - -
- - Parameters -
- -
event : EventObject
-
The original event object
- -
target : DomObject
-
The element clicked on.
- -
- - -
- -
-
-
- -
-
-
- - longTap - ( EventObject event, DomObject target ) - - - - - $.fn.swipe -
-
-
-
-
- A long tap handler triggered once a tap has been release if the tap was longer than the longTapThreshold. -You can set the time delay for a long tap with the $.fn.swipe.defaults#longTapThreshold property. - code » -
- - - - - - - - - -
- - Parameters -
- -
event : EventObject
-
The original event object
- -
target : DomObject
-
The element clicked on.
- -
- - -
- -
-
-
- -
-
-
- - pinchIn - ( EventObject event, int direction, int distance, int duration, int fingerCount, int zoom, object fingerData ) - - - - - $.fn.swipe -
-
-
-
-
- A handler triggered for pinch in events. - code » -
- - - - - - - -
- - Parameters -
- -
event : EventObject
-
The original event object
- -
direction : int
-
The direction the user pinched in. See $.fn.swipe.directions
- -
distance : int
-
The distance the user pinched
- -
duration : int
-
The duration of the swipe in milliseconds
- -
fingerCount : int
-
The number of fingers used. See $.fn.swipe.fingers
- -
zoom : int
-
The zoom/scale level the user pinched too, 0-1.
- -
fingerData : object
-
The coordinates of fingers in event
- -
- - -
- -
-
-
- -
-
-
- - pinchOut - ( EventObject event, int direction, int distance, int duration, int fingerCount, int zoom, object fingerData ) - - - - - $.fn.swipe -
-
-
-
-
- A handler triggered for pinch out events. - code » -
- - - - - - - -
- - Parameters -
- -
event : EventObject
-
The original event object
- -
direction : int
-
The direction the user pinched in. See $.fn.swipe.directions
- -
distance : int
-
The distance the user pinched
- -
duration : int
-
The duration of the swipe in milliseconds
- -
fingerCount : int
-
The number of fingers used. See $.fn.swipe.fingers
- -
zoom : int
-
The zoom/scale level the user pinched too, 0-1.
- -
fingerData : object
-
The coordinates of fingers in event
- -
- - -
- -
-
-
- -
-
-
- - pinchStatus - ( EventObject event, int direction, int distance, int duration, int fingerCount, int zoom, object fingerData ) - - - - - $.fn.swipe -
-
-
-
-
- A handler triggered for all pinch events. This handler is constantly fired for the duration of the pinch. This is triggered regardless of thresholds. - code » -
- - - - - - - -
- - Parameters -
- -
event : EventObject
-
The original event object
- -
direction : int
-
The direction the user pinched in. See $.fn.swipe.directions
- -
distance : int
-
The distance the user pinched
- -
duration : int
-
The duration of the swipe in milliseconds
- -
fingerCount : int
-
The number of fingers used. See $.fn.swipe.fingers
- -
zoom : int
-
The zoom/scale level the user pinched too, 0-1.
- -
fingerData : object
-
The coordinates of fingers in event
- -
- - -
- -
-
-
- -
-
-
- - swipe - ( EventObject event, int direction, int distance, int duration, int fingerCount, object fingerData ) - - - - - $.fn.swipe -
-
-
-
-
- A catch all handler that is triggered for all swipe directions. - code » -
- - - - - - - -
- - Parameters -
- -
event : EventObject
-
The original event object
- -
direction : int
-
The direction the user swiped in. See $.fn.swipe.directions
- -
distance : int
-
The distance the user swiped
- -
duration : int
-
The duration of the swipe in milliseconds
- -
fingerCount : int
-
The number of fingers used. See $.fn.swipe.fingers
- -
fingerData : object
-
The coordinates of fingers in event
- -
- - -
- -
-
-
- -
-
-
- - swipeDown - ( EventObject event, int direction, int distance, int duration, int fingerCount, object fingerData ) - - - - - $.fn.swipe -
-
-
-
-
- A handler that is triggered for "down" swipes. - code » -
- - - - - - - -
- - Parameters -
- -
event : EventObject
-
The original event object
- -
direction : int
-
The direction the user swiped in. See $.fn.swipe.directions
- -
distance : int
-
The distance the user swiped
- -
duration : int
-
The duration of the swipe in milliseconds
- -
fingerCount : int
-
The number of fingers used. See $.fn.swipe.fingers
- -
fingerData : object
-
The coordinates of fingers in event
- -
- - -
- -
-
-
- -
-
-
- - swipeLeft - ( EventObject event, int direction, int distance, int duration, int fingerCount, object fingerData ) - - - - - $.fn.swipe -
-
-
-
-
- A handler that is triggered for "left" swipes. - code » -
- - - - - - - -
- - Parameters -
- -
event : EventObject
-
The original event object
- -
direction : int
-
The direction the user swiped in. See $.fn.swipe.directions
- -
distance : int
-
The distance the user swiped
- -
duration : int
-
The duration of the swipe in milliseconds
- -
fingerCount : int
-
The number of fingers used. See $.fn.swipe.fingers
- -
fingerData : object
-
The coordinates of fingers in event
- -
- - -
- -
-
-
- -
-
-
- - swipeRight - ( EventObject event, int direction, int distance, int duration, int fingerCount, object fingerData ) - - - - - $.fn.swipe -
-
-
-
-
- A handler that is triggered for "right" swipes. - code » -
- - - - - - - -
- - Parameters -
- -
event : EventObject
-
The original event object
- -
direction : int
-
The direction the user swiped in. See $.fn.swipe.directions
- -
distance : int
-
The distance the user swiped
- -
duration : int
-
The duration of the swipe in milliseconds
- -
fingerCount : int
-
The number of fingers used. See $.fn.swipe.fingers
- -
fingerData : object
-
The coordinates of fingers in event
- -
- - -
- -
-
-
- -
-
-
- - swipeStatus - ( EventObject event, string phase, string direction, int distance, int duration, int fingerCount, object fingerData ) - - - - - $.fn.swipe -
-
-
-
-
- A handler triggered for every phase of the swipe. This handler is constantly fired for the duration of the pinch. -This is triggered regardless of swipe thresholds. - code » -
- - - - - - - -
- - Parameters -
- -
event : EventObject
-
The original event object
- -
phase : string
-
The phase of the swipe event. See $.fn.swipe.phases
- -
direction : string
-
The direction the user swiped in. This is null if the user has yet to move. See $.fn.swipe.directions
- -
distance : int
-
The distance the user swiped. This is 0 if the user has yet to move.
- -
duration : int
-
The duration of the swipe in milliseconds
- -
fingerCount : int
-
The number of fingers used. See $.fn.swipe.fingers
- -
fingerData : object
-
The coordinates of fingers in event
- -
- - -
- -
-
-
- -
-
-
- - swipeUp - ( EventObject event, int direction, int distance, int duration, int fingerCount, object fingerData ) - - - - - $.fn.swipe -
-
-
-
-
- A handler that is triggered for "up" swipes. - code » -
- - - - - - - -
- - Parameters -
- -
event : EventObject
-
The original event object
- -
direction : int
-
The direction the user swiped in. See $.fn.swipe.directions
- -
distance : int
-
The distance the user swiped
- -
duration : int
-
The duration of the swipe in milliseconds
- -
fingerCount : int
-
The number of fingers used. See $.fn.swipe.fingers
- -
fingerData : object
-
The coordinates of fingers in event
- -
- - -
- -
-
-
- -
-
-
- - tap - ( EventObject event, DomObject target ) - - - - - $.fn.swipe -
-
-
-
-
- A click / tap handler triggered when a user simply clicks or taps, rather than swipes on an element. - code » -
- - - - - - - -
- - Parameters -
- -
event : EventObject
-
The original event object
- -
target : DomObject
-
The element clicked on.
- -
- - -
- -
-
-
- -
- - - - - - - -
- -

Documentation generated by JsDoc Toolkit 2.4.0 on Wed Jun 04 2014 13:36:57 GMT+0100 (BST)

-
-
- diff --git a/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.pageScroll.html b/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.pageScroll.html deleted file mode 100644 index ace2f2e9ce..0000000000 --- a/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.pageScroll.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - - JsDoc Reference - $.fn.swipe.pageScroll - - - - - - - - - - - - -
- - - - - - -
-
- -
- -
- - -
- -
- -

- - Namespace $.fn.swipe.pageScroll - - - - - - -

- - -
- -
- - -
- - - - - Instance members - - - - - - - - -
- - -

Namespace

-
-
-
- $.fn.swipe.pageScroll - - - - - - Static -
-
-
- The page scroll constants that can be used to set the value of allowPageScroll option -These properties are read only - - code » - -
-
-
-
- - - - - -

-

Instance members

- - -

Instance PropertiesDefined By

-
- -
-
- AUTO - : string - - - - - - $.fn.swipe.pageScroll -
-
-
-
- Constant indicating either horizontal or vertical will be allowed, depending on the swipe handlers registered. Value is "auto". - code » -
- - - - - - - -
-
-
- -
-
- HORIZONTAL - : string - - - - - - $.fn.swipe.pageScroll -
-
-
-
- Constant indicating horizontal page scrolling is allowed. Value is "horizontal". - code » -
- - - - - - - -
-
-
- -
-
- NONE - : string - - - - - - $.fn.swipe.pageScroll -
-
-
-
- Constant indicating no page scrolling is allowed. Value is "none". - code » -
- - - - - - - -
-
-
- -
-
- VERTICAL - : string - - - - - - $.fn.swipe.pageScroll -
-
-
-
- Constant indicating vertical page scrolling is allowed. Value is "vertical". - code » -
- - - - - - - -
-
-
- -
- - - - - - - - - - - - - - - - - - -
- -

Documentation generated by JsDoc Toolkit 2.4.0 on Wed Jun 04 2014 13:36:57 GMT+0100 (BST)

-
-
- diff --git a/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.phases.html b/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.phases.html deleted file mode 100644 index 806774f36c..0000000000 --- a/api/js/jquery/TouchSwipe/docs/symbols/$.fn.swipe.phases.html +++ /dev/null @@ -1,290 +0,0 @@ - - - - - - JsDoc Reference - $.fn.swipe.phases - - - - - - - - - - - - -
- - - - - - -
-
- -
- -
- - -
- -
- -

- - Namespace $.fn.swipe.phases - - - - - - -

- - -
- -
- - -
- - - - - Instance members - - - - - - - - -
- - -

Namespace

-
-
-
- $.fn.swipe.phases - - - - - - Static -
-
-
- The phases that a touch event goes through. The phase is passed to the event handlers. -These properties are read only, attempting to change them will not alter the values passed to the event handlers. - - code » - -
-
-
-
- - - - - -

-

Instance members

- - -

Instance PropertiesDefined By

-
- -
-
- PHASE_CANCEL - : string - - - - - - $.fn.swipe.phases -
-
-
-
- Constant indicating the cancel phase of the touch event. Value is "cancel". - code » -
- - - - - - - -
-
-
- -
-
- PHASE_END - : string - - - - - - $.fn.swipe.phases -
-
-
-
- Constant indicating the end phase of the touch event. Value is "end". - code » -
- - - - - - - -
-
-
- -
-
- PHASE_MOVE - : string - - - - - - $.fn.swipe.phases -
-
-
-
- Constant indicating the move phase of the touch event. Value is "move". - code » -
- - - - - - - -
-
-
- -
-
- PHASE_START - : string - - - - - - $.fn.swipe.phases -
-
-
-
- Constant indicating the start phase of the touch event. Value is "start". - code » -
- - - - - - - -
-
-
- -
- - - - - - - - - - - - - - - - - - -
- -

Documentation generated by JsDoc Toolkit 2.4.0 on Wed Jun 04 2014 13:36:57 GMT+0100 (BST)

-
-
- diff --git a/api/js/jquery/TouchSwipe/docs/symbols/$.html b/api/js/jquery/TouchSwipe/docs/symbols/$.html deleted file mode 100644 index 82ee531731..0000000000 --- a/api/js/jquery/TouchSwipe/docs/symbols/$.html +++ /dev/null @@ -1,171 +0,0 @@ - - - - - - JsDoc Reference - $ - - - - - - - - - - - - -
- - - - - - -
-
- -
- -
- - -
- -
- -

- - Class $ - - - - - - -

- - -
- -
- - -
- - Constructor - - - - - - - - - - - -
- - -

-

Constructor

-
-
-
- $ - ( ) - - - - - - - -
-
-
-
- See (http://jquery.com/). - code » -
- - - - - - - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - -
- -

Documentation generated by JsDoc Toolkit 2.4.0 on Wed Jun 04 2014 13:36:56 GMT+0100 (BST)

-
-
- diff --git a/api/js/jquery/TouchSwipe/docs/symbols/_global_.html b/api/js/jquery/TouchSwipe/docs/symbols/_global_.html deleted file mode 100644 index 760bd5f75a..0000000000 --- a/api/js/jquery/TouchSwipe/docs/symbols/_global_.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - JsDoc Reference - _global_ - - - - - - - - - - - - -
- - - - - - -
-
- -
- -
- - -
- -
- -

- - Built-In Namespace _global_ - - - - - - -

- - -
- -
- - -
- - - - - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - -
- -

Documentation generated by JsDoc Toolkit 2.4.0 on Wed Jun 04 2014 13:36:57 GMT+0100 (BST)

-
-
- diff --git a/api/js/jquery/TouchSwipe/docs/symbols/src/jquery.touchSwipe.js.html b/api/js/jquery/TouchSwipe/docs/symbols/src/jquery.touchSwipe.js.html deleted file mode 100644 index b7a079b69d..0000000000 --- a/api/js/jquery/TouchSwipe/docs/symbols/src/jquery.touchSwipe.js.html +++ /dev/null @@ -1,2126 +0,0 @@ - - - - - Source - jquery.touchSwipe.js - - - - - - - - - - - -
- - - - - - -
-
- -
- -
- - -
- -
- - -
/*
-* @fileOverview TouchSwipe - jQuery Plugin
-* @version 1.6.6
-*
-* @author Matt Bryson http://www.github.com/mattbryson
-* @see https://github.com/mattbryson/TouchSwipe-Jquery-Plugin
-* @see http://labs.skinkers.com/touchSwipe/
-* @see http://plugins.jquery.com/project/touchSwipe
-*
-* Copyright (c) 2010 Matt Bryson
-* Dual licensed under the MIT or GPL Version 2 licenses.
-*
-*/
-
-/*
-*
-* Changelog
-* $Date: 2010-12-12 (Wed, 12 Dec 2010) $
-* $version: 1.0.0
-* $version: 1.0.1 - removed multibyte comments
-*
-* $Date: 2011-21-02 (Mon, 21 Feb 2011) $
-* $version: 1.1.0 	- added allowPageScroll property to allow swiping and scrolling of page
-*					- changed handler signatures so one handler can be used for multiple events
-* $Date: 2011-23-02 (Wed, 23 Feb 2011) $
-* $version: 1.2.0 	- added click handler. This is fired if the user simply clicks and does not swipe. The event object and click target are passed to handler.
-*					- If you use the http://code.google.com/p/jquery-ui-for-ipad-and-iphone/ plugin, you can also assign jQuery mouse events to children of a touchSwipe object.
-* $version: 1.2.1 	- removed console log!
-*
-* $version: 1.2.2 	- Fixed bug where scope was not preserved in callback methods.
-*
-* $Date: 2011-28-04 (Thurs, 28 April 2011) $
-* $version: 1.2.4 	- Changed licence terms to be MIT or GPL inline with jQuery. Added check for support of touch events to stop non compatible browsers erroring.
-*
-* $Date: 2011-27-09 (Tues, 27 September 2011) $
-* $version: 1.2.5 	- Added support for testing swipes with mouse on desktop browser (thanks to https://github.com/joelhy)
-*
-* $Date: 2012-14-05 (Mon, 14 May 2012) $
-* $version: 1.2.6 	- Added timeThreshold between start and end touch, so user can ignore slow swipes (thanks to Mark Chase). Default is null, all swipes are detected
-*
-* $Date: 2012-05-06 (Tues, 05 June 2012) $
-* $version: 1.2.7 	- Changed time threshold to have null default for backwards compatibility. Added duration param passed back in events, and refactored how time is handled.
-*
-* $Date: 2012-05-06 (Tues, 05 June 2012) $
-* $version: 1.2.8 	- Added the possibility to return a value like null or false in the trigger callback. In that way we can control when the touch start/move should take effect or not (simply by returning in some cases return null; or return false;) This effects the ontouchstart/ontouchmove event.
-*
-* $Date: 2012-06-06 (Wed, 06 June 2012) $
-* $version: 1.3.0 	- Refactored whole plugin to allow for methods to be executed, as well as exposed defaults for user override. Added 'enable', 'disable', and 'destroy' methods
-*
-* $Date: 2012-05-06 (Fri, 05 June 2012) $
-* $version: 1.3.1 	- Bug fixes  - bind() with false as last argument is no longer supported in jQuery 1.6, also, if you just click, the duration is now returned correctly.
-*
-* $Date: 2012-29-07 (Sun, 29 July 2012) $
-* $version: 1.3.2	- Added fallbackToMouseEvents option to NOT capture mouse events on non touch devices.
-* 			- Added "all" fingers value to the fingers property, so any combination of fingers triggers the swipe, allowing event handlers to check the finger count
-*
-* $Date: 2012-09-08 (Thurs, 9 Aug 2012) $
-* $version: 1.3.3	- Code tidy prep for minefied version
-*
-* $Date: 2012-04-10 (wed, 4 Oct 2012) $
-* $version: 1.4.0	- Added pinch support, pinchIn and pinchOut
-*
-* $Date: 2012-11-10 (Thurs, 11 Oct 2012) $
-* $version: 1.5.0	- Added excludedElements, a jquery selector that specifies child elements that do NOT trigger swipes. By default, this is one select that removes all form, input select, button and anchor elements.
-*
-* $Date: 2012-22-10 (Mon, 22 Oct 2012) $
-* $version: 1.5.1	- Fixed bug with jQuery 1.8 and trailing comma in excludedElements
-*					- Fixed bug with IE and eventPreventDefault()
-* $Date: 2013-01-12 (Fri, 12 Jan 2013) $
-* $version: 1.6.0	- Fixed bugs with pinching, mainly when both pinch and swipe enabled, as well as adding time threshold for multifinger gestures, so releasing one finger beofre the other doesnt trigger as single finger gesture.
-*					- made the demo site all static local HTML pages so they can be run locally by a developer
-*					- added jsDoc comments and added documentation for the plugin	
-*					- code tidy
-*					- added triggerOnTouchLeave property that will end the event when the user swipes off the element.
-* $Date: 2013-03-23 (Sat, 23 Mar 2013) $
-* $version: 1.6.1	- Added support for ie8 touch events
-* $version: 1.6.2	- Added support for events binding with on / off / bind in jQ for all callback names.
-*                   - Deprecated the 'click' handler in favour of tap.
-*                   - added cancelThreshold property
-*                   - added option method to update init options at runtime
-* $version 1.6.3    - added doubletap, longtap events and longTapThreshold, doubleTapThreshold property
-*
-* $Date: 2013-04-04 (Thurs, 04 April 2013) $
-* $version 1.6.4    - Fixed bug with cancelThreshold introduced in 1.6.3, where swipe status no longer fired start event, and stopped once swiping back.
-*
-* $Date: 2013-08-24 (Sat, 24 Aug 2013) $
-* $version 1.6.5    - Merged a few pull requests fixing various bugs, added AMD support.
-*
-* $Date: 2014-06-04 (Wed, 04 June 2014) $
-* $version 1.6.6 	- Merge of pull requests.
-*    				- IE10 touch support 
-*    				- Only prevent default event handling on valid swipe
-*    				- Separate license/changelog comment
-*    				- Detect if the swipe is valid at the end of the touch event.
-*    				- Pass fingerdata to event handlers. 
-*    				- Add 'hold' gesture 
-*    				- Be more tolerant about the tap distance
-*    				- Typos and minor fixes
-*/
-
-/**
- * See (http://jquery.com/).
- * @name $
- * @class 
- * See the jQuery Library  (http://jquery.com/) for full details.  This just
- * documents the function and classes that are added to jQuery by this plug-in.
- */
- 
-/**
- * See (http://jquery.com/)
- * @name fn
- * @class 
- * See the jQuery Library  (http://jquery.com/) for full details.  This just
- * documents the function and classes that are added to jQuery by this plug-in.
- * @memberOf $
- */
-
-
-
-(function (factory) {
-    if (typeof define === 'function' && define.amd && define.amd.jQuery) {
-        // AMD. Register as anonymous module.
-        define(['jquery'], factory);
-    } else {
-        // Browser globals.
-        factory(jQuery);
-    }
-}(function ($) {
-	"use strict";
-
-	//Constants
-	var LEFT = "left",
-		RIGHT = "right",
-		UP = "up",
-		DOWN = "down",
-		IN = "in",
-		OUT = "out",
-
-		NONE = "none",
-		AUTO = "auto",
-		
-		SWIPE = "swipe",
-		PINCH = "pinch",
-		TAP = "tap",
-		DOUBLE_TAP = "doubletap",
-		LONG_TAP = "longtap",
-		HOLD = "hold",
-		
-		HORIZONTAL = "horizontal",
-		VERTICAL = "vertical",
-
-		ALL_FINGERS = "all",
-		
-		DOUBLE_TAP_THRESHOLD = 10,
-
-		PHASE_START = "start",
-		PHASE_MOVE = "move",
-		PHASE_END = "end",
-		PHASE_CANCEL = "cancel",
-
-		SUPPORTS_TOUCH = 'ontouchstart' in window,
-		
-		SUPPORTS_POINTER_IE10 = window.navigator.msPointerEnabled && !window.navigator.pointerEnabled,
-		
-		SUPPORTS_POINTER = window.navigator.pointerEnabled || window.navigator.msPointerEnabled,
-
-		PLUGIN_NS = 'TouchSwipe';
-
-
-
-	/**
-	* The default configuration, and available options to configure touch swipe with.
-	* You can set the default values by updating any of the properties prior to instantiation.
-	* @name $.fn.swipe.defaults
-	* @namespace
-	* @property {int} [fingers=1] The number of fingers to detect in a swipe. Any swipes that do not meet this requirement will NOT trigger swipe handlers.
-	* @property {int} [threshold=75] The number of pixels that the user must move their finger by before it is considered a swipe. 
-	* @property {int} [cancelThreshold=null] The number of pixels that the user must move their finger back from the original swipe direction to cancel the gesture.
-	* @property {int} [pinchThreshold=20] The number of pixels that the user must pinch their finger by before it is considered a pinch. 
-	* @property {int} [maxTimeThreshold=null] Time, in milliseconds, between touchStart and touchEnd must NOT exceed in order to be considered a swipe. 
-	* @property {int} [fingerReleaseThreshold=250] Time in milliseconds between releasing multiple fingers.  If 2 fingers are down, and are released one after the other, if they are within this threshold, it counts as a simultaneous release. 
-	* @property {int} [longTapThreshold=500] Time in milliseconds between tap and release for a long tap
-	* @property {int} [doubleTapThreshold=200] Time in milliseconds between 2 taps to count as a double tap
-	* @property {function} [swipe=null] A handler to catch all swipes. See {@link $.fn.swipe#event:swipe}
-	* @property {function} [swipeLeft=null] A handler that is triggered for "left" swipes. See {@link $.fn.swipe#event:swipeLeft}
-	* @property {function} [swipeRight=null] A handler that is triggered for "right" swipes. See {@link $.fn.swipe#event:swipeRight}
-	* @property {function} [swipeUp=null] A handler that is triggered for "up" swipes. See {@link $.fn.swipe#event:swipeUp}
-	* @property {function} [swipeDown=null] A handler that is triggered for "down" swipes. See {@link $.fn.swipe#event:swipeDown}
-	* @property {function} [swipeStatus=null] A handler triggered for every phase of the swipe. See {@link $.fn.swipe#event:swipeStatus}
-	* @property {function} [pinchIn=null] A handler triggered for pinch in events. See {@link $.fn.swipe#event:pinchIn}
-	* @property {function} [pinchOut=null] A handler triggered for pinch out events. See {@link $.fn.swipe#event:pinchOut}
-	* @property {function} [pinchStatus=null] A handler triggered for every phase of a pinch. See {@link $.fn.swipe#event:pinchStatus}
-	* @property {function} [tap=null] A handler triggered when a user just taps on the item, rather than swipes it. If they do not move, tap is triggered, if they do move, it is not. 
-	* @property {function} [doubleTap=null] A handler triggered when a user double taps on the item. The delay between taps can be set with the doubleTapThreshold property. See {@link $.fn.swipe.defaults#doubleTapThreshold}
-	* @property {function} [longTap=null] A handler triggered when a user long taps on the item. The delay between start and end can be set with the longTapThreshold property. See {@link $.fn.swipe.defaults#longTapThreshold}
-	* @property (function) [hold=null] A handler triggered when a user reaches longTapThreshold on the item. See {@link $.fn.swipe.defaults#longTapThreshold}
-	* @property {boolean} [triggerOnTouchEnd=true] If true, the swipe events are triggered when the touch end event is received (user releases finger).  If false, it will be triggered on reaching the threshold, and then cancel the touch event automatically. 
-	* @property {boolean} [triggerOnTouchLeave=false] If true, then when the user leaves the swipe object, the swipe will end and trigger appropriate handlers. 
-	* @property {string|undefined} [allowPageScroll='auto'] How the browser handles page scrolls when the user is swiping on a touchSwipe object. See {@link $.fn.swipe.pageScroll}.  <br/><br/>
-										<code>"auto"</code> : all undefined swipes will cause the page to scroll in that direction. <br/>
-										<code>"none"</code> : the page will not scroll when user swipes. <br/>
-										<code>"horizontal"</code> : will force page to scroll on horizontal swipes. <br/>
-										<code>"vertical"</code> : will force page to scroll on vertical swipes. <br/>
-	* @property {boolean} [fallbackToMouseEvents=true] If true mouse events are used when run on a non touch device, false will stop swipes being triggered by mouse events on non tocuh devices. 
-	* @property {string} [excludedElements="button, input, select, textarea, a, .noSwipe"] A jquery selector that specifies child elements that do NOT trigger swipes. By default this excludes all form, input, select, button, anchor and .noSwipe elements. 
-	
-	*/
-	var defaults = {
-		fingers: 1, 		
-		threshold: 75, 	
-		cancelThreshold:null,	
-		pinchThreshold:20,
-		maxTimeThreshold: null, 
-		fingerReleaseThreshold:250, 
-		longTapThreshold:500,
-		doubleTapThreshold:200,
-		swipe: null, 		
-		swipeLeft: null, 	
-		swipeRight: null, 	
-		swipeUp: null, 		
-		swipeDown: null, 	
-		swipeStatus: null, 	
-		pinchIn:null,		
-		pinchOut:null,		
-		pinchStatus:null,	
-		click:null, //Deprecated since 1.6.2
-		tap:null,
-		doubleTap:null,
-		longTap:null, 		
-		hold:null, 
-		triggerOnTouchEnd: true, 
-		triggerOnTouchLeave:false, 
-		allowPageScroll: "auto", 
-		fallbackToMouseEvents: true,	
-		excludedElements:"label, button, input, select, textarea, a, .noSwipe"
-	};
-
-
-
-	/**
-	* Applies TouchSwipe behaviour to one or more jQuery objects.
-	* The TouchSwipe plugin can be instantiated via this method, or methods within 
-	* TouchSwipe can be executed via this method as per jQuery plugin architecture.
-	* @see TouchSwipe
-	* @class
-	* @param {Mixed} method If the current DOMNode is a TouchSwipe object, and <code>method</code> is a TouchSwipe method, then
-	* the <code>method</code> is executed, and any following arguments are passed to the TouchSwipe method.
-	* If <code>method</code> is an object, then the TouchSwipe class is instantiated on the current DOMNode, passing the 
-	* configuration properties defined in the object. See TouchSwipe
-	*
-	*/
-	$.fn.swipe = function (method) {
-		var $this = $(this),
-			plugin = $this.data(PLUGIN_NS);
-
-		//Check if we are already instantiated and trying to execute a method	
-		if (plugin && typeof method === 'string') {
-			if (plugin[method]) {
-				return plugin[method].apply(this, Array.prototype.slice.call(arguments, 1));
-			} else {
-				$.error('Method ' + method + ' does not exist on jQuery.swipe');
-			}
-		}
-		//Else not instantiated and trying to pass init object (or nothing)
-		else if (!plugin && (typeof method === 'object' || !method)) {
-			return init.apply(this, arguments);
-		}
-
-		return $this;
-	};
-
-	//Expose our defaults so a user could override the plugin defaults
-	$.fn.swipe.defaults = defaults;
-
-	/**
-	* The phases that a touch event goes through.  The <code>phase</code> is passed to the event handlers. 
-	* These properties are read only, attempting to change them will not alter the values passed to the event handlers.
-	* @namespace
-	* @readonly
-	* @property {string} PHASE_START Constant indicating the start phase of the touch event. Value is <code>"start"</code>.
-	* @property {string} PHASE_MOVE Constant indicating the move phase of the touch event. Value is <code>"move"</code>.
-	* @property {string} PHASE_END Constant indicating the end phase of the touch event. Value is <code>"end"</code>.
-	* @property {string} PHASE_CANCEL Constant indicating the cancel phase of the touch event. Value is <code>"cancel"</code>.
-	*/
-	$.fn.swipe.phases = {
-		PHASE_START: PHASE_START,
-		PHASE_MOVE: PHASE_MOVE,
-		PHASE_END: PHASE_END,
-		PHASE_CANCEL: PHASE_CANCEL
-	};
-
-	/**
-	* The direction constants that are passed to the event handlers. 
-	* These properties are read only, attempting to change them will not alter the values passed to the event handlers.
-	* @namespace
-	* @readonly
-	* @property {string} LEFT Constant indicating the left direction. Value is <code>"left"</code>.
-	* @property {string} RIGHT Constant indicating the right direction. Value is <code>"right"</code>.
-	* @property {string} UP Constant indicating the up direction. Value is <code>"up"</code>.
-	* @property {string} DOWN Constant indicating the down direction. Value is <code>"cancel"</code>.
-	* @property {string} IN Constant indicating the in direction. Value is <code>"in"</code>.
-	* @property {string} OUT Constant indicating the out direction. Value is <code>"out"</code>.
-	*/
-	$.fn.swipe.directions = {
-		LEFT: LEFT,
-		RIGHT: RIGHT,
-		UP: UP,
-		DOWN: DOWN,
-		IN : IN,
-		OUT: OUT
-	};
-	
-	/**
-	* The page scroll constants that can be used to set the value of <code>allowPageScroll</code> option
-	* These properties are read only
-	* @namespace
-	* @readonly
-	* @see $.fn.swipe.defaults#allowPageScroll
-	* @property {string} NONE Constant indicating no page scrolling is allowed. Value is <code>"none"</code>.
-	* @property {string} HORIZONTAL Constant indicating horizontal page scrolling is allowed. Value is <code>"horizontal"</code>.
-	* @property {string} VERTICAL Constant indicating vertical page scrolling is allowed. Value is <code>"vertical"</code>.
-	* @property {string} AUTO Constant indicating either horizontal or vertical will be allowed, depending on the swipe handlers registered. Value is <code>"auto"</code>.
-	*/
-	$.fn.swipe.pageScroll = {
-		NONE: NONE,
-		HORIZONTAL: HORIZONTAL,
-		VERTICAL: VERTICAL,
-		AUTO: AUTO
-	};
-
-	/**
-	* Constants representing the number of fingers used in a swipe.  These are used to set both the value of <code>fingers</code> in the 
-	* options object, as well as the value of the <code>fingers</code> event property.
-	* These properties are read only, attempting to change them will not alter the values passed to the event handlers.
-	* @namespace
-	* @readonly
-	* @see $.fn.swipe.defaults#fingers
-	* @property {string} ONE Constant indicating 1 finger is to be detected / was detected. Value is <code>1</code>.
-	* @property {string} TWO Constant indicating 2 fingers are to be detected / were detected. Value is <code>1</code>.
-	* @property {string} THREE Constant indicating 3 finger are to be detected / were detected. Value is <code>1</code>.
-	* @property {string} ALL Constant indicating any combination of finger are to be detected.  Value is <code>"all"</code>.
-	*/
-	$.fn.swipe.fingers = {
-		ONE: 1,
-		TWO: 2,
-		THREE: 3,
-		ALL: ALL_FINGERS
-	};
-
-	/**
-	* Initialise the plugin for each DOM element matched
-	* This creates a new instance of the main TouchSwipe class for each DOM element, and then
-	* saves a reference to that instance in the elements data property.
-	* @internal
-	*/
-	function init(options) {
-		//Prep and extend the options
-		if (options && (options.allowPageScroll === undefined && (options.swipe !== undefined || options.swipeStatus !== undefined))) {
-			options.allowPageScroll = NONE;
-		}
-		
-        //Check for deprecated options
-		//Ensure that any old click handlers are assigned to the new tap, unless we have a tap
-		if(options.click!==undefined && options.tap===undefined) {
-		    options.tap = options.click;
-		}
-
-		if (!options) {
-			options = {};
-		}
-		
-        //pass empty object so we dont modify the defaults
-		options = $.extend({}, $.fn.swipe.defaults, options);
-
-		//For each element instantiate the plugin
-		return this.each(function () {
-			var $this = $(this);
-
-			//Check we havent already initialised the plugin
-			var plugin = $this.data(PLUGIN_NS);
-
-			if (!plugin) {
-				plugin = new TouchSwipe(this, options);
-				$this.data(PLUGIN_NS, plugin);
-			}
-		});
-	}
-
-	/**
-	* Main TouchSwipe Plugin Class.
-	* Do not use this to construct your TouchSwipe object, use the jQuery plugin method $.fn.swipe(); {@link $.fn.swipe}
-	* @private
-	* @name TouchSwipe
-	* @param {DOMNode} element The HTML DOM object to apply to plugin to
-	* @param {Object} options The options to configure the plugin with.  @link {$.fn.swipe.defaults}
-	* @see $.fh.swipe.defaults
-	* @see $.fh.swipe
-    * @class
-	*/
-	function TouchSwipe(element, options) {
-        var useTouchEvents = (SUPPORTS_TOUCH || SUPPORTS_POINTER || !options.fallbackToMouseEvents),
-            START_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerDown' : 'pointerdown') : 'touchstart') : 'mousedown',
-            MOVE_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerMove' : 'pointermove') : 'touchmove') : 'mousemove',
-            END_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerUp' : 'pointerup') : 'touchend') : 'mouseup',
-            LEAVE_EV = useTouchEvents ? null : 'mouseleave', //we manually detect leave on touch devices, so null event here
-            CANCEL_EV = (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerCancel' : 'pointercancel') : 'touchcancel');
-
-
-
-		//touch properties
-		var distance = 0,
-			direction = null,
-			duration = 0,
-			startTouchesDistance = 0,
-			endTouchesDistance = 0,
-			pinchZoom = 1,
-			pinchDistance = 0,
-			pinchDirection = 0,
-			maximumsMap=null;
-
-		
-		
-		//jQuery wrapped element for this instance
-		var $element = $(element);
-		
-		//Current phase of th touch cycle
-		var phase = "start";
-
-		// the current number of fingers being used.
-		var fingerCount = 0; 			
-
-		//track mouse points / delta
-		var fingerData=null;
-
-		//track times
-		var startTime = 0,
-			endTime = 0,
-			previousTouchEndTime=0,
-			previousTouchFingerCount=0,
-			doubleTapStartTime=0;
-
-		//Timeouts
-		var singleTapTimeout=null,
-			holdTimeout=null;
-        
-		// Add gestures to all swipable areas if supported
-		try {
-			$element.bind(START_EV, touchStart);
-			$element.bind(CANCEL_EV, touchCancel);
-		}
-		catch (e) {
-			$.error('events not supported ' + START_EV + ',' + CANCEL_EV + ' on jQuery.swipe');
-		}
-
-		//
-		//Public methods
-		//
-		
-		/**
-		* re-enables the swipe plugin with the previous configuration
-		* @function
-		* @name $.fn.swipe#enable
-		* @return {DOMNode} The Dom element that was registered with TouchSwipe 
-		* @example $("#element").swipe("enable");
-		*/
-		this.enable = function () {
-			$element.bind(START_EV, touchStart);
-			$element.bind(CANCEL_EV, touchCancel);
-			return $element;
-		};
-
-		/**
-		* disables the swipe plugin
-		* @function
-		* @name $.fn.swipe#disable
-		* @return {DOMNode} The Dom element that is now registered with TouchSwipe
-	    * @example $("#element").swipe("disable");
-		*/
-		this.disable = function () {
-			removeListeners();
-			return $element;
-		};
-
-		/**
-		* Destroy the swipe plugin completely. To use any swipe methods, you must re initialise the plugin.
-		* @function
-		* @name $.fn.swipe#destroy
-		* @return {DOMNode} The Dom element that was registered with TouchSwipe 
-		* @example $("#element").swipe("destroy");
-		*/
-		this.destroy = function () {
-			removeListeners();
-			$element.data(PLUGIN_NS, null);
-			return $element;
-		};
-
-
-        /**
-         * Allows run time updating of the swipe configuration options.
-         * @function
-    	 * @name $.fn.swipe#option
-    	 * @param {String} property The option property to get or set
-         * @param {Object} [value] The value to set the property to
-		 * @return {Object} If only a property name is passed, then that property value is returned.
-		 * @example $("#element").swipe("option", "threshold"); // return the threshold
-         * @example $("#element").swipe("option", "threshold", 100); // set the threshold after init
-         * @see $.fn.swipe.defaults
-         *
-         */
-        this.option = function (property, value) {
-            if(options[property]!==undefined) {
-                if(value===undefined) {
-                    return options[property];
-                } else {
-                    options[property] = value;
-                }
-            } else {
-                $.error('Option ' + property + ' does not exist on jQuery.swipe.options');
-            }
-
-            return null;
-        }
-
-		//
-		// Private methods
-		//
-		
-		//
-		// EVENTS
-		//
-		/**
-		* Event handler for a touch start event.
-		* Stops the default click event from triggering and stores where we touched
-		* @inner
-		* @param {object} jqEvent The normalised jQuery event object.
-		*/
-		function touchStart(jqEvent) {
-			//If we already in a touch event (a finger already in use) then ignore subsequent ones..
-			if( getTouchInProgress() )
-				return;
-			
-			//Check if this element matches any in the excluded elements selectors,  or its parent is excluded, if so, DON'T swipe
-			if( $(jqEvent.target).closest( options.excludedElements, $element ).length>0 ) 
-				return;
-				
-			//As we use Jquery bind for events, we need to target the original event object
-			//If these events are being programmatically triggered, we don't have an original event object, so use the Jq one.
-			var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent;
-			
-			var ret,
-				evt = SUPPORTS_TOUCH ? event.touches[0] : event;
-
-			phase = PHASE_START;
-
-			//If we support touches, get the finger count
-			if (SUPPORTS_TOUCH) {
-				// get the total number of fingers touching the screen
-				fingerCount = event.touches.length;
-			}
-			//Else this is the desktop, so stop the browser from dragging the image
-			else {
-				jqEvent.preventDefault(); //call this on jq event so we are cross browser
-			}
-
-			//clear vars..
-			distance = 0;
-			direction = null;
-			pinchDirection=null;
-			duration = 0;
-			startTouchesDistance=0;
-			endTouchesDistance=0;
-			pinchZoom = 1;
-			pinchDistance = 0;
-			fingerData=createAllFingerData();
-			maximumsMap=createMaximumsData();
-			cancelMultiFingerRelease();
-
-			
-			// check the number of fingers is what we are looking for, or we are capturing pinches
-			if (!SUPPORTS_TOUCH || (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || hasPinches()) {
-				// get the coordinates of the touch
-				createFingerData( 0, evt );
-				startTime = getTimeStamp();
-				
-				if(fingerCount==2) {
-					//Keep track of the initial pinch distance, so we can calculate the diff later
-					//Store second finger data as start
-					createFingerData( 1, event.touches[1] );
-					startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start);
-				}
-				
-				if (options.swipeStatus || options.pinchStatus) {
-					ret = triggerHandler(event, phase);
-				}
-			}
-			else {
-				//A touch with more or less than the fingers we are looking for, so cancel
-				ret = false; 
-			}
-
-			//If we have a return value from the users handler, then return and cancel
-			if (ret === false) {
-				phase = PHASE_CANCEL;
-				triggerHandler(event, phase);
-				return ret;
-			}
-			else {
-				if (options.hold) {
-					holdTimeout = setTimeout($.proxy(function() {
-						//Trigger the event
-						$element.trigger('hold', [event.target]);
-						//Fire the callback
-						if(options.hold) {
-							ret = options.hold.call($element, event, event.target);
-						}
-					}, this), options.longTapThreshold );
-				}
-
-				setTouchInProgress(true);
-			}
-
-            return null;
-		};
-		
-		
-		
-		/**
-		* Event handler for a touch move event. 
-		* If we change fingers during move, then cancel the event
-		* @inner
-		* @param {object} jqEvent The normalised jQuery event object.
-		*/
-		function touchMove(jqEvent) {
-			
-			//As we use Jquery bind for events, we need to target the original event object
-			//If these events are being programmatically triggered, we don't have an original event object, so use the Jq one.
-			var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent;
-			
-			//If we are ending, cancelling, or within the threshold of 2 fingers being released, don't track anything..
-			if (phase === PHASE_END || phase === PHASE_CANCEL || inMultiFingerRelease())
-				return;
-
-			var ret,
-				evt = SUPPORTS_TOUCH ? event.touches[0] : event;
-			
-
-			//Update the  finger data 
-			var currentFinger = updateFingerData(evt);
-			endTime = getTimeStamp();
-			
-			if (SUPPORTS_TOUCH) {
-				fingerCount = event.touches.length;
-			}
-
-			if (options.hold)
-				clearTimeout(holdTimeout);
-
-			phase = PHASE_MOVE;
-
-			//If we have 2 fingers get Touches distance as well
-			if(fingerCount==2) {
-				
-				//Keep track of the initial pinch distance, so we can calculate the diff later
-				//We do this here as well as the start event, in case they start with 1 finger, and the press 2 fingers
-				if(startTouchesDistance==0) {
-					//Create second finger if this is the first time...
-					createFingerData( 1, event.touches[1] );
-					
-					startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start);
-				} else {
-					//Else just update the second finger
-					updateFingerData(event.touches[1]);
-				
-					endTouchesDistance = calculateTouchesDistance(fingerData[0].end, fingerData[1].end);
-					pinchDirection = calculatePinchDirection(fingerData[0].end, fingerData[1].end);
-				}
-				
-				
-				pinchZoom = calculatePinchZoom(startTouchesDistance, endTouchesDistance);
-				pinchDistance = Math.abs(startTouchesDistance - endTouchesDistance);
-			}
-			
-			
-			if ( (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH || hasPinches() ) {
-				
-				direction = calculateDirection(currentFinger.start, currentFinger.end);
-				
-				//Check if we need to prevent default event (page scroll / pinch zoom) or not
-				validateDefaultEvent(jqEvent, direction);
-
-				//Distance and duration are all off the main finger
-				distance = calculateDistance(currentFinger.start, currentFinger.end);
-				duration = calculateDuration();
-
-                //Cache the maximum distance we made in this direction
-                setMaxDistance(direction, distance);
-
-
-				if (options.swipeStatus || options.pinchStatus) {
-					ret = triggerHandler(event, phase);
-				}
-				
-				
-				//If we trigger end events when threshold are met, or trigger events when touch leaves element
-				if(!options.triggerOnTouchEnd || options.triggerOnTouchLeave) {
-					
-					var inBounds = true;
-					
-					//If checking if we leave the element, run the bounds check (we can use touchleave as its not supported on webkit)
-					if(options.triggerOnTouchLeave) {
-						var bounds = getbounds( this );
-						inBounds = isInBounds( currentFinger.end, bounds );
-					}
-					
-					//Trigger end handles as we swipe if thresholds met or if we have left the element if the user has asked to check these..
-					if(!options.triggerOnTouchEnd && inBounds) {
-						phase = getNextPhase( PHASE_MOVE );
-					} 
-					//We end if out of bounds here, so set current phase to END, and check if its modified 
-					else if(options.triggerOnTouchLeave && !inBounds ) {
-						phase = getNextPhase( PHASE_END );
-					}
-						
-					if(phase==PHASE_CANCEL || phase==PHASE_END)	{
-						triggerHandler(event, phase);
-					}				
-				}
-			}
-			else {
-				phase = PHASE_CANCEL;
-				triggerHandler(event, phase);
-			}
-
-			if (ret === false) {
-				phase = PHASE_CANCEL;
-				triggerHandler(event, phase);
-			}
-		}
-
-
-
-		/**
-		* Event handler for a touch end event. 
-		* Calculate the direction and trigger events
-		* @inner
-		* @param {object} jqEvent The normalised jQuery event object.
-		*/
-		function touchEnd(jqEvent) {
-			//As we use Jquery bind for events, we need to target the original event object
-			var event = jqEvent.originalEvent;
-				
-
-			//If we are still in a touch with another finger return
-			//This allows us to wait a fraction and see if the other finger comes up, if it does within the threshold, then we treat it as a multi release, not a single release.
-			if (SUPPORTS_TOUCH) {
-				if(event.touches.length>0) {
-					startMultiFingerRelease();
-					return true;
-				}
-			}
-			
-			//If a previous finger has been released, check how long ago, if within the threshold, then assume it was a multifinger release.
-			//This is used to allow 2 fingers to release fractionally after each other, whilst maintainig the event as containg 2 fingers, not 1
-			if(inMultiFingerRelease()) {	
-				fingerCount=previousTouchFingerCount;
-			}	
-		
-			//Set end of swipe
-			endTime = getTimeStamp();
-			
-			//Get duration incase move was never fired
-			duration = calculateDuration();
-			
-			//If we trigger handlers at end of swipe OR, we trigger during, but they didnt trigger and we are still in the move phase
-			if(didSwipeBackToCancel() || !validateSwipeDistance()) {
-			    phase = PHASE_CANCEL;
-                triggerHandler(event, phase);
-			} else if (options.triggerOnTouchEnd || (options.triggerOnTouchEnd == false && phase === PHASE_MOVE)) {
-				//call this on jq event so we are cross browser 
-				jqEvent.preventDefault(); 
-				phase = PHASE_END;
-                triggerHandler(event, phase);
-			}
-			//Special cases - A tap should always fire on touch end regardless,
-			//So here we manually trigger the tap end handler by itself
-			//We dont run trigger handler as it will re-trigger events that may have fired already
-			else if (!options.triggerOnTouchEnd && hasTap()) {
-                //Trigger the pinch events...
-			    phase = PHASE_END;
-			    triggerHandlerForGesture(event, phase, TAP);
-			}
-			else if (phase === PHASE_MOVE) {
-				phase = PHASE_CANCEL;
-				triggerHandler(event, phase);
-			}
-
-			setTouchInProgress(false);
-
-            return null;
-		}
-
-
-
-		/**
-		* Event handler for a touch cancel event. 
-		* Clears current vars
-		* @inner
-		*/
-		function touchCancel() {
-			// reset the variables back to default values
-			fingerCount = 0;
-			endTime = 0;
-			startTime = 0;
-			startTouchesDistance=0;
-			endTouchesDistance=0;
-			pinchZoom=1;
-			
-			//If we were in progress of tracking a possible multi touch end, then re set it.
-			cancelMultiFingerRelease();
-			
-			setTouchInProgress(false);
-		}
-		
-		
-		/**
-		* Event handler for a touch leave event. 
-		* This is only triggered on desktops, in touch we work this out manually
-		* as the touchleave event is not supported in webkit
-		* @inner
-		*/
-		function touchLeave(jqEvent) {
-			var event = jqEvent.originalEvent;
-			
-			//If we have the trigger on leave property set....
-			if(options.triggerOnTouchLeave) {
-				phase = getNextPhase( PHASE_END );
-				triggerHandler(event, phase);
-			}
-		}
-		
-		/**
-		* Removes all listeners that were associated with the plugin
-		* @inner
-		*/
-		function removeListeners() {
-			$element.unbind(START_EV, touchStart);
-			$element.unbind(CANCEL_EV, touchCancel);
-			$element.unbind(MOVE_EV, touchMove);
-			$element.unbind(END_EV, touchEnd);
-			
-			//we only have leave events on desktop, we manually calculate leave on touch as its not supported in webkit
-			if(LEAVE_EV) { 
-				$element.unbind(LEAVE_EV, touchLeave);
-			}
-			
-			setTouchInProgress(false);
-		}
-
-		
-		/**
-		 * Checks if the time and distance thresholds have been met, and if so then the appropriate handlers are fired.
-		 */
-		function getNextPhase(currentPhase) {
-			
-			var nextPhase = currentPhase;
-			
-			// Ensure we have valid swipe (under time and over distance  and check if we are out of bound...)
-			var validTime = validateSwipeTime();
-			var validDistance = validateSwipeDistance();
-			var didCancel = didSwipeBackToCancel();
-						
-			//If we have exceeded our time, then cancel	
-			if(!validTime || didCancel) {
-				nextPhase = PHASE_CANCEL;
-			}
-			//Else if we are moving, and have reached distance then end
-			else if (validDistance && currentPhase == PHASE_MOVE && (!options.triggerOnTouchEnd || options.triggerOnTouchLeave) ) {
-				nextPhase = PHASE_END;
-			} 
-			//Else if we have ended by leaving and didn't reach distance, then cancel
-			else if (!validDistance && currentPhase==PHASE_END && options.triggerOnTouchLeave) {
-				nextPhase = PHASE_CANCEL;
-			}
-			
-			return nextPhase;
-		}
-		
-		
-		/**
-		* Trigger the relevant event handler
-		* The handlers are passed the original event, the element that was swiped, and in the case of the catch all handler, the direction that was swiped, "left", "right", "up", or "down"
-		* @param {object} event the original event object
-		* @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases}
-		* @inner
-		*/
-		function triggerHandler(event, phase) {
-			
-			var ret = undefined;
-			
-			// SWIPE GESTURES
-			if(didSwipe() || hasSwipes()) { //hasSwipes as status needs to fire even if swipe is invalid
-				//Trigger the swipe events...
-				ret = triggerHandlerForGesture(event, phase, SWIPE);
-			} 
-			
-			// PINCH GESTURES (if the above didn't cancel)
-			else if((didPinch() || hasPinches()) && ret!==false) {
-				//Trigger the pinch events...
-				ret = triggerHandlerForGesture(event, phase, PINCH);
-			}
-			
-			// CLICK / TAP (if the above didn't cancel)
-			if(didDoubleTap() && ret!==false) {
-				//Trigger the tap events...
-				ret = triggerHandlerForGesture(event, phase, DOUBLE_TAP);
-			}
-			
-			// CLICK / TAP (if the above didn't cancel)
-			else if(didLongTap() && ret!==false) {
-				//Trigger the tap events...
-				ret = triggerHandlerForGesture(event, phase, LONG_TAP);
-			}
-
-			// CLICK / TAP (if the above didn't cancel)
-			else if(didTap() && ret!==false) {
-				//Trigger the tap event..
-				ret = triggerHandlerForGesture(event, phase, TAP);
-			}
-			
-			
-			
-			// If we are cancelling the gesture, then manually trigger the reset handler
-			if (phase === PHASE_CANCEL) {
-				touchCancel(event);
-			}
-			
-			// If we are ending the gesture, then manually trigger the reset handler IF all fingers are off
-			if(phase === PHASE_END) {
-				//If we support touch, then check that all fingers are off before we cancel
-				if (SUPPORTS_TOUCH) {
-					if(event.touches.length==0) {
-						touchCancel(event);	
-					}
-				} 
-				else {
-					touchCancel(event);
-				}
-			}
-					
-			return ret;
-		}
-		
-		
-		
-		/**
-		* Trigger the relevant event handler
-		* The handlers are passed the original event, the element that was swiped, and in the case of the catch all handler, the direction that was swiped, "left", "right", "up", or "down"
-		* @param {object} event the original event object
-		* @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases}
-		* @param {string} gesture the gesture to trigger a handler for : PINCH or SWIPE {@link $.fn.swipe.gestures}
-		* @return Boolean False, to indicate that the event should stop propagation, or void.
-		* @inner
-		*/
-		function triggerHandlerForGesture(event, phase, gesture) {	
-			
-			var ret=undefined;
-			
-			//SWIPES....
-			if(gesture==SWIPE) {
-				//Trigger status every time..
-				
-				//Trigger the event...
-				$element.trigger('swipeStatus', [phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData]);
-				
-				//Fire the callback
-				if (options.swipeStatus) {
-					ret = options.swipeStatus.call($element, event, phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData);
-					//If the status cancels, then dont run the subsequent event handlers..
-					if(ret===false) return false;
-				}
-				
-				
-				
-				
-				if (phase == PHASE_END && validateSwipe()) {
-					//Fire the catch all event
-					$element.trigger('swipe', [direction, distance, duration, fingerCount, fingerData]);
-					
-					//Fire catch all callback
-					if (options.swipe) {
-						ret = options.swipe.call($element, event, direction, distance, duration, fingerCount, fingerData);
-						//If the status cancels, then dont run the subsequent event handlers..
-						if(ret===false) return false;
-					}
-					
-					//trigger direction specific event handlers	
-					switch (direction) {
-						case LEFT:
-							//Trigger the event
-							$element.trigger('swipeLeft', [direction, distance, duration, fingerCount, fingerData]);
-					
-					        //Fire the callback
-							if (options.swipeLeft) {
-								ret = options.swipeLeft.call($element, event, direction, distance, duration, fingerCount, fingerData);
-							}
-							break;
-	
-						case RIGHT:
-							//Trigger the event
-					        $element.trigger('swipeRight', [direction, distance, duration, fingerCount, fingerData]);
-					
-					        //Fire the callback
-							if (options.swipeRight) {
-								ret = options.swipeRight.call($element, event, direction, distance, duration, fingerCount, fingerData);
-							}
-							break;
-	
-						case UP:
-							//Trigger the event
-					        $element.trigger('swipeUp', [direction, distance, duration, fingerCount, fingerData]);
-					
-					        //Fire the callback
-							if (options.swipeUp) {
-								ret = options.swipeUp.call($element, event, direction, distance, duration, fingerCount, fingerData);
-							}
-							break;
-	
-						case DOWN:
-							//Trigger the event
-					        $element.trigger('swipeDown', [direction, distance, duration, fingerCount, fingerData]);
-					
-					        //Fire the callback
-							if (options.swipeDown) {
-								ret = options.swipeDown.call($element, event, direction, distance, duration, fingerCount, fingerData);
-							}
-							break;
-					}
-				}
-			}
-			
-			
-			//PINCHES....
-			if(gesture==PINCH) {
-				//Trigger the event
-			     $element.trigger('pinchStatus', [phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]);
-					
-                //Fire the callback
-				if (options.pinchStatus) {
-					ret = options.pinchStatus.call($element, event, phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData);
-					//If the status cancels, then dont run the subsequent event handlers..
-					if(ret===false) return false;
-				}
-				
-				if(phase==PHASE_END && validatePinch()) {
-					
-					switch (pinchDirection) {
-						case IN:
-							//Trigger the event
-                            $element.trigger('pinchIn', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]);
-                    
-                            //Fire the callback
-                            if (options.pinchIn) {
-								ret = options.pinchIn.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData);
-							}
-							break;
-						
-						case OUT:
-							//Trigger the event
-                            $element.trigger('pinchOut', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]);
-                    
-                            //Fire the callback
-                            if (options.pinchOut) {
-								ret = options.pinchOut.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData);
-							}
-							break;	
-					}
-				}
-			}
-			
-
-
-                
-	    		
-			if(gesture==TAP) {
-				if(phase === PHASE_CANCEL || phase === PHASE_END) {
-					
-    			    
-    			    //Cancel any existing double tap
-				    clearTimeout(singleTapTimeout);
-    			    //Cancel hold timeout
-				    clearTimeout(holdTimeout);
-				           
-					//If we are also looking for doubelTaps, wait incase this is one...
-				    if(hasDoubleTap() && !inDoubleTap()) {
-				        //Cache the time of this tap
-                        doubleTapStartTime = getTimeStamp();
-                       
-				        //Now wait for the double tap timeout, and trigger this single tap
-				        //if its not cancelled by a double tap
-				        singleTapTimeout = setTimeout($.proxy(function() {
-        			        doubleTapStartTime=null;
-        			        //Trigger the event
-                			$element.trigger('tap', [event.target]);
-
-                        
-                            //Fire the callback
-                            if(options.tap) {
-                                ret = options.tap.call($element, event, event.target);
-                            }
-    			        }, this), options.doubleTapThreshold );
-    			    	
-    			    } else {
-                        doubleTapStartTime=null;
-                        
-                        //Trigger the event
-                        $element.trigger('tap', [event.target]);
-
-                        
-                        //Fire the callback
-                        if(options.tap) {
-                            ret = options.tap.call($element, event, event.target);
-                        }
-	    		    }
-	    		}
-			}
-			
-			else if (gesture==DOUBLE_TAP) {
-				if(phase === PHASE_CANCEL || phase === PHASE_END) {
-					//Cancel any pending singletap 
-				    clearTimeout(singleTapTimeout);
-				    doubleTapStartTime=null;
-				        
-                    //Trigger the event
-                    $element.trigger('doubletap', [event.target]);
-                
-                    //Fire the callback
-                    if(options.doubleTap) {
-                        ret = options.doubleTap.call($element, event, event.target);
-                    }
-	    		}
-			}
-			
-			else if (gesture==LONG_TAP) {
-				if(phase === PHASE_CANCEL || phase === PHASE_END) {
-					//Cancel any pending singletap (shouldnt be one)
-				    clearTimeout(singleTapTimeout);
-				    doubleTapStartTime=null;
-				        
-                    //Trigger the event
-                    $element.trigger('longtap', [event.target]);
-                
-                    //Fire the callback
-                    if(options.longTap) {
-                        ret = options.longTap.call($element, event, event.target);
-                    }
-	    		}
-			}				
-				
-			return ret;
-		}
-
-
-
-		
-		//
-		// GESTURE VALIDATION
-		//
-		
-		/**
-		* Checks the user has swipe far enough
-		* @return Boolean if <code>threshold</code> has been set, return true if the threshold was met, else false.
-		* If no threshold was set, then we return true.
-		* @inner
-		*/
-		function validateSwipeDistance() {
-			var valid = true;
-			//If we made it past the min swipe distance..
-			if (options.threshold !== null) {
-				valid = distance >= options.threshold;
-			}
-			
-            return valid;
-		}
-		
-		/**
-		* Checks the user has swiped back to cancel.
-		* @return Boolean if <code>cancelThreshold</code> has been set, return true if the cancelThreshold was met, else false.
-		* If no cancelThreshold was set, then we return true.
-		* @inner
-		*/
-		function didSwipeBackToCancel() {
-            var cancelled = false;
-    		if(options.cancelThreshold !== null && direction !==null)  {
-    		    cancelled =  (getMaxDistance( direction ) - distance) >= options.cancelThreshold;
-			}
-			
-			return cancelled;
-		}
-
-		/**
-		* Checks the user has pinched far enough
-		* @return Boolean if <code>pinchThreshold</code> has been set, return true if the threshold was met, else false.
-		* If no threshold was set, then we return true.
-		* @inner
-		*/
-		function validatePinchDistance() {
-			if (options.pinchThreshold !== null) {
-				return pinchDistance >= options.pinchThreshold;
-			}
-			return true;
-		}
-
-		/**
-		* Checks that the time taken to swipe meets the minimum / maximum requirements
-		* @return Boolean
-		* @inner
-		*/
-		function validateSwipeTime() {
-			var result;
-			//If no time set, then return true
-
-			if (options.maxTimeThreshold) {
-				if (duration >= options.maxTimeThreshold) {
-					result = false;
-				} else {
-					result = true;
-				}
-			}
-			else {
-				result = true;
-			}
-
-			return result;
-		}
-
-
-		/**
-		* Checks direction of the swipe and the value allowPageScroll to see if we should allow or prevent the default behaviour from occurring.
-		* This will essentially allow page scrolling or not when the user is swiping on a touchSwipe object.
-		* @param {object} jqEvent The normalised jQuery representation of the event object.
-		* @param {string} direction The direction of the event. See {@link $.fn.swipe.directions}
-		* @see $.fn.swipe.directions
-		* @inner
-		*/
-		function validateDefaultEvent(jqEvent, direction) {
-			if (options.allowPageScroll === NONE || hasPinches()) {
-				jqEvent.preventDefault();
-			} else {
-				var auto = options.allowPageScroll === AUTO;
-
-				switch (direction) {
-					case LEFT:
-						if ((options.swipeLeft && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) {
-							jqEvent.preventDefault();
-						}
-						break;
-
-					case RIGHT:
-						if ((options.swipeRight && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) {
-							jqEvent.preventDefault();
-						}
-						break;
-
-					case UP:
-						if ((options.swipeUp && auto) || (!auto && options.allowPageScroll != VERTICAL)) {
-							jqEvent.preventDefault();
-						}
-						break;
-
-					case DOWN:
-						if ((options.swipeDown && auto) || (!auto && options.allowPageScroll != VERTICAL)) {
-							jqEvent.preventDefault();
-						}
-						break;
-				}
-			}
-
-		}
-
-
-		// PINCHES
-		/**
-		 * Returns true of the current pinch meets the thresholds
-		 * @return Boolean
-		 * @inner
-		*/
-		function validatePinch() {
-		    var hasCorrectFingerCount = validateFingers();
-		    var hasEndPoint = validateEndPoint();
-			var hasCorrectDistance = validatePinchDistance();
-			return hasCorrectFingerCount && hasEndPoint && hasCorrectDistance;
-			
-		}
-		
-		/**
-		 * Returns true if any Pinch events have been registered
-		 * @return Boolean
-		 * @inner
-		*/
-		function hasPinches() {
-			//Enure we dont return 0 or null for false values
-			return !!(options.pinchStatus || options.pinchIn || options.pinchOut);
-		}
-		
-		/**
-		 * Returns true if we are detecting pinches, and have one
-		 * @return Boolean
-		 * @inner
-		 */
-		function didPinch() {
-			//Enure we dont return 0 or null for false values
-			return !!(validatePinch() && hasPinches());
-		}
-
-
-
-
-		// SWIPES
-		/**
-		 * Returns true if the current swipe meets the thresholds
-		 * @return Boolean
-		 * @inner
-		*/
-		function validateSwipe() {
-			//Check validity of swipe
-			var hasValidTime = validateSwipeTime();
-			var hasValidDistance = validateSwipeDistance();	
-			var hasCorrectFingerCount = validateFingers();
-		    var hasEndPoint = validateEndPoint();
-		    var didCancel = didSwipeBackToCancel();	
-		    
-			// if the user swiped more than the minimum length, perform the appropriate action
-			// hasValidDistance is null when no distance is set 
-			var valid =  !didCancel && hasEndPoint && hasCorrectFingerCount && hasValidDistance && hasValidTime;
-			
-			return valid;
-		}
-		
-		/**
-		 * Returns true if any Swipe events have been registered
-		 * @return Boolean
-		 * @inner
-		*/
-		function hasSwipes() {
-			//Enure we dont return 0 or null for false values
-			return !!(options.swipe || options.swipeStatus || options.swipeLeft || options.swipeRight || options.swipeUp || options.swipeDown);
-		}
-		
-		
-		/**
-		 * Returns true if we are detecting swipes and have one
-		 * @return Boolean
-		 * @inner
-		*/
-		function didSwipe() {
-			//Enure we dont return 0 or null for false values
-			return !!(validateSwipe() && hasSwipes());
-		}
-
-        /**
-		 * Returns true if we have matched the number of fingers we are looking for
-		 * @return Boolean
-		 * @inner
-		*/
-        function validateFingers() {
-            //The number of fingers we want were matched, or on desktop we ignore
-    		return ((fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH);
-    	}
-        
-        /**
-		 * Returns true if we have an end point for the swipe
-		 * @return Boolean
-		 * @inner
-		*/
-        function validateEndPoint() {
-            //We have an end value for the finger
-		    return fingerData[0].end.x !== 0;
-        }
-
-		// TAP / CLICK
-		/**
-		 * Returns true if a click / tap events have been registered
-		 * @return Boolean
-		 * @inner
-		*/
-		function hasTap() {
-			//Enure we dont return 0 or null for false values
-			return !!(options.tap) ;
-		}
-		
-		/**
-		 * Returns true if a double tap events have been registered
-		 * @return Boolean
-		 * @inner
-		*/
-		function hasDoubleTap() {
-			//Enure we dont return 0 or null for false values
-			return !!(options.doubleTap) ;
-		}
-		
-		/**
-		 * Returns true if any long tap events have been registered
-		 * @return Boolean
-		 * @inner
-		*/
-		function hasLongTap() {
-			//Enure we dont return 0 or null for false values
-			return !!(options.longTap) ;
-		}
-		
-		/**
-		 * Returns true if we could be in the process of a double tap (one tap has occurred, we are listening for double taps, and the threshold hasn't past.
-		 * @return Boolean
-		 * @inner
-		*/
-		function validateDoubleTap() {
-		    if(doubleTapStartTime==null){
-		        return false;
-		    }
-		    var now = getTimeStamp();
-		    return (hasDoubleTap() && ((now-doubleTapStartTime) <= options.doubleTapThreshold));
-		}
-		
-		/**
-		 * Returns true if we could be in the process of a double tap (one tap has occurred, we are listening for double taps, and the threshold hasn't past.
-		 * @return Boolean
-		 * @inner
-		*/
-		function inDoubleTap() {
-		    return validateDoubleTap();
-		}
-		
-		
-		/**
-		 * Returns true if we have a valid tap
-		 * @return Boolean
-		 * @inner
-		*/
-		function validateTap() {
-		    return ((fingerCount === 1 || !SUPPORTS_TOUCH) && (isNaN(distance) || distance < options.threshold));
-		}
-		
-		/**
-		 * Returns true if we have a valid long tap
-		 * @return Boolean
-		 * @inner
-		*/
-		function validateLongTap() {
-		    //slight threshold on moving finger
-            return ((duration > options.longTapThreshold) && (distance < DOUBLE_TAP_THRESHOLD)); 
-		}
-		
-		/**
-		 * Returns true if we are detecting taps and have one
-		 * @return Boolean
-		 * @inner
-		*/
-		function didTap() {
-		    //Enure we dont return 0 or null for false values
-			return !!(validateTap() && hasTap());
-		}
-		
-		
-		/**
-		 * Returns true if we are detecting double taps and have one
-		 * @return Boolean
-		 * @inner
-		*/
-		function didDoubleTap() {
-		    //Enure we dont return 0 or null for false values
-			return !!(validateDoubleTap() && hasDoubleTap());
-		}
-		
-		/**
-		 * Returns true if we are detecting long taps and have one
-		 * @return Boolean
-		 * @inner
-		*/
-		function didLongTap() {
-		    //Enure we dont return 0 or null for false values
-			return !!(validateLongTap() && hasLongTap());
-		}
-		
-		
-		
-		
-		// MULTI FINGER TOUCH
-		/**
-		 * Starts tracking the time between 2 finger releases, and keeps track of how many fingers we initially had up
-		 * @inner
-		*/
-		function startMultiFingerRelease() {
-			previousTouchEndTime = getTimeStamp();
-			previousTouchFingerCount = event.touches.length+1;
-		}
-		
-		/**
-		 * Cancels the tracking of time between 2 finger releases, and resets counters
-		 * @inner
-		*/
-		function cancelMultiFingerRelease() {
-			previousTouchEndTime = 0;
-			previousTouchFingerCount = 0;
-		}
-		
-		/**
-		 * Checks if we are in the threshold between 2 fingers being released 
-		 * @return Boolean
-		 * @inner
-		*/
-		function inMultiFingerRelease() {
-			
-			var withinThreshold = false;
-			
-			if(previousTouchEndTime) {	
-				var diff = getTimeStamp() - previousTouchEndTime	
-				if( diff<=options.fingerReleaseThreshold ) {
-					withinThreshold = true;
-				}
-			}
-			
-			return withinThreshold;	
-		}
-		
-
-		/**
-		* gets a data flag to indicate that a touch is in progress
-		* @return Boolean
-		* @inner
-		*/
-		function getTouchInProgress() {
-			//strict equality to ensure only true and false are returned
-			return !!($element.data(PLUGIN_NS+'_intouch') === true);
-		}
-		
-		/**
-		* Sets a data flag to indicate that a touch is in progress
-		* @param {boolean} val The value to set the property to
-		* @inner
-		*/
-		function setTouchInProgress(val) {
-			
-			//Add or remove event listeners depending on touch status
-			if(val===true) {
-				$element.bind(MOVE_EV, touchMove);
-				$element.bind(END_EV, touchEnd);
-				
-				//we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit
-				if(LEAVE_EV) { 
-					$element.bind(LEAVE_EV, touchLeave);
-				}
-			} else {
-				$element.unbind(MOVE_EV, touchMove, false);
-				$element.unbind(END_EV, touchEnd, false);
-			
-				//we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit
-				if(LEAVE_EV) { 
-					$element.unbind(LEAVE_EV, touchLeave, false);
-				}
-			}
-			
-		
-			//strict equality to ensure only true and false can update the value
-			$element.data(PLUGIN_NS+'_intouch', val === true);
-		}
-		
-		
-		/**
-		 * Creates the finger data for the touch/finger in the event object.
-		 * @param {int} index The index in the array to store the finger data (usually the order the fingers were pressed)
-		 * @param {object} evt The event object containing finger data
-		 * @return finger data object
-		 * @inner
-		*/
-		function createFingerData( index, evt ) {
-			var id = evt.identifier!==undefined ? evt.identifier : 0; 
-			
-			fingerData[index].identifier = id;
-			fingerData[index].start.x = fingerData[index].end.x = evt.pageX||evt.clientX;
-			fingerData[index].start.y = fingerData[index].end.y = evt.pageY||evt.clientY;
-			
-			return fingerData[index];
-		}
-		
-		/**
-		 * Updates the finger data for a particular event object
-		 * @param {object} evt The event object containing the touch/finger data to upadte
-		 * @return a finger data object.
-		 * @inner
-		*/
-		function updateFingerData(evt) {
-			
-			var id = evt.identifier!==undefined ? evt.identifier : 0; 
-			var f = getFingerData( id );
-			
-			f.end.x = evt.pageX||evt.clientX;
-			f.end.y = evt.pageY||evt.clientY;
-			
-			return f;
-		}
-		
-		/**
-		 * Returns a finger data object by its event ID.
-		 * Each touch event has an identifier property, which is used 
-		 * to track repeat touches
-		 * @param {int} id The unique id of the finger in the sequence of touch events.
-		 * @return a finger data object.
-		 * @inner
-		*/
-		function getFingerData( id ) {
-			for(var i=0; i<fingerData.length; i++) {
-				if(fingerData[i].identifier == id) {
-					return fingerData[i];	
-				}
-			}
-		}
-		
-		/**
-		 * Creats all the finger onjects and returns an array of finger data
-		 * @return Array of finger objects
-		 * @inner
-		*/
-		function createAllFingerData() {
-			var fingerData=[];
-			for (var i=0; i<=5; i++) {
-				fingerData.push({
-					start:{ x: 0, y: 0 },
-					end:{ x: 0, y: 0 },
-					identifier:0
-				});
-			}
-			
-			return fingerData;
-		}
-		
-		/**
-		 * Sets the maximum distance swiped in the given direction. 
-		 * If the new value is lower than the current value, the max value is not changed.
-		 * @param {string}  direction The direction of the swipe
-		 * @param {int}  distance The distance of the swipe
-		 * @inner
-		*/
-		function setMaxDistance(direction, distance) {
-    		distance = Math.max(distance, getMaxDistance(direction) );
-    		maximumsMap[direction].distance = distance;
-		}
-        
-        /**
-		 * gets the maximum distance swiped in the given direction. 
-		 * @param {string}  direction The direction of the swipe
-		 * @return int  The distance of the swipe
-		 * @inner
-		*/        
-		function getMaxDistance(direction) {
-			if (maximumsMap[direction]) return maximumsMap[direction].distance;
-			return undefined;
-		}
-		
-		/**
-		 * Creats a map of directions to maximum swiped values.
-		 * @return Object A dictionary of maximum values, indexed by direction.
-		 * @inner
-		*/
-		function createMaximumsData() {
-			var maxData={};
-			maxData[LEFT]=createMaximumVO(LEFT);
-			maxData[RIGHT]=createMaximumVO(RIGHT);
-			maxData[UP]=createMaximumVO(UP);
-			maxData[DOWN]=createMaximumVO(DOWN);
-			
-			return maxData;
-		}
-		
-		/**
-		 * Creates a map maximum swiped values for a given swipe direction
-		 * @param {string} The direction that these values will be associated with
-		 * @return Object Maximum values
-		 * @inner
-		*/
-		function createMaximumVO(dir) {
-		    return { 
-		        direction:dir, 
-		        distance:0
-		    }
-		}
-		
-		
-		//
-		// MATHS / UTILS
-		//
-
-		/**
-		* Calculate the duration of the swipe
-		* @return int
-		* @inner
-		*/
-		function calculateDuration() {
-			return endTime - startTime;
-		}
-		
-		/**
-		* Calculate the distance between 2 touches (pinch)
-		* @param {point} startPoint A point object containing x and y co-ordinates
-	    * @param {point} endPoint A point object containing x and y co-ordinates
-	    * @return int;
-		* @inner
-		*/
-		function calculateTouchesDistance(startPoint, endPoint) {
-			var diffX = Math.abs(startPoint.x - endPoint.x);
-			var diffY = Math.abs(startPoint.y - endPoint.y);
-				
-			return Math.round(Math.sqrt(diffX*diffX+diffY*diffY));
-		}
-		
-		/**
-		* Calculate the zoom factor between the start and end distances
-		* @param {int} startDistance Distance (between 2 fingers) the user started pinching at
-	    * @param {int} endDistance Distance (between 2 fingers) the user ended pinching at
-	    * @return float The zoom value from 0 to 1.
-		* @inner
-		*/
-		function calculatePinchZoom(startDistance, endDistance) {
-			var percent = (endDistance/startDistance) * 1;
-			return percent.toFixed(2);
-		}
-		
-		
-		/**
-		* Returns the pinch direction, either IN or OUT for the given points
-		* @return string Either {@link $.fn.swipe.directions.IN} or {@link $.fn.swipe.directions.OUT}
-		* @see $.fn.swipe.directions
-		* @inner
-		*/
-		function calculatePinchDirection() {
-			if(pinchZoom<1) {
-				return OUT;
-			}
-			else {
-				return IN;
-			}
-		}
-		
-		
-		/**
-		* Calculate the length / distance of the swipe
-		* @param {point} startPoint A point object containing x and y co-ordinates
-	    * @param {point} endPoint A point object containing x and y co-ordinates
-	    * @return int
-		* @inner
-		*/
-		function calculateDistance(startPoint, endPoint) {
-			return Math.round(Math.sqrt(Math.pow(endPoint.x - startPoint.x, 2) + Math.pow(endPoint.y - startPoint.y, 2)));
-		}
-
-		/**
-		* Calculate the angle of the swipe
-		* @param {point} startPoint A point object containing x and y co-ordinates
-	    * @param {point} endPoint A point object containing x and y co-ordinates
-	    * @return int
-		* @inner
-		*/
-		function calculateAngle(startPoint, endPoint) {
-			var x = startPoint.x - endPoint.x;
-			var y = endPoint.y - startPoint.y;
-			var r = Math.atan2(y, x); //radians
-			var angle = Math.round(r * 180 / Math.PI); //degrees
-
-			//ensure value is positive
-			if (angle < 0) {
-				angle = 360 - Math.abs(angle);
-			}
-
-			return angle;
-		}
-
-		/**
-		* Calculate the direction of the swipe
-		* This will also call calculateAngle to get the latest angle of swipe
-		* @param {point} startPoint A point object containing x and y co-ordinates
-	    * @param {point} endPoint A point object containing x and y co-ordinates
-	    * @return string Either {@link $.fn.swipe.directions.LEFT} / {@link $.fn.swipe.directions.RIGHT} / {@link $.fn.swipe.directions.DOWN} / {@link $.fn.swipe.directions.UP}
-		* @see $.fn.swipe.directions
-		* @inner
-		*/
-		function calculateDirection(startPoint, endPoint ) {
-			var angle = calculateAngle(startPoint, endPoint);
-
-			if ((angle <= 45) && (angle >= 0)) {
-				return LEFT;
-			} else if ((angle <= 360) && (angle >= 315)) {
-				return LEFT;
-			} else if ((angle >= 135) && (angle <= 225)) {
-				return RIGHT;
-			} else if ((angle > 45) && (angle < 135)) {
-				return DOWN;
-			} else {
-				return UP;
-			}
-		}
-		
-
-		/**
-		* Returns a MS time stamp of the current time
-		* @return int
-		* @inner
-		*/
-		function getTimeStamp() {
-			var now = new Date();
-			return now.getTime();
-		}
-		
-		
-		
-		/**
-		 * Returns a bounds object with left, right, top and bottom properties for the element specified.
-		 * @param {DomNode} The DOM node to get the bounds for.
-		 */
-		function getbounds( el ) {
-			el = $(el);
-			var offset = el.offset();
-			
-			var bounds = {	
-					left:offset.left,
-					right:offset.left+el.outerWidth(),
-					top:offset.top,
-					bottom:offset.top+el.outerHeight()
-					}
-			
-			return bounds;	
-		}
-		
-		
-		/**
-		 * Checks if the point object is in the bounds object.
-		 * @param {object} point A point object.
-		 * @param {int} point.x The x value of the point.
-		 * @param {int} point.y The x value of the point.
-		 * @param {object} bounds The bounds object to test
-		 * @param {int} bounds.left The leftmost value
-		 * @param {int} bounds.right The righttmost value
-		 * @param {int} bounds.top The topmost value
-		* @param {int} bounds.bottom The bottommost value
-		 */
-		function isInBounds(point, bounds) {
-			return (point.x > bounds.left && point.x < bounds.right && point.y > bounds.top && point.y < bounds.bottom);
-		};
-	
-	
-	}
-	
-	
-
-
-/**
- * A catch all handler that is triggered for all swipe directions. 
- * @name $.fn.swipe#swipe
- * @event
- * @default null
- * @param {EventObject} event The original event object
- * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
- * @param {int} distance The distance the user swiped
- * @param {int} duration The duration of the swipe in milliseconds
- * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
- * @param {object} fingerData The coordinates of fingers in event
- */
- 
-
-
-
-/**
- * A handler that is triggered for "left" swipes.
- * @name $.fn.swipe#swipeLeft
- * @event
- * @default null
- * @param {EventObject} event The original event object
- * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
- * @param {int} distance The distance the user swiped
- * @param {int} duration The duration of the swipe in milliseconds
- * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
- * @param {object} fingerData The coordinates of fingers in event
- */
- 
-/**
- * A handler that is triggered for "right" swipes.
- * @name $.fn.swipe#swipeRight
- * @event
- * @default null
- * @param {EventObject} event The original event object
- * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
- * @param {int} distance The distance the user swiped
- * @param {int} duration The duration of the swipe in milliseconds
- * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
- * @param {object} fingerData The coordinates of fingers in event
- */
-
-/**
- * A handler that is triggered for "up" swipes.
- * @name $.fn.swipe#swipeUp
- * @event
- * @default null
- * @param {EventObject} event The original event object
- * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
- * @param {int} distance The distance the user swiped
- * @param {int} duration The duration of the swipe in milliseconds
- * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
- * @param {object} fingerData The coordinates of fingers in event
- */
- 
-/**
- * A handler that is triggered for "down" swipes.
- * @name $.fn.swipe#swipeDown
- * @event
- * @default null
- * @param {EventObject} event The original event object
- * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
- * @param {int} distance The distance the user swiped
- * @param {int} duration The duration of the swipe in milliseconds
- * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
- * @param {object} fingerData The coordinates of fingers in event
- */
- 
-/**
- * A handler triggered for every phase of the swipe. This handler is constantly fired for the duration of the pinch.
- * This is triggered regardless of swipe thresholds.
- * @name $.fn.swipe#swipeStatus
- * @event
- * @default null
- * @param {EventObject} event The original event object
- * @param {string} phase The phase of the swipe event. See {@link $.fn.swipe.phases}
- * @param {string} direction The direction the user swiped in. This is null if the user has yet to move. See {@link $.fn.swipe.directions}
- * @param {int} distance The distance the user swiped. This is 0 if the user has yet to move.
- * @param {int} duration The duration of the swipe in milliseconds
- * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
- * @param {object} fingerData The coordinates of fingers in event
- */
- 
-/**
- * A handler triggered for pinch in events.
- * @name $.fn.swipe#pinchIn
- * @event
- * @default null
- * @param {EventObject} event The original event object
- * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
- * @param {int} distance The distance the user pinched
- * @param {int} duration The duration of the swipe in milliseconds
- * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
- * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
- * @param {object} fingerData The coordinates of fingers in event
- */
-
-/**
- * A handler triggered for pinch out events.
- * @name $.fn.swipe#pinchOut
- * @event
- * @default null
- * @param {EventObject} event The original event object
- * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
- * @param {int} distance The distance the user pinched
- * @param {int} duration The duration of the swipe in milliseconds
- * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
- * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
- * @param {object} fingerData The coordinates of fingers in event
- */ 
-
-/**
- * A handler triggered for all pinch events. This handler is constantly fired for the duration of the pinch. This is triggered regardless of thresholds.
- * @name $.fn.swipe#pinchStatus
- * @event
- * @default null
- * @param {EventObject} event The original event object
- * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
- * @param {int} distance The distance the user pinched
- * @param {int} duration The duration of the swipe in milliseconds
- * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
- * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
- * @param {object} fingerData The coordinates of fingers in event
- */
-
-/**
- * A click handler triggered when a user simply clicks, rather than swipes on an element.
- * This is deprecated since version 1.6.2, any assignment to click will be assigned to the tap handler.
- * You cannot use <code>on</code> to bind to this event as the default jQ <code>click</code> event will be triggered.
- * Use the <code>tap</code> event instead.
- * @name $.fn.swipe#click
- * @event
- * @deprecated since version 1.6.2, please use {@link $.fn.swipe#tap} instead 
- * @default null
- * @param {EventObject} event The original event object
- * @param {DomObject} target The element clicked on.
- */
- 
- /**
- * A click / tap handler triggered when a user simply clicks or taps, rather than swipes on an element.
- * @name $.fn.swipe#tap
- * @event
- * @default null
- * @param {EventObject} event The original event object
- * @param {DomObject} target The element clicked on.
- */
- 
-/**
- * A double tap handler triggered when a user double clicks or taps on an element.
- * You can set the time delay for a double tap with the {@link $.fn.swipe.defaults#doubleTapThreshold} property. 
- * Note: If you set both <code>doubleTap</code> and <code>tap</code> handlers, the <code>tap</code> event will be delayed by the <code>doubleTapThreshold</code>
- * as the script needs to check if its a double tap.
- * @name $.fn.swipe#doubleTap
- * @see  $.fn.swipe.defaults#doubleTapThreshold
- * @event
- * @default null
- * @param {EventObject} event The original event object
- * @param {DomObject} target The element clicked on.
- */
- 
- /**
- * A long tap handler triggered once a tap has been release if the tap was longer than the longTapThreshold.
- * You can set the time delay for a long tap with the {@link $.fn.swipe.defaults#longTapThreshold} property. 
- * @name $.fn.swipe#longTap
- * @see  $.fn.swipe.defaults#longTapThreshold
- * @event
- * @default null
- * @param {EventObject} event The original event object
- * @param {DomObject} target The element clicked on.
- */
-
-  /**
- * A hold tap handler triggered as soon as the longTapThreshold is reached
- * You can set the time delay for a long tap with the {@link $.fn.swipe.defaults#longTapThreshold} property. 
- * @name $.fn.swipe#hold
- * @see  $.fn.swipe.defaults#longTapThreshold
- * @event
- * @default null
- * @param {EventObject} event The original event object
- * @param {DomObject} target The element clicked on.
- */
-
-}));
-
-
-
- - -
- -

Documentation generated by JsDoc Toolkit 2.4.0 on Wed Jun 04 2014 13:36:57 GMT+0100 (BST)

-
-
- - - diff --git a/api/js/jquery/TouchSwipe/jquery.touchSwipe.js b/api/js/jquery/TouchSwipe/jquery.touchSwipe.js deleted file mode 100644 index 587bbfb9e3..0000000000 --- a/api/js/jquery/TouchSwipe/jquery.touchSwipe.js +++ /dev/null @@ -1,2036 +0,0 @@ -/* -* @fileOverview TouchSwipe - jQuery Plugin -* @version 1.6.6 -* -* @author Matt Bryson http://www.github.com/mattbryson -* @see https://github.com/mattbryson/TouchSwipe-Jquery-Plugin -* @see http://labs.skinkers.com/touchSwipe/ -* @see http://plugins.jquery.com/project/touchSwipe -* -* Copyright (c) 2010 Matt Bryson -* Dual licensed under the MIT or GPL Version 2 licenses. -* -*/ - -/* -* -* Changelog -* $Date: 2010-12-12 (Wed, 12 Dec 2010) $ -* $version: 1.0.0 -* $version: 1.0.1 - removed multibyte comments -* -* $Date: 2011-21-02 (Mon, 21 Feb 2011) $ -* $version: 1.1.0 - added allowPageScroll property to allow swiping and scrolling of page -* - changed handler signatures so one handler can be used for multiple events -* $Date: 2011-23-02 (Wed, 23 Feb 2011) $ -* $version: 1.2.0 - added click handler. This is fired if the user simply clicks and does not swipe. The event object and click target are passed to handler. -* - If you use the http://code.google.com/p/jquery-ui-for-ipad-and-iphone/ plugin, you can also assign jQuery mouse events to children of a touchSwipe object. -* $version: 1.2.1 - removed console log! -* -* $version: 1.2.2 - Fixed bug where scope was not preserved in callback methods. -* -* $Date: 2011-28-04 (Thurs, 28 April 2011) $ -* $version: 1.2.4 - Changed licence terms to be MIT or GPL inline with jQuery. Added check for support of touch events to stop non compatible browsers erroring. -* -* $Date: 2011-27-09 (Tues, 27 September 2011) $ -* $version: 1.2.5 - Added support for testing swipes with mouse on desktop browser (thanks to https://github.com/joelhy) -* -* $Date: 2012-14-05 (Mon, 14 May 2012) $ -* $version: 1.2.6 - Added timeThreshold between start and end touch, so user can ignore slow swipes (thanks to Mark Chase). Default is null, all swipes are detected -* -* $Date: 2012-05-06 (Tues, 05 June 2012) $ -* $version: 1.2.7 - Changed time threshold to have null default for backwards compatibility. Added duration param passed back in events, and refactored how time is handled. -* -* $Date: 2012-05-06 (Tues, 05 June 2012) $ -* $version: 1.2.8 - Added the possibility to return a value like null or false in the trigger callback. In that way we can control when the touch start/move should take effect or not (simply by returning in some cases return null; or return false;) This effects the ontouchstart/ontouchmove event. -* -* $Date: 2012-06-06 (Wed, 06 June 2012) $ -* $version: 1.3.0 - Refactored whole plugin to allow for methods to be executed, as well as exposed defaults for user override. Added 'enable', 'disable', and 'destroy' methods -* -* $Date: 2012-05-06 (Fri, 05 June 2012) $ -* $version: 1.3.1 - Bug fixes - bind() with false as last argument is no longer supported in jQuery 1.6, also, if you just click, the duration is now returned correctly. -* -* $Date: 2012-29-07 (Sun, 29 July 2012) $ -* $version: 1.3.2 - Added fallbackToMouseEvents option to NOT capture mouse events on non touch devices. -* - Added "all" fingers value to the fingers property, so any combination of fingers triggers the swipe, allowing event handlers to check the finger count -* -* $Date: 2012-09-08 (Thurs, 9 Aug 2012) $ -* $version: 1.3.3 - Code tidy prep for minefied version -* -* $Date: 2012-04-10 (wed, 4 Oct 2012) $ -* $version: 1.4.0 - Added pinch support, pinchIn and pinchOut -* -* $Date: 2012-11-10 (Thurs, 11 Oct 2012) $ -* $version: 1.5.0 - Added excludedElements, a jquery selector that specifies child elements that do NOT trigger swipes. By default, this is one select that removes all form, input select, button and anchor elements. -* -* $Date: 2012-22-10 (Mon, 22 Oct 2012) $ -* $version: 1.5.1 - Fixed bug with jQuery 1.8 and trailing comma in excludedElements -* - Fixed bug with IE and eventPreventDefault() -* $Date: 2013-01-12 (Fri, 12 Jan 2013) $ -* $version: 1.6.0 - Fixed bugs with pinching, mainly when both pinch and swipe enabled, as well as adding time threshold for multifinger gestures, so releasing one finger beofre the other doesnt trigger as single finger gesture. -* - made the demo site all static local HTML pages so they can be run locally by a developer -* - added jsDoc comments and added documentation for the plugin -* - code tidy -* - added triggerOnTouchLeave property that will end the event when the user swipes off the element. -* $Date: 2013-03-23 (Sat, 23 Mar 2013) $ -* $version: 1.6.1 - Added support for ie8 touch events -* $version: 1.6.2 - Added support for events binding with on / off / bind in jQ for all callback names. -* - Deprecated the 'click' handler in favour of tap. -* - added cancelThreshold property -* - added option method to update init options at runtime -* $version 1.6.3 - added doubletap, longtap events and longTapThreshold, doubleTapThreshold property -* -* $Date: 2013-04-04 (Thurs, 04 April 2013) $ -* $version 1.6.4 - Fixed bug with cancelThreshold introduced in 1.6.3, where swipe status no longer fired start event, and stopped once swiping back. -* -* $Date: 2013-08-24 (Sat, 24 Aug 2013) $ -* $version 1.6.5 - Merged a few pull requests fixing various bugs, added AMD support. -* -* $Date: 2014-06-04 (Wed, 04 June 2014) $ -* $version 1.6.6 - Merge of pull requests. -* - IE10 touch support -* - Only prevent default event handling on valid swipe -* - Separate license/changelog comment -* - Detect if the swipe is valid at the end of the touch event. -* - Pass fingerdata to event handlers. -* - Add 'hold' gesture -* - Be more tolerant about the tap distance -* - Typos and minor fixes -*/ - -/** - * See (http://jquery.com/). - * @name $ - * @class - * See the jQuery Library (http://jquery.com/) for full details. This just - * documents the function and classes that are added to jQuery by this plug-in. - */ - -/** - * See (http://jquery.com/) - * @name fn - * @class - * See the jQuery Library (http://jquery.com/) for full details. This just - * documents the function and classes that are added to jQuery by this plug-in. - * @memberOf $ - */ - - - -(function (factory) { - if (typeof define === 'function' && define.amd && define.amd.jQuery) { - // AMD. Register as anonymous module. - define(['jquery'], factory); - } else { - // Browser globals. - factory(jQuery); - } -}(function ($) { - "use strict"; - - //Constants - var LEFT = "left", - RIGHT = "right", - UP = "up", - DOWN = "down", - IN = "in", - OUT = "out", - - NONE = "none", - AUTO = "auto", - - SWIPE = "swipe", - PINCH = "pinch", - TAP = "tap", - DOUBLE_TAP = "doubletap", - LONG_TAP = "longtap", - HOLD = "hold", - - HORIZONTAL = "horizontal", - VERTICAL = "vertical", - - ALL_FINGERS = "all", - - DOUBLE_TAP_THRESHOLD = 10, - - PHASE_START = "start", - PHASE_MOVE = "move", - PHASE_END = "end", - PHASE_CANCEL = "cancel", - - SUPPORTS_TOUCH = 'ontouchstart' in window, - - SUPPORTS_POINTER_IE10 = window.navigator.msPointerEnabled && !window.navigator.pointerEnabled, - - SUPPORTS_POINTER = window.navigator.pointerEnabled || window.navigator.msPointerEnabled, - - PLUGIN_NS = 'TouchSwipe'; - - - - /** - * The default configuration, and available options to configure touch swipe with. - * You can set the default values by updating any of the properties prior to instantiation. - * @name $.fn.swipe.defaults - * @namespace - * @property {int} [fingers=1] The number of fingers to detect in a swipe. Any swipes that do not meet this requirement will NOT trigger swipe handlers. - * @property {int} [threshold=75] The number of pixels that the user must move their finger by before it is considered a swipe. - * @property {int} [cancelThreshold=null] The number of pixels that the user must move their finger back from the original swipe direction to cancel the gesture. - * @property {int} [pinchThreshold=20] The number of pixels that the user must pinch their finger by before it is considered a pinch. - * @property {int} [maxTimeThreshold=null] Time, in milliseconds, between touchStart and touchEnd must NOT exceed in order to be considered a swipe. - * @property {int} [fingerReleaseThreshold=250] Time in milliseconds between releasing multiple fingers. If 2 fingers are down, and are released one after the other, if they are within this threshold, it counts as a simultaneous release. - * @property {int} [longTapThreshold=500] Time in milliseconds between tap and release for a long tap - * @property {int} [doubleTapThreshold=200] Time in milliseconds between 2 taps to count as a double tap - * @property {function} [swipe=null] A handler to catch all swipes. See {@link $.fn.swipe#event:swipe} - * @property {function} [swipeLeft=null] A handler that is triggered for "left" swipes. See {@link $.fn.swipe#event:swipeLeft} - * @property {function} [swipeRight=null] A handler that is triggered for "right" swipes. See {@link $.fn.swipe#event:swipeRight} - * @property {function} [swipeUp=null] A handler that is triggered for "up" swipes. See {@link $.fn.swipe#event:swipeUp} - * @property {function} [swipeDown=null] A handler that is triggered for "down" swipes. See {@link $.fn.swipe#event:swipeDown} - * @property {function} [swipeStatus=null] A handler triggered for every phase of the swipe. See {@link $.fn.swipe#event:swipeStatus} - * @property {function} [pinchIn=null] A handler triggered for pinch in events. See {@link $.fn.swipe#event:pinchIn} - * @property {function} [pinchOut=null] A handler triggered for pinch out events. See {@link $.fn.swipe#event:pinchOut} - * @property {function} [pinchStatus=null] A handler triggered for every phase of a pinch. See {@link $.fn.swipe#event:pinchStatus} - * @property {function} [tap=null] A handler triggered when a user just taps on the item, rather than swipes it. If they do not move, tap is triggered, if they do move, it is not. - * @property {function} [doubleTap=null] A handler triggered when a user double taps on the item. The delay between taps can be set with the doubleTapThreshold property. See {@link $.fn.swipe.defaults#doubleTapThreshold} - * @property {function} [longTap=null] A handler triggered when a user long taps on the item. The delay between start and end can be set with the longTapThreshold property. See {@link $.fn.swipe.defaults#longTapThreshold} - * @property (function) [hold=null] A handler triggered when a user reaches longTapThreshold on the item. See {@link $.fn.swipe.defaults#longTapThreshold} - * @property {boolean} [triggerOnTouchEnd=true] If true, the swipe events are triggered when the touch end event is received (user releases finger). If false, it will be triggered on reaching the threshold, and then cancel the touch event automatically. - * @property {boolean} [triggerOnTouchLeave=false] If true, then when the user leaves the swipe object, the swipe will end and trigger appropriate handlers. - * @property {string|undefined} [allowPageScroll='auto'] How the browser handles page scrolls when the user is swiping on a touchSwipe object. See {@link $.fn.swipe.pageScroll}.

- "auto" : all undefined swipes will cause the page to scroll in that direction.
- "none" : the page will not scroll when user swipes.
- "horizontal" : will force page to scroll on horizontal swipes.
- "vertical" : will force page to scroll on vertical swipes.
- * @property {boolean} [fallbackToMouseEvents=true] If true mouse events are used when run on a non touch device, false will stop swipes being triggered by mouse events on non tocuh devices. - * @property {string} [excludedElements="button, input, select, textarea, a, .noSwipe"] A jquery selector that specifies child elements that do NOT trigger swipes. By default this excludes all form, input, select, button, anchor and .noSwipe elements. - - */ - var defaults = { - fingers: 1, - threshold: 75, - cancelThreshold:null, - pinchThreshold:20, - maxTimeThreshold: null, - fingerReleaseThreshold:250, - longTapThreshold:500, - doubleTapThreshold:200, - swipe: null, - swipeLeft: null, - swipeRight: null, - swipeUp: null, - swipeDown: null, - swipeStatus: null, - pinchIn:null, - pinchOut:null, - pinchStatus:null, - click:null, //Deprecated since 1.6.2 - tap:null, - doubleTap:null, - longTap:null, - hold:null, - triggerOnTouchEnd: true, - triggerOnTouchLeave:false, - allowPageScroll: "auto", - fallbackToMouseEvents: true, - excludedElements:"label, button, input, select, textarea, a, .noSwipe" - }; - - - - /** - * Applies TouchSwipe behaviour to one or more jQuery objects. - * The TouchSwipe plugin can be instantiated via this method, or methods within - * TouchSwipe can be executed via this method as per jQuery plugin architecture. - * @see TouchSwipe - * @class - * @param {Mixed} method If the current DOMNode is a TouchSwipe object, and method is a TouchSwipe method, then - * the method is executed, and any following arguments are passed to the TouchSwipe method. - * If method is an object, then the TouchSwipe class is instantiated on the current DOMNode, passing the - * configuration properties defined in the object. See TouchSwipe - * - */ - $.fn.swipe = function (method) { - var $this = $(this), - plugin = $this.data(PLUGIN_NS); - - //Check if we are already instantiated and trying to execute a method - if (plugin && typeof method === 'string') { - if (plugin[method]) { - return plugin[method].apply(this, Array.prototype.slice.call(arguments, 1)); - } else { - $.error('Method ' + method + ' does not exist on jQuery.swipe'); - } - } - //Else not instantiated and trying to pass init object (or nothing) - else if (!plugin && (typeof method === 'object' || !method)) { - return init.apply(this, arguments); - } - - return $this; - }; - - //Expose our defaults so a user could override the plugin defaults - $.fn.swipe.defaults = defaults; - - /** - * The phases that a touch event goes through. The phase is passed to the event handlers. - * These properties are read only, attempting to change them will not alter the values passed to the event handlers. - * @namespace - * @readonly - * @property {string} PHASE_START Constant indicating the start phase of the touch event. Value is "start". - * @property {string} PHASE_MOVE Constant indicating the move phase of the touch event. Value is "move". - * @property {string} PHASE_END Constant indicating the end phase of the touch event. Value is "end". - * @property {string} PHASE_CANCEL Constant indicating the cancel phase of the touch event. Value is "cancel". - */ - $.fn.swipe.phases = { - PHASE_START: PHASE_START, - PHASE_MOVE: PHASE_MOVE, - PHASE_END: PHASE_END, - PHASE_CANCEL: PHASE_CANCEL - }; - - /** - * The direction constants that are passed to the event handlers. - * These properties are read only, attempting to change them will not alter the values passed to the event handlers. - * @namespace - * @readonly - * @property {string} LEFT Constant indicating the left direction. Value is "left". - * @property {string} RIGHT Constant indicating the right direction. Value is "right". - * @property {string} UP Constant indicating the up direction. Value is "up". - * @property {string} DOWN Constant indicating the down direction. Value is "cancel". - * @property {string} IN Constant indicating the in direction. Value is "in". - * @property {string} OUT Constant indicating the out direction. Value is "out". - */ - $.fn.swipe.directions = { - LEFT: LEFT, - RIGHT: RIGHT, - UP: UP, - DOWN: DOWN, - IN : IN, - OUT: OUT - }; - - /** - * The page scroll constants that can be used to set the value of allowPageScroll option - * These properties are read only - * @namespace - * @readonly - * @see $.fn.swipe.defaults#allowPageScroll - * @property {string} NONE Constant indicating no page scrolling is allowed. Value is "none". - * @property {string} HORIZONTAL Constant indicating horizontal page scrolling is allowed. Value is "horizontal". - * @property {string} VERTICAL Constant indicating vertical page scrolling is allowed. Value is "vertical". - * @property {string} AUTO Constant indicating either horizontal or vertical will be allowed, depending on the swipe handlers registered. Value is "auto". - */ - $.fn.swipe.pageScroll = { - NONE: NONE, - HORIZONTAL: HORIZONTAL, - VERTICAL: VERTICAL, - AUTO: AUTO - }; - - /** - * Constants representing the number of fingers used in a swipe. These are used to set both the value of fingers in the - * options object, as well as the value of the fingers event property. - * These properties are read only, attempting to change them will not alter the values passed to the event handlers. - * @namespace - * @readonly - * @see $.fn.swipe.defaults#fingers - * @property {string} ONE Constant indicating 1 finger is to be detected / was detected. Value is 1. - * @property {string} TWO Constant indicating 2 fingers are to be detected / were detected. Value is 1. - * @property {string} THREE Constant indicating 3 finger are to be detected / were detected. Value is 1. - * @property {string} ALL Constant indicating any combination of finger are to be detected. Value is "all". - */ - $.fn.swipe.fingers = { - ONE: 1, - TWO: 2, - THREE: 3, - ALL: ALL_FINGERS - }; - - /** - * Initialise the plugin for each DOM element matched - * This creates a new instance of the main TouchSwipe class for each DOM element, and then - * saves a reference to that instance in the elements data property. - * @internal - */ - function init(options) { - //Prep and extend the options - if (options && (options.allowPageScroll === undefined && (options.swipe !== undefined || options.swipeStatus !== undefined))) { - options.allowPageScroll = NONE; - } - - //Check for deprecated options - //Ensure that any old click handlers are assigned to the new tap, unless we have a tap - if(options.click!==undefined && options.tap===undefined) { - options.tap = options.click; - } - - if (!options) { - options = {}; - } - - //pass empty object so we dont modify the defaults - options = $.extend({}, $.fn.swipe.defaults, options); - - //For each element instantiate the plugin - return this.each(function () { - var $this = $(this); - - //Check we havent already initialised the plugin - var plugin = $this.data(PLUGIN_NS); - - if (!plugin) { - plugin = new TouchSwipe(this, options); - $this.data(PLUGIN_NS, plugin); - } - }); - } - - /** - * Main TouchSwipe Plugin Class. - * Do not use this to construct your TouchSwipe object, use the jQuery plugin method $.fn.swipe(); {@link $.fn.swipe} - * @private - * @name TouchSwipe - * @param {DOMNode} element The HTML DOM object to apply to plugin to - * @param {Object} options The options to configure the plugin with. @link {$.fn.swipe.defaults} - * @see $.fh.swipe.defaults - * @see $.fh.swipe - * @class - */ - function TouchSwipe(element, options) { - var useTouchEvents = (SUPPORTS_TOUCH || SUPPORTS_POINTER || !options.fallbackToMouseEvents), - START_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerDown' : 'pointerdown') : 'touchstart') : 'mousedown', - MOVE_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerMove' : 'pointermove') : 'touchmove') : 'mousemove', - END_EV = useTouchEvents ? (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerUp' : 'pointerup') : 'touchend') : 'mouseup', - LEAVE_EV = useTouchEvents ? null : 'mouseleave', //we manually detect leave on touch devices, so null event here - CANCEL_EV = (SUPPORTS_POINTER ? (SUPPORTS_POINTER_IE10 ? 'MSPointerCancel' : 'pointercancel') : 'touchcancel'); - - - - //touch properties - var distance = 0, - direction = null, - duration = 0, - startTouchesDistance = 0, - endTouchesDistance = 0, - pinchZoom = 1, - pinchDistance = 0, - pinchDirection = 0, - maximumsMap=null; - - - - //jQuery wrapped element for this instance - var $element = $(element); - - //Current phase of th touch cycle - var phase = "start"; - - // the current number of fingers being used. - var fingerCount = 0; - - //track mouse points / delta - var fingerData=null; - - //track times - var startTime = 0, - endTime = 0, - previousTouchEndTime=0, - previousTouchFingerCount=0, - doubleTapStartTime=0; - - //Timeouts - var singleTapTimeout=null, - holdTimeout=null; - - // Add gestures to all swipable areas if supported - try { - $element.bind(START_EV, touchStart); - $element.bind(CANCEL_EV, touchCancel); - } - catch (e) { - $.error('events not supported ' + START_EV + ',' + CANCEL_EV + ' on jQuery.swipe'); - } - - // - //Public methods - // - - /** - * re-enables the swipe plugin with the previous configuration - * @function - * @name $.fn.swipe#enable - * @return {DOMNode} The Dom element that was registered with TouchSwipe - * @example $("#element").swipe("enable"); - */ - this.enable = function () { - $element.bind(START_EV, touchStart); - $element.bind(CANCEL_EV, touchCancel); - return $element; - }; - - /** - * disables the swipe plugin - * @function - * @name $.fn.swipe#disable - * @return {DOMNode} The Dom element that is now registered with TouchSwipe - * @example $("#element").swipe("disable"); - */ - this.disable = function () { - removeListeners(); - return $element; - }; - - /** - * Destroy the swipe plugin completely. To use any swipe methods, you must re initialise the plugin. - * @function - * @name $.fn.swipe#destroy - * @return {DOMNode} The Dom element that was registered with TouchSwipe - * @example $("#element").swipe("destroy"); - */ - this.destroy = function () { - removeListeners(); - $element.data(PLUGIN_NS, null); - return $element; - }; - - - /** - * Allows run time updating of the swipe configuration options. - * @function - * @name $.fn.swipe#option - * @param {String} property The option property to get or set - * @param {Object} [value] The value to set the property to - * @return {Object} If only a property name is passed, then that property value is returned. - * @example $("#element").swipe("option", "threshold"); // return the threshold - * @example $("#element").swipe("option", "threshold", 100); // set the threshold after init - * @see $.fn.swipe.defaults - * - */ - this.option = function (property, value) { - if(options[property]!==undefined) { - if(value===undefined) { - return options[property]; - } else { - options[property] = value; - } - } else { - $.error('Option ' + property + ' does not exist on jQuery.swipe.options'); - } - - return null; - } - - // - // Private methods - // - - // - // EVENTS - // - /** - * Event handler for a touch start event. - * Stops the default click event from triggering and stores where we touched - * @inner - * @param {object} jqEvent The normalised jQuery event object. - */ - function touchStart(jqEvent) { - //If we already in a touch event (a finger already in use) then ignore subsequent ones.. - if( getTouchInProgress() ) - return; - - //Check if this element matches any in the excluded elements selectors, or its parent is excluded, if so, DON'T swipe - if( $(jqEvent.target).closest( options.excludedElements, $element ).length>0 ) - return; - - //As we use Jquery bind for events, we need to target the original event object - //If these events are being programmatically triggered, we don't have an original event object, so use the Jq one. - var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent; - - var ret, - evt = SUPPORTS_TOUCH ? event.touches[0] : event; - - phase = PHASE_START; - - //If we support touches, get the finger count - if (SUPPORTS_TOUCH) { - // get the total number of fingers touching the screen - fingerCount = event.touches.length; - } - //Else this is the desktop, so stop the browser from dragging the image - else { - jqEvent.preventDefault(); //call this on jq event so we are cross browser - } - - //clear vars.. - distance = 0; - direction = null; - pinchDirection=null; - duration = 0; - startTouchesDistance=0; - endTouchesDistance=0; - pinchZoom = 1; - pinchDistance = 0; - fingerData=createAllFingerData(); - maximumsMap=createMaximumsData(); - cancelMultiFingerRelease(); - - - // check the number of fingers is what we are looking for, or we are capturing pinches - if (!SUPPORTS_TOUCH || (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || hasPinches()) { - // get the coordinates of the touch - createFingerData( 0, evt ); - startTime = getTimeStamp(); - - if(fingerCount==2) { - //Keep track of the initial pinch distance, so we can calculate the diff later - //Store second finger data as start - createFingerData( 1, event.touches[1] ); - startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start); - } - - if (options.swipeStatus || options.pinchStatus) { - ret = triggerHandler(event, phase); - } - } - else { - //A touch with more or less than the fingers we are looking for, so cancel - ret = false; - } - - //If we have a return value from the users handler, then return and cancel - if (ret === false) { - phase = PHASE_CANCEL; - triggerHandler(event, phase); - return ret; - } - else { - if (options.hold) { - holdTimeout = setTimeout($.proxy(function() { - //Trigger the event - $element.trigger('hold', [event.target]); - //Fire the callback - if(options.hold) { - ret = options.hold.call($element, event, event.target); - } - }, this), options.longTapThreshold ); - } - - setTouchInProgress(true); - } - - return null; - }; - - - - /** - * Event handler for a touch move event. - * If we change fingers during move, then cancel the event - * @inner - * @param {object} jqEvent The normalised jQuery event object. - */ - function touchMove(jqEvent) { - - //As we use Jquery bind for events, we need to target the original event object - //If these events are being programmatically triggered, we don't have an original event object, so use the Jq one. - var event = jqEvent.originalEvent ? jqEvent.originalEvent : jqEvent; - - //If we are ending, cancelling, or within the threshold of 2 fingers being released, don't track anything.. - if (phase === PHASE_END || phase === PHASE_CANCEL || inMultiFingerRelease()) - return; - - var ret, - evt = SUPPORTS_TOUCH ? event.touches[0] : event; - - - //Update the finger data - var currentFinger = updateFingerData(evt); - endTime = getTimeStamp(); - - if (SUPPORTS_TOUCH) { - fingerCount = event.touches.length; - } - - if (options.hold) - clearTimeout(holdTimeout); - - phase = PHASE_MOVE; - - //If we have 2 fingers get Touches distance as well - if(fingerCount==2) { - - //Keep track of the initial pinch distance, so we can calculate the diff later - //We do this here as well as the start event, in case they start with 1 finger, and the press 2 fingers - if(startTouchesDistance==0) { - //Create second finger if this is the first time... - createFingerData( 1, event.touches[1] ); - - startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start); - } else { - //Else just update the second finger - updateFingerData(event.touches[1]); - - endTouchesDistance = calculateTouchesDistance(fingerData[0].end, fingerData[1].end); - pinchDirection = calculatePinchDirection(fingerData[0].end, fingerData[1].end); - } - - - pinchZoom = calculatePinchZoom(startTouchesDistance, endTouchesDistance); - pinchDistance = Math.abs(startTouchesDistance - endTouchesDistance); - } - - - if ( (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH || hasPinches() ) { - - direction = calculateDirection(currentFinger.start, currentFinger.end); - - //Check if we need to prevent default event (page scroll / pinch zoom) or not - validateDefaultEvent(jqEvent, direction); - - //Distance and duration are all off the main finger - distance = calculateDistance(currentFinger.start, currentFinger.end); - duration = calculateDuration(); - - //Cache the maximum distance we made in this direction - setMaxDistance(direction, distance); - - - if (options.swipeStatus || options.pinchStatus) { - ret = triggerHandler(event, phase); - } - - - //If we trigger end events when threshold are met, or trigger events when touch leaves element - if(!options.triggerOnTouchEnd || options.triggerOnTouchLeave) { - - var inBounds = true; - - //If checking if we leave the element, run the bounds check (we can use touchleave as its not supported on webkit) - if(options.triggerOnTouchLeave) { - var bounds = getbounds( this ); - inBounds = isInBounds( currentFinger.end, bounds ); - } - - //Trigger end handles as we swipe if thresholds met or if we have left the element if the user has asked to check these.. - if(!options.triggerOnTouchEnd && inBounds) { - phase = getNextPhase( PHASE_MOVE ); - } - //We end if out of bounds here, so set current phase to END, and check if its modified - else if(options.triggerOnTouchLeave && !inBounds ) { - phase = getNextPhase( PHASE_END ); - } - - if(phase==PHASE_CANCEL || phase==PHASE_END) { - triggerHandler(event, phase); - } - } - } - else { - phase = PHASE_CANCEL; - triggerHandler(event, phase); - } - - if (ret === false) { - phase = PHASE_CANCEL; - triggerHandler(event, phase); - } - } - - - - /** - * Event handler for a touch end event. - * Calculate the direction and trigger events - * @inner - * @param {object} jqEvent The normalised jQuery event object. - */ - function touchEnd(jqEvent) { - //As we use Jquery bind for events, we need to target the original event object - var event = jqEvent.originalEvent; - - - //If we are still in a touch with another finger return - //This allows us to wait a fraction and see if the other finger comes up, if it does within the threshold, then we treat it as a multi release, not a single release. - if (SUPPORTS_TOUCH) { - if(event.touches.length>0) { - startMultiFingerRelease(); - return true; - } - } - - //If a previous finger has been released, check how long ago, if within the threshold, then assume it was a multifinger release. - //This is used to allow 2 fingers to release fractionally after each other, whilst maintainig the event as containg 2 fingers, not 1 - if(inMultiFingerRelease()) { - fingerCount=previousTouchFingerCount; - } - - //Set end of swipe - endTime = getTimeStamp(); - - //Get duration incase move was never fired - duration = calculateDuration(); - - //If we trigger handlers at end of swipe OR, we trigger during, but they didnt trigger and we are still in the move phase - if(didSwipeBackToCancel() || !validateSwipeDistance()) { - phase = PHASE_CANCEL; - triggerHandler(event, phase); - } else if (options.triggerOnTouchEnd || (options.triggerOnTouchEnd == false && phase === PHASE_MOVE)) { - //call this on jq event so we are cross browser - jqEvent.preventDefault(); - phase = PHASE_END; - triggerHandler(event, phase); - } - //Special cases - A tap should always fire on touch end regardless, - //So here we manually trigger the tap end handler by itself - //We dont run trigger handler as it will re-trigger events that may have fired already - else if (!options.triggerOnTouchEnd && hasTap()) { - //Trigger the pinch events... - phase = PHASE_END; - triggerHandlerForGesture(event, phase, TAP); - } - else if (phase === PHASE_MOVE) { - phase = PHASE_CANCEL; - triggerHandler(event, phase); - } - - setTouchInProgress(false); - - return null; - } - - - - /** - * Event handler for a touch cancel event. - * Clears current vars - * @inner - */ - function touchCancel() { - // reset the variables back to default values - fingerCount = 0; - endTime = 0; - startTime = 0; - startTouchesDistance=0; - endTouchesDistance=0; - pinchZoom=1; - - //If we were in progress of tracking a possible multi touch end, then re set it. - cancelMultiFingerRelease(); - - setTouchInProgress(false); - } - - - /** - * Event handler for a touch leave event. - * This is only triggered on desktops, in touch we work this out manually - * as the touchleave event is not supported in webkit - * @inner - */ - function touchLeave(jqEvent) { - var event = jqEvent.originalEvent; - - //If we have the trigger on leave property set.... - if(options.triggerOnTouchLeave) { - phase = getNextPhase( PHASE_END ); - triggerHandler(event, phase); - } - } - - /** - * Removes all listeners that were associated with the plugin - * @inner - */ - function removeListeners() { - $element.unbind(START_EV, touchStart); - $element.unbind(CANCEL_EV, touchCancel); - $element.unbind(MOVE_EV, touchMove); - $element.unbind(END_EV, touchEnd); - - //we only have leave events on desktop, we manually calculate leave on touch as its not supported in webkit - if(LEAVE_EV) { - $element.unbind(LEAVE_EV, touchLeave); - } - - setTouchInProgress(false); - } - - - /** - * Checks if the time and distance thresholds have been met, and if so then the appropriate handlers are fired. - */ - function getNextPhase(currentPhase) { - - var nextPhase = currentPhase; - - // Ensure we have valid swipe (under time and over distance and check if we are out of bound...) - var validTime = validateSwipeTime(); - var validDistance = validateSwipeDistance(); - var didCancel = didSwipeBackToCancel(); - - //If we have exceeded our time, then cancel - if(!validTime || didCancel) { - nextPhase = PHASE_CANCEL; - } - //Else if we are moving, and have reached distance then end - else if (validDistance && currentPhase == PHASE_MOVE && (!options.triggerOnTouchEnd || options.triggerOnTouchLeave) ) { - nextPhase = PHASE_END; - } - //Else if we have ended by leaving and didn't reach distance, then cancel - else if (!validDistance && currentPhase==PHASE_END && options.triggerOnTouchLeave) { - nextPhase = PHASE_CANCEL; - } - - return nextPhase; - } - - - /** - * Trigger the relevant event handler - * The handlers are passed the original event, the element that was swiped, and in the case of the catch all handler, the direction that was swiped, "left", "right", "up", or "down" - * @param {object} event the original event object - * @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases} - * @inner - */ - function triggerHandler(event, phase) { - - var ret = undefined; - - // SWIPE GESTURES - if(didSwipe() || hasSwipes()) { //hasSwipes as status needs to fire even if swipe is invalid - //Trigger the swipe events... - ret = triggerHandlerForGesture(event, phase, SWIPE); - } - - // PINCH GESTURES (if the above didn't cancel) - else if((didPinch() || hasPinches()) && ret!==false) { - //Trigger the pinch events... - ret = triggerHandlerForGesture(event, phase, PINCH); - } - - // CLICK / TAP (if the above didn't cancel) - if(didDoubleTap() && ret!==false) { - //Trigger the tap events... - ret = triggerHandlerForGesture(event, phase, DOUBLE_TAP); - } - - // CLICK / TAP (if the above didn't cancel) - else if(didLongTap() && ret!==false) { - //Trigger the tap events... - ret = triggerHandlerForGesture(event, phase, LONG_TAP); - } - - // CLICK / TAP (if the above didn't cancel) - else if(didTap() && ret!==false) { - //Trigger the tap event.. - ret = triggerHandlerForGesture(event, phase, TAP); - } - - - - // If we are cancelling the gesture, then manually trigger the reset handler - if (phase === PHASE_CANCEL) { - touchCancel(event); - } - - // If we are ending the gesture, then manually trigger the reset handler IF all fingers are off - if(phase === PHASE_END) { - //If we support touch, then check that all fingers are off before we cancel - if (SUPPORTS_TOUCH) { - if(event.touches.length==0) { - touchCancel(event); - } - } - else { - touchCancel(event); - } - } - - return ret; - } - - - - /** - * Trigger the relevant event handler - * The handlers are passed the original event, the element that was swiped, and in the case of the catch all handler, the direction that was swiped, "left", "right", "up", or "down" - * @param {object} event the original event object - * @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases} - * @param {string} gesture the gesture to trigger a handler for : PINCH or SWIPE {@link $.fn.swipe.gestures} - * @return Boolean False, to indicate that the event should stop propagation, or void. - * @inner - */ - function triggerHandlerForGesture(event, phase, gesture) { - - var ret=undefined; - - //SWIPES.... - if(gesture==SWIPE) { - //Trigger status every time.. - - //Trigger the event... - $element.trigger('swipeStatus', [phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData]); - - //Fire the callback - if (options.swipeStatus) { - ret = options.swipeStatus.call($element, event, phase, direction || null, distance || 0, duration || 0, fingerCount, fingerData); - //If the status cancels, then dont run the subsequent event handlers.. - if(ret===false) return false; - } - - - - - if (phase == PHASE_END && validateSwipe()) { - //Fire the catch all event - $element.trigger('swipe', [direction, distance, duration, fingerCount, fingerData]); - - //Fire catch all callback - if (options.swipe) { - ret = options.swipe.call($element, event, direction, distance, duration, fingerCount, fingerData); - //If the status cancels, then dont run the subsequent event handlers.. - if(ret===false) return false; - } - - //trigger direction specific event handlers - switch (direction) { - case LEFT: - //Trigger the event - $element.trigger('swipeLeft', [direction, distance, duration, fingerCount, fingerData]); - - //Fire the callback - if (options.swipeLeft) { - ret = options.swipeLeft.call($element, event, direction, distance, duration, fingerCount, fingerData); - } - break; - - case RIGHT: - //Trigger the event - $element.trigger('swipeRight', [direction, distance, duration, fingerCount, fingerData]); - - //Fire the callback - if (options.swipeRight) { - ret = options.swipeRight.call($element, event, direction, distance, duration, fingerCount, fingerData); - } - break; - - case UP: - //Trigger the event - $element.trigger('swipeUp', [direction, distance, duration, fingerCount, fingerData]); - - //Fire the callback - if (options.swipeUp) { - ret = options.swipeUp.call($element, event, direction, distance, duration, fingerCount, fingerData); - } - break; - - case DOWN: - //Trigger the event - $element.trigger('swipeDown', [direction, distance, duration, fingerCount, fingerData]); - - //Fire the callback - if (options.swipeDown) { - ret = options.swipeDown.call($element, event, direction, distance, duration, fingerCount, fingerData); - } - break; - } - } - } - - - //PINCHES.... - if(gesture==PINCH) { - //Trigger the event - $element.trigger('pinchStatus', [phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]); - - //Fire the callback - if (options.pinchStatus) { - ret = options.pinchStatus.call($element, event, phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData); - //If the status cancels, then dont run the subsequent event handlers.. - if(ret===false) return false; - } - - if(phase==PHASE_END && validatePinch()) { - - switch (pinchDirection) { - case IN: - //Trigger the event - $element.trigger('pinchIn', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]); - - //Fire the callback - if (options.pinchIn) { - ret = options.pinchIn.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData); - } - break; - - case OUT: - //Trigger the event - $element.trigger('pinchOut', [pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData]); - - //Fire the callback - if (options.pinchOut) { - ret = options.pinchOut.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom, fingerData); - } - break; - } - } - } - - - - - - if(gesture==TAP) { - if(phase === PHASE_CANCEL || phase === PHASE_END) { - - - //Cancel any existing double tap - clearTimeout(singleTapTimeout); - //Cancel hold timeout - clearTimeout(holdTimeout); - - //If we are also looking for doubelTaps, wait incase this is one... - if(hasDoubleTap() && !inDoubleTap()) { - //Cache the time of this tap - doubleTapStartTime = getTimeStamp(); - - //Now wait for the double tap timeout, and trigger this single tap - //if its not cancelled by a double tap - singleTapTimeout = setTimeout($.proxy(function() { - doubleTapStartTime=null; - //Trigger the event - $element.trigger('tap', [event.target]); - - - //Fire the callback - if(options.tap) { - ret = options.tap.call($element, event, event.target); - } - }, this), options.doubleTapThreshold ); - - } else { - doubleTapStartTime=null; - - //Trigger the event - $element.trigger('tap', [event.target]); - - - //Fire the callback - if(options.tap) { - ret = options.tap.call($element, event, event.target); - } - } - } - } - - else if (gesture==DOUBLE_TAP) { - if(phase === PHASE_CANCEL || phase === PHASE_END) { - //Cancel any pending singletap - clearTimeout(singleTapTimeout); - doubleTapStartTime=null; - - //Trigger the event - $element.trigger('doubletap', [event.target]); - - //Fire the callback - if(options.doubleTap) { - ret = options.doubleTap.call($element, event, event.target); - } - } - } - - else if (gesture==LONG_TAP) { - if(phase === PHASE_CANCEL || phase === PHASE_END) { - //Cancel any pending singletap (shouldnt be one) - clearTimeout(singleTapTimeout); - doubleTapStartTime=null; - - //Trigger the event - $element.trigger('longtap', [event.target]); - - //Fire the callback - if(options.longTap) { - ret = options.longTap.call($element, event, event.target); - } - } - } - - return ret; - } - - - - - // - // GESTURE VALIDATION - // - - /** - * Checks the user has swipe far enough - * @return Boolean if threshold has been set, return true if the threshold was met, else false. - * If no threshold was set, then we return true. - * @inner - */ - function validateSwipeDistance() { - var valid = true; - //If we made it past the min swipe distance.. - if (options.threshold !== null) { - valid = distance >= options.threshold; - } - - return valid; - } - - /** - * Checks the user has swiped back to cancel. - * @return Boolean if cancelThreshold has been set, return true if the cancelThreshold was met, else false. - * If no cancelThreshold was set, then we return true. - * @inner - */ - function didSwipeBackToCancel() { - var cancelled = false; - if(options.cancelThreshold !== null && direction !==null) { - cancelled = (getMaxDistance( direction ) - distance) >= options.cancelThreshold; - } - - return cancelled; - } - - /** - * Checks the user has pinched far enough - * @return Boolean if pinchThreshold has been set, return true if the threshold was met, else false. - * If no threshold was set, then we return true. - * @inner - */ - function validatePinchDistance() { - if (options.pinchThreshold !== null) { - return pinchDistance >= options.pinchThreshold; - } - return true; - } - - /** - * Checks that the time taken to swipe meets the minimum / maximum requirements - * @return Boolean - * @inner - */ - function validateSwipeTime() { - var result; - //If no time set, then return true - - if (options.maxTimeThreshold) { - if (duration >= options.maxTimeThreshold) { - result = false; - } else { - result = true; - } - } - else { - result = true; - } - - return result; - } - - - /** - * Checks direction of the swipe and the value allowPageScroll to see if we should allow or prevent the default behaviour from occurring. - * This will essentially allow page scrolling or not when the user is swiping on a touchSwipe object. - * @param {object} jqEvent The normalised jQuery representation of the event object. - * @param {string} direction The direction of the event. See {@link $.fn.swipe.directions} - * @see $.fn.swipe.directions - * @inner - */ - function validateDefaultEvent(jqEvent, direction) { - if (options.allowPageScroll === NONE || hasPinches()) { - jqEvent.preventDefault(); - } else { - var auto = options.allowPageScroll === AUTO; - - switch (direction) { - case LEFT: - if ((options.swipeLeft && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) { - jqEvent.preventDefault(); - } - break; - - case RIGHT: - if ((options.swipeRight && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) { - jqEvent.preventDefault(); - } - break; - - case UP: - if ((options.swipeUp && auto) || (!auto && options.allowPageScroll != VERTICAL)) { - jqEvent.preventDefault(); - } - break; - - case DOWN: - if ((options.swipeDown && auto) || (!auto && options.allowPageScroll != VERTICAL)) { - jqEvent.preventDefault(); - } - break; - } - } - - } - - - // PINCHES - /** - * Returns true of the current pinch meets the thresholds - * @return Boolean - * @inner - */ - function validatePinch() { - var hasCorrectFingerCount = validateFingers(); - var hasEndPoint = validateEndPoint(); - var hasCorrectDistance = validatePinchDistance(); - return hasCorrectFingerCount && hasEndPoint && hasCorrectDistance; - - } - - /** - * Returns true if any Pinch events have been registered - * @return Boolean - * @inner - */ - function hasPinches() { - //Enure we dont return 0 or null for false values - return !!(options.pinchStatus || options.pinchIn || options.pinchOut); - } - - /** - * Returns true if we are detecting pinches, and have one - * @return Boolean - * @inner - */ - function didPinch() { - //Enure we dont return 0 or null for false values - return !!(validatePinch() && hasPinches()); - } - - - - - // SWIPES - /** - * Returns true if the current swipe meets the thresholds - * @return Boolean - * @inner - */ - function validateSwipe() { - //Check validity of swipe - var hasValidTime = validateSwipeTime(); - var hasValidDistance = validateSwipeDistance(); - var hasCorrectFingerCount = validateFingers(); - var hasEndPoint = validateEndPoint(); - var didCancel = didSwipeBackToCancel(); - - // if the user swiped more than the minimum length, perform the appropriate action - // hasValidDistance is null when no distance is set - var valid = !didCancel && hasEndPoint && hasCorrectFingerCount && hasValidDistance && hasValidTime; - - return valid; - } - - /** - * Returns true if any Swipe events have been registered - * @return Boolean - * @inner - */ - function hasSwipes() { - //Enure we dont return 0 or null for false values - return !!(options.swipe || options.swipeStatus || options.swipeLeft || options.swipeRight || options.swipeUp || options.swipeDown); - } - - - /** - * Returns true if we are detecting swipes and have one - * @return Boolean - * @inner - */ - function didSwipe() { - //Enure we dont return 0 or null for false values - return !!(validateSwipe() && hasSwipes()); - } - - /** - * Returns true if we have matched the number of fingers we are looking for - * @return Boolean - * @inner - */ - function validateFingers() { - //The number of fingers we want were matched, or on desktop we ignore - return ((fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH); - } - - /** - * Returns true if we have an end point for the swipe - * @return Boolean - * @inner - */ - function validateEndPoint() { - //We have an end value for the finger - return fingerData[0].end.x !== 0; - } - - // TAP / CLICK - /** - * Returns true if a click / tap events have been registered - * @return Boolean - * @inner - */ - function hasTap() { - //Enure we dont return 0 or null for false values - return !!(options.tap) ; - } - - /** - * Returns true if a double tap events have been registered - * @return Boolean - * @inner - */ - function hasDoubleTap() { - //Enure we dont return 0 or null for false values - return !!(options.doubleTap) ; - } - - /** - * Returns true if any long tap events have been registered - * @return Boolean - * @inner - */ - function hasLongTap() { - //Enure we dont return 0 or null for false values - return !!(options.longTap) ; - } - - /** - * Returns true if we could be in the process of a double tap (one tap has occurred, we are listening for double taps, and the threshold hasn't past. - * @return Boolean - * @inner - */ - function validateDoubleTap() { - if(doubleTapStartTime==null){ - return false; - } - var now = getTimeStamp(); - return (hasDoubleTap() && ((now-doubleTapStartTime) <= options.doubleTapThreshold)); - } - - /** - * Returns true if we could be in the process of a double tap (one tap has occurred, we are listening for double taps, and the threshold hasn't past. - * @return Boolean - * @inner - */ - function inDoubleTap() { - return validateDoubleTap(); - } - - - /** - * Returns true if we have a valid tap - * @return Boolean - * @inner - */ - function validateTap() { - return ((fingerCount === 1 || !SUPPORTS_TOUCH) && (isNaN(distance) || distance < options.threshold)); - } - - /** - * Returns true if we have a valid long tap - * @return Boolean - * @inner - */ - function validateLongTap() { - //slight threshold on moving finger - return ((duration > options.longTapThreshold) && (distance < DOUBLE_TAP_THRESHOLD)); - } - - /** - * Returns true if we are detecting taps and have one - * @return Boolean - * @inner - */ - function didTap() { - //Enure we dont return 0 or null for false values - return !!(validateTap() && hasTap()); - } - - - /** - * Returns true if we are detecting double taps and have one - * @return Boolean - * @inner - */ - function didDoubleTap() { - //Enure we dont return 0 or null for false values - return !!(validateDoubleTap() && hasDoubleTap()); - } - - /** - * Returns true if we are detecting long taps and have one - * @return Boolean - * @inner - */ - function didLongTap() { - //Enure we dont return 0 or null for false values - return !!(validateLongTap() && hasLongTap()); - } - - - - - // MULTI FINGER TOUCH - /** - * Starts tracking the time between 2 finger releases, and keeps track of how many fingers we initially had up - * @inner - */ - function startMultiFingerRelease() { - previousTouchEndTime = getTimeStamp(); - previousTouchFingerCount = event.touches.length+1; - } - - /** - * Cancels the tracking of time between 2 finger releases, and resets counters - * @inner - */ - function cancelMultiFingerRelease() { - previousTouchEndTime = 0; - previousTouchFingerCount = 0; - } - - /** - * Checks if we are in the threshold between 2 fingers being released - * @return Boolean - * @inner - */ - function inMultiFingerRelease() { - - var withinThreshold = false; - - if(previousTouchEndTime) { - var diff = getTimeStamp() - previousTouchEndTime - if( diff<=options.fingerReleaseThreshold ) { - withinThreshold = true; - } - } - - return withinThreshold; - } - - - /** - * gets a data flag to indicate that a touch is in progress - * @return Boolean - * @inner - */ - function getTouchInProgress() { - //strict equality to ensure only true and false are returned - return !!($element.data(PLUGIN_NS+'_intouch') === true); - } - - /** - * Sets a data flag to indicate that a touch is in progress - * @param {boolean} val The value to set the property to - * @inner - */ - function setTouchInProgress(val) { - - //Add or remove event listeners depending on touch status - if(val===true) { - $element.bind(MOVE_EV, touchMove); - $element.bind(END_EV, touchEnd); - - //we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit - if(LEAVE_EV) { - $element.bind(LEAVE_EV, touchLeave); - } - } else { - $element.unbind(MOVE_EV, touchMove, false); - $element.unbind(END_EV, touchEnd, false); - - //we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit - if(LEAVE_EV) { - $element.unbind(LEAVE_EV, touchLeave, false); - } - } - - - //strict equality to ensure only true and false can update the value - $element.data(PLUGIN_NS+'_intouch', val === true); - } - - - /** - * Creates the finger data for the touch/finger in the event object. - * @param {int} index The index in the array to store the finger data (usually the order the fingers were pressed) - * @param {object} evt The event object containing finger data - * @return finger data object - * @inner - */ - function createFingerData( index, evt ) { - var id = evt.identifier!==undefined ? evt.identifier : 0; - - fingerData[index].identifier = id; - fingerData[index].start.x = fingerData[index].end.x = evt.pageX||evt.clientX; - fingerData[index].start.y = fingerData[index].end.y = evt.pageY||evt.clientY; - - return fingerData[index]; - } - - /** - * Updates the finger data for a particular event object - * @param {object} evt The event object containing the touch/finger data to upadte - * @return a finger data object. - * @inner - */ - function updateFingerData(evt) { - - var id = evt.identifier!==undefined ? evt.identifier : 0; - var f = getFingerData( id ); - - f.end.x = evt.pageX||evt.clientX; - f.end.y = evt.pageY||evt.clientY; - - return f; - } - - /** - * Returns a finger data object by its event ID. - * Each touch event has an identifier property, which is used - * to track repeat touches - * @param {int} id The unique id of the finger in the sequence of touch events. - * @return a finger data object. - * @inner - */ - function getFingerData( id ) { - for(var i=0; i= 0)) { - return LEFT; - } else if ((angle <= 360) && (angle >= 315)) { - return LEFT; - } else if ((angle >= 135) && (angle <= 225)) { - return RIGHT; - } else if ((angle > 45) && (angle < 135)) { - return DOWN; - } else { - return UP; - } - } - - - /** - * Returns a MS time stamp of the current time - * @return int - * @inner - */ - function getTimeStamp() { - var now = new Date(); - return now.getTime(); - } - - - - /** - * Returns a bounds object with left, right, top and bottom properties for the element specified. - * @param {DomNode} The DOM node to get the bounds for. - */ - function getbounds( el ) { - el = $(el); - var offset = el.offset(); - - var bounds = { - left:offset.left, - right:offset.left+el.outerWidth(), - top:offset.top, - bottom:offset.top+el.outerHeight() - } - - return bounds; - } - - - /** - * Checks if the point object is in the bounds object. - * @param {object} point A point object. - * @param {int} point.x The x value of the point. - * @param {int} point.y The x value of the point. - * @param {object} bounds The bounds object to test - * @param {int} bounds.left The leftmost value - * @param {int} bounds.right The righttmost value - * @param {int} bounds.top The topmost value - * @param {int} bounds.bottom The bottommost value - */ - function isInBounds(point, bounds) { - return (point.x > bounds.left && point.x < bounds.right && point.y > bounds.top && point.y < bounds.bottom); - }; - - - } - - - - -/** - * A catch all handler that is triggered for all swipe directions. - * @name $.fn.swipe#swipe - * @event - * @default null - * @param {EventObject} event The original event object - * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} - * @param {int} distance The distance the user swiped - * @param {int} duration The duration of the swipe in milliseconds - * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} - * @param {object} fingerData The coordinates of fingers in event - */ - - - - -/** - * A handler that is triggered for "left" swipes. - * @name $.fn.swipe#swipeLeft - * @event - * @default null - * @param {EventObject} event The original event object - * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} - * @param {int} distance The distance the user swiped - * @param {int} duration The duration of the swipe in milliseconds - * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} - * @param {object} fingerData The coordinates of fingers in event - */ - -/** - * A handler that is triggered for "right" swipes. - * @name $.fn.swipe#swipeRight - * @event - * @default null - * @param {EventObject} event The original event object - * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} - * @param {int} distance The distance the user swiped - * @param {int} duration The duration of the swipe in milliseconds - * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} - * @param {object} fingerData The coordinates of fingers in event - */ - -/** - * A handler that is triggered for "up" swipes. - * @name $.fn.swipe#swipeUp - * @event - * @default null - * @param {EventObject} event The original event object - * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} - * @param {int} distance The distance the user swiped - * @param {int} duration The duration of the swipe in milliseconds - * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} - * @param {object} fingerData The coordinates of fingers in event - */ - -/** - * A handler that is triggered for "down" swipes. - * @name $.fn.swipe#swipeDown - * @event - * @default null - * @param {EventObject} event The original event object - * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions} - * @param {int} distance The distance the user swiped - * @param {int} duration The duration of the swipe in milliseconds - * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} - * @param {object} fingerData The coordinates of fingers in event - */ - -/** - * A handler triggered for every phase of the swipe. This handler is constantly fired for the duration of the pinch. - * This is triggered regardless of swipe thresholds. - * @name $.fn.swipe#swipeStatus - * @event - * @default null - * @param {EventObject} event The original event object - * @param {string} phase The phase of the swipe event. See {@link $.fn.swipe.phases} - * @param {string} direction The direction the user swiped in. This is null if the user has yet to move. See {@link $.fn.swipe.directions} - * @param {int} distance The distance the user swiped. This is 0 if the user has yet to move. - * @param {int} duration The duration of the swipe in milliseconds - * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} - * @param {object} fingerData The coordinates of fingers in event - */ - -/** - * A handler triggered for pinch in events. - * @name $.fn.swipe#pinchIn - * @event - * @default null - * @param {EventObject} event The original event object - * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions} - * @param {int} distance The distance the user pinched - * @param {int} duration The duration of the swipe in milliseconds - * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} - * @param {int} zoom The zoom/scale level the user pinched too, 0-1. - * @param {object} fingerData The coordinates of fingers in event - */ - -/** - * A handler triggered for pinch out events. - * @name $.fn.swipe#pinchOut - * @event - * @default null - * @param {EventObject} event The original event object - * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions} - * @param {int} distance The distance the user pinched - * @param {int} duration The duration of the swipe in milliseconds - * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} - * @param {int} zoom The zoom/scale level the user pinched too, 0-1. - * @param {object} fingerData The coordinates of fingers in event - */ - -/** - * A handler triggered for all pinch events. This handler is constantly fired for the duration of the pinch. This is triggered regardless of thresholds. - * @name $.fn.swipe#pinchStatus - * @event - * @default null - * @param {EventObject} event The original event object - * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions} - * @param {int} distance The distance the user pinched - * @param {int} duration The duration of the swipe in milliseconds - * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers} - * @param {int} zoom The zoom/scale level the user pinched too, 0-1. - * @param {object} fingerData The coordinates of fingers in event - */ - -/** - * A click handler triggered when a user simply clicks, rather than swipes on an element. - * This is deprecated since version 1.6.2, any assignment to click will be assigned to the tap handler. - * You cannot use on to bind to this event as the default jQ click event will be triggered. - * Use the tap event instead. - * @name $.fn.swipe#click - * @event - * @deprecated since version 1.6.2, please use {@link $.fn.swipe#tap} instead - * @default null - * @param {EventObject} event The original event object - * @param {DomObject} target The element clicked on. - */ - - /** - * A click / tap handler triggered when a user simply clicks or taps, rather than swipes on an element. - * @name $.fn.swipe#tap - * @event - * @default null - * @param {EventObject} event The original event object - * @param {DomObject} target The element clicked on. - */ - -/** - * A double tap handler triggered when a user double clicks or taps on an element. - * You can set the time delay for a double tap with the {@link $.fn.swipe.defaults#doubleTapThreshold} property. - * Note: If you set both doubleTap and tap handlers, the tap event will be delayed by the doubleTapThreshold - * as the script needs to check if its a double tap. - * @name $.fn.swipe#doubleTap - * @see $.fn.swipe.defaults#doubleTapThreshold - * @event - * @default null - * @param {EventObject} event The original event object - * @param {DomObject} target The element clicked on. - */ - - /** - * A long tap handler triggered once a tap has been release if the tap was longer than the longTapThreshold. - * You can set the time delay for a long tap with the {@link $.fn.swipe.defaults#longTapThreshold} property. - * @name $.fn.swipe#longTap - * @see $.fn.swipe.defaults#longTapThreshold - * @event - * @default null - * @param {EventObject} event The original event object - * @param {DomObject} target The element clicked on. - */ - - /** - * A hold tap handler triggered as soon as the longTapThreshold is reached - * You can set the time delay for a long tap with the {@link $.fn.swipe.defaults#longTapThreshold} property. - * @name $.fn.swipe#hold - * @see $.fn.swipe.defaults#longTapThreshold - * @event - * @default null - * @param {EventObject} event The original event object - * @param {DomObject} target The element clicked on. - */ - -})); diff --git a/api/js/jquery/TouchSwipe/jquery.touchSwipe.min.js b/api/js/jquery/TouchSwipe/jquery.touchSwipe.min.js deleted file mode 100644 index f053f10bf3..0000000000 --- a/api/js/jquery/TouchSwipe/jquery.touchSwipe.min.js +++ /dev/null @@ -1 +0,0 @@ -(function(a){if(typeof define==="function"&&define.amd&&define.amd.jQuery){define(["jquery"],a)}else{a(jQuery)}}(function(f){var p="left",o="right",e="up",x="down",c="in",z="out",m="none",s="auto",l="swipe",t="pinch",A="tap",j="doubletap",b="longtap",y="hold",D="horizontal",u="vertical",i="all",r=10,g="start",k="move",h="end",q="cancel",a="ontouchstart" in window,v=window.navigator.msPointerEnabled&&!window.navigator.pointerEnabled,d=window.navigator.pointerEnabled||window.navigator.msPointerEnabled,B="TouchSwipe";var n={fingers:1,threshold:75,cancelThreshold:null,pinchThreshold:20,maxTimeThreshold:null,fingerReleaseThreshold:250,longTapThreshold:500,doubleTapThreshold:200,swipe:null,swipeLeft:null,swipeRight:null,swipeUp:null,swipeDown:null,swipeStatus:null,pinchIn:null,pinchOut:null,pinchStatus:null,click:null,tap:null,doubleTap:null,longTap:null,hold:null,triggerOnTouchEnd:true,triggerOnTouchLeave:false,allowPageScroll:"auto",fallbackToMouseEvents:true,excludedElements:"label, button, input, select, textarea, a, .noSwipe"};f.fn.swipe=function(G){var F=f(this),E=F.data(B);if(E&&typeof G==="string"){if(E[G]){return E[G].apply(this,Array.prototype.slice.call(arguments,1))}else{f.error("Method "+G+" does not exist on jQuery.swipe")}}else{if(!E&&(typeof G==="object"||!G)){return w.apply(this,arguments)}}return F};f.fn.swipe.defaults=n;f.fn.swipe.phases={PHASE_START:g,PHASE_MOVE:k,PHASE_END:h,PHASE_CANCEL:q};f.fn.swipe.directions={LEFT:p,RIGHT:o,UP:e,DOWN:x,IN:c,OUT:z};f.fn.swipe.pageScroll={NONE:m,HORIZONTAL:D,VERTICAL:u,AUTO:s};f.fn.swipe.fingers={ONE:1,TWO:2,THREE:3,ALL:i};function w(E){if(E&&(E.allowPageScroll===undefined&&(E.swipe!==undefined||E.swipeStatus!==undefined))){E.allowPageScroll=m}if(E.click!==undefined&&E.tap===undefined){E.tap=E.click}if(!E){E={}}E=f.extend({},f.fn.swipe.defaults,E);return this.each(function(){var G=f(this);var F=G.data(B);if(!F){F=new C(this,E);G.data(B,F)}})}function C(a4,av){var az=(a||d||!av.fallbackToMouseEvents),J=az?(d?(v?"MSPointerDown":"pointerdown"):"touchstart"):"mousedown",ay=az?(d?(v?"MSPointerMove":"pointermove"):"touchmove"):"mousemove",U=az?(d?(v?"MSPointerUp":"pointerup"):"touchend"):"mouseup",S=az?null:"mouseleave",aD=(d?(v?"MSPointerCancel":"pointercancel"):"touchcancel");var ag=0,aP=null,ab=0,a1=0,aZ=0,G=1,aq=0,aJ=0,M=null;var aR=f(a4);var Z="start";var W=0;var aQ=null;var T=0,a2=0,a5=0,ad=0,N=0;var aW=null,af=null;try{aR.bind(J,aN);aR.bind(aD,a9)}catch(ak){f.error("events not supported "+J+","+aD+" on jQuery.swipe")}this.enable=function(){aR.bind(J,aN);aR.bind(aD,a9);return aR};this.disable=function(){aK();return aR};this.destroy=function(){aK();aR.data(B,null);return aR};this.option=function(bc,bb){if(av[bc]!==undefined){if(bb===undefined){return av[bc]}else{av[bc]=bb}}else{f.error("Option "+bc+" does not exist on jQuery.swipe.options")}return null};function aN(bd){if(aB()){return}if(f(bd.target).closest(av.excludedElements,aR).length>0){return}var be=bd.originalEvent?bd.originalEvent:bd;var bc,bb=a?be.touches[0]:be;Z=g;if(a){W=be.touches.length}else{bd.preventDefault()}ag=0;aP=null;aJ=null;ab=0;a1=0;aZ=0;G=1;aq=0;aQ=aj();M=aa();R();if(!a||(W===av.fingers||av.fingers===i)||aX()){ai(0,bb);T=at();if(W==2){ai(1,be.touches[1]);a1=aZ=au(aQ[0].start,aQ[1].start)}if(av.swipeStatus||av.pinchStatus){bc=O(be,Z)}}else{bc=false}if(bc===false){Z=q;O(be,Z);return bc}else{if(av.hold){af=setTimeout(f.proxy(function(){aR.trigger("hold",[be.target]);if(av.hold){bc=av.hold.call(aR,be,be.target)}},this),av.longTapThreshold)}ao(true)}return null}function a3(be){var bh=be.originalEvent?be.originalEvent:be;if(Z===h||Z===q||am()){return}var bd,bc=a?bh.touches[0]:bh;var bf=aH(bc);a2=at();if(a){W=bh.touches.length}if(av.hold){clearTimeout(af)}Z=k;if(W==2){if(a1==0){ai(1,bh.touches[1]);a1=aZ=au(aQ[0].start,aQ[1].start)}else{aH(bh.touches[1]);aZ=au(aQ[0].end,aQ[1].end);aJ=ar(aQ[0].end,aQ[1].end)}G=a7(a1,aZ);aq=Math.abs(a1-aZ)}if((W===av.fingers||av.fingers===i)||!a||aX()){aP=aL(bf.start,bf.end);al(be,aP);ag=aS(bf.start,bf.end);ab=aM();aI(aP,ag);if(av.swipeStatus||av.pinchStatus){bd=O(bh,Z)}if(!av.triggerOnTouchEnd||av.triggerOnTouchLeave){var bb=true;if(av.triggerOnTouchLeave){var bg=aY(this);bb=E(bf.end,bg)}if(!av.triggerOnTouchEnd&&bb){Z=aC(k)}else{if(av.triggerOnTouchLeave&&!bb){Z=aC(h)}}if(Z==q||Z==h){O(bh,Z)}}}else{Z=q;O(bh,Z)}if(bd===false){Z=q;O(bh,Z)}}function L(bb){var bc=bb.originalEvent;if(a){if(bc.touches.length>0){F();return true}}if(am()){W=ad}a2=at();ab=aM();if(ba()||!an()){Z=q;O(bc,Z)}else{if(av.triggerOnTouchEnd||(av.triggerOnTouchEnd==false&&Z===k)){bb.preventDefault();Z=h;O(bc,Z)}else{if(!av.triggerOnTouchEnd&&a6()){Z=h;aF(bc,Z,A)}else{if(Z===k){Z=q;O(bc,Z)}}}}ao(false);return null}function a9(){W=0;a2=0;T=0;a1=0;aZ=0;G=1;R();ao(false)}function K(bb){var bc=bb.originalEvent;if(av.triggerOnTouchLeave){Z=aC(h);O(bc,Z)}}function aK(){aR.unbind(J,aN);aR.unbind(aD,a9);aR.unbind(ay,a3);aR.unbind(U,L);if(S){aR.unbind(S,K)}ao(false)}function aC(bf){var be=bf;var bd=aA();var bc=an();var bb=ba();if(!bd||bb){be=q}else{if(bc&&bf==k&&(!av.triggerOnTouchEnd||av.triggerOnTouchLeave)){be=h}else{if(!bc&&bf==h&&av.triggerOnTouchLeave){be=q}}}return be}function O(bd,bb){var bc=undefined;if(I()||V()){bc=aF(bd,bb,l)}else{if((P()||aX())&&bc!==false){bc=aF(bd,bb,t)}}if(aG()&&bc!==false){bc=aF(bd,bb,j)}else{if(ap()&&bc!==false){bc=aF(bd,bb,b)}else{if(ah()&&bc!==false){bc=aF(bd,bb,A)}}}if(bb===q){a9(bd)}if(bb===h){if(a){if(bd.touches.length==0){a9(bd)}}else{a9(bd)}}return bc}function aF(be,bb,bd){var bc=undefined;if(bd==l){aR.trigger("swipeStatus",[bb,aP||null,ag||0,ab||0,W,aQ]);if(av.swipeStatus){bc=av.swipeStatus.call(aR,be,bb,aP||null,ag||0,ab||0,W,aQ);if(bc===false){return false}}if(bb==h&&aV()){aR.trigger("swipe",[aP,ag,ab,W,aQ]);if(av.swipe){bc=av.swipe.call(aR,be,aP,ag,ab,W,aQ);if(bc===false){return false}}switch(aP){case p:aR.trigger("swipeLeft",[aP,ag,ab,W,aQ]);if(av.swipeLeft){bc=av.swipeLeft.call(aR,be,aP,ag,ab,W,aQ)}break;case o:aR.trigger("swipeRight",[aP,ag,ab,W,aQ]);if(av.swipeRight){bc=av.swipeRight.call(aR,be,aP,ag,ab,W,aQ)}break;case e:aR.trigger("swipeUp",[aP,ag,ab,W,aQ]);if(av.swipeUp){bc=av.swipeUp.call(aR,be,aP,ag,ab,W,aQ)}break;case x:aR.trigger("swipeDown",[aP,ag,ab,W,aQ]);if(av.swipeDown){bc=av.swipeDown.call(aR,be,aP,ag,ab,W,aQ)}break}}}if(bd==t){aR.trigger("pinchStatus",[bb,aJ||null,aq||0,ab||0,W,G,aQ]);if(av.pinchStatus){bc=av.pinchStatus.call(aR,be,bb,aJ||null,aq||0,ab||0,W,G,aQ);if(bc===false){return false}}if(bb==h&&a8()){switch(aJ){case c:aR.trigger("pinchIn",[aJ||null,aq||0,ab||0,W,G,aQ]);if(av.pinchIn){bc=av.pinchIn.call(aR,be,aJ||null,aq||0,ab||0,W,G,aQ)}break;case z:aR.trigger("pinchOut",[aJ||null,aq||0,ab||0,W,G,aQ]);if(av.pinchOut){bc=av.pinchOut.call(aR,be,aJ||null,aq||0,ab||0,W,G,aQ)}break}}}if(bd==A){if(bb===q||bb===h){clearTimeout(aW);clearTimeout(af);if(Y()&&!H()){N=at();aW=setTimeout(f.proxy(function(){N=null;aR.trigger("tap",[be.target]);if(av.tap){bc=av.tap.call(aR,be,be.target)}},this),av.doubleTapThreshold)}else{N=null;aR.trigger("tap",[be.target]);if(av.tap){bc=av.tap.call(aR,be,be.target)}}}}else{if(bd==j){if(bb===q||bb===h){clearTimeout(aW);N=null;aR.trigger("doubletap",[be.target]);if(av.doubleTap){bc=av.doubleTap.call(aR,be,be.target)}}}else{if(bd==b){if(bb===q||bb===h){clearTimeout(aW);N=null;aR.trigger("longtap",[be.target]);if(av.longTap){bc=av.longTap.call(aR,be,be.target)}}}}}return bc}function an(){var bb=true;if(av.threshold!==null){bb=ag>=av.threshold}return bb}function ba(){var bb=false;if(av.cancelThreshold!==null&&aP!==null){bb=(aT(aP)-ag)>=av.cancelThreshold}return bb}function ae(){if(av.pinchThreshold!==null){return aq>=av.pinchThreshold}return true}function aA(){var bb;if(av.maxTimeThreshold){if(ab>=av.maxTimeThreshold){bb=false}else{bb=true}}else{bb=true}return bb}function al(bb,bc){if(av.allowPageScroll===m||aX()){bb.preventDefault()}else{var bd=av.allowPageScroll===s;switch(bc){case p:if((av.swipeLeft&&bd)||(!bd&&av.allowPageScroll!=D)){bb.preventDefault()}break;case o:if((av.swipeRight&&bd)||(!bd&&av.allowPageScroll!=D)){bb.preventDefault()}break;case e:if((av.swipeUp&&bd)||(!bd&&av.allowPageScroll!=u)){bb.preventDefault()}break;case x:if((av.swipeDown&&bd)||(!bd&&av.allowPageScroll!=u)){bb.preventDefault()}break}}}function a8(){var bc=aO();var bb=X();var bd=ae();return bc&&bb&&bd}function aX(){return !!(av.pinchStatus||av.pinchIn||av.pinchOut)}function P(){return !!(a8()&&aX())}function aV(){var be=aA();var bg=an();var bd=aO();var bb=X();var bc=ba();var bf=!bc&&bb&&bd&&bg&&be;return bf}function V(){return !!(av.swipe||av.swipeStatus||av.swipeLeft||av.swipeRight||av.swipeUp||av.swipeDown)}function I(){return !!(aV()&&V())}function aO(){return((W===av.fingers||av.fingers===i)||!a)}function X(){return aQ[0].end.x!==0}function a6(){return !!(av.tap)}function Y(){return !!(av.doubleTap)}function aU(){return !!(av.longTap)}function Q(){if(N==null){return false}var bb=at();return(Y()&&((bb-N)<=av.doubleTapThreshold))}function H(){return Q()}function ax(){return((W===1||!a)&&(isNaN(ag)||agav.longTapThreshold)&&(ag=0)){return p}else{if((bd<=360)&&(bd>=315)){return p}else{if((bd>=135)&&(bd<=225)){return o}else{if((bd>45)&&(bd<135)){return x}else{return e}}}}}function at(){var bb=new Date();return bb.getTime()}function aY(bb){bb=f(bb);var bd=bb.offset();var bc={left:bd.left,right:bd.left+bb.outerWidth(),top:bd.top,bottom:bd.top+bb.outerHeight()};return bc}function E(bb,bc){return(bb.x>bc.left&&bb.xbc.top&&bb.y ...mobile browsers will wait approximately 300ms from the time that you tap the button to fire the click event. The reason for this is that the browser is waiting to see if you are actually performing a double tap. - -## Compatibility ## - -The library has been deployed as part of the [FT Web App](http://app.ft.com/) and is tried and tested on the following mobile browsers: - -* Mobile Safari on iOS 3 and upwards -* Chrome on iOS 5 and upwards -* Chrome on Android (ICS) -* Opera Mobile 11.5 and upwards -* Android Browser since Android 2 -* PlayBook OS 1 and upwards - -## When it isn't needed ## - -FastClick doesn't attach any listeners on desktop browsers. - -Chrome 32+ on Android with `width=device-width` in the [viewport meta tag](https://developer.mozilla.org/en-US/docs/Mobile/Viewport_meta_tag) doesn't have a 300ms delay, therefore listeners aren't attached. - -```html - -``` - -Same goes for Chrome on Android (all versions) with `user-scalable=no` in the viewport meta tag. But be aware that `user-scalable=no` also disables pinch zooming, which may be an accessibility concern. - -For IE11+, you can use `touch-action: manipulation;` to disable double-tap-to-zoom on certain elements (like links and buttons). For IE10 use `-ms-touch-action: manipulation`. - -## Usage ## - -Include fastclick.js in your JavaScript bundle or add it to your HTML page like this: - -```html - -``` - -The script must be loaded prior to instantiating FastClick on any element of the page. - -To instantiate FastClick on the `body`, which is the recommended method of use: - -```js -if ('addEventListener' in document) { - document.addEventListener('DOMContentLoaded', function() { - FastClick.attach(document.body); - }, false); -} -``` - -Or, if you're using jQuery: - -```js -$(function() { - FastClick.attach(document.body); -}); -``` - -If you're using Browserify or another CommonJS-style module system, the `FastClick.attach` function will be returned when you call `require('fastclick')`. As a result, the easiest way to use FastClick with these loaders is as follows: - -```js -var attachFastClick = require('fastclick'); -attachFastClick(document.body); -``` - -### Minified ### - -Run `make` to build a minified version of FastClick using the Closure Compiler REST API. The minified file is saved to `build/fastclick.min.js` or you can [download a pre-minified version](http://build.origami.ft.com/bundles/js?modules=fastclick). - -Note: the pre-minified version is built using [our build service](http://origami.ft.com/docs/developer-guide/build-service/) which exposes the `FastClick` object through `Origami.fastclick` and will have the Browserify/CommonJS API (see above). - -```js -var attachFastClick = Origami.fastclick; -attachFastClick(document.body); -``` - -### AMD ### - -FastClick has AMD (Asynchronous Module Definition) support. This allows it to be lazy-loaded with an AMD loader, such as [RequireJS](http://requirejs.org/). Note that when using the AMD style require, the full `FastClick` object will be returned, _not_ `FastClick.attach` - -```js -var FastClick = require('fastclick'); -FastClick.attach(document.body, options); -``` - -### Package managers ### - -You can install FastClick using [Component](https://github.com/component/component), [npm](https://npmjs.org/package/fastclick) or [Bower](http://bower.io/). - -For Ruby, there's a third-party gem called [fastclick-rails](http://rubygems.org/gems/fastclick-rails). For .NET there's a [NuGet package](http://nuget.org/packages/FastClick). - -## Advanced ## - -### Ignore certain elements with `needsclick` ### - -Sometimes you need FastClick to ignore certain elements. You can do this easily by adding the `needsclick` class. -```html -Ignored by FastClick -``` - -#### Use case 1: non-synthetic click required #### - -Internally, FastClick uses `document.createEvent` to fire a synthetic `click` event as soon as `touchend` is fired by the browser. It then suppresses the additional `click` event created by the browser after that. In some cases, the non-synthetic `click` event created by the browser is required, as described in the [triggering focus example](http://ftlabs.github.com/fastclick/examples/focus.html). - -This is where the `needsclick` class comes in. Add the class to any element that requires a non-synthetic click. - -#### Use case 2: Twitter Bootstrap 2.2.2 dropdowns #### - -Another example of when to use the `needsclick` class is with dropdowns in Twitter Bootstrap 2.2.2. Bootstrap add its own `touchstart` listener for dropdowns, so you want to tell FastClick to ignore those. If you don't, touch devices will automatically close the dropdown as soon as it is clicked, because both FastClick and Bootstrap execute the synthetic click, one opens the dropdown, the second closes it immediately after. - -```html -Dropdown -``` - -## Examples ## - -FastClick is designed to cope with many different browser oddities. Here are some examples to illustrate this: - -* [basic use](http://ftlabs.github.com/fastclick/examples/layer.html) showing the increase in perceived responsiveness -* [triggering focus](http://ftlabs.github.com/fastclick/examples/focus.html) on an input element from a `click` handler -* [input element](http://ftlabs.github.com/fastclick/examples/input.html) which never receives clicks but gets fast focus - -## Tests ## - -There are no automated tests. The files in `tests/` are manual reduced test cases. We've had a think about how best to test these cases, but they tend to be very browser/device specific and sometimes subjective which means it's not so trivial to test. - -## Credits and collaboration ## - -FastClick is maintained by [Rowan Beentje](http://twitter.com/rowanbeentje), [Matthew Caruana Galizia](http://twitter.com/mcaruanagalizia) and [Matthew Andrews](http://twitter.com/andrewsmatt) at [FT Labs](http://labs.ft.com). All open source code released by FT Labs is licenced under the MIT licence. We welcome comments, feedback and suggestions. Please feel free to raise an issue or pull request. diff --git a/api/js/jquery/fastclick/lib/fastclick.js b/api/js/jquery/fastclick/lib/fastclick.js deleted file mode 100755 index 12ac00a504..0000000000 --- a/api/js/jquery/fastclick/lib/fastclick.js +++ /dev/null @@ -1,841 +0,0 @@ -(function () { - 'use strict'; - - /** - * @preserve FastClick: polyfill to remove click delays on browsers with touch UIs. - * - * @codingstandard ftlabs-jsv2 - * @copyright The Financial Times Limited [All Rights Reserved] - * @license MIT License (see LICENSE.txt) - */ - - /*jslint browser:true, node:true*/ - /*global define, Event, Node*/ - - - /** - * Instantiate fast-clicking listeners on the specified layer. - * - * @constructor - * @param {Element} layer The layer to listen on - * @param {Object} [options={}] The options to override the defaults - */ - function FastClick(layer, options) { - var oldOnClick; - - options = options || {}; - - /** - * Whether a click is currently being tracked. - * - * @type boolean - */ - this.trackingClick = false; - - - /** - * Timestamp for when click tracking started. - * - * @type number - */ - this.trackingClickStart = 0; - - - /** - * The element being tracked for a click. - * - * @type EventTarget - */ - this.targetElement = null; - - - /** - * X-coordinate of touch start event. - * - * @type number - */ - this.touchStartX = 0; - - - /** - * Y-coordinate of touch start event. - * - * @type number - */ - this.touchStartY = 0; - - - /** - * ID of the last touch, retrieved from Touch.identifier. - * - * @type number - */ - this.lastTouchIdentifier = 0; - - - /** - * Touchmove boundary, beyond which a click will be cancelled. - * - * @type number - */ - this.touchBoundary = options.touchBoundary || 10; - - - /** - * The FastClick layer. - * - * @type Element - */ - this.layer = layer; - - /** - * The minimum time between tap(touchstart and touchend) events - * - * @type number - */ - this.tapDelay = options.tapDelay || 200; - - /** - * The maximum time for a tap - * - * @type number - */ - this.tapTimeout = options.tapTimeout || 700; - - if (FastClick.notNeeded(layer)) { - return; - } - - // Some old versions of Android don't have Function.prototype.bind - function bind(method, context) { - return function() { return method.apply(context, arguments); }; - } - - - var methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel']; - var context = this; - for (var i = 0, l = methods.length; i < l; i++) { - context[methods[i]] = bind(context[methods[i]], context); - } - - // Set up event handlers as required - if (deviceIsAndroid) { - layer.addEventListener('mouseover', this.onMouse, true); - layer.addEventListener('mousedown', this.onMouse, true); - layer.addEventListener('mouseup', this.onMouse, true); - } - - layer.addEventListener('click', this.onClick, true); - layer.addEventListener('touchstart', this.onTouchStart, false); - layer.addEventListener('touchmove', this.onTouchMove, false); - layer.addEventListener('touchend', this.onTouchEnd, false); - layer.addEventListener('touchcancel', this.onTouchCancel, false); - - // Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2) - // which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick - // layer when they are cancelled. - if (!Event.prototype.stopImmediatePropagation) { - layer.removeEventListener = function(type, callback, capture) { - var rmv = Node.prototype.removeEventListener; - if (type === 'click') { - rmv.call(layer, type, callback.hijacked || callback, capture); - } else { - rmv.call(layer, type, callback, capture); - } - }; - - layer.addEventListener = function(type, callback, capture) { - var adv = Node.prototype.addEventListener; - if (type === 'click') { - adv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) { - if (!event.propagationStopped) { - callback(event); - } - }), capture); - } else { - adv.call(layer, type, callback, capture); - } - }; - } - - // If a handler is already declared in the element's onclick attribute, it will be fired before - // FastClick's onClick handler. Fix this by pulling out the user-defined handler function and - // adding it as listener. - if (typeof layer.onclick === 'function') { - - // Android browser on at least 3.2 requires a new reference to the function in layer.onclick - // - the old one won't work if passed to addEventListener directly. - oldOnClick = layer.onclick; - layer.addEventListener('click', function(event) { - oldOnClick(event); - }, false); - layer.onclick = null; - } - } - - /** - * Windows Phone 8.1 fakes user agent string to look like Android and iPhone. - * - * @type boolean - */ - var deviceIsWindowsPhone = navigator.userAgent.indexOf("Windows Phone") >= 0; - - /** - * Android requires exceptions. - * - * @type boolean - */ - var deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0 && !deviceIsWindowsPhone; - - - /** - * iOS requires exceptions. - * - * @type boolean - */ - var deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent) && !deviceIsWindowsPhone; - - - /** - * iOS 4 requires an exception for select elements. - * - * @type boolean - */ - var deviceIsIOS4 = deviceIsIOS && (/OS 4_\d(_\d)?/).test(navigator.userAgent); - - - /** - * iOS 6.0-7.* requires the target element to be manually derived - * - * @type boolean - */ - var deviceIsIOSWithBadTarget = deviceIsIOS && (/OS [6-7]_\d/).test(navigator.userAgent); - - /** - * BlackBerry requires exceptions. - * - * @type boolean - */ - var deviceIsBlackBerry10 = navigator.userAgent.indexOf('BB10') > 0; - - /** - * Determine whether a given element requires a native click. - * - * @param {EventTarget|Element} target Target DOM element - * @returns {boolean} Returns true if the element needs a native click - */ - FastClick.prototype.needsClick = function(target) { - switch (target.nodeName.toLowerCase()) { - - // Don't send a synthetic click to disabled inputs (issue #62) - case 'button': - case 'select': - case 'textarea': - if (target.disabled) { - return true; - } - - break; - case 'input': - - // File inputs need real clicks on iOS 6 due to a browser bug (issue #68) - if ((deviceIsIOS && target.type === 'file') || target.disabled) { - return true; - } - - break; - case 'label': - case 'iframe': // iOS8 homescreen apps can prevent events bubbling into frames - case 'video': - return true; - } - - return (/\bneedsclick\b/).test(target.className); - }; - - - /** - * Determine whether a given element requires a call to focus to simulate click into element. - * - * @param {EventTarget|Element} target Target DOM element - * @returns {boolean} Returns true if the element requires a call to focus to simulate native click. - */ - FastClick.prototype.needsFocus = function(target) { - switch (target.nodeName.toLowerCase()) { - case 'textarea': - return true; - case 'select': - return !deviceIsAndroid; - case 'input': - switch (target.type) { - case 'button': - case 'checkbox': - case 'file': - case 'image': - case 'radio': - case 'submit': - return false; - } - - // No point in attempting to focus disabled inputs - return !target.disabled && !target.readOnly; - default: - return (/\bneedsfocus\b/).test(target.className); - } - }; - - - /** - * Send a click event to the specified element. - * - * @param {EventTarget|Element} targetElement - * @param {Event} event - */ - FastClick.prototype.sendClick = function(targetElement, event) { - var clickEvent, touch; - - // On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24) - if (document.activeElement && document.activeElement !== targetElement) { - document.activeElement.blur(); - } - - touch = event.changedTouches[0]; - - // Synthesise a click event, with an extra attribute so it can be tracked - clickEvent = document.createEvent('MouseEvents'); - clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null); - clickEvent.forwardedTouchEvent = true; - targetElement.dispatchEvent(clickEvent); - }; - - FastClick.prototype.determineEventType = function(targetElement) { - - //Issue #159: Android Chrome Select Box does not open with a synthetic click event - if (deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') { - return 'mousedown'; - } - - return 'click'; - }; - - - /** - * @param {EventTarget|Element} targetElement - */ - FastClick.prototype.focus = function(targetElement) { - var length; - - // Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724. - if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month') { - length = targetElement.value.length; - targetElement.setSelectionRange(length, length); - } else { - targetElement.focus(); - } - }; - - - /** - * Check whether the given target element is a child of a scrollable layer and if so, set a flag on it. - * - * @param {EventTarget|Element} targetElement - */ - FastClick.prototype.updateScrollParent = function(targetElement) { - var scrollParent, parentElement; - - scrollParent = targetElement.fastClickScrollParent; - - // Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the - // target element was moved to another parent. - if (!scrollParent || !scrollParent.contains(targetElement)) { - parentElement = targetElement; - do { - if (parentElement.scrollHeight > parentElement.offsetHeight) { - scrollParent = parentElement; - targetElement.fastClickScrollParent = parentElement; - break; - } - - parentElement = parentElement.parentElement; - } while (parentElement); - } - - // Always update the scroll top tracker if possible. - if (scrollParent) { - scrollParent.fastClickLastScrollTop = scrollParent.scrollTop; - } - }; - - - /** - * @param {EventTarget} targetElement - * @returns {Element|EventTarget} - */ - FastClick.prototype.getTargetElementFromEventTarget = function(eventTarget) { - - // On some older browsers (notably Safari on iOS 4.1 - see issue #56) the event target may be a text node. - if (eventTarget.nodeType === Node.TEXT_NODE) { - return eventTarget.parentNode; - } - - return eventTarget; - }; - - - /** - * On touch start, record the position and scroll offset. - * - * @param {Event} event - * @returns {boolean} - */ - FastClick.prototype.onTouchStart = function(event) { - var targetElement, touch, selection; - - // Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111). - if (event.targetTouches.length > 1) { - return true; - } - - targetElement = this.getTargetElementFromEventTarget(event.target); - touch = event.targetTouches[0]; - - if (deviceIsIOS) { - - // Only trusted events will deselect text on iOS (issue #49) - selection = window.getSelection(); - if (selection.rangeCount && !selection.isCollapsed) { - return true; - } - - if (!deviceIsIOS4) { - - // Weird things happen on iOS when an alert or confirm dialog is opened from a click event callback (issue #23): - // when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched - // with the same identifier as the touch event that previously triggered the click that triggered the alert. - // Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an - // immediately preceeding touch event (issue #52), so this fix is unavailable on that platform. - // Issue 120: touch.identifier is 0 when Chrome dev tools 'Emulate touch events' is set with an iOS device UA string, - // which causes all touch events to be ignored. As this block only applies to iOS, and iOS identifiers are always long, - // random integers, it's safe to to continue if the identifier is 0 here. - if (touch.identifier && touch.identifier === this.lastTouchIdentifier) { - event.preventDefault(); - return false; - } - - this.lastTouchIdentifier = touch.identifier; - - // If the target element is a child of a scrollable layer (using -webkit-overflow-scrolling: touch) and: - // 1) the user does a fling scroll on the scrollable layer - // 2) the user stops the fling scroll with another tap - // then the event.target of the last 'touchend' event will be the element that was under the user's finger - // when the fling scroll was started, causing FastClick to send a click event to that layer - unless a check - // is made to ensure that a parent layer was not scrolled before sending a synthetic click (issue #42). - this.updateScrollParent(targetElement); - } - } - - this.trackingClick = true; - this.trackingClickStart = event.timeStamp; - this.targetElement = targetElement; - - this.touchStartX = touch.pageX; - this.touchStartY = touch.pageY; - - // Prevent phantom clicks on fast double-tap (issue #36) - if ((event.timeStamp - this.lastClickTime) < this.tapDelay) { - event.preventDefault(); - } - - return true; - }; - - - /** - * Based on a touchmove event object, check whether the touch has moved past a boundary since it started. - * - * @param {Event} event - * @returns {boolean} - */ - FastClick.prototype.touchHasMoved = function(event) { - var touch = event.changedTouches[0], boundary = this.touchBoundary; - - if (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) { - return true; - } - - return false; - }; - - - /** - * Update the last position. - * - * @param {Event} event - * @returns {boolean} - */ - FastClick.prototype.onTouchMove = function(event) { - if (!this.trackingClick) { - return true; - } - - // If the touch has moved, cancel the click tracking - if (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) { - this.trackingClick = false; - this.targetElement = null; - } - - return true; - }; - - - /** - * Attempt to find the labelled control for the given label element. - * - * @param {EventTarget|HTMLLabelElement} labelElement - * @returns {Element|null} - */ - FastClick.prototype.findControl = function(labelElement) { - - // Fast path for newer browsers supporting the HTML5 control attribute - if (labelElement.control !== undefined) { - return labelElement.control; - } - - // All browsers under test that support touch events also support the HTML5 htmlFor attribute - if (labelElement.htmlFor) { - return document.getElementById(labelElement.htmlFor); - } - - // If no for attribute exists, attempt to retrieve the first labellable descendant element - // the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label - return labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea'); - }; - - - /** - * On touch end, determine whether to send a click event at once. - * - * @param {Event} event - * @returns {boolean} - */ - FastClick.prototype.onTouchEnd = function(event) { - var forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement; - - if (!this.trackingClick) { - return true; - } - - // Prevent phantom clicks on fast double-tap (issue #36) - if ((event.timeStamp - this.lastClickTime) < this.tapDelay) { - this.cancelNextClick = true; - return true; - } - - if ((event.timeStamp - this.trackingClickStart) > this.tapTimeout) { - return true; - } - - // Reset to prevent wrong click cancel on input (issue #156). - this.cancelNextClick = false; - - this.lastClickTime = event.timeStamp; - - trackingClickStart = this.trackingClickStart; - this.trackingClick = false; - this.trackingClickStart = 0; - - // On some iOS devices, the targetElement supplied with the event is invalid if the layer - // is performing a transition or scroll, and has to be re-detected manually. Note that - // for this to function correctly, it must be called *after* the event target is checked! - // See issue #57; also filed as rdar://13048589 . - if (deviceIsIOSWithBadTarget) { - touch = event.changedTouches[0]; - - // In certain cases arguments of elementFromPoint can be negative, so prevent setting targetElement to null - targetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement; - targetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent; - } - - targetTagName = targetElement.tagName.toLowerCase(); - if (targetTagName === 'label') { - forElement = this.findControl(targetElement); - if (forElement) { - this.focus(targetElement); - if (deviceIsAndroid) { - return false; - } - - targetElement = forElement; - } - } else if (this.needsFocus(targetElement)) { - - // Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through. - // Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37). - if ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) { - this.targetElement = null; - return false; - } - - this.focus(targetElement); - this.sendClick(targetElement, event); - - // Select elements need the event to go through on iOS 4, otherwise the selector menu won't open. - // Also this breaks opening selects when VoiceOver is active on iOS6, iOS7 (and possibly others) - if (!deviceIsIOS || targetTagName !== 'select') { - this.targetElement = null; - event.preventDefault(); - } - - return false; - } - - if (deviceIsIOS && !deviceIsIOS4) { - - // Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled - // and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42). - scrollParent = targetElement.fastClickScrollParent; - if (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) { - return true; - } - } - - // Prevent the actual click from going though - unless the target node is marked as requiring - // real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted. - if (!this.needsClick(targetElement)) { - event.preventDefault(); - this.sendClick(targetElement, event); - } - - return false; - }; - - - /** - * On touch cancel, stop tracking the click. - * - * @returns {void} - */ - FastClick.prototype.onTouchCancel = function() { - this.trackingClick = false; - this.targetElement = null; - }; - - - /** - * Determine mouse events which should be permitted. - * - * @param {Event} event - * @returns {boolean} - */ - FastClick.prototype.onMouse = function(event) { - - // If a target element was never set (because a touch event was never fired) allow the event - if (!this.targetElement) { - return true; - } - - if (event.forwardedTouchEvent) { - return true; - } - - // Programmatically generated events targeting a specific element should be permitted - if (!event.cancelable) { - return true; - } - - // Derive and check the target element to see whether the mouse event needs to be permitted; - // unless explicitly enabled, prevent non-touch click events from triggering actions, - // to prevent ghost/doubleclicks. - if (!this.needsClick(this.targetElement) || this.cancelNextClick) { - - // Prevent any user-added listeners declared on FastClick element from being fired. - if (event.stopImmediatePropagation) { - event.stopImmediatePropagation(); - } else { - - // Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2) - event.propagationStopped = true; - } - - // Cancel the event - event.stopPropagation(); - event.preventDefault(); - - return false; - } - - // If the mouse event is permitted, return true for the action to go through. - return true; - }; - - - /** - * On actual clicks, determine whether this is a touch-generated click, a click action occurring - * naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or - * an actual click which should be permitted. - * - * @param {Event} event - * @returns {boolean} - */ - FastClick.prototype.onClick = function(event) { - var permitted; - - // It's possible for another FastClick-like library delivered with third-party code to fire a click event before FastClick does (issue #44). In that case, set the click-tracking flag back to false and return early. This will cause onTouchEnd to return early. - if (this.trackingClick) { - this.targetElement = null; - this.trackingClick = false; - return true; - } - - // Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target. - if (event.target.type === 'submit' && event.detail === 0) { - return true; - } - - permitted = this.onMouse(event); - - // Only unset targetElement if the click is not permitted. This will ensure that the check for !targetElement in onMouse fails and the browser's click doesn't go through. - if (!permitted) { - this.targetElement = null; - } - - // If clicks are permitted, return true for the action to go through. - return permitted; - }; - - - /** - * Remove all FastClick's event listeners. - * - * @returns {void} - */ - FastClick.prototype.destroy = function() { - var layer = this.layer; - - if (deviceIsAndroid) { - layer.removeEventListener('mouseover', this.onMouse, true); - layer.removeEventListener('mousedown', this.onMouse, true); - layer.removeEventListener('mouseup', this.onMouse, true); - } - - layer.removeEventListener('click', this.onClick, true); - layer.removeEventListener('touchstart', this.onTouchStart, false); - layer.removeEventListener('touchmove', this.onTouchMove, false); - layer.removeEventListener('touchend', this.onTouchEnd, false); - layer.removeEventListener('touchcancel', this.onTouchCancel, false); - }; - - - /** - * Check whether FastClick is needed. - * - * @param {Element} layer The layer to listen on - */ - FastClick.notNeeded = function(layer) { - var metaViewport; - var chromeVersion; - var blackberryVersion; - var firefoxVersion; - - // Devices that don't support touch don't need FastClick - if (typeof window.ontouchstart === 'undefined') { - return true; - } - - // Chrome version - zero for other browsers - chromeVersion = +(/Chrome\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1]; - - if (chromeVersion) { - - if (deviceIsAndroid) { - metaViewport = document.querySelector('meta[name=viewport]'); - - if (metaViewport) { - // Chrome on Android with user-scalable="no" doesn't need FastClick (issue #89) - if (metaViewport.content.indexOf('user-scalable=no') !== -1) { - return true; - } - // Chrome 32 and above with width=device-width or less don't need FastClick - if (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) { - return true; - } - } - - // Chrome desktop doesn't need FastClick (issue #15) - } else { - return true; - } - } - - if (deviceIsBlackBerry10) { - blackberryVersion = navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/); - - // BlackBerry 10.3+ does not require Fastclick library. - // https://github.com/ftlabs/fastclick/issues/251 - if (blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3) { - metaViewport = document.querySelector('meta[name=viewport]'); - - if (metaViewport) { - // user-scalable=no eliminates click delay. - if (metaViewport.content.indexOf('user-scalable=no') !== -1) { - return true; - } - // width=device-width (or less than device-width) eliminates click delay. - if (document.documentElement.scrollWidth <= window.outerWidth) { - return true; - } - } - } - } - - // IE10 with -ms-touch-action: none or manipulation, which disables double-tap-to-zoom (issue #97) - if (layer.style.msTouchAction === 'none' || layer.style.touchAction === 'manipulation') { - return true; - } - - // Firefox version - zero for other browsers - firefoxVersion = +(/Firefox\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1]; - - if (firefoxVersion >= 27) { - // Firefox 27+ does not have tap delay if the content is not zoomable - https://bugzilla.mozilla.org/show_bug.cgi?id=922896 - - metaViewport = document.querySelector('meta[name=viewport]'); - if (metaViewport && (metaViewport.content.indexOf('user-scalable=no') !== -1 || document.documentElement.scrollWidth <= window.outerWidth)) { - return true; - } - } - - // IE11: prefixed -ms-touch-action is no longer supported and it's recomended to use non-prefixed version - // http://msdn.microsoft.com/en-us/library/windows/apps/Hh767313.aspx - if (layer.style.touchAction === 'none' || layer.style.touchAction === 'manipulation') { - return true; - } - - return false; - }; - - - /** - * Factory method for creating a FastClick object - * - * @param {Element} layer The layer to listen on - * @param {Object} [options={}] The options to override the defaults - */ - FastClick.attach = function(layer, options) { - return new FastClick(layer, options); - }; - - - if (typeof define === 'function' && typeof define.amd === 'object' && define.amd) { - - // AMD. Register as an anonymous module. - define(function() { - return FastClick; - }); - } else if (typeof module !== 'undefined' && module.exports) { - module.exports = FastClick.attach; - module.exports.FastClick = FastClick; - } else { - window.FastClick = FastClick; - } -}()); diff --git a/api/js/jquery/gridster/.gitignore b/api/js/jquery/gridster/.gitignore deleted file mode 100644 index 0a1c9db0be..0000000000 --- a/api/js/jquery/gridster/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -node_modules/ -gh-pages/ -demo/ -.idea \ No newline at end of file diff --git a/api/js/jquery/gridster/LICENSE b/api/js/jquery/gridster/LICENSE deleted file mode 100644 index 869f81f5b6..0000000000 --- a/api/js/jquery/gridster/LICENSE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2012 Ducksboard - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/api/js/jquery/gridster/README.md b/api/js/jquery/gridster/README.md deleted file mode 100644 index a9fba1423c..0000000000 --- a/api/js/jquery/gridster/README.md +++ /dev/null @@ -1,52 +0,0 @@ -Gridster.js -=========== - -Gridster is a jQuery plugin that makes building intuitive draggable -layouts from elements spanning multiple columns. You can even -dynamically add and remove elements from the grid. - -More at [http://gridster.net/](http://gridster.net/). - -Updating Begins -=============== - -Hi all, I have begun merging my fork with the main repository -and am making some much needed fixes in the process. - -I am devoting an hour a day until it gets done. - -Thanks, - -Dustin - - -Public Service Announcement from Dustin Moore (dustmoo) -======================================================= - -Gridster is not currently being actively maintained by -[Ducksboard](http://ducksboard.com/). - -I and others have been given access to the repo to help - maintain and address issues. - -I have created a fork of gridster that supports more advanced - features, like widget-swapping and static widgets. - -It can be found here: https://github.com/dustmoo/gridster.js - -Currently the code-base is different and I don't have time to -reconcile the fork with this repo. - -If anyone would like to help me improve my fork and reconcile -it with the main library I would be happy for the help. - - -License -======= - -Distributed under the MIT license. - -Whodunit -======== - -Gridster is built by [Ducksboard](http://ducksboard.com/). diff --git a/api/js/jquery/gridster/jquery.gridster.css b/api/js/jquery/gridster/jquery.gridster.css deleted file mode 100644 index e07b7e01c1..0000000000 --- a/api/js/jquery/gridster/jquery.gridster.css +++ /dev/null @@ -1,60 +0,0 @@ -.gridster { - position:relative; -} - -.gridster > * { - margin: 0 auto; - -webkit-transition: height .4s; - -moz-transition: height .4s; - -o-transition: height .4s; - -ms-transition: height .4s; - transition: height .4s; -} - -.gridster .gs_w{ - z-index: 2; - position: absolute; -} - -.ready .gs_w:not(.preview-holder) { - -webkit-transition: opacity .3s, left .3s, top .3s; - -moz-transition: opacity .3s, left .3s, top .3s; - -o-transition: opacity .3s, left .3s, top .3s; - transition: opacity .3s, left .3s, top .3s; -} - -.ready .gs_w:not(.preview-holder) { - -webkit-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s; - -moz-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s; - -o-transition: opacity .3s, left .3s, top .3s, width .3s, height .3s; - transition: opacity .3s, left .3s, top .3s, width .3s, height .3s; -} - -.gridster .preview-holder { - z-index: 1; - position: absolute; - background-color: #fff; - border-color: #fff; - opacity: 0.3; -} - -.gridster .player-revert { - z-index: 10!important; - -webkit-transition: left .3s, top .3s!important; - -moz-transition: left .3s, top .3s!important; - -o-transition: left .3s, top .3s!important; - transition: left .3s, top .3s!important; -} - -.gridster .dragging { - z-index: 10!important; - -webkit-transition: all 0s !important; - -moz-transition: all 0s !important; - -o-transition: all 0s !important; - transition: all 0s !important; -} - -/* Uncomment this if you set helper : "clone" in draggable options */ -/*.gridster .player { - opacity:0; -}*/ diff --git a/api/js/jquery/gridster/jquery.gridster.js b/api/js/jquery/gridster/jquery.gridster.js deleted file mode 100644 index b9ebb277bc..0000000000 --- a/api/js/jquery/gridster/jquery.gridster.js +++ /dev/null @@ -1,3987 +0,0 @@ -/*! gridster.js - v0.5.6 - 2014-09-25 -* http://gridster.net/ -* Copyright (c) 2014 ducksboard; Licensed MIT */ - -;(function(root, factory) { - - if (typeof define === 'function' && define.amd) { - define('gridster-coords', ['jquery'], factory); - } else { - root.GridsterCoords = factory(root.$ || root.jQuery); - } - -}(this, function($) { - /** - * Creates objects with coordinates (x1, y1, x2, y2, cx, cy, width, height) - * to simulate DOM elements on the screen. - * Coords is used by Gridster to create a faux grid with any DOM element can - * collide. - * - * @class Coords - * @param {HTMLElement|Object} obj The jQuery HTMLElement or a object with: left, - * top, width and height properties. - * @return {Object} Coords instance. - * @constructor - */ - function Coords(obj) { - if (obj[0] && $.isPlainObject(obj[0])) { - this.data = obj[0]; - }else { - this.el = obj; - } - - this.isCoords = true; - this.coords = {}; - this.init(); - return this; - } - - - var fn = Coords.prototype; - - - fn.init = function(){ - this.set(); - this.original_coords = this.get(); - }; - - - fn.set = function(update, not_update_offsets) { - var el = this.el; - - if (el && !update) { - this.data = el.offset(); - this.data.width = el.width(); - this.data.height = el.height(); - } - - if (el && update && !not_update_offsets) { - var offset = el.offset(); - this.data.top = offset.top; - this.data.left = offset.left; - } - - var d = this.data; - - typeof d.left === 'undefined' && (d.left = d.x1); - typeof d.top === 'undefined' && (d.top = d.y1); - - this.coords.x1 = d.left; - this.coords.y1 = d.top; - this.coords.x2 = d.left + d.width; - this.coords.y2 = d.top + d.height; - this.coords.cx = d.left + (d.width / 2); - this.coords.cy = d.top + (d.height / 2); - this.coords.width = d.width; - this.coords.height = d.height; - this.coords.el = el || false ; - - return this; - }; - - - fn.update = function(data){ - if (!data && !this.el) { - return this; - } - - if (data) { - var new_data = $.extend({}, this.data, data); - this.data = new_data; - return this.set(true, true); - } - - this.set(true); - return this; - }; - - - fn.get = function(){ - return this.coords; - }; - - fn.destroy = function() { - this.el.removeData('coords'); - delete this.el; - }; - - //jQuery adapter - $.fn.coords = function() { - if (this.data('coords') ) { - return this.data('coords'); - } - - var ins = new Coords(this, arguments[0]); - this.data('coords', ins); - return ins; - }; - - return Coords; - -})); - -;(function(root, factory) { - - if (typeof define === 'function' && define.amd) { - define('gridster-collision', ['jquery', 'gridster-coords'], factory); - } else { - root.GridsterCollision = factory(root.$ || root.jQuery, - root.GridsterCoords); - } - -}(this, function($, Coords) { - - var defaults = { - colliders_context: document.body, - overlapping_region: 'C' - // ,on_overlap: function(collider_data){}, - // on_overlap_start : function(collider_data){}, - // on_overlap_stop : function(collider_data){} - }; - - - /** - * Detects collisions between a DOM element against other DOM elements or - * Coords objects. - * - * @class Collision - * @uses Coords - * @param {HTMLElement} el The jQuery wrapped HTMLElement. - * @param {HTMLElement|Array} colliders Can be a jQuery collection - * of HTMLElements or an Array of Coords instances. - * @param {Object} [options] An Object with all options you want to - * overwrite: - * @param {String} [options.overlapping_region] Determines when collision - * is valid, depending on the overlapped area. Values can be: 'N', 'S', - * 'W', 'E', 'C' or 'all'. Default is 'C'. - * @param {Function} [options.on_overlap_start] Executes a function the first - * time each `collider ` is overlapped. - * @param {Function} [options.on_overlap_stop] Executes a function when a - * `collider` is no longer collided. - * @param {Function} [options.on_overlap] Executes a function when the - * mouse is moved during the collision. - * @return {Object} Collision instance. - * @constructor - */ - function Collision(el, colliders, options) { - this.options = $.extend(defaults, options); - this.$element = el; - this.last_colliders = []; - this.last_colliders_coords = []; - this.set_colliders(colliders); - - this.init(); - } - - Collision.defaults = defaults; - - var fn = Collision.prototype; - - - fn.init = function() { - this.find_collisions(); - }; - - - fn.overlaps = function(a, b) { - var x = false; - var y = false; - - if ((b.x1 >= a.x1 && b.x1 <= a.x2) || - (b.x2 >= a.x1 && b.x2 <= a.x2) || - (a.x1 >= b.x1 && a.x2 <= b.x2) - ) { x = true; } - - if ((b.y1 >= a.y1 && b.y1 <= a.y2) || - (b.y2 >= a.y1 && b.y2 <= a.y2) || - (a.y1 >= b.y1 && a.y2 <= b.y2) - ) { y = true; } - - return (x && y); - }; - - - fn.detect_overlapping_region = function(a, b){ - var regionX = ''; - var regionY = ''; - - if (a.y1 > b.cy && a.y1 < b.y2) { regionX = 'N'; } - if (a.y2 > b.y1 && a.y2 < b.cy) { regionX = 'S'; } - if (a.x1 > b.cx && a.x1 < b.x2) { regionY = 'W'; } - if (a.x2 > b.x1 && a.x2 < b.cx) { regionY = 'E'; } - - return (regionX + regionY) || 'C'; - }; - - - fn.calculate_overlapped_area_coords = function(a, b){ - var x1 = Math.max(a.x1, b.x1); - var y1 = Math.max(a.y1, b.y1); - var x2 = Math.min(a.x2, b.x2); - var y2 = Math.min(a.y2, b.y2); - - return $({ - left: x1, - top: y1, - width : (x2 - x1), - height: (y2 - y1) - }).coords().get(); - }; - - - fn.calculate_overlapped_area = function(coords){ - return (coords.width * coords.height); - }; - - - fn.manage_colliders_start_stop = function(new_colliders_coords, start_callback, stop_callback){ - var last = this.last_colliders_coords; - - for (var i = 0, il = last.length; i < il; i++) { - if ($.inArray(last[i], new_colliders_coords) === -1) { - start_callback.call(this, last[i]); - } - } - - for (var j = 0, jl = new_colliders_coords.length; j < jl; j++) { - if ($.inArray(new_colliders_coords[j], last) === -1) { - stop_callback.call(this, new_colliders_coords[j]); - } - - } - }; - - - fn.find_collisions = function(player_data_coords){ - var self = this; - var overlapping_region = this.options.overlapping_region; - var colliders_coords = []; - var colliders_data = []; - var $colliders = (this.colliders || this.$colliders); - var count = $colliders.length; - var player_coords = self.$element.coords() - .update(player_data_coords || false).get(); - - while(count--){ - var $collider = self.$colliders ? - $($colliders[count]) : $colliders[count]; - var $collider_coords_ins = ($collider.isCoords) ? - $collider : $collider.coords(); - var collider_coords = $collider_coords_ins.get(); - var overlaps = self.overlaps(player_coords, collider_coords); - - if (!overlaps) { - continue; - } - - var region = self.detect_overlapping_region( - player_coords, collider_coords); - - //todo: make this an option - if (region === overlapping_region || overlapping_region === 'all') { - - var area_coords = self.calculate_overlapped_area_coords( - player_coords, collider_coords); - var area = self.calculate_overlapped_area(area_coords); - var collider_data = { - area: area, - area_coords : area_coords, - region: region, - coords: collider_coords, - player_coords: player_coords, - el: $collider - }; - - if (self.options.on_overlap) { - self.options.on_overlap.call(this, collider_data); - } - colliders_coords.push($collider_coords_ins); - colliders_data.push(collider_data); - } - } - - if (self.options.on_overlap_stop || self.options.on_overlap_start) { - this.manage_colliders_start_stop(colliders_coords, - self.options.on_overlap_start, self.options.on_overlap_stop); - } - - this.last_colliders_coords = colliders_coords; - - return colliders_data; - }; - - - fn.get_closest_colliders = function(player_data_coords){ - var colliders = this.find_collisions(player_data_coords); - - colliders.sort(function(a, b) { - /* if colliders are being overlapped by the "C" (center) region, - * we have to set a lower index in the array to which they are placed - * above in the grid. */ - if (a.region === 'C' && b.region === 'C') { - if (a.coords.y1 < b.coords.y1 || a.coords.x1 < b.coords.x1) { - return - 1; - }else{ - return 1; - } - } - - if (a.area < b.area) { - return 1; - } - - return 1; - }); - return colliders; - }; - - - fn.set_colliders = function(colliders) { - if (typeof colliders === 'string' || colliders instanceof $) { - this.$colliders = $(colliders, - this.options.colliders_context).not(this.$element); - }else{ - this.colliders = $(colliders); - } - }; - - - //jQuery adapter - $.fn.collision = function(collider, options) { - return new Collision( this, collider, options ); - }; - - return Collision; - -})); - -;(function(window, undefined) { - - /* Delay, debounce and throttle functions taken from underscore.js - * - * Copyright (c) 2009-2013 Jeremy Ashkenas, DocumentCloud and - * Investigative Reporters & Editors - * - * 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. - */ - - window.delay = function(func, wait) { - var args = Array.prototype.slice.call(arguments, 2); - return setTimeout(function(){ return func.apply(null, args); }, wait); - }; - - window.debounce = function(func, wait, immediate) { - var timeout; - return function() { - var context = this, args = arguments; - var later = function() { - timeout = null; - if (!immediate) func.apply(context, args); - }; - if (immediate && !timeout) func.apply(context, args); - clearTimeout(timeout); - timeout = setTimeout(later, wait); - }; - }; - - window.throttle = function(func, wait) { - var context, args, timeout, throttling, more, result; - var whenDone = debounce( - function(){ more = throttling = false; }, wait); - return function() { - context = this; args = arguments; - var later = function() { - timeout = null; - if (more) func.apply(context, args); - whenDone(); - }; - if (!timeout) timeout = setTimeout(later, wait); - if (throttling) { - more = true; - } else { - result = func.apply(context, args); - } - whenDone(); - throttling = true; - return result; - }; - }; - -})(window); - -;(function(root, factory) { - - if (typeof define === 'function' && define.amd) { - define('gridster-draggable', ['jquery'], factory); - } else { - root.GridsterDraggable = factory(root.$ || root.jQuery); - } - -}(this, function($) { - - var defaults = { - items: 'li', - distance: 1, - limit: true, - offset_left: 0, - autoscroll: true, - ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'], // or function - handle: null, - container_width: 0, // 0 == auto - move_element: true, - helper: false, // or 'clone' - remove_helper: true - // drag: function(e) {}, - // start : function(e, ui) {}, - // stop : function(e) {} - }; - - var $window = $(window); - var dir_map = { x : 'left', y : 'top' }; - var isTouch = !!('ontouchstart' in window); - - var capitalize = function(str) { - return str.charAt(0).toUpperCase() + str.slice(1); - }; - - var idCounter = 0; - var uniqId = function() { - return ++idCounter + ''; - } - - /** - * Basic drag implementation for DOM elements inside a container. - * Provide start/stop/drag callbacks. - * - * @class Draggable - * @param {HTMLElement} el The HTMLelement that contains all the widgets - * to be dragged. - * @param {Object} [options] An Object with all options you want to - * overwrite: - * @param {HTMLElement|String} [options.items] Define who will - * be the draggable items. Can be a CSS Selector String or a - * collection of HTMLElements. - * @param {Number} [options.distance] Distance in pixels after mousedown - * the mouse must move before dragging should start. - * @param {Boolean} [options.limit] Constrains dragging to the width of - * the container - * @param {Object|Function} [options.ignore_dragging] Array of node names - * that sould not trigger dragging, by default is `['INPUT', 'TEXTAREA', - * 'SELECT', 'BUTTON']`. If a function is used return true to ignore dragging. - * @param {offset_left} [options.offset_left] Offset added to the item - * that is being dragged. - * @param {Number} [options.drag] Executes a callback when the mouse is - * moved during the dragging. - * @param {Number} [options.start] Executes a callback when the drag - * starts. - * @param {Number} [options.stop] Executes a callback when the drag stops. - * @return {Object} Returns `el`. - * @constructor - */ - function Draggable(el, options) { - this.options = $.extend({}, defaults, options); - this.$document = $(document); - this.$container = $(el); - this.$dragitems = $(this.options.items, this.$container); - this.is_dragging = false; - this.player_min_left = 0 + this.options.offset_left; - this.id = uniqId(); - this.ns = '.gridster-draggable-' + this.id; - this.init(); - } - - Draggable.defaults = defaults; - - var fn = Draggable.prototype; - - fn.init = function() { - var pos = this.$container.css('position'); - this.calculate_dimensions(); - this.$container.css('position', pos === 'static' ? 'relative' : pos); - this.disabled = false; - this.events(); - - $(window).bind(this.nsEvent('resize'), - throttle($.proxy(this.calculate_dimensions, this), 200)); - }; - - fn.nsEvent = function(ev) { - return (ev || '') + this.ns; - }; - - fn.events = function() { - this.pointer_events = { - start: this.nsEvent('touchstart') + ' ' + this.nsEvent('mousedown'), - move: this.nsEvent('touchmove') + ' ' + this.nsEvent('mousemove'), - end: this.nsEvent('touchend') + ' ' + this.nsEvent('mouseup'), - }; - - this.$container.on(this.nsEvent('selectstart'), - $.proxy(this.on_select_start, this)); - - this.$container.on(this.pointer_events.start, this.options.items, - $.proxy(this.drag_handler, this)); - - this.$document.on(this.pointer_events.end, $.proxy(function(e) { - this.is_dragging = false; - if (this.disabled) { return; } - this.$document.off(this.pointer_events.move); - if (this.drag_start) { - this.on_dragstop(e); - } - }, this)); - }; - - fn.get_actual_pos = function($el) { - var pos = $el.position(); - return pos; - }; - - - fn.get_mouse_pos = function(e) { - if (e.originalEvent && e.originalEvent.touches) { - var oe = e.originalEvent; - e = oe.touches.length ? oe.touches[0] : oe.changedTouches[0]; - } - - return { - left: e.clientX, - top: e.clientY - }; - }; - - - fn.get_offset = function(e) { - e.preventDefault(); - var mouse_actual_pos = this.get_mouse_pos(e); - var diff_x = Math.round( - mouse_actual_pos.left - this.mouse_init_pos.left); - var diff_y = Math.round(mouse_actual_pos.top - this.mouse_init_pos.top); - - var left = Math.round(this.el_init_offset.left + - diff_x - this.baseX + $(window).scrollLeft() - this.win_offset_x); - var top = Math.round(this.el_init_offset.top + - diff_y - this.baseY + $(window).scrollTop() - this.win_offset_y); - - if (this.options.limit) { - if (left > this.player_max_left) { - left = this.player_max_left; - } else if(left < this.player_min_left) { - left = this.player_min_left; - } - } - - return { - position: { - left: left, - top: top - }, - pointer: { - left: mouse_actual_pos.left, - top: mouse_actual_pos.top, - diff_left: diff_x + ($(window).scrollLeft() - this.win_offset_x), - diff_top: diff_y + ($(window).scrollTop() - this.win_offset_y) - } - }; - }; - - - fn.get_drag_data = function(e) { - var offset = this.get_offset(e); - offset.$player = this.$player; - offset.$helper = this.helper ? this.$helper : this.$player; - - return offset; - }; - - - fn.set_limits = function(container_width) { - container_width || (container_width = this.$container.width()); - this.player_max_left = (container_width - this.player_width + - - this.options.offset_left); - - this.options.container_width = container_width; - - return this; - }; - - - fn.scroll_in = function(axis, data) { - var dir_prop = dir_map[axis]; - - var area_size = 50; - var scroll_inc = 30; - - var is_x = axis === 'x'; - var window_size = is_x ? this.window_width : this.window_height; - var doc_size = is_x ? $(document).width() : $(document).height(); - var player_size = is_x ? this.$player.width() : this.$player.height(); - - var next_scroll; - var scroll_offset = $window['scroll' + capitalize(dir_prop)](); - var min_window_pos = scroll_offset; - var max_window_pos = min_window_pos + window_size; - - var mouse_next_zone = max_window_pos - area_size; // down/right - var mouse_prev_zone = min_window_pos + area_size; // up/left - - var abs_mouse_pos = min_window_pos + data.pointer[dir_prop]; - - var max_player_pos = (doc_size - window_size + player_size); - - if (abs_mouse_pos >= mouse_next_zone) { - next_scroll = scroll_offset + scroll_inc; - if (next_scroll < max_player_pos) { - $window['scroll' + capitalize(dir_prop)](next_scroll); - this['scroll_offset_' + axis] += scroll_inc; - } - } - - if (abs_mouse_pos <= mouse_prev_zone) { - next_scroll = scroll_offset - scroll_inc; - if (next_scroll > 0) { - $window['scroll' + capitalize(dir_prop)](next_scroll); - this['scroll_offset_' + axis] -= scroll_inc; - } - } - - return this; - }; - - - fn.manage_scroll = function(data) { - this.scroll_in('x', data); - this.scroll_in('y', data); - }; - - - fn.calculate_dimensions = function(e) { - this.window_height = $window.height(); - this.window_width = $window.width(); - }; - - - fn.drag_handler = function(e) { - var node = e.target.nodeName; - // skip if drag is disabled, or click was not done with the mouse primary button - if (this.disabled || e.which !== 1 && !isTouch) { - return; - } - - if (this.ignore_drag(e)) { - return; - } - - var self = this; - var first = true; - this.$player = $(e.currentTarget); - - this.el_init_pos = this.get_actual_pos(this.$player); - this.mouse_init_pos = this.get_mouse_pos(e); - this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top; - - this.$document.on(this.pointer_events.move, function(mme) { - var mouse_actual_pos = self.get_mouse_pos(mme); - var diff_x = Math.abs( - mouse_actual_pos.left - self.mouse_init_pos.left); - var diff_y = Math.abs( - mouse_actual_pos.top - self.mouse_init_pos.top); - if (!(diff_x > self.options.distance || - diff_y > self.options.distance) - ) { - return false; - } - - if (first) { - first = false; - self.on_dragstart.call(self, mme); - return false; - } - - if (self.is_dragging === true) { - self.on_dragmove.call(self, mme); - } - - return false; - }); - - if (!isTouch) { return false; } - }; - - - fn.on_dragstart = function(e) { - e.preventDefault(); - - if (this.is_dragging) { return this; } - - this.drag_start = this.is_dragging = true; - var offset = this.$container.offset(); - this.baseX = Math.round(offset.left); - this.baseY = Math.round(offset.top); - this.initial_container_width = this.options.container_width || this.$container.width(); - - if (this.options.helper === 'clone') { - this.$helper = this.$player.clone() - .appendTo(this.$container).addClass('helper'); - this.helper = true; - } else { - this.helper = false; - } - - this.win_offset_y = $(window).scrollTop(); - this.win_offset_x = $(window).scrollLeft(); - this.scroll_offset_y = 0; - this.scroll_offset_x = 0; - this.el_init_offset = this.$player.offset(); - this.player_width = this.$player.width(); - this.player_height = this.$player.height(); - - this.set_limits(this.options.container_width); - - if (this.options.start) { - this.options.start.call(this.$player, e, this.get_drag_data(e)); - } - return false; - }; - - - fn.on_dragmove = function(e) { - var data = this.get_drag_data(e); - - this.options.autoscroll && this.manage_scroll(data); - - if (this.options.move_element) { - (this.helper ? this.$helper : this.$player).css({ - 'position': 'absolute', - 'left' : data.position.left, - 'top' : data.position.top - }); - } - - var last_position = this.last_position || data.position; - data.prev_position = last_position; - - if (this.options.drag) { - this.options.drag.call(this.$player, e, data); - } - - this.last_position = data.position; - return false; - }; - - - fn.on_dragstop = function(e) { - var data = this.get_drag_data(e); - this.drag_start = false; - - if (this.options.stop) { - this.options.stop.call(this.$player, e, data); - } - - if (this.helper && this.options.remove_helper) { - this.$helper.remove(); - } - - return false; - }; - - fn.on_select_start = function(e) { - if (this.disabled) { return; } - - if (this.ignore_drag(e)) { - return; - } - - return false; - }; - - fn.enable = function() { - this.disabled = false; - }; - - fn.disable = function() { - this.disabled = true; - }; - - fn.destroy = function() { - this.disable(); - - this.$container.off(this.ns); - this.$document.off(this.ns); - $(window).off(this.ns); - - $.removeData(this.$container, 'drag'); - }; - - fn.ignore_drag = function(event) { - if (this.options.handle) { - return !$(event.target).is(this.options.handle); - } - - if ($.isFunction(this.options.ignore_dragging)) { - return this.options.ignore_dragging(event); - } - - return $(event.target).is(this.options.ignore_dragging.join(', ')); - }; - - //jQuery adapter - $.fn.drag = function ( options ) { - return new Draggable(this, options); - }; - - return Draggable; - -})); - -;(function(root, factory) { - - if (typeof define === 'function' && define.amd) { - define(['jquery', 'gridster-draggable', 'gridster-collision'], factory); - } else { - root.Gridster = factory(root.$ || root.jQuery, root.GridsterDraggable, - root.GridsterCollision); - } - - }(this, function($, Draggable, Collision) { - - var defaults = { - namespace: '', - widget_selector: 'li', - widget_margins: [10, 10], - widget_base_dimensions: [400, 225], - extra_rows: 0, - extra_cols: 0, - min_cols: 1, - max_cols: Infinity, - min_rows: 15, - max_size_x: false, - autogrow_cols: false, - autogenerate_stylesheet: true, - avoid_overlapped_widgets: true, - auto_init: true, - serialize_params: function($w, wgd) { - return { - col: wgd.col, - row: wgd.row, - size_x: wgd.size_x, - size_y: wgd.size_y - }; - }, - collision: {}, - draggable: { - items: '.gs-w', - distance: 4, - ignore_dragging: Draggable.defaults.ignore_dragging.slice(0) - }, - resize: { - enabled: false, - axes: ['both'], - handle_append_to: '', - handle_class: 'gs-resize-handle', - max_size: [Infinity, Infinity], - min_size: [1, 1] - } - }; - - /** - * @class Gridster - * @uses Draggable - * @uses Collision - * @param {HTMLElement} el The HTMLelement that contains all the widgets. - * @param {Object} [options] An Object with all options you want to - * overwrite: - * @param {HTMLElement|String} [options.widget_selector] Define who will - * be the draggable widgets. Can be a CSS Selector String or a - * collection of HTMLElements - * @param {Array} [options.widget_margins] Margin between widgets. - * The first index for the horizontal margin (left, right) and - * the second for the vertical margin (top, bottom). - * @param {Array} [options.widget_base_dimensions] Base widget dimensions - * in pixels. The first index for the width and the second for the - * height. - * @param {Number} [options.extra_cols] Add more columns in addition to - * those that have been calculated. - * @param {Number} [options.extra_rows] Add more rows in addition to - * those that have been calculated. - * @param {Number} [options.min_cols] The minimum required columns. - * @param {Number} [options.max_cols] The maximum columns possible (set to null - * for no maximum). - * @param {Number} [options.min_rows] The minimum required rows. - * @param {Number} [options.max_size_x] The maximum number of columns - * that a widget can span. - * @param {Boolean} [options.autogenerate_stylesheet] If true, all the - * CSS required to position all widgets in their respective columns - * and rows will be generated automatically and injected to the - * `` of the document. You can set this to false, and write - * your own CSS targeting rows and cols via data-attributes like so: - * `[data-col="1"] { left: 10px; }` - * @param {Boolean} [options.avoid_overlapped_widgets] Avoid that widgets loaded - * from the DOM can be overlapped. It is helpful if the positions were - * bad stored in the database or if there was any conflict. - * @param {Boolean} [options.auto_init] Automatically call gridster init - * method or not when the plugin is instantiated. - * @param {Function} [options.serialize_params] Return the data you want - * for each widget in the serialization. Two arguments are passed: - * `$w`: the jQuery wrapped HTMLElement, and `wgd`: the grid - * coords object (`col`, `row`, `size_x`, `size_y`). - * @param {Object} [options.collision] An Object with all options for - * Collision class you want to overwrite. See Collision docs for - * more info. - * @param {Object} [options.draggable] An Object with all options for - * Draggable class you want to overwrite. See Draggable docs for more - * info. - * @param {Object|Function} [options.draggable.ignore_dragging] Note that - * if you use a Function, and resize is enabled, you should ignore the - * resize handlers manually (options.resize.handle_class). - * @param {Object} [options.resize] An Object with resize config options. - * @param {Boolean} [options.resize.enabled] Set to true to enable - * resizing. - * @param {Array} [options.resize.axes] Axes in which widgets can be - * resized. Possible values: ['x', 'y', 'both']. - * @param {String} [options.resize.handle_append_to] Set a valid CSS - * selector to append resize handles to. - * @param {String} [options.resize.handle_class] CSS class name used - * by resize handles. - * @param {Array} [options.resize.max_size] Limit widget dimensions - * when resizing. Array values should be integers: - * `[max_cols_occupied, max_rows_occupied]` - * @param {Array} [options.resize.min_size] Limit widget dimensions - * when resizing. Array values should be integers: - * `[min_cols_occupied, min_rows_occupied]` - * @param {Function} [options.resize.start] Function executed - * when resizing starts. - * @param {Function} [otions.resize.resize] Function executed - * during the resizing. - * @param {Function} [options.resize.stop] Function executed - * when resizing stops. - * - * @constructor - */ - function Gridster(el, options) { - this.options = $.extend(true, {}, defaults, options); - this.$el = $(el); - this.$wrapper = this.$el.parent(); - this.$widgets = this.$el.children( - this.options.widget_selector).addClass('gs-w'); - this.widgets = []; - this.$changed = $([]); - this.wrapper_width = this.$wrapper.width(); - this.min_widget_width = (this.options.widget_margins[0] * 2) + - this.options.widget_base_dimensions[0]; - this.min_widget_height = (this.options.widget_margins[1] * 2) + - this.options.widget_base_dimensions[1]; - - this.generated_stylesheets = []; - this.$style_tags = $([]); - - this.options.auto_init && this.init(); - } - - Gridster.defaults = defaults; - Gridster.generated_stylesheets = []; - - - /** - * Sorts an Array of grid coords objects (representing the grid coords of - * each widget) in ascending way. - * - * @method sort_by_row_asc - * @param {Array} widgets Array of grid coords objects - * @return {Array} Returns the array sorted. - */ - Gridster.sort_by_row_asc = function(widgets) { - widgets = widgets.sort(function(a, b) { - if (!a.row) { - a = $(a).coords().grid; - b = $(b).coords().grid; - } - - if (a.row > b.row) { - return 1; - } - return -1; - }); - - return widgets; - }; - - - /** - * Sorts an Array of grid coords objects (representing the grid coords of - * each widget) placing first the empty cells upper left. - * - * @method sort_by_row_and_col_asc - * @param {Array} widgets Array of grid coords objects - * @return {Array} Returns the array sorted. - */ - Gridster.sort_by_row_and_col_asc = function(widgets) { - widgets = widgets.sort(function(a, b) { - if (a.row > b.row || a.row === b.row && a.col > b.col) { - return 1; - } - return -1; - }); - - return widgets; - }; - - - /** - * Sorts an Array of grid coords objects by column (representing the grid - * coords of each widget) in ascending way. - * - * @method sort_by_col_asc - * @param {Array} widgets Array of grid coords objects - * @return {Array} Returns the array sorted. - */ - Gridster.sort_by_col_asc = function(widgets) { - widgets = widgets.sort(function(a, b) { - if (a.col > b.col) { - return 1; - } - return -1; - }); - - return widgets; - }; - - - /** - * Sorts an Array of grid coords objects (representing the grid coords of - * each widget) in descending way. - * - * @method sort_by_row_desc - * @param {Array} widgets Array of grid coords objects - * @return {Array} Returns the array sorted. - */ - Gridster.sort_by_row_desc = function(widgets) { - widgets = widgets.sort(function(a, b) { - if (a.row + a.size_y < b.row + b.size_y) { - return 1; - } - return -1; - }); - return widgets; - }; - - - - /** Instance Methods **/ - - var fn = Gridster.prototype; - - fn.init = function() { - this.options.resize.enabled && this.setup_resize(); - this.generate_grid_and_stylesheet(); - this.get_widgets_from_DOM(); - this.set_dom_grid_height(); - this.set_dom_grid_width(); - this.$wrapper.addClass('ready'); - this.draggable(); - this.options.resize.enabled && this.resizable(); - - $(window).bind('resize.gridster', throttle( - $.proxy(this.recalculate_faux_grid, this), 200)); - }; - - - /** - * Disables dragging. - * - * @method disable - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.disable = function() { - this.$wrapper.find('.player-revert').removeClass('player-revert'); - this.drag_api.disable(); - return this; - }; - - - /** - * Enables dragging. - * - * @method enable - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.enable = function() { - this.drag_api.enable(); - return this; - }; - - - - /** - * Disables drag-and-drop widget resizing. - * - * @method disable - * @return {Class} Returns instance of gridster Class. - */ - fn.disable_resize = function() { - this.$el.addClass('gs-resize-disabled'); - this.resize_api.disable(); - return this; - }; - - - /** - * Enables drag-and-drop widget resizing. - * - * @method enable - * @return {Class} Returns instance of gridster Class. - */ - fn.enable_resize = function() { - this.$el.removeClass('gs-resize-disabled'); - this.resize_api.enable(); - return this; - }; - - - /** - * Add a new widget to the grid. - * - * @method add_widget - * @param {String|HTMLElement} html The string representing the HTML of the widget - * or the HTMLElement. - * @param {Number} [size_x] The nº of rows the widget occupies horizontally. - * @param {Number} [size_y] The nº of columns the widget occupies vertically. - * @param {Number} [col] The column the widget should start in. - * @param {Number} [row] The row the widget should start in. - * @param {Array} [max_size] max_size Maximun size (in units) for width and height. - * @param {Array} [min_size] min_size Minimum size (in units) for width and height. - * @return {HTMLElement} Returns the jQuery wrapped HTMLElement representing. - * the widget that was just created. - */ - fn.add_widget = function(html, size_x, size_y, col, row, max_size, min_size) { - var pos; - size_x || (size_x = 1); - size_y || (size_y = 1); - - if (!col & !row) { - pos = this.next_position(size_x, size_y); - } else { - pos = { - col: col, - row: row, - size_x: size_x, - size_y: size_y - }; - - this.empty_cells(col, row, size_x, size_y); - } - - var $w = $(html).attr({ - 'data-col': pos.col, - 'data-row': pos.row, - 'data-sizex' : size_x, - 'data-sizey' : size_y - }).addClass('gs-w').appendTo(this.$el).hide(); - - this.$widgets = this.$widgets.add($w); - - this.register_widget($w); - - this.add_faux_rows(pos.size_y); - //this.add_faux_cols(pos.size_x); - - if (max_size) { - this.set_widget_max_size($w, max_size); - } - - if (min_size) { - this.set_widget_min_size($w, min_size); - } - - this.set_dom_grid_width(); - this.set_dom_grid_height(); - - this.drag_api.set_limits(this.cols * this.min_widget_width); - - return $w.fadeIn(); - }; - - - /** - * Change widget size limits. - * - * @method set_widget_min_size - * @param {HTMLElement|Number} $widget The jQuery wrapped HTMLElement - * representing the widget or an index representing the desired widget. - * @param {Array} min_size Minimum size (in units) for width and height. - * @return {HTMLElement} Returns instance of gridster Class. - */ - fn.set_widget_min_size = function($widget, min_size) { - $widget = typeof $widget === 'number' ? - this.$widgets.eq($widget) : $widget; - - if (!$widget.length) { return this; } - - var wgd = $widget.data('coords').grid; - wgd.min_size_x = min_size[0]; - wgd.min_size_y = min_size[1]; - - return this; - }; - - - /** - * Change widget size limits. - * - * @method set_widget_max_size - * @param {HTMLElement|Number} $widget The jQuery wrapped HTMLElement - * representing the widget or an index representing the desired widget. - * @param {Array} max_size Maximun size (in units) for width and height. - * @return {HTMLElement} Returns instance of gridster Class. - */ - fn.set_widget_max_size = function($widget, max_size) { - $widget = typeof $widget === 'number' ? - this.$widgets.eq($widget) : $widget; - - if (!$widget.length) { return this; } - - var wgd = $widget.data('coords').grid; - wgd.max_size_x = max_size[0]; - wgd.max_size_y = max_size[1]; - - return this; - }; - - - /** - * Append the resize handle into a widget. - * - * @method add_resize_handle - * @param {HTMLElement} $widget The jQuery wrapped HTMLElement - * representing the widget. - * @return {HTMLElement} Returns instance of gridster Class. - */ - fn.add_resize_handle = function($w) { - var append_to = this.options.resize.handle_append_to; - $(this.resize_handle_tpl).appendTo( append_to ? $(append_to, $w) : $w); - - return this; - }; - - - /** - * Change the size of a widget. Width is limited to the current grid width. - * - * @method resize_widget - * @param {HTMLElement} $widget The jQuery wrapped HTMLElement - * representing the widget. - * @param {Number} size_x The number of columns that will occupy the widget. - * By default size_x is limited to the space available from - * the column where the widget begins, until the last column to the right. - * @param {Number} size_y The number of rows that will occupy the widget. - * @param {Function} [callback] Function executed when the widget is removed. - * @return {HTMLElement} Returns $widget. - */ - fn.resize_widget = function($widget, size_x, size_y, callback) { - var wgd = $widget.coords().grid; - var col = wgd.col; - var max_cols = this.options.max_cols; - var old_size_y = wgd.size_y; - var old_col = wgd.col; - var new_col = old_col; - - size_x || (size_x = wgd.size_x); - size_y || (size_y = wgd.size_y); - - if (max_cols !== Infinity) { - size_x = Math.min(size_x, max_cols - col + 1); - } - - if (size_y > old_size_y) { - this.add_faux_rows(Math.max(size_y - old_size_y, 0)); - } - - var player_rcol = (col + size_x - 1); - if (player_rcol > this.cols) { - this.add_faux_cols(player_rcol - this.cols); - } - - var new_grid_data = { - col: new_col, - row: wgd.row, - size_x: size_x, - size_y: size_y - }; - - this.mutate_widget_in_gridmap($widget, wgd, new_grid_data); - - this.set_dom_grid_height(); - this.set_dom_grid_width(); - - if (callback) { - callback.call(this, new_grid_data.size_x, new_grid_data.size_y); - } - - return $widget; - }; - - - /** - * Mutate widget dimensions and position in the grid map. - * - * @method mutate_widget_in_gridmap - * @param {HTMLElement} $widget The jQuery wrapped HTMLElement - * representing the widget to mutate. - * @param {Object} wgd Current widget grid data (col, row, size_x, size_y). - * @param {Object} new_wgd New widget grid data. - * @return {HTMLElement} Returns instance of gridster Class. - */ - fn.mutate_widget_in_gridmap = function($widget, wgd, new_wgd) { - var old_size_x = wgd.size_x; - var old_size_y = wgd.size_y; - - var old_cells_occupied = this.get_cells_occupied(wgd); - var new_cells_occupied = this.get_cells_occupied(new_wgd); - - var empty_cols = []; - $.each(old_cells_occupied.cols, function(i, col) { - if ($.inArray(col, new_cells_occupied.cols) === -1) { - empty_cols.push(col); - } - }); - - var occupied_cols = []; - $.each(new_cells_occupied.cols, function(i, col) { - if ($.inArray(col, old_cells_occupied.cols) === -1) { - occupied_cols.push(col); - } - }); - - var empty_rows = []; - $.each(old_cells_occupied.rows, function(i, row) { - if ($.inArray(row, new_cells_occupied.rows) === -1) { - empty_rows.push(row); - } - }); - - var occupied_rows = []; - $.each(new_cells_occupied.rows, function(i, row) { - if ($.inArray(row, old_cells_occupied.rows) === -1) { - occupied_rows.push(row); - } - }); - - this.remove_from_gridmap(wgd); - - if (occupied_cols.length) { - var cols_to_empty = [ - new_wgd.col, new_wgd.row, new_wgd.size_x, Math.min(old_size_y, new_wgd.size_y), $widget - ]; - this.empty_cells.apply(this, cols_to_empty); - } - - if (occupied_rows.length) { - var rows_to_empty = [new_wgd.col, new_wgd.row, new_wgd.size_x, new_wgd.size_y, $widget]; - this.empty_cells.apply(this, rows_to_empty); - } - - // not the same that wgd = new_wgd; - wgd.col = new_wgd.col; - wgd.row = new_wgd.row; - wgd.size_x = new_wgd.size_x; - wgd.size_y = new_wgd.size_y; - - this.add_to_gridmap(new_wgd, $widget); - - $widget.removeClass('player-revert'); - - //update coords instance attributes - $widget.data('coords').update({ - width: (new_wgd.size_x * this.options.widget_base_dimensions[0] + - ((new_wgd.size_x - 1) * this.options.widget_margins[0]) * 2), - height: (new_wgd.size_y * this.options.widget_base_dimensions[1] + - ((new_wgd.size_y - 1) * this.options.widget_margins[1]) * 2) - }); - - $widget.attr({ - 'data-col': new_wgd.col, - 'data-row': new_wgd.row, - 'data-sizex': new_wgd.size_x, - 'data-sizey': new_wgd.size_y - }); - - if (empty_cols.length) { - var cols_to_remove_holes = [ - empty_cols[0], new_wgd.row, - empty_cols.length, - Math.min(old_size_y, new_wgd.size_y), - $widget - ]; - - this.remove_empty_cells.apply(this, cols_to_remove_holes); - } - - if (empty_rows.length) { - var rows_to_remove_holes = [ - new_wgd.col, new_wgd.row, new_wgd.size_x, new_wgd.size_y, $widget - ]; - this.remove_empty_cells.apply(this, rows_to_remove_holes); - } - - this.move_widget_up($widget); - - return this; - }; - - - /** - * Move down widgets in cells represented by the arguments col, row, size_x, - * size_y - * - * @method empty_cells - * @param {Number} col The column where the group of cells begin. - * @param {Number} row The row where the group of cells begin. - * @param {Number} size_x The number of columns that the group of cells - * occupy. - * @param {Number} size_y The number of rows that the group of cells - * occupy. - * @param {HTMLElement} $exclude Exclude widgets from being moved. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.empty_cells = function(col, row, size_x, size_y, $exclude) { - var $nexts = this.widgets_below({ - col: col, - row: row - size_y, - size_x: size_x, - size_y: size_y - }); - - $nexts.not($exclude).each($.proxy(function(i, w) { - var wgd = $(w).coords().grid; - if ( !(wgd.row <= (row + size_y - 1))) { return; } - var diff = (row + size_y) - wgd.row; - this.move_widget_down($(w), diff); - }, this)); - - this.set_dom_grid_height(); - - return this; - }; - - - /** - * Move up widgets below cells represented by the arguments col, row, size_x, - * size_y. - * - * @method remove_empty_cells - * @param {Number} col The column where the group of cells begin. - * @param {Number} row The row where the group of cells begin. - * @param {Number} size_x The number of columns that the group of cells - * occupy. - * @param {Number} size_y The number of rows that the group of cells - * occupy. - * @param {HTMLElement} exclude Exclude widgets from being moved. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.remove_empty_cells = function(col, row, size_x, size_y, exclude) { - var $nexts = this.widgets_below({ - col: col, - row: row, - size_x: size_x, - size_y: size_y - }); - - $nexts.not(exclude).each($.proxy(function(i, widget) { - this.move_widget_up( $(widget), size_y ); - }, this)); - - this.set_dom_grid_height(); - - return this; - }; - - - /** - * Get the most left column below to add a new widget. - * - * @method next_position - * @param {Number} size_x The nº of rows the widget occupies horizontally. - * @param {Number} size_y The nº of columns the widget occupies vertically. - * @return {Object} Returns a grid coords object representing the future - * widget coords. - */ - fn.next_position = function(size_x, size_y) { - size_x || (size_x = 1); - size_y || (size_y = 1); - var ga = this.gridmap; - var cols_l = ga.length; - var valid_pos = []; - var rows_l; - - for (var c = 1; c < cols_l; c++) { - rows_l = ga[c].length; - for (var r = 1; r <= rows_l; r++) { - var can_move_to = this.can_move_to({ - size_x: size_x, - size_y: size_y - }, c, r); - - if (can_move_to) { - valid_pos.push({ - col: c, - row: r, - size_y: size_y, - size_x: size_x - }); - } - } - } - - if (valid_pos.length) { - return Gridster.sort_by_row_and_col_asc(valid_pos)[0]; - } - return false; - }; - - - /** - * Remove a widget from the grid. - * - * @method remove_widget - * @param {HTMLElement} el The jQuery wrapped HTMLElement you want to remove. - * @param {Boolean|Function} silent If true, widgets below the removed one - * will not move up. If a Function is passed it will be used as callback. - * @param {Function} callback Function executed when the widget is removed. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.remove_widget = function(el, silent, callback) { - var $el = el instanceof $ ? el : $(el); - var wgd = $el.coords().grid; - - // if silent is a function assume it's a callback - if ($.isFunction(silent)) { - callback = silent; - silent = false; - } - - this.cells_occupied_by_placeholder = {}; - this.$widgets = this.$widgets.not($el); - - var $nexts = this.widgets_below($el); - - this.remove_from_gridmap(wgd); - - $el.fadeOut($.proxy(function() { - $el.remove(); - - if (!silent) { - $nexts.each($.proxy(function(i, widget) { - this.move_widget_up( $(widget), wgd.size_y ); - }, this)); - } - - this.set_dom_grid_height(); - - if (callback) { - callback.call(this, el); - } - }, this)); - - return this; - }; - - - /** - * Remove all widgets from the grid. - * - * @method remove_all_widgets - * @param {Function} callback Function executed for each widget removed. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.remove_all_widgets = function(callback) { - this.$widgets.each($.proxy(function(i, el){ - this.remove_widget(el, true, callback); - }, this)); - - return this; - }; - - - /** - * Returns a serialized array of the widgets in the grid. - * - * @method serialize - * @param {HTMLElement} [$widgets] The collection of jQuery wrapped - * HTMLElements you want to serialize. If no argument is passed all widgets - * will be serialized. - * @return {Array} Returns an Array of Objects with the data specified in - * the serialize_params option. - */ - fn.serialize = function($widgets) { - $widgets || ($widgets = this.$widgets); - - return $widgets.map($.proxy(function(i, widget) { - var $w = $(widget); - return this.options.serialize_params($w, $w.coords().grid); - }, this)).get(); - }; - - - /** - * Returns a serialized array of the widgets that have changed their - * position. - * - * @method serialize_changed - * @return {Array} Returns an Array of Objects with the data specified in - * the serialize_params option. - */ - fn.serialize_changed = function() { - return this.serialize(this.$changed); - }; - - - /** - * Convert widgets from DOM elements to "widget grid data" Objects. - * - * @method dom_to_coords - * @param {HTMLElement} $widget The widget to be converted. - */ - fn.dom_to_coords = function($widget) { - return { - 'col': parseInt($widget.attr('data-col'), 10), - 'row': parseInt($widget.attr('data-row'), 10), - 'size_x': parseInt($widget.attr('data-sizex'), 10) || 1, - 'size_y': parseInt($widget.attr('data-sizey'), 10) || 1, - 'max_size_x': parseInt($widget.attr('data-max-sizex'), 10) || false, - 'max_size_y': parseInt($widget.attr('data-max-sizey'), 10) || false, - 'min_size_x': parseInt($widget.attr('data-min-sizex'), 10) || false, - 'min_size_y': parseInt($widget.attr('data-min-sizey'), 10) || false, - 'el': $widget - }; - }; - - - /** - * Creates the grid coords object representing the widget an add it to the - * mapped array of positions. - * - * @method register_widget - * @param {HTMLElement|Object} $el jQuery wrapped HTMLElement representing - * the widget, or an "widget grid data" Object with (col, row, el ...). - * @return {Boolean} Returns true if the widget final position is different - * than the original. - */ - fn.register_widget = function($el) { - var isDOM = $el instanceof jQuery; - var wgd = isDOM ? this.dom_to_coords($el) : $el; - var posChanged = false; - isDOM || ($el = wgd.el); - - var empty_upper_row = this.can_go_widget_up(wgd); - if (empty_upper_row) { - wgd.row = empty_upper_row; - $el.attr('data-row', empty_upper_row); - this.$el.trigger('gridster:positionchanged', [wgd]); - posChanged = true; - } - - if (this.options.avoid_overlapped_widgets && - !this.can_move_to( - {size_x: wgd.size_x, size_y: wgd.size_y}, wgd.col, wgd.row) - ) { - $.extend(wgd, this.next_position(wgd.size_x, wgd.size_y)); - $el.attr({ - 'data-col': wgd.col, - 'data-row': wgd.row, - 'data-sizex': wgd.size_x, - 'data-sizey': wgd.size_y - }); - posChanged = true; - } - - // attach Coord object to player data-coord attribute - $el.data('coords', $el.coords()); - // Extend Coord object with grid position info - $el.data('coords').grid = wgd; - - this.add_to_gridmap(wgd, $el); - - this.options.resize.enabled && this.add_resize_handle($el); - - return posChanged; - }; - - - /** - * Update in the mapped array of positions the value of cells represented by - * the grid coords object passed in the `grid_data` param. - * - * @param {Object} grid_data The grid coords object representing the cells - * to update in the mapped array. - * @param {HTMLElement|Boolean} value Pass `false` or the jQuery wrapped - * HTMLElement, depends if you want to delete an existing position or add - * a new one. - * @method update_widget_position - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.update_widget_position = function(grid_data, value) { - this.for_each_cell_occupied(grid_data, function(col, row) { - if (!this.gridmap[col]) { return this; } - this.gridmap[col][row] = value; - }); - return this; - }; - - - /** - * Remove a widget from the mapped array of positions. - * - * @method remove_from_gridmap - * @param {Object} grid_data The grid coords object representing the cells - * to update in the mapped array. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.remove_from_gridmap = function(grid_data) { - return this.update_widget_position(grid_data, false); - }; - - - /** - * Add a widget to the mapped array of positions. - * - * @method add_to_gridmap - * @param {Object} grid_data The grid coords object representing the cells - * to update in the mapped array. - * @param {HTMLElement|Boolean} value The value to set in the specified - * position . - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.add_to_gridmap = function(grid_data, value) { - this.update_widget_position(grid_data, value || grid_data.el); - - if (grid_data.el) { - var $widgets = this.widgets_below(grid_data.el); - $widgets.each($.proxy(function(i, widget) { - this.move_widget_up( $(widget)); - }, this)); - } - }; - - - /** - * Make widgets draggable. - * - * @uses Draggable - * @method draggable - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.draggable = function() { - var self = this; - var draggable_options = $.extend(true, {}, this.options.draggable, { - offset_left: this.options.widget_margins[0], - offset_top: this.options.widget_margins[1], - container_width: this.cols * this.min_widget_width, - limit: true, - start: function(event, ui) { - self.$widgets.filter('.player-revert') - .removeClass('player-revert'); - - self.$player = $(this); - self.$helper = $(ui.$helper); - - self.helper = !self.$helper.is(self.$player); - - self.on_start_drag.call(self, event, ui); - self.$el.trigger('gridster:dragstart'); - }, - stop: function(event, ui) { - self.on_stop_drag.call(self, event, ui); - self.$el.trigger('gridster:dragstop'); - }, - drag: throttle(function(event, ui) { - self.on_drag.call(self, event, ui); - self.$el.trigger('gridster:drag'); - }, 60) - }); - - this.drag_api = this.$el.drag(draggable_options); - return this; - }; - - - /** - * Bind resize events to get resize working. - * - * @method resizable - * @return {Class} Returns instance of gridster Class. - */ - fn.resizable = function() { - this.resize_api = this.$el.drag({ - items: '.' + this.options.resize.handle_class, - offset_left: this.options.widget_margins[0], - container_width: this.container_width, - move_element: false, - resize: true, - limit: this.options.autogrow_cols ? false : true, - start: $.proxy(this.on_start_resize, this), - stop: $.proxy(function(event, ui) { - delay($.proxy(function() { - this.on_stop_resize(event, ui); - }, this), 120); - }, this), - drag: throttle($.proxy(this.on_resize, this), 60) - }); - - return this; - }; - - - /** - * Setup things required for resizing. Like build templates for drag handles. - * - * @method setup_resize - * @return {Class} Returns instance of gridster Class. - */ - fn.setup_resize = function() { - this.resize_handle_class = this.options.resize.handle_class; - var axes = this.options.resize.axes; - var handle_tpl = ''; - - this.resize_handle_tpl = $.map(axes, function(type) { - return handle_tpl.replace('{type}', type); - }).join(''); - - if ($.isArray(this.options.draggable.ignore_dragging)) { - this.options.draggable.ignore_dragging.push( - '.' + this.resize_handle_class); - } - - return this; - }; - - - /** - * This function is executed when the player begins to be dragged. - * - * @method on_start_drag - * @param {Event} event The original browser event - * @param {Object} ui A prepared ui object with useful drag-related data - */ - fn.on_start_drag = function(event, ui) { - this.$helper.add(this.$player).add(this.$wrapper).addClass('dragging'); - - this.highest_col = this.get_highest_occupied_cell().col; - - this.$player.addClass('player'); - this.player_grid_data = this.$player.coords().grid; - this.placeholder_grid_data = $.extend({}, this.player_grid_data); - - this.set_dom_grid_height(this.$el.height() + - (this.player_grid_data.size_y * this.min_widget_height)); - - this.set_dom_grid_width(this.cols); - - var pgd_sizex = this.player_grid_data.size_x; - var cols_diff = this.cols - this.highest_col; - - if (this.options.autogrow_cols && cols_diff <= pgd_sizex) { - this.add_faux_cols(Math.min(pgd_sizex - cols_diff, 1)); - } - - var colliders = this.faux_grid; - var coords = this.$player.data('coords').coords; - - this.cells_occupied_by_player = this.get_cells_occupied( - this.player_grid_data); - this.cells_occupied_by_placeholder = this.get_cells_occupied( - this.placeholder_grid_data); - - this.last_cols = []; - this.last_rows = []; - - // see jquery.collision.js - this.collision_api = this.$helper.collision( - colliders, this.options.collision); - - this.$preview_holder = $('<' + this.$player.get(0).tagName + ' />', { - 'class': 'preview-holder', - 'data-row': this.$player.attr('data-row'), - 'data-col': this.$player.attr('data-col'), - css: { - width: coords.width, - height: coords.height - } - }).appendTo(this.$el); - - if (this.options.draggable.start) { - this.options.draggable.start.call(this, event, ui); - } - }; - - - /** - * This function is executed when the player is being dragged. - * - * @method on_drag - * @param {Event} event The original browser event - * @param {Object} ui A prepared ui object with useful drag-related data - */ - fn.on_drag = function(event, ui) { - //break if dragstop has been fired - if (this.$player === null) { - return false; - } - - var abs_offset = { - left: ui.position.left + this.baseX, - top: ui.position.top + this.baseY - }; - - // auto grow cols - if (this.options.autogrow_cols) { - var prcol = this.placeholder_grid_data.col + - this.placeholder_grid_data.size_x - 1; - - // "- 1" due to adding at least 1 column in on_start_drag - if (prcol >= this.cols - 1 && this.options.max_cols >= this.cols + 1) { - this.add_faux_cols(1); - this.set_dom_grid_width(this.cols + 1); - this.drag_api.set_limits(this.container_width); - } - - this.collision_api.set_colliders(this.faux_grid); - } - - this.colliders_data = this.collision_api.get_closest_colliders( - abs_offset); - - this.on_overlapped_column_change( - this.on_start_overlapping_column, this.on_stop_overlapping_column); - - this.on_overlapped_row_change( - this.on_start_overlapping_row, this.on_stop_overlapping_row); - - - if (this.helper && this.$player) { - this.$player.css({ - 'left': ui.position.left, - 'top': ui.position.top - }); - } - - if (this.options.draggable.drag) { - this.options.draggable.drag.call(this, event, ui); - } - }; - - - /** - * This function is executed when the player stops being dragged. - * - * @method on_stop_drag - * @param {Event} event The original browser event - * @param {Object} ui A prepared ui object with useful drag-related data - */ - fn.on_stop_drag = function(event, ui) { - this.$helper.add(this.$player).add(this.$wrapper) - .removeClass('dragging'); - - ui.position.left = ui.position.left + this.baseX; - ui.position.top = ui.position.top + this.baseY; - this.colliders_data = this.collision_api.get_closest_colliders( - ui.position); - - this.on_overlapped_column_change( - this.on_start_overlapping_column, - this.on_stop_overlapping_column - ); - - this.on_overlapped_row_change( - this.on_start_overlapping_row, - this.on_stop_overlapping_row - ); - - this.$player.addClass('player-revert').removeClass('player') - .attr({ - 'data-col': this.placeholder_grid_data.col, - 'data-row': this.placeholder_grid_data.row - }).css({ - 'left': '', - 'top': '' - }); - - this.$changed = this.$changed.add(this.$player); - - this.cells_occupied_by_player = this.get_cells_occupied( - this.placeholder_grid_data); - this.set_cells_player_occupies( - this.placeholder_grid_data.col, this.placeholder_grid_data.row); - - this.$player.coords().grid.row = this.placeholder_grid_data.row; - this.$player.coords().grid.col = this.placeholder_grid_data.col; - - if (this.options.draggable.stop) { - this.options.draggable.stop.call(this, event, ui); - } - - this.$preview_holder.remove(); - - this.$player = null; - this.$helper = null; - this.placeholder_grid_data = {}; - this.player_grid_data = {}; - this.cells_occupied_by_placeholder = {}; - this.cells_occupied_by_player = {}; - - this.set_dom_grid_height(); - this.set_dom_grid_width(); - - if (this.options.autogrow_cols) { - this.drag_api.set_limits(this.cols * this.min_widget_width); - } - }; - - - /** - * This function is executed every time a widget starts to be resized. - * - * @method on_start_resize - * @param {Event} event The original browser event - * @param {Object} ui A prepared ui object with useful drag-related data - */ - fn.on_start_resize = function(event, ui) { - this.$resized_widget = ui.$player.closest('.gs-w'); - this.resize_coords = this.$resized_widget.coords(); - this.resize_wgd = this.resize_coords.grid; - this.resize_initial_width = this.resize_coords.coords.width; - this.resize_initial_height = this.resize_coords.coords.height; - this.resize_initial_sizex = this.resize_coords.grid.size_x; - this.resize_initial_sizey = this.resize_coords.grid.size_y; - this.resize_initial_col = this.resize_coords.grid.col; - this.resize_last_sizex = this.resize_initial_sizex; - this.resize_last_sizey = this.resize_initial_sizey; - - this.resize_max_size_x = Math.min(this.resize_wgd.max_size_x || - this.options.resize.max_size[0], - this.options.max_cols - this.resize_initial_col + 1); - this.resize_max_size_y = this.resize_wgd.max_size_y || - this.options.resize.max_size[1]; - - this.resize_min_size_x = (this.resize_wgd.min_size_x || - this.options.resize.min_size[0] || 1); - this.resize_min_size_y = (this.resize_wgd.min_size_y || - this.options.resize.min_size[1] || 1); - - this.resize_initial_last_col = this.get_highest_occupied_cell().col; - - this.set_dom_grid_width(this.cols); - - this.resize_dir = { - right: ui.$player.is('.' + this.resize_handle_class + '-x'), - bottom: ui.$player.is('.' + this.resize_handle_class + '-y') - }; - - this.$resized_widget.css({ - 'min-width': this.options.widget_base_dimensions[0], - 'min-height': this.options.widget_base_dimensions[1] - }); - - var nodeName = this.$resized_widget.get(0).tagName; - this.$resize_preview_holder = $('<' + nodeName + ' />', { - 'class': 'preview-holder resize-preview-holder', - 'data-row': this.$resized_widget.attr('data-row'), - 'data-col': this.$resized_widget.attr('data-col'), - 'css': { - 'width': this.resize_initial_width, - 'height': this.resize_initial_height - } - }).appendTo(this.$el); - - this.$resized_widget.addClass('resizing'); - - if (this.options.resize.start) { - this.options.resize.start.call(this, event, ui, this.$resized_widget); - } - - this.$el.trigger('gridster:resizestart'); - }; - - - /** - * This function is executed every time a widget stops being resized. - * - * @method on_stop_resize - * @param {Event} event The original browser event - * @param {Object} ui A prepared ui object with useful drag-related data - */ - fn.on_stop_resize = function(event, ui) { - this.$resized_widget - .removeClass('resizing') - .css({ - 'width': '', - 'height': '' - }); - - delay($.proxy(function() { - this.$resize_preview_holder - .remove() - .css({ - 'min-width': '', - 'min-height': '' - }); - - if (this.options.resize.stop) { - this.options.resize.stop.call(this, event, ui, this.$resized_widget); - } - - this.$el.trigger('gridster:resizestop'); - }, this), 300); - - this.set_dom_grid_width(); - - if (this.options.autogrow_cols) { - this.drag_api.set_limits(this.cols * this.min_widget_width); - } - }; - - - /** - * This function is executed when a widget is being resized. - * - * @method on_resize - * @param {Event} event The original browser event - * @param {Object} ui A prepared ui object with useful drag-related data - */ - fn.on_resize = function(event, ui) { - var rel_x = (ui.pointer.diff_left); - var rel_y = (ui.pointer.diff_top); - var wbd_x = this.options.widget_base_dimensions[0]; - var wbd_y = this.options.widget_base_dimensions[1]; - var margin_x = this.options.widget_margins[0]; - var margin_y = this.options.widget_margins[1]; - var max_size_x = this.resize_max_size_x; - var min_size_x = this.resize_min_size_x; - var max_size_y = this.resize_max_size_y; - var min_size_y = this.resize_min_size_y; - var autogrow = this.options.autogrow_cols; - var width; - var max_width = Infinity; - var max_height = Infinity; - - var inc_units_x = Math.ceil((rel_x / (wbd_x + margin_x * 2)) - 0.2); - var inc_units_y = Math.ceil((rel_y / (wbd_y + margin_y * 2)) - 0.2); - - var size_x = Math.max(1, this.resize_initial_sizex + inc_units_x); - var size_y = Math.max(1, this.resize_initial_sizey + inc_units_y); - - var max_cols = (this.container_width / this.min_widget_width) - - this.resize_initial_col + 1; - var limit_width = ((max_cols * this.min_widget_width) - margin_x * 2); - - size_x = Math.max(Math.min(size_x, max_size_x), min_size_x); - size_x = Math.min(max_cols, size_x); - width = (max_size_x * wbd_x) + ((size_x - 1) * margin_x * 2); - max_width = Math.min(width, limit_width); - min_width = (min_size_x * wbd_x) + ((size_x - 1) * margin_x * 2); - - size_y = Math.max(Math.min(size_y, max_size_y), min_size_y); - max_height = (max_size_y * wbd_y) + ((size_y - 1) * margin_y * 2); - min_height = (min_size_y * wbd_y) + ((size_y - 1) * margin_y * 2); - - if (this.resize_dir.right) { - size_y = this.resize_initial_sizey; - } else if (this.resize_dir.bottom) { - size_x = this.resize_initial_sizex; - } - - if (autogrow) { - var last_widget_col = this.resize_initial_col + size_x - 1; - if (autogrow && this.resize_initial_last_col <= last_widget_col) { - this.set_dom_grid_width(Math.max(last_widget_col + 1, this.cols)); - - if (this.cols < last_widget_col) { - this.add_faux_cols(last_widget_col - this.cols); - } - } - } - - var css_props = {}; - !this.resize_dir.bottom && (css_props.width = Math.max(Math.min( - this.resize_initial_width + rel_x, max_width), min_width)); - !this.resize_dir.right && (css_props.height = Math.max(Math.min( - this.resize_initial_height + rel_y, max_height), min_height)); - - this.$resized_widget.css(css_props); - - if (size_x !== this.resize_last_sizex || - size_y !== this.resize_last_sizey) { - - this.resize_widget(this.$resized_widget, size_x, size_y); - this.set_dom_grid_width(this.cols); - - this.$resize_preview_holder.css({ - 'width': '', - 'height': '' - }).attr({ - 'data-row': this.$resized_widget.attr('data-row'), - 'data-sizex': size_x, - 'data-sizey': size_y - }); - } - - if (this.options.resize.resize) { - this.options.resize.resize.call(this, event, ui, this.$resized_widget); - } - - this.$el.trigger('gridster:resize'); - - this.resize_last_sizex = size_x; - this.resize_last_sizey = size_y; - }; - - - /** - * Executes the callbacks passed as arguments when a column begins to be - * overlapped or stops being overlapped. - * - * @param {Function} start_callback Function executed when a new column - * begins to be overlapped. The column is passed as first argument. - * @param {Function} stop_callback Function executed when a column stops - * being overlapped. The column is passed as first argument. - * @method on_overlapped_column_change - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.on_overlapped_column_change = function(start_callback, stop_callback) { - if (!this.colliders_data.length) { - return this; - } - var cols = this.get_targeted_columns( - this.colliders_data[0].el.data.col); - - var last_n_cols = this.last_cols.length; - var n_cols = cols.length; - var i; - - for (i = 0; i < n_cols; i++) { - if ($.inArray(cols[i], this.last_cols) === -1) { - (start_callback || $.noop).call(this, cols[i]); - } - } - - for (i = 0; i< last_n_cols; i++) { - if ($.inArray(this.last_cols[i], cols) === -1) { - (stop_callback || $.noop).call(this, this.last_cols[i]); - } - } - - this.last_cols = cols; - - return this; - }; - - - /** - * Executes the callbacks passed as arguments when a row starts to be - * overlapped or stops being overlapped. - * - * @param {Function} start_callback Function executed when a new row begins - * to be overlapped. The row is passed as first argument. - * @param {Function} end_callback Function executed when a row stops being - * overlapped. The row is passed as first argument. - * @method on_overlapped_row_change - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.on_overlapped_row_change = function(start_callback, end_callback) { - if (!this.colliders_data.length) { - return this; - } - var rows = this.get_targeted_rows(this.colliders_data[0].el.data.row); - var last_n_rows = this.last_rows.length; - var n_rows = rows.length; - var i; - - for (i = 0; i < n_rows; i++) { - if ($.inArray(rows[i], this.last_rows) === -1) { - (start_callback || $.noop).call(this, rows[i]); - } - } - - for (i = 0; i < last_n_rows; i++) { - if ($.inArray(this.last_rows[i], rows) === -1) { - (end_callback || $.noop).call(this, this.last_rows[i]); - } - } - - this.last_rows = rows; - }; - - - /** - * Sets the current position of the player - * - * @param {Number} col - * @param {Number} row - * @param {Boolean} no_player - * @method set_player - * @return {object} - */ - fn.set_player = function(col, row, no_player) { - var self = this; - if (!no_player) { - this.empty_cells_player_occupies(); - } - var cell = !no_player ? self.colliders_data[0].el.data : {col: col}; - var to_col = cell.col; - var to_row = row || cell.row; - - this.player_grid_data = { - col: to_col, - row: to_row, - size_y : this.player_grid_data.size_y, - size_x : this.player_grid_data.size_x - }; - - this.cells_occupied_by_player = this.get_cells_occupied( - this.player_grid_data); - - var $overlapped_widgets = this.get_widgets_overlapped( - this.player_grid_data); - - var constraints = this.widgets_constraints($overlapped_widgets); - - this.manage_movements(constraints.can_go_up, to_col, to_row); - this.manage_movements(constraints.can_not_go_up, to_col, to_row); - - /* if there is not widgets overlapping in the new player position, - * update the new placeholder position. */ - if (!$overlapped_widgets.length) { - var pp = this.can_go_player_up(this.player_grid_data); - if (pp !== false) { - to_row = pp; - } - this.set_placeholder(to_col, to_row); - } - - return { - col: to_col, - row: to_row - }; - }; - - - /** - * See which of the widgets in the $widgets param collection can go to - * a upper row and which not. - * - * @method widgets_contraints - * @param {jQuery} $widgets A jQuery wrapped collection of - * HTMLElements. - * @return {object} Returns a literal Object with two keys: `can_go_up` & - * `can_not_go_up`. Each contains a set of HTMLElements. - */ - fn.widgets_constraints = function($widgets) { - var $widgets_can_go_up = $([]); - var $widgets_can_not_go_up; - var wgd_can_go_up = []; - var wgd_can_not_go_up = []; - - $widgets.each($.proxy(function(i, w) { - var $w = $(w); - var wgd = $w.coords().grid; - if (this.can_go_widget_up(wgd)) { - $widgets_can_go_up = $widgets_can_go_up.add($w); - wgd_can_go_up.push(wgd); - } else { - wgd_can_not_go_up.push(wgd); - } - }, this)); - - $widgets_can_not_go_up = $widgets.not($widgets_can_go_up); - - return { - can_go_up: Gridster.sort_by_row_asc(wgd_can_go_up), - can_not_go_up: Gridster.sort_by_row_desc(wgd_can_not_go_up) - }; - }; - - - /** - * Sorts an Array of grid coords objects (representing the grid coords of - * each widget) in descending way. - * - * @method manage_movements - * @param {jQuery} $widgets A jQuery collection of HTMLElements - * representing the widgets you want to move. - * @param {Number} to_col The column to which we want to move the widgets. - * @param {Number} to_row The row to which we want to move the widgets. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.manage_movements = function($widgets, to_col, to_row) { - $.each($widgets, $.proxy(function(i, w) { - var wgd = w; - var $w = wgd.el; - - var can_go_widget_up = this.can_go_widget_up(wgd); - - if (can_go_widget_up) { - //target CAN go up - //so move widget up - this.move_widget_to($w, can_go_widget_up); - this.set_placeholder(to_col, can_go_widget_up + wgd.size_y); - - } else { - //target can't go up - var can_go_player_up = this.can_go_player_up( - this.player_grid_data); - - if (!can_go_player_up) { - // target can't go up - // player cant't go up - // so we need to move widget down to a position that dont - // overlaps player - var y = (to_row + this.player_grid_data.size_y) - wgd.row; - - this.move_widget_down($w, y); - this.set_placeholder(to_col, to_row); - } - } - }, this)); - - return this; - }; - - /** - * Determines if there is a widget in the row and col given. Or if the - * HTMLElement passed as first argument is the player. - * - * @method is_player - * @param {Number|HTMLElement} col_or_el A jQuery wrapped collection of - * HTMLElements. - * @param {Number} [row] The column to which we want to move the widgets. - * @return {Boolean} Returns true or false. - */ - fn.is_player = function(col_or_el, row) { - if (row && !this.gridmap[col_or_el]) { return false; } - var $w = row ? this.gridmap[col_or_el][row] : col_or_el; - return $w && ($w.is(this.$player) || $w.is(this.$helper)); - }; - - - /** - * Determines if the widget that is being dragged is currently over the row - * and col given. - * - * @method is_player_in - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_player_in = function(col, row) { - var c = this.cells_occupied_by_player || {}; - return $.inArray(col, c.cols) >= 0 && $.inArray(row, c.rows) >= 0; - }; - - - /** - * Determines if the placeholder is currently over the row and col given. - * - * @method is_placeholder_in - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_placeholder_in = function(col, row) { - var c = this.cells_occupied_by_placeholder || {}; - return this.is_placeholder_in_col(col) && $.inArray(row, c.rows) >= 0; - }; - - - /** - * Determines if the placeholder is currently over the column given. - * - * @method is_placeholder_in_col - * @param {Number} col The column to check. - * @return {Boolean} Returns true or false. - */ - fn.is_placeholder_in_col = function(col) { - var c = this.cells_occupied_by_placeholder || []; - return $.inArray(col, c.cols) >= 0; - }; - - - /** - * Determines if the cell represented by col and row params is empty. - * - * @method is_empty - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_empty = function(col, row) { - if (typeof this.gridmap[col] !== 'undefined') { - if(typeof this.gridmap[col][row] !== 'undefined' && - this.gridmap[col][row] === false - ) { - return true; - } - return false; - } - return true; - }; - - - /** - * Determines if the cell represented by col and row params is occupied. - * - * @method is_occupied - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_occupied = function(col, row) { - if (!this.gridmap[col]) { - return false; - } - - if (this.gridmap[col][row]) { - return true; - } - return false; - }; - - - /** - * Determines if there is a widget in the cell represented by col/row params. - * - * @method is_widget - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean|HTMLElement} Returns false if there is no widget, - * else returns the jQuery HTMLElement - */ - fn.is_widget = function(col, row) { - var cell = this.gridmap[col]; - if (!cell) { - return false; - } - - cell = cell[row]; - - if (cell) { - return cell; - } - - return false; - }; - - - /** - * Determines if there is a widget in the cell represented by col/row - * params and if this is under the widget that is being dragged. - * - * @method is_widget_under_player - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_widget_under_player = function(col, row) { - if (this.is_widget(col, row)) { - return this.is_player_in(col, row); - } - return false; - }; - - - /** - * Get widgets overlapping with the player or with the object passed - * representing the grid cells. - * - * @method get_widgets_under_player - * @return {HTMLElement} Returns a jQuery collection of HTMLElements - */ - fn.get_widgets_under_player = function(cells) { - cells || (cells = this.cells_occupied_by_player || {cols: [], rows: []}); - var $widgets = $([]); - - $.each(cells.cols, $.proxy(function(i, col) { - $.each(cells.rows, $.proxy(function(i, row) { - if(this.is_widget(col, row)) { - $widgets = $widgets.add(this.gridmap[col][row]); - } - }, this)); - }, this)); - - return $widgets; - }; - - - /** - * Put placeholder at the row and column specified. - * - * @method set_placeholder - * @param {Number} col The column to which we want to move the - * placeholder. - * @param {Number} row The row to which we want to move the - * placeholder. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.set_placeholder = function(col, row) { - var phgd = $.extend({}, this.placeholder_grid_data); - var $nexts = this.widgets_below({ - col: phgd.col, - row: phgd.row, - size_y: phgd.size_y, - size_x: phgd.size_x - }); - - // Prevents widgets go out of the grid - var right_col = (col + phgd.size_x - 1); - if (right_col > this.cols) { - col = col - (right_col - col); - } - - var moved_down = this.placeholder_grid_data.row < row; - var changed_column = this.placeholder_grid_data.col !== col; - - this.placeholder_grid_data.col = col; - this.placeholder_grid_data.row = row; - - this.cells_occupied_by_placeholder = this.get_cells_occupied( - this.placeholder_grid_data); - - this.$preview_holder.attr({ - 'data-row' : row, - 'data-col' : col - }); - - if (moved_down || changed_column) { - $nexts.each($.proxy(function(i, widget) { - this.move_widget_up( - $(widget), this.placeholder_grid_data.col - col + phgd.size_y); - }, this)); - } - - var $widgets_under_ph = this.get_widgets_under_player( - this.cells_occupied_by_placeholder); - - if ($widgets_under_ph.length) { - $widgets_under_ph.each($.proxy(function(i, widget) { - var $w = $(widget); - this.move_widget_down( - $w, row + phgd.size_y - $w.data('coords').grid.row); - }, this)); - } - - }; - - - /** - * Determines whether the player can move to a position above. - * - * @method can_go_player_up - * @param {Object} widget_grid_data The actual grid coords object of the - * player. - * @return {Number|Boolean} If the player can be moved to an upper row - * returns the row number, else returns false. - */ - fn.can_go_player_up = function(widget_grid_data) { - var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1; - var result = true; - var upper_rows = []; - var min_row = 10000; - var $widgets_under_player = this.get_widgets_under_player(); - - /* generate an array with columns as index and array with upper rows - * empty as value */ - this.for_each_column_occupied(widget_grid_data, function(tcol) { - var grid_col = this.gridmap[tcol]; - var r = p_bottom_row + 1; - upper_rows[tcol] = []; - - while (--r > 0) { - if (this.is_empty(tcol, r) || this.is_player(tcol, r) || - this.is_widget(tcol, r) && - grid_col[r].is($widgets_under_player) - ) { - upper_rows[tcol].push(r); - min_row = r < min_row ? r : min_row; - } else { - break; - } - } - - if (upper_rows[tcol].length === 0) { - result = false; - return true; //break - } - - upper_rows[tcol].sort(function(a, b) { - return a - b; - }); - }); - - if (!result) { return false; } - - return this.get_valid_rows(widget_grid_data, upper_rows, min_row); - }; - - - /** - * Determines whether a widget can move to a position above. - * - * @method can_go_widget_up - * @param {Object} widget_grid_data The actual grid coords object of the - * widget we want to check. - * @return {Number|Boolean} If the widget can be moved to an upper row - * returns the row number, else returns false. - */ - fn.can_go_widget_up = function(widget_grid_data) { - var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1; - var result = true; - var upper_rows = []; - var min_row = 10000; - - /* generate an array with columns as index and array with topmost rows - * empty as value */ - this.for_each_column_occupied(widget_grid_data, function(tcol) { - var grid_col = this.gridmap[tcol]; - upper_rows[tcol] = []; - - var r = p_bottom_row + 1; - // iterate over each row - while (--r > 0) { - if (this.is_widget(tcol, r) && !this.is_player_in(tcol, r)) { - if (!grid_col[r].is(widget_grid_data.el)) { - break; - } - } - - if (!this.is_player(tcol, r) && - !this.is_placeholder_in(tcol, r) && - !this.is_player_in(tcol, r)) { - upper_rows[tcol].push(r); - } - - if (r < min_row) { - min_row = r; - } - } - - if (upper_rows[tcol].length === 0) { - result = false; - return true; //break - } - - upper_rows[tcol].sort(function(a, b) { - return a - b; - }); - }); - - if (!result) { return false; } - - return this.get_valid_rows(widget_grid_data, upper_rows, min_row); - }; - - - /** - * Search a valid row for the widget represented by `widget_grid_data' in - * the `upper_rows` array. Iteration starts from row specified in `min_row`. - * - * @method get_valid_rows - * @param {Object} widget_grid_data The actual grid coords object of the - * player. - * @param {Array} upper_rows An array with columns as index and arrays - * of valid rows as values. - * @param {Number} min_row The upper row from which the iteration will start. - * @return {Number|Boolean} Returns the upper row valid from the `upper_rows` - * for the widget in question. - */ - fn.get_valid_rows = function(widget_grid_data, upper_rows, min_row) { - var p_top_row = widget_grid_data.row; - var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1; - var size_y = widget_grid_data.size_y; - var r = min_row - 1; - var valid_rows = []; - - while (++r <= p_bottom_row ) { - var common = true; - $.each(upper_rows, function(col, rows) { - if ($.isArray(rows) && $.inArray(r, rows) === -1) { - common = false; - } - }); - - if (common === true) { - valid_rows.push(r); - if (valid_rows.length === size_y) { - break; - } - } - } - - var new_row = false; - if (size_y === 1) { - if (valid_rows[0] !== p_top_row) { - new_row = valid_rows[0] || false; - } - } else { - if (valid_rows[0] !== p_top_row) { - new_row = this.get_consecutive_numbers_index( - valid_rows, size_y); - } - } - - return new_row; - }; - - - fn.get_consecutive_numbers_index = function(arr, size_y) { - var max = arr.length; - var result = []; - var first = true; - var prev = -1; // or null? - - for (var i=0; i < max; i++) { - if (first || arr[i] === prev + 1) { - result.push(i); - if (result.length === size_y) { - break; - } - first = false; - } else { - result = []; - first = true; - } - - prev = arr[i]; - } - - return result.length >= size_y ? arr[result[0]] : false; - }; - - - /** - * Get widgets overlapping with the player. - * - * @method get_widgets_overlapped - * @return {jQuery} Returns a jQuery collection of HTMLElements. - */ - fn.get_widgets_overlapped = function() { - var $w; - var $widgets = $([]); - var used = []; - var rows_from_bottom = this.cells_occupied_by_player.rows.slice(0); - rows_from_bottom.reverse(); - - $.each(this.cells_occupied_by_player.cols, $.proxy(function(i, col) { - $.each(rows_from_bottom, $.proxy(function(i, row) { - // if there is a widget in the player position - if (!this.gridmap[col]) { return true; } //next iteration - var $w = this.gridmap[col][row]; - if (this.is_occupied(col, row) && !this.is_player($w) && - $.inArray($w, used) === -1 - ) { - $widgets = $widgets.add($w); - used.push($w); - } - - }, this)); - }, this)); - - return $widgets; - }; - - - /** - * This callback is executed when the player begins to collide with a column. - * - * @method on_start_overlapping_column - * @param {Number} col The collided column. - * @return {jQuery} Returns a jQuery collection of HTMLElements. - */ - fn.on_start_overlapping_column = function(col) { - this.set_player(col, false); - }; - - - /** - * A callback executed when the player begins to collide with a row. - * - * @method on_start_overlapping_row - * @param {Number} row The collided row. - * @return {jQuery} Returns a jQuery collection of HTMLElements. - */ - fn.on_start_overlapping_row = function(row) { - this.set_player(false, row); - }; - - - /** - * A callback executed when the the player ends to collide with a column. - * - * @method on_stop_overlapping_column - * @param {Number} col The collided row. - * @return {jQuery} Returns a jQuery collection of HTMLElements. - */ - fn.on_stop_overlapping_column = function(col) { - this.set_player(col, false); - - var self = this; - this.for_each_widget_below(col, this.cells_occupied_by_player.rows[0], - function(tcol, trow) { - self.move_widget_up(this, self.player_grid_data.size_y); - }); - }; - - - /** - * This callback is executed when the player ends to collide with a row. - * - * @method on_stop_overlapping_row - * @param {Number} row The collided row. - * @return {jQuery} Returns a jQuery collection of HTMLElements. - */ - fn.on_stop_overlapping_row = function(row) { - this.set_player(false, row); - - var self = this; - var cols = this.cells_occupied_by_player.cols; - for (var c = 0, cl = cols.length; c < cl; c++) { - this.for_each_widget_below(cols[c], row, function(tcol, trow) { - self.move_widget_up(this, self.player_grid_data.size_y); - }); - } - }; - - - /** - * Move a widget to a specific row. The cell or cells must be empty. - * If the widget has widgets below, all of these widgets will be moved also - * if they can. - * - * @method move_widget_to - * @param {HTMLElement} $widget The jQuery wrapped HTMLElement of the - * widget is going to be moved. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.move_widget_to = function($widget, row) { - var self = this; - var widget_grid_data = $widget.coords().grid; - var diff = row - widget_grid_data.row; - var $next_widgets = this.widgets_below($widget); - - var can_move_to_new_cell = this.can_move_to( - widget_grid_data, widget_grid_data.col, row, $widget); - - if (can_move_to_new_cell === false) { - return false; - } - - this.remove_from_gridmap(widget_grid_data); - widget_grid_data.row = row; - this.add_to_gridmap(widget_grid_data); - $widget.attr('data-row', row); - this.$changed = this.$changed.add($widget); - - - $next_widgets.each(function(i, widget) { - var $w = $(widget); - var wgd = $w.coords().grid; - var can_go_up = self.can_go_widget_up(wgd); - if (can_go_up && can_go_up !== wgd.row) { - self.move_widget_to($w, can_go_up); - } - }); - - return this; - }; - - - /** - * Move up the specified widget and all below it. - * - * @method move_widget_up - * @param {HTMLElement} $widget The widget you want to move. - * @param {Number} [y_units] The number of cells that the widget has to move. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.move_widget_up = function($widget, y_units) { - var el_grid_data = $widget.coords().grid; - var actual_row = el_grid_data.row; - var moved = []; - var can_go_up = true; - y_units || (y_units = 1); - - if (!this.can_go_up($widget)) { return false; } //break; - - this.for_each_column_occupied(el_grid_data, function(col) { - // can_go_up - if ($.inArray($widget, moved) === -1) { - var widget_grid_data = $widget.coords().grid; - var next_row = actual_row - y_units; - next_row = this.can_go_up_to_row( - widget_grid_data, col, next_row); - - if (!next_row) { - return true; - } - - var $next_widgets = this.widgets_below($widget); - - this.remove_from_gridmap(widget_grid_data); - widget_grid_data.row = next_row; - this.add_to_gridmap(widget_grid_data); - $widget.attr('data-row', widget_grid_data.row); - this.$changed = this.$changed.add($widget); - - moved.push($widget); - - $next_widgets.each($.proxy(function(i, widget) { - this.move_widget_up($(widget), y_units); - }, this)); - } - }); - - }; - - - /** - * Move down the specified widget and all below it. - * - * @method move_widget_down - * @param {jQuery} $widget The jQuery object representing the widget - * you want to move. - * @param {Number} y_units The number of cells that the widget has to move. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.move_widget_down = function($widget, y_units) { - var el_grid_data, actual_row, moved, y_diff; - - if (y_units <= 0) { return false; } - - el_grid_data = $widget.coords().grid; - actual_row = el_grid_data.row; - moved = []; - y_diff = y_units; - - if (!$widget) { return false; } - - if ($.inArray($widget, moved) === -1) { - - var widget_grid_data = $widget.coords().grid; - var next_row = actual_row + y_units; - var $next_widgets = this.widgets_below($widget); - - this.remove_from_gridmap(widget_grid_data); - - $next_widgets.each($.proxy(function(i, widget) { - var $w = $(widget); - var wd = $w.coords().grid; - var tmp_y = this.displacement_diff( - wd, widget_grid_data, y_diff); - - if (tmp_y > 0) { - this.move_widget_down($w, tmp_y); - } - }, this)); - - widget_grid_data.row = next_row; - this.update_widget_position(widget_grid_data, $widget); - $widget.attr('data-row', widget_grid_data.row); - this.$changed = this.$changed.add($widget); - - moved.push($widget); - } - }; - - - /** - * Check if the widget can move to the specified row, else returns the - * upper row possible. - * - * @method can_go_up_to_row - * @param {Number} widget_grid_data The current grid coords object of the - * widget. - * @param {Number} col The target column. - * @param {Number} row The target row. - * @return {Boolean|Number} Returns the row number if the widget can move - * to the target position, else returns false. - */ - fn.can_go_up_to_row = function(widget_grid_data, col, row) { - var ga = this.gridmap; - var result = true; - var urc = []; // upper_rows_in_columns - var actual_row = widget_grid_data.row; - var r; - - /* generate an array with columns as index and array with - * upper rows empty in the column */ - this.for_each_column_occupied(widget_grid_data, function(tcol) { - var grid_col = ga[tcol]; - urc[tcol] = []; - - r = actual_row; - while (r--) { - if (this.is_empty(tcol, r) && - !this.is_placeholder_in(tcol, r) - ) { - urc[tcol].push(r); - } else { - break; - } - } - - if (!urc[tcol].length) { - result = false; - return true; - } - - }); - - if (!result) { return false; } - - /* get common rows starting from upper position in all the columns - * that widget occupies */ - r = row; - for (r = 1; r < actual_row; r++) { - var common = true; - - for (var uc = 0, ucl = urc.length; uc < ucl; uc++) { - if (urc[uc] && $.inArray(r, urc[uc]) === -1) { - common = false; - } - } - - if (common === true) { - result = r; - break; - } - } - - return result; - }; - - - fn.displacement_diff = function(widget_grid_data, parent_bgd, y_units) { - var actual_row = widget_grid_data.row; - var diffs = []; - var parent_max_y = parent_bgd.row + parent_bgd.size_y; - - this.for_each_column_occupied(widget_grid_data, function(col) { - var temp_y_units = 0; - - for (var r = parent_max_y; r < actual_row; r++) { - if (this.is_empty(col, r)) { - temp_y_units = temp_y_units + 1; - } - } - - diffs.push(temp_y_units); - }); - - var max_diff = Math.max.apply(Math, diffs); - y_units = (y_units - max_diff); - - return y_units > 0 ? y_units : 0; - }; - - - /** - * Get widgets below a widget. - * - * @method widgets_below - * @param {HTMLElement} $el The jQuery wrapped HTMLElement. - * @return {jQuery} A jQuery collection of HTMLElements. - */ - fn.widgets_below = function($el) { - var el_grid_data = $.isPlainObject($el) ? $el : $el.coords().grid; - var self = this; - var ga = this.gridmap; - var next_row = el_grid_data.row + el_grid_data.size_y - 1; - var $nexts = $([]); - - this.for_each_column_occupied(el_grid_data, function(col) { - self.for_each_widget_below(col, next_row, function(tcol, trow) { - if (!self.is_player(this) && $.inArray(this, $nexts) === -1) { - $nexts = $nexts.add(this); - return true; // break - } - }); - }); - - return Gridster.sort_by_row_asc($nexts); - }; - - - /** - * Update the array of mapped positions with the new player position. - * - * @method set_cells_player_occupies - * @param {Number} col The new player col. - * @param {Number} col The new player row. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.set_cells_player_occupies = function(col, row) { - this.remove_from_gridmap(this.placeholder_grid_data); - this.placeholder_grid_data.col = col; - this.placeholder_grid_data.row = row; - this.add_to_gridmap(this.placeholder_grid_data, this.$player); - return this; - }; - - - /** - * Remove from the array of mapped positions the reference to the player. - * - * @method empty_cells_player_occupies - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.empty_cells_player_occupies = function() { - this.remove_from_gridmap(this.placeholder_grid_data); - return this; - }; - - - fn.can_go_up = function($el) { - var el_grid_data = $el.coords().grid; - var initial_row = el_grid_data.row; - var prev_row = initial_row - 1; - var ga = this.gridmap; - var upper_rows_by_column = []; - - var result = true; - if (initial_row === 1) { return false; } - - this.for_each_column_occupied(el_grid_data, function(col) { - var $w = this.is_widget(col, prev_row); - - if (this.is_occupied(col, prev_row) || - this.is_player(col, prev_row) || - this.is_placeholder_in(col, prev_row) || - this.is_player_in(col, prev_row) - ) { - result = false; - return true; //break - } - }); - - return result; - }; - - - /** - * Check if it's possible to move a widget to a specific col/row. It takes - * into account the dimensions (`size_y` and `size_x` attrs. of the grid - * coords object) the widget occupies. - * - * @method can_move_to - * @param {Object} widget_grid_data The grid coords object that represents - * the widget. - * @param {Object} col The col to check. - * @param {Object} row The row to check. - * @param {Number} [max_row] The max row allowed. - * @return {Boolean} Returns true if all cells are empty, else return false. - */ - fn.can_move_to = function(widget_grid_data, col, row, max_row) { - var ga = this.gridmap; - var $w = widget_grid_data.el; - var future_wd = { - size_y: widget_grid_data.size_y, - size_x: widget_grid_data.size_x, - col: col, - row: row - }; - var result = true; - - //Prevents widgets go out of the grid - var right_col = col + widget_grid_data.size_x - 1; - if (right_col > this.cols) { - return false; - } - - if (max_row && max_row < row + widget_grid_data.size_y - 1) { - return false; - } - - this.for_each_cell_occupied(future_wd, function(tcol, trow) { - var $tw = this.is_widget(tcol, trow); - if ($tw && (!widget_grid_data.el || $tw.is($w))) { - result = false; - } - }); - - return result; - }; - - - /** - * Given the leftmost column returns all columns that are overlapping - * with the player. - * - * @method get_targeted_columns - * @param {Number} [from_col] The leftmost column. - * @return {Array} Returns an array with column numbers. - */ - fn.get_targeted_columns = function(from_col) { - var max = (from_col || this.player_grid_data.col) + - (this.player_grid_data.size_x - 1); - var cols = []; - for (var col = from_col; col <= max; col++) { - cols.push(col); - } - return cols; - }; - - - /** - * Given the upper row returns all rows that are overlapping with the player. - * - * @method get_targeted_rows - * @param {Number} [from_row] The upper row. - * @return {Array} Returns an array with row numbers. - */ - fn.get_targeted_rows = function(from_row) { - var max = (from_row || this.player_grid_data.row) + - (this.player_grid_data.size_y - 1); - var rows = []; - for (var row = from_row; row <= max; row++) { - rows.push(row); - } - return rows; - }; - - /** - * Get all columns and rows that a widget occupies. - * - * @method get_cells_occupied - * @param {Object} el_grid_data The grid coords object of the widget. - * @return {Object} Returns an object like `{ cols: [], rows: []}`. - */ - fn.get_cells_occupied = function(el_grid_data) { - var cells = { cols: [], rows: []}; - var i; - if (arguments[1] instanceof $) { - el_grid_data = arguments[1].coords().grid; - } - - for (i = 0; i < el_grid_data.size_x; i++) { - var col = el_grid_data.col + i; - cells.cols.push(col); - } - - for (i = 0; i < el_grid_data.size_y; i++) { - var row = el_grid_data.row + i; - cells.rows.push(row); - } - - return cells; - }; - - - /** - * Iterate over the cells occupied by a widget executing a function for - * each one. - * - * @method for_each_cell_occupied - * @param {Object} el_grid_data The grid coords object that represents the - * widget. - * @param {Function} callback The function to execute on each column - * iteration. Column and row are passed as arguments. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_cell_occupied = function(grid_data, callback) { - this.for_each_column_occupied(grid_data, function(col) { - this.for_each_row_occupied(grid_data, function(row) { - callback.call(this, col, row); - }); - }); - return this; - }; - - - /** - * Iterate over the columns occupied by a widget executing a function for - * each one. - * - * @method for_each_column_occupied - * @param {Object} el_grid_data The grid coords object that represents - * the widget. - * @param {Function} callback The function to execute on each column - * iteration. The column number is passed as first argument. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_column_occupied = function(el_grid_data, callback) { - for (var i = 0; i < el_grid_data.size_x; i++) { - var col = el_grid_data.col + i; - callback.call(this, col, el_grid_data); - } - }; - - - /** - * Iterate over the rows occupied by a widget executing a function for - * each one. - * - * @method for_each_row_occupied - * @param {Object} el_grid_data The grid coords object that represents - * the widget. - * @param {Function} callback The function to execute on each column - * iteration. The row number is passed as first argument. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_row_occupied = function(el_grid_data, callback) { - for (var i = 0; i < el_grid_data.size_y; i++) { - var row = el_grid_data.row + i; - callback.call(this, row, el_grid_data); - } - }; - - - - fn._traversing_widgets = function(type, direction, col, row, callback) { - var ga = this.gridmap; - if (!ga[col]) { return; } - - var cr, max; - var action = type + '/' + direction; - if (arguments[2] instanceof $) { - var el_grid_data = arguments[2].coords().grid; - col = el_grid_data.col; - row = el_grid_data.row; - callback = arguments[3]; - } - var matched = []; - var trow = row; - - - var methods = { - 'for_each/above': function() { - while (trow--) { - if (trow > 0 && this.is_widget(col, trow) && - $.inArray(ga[col][trow], matched) === -1 - ) { - cr = callback.call(ga[col][trow], col, trow); - matched.push(ga[col][trow]); - if (cr) { break; } - } - } - }, - 'for_each/below': function() { - for (trow = row + 1, max = ga[col].length; trow < max; trow++) { - if (this.is_widget(col, trow) && - $.inArray(ga[col][trow], matched) === -1 - ) { - cr = callback.call(ga[col][trow], col, trow); - matched.push(ga[col][trow]); - if (cr) { break; } - } - } - } - }; - - if (methods[action]) { - methods[action].call(this); - } - }; - - - /** - * Iterate over each widget above the column and row specified. - * - * @method for_each_widget_above - * @param {Number} col The column to start iterating. - * @param {Number} row The row to start iterating. - * @param {Function} callback The function to execute on each widget - * iteration. The value of `this` inside the function is the jQuery - * wrapped HTMLElement. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_widget_above = function(col, row, callback) { - this._traversing_widgets('for_each', 'above', col, row, callback); - return this; - }; - - - /** - * Iterate over each widget below the column and row specified. - * - * @method for_each_widget_below - * @param {Number} col The column to start iterating. - * @param {Number} row The row to start iterating. - * @param {Function} callback The function to execute on each widget - * iteration. The value of `this` inside the function is the jQuery wrapped - * HTMLElement. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_widget_below = function(col, row, callback) { - this._traversing_widgets('for_each', 'below', col, row, callback); - return this; - }; - - - /** - * Returns the highest occupied cell in the grid. - * - * @method get_highest_occupied_cell - * @return {Object} Returns an object with `col` and `row` numbers. - */ - fn.get_highest_occupied_cell = function() { - var r; - var gm = this.gridmap; - var rl = gm[1].length; - var rows = [], cols = []; - var row_in_col = []; - for (var c = gm.length - 1; c >= 1; c--) { - for (r = rl - 1; r >= 1; r--) { - if (this.is_widget(c, r)) { - rows.push(r); - cols.push(c); - break; - } - } - } - - return { - col: Math.max.apply(Math, cols), - row: Math.max.apply(Math, rows) - }; - }; - - - fn.get_widgets_from = function(col, row) { - var ga = this.gridmap; - var $widgets = $(); - - if (col) { - $widgets = $widgets.add( - this.$widgets.filter(function() { - var tcol = $(this).attr('data-col'); - return (tcol === col || tcol > col); - }) - ); - } - - if (row) { - $widgets = $widgets.add( - this.$widgets.filter(function() { - var trow = $(this).attr('data-row'); - return (trow === row || trow > row); - }) - ); - } - - return $widgets; - }; - - - /** - * Set the current height of the parent grid. - * - * @method set_dom_grid_height - * @return {Object} Returns the instance of the Gridster class. - */ - fn.set_dom_grid_height = function(height) { - if (typeof height === 'undefined') { - var r = this.get_highest_occupied_cell().row; - height = r * this.min_widget_height; - } - - this.container_height = height; - this.$el.css('height', this.container_height); - return this; - }; - - /** - * Set the current width of the parent grid. - * - * @method set_dom_grid_width - * @return {Object} Returns the instance of the Gridster class. - */ - fn.set_dom_grid_width = function(cols) { - if (typeof cols === 'undefined') { - cols = this.get_highest_occupied_cell().col; - } - - var max_cols = (this.options.autogrow_cols ? this.options.max_cols : - this.cols); - - cols = Math.min(max_cols, Math.max(cols, this.options.min_cols)); - this.container_width = cols * this.min_widget_width; - this.$el.css('width', this.container_width); - return this; - }; - - - /** - * It generates the neccessary styles to position the widgets. - * - * @method generate_stylesheet - * @param {Number} rows Number of columns. - * @param {Number} cols Number of rows. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.generate_stylesheet = function(opts) { - var styles = ''; - var max_size_x = this.options.max_size_x || this.cols; - var max_rows = 0; - var max_cols = 0; - var i; - var rules; - - opts || (opts = {}); - opts.cols || (opts.cols = this.cols); - opts.rows || (opts.rows = this.rows); - opts.namespace || (opts.namespace = this.options.namespace); - opts.widget_base_dimensions || - (opts.widget_base_dimensions = this.options.widget_base_dimensions); - opts.widget_margins || - (opts.widget_margins = this.options.widget_margins); - opts.min_widget_width = (opts.widget_margins[0] * 2) + - opts.widget_base_dimensions[0]; - opts.min_widget_height = (opts.widget_margins[1] * 2) + - opts.widget_base_dimensions[1]; - - // don't duplicate stylesheets for the same configuration - var serialized_opts = $.param(opts); - if ($.inArray(serialized_opts, Gridster.generated_stylesheets) >= 0) { - return false; - } - - this.generated_stylesheets.push(serialized_opts); - Gridster.generated_stylesheets.push(serialized_opts); - - /* generate CSS styles for cols */ - for (i = opts.cols; i >= 0; i--) { - styles += (opts.namespace + ' [data-col="'+ (i + 1) + '"] { left:' + - ((i * opts.widget_base_dimensions[0]) + - (i * opts.widget_margins[0]) + - ((i + 1) * opts.widget_margins[0])) + 'px; }\n'); - } - - /* generate CSS styles for rows */ - for (i = opts.rows; i >= 0; i--) { - styles += (opts.namespace + ' [data-row="' + (i + 1) + '"] { top:' + - ((i * opts.widget_base_dimensions[1]) + - (i * opts.widget_margins[1]) + - ((i + 1) * opts.widget_margins[1]) ) + 'px; }\n'); - } - - for (var y = 1; y <= opts.rows; y++) { - styles += (opts.namespace + ' [data-sizey="' + y + '"] { height:' + - (y * opts.widget_base_dimensions[1] + - (y - 1) * (opts.widget_margins[1] * 2)) + 'px; }\n'); - } - - for (var x = 1; x <= max_size_x; x++) { - styles += (opts.namespace + ' [data-sizex="' + x + '"] { width:' + - (x * opts.widget_base_dimensions[0] + - (x - 1) * (opts.widget_margins[0] * 2)) + 'px; }\n'); - } - - this.remove_style_tags(); - - return this.add_style_tag(styles); - }; - - - /** - * Injects the given CSS as string to the head of the document. - * - * @method add_style_tag - * @param {String} css The styles to apply. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.add_style_tag = function(css) { - var d = document; - var tag = d.createElement('style'); - - d.getElementsByTagName('head')[0].appendChild(tag); - tag.setAttribute('type', 'text/css'); - - if (tag.styleSheet) { - tag.styleSheet.cssText = css; - } else { - tag.appendChild(document.createTextNode(css)); - } - - this.$style_tags = this.$style_tags.add(tag); - - return this; - }; - - - /** - * Remove the style tag with the associated id from the head of the document - * - * @method remove_style_tag - * @return {Object} Returns the instance of the Gridster class. - */ - fn.remove_style_tags = function() { - var all_styles = Gridster.generated_stylesheets; - var ins_styles = this.generated_stylesheets; - - this.$style_tags.remove(); - - Gridster.generated_stylesheets = $.map(all_styles, function(s) { - if ($.inArray(s, ins_styles) === -1) { return s; } - }); - }; - - - /** - * Generates a faux grid to collide with it when a widget is dragged and - * detect row or column that we want to go. - * - * @method generate_faux_grid - * @param {Number} rows Number of columns. - * @param {Number} cols Number of rows. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.generate_faux_grid = function(rows, cols) { - this.faux_grid = []; - this.gridmap = []; - var col; - var row; - for (col = cols; col > 0; col--) { - this.gridmap[col] = []; - for (row = rows; row > 0; row--) { - this.add_faux_cell(row, col); - } - } - return this; - }; - - - /** - * Add cell to the faux grid. - * - * @method add_faux_cell - * @param {Number} row The row for the new faux cell. - * @param {Number} col The col for the new faux cell. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.add_faux_cell = function(row, col) { - var coords = $({ - left: this.baseX + ((col - 1) * this.min_widget_width), - top: this.baseY + (row -1) * this.min_widget_height, - width: this.min_widget_width, - height: this.min_widget_height, - col: col, - row: row, - original_col: col, - original_row: row - }).coords(); - - if (!$.isArray(this.gridmap[col])) { - this.gridmap[col] = []; - } - - this.gridmap[col][row] = false; - this.faux_grid.push(coords); - - return this; - }; - - - /** - * Add rows to the faux grid. - * - * @method add_faux_rows - * @param {Number} rows The number of rows you want to add to the faux grid. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.add_faux_rows = function(rows) { - var actual_rows = this.rows; - var max_rows = actual_rows + (rows || 1); - - for (var r = max_rows; r > actual_rows; r--) { - for (var c = this.cols; c >= 1; c--) { - this.add_faux_cell(r, c); - } - } - - this.rows = max_rows; - - if (this.options.autogenerate_stylesheet) { - this.generate_stylesheet(); - } - - return this; - }; - - /** - * Add cols to the faux grid. - * - * @method add_faux_cols - * @param {Number} cols The number of cols you want to add to the faux grid. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.add_faux_cols = function(cols) { - var actual_cols = this.cols; - var max_cols = actual_cols + (cols || 1); - max_cols = Math.min(max_cols, this.options.max_cols); - - for (var c = actual_cols + 1; c <= max_cols; c++) { - for (var r = this.rows; r >= 1; r--) { - this.add_faux_cell(r, c); - } - } - - this.cols = max_cols; - - if (this.options.autogenerate_stylesheet) { - this.generate_stylesheet(); - } - - return this; - }; - - - /** - * Recalculates the offsets for the faux grid. You need to use it when - * the browser is resized. - * - * @method recalculate_faux_grid - * @return {Object} Returns the instance of the Gridster class. - */ - fn.recalculate_faux_grid = function() { - var aw = this.$wrapper.width(); - this.baseX = ($(window).width() - aw) / 2; - this.baseY = this.$wrapper.offset().top; - - $.each(this.faux_grid, $.proxy(function(i, coords) { - this.faux_grid[i] = coords.update({ - left: this.baseX + (coords.data.col -1) * this.min_widget_width, - top: this.baseY + (coords.data.row -1) * this.min_widget_height - }); - }, this)); - - return this; - }; - - - /** - * Get all widgets in the DOM and register them. - * - * @method get_widgets_from_DOM - * @return {Object} Returns the instance of the Gridster class. - */ - fn.get_widgets_from_DOM = function() { - var widgets_coords = this.$widgets.map($.proxy(function(i, widget) { - var $w = $(widget); - return this.dom_to_coords($w); - }, this)); - - widgets_coords = Gridster.sort_by_row_and_col_asc(widgets_coords); - - var changes = $(widgets_coords).map($.proxy(function(i, wgd) { - return this.register_widget(wgd) || null; - }, this)); - - if (changes.length) { - this.$el.trigger('gridster:positionschanged'); - } - - return this; - }; - - - /** - * Calculate columns and rows to be set based on the configuration - * parameters, grid dimensions, etc ... - * - * @method generate_grid_and_stylesheet - * @return {Object} Returns the instance of the Gridster class. - */ - fn.generate_grid_and_stylesheet = function() { - var aw = this.$wrapper.width(); - var max_cols = this.options.max_cols; - - var cols = Math.floor(aw / this.min_widget_width) + - this.options.extra_cols; - - var actual_cols = this.$widgets.map(function() { - return $(this).attr('data-col'); - }).get(); - - //needed to pass tests with phantomjs - actual_cols.length || (actual_cols = [0]); - - var min_cols = Math.max.apply(Math, actual_cols); - - this.cols = Math.max(min_cols, cols, this.options.min_cols); - - if (max_cols !== Infinity && max_cols >= min_cols && max_cols < this.cols) { - this.cols = max_cols; - } - - // get all rows that could be occupied by the current widgets - var max_rows = this.options.extra_rows; - this.$widgets.each(function(i, w) { - max_rows += (+$(w).attr('data-sizey')); - }); - - this.rows = Math.max(max_rows, this.options.min_rows); - - this.baseX = ($(window).width() - aw) / 2; - this.baseY = this.$wrapper.offset().top; - - if (this.options.autogenerate_stylesheet) { - this.generate_stylesheet(); - } - - return this.generate_faux_grid(this.rows, this.cols); - }; - - /** - * Destroy this gridster by removing any sign of its presence, making it easy to avoid memory leaks - * - * @method destroy - * @param {Boolean} remove If true, remove gridster from DOM. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.destroy = function(remove) { - this.$el.removeData('gridster'); - - // remove bound callback on window resize - $(window).unbind('.gridster'); - - if (this.drag_api) { - this.drag_api.destroy(); - } - - this.remove_style_tags(); - - remove && this.$el.remove(); - - return this; - }; - - - //jQuery adapter - $.fn.gridster = function(options) { - return this.each(function() { - if (! $(this).data('gridster')) { - $(this).data('gridster', new Gridster( this, options )); - } - }); - }; - - return Gridster; - -})); diff --git a/api/js/jquery/gridster/jquery.gridster.min.css b/api/js/jquery/gridster/jquery.gridster.min.css deleted file mode 100644 index 10ff0faa46..0000000000 --- a/api/js/jquery/gridster/jquery.gridster.min.css +++ /dev/null @@ -1 +0,0 @@ -.gridster{position:relative}.gridster>*{margin:0 auto;-webkit-transition:height .4s;-moz-transition:height .4s;-o-transition:height .4s;-ms-transition:height .4s;transition:height .4s}.gridster .gs_w{z-index:2;position:absolute}.ready .gs_w:not(.preview-holder){-webkit-transition:opacity .3s,left .3s,top .3s;-moz-transition:opacity .3s,left .3s,top .3s;-o-transition:opacity .3s,left .3s,top .3s;transition:opacity .3s,left .3s,top .3s}.ready .gs_w:not(.preview-holder){-webkit-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;-moz-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;-o-transition:opacity .3s,left .3s,top .3s,width .3s,height .3s;transition:opacity .3s,left .3s,top .3s,width .3s,height .3s}.gridster .preview-holder{z-index:1;position:absolute;background-color:#fff;border-color:#fff;opacity:.3}.gridster .player-revert{z-index:10!important;-webkit-transition:left .3s,top .3s!important;-moz-transition:left .3s,top .3s!important;-o-transition:left .3s,top .3s!important;transition:left .3s,top .3s!important}.gridster .dragging{z-index:10!important;-webkit-transition:all 0s!important;-moz-transition:all 0s!important;-o-transition:all 0s!important;transition:all 0s!important} \ No newline at end of file diff --git a/api/js/jquery/gridster/jquery.gridster.min.js b/api/js/jquery/gridster/jquery.gridster.min.js deleted file mode 100644 index c5f225e056..0000000000 --- a/api/js/jquery/gridster/jquery.gridster.min.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(t){function i(i){return i[0]&&t.isPlainObject(i[0])?this.data=i[0]:this.el=i,this.isCoords=!0,this.coords={},this.init(),this}var e=i.prototype;e.init=function(){this.set(),this.original_coords=this.get()},e.set=function(t,i){var e=this.el;if(e&&!t&&(this.data=e.offset(),this.data.width=e.width(),this.data.height=e.height()),e&&t&&!i){var s=e.offset();this.data.top=s.top,this.data.left=s.left}var r=this.data;return this.coords.x1=r.left,this.coords.y1=r.top,this.coords.x2=r.left+r.width,this.coords.y2=r.top+r.height,this.coords.cx=r.left+r.width/2,this.coords.cy=r.top+r.height/2,this.coords.width=r.width,this.coords.height=r.height,this.coords.el=e||!1,this},e.update=function(i){if(!i&&!this.el)return this;if(i){var e=t.extend({},this.data,i);return this.data=e,this.set(!0,!0)}return this.set(!0),this},e.get=function(){return this.coords},t.fn.coords=function(){if(this.data("coords"))return this.data("coords");var t=new i(this,arguments[0]);return this.data("coords",t),t}})(jQuery,window,document),function(t,i,e){function s(i,e,s){this.options=t.extend(r,s),this.$element=i,this.last_colliders=[],this.last_colliders_coords=[],"string"==typeof e||e instanceof jQuery?this.$colliders=t(e,this.options.colliders_context).not(this.$element):this.colliders=t(e),this.init()}var r={colliders_context:e.body},o=s.prototype;o.init=function(){this.find_collisions()},o.overlaps=function(t,i){var e=!1,s=!1;return(i.x1>=t.x1&&i.x1<=t.x2||i.x2>=t.x1&&i.x2<=t.x2||t.x1>=i.x1&&t.x2<=i.x2)&&(e=!0),(i.y1>=t.y1&&i.y1<=t.y2||i.y2>=t.y1&&i.y2<=t.y2||t.y1>=i.y1&&t.y2<=i.y2)&&(s=!0),e&&s},o.detect_overlapping_region=function(t,i){var e="",s="";return t.y1>i.cy&&t.y1i.y1&&t.y2i.cx&&t.x1i.x1&&t.x2o;o++)-1===t.inArray(r[o],i)&&e.call(this,r[o]);for(var n=0,_=i.length;_>n;n++)-1===t.inArray(i[n],r)&&s.call(this,i[n])},o.find_collisions=function(i){for(var e=this,s=[],r=[],o=this.colliders||this.$colliders,a=o.length,n=e.$element.coords().update(i||!1).get();a--;){var _=e.$colliders?t(o[a]):o[a],h=_.isCoords?_:_.coords(),d=h.get(),l=e.overlaps(n,d);if(l){var c=e.detect_overlapping_region(n,d);if("C"===c){var p=e.calculate_overlapped_area_coords(n,d),g=e.calculate_overlapped_area(p),u={area:g,area_coords:p,region:c,coords:d,player_coords:n,el:_};e.options.on_overlap&&e.options.on_overlap.call(this,u),s.push(h),r.push(u)}}}return(e.options.on_overlap_stop||e.options.on_overlap_start)&&this.manage_colliders_start_stop(s,e.options.on_overlap_start,e.options.on_overlap_stop),this.last_colliders_coords=s,r},o.get_closest_colliders=function(t){var i=this.find_collisions(t);return i.sort(function(t,i){return"C"===t.region&&"C"===i.region?t.coords.y1this.player_max_left?r=this.player_max_left:this.player_min_left>r&&(r=this.player_min_left)),{left:r,top:o,mouse_left:i.left,mouse_top:i.top}},_.manage_scroll=function(t){var i,e=o.scrollTop(),s=e,r=s+this.window_height,a=r-50,n=s+50;t.mouse_left;var _=s+t.mouse_top,h=this.doc_height-this.window_height+this.player_height;_>=a&&(i=e+30,h>i&&(o.scrollTop(i),this.scrollOffset=this.scrollOffset+30)),n>=_&&(i=e-30,i>0&&(o.scrollTop(i),this.scrollOffset=this.scrollOffset-30))},_.calculate_positions=function(){this.window_height=o.height()},_.drag_handler=function(i){if(i.target.nodeName,!this.disabled&&(1===i.which||a)&&!this.ignore_drag(i)){var e=this,s=!0;return this.$player=t(i.currentTarget),this.el_init_pos=this.get_actual_pos(this.$player),this.mouse_init_pos=this.get_mouse_pos(i),this.offsetY=this.mouse_init_pos.top-this.el_init_pos.top,this.on_pointer_events_move=function(t){var i=e.get_mouse_pos(t),r=Math.abs(i.left-e.mouse_init_pos.left),o=Math.abs(i.top-e.mouse_init_pos.top);return r>e.options.distance||o>e.options.distance?s?(s=!1,e.on_dragstart.call(e,t),!1):(e.is_dragging===!0&&e.on_dragmove.call(e,t),!1):!1},this.$body.on(n.move,this.on_pointer_events_move),!1}},_.on_dragstart=function(i){i.preventDefault(),this.drag_start=!0,this.is_dragging=!0;var s=this.$container.offset();return this.baseX=Math.round(s.left),this.baseY=Math.round(s.top),this.doc_height=t(e).height(),"clone"===this.options.helper?(this.$helper=this.$player.clone().appendTo(this.$container).addClass("helper"),this.helper=!0):this.helper=!1,this.scrollOffset=0,this.el_init_offset=this.$player.offset(),this.player_width=this.$player.width(),this.player_height=this.$player.height(),this.player_max_left=this.$container.width()-this.player_width+this.options.offset_left,this.options.start&&this.options.start.call(this.$player,i,{helper:this.helper?this.$helper:this.$player}),!1},_.on_dragmove=function(t){var i=this.get_offset(t);this.options.autoscroll&&this.manage_scroll(i),(this.helper?this.$helper:this.$player).css({position:"absolute",left:i.left,top:i.top});var e={position:{left:i.left,top:i.top}};return this.options.drag&&this.options.drag.call(this.$player,t,e),!1},_.on_dragstop=function(t){var i=this.get_offset(t);this.drag_start=!1;var e={position:{left:i.left,top:i.top}};return this.options.stop&&this.options.stop.call(this.$player,t,e),this.helper&&this.$helper.remove(),!1},_.on_select_start=function(t){return this.disabled||this.ignore_drag(t)?undefined:!1},_.enable=function(){this.disabled=!1},_.disable=function(){this.disabled=!0},_.destroy=function(){this.disable(),this.$container.off("selectstart",this.proxied_on_select_start),this.$container.off(n.start,this.proxied_drag_handler),this.$body.off(n.end,this.proxied_pointer_events_end),this.$body.off(n.move,this.on_pointer_events_move),t(i).unbind("resize",this.on_window_resize),t.removeData(this.$container,"drag")},_.ignore_drag=function(i){return this.options.handle?!t(i.target).is(this.options.handle):t.inArray(i.target.nodeName,this.options.ignore_dragging)>=0},t.fn.dragg=function(i){return this.each(function(){t.data(this,"drag")||t.data(this,"drag",new s(this,i))})}}(jQuery,window,document),function(t,i,e){function s(i,e){this.options=t.extend(!0,r,e),this.$el=t(i),this.$wrapper=this.$el.parent(),this.$widgets=this.$el.children(this.options.widget_selector).addClass("gs_w"),this.widgets=[],this.$changed=t([]),this.w_queue={},this.wrapper_width=this.$wrapper.width(),this.min_widget_width=2*this.options.widget_margins[0]+this.options.widget_base_dimensions[0],this.min_widget_height=2*this.options.widget_margins[1]+this.options.widget_base_dimensions[1],this.init()}var r={namespace:"",widget_selector:"li",static_class:"static",widget_margins:[10,10],widget_base_dimensions:[400,225],extra_rows:0,extra_cols:0,min_cols:1,max_cols:60,min_rows:15,max_rows:15,max_size_x:6,autogenerate_stylesheet:!0,avoid_overlapped_widgets:!0,shift_larger_widgets_down:!0,serialize_params:function(t,i){return{col:i.col,row:i.row,size_x:i.size_x,size_y:i.size_y}},collision:{},draggable:{distance:4,items:".gs_w:not(.static)"}};s.generated_stylesheets=[];var o=s.prototype;o.init=function(){this.generate_grid_and_stylesheet(),this.get_widgets_from_DOM(),this.set_dom_grid_height(),this.$wrapper.addClass("ready"),this.draggable(),t(i).bind("resize",throttle(t.proxy(this.recalculate_faux_grid,this),200))},o.disable=function(){return this.$wrapper.find(".player-revert").removeClass("player-revert"),this.drag_api.disable(),this},o.enable=function(){return this.drag_api.enable(),this},o.add_widget=function(i,e,s,r,o){var a;e||(e=1),s||(s=1),!r&!o?a=this.next_position(e,s):(a={col:r,row:o},this.empty_cells(r,o,e,s));var n=t(i).attr({"data-col":a.col,"data-row":a.row,"data-sizex":e,"data-sizey":s}).addClass("gs_w").appendTo(this.$el).hide();return this.$widgets=this.$widgets.add(n),this.$changed=this.$changed.add(n),this.register_widget(n),this.add_faux_rows(a.size_y),this.set_dom_grid_height(),n.fadeIn()},o.resize_widget=function(i,e,s){var r=i.coords().grid;e||(e=r.size_x),s||(s=r.size_y),e>this.cols&&(e=this.cols);var o=this.get_cells_occupied(r),a=r.size_x,n=r.size_y,_=r.col,h=_;if(_+e-1>this.cols){var d=_+(e-1)-this.cols,l=_-d;h=Math.max(1,l)}var c={col:h,row:r.row,size_x:e,size_y:s},p=this.get_cells_occupied(c),g=[];t.each(o.cols,function(i,e){-1===t.inArray(e,p.cols)&&g.push(e)});var u=[];t.each(p.cols,function(i,e){-1===t.inArray(e,o.cols)&&u.push(e)});var f=[];t.each(o.rows,function(i,e){-1===t.inArray(e,p.rows)&&f.push(e)});var w=[];if(t.each(p.rows,function(i,e){-1===t.inArray(e,o.rows)&&w.push(e)}),this.remove_from_gridmap(r),u.length){var y=[h,r.row,e,Math.min(n,s),i];this.empty_cells.apply(this,y)}if(w.length){var v=[h,r.row,e,s,i];this.empty_cells.apply(this,v)}if(r.col=h,r.size_x=e,r.size_y=s,this.add_to_gridmap(c,i),i.data("coords").update({width:e*this.options.widget_base_dimensions[0]+2*(e-1)*this.options.widget_margins[0],height:s*this.options.widget_base_dimensions[1]+2*(s-1)*this.options.widget_margins[1]}),s>n&&this.add_faux_rows(s-n),e>a&&this.add_faux_cols(e-a),i.attr({"data-col":h,"data-sizex":e,"data-sizey":s}),g.length){var m=[g[0],r.row,g.length,Math.min(n,s),i];this.remove_empty_cells.apply(this,m)}if(f.length){var x=[h,r.row,e,s,i];this.remove_empty_cells.apply(this,x)}return i},o.empty_cells=function(i,e,s,r,o){var a=this.widgets_below({col:i,row:e-r,size_x:s,size_y:r});return a.not(o).each(t.proxy(function(i,s){var o=t(s).coords().grid;if(e+r-1>=o.row){var a=e+r-o.row;this.move_widget_down(t(s),a)}},this)),this.set_dom_grid_height(),this},o.remove_empty_cells=function(t,i,e,s){return this.widgets_below({col:t,row:i,size_x:e,size_y:s}),this.set_dom_grid_height(),this},o.next_position=function(t,i){t||(t=1),i||(i=1);for(var e,s=this.gridmap,r=s.length,o=[],a=1;r>a;a++){e=s[a].length;for(var n=1;e>=n;n++){var _=this.can_move_to({size_x:t,size_y:i},a,n);_&&o.push({col:a,row:n,size_y:i,size_x:t})}}return o.length?this.sort_by_row_and_col_asc(o)[0]:!1},o.remove_by_grid=function(t,i){var e=this.is_widget(t,i);e&&this.remove_widget(e)},o.remove_widget=function(i,e,s){var r=i instanceof jQuery?i:t(i),o=r.coords().grid;t.isFunction(e)&&(s=e,e=!1),this.cells_occupied_by_placeholder={},this.$widgets=this.$widgets.not(r);var a=this.widgets_below(r);this.remove_from_gridmap(o),r.fadeOut(t.proxy(function(){r.remove(),e||a.each(t.proxy(function(i,e){this.move_widget_up(t(e),o.size_y)},this)),this.set_dom_grid_height(),s&&s.call(this,i)},this))},o.remove_all_widgets=function(i){return this.$widgets.each(t.proxy(function(t,e){this.remove_widget(e,!0,i)},this)),this},o.serialize=function(i){i||(i=this.$widgets);var e=[];return i.each(t.proxy(function(i,s){t(s).coords().grid!==undefined&&e.push(this.options.serialize_params(t(s),t(s).coords().grid))},this)),e},o.serialize_changed=function(){return this.serialize(this.$changed)},o.register_widget=function(t){var i={col:parseInt(t.attr("data-col"),10),row:parseInt(t.attr("data-row"),10),size_x:parseInt(t.attr("data-sizex"),10),size_y:parseInt(t.attr("data-sizey"),10),el:t};return this.options.avoid_overlapped_widgets&&!this.can_move_to({size_x:i.size_x,size_y:i.size_y},i.col,i.row)&&(i=this.next_position(i.size_x,i.size_y),i.el=t,t.attr({"data-col":i.col,"data-row":i.row,"data-sizex":i.size_x,"data-sizey":i.size_y})),t.data("coords",t.coords()),t.data("coords").grid=i,this.add_to_gridmap(i,t),this},o.update_widget_position=function(t,i){return this.for_each_cell_occupied(t,function(t,e){return this.gridmap[t]?(this.gridmap[t][e]=i,undefined):this}),this},o.remove_from_gridmap=function(t){return this.update_widget_position(t,!1)},o.add_to_gridmap=function(t,i){this.update_widget_position(t,i||t.el)},o.draggable=function(){var i=this,e=t.extend(!0,{},this.options.draggable,{offset_left:this.options.widget_margins[0],start:function(e,s){i.$widgets.filter(".player-revert").removeClass("player-revert"),i.$player=t(this),i.$helper="clone"===i.options.draggable.helper?t(s.helper):i.$player,i.helper=!i.$helper.is(i.$player),i.on_start_drag.call(i,e,s),i.$el.trigger("gridster:dragstart")},stop:function(t,e){i.on_stop_drag.call(i,t,e),i.$el.trigger("gridster:dragstop")},drag:throttle(function(t,e){i.on_drag.call(i,t,e),i.$el.trigger("gridster:drag")},60)});return this.drag_api=this.$el.dragg(e).data("drag"),this},o.on_start_drag=function(i,e){this.$helper.add(this.$player).add(this.$wrapper).addClass("dragging"),this.$player.addClass("player"),this.player_grid_data=this.$player.coords().grid,this.placeholder_grid_data=t.extend({},this.player_grid_data),this.$el.css("height",this.$el.height()+this.player_grid_data.size_y*this.min_widget_height);var s=this.faux_grid,r=this.$player.data("coords").coords;this.cells_occupied_by_player=this.get_cells_occupied(this.player_grid_data),this.cells_occupied_by_placeholder=this.get_cells_occupied(this.placeholder_grid_data),this.last_cols=[],this.last_rows=[],this.collision_api=this.$helper.collision(s,this.options.collision),this.$preview_holder=t("
  • ",{"class":"preview-holder","data-row":this.$player.attr("data-row"),"data-col":this.$player.attr("data-col"),css:{width:r.width,height:r.height}}).appendTo(this.$el),this.options.draggable.start&&this.options.draggable.start.call(this,i,e)},o.on_drag=function(t,i){if(null===this.$player)return!1;var e={left:i.position.left+this.baseX,top:i.position.top+this.baseY};this.colliders_data=this.collision_api.get_closest_colliders(e),this.on_overlapped_column_change(this.on_start_overlapping_column,this.on_stop_overlapping_column),this.on_overlapped_row_change(this.on_start_overlapping_row,this.on_stop_overlapping_row),this.helper&&this.$player&&this.$player.css({left:i.position.left,top:i.position.top}),this.options.draggable.drag&&this.options.draggable.drag.call(this,t,i)},o.on_stop_drag=function(t,i){this.$helper.add(this.$player).add(this.$wrapper).removeClass("dragging"),i.position.left=i.position.left+this.baseX,i.position.top=i.position.top+this.baseY,this.colliders_data=this.collision_api.get_closest_colliders(i.position),this.on_overlapped_column_change(this.on_start_overlapping_column,this.on_stop_overlapping_column),this.on_overlapped_row_change(this.on_start_overlapping_row,this.on_stop_overlapping_row),this.$player.addClass("player-revert").removeClass("player").attr({"data-col":this.placeholder_grid_data.col,"data-row":this.placeholder_grid_data.row}).css({left:"",top:""}),this.$changed=this.$changed.add(this.$player),this.cells_occupied_by_player=this.get_cells_occupied(this.placeholder_grid_data),this.set_cells_player_occupies(this.placeholder_grid_data.col,this.placeholder_grid_data.row),this.$player.coords().grid.row=this.placeholder_grid_data.row,this.$player.coords().grid.col=this.placeholder_grid_data.col,this.options.draggable.stop&&this.options.draggable.stop.call(this,t,i),this.$preview_holder.remove(),this.$player=null,this.$helper=null,this.placeholder_grid_data={},this.player_grid_data={},this.cells_occupied_by_placeholder={},this.cells_occupied_by_player={},this.w_queue={},this.set_dom_grid_height()},o.on_overlapped_column_change=function(i,e){if(this.colliders_data.length){var s,r=this.get_targeted_columns(this.colliders_data[0].el.data.col),o=this.last_cols.length,a=r.length;for(s=0;a>s;s++)-1===t.inArray(r[s],this.last_cols)&&(i||t.noop).call(this,r[s]);for(s=0;o>s;s++)-1===t.inArray(this.last_cols[s],r)&&(e||t.noop).call(this,this.last_cols[s]);return this.last_cols=r,this}},o.on_overlapped_row_change=function(i,e){if(this.colliders_data.length){var s,r=this.get_targeted_rows(this.colliders_data[0].el.data.row),o=this.last_rows.length,a=r.length;for(s=0;a>s;s++)-1===t.inArray(r[s],this.last_rows)&&(i||t.noop).call(this,r[s]);for(s=0;o>s;s++)-1===t.inArray(this.last_rows[s],r)&&(e||t.noop).call(this,this.last_rows[s]);this.last_rows=r}},o.set_player=function(i,e,s){var r=this,o=!1;s||this.empty_cells_player_occupies();var a=s?{col:i}:r.colliders_data[0].el.data,n=a.col,_=a.row||e;this.player_grid_data={col:n,row:_,size_y:this.player_grid_data.size_y,size_x:this.player_grid_data.size_x},this.cells_occupied_by_player=this.get_cells_occupied(this.player_grid_data),this.cells_occupied_by_placeholder=this.get_cells_occupied(this.placeholder_grid_data);var h=this.get_widgets_overlapped(this.player_grid_data),d=this.player_grid_data.size_y,l=this.player_grid_data.size_x,c=this.cells_occupied_by_placeholder,p=this;if(h.each(t.proxy(function(i,e){var s=t(e),r=s.coords().grid,a=c.cols[0]+l-1,g=c.rows[0]+d-1;if(s.hasClass(p.options.static_class))return!0;if(l>=r.size_x&&d>=r.size_y)if(p.is_swap_occupied(c.cols[0],r.row,r.size_x,r.size_y)||p.is_player_in(c.cols[0],r.row)||p.is_in_queue(c.cols[0],r.row,s))if(p.is_swap_occupied(a,r.row,r.size_x,r.size_y)||p.is_player_in(a,r.row)||p.is_in_queue(a,r.row,s))if(p.is_swap_occupied(r.col,c.rows[0],r.size_x,r.size_y)||p.is_player_in(r.col,c.rows[0])||p.is_in_queue(r.col,c.rows[0],s))if(p.is_swap_occupied(r.col,g,r.size_x,r.size_y)||p.is_player_in(r.col,g)||p.is_in_queue(r.col,g,s))if(p.is_swap_occupied(c.cols[0],c.rows[0],r.size_x,r.size_y)||p.is_player_in(c.cols[0],c.rows[0])||p.is_in_queue(c.cols[0],c.rows[0],s))for(var u=0;l>u;u++)for(var f=0;d>f;f++){var w=c.cols[0]+u,y=c.rows[0]+f;if(!p.is_swap_occupied(w,y,r.size_x,r.size_y)&&!p.is_player_in(w,y)&&!p.is_in_queue(w,y,s)){o=p.queue_widget(w,y,s),u=l;break}}else o=p.queue_widget(c.cols[0],c.rows[0],s);else o=p.queue_widget(r.col,g,s);else o=p.queue_widget(r.col,c.rows[0],s);else o=p.queue_widget(a,r.row,s);else o=p.queue_widget(c.cols[0],r.row,s);else p.options.shift_larger_widgets_down&&!o&&h.each(t.proxy(function(i,e){var s=t(e);s.coords().grid,p.can_go_down(s)&&(p.move_widget_down(s,p.player_grid_data.size_y),p.set_placeholder(n,_))}));p.clean_up_changed()})),o&&this.can_placeholder_be_set(n,_,l,d)){for(var g in this.w_queue){var i=parseInt(g.split("_")[0]),e=parseInt(g.split("_")[1]);"full"!=this.w_queue[g]&&this.new_move_widget_to(this.w_queue[g],i,e)}this.set_placeholder(n,_)}if(!h.length){var u=this.can_go_player_up(this.player_grid_data);u!==!1&&(_=u),this.can_placeholder_be_set(n,_,l,d)&&this.set_placeholder(n,_)}return this.w_queue={},{col:n,row:_}},o.is_swap_occupied=function(t,i,e,s){for(var r=!1,o=0;e>o;o++)for(var a=0;s>a;a++){var n=t+o,_=i+a,h=n+"_"+_;if(this.is_occupied(n,_))r=!0;else if(h in this.w_queue){if("full"==this.w_queue[h]){r=!0;continue}$tw=this.w_queue[h],tgd=$tw.coords().grid,this.is_widget_under_player(tgd.col,tgd.row)||delete this.w_queue[h]}_>parseInt(this.options.max_rows)&&(r=!0),n>parseInt(this.options.max_cols)&&(r=!0),this.is_player_in(n,_)&&(r=!0)}return r},o.can_placeholder_be_set=function(t,i,e,s){for(var r=!0,o=0;e>o;o++)for(var a=0;s>a;a++){var n=t+o,_=i+a,h=this.is_widget(n,_);_>parseInt(this.options.max_rows)&&(r=!1),n>parseInt(this.options.max_cols)&&(r=!1),this.is_occupied(n,_)&&!this.is_widget_queued_and_can_move(h)&&(r=!1)}return r},o.queue_widget=function(t,i,e){var s=e,r=s.coords().grid,o=t+"_"+i;if(o in this.w_queue)return!1;this.w_queue[o]=s;for(var a=0;r.size_x>a;a++)for(var n=0;r.size_y>n;n++){var _=t+a,h=i+n,d=_+"_"+h;d!=o&&(this.w_queue[d]="full")}return!0},o.is_widget_queued_and_can_move=function(t){var i=!1;if(t===!1)return!1;for(var e in this.w_queue)if("full"!=this.w_queue[e]&&this.w_queue[e].attr("data-col")==t.attr("data-col")&&this.w_queue[e].attr("data-row")==t.attr("data-row")){i=!0;for(var s=this.w_queue[e],r=parseInt(e.split("_")[0]),o=parseInt(e.split("_")[1]),a=s.coords().grid,n=0;a.size_x>n;n++)for(var _=0;a.size_y>_;_++){var h=r+n,d=o+_;this.is_player_in(h,d)&&(i=!1)}}return i},o.is_in_queue=function(t,i,e){var s=!1,r=t+"_"+i;return r in this.w_queue&&("full"==this.w_queue[r]?s=!0:($tw=this.w_queue[r],tgd=$tw.coords().grid,this.is_widget_under_player(tgd.col,tgd.row)?this.w_queue[r].attr("data-col")==e.attr("data-col")&&this.w_queue[r].attr("data-row")==e.attr("data-row")?(delete this.w_queue[r],s=!1):s=!0:(delete this.w_queue[r],s=!1))),s},o.widgets_constraints=function(i){var e,s=t([]),r=[],o=[];return i.each(t.proxy(function(i,e){var a=t(e),n=a.coords().grid;this.can_go_widget_up(n)?(s=s.add(a),r.push(n)):o.push(n)},this)),e=i.not(s),{can_go_up:this.sort_by_row_asc(r),can_not_go_up:this.sort_by_row_desc(o)}},o.sort_by_row_asc=function(i){return i=i.sort(function(i,e){return i.row||(i=t(i).coords().grid,e=t(e).coords().grid),i.row>e.row?1:-1})},o.sort_by_row_and_col_asc=function(t){return t=t.sort(function(t,i){return t.row>i.row||t.row===i.row&&t.col>i.col?1:-1})},o.sort_by_col_asc=function(t){return t=t.sort(function(t,i){return t.col>i.col?1:-1})},o.sort_by_row_desc=function(t){return t=t.sort(function(t,i){return t.row+t.size_y=0&&t.inArray(e,s.rows)>=0},o.is_placeholder_in=function(i,e){var s=this.cells_occupied_by_placeholder||{};return this.is_placeholder_in_col(i)&&t.inArray(e,s.rows)>=0},o.is_placeholder_in_col=function(i){var e=this.cells_occupied_by_placeholder||[];return t.inArray(i,e.cols)>=0},o.is_empty=function(t,i){return this.gridmap[t]!==undefined&&this.gridmap[t][i]!==undefined&&this.gridmap[t][i]===!1?!0:!1},o.is_occupied=function(t,i){return this.gridmap[t]?this.gridmap[t][i]?!0:!1:!1},o.is_widget=function(t,i){var e=this.gridmap[t];return e?(e=e[i],e?e:!1):!1},o.is_static=function(t,i){var e=this.gridmap[t];return e?(e=e[i],e&&e.hasClass(this.options.static_class)?!0:!1):!1},o.is_widget_under_player=function(t,i){return this.is_widget(t,i)?this.is_player_in(t,i):!1},o.get_widgets_under_player=function(i){i||(i=this.cells_occupied_by_player||{cols:[],rows:[]});var e=t([]);return t.each(i.cols,t.proxy(function(s,r){t.each(i.rows,t.proxy(function(t,i){this.is_widget(r,i)&&(e=e.add(this.gridmap[r][i]))},this))},this)),e},o.set_placeholder=function(i,e){var s=t.extend({},this.placeholder_grid_data),r=this.widgets_below({col:s.col,row:s.row,size_y:s.size_y,size_x:s.size_x}),o=i+s.size_x-1;o>this.cols&&(i-=o-i);var a=e>this.placeholder_grid_data.row,n=this.placeholder_grid_data.col!==i;this.placeholder_grid_data.col=i,this.placeholder_grid_data.row=e,this.cells_occupied_by_placeholder=this.get_cells_occupied(this.placeholder_grid_data),this.$preview_holder.attr({"data-row":e,"data-col":i}),(a||n)&&r.each(t.proxy(function(i,e){$w=t(e),wgd=$w.coords().grid;var s=this.can_go_widget_up(wgd);s&&this.move_widget_to($w,s)},this));var _=this.get_widgets_under_player(this.cells_occupied_by_placeholder);_.length&&_.each(t.proxy(function(i,r){var o=t(r);this.move_widget_down(o,e+s.size_y-o.data("coords").grid.row)},this))},o.can_go_player_up=function(t){var i=t.row+t.size_y-1,e=!0,s=[],r=1e4,o=this.get_widgets_under_player();return this.for_each_column_occupied(t,function(t){var a=this.gridmap[t],n=i+1;for(s[t]=[];--n>0&&(this.is_empty(t,n)||this.is_player(t,n)||this.is_widget(t,n)&&a[n].is(o));)s[t].push(n),r=r>n?n:r;return 0===s[t].length?(e=!1,!0):(s[t].sort(),undefined)}),e?this.get_valid_rows(t,s,r):!1},o.can_go_widget_up=function(t){var i=t.row+t.size_y-1,e=!0,s=[],r=1e4;return this.for_each_column_occupied(t,function(o){var a=this.gridmap[o];s[o]=[];for(var n=i+1;--n>0&&(!this.is_widget(o,n)||this.is_player_in(o,n)||a[n].is(t.el));)this.is_player(o,n)||this.is_placeholder_in(o,n)||this.is_player_in(o,n)||s[o].push(n),r>n&&(r=n);return 0===s[o].length?(e=!1,!0):(s[o].sort(),undefined)}),e?this.get_valid_rows(t,s,r):!1},o.get_valid_rows=function(i,e,s){for(var r=i.row,o=i.row+i.size_y-1,a=i.size_y,n=s-1,_=[];o>=++n;){var h=!0;if(t.each(e,function(i,e){t.isArray(e)&&-1===t.inArray(n,e)&&(h=!1)}),h===!0&&(_.push(n),_.length===a))break}var d=!1;return 1===a?_[0]!==r&&(d=_[0]||!1):_[0]!==r&&(d=this.get_consecutive_numbers_index(_,a)),d},o.get_consecutive_numbers_index=function(t,i){for(var e=t.length,s=[],r=!0,o=-1,a=0;e>a;a++){if(r||t[a]===o+1){if(s.push(a),s.length===i)break;r=!1}else s=[],r=!0;o=t[a]}return s.length>=i?t[s[0]]:!1},o.get_widgets_overlapped=function(){var i=t([]),e=[],s=this.cells_occupied_by_player.rows.slice(0);return s.reverse(),t.each(this.cells_occupied_by_player.cols,t.proxy(function(r,o){t.each(s,t.proxy(function(s,r){if(!this.gridmap[o])return!0;var a=this.gridmap[o][r];this.is_occupied(o,r)&&!this.is_player(a)&&-1===t.inArray(a,e)&&(i=i.add(a),e.push(a))},this))},this)),i},o.on_start_overlapping_column=function(t){this.set_player(t,!1)},o.on_start_overlapping_row=function(t){this.set_player(!1,t)},o.on_stop_overlapping_column=function(t){var i=this;this.options.shift_larger_widgets_down&&this.for_each_widget_below(t,this.cells_occupied_by_player.rows[0],function(){i.move_widget_up(this,i.player_grid_data.size_y)})},o.on_stop_overlapping_row=function(t){var i=this,e=this.cells_occupied_by_player.cols;if(this.options.shift_larger_widgets_down)for(var s=0,r=e.length;r>s;s++)this.for_each_widget_below(e[s],t,function(){console.log("from_on_stop_overlapping_row"),i.move_widget_up(this,i.player_grid_data.size_y)})},o.new_move_widget_to=function(t,i,e){var s=t.coords().grid;return this.remove_from_gridmap(s),s.row=e,s.col=i,this.add_to_gridmap(s),t.attr("data-row",e),t.attr("data-col",i),this.update_widget_position(s,t),this.$changed=this.$changed.add(t),this},o.move_widget_to=function(i,e){var s=this,r=i.coords().grid;e-r.row;var o=this.widgets_below(i),a=this.can_move_to(r,r.col,e,i);return a===!1?!1:(this.remove_from_gridmap(r),r.row=e,this.add_to_gridmap(r),i.attr("data-row",e),this.$changed=this.$changed.add(i),o.each(function(i,e){var r=t(e),o=r.coords().grid,a=s.can_go_widget_up(o);a&&a!==o.row&&s.move_widget_to(r,a)}),this)},o.move_widget_up=function(i,e){var s=i.coords().grid,r=s.row,o=[];return e||(e=1),this.can_go_up(i)?(this.for_each_column_occupied(s,function(s){if(-1===t.inArray(i,o)){var a=i.coords().grid,n=r-e;if(n=this.can_go_up_to_row(a,s,n),!n)return!0;this.widgets_below(i),this.remove_from_gridmap(a),a.row=n,this.add_to_gridmap(a),i.attr("data-row",a.row),this.$changed=this.$changed.add(i),o.push(i)}}),undefined):!1},o.move_widget_down=function(i,e){var s=i.coords().grid,r=s.row,o=[],a=e;if(!i)return!1;if(-1===t.inArray(i,o)){var n=i.coords().grid,_=r+e,h=this.widgets_below(i);this.remove_from_gridmap(n),h.each(t.proxy(function(i,e){var s=t(e),r=s.coords().grid,o=this.displacement_diff(r,n,a);o>0&&this.move_widget_down(s,o)},this)),n.row=_,this.update_widget_position(n,i),i.attr("data-row",n.row),this.$changed=this.$changed.add(i),o.push(i)}},o.can_go_up_to_row=function(i,e,s){var r,o=this.gridmap,a=!0,n=[],_=i.row;if(this.for_each_column_occupied(i,function(t){for(o[t],n[t]=[],r=_;r--&&this.is_empty(t,r)&&!this.is_placeholder_in(t,r);)n[t].push(r);return n[t].length?undefined:(a=!1,!0)}),!a)return!1;for(r=s,r=1;_>r;r++){for(var h=!0,d=0,l=n.length;l>d;d++)n[d]&&-1===t.inArray(r,n[d])&&(h=!1);if(h===!0){a=r;break}}return a},o.displacement_diff=function(t,i,e){var s=t.row,r=[],o=i.row+i.size_y;this.for_each_column_occupied(t,function(t){for(var i=0,e=o;s>e;e++)this.is_empty(t,e)&&(i+=1);r.push(i)});var a=Math.max.apply(Math,r);return e-=a,e>0?e:0},o.widgets_below=function(i){var e=t.isPlainObject(i)?i:i.coords().grid,s=this;this.gridmap;var r=e.row+e.size_y-1,o=t([]);return this.for_each_column_occupied(e,function(i){s.for_each_widget_below(i,r,function(){return s.is_player(this)||-1!==t.inArray(this,o)?undefined:(o=o.add(this),!0)})}),this.sort_by_row_asc(o)},o.set_cells_player_occupies=function(t,i){return this.remove_from_gridmap(this.placeholder_grid_data),this.placeholder_grid_data.col=t,this.placeholder_grid_data.row=i,this.add_to_gridmap(this.placeholder_grid_data,this.$player),this},o.empty_cells_player_occupies=function(){return this.remove_from_gridmap(this.placeholder_grid_data),this},o.can_go_down=function(i){var e=!0,s=this;return i.hasClass(this.options.static_class)&&(e=!1),this.widgets_below(i).each(function(){t(this).hasClass(s.options.static_class)&&(e=!1)}),e},o.can_go_up=function(t){var i=t.coords().grid,e=i.row,s=e-1;this.gridmap;var r=!0;return 1===e?!1:(this.for_each_column_occupied(i,function(t){return this.is_widget(t,s),this.is_occupied(t,s)||this.is_player(t,s)||this.is_placeholder_in(t,s)||this.is_player_in(t,s)?(r=!1,!0):undefined}),r)},o.can_move_to=function(t,i,e,s){this.gridmap;var r=t.el,o={size_y:t.size_y,size_x:t.size_x,col:i,row:e},a=!0,n=i+t.size_x-1;return n>this.cols?!1:s&&e+t.size_y-1>s?!1:(this.for_each_cell_occupied(o,function(i,e){var s=this.is_widget(i,e);!s||t.el&&!s.is(r)||(a=!1)}),a)},o.get_targeted_columns=function(t){for(var i=(t||this.player_grid_data.col)+(this.player_grid_data.size_x-1),e=[],s=t;i>=s;s++)e.push(s);return e},o.get_targeted_rows=function(t){for(var i=(t||this.player_grid_data.row)+(this.player_grid_data.size_y-1),e=[],s=t;i>=s;s++)e.push(s);return e},o.get_cells_occupied=function(t){var i,e={cols:[],rows:[]};for(arguments[1]instanceof jQuery&&(t=arguments[1].coords().grid),i=0;t.size_x>i;i++){var s=t.col+i;e.cols.push(s)}for(i=0;t.size_y>i;i++){var r=t.row+i; -e.rows.push(r)}return e},o.for_each_cell_occupied=function(t,i){return this.for_each_column_occupied(t,function(e){this.for_each_row_occupied(t,function(t){i.call(this,e,t)})}),this},o.for_each_column_occupied=function(t,i){for(var e=0;t.size_x>e;e++){var s=t.col+e;i.call(this,s,t)}},o.for_each_row_occupied=function(t,i){for(var e=0;t.size_y>e;e++){var s=t.row+e;i.call(this,s,t)}},o.clean_up_changed=function(){$gr=this,$gr.$changed.each(function(){$gr.options.shift_larger_widgets_down&&$gr.move_widget_up(t(this))})},o._traversing_widgets=function(i,e,s,r,o){var a=this.gridmap;if(a[s]){var n,_,h=i+"/"+e;if(arguments[2]instanceof jQuery){var d=arguments[2].coords().grid;s=d.col,r=d.row,o=arguments[3]}var l=[],c=r,p={"for_each/above":function(){for(;c--&&!(c>0&&this.is_widget(s,c)&&-1===t.inArray(a[s][c],l)&&(n=o.call(a[s][c],s,c),l.push(a[s][c]),n)););},"for_each/below":function(){for(c=r+1,_=a[s].length;_>c;c++)this.is_widget(s,c)&&-1===t.inArray(a[s][c],l)&&(n=o.call(a[s][c],s,c),l.push(a[s][c]))}};p[h]&&p[h].call(this)}},o.for_each_widget_above=function(t,i,e){return this._traversing_widgets("for_each","above",t,i,e),this},o.for_each_widget_below=function(t,i,e){return this._traversing_widgets("for_each","below",t,i,e),this},o.get_highest_occupied_cell=function(){for(var t,i=this.gridmap,e=[],s=[],r=i.length-1;r>=1;r--)for(t=i[r].length-1;t>=1;t--)if(this.is_widget(r,t)){e.push(t),s[t]=r;break}var o=Math.max.apply(Math,e);return this.highest_occupied_cell={col:s[o],row:o},this.highest_occupied_cell},o.get_widgets_from=function(i,e){this.gridmap;var s=t();return i&&(s=s.add(this.$widgets.filter(function(){var e=t(this).attr("data-col");return e===i||e>i}))),e&&(s=s.add(this.$widgets.filter(function(){var i=t(this).attr("data-row");return i===e||i>e}))),s},o.set_dom_grid_height=function(){var t=this.get_highest_occupied_cell().row;return this.$el.css("height",t*this.min_widget_height),this},o.generate_stylesheet=function(i){var e,r="",o=this.options.max_size_x;i||(i={}),i.cols||(i.cols=this.cols),i.rows||(i.rows=this.rows),i.namespace||(i.namespace=this.options.namespace),i.widget_base_dimensions||(i.widget_base_dimensions=this.options.widget_base_dimensions),i.widget_margins||(i.widget_margins=this.options.widget_margins),i.min_widget_width=2*i.widget_margins[0]+i.widget_base_dimensions[0],i.min_widget_height=2*i.widget_margins[1]+i.widget_base_dimensions[1];var a=t.param(i);if(t.inArray(a,s.generated_stylesheets)>=0)return!1;for(s.generated_stylesheets.push(a),e=i.cols;e>=0;e--)r+=i.namespace+' [data-col="'+(e+1)+'"] { left:'+(e*i.widget_base_dimensions[0]+e*i.widget_margins[0]+(e+1)*i.widget_margins[0])+"px;} ";for(e=i.rows;e>=0;e--)r+=i.namespace+' [data-row="'+(e+1)+'"] { top:'+(e*i.widget_base_dimensions[1]+e*i.widget_margins[1]+(e+1)*i.widget_margins[1])+"px;} ";for(var n=1;i.rows>=n;n++)r+=i.namespace+' [data-sizey="'+n+'"] { height:'+(n*i.widget_base_dimensions[1]+(n-1)*2*i.widget_margins[1])+"px;}";for(var _=1;o>=_;_++)r+=i.namespace+' [data-sizex="'+_+'"] { width:'+(_*i.widget_base_dimensions[0]+(_-1)*2*i.widget_margins[0])+"px;}";return this.add_style_tag(r)},o.add_style_tag=function(t){var i=e,s=i.createElement("style");return i.getElementsByTagName("head")[0].appendChild(s),s.setAttribute("type","text/css"),s.styleSheet?s.styleSheet.cssText=t:s.appendChild(e.createTextNode(t)),this},o.generate_faux_grid=function(t,i){this.faux_grid=[],this.gridmap=[];var e,s;for(e=i;e>0;e--)for(this.gridmap[e]=[],s=t;s>0;s--)this.add_faux_cell(s,e);return this},o.add_faux_cell=function(i,e){var s=t({left:this.baseX+(e-1)*this.min_widget_width,top:this.baseY+(i-1)*this.min_widget_height,width:this.min_widget_width,height:this.min_widget_height,col:e,row:i,original_col:e,original_row:i}).coords();return t.isArray(this.gridmap[e])||(this.gridmap[e]=[]),this.gridmap[e][i]=!1,this.faux_grid.push(s),this},o.add_faux_rows=function(t){for(var i=this.rows,e=i+(t||1),s=e;s>i;s--)for(var r=this.cols;r>=1;r--)this.add_faux_cell(s,r);return this.rows=e,this.options.autogenerate_stylesheet&&this.generate_stylesheet(),this},o.add_faux_cols=function(t){for(var i=this.cols,e=i+(t||1),s=i;e>s;s++)for(var r=this.rows;r>=1;r--)this.add_faux_cell(r,s);return this.cols=e,this.options.autogenerate_stylesheet&&this.generate_stylesheet(),this},o.recalculate_faux_grid=function(){var e=this.$wrapper.width();return this.baseX=(t(i).width()-e)/2,this.baseY=this.$wrapper.offset().top,t.each(this.faux_grid,t.proxy(function(t,i){this.faux_grid[t]=i.update({left:this.baseX+(i.data.col-1)*this.min_widget_width,top:this.baseY+(i.data.row-1)*this.min_widget_height})},this)),this},o.get_widgets_from_DOM=function(){return this.$widgets.each(t.proxy(function(i,e){this.register_widget(t(e))},this)),this},o.generate_grid_and_stylesheet=function(){var e=this.$wrapper.width();this.$wrapper.height();var s=Math.floor(e/this.min_widget_width)+this.options.extra_cols,r=this.$widgets.map(function(){return t(this).attr("data-col")});r=Array.prototype.slice.call(r,0),r.length||(r=[0]);var o=Math.max.apply(Math,r),a=this.options.extra_rows;return this.$widgets.each(function(i,e){a+=+t(e).attr("data-sizey")}),this.cols=Math.max(o,s,this.options.min_cols),this.rows=this.options.max_rows,this.baseX=(t(i).width()-e)/2,this.baseY=this.$wrapper.offset().top,this.options.autogenerate_stylesheet&&this.generate_stylesheet(),this.generate_faux_grid(this.rows,this.cols)},t.fn.gridster=function(i){return this.each(function(){t(this).data("gridster")||t(this).data("gridster",new s(this,i))})},t.Gridster=o}(jQuery,window,document); \ No newline at end of file diff --git a/api/js/jquery/gridster/jquery.gridster.with-extras.js b/api/js/jquery/gridster/jquery.gridster.with-extras.js deleted file mode 100644 index b5ec7d1014..0000000000 --- a/api/js/jquery/gridster/jquery.gridster.with-extras.js +++ /dev/null @@ -1,3778 +0,0 @@ -/* - * jquery.coords - * https://github.com/ducksboard/gridster.js - * - * Copyright (c) 2012 ducksboard - * Licensed under the MIT licenses. - */ - -;(function($, window, document, undefined){ - /** - * Creates objects with coordinates (x1, y1, x2, y2, cx, cy, width, height) - * to simulate DOM elements on the screen. - * Coords is used by Gridster to create a faux grid with any DOM element can - * collide. - * - * @class Coords - * @param {HTMLElement|Object} obj The jQuery HTMLElement or a object with: left, - * top, width and height properties. - * @return {Object} Coords instance. - * @constructor - */ - function Coords(obj) { - if (obj[0] && $.isPlainObject(obj[0])) { - this.data = obj[0]; - }else { - this.el = obj; - } - - this.isCoords = true; - this.coords = {}; - this.init(); - return this; - } - - - var fn = Coords.prototype; - - - fn.init = function(){ - this.set(); - this.original_coords = this.get(); - }; - - - fn.set = function(update, not_update_offsets) { - var el = this.el; - - if (el && !update) { - this.data = el.offset(); - this.data.width = el.width(); - this.data.height = el.height(); - } - - if (el && update && !not_update_offsets) { - var offset = el.offset(); - this.data.top = offset.top; - this.data.left = offset.left; - } - - var d = this.data; - - this.coords.x1 = d.left; - this.coords.y1 = d.top; - this.coords.x2 = d.left + d.width; - this.coords.y2 = d.top + d.height; - this.coords.cx = d.left + (d.width / 2); - this.coords.cy = d.top + (d.height / 2); - this.coords.width = d.width; - this.coords.height = d.height; - this.coords.el = el || false ; - - return this; - }; - - - fn.update = function(data){ - if (!data && !this.el) { - return this; - } - - if (data) { - var new_data = $.extend({}, this.data, data); - this.data = new_data; - return this.set(true, true); - } - - this.set(true); - return this; - }; - - - fn.get = function(){ - return this.coords; - }; - - - //jQuery adapter - $.fn.coords = function() { - if (this.data('coords') ) { - return this.data('coords'); - } - - var ins = new Coords(this, arguments[0]); - this.data('coords', ins); - return ins; - }; - -}(jQuery, window, document)); - -/* - * jquery.collision - * https://github.com/ducksboard/gridster.js - * - * Copyright (c) 2012 ducksboard - * Licensed under the MIT licenses. - */ - -;(function($, window, document, undefined){ - - var defaults = { - colliders_context: document.body - // ,on_overlap: function(collider_data){}, - // on_overlap_start : function(collider_data){}, - // on_overlap_stop : function(collider_data){} - }; - - - /** - * Detects collisions between a DOM element against other DOM elements or - * Coords objects. - * - * @class Collision - * @uses Coords - * @param {HTMLElement} el The jQuery wrapped HTMLElement. - * @param {HTMLElement|Array} colliders Can be a jQuery collection - * of HTMLElements or an Array of Coords instances. - * @param {Object} [options] An Object with all options you want to - * overwrite: - * @param {Function} [options.on_overlap_start] Executes a function the first - * time each `collider ` is overlapped. - * @param {Function} [options.on_overlap_stop] Executes a function when a - * `collider` is no longer collided. - * @param {Function} [options.on_overlap] Executes a function when the - * mouse is moved during the collision. - * @return {Object} Collision instance. - * @constructor - */ - function Collision(el, colliders, options) { - this.options = $.extend(defaults, options); - this.$element = el; - this.last_colliders = []; - this.last_colliders_coords = []; - if (typeof colliders === 'string' || colliders instanceof jQuery) { - this.$colliders = $(colliders, - this.options.colliders_context).not(this.$element); - }else{ - this.colliders = $(colliders); - } - - this.init(); - } - - - var fn = Collision.prototype; - - - fn.init = function() { - this.find_collisions(); - }; - - - fn.overlaps = function(a, b) { - var x = false; - var y = false; - - if ((b.x1 >= a.x1 && b.x1 <= a.x2) || - (b.x2 >= a.x1 && b.x2 <= a.x2) || - (a.x1 >= b.x1 && a.x2 <= b.x2) - ) { x = true; } - - if ((b.y1 >= a.y1 && b.y1 <= a.y2) || - (b.y2 >= a.y1 && b.y2 <= a.y2) || - (a.y1 >= b.y1 && a.y2 <= b.y2) - ) { y = true; } - - return (x && y); - }; - - - fn.detect_overlapping_region = function(a, b){ - var regionX = ''; - var regionY = ''; - - if (a.y1 > b.cy && a.y1 < b.y2) { regionX = 'N'; } - if (a.y2 > b.y1 && a.y2 < b.cy) { regionX = 'S'; } - if (a.x1 > b.cx && a.x1 < b.x2) { regionY = 'W'; } - if (a.x2 > b.x1 && a.x2 < b.cx) { regionY = 'E'; } - - return (regionX + regionY) || 'C'; - }; - - - fn.calculate_overlapped_area_coords = function(a, b){ - var x1 = Math.max(a.x1, b.x1); - var y1 = Math.max(a.y1, b.y1); - var x2 = Math.min(a.x2, b.x2); - var y2 = Math.min(a.y2, b.y2); - - return $({ - left: x1, - top: y1, - width : (x2 - x1), - height: (y2 - y1) - }).coords().get(); - }; - - - fn.calculate_overlapped_area = function(coords){ - return (coords.width * coords.height); - }; - - - fn.manage_colliders_start_stop = function(new_colliders_coords, start_callback, stop_callback){ - var last = this.last_colliders_coords; - - for (var i = 0, il = last.length; i < il; i++) { - if ($.inArray(last[i], new_colliders_coords) === -1) { - start_callback.call(this, last[i]); - } - } - - for (var j = 0, jl = new_colliders_coords.length; j < jl; j++) { - if ($.inArray(new_colliders_coords[j], last) === -1) { - stop_callback.call(this, new_colliders_coords[j]); - } - - } - }; - - - fn.find_collisions = function(player_data_coords){ - var self = this; - var colliders_coords = []; - var colliders_data = []; - var $colliders = (this.colliders || this.$colliders); - var count = $colliders.length; - var player_coords = self.$element.coords() - .update(player_data_coords || false).get(); - - while(count--){ - var $collider = self.$colliders ? - $($colliders[count]) : $colliders[count]; - var $collider_coords_ins = ($collider.isCoords) ? - $collider : $collider.coords(); - var collider_coords = $collider_coords_ins.get(); - var overlaps = self.overlaps(player_coords, collider_coords); - - if (!overlaps) { - continue; - } - - var region = self.detect_overlapping_region( - player_coords, collider_coords); - - //todo: make this an option - if (region === 'C'){ - var area_coords = self.calculate_overlapped_area_coords( - player_coords, collider_coords); - var area = self.calculate_overlapped_area(area_coords); - var collider_data = { - area: area, - area_coords : area_coords, - region: region, - coords: collider_coords, - player_coords: player_coords, - el: $collider - }; - - if (self.options.on_overlap) { - self.options.on_overlap.call(this, collider_data); - } - colliders_coords.push($collider_coords_ins); - colliders_data.push(collider_data); - } - } - - if (self.options.on_overlap_stop || self.options.on_overlap_start) { - this.manage_colliders_start_stop(colliders_coords, - self.options.on_overlap_start, self.options.on_overlap_stop); - } - - this.last_colliders_coords = colliders_coords; - - return colliders_data; - }; - - - fn.get_closest_colliders = function(player_data_coords){ - var colliders = this.find_collisions(player_data_coords); - - colliders.sort(function(a, b) { - /* if colliders are being overlapped by the "C" (center) region, - * we have to set a lower index in the array to which they are placed - * above in the grid. */ - if (a.region === 'C' && b.region === 'C') { - if (a.coords.y1 < b.coords.y1 || a.coords.x1 < b.coords.x1) { - return - 1; - }else{ - return 1; - } - } - - if (a.area < b.area) { - return 1; - } - - return 1; - }); - return colliders; - }; - - - //jQuery adapter - $.fn.collision = function(collider, options) { - return new Collision( this, collider, options ); - }; - - -}(jQuery, window, document)); - -;(function(window, undefined) { - /* Debounce and throttle functions taken from underscore.js */ - window.debounce = function(func, wait, immediate) { - var timeout; - return function() { - var context = this, args = arguments; - var later = function() { - timeout = null; - if (!immediate) func.apply(context, args); - }; - if (immediate && !timeout) func.apply(context, args); - clearTimeout(timeout); - timeout = setTimeout(later, wait); - }; - }; - - - window.throttle = function(func, wait) { - var context, args, timeout, throttling, more, result; - var whenDone = debounce( - function(){ more = throttling = false; }, wait); - return function() { - context = this; args = arguments; - var later = function() { - timeout = null; - if (more) func.apply(context, args); - whenDone(); - }; - if (!timeout) timeout = setTimeout(later, wait); - if (throttling) { - more = true; - } else { - result = func.apply(context, args); - } - whenDone(); - throttling = true; - return result; - }; - }; - -})(window); - -/* - * jquery.draggable - * https://github.com/ducksboard/gridster.js - * - * Copyright (c) 2012 ducksboard - * Licensed under the MIT licenses. - */ - -;(function($, window, document, undefined){ - - var defaults = { - items: '.gs_w', - distance: 1, - limit: true, - offset_left: 0, - autoscroll: true, - ignore_dragging: ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'], - handle: null - // drag: function(e){}, - // start : function(e, ui){}, - // stop : function(e){} - }; - - var $window = $(window); - var isTouch = !!('ontouchstart' in window); - var pointer_events = { - start: isTouch ? 'touchstart' : 'mousedown.draggable', - move: isTouch ? 'touchmove' : 'mousemove.draggable', - end: isTouch ? 'touchend' : 'mouseup.draggable' - }; - - /** - * Basic drag implementation for DOM elements inside a container. - * Provide start/stop/drag callbacks. - * - * @class Draggable - * @param {HTMLElement} el The HTMLelement that contains all the widgets - * to be dragged. - * @param {Object} [options] An Object with all options you want to - * overwrite: - * @param {HTMLElement|String} [options.items] Define who will - * be the draggable items. Can be a CSS Selector String or a - * collection of HTMLElements. - * @param {Number} [options.distance] Distance in pixels after mousedown - * the mouse must move before dragging should start. - * @param {Boolean} [options.limit] Constrains dragging to the width of - * the container - * @param {offset_left} [options.offset_left] Offset added to the item - * that is being dragged. - * @param {Number} [options.drag] Executes a callback when the mouse is - * moved during the dragging. - * @param {Number} [options.start] Executes a callback when the drag - * starts. - * @param {Number} [options.stop] Executes a callback when the drag stops. - * @return {Object} Returns `el`. - * @constructor - */ - function Draggable(el, options) { - this.options = $.extend({}, defaults, options); - this.$body = $(document.body); - this.$container = $(el); - this.$dragitems = $(this.options.items, this.$container); - this.is_dragging = false; - this.player_min_left = 0 + this.options.offset_left; - this.init(); - } - - var fn = Draggable.prototype; - - fn.init = function() { - this.calculate_positions(); - this.$container.css('position', 'relative'); - this.disabled = false; - this.events(); - - this.on_window_resize = throttle($.proxy(this.calculate_positions, this), 200); - $(window).bind('resize', this.on_window_resize); - }; - - fn.events = function() { - this.proxied_on_select_start = $.proxy(this.on_select_start, this); - this.$container.on('selectstart', this.proxied_on_select_start); - - this.proxied_drag_handler = $.proxy(this.drag_handler, this); - this.$container.on(pointer_events.start, this.options.items, this.proxied_drag_handler); - - this.proxied_pointer_events_end = $.proxy(function(e) { - this.is_dragging = false; - if (this.disabled) { return; } - this.$body.off(pointer_events.move); - if (this.drag_start) { - this.on_dragstop(e); - } - }, this); - this.$body.on(pointer_events.end, this.proxied_pointer_events_end); - }; - - fn.get_actual_pos = function($el) { - var pos = $el.position(); - return pos; - }; - - - fn.get_mouse_pos = function(e) { - if (isTouch) { - var oe = e.originalEvent; - e = oe.touches.length ? oe.touches[0] : oe.changedTouches[0]; - } - - return { - left: e.clientX, - top: e.clientY - }; - }; - - - fn.get_offset = function(e) { - e.preventDefault(); - var mouse_actual_pos = this.get_mouse_pos(e); - var diff_x = Math.round( - mouse_actual_pos.left - this.mouse_init_pos.left); - var diff_y = Math.round(mouse_actual_pos.top - this.mouse_init_pos.top); - - var left = Math.round(this.el_init_offset.left + diff_x - this.baseX); - var top = Math.round( - this.el_init_offset.top + diff_y - this.baseY + this.scrollOffset); - - if (this.options.limit) { - if (left > this.player_max_left) { - left = this.player_max_left; - }else if(left < this.player_min_left) { - left = this.player_min_left; - } - } - - return { - left: left, - top: top, - mouse_left: mouse_actual_pos.left, - mouse_top: mouse_actual_pos.top - }; - }; - - - fn.manage_scroll = function(offset) { - /* scroll document */ - var nextScrollTop; - var scrollTop = $window.scrollTop(); - var min_window_y = scrollTop; - var max_window_y = min_window_y + this.window_height; - - var mouse_down_zone = max_window_y - 50; - var mouse_up_zone = min_window_y + 50; - - var abs_mouse_left = offset.mouse_left; - var abs_mouse_top = min_window_y + offset.mouse_top; - - var max_player_y = (this.doc_height - this.window_height + - this.player_height); - - if (abs_mouse_top >= mouse_down_zone) { - nextScrollTop = scrollTop + 30; - if (nextScrollTop < max_player_y) { - $window.scrollTop(nextScrollTop); - this.scrollOffset = this.scrollOffset + 30; - } - } - - if (abs_mouse_top <= mouse_up_zone) { - nextScrollTop = scrollTop - 30; - if (nextScrollTop > 0) { - $window.scrollTop(nextScrollTop); - this.scrollOffset = this.scrollOffset - 30; - } - } - }; - - - fn.calculate_positions = function(e) { - this.window_height = $window.height(); - }; - - - fn.drag_handler = function(e) { - var node = e.target.nodeName; - if (this.disabled || e.which !== 1 && !isTouch) { - return; - } - - if (this.ignore_drag(e)) { - return; - } - - var self = this; - var first = true; - this.$player = $(e.currentTarget); - - this.el_init_pos = this.get_actual_pos(this.$player); - this.mouse_init_pos = this.get_mouse_pos(e); - this.offsetY = this.mouse_init_pos.top - this.el_init_pos.top; - - this.on_pointer_events_move = function(mme){ - var mouse_actual_pos = self.get_mouse_pos(mme); - var diff_x = Math.abs( - mouse_actual_pos.left - self.mouse_init_pos.left); - var diff_y = Math.abs( - mouse_actual_pos.top - self.mouse_init_pos.top); - if (!(diff_x > self.options.distance || - diff_y > self.options.distance) - ) { - return false; - } - - if (first) { - first = false; - self.on_dragstart.call(self, mme); - return false; - } - - if (self.is_dragging === true) { - self.on_dragmove.call(self, mme); - } - - return false; - }; - - this.$body.on(pointer_events.move, this.on_pointer_events_move); - - return false; - }; - - - fn.on_dragstart = function(e) { - e.preventDefault(); - this.drag_start = true; - this.is_dragging = true; - var offset = this.$container.offset(); - this.baseX = Math.round(offset.left); - this.baseY = Math.round(offset.top); - this.doc_height = $(document).height(); - - if (this.options.helper === 'clone') { - this.$helper = this.$player.clone() - .appendTo(this.$container).addClass('helper'); - this.helper = true; - }else{ - this.helper = false; - } - this.scrollOffset = 0; - this.el_init_offset = this.$player.offset(); - this.player_width = this.$player.width(); - this.player_height = this.$player.height(); - this.player_max_left = (this.$container.width() - this.player_width + - this.options.offset_left); - - if (this.options.start) { - this.options.start.call(this.$player, e, { - helper: this.helper ? this.$helper : this.$player - }); - } - return false; - }; - - - fn.on_dragmove = function(e) { - var offset = this.get_offset(e); - - this.options.autoscroll && this.manage_scroll(offset); - - (this.helper ? this.$helper : this.$player).css({ - 'position': 'absolute', - 'left' : offset.left, - 'top' : offset.top - }); - - var ui = { - 'position': { - 'left': offset.left, - 'top': offset.top - } - }; - - if (this.options.drag) { - this.options.drag.call(this.$player, e, ui); - } - return false; - }; - - - fn.on_dragstop = function(e) { - var offset = this.get_offset(e); - this.drag_start = false; - - var ui = { - 'position': { - 'left': offset.left, - 'top': offset.top - } - }; - - if (this.options.stop) { - this.options.stop.call(this.$player, e, ui); - } - - if (this.helper) { - this.$helper.remove(); - } - - return false; - }; - - fn.on_select_start = function(e) { - if (this.disabled) { return; } - - if (this.ignore_drag(e)) { - return; - } - - return false; - }; - - fn.enable = function() { - this.disabled = false; - }; - - fn.disable = function() { - this.disabled = true; - }; - - - fn.destroy = function(){ - this.disable(); - - this.$container.off('selectstart', this.proxied_on_select_start); - this.$container.off(pointer_events.start, this.proxied_drag_handler); - this.$body.off(pointer_events.end, this.proxied_pointer_events_end); - this.$body.off(pointer_events.move, this.on_pointer_events_move); - $(window).unbind('resize', this.on_window_resize); - - $.removeData(this.$container, 'drag'); - }; - - fn.ignore_drag = function(event) { - if (this.options.handle) { - return !$(event.target).is(this.options.handle); - } - - return $.inArray(event.target.nodeName, this.options.ignore_dragging) >= 0; - }; - - //jQuery adapter - $.fn.dragg = function ( options ) { - return this.each(function () { - if (!$.data(this, 'drag')) { - $.data(this, 'drag', new Draggable( this, options )); - } - }); - }; - - -}(jQuery, window, document)); - -/* - * jquery.gridster - * https://github.com/ducksboard/gridster.js - * - * Copyright (c) 2012 ducksboard - * Licensed under the MIT licenses. - */ -;(function($, window, document, undefined) { - - //ToDo Max_cols and Max_size_x conflict.. need to unify - var defaults = { - namespace: '', - widget_selector: 'li', - static_class: 'static', - widget_margins: [10, 10], - widget_base_dimensions: [400, 225], - extra_rows: 0, - extra_cols: 0, - min_cols: 1, - max_cols: 60, - min_rows: 15, - max_rows: 15, - max_size_x: 6, - autogenerate_stylesheet: true, - avoid_overlapped_widgets: true, - shift_larger_widgets_down: true, - serialize_params: function($w, wgd) { - return { - col: wgd.col, - row: wgd.row, - size_x: wgd.size_x, - size_y: wgd.size_y - }; - }, - collision: {}, - draggable: { - distance: 4, - items: ".gs_w:not(.static)" - } - }; - - - /** - * @class Gridster - * @uses Draggable - * @uses Collision - * @param {HTMLElement} el The HTMLelement that contains all the widgets. - * @param {Object} [options] An Object with all options you want to - * overwrite: - * @param {HTMLElement|String} [options.widget_selector] Define who will - * be the draggable widgets. Can be a CSS Selector String or a - * collection of HTMLElements - * @param {Array} [options.widget_margins] Margin between widgets. - * The first index for the horizontal margin (left, right) and - * the second for the vertical margin (top, bottom). - * @param {Array} [options.widget_base_dimensions] Base widget dimensions - * in pixels. The first index for the width and the second for the - * height. - * @param {Number} [options.extra_cols] Add more columns in addition to - * those that have been calculated. - * @param {Number} [options.extra_rows] Add more rows in addition to - * those that have been calculated. - * @param {Number} [options.min_cols] The minimum required columns. - * @param {Number} [options.min_rows] The minimum required rows. - * @param {Number} [options.max_size_x] The maximum number of columns - * that a widget can span. - * @param {Boolean} [options.autogenerate_stylesheet] If true, all the - * CSS required to position all widgets in their respective columns - * and rows will be generated automatically and injected to the - * `` of the document. You can set this to false, and write - * your own CSS targeting rows and cols via data-attributes like so: - * `[data-col="1"] { left: 10px; }` - * @param {Boolean} [options.avoid_overlapped_widgets] Avoid that widgets loaded - * from the DOM can be overlapped. It is helpful if the positions were - * bad stored in the database or if there was any conflict. - * @param {Function} [options.serialize_params] Return the data you want - * for each widget in the serialization. Two arguments are passed: - * `$w`: the jQuery wrapped HTMLElement, and `wgd`: the grid - * coords object (`col`, `row`, `size_x`, `size_y`). - * @param {Object} [options.collision] An Object with all options for - * Collision class you want to overwrite. See Collision docs for - * more info. - * @param {Object} [options.draggable] An Object with all options for - * Draggable class you want to overwrite. See Draggable docs for more - * info. - * - * @constructor - */ - function Gridster(el, options) { - this.options = $.extend(true, defaults, options); - this.$el = $(el); - this.$wrapper = this.$el.parent(); - this.$widgets = this.$el.children(this.options.widget_selector).addClass('gs_w'); - this.widgets = []; - this.$changed = $([]); - this.w_queue = {}; - this.wrapper_width = this.$wrapper.width(); - this.min_widget_width = (this.options.widget_margins[0] * 2) + - this.options.widget_base_dimensions[0]; - this.min_widget_height = (this.options.widget_margins[1] * 2) + - this.options.widget_base_dimensions[1]; - this.init(); - } - - Gridster.generated_stylesheets = []; - - var fn = Gridster.prototype; - - fn.init = function() { - this.generate_grid_and_stylesheet(); - this.get_widgets_from_DOM(); - this.set_dom_grid_height(); - this.$wrapper.addClass('ready'); - this.draggable(); - - $(window).bind( - 'resize', throttle($.proxy(this.recalculate_faux_grid, this), 200)); - }; - - - /** - * Disables dragging. - * - * @method disable - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.disable = function() { - this.$wrapper.find('.player-revert').removeClass('player-revert'); - this.drag_api.disable(); - return this; - }; - - - /** - * Enables dragging. - * - * @method enable - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.enable = function() { - this.drag_api.enable(); - return this; - }; - - - /** - * Add a new widget to the grid. - * - * @method add_widget - * @param {String|HTMLElement} html The string representing the HTML of the widget - * or the HTMLElement. - * @param {Number} [size_x] The nº of rows the widget occupies horizontally. - * @param {Number} [size_y] The nº of columns the widget occupies vertically. - * @param {Number} [col] The column the widget should start in. - * @param {Number} [row] The row the widget should start in. - * @return {HTMLElement} Returns the jQuery wrapped HTMLElement representing. - * the widget that was just created. - */ - fn.add_widget = function(html, size_x, size_y, col, row) { - var pos; - size_x || (size_x = 1); - size_y || (size_y = 1); - - if (!col & !row) { - pos = this.next_position(size_x, size_y); - }else{ - pos = { - col: col, - row: row - }; - - this.empty_cells(col, row, size_x, size_y); - } - - var $w = $(html).attr({ - 'data-col': pos.col, - 'data-row': pos.row, - 'data-sizex' : size_x, - 'data-sizey' : size_y - }).addClass('gs_w').appendTo(this.$el).hide(); - - this.$widgets = this.$widgets.add($w); - this.$changed = this.$changed.add($w); - - this.register_widget($w); - - this.add_faux_rows(pos.size_y); - //this.add_faux_cols(pos.size_x); - - this.set_dom_grid_height(); - - return $w.fadeIn(); - }; - - - - /** - * Change the size of a widget. - * - * @method resize_widget - * @param {HTMLElement} $widget The jQuery wrapped HTMLElement - * representing the widget. - * @param {Number} size_x The number of columns that will occupy the widget. - * @param {Number} size_y The number of rows that will occupy the widget. - * @return {HTMLElement} Returns $widget. - */ - fn.resize_widget = function($widget, size_x, size_y) { - var wgd = $widget.coords().grid; - size_x || (size_x = wgd.size_x); - size_y || (size_y = wgd.size_y); - - if (size_x > this.cols) { - size_x = this.cols; - } - - var old_cells_occupied = this.get_cells_occupied(wgd); - var old_size_x = wgd.size_x; - var old_size_y = wgd.size_y; - var old_col = wgd.col; - var new_col = old_col; - var wider = size_x > old_size_x; - var taller = size_y > old_size_y; - - if (old_col + size_x - 1 > this.cols) { - var diff = old_col + (size_x - 1) - this.cols; - var c = old_col - diff; - new_col = Math.max(1, c); - } - - var new_grid_data = { - col: new_col, - row: wgd.row, - size_x: size_x, - size_y: size_y - }; - - var new_cells_occupied = this.get_cells_occupied(new_grid_data); - - var empty_cols = []; - $.each(old_cells_occupied.cols, function(i, col) { - if ($.inArray(col, new_cells_occupied.cols) === -1) { - empty_cols.push(col); - } - }); - - var occupied_cols = []; - $.each(new_cells_occupied.cols, function(i, col) { - if ($.inArray(col, old_cells_occupied.cols) === -1) { - occupied_cols.push(col); - } - }); - - var empty_rows = []; - $.each(old_cells_occupied.rows, function(i, row) { - if ($.inArray(row, new_cells_occupied.rows) === -1) { - empty_rows.push(row); - } - }); - - var occupied_rows = []; - $.each(new_cells_occupied.rows, function(i, row) { - if ($.inArray(row, old_cells_occupied.rows) === -1) { - occupied_rows.push(row); - } - }); - - this.remove_from_gridmap(wgd); - - if (occupied_cols.length) { - var cols_to_empty = [ - new_col, wgd.row, size_x, Math.min(old_size_y, size_y), $widget - ]; - this.empty_cells.apply(this, cols_to_empty); - } - - if (occupied_rows.length) { - var rows_to_empty = [new_col, wgd.row, size_x, size_y, $widget]; - this.empty_cells.apply(this, rows_to_empty); - } - - wgd.col = new_col; - wgd.size_x = size_x; - wgd.size_y = size_y; - this.add_to_gridmap(new_grid_data, $widget); - - //update coords instance attributes - $widget.data('coords').update({ - width: (size_x * this.options.widget_base_dimensions[0] + - ((size_x - 1) * this.options.widget_margins[0]) * 2), - height: (size_y * this.options.widget_base_dimensions[1] + - ((size_y - 1) * this.options.widget_margins[1]) * 2) - }); - - if (size_y > old_size_y) { - this.add_faux_rows(size_y - old_size_y); - } - - if (size_x > old_size_x) { - this.add_faux_cols(size_x - old_size_x); - } - - $widget.attr({ - 'data-col': new_col, - 'data-sizex': size_x, - 'data-sizey': size_y - }); - - if (empty_cols.length) { - var cols_to_remove_holes = [ - empty_cols[0], wgd.row, - empty_cols.length, - Math.min(old_size_y, size_y), - $widget - ]; - - this.remove_empty_cells.apply(this, cols_to_remove_holes); - } - - if (empty_rows.length) { - var rows_to_remove_holes = [ - new_col, wgd.row, size_x, size_y, $widget - ]; - this.remove_empty_cells.apply(this, rows_to_remove_holes); - } - - return $widget; - }; - - /** - * Move down widgets in cells represented by the arguments col, row, size_x, - * size_y - * - * @method empty_cells - * @param {Number} col The column where the group of cells begin. - * @param {Number} row The row where the group of cells begin. - * @param {Number} size_x The number of columns that the group of cells - * occupy. - * @param {Number} size_y The number of rows that the group of cells - * occupy. - * @param {HTMLElement} $exclude Exclude widgets from being moved. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.empty_cells = function(col, row, size_x, size_y, $exclude) { - var $nexts = this.widgets_below({ - col: col, - row: row - size_y, - size_x: size_x, - size_y: size_y - }); - - $nexts.not($exclude).each($.proxy(function(i, w) { - var wgd = $(w).coords().grid; - if (!(wgd.row <= (row + size_y - 1))) { return; } - var diff = (row + size_y) - wgd.row; - this.move_widget_down($(w), diff); - }, this)); - - this.set_dom_grid_height(); - - return this; - }; - - - /** - * Move up widgets below cells represented by the arguments col, row, size_x, - * size_y. - * - * @method remove_empty_cells - * @param {Number} col The column where the group of cells begin. - * @param {Number} row The row where the group of cells begin. - * @param {Number} size_x The number of columns that the group of cells - * occupy. - * @param {Number} size_y The number of rows that the group of cells - * occupy. - * @param {HTMLElement} $exclude Exclude widgets from being moved. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.remove_empty_cells = function(col, row, size_x, size_y, exclude) { - var $nexts = this.widgets_below({ - col: col, - row: row, - size_x: size_x, - size_y: size_y - }); - - /* - $nexts.not(exclude).each($.proxy(function(i, widget) { - console.log("from_remove") - this.move_widget_up( $(widget), size_y ); - }, this)); - */ - - this.set_dom_grid_height(); - - return this; - }; - - - /** - * Get the most left column below to add a new widget. - * - * @method next_position - * @param {Number} size_x The nº of rows the widget occupies horizontally. - * @param {Number} size_y The nº of columns the widget occupies vertically. - * @return {Object} Returns a grid coords object representing the future - * widget coords. - */ - fn.next_position = function(size_x, size_y) { - size_x || (size_x = 1); - size_y || (size_y = 1); - var ga = this.gridmap; - var cols_l = ga.length; - var valid_pos = []; - var rows_l; - - for (var c = 1; c < cols_l; c++) { - rows_l = ga[c].length; - for (var r = 1; r <= rows_l; r++) { - var can_move_to = this.can_move_to({ - size_x: size_x, - size_y: size_y - }, c, r); - - if (can_move_to) { - valid_pos.push({ - col: c, - row: r, - size_y: size_y, - size_x: size_x - }); - } - } - } - - if (valid_pos.length) { - return this.sort_by_row_and_col_asc(valid_pos)[0]; - } - return false; - }; - - fn.remove_by_grid = function(col, row){ - var $w = this.is_widget(col, row); - if($w){ - this.remove_widget($w); - } - } - - - /** - * Remove a widget from the grid. - * - * @method remove_widget - * @param {HTMLElement} el The jQuery wrapped HTMLElement you want to remove. - * @param {Boolean|Function} silent If true, widgets below the removed one - * will not move up. If a Function is passed it will be used as callback. - * @param {Function} callback Function executed when the widget is removed. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.remove_widget = function(el, silent, callback) { - var $el = el instanceof jQuery ? el : $(el); - var wgd = $el.coords().grid; - - // if silent is a function assume it's a callback - if ($.isFunction(silent)) { - callback = silent; - silent = false; - } - - this.cells_occupied_by_placeholder = {}; - this.$widgets = this.$widgets.not($el); - - var $nexts = this.widgets_below($el); - - this.remove_from_gridmap(wgd); - - $el.fadeOut($.proxy(function() { - $el.remove(); - - if (!silent) { - $nexts.each($.proxy(function(i, widget) { - this.move_widget_up( $(widget), wgd.size_y ); - }, this)); - } - - this.set_dom_grid_height(); - - if (callback) { - callback.call(this, el); - } - }, this)); - }; - - - /** - * Remove all widgets from the grid. - * - * @method remove_all_widgets - * @param {Function} callback Function executed for each widget removed. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.remove_all_widgets = function(callback) { - this.$widgets.each($.proxy(function(i, el){ - this.remove_widget(el, true, callback); - }, this)); - - return this; - }; - - - /** - * Returns a serialized array of the widgets in the grid. - * - * @method serialize - * @param {HTMLElement} [$widgets] The collection of jQuery wrapped - * HTMLElements you want to serialize. If no argument is passed all widgets - * will be serialized. - * @return {Array} Returns an Array of Objects with the data specified in - * the serialize_params option. - */ - fn.serialize = function($widgets) { - $widgets || ($widgets = this.$widgets); - var result = []; - $widgets.each($.proxy(function(i, widget) { - if(typeof($(widget).coords().grid) != "undefined"){ - result.push(this.options.serialize_params( - $(widget), $(widget).coords().grid ) ); - } - }, this)); - - return result; - }; - - /** - * Returns a serialized array of the widgets that have changed their - * position. - * - * @method serialize_changed - * @return {Array} Returns an Array of Objects with the data specified in - * the serialize_params option. - */ - fn.serialize_changed = function() { - return this.serialize(this.$changed); - }; - - - /** - * Creates the grid coords object representing the widget a add it to the - * mapped array of positions. - * - * @method register_widget - * @return {Array} Returns the instance of the Gridster class. - */ - fn.register_widget = function($el) { - - var wgd = { - 'col': parseInt($el.attr('data-col'), 10), - 'row': parseInt($el.attr('data-row'), 10), - 'size_x': parseInt($el.attr('data-sizex'), 10), - 'size_y': parseInt($el.attr('data-sizey'), 10), - 'el': $el - }; - - if (this.options.avoid_overlapped_widgets && - !this.can_move_to( - {size_x: wgd.size_x, size_y: wgd.size_y}, wgd.col, wgd.row) - ) { - /*if(!$el.hasClass('.disp_ad')){ - $el.remove(); - return false; - }*/ - wgd = this.next_position(wgd.size_x, wgd.size_y); - wgd.el = $el; - $el.attr({ - 'data-col': wgd.col, - 'data-row': wgd.row, - 'data-sizex': wgd.size_x, - 'data-sizey': wgd.size_y - }); - } - - // attach Coord object to player data-coord attribute - $el.data('coords', $el.coords()); - - // Extend Coord object with grid position info - $el.data('coords').grid = wgd; - - this.add_to_gridmap(wgd, $el); - - return this; - }; - - - /** - * Update in the mapped array of positions the value of cells represented by - * the grid coords object passed in the `grid_data` param. - * - * @param {Object} grid_data The grid coords object representing the cells - * to update in the mapped array. - * @param {HTMLElement|Boolean} value Pass `false` or the jQuery wrapped - * HTMLElement, depends if you want to delete an existing position or add - * a new one. - * @method update_widget_position - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.update_widget_position = function(grid_data, value) { - this.for_each_cell_occupied(grid_data, function(col, row) { - if (!this.gridmap[col]) { return this; } - this.gridmap[col][row] = value; - }); - return this; - }; - - - /** - * Remove a widget from the mapped array of positions. - * - * @method remove_from_gridmap - * @param {Object} grid_data The grid coords object representing the cells - * to update in the mapped array. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.remove_from_gridmap = function(grid_data) { - return this.update_widget_position(grid_data, false); - }; - - - /** - * Add a widget to the mapped array of positions. - * - * @method add_to_gridmap - * @param {Object} grid_data The grid coords object representing the cells - * to update in the mapped array. - * @param {HTMLElement|Boolean} value The value to set in the specified - * position . - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.add_to_gridmap = function(grid_data, value) { - this.update_widget_position(grid_data, value || grid_data.el); - /*if (grid_data.el) { - var $widgets = this.widgets_below(grid_data.el); - $widgets.each($.proxy(function(i, widget) { - console.log("from_add_to_gridmap"); - this.move_widget_up( $(widget)); - }, this)); - } */ - }; - - - /** - * Make widgets draggable. - * - * @uses Draggable - * @method draggable - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.draggable = function() { - var self = this; - var draggable_options = $.extend(true, {}, this.options.draggable, { - offset_left: this.options.widget_margins[0], - start: function(event, ui) { - self.$widgets.filter('.player-revert') - .removeClass('player-revert'); - - self.$player = $(this); - self.$helper = self.options.draggable.helper === 'clone' ? - $(ui.helper) : self.$player; - self.helper = !self.$helper.is(self.$player); - - self.on_start_drag.call(self, event, ui); - self.$el.trigger('gridster:dragstart'); - }, - stop: function(event, ui) { - self.on_stop_drag.call(self, event, ui); - self.$el.trigger('gridster:dragstop'); - }, - drag: throttle(function(event, ui) { - self.on_drag.call(self, event, ui); - self.$el.trigger('gridster:drag'); - }, 60) - }); - - this.drag_api = this.$el.dragg(draggable_options).data('drag'); - return this; - }; - - - /** - * This function is executed when the player begins to be dragged. - * - * @method on_start_drag - * @param {Event} The original browser event - * @param {Object} A prepared ui object. - */ - fn.on_start_drag = function(event, ui) { - - this.$helper.add(this.$player).add(this.$wrapper).addClass('dragging'); - - this.$player.addClass('player'); - this.player_grid_data = this.$player.coords().grid; - this.placeholder_grid_data = $.extend({}, this.player_grid_data); - - //set new grid height along the dragging period - this.$el.css('height', this.$el.height() + - (this.player_grid_data.size_y * this.min_widget_height)); - - var colliders = this.faux_grid; - var coords = this.$player.data('coords').coords; - - this.cells_occupied_by_player = this.get_cells_occupied( - this.player_grid_data); - this.cells_occupied_by_placeholder = this.get_cells_occupied( - this.placeholder_grid_data); - - this.last_cols = []; - this.last_rows = []; - - - // see jquery.collision.js - this.collision_api = this.$helper.collision( - colliders, this.options.collision); - - this.$preview_holder = $('
  • ', { - 'class': 'preview-holder', - 'data-row': this.$player.attr('data-row'), - 'data-col': this.$player.attr('data-col'), - css: { - width: coords.width, - height: coords.height - } - }).appendTo(this.$el); - - if (this.options.draggable.start) { - this.options.draggable.start.call(this, event, ui); - } - }; - - - /** - * This function is executed when the player is being dragged. - * - * @method on_drag - * @param {Event} The original browser event - * @param {Object} A prepared ui object. - */ - fn.on_drag = function(event, ui) { - //break if dragstop has been fired - if (this.$player === null) { - return false; - } - - var abs_offset = { - left: ui.position.left + this.baseX, - top: ui.position.top + this.baseY - }; - - this.colliders_data = this.collision_api.get_closest_colliders( - abs_offset); - - this.on_overlapped_column_change( - this.on_start_overlapping_column, - this.on_stop_overlapping_column - ); - - this.on_overlapped_row_change( - this.on_start_overlapping_row, - this.on_stop_overlapping_row - ); - - if (this.helper && this.$player) { - this.$player.css({ - 'left': ui.position.left, - 'top': ui.position.top - }); - } - - if (this.options.draggable.drag) { - this.options.draggable.drag.call(this, event, ui); - } - }; - - /** - * This function is executed when the player stops being dragged. - * - * @method on_stop_drag - * @param {Event} The original browser event - * @param {Object} A prepared ui object. - */ - fn.on_stop_drag = function(event, ui) { - this.$helper.add(this.$player).add(this.$wrapper) - .removeClass('dragging'); - - ui.position.left = ui.position.left + this.baseX; - ui.position.top = ui.position.top + this.baseY; - this.colliders_data = this.collision_api.get_closest_colliders(ui.position); - - this.on_overlapped_column_change( - this.on_start_overlapping_column, - this.on_stop_overlapping_column - ); - - this.on_overlapped_row_change( - this.on_start_overlapping_row, - this.on_stop_overlapping_row - ); - - this.$player.addClass('player-revert').removeClass('player') - .attr({ - 'data-col': this.placeholder_grid_data.col, - 'data-row': this.placeholder_grid_data.row - }).css({ - 'left': '', - 'top': '' - }); - - this.$changed = this.$changed.add(this.$player); - - this.cells_occupied_by_player = this.get_cells_occupied( - this.placeholder_grid_data); - this.set_cells_player_occupies( - this.placeholder_grid_data.col, this.placeholder_grid_data.row); - - this.$player.coords().grid.row = this.placeholder_grid_data.row; - this.$player.coords().grid.col = this.placeholder_grid_data.col; - - if (this.options.draggable.stop) { - this.options.draggable.stop.call(this, event, ui); - } - - this.$preview_holder.remove(); - - this.$player = null; - this.$helper = null; - this.placeholder_grid_data = {}; - this.player_grid_data = {}; - this.cells_occupied_by_placeholder = {}; - this.cells_occupied_by_player = {}; - this.w_queue = {}; - - this.set_dom_grid_height(); - }; - - - /** - * Executes the callbacks passed as arguments when a column begins to be - * overlapped or stops being overlapped. - * - * @param {Function} start_callback Function executed when a new column - * begins to be overlapped. The column is passed as first argument. - * @param {Function} stop_callback Function executed when a column stops - * being overlapped. The column is passed as first argument. - * @method on_overlapped_column_change - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.on_overlapped_column_change = function(start_callback, stop_callback) { - if (!this.colliders_data.length) { - return; - } - var cols = this.get_targeted_columns( - this.colliders_data[0].el.data.col); - - var last_n_cols = this.last_cols.length; - var n_cols = cols.length; - var i; - - for (i = 0; i < n_cols; i++) { - if ($.inArray(cols[i], this.last_cols) === -1) { - (start_callback || $.noop).call(this, cols[i]); - } - } - - for (i = 0; i< last_n_cols; i++) { - if ($.inArray(this.last_cols[i], cols) === -1) { - (stop_callback || $.noop).call(this, this.last_cols[i]); - } - } - - this.last_cols = cols; - - return this; - }; - - - /** - * Executes the callbacks passed as arguments when a row starts to be - * overlapped or stops being overlapped. - * - * @param {Function} start_callback Function executed when a new row begins - * to be overlapped. The row is passed as first argument. - * @param {Function} stop_callback Function executed when a row stops being - * overlapped. The row is passed as first argument. - * @method on_overlapped_row_change - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.on_overlapped_row_change = function(start_callback, end_callback) { - if (!this.colliders_data.length) { - return; - } - var rows = this.get_targeted_rows(this.colliders_data[0].el.data.row); - var last_n_rows = this.last_rows.length; - var n_rows = rows.length; - var i; - - for (i = 0; i < n_rows; i++) { - if ($.inArray(rows[i], this.last_rows) === -1) { - (start_callback || $.noop).call(this, rows[i]); - } - } - - for (i = 0; i < last_n_rows; i++) { - if ($.inArray(this.last_rows[i], rows) === -1) { - (end_callback || $.noop).call(this, this.last_rows[i]); - } - } - - this.last_rows = rows; - }; - - - /** - * Sets the current position of the player - * - * @param {Function} start_callback Function executed when a new row begins - * to be overlapped. The row is passed as first argument. - * @param {Function} stop_callback Function executed when a row stops being - * overlapped. The row is passed as first argument. - * @method set_player - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.set_player = function(col, row, no_player) { - var self = this; - var swap = false; - if (!no_player) { - this.empty_cells_player_occupies(); - } - var cell = !no_player ? self.colliders_data[0].el.data : {col: col}; - var to_col = cell.col; - var to_row = cell.row || row; - - this.player_grid_data = { - col: to_col, - row: to_row, - size_y : this.player_grid_data.size_y, - size_x : this.player_grid_data.size_x - }; - - this.cells_occupied_by_player = this.get_cells_occupied( - this.player_grid_data); - - //Added placeholder for more advanced movement. - this.cells_occupied_by_placeholder = this.get_cells_occupied( - this.placeholder_grid_data); - - var $overlapped_widgets = this.get_widgets_overlapped( - this.player_grid_data); - - var player_size_y = this.player_grid_data.size_y; - var player_size_x = this.player_grid_data.size_x; - var placeholder_cells = this.cells_occupied_by_placeholder; - var $gr = this; - - - //Queue Swaps - $overlapped_widgets.each($.proxy(function(i, w){ - var $w = $(w); - var wgd = $w.coords().grid; - var outside_col = placeholder_cells.cols[0]+player_size_x-1; - var outside_row = placeholder_cells.rows[0]+player_size_y-1; - if ($w.hasClass($gr.options.static_class)){ - //next iteration - return true; - } - if(wgd.size_x <= player_size_x && wgd.size_y <= player_size_y){ - if(!$gr.is_swap_occupied(placeholder_cells.cols[0], wgd.row, wgd.size_x, wgd.size_y) && !$gr.is_player_in(placeholder_cells.cols[0], wgd.row) && !$gr.is_in_queue(placeholder_cells.cols[0], wgd.row, $w)){ - swap = $gr.queue_widget(placeholder_cells.cols[0], wgd.row, $w); - } - else if(!$gr.is_swap_occupied(outside_col, wgd.row, wgd.size_x, wgd.size_y) && !$gr.is_player_in(outside_col, wgd.row) && !$gr.is_in_queue(outside_col, wgd.row, $w)){ - swap = $gr.queue_widget(outside_col, wgd.row, $w); - } - else if(!$gr.is_swap_occupied(wgd.col, placeholder_cells.rows[0], wgd.size_x, wgd.size_y) && !$gr.is_player_in(wgd.col, placeholder_cells.rows[0]) && !$gr.is_in_queue(wgd.col, placeholder_cells.rows[0], $w)){ - swap = $gr.queue_widget(wgd.col, placeholder_cells.rows[0], $w); - } - else if(!$gr.is_swap_occupied(wgd.col, outside_row, wgd.size_x, wgd.size_y) && !$gr.is_player_in(wgd.col, outside_row) && !$gr.is_in_queue(wgd.col, outside_row, $w)){ - swap = $gr.queue_widget(wgd.col, outside_row, $w); - } - else if(!$gr.is_swap_occupied(placeholder_cells.cols[0],placeholder_cells.rows[0], wgd.size_x, wgd.size_y) && !$gr.is_player_in(placeholder_cells.cols[0],placeholder_cells.rows[0]) && !$gr.is_in_queue(placeholder_cells.cols[0],placeholder_cells.rows[0], $w)){ - swap = $gr.queue_widget(placeholder_cells.cols[0], placeholder_cells.rows[0], $w); - } else { - //in one last attempt we check for any other empty spaces - for (var c = 0; c < player_size_x; c++){ - for (var r = 0; r < player_size_y; r++){ - var colc = placeholder_cells.cols[0]+c; - var rowc = placeholder_cells.rows[0]+r; - if (!$gr.is_swap_occupied(colc,rowc, wgd.size_x, wgd.size_y) && !$gr.is_player_in(colc,rowc) && !$gr.is_in_queue(colc, rowc, $w)){ - swap = $gr.queue_widget(colc, rowc, $w); - c = player_size_x; - break; - } - } - } - - } - } else if ($gr.options.shift_larger_widgets_down && !swap) { - $overlapped_widgets.each($.proxy(function(i, w){ - var $w = $(w); - var wgd = $w.coords().grid; - - if($gr.can_go_down($w)){ - $gr.move_widget_down($w, $gr.player_grid_data.size_y); - $gr.set_placeholder(to_col, to_row); - } - })); - } - - $gr.clean_up_changed(); - })); - - - /* To show queued items in console - for(var key in this.w_queue){ - console.log("key " +key); - console.log(this.w_queue[key]); - } - */ - - //Move queued widgets - if(swap && this.can_placeholder_be_set(to_col, to_row, player_size_x, player_size_y)){ - for(var key in this.w_queue){ - var col = parseInt(key.split("_")[0]); - var row = parseInt(key.split("_")[1]); - if (this.w_queue[key] != "full"){ - this.new_move_widget_to(this.w_queue[key], col, row); - } - } - this.set_placeholder(to_col, to_row); - } - - /* if there is not widgets overlapping in the new player position, - * update the new placeholder position. */ - if (!$overlapped_widgets.length) { - var pp = this.can_go_player_up(this.player_grid_data); - if (pp !== false) { - to_row = pp; - } - if(this.can_placeholder_be_set(to_col, to_row, player_size_x, player_size_y)){ - this.set_placeholder(to_col, to_row); - } - } - - this.w_queue = {}; - - return { - col: to_col, - row: to_row - }; - }; - - - fn.is_swap_occupied = function(col, row, w_size_x, w_size_y) { - var occupied = false; - for (var c = 0; c < w_size_x; c++){ - for (var r = 0; r < w_size_y; r++){ - var colc = col + c; - var rowc = row + r; - var key = colc+"_"+rowc; - if(this.is_occupied(colc,rowc)){ - occupied = true; - } else if(key in this.w_queue){ - if(this.w_queue[key] == "full"){ - occupied = true; - continue; - } - $tw = this.w_queue[key]; - tgd = $tw.coords().grid; - //remove queued items if no longer under player. - if(!this.is_widget_under_player(tgd.col,tgd.row)){ - delete this.w_queue[key]; - } - } - if(rowc > parseInt(this.options.max_rows)){ - occupied = true; - } - if(colc > parseInt(this.options.max_cols)){ - occupied = true; - } - if (this.is_player_in(colc,rowc)){ - occupied = true; - } - } - } - - return occupied; - } - - fn.can_placeholder_be_set = function(col, row, player_size_x, player_size_y){ - var can_set = true; - for (var c = 0; c < player_size_x; c++){ - for (var r = 0; r < player_size_y; r++){ - var colc = col + c; - var rowc = row + r; - var key = colc+"_"+rowc; - var $tw = this.is_widget(colc, rowc); - //if this space is occupied and not queued for move. - if(rowc > parseInt(this.options.max_rows)){ - can_set = false; - } - if(colc > parseInt(this.options.max_cols)){ - can_set = false; - } - if(this.is_occupied(colc,rowc) && !this.is_widget_queued_and_can_move($tw)){ - can_set = false; - } - } - } - return can_set; - } - - fn.queue_widget = function(col, row, $widget){ - var $w = $widget - var wgd = $w.coords().grid; - var primary_key = col+"_"+row; - if (primary_key in this.w_queue){ - return false; - } - - this.w_queue[primary_key] = $w; - - for (var c = 0; c < wgd.size_x; c++){ - for (var r = 0; r < wgd.size_y; r++){ - var colc = col + c; - var rowc = row + r; - var key = colc+"_"+rowc; - if (key == primary_key){ - continue; - } - this.w_queue[key] = "full"; - } - } - - return true; - } - - fn.is_widget_queued_and_can_move = function($widget){ - var queued = false; - if ($widget === false){ - return false; - } - - for(var key in this.w_queue){ - if(this.w_queue[key] == "full"){ - continue; - } - if(this.w_queue[key].attr("data-col") == $widget.attr("data-col") && this.w_queue[key].attr("data-row") == $widget.attr("data-row")){ - queued = true; - //test whole space - var $w = this.w_queue[key]; - var dcol = parseInt(key.split("_")[0]); - var drow = parseInt(key.split("_")[1]); - var wgd = $w.coords().grid; - - for (var c = 0; c < wgd.size_x; c++){ - for (var r = 0; r < wgd.size_y; r++){ - var colc = dcol + c; - var rowc = drow + r; - if (this.is_player_in(colc,rowc)){ - queued = false; - } - - } - } - - } - } - - return queued - } - - fn.is_in_queue = function(col,row, $widget){ - var queued = false; - var key = col+"_"+row; - - if ((key in this.w_queue)){ - if (this.w_queue[key] == "full"){ - queued = true; - } else { - $tw = this.w_queue[key]; - tgd = $tw.coords().grid; - if(!this.is_widget_under_player(tgd.col,tgd.row)){ - delete this.w_queue[key] - queued = false; - } else if(this.w_queue[key].attr("data-col") == $widget.attr("data-col") && this.w_queue[key].attr("data-row") == $widget.attr("data-row")) { - delete this.w_queue[key] - queued = false; - } else { - queued = true; - } - } - } - - return queued; - } - - - /** - * See which of the widgets in the $widgets param collection can go to - * a upper row and which not. - * - * @method widgets_contraints - * @param {HTMLElements} $widgets A jQuery wrapped collection of - * HTMLElements. - * @return {Array} Returns a literal Object with two keys: `can_go_up` & - * `can_not_go_up`. Each contains a set of HTMLElements. - */ - fn.widgets_constraints = function($widgets) { - var $widgets_can_go_up = $([]); - var $widgets_can_not_go_up; - var wgd_can_go_up = []; - var wgd_can_not_go_up = []; - - $widgets.each($.proxy(function(i, w) { - var $w = $(w); - var wgd = $w.coords().grid; - if (this.can_go_widget_up(wgd)) { - $widgets_can_go_up = $widgets_can_go_up.add($w); - wgd_can_go_up.push(wgd); - }else{ - wgd_can_not_go_up.push(wgd); - } - }, this)); - - $widgets_can_not_go_up = $widgets.not($widgets_can_go_up); - - return { - can_go_up: this.sort_by_row_asc(wgd_can_go_up), - can_not_go_up: this.sort_by_row_desc(wgd_can_not_go_up) - }; - }; - - - /** - * Sorts an Array of grid coords objects (representing the grid coords of - * each widget) in ascending way. - * - * @method sort_by_row_asc - * @param {Array} widgets Array of grid coords objects - * @return {Array} Returns the array sorted. - */ - fn.sort_by_row_asc = function(widgets) { - widgets = widgets.sort(function(a, b) { - if (!a.row) { - a = $(a).coords().grid; - b = $(b).coords().grid; - } - - if (a.row > b.row) { - return 1; - } - return -1; - }); - - return widgets; - }; - - - /** - * Sorts an Array of grid coords objects (representing the grid coords of - * each widget) placing first the empty cells upper left. - * - * @method sort_by_row_and_col_asc - * @param {Array} widgets Array of grid coords objects - * @return {Array} Returns the array sorted. - */ - fn.sort_by_row_and_col_asc = function(widgets) { - widgets = widgets.sort(function(a, b) { - if (a.row > b.row || a.row === b.row && a.col > b.col) { - return 1; - } - return -1; - }); - - return widgets; - }; - - - /** - * Sorts an Array of grid coords objects by column (representing the grid - * coords of each widget) in ascending way. - * - * @method sort_by_col_asc - * @param {Array} widgets Array of grid coords objects - * @return {Array} Returns the array sorted. - */ - fn.sort_by_col_asc = function(widgets) { - widgets = widgets.sort(function(a, b) { - if (a.col > b.col) { - return 1; - } - return -1; - }); - - return widgets; - }; - - - /** - * Sorts an Array of grid coords objects (representing the grid coords of - * each widget) in descending way. - * - * @method sort_by_row_desc - * @param {Array} widgets Array of grid coords objects - * @return {Array} Returns the array sorted. - */ - fn.sort_by_row_desc = function(widgets) { - widgets = widgets.sort(function(a, b) { - if (a.row + a.size_y < b.row + b.size_y) { - return 1; - } - return -1; - }); - return widgets; - }; - - - /** - * Sorts an Array of grid coords objects (representing the grid coords of - * each widget) in descending way. - - * Depreciated. - * - * @method manage_movements - * @param {HTMLElements} $widgets A jQuery collection of HTMLElements - * representing the widgets you want to move. - * @param {Number} to_col The column to which we want to move the widgets. - * @param {Number} to_row The row to which we want to move the widgets. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.manage_movements = function($widgets, to_col, to_row) { - $.each($widgets, $.proxy(function(i, w) { - var wgd = w; - var $w = wgd.el; - - var can_go_widget_up = this.can_go_widget_up(wgd); - - if (can_go_widget_up) { - //target CAN go up - //so move widget up - this.move_widget_to($w, can_go_widget_up); - this.set_placeholder(to_col, can_go_widget_up + wgd.size_y); - - } else { - //target can't go up - var can_go_player_up = this.can_go_player_up( - this.player_grid_data); - - if (!can_go_player_up) { - // target can't go up - // player cant't go up - // so we need to move widget down to a position that dont - // overlaps player - var y = (to_row + this.player_grid_data.size_y) - wgd.row; - if (this.can_go_down($w)){ - console.log("In Move Down!") - this.move_widget_down($w, y); - this.set_placeholder(to_col, to_row); - } - } - } - }, this)); - - return this; - }; - - /** - * Determines if there is a widget in the row and col given. Or if the - * HTMLElement passed as first argument is the player. - * - * @method is_player - * @param {Number|HTMLElement} col_or_el A jQuery wrapped collection of - * HTMLElements. - * @param {Number} [row] The column to which we want to move the widgets. - * @return {Boolean} Returns true or false. - */ - fn.is_player = function(col_or_el, row) { - if (row && !this.gridmap[col_or_el]) { return false; } - var $w = row ? this.gridmap[col_or_el][row] : col_or_el; - return $w && ($w.is(this.$player) || $w.is(this.$helper)); - }; - - - /** - * Determines if the widget that is being dragged is currently over the row - * and col given. - * - * @method is_player_in - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_player_in = function(col, row) { - var c = this.cells_occupied_by_player || {}; - return $.inArray(col, c.cols) >= 0 && $.inArray(row, c.rows) >= 0; - }; - - - /** - * Determines if the placeholder is currently over the row and col given. - * - * @method is_placeholder_in - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_placeholder_in = function(col, row) { - var c = this.cells_occupied_by_placeholder || {}; - return this.is_placeholder_in_col(col) && $.inArray(row, c.rows) >= 0; - }; - - - /** - * Determines if the placeholder is currently over the column given. - * - * @method is_placeholder_in_col - * @param {Number} col The column to check. - * @return {Boolean} Returns true or false. - */ - fn.is_placeholder_in_col = function(col) { - var c = this.cells_occupied_by_placeholder || []; - return $.inArray(col, c.cols) >= 0; - }; - - - /** - * Determines if the cell represented by col and row params is empty. - * - * @method is_empty - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_empty = function(col, row) { - if (typeof this.gridmap[col] !== 'undefined' && - typeof this.gridmap[col][row] !== 'undefined' && - this.gridmap[col][row] === false - ) { - return true; - } - return false; - }; - - - /** - * Determines if the cell represented by col and row params is occupied. - * - * @method is_occupied - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_occupied = function(col, row) { - if (!this.gridmap[col]) { - return false; - } - - if (this.gridmap[col][row]) { - return true; - } - return false; - }; - - - /** - * Determines if there is a widget in the cell represented by col/row params. - * - * @method is_widget - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean|HTMLElement} Returns false if there is no widget, - * else returns the jQuery HTMLElement - */ - fn.is_widget = function(col, row) { - var cell = this.gridmap[col]; - if (!cell) { - return false; - } - - cell = cell[row]; - - if (cell) { - return cell; - } - - return false; - }; - - /** - * Determines if widget is supposed to be static. - * @method is_static - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true if widget exists and has static class, - * else returns false - */ - - fn.is_static = function(col, row) { - var cell = this.gridmap[col]; - if (!cell) { - return false; - } - - cell = cell[row]; - - if (cell) { - if(cell.hasClass(this.options.static_class)){ - return true; - } - } - - return false; - }; - - - /** - * Determines if there is a widget in the cell represented by col/row - * params and if this is under the widget that is being dragged. - * - * @method is_widget_under_player - * @param {Number} col The column to check. - * @param {Number} row The row to check. - * @return {Boolean} Returns true or false. - */ - fn.is_widget_under_player = function(col, row) { - if (this.is_widget(col, row)) { - return this.is_player_in(col, row); - } - return false; - }; - - - /** - * Get widgets overlapping with the player or with the object passed - * representing the grid cells. - * - * @method get_widgets_under_player - * @return {HTMLElement} Returns a jQuery collection of HTMLElements - */ - fn.get_widgets_under_player = function(cells) { - cells || (cells = this.cells_occupied_by_player || {cols: [], rows: []}); - var $widgets = $([]); - - $.each(cells.cols, $.proxy(function(i, col) { - $.each(cells.rows, $.proxy(function(i, row) { - if(this.is_widget(col, row)) { - $widgets = $widgets.add(this.gridmap[col][row]); - } - }, this)); - }, this)); - - return $widgets; - }; - - - /** - * Put placeholder at the row and column specified. - * - * @method set_placeholder - * @param {Number} col The column to which we want to move the - * placeholder. - * @param {Number} row The row to which we want to move the - * placeholder. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.set_placeholder = function(col, row) { - var phgd = $.extend({}, this.placeholder_grid_data); - var $nexts = this.widgets_below({ - col: phgd.col, - row: phgd.row, - size_y: phgd.size_y, - size_x: phgd.size_x - }); - - // Prevents widgets go out of the grid - var right_col = (col + phgd.size_x - 1); - if (right_col > this.cols) { - col = col - (right_col - col); - } - - var moved_down = this.placeholder_grid_data.row < row; - var changed_column = this.placeholder_grid_data.col !== col; - - this.placeholder_grid_data.col = col; - this.placeholder_grid_data.row = row; - - this.cells_occupied_by_placeholder = this.get_cells_occupied( - this.placeholder_grid_data); - - this.$preview_holder.attr({ - 'data-row' : row, - 'data-col' : col - }); - - if (moved_down || changed_column) { - $nexts.each($.proxy(function(i, widget) { - //Make sure widget is at it's topmost position - $w = $(widget); - wgd = $w.coords().grid; - - var can_go_widget_up = this.can_go_widget_up(wgd); - - if (can_go_widget_up) { - this.move_widget_to($w, can_go_widget_up); - } - - }, this)); - } - - - var $widgets_under_ph = this.get_widgets_under_player(this.cells_occupied_by_placeholder); - if ($widgets_under_ph.length) { - $widgets_under_ph.each($.proxy(function(i, widget) { - var $w = $(widget); - this.move_widget_down( - $w, row + phgd.size_y - $w.data('coords').grid.row); - }, this)); - } - - }; - - - /** - * Determines whether the player can move to a position above. - * - * @method can_go_player_up - * @param {Object} widget_grid_data The actual grid coords object of the - * player. - * @return {Number|Boolean} If the player can be moved to an upper row - * returns the row number, else returns false. - */ - fn.can_go_player_up = function(widget_grid_data) { - var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1; - var result = true; - var upper_rows = []; - var min_row = 10000; - var $widgets_under_player = this.get_widgets_under_player(); - - /* generate an array with columns as index and array with upper rows - * empty as value */ - this.for_each_column_occupied(widget_grid_data, function(tcol) { - var grid_col = this.gridmap[tcol]; - var r = p_bottom_row + 1; - upper_rows[tcol] = []; - - while (--r > 0) { - if (this.is_empty(tcol, r) || this.is_player(tcol, r) || - this.is_widget(tcol, r) && - grid_col[r].is($widgets_under_player) - ) { - upper_rows[tcol].push(r); - min_row = r < min_row ? r : min_row; - }else{ - break; - } - } - - if (upper_rows[tcol].length === 0) { - result = false; - return true; //break - } - - upper_rows[tcol].sort(); - }); - - if (!result) { return false; } - - return this.get_valid_rows(widget_grid_data, upper_rows, min_row); - }; - - - /** - * Determines whether a widget can move to a position above. - * - * @method can_go_widget_up - * @param {Object} widget_grid_data The actual grid coords object of the - * widget we want to check. - * @return {Number|Boolean} If the widget can be moved to an upper row - * returns the row number, else returns false. - */ - fn.can_go_widget_up = function(widget_grid_data) { - var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1; - var result = true; - var upper_rows = []; - var min_row = 10000; - - /* generate an array with columns as index and array with topmost rows - * empty as value */ - this.for_each_column_occupied(widget_grid_data, function(tcol) { - var grid_col = this.gridmap[tcol]; - upper_rows[tcol] = []; - - var r = p_bottom_row + 1; - // iterate over each row - while (--r > 0) { - if (this.is_widget(tcol, r) && !this.is_player_in(tcol, r)) { - if (!grid_col[r].is(widget_grid_data.el)) { - break; - } - } - - if (!this.is_player(tcol, r) && - !this.is_placeholder_in(tcol, r) && - !this.is_player_in(tcol, r)) { - upper_rows[tcol].push(r); - } - - if (r < min_row) { - min_row = r; - } - } - - if (upper_rows[tcol].length === 0) { - result = false; - return true; //break - } - - upper_rows[tcol].sort(); - }); - - if (!result) { return false; } - - return this.get_valid_rows(widget_grid_data, upper_rows, min_row); - }; - - - /** - * Search a valid row for the widget represented by `widget_grid_data' in - * the `upper_rows` array. Iteration starts from row specified in `min_row`. - * - * @method get_valid_rows - * @param {Object} widget_grid_data The actual grid coords object of the - * player. - * @param {Array} upper_rows An array with columns as index and arrays - * of valid rows as values. - * @param {Number} min_row The upper row from which the iteration will start. - * @return {Number|Boolean} Returns the upper row valid from the `upper_rows` - * for the widget in question. - */ - fn.get_valid_rows = function(widget_grid_data, upper_rows, min_row) { - var p_top_row = widget_grid_data.row; - var p_bottom_row = widget_grid_data.row + widget_grid_data.size_y - 1; - var size_y = widget_grid_data.size_y; - var r = min_row - 1; - var valid_rows = []; - - while (++r <= p_bottom_row ) { - var common = true; - $.each(upper_rows, function(col, rows) { - if ($.isArray(rows) && $.inArray(r, rows) === -1) { - common = false; - } - }); - - if (common === true) { - valid_rows.push(r); - if (valid_rows.length === size_y) { - break; - } - } - } - - var new_row = false; - if (size_y === 1) { - if (valid_rows[0] !== p_top_row) { - new_row = valid_rows[0] || false; - } - }else{ - if (valid_rows[0] !== p_top_row) { - new_row = this.get_consecutive_numbers_index( - valid_rows, size_y); - } - } - - return new_row; - }; - - - fn.get_consecutive_numbers_index = function(arr, size_y) { - var max = arr.length; - var result = []; - var first = true; - var prev = -1; // or null? - - for (var i=0; i < max; i++) { - if (first || arr[i] === prev + 1) { - result.push(i); - if (result.length === size_y) { - break; - } - first = false; - }else{ - result = []; - first = true; - } - - prev = arr[i]; - } - - return result.length >= size_y ? arr[result[0]] : false; - }; - - - /** - * Get widgets overlapping with the player. - * - * @method get_widgets_overlapped - * @return {HTMLElements} Returns a jQuery collection of HTMLElements. - */ - fn.get_widgets_overlapped = function() { - var $w; - var $widgets = $([]); - var used = []; - var rows_from_bottom = this.cells_occupied_by_player.rows.slice(0); - rows_from_bottom.reverse(); - - $.each(this.cells_occupied_by_player.cols, $.proxy(function(i, col) { - $.each(rows_from_bottom, $.proxy(function(i, row) { - // if there is a widget in the player position - if (!this.gridmap[col]) { return true; } //next iteration - var $w = this.gridmap[col][row]; - if (this.is_occupied(col, row) && !this.is_player($w) && - $.inArray($w, used) === -1 - ) { - $widgets = $widgets.add($w); - used.push($w); - } - - }, this)); - }, this)); - - return $widgets; - }; - - - /** - * This callback is executed when the player begins to collide with a column. - * - * @method on_start_overlapping_column - * @param {Number} col The collided column. - * @return {HTMLElements} Returns a jQuery collection of HTMLElements. - */ - fn.on_start_overlapping_column = function(col) { - this.set_player(col, false); - }; - - - /** - * A callback executed when the player begins to collide with a row. - * - * @method on_start_overlapping_row - * @param {Number} col The collided row. - * @return {HTMLElements} Returns a jQuery collection of HTMLElements. - */ - fn.on_start_overlapping_row = function(row) { - this.set_player(false, row); - }; - - - /** - * A callback executed when the the player ends to collide with a column. - * - * @method on_stop_overlapping_column - * @param {Number} col The collided row. - * @return {HTMLElements} Returns a jQuery collection of HTMLElements. - */ - fn.on_stop_overlapping_column = function(col) { - //this.set_player(col, false); - var self = this; - if(this.options.shift_larger_widgets_down){ - this.for_each_widget_below(col, this.cells_occupied_by_player.rows[0], - function(tcol, trow) { - self.move_widget_up(this, self.player_grid_data.size_y); - }); - } - }; - - - /** - * This callback is executed when the player ends to collide with a row. - * - * @method on_stop_overlapping_row - * @param {Number} row The collided row. - * @return {HTMLElements} Returns a jQuery collection of HTMLElements. - */ - fn.on_stop_overlapping_row = function(row) { - //this.set_player(false, row); - var self = this; - var cols = this.cells_occupied_by_player.cols; - if(this.options.shift_larger_widgets_down){ - for (var c = 0, cl = cols.length; c < cl; c++) { - this.for_each_widget_below(cols[c], row, function(tcol, trow) { - console.log("from_on_stop_overlapping_row"); - self.move_widget_up(this, self.player_grid_data.size_y); - }); - } - } - }; - - //Not yet part of api - DM. - fn.new_move_widget_to = function($widget, col, row){ - var self = this; - var widget_grid_data = $widget.coords().grid; - - this.remove_from_gridmap(widget_grid_data); - widget_grid_data.row = row; - widget_grid_data.col = col; - - this.add_to_gridmap(widget_grid_data); - $widget.attr('data-row', row); - $widget.attr('data-col', col); - this.update_widget_position(widget_grid_data, $widget); - this.$changed = this.$changed.add($widget); - - return this; - } - - - /** - * Move a widget to a specific row. The cell or cells must be empty. - * If the widget has widgets below, all of these widgets will be moved also - * if they can. - * - * @method move_widget_to - * @param {HTMLElement} $widget The jQuery wrapped HTMLElement of the - * widget is going to be moved. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.move_widget_to = function($widget, row) { - var self = this; - var widget_grid_data = $widget.coords().grid; - var diff = row - widget_grid_data.row; - var $next_widgets = this.widgets_below($widget); - - var can_move_to_new_cell = this.can_move_to( - widget_grid_data, widget_grid_data.col, row, $widget); - - if (can_move_to_new_cell === false) { - return false; - } - - this.remove_from_gridmap(widget_grid_data); - widget_grid_data.row = row; - this.add_to_gridmap(widget_grid_data); - $widget.attr('data-row', row); - this.$changed = this.$changed.add($widget); - - - $next_widgets.each(function(i, widget) { - var $w = $(widget); - var wgd = $w.coords().grid; - var can_go_up = self.can_go_widget_up(wgd); - if (can_go_up && can_go_up !== wgd.row) { - self.move_widget_to($w, can_go_up); - } - }); - - return this; - }; - - - /** - * Move up the specified widget and all below it. - * - * @method move_widget_up - * @param {HTMLElement} $widget The widget you want to move. - * @param {Number} [y_units] The number of cells that the widget has to move. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.move_widget_up = function($widget, y_units) { - var el_grid_data = $widget.coords().grid; - var actual_row = el_grid_data.row; - var moved = []; - var can_go_up = true; - y_units || (y_units = 1); - - if (!this.can_go_up($widget)) { return false; } //break; - - this.for_each_column_occupied(el_grid_data, function(col) { - // can_go_up - if ($.inArray($widget, moved) === -1) { - var widget_grid_data = $widget.coords().grid; - var next_row = actual_row - y_units; - next_row = this.can_go_up_to_row( - widget_grid_data, col, next_row); - - if (!next_row) { - return true; - } - - var $next_widgets = this.widgets_below($widget); - - this.remove_from_gridmap(widget_grid_data); - widget_grid_data.row = next_row; - this.add_to_gridmap(widget_grid_data); - $widget.attr('data-row', widget_grid_data.row); - this.$changed = this.$changed.add($widget); - - moved.push($widget); - - /* $next_widgets.each($.proxy(function(i, widget) { - console.log("from_within_move_widget_up"); - this.move_widget_up($(widget), y_units); - }, this)); */ - } - }); - - }; - - - /** - * Move down the specified widget and all below it. - * - * @method move_widget_down - * @param {HTMLElement} $widget The jQuery object representing the widget - * you want to move. - * @param {Number} The number of cells that the widget has to move. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.move_widget_down = function($widget, y_units) { - var el_grid_data = $widget.coords().grid; - var actual_row = el_grid_data.row; - var moved = []; - var y_diff = y_units; - - if (!$widget) { return false; } - - if ($.inArray($widget, moved) === -1) { - - var widget_grid_data = $widget.coords().grid; - var next_row = actual_row + y_units; - var $next_widgets = this.widgets_below($widget); - - this.remove_from_gridmap(widget_grid_data); - - $next_widgets.each($.proxy(function(i, widget) { - var $w = $(widget); - var wd = $w.coords().grid; - var tmp_y = this.displacement_diff( - wd, widget_grid_data, y_diff); - - if (tmp_y > 0) { - this.move_widget_down($w, tmp_y); - } - }, this)); - - widget_grid_data.row = next_row; - this.update_widget_position(widget_grid_data, $widget); - $widget.attr('data-row', widget_grid_data.row); - this.$changed = this.$changed.add($widget); - - moved.push($widget); - } - }; - - - /** - * Check if the widget can move to the specified row, else returns the - * upper row possible. - * - * @method can_go_up_to_row - * @param {Number} widget_grid_data The current grid coords object of the - * widget. - * @param {Number} col The target column. - * @param {Number} row The target row. - * @return {Boolean|Number} Returns the row number if the widget can move - * to the target position, else returns false. - */ - fn.can_go_up_to_row = function(widget_grid_data, col, row) { - var ga = this.gridmap; - var result = true; - var urc = []; // upper_rows_in_columns - var actual_row = widget_grid_data.row; - var r; - - /* generate an array with columns as index and array with - * upper rows empty in the column */ - this.for_each_column_occupied(widget_grid_data, function(tcol) { - var grid_col = ga[tcol]; - urc[tcol] = []; - - r = actual_row; - while (r--) { - if (this.is_empty(tcol, r) && - !this.is_placeholder_in(tcol, r) - ) { - urc[tcol].push(r); - }else{ - break; - } - } - - if (!urc[tcol].length) { - result = false; - return true; - } - - }); - - if (!result) { return false; } - - /* get common rows starting from upper position in all the columns - * that widget occupies */ - r = row; - for (r = 1; r < actual_row; r++) { - var common = true; - - for (var uc = 0, ucl = urc.length; uc < ucl; uc++) { - if (urc[uc] && $.inArray(r, urc[uc]) === -1) { - common = false; - } - } - - if (common === true) { - result = r; - break; - } - } - - return result; - }; - - - fn.displacement_diff = function(widget_grid_data, parent_bgd, y_units) { - var actual_row = widget_grid_data.row; - var diffs = []; - var parent_max_y = parent_bgd.row + parent_bgd.size_y; - - this.for_each_column_occupied(widget_grid_data, function(col) { - var temp_y_units = 0; - - for (var r = parent_max_y; r < actual_row; r++) { - if (this.is_empty(col, r)) { - temp_y_units = temp_y_units + 1; - } - } - - diffs.push(temp_y_units); - }); - - var max_diff = Math.max.apply(Math, diffs); - y_units = (y_units - max_diff); - - return y_units > 0 ? y_units : 0; - }; - - - /** - * Get widgets below a widget. - * - * @method widgets_below - * @param {HTMLElement} $el The jQuery wrapped HTMLElement. - * @return {HTMLElements} A jQuery collection of HTMLElements. - */ - fn.widgets_below = function($el) { - var el_grid_data = $.isPlainObject($el) ? $el : $el.coords().grid; - var self = this; - var ga = this.gridmap; - var next_row = el_grid_data.row + el_grid_data.size_y - 1; - var $nexts = $([]); - - this.for_each_column_occupied(el_grid_data, function(col) { - self.for_each_widget_below(col, next_row, function(tcol, trow) { - if (!self.is_player(this) && $.inArray(this, $nexts) === -1) { - $nexts = $nexts.add(this); - return true; // break - } - }); - }); - - return this.sort_by_row_asc($nexts); - }; - - - /** - * Update the array of mapped positions with the new player position. - * - * @method set_cells_player_occupies - * @param {Number} col The new player col. - * @param {Number} col The new player row. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.set_cells_player_occupies = function(col, row) { - this.remove_from_gridmap(this.placeholder_grid_data); - this.placeholder_grid_data.col = col; - this.placeholder_grid_data.row = row; - this.add_to_gridmap(this.placeholder_grid_data, this.$player); - return this; - }; - - - /** - * Remove from the array of mapped positions the reference to the player. - * - * @method empty_cells_player_occupies - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.empty_cells_player_occupies = function() { - this.remove_from_gridmap(this.placeholder_grid_data); - return this; - }; - - fn.can_go_down = function($el) { - var can_go_down = true; - var $gr = this; - - if ($el.hasClass(this.options.static_class)){ - can_go_down = false; - } - - this.widgets_below($el).each(function(){ - if ($(this).hasClass($gr.options.static_class)){ - can_go_down = false; - } - }) - - return can_go_down; - } - - - fn.can_go_up = function($el) { - var el_grid_data = $el.coords().grid; - var initial_row = el_grid_data.row; - var prev_row = initial_row - 1; - var ga = this.gridmap; - var upper_rows_by_column = []; - - var result = true; - if (initial_row === 1) { return false; } - - this.for_each_column_occupied(el_grid_data, function(col) { - var $w = this.is_widget(col, prev_row); - - if (this.is_occupied(col, prev_row) || - this.is_player(col, prev_row) || - this.is_placeholder_in(col, prev_row) || - this.is_player_in(col, prev_row) - ) { - result = false; - return true; //break - } - }); - - return result; - }; - - - - /** - * Check if it's possible to move a widget to a specific col/row. It takes - * into account the dimensions (`size_y` and `size_x` attrs. of the grid - * coords object) the widget occupies. - * - * @method can_move_to - * @param {Object} widget_grid_data The grid coords object that represents - * the widget. - * @param {Object} col The col to check. - * @param {Object} row The row to check. - * @param {Number} [max_row] The max row allowed. - * @return {Boolean} Returns true if all cells are empty, else return false. - */ - fn.can_move_to = function(widget_grid_data, col, row, max_row) { - var ga = this.gridmap; - var $w = widget_grid_data.el; - var future_wd = { - size_y: widget_grid_data.size_y, - size_x: widget_grid_data.size_x, - col: col, - row: row - }; - var result = true; - - //Prevents widgets go out of the grid - var right_col = col + widget_grid_data.size_x - 1; - if (right_col > this.cols) { - return false; - } - - if (max_row && max_row < row + widget_grid_data.size_y - 1) { - return false; - } - - this.for_each_cell_occupied(future_wd, function(tcol, trow) { - var $tw = this.is_widget(tcol, trow); - if ($tw && (!widget_grid_data.el || $tw.is($w))) { - result = false; - } - }); - - return result; - }; - - - /** - * Given the leftmost column returns all columns that are overlapping - * with the player. - * - * @method get_targeted_columns - * @param {Number} [from_col] The leftmost column. - * @return {Array} Returns an array with column numbers. - */ - fn.get_targeted_columns = function(from_col) { - var max = (from_col || this.player_grid_data.col) + - (this.player_grid_data.size_x - 1); - var cols = []; - for (var col = from_col; col <= max; col++) { - cols.push(col); - } - return cols; - }; - - - /** - * Given the upper row returns all rows that are overlapping with the player. - * - * @method get_targeted_rows - * @param {Number} [from_row] The upper row. - * @return {Array} Returns an array with row numbers. - */ - fn.get_targeted_rows = function(from_row) { - var max = (from_row || this.player_grid_data.row) + - (this.player_grid_data.size_y - 1); - var rows = []; - for (var row = from_row; row <= max; row++) { - rows.push(row); - } - return rows; - }; - - /** - * Get all columns and rows that a widget occupies. - * - * @method get_cells_occupied - * @param {Object} el_grid_data The grid coords object of the widget. - * @return {Object} Returns an object like `{ cols: [], rows: []}`. - */ - fn.get_cells_occupied = function(el_grid_data) { - var cells = { cols: [], rows: []}; - var i; - if (arguments[1] instanceof jQuery) { - el_grid_data = arguments[1].coords().grid; - } - - for (i = 0; i < el_grid_data.size_x; i++) { - var col = el_grid_data.col + i; - cells.cols.push(col); - } - - for (i = 0; i < el_grid_data.size_y; i++) { - var row = el_grid_data.row + i; - cells.rows.push(row); - } - - return cells; - }; - - - /** - * Iterate over the cells occupied by a widget executing a function for - * each one. - * - * @method for_each_cell_occupied - * @param {Object} el_grid_data The grid coords object that represents the - * widget. - * @param {Function} callback The function to execute on each column - * iteration. Column and row are passed as arguments. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_cell_occupied = function(grid_data, callback) { - this.for_each_column_occupied(grid_data, function(col) { - this.for_each_row_occupied(grid_data, function(row) { - callback.call(this, col, row); - }); - }); - return this; - }; - - - /** - * Iterate over the columns occupied by a widget executing a function for - * each one. - * - * @method for_each_column_occupied - * @param {Object} el_grid_data The grid coords object that represents - * the widget. - * @param {Function} callback The function to execute on each column - * iteration. The column number is passed as first argument. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_column_occupied = function(el_grid_data, callback) { - for (var i = 0; i < el_grid_data.size_x; i++) { - var col = el_grid_data.col + i; - callback.call(this, col, el_grid_data); - } - }; - - - /** - * Iterate over the rows occupied by a widget executing a function for - * each one. - * - * @method for_each_row_occupied - * @param {Object} el_grid_data The grid coords object that represents - * the widget. - * @param {Function} callback The function to execute on each column - * iteration. The row number is passed as first argument. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_row_occupied = function(el_grid_data, callback) { - for (var i = 0; i < el_grid_data.size_y; i++) { - var row = el_grid_data.row + i; - callback.call(this, row, el_grid_data); - } - }; - - fn.clean_up_changed = function(){ - $gr = this; - $gr.$changed.each(function(){ - if($gr.options.shift_larger_widgets_down){ - $gr.move_widget_up($(this)); - } - }); - } - - - - fn._traversing_widgets = function(type, direction, col, row, callback) { - var ga = this.gridmap; - if (!ga[col]) { return; } - - var cr, max; - var action = type + '/' + direction; - if (arguments[2] instanceof jQuery) { - var el_grid_data = arguments[2].coords().grid; - col = el_grid_data.col; - row = el_grid_data.row; - callback = arguments[3]; - } - var matched = []; - var trow = row; - - - var methods = { - 'for_each/above': function() { - while (trow--) { - if (trow > 0 && this.is_widget(col, trow) && - $.inArray(ga[col][trow], matched) === -1 - ) { - cr = callback.call(ga[col][trow], col, trow); - matched.push(ga[col][trow]); - if (cr) { break; } - } - } - }, - 'for_each/below': function() { - for (trow = row + 1, max = ga[col].length; trow < max; trow++) { - if (this.is_widget(col, trow) && - $.inArray(ga[col][trow], matched) === -1 - ) { - cr = callback.call(ga[col][trow], col, trow); - matched.push(ga[col][trow]); - //break was causing problems, leaving for testing. - //if (cr) { break; } - } - } - } - }; - - if (methods[action]) { - methods[action].call(this); - } - }; - - - /** - * Iterate over each widget above the column and row specified. - * - * @method for_each_widget_above - * @param {Number} col The column to start iterating. - * @param {Number} row The row to start iterating. - * @param {Function} callback The function to execute on each widget - * iteration. The value of `this` inside the function is the jQuery - * wrapped HTMLElement. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_widget_above = function(col, row, callback) { - this._traversing_widgets('for_each', 'above', col, row, callback); - return this; - }; - - - /** - * Iterate over each widget below the column and row specified. - * - * @method for_each_widget_below - * @param {Number} col The column to start iterating. - * @param {Number} row The row to start iterating. - * @param {Function} callback The function to execute on each widget - * iteration. The value of `this` inside the function is the jQuery wrapped - * HTMLElement. - * @return {Class} Returns the instance of the Gridster Class. - */ - fn.for_each_widget_below = function(col, row, callback) { - this._traversing_widgets('for_each', 'below', col, row, callback); - return this; - }; - - - /** - * Returns the highest occupied cell in the grid. - * - * @method get_highest_occupied_cell - * @return {Object} Returns an object with `col` and `row` numbers. - */ - fn.get_highest_occupied_cell = function() { - var r; - var gm = this.gridmap; - var rows = []; - var row_in_col = []; - for (var c = gm.length - 1; c >= 1; c--) { - for (r = gm[c].length - 1; r >= 1; r--) { - if (this.is_widget(c, r)) { - rows.push(r); - row_in_col[r] = c; - break; - } - } - } - - var highest_row = Math.max.apply(Math, rows); - - this.highest_occupied_cell = { - col: row_in_col[highest_row], - row: highest_row - }; - - return this.highest_occupied_cell; - }; - - - fn.get_widgets_from = function(col, row) { - var ga = this.gridmap; - var $widgets = $(); - - if (col) { - $widgets = $widgets.add( - this.$widgets.filter(function() { - var tcol = $(this).attr('data-col'); - return (tcol === col || tcol > col); - }) - ); - } - - if (row) { - $widgets = $widgets.add( - this.$widgets.filter(function() { - var trow = $(this).attr('data-row'); - return (trow === row || trow > row); - }) - ); - } - - return $widgets; - }; - - - /** - * Set the current height of the parent grid. - * - * @method set_dom_grid_height - * @return {Object} Returns the instance of the Gridster class. - */ - fn.set_dom_grid_height = function() { - var r = this.get_highest_occupied_cell().row; - this.$el.css('height', r * this.min_widget_height); - return this; - }; - - - /** - * It generates the neccessary styles to position the widgets. - * - * @method generate_stylesheet - * @param {Number} rows Number of columns. - * @param {Number} cols Number of rows. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.generate_stylesheet = function(opts) { - var styles = ''; - var max_size_x = this.options.max_size_x; - var max_rows = 0; - var max_cols = 0; - var i; - var rules; - - opts || (opts = {}); - opts.cols || (opts.cols = this.cols); - opts.rows || (opts.rows = this.rows); - opts.namespace || (opts.namespace = this.options.namespace); - opts.widget_base_dimensions || - (opts.widget_base_dimensions = this.options.widget_base_dimensions); - opts.widget_margins || - (opts.widget_margins = this.options.widget_margins); - opts.min_widget_width = (opts.widget_margins[0] * 2) + - opts.widget_base_dimensions[0]; - opts.min_widget_height = (opts.widget_margins[1] * 2) + - opts.widget_base_dimensions[1]; - - // don't duplicate stylesheets for the same configuration - var serialized_opts = $.param(opts); - if ($.inArray(serialized_opts, Gridster.generated_stylesheets) >= 0) { - return false; - } - - Gridster.generated_stylesheets.push(serialized_opts); - - /* generate CSS styles for cols */ - for (i = opts.cols; i >= 0; i--) { - styles += (opts.namespace + ' [data-col="'+ (i + 1) + '"] { left:' + - ((i * opts.widget_base_dimensions[0]) + - (i * opts.widget_margins[0]) + - ((i + 1) * opts.widget_margins[0])) + 'px;} '); - } - - /* generate CSS styles for rows */ - for (i = opts.rows; i >= 0; i--) { - styles += (opts.namespace + ' [data-row="' + (i + 1) + '"] { top:' + - ((i * opts.widget_base_dimensions[1]) + - (i * opts.widget_margins[1]) + - ((i + 1) * opts.widget_margins[1]) ) + 'px;} '); - } - - for (var y = 1; y <= opts.rows; y++) { - styles += (opts.namespace + ' [data-sizey="' + y + '"] { height:' + - (y * opts.widget_base_dimensions[1] + - (y - 1) * (opts.widget_margins[1] * 2)) + 'px;}'); - } - - for (var x = 1; x <= max_size_x; x++) { - styles += (opts.namespace + ' [data-sizex="' + x + '"] { width:' + - (x * opts.widget_base_dimensions[0] + - (x - 1) * (opts.widget_margins[0] * 2)) + 'px;}'); - } - - return this.add_style_tag(styles); - }; - - - /** - * Injects the given CSS as string to the head of the document. - * - * @method add_style_tag - * @param {String} css The styles to apply. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.add_style_tag = function(css) { - var d = document; - var tag = d.createElement('style'); - - d.getElementsByTagName('head')[0].appendChild(tag); - tag.setAttribute('type', 'text/css'); - - if (tag.styleSheet) { - tag.styleSheet.cssText = css; - }else{ - tag.appendChild(document.createTextNode(css)); - } - return this; - }; - - - /** - * Generates a faux grid to collide with it when a widget is dragged and - * detect row or column that we want to go. - * - * @method generate_faux_grid - * @param {Number} rows Number of columns. - * @param {Number} cols Number of rows. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.generate_faux_grid = function(rows, cols) { - this.faux_grid = []; - this.gridmap = []; - var col; - var row; - for (col = cols; col > 0; col--) { - this.gridmap[col] = []; - for (row = rows; row > 0; row--) { - this.add_faux_cell(row, col); - } - } - return this; - }; - - - /** - * Add cell to the faux grid. - * - * @method add_faux_cell - * @param {Number} row The row for the new faux cell. - * @param {Number} col The col for the new faux cell. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.add_faux_cell = function(row, col) { - var coords = $({ - left: this.baseX + ((col - 1) * this.min_widget_width), - top: this.baseY + (row -1) * this.min_widget_height, - width: this.min_widget_width, - height: this.min_widget_height, - col: col, - row: row, - original_col: col, - original_row: row - }).coords(); - - if (!$.isArray(this.gridmap[col])) { - this.gridmap[col] = []; - } - - this.gridmap[col][row] = false; - this.faux_grid.push(coords); - - return this; - }; - - - /** - * Add rows to the faux grid. - * - * @method add_faux_rows - * @param {Number} rows The number of rows you want to add to the faux grid. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.add_faux_rows = function(rows) { - var actual_rows = this.rows; - var max_rows = actual_rows + (rows || 1); - - for (var r = max_rows; r > actual_rows; r--) { - for (var c = this.cols; c >= 1; c--) { - this.add_faux_cell(r, c); - } - } - - this.rows = max_rows; - - if (this.options.autogenerate_stylesheet) { - this.generate_stylesheet(); - } - - return this; - }; - - /** - * Add cols to the faux grid. - * - * @method add_faux_cols - * @param {Number} cols The number of cols you want to add to the faux grid. - * @return {Object} Returns the instance of the Gridster class. - */ - fn.add_faux_cols = function(cols) { - var actual_cols = this.cols; - var max_cols = actual_cols + (cols || 1); - - for (var c = actual_cols; c < max_cols; c++) { - for (var r = this.rows; r >= 1; r--) { - this.add_faux_cell(r, c); - } - } - - this.cols = max_cols; - - if (this.options.autogenerate_stylesheet) { - this.generate_stylesheet(); - } - - return this; - }; - - - /** - * Recalculates the offsets for the faux grid. You need to use it when - * the browser is resized. - * - * @method recalculate_faux_grid - * @return {Object} Returns the instance of the Gridster class. - */ - fn.recalculate_faux_grid = function() { - var aw = this.$wrapper.width(); - this.baseX = ($(window).width() - aw) / 2; - this.baseY = this.$wrapper.offset().top; - - $.each(this.faux_grid, $.proxy(function(i, coords) { - this.faux_grid[i] = coords.update({ - left: this.baseX + (coords.data.col -1) * this.min_widget_width, - top: this.baseY + (coords.data.row -1) * this.min_widget_height - }); - - }, this)); - - return this; - }; - - - /** - * Get all widgets in the DOM and register them. - * - * @method get_widgets_from_DOM - * @return {Object} Returns the instance of the Gridster class. - */ - fn.get_widgets_from_DOM = function() { - this.$widgets.each($.proxy(function(i, widget) { - this.register_widget($(widget)); - }, this)); - return this; - }; - - - /** - * Calculate columns and rows to be set based on the configuration - * parameters, grid dimensions, etc ... - * - * @method generate_grid_and_stylesheet - * @return {Object} Returns the instance of the Gridster class. - */ - fn.generate_grid_and_stylesheet = function() { - var aw = this.$wrapper.width(); - var ah = this.$wrapper.height(); - - var cols = Math.floor(aw / this.min_widget_width) + - this.options.extra_cols; - - var actual_cols = this.$widgets.map(function() { - return $(this).attr('data-col'); - }); - actual_cols = Array.prototype.slice.call(actual_cols, 0); - //needed to pass tests with phantomjs - actual_cols.length || (actual_cols = [0]); - - var min_cols = Math.max.apply(Math, actual_cols); - - // get all rows that could be occupied by the current widgets - var max_rows = this.options.extra_rows; - this.$widgets.each(function(i, w) { - max_rows += (+$(w).attr('data-sizey')); - }); - - this.cols = Math.max(min_cols, cols, this.options.min_cols); - //this.rows = Math.max(max_rows, this.options.min_rows); - this.rows = this.options.max_rows; - - this.baseX = ($(window).width() - aw) / 2; - this.baseY = this.$wrapper.offset().top; - - if (this.options.autogenerate_stylesheet) { - this.generate_stylesheet(); - } - - return this.generate_faux_grid(this.rows, this.cols); - }; - - - //jQuery adapter - $.fn.gridster = function(options) { - return this.each(function() { - if (!$(this).data('gridster')) { - $(this).data('gridster', new Gridster( this, options )); - } - }); - }; - - $.Gridster = fn; - -}(jQuery, window, document)); - -;(function($, window, document, undefined) { - - var fn = $.Gridster; - - fn.widgets_in_col = function(col) { - if (!this.gridmap[col]) { - return false; - } - - for (var i = this.gridmap[col].length - 1; i >= 0; i--) { - if (this.is_widget(col, i) !== false) { - return true; - } - } - - return false; - }; - - fn.widgets_in_row = function(row) { - for (var i = this.gridmap.length; i >= 1; i--) { - if (this.is_widget(i, row) !== false) { - return true; - } - } - - return false; - }; - - - fn.widgets_in_range = function(col1, row1, col2, row2) { - var valid_cols = []; - var valid_rows = []; - var $widgets = $([]); - var c, r, $w, wgd; - - for (c = col2; c >= col1; c--) { - for (r = row2; r >= row1; r--) { - $w = this.is_widget(c, r); - - if ($w !== false) { - wgd = $w.data('coords').grid; - if (wgd.col >= col1 && wgd.col <= col2 && - wgd.row >= row1 && wgd.row <= row2 - ) { - $widgets = $widgets.add($w); - } - } - } - } - - return $widgets; - }; - - - fn.get_bottom_most_occupied_cell = function() { - var row = 0; - var col = 0; - this.for_each_cell(function($el, c, r) { - if ($el && r > row) { - row = r; - col = c; - } - }); - - return {col: col, row: row}; - }; - - - fn.get_right_most_occupied_cell = function() { - var row = 0; - var col = 0; - this.for_each_cell(function($el, c, r) { - if ($el) { - row = r; - col = c; - return false; - } - }); - - return {col: col, row: row}; - }; - - - fn.for_each_cell = function(callback, gridmap) { - gridmap || (gridmap = this.gridmap); - var cols = gridmap.length; - var rows = gridmap[1].length; - - cols_iter: - for (var c = cols - 1; c >= 1; c--) { - for (var r = rows - 1; r >= 1; r--) { - var $el = gridmap[c] && gridmap[c][r]; - if (callback) { - if (callback.call(this, $el, c, r) === false) { - break cols_iter; - } else { continue; } - } - } - } - }; - - - fn.next_position_in_range = function(size_x, size_y, max_rows) { - size_x || (size_x = 1); - size_y || (size_y = 1); - var ga = this.gridmap; - var cols_l = ga.length; - var valid_pos = []; - var rows_l; - - for (var c = 1; c < cols_l; c++) { - rows_l = max_rows || ga[c].length; - for (var r = 1; r <= rows_l; r++) { - var can_move_to = this.can_move_to({ - size_x: size_x, - size_y: size_y - }, c, r, max_rows); - - if (can_move_to) { - valid_pos.push({ - col: c, - row: r, - size_y: size_y, - size_x: size_x - }); - } - } - } - - if (valid_pos.length >= 1) { - return this.sort_by_col_asc(valid_pos)[0]; - } - - return false; - }; - - - fn.closest_to_right = function(col, row) { - if (!this.gridmap[col]) { return false; } - var cols_l = this.gridmap.length - 1; - - for (var c = col; c <= cols_l; c++) { - if (this.gridmap[c][row]) { - return { col: c, row: row }; - } - } - - return false; - }; - - - fn.closest_to_left = function(col, row) { - var cols_l = this.gridmap.length - 1; - if (!this.gridmap[col]) { return false; } - - for (var c = col; c >= 1; c--) { - if (this.gridmap[c][row]) { - return { col: c, row: row }; - } - } - - return false; - }; - -}(jQuery, window, document)); diff --git a/api/js/jquery/gridster/jquery.gridster.with-extras.min.js b/api/js/jquery/gridster/jquery.gridster.with-extras.min.js deleted file mode 100644 index 2404042b98..0000000000 --- a/api/js/jquery/gridster/jquery.gridster.with-extras.min.js +++ /dev/null @@ -1,2 +0,0 @@ -(function(t){function i(i){return i[0]&&t.isPlainObject(i[0])?this.data=i[0]:this.el=i,this.isCoords=!0,this.coords={},this.init(),this}var e=i.prototype;e.init=function(){this.set(),this.original_coords=this.get()},e.set=function(t,i){var e=this.el;if(e&&!t&&(this.data=e.offset(),this.data.width=e.width(),this.data.height=e.height()),e&&t&&!i){var s=e.offset();this.data.top=s.top,this.data.left=s.left}var r=this.data;return this.coords.x1=r.left,this.coords.y1=r.top,this.coords.x2=r.left+r.width,this.coords.y2=r.top+r.height,this.coords.cx=r.left+r.width/2,this.coords.cy=r.top+r.height/2,this.coords.width=r.width,this.coords.height=r.height,this.coords.el=e||!1,this},e.update=function(i){if(!i&&!this.el)return this;if(i){var e=t.extend({},this.data,i);return this.data=e,this.set(!0,!0)}return this.set(!0),this},e.get=function(){return this.coords},t.fn.coords=function(){if(this.data("coords"))return this.data("coords");var t=new i(this,arguments[0]);return this.data("coords",t),t}})(jQuery,window,document),function(t,i,e){function s(i,e,s){this.options=t.extend(r,s),this.$element=i,this.last_colliders=[],this.last_colliders_coords=[],"string"==typeof e||e instanceof jQuery?this.$colliders=t(e,this.options.colliders_context).not(this.$element):this.colliders=t(e),this.init()}var r={colliders_context:e.body},o=s.prototype;o.init=function(){this.find_collisions()},o.overlaps=function(t,i){var e=!1,s=!1;return(i.x1>=t.x1&&i.x1<=t.x2||i.x2>=t.x1&&i.x2<=t.x2||t.x1>=i.x1&&t.x2<=i.x2)&&(e=!0),(i.y1>=t.y1&&i.y1<=t.y2||i.y2>=t.y1&&i.y2<=t.y2||t.y1>=i.y1&&t.y2<=i.y2)&&(s=!0),e&&s},o.detect_overlapping_region=function(t,i){var e="",s="";return t.y1>i.cy&&t.y1i.y1&&t.y2i.cx&&t.x1i.x1&&t.x2o;o++)-1===t.inArray(r[o],i)&&e.call(this,r[o]);for(var n=0,_=i.length;_>n;n++)-1===t.inArray(i[n],r)&&s.call(this,i[n])},o.find_collisions=function(i){for(var e=this,s=[],r=[],o=this.colliders||this.$colliders,a=o.length,n=e.$element.coords().update(i||!1).get();a--;){var _=e.$colliders?t(o[a]):o[a],h=_.isCoords?_:_.coords(),d=h.get(),l=e.overlaps(n,d);if(l){var c=e.detect_overlapping_region(n,d);if("C"===c){var p=e.calculate_overlapped_area_coords(n,d),g=e.calculate_overlapped_area(p),u={area:g,area_coords:p,region:c,coords:d,player_coords:n,el:_};e.options.on_overlap&&e.options.on_overlap.call(this,u),s.push(h),r.push(u)}}}return(e.options.on_overlap_stop||e.options.on_overlap_start)&&this.manage_colliders_start_stop(s,e.options.on_overlap_start,e.options.on_overlap_stop),this.last_colliders_coords=s,r},o.get_closest_colliders=function(t){var i=this.find_collisions(t);return i.sort(function(t,i){return"C"===t.region&&"C"===i.region?t.coords.y1this.player_max_left?r=this.player_max_left:this.player_min_left>r&&(r=this.player_min_left)),{left:r,top:o,mouse_left:i.left,mouse_top:i.top}},_.manage_scroll=function(t){var i,e=o.scrollTop(),s=e,r=s+this.window_height,a=r-50,n=s+50;t.mouse_left;var _=s+t.mouse_top,h=this.doc_height-this.window_height+this.player_height;_>=a&&(i=e+30,h>i&&(o.scrollTop(i),this.scrollOffset=this.scrollOffset+30)),n>=_&&(i=e-30,i>0&&(o.scrollTop(i),this.scrollOffset=this.scrollOffset-30))},_.calculate_positions=function(){this.window_height=o.height()},_.drag_handler=function(i){if(i.target.nodeName,!this.disabled&&(1===i.which||a)&&!this.ignore_drag(i)){var e=this,s=!0;return this.$player=t(i.currentTarget),this.el_init_pos=this.get_actual_pos(this.$player),this.mouse_init_pos=this.get_mouse_pos(i),this.offsetY=this.mouse_init_pos.top-this.el_init_pos.top,this.on_pointer_events_move=function(t){var i=e.get_mouse_pos(t),r=Math.abs(i.left-e.mouse_init_pos.left),o=Math.abs(i.top-e.mouse_init_pos.top);return r>e.options.distance||o>e.options.distance?s?(s=!1,e.on_dragstart.call(e,t),!1):(e.is_dragging===!0&&e.on_dragmove.call(e,t),!1):!1},this.$body.on(n.move,this.on_pointer_events_move),!1}},_.on_dragstart=function(i){i.preventDefault(),this.drag_start=!0,this.is_dragging=!0;var s=this.$container.offset();return this.baseX=Math.round(s.left),this.baseY=Math.round(s.top),this.doc_height=t(e).height(),"clone"===this.options.helper?(this.$helper=this.$player.clone().appendTo(this.$container).addClass("helper"),this.helper=!0):this.helper=!1,this.scrollOffset=0,this.el_init_offset=this.$player.offset(),this.player_width=this.$player.width(),this.player_height=this.$player.height(),this.player_max_left=this.$container.width()-this.player_width+this.options.offset_left,this.options.start&&this.options.start.call(this.$player,i,{helper:this.helper?this.$helper:this.$player}),!1},_.on_dragmove=function(t){var i=this.get_offset(t);this.options.autoscroll&&this.manage_scroll(i),(this.helper?this.$helper:this.$player).css({position:"absolute",left:i.left,top:i.top});var e={position:{left:i.left,top:i.top}};return this.options.drag&&this.options.drag.call(this.$player,t,e),!1},_.on_dragstop=function(t){var i=this.get_offset(t);this.drag_start=!1;var e={position:{left:i.left,top:i.top}};return this.options.stop&&this.options.stop.call(this.$player,t,e),this.helper&&this.$helper.remove(),!1},_.on_select_start=function(t){return this.disabled||this.ignore_drag(t)?undefined:!1},_.enable=function(){this.disabled=!1},_.disable=function(){this.disabled=!0},_.destroy=function(){this.disable(),this.$container.off("selectstart",this.proxied_on_select_start),this.$container.off(n.start,this.proxied_drag_handler),this.$body.off(n.end,this.proxied_pointer_events_end),this.$body.off(n.move,this.on_pointer_events_move),t(i).unbind("resize",this.on_window_resize),t.removeData(this.$container,"drag")},_.ignore_drag=function(i){return this.options.handle?!t(i.target).is(this.options.handle):t.inArray(i.target.nodeName,this.options.ignore_dragging)>=0},t.fn.dragg=function(i){return this.each(function(){t.data(this,"drag")||t.data(this,"drag",new s(this,i))})}}(jQuery,window,document),function(t,i,e){function s(i,e){this.options=t.extend(!0,r,e),this.$el=t(i),this.$wrapper=this.$el.parent(),this.$widgets=this.$el.children(this.options.widget_selector).addClass("gs_w"),this.widgets=[],this.$changed=t([]),this.w_queue={},this.wrapper_width=this.$wrapper.width(),this.min_widget_width=2*this.options.widget_margins[0]+this.options.widget_base_dimensions[0],this.min_widget_height=2*this.options.widget_margins[1]+this.options.widget_base_dimensions[1],this.init()}var r={namespace:"",widget_selector:"li",static_class:"static",widget_margins:[10,10],widget_base_dimensions:[400,225],extra_rows:0,extra_cols:0,min_cols:1,max_cols:60,min_rows:15,max_rows:15,max_size_x:6,autogenerate_stylesheet:!0,avoid_overlapped_widgets:!0,shift_larger_widgets_down:!0,serialize_params:function(t,i){return{col:i.col,row:i.row,size_x:i.size_x,size_y:i.size_y}},collision:{},draggable:{distance:4,items:".gs_w:not(.static)"}};s.generated_stylesheets=[];var o=s.prototype;o.init=function(){this.generate_grid_and_stylesheet(),this.get_widgets_from_DOM(),this.set_dom_grid_height(),this.$wrapper.addClass("ready"),this.draggable(),t(i).bind("resize",throttle(t.proxy(this.recalculate_faux_grid,this),200))},o.disable=function(){return this.$wrapper.find(".player-revert").removeClass("player-revert"),this.drag_api.disable(),this},o.enable=function(){return this.drag_api.enable(),this},o.add_widget=function(i,e,s,r,o){var a;e||(e=1),s||(s=1),!r&!o?a=this.next_position(e,s):(a={col:r,row:o},this.empty_cells(r,o,e,s));var n=t(i).attr({"data-col":a.col,"data-row":a.row,"data-sizex":e,"data-sizey":s}).addClass("gs_w").appendTo(this.$el).hide();return this.$widgets=this.$widgets.add(n),this.$changed=this.$changed.add(n),this.register_widget(n),this.add_faux_rows(a.size_y),this.set_dom_grid_height(),n.fadeIn()},o.resize_widget=function(i,e,s){var r=i.coords().grid;e||(e=r.size_x),s||(s=r.size_y),e>this.cols&&(e=this.cols);var o=this.get_cells_occupied(r),a=r.size_x,n=r.size_y,_=r.col,h=_;if(_+e-1>this.cols){var d=_+(e-1)-this.cols,l=_-d;h=Math.max(1,l)}var c={col:h,row:r.row,size_x:e,size_y:s},p=this.get_cells_occupied(c),g=[];t.each(o.cols,function(i,e){-1===t.inArray(e,p.cols)&&g.push(e)});var u=[];t.each(p.cols,function(i,e){-1===t.inArray(e,o.cols)&&u.push(e)});var f=[];t.each(o.rows,function(i,e){-1===t.inArray(e,p.rows)&&f.push(e)});var w=[];if(t.each(p.rows,function(i,e){-1===t.inArray(e,o.rows)&&w.push(e)}),this.remove_from_gridmap(r),u.length){var y=[h,r.row,e,Math.min(n,s),i];this.empty_cells.apply(this,y)}if(w.length){var v=[h,r.row,e,s,i];this.empty_cells.apply(this,v)}if(r.col=h,r.size_x=e,r.size_y=s,this.add_to_gridmap(c,i),i.data("coords").update({width:e*this.options.widget_base_dimensions[0]+2*(e-1)*this.options.widget_margins[0],height:s*this.options.widget_base_dimensions[1]+2*(s-1)*this.options.widget_margins[1]}),s>n&&this.add_faux_rows(s-n),e>a&&this.add_faux_cols(e-a),i.attr({"data-col":h,"data-sizex":e,"data-sizey":s}),g.length){var m=[g[0],r.row,g.length,Math.min(n,s),i];this.remove_empty_cells.apply(this,m)}if(f.length){var x=[h,r.row,e,s,i];this.remove_empty_cells.apply(this,x)}return i},o.empty_cells=function(i,e,s,r,o){var a=this.widgets_below({col:i,row:e-r,size_x:s,size_y:r});return a.not(o).each(t.proxy(function(i,s){var o=t(s).coords().grid;if(e+r-1>=o.row){var a=e+r-o.row;this.move_widget_down(t(s),a)}},this)),this.set_dom_grid_height(),this},o.remove_empty_cells=function(t,i,e,s){return this.widgets_below({col:t,row:i,size_x:e,size_y:s}),this.set_dom_grid_height(),this},o.next_position=function(t,i){t||(t=1),i||(i=1);for(var e,s=this.gridmap,r=s.length,o=[],a=1;r>a;a++){e=s[a].length;for(var n=1;e>=n;n++){var _=this.can_move_to({size_x:t,size_y:i},a,n);_&&o.push({col:a,row:n,size_y:i,size_x:t})}}return o.length?this.sort_by_row_and_col_asc(o)[0]:!1},o.remove_by_grid=function(t,i){var e=this.is_widget(t,i);e&&this.remove_widget(e)},o.remove_widget=function(i,e,s){var r=i instanceof jQuery?i:t(i),o=r.coords().grid;t.isFunction(e)&&(s=e,e=!1),this.cells_occupied_by_placeholder={},this.$widgets=this.$widgets.not(r);var a=this.widgets_below(r);this.remove_from_gridmap(o),r.fadeOut(t.proxy(function(){r.remove(),e||a.each(t.proxy(function(i,e){this.move_widget_up(t(e),o.size_y)},this)),this.set_dom_grid_height(),s&&s.call(this,i)},this))},o.remove_all_widgets=function(i){return this.$widgets.each(t.proxy(function(t,e){this.remove_widget(e,!0,i)},this)),this},o.serialize=function(i){i||(i=this.$widgets);var e=[];return i.each(t.proxy(function(i,s){t(s).coords().grid!==undefined&&e.push(this.options.serialize_params(t(s),t(s).coords().grid))},this)),e},o.serialize_changed=function(){return this.serialize(this.$changed)},o.register_widget=function(t){var i={col:parseInt(t.attr("data-col"),10),row:parseInt(t.attr("data-row"),10),size_x:parseInt(t.attr("data-sizex"),10),size_y:parseInt(t.attr("data-sizey"),10),el:t};return this.options.avoid_overlapped_widgets&&!this.can_move_to({size_x:i.size_x,size_y:i.size_y},i.col,i.row)&&(i=this.next_position(i.size_x,i.size_y),i.el=t,t.attr({"data-col":i.col,"data-row":i.row,"data-sizex":i.size_x,"data-sizey":i.size_y})),t.data("coords",t.coords()),t.data("coords").grid=i,this.add_to_gridmap(i,t),this},o.update_widget_position=function(t,i){return this.for_each_cell_occupied(t,function(t,e){return this.gridmap[t]?(this.gridmap[t][e]=i,undefined):this}),this},o.remove_from_gridmap=function(t){return this.update_widget_position(t,!1)},o.add_to_gridmap=function(t,i){this.update_widget_position(t,i||t.el)},o.draggable=function(){var i=this,e=t.extend(!0,{},this.options.draggable,{offset_left:this.options.widget_margins[0],start:function(e,s){i.$widgets.filter(".player-revert").removeClass("player-revert"),i.$player=t(this),i.$helper="clone"===i.options.draggable.helper?t(s.helper):i.$player,i.helper=!i.$helper.is(i.$player),i.on_start_drag.call(i,e,s),i.$el.trigger("gridster:dragstart")},stop:function(t,e){i.on_stop_drag.call(i,t,e),i.$el.trigger("gridster:dragstop")},drag:throttle(function(t,e){i.on_drag.call(i,t,e),i.$el.trigger("gridster:drag")},60)});return this.drag_api=this.$el.dragg(e).data("drag"),this},o.on_start_drag=function(i,e){this.$helper.add(this.$player).add(this.$wrapper).addClass("dragging"),this.$player.addClass("player"),this.player_grid_data=this.$player.coords().grid,this.placeholder_grid_data=t.extend({},this.player_grid_data),this.$el.css("height",this.$el.height()+this.player_grid_data.size_y*this.min_widget_height);var s=this.faux_grid,r=this.$player.data("coords").coords;this.cells_occupied_by_player=this.get_cells_occupied(this.player_grid_data),this.cells_occupied_by_placeholder=this.get_cells_occupied(this.placeholder_grid_data),this.last_cols=[],this.last_rows=[],this.collision_api=this.$helper.collision(s,this.options.collision),this.$preview_holder=t("
  • ",{"class":"preview-holder","data-row":this.$player.attr("data-row"),"data-col":this.$player.attr("data-col"),css:{width:r.width,height:r.height}}).appendTo(this.$el),this.options.draggable.start&&this.options.draggable.start.call(this,i,e)},o.on_drag=function(t,i){if(null===this.$player)return!1;var e={left:i.position.left+this.baseX,top:i.position.top+this.baseY};this.colliders_data=this.collision_api.get_closest_colliders(e),this.on_overlapped_column_change(this.on_start_overlapping_column,this.on_stop_overlapping_column),this.on_overlapped_row_change(this.on_start_overlapping_row,this.on_stop_overlapping_row),this.helper&&this.$player&&this.$player.css({left:i.position.left,top:i.position.top}),this.options.draggable.drag&&this.options.draggable.drag.call(this,t,i)},o.on_stop_drag=function(t,i){this.$helper.add(this.$player).add(this.$wrapper).removeClass("dragging"),i.position.left=i.position.left+this.baseX,i.position.top=i.position.top+this.baseY,this.colliders_data=this.collision_api.get_closest_colliders(i.position),this.on_overlapped_column_change(this.on_start_overlapping_column,this.on_stop_overlapping_column),this.on_overlapped_row_change(this.on_start_overlapping_row,this.on_stop_overlapping_row),this.$player.addClass("player-revert").removeClass("player").attr({"data-col":this.placeholder_grid_data.col,"data-row":this.placeholder_grid_data.row}).css({left:"",top:""}),this.$changed=this.$changed.add(this.$player),this.cells_occupied_by_player=this.get_cells_occupied(this.placeholder_grid_data),this.set_cells_player_occupies(this.placeholder_grid_data.col,this.placeholder_grid_data.row),this.$player.coords().grid.row=this.placeholder_grid_data.row,this.$player.coords().grid.col=this.placeholder_grid_data.col,this.options.draggable.stop&&this.options.draggable.stop.call(this,t,i),this.$preview_holder.remove(),this.$player=null,this.$helper=null,this.placeholder_grid_data={},this.player_grid_data={},this.cells_occupied_by_placeholder={},this.cells_occupied_by_player={},this.w_queue={},this.set_dom_grid_height()},o.on_overlapped_column_change=function(i,e){if(this.colliders_data.length){var s,r=this.get_targeted_columns(this.colliders_data[0].el.data.col),o=this.last_cols.length,a=r.length;for(s=0;a>s;s++)-1===t.inArray(r[s],this.last_cols)&&(i||t.noop).call(this,r[s]);for(s=0;o>s;s++)-1===t.inArray(this.last_cols[s],r)&&(e||t.noop).call(this,this.last_cols[s]);return this.last_cols=r,this}},o.on_overlapped_row_change=function(i,e){if(this.colliders_data.length){var s,r=this.get_targeted_rows(this.colliders_data[0].el.data.row),o=this.last_rows.length,a=r.length;for(s=0;a>s;s++)-1===t.inArray(r[s],this.last_rows)&&(i||t.noop).call(this,r[s]);for(s=0;o>s;s++)-1===t.inArray(this.last_rows[s],r)&&(e||t.noop).call(this,this.last_rows[s]);this.last_rows=r}},o.set_player=function(i,e,s){var r=this,o=!1;s||this.empty_cells_player_occupies();var a=s?{col:i}:r.colliders_data[0].el.data,n=a.col,_=a.row||e;this.player_grid_data={col:n,row:_,size_y:this.player_grid_data.size_y,size_x:this.player_grid_data.size_x},this.cells_occupied_by_player=this.get_cells_occupied(this.player_grid_data),this.cells_occupied_by_placeholder=this.get_cells_occupied(this.placeholder_grid_data);var h=this.get_widgets_overlapped(this.player_grid_data),d=this.player_grid_data.size_y,l=this.player_grid_data.size_x,c=this.cells_occupied_by_placeholder,p=this;if(h.each(t.proxy(function(i,e){var s=t(e),r=s.coords().grid,a=c.cols[0]+l-1,g=c.rows[0]+d-1;if(s.hasClass(p.options.static_class))return!0;if(l>=r.size_x&&d>=r.size_y)if(p.is_swap_occupied(c.cols[0],r.row,r.size_x,r.size_y)||p.is_player_in(c.cols[0],r.row)||p.is_in_queue(c.cols[0],r.row,s))if(p.is_swap_occupied(a,r.row,r.size_x,r.size_y)||p.is_player_in(a,r.row)||p.is_in_queue(a,r.row,s))if(p.is_swap_occupied(r.col,c.rows[0],r.size_x,r.size_y)||p.is_player_in(r.col,c.rows[0])||p.is_in_queue(r.col,c.rows[0],s))if(p.is_swap_occupied(r.col,g,r.size_x,r.size_y)||p.is_player_in(r.col,g)||p.is_in_queue(r.col,g,s))if(p.is_swap_occupied(c.cols[0],c.rows[0],r.size_x,r.size_y)||p.is_player_in(c.cols[0],c.rows[0])||p.is_in_queue(c.cols[0],c.rows[0],s))for(var u=0;l>u;u++)for(var f=0;d>f;f++){var w=c.cols[0]+u,y=c.rows[0]+f;if(!p.is_swap_occupied(w,y,r.size_x,r.size_y)&&!p.is_player_in(w,y)&&!p.is_in_queue(w,y,s)){o=p.queue_widget(w,y,s),u=l;break}}else o=p.queue_widget(c.cols[0],c.rows[0],s);else o=p.queue_widget(r.col,g,s);else o=p.queue_widget(r.col,c.rows[0],s);else o=p.queue_widget(a,r.row,s);else o=p.queue_widget(c.cols[0],r.row,s);else p.options.shift_larger_widgets_down&&!o&&h.each(t.proxy(function(i,e){var s=t(e);s.coords().grid,p.can_go_down(s)&&(p.move_widget_down(s,p.player_grid_data.size_y),p.set_placeholder(n,_))}));p.clean_up_changed()})),o&&this.can_placeholder_be_set(n,_,l,d)){for(var g in this.w_queue){var i=parseInt(g.split("_")[0]),e=parseInt(g.split("_")[1]);"full"!=this.w_queue[g]&&this.new_move_widget_to(this.w_queue[g],i,e)}this.set_placeholder(n,_)}if(!h.length){var u=this.can_go_player_up(this.player_grid_data);u!==!1&&(_=u),this.can_placeholder_be_set(n,_,l,d)&&this.set_placeholder(n,_)}return this.w_queue={},{col:n,row:_}},o.is_swap_occupied=function(t,i,e,s){for(var r=!1,o=0;e>o;o++)for(var a=0;s>a;a++){var n=t+o,_=i+a,h=n+"_"+_;if(this.is_occupied(n,_))r=!0;else if(h in this.w_queue){if("full"==this.w_queue[h]){r=!0;continue}$tw=this.w_queue[h],tgd=$tw.coords().grid,this.is_widget_under_player(tgd.col,tgd.row)||delete this.w_queue[h]}_>parseInt(this.options.max_rows)&&(r=!0),n>parseInt(this.options.max_cols)&&(r=!0),this.is_player_in(n,_)&&(r=!0)}return r},o.can_placeholder_be_set=function(t,i,e,s){for(var r=!0,o=0;e>o;o++)for(var a=0;s>a;a++){var n=t+o,_=i+a,h=this.is_widget(n,_);_>parseInt(this.options.max_rows)&&(r=!1),n>parseInt(this.options.max_cols)&&(r=!1),this.is_occupied(n,_)&&!this.is_widget_queued_and_can_move(h)&&(r=!1)}return r},o.queue_widget=function(t,i,e){var s=e,r=s.coords().grid,o=t+"_"+i;if(o in this.w_queue)return!1;this.w_queue[o]=s;for(var a=0;r.size_x>a;a++)for(var n=0;r.size_y>n;n++){var _=t+a,h=i+n,d=_+"_"+h;d!=o&&(this.w_queue[d]="full")}return!0},o.is_widget_queued_and_can_move=function(t){var i=!1;if(t===!1)return!1;for(var e in this.w_queue)if("full"!=this.w_queue[e]&&this.w_queue[e].attr("data-col")==t.attr("data-col")&&this.w_queue[e].attr("data-row")==t.attr("data-row")){i=!0;for(var s=this.w_queue[e],r=parseInt(e.split("_")[0]),o=parseInt(e.split("_")[1]),a=s.coords().grid,n=0;a.size_x>n;n++)for(var _=0;a.size_y>_;_++){var h=r+n,d=o+_;this.is_player_in(h,d)&&(i=!1)}}return i},o.is_in_queue=function(t,i,e){var s=!1,r=t+"_"+i;return r in this.w_queue&&("full"==this.w_queue[r]?s=!0:($tw=this.w_queue[r],tgd=$tw.coords().grid,this.is_widget_under_player(tgd.col,tgd.row)?this.w_queue[r].attr("data-col")==e.attr("data-col")&&this.w_queue[r].attr("data-row")==e.attr("data-row")?(delete this.w_queue[r],s=!1):s=!0:(delete this.w_queue[r],s=!1))),s},o.widgets_constraints=function(i){var e,s=t([]),r=[],o=[];return i.each(t.proxy(function(i,e){var a=t(e),n=a.coords().grid;this.can_go_widget_up(n)?(s=s.add(a),r.push(n)):o.push(n)},this)),e=i.not(s),{can_go_up:this.sort_by_row_asc(r),can_not_go_up:this.sort_by_row_desc(o)}},o.sort_by_row_asc=function(i){return i=i.sort(function(i,e){return i.row||(i=t(i).coords().grid,e=t(e).coords().grid),i.row>e.row?1:-1})},o.sort_by_row_and_col_asc=function(t){return t=t.sort(function(t,i){return t.row>i.row||t.row===i.row&&t.col>i.col?1:-1})},o.sort_by_col_asc=function(t){return t=t.sort(function(t,i){return t.col>i.col?1:-1})},o.sort_by_row_desc=function(t){return t=t.sort(function(t,i){return t.row+t.size_y=0&&t.inArray(e,s.rows)>=0},o.is_placeholder_in=function(i,e){var s=this.cells_occupied_by_placeholder||{};return this.is_placeholder_in_col(i)&&t.inArray(e,s.rows)>=0},o.is_placeholder_in_col=function(i){var e=this.cells_occupied_by_placeholder||[];return t.inArray(i,e.cols)>=0},o.is_empty=function(t,i){return this.gridmap[t]!==undefined&&this.gridmap[t][i]!==undefined&&this.gridmap[t][i]===!1?!0:!1},o.is_occupied=function(t,i){return this.gridmap[t]?this.gridmap[t][i]?!0:!1:!1},o.is_widget=function(t,i){var e=this.gridmap[t];return e?(e=e[i],e?e:!1):!1},o.is_static=function(t,i){var e=this.gridmap[t];return e?(e=e[i],e&&e.hasClass(this.options.static_class)?!0:!1):!1},o.is_widget_under_player=function(t,i){return this.is_widget(t,i)?this.is_player_in(t,i):!1},o.get_widgets_under_player=function(i){i||(i=this.cells_occupied_by_player||{cols:[],rows:[]});var e=t([]);return t.each(i.cols,t.proxy(function(s,r){t.each(i.rows,t.proxy(function(t,i){this.is_widget(r,i)&&(e=e.add(this.gridmap[r][i]))},this))},this)),e},o.set_placeholder=function(i,e){var s=t.extend({},this.placeholder_grid_data),r=this.widgets_below({col:s.col,row:s.row,size_y:s.size_y,size_x:s.size_x}),o=i+s.size_x-1;o>this.cols&&(i-=o-i);var a=e>this.placeholder_grid_data.row,n=this.placeholder_grid_data.col!==i;this.placeholder_grid_data.col=i,this.placeholder_grid_data.row=e,this.cells_occupied_by_placeholder=this.get_cells_occupied(this.placeholder_grid_data),this.$preview_holder.attr({"data-row":e,"data-col":i}),(a||n)&&r.each(t.proxy(function(i,e){$w=t(e),wgd=$w.coords().grid;var s=this.can_go_widget_up(wgd);s&&this.move_widget_to($w,s)},this));var _=this.get_widgets_under_player(this.cells_occupied_by_placeholder);_.length&&_.each(t.proxy(function(i,r){var o=t(r);this.move_widget_down(o,e+s.size_y-o.data("coords").grid.row)},this))},o.can_go_player_up=function(t){var i=t.row+t.size_y-1,e=!0,s=[],r=1e4,o=this.get_widgets_under_player();return this.for_each_column_occupied(t,function(t){var a=this.gridmap[t],n=i+1;for(s[t]=[];--n>0&&(this.is_empty(t,n)||this.is_player(t,n)||this.is_widget(t,n)&&a[n].is(o));)s[t].push(n),r=r>n?n:r;return 0===s[t].length?(e=!1,!0):(s[t].sort(),undefined)}),e?this.get_valid_rows(t,s,r):!1},o.can_go_widget_up=function(t){var i=t.row+t.size_y-1,e=!0,s=[],r=1e4;return this.for_each_column_occupied(t,function(o){var a=this.gridmap[o];s[o]=[];for(var n=i+1;--n>0&&(!this.is_widget(o,n)||this.is_player_in(o,n)||a[n].is(t.el));)this.is_player(o,n)||this.is_placeholder_in(o,n)||this.is_player_in(o,n)||s[o].push(n),r>n&&(r=n);return 0===s[o].length?(e=!1,!0):(s[o].sort(),undefined)}),e?this.get_valid_rows(t,s,r):!1},o.get_valid_rows=function(i,e,s){for(var r=i.row,o=i.row+i.size_y-1,a=i.size_y,n=s-1,_=[];o>=++n;){var h=!0;if(t.each(e,function(i,e){t.isArray(e)&&-1===t.inArray(n,e)&&(h=!1)}),h===!0&&(_.push(n),_.length===a))break}var d=!1;return 1===a?_[0]!==r&&(d=_[0]||!1):_[0]!==r&&(d=this.get_consecutive_numbers_index(_,a)),d},o.get_consecutive_numbers_index=function(t,i){for(var e=t.length,s=[],r=!0,o=-1,a=0;e>a;a++){if(r||t[a]===o+1){if(s.push(a),s.length===i)break;r=!1}else s=[],r=!0;o=t[a]}return s.length>=i?t[s[0]]:!1},o.get_widgets_overlapped=function(){var i=t([]),e=[],s=this.cells_occupied_by_player.rows.slice(0);return s.reverse(),t.each(this.cells_occupied_by_player.cols,t.proxy(function(r,o){t.each(s,t.proxy(function(s,r){if(!this.gridmap[o])return!0;var a=this.gridmap[o][r];this.is_occupied(o,r)&&!this.is_player(a)&&-1===t.inArray(a,e)&&(i=i.add(a),e.push(a))},this))},this)),i},o.on_start_overlapping_column=function(t){this.set_player(t,!1)},o.on_start_overlapping_row=function(t){this.set_player(!1,t)},o.on_stop_overlapping_column=function(t){var i=this;this.options.shift_larger_widgets_down&&this.for_each_widget_below(t,this.cells_occupied_by_player.rows[0],function(){i.move_widget_up(this,i.player_grid_data.size_y)})},o.on_stop_overlapping_row=function(t){var i=this,e=this.cells_occupied_by_player.cols;if(this.options.shift_larger_widgets_down)for(var s=0,r=e.length;r>s;s++)this.for_each_widget_below(e[s],t,function(){console.log("from_on_stop_overlapping_row"),i.move_widget_up(this,i.player_grid_data.size_y)})},o.new_move_widget_to=function(t,i,e){var s=t.coords().grid;return this.remove_from_gridmap(s),s.row=e,s.col=i,this.add_to_gridmap(s),t.attr("data-row",e),t.attr("data-col",i),this.update_widget_position(s,t),this.$changed=this.$changed.add(t),this},o.move_widget_to=function(i,e){var s=this,r=i.coords().grid;e-r.row;var o=this.widgets_below(i),a=this.can_move_to(r,r.col,e,i);return a===!1?!1:(this.remove_from_gridmap(r),r.row=e,this.add_to_gridmap(r),i.attr("data-row",e),this.$changed=this.$changed.add(i),o.each(function(i,e){var r=t(e),o=r.coords().grid,a=s.can_go_widget_up(o);a&&a!==o.row&&s.move_widget_to(r,a)}),this)},o.move_widget_up=function(i,e){var s=i.coords().grid,r=s.row,o=[];return e||(e=1),this.can_go_up(i)?(this.for_each_column_occupied(s,function(s){if(-1===t.inArray(i,o)){var a=i.coords().grid,n=r-e;if(n=this.can_go_up_to_row(a,s,n),!n)return!0;this.widgets_below(i),this.remove_from_gridmap(a),a.row=n,this.add_to_gridmap(a),i.attr("data-row",a.row),this.$changed=this.$changed.add(i),o.push(i)}}),undefined):!1},o.move_widget_down=function(i,e){var s=i.coords().grid,r=s.row,o=[],a=e;if(!i)return!1;if(-1===t.inArray(i,o)){var n=i.coords().grid,_=r+e,h=this.widgets_below(i);this.remove_from_gridmap(n),h.each(t.proxy(function(i,e){var s=t(e),r=s.coords().grid,o=this.displacement_diff(r,n,a);o>0&&this.move_widget_down(s,o)},this)),n.row=_,this.update_widget_position(n,i),i.attr("data-row",n.row),this.$changed=this.$changed.add(i),o.push(i)}},o.can_go_up_to_row=function(i,e,s){var r,o=this.gridmap,a=!0,n=[],_=i.row;if(this.for_each_column_occupied(i,function(t){for(o[t],n[t]=[],r=_;r--&&this.is_empty(t,r)&&!this.is_placeholder_in(t,r);)n[t].push(r);return n[t].length?undefined:(a=!1,!0)}),!a)return!1;for(r=s,r=1;_>r;r++){for(var h=!0,d=0,l=n.length;l>d;d++)n[d]&&-1===t.inArray(r,n[d])&&(h=!1);if(h===!0){a=r;break}}return a},o.displacement_diff=function(t,i,e){var s=t.row,r=[],o=i.row+i.size_y;this.for_each_column_occupied(t,function(t){for(var i=0,e=o;s>e;e++)this.is_empty(t,e)&&(i+=1);r.push(i)});var a=Math.max.apply(Math,r);return e-=a,e>0?e:0},o.widgets_below=function(i){var e=t.isPlainObject(i)?i:i.coords().grid,s=this;this.gridmap;var r=e.row+e.size_y-1,o=t([]);return this.for_each_column_occupied(e,function(i){s.for_each_widget_below(i,r,function(){return s.is_player(this)||-1!==t.inArray(this,o)?undefined:(o=o.add(this),!0)})}),this.sort_by_row_asc(o)},o.set_cells_player_occupies=function(t,i){return this.remove_from_gridmap(this.placeholder_grid_data),this.placeholder_grid_data.col=t,this.placeholder_grid_data.row=i,this.add_to_gridmap(this.placeholder_grid_data,this.$player),this},o.empty_cells_player_occupies=function(){return this.remove_from_gridmap(this.placeholder_grid_data),this},o.can_go_down=function(i){var e=!0,s=this;return i.hasClass(this.options.static_class)&&(e=!1),this.widgets_below(i).each(function(){t(this).hasClass(s.options.static_class)&&(e=!1)}),e},o.can_go_up=function(t){var i=t.coords().grid,e=i.row,s=e-1;this.gridmap;var r=!0;return 1===e?!1:(this.for_each_column_occupied(i,function(t){return this.is_widget(t,s),this.is_occupied(t,s)||this.is_player(t,s)||this.is_placeholder_in(t,s)||this.is_player_in(t,s)?(r=!1,!0):undefined}),r)},o.can_move_to=function(t,i,e,s){this.gridmap;var r=t.el,o={size_y:t.size_y,size_x:t.size_x,col:i,row:e},a=!0,n=i+t.size_x-1;return n>this.cols?!1:s&&e+t.size_y-1>s?!1:(this.for_each_cell_occupied(o,function(i,e){var s=this.is_widget(i,e);!s||t.el&&!s.is(r)||(a=!1)}),a)},o.get_targeted_columns=function(t){for(var i=(t||this.player_grid_data.col)+(this.player_grid_data.size_x-1),e=[],s=t;i>=s;s++)e.push(s);return e},o.get_targeted_rows=function(t){for(var i=(t||this.player_grid_data.row)+(this.player_grid_data.size_y-1),e=[],s=t;i>=s;s++)e.push(s);return e},o.get_cells_occupied=function(t){var i,e={cols:[],rows:[]};for(arguments[1]instanceof jQuery&&(t=arguments[1].coords().grid),i=0;t.size_x>i;i++){var s=t.col+i;e.cols.push(s)}for(i=0;t.size_y>i;i++){var r=t.row+i; -e.rows.push(r)}return e},o.for_each_cell_occupied=function(t,i){return this.for_each_column_occupied(t,function(e){this.for_each_row_occupied(t,function(t){i.call(this,e,t)})}),this},o.for_each_column_occupied=function(t,i){for(var e=0;t.size_x>e;e++){var s=t.col+e;i.call(this,s,t)}},o.for_each_row_occupied=function(t,i){for(var e=0;t.size_y>e;e++){var s=t.row+e;i.call(this,s,t)}},o.clean_up_changed=function(){$gr=this,$gr.$changed.each(function(){$gr.options.shift_larger_widgets_down&&$gr.move_widget_up(t(this))})},o._traversing_widgets=function(i,e,s,r,o){var a=this.gridmap;if(a[s]){var n,_,h=i+"/"+e;if(arguments[2]instanceof jQuery){var d=arguments[2].coords().grid;s=d.col,r=d.row,o=arguments[3]}var l=[],c=r,p={"for_each/above":function(){for(;c--&&!(c>0&&this.is_widget(s,c)&&-1===t.inArray(a[s][c],l)&&(n=o.call(a[s][c],s,c),l.push(a[s][c]),n)););},"for_each/below":function(){for(c=r+1,_=a[s].length;_>c;c++)this.is_widget(s,c)&&-1===t.inArray(a[s][c],l)&&(n=o.call(a[s][c],s,c),l.push(a[s][c]))}};p[h]&&p[h].call(this)}},o.for_each_widget_above=function(t,i,e){return this._traversing_widgets("for_each","above",t,i,e),this},o.for_each_widget_below=function(t,i,e){return this._traversing_widgets("for_each","below",t,i,e),this},o.get_highest_occupied_cell=function(){for(var t,i=this.gridmap,e=[],s=[],r=i.length-1;r>=1;r--)for(t=i[r].length-1;t>=1;t--)if(this.is_widget(r,t)){e.push(t),s[t]=r;break}var o=Math.max.apply(Math,e);return this.highest_occupied_cell={col:s[o],row:o},this.highest_occupied_cell},o.get_widgets_from=function(i,e){this.gridmap;var s=t();return i&&(s=s.add(this.$widgets.filter(function(){var e=t(this).attr("data-col");return e===i||e>i}))),e&&(s=s.add(this.$widgets.filter(function(){var i=t(this).attr("data-row");return i===e||i>e}))),s},o.set_dom_grid_height=function(){var t=this.get_highest_occupied_cell().row;return this.$el.css("height",t*this.min_widget_height),this},o.generate_stylesheet=function(i){var e,r="",o=this.options.max_size_x;i||(i={}),i.cols||(i.cols=this.cols),i.rows||(i.rows=this.rows),i.namespace||(i.namespace=this.options.namespace),i.widget_base_dimensions||(i.widget_base_dimensions=this.options.widget_base_dimensions),i.widget_margins||(i.widget_margins=this.options.widget_margins),i.min_widget_width=2*i.widget_margins[0]+i.widget_base_dimensions[0],i.min_widget_height=2*i.widget_margins[1]+i.widget_base_dimensions[1];var a=t.param(i);if(t.inArray(a,s.generated_stylesheets)>=0)return!1;for(s.generated_stylesheets.push(a),e=i.cols;e>=0;e--)r+=i.namespace+' [data-col="'+(e+1)+'"] { left:'+(e*i.widget_base_dimensions[0]+e*i.widget_margins[0]+(e+1)*i.widget_margins[0])+"px;} ";for(e=i.rows;e>=0;e--)r+=i.namespace+' [data-row="'+(e+1)+'"] { top:'+(e*i.widget_base_dimensions[1]+e*i.widget_margins[1]+(e+1)*i.widget_margins[1])+"px;} ";for(var n=1;i.rows>=n;n++)r+=i.namespace+' [data-sizey="'+n+'"] { height:'+(n*i.widget_base_dimensions[1]+(n-1)*2*i.widget_margins[1])+"px;}";for(var _=1;o>=_;_++)r+=i.namespace+' [data-sizex="'+_+'"] { width:'+(_*i.widget_base_dimensions[0]+(_-1)*2*i.widget_margins[0])+"px;}";return this.add_style_tag(r)},o.add_style_tag=function(t){var i=e,s=i.createElement("style");return i.getElementsByTagName("head")[0].appendChild(s),s.setAttribute("type","text/css"),s.styleSheet?s.styleSheet.cssText=t:s.appendChild(e.createTextNode(t)),this},o.generate_faux_grid=function(t,i){this.faux_grid=[],this.gridmap=[];var e,s;for(e=i;e>0;e--)for(this.gridmap[e]=[],s=t;s>0;s--)this.add_faux_cell(s,e);return this},o.add_faux_cell=function(i,e){var s=t({left:this.baseX+(e-1)*this.min_widget_width,top:this.baseY+(i-1)*this.min_widget_height,width:this.min_widget_width,height:this.min_widget_height,col:e,row:i,original_col:e,original_row:i}).coords();return t.isArray(this.gridmap[e])||(this.gridmap[e]=[]),this.gridmap[e][i]=!1,this.faux_grid.push(s),this},o.add_faux_rows=function(t){for(var i=this.rows,e=i+(t||1),s=e;s>i;s--)for(var r=this.cols;r>=1;r--)this.add_faux_cell(s,r);return this.rows=e,this.options.autogenerate_stylesheet&&this.generate_stylesheet(),this},o.add_faux_cols=function(t){for(var i=this.cols,e=i+(t||1),s=i;e>s;s++)for(var r=this.rows;r>=1;r--)this.add_faux_cell(r,s);return this.cols=e,this.options.autogenerate_stylesheet&&this.generate_stylesheet(),this},o.recalculate_faux_grid=function(){var e=this.$wrapper.width();return this.baseX=(t(i).width()-e)/2,this.baseY=this.$wrapper.offset().top,t.each(this.faux_grid,t.proxy(function(t,i){this.faux_grid[t]=i.update({left:this.baseX+(i.data.col-1)*this.min_widget_width,top:this.baseY+(i.data.row-1)*this.min_widget_height})},this)),this},o.get_widgets_from_DOM=function(){return this.$widgets.each(t.proxy(function(i,e){this.register_widget(t(e))},this)),this},o.generate_grid_and_stylesheet=function(){var e=this.$wrapper.width();this.$wrapper.height();var s=Math.floor(e/this.min_widget_width)+this.options.extra_cols,r=this.$widgets.map(function(){return t(this).attr("data-col")});r=Array.prototype.slice.call(r,0),r.length||(r=[0]);var o=Math.max.apply(Math,r),a=this.options.extra_rows;return this.$widgets.each(function(i,e){a+=+t(e).attr("data-sizey")}),this.cols=Math.max(o,s,this.options.min_cols),this.rows=this.options.max_rows,this.baseX=(t(i).width()-e)/2,this.baseY=this.$wrapper.offset().top,this.options.autogenerate_stylesheet&&this.generate_stylesheet(),this.generate_faux_grid(this.rows,this.cols)},t.fn.gridster=function(i){return this.each(function(){t(this).data("gridster")||t(this).data("gridster",new s(this,i))})},t.Gridster=o}(jQuery,window,document),function(t){var i=t.Gridster;i.widgets_in_col=function(t){if(!this.gridmap[t])return!1;for(var i=this.gridmap[t].length-1;i>=0;i--)if(this.is_widget(t,i)!==!1)return!0;return!1},i.widgets_in_row=function(t){for(var i=this.gridmap.length;i>=1;i--)if(this.is_widget(i,t)!==!1)return!0;return!1},i.widgets_in_range=function(i,e,s,r){var o,a,n,_,h=t([]);for(o=s;o>=i;o--)for(a=r;a>=e;a--)n=this.is_widget(o,a),n!==!1&&(_=n.data("coords").grid,_.col>=i&&s>=_.col&&_.row>=e&&r>=_.row&&(h=h.add(n)));return h},i.get_bottom_most_occupied_cell=function(){var t=0,i=0;return this.for_each_cell(function(e,s,r){e&&r>t&&(t=r,i=s)}),{col:i,row:t}},i.get_right_most_occupied_cell=function(){var t=0,i=0;return this.for_each_cell(function(e,s,r){return e?(t=r,i=s,!1):undefined}),{col:i,row:t}},i.for_each_cell=function(t,i){i||(i=this.gridmap);var e=i.length,s=i[1].length;t:for(var r=e-1;r>=1;r--)for(var o=s-1;o>=1;o--){var a=i[r]&&i[r][o];if(t){if(t.call(this,a,r,o)===!1)break t}else;}},i.next_position_in_range=function(t,i,e){t||(t=1),i||(i=1);for(var s,r=this.gridmap,o=r.length,a=[],n=1;o>n;n++){s=e||r[n].length;for(var _=1;s>=_;_++){var h=this.can_move_to({size_x:t,size_y:i},n,_,e);h&&a.push({col:n,row:_,size_y:i,size_x:t})}}return a.length>=1?this.sort_by_col_asc(a)[0]:!1},i.closest_to_right=function(t,i){if(!this.gridmap[t])return!1;for(var e=this.gridmap.length-1,s=t;e>=s;s++)if(this.gridmap[s][i])return{col:s,row:i};return!1},i.closest_to_left=function(t,i){if(this.gridmap.length-1,!this.gridmap[t])return!1;for(var e=t;e>=1;e--)if(this.gridmap[e][i])return{col:e,row:i};return!1}}(jQuery,window,document); \ No newline at end of file diff --git a/api/js/jquery/jquery-ui.js b/api/js/jquery/jquery-ui.js deleted file mode 100644 index ce8731b07a..0000000000 --- a/api/js/jquery/jquery-ui.js +++ /dev/null @@ -1,16582 +0,0 @@ -/*! jQuery UI - v1.11.2 - 2014-10-16 -* http://jqueryui.com -* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js -* Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */ - -(function( factory ) { - if ( typeof define === "function" && define.amd ) { - - // AMD. Register as an anonymous module. - define([ "jquery" ], factory ); - } else { - - // Browser globals - factory( jQuery ); - } -}(function( $ ) { -/*! - * jQuery UI Core 1.11.2 - * http://jqueryui.com - * - * Copyright 2014 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/category/ui-core/ - */ - - -// $.ui might exist from components with no dependencies, e.g., $.ui.position -$.ui = $.ui || {}; - -$.extend( $.ui, { - version: "1.11.2", - - keyCode: { - BACKSPACE: 8, - COMMA: 188, - DELETE: 46, - DOWN: 40, - END: 35, - ENTER: 13, - ESCAPE: 27, - HOME: 36, - LEFT: 37, - PAGE_DOWN: 34, - PAGE_UP: 33, - PERIOD: 190, - RIGHT: 39, - SPACE: 32, - TAB: 9, - UP: 38 - } -}); - -// plugins -$.fn.extend({ - scrollParent: function( includeHidden ) { - var position = this.css( "position" ), - excludeStaticParent = position === "absolute", - overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/, - scrollParent = this.parents().filter( function() { - var parent = $( this ); - if ( excludeStaticParent && parent.css( "position" ) === "static" ) { - return false; - } - return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) + parent.css( "overflow-x" ) ); - }).eq( 0 ); - - return position === "fixed" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent; - }, - - uniqueId: (function() { - var uuid = 0; - - return function() { - return this.each(function() { - if ( !this.id ) { - this.id = "ui-id-" + ( ++uuid ); - } - }); - }; - })(), - - removeUniqueId: function() { - return this.each(function() { - if ( /^ui-id-\d+$/.test( this.id ) ) { - $( this ).removeAttr( "id" ); - } - }); - } -}); - -// selectors -function focusable( element, isTabIndexNotNaN ) { - var map, mapName, img, - nodeName = element.nodeName.toLowerCase(); - if ( "area" === nodeName ) { - map = element.parentNode; - mapName = map.name; - if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) { - return false; - } - img = $( "img[usemap='#" + mapName + "']" )[ 0 ]; - return !!img && visible( img ); - } - return ( /input|select|textarea|button|object/.test( nodeName ) ? - !element.disabled : - "a" === nodeName ? - element.href || isTabIndexNotNaN : - isTabIndexNotNaN) && - // the element and all of its ancestors must be visible - visible( element ); -} - -function visible( element ) { - return $.expr.filters.visible( element ) && - !$( element ).parents().addBack().filter(function() { - return $.css( this, "visibility" ) === "hidden"; - }).length; -} - -$.extend( $.expr[ ":" ], { - data: $.expr.createPseudo ? - $.expr.createPseudo(function( dataName ) { - return function( elem ) { - return !!$.data( elem, dataName ); - }; - }) : - // support: jQuery <1.8 - function( elem, i, match ) { - return !!$.data( elem, match[ 3 ] ); - }, - - focusable: function( element ) { - return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) ); - }, - - tabbable: function( element ) { - var tabIndex = $.attr( element, "tabindex" ), - isTabIndexNaN = isNaN( tabIndex ); - return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN ); - } -}); - -// support: jQuery <1.8 -if ( !$( "" ).outerWidth( 1 ).jquery ) { - $.each( [ "Width", "Height" ], function( i, name ) { - var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ], - type = name.toLowerCase(), - orig = { - innerWidth: $.fn.innerWidth, - innerHeight: $.fn.innerHeight, - outerWidth: $.fn.outerWidth, - outerHeight: $.fn.outerHeight - }; - - function reduce( elem, size, border, margin ) { - $.each( side, function() { - size -= parseFloat( $.css( elem, "padding" + this ) ) || 0; - if ( border ) { - size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0; - } - if ( margin ) { - size -= parseFloat( $.css( elem, "margin" + this ) ) || 0; - } - }); - return size; - } - - $.fn[ "inner" + name ] = function( size ) { - if ( size === undefined ) { - return orig[ "inner" + name ].call( this ); - } - - return this.each(function() { - $( this ).css( type, reduce( this, size ) + "px" ); - }); - }; - - $.fn[ "outer" + name] = function( size, margin ) { - if ( typeof size !== "number" ) { - return orig[ "outer" + name ].call( this, size ); - } - - return this.each(function() { - $( this).css( type, reduce( this, size, true, margin ) + "px" ); - }); - }; - }); -} - -// support: jQuery <1.8 -if ( !$.fn.addBack ) { - $.fn.addBack = function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter( selector ) - ); - }; -} - -// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413) -if ( $( "" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) { - $.fn.removeData = (function( removeData ) { - return function( key ) { - if ( arguments.length ) { - return removeData.call( this, $.camelCase( key ) ); - } else { - return removeData.call( this ); - } - }; - })( $.fn.removeData ); -} - -// deprecated -$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() ); - -$.fn.extend({ - focus: (function( orig ) { - return function( delay, fn ) { - return typeof delay === "number" ? - this.each(function() { - var elem = this; - setTimeout(function() { - $( elem ).focus(); - if ( fn ) { - fn.call( elem ); - } - }, delay ); - }) : - orig.apply( this, arguments ); - }; - })( $.fn.focus ), - - disableSelection: (function() { - var eventType = "onselectstart" in document.createElement( "div" ) ? - "selectstart" : - "mousedown"; - - return function() { - return this.bind( eventType + ".ui-disableSelection", function( event ) { - event.preventDefault(); - }); - }; - })(), - - enableSelection: function() { - return this.unbind( ".ui-disableSelection" ); - }, - - zIndex: function( zIndex ) { - if ( zIndex !== undefined ) { - return this.css( "zIndex", zIndex ); - } - - if ( this.length ) { - var elem = $( this[ 0 ] ), position, value; - while ( elem.length && elem[ 0 ] !== document ) { - // Ignore z-index if position is set to a value where z-index is ignored by the browser - // This makes behavior of this function consistent across browsers - // WebKit always returns auto if the element is positioned - position = elem.css( "position" ); - if ( position === "absolute" || position === "relative" || position === "fixed" ) { - // IE returns 0 when zIndex is not specified - // other browsers return a string - // we ignore the case of nested elements with an explicit value of 0 - //
    - value = parseInt( elem.css( "zIndex" ), 10 ); - if ( !isNaN( value ) && value !== 0 ) { - return value; - } - } - elem = elem.parent(); - } - } - - return 0; - } -}); - -// $.ui.plugin is deprecated. Use $.widget() extensions instead. -$.ui.plugin = { - add: function( module, option, set ) { - var i, - proto = $.ui[ module ].prototype; - for ( i in set ) { - proto.plugins[ i ] = proto.plugins[ i ] || []; - proto.plugins[ i ].push( [ option, set[ i ] ] ); - } - }, - call: function( instance, name, args, allowDisconnected ) { - var i, - set = instance.plugins[ name ]; - - if ( !set ) { - return; - } - - if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) { - return; - } - - for ( i = 0; i < set.length; i++ ) { - if ( instance.options[ set[ i ][ 0 ] ] ) { - set[ i ][ 1 ].apply( instance.element, args ); - } - } - } -}; - - -/*! - * jQuery UI Widget 1.11.2 - * http://jqueryui.com - * - * Copyright 2014 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/jQuery.widget/ - */ - - -var widget_uuid = 0, - widget_slice = Array.prototype.slice; - -$.cleanData = (function( orig ) { - return function( elems ) { - var events, elem, i; - for ( i = 0; (elem = elems[i]) != null; i++ ) { - try { - - // Only trigger remove when necessary to save time - events = $._data( elem, "events" ); - if ( events && events.remove ) { - $( elem ).triggerHandler( "remove" ); - } - - // http://bugs.jquery.com/ticket/8235 - } catch ( e ) {} - } - orig( elems ); - }; -})( $.cleanData ); - -$.widget = function( name, base, prototype ) { - var fullName, existingConstructor, constructor, basePrototype, - // proxiedPrototype allows the provided prototype to remain unmodified - // so that it can be used as a mixin for multiple widgets (#8876) - proxiedPrototype = {}, - namespace = name.split( "." )[ 0 ]; - - name = name.split( "." )[ 1 ]; - fullName = namespace + "-" + name; - - if ( !prototype ) { - prototype = base; - base = $.Widget; - } - - // create selector for plugin - $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) { - return !!$.data( elem, fullName ); - }; - - $[ namespace ] = $[ namespace ] || {}; - existingConstructor = $[ namespace ][ name ]; - constructor = $[ namespace ][ name ] = function( options, element ) { - // allow instantiation without "new" keyword - if ( !this._createWidget ) { - return new constructor( options, element ); - } - - // allow instantiation without initializing for simple inheritance - // must use "new" keyword (the code above always passes args) - if ( arguments.length ) { - this._createWidget( options, element ); - } - }; - // extend with the existing constructor to carry over any static properties - $.extend( constructor, existingConstructor, { - version: prototype.version, - // copy the object used to create the prototype in case we need to - // redefine the widget later - _proto: $.extend( {}, prototype ), - // track widgets that inherit from this widget in case this widget is - // redefined after a widget inherits from it - _childConstructors: [] - }); - - basePrototype = new base(); - // we need to make the options hash a property directly on the new instance - // otherwise we'll modify the options hash on the prototype that we're - // inheriting from - basePrototype.options = $.widget.extend( {}, basePrototype.options ); - $.each( prototype, function( prop, value ) { - if ( !$.isFunction( value ) ) { - proxiedPrototype[ prop ] = value; - return; - } - proxiedPrototype[ prop ] = (function() { - var _super = function() { - return base.prototype[ prop ].apply( this, arguments ); - }, - _superApply = function( args ) { - return base.prototype[ prop ].apply( this, args ); - }; - return function() { - var __super = this._super, - __superApply = this._superApply, - returnValue; - - this._super = _super; - this._superApply = _superApply; - - returnValue = value.apply( this, arguments ); - - this._super = __super; - this._superApply = __superApply; - - return returnValue; - }; - })(); - }); - constructor.prototype = $.widget.extend( basePrototype, { - // TODO: remove support for widgetEventPrefix - // always use the name + a colon as the prefix, e.g., draggable:start - // don't prefix for widgets that aren't DOM-based - widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name - }, proxiedPrototype, { - constructor: constructor, - namespace: namespace, - widgetName: name, - widgetFullName: fullName - }); - - // If this widget is being redefined then we need to find all widgets that - // are inheriting from it and redefine all of them so that they inherit from - // the new version of this widget. We're essentially trying to replace one - // level in the prototype chain. - if ( existingConstructor ) { - $.each( existingConstructor._childConstructors, function( i, child ) { - var childPrototype = child.prototype; - - // redefine the child widget using the same prototype that was - // originally used, but inherit from the new version of the base - $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto ); - }); - // remove the list of existing child constructors from the old constructor - // so the old child constructors can be garbage collected - delete existingConstructor._childConstructors; - } else { - base._childConstructors.push( constructor ); - } - - $.widget.bridge( name, constructor ); - - return constructor; -}; - -$.widget.extend = function( target ) { - var input = widget_slice.call( arguments, 1 ), - inputIndex = 0, - inputLength = input.length, - key, - value; - for ( ; inputIndex < inputLength; inputIndex++ ) { - for ( key in input[ inputIndex ] ) { - value = input[ inputIndex ][ key ]; - if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) { - // Clone objects - if ( $.isPlainObject( value ) ) { - target[ key ] = $.isPlainObject( target[ key ] ) ? - $.widget.extend( {}, target[ key ], value ) : - // Don't extend strings, arrays, etc. with objects - $.widget.extend( {}, value ); - // Copy everything else by reference - } else { - target[ key ] = value; - } - } - } - } - return target; -}; - -$.widget.bridge = function( name, object ) { - var fullName = object.prototype.widgetFullName || name; - $.fn[ name ] = function( options ) { - var isMethodCall = typeof options === "string", - args = widget_slice.call( arguments, 1 ), - returnValue = this; - - // allow multiple hashes to be passed on init - options = !isMethodCall && args.length ? - $.widget.extend.apply( null, [ options ].concat(args) ) : - options; - - if ( isMethodCall ) { - this.each(function() { - var methodValue, - instance = $.data( this, fullName ); - if ( options === "instance" ) { - returnValue = instance; - return false; - } - if ( !instance ) { - return $.error( "cannot call methods on " + name + " prior to initialization; " + - "attempted to call method '" + options + "'" ); - } - if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) { - return $.error( "no such method '" + options + "' for " + name + " widget instance" ); - } - methodValue = instance[ options ].apply( instance, args ); - if ( methodValue !== instance && methodValue !== undefined ) { - returnValue = methodValue && methodValue.jquery ? - returnValue.pushStack( methodValue.get() ) : - methodValue; - return false; - } - }); - } else { - this.each(function() { - var instance = $.data( this, fullName ); - if ( instance ) { - instance.option( options || {} ); - if ( instance._init ) { - instance._init(); - } - } else { - $.data( this, fullName, new object( options, this ) ); - } - }); - } - - return returnValue; - }; -}; - -$.Widget = function( /* options, element */ ) {}; -$.Widget._childConstructors = []; - -$.Widget.prototype = { - widgetName: "widget", - widgetEventPrefix: "", - defaultElement: "
    ", - options: { - disabled: false, - - // callbacks - create: null - }, - _createWidget: function( options, element ) { - element = $( element || this.defaultElement || this )[ 0 ]; - this.element = $( element ); - this.uuid = widget_uuid++; - this.eventNamespace = "." + this.widgetName + this.uuid; - - this.bindings = $(); - this.hoverable = $(); - this.focusable = $(); - - if ( element !== this ) { - $.data( element, this.widgetFullName, this ); - this._on( true, this.element, { - remove: function( event ) { - if ( event.target === element ) { - this.destroy(); - } - } - }); - this.document = $( element.style ? - // element within the document - element.ownerDocument : - // element is window or document - element.document || element ); - this.window = $( this.document[0].defaultView || this.document[0].parentWindow ); - } - - this.options = $.widget.extend( {}, - this.options, - this._getCreateOptions(), - options ); - - this._create(); - this._trigger( "create", null, this._getCreateEventData() ); - this._init(); - }, - _getCreateOptions: $.noop, - _getCreateEventData: $.noop, - _create: $.noop, - _init: $.noop, - - destroy: function() { - this._destroy(); - // we can probably remove the unbind calls in 2.0 - // all event bindings should go through this._on() - this.element - .unbind( this.eventNamespace ) - .removeData( this.widgetFullName ) - // support: jquery <1.6.3 - // http://bugs.jquery.com/ticket/9413 - .removeData( $.camelCase( this.widgetFullName ) ); - this.widget() - .unbind( this.eventNamespace ) - .removeAttr( "aria-disabled" ) - .removeClass( - this.widgetFullName + "-disabled " + - "ui-state-disabled" ); - - // clean up events and states - this.bindings.unbind( this.eventNamespace ); - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - }, - _destroy: $.noop, - - widget: function() { - return this.element; - }, - - option: function( key, value ) { - var options = key, - parts, - curOption, - i; - - if ( arguments.length === 0 ) { - // don't return a reference to the internal hash - return $.widget.extend( {}, this.options ); - } - - if ( typeof key === "string" ) { - // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } } - options = {}; - parts = key.split( "." ); - key = parts.shift(); - if ( parts.length ) { - curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] ); - for ( i = 0; i < parts.length - 1; i++ ) { - curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {}; - curOption = curOption[ parts[ i ] ]; - } - key = parts.pop(); - if ( arguments.length === 1 ) { - return curOption[ key ] === undefined ? null : curOption[ key ]; - } - curOption[ key ] = value; - } else { - if ( arguments.length === 1 ) { - return this.options[ key ] === undefined ? null : this.options[ key ]; - } - options[ key ] = value; - } - } - - this._setOptions( options ); - - return this; - }, - _setOptions: function( options ) { - var key; - - for ( key in options ) { - this._setOption( key, options[ key ] ); - } - - return this; - }, - _setOption: function( key, value ) { - this.options[ key ] = value; - - if ( key === "disabled" ) { - this.widget() - .toggleClass( this.widgetFullName + "-disabled", !!value ); - - // If the widget is becoming disabled, then nothing is interactive - if ( value ) { - this.hoverable.removeClass( "ui-state-hover" ); - this.focusable.removeClass( "ui-state-focus" ); - } - } - - return this; - }, - - enable: function() { - return this._setOptions({ disabled: false }); - }, - disable: function() { - return this._setOptions({ disabled: true }); - }, - - _on: function( suppressDisabledCheck, element, handlers ) { - var delegateElement, - instance = this; - - // no suppressDisabledCheck flag, shuffle arguments - if ( typeof suppressDisabledCheck !== "boolean" ) { - handlers = element; - element = suppressDisabledCheck; - suppressDisabledCheck = false; - } - - // no element argument, shuffle and use this.element - if ( !handlers ) { - handlers = element; - element = this.element; - delegateElement = this.widget(); - } else { - element = delegateElement = $( element ); - this.bindings = this.bindings.add( element ); - } - - $.each( handlers, function( event, handler ) { - function handlerProxy() { - // allow widgets to customize the disabled handling - // - disabled as an array instead of boolean - // - disabled class as method for disabling individual parts - if ( !suppressDisabledCheck && - ( instance.options.disabled === true || - $( this ).hasClass( "ui-state-disabled" ) ) ) { - return; - } - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - - // copy the guid so direct unbinding works - if ( typeof handler !== "string" ) { - handlerProxy.guid = handler.guid = - handler.guid || handlerProxy.guid || $.guid++; - } - - var match = event.match( /^([\w:-]*)\s*(.*)$/ ), - eventName = match[1] + instance.eventNamespace, - selector = match[2]; - if ( selector ) { - delegateElement.delegate( selector, eventName, handlerProxy ); - } else { - element.bind( eventName, handlerProxy ); - } - }); - }, - - _off: function( element, eventName ) { - eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + - this.eventNamespace; - element.unbind( eventName ).undelegate( eventName ); - - // Clear the stack to avoid memory leaks (#10056) - this.bindings = $( this.bindings.not( element ).get() ); - this.focusable = $( this.focusable.not( element ).get() ); - this.hoverable = $( this.hoverable.not( element ).get() ); - }, - - _delay: function( handler, delay ) { - function handlerProxy() { - return ( typeof handler === "string" ? instance[ handler ] : handler ) - .apply( instance, arguments ); - } - var instance = this; - return setTimeout( handlerProxy, delay || 0 ); - }, - - _hoverable: function( element ) { - this.hoverable = this.hoverable.add( element ); - this._on( element, { - mouseenter: function( event ) { - $( event.currentTarget ).addClass( "ui-state-hover" ); - }, - mouseleave: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-hover" ); - } - }); - }, - - _focusable: function( element ) { - this.focusable = this.focusable.add( element ); - this._on( element, { - focusin: function( event ) { - $( event.currentTarget ).addClass( "ui-state-focus" ); - }, - focusout: function( event ) { - $( event.currentTarget ).removeClass( "ui-state-focus" ); - } - }); - }, - - _trigger: function( type, event, data ) { - var prop, orig, - callback = this.options[ type ]; - - data = data || {}; - event = $.Event( event ); - event.type = ( type === this.widgetEventPrefix ? - type : - this.widgetEventPrefix + type ).toLowerCase(); - // the original event may come from any element - // so we need to reset the target on the new event - event.target = this.element[ 0 ]; - - // copy original event properties over to the new event - orig = event.originalEvent; - if ( orig ) { - for ( prop in orig ) { - if ( !( prop in event ) ) { - event[ prop ] = orig[ prop ]; - } - } - } - - this.element.trigger( event, data ); - return !( $.isFunction( callback ) && - callback.apply( this.element[0], [ event ].concat( data ) ) === false || - event.isDefaultPrevented() ); - } -}; - -$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) { - $.Widget.prototype[ "_" + method ] = function( element, options, callback ) { - if ( typeof options === "string" ) { - options = { effect: options }; - } - var hasOptions, - effectName = !options ? - method : - options === true || typeof options === "number" ? - defaultEffect : - options.effect || defaultEffect; - options = options || {}; - if ( typeof options === "number" ) { - options = { duration: options }; - } - hasOptions = !$.isEmptyObject( options ); - options.complete = callback; - if ( options.delay ) { - element.delay( options.delay ); - } - if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) { - element[ method ]( options ); - } else if ( effectName !== method && element[ effectName ] ) { - element[ effectName ]( options.duration, options.easing, callback ); - } else { - element.queue(function( next ) { - $( this )[ method ](); - if ( callback ) { - callback.call( element[ 0 ] ); - } - next(); - }); - } - }; -}); - -var widget = $.widget; - - -/*! - * jQuery UI Mouse 1.11.2 - * http://jqueryui.com - * - * Copyright 2014 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/mouse/ - */ - - -var mouseHandled = false; -$( document ).mouseup( function() { - mouseHandled = false; -}); - -var mouse = $.widget("ui.mouse", { - version: "1.11.2", - options: { - cancel: "input,textarea,button,select,option", - distance: 1, - delay: 0 - }, - _mouseInit: function() { - var that = this; - - this.element - .bind("mousedown." + this.widgetName, function(event) { - return that._mouseDown(event); - }) - .bind("click." + this.widgetName, function(event) { - if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) { - $.removeData(event.target, that.widgetName + ".preventClickEvent"); - event.stopImmediatePropagation(); - return false; - } - }); - - this.started = false; - }, - - // TODO: make sure destroying one instance of mouse doesn't mess with - // other instances of mouse - _mouseDestroy: function() { - this.element.unbind("." + this.widgetName); - if ( this._mouseMoveDelegate ) { - this.document - .unbind("mousemove." + this.widgetName, this._mouseMoveDelegate) - .unbind("mouseup." + this.widgetName, this._mouseUpDelegate); - } - }, - - _mouseDown: function(event) { - // don't let more than one widget handle mouseStart - if ( mouseHandled ) { - return; - } - - this._mouseMoved = false; - - // we may have missed mouseup (out of window) - (this._mouseStarted && this._mouseUp(event)); - - this._mouseDownEvent = event; - - var that = this, - btnIsLeft = (event.which === 1), - // event.target.nodeName works around a bug in IE 8 with - // disabled inputs (#7620) - elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false); - if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) { - return true; - } - - this.mouseDelayMet = !this.options.delay; - if (!this.mouseDelayMet) { - this._mouseDelayTimer = setTimeout(function() { - that.mouseDelayMet = true; - }, this.options.delay); - } - - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { - this._mouseStarted = (this._mouseStart(event) !== false); - if (!this._mouseStarted) { - event.preventDefault(); - return true; - } - } - - // Click event may never have fired (Gecko & Opera) - if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) { - $.removeData(event.target, this.widgetName + ".preventClickEvent"); - } - - // these delegates are required to keep context - this._mouseMoveDelegate = function(event) { - return that._mouseMove(event); - }; - this._mouseUpDelegate = function(event) { - return that._mouseUp(event); - }; - - this.document - .bind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .bind( "mouseup." + this.widgetName, this._mouseUpDelegate ); - - event.preventDefault(); - - mouseHandled = true; - return true; - }, - - _mouseMove: function(event) { - // Only check for mouseups outside the document if you've moved inside the document - // at least once. This prevents the firing of mouseup in the case of IE<9, which will - // fire a mousemove event if content is placed under the cursor. See #7778 - // Support: IE <9 - if ( this._mouseMoved ) { - // IE mouseup check - mouseup happened when mouse was out of window - if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) { - return this._mouseUp(event); - - // Iframe mouseup check - mouseup occurred in another document - } else if ( !event.which ) { - return this._mouseUp( event ); - } - } - - if ( event.which || event.button ) { - this._mouseMoved = true; - } - - if (this._mouseStarted) { - this._mouseDrag(event); - return event.preventDefault(); - } - - if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) { - this._mouseStarted = - (this._mouseStart(this._mouseDownEvent, event) !== false); - (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event)); - } - - return !this._mouseStarted; - }, - - _mouseUp: function(event) { - this.document - .unbind( "mousemove." + this.widgetName, this._mouseMoveDelegate ) - .unbind( "mouseup." + this.widgetName, this._mouseUpDelegate ); - - if (this._mouseStarted) { - this._mouseStarted = false; - - if (event.target === this._mouseDownEvent.target) { - $.data(event.target, this.widgetName + ".preventClickEvent", true); - } - - this._mouseStop(event); - } - - mouseHandled = false; - return false; - }, - - _mouseDistanceMet: function(event) { - return (Math.max( - Math.abs(this._mouseDownEvent.pageX - event.pageX), - Math.abs(this._mouseDownEvent.pageY - event.pageY) - ) >= this.options.distance - ); - }, - - _mouseDelayMet: function(/* event */) { - return this.mouseDelayMet; - }, - - // These are placeholder methods, to be overriden by extending plugin - _mouseStart: function(/* event */) {}, - _mouseDrag: function(/* event */) {}, - _mouseStop: function(/* event */) {}, - _mouseCapture: function(/* event */) { return true; } -}); - - -/*! - * jQuery UI Position 1.11.2 - * http://jqueryui.com - * - * Copyright 2014 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/position/ - */ - -(function() { - -$.ui = $.ui || {}; - -var cachedScrollbarWidth, supportsOffsetFractions, - max = Math.max, - abs = Math.abs, - round = Math.round, - rhorizontal = /left|center|right/, - rvertical = /top|center|bottom/, - roffset = /[\+\-]\d+(\.[\d]+)?%?/, - rposition = /^\w+/, - rpercent = /%$/, - _position = $.fn.position; - -function getOffsets( offsets, width, height ) { - return [ - parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ), - parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 ) - ]; -} - -function parseCss( element, property ) { - return parseInt( $.css( element, property ), 10 ) || 0; -} - -function getDimensions( elem ) { - var raw = elem[0]; - if ( raw.nodeType === 9 ) { - return { - width: elem.width(), - height: elem.height(), - offset: { top: 0, left: 0 } - }; - } - if ( $.isWindow( raw ) ) { - return { - width: elem.width(), - height: elem.height(), - offset: { top: elem.scrollTop(), left: elem.scrollLeft() } - }; - } - if ( raw.preventDefault ) { - return { - width: 0, - height: 0, - offset: { top: raw.pageY, left: raw.pageX } - }; - } - return { - width: elem.outerWidth(), - height: elem.outerHeight(), - offset: elem.offset() - }; -} - -$.position = { - scrollbarWidth: function() { - if ( cachedScrollbarWidth !== undefined ) { - return cachedScrollbarWidth; - } - var w1, w2, - div = $( "
    " ), - innerDiv = div.children()[0]; - - $( "body" ).append( div ); - w1 = innerDiv.offsetWidth; - div.css( "overflow", "scroll" ); - - w2 = innerDiv.offsetWidth; - - if ( w1 === w2 ) { - w2 = div[0].clientWidth; - } - - div.remove(); - - return (cachedScrollbarWidth = w1 - w2); - }, - getScrollInfo: function( within ) { - var overflowX = within.isWindow || within.isDocument ? "" : - within.element.css( "overflow-x" ), - overflowY = within.isWindow || within.isDocument ? "" : - within.element.css( "overflow-y" ), - hasOverflowX = overflowX === "scroll" || - ( overflowX === "auto" && within.width < within.element[0].scrollWidth ), - hasOverflowY = overflowY === "scroll" || - ( overflowY === "auto" && within.height < within.element[0].scrollHeight ); - return { - width: hasOverflowY ? $.position.scrollbarWidth() : 0, - height: hasOverflowX ? $.position.scrollbarWidth() : 0 - }; - }, - getWithinInfo: function( element ) { - var withinElement = $( element || window ), - isWindow = $.isWindow( withinElement[0] ), - isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9; - return { - element: withinElement, - isWindow: isWindow, - isDocument: isDocument, - offset: withinElement.offset() || { left: 0, top: 0 }, - scrollLeft: withinElement.scrollLeft(), - scrollTop: withinElement.scrollTop(), - - // support: jQuery 1.6.x - // jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows - width: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(), - height: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight() - }; - } -}; - -$.fn.position = function( options ) { - if ( !options || !options.of ) { - return _position.apply( this, arguments ); - } - - // make a copy, we don't want to modify arguments - options = $.extend( {}, options ); - - var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions, - target = $( options.of ), - within = $.position.getWithinInfo( options.within ), - scrollInfo = $.position.getScrollInfo( within ), - collision = ( options.collision || "flip" ).split( " " ), - offsets = {}; - - dimensions = getDimensions( target ); - if ( target[0].preventDefault ) { - // force left top to allow flipping - options.at = "left top"; - } - targetWidth = dimensions.width; - targetHeight = dimensions.height; - targetOffset = dimensions.offset; - // clone to reuse original targetOffset later - basePosition = $.extend( {}, targetOffset ); - - // force my and at to have valid horizontal and vertical positions - // if a value is missing or invalid, it will be converted to center - $.each( [ "my", "at" ], function() { - var pos = ( options[ this ] || "" ).split( " " ), - horizontalOffset, - verticalOffset; - - if ( pos.length === 1) { - pos = rhorizontal.test( pos[ 0 ] ) ? - pos.concat( [ "center" ] ) : - rvertical.test( pos[ 0 ] ) ? - [ "center" ].concat( pos ) : - [ "center", "center" ]; - } - pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center"; - pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center"; - - // calculate offsets - horizontalOffset = roffset.exec( pos[ 0 ] ); - verticalOffset = roffset.exec( pos[ 1 ] ); - offsets[ this ] = [ - horizontalOffset ? horizontalOffset[ 0 ] : 0, - verticalOffset ? verticalOffset[ 0 ] : 0 - ]; - - // reduce to just the positions without the offsets - options[ this ] = [ - rposition.exec( pos[ 0 ] )[ 0 ], - rposition.exec( pos[ 1 ] )[ 0 ] - ]; - }); - - // normalize collision option - if ( collision.length === 1 ) { - collision[ 1 ] = collision[ 0 ]; - } - - if ( options.at[ 0 ] === "right" ) { - basePosition.left += targetWidth; - } else if ( options.at[ 0 ] === "center" ) { - basePosition.left += targetWidth / 2; - } - - if ( options.at[ 1 ] === "bottom" ) { - basePosition.top += targetHeight; - } else if ( options.at[ 1 ] === "center" ) { - basePosition.top += targetHeight / 2; - } - - atOffset = getOffsets( offsets.at, targetWidth, targetHeight ); - basePosition.left += atOffset[ 0 ]; - basePosition.top += atOffset[ 1 ]; - - return this.each(function() { - var collisionPosition, using, - elem = $( this ), - elemWidth = elem.outerWidth(), - elemHeight = elem.outerHeight(), - marginLeft = parseCss( this, "marginLeft" ), - marginTop = parseCss( this, "marginTop" ), - collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width, - collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height, - position = $.extend( {}, basePosition ), - myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() ); - - if ( options.my[ 0 ] === "right" ) { - position.left -= elemWidth; - } else if ( options.my[ 0 ] === "center" ) { - position.left -= elemWidth / 2; - } - - if ( options.my[ 1 ] === "bottom" ) { - position.top -= elemHeight; - } else if ( options.my[ 1 ] === "center" ) { - position.top -= elemHeight / 2; - } - - position.left += myOffset[ 0 ]; - position.top += myOffset[ 1 ]; - - // if the browser doesn't support fractions, then round for consistent results - if ( !supportsOffsetFractions ) { - position.left = round( position.left ); - position.top = round( position.top ); - } - - collisionPosition = { - marginLeft: marginLeft, - marginTop: marginTop - }; - - $.each( [ "left", "top" ], function( i, dir ) { - if ( $.ui.position[ collision[ i ] ] ) { - $.ui.position[ collision[ i ] ][ dir ]( position, { - targetWidth: targetWidth, - targetHeight: targetHeight, - elemWidth: elemWidth, - elemHeight: elemHeight, - collisionPosition: collisionPosition, - collisionWidth: collisionWidth, - collisionHeight: collisionHeight, - offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ], - my: options.my, - at: options.at, - within: within, - elem: elem - }); - } - }); - - if ( options.using ) { - // adds feedback as second argument to using callback, if present - using = function( props ) { - var left = targetOffset.left - position.left, - right = left + targetWidth - elemWidth, - top = targetOffset.top - position.top, - bottom = top + targetHeight - elemHeight, - feedback = { - target: { - element: target, - left: targetOffset.left, - top: targetOffset.top, - width: targetWidth, - height: targetHeight - }, - element: { - element: elem, - left: position.left, - top: position.top, - width: elemWidth, - height: elemHeight - }, - horizontal: right < 0 ? "left" : left > 0 ? "right" : "center", - vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle" - }; - if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) { - feedback.horizontal = "center"; - } - if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) { - feedback.vertical = "middle"; - } - if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) { - feedback.important = "horizontal"; - } else { - feedback.important = "vertical"; - } - options.using.call( this, props, feedback ); - }; - } - - elem.offset( $.extend( position, { using: using } ) ); - }); -}; - -$.ui.position = { - fit: { - left: function( position, data ) { - var within = data.within, - withinOffset = within.isWindow ? within.scrollLeft : within.offset.left, - outerWidth = within.width, - collisionPosLeft = position.left - data.collisionPosition.marginLeft, - overLeft = withinOffset - collisionPosLeft, - overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset, - newOverRight; - - // element is wider than within - if ( data.collisionWidth > outerWidth ) { - // element is initially over the left side of within - if ( overLeft > 0 && overRight <= 0 ) { - newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset; - position.left += overLeft - newOverRight; - // element is initially over right side of within - } else if ( overRight > 0 && overLeft <= 0 ) { - position.left = withinOffset; - // element is initially over both left and right sides of within - } else { - if ( overLeft > overRight ) { - position.left = withinOffset + outerWidth - data.collisionWidth; - } else { - position.left = withinOffset; - } - } - // too far left -> align with left edge - } else if ( overLeft > 0 ) { - position.left += overLeft; - // too far right -> align with right edge - } else if ( overRight > 0 ) { - position.left -= overRight; - // adjust based on position and margin - } else { - position.left = max( position.left - collisionPosLeft, position.left ); - } - }, - top: function( position, data ) { - var within = data.within, - withinOffset = within.isWindow ? within.scrollTop : within.offset.top, - outerHeight = data.within.height, - collisionPosTop = position.top - data.collisionPosition.marginTop, - overTop = withinOffset - collisionPosTop, - overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset, - newOverBottom; - - // element is taller than within - if ( data.collisionHeight > outerHeight ) { - // element is initially over the top of within - if ( overTop > 0 && overBottom <= 0 ) { - newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset; - position.top += overTop - newOverBottom; - // element is initially over bottom of within - } else if ( overBottom > 0 && overTop <= 0 ) { - position.top = withinOffset; - // element is initially over both top and bottom of within - } else { - if ( overTop > overBottom ) { - position.top = withinOffset + outerHeight - data.collisionHeight; - } else { - position.top = withinOffset; - } - } - // too far up -> align with top - } else if ( overTop > 0 ) { - position.top += overTop; - // too far down -> align with bottom edge - } else if ( overBottom > 0 ) { - position.top -= overBottom; - // adjust based on position and margin - } else { - position.top = max( position.top - collisionPosTop, position.top ); - } - } - }, - flip: { - left: function( position, data ) { - var within = data.within, - withinOffset = within.offset.left + within.scrollLeft, - outerWidth = within.width, - offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left, - collisionPosLeft = position.left - data.collisionPosition.marginLeft, - overLeft = collisionPosLeft - offsetLeft, - overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft, - myOffset = data.my[ 0 ] === "left" ? - -data.elemWidth : - data.my[ 0 ] === "right" ? - data.elemWidth : - 0, - atOffset = data.at[ 0 ] === "left" ? - data.targetWidth : - data.at[ 0 ] === "right" ? - -data.targetWidth : - 0, - offset = -2 * data.offset[ 0 ], - newOverRight, - newOverLeft; - - if ( overLeft < 0 ) { - newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset; - if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) { - position.left += myOffset + atOffset + offset; - } - } else if ( overRight > 0 ) { - newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft; - if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) { - position.left += myOffset + atOffset + offset; - } - } - }, - top: function( position, data ) { - var within = data.within, - withinOffset = within.offset.top + within.scrollTop, - outerHeight = within.height, - offsetTop = within.isWindow ? within.scrollTop : within.offset.top, - collisionPosTop = position.top - data.collisionPosition.marginTop, - overTop = collisionPosTop - offsetTop, - overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop, - top = data.my[ 1 ] === "top", - myOffset = top ? - -data.elemHeight : - data.my[ 1 ] === "bottom" ? - data.elemHeight : - 0, - atOffset = data.at[ 1 ] === "top" ? - data.targetHeight : - data.at[ 1 ] === "bottom" ? - -data.targetHeight : - 0, - offset = -2 * data.offset[ 1 ], - newOverTop, - newOverBottom; - if ( overTop < 0 ) { - newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset; - if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) { - position.top += myOffset + atOffset + offset; - } - } else if ( overBottom > 0 ) { - newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop; - if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) { - position.top += myOffset + atOffset + offset; - } - } - } - }, - flipfit: { - left: function() { - $.ui.position.flip.left.apply( this, arguments ); - $.ui.position.fit.left.apply( this, arguments ); - }, - top: function() { - $.ui.position.flip.top.apply( this, arguments ); - $.ui.position.fit.top.apply( this, arguments ); - } - } -}; - -// fraction support test -(function() { - var testElement, testElementParent, testElementStyle, offsetLeft, i, - body = document.getElementsByTagName( "body" )[ 0 ], - div = document.createElement( "div" ); - - //Create a "fake body" for testing based on method used in jQuery.support - testElement = document.createElement( body ? "div" : "body" ); - testElementStyle = { - visibility: "hidden", - width: 0, - height: 0, - border: 0, - margin: 0, - background: "none" - }; - if ( body ) { - $.extend( testElementStyle, { - position: "absolute", - left: "-1000px", - top: "-1000px" - }); - } - for ( i in testElementStyle ) { - testElement.style[ i ] = testElementStyle[ i ]; - } - testElement.appendChild( div ); - testElementParent = body || document.documentElement; - testElementParent.insertBefore( testElement, testElementParent.firstChild ); - - div.style.cssText = "position: absolute; left: 10.7432222px;"; - - offsetLeft = $( div ).offset().left; - supportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11; - - testElement.innerHTML = ""; - testElementParent.removeChild( testElement ); -})(); - -})(); - -var position = $.ui.position; - - -/*! - * jQuery UI Accordion 1.11.2 - * http://jqueryui.com - * - * Copyright 2014 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/accordion/ - */ - - -var accordion = $.widget( "ui.accordion", { - version: "1.11.2", - options: { - active: 0, - animate: {}, - collapsible: false, - event: "click", - header: "> li > :first-child,> :not(li):even", - heightStyle: "auto", - icons: { - activeHeader: "ui-icon-triangle-1-s", - header: "ui-icon-triangle-1-e" - }, - - // callbacks - activate: null, - beforeActivate: null - }, - - hideProps: { - borderTopWidth: "hide", - borderBottomWidth: "hide", - paddingTop: "hide", - paddingBottom: "hide", - height: "hide" - }, - - showProps: { - borderTopWidth: "show", - borderBottomWidth: "show", - paddingTop: "show", - paddingBottom: "show", - height: "show" - }, - - _create: function() { - var options = this.options; - this.prevShow = this.prevHide = $(); - this.element.addClass( "ui-accordion ui-widget ui-helper-reset" ) - // ARIA - .attr( "role", "tablist" ); - - // don't allow collapsible: false and active: false / null - if ( !options.collapsible && (options.active === false || options.active == null) ) { - options.active = 0; - } - - this._processPanels(); - // handle negative values - if ( options.active < 0 ) { - options.active += this.headers.length; - } - this._refresh(); - }, - - _getCreateEventData: function() { - return { - header: this.active, - panel: !this.active.length ? $() : this.active.next() - }; - }, - - _createIcons: function() { - var icons = this.options.icons; - if ( icons ) { - $( "" ) - .addClass( "ui-accordion-header-icon ui-icon " + icons.header ) - .prependTo( this.headers ); - this.active.children( ".ui-accordion-header-icon" ) - .removeClass( icons.header ) - .addClass( icons.activeHeader ); - this.headers.addClass( "ui-accordion-icons" ); - } - }, - - _destroyIcons: function() { - this.headers - .removeClass( "ui-accordion-icons" ) - .children( ".ui-accordion-header-icon" ) - .remove(); - }, - - _destroy: function() { - var contents; - - // clean up main element - this.element - .removeClass( "ui-accordion ui-widget ui-helper-reset" ) - .removeAttr( "role" ); - - // clean up headers - this.headers - .removeClass( "ui-accordion-header ui-accordion-header-active ui-state-default " + - "ui-corner-all ui-state-active ui-state-disabled ui-corner-top" ) - .removeAttr( "role" ) - .removeAttr( "aria-expanded" ) - .removeAttr( "aria-selected" ) - .removeAttr( "aria-controls" ) - .removeAttr( "tabIndex" ) - .removeUniqueId(); - - this._destroyIcons(); - - // clean up content panels - contents = this.headers.next() - .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom " + - "ui-accordion-content ui-accordion-content-active ui-state-disabled" ) - .css( "display", "" ) - .removeAttr( "role" ) - .removeAttr( "aria-hidden" ) - .removeAttr( "aria-labelledby" ) - .removeUniqueId(); - - if ( this.options.heightStyle !== "content" ) { - contents.css( "height", "" ); - } - }, - - _setOption: function( key, value ) { - if ( key === "active" ) { - // _activate() will handle invalid values and update this.options - this._activate( value ); - return; - } - - if ( key === "event" ) { - if ( this.options.event ) { - this._off( this.headers, this.options.event ); - } - this._setupEvents( value ); - } - - this._super( key, value ); - - // setting collapsible: false while collapsed; open first panel - if ( key === "collapsible" && !value && this.options.active === false ) { - this._activate( 0 ); - } - - if ( key === "icons" ) { - this._destroyIcons(); - if ( value ) { - this._createIcons(); - } - } - - // #5332 - opacity doesn't cascade to positioned elements in IE - // so we need to add the disabled class to the headers and panels - if ( key === "disabled" ) { - this.element - .toggleClass( "ui-state-disabled", !!value ) - .attr( "aria-disabled", value ); - this.headers.add( this.headers.next() ) - .toggleClass( "ui-state-disabled", !!value ); - } - }, - - _keydown: function( event ) { - if ( event.altKey || event.ctrlKey ) { - return; - } - - var keyCode = $.ui.keyCode, - length = this.headers.length, - currentIndex = this.headers.index( event.target ), - toFocus = false; - - switch ( event.keyCode ) { - case keyCode.RIGHT: - case keyCode.DOWN: - toFocus = this.headers[ ( currentIndex + 1 ) % length ]; - break; - case keyCode.LEFT: - case keyCode.UP: - toFocus = this.headers[ ( currentIndex - 1 + length ) % length ]; - break; - case keyCode.SPACE: - case keyCode.ENTER: - this._eventHandler( event ); - break; - case keyCode.HOME: - toFocus = this.headers[ 0 ]; - break; - case keyCode.END: - toFocus = this.headers[ length - 1 ]; - break; - } - - if ( toFocus ) { - $( event.target ).attr( "tabIndex", -1 ); - $( toFocus ).attr( "tabIndex", 0 ); - toFocus.focus(); - event.preventDefault(); - } - }, - - _panelKeyDown: function( event ) { - if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) { - $( event.currentTarget ).prev().focus(); - } - }, - - refresh: function() { - var options = this.options; - this._processPanels(); - - // was collapsed or no panel - if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) { - options.active = false; - this.active = $(); - // active false only when collapsible is true - } else if ( options.active === false ) { - this._activate( 0 ); - // was active, but active panel is gone - } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) { - // all remaining panel are disabled - if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) { - options.active = false; - this.active = $(); - // activate previous panel - } else { - this._activate( Math.max( 0, options.active - 1 ) ); - } - // was active, active panel still exists - } else { - // make sure active index is correct - options.active = this.headers.index( this.active ); - } - - this._destroyIcons(); - - this._refresh(); - }, - - _processPanels: function() { - var prevHeaders = this.headers, - prevPanels = this.panels; - - this.headers = this.element.find( this.options.header ) - .addClass( "ui-accordion-header ui-state-default ui-corner-all" ); - - this.panels = this.headers.next() - .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" ) - .filter( ":not(.ui-accordion-content-active)" ) - .hide(); - - // Avoid memory leaks (#10056) - if ( prevPanels ) { - this._off( prevHeaders.not( this.headers ) ); - this._off( prevPanels.not( this.panels ) ); - } - }, - - _refresh: function() { - var maxHeight, - options = this.options, - heightStyle = options.heightStyle, - parent = this.element.parent(); - - this.active = this._findActive( options.active ) - .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ) - .removeClass( "ui-corner-all" ); - this.active.next() - .addClass( "ui-accordion-content-active" ) - .show(); - - this.headers - .attr( "role", "tab" ) - .each(function() { - var header = $( this ), - headerId = header.uniqueId().attr( "id" ), - panel = header.next(), - panelId = panel.uniqueId().attr( "id" ); - header.attr( "aria-controls", panelId ); - panel.attr( "aria-labelledby", headerId ); - }) - .next() - .attr( "role", "tabpanel" ); - - this.headers - .not( this.active ) - .attr({ - "aria-selected": "false", - "aria-expanded": "false", - tabIndex: -1 - }) - .next() - .attr({ - "aria-hidden": "true" - }) - .hide(); - - // make sure at least one header is in the tab order - if ( !this.active.length ) { - this.headers.eq( 0 ).attr( "tabIndex", 0 ); - } else { - this.active.attr({ - "aria-selected": "true", - "aria-expanded": "true", - tabIndex: 0 - }) - .next() - .attr({ - "aria-hidden": "false" - }); - } - - this._createIcons(); - - this._setupEvents( options.event ); - - if ( heightStyle === "fill" ) { - maxHeight = parent.height(); - this.element.siblings( ":visible" ).each(function() { - var elem = $( this ), - position = elem.css( "position" ); - - if ( position === "absolute" || position === "fixed" ) { - return; - } - maxHeight -= elem.outerHeight( true ); - }); - - this.headers.each(function() { - maxHeight -= $( this ).outerHeight( true ); - }); - - this.headers.next() - .each(function() { - $( this ).height( Math.max( 0, maxHeight - - $( this ).innerHeight() + $( this ).height() ) ); - }) - .css( "overflow", "auto" ); - } else if ( heightStyle === "auto" ) { - maxHeight = 0; - this.headers.next() - .each(function() { - maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() ); - }) - .height( maxHeight ); - } - }, - - _activate: function( index ) { - var active = this._findActive( index )[ 0 ]; - - // trying to activate the already active panel - if ( active === this.active[ 0 ] ) { - return; - } - - // trying to collapse, simulate a click on the currently active header - active = active || this.active[ 0 ]; - - this._eventHandler({ - target: active, - currentTarget: active, - preventDefault: $.noop - }); - }, - - _findActive: function( selector ) { - return typeof selector === "number" ? this.headers.eq( selector ) : $(); - }, - - _setupEvents: function( event ) { - var events = { - keydown: "_keydown" - }; - if ( event ) { - $.each( event.split( " " ), function( index, eventName ) { - events[ eventName ] = "_eventHandler"; - }); - } - - this._off( this.headers.add( this.headers.next() ) ); - this._on( this.headers, events ); - this._on( this.headers.next(), { keydown: "_panelKeyDown" }); - this._hoverable( this.headers ); - this._focusable( this.headers ); - }, - - _eventHandler: function( event ) { - var options = this.options, - active = this.active, - clicked = $( event.currentTarget ), - clickedIsActive = clicked[ 0 ] === active[ 0 ], - collapsing = clickedIsActive && options.collapsible, - toShow = collapsing ? $() : clicked.next(), - toHide = active.next(), - eventData = { - oldHeader: active, - oldPanel: toHide, - newHeader: collapsing ? $() : clicked, - newPanel: toShow - }; - - event.preventDefault(); - - if ( - // click on active header, but not collapsible - ( clickedIsActive && !options.collapsible ) || - // allow canceling activation - ( this._trigger( "beforeActivate", event, eventData ) === false ) ) { - return; - } - - options.active = collapsing ? false : this.headers.index( clicked ); - - // when the call to ._toggle() comes after the class changes - // it causes a very odd bug in IE 8 (see #6720) - this.active = clickedIsActive ? $() : clicked; - this._toggle( eventData ); - - // switch classes - // corner classes on the previously active header stay after the animation - active.removeClass( "ui-accordion-header-active ui-state-active" ); - if ( options.icons ) { - active.children( ".ui-accordion-header-icon" ) - .removeClass( options.icons.activeHeader ) - .addClass( options.icons.header ); - } - - if ( !clickedIsActive ) { - clicked - .removeClass( "ui-corner-all" ) - .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" ); - if ( options.icons ) { - clicked.children( ".ui-accordion-header-icon" ) - .removeClass( options.icons.header ) - .addClass( options.icons.activeHeader ); - } - - clicked - .next() - .addClass( "ui-accordion-content-active" ); - } - }, - - _toggle: function( data ) { - var toShow = data.newPanel, - toHide = this.prevShow.length ? this.prevShow : data.oldPanel; - - // handle activating a panel during the animation for another activation - this.prevShow.add( this.prevHide ).stop( true, true ); - this.prevShow = toShow; - this.prevHide = toHide; - - if ( this.options.animate ) { - this._animate( toShow, toHide, data ); - } else { - toHide.hide(); - toShow.show(); - this._toggleComplete( data ); - } - - toHide.attr({ - "aria-hidden": "true" - }); - toHide.prev().attr( "aria-selected", "false" ); - // if we're switching panels, remove the old header from the tab order - // if we're opening from collapsed state, remove the previous header from the tab order - // if we're collapsing, then keep the collapsing header in the tab order - if ( toShow.length && toHide.length ) { - toHide.prev().attr({ - "tabIndex": -1, - "aria-expanded": "false" - }); - } else if ( toShow.length ) { - this.headers.filter(function() { - return $( this ).attr( "tabIndex" ) === 0; - }) - .attr( "tabIndex", -1 ); - } - - toShow - .attr( "aria-hidden", "false" ) - .prev() - .attr({ - "aria-selected": "true", - tabIndex: 0, - "aria-expanded": "true" - }); - }, - - _animate: function( toShow, toHide, data ) { - var total, easing, duration, - that = this, - adjust = 0, - down = toShow.length && - ( !toHide.length || ( toShow.index() < toHide.index() ) ), - animate = this.options.animate || {}, - options = down && animate.down || animate, - complete = function() { - that._toggleComplete( data ); - }; - - if ( typeof options === "number" ) { - duration = options; - } - if ( typeof options === "string" ) { - easing = options; - } - // fall back from options to animation in case of partial down settings - easing = easing || options.easing || animate.easing; - duration = duration || options.duration || animate.duration; - - if ( !toHide.length ) { - return toShow.animate( this.showProps, duration, easing, complete ); - } - if ( !toShow.length ) { - return toHide.animate( this.hideProps, duration, easing, complete ); - } - - total = toShow.show().outerHeight(); - toHide.animate( this.hideProps, { - duration: duration, - easing: easing, - step: function( now, fx ) { - fx.now = Math.round( now ); - } - }); - toShow - .hide() - .animate( this.showProps, { - duration: duration, - easing: easing, - complete: complete, - step: function( now, fx ) { - fx.now = Math.round( now ); - if ( fx.prop !== "height" ) { - adjust += fx.now; - } else if ( that.options.heightStyle !== "content" ) { - fx.now = Math.round( total - toHide.outerHeight() - adjust ); - adjust = 0; - } - } - }); - }, - - _toggleComplete: function( data ) { - var toHide = data.oldPanel; - - toHide - .removeClass( "ui-accordion-content-active" ) - .prev() - .removeClass( "ui-corner-top" ) - .addClass( "ui-corner-all" ); - - // Work around for rendering bug in IE (#5421) - if ( toHide.length ) { - toHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className; - } - this._trigger( "activate", null, data ); - } -}); - - -/*! - * jQuery UI Menu 1.11.2 - * http://jqueryui.com - * - * Copyright 2014 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/menu/ - */ - - -var menu = $.widget( "ui.menu", { - version: "1.11.2", - defaultElement: "
  • " + - ""; - thead = (showWeek ? "" : ""); - for (dow = 0; dow < 7; dow++) { // days of the week - day = (dow + firstDay) % 7; - thead += ""; - } - calender += thead + ""; - daysInMonth = this._getDaysInMonth(drawYear, drawMonth); - if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) { - inst.selectedDay = Math.min(inst.selectedDay, daysInMonth); - } - leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7; - curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate - numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043) - this.maxRows = numRows; - printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays)); - for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows - calender += ""; - tbody = (!showWeek ? "" : ""); - for (dow = 0; dow < 7; dow++) { // create date picker days - daySettings = (beforeShowDay ? - beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]); - otherMonth = (printDate.getMonth() !== drawMonth); - unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] || - (minDate && printDate < minDate) || (maxDate && printDate > maxDate); - tbody += ""; // display selectable date - printDate.setDate(printDate.getDate() + 1); - printDate = this._daylightSavingAdjust(printDate); - } - calender += tbody + ""; - } - drawMonth++; - if (drawMonth > 11) { - drawMonth = 0; - drawYear++; - } - calender += "
    " + this._get(inst, "weekHeader") + "= 5 ? " class='ui-datepicker-week-end'" : "") + ">" + - "" + dayNamesMin[day] + "
    " + - this._get(inst, "calculateWeek")(printDate) + "" + // actions - (otherMonth && !showOtherMonths ? " " : // display for other months - (unselectable ? "" + printDate.getDate() + "" : "" + printDate.getDate() + "")) + "
    " + (isMultiMonth ? "
    " + - ((numMonths[0] > 0 && col === numMonths[1]-1) ? "
    " : "") : ""); - group += calender; - } - html += group; - } - html += buttonPanel; - inst._keyEvent = false; - return html; - }, - - /* Generate the month and year header. */ - _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate, - secondary, monthNames, monthNamesShort) { - - var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear, - changeMonth = this._get(inst, "changeMonth"), - changeYear = this._get(inst, "changeYear"), - showMonthAfterYear = this._get(inst, "showMonthAfterYear"), - html = "
    ", - monthHtml = ""; - - // month selection - if (secondary || !changeMonth) { - monthHtml += "" + monthNames[drawMonth] + ""; - } else { - inMinYear = (minDate && minDate.getFullYear() === drawYear); - inMaxYear = (maxDate && maxDate.getFullYear() === drawYear); - monthHtml += ""; - } - - if (!showMonthAfterYear) { - html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : ""); - } - - // year selection - if ( !inst.yearshtml ) { - inst.yearshtml = ""; - if (secondary || !changeYear) { - html += "" + drawYear + ""; - } else { - // determine range of years to display - years = this._get(inst, "yearRange").split(":"); - thisYear = new Date().getFullYear(); - determineYear = function(value) { - var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) : - (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) : - parseInt(value, 10))); - return (isNaN(year) ? thisYear : year); - }; - year = determineYear(years[0]); - endYear = Math.max(year, determineYear(years[1] || "")); - year = (minDate ? Math.max(year, minDate.getFullYear()) : year); - endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear); - inst.yearshtml += ""; - - html += inst.yearshtml; - inst.yearshtml = null; - } - } - - html += this._get(inst, "yearSuffix"); - if (showMonthAfterYear) { - html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml; - } - html += "
    "; // Close datepicker_header - return html; - }, - - /* Adjust one of the date sub-fields. */ - _adjustInstDate: function(inst, offset, period) { - var year = inst.drawYear + (period === "Y" ? offset : 0), - month = inst.drawMonth + (period === "M" ? offset : 0), - day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0), - date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day))); - - inst.selectedDay = date.getDate(); - inst.drawMonth = inst.selectedMonth = date.getMonth(); - inst.drawYear = inst.selectedYear = date.getFullYear(); - if (period === "M" || period === "Y") { - this._notifyChange(inst); - } - }, - - /* Ensure a date is within any min/max bounds. */ - _restrictMinMax: function(inst, date) { - var minDate = this._getMinMaxDate(inst, "min"), - maxDate = this._getMinMaxDate(inst, "max"), - newDate = (minDate && date < minDate ? minDate : date); - return (maxDate && newDate > maxDate ? maxDate : newDate); - }, - - /* Notify change of month/year. */ - _notifyChange: function(inst) { - var onChange = this._get(inst, "onChangeMonthYear"); - if (onChange) { - onChange.apply((inst.input ? inst.input[0] : null), - [inst.selectedYear, inst.selectedMonth + 1, inst]); - } - }, - - /* Determine the number of months to show. */ - _getNumberOfMonths: function(inst) { - var numMonths = this._get(inst, "numberOfMonths"); - return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths)); - }, - - /* Determine the current maximum date - ensure no time components are set. */ - _getMinMaxDate: function(inst, minMax) { - return this._determineDate(inst, this._get(inst, minMax + "Date"), null); - }, - - /* Find the number of days in a given month. */ - _getDaysInMonth: function(year, month) { - return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate(); - }, - - /* Find the day of the week of the first of a month. */ - _getFirstDayOfMonth: function(year, month) { - return new Date(year, month, 1).getDay(); - }, - - /* Determines if we should allow a "next/prev" month display change. */ - _canAdjustMonth: function(inst, offset, curYear, curMonth) { - var numMonths = this._getNumberOfMonths(inst), - date = this._daylightSavingAdjust(new Date(curYear, - curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1)); - - if (offset < 0) { - date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth())); - } - return this._isInRange(inst, date); - }, - - /* Is the given date in the accepted range? */ - _isInRange: function(inst, date) { - var yearSplit, currentYear, - minDate = this._getMinMaxDate(inst, "min"), - maxDate = this._getMinMaxDate(inst, "max"), - minYear = null, - maxYear = null, - years = this._get(inst, "yearRange"); - if (years){ - yearSplit = years.split(":"); - currentYear = new Date().getFullYear(); - minYear = parseInt(yearSplit[0], 10); - maxYear = parseInt(yearSplit[1], 10); - if ( yearSplit[0].match(/[+\-].*/) ) { - minYear += currentYear; - } - if ( yearSplit[1].match(/[+\-].*/) ) { - maxYear += currentYear; - } - } - - return ((!minDate || date.getTime() >= minDate.getTime()) && - (!maxDate || date.getTime() <= maxDate.getTime()) && - (!minYear || date.getFullYear() >= minYear) && - (!maxYear || date.getFullYear() <= maxYear)); - }, - - /* Provide the configuration settings for formatting/parsing. */ - _getFormatConfig: function(inst) { - var shortYearCutoff = this._get(inst, "shortYearCutoff"); - shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff : - new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10)); - return {shortYearCutoff: shortYearCutoff, - dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"), - monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")}; - }, - - /* Format the given date for display. */ - _formatDate: function(inst, day, month, year) { - if (!day) { - inst.currentDay = inst.selectedDay; - inst.currentMonth = inst.selectedMonth; - inst.currentYear = inst.selectedYear; - } - var date = (day ? (typeof day === "object" ? day : - this._daylightSavingAdjust(new Date(year, month, day))) : - this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay))); - return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst)); - } -}); - -/* - * Bind hover events for datepicker elements. - * Done via delegate so the binding only occurs once in the lifetime of the parent div. - * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker. - */ -function datepicker_bindHover(dpDiv) { - var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a"; - return dpDiv.delegate(selector, "mouseout", function() { - $(this).removeClass("ui-state-hover"); - if (this.className.indexOf("ui-datepicker-prev") !== -1) { - $(this).removeClass("ui-datepicker-prev-hover"); - } - if (this.className.indexOf("ui-datepicker-next") !== -1) { - $(this).removeClass("ui-datepicker-next-hover"); - } - }) - .delegate( selector, "mouseover", datepicker_handleMouseover ); -} - -function datepicker_handleMouseover() { - if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) { - $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover"); - $(this).addClass("ui-state-hover"); - if (this.className.indexOf("ui-datepicker-prev") !== -1) { - $(this).addClass("ui-datepicker-prev-hover"); - } - if (this.className.indexOf("ui-datepicker-next") !== -1) { - $(this).addClass("ui-datepicker-next-hover"); - } - } -} - -/* jQuery extend now ignores nulls! */ -function datepicker_extendRemove(target, props) { - $.extend(target, props); - for (var name in props) { - if (props[name] == null) { - target[name] = props[name]; - } - } - return target; -} - -/* Invoke the datepicker functionality. - @param options string - a command, optionally followed by additional parameters or - Object - settings for attaching new datepicker functionality - @return jQuery object */ -$.fn.datepicker = function(options){ - - /* Verify an empty collection wasn't passed - Fixes #6976 */ - if ( !this.length ) { - return this; - } - - /* Initialise the date picker. */ - if (!$.datepicker.initialized) { - $(document).mousedown($.datepicker._checkExternalClick); - $.datepicker.initialized = true; - } - - /* Append datepicker main container to body if not exist. */ - if ($("#"+$.datepicker._mainDivId).length === 0) { - $("body").append($.datepicker.dpDiv); - } - - var otherArgs = Array.prototype.slice.call(arguments, 1); - if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) { - return $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this[0]].concat(otherArgs)); - } - if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") { - return $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this[0]].concat(otherArgs)); - } - return this.each(function() { - typeof options === "string" ? - $.datepicker["_" + options + "Datepicker"]. - apply($.datepicker, [this].concat(otherArgs)) : - $.datepicker._attachDatepicker(this, options); - }); -}; - -$.datepicker = new Datepicker(); // singleton instance -$.datepicker.initialized = false; -$.datepicker.uuid = new Date().getTime(); -$.datepicker.version = "1.11.2"; - -var datepicker = $.datepicker; - - -/*! - * jQuery UI Draggable 1.11.2 - * http://jqueryui.com - * - * Copyright 2014 jQuery Foundation and other contributors - * Released under the MIT license. - * http://jquery.org/license - * - * http://api.jqueryui.com/draggable/ - */ - - -$.widget("ui.draggable", $.ui.mouse, { - version: "1.11.2", - widgetEventPrefix: "drag", - options: { - addClasses: true, - appendTo: "parent", - axis: false, - connectToSortable: false, - containment: false, - cursor: "auto", - cursorAt: false, - grid: false, - handle: false, - helper: "original", - iframeFix: false, - opacity: false, - refreshPositions: false, - revert: false, - revertDuration: 500, - scope: "default", - scroll: true, - scrollSensitivity: 20, - scrollSpeed: 20, - snap: false, - snapMode: "both", - snapTolerance: 20, - stack: false, - zIndex: false, - - // callbacks - drag: null, - start: null, - stop: null - }, - _create: function() { - - if ( this.options.helper === "original" ) { - this._setPositionRelative(); - } - if (this.options.addClasses){ - this.element.addClass("ui-draggable"); - } - if (this.options.disabled){ - this.element.addClass("ui-draggable-disabled"); - } - this._setHandleClassName(); - - this._mouseInit(); - }, - - _setOption: function( key, value ) { - this._super( key, value ); - if ( key === "handle" ) { - this._removeHandleClassName(); - this._setHandleClassName(); - } - }, - - _destroy: function() { - if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) { - this.destroyOnClear = true; - return; - } - this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" ); - this._removeHandleClassName(); - this._mouseDestroy(); - }, - - _mouseCapture: function(event) { - var o = this.options; - - this._blurActiveElement( event ); - - // among others, prevent a drag on a resizable-handle - if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) { - return false; - } - - //Quit if we're not on a valid handle - this.handle = this._getHandle(event); - if (!this.handle) { - return false; - } - - this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix ); - - return true; - - }, - - _blockFrames: function( selector ) { - this.iframeBlocks = this.document.find( selector ).map(function() { - var iframe = $( this ); - - return $( "
    " ) - .css( "position", "absolute" ) - .appendTo( iframe.parent() ) - .outerWidth( iframe.outerWidth() ) - .outerHeight( iframe.outerHeight() ) - .offset( iframe.offset() )[ 0 ]; - }); - }, - - _unblockFrames: function() { - if ( this.iframeBlocks ) { - this.iframeBlocks.remove(); - delete this.iframeBlocks; - } - }, - - _blurActiveElement: function( event ) { - var document = this.document[ 0 ]; - - // Only need to blur if the event occurred on the draggable itself, see #10527 - if ( !this.handleElement.is( event.target ) ) { - return; - } - - // support: IE9 - // IE9 throws an "Unspecified error" accessing document.activeElement from an