Google Language Translator - Version 5.0.0

Version Description

Download this release

Release Info

Developer rm2773
Plugin Icon wp plugin Google Language Translator
Version 5.0.0
Comparing to
See all releases

Code changes from version 4.0.9 to 5.0.0

css/jquery-ui.css DELETED
File without changes
google-language-translator.php CHANGED
@@ -2,7 +2,7 @@
2
  /*
3
  Plugin Name: Google Language Translator
4
  Plugin URI: http://www.studio88design.com/plugins/google-language-translator
5
- Version: 4.0.9
6
  Description: The MOST SIMPLE Google Translator plugin. This plugin adds Google Translator to your website by using a single shortcode, [google-translator]. Settings include: layout style, hide/show specific languages, hide/show Google toolbar, and hide/show Google branding. Add the shortcode to pages, posts, and widgets.
7
  Author: Rob Myrick
8
  Author URI: http://www.wp-studio.net/
@@ -25,7 +25,7 @@ class google_language_translator {
25
  'bg' => 'Bulgarian',
26
  'ca' => 'Catalan',
27
  'ceb' => 'Cebuano',
28
- 'zh-CN' => 'Chinese(Simplified)',
29
  'zh-TW' => 'Chinese(Traditional)',
30
  'hr' => 'Croatian',
31
  'cs' => 'Czech',
@@ -187,15 +187,11 @@ class google_language_translator {
187
  wp_enqueue_style( 'toolbar.css' );
188
  }
189
 
190
- wp_enqueue_script( 'jquery-ui.js', plugins_url('js/jquery-ui.js',__FILE__), array('jquery'));
191
- wp_enqueue_script( 'jquery-ui-sortable.js', plugins_url('js/jquery-ui-sortable.js',__FILE__), array('jquery'));
192
- wp_enqueue_script( 'jquery-ui-widget.js', plugins_url('js/jquery-ui-widget.js',__FILE__), array('jquery'));
193
- wp_enqueue_script( 'jquery-ui-mouse.js', plugins_url('js/jquery-ui-mouse.js',__FILE__), array('jquery'));
194
  wp_enqueue_script( 'load_sortable_flags', plugins_url('js/load-sortable-flags.js',__FILE__), array('jquery'));
195
- wp_register_style( 'jquery-ui.css', plugins_url('css/jquery-ui.css',__FILE__) );
196
  wp_register_style( 'style.css', plugins_url('css/style.css', __FILE__) );
197
  wp_enqueue_style( 'style.css' );
198
- wp_enqueue_style( 'jquery-ui.css' );
199
  }
200
 
201
  public function flags() {
@@ -282,15 +278,7 @@ class google_language_translator {
282
  }
283
 
284
  public function footer_script() {
285
-
286
- global $shortcode_started;
287
-
288
- if (!$shortcode_started):
289
- //echo 'shortcode not loaded';
290
- else:
291
- //echo 'true';
292
- endif;
293
-
294
  $default_language = get_option('googlelanguagetranslator_language');
295
  $language_choices = $this->googlelanguagetranslator_included_languages();
296
  $get_language_option = get_option('googlelanguagetranslator_language_option');
@@ -300,52 +288,7 @@ class google_language_translator {
300
  $is_multilanguage = get_option('googlelanguagetranslator_multilanguage');
301
  $auto_display = ', autoDisplay: false';
302
  $str = ''; ?>
303
-
304
- <script>
305
- jQuery(document).ready(function($) {
306
- $("a.nturl").on("click",function() {
307
- default_lang = "<?php echo get_option('googlelanguagetranslator_language'); ?>";
308
- lang_prefix = $(this).attr("class").split(" ")[2];
309
-
310
- if (lang_prefix == default_lang) {
311
- load_default();
312
- } else {
313
- load_selected_language();
314
- }
315
-
316
- function load_default() {
317
- doGoogleLanguageTranslator(default_lang + "|" + default_lang);
318
- }
319
-
320
- function load_selected_language() {
321
- doGoogleLanguageTranslator(default_lang + "|" + lang_prefix);
322
- }
323
- });
324
-
325
- $("a.flag").on("click",function() {
326
- default_lang = "<?php echo get_option('googlelanguagetranslator_language'); ?>";
327
- lang_prefix = $(this).attr("class").split(" ")[2];
328
-
329
- if (lang_prefix == default_lang) {
330
- load_default();
331
- } else {
332
- load_selected_language();
333
- }
334
-
335
- function load_default() {
336
- doGoogleLanguageTranslator(default_lang + "|" + default_lang);
337
- }
338
-
339
- function load_selected_language() {
340
- doGoogleLanguageTranslator(default_lang + "|" + lang_prefix);
341
- }
342
- });
343
-
344
- if ($ ("body > #google_language_translator").length == 0) {
345
- $("#glt-footer").html("<div id='google_language_translator'></div>");
346
- }
347
- });
348
- </script>
349
 
350
  <?php
351
 
@@ -369,24 +312,7 @@ class google_language_translator {
369
  $language_name_flag = $language_name;
370
  if ($flag_choice_key == '1') {
371
  if ( isset ( $get_flag_choices['flag-'.$language_code.''] ) ) {
372
- if ( $language_name == 'English' && $english_flag_choice == 'canadian_flag') {
373
- $language_name_flag = 'Canada';
374
- }
375
- if ( $language_name == "English" && $english_flag_choice == 'us_flag') {
376
- $language_name_flag = 'United-States';
377
- }
378
- if ( $language_name == 'Spanish' && $spanish_flag_choice == 'mexican_flag') {
379
- $language_name_flag = 'Mexico';
380
- }
381
- if ( $language_name == 'Portuguese' && $portuguese_flag_choice == 'brazilian_flag') {
382
- $language_name_flag = 'Brazil';
383
- }
384
-
385
- if ($lang_attribute == 'yes') {
386
- $str.='<li id="'.$language_name.'"><a title="'.$language_name.'" class="notranslate flag '.$language_code.'"></a></li>';
387
- } else {
388
  $str.="<li id='".$language_name."'><a title='".$language_name."' class='notranslate flag ".$language_code."'></a></li>";
389
- }
390
  }
391
  } //$key
392
  }//foreach
@@ -398,24 +324,7 @@ class google_language_translator {
398
  if ($flag_choice_key == '1') {
399
  if (in_array($language_name,$this->languages_array)) {
400
  if ( isset ( $get_flag_choices['flag-'.$language_code.''] ) ) {
401
- if ( $language_name == 'English' && $english_flag_choice == 'canadian_flag') {
402
- $language_name_flag = 'Canada';
403
- }
404
- if ( $language_name == "English" && $english_flag_choice == 'us_flag') {
405
- $language_name_flag = 'United-States';
406
- }
407
- if ( $language_name == 'Spanish' && $spanish_flag_choice == 'mexican_flag') {
408
- $language_name_flag = 'Mexico';
409
- }
410
- if ( $language_name == 'Portuguese' && $portuguese_flag_choice == 'brazilian_flag') {
411
- $language_name_flag = 'Brazil';
412
- }
413
-
414
- if ($lang_attribute == 'yes') {
415
- $str.='<li id="'.$language_name.'"><a title="'.$language_name.'" class="notranslate flag '.$language_code.'"></a></li>';
416
- } else {
417
  $str.="<li id='".$language_name."'><a title='".$language_name."' class='notranslate flag ".$language_code."'></a></li>";
418
- }
419
  } //isset
420
  } //in_array
421
  }//flag_choice_key
@@ -435,14 +344,12 @@ class google_language_translator {
435
 
436
  if ($is_multilanguage == 1) {
437
  $multilanguagePage = ', multilanguagePage:true';
438
- $str.="<div id='glt-footer'></div><script type='text/javascript'>";
439
- $str.="function GoogleLanguageTranslatorInit() { new google.translate.TranslateElement({pageLanguage: '".$default_language."'".$language_choices . ($layout=='Horizontal' ? $horizontal_layout : '') . $auto_display . $multilanguagePage . $this->analytics()."}, 'google_language_translator');}</script>";
440
  $str.="<script type='text/javascript' src='//translate.google.com/translate_a/element.js?cb=GoogleLanguageTranslatorInit'></script>";
441
  echo $str;
442
 
443
  } elseif ($is_multilanguage == 0) {
444
- $str.="<div id='glt-footer'></div><script type='text/javascript'>";
445
- $str.="function GoogleLanguageTranslatorInit() { new google.translate.TranslateElement({pageLanguage: '".$default_language."'".$language_choices . ($layout=='Horizontal' ? $horizontal_layout : '') . $auto_display . $this->analytics()."}, 'google_language_translator');}</script>";
446
  $str.="<script type='text/javascript' src='//translate.google.com/translate_a/element.js?cb=GoogleLanguageTranslatorInit'></script>";
447
  echo $str;
448
  }
@@ -991,7 +898,7 @@ class google_language_translator {
991
  <div class="wrap">
992
  <div id="icon-options-general" class="icon32"></div>
993
  <h2><span class="notranslate">Google Language Translator</span></h2>
994
- <form action="<?php echo admin_url('options.php'); ?>" method="post">
995
  <div class="metabox-holder has-right-sidebar" style="float:left; width:65%">
996
  <div class="postbox" style="width: 100%">
997
  <h3 class="notranslate">Settings</h3>
@@ -1032,7 +939,7 @@ class google_language_translator {
1032
  </tr>
1033
 
1034
  <tr class="notranslate">
1035
- <td>Show floating translation widget? <strong style="color:red">(New!)</strong><br/>
1036
  <span>("All Languages" option <strong><u>must</u></strong> be chosen to show widget.)</span>
1037
  </td>
1038
  <td><?php $this->googlelanguagetranslator_floating_widget_cb(); ?></td>
@@ -1063,10 +970,10 @@ class google_language_translator {
1063
  <td class="flagdisplay"><?php $this->googlelanguagetranslator_flags_alignment_cb(); ?></td>
1064
  </tr>
1065
 
1066
- <tr class="manage_translations notranslate">
1067
  <td>Turn on translation management? &nbsp;<a href="#TB_inline?width=200&height=300&inlineId=translation-management-description" title="What is Translation Management?" class="thickbox">Learn more</a><div id="translation-management-description" style="display:none"><p>Translation management is an interface that allows you to manage specific words and phrases on your website. The interface is linked directly to your Google Account, and no special subscriptions are necessary to setup this feature.</p><p>If translation management setting is checked, users who browse your website can hover their mouse over specific words and phrases, then send translation suggestions directly to your Google Translate account! You can then "approve" those suggestions, and Google will automatically display them when translations are requested by your users.</p><p>Translation management requires that you insert a custom meta tag into the <code>head</code> section of your website.</p><p><a href="http://translate.google.com/manager/website/settings" target="_blank">Click here to to get the required meta tag</a></p></div></td>
1068
  <td><?php $this->googlelanguagetranslator_manage_translations_cb(); ?></td>
1069
- </tr>
1070
 
1071
  <tr class="multilanguage notranslate">
1072
  <td>Multilanguage Page option? &nbsp;<a href="#TB_inline?width=200&height=150&inlineId=multilanguage-page-description" title="What is the Multi-Language Page Option?" class="thickbox">Learn more</a><div id="multilanguage-page-description" style="display:none"><p>If checked, Google will automatically convert text written in multiple languages, into the single language requested by your user.</p><p>In most cases, this setting is not recommended, although for certain websites it might be necessary.</p></div></td>
@@ -1102,18 +1009,38 @@ class google_language_translator {
1102
 
1103
  <tr class="notranslate">
1104
  <td colspan="2">
1105
- <a href="#TB_inline?width=200&height=450&inlineId=single-language-shortcode-description" title="How to place a single language in your Wordpress menu" class="thickbox">How to place a single language in your Wordpress menu</a><div id="single-language-shortcode-description" style="display:none"><p>For menu usage, you need to create a new menu, or use an existing menu, by navigating to "Appearance > Menus".</p><p>First you will need to enable "descriptions" for your menu items, which can be found in a tab labeled "Screen Options" in the upper-right area of the page.</p><p>Once descriptions are enabled, follow these steps:<br/><ol><li>Create a new menu item using "Link" as the menu item type.</li><li>Use <code style="border:none">#</code> for the URL</li><li>Enter a navigation label of your choice. This label does not appear on your website - it is meant only to help you identify the menu item.</li><li>Place the following shortcode into the "description" field, and modify it to display the language and navigation label of your choice:</p></li></ol>
1106
- <p><code>[glt language="Spanish" label="Español"]</code></p>
1107
- </div></td>
 
 
 
 
 
 
 
 
 
 
 
1108
  </tr>
1109
 
1110
  <tr class="notranslate">
1111
- <td><?php submit_button(); ?></td>
 
 
 
 
 
 
 
 
 
 
1112
  <td></td>
1113
  </tr>
1114
  </table>
1115
-
1116
- </div> <!-- .postbox -->
1117
  </div> <!-- .metbox-holder -->
1118
 
1119
  <div class="metabox-holder" style="float:right; clear:right; width:33%">
@@ -1121,7 +1048,7 @@ class google_language_translator {
1121
  <h3 class="notranslate">Preview</h3>
1122
  <table style="width:100%">
1123
  <tr>
1124
- <td style="box-sizing:border-box; -webkit-box-sizing:border-box; -moz-box-sizing:border-box; padding:15px 15px; margin:0px"><span style="color:red; font-weight:bold" class="notranslate">(New!)</span><span class="notranslate"> Drag &amp; drop flags to change their position.<br/><br/>(Note: flag order resets when flags are added/removed)</span><br/><br/><?php echo do_shortcode('[google-translator]'); ?><p class="hello"><span class="notranslate">Translated text:</span> &nbsp; <span>Hello</span></p></td>
1125
  </tr>
1126
 
1127
  <tr>
@@ -1162,10 +1089,10 @@ class google_language_translator {
1162
 
1163
  <div class="metabox-holder notranslate" style="float: right; width: 33%;">
1164
  <div class="postbox">
1165
- <h3>GLT Premium 4.0.1 is Here! $15</h3>
1166
  <div class="inside"><a href="http://www.wp-studio.net/" target="_blank"><img style="background:#444; border-radius:3px; -webkit-border-radius:3px; -moz-border-radius:3px" src="<?php echo plugins_url('google-language-translator/images/logo.png'); ?>"></a><br />
1167
  <ul id="features" style="margin-left:15px">
1168
- <li style="list-style:square outside"><span style="color:red; font-weight:bold">New!</span> Manual Translation Module!</li>
1169
  <li style="list-style:square outside"><span style="color:red; font-weight:bold">New!</span> Exclude any specific area of your website from translation, directly from your settings panel</li>
1170
  <li style="list-style:square outside">81 Languages</li>
1171
  <li style="list-style:square outside">jQuery-powered language switcher<br/>(No Adobe Flash required)</li>
2
  /*
3
  Plugin Name: Google Language Translator
4
  Plugin URI: http://www.studio88design.com/plugins/google-language-translator
5
+ Version: 5.0.0
6
  Description: The MOST SIMPLE Google Translator plugin. This plugin adds Google Translator to your website by using a single shortcode, [google-translator]. Settings include: layout style, hide/show specific languages, hide/show Google toolbar, and hide/show Google branding. Add the shortcode to pages, posts, and widgets.
7
  Author: Rob Myrick
8
  Author URI: http://www.wp-studio.net/
25
  'bg' => 'Bulgarian',
26
  'ca' => 'Catalan',
27
  'ceb' => 'Cebuano',
28
+ 'zh-CN' => 'Chinese',
29
  'zh-TW' => 'Chinese(Traditional)',
30
  'hr' => 'Croatian',
31
  'cs' => 'Czech',
187
  wp_enqueue_style( 'toolbar.css' );
188
  }
189
 
190
+ wp_enqueue_script( 'jquery-ui-core');
191
+ wp_enqueue_script( 'jquery-ui-sortable');
 
 
192
  wp_enqueue_script( 'load_sortable_flags', plugins_url('js/load-sortable-flags.js',__FILE__), array('jquery'));
 
193
  wp_register_style( 'style.css', plugins_url('css/style.css', __FILE__) );
194
  wp_enqueue_style( 'style.css' );
 
195
  }
196
 
197
  public function flags() {
278
  }
279
 
280
  public function footer_script() {
281
+ global $shortcode_started;
 
 
 
 
 
 
 
 
282
  $default_language = get_option('googlelanguagetranslator_language');
283
  $language_choices = $this->googlelanguagetranslator_included_languages();
284
  $get_language_option = get_option('googlelanguagetranslator_language_option');
288
  $is_multilanguage = get_option('googlelanguagetranslator_multilanguage');
289
  $auto_display = ', autoDisplay: false';
290
  $str = ''; ?>
291
+ <script>jQuery(document).ready(function(a){a("a.nturl").on("click",function(){function l(){doGoogleLanguageTranslator(default_lang+"|"+default_lang)}function n(){doGoogleLanguageTranslator(default_lang+"|"+lang_prefix)}default_lang="<?php echo get_option('googlelanguagetranslator_language'); ?>",lang_prefix=a(this).attr("class").split(" ")[2],lang_prefix==default_lang?l():n()}),a("a.flag").on("click",function(){function l(){doGoogleLanguageTranslator(default_lang+"|"+default_lang)}function n(){doGoogleLanguageTranslator(default_lang+"|"+lang_prefix)}default_lang="<?php echo get_option('googlelanguagetranslator_language'); ?>",lang_prefix=a(this).attr("class").split(" ")[2],a(".tool-container").hide(),lang_prefix==default_lang?l():n()}),0==a("body > #google_language_translator").length&&a("#glt-footer").html("<div id='google_language_translator'></div>")});</script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
 
293
  <?php
294
 
312
  $language_name_flag = $language_name;
313
  if ($flag_choice_key == '1') {
314
  if ( isset ( $get_flag_choices['flag-'.$language_code.''] ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  $str.="<li id='".$language_name."'><a title='".$language_name."' class='notranslate flag ".$language_code."'></a></li>";
 
316
  }
317
  } //$key
318
  }//foreach
324
  if ($flag_choice_key == '1') {
325
  if (in_array($language_name,$this->languages_array)) {
326
  if ( isset ( $get_flag_choices['flag-'.$language_code.''] ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
  $str.="<li id='".$language_name."'><a title='".$language_name."' class='notranslate flag ".$language_code."'></a></li>";
 
328
  } //isset
329
  } //in_array
330
  }//flag_choice_key
344
 
345
  if ($is_multilanguage == 1) {
346
  $multilanguagePage = ', multilanguagePage:true';
347
+ $str.="<div id='glt-footer'></div><script type='text/javascript'>function GoogleLanguageTranslatorInit() { new google.translate.TranslateElement({pageLanguage: '".$default_language."'".$language_choices . ($layout=='Horizontal' ? $horizontal_layout : '') . $auto_display . $multilanguagePage . $this->analytics()."}, 'google_language_translator');}</script>";
 
348
  $str.="<script type='text/javascript' src='//translate.google.com/translate_a/element.js?cb=GoogleLanguageTranslatorInit'></script>";
349
  echo $str;
350
 
351
  } elseif ($is_multilanguage == 0) {
352
+ $str.="<div id='glt-footer'></div><script type='text/javascript'>function GoogleLanguageTranslatorInit() { new google.translate.TranslateElement({pageLanguage: '".$default_language."'".$language_choices . ($layout=='Horizontal' ? $horizontal_layout : '') . $auto_display . $this->analytics()."}, 'google_language_translator');}</script>";
 
353
  $str.="<script type='text/javascript' src='//translate.google.com/translate_a/element.js?cb=GoogleLanguageTranslatorInit'></script>";
354
  echo $str;
355
  }
898
  <div class="wrap">
899
  <div id="icon-options-general" class="icon32"></div>
900
  <h2><span class="notranslate">Google Language Translator</span></h2>
901
+ <form action="<?php echo admin_url( '/options.php'); ?>" method="post">
902
  <div class="metabox-holder has-right-sidebar" style="float:left; width:65%">
903
  <div class="postbox" style="width: 100%">
904
  <h3 class="notranslate">Settings</h3>
939
  </tr>
940
 
941
  <tr class="notranslate">
942
+ <td>Show floating translation widget?<br/>
943
  <span>("All Languages" option <strong><u>must</u></strong> be chosen to show widget.)</span>
944
  </td>
945
  <td><?php $this->googlelanguagetranslator_floating_widget_cb(); ?></td>
970
  <td class="flagdisplay"><?php $this->googlelanguagetranslator_flags_alignment_cb(); ?></td>
971
  </tr>
972
 
973
+ <!--<tr class="manage_translations notranslate">
974
  <td>Turn on translation management? &nbsp;<a href="#TB_inline?width=200&height=300&inlineId=translation-management-description" title="What is Translation Management?" class="thickbox">Learn more</a><div id="translation-management-description" style="display:none"><p>Translation management is an interface that allows you to manage specific words and phrases on your website. The interface is linked directly to your Google Account, and no special subscriptions are necessary to setup this feature.</p><p>If translation management setting is checked, users who browse your website can hover their mouse over specific words and phrases, then send translation suggestions directly to your Google Translate account! You can then "approve" those suggestions, and Google will automatically display them when translations are requested by your users.</p><p>Translation management requires that you insert a custom meta tag into the <code>head</code> section of your website.</p><p><a href="http://translate.google.com/manager/website/settings" target="_blank">Click here to to get the required meta tag</a></p></div></td>
975
  <td><?php $this->googlelanguagetranslator_manage_translations_cb(); ?></td>
976
+ </tr>-->
977
 
978
  <tr class="multilanguage notranslate">
979
  <td>Multilanguage Page option? &nbsp;<a href="#TB_inline?width=200&height=150&inlineId=multilanguage-page-description" title="What is the Multi-Language Page Option?" class="thickbox">Learn more</a><div id="multilanguage-page-description" style="display:none"><p>If checked, Google will automatically convert text written in multiple languages, into the single language requested by your user.</p><p>In most cases, this setting is not recommended, although for certain websites it might be necessary.</p></div></td>
1009
 
1010
  <tr class="notranslate">
1011
  <td colspan="2">
1012
+ <a href="#TB_inline?width=200&height=450&inlineId=single-language-shortcode-description" title="How to place a single language in your Wordpress menu" class="thickbox">How to place a single language in your Wordpress menu</a>
1013
+ <div id="single-language-shortcode-description" style="display:none">
1014
+ <p>For menu usage, you need to create a new menu, or use an existing menu, by navigating to "Appearance > Menus".</p>
1015
+ <p>First you will need to enable "descriptions" for your menu items, which can be found in a tab labeled "Screen Options" in the upper-right area of the page.</p>
1016
+ <p>Once descriptions are enabled, follow these steps:<br/>
1017
+ <ol>
1018
+ <li>Create a new menu item using "Link" as the menu item type.</li>
1019
+ <li>Use <code style="border:none">#</code> for the URL</li>
1020
+ <li>Enter a navigation label of your choice. This label does not appear on your website - it is meant only to help you identify the menu item.</li>
1021
+ <li>Place the following shortcode into the "description" field, and modify it to display the language and navigation label of your choice:</li>
1022
+ </ol>
1023
+ <p><code>[glt language="Spanish" label="Español"]</code></p>
1024
+ </div>
1025
+ </td>
1026
  </tr>
1027
 
1028
  <tr class="notranslate">
1029
+ <td>
1030
+ <?php
1031
+ if (isset($_POST['submit'])) {
1032
+ if (empty($_POST['submit']) && !check_admin_referer( 'glt-save-settings', 'glt-save-settings-nonce' )) {
1033
+ wp_die();
1034
+ } else { echo 'hello'; }
1035
+ }
1036
+ wp_nonce_field('glt-save-settings, glt-save-settings-nonce', false);
1037
+ submit_button();
1038
+ ?>
1039
+ </td>
1040
  <td></td>
1041
  </tr>
1042
  </table>
1043
+ </div> <!-- .postbox -->
 
1044
  </div> <!-- .metbox-holder -->
1045
 
1046
  <div class="metabox-holder" style="float:right; clear:right; width:33%">
1048
  <h3 class="notranslate">Preview</h3>
1049
  <table style="width:100%">
1050
  <tr>
1051
+ <td style="box-sizing:border-box; -webkit-box-sizing:border-box; -moz-box-sizing:border-box; padding:15px 15px; margin:0px"><span class="notranslate"> Drag &amp; drop flags to change their position.<br/><br/>(Note: flag order resets when flags are added/removed)</span><br/><br/><?php echo do_shortcode('[google-translator]'); ?><p class="hello"><span class="notranslate">Translated text:</span> &nbsp; <span>Hello</span></p></td>
1052
  </tr>
1053
 
1054
  <tr>
1089
 
1090
  <div class="metabox-holder notranslate" style="float: right; width: 33%;">
1091
  <div class="postbox">
1092
+ <h3>GLT Premium 4.0.9 is Here! $30</h3>
1093
  <div class="inside"><a href="http://www.wp-studio.net/" target="_blank"><img style="background:#444; border-radius:3px; -webkit-border-radius:3px; -moz-border-radius:3px" src="<?php echo plugins_url('google-language-translator/images/logo.png'); ?>"></a><br />
1094
  <ul id="features" style="margin-left:15px">
1095
+ <li style="list-style:square outside"><span style="color:red; font-weight:bold">New!</span> Manual Translation Module (Experimental)!</li>
1096
  <li style="list-style:square outside"><span style="color:red; font-weight:bold">New!</span> Exclude any specific area of your website from translation, directly from your settings panel</li>
1097
  <li style="list-style:square outside">81 Languages</li>
1098
  <li style="list-style:square outside">jQuery-powered language switcher<br/>(No Adobe Flash required)</li>
js/flags.js CHANGED
@@ -1,10 +1,39 @@
1
- /*-------------------------------------------------------------------------------*
2
- * Script for onClick trigger functionality used by flag images
3
- * Full Credit: Edvard Ananyan at http://edo.webmaster.am (author of GTranslate translator plugin)
4
- * GTranslate Free Version is licensed under GNU/GPL license
5
- *-------------------------------------------------------------------------------*/
6
-
7
- /* <![CDATA[ */
8
- eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('6 7(a,b){n{4(2.9){3 c=2.9("o");c.p(b,f,f);a.q(c)}g{3 c=2.r();a.s(\'t\'+b,c)}}u(e){}}6 h(a){4(a.8)a=a.8;4(a==\'\')v;3 b=a.w(\'|\')[1];3 c;3 d=2.x(\'y\');z(3 i=0;i<d.5;i++)4(d[i].A==\'B-C-D\')c=d[i];4(2.j(\'k\')==E||2.j(\'k\').l.5==0||c.5==0||c.l.5==0){F(6(){h(a)},G)}g{c.8=b;7(c,\'m\');7(c,\'m\')}}',43,43,'||document|var|if|length|function|GTranslateFireEvent|value|createEvent||||||true|else|doGoogleLanguageTranslator||getElementById|google_language_translator|innerHTML|change|try|HTMLEvents|initEvent|dispatchEvent|createEventObject|fireEvent|on|catch|return|split|getElementsByTagName|select|for|className|goog|te|combo|null|setTimeout|500'.split('|'),0,{}))
9
- /* ]]> */
10
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*-------------------------------------------------------------------------------*
2
+ * Script for onClick trigger functionality used by flag images
3
+ * Script modified from original GTranslate plugin created by Edvard Ananyan at http://edo.webmaster.am
4
+ * GTranslate Free Version is licensed under GNU/GPL license
5
+ *-------------------------------------------------------------------------------*/
6
+
7
+ /* <![CDATA[ */
8
+ function GLTFireEvent(a, b) {
9
+ try {
10
+ if (document.createEvent) {
11
+ var c = document.createEvent("HTMLEvents");
12
+ c.initEvent(b, true, true);
13
+ a.dispatchEvent(c)
14
+ } else {
15
+ var c = document.createEventObject();
16
+ a.fireEvent('on' + b, c)
17
+ }
18
+ } catch (e) {}
19
+ }
20
+
21
+ function doGoogleLanguageTranslator(a) {
22
+ if (a.value) a = a.value;
23
+ if (a == '') return;
24
+ var b = a.split('|')[1];
25
+ var c;
26
+ var d = document.getElementsByTagName('select');
27
+ for (var i = 0; i < d.length; i++)
28
+ if (d[i].className == 'goog-te-combo') c = d[i];
29
+ if (document.getElementById('google_language_translator') == null || document.getElementById('google_language_translator').innerHTML.length == 0 || c.length == 0 || c.innerHTML.length == 0) {
30
+ setTimeout(function() {
31
+ doGoogleLanguageTranslator(a)
32
+ }, 500)
33
+ } else {
34
+ c.value = b;
35
+ GLTFireEvent(c, 'change');
36
+ GLTFireEvent(c, 'change')
37
+ }
38
+ }
39
+ /* ]]> */
js/jquery-ui-mouse.js DELETED
@@ -1,169 +0,0 @@
1
- /*!
2
- * jQuery UI Mouse 1.10.4
3
- * http://jqueryui.com
4
- *
5
- * Copyright 2014 jQuery Foundation and other contributors
6
- * Released under the MIT license.
7
- * http://jquery.org/license
8
- *
9
- * http://api.jqueryui.com/mouse/
10
- *
11
- * Depends:
12
- * jquery.ui.widget.js
13
- */
14
- (function( $, undefined ) {
15
-
16
- var mouseHandled = false;
17
- $( document ).mouseup( function() {
18
- mouseHandled = false;
19
- });
20
-
21
- $.widget("ui.mouse", {
22
- version: "1.10.4",
23
- options: {
24
- cancel: "input,textarea,button,select,option",
25
- distance: 1,
26
- delay: 0
27
- },
28
- _mouseInit: function() {
29
- var that = this;
30
-
31
- this.element
32
- .bind("mousedown."+this.widgetName, function(event) {
33
- return that._mouseDown(event);
34
- })
35
- .bind("click."+this.widgetName, function(event) {
36
- if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
37
- $.removeData(event.target, that.widgetName + ".preventClickEvent");
38
- event.stopImmediatePropagation();
39
- return false;
40
- }
41
- });
42
-
43
- this.started = false;
44
- },
45
-
46
- // TODO: make sure destroying one instance of mouse doesn't mess with
47
- // other instances of mouse
48
- _mouseDestroy: function() {
49
- this.element.unbind("."+this.widgetName);
50
- if ( this._mouseMoveDelegate ) {
51
- $(document)
52
- .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
53
- .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
54
- }
55
- },
56
-
57
- _mouseDown: function(event) {
58
- // don't let more than one widget handle mouseStart
59
- if( mouseHandled ) { return; }
60
-
61
- // we may have missed mouseup (out of window)
62
- (this._mouseStarted && this._mouseUp(event));
63
-
64
- this._mouseDownEvent = event;
65
-
66
- var that = this,
67
- btnIsLeft = (event.which === 1),
68
- // event.target.nodeName works around a bug in IE 8 with
69
- // disabled inputs (#7620)
70
- elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
71
- if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
72
- return true;
73
- }
74
-
75
- this.mouseDelayMet = !this.options.delay;
76
- if (!this.mouseDelayMet) {
77
- this._mouseDelayTimer = setTimeout(function() {
78
- that.mouseDelayMet = true;
79
- }, this.options.delay);
80
- }
81
-
82
- if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
83
- this._mouseStarted = (this._mouseStart(event) !== false);
84
- if (!this._mouseStarted) {
85
- event.preventDefault();
86
- return true;
87
- }
88
- }
89
-
90
- // Click event may never have fired (Gecko & Opera)
91
- if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
92
- $.removeData(event.target, this.widgetName + ".preventClickEvent");
93
- }
94
-
95
- // these delegates are required to keep context
96
- this._mouseMoveDelegate = function(event) {
97
- return that._mouseMove(event);
98
- };
99
- this._mouseUpDelegate = function(event) {
100
- return that._mouseUp(event);
101
- };
102
- $(document)
103
- .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
104
- .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
105
-
106
- event.preventDefault();
107
-
108
- mouseHandled = true;
109
- return true;
110
- },
111
-
112
- _mouseMove: function(event) {
113
- // IE mouseup check - mouseup happened when mouse was out of window
114
- if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
115
- return this._mouseUp(event);
116
- }
117
-
118
- if (this._mouseStarted) {
119
- this._mouseDrag(event);
120
- return event.preventDefault();
121
- }
122
-
123
- if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
124
- this._mouseStarted =
125
- (this._mouseStart(this._mouseDownEvent, event) !== false);
126
- (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
127
- }
128
-
129
- return !this._mouseStarted;
130
- },
131
-
132
- _mouseUp: function(event) {
133
- $(document)
134
- .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
135
- .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
136
-
137
- if (this._mouseStarted) {
138
- this._mouseStarted = false;
139
-
140
- if (event.target === this._mouseDownEvent.target) {
141
- $.data(event.target, this.widgetName + ".preventClickEvent", true);
142
- }
143
-
144
- this._mouseStop(event);
145
- }
146
-
147
- return false;
148
- },
149
-
150
- _mouseDistanceMet: function(event) {
151
- return (Math.max(
152
- Math.abs(this._mouseDownEvent.pageX - event.pageX),
153
- Math.abs(this._mouseDownEvent.pageY - event.pageY)
154
- ) >= this.options.distance
155
- );
156
- },
157
-
158
- _mouseDelayMet: function(/* event */) {
159
- return this.mouseDelayMet;
160
- },
161
-
162
- // These are placeholder methods, to be overriden by extending plugin
163
- _mouseStart: function(/* event */) {},
164
- _mouseDrag: function(/* event */) {},
165
- _mouseStop: function(/* event */) {},
166
- _mouseCapture: function(/* event */) { return true; }
167
- });
168
-
169
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/jquery-ui-sortable.js DELETED
@@ -1,1289 +0,0 @@
1
- /*!
2
- * jQuery UI Sortable 1.10.4
3
- * http://jqueryui.com
4
- *
5
- * Copyright 2014 jQuery Foundation and other contributors
6
- * Released under the MIT license.
7
- * http://jquery.org/license
8
- *
9
- * http://api.jqueryui.com/sortable/
10
- *
11
- * Depends:
12
- * jquery.ui.core.js
13
- * jquery.ui.mouse.js
14
- * jquery.ui.widget.js
15
- */
16
- (function( $, undefined ) {
17
-
18
- function isOverAxis( x, reference, size ) {
19
- return ( x > reference ) && ( x < ( reference + size ) );
20
- }
21
-
22
- function isFloating(item) {
23
- return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
24
- }
25
-
26
- $.widget("ui.sortable", $.ui.mouse, {
27
- version: "1.10.4",
28
- widgetEventPrefix: "sort",
29
- ready: false,
30
- options: {
31
- appendTo: "parent",
32
- axis: false,
33
- connectWith: false,
34
- containment: false,
35
- cursor: "auto",
36
- cursorAt: false,
37
- dropOnEmpty: true,
38
- forcePlaceholderSize: false,
39
- forceHelperSize: false,
40
- grid: false,
41
- handle: false,
42
- helper: "original",
43
- items: "> *",
44
- opacity: false,
45
- placeholder: false,
46
- revert: false,
47
- scroll: true,
48
- scrollSensitivity: 20,
49
- scrollSpeed: 20,
50
- scope: "default",
51
- tolerance: "intersect",
52
- zIndex: 1000,
53
-
54
- // callbacks
55
- activate: null,
56
- beforeStop: null,
57
- change: null,
58
- deactivate: null,
59
- out: null,
60
- over: null,
61
- receive: null,
62
- remove: null,
63
- sort: null,
64
- start: null,
65
- stop: null,
66
- update: null
67
- },
68
- _create: function() {
69
-
70
- var o = this.options;
71
- this.containerCache = {};
72
- this.element.addClass("ui-sortable");
73
-
74
- //Get the items
75
- this.refresh();
76
-
77
- //Let's determine if the items are being displayed horizontally
78
- this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
79
-
80
- //Let's determine the parent's offset
81
- this.offset = this.element.offset();
82
-
83
- //Initialize mouse events for interaction
84
- this._mouseInit();
85
-
86
- //We're ready to go
87
- this.ready = true;
88
-
89
- },
90
-
91
- _destroy: function() {
92
- this.element
93
- .removeClass("ui-sortable ui-sortable-disabled");
94
- this._mouseDestroy();
95
-
96
- for ( var i = this.items.length - 1; i >= 0; i-- ) {
97
- this.items[i].item.removeData(this.widgetName + "-item");
98
- }
99
-
100
- return this;
101
- },
102
-
103
- _setOption: function(key, value){
104
- if ( key === "disabled" ) {
105
- this.options[ key ] = value;
106
-
107
- this.widget().toggleClass( "ui-sortable-disabled", !!value );
108
- } else {
109
- // Don't call widget base _setOption for disable as it adds ui-state-disabled class
110
- $.Widget.prototype._setOption.apply(this, arguments);
111
- }
112
- },
113
-
114
- _mouseCapture: function(event, overrideHandle) {
115
- var currentItem = null,
116
- validHandle = false,
117
- that = this;
118
-
119
- if (this.reverting) {
120
- return false;
121
- }
122
-
123
- if(this.options.disabled || this.options.type === "static") {
124
- return false;
125
- }
126
-
127
- //We have to refresh the items data once first
128
- this._refreshItems(event);
129
-
130
- //Find out if the clicked node (or one of its parents) is a actual item in this.items
131
- $(event.target).parents().each(function() {
132
- if($.data(this, that.widgetName + "-item") === that) {
133
- currentItem = $(this);
134
- return false;
135
- }
136
- });
137
- if($.data(event.target, that.widgetName + "-item") === that) {
138
- currentItem = $(event.target);
139
- }
140
-
141
- if(!currentItem) {
142
- return false;
143
- }
144
- if(this.options.handle && !overrideHandle) {
145
- $(this.options.handle, currentItem).find("*").addBack().each(function() {
146
- if(this === event.target) {
147
- validHandle = true;
148
- }
149
- });
150
- if(!validHandle) {
151
- return false;
152
- }
153
- }
154
-
155
- this.currentItem = currentItem;
156
- this._removeCurrentsFromItems();
157
- return true;
158
-
159
- },
160
-
161
- _mouseStart: function(event, overrideHandle, noActivation) {
162
-
163
- var i, body,
164
- o = this.options;
165
-
166
- this.currentContainer = this;
167
-
168
- //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
169
- this.refreshPositions();
170
-
171
- //Create and append the visible helper
172
- this.helper = this._createHelper(event);
173
-
174
- //Cache the helper size
175
- this._cacheHelperProportions();
176
-
177
- /*
178
- * - Position generation -
179
- * This block generates everything position related - it's the core of draggables.
180
- */
181
-
182
- //Cache the margins of the original element
183
- this._cacheMargins();
184
-
185
- //Get the next scrolling parent
186
- this.scrollParent = this.helper.scrollParent();
187
-
188
- //The element's absolute position on the page minus margins
189
- this.offset = this.currentItem.offset();
190
- this.offset = {
191
- top: this.offset.top - this.margins.top,
192
- left: this.offset.left - this.margins.left
193
- };
194
-
195
- $.extend(this.offset, {
196
- click: { //Where the click happened, relative to the element
197
- left: event.pageX - this.offset.left,
198
- top: event.pageY - this.offset.top
199
- },
200
- parent: this._getParentOffset(),
201
- relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
202
- });
203
-
204
- // Only after we got the offset, we can change the helper's position to absolute
205
- // TODO: Still need to figure out a way to make relative sorting possible
206
- this.helper.css("position", "absolute");
207
- this.cssPosition = this.helper.css("position");
208
-
209
- //Generate the original position
210
- this.originalPosition = this._generatePosition(event);
211
- this.originalPageX = event.pageX;
212
- this.originalPageY = event.pageY;
213
-
214
- //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
215
- (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
216
-
217
- //Cache the former DOM position
218
- this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
219
-
220
- //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
221
- if(this.helper[0] !== this.currentItem[0]) {
222
- this.currentItem.hide();
223
- }
224
-
225
- //Create the placeholder
226
- this._createPlaceholder();
227
-
228
- //Set a containment if given in the options
229
- if(o.containment) {
230
- this._setContainment();
231
- }
232
-
233
- if( o.cursor && o.cursor !== "auto" ) { // cursor option
234
- body = this.document.find( "body" );
235
-
236
- // support: IE
237
- this.storedCursor = body.css( "cursor" );
238
- body.css( "cursor", o.cursor );
239
-
240
- this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
241
- }
242
-
243
- if(o.opacity) { // opacity option
244
- if (this.helper.css("opacity")) {
245
- this._storedOpacity = this.helper.css("opacity");
246
- }
247
- this.helper.css("opacity", o.opacity);
248
- }
249
-
250
- if(o.zIndex) { // zIndex option
251
- if (this.helper.css("zIndex")) {
252
- this._storedZIndex = this.helper.css("zIndex");
253
- }
254
- this.helper.css("zIndex", o.zIndex);
255
- }
256
-
257
- //Prepare scrolling
258
- if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
259
- this.overflowOffset = this.scrollParent.offset();
260
- }
261
-
262
- //Call callbacks
263
- this._trigger("start", event, this._uiHash());
264
-
265
- //Recache the helper size
266
- if(!this._preserveHelperProportions) {
267
- this._cacheHelperProportions();
268
- }
269
-
270
-
271
- //Post "activate" events to possible containers
272
- if( !noActivation ) {
273
- for ( i = this.containers.length - 1; i >= 0; i-- ) {
274
- this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
275
- }
276
- }
277
-
278
- //Prepare possible droppables
279
- if($.ui.ddmanager) {
280
- $.ui.ddmanager.current = this;
281
- }
282
-
283
- if ($.ui.ddmanager && !o.dropBehaviour) {
284
- $.ui.ddmanager.prepareOffsets(this, event);
285
- }
286
-
287
- this.dragging = true;
288
-
289
- this.helper.addClass("ui-sortable-helper");
290
- this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
291
- return true;
292
-
293
- },
294
-
295
- _mouseDrag: function(event) {
296
- var i, item, itemElement, intersection,
297
- o = this.options,
298
- scrolled = false;
299
-
300
- //Compute the helpers position
301
- this.position = this._generatePosition(event);
302
- this.positionAbs = this._convertPositionTo("absolute");
303
-
304
- if (!this.lastPositionAbs) {
305
- this.lastPositionAbs = this.positionAbs;
306
- }
307
-
308
- //Do scrolling
309
- if(this.options.scroll) {
310
- if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
311
-
312
- if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
313
- this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
314
- } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
315
- this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
316
- }
317
-
318
- if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
319
- this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
320
- } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
321
- this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
322
- }
323
-
324
- } else {
325
-
326
- if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
327
- scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
328
- } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
329
- scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
330
- }
331
-
332
- if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
333
- scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
334
- } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
335
- scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
336
- }
337
-
338
- }
339
-
340
- if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
341
- $.ui.ddmanager.prepareOffsets(this, event);
342
- }
343
- }
344
-
345
- //Regenerate the absolute position used for position checks
346
- this.positionAbs = this._convertPositionTo("absolute");
347
-
348
- //Set the helper position
349
- if(!this.options.axis || this.options.axis !== "y") {
350
- this.helper[0].style.left = this.position.left+"px";
351
- }
352
- if(!this.options.axis || this.options.axis !== "x") {
353
- this.helper[0].style.top = this.position.top+"px";
354
- }
355
-
356
- //Rearrange
357
- for (i = this.items.length - 1; i >= 0; i--) {
358
-
359
- //Cache variables and intersection, continue if no intersection
360
- item = this.items[i];
361
- itemElement = item.item[0];
362
- intersection = this._intersectsWithPointer(item);
363
- if (!intersection) {
364
- continue;
365
- }
366
-
367
- // Only put the placeholder inside the current Container, skip all
368
- // items from other containers. This works because when moving
369
- // an item from one container to another the
370
- // currentContainer is switched before the placeholder is moved.
371
- //
372
- // Without this, moving items in "sub-sortables" can cause
373
- // the placeholder to jitter beetween the outer and inner container.
374
- if (item.instance !== this.currentContainer) {
375
- continue;
376
- }
377
-
378
- // cannot intersect with itself
379
- // no useless actions that have been done before
380
- // no action if the item moved is the parent of the item checked
381
- if (itemElement !== this.currentItem[0] &&
382
- this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
383
- !$.contains(this.placeholder[0], itemElement) &&
384
- (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
385
- ) {
386
-
387
- this.direction = intersection === 1 ? "down" : "up";
388
-
389
- if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
390
- this._rearrange(event, item);
391
- } else {
392
- break;
393
- }
394
-
395
- this._trigger("change", event, this._uiHash());
396
- break;
397
- }
398
- }
399
-
400
- //Post events to containers
401
- this._contactContainers(event);
402
-
403
- //Interconnect with droppables
404
- if($.ui.ddmanager) {
405
- $.ui.ddmanager.drag(this, event);
406
- }
407
-
408
- //Call callbacks
409
- this._trigger("sort", event, this._uiHash());
410
-
411
- this.lastPositionAbs = this.positionAbs;
412
- return false;
413
-
414
- },
415
-
416
- _mouseStop: function(event, noPropagation) {
417
-
418
- if(!event) {
419
- return;
420
- }
421
-
422
- //If we are using droppables, inform the manager about the drop
423
- if ($.ui.ddmanager && !this.options.dropBehaviour) {
424
- $.ui.ddmanager.drop(this, event);
425
- }
426
-
427
- if(this.options.revert) {
428
- var that = this,
429
- cur = this.placeholder.offset(),
430
- axis = this.options.axis,
431
- animation = {};
432
-
433
- if ( !axis || axis === "x" ) {
434
- animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
435
- }
436
- if ( !axis || axis === "y" ) {
437
- animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
438
- }
439
- this.reverting = true;
440
- $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
441
- that._clear(event);
442
- });
443
- } else {
444
- this._clear(event, noPropagation);
445
- }
446
-
447
- return false;
448
-
449
- },
450
-
451
- cancel: function() {
452
-
453
- if(this.dragging) {
454
-
455
- this._mouseUp({ target: null });
456
-
457
- if(this.options.helper === "original") {
458
- this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
459
- } else {
460
- this.currentItem.show();
461
- }
462
-
463
- //Post deactivating events to containers
464
- for (var i = this.containers.length - 1; i >= 0; i--){
465
- this.containers[i]._trigger("deactivate", null, this._uiHash(this));
466
- if(this.containers[i].containerCache.over) {
467
- this.containers[i]._trigger("out", null, this._uiHash(this));
468
- this.containers[i].containerCache.over = 0;
469
- }
470
- }
471
-
472
- }
473
-
474
- if (this.placeholder) {
475
- //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
476
- if(this.placeholder[0].parentNode) {
477
- this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
478
- }
479
- if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
480
- this.helper.remove();
481
- }
482
-
483
- $.extend(this, {
484
- helper: null,
485
- dragging: false,
486
- reverting: false,
487
- _noFinalSort: null
488
- });
489
-
490
- if(this.domPosition.prev) {
491
- $(this.domPosition.prev).after(this.currentItem);
492
- } else {
493
- $(this.domPosition.parent).prepend(this.currentItem);
494
- }
495
- }
496
-
497
- return this;
498
-
499
- },
500
-
501
- serialize: function(o) {
502
-
503
- var items = this._getItemsAsjQuery(o && o.connected),
504
- str = [];
505
- o = o || {};
506
-
507
- $(items).each(function() {
508
- var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
509
- if (res) {
510
- str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
511
- }
512
- });
513
-
514
- if(!str.length && o.key) {
515
- str.push(o.key + "=");
516
- }
517
-
518
- return str.join("&");
519
-
520
- },
521
-
522
- toArray: function(o) {
523
-
524
- var items = this._getItemsAsjQuery(o && o.connected),
525
- ret = [];
526
-
527
- o = o || {};
528
-
529
- items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
530
- return ret;
531
-
532
- },
533
-
534
- /* Be careful with the following core functions */
535
- _intersectsWith: function(item) {
536
-
537
- var x1 = this.positionAbs.left,
538
- x2 = x1 + this.helperProportions.width,
539
- y1 = this.positionAbs.top,
540
- y2 = y1 + this.helperProportions.height,
541
- l = item.left,
542
- r = l + item.width,
543
- t = item.top,
544
- b = t + item.height,
545
- dyClick = this.offset.click.top,
546
- dxClick = this.offset.click.left,
547
- isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
548
- isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
549
- isOverElement = isOverElementHeight && isOverElementWidth;
550
-
551
- if ( this.options.tolerance === "pointer" ||
552
- this.options.forcePointerForContainers ||
553
- (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
554
- ) {
555
- return isOverElement;
556
- } else {
557
-
558
- return (l < x1 + (this.helperProportions.width / 2) && // Right Half
559
- x2 - (this.helperProportions.width / 2) < r && // Left Half
560
- t < y1 + (this.helperProportions.height / 2) && // Bottom Half
561
- y2 - (this.helperProportions.height / 2) < b ); // Top Half
562
-
563
- }
564
- },
565
-
566
- _intersectsWithPointer: function(item) {
567
-
568
- var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
569
- isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
570
- isOverElement = isOverElementHeight && isOverElementWidth,
571
- verticalDirection = this._getDragVerticalDirection(),
572
- horizontalDirection = this._getDragHorizontalDirection();
573
-
574
- if (!isOverElement) {
575
- return false;
576
- }
577
-
578
- return this.floating ?
579
- ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
580
- : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
581
-
582
- },
583
-
584
- _intersectsWithSides: function(item) {
585
-
586
- var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
587
- isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
588
- verticalDirection = this._getDragVerticalDirection(),
589
- horizontalDirection = this._getDragHorizontalDirection();
590
-
591
- if (this.floating && horizontalDirection) {
592
- return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
593
- } else {
594
- return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
595
- }
596
-
597
- },
598
-
599
- _getDragVerticalDirection: function() {
600
- var delta = this.positionAbs.top - this.lastPositionAbs.top;
601
- return delta !== 0 && (delta > 0 ? "down" : "up");
602
- },
603
-
604
- _getDragHorizontalDirection: function() {
605
- var delta = this.positionAbs.left - this.lastPositionAbs.left;
606
- return delta !== 0 && (delta > 0 ? "right" : "left");
607
- },
608
-
609
- refresh: function(event) {
610
- this._refreshItems(event);
611
- this.refreshPositions();
612
- return this;
613
- },
614
-
615
- _connectWith: function() {
616
- var options = this.options;
617
- return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
618
- },
619
-
620
- _getItemsAsjQuery: function(connected) {
621
-
622
- var i, j, cur, inst,
623
- items = [],
624
- queries = [],
625
- connectWith = this._connectWith();
626
-
627
- if(connectWith && connected) {
628
- for (i = connectWith.length - 1; i >= 0; i--){
629
- cur = $(connectWith[i]);
630
- for ( j = cur.length - 1; j >= 0; j--){
631
- inst = $.data(cur[j], this.widgetFullName);
632
- if(inst && inst !== this && !inst.options.disabled) {
633
- queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
634
- }
635
- }
636
- }
637
- }
638
-
639
- queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
640
-
641
- function addItems() {
642
- items.push( this );
643
- }
644
- for (i = queries.length - 1; i >= 0; i--){
645
- queries[i][0].each( addItems );
646
- }
647
-
648
- return $(items);
649
-
650
- },
651
-
652
- _removeCurrentsFromItems: function() {
653
-
654
- var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
655
-
656
- this.items = $.grep(this.items, function (item) {
657
- for (var j=0; j < list.length; j++) {
658
- if(list[j] === item.item[0]) {
659
- return false;
660
- }
661
- }
662
- return true;
663
- });
664
-
665
- },
666
-
667
- _refreshItems: function(event) {
668
-
669
- this.items = [];
670
- this.containers = [this];
671
-
672
- var i, j, cur, inst, targetData, _queries, item, queriesLength,
673
- items = this.items,
674
- queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
675
- connectWith = this._connectWith();
676
-
677
- if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
678
- for (i = connectWith.length - 1; i >= 0; i--){
679
- cur = $(connectWith[i]);
680
- for (j = cur.length - 1; j >= 0; j--){
681
- inst = $.data(cur[j], this.widgetFullName);
682
- if(inst && inst !== this && !inst.options.disabled) {
683
- queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
684
- this.containers.push(inst);
685
- }
686
- }
687
- }
688
- }
689
-
690
- for (i = queries.length - 1; i >= 0; i--) {
691
- targetData = queries[i][1];
692
- _queries = queries[i][0];
693
-
694
- for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
695
- item = $(_queries[j]);
696
-
697
- item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
698
-
699
- items.push({
700
- item: item,
701
- instance: targetData,
702
- width: 0, height: 0,
703
- left: 0, top: 0
704
- });
705
- }
706
- }
707
-
708
- },
709
-
710
- refreshPositions: function(fast) {
711
-
712
- //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
713
- if(this.offsetParent && this.helper) {
714
- this.offset.parent = this._getParentOffset();
715
- }
716
-
717
- var i, item, t, p;
718
-
719
- for (i = this.items.length - 1; i >= 0; i--){
720
- item = this.items[i];
721
-
722
- //We ignore calculating positions of all connected containers when we're not over them
723
- if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
724
- continue;
725
- }
726
-
727
- t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
728
-
729
- if (!fast) {
730
- item.width = t.outerWidth();
731
- item.height = t.outerHeight();
732
- }
733
-
734
- p = t.offset();
735
- item.left = p.left;
736
- item.top = p.top;
737
- }
738
-
739
- if(this.options.custom && this.options.custom.refreshContainers) {
740
- this.options.custom.refreshContainers.call(this);
741
- } else {
742
- for (i = this.containers.length - 1; i >= 0; i--){
743
- p = this.containers[i].element.offset();
744
- this.containers[i].containerCache.left = p.left;
745
- this.containers[i].containerCache.top = p.top;
746
- this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
747
- this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
748
- }
749
- }
750
-
751
- return this;
752
- },
753
-
754
- _createPlaceholder: function(that) {
755
- that = that || this;
756
- var className,
757
- o = that.options;
758
-
759
- if(!o.placeholder || o.placeholder.constructor === String) {
760
- className = o.placeholder;
761
- o.placeholder = {
762
- element: function() {
763
-
764
- var nodeName = that.currentItem[0].nodeName.toLowerCase(),
765
- element = $( "<" + nodeName + ">", that.document[0] )
766
- .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
767
- .removeClass("ui-sortable-helper");
768
-
769
- if ( nodeName === "tr" ) {
770
- that.currentItem.children().each(function() {
771
- $( "<td>&#160;</td>", that.document[0] )
772
- .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
773
- .appendTo( element );
774
- });
775
- } else if ( nodeName === "img" ) {
776
- element.attr( "src", that.currentItem.attr( "src" ) );
777
- }
778
-
779
- if ( !className ) {
780
- element.css( "visibility", "hidden" );
781
- }
782
-
783
- return element;
784
- },
785
- update: function(container, p) {
786
-
787
- // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
788
- // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
789
- if(className && !o.forcePlaceholderSize) {
790
- return;
791
- }
792
-
793
- //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
794
- if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
795
- if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
796
- }
797
- };
798
- }
799
-
800
- //Create the placeholder
801
- that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
802
-
803
- //Append it after the actual current item
804
- that.currentItem.after(that.placeholder);
805
-
806
- //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
807
- o.placeholder.update(that, that.placeholder);
808
-
809
- },
810
-
811
- _contactContainers: function(event) {
812
- var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
813
- innermostContainer = null,
814
- innermostIndex = null;
815
-
816
- // get innermost container that intersects with item
817
- for (i = this.containers.length - 1; i >= 0; i--) {
818
-
819
- // never consider a container that's located within the item itself
820
- if($.contains(this.currentItem[0], this.containers[i].element[0])) {
821
- continue;
822
- }
823
-
824
- if(this._intersectsWith(this.containers[i].containerCache)) {
825
-
826
- // if we've already found a container and it's more "inner" than this, then continue
827
- if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
828
- continue;
829
- }
830
-
831
- innermostContainer = this.containers[i];
832
- innermostIndex = i;
833
-
834
- } else {
835
- // container doesn't intersect. trigger "out" event if necessary
836
- if(this.containers[i].containerCache.over) {
837
- this.containers[i]._trigger("out", event, this._uiHash(this));
838
- this.containers[i].containerCache.over = 0;
839
- }
840
- }
841
-
842
- }
843
-
844
- // if no intersecting containers found, return
845
- if(!innermostContainer) {
846
- return;
847
- }
848
-
849
- // move the item into the container if it's not there already
850
- if(this.containers.length === 1) {
851
- if (!this.containers[innermostIndex].containerCache.over) {
852
- this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
853
- this.containers[innermostIndex].containerCache.over = 1;
854
- }
855
- } else {
856
-
857
- //When entering a new container, we will find the item with the least distance and append our item near it
858
- dist = 10000;
859
- itemWithLeastDistance = null;
860
- floating = innermostContainer.floating || isFloating(this.currentItem);
861
- posProperty = floating ? "left" : "top";
862
- sizeProperty = floating ? "width" : "height";
863
- base = this.positionAbs[posProperty] + this.offset.click[posProperty];
864
- for (j = this.items.length - 1; j >= 0; j--) {
865
- if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
866
- continue;
867
- }
868
- if(this.items[j].item[0] === this.currentItem[0]) {
869
- continue;
870
- }
871
- if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
872
- continue;
873
- }
874
- cur = this.items[j].item.offset()[posProperty];
875
- nearBottom = false;
876
- if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
877
- nearBottom = true;
878
- cur += this.items[j][sizeProperty];
879
- }
880
-
881
- if(Math.abs(cur - base) < dist) {
882
- dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
883
- this.direction = nearBottom ? "up": "down";
884
- }
885
- }
886
-
887
- //Check if dropOnEmpty is enabled
888
- if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
889
- return;
890
- }
891
-
892
- if(this.currentContainer === this.containers[innermostIndex]) {
893
- return;
894
- }
895
-
896
- itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
897
- this._trigger("change", event, this._uiHash());
898
- this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
899
- this.currentContainer = this.containers[innermostIndex];
900
-
901
- //Update the placeholder
902
- this.options.placeholder.update(this.currentContainer, this.placeholder);
903
-
904
- this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
905
- this.containers[innermostIndex].containerCache.over = 1;
906
- }
907
-
908
-
909
- },
910
-
911
- _createHelper: function(event) {
912
-
913
- var o = this.options,
914
- helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
915
-
916
- //Add the helper to the DOM if that didn't happen already
917
- if(!helper.parents("body").length) {
918
- $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
919
- }
920
-
921
- if(helper[0] === this.currentItem[0]) {
922
- this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
923
- }
924
-
925
- if(!helper[0].style.width || o.forceHelperSize) {
926
- helper.width(this.currentItem.width());
927
- }
928
- if(!helper[0].style.height || o.forceHelperSize) {
929
- helper.height(this.currentItem.height());
930
- }
931
-
932
- return helper;
933
-
934
- },
935
-
936
- _adjustOffsetFromHelper: function(obj) {
937
- if (typeof obj === "string") {
938
- obj = obj.split(" ");
939
- }
940
- if ($.isArray(obj)) {
941
- obj = {left: +obj[0], top: +obj[1] || 0};
942
- }
943
- if ("left" in obj) {
944
- this.offset.click.left = obj.left + this.margins.left;
945
- }
946
- if ("right" in obj) {
947
- this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
948
- }
949
- if ("top" in obj) {
950
- this.offset.click.top = obj.top + this.margins.top;
951
- }
952
- if ("bottom" in obj) {
953
- this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
954
- }
955
- },
956
-
957
- _getParentOffset: function() {
958
-
959
-
960
- //Get the offsetParent and cache its position
961
- this.offsetParent = this.helper.offsetParent();
962
- var po = this.offsetParent.offset();
963
-
964
- // This is a special case where we need to modify a offset calculated on start, since the following happened:
965
- // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
966
- // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
967
- // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
968
- if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
969
- po.left += this.scrollParent.scrollLeft();
970
- po.top += this.scrollParent.scrollTop();
971
- }
972
-
973
- // This needs to be actually done for all browsers, since pageX/pageY includes this information
974
- // with an ugly IE fix
975
- if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
976
- po = { top: 0, left: 0 };
977
- }
978
-
979
- return {
980
- top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
981
- left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
982
- };
983
-
984
- },
985
-
986
- _getRelativeOffset: function() {
987
-
988
- if(this.cssPosition === "relative") {
989
- var p = this.currentItem.position();
990
- return {
991
- top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
992
- left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
993
- };
994
- } else {
995
- return { top: 0, left: 0 };
996
- }
997
-
998
- },
999
-
1000
- _cacheMargins: function() {
1001
- this.margins = {
1002
- left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
1003
- top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
1004
- };
1005
- },
1006
-
1007
- _cacheHelperProportions: function() {
1008
- this.helperProportions = {
1009
- width: this.helper.outerWidth(),
1010
- height: this.helper.outerHeight()
1011
- };
1012
- },
1013
-
1014
- _setContainment: function() {
1015
-
1016
- var ce, co, over,
1017
- o = this.options;
1018
- if(o.containment === "parent") {
1019
- o.containment = this.helper[0].parentNode;
1020
- }
1021
- if(o.containment === "document" || o.containment === "window") {
1022
- this.containment = [
1023
- 0 - this.offset.relative.left - this.offset.parent.left,
1024
- 0 - this.offset.relative.top - this.offset.parent.top,
1025
- $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
1026
- ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
1027
- ];
1028
- }
1029
-
1030
- if(!(/^(document|window|parent)$/).test(o.containment)) {
1031
- ce = $(o.containment)[0];
1032
- co = $(o.containment).offset();
1033
- over = ($(ce).css("overflow") !== "hidden");
1034
-
1035
- this.containment = [
1036
- co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
1037
- co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
1038
- co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
1039
- co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
1040
- ];
1041
- }
1042
-
1043
- },
1044
-
1045
- _convertPositionTo: function(d, pos) {
1046
-
1047
- if(!pos) {
1048
- pos = this.position;
1049
- }
1050
- var mod = d === "absolute" ? 1 : -1,
1051
- scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
1052
- scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1053
-
1054
- return {
1055
- top: (
1056
- pos.top + // The absolute mouse position
1057
- this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
1058
- this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
1059
- ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
1060
- ),
1061
- left: (
1062
- pos.left + // The absolute mouse position
1063
- this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
1064
- this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
1065
- ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
1066
- )
1067
- };
1068
-
1069
- },
1070
-
1071
- _generatePosition: function(event) {
1072
-
1073
- var top, left,
1074
- o = this.options,
1075
- pageX = event.pageX,
1076
- pageY = event.pageY,
1077
- scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
1078
-
1079
- // This is another very weird special case that only happens for relative elements:
1080
- // 1. If the css position is relative
1081
- // 2. and the scroll parent is the document or similar to the offset parent
1082
- // we have to refresh the relative offset during the scroll so there are no jumps
1083
- if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
1084
- this.offset.relative = this._getRelativeOffset();
1085
- }
1086
-
1087
- /*
1088
- * - Position constraining -
1089
- * Constrain the position to a mix of grid, containment.
1090
- */
1091
-
1092
- if(this.originalPosition) { //If we are not dragging yet, we won't check for options
1093
-
1094
- if(this.containment) {
1095
- if(event.pageX - this.offset.click.left < this.containment[0]) {
1096
- pageX = this.containment[0] + this.offset.click.left;
1097
- }
1098
- if(event.pageY - this.offset.click.top < this.containment[1]) {
1099
- pageY = this.containment[1] + this.offset.click.top;
1100
- }
1101
- if(event.pageX - this.offset.click.left > this.containment[2]) {
1102
- pageX = this.containment[2] + this.offset.click.left;
1103
- }
1104
- if(event.pageY - this.offset.click.top > this.containment[3]) {
1105
- pageY = this.containment[3] + this.offset.click.top;
1106
- }
1107
- }
1108
-
1109
- if(o.grid) {
1110
- top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
1111
- pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
1112
-
1113
- left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
1114
- pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
1115
- }
1116
-
1117
- }
1118
-
1119
- return {
1120
- top: (
1121
- pageY - // The absolute mouse position
1122
- this.offset.click.top - // Click offset (relative to the element)
1123
- this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
1124
- this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
1125
- ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
1126
- ),
1127
- left: (
1128
- pageX - // The absolute mouse position
1129
- this.offset.click.left - // Click offset (relative to the element)
1130
- this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
1131
- this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
1132
- ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
1133
- )
1134
- };
1135
-
1136
- },
1137
-
1138
- _rearrange: function(event, i, a, hardRefresh) {
1139
-
1140
- a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
1141
-
1142
- //Various things done here to improve the performance:
1143
- // 1. we create a setTimeout, that calls refreshPositions
1144
- // 2. on the instance, we have a counter variable, that get's higher after every append
1145
- // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
1146
- // 4. this lets only the last addition to the timeout stack through
1147
- this.counter = this.counter ? ++this.counter : 1;
1148
- var counter = this.counter;
1149
-
1150
- this._delay(function() {
1151
- if(counter === this.counter) {
1152
- this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
1153
- }
1154
- });
1155
-
1156
- },
1157
-
1158
- _clear: function(event, noPropagation) {
1159
-
1160
- this.reverting = false;
1161
- // We delay all events that have to be triggered to after the point where the placeholder has been removed and
1162
- // everything else normalized again
1163
- var i,
1164
- delayedTriggers = [];
1165
-
1166
- // We first have to update the dom position of the actual currentItem
1167
- // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
1168
- if(!this._noFinalSort && this.currentItem.parent().length) {
1169
- this.placeholder.before(this.currentItem);
1170
- }
1171
- this._noFinalSort = null;
1172
-
1173
- if(this.helper[0] === this.currentItem[0]) {
1174
- for(i in this._storedCSS) {
1175
- if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
1176
- this._storedCSS[i] = "";
1177
- }
1178
- }
1179
- this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
1180
- } else {
1181
- this.currentItem.show();
1182
- }
1183
-
1184
- if(this.fromOutside && !noPropagation) {
1185
- delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
1186
- }
1187
- if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
1188
- delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
1189
- }
1190
-
1191
- // Check if the items Container has Changed and trigger appropriate
1192
- // events.
1193
- if (this !== this.currentContainer) {
1194
- if(!noPropagation) {
1195
- delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
1196
- delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
1197
- delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
1198
- }
1199
- }
1200
-
1201
-
1202
- //Post events to containers
1203
- function delayEvent( type, instance, container ) {
1204
- return function( event ) {
1205
- container._trigger( type, event, instance._uiHash( instance ) );
1206
- };
1207
- }
1208
- for (i = this.containers.length - 1; i >= 0; i--){
1209
- if (!noPropagation) {
1210
- delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
1211
- }
1212
- if(this.containers[i].containerCache.over) {
1213
- delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
1214
- this.containers[i].containerCache.over = 0;
1215
- }
1216
- }
1217
-
1218
- //Do what was originally in plugins
1219
- if ( this.storedCursor ) {
1220
- this.document.find( "body" ).css( "cursor", this.storedCursor );
1221
- this.storedStylesheet.remove();
1222
- }
1223
- if(this._storedOpacity) {
1224
- this.helper.css("opacity", this._storedOpacity);
1225
- }
1226
- if(this._storedZIndex) {
1227
- this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
1228
- }
1229
-
1230
- this.dragging = false;
1231
- if(this.cancelHelperRemoval) {
1232
- if(!noPropagation) {
1233
- this._trigger("beforeStop", event, this._uiHash());
1234
- for (i=0; i < delayedTriggers.length; i++) {
1235
- delayedTriggers[i].call(this, event);
1236
- } //Trigger all delayed events
1237
- this._trigger("stop", event, this._uiHash());
1238
- }
1239
-
1240
- this.fromOutside = false;
1241
- return false;
1242
- }
1243
-
1244
- if(!noPropagation) {
1245
- this._trigger("beforeStop", event, this._uiHash());
1246
- }
1247
-
1248
- //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
1249
- this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
1250
-
1251
- if(this.helper[0] !== this.currentItem[0]) {
1252
- this.helper.remove();
1253
- }
1254
- this.helper = null;
1255
-
1256
- if(!noPropagation) {
1257
- for (i=0; i < delayedTriggers.length; i++) {
1258
- delayedTriggers[i].call(this, event);
1259
- } //Trigger all delayed events
1260
- this._trigger("stop", event, this._uiHash());
1261
- }
1262
-
1263
- this.fromOutside = false;
1264
- return true;
1265
-
1266
- },
1267
-
1268
- _trigger: function() {
1269
- if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
1270
- this.cancel();
1271
- }
1272
- },
1273
-
1274
- _uiHash: function(_inst) {
1275
- var inst = _inst || this;
1276
- return {
1277
- helper: inst.helper,
1278
- placeholder: inst.placeholder || $([]),
1279
- position: inst.position,
1280
- originalPosition: inst.originalPosition,
1281
- offset: inst.positionAbs,
1282
- item: inst.currentItem,
1283
- sender: _inst ? _inst.element : null
1284
- };
1285
- }
1286
-
1287
- });
1288
-
1289
- })(jQuery);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/jquery-ui-widget.js DELETED
@@ -1,521 +0,0 @@
1
- /*!
2
- * jQuery UI Widget 1.10.4
3
- * http://jqueryui.com
4
- *
5
- * Copyright 2014 jQuery Foundation and other contributors
6
- * Released under the MIT license.
7
- * http://jquery.org/license
8
- *
9
- * http://api.jqueryui.com/jQuery.widget/
10
- */
11
- (function( $, undefined ) {
12
-
13
- var uuid = 0,
14
- slice = Array.prototype.slice,
15
- _cleanData = $.cleanData;
16
- $.cleanData = function( elems ) {
17
- for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
18
- try {
19
- $( elem ).triggerHandler( "remove" );
20
- // http://bugs.jquery.com/ticket/8235
21
- } catch( e ) {}
22
- }
23
- _cleanData( elems );
24
- };
25
-
26
- $.widget = function( name, base, prototype ) {
27
- var fullName, existingConstructor, constructor, basePrototype,
28
- // proxiedPrototype allows the provided prototype to remain unmodified
29
- // so that it can be used as a mixin for multiple widgets (#8876)
30
- proxiedPrototype = {},
31
- namespace = name.split( "." )[ 0 ];
32
-
33
- name = name.split( "." )[ 1 ];
34
- fullName = namespace + "-" + name;
35
-
36
- if ( !prototype ) {
37
- prototype = base;
38
- base = $.Widget;
39
- }
40
-
41
- // create selector for plugin
42
- $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
43
- return !!$.data( elem, fullName );
44
- };
45
-
46
- $[ namespace ] = $[ namespace ] || {};
47
- existingConstructor = $[ namespace ][ name ];
48
- constructor = $[ namespace ][ name ] = function( options, element ) {
49
- // allow instantiation without "new" keyword
50
- if ( !this._createWidget ) {
51
- return new constructor( options, element );
52
- }
53
-
54
- // allow instantiation without initializing for simple inheritance
55
- // must use "new" keyword (the code above always passes args)
56
- if ( arguments.length ) {
57
- this._createWidget( options, element );
58
- }
59
- };
60
- // extend with the existing constructor to carry over any static properties
61
- $.extend( constructor, existingConstructor, {
62
- version: prototype.version,
63
- // copy the object used to create the prototype in case we need to
64
- // redefine the widget later
65
- _proto: $.extend( {}, prototype ),
66
- // track widgets that inherit from this widget in case this widget is
67
- // redefined after a widget inherits from it
68
- _childConstructors: []
69
- });
70
-
71
- basePrototype = new base();
72
- // we need to make the options hash a property directly on the new instance
73
- // otherwise we'll modify the options hash on the prototype that we're
74
- // inheriting from
75
- basePrototype.options = $.widget.extend( {}, basePrototype.options );
76
- $.each( prototype, function( prop, value ) {
77
- if ( !$.isFunction( value ) ) {
78
- proxiedPrototype[ prop ] = value;
79
- return;
80
- }
81
- proxiedPrototype[ prop ] = (function() {
82
- var _super = function() {
83
- return base.prototype[ prop ].apply( this, arguments );
84
- },
85
- _superApply = function( args ) {
86
- return base.prototype[ prop ].apply( this, args );
87
- };
88
- return function() {
89
- var __super = this._super,
90
- __superApply = this._superApply,
91
- returnValue;
92
-
93
- this._super = _super;
94
- this._superApply = _superApply;
95
-
96
- returnValue = value.apply( this, arguments );
97
-
98
- this._super = __super;
99
- this._superApply = __superApply;
100
-
101
- return returnValue;
102
- };
103
- })();
104
- });
105
- constructor.prototype = $.widget.extend( basePrototype, {
106
- // TODO: remove support for widgetEventPrefix
107
- // always use the name + a colon as the prefix, e.g., draggable:start
108
- // don't prefix for widgets that aren't DOM-based
109
- widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
110
- }, proxiedPrototype, {
111
- constructor: constructor,
112
- namespace: namespace,
113
- widgetName: name,
114
- widgetFullName: fullName
115
- });
116
-
117
- // If this widget is being redefined then we need to find all widgets that
118
- // are inheriting from it and redefine all of them so that they inherit from
119
- // the new version of this widget. We're essentially trying to replace one
120
- // level in the prototype chain.
121
- if ( existingConstructor ) {
122
- $.each( existingConstructor._childConstructors, function( i, child ) {
123
- var childPrototype = child.prototype;
124
-
125
- // redefine the child widget using the same prototype that was
126
- // originally used, but inherit from the new version of the base
127
- $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
128
- });
129
- // remove the list of existing child constructors from the old constructor
130
- // so the old child constructors can be garbage collected
131
- delete existingConstructor._childConstructors;
132
- } else {
133
- base._childConstructors.push( constructor );
134
- }
135
-
136
- $.widget.bridge( name, constructor );
137
- };
138
-
139
- $.widget.extend = function( target ) {
140
- var input = slice.call( arguments, 1 ),
141
- inputIndex = 0,
142
- inputLength = input.length,
143
- key,
144
- value;
145
- for ( ; inputIndex < inputLength; inputIndex++ ) {
146
- for ( key in input[ inputIndex ] ) {
147
- value = input[ inputIndex ][ key ];
148
- if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
149
- // Clone objects
150
- if ( $.isPlainObject( value ) ) {
151
- target[ key ] = $.isPlainObject( target[ key ] ) ?
152
- $.widget.extend( {}, target[ key ], value ) :
153
- // Don't extend strings, arrays, etc. with objects
154
- $.widget.extend( {}, value );
155
- // Copy everything else by reference
156
- } else {
157
- target[ key ] = value;
158
- }
159
- }
160
- }
161
- }
162
- return target;
163
- };
164
-
165
- $.widget.bridge = function( name, object ) {
166
- var fullName = object.prototype.widgetFullName || name;
167
- $.fn[ name ] = function( options ) {
168
- var isMethodCall = typeof options === "string",
169
- args = slice.call( arguments, 1 ),
170
- returnValue = this;
171
-
172
- // allow multiple hashes to be passed on init
173
- options = !isMethodCall && args.length ?
174
- $.widget.extend.apply( null, [ options ].concat(args) ) :
175
- options;
176
-
177
- if ( isMethodCall ) {
178
- this.each(function() {
179
- var methodValue,
180
- instance = $.data( this, fullName );
181
- if ( !instance ) {
182
- return $.error( "cannot call methods on " + name + " prior to initialization; " +
183
- "attempted to call method '" + options + "'" );
184
- }
185
- if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
186
- return $.error( "no such method '" + options + "' for " + name + " widget instance" );
187
- }
188
- methodValue = instance[ options ].apply( instance, args );
189
- if ( methodValue !== instance && methodValue !== undefined ) {
190
- returnValue = methodValue && methodValue.jquery ?
191
- returnValue.pushStack( methodValue.get() ) :
192
- methodValue;
193
- return false;
194
- }
195
- });
196
- } else {
197
- this.each(function() {
198
- var instance = $.data( this, fullName );
199
- if ( instance ) {
200
- instance.option( options || {} )._init();
201
- } else {
202
- $.data( this, fullName, new object( options, this ) );
203
- }
204
- });
205
- }
206
-
207
- return returnValue;
208
- };
209
- };
210
-
211
- $.Widget = function( /* options, element */ ) {};
212
- $.Widget._childConstructors = [];
213
-
214
- $.Widget.prototype = {
215
- widgetName: "widget",
216
- widgetEventPrefix: "",
217
- defaultElement: "<div>",
218
- options: {
219
- disabled: false,
220
-
221
- // callbacks
222
- create: null
223
- },
224
- _createWidget: function( options, element ) {
225
- element = $( element || this.defaultElement || this )[ 0 ];
226
- this.element = $( element );
227
- this.uuid = uuid++;
228
- this.eventNamespace = "." + this.widgetName + this.uuid;
229
- this.options = $.widget.extend( {},
230
- this.options,
231
- this._getCreateOptions(),
232
- options );
233
-
234
- this.bindings = $();
235
- this.hoverable = $();
236
- this.focusable = $();
237
-
238
- if ( element !== this ) {
239
- $.data( element, this.widgetFullName, this );
240
- this._on( true, this.element, {
241
- remove: function( event ) {
242
- if ( event.target === element ) {
243
- this.destroy();
244
- }
245
- }
246
- });
247
- this.document = $( element.style ?
248
- // element within the document
249
- element.ownerDocument :
250
- // element is window or document
251
- element.document || element );
252
- this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
253
- }
254
-
255
- this._create();
256
- this._trigger( "create", null, this._getCreateEventData() );
257
- this._init();
258
- },
259
- _getCreateOptions: $.noop,
260
- _getCreateEventData: $.noop,
261
- _create: $.noop,
262
- _init: $.noop,
263
-
264
- destroy: function() {
265
- this._destroy();
266
- // we can probably remove the unbind calls in 2.0
267
- // all event bindings should go through this._on()
268
- this.element
269
- .unbind( this.eventNamespace )
270
- // 1.9 BC for #7810
271
- // TODO remove dual storage
272
- .removeData( this.widgetName )
273
- .removeData( this.widgetFullName )
274
- // support: jquery <1.6.3
275
- // http://bugs.jquery.com/ticket/9413
276
- .removeData( $.camelCase( this.widgetFullName ) );
277
- this.widget()
278
- .unbind( this.eventNamespace )
279
- .removeAttr( "aria-disabled" )
280
- .removeClass(
281
- this.widgetFullName + "-disabled " +
282
- "ui-state-disabled" );
283
-
284
- // clean up events and states
285
- this.bindings.unbind( this.eventNamespace );
286
- this.hoverable.removeClass( "ui-state-hover" );
287
- this.focusable.removeClass( "ui-state-focus" );
288
- },
289
- _destroy: $.noop,
290
-
291
- widget: function() {
292
- return this.element;
293
- },
294
-
295
- option: function( key, value ) {
296
- var options = key,
297
- parts,
298
- curOption,
299
- i;
300
-
301
- if ( arguments.length === 0 ) {
302
- // don't return a reference to the internal hash
303
- return $.widget.extend( {}, this.options );
304
- }
305
-
306
- if ( typeof key === "string" ) {
307
- // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
308
- options = {};
309
- parts = key.split( "." );
310
- key = parts.shift();
311
- if ( parts.length ) {
312
- curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
313
- for ( i = 0; i < parts.length - 1; i++ ) {
314
- curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
315
- curOption = curOption[ parts[ i ] ];
316
- }
317
- key = parts.pop();
318
- if ( arguments.length === 1 ) {
319
- return curOption[ key ] === undefined ? null : curOption[ key ];
320
- }
321
- curOption[ key ] = value;
322
- } else {
323
- if ( arguments.length === 1 ) {
324
- return this.options[ key ] === undefined ? null : this.options[ key ];
325
- }
326
- options[ key ] = value;
327
- }
328
- }
329
-
330
- this._setOptions( options );
331
-
332
- return this;
333
- },
334
- _setOptions: function( options ) {
335
- var key;
336
-
337
- for ( key in options ) {
338
- this._setOption( key, options[ key ] );
339
- }
340
-
341
- return this;
342
- },
343
- _setOption: function( key, value ) {
344
- this.options[ key ] = value;
345
-
346
- if ( key === "disabled" ) {
347
- this.widget()
348
- .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
349
- .attr( "aria-disabled", value );
350
- this.hoverable.removeClass( "ui-state-hover" );
351
- this.focusable.removeClass( "ui-state-focus" );
352
- }
353
-
354
- return this;
355
- },
356
-
357
- enable: function() {
358
- return this._setOption( "disabled", false );
359
- },
360
- disable: function() {
361
- return this._setOption( "disabled", true );
362
- },
363
-
364
- _on: function( suppressDisabledCheck, element, handlers ) {
365
- var delegateElement,
366
- instance = this;
367
-
368
- // no suppressDisabledCheck flag, shuffle arguments
369
- if ( typeof suppressDisabledCheck !== "boolean" ) {
370
- handlers = element;
371
- element = suppressDisabledCheck;
372
- suppressDisabledCheck = false;
373
- }
374
-
375
- // no element argument, shuffle and use this.element
376
- if ( !handlers ) {
377
- handlers = element;
378
- element = this.element;
379
- delegateElement = this.widget();
380
- } else {
381
- // accept selectors, DOM elements
382
- element = delegateElement = $( element );
383
- this.bindings = this.bindings.add( element );
384
- }
385
-
386
- $.each( handlers, function( event, handler ) {
387
- function handlerProxy() {
388
- // allow widgets to customize the disabled handling
389
- // - disabled as an array instead of boolean
390
- // - disabled class as method for disabling individual parts
391
- if ( !suppressDisabledCheck &&
392
- ( instance.options.disabled === true ||
393
- $( this ).hasClass( "ui-state-disabled" ) ) ) {
394
- return;
395
- }
396
- return ( typeof handler === "string" ? instance[ handler ] : handler )
397
- .apply( instance, arguments );
398
- }
399
-
400
- // copy the guid so direct unbinding works
401
- if ( typeof handler !== "string" ) {
402
- handlerProxy.guid = handler.guid =
403
- handler.guid || handlerProxy.guid || $.guid++;
404
- }
405
-
406
- var match = event.match( /^(\w+)\s*(.*)$/ ),
407
- eventName = match[1] + instance.eventNamespace,
408
- selector = match[2];
409
- if ( selector ) {
410
- delegateElement.delegate( selector, eventName, handlerProxy );
411
- } else {
412
- element.bind( eventName, handlerProxy );
413
- }
414
- });
415
- },
416
-
417
- _off: function( element, eventName ) {
418
- eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
419
- element.unbind( eventName ).undelegate( eventName );
420
- },
421
-
422
- _delay: function( handler, delay ) {
423
- function handlerProxy() {
424
- return ( typeof handler === "string" ? instance[ handler ] : handler )
425
- .apply( instance, arguments );
426
- }
427
- var instance = this;
428
- return setTimeout( handlerProxy, delay || 0 );
429
- },
430
-
431
- _hoverable: function( element ) {
432
- this.hoverable = this.hoverable.add( element );
433
- this._on( element, {
434
- mouseenter: function( event ) {
435
- $( event.currentTarget ).addClass( "ui-state-hover" );
436
- },
437
- mouseleave: function( event ) {
438
- $( event.currentTarget ).removeClass( "ui-state-hover" );
439
- }
440
- });
441
- },
442
-
443
- _focusable: function( element ) {
444
- this.focusable = this.focusable.add( element );
445
- this._on( element, {
446
- focusin: function( event ) {
447
- $( event.currentTarget ).addClass( "ui-state-focus" );
448
- },
449
- focusout: function( event ) {
450
- $( event.currentTarget ).removeClass( "ui-state-focus" );
451
- }
452
- });
453
- },
454
-
455
- _trigger: function( type, event, data ) {
456
- var prop, orig,
457
- callback = this.options[ type ];
458
-
459
- data = data || {};
460
- event = $.Event( event );
461
- event.type = ( type === this.widgetEventPrefix ?
462
- type :
463
- this.widgetEventPrefix + type ).toLowerCase();
464
- // the original event may come from any element
465
- // so we need to reset the target on the new event
466
- event.target = this.element[ 0 ];
467
-
468
- // copy original event properties over to the new event
469
- orig = event.originalEvent;
470
- if ( orig ) {
471
- for ( prop in orig ) {
472
- if ( !( prop in event ) ) {
473
- event[ prop ] = orig[ prop ];
474
- }
475
- }
476
- }
477
-
478
- this.element.trigger( event, data );
479
- return !( $.isFunction( callback ) &&
480
- callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
481
- event.isDefaultPrevented() );
482
- }
483
- };
484
-
485
- $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
486
- $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
487
- if ( typeof options === "string" ) {
488
- options = { effect: options };
489
- }
490
- var hasOptions,
491
- effectName = !options ?
492
- method :
493
- options === true || typeof options === "number" ?
494
- defaultEffect :
495
- options.effect || defaultEffect;
496
- options = options || {};
497
- if ( typeof options === "number" ) {
498
- options = { duration: options };
499
- }
500
- hasOptions = !$.isEmptyObject( options );
501
- options.complete = callback;
502
- if ( options.delay ) {
503
- element.delay( options.delay );
504
- }
505
- if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
506
- element[ method ]( options );
507
- } else if ( effectName !== method && element[ effectName ] ) {
508
- element[ effectName ]( options.duration, options.easing, callback );
509
- } else {
510
- element.queue(function( next ) {
511
- $( this )[ method ]();
512
- if ( callback ) {
513
- callback.call( element[ 0 ] );
514
- }
515
- next();
516
- });
517
- }
518
- };
519
- });
520
-
521
- })( jQuery );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/jquery-ui.js DELETED
@@ -1,15040 +0,0 @@
1
- /*! jQuery UI - v1.10.4 - 2014-01-17
2
- * http://jqueryui.com
3
- * Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.effect.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js, jquery.ui.menu.js, jquery.ui.position.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js
4
- * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
5
- (function( $, undefined ) {
6
-
7
- var uuid = 0,
8
- runiqueId = /^ui-id-\d+$/;
9
-
10
- // $.ui might exist from components with no dependencies, e.g., $.ui.position
11
- $.ui = $.ui || {};
12
-
13
- $.extend( $.ui, {
14
- version: "1.10.4",
15
-
16
- keyCode: {
17
- BACKSPACE: 8,
18
- COMMA: 188,
19
- DELETE: 46,
20
- DOWN: 40,
21
- END: 35,
22
- ENTER: 13,
23
- ESCAPE: 27,
24
- HOME: 36,
25
- LEFT: 37,
26
- NUMPAD_ADD: 107,
27
- NUMPAD_DECIMAL: 110,
28
- NUMPAD_DIVIDE: 111,
29
- NUMPAD_ENTER: 108,
30
- NUMPAD_MULTIPLY: 106,
31
- NUMPAD_SUBTRACT: 109,
32
- PAGE_DOWN: 34,
33
- PAGE_UP: 33,
34
- PERIOD: 190,
35
- RIGHT: 39,
36
- SPACE: 32,
37
- TAB: 9,
38
- UP: 38
39
- }
40
- });
41
-
42
- // plugins
43
- $.fn.extend({
44
- focus: (function( orig ) {
45
- return function( delay, fn ) {
46
- return typeof delay === "number" ?
47
- this.each(function() {
48
- var elem = this;
49
- setTimeout(function() {
50
- $( elem ).focus();
51
- if ( fn ) {
52
- fn.call( elem );
53
- }
54
- }, delay );
55
- }) :
56
- orig.apply( this, arguments );
57
- };
58
- })( $.fn.focus ),
59
-
60
- scrollParent: function() {
61
- var scrollParent;
62
- if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
63
- scrollParent = this.parents().filter(function() {
64
- return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
65
- }).eq(0);
66
- } else {
67
- scrollParent = this.parents().filter(function() {
68
- return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
69
- }).eq(0);
70
- }
71
-
72
- return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
73
- },
74
-
75
- zIndex: function( zIndex ) {
76
- if ( zIndex !== undefined ) {
77
- return this.css( "zIndex", zIndex );
78
- }
79
-
80
- if ( this.length ) {
81
- var elem = $( this[ 0 ] ), position, value;
82
- while ( elem.length && elem[ 0 ] !== document ) {
83
- // Ignore z-index if position is set to a value where z-index is ignored by the browser
84
- // This makes behavior of this function consistent across browsers
85
- // WebKit always returns auto if the element is positioned
86
- position = elem.css( "position" );
87
- if ( position === "absolute" || position === "relative" || position === "fixed" ) {
88
- // IE returns 0 when zIndex is not specified
89
- // other browsers return a string
90
- // we ignore the case of nested elements with an explicit value of 0
91
- // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
92
- value = parseInt( elem.css( "zIndex" ), 10 );
93
- if ( !isNaN( value ) && value !== 0 ) {
94
- return value;
95
- }
96
- }
97
- elem = elem.parent();
98
- }
99
- }
100
-
101
- return 0;
102
- },
103
-
104
- uniqueId: function() {
105
- return this.each(function() {
106
- if ( !this.id ) {
107
- this.id = "ui-id-" + (++uuid);
108
- }
109
- });
110
- },
111
-
112
- removeUniqueId: function() {
113
- return this.each(function() {
114
- if ( runiqueId.test( this.id ) ) {
115
- $( this ).removeAttr( "id" );
116
- }
117
- });
118
- }
119
- });
120
-
121
- // selectors
122
- function focusable( element, isTabIndexNotNaN ) {
123
- var map, mapName, img,
124
- nodeName = element.nodeName.toLowerCase();
125
- if ( "area" === nodeName ) {
126
- map = element.parentNode;
127
- mapName = map.name;
128
- if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
129
- return false;
130
- }
131
- img = $( "img[usemap=#" + mapName + "]" )[0];
132
- return !!img && visible( img );
133
- }
134
- return ( /input|select|textarea|button|object/.test( nodeName ) ?
135
- !element.disabled :
136
- "a" === nodeName ?
137
- element.href || isTabIndexNotNaN :
138
- isTabIndexNotNaN) &&
139
- // the element and all of its ancestors must be visible
140
- visible( element );
141
- }
142
-
143
- function visible( element ) {
144
- return $.expr.filters.visible( element ) &&
145
- !$( element ).parents().addBack().filter(function() {
146
- return $.css( this, "visibility" ) === "hidden";
147
- }).length;
148
- }
149
-
150
- $.extend( $.expr[ ":" ], {
151
- data: $.expr.createPseudo ?
152
- $.expr.createPseudo(function( dataName ) {
153
- return function( elem ) {
154
- return !!$.data( elem, dataName );
155
- };
156
- }) :
157
- // support: jQuery <1.8
158
- function( elem, i, match ) {
159
- return !!$.data( elem, match[ 3 ] );
160
- },
161
-
162
- focusable: function( element ) {
163
- return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
164
- },
165
-
166
- tabbable: function( element ) {
167
- var tabIndex = $.attr( element, "tabindex" ),
168
- isTabIndexNaN = isNaN( tabIndex );
169
- return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
170
- }
171
- });
172
-
173
- // support: jQuery <1.8
174
- if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
175
- $.each( [ "Width", "Height" ], function( i, name ) {
176
- var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
177
- type = name.toLowerCase(),
178
- orig = {
179
- innerWidth: $.fn.innerWidth,
180
- innerHeight: $.fn.innerHeight,
181
- outerWidth: $.fn.outerWidth,
182
- outerHeight: $.fn.outerHeight
183
- };
184
-
185
- function reduce( elem, size, border, margin ) {
186
- $.each( side, function() {
187
- size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
188
- if ( border ) {
189
- size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
190
- }
191
- if ( margin ) {
192
- size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
193
- }
194
- });
195
- return size;
196
- }
197
-
198
- $.fn[ "inner" + name ] = function( size ) {
199
- if ( size === undefined ) {
200
- return orig[ "inner" + name ].call( this );
201
- }
202
-
203
- return this.each(function() {
204
- $( this ).css( type, reduce( this, size ) + "px" );
205
- });
206
- };
207
-
208
- $.fn[ "outer" + name] = function( size, margin ) {
209
- if ( typeof size !== "number" ) {
210
- return orig[ "outer" + name ].call( this, size );
211
- }
212
-
213
- return this.each(function() {
214
- $( this).css( type, reduce( this, size, true, margin ) + "px" );
215
- });
216
- };
217
- });
218
- }
219
-
220
- // support: jQuery <1.8
221
- if ( !$.fn.addBack ) {
222
- $.fn.addBack = function( selector ) {
223
- return this.add( selector == null ?
224
- this.prevObject : this.prevObject.filter( selector )
225
- );
226
- };
227
- }
228
-
229
- // support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
230
- if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
231
- $.fn.removeData = (function( removeData ) {
232
- return function( key ) {
233
- if ( arguments.length ) {
234
- return removeData.call( this, $.camelCase( key ) );
235
- } else {
236
- return removeData.call( this );
237
- }
238
- };
239
- })( $.fn.removeData );
240
- }
241
-
242
-
243
-
244
-
245
-
246
- // deprecated
247
- $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
248
-
249
- $.support.selectstart = "onselectstart" in document.createElement( "div" );
250
- $.fn.extend({
251
- disableSelection: function() {
252
- return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
253
- ".ui-disableSelection", function( event ) {
254
- event.preventDefault();
255
- });
256
- },
257
-
258
- enableSelection: function() {
259
- return this.unbind( ".ui-disableSelection" );
260
- }
261
- });
262
-
263
- $.extend( $.ui, {
264
- // $.ui.plugin is deprecated. Use $.widget() extensions instead.
265
- plugin: {
266
- add: function( module, option, set ) {
267
- var i,
268
- proto = $.ui[ module ].prototype;
269
- for ( i in set ) {
270
- proto.plugins[ i ] = proto.plugins[ i ] || [];
271
- proto.plugins[ i ].push( [ option, set[ i ] ] );
272
- }
273
- },
274
- call: function( instance, name, args ) {
275
- var i,
276
- set = instance.plugins[ name ];
277
- if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
278
- return;
279
- }
280
-
281
- for ( i = 0; i < set.length; i++ ) {
282
- if ( instance.options[ set[ i ][ 0 ] ] ) {
283
- set[ i ][ 1 ].apply( instance.element, args );
284
- }
285
- }
286
- }
287
- },
288
-
289
- // only used by resizable
290
- hasScroll: function( el, a ) {
291
-
292
- //If overflow is hidden, the element might have extra content, but the user wants to hide it
293
- if ( $( el ).css( "overflow" ) === "hidden") {
294
- return false;
295
- }
296
-
297
- var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
298
- has = false;
299
-
300
- if ( el[ scroll ] > 0 ) {
301
- return true;
302
- }
303
-
304
- // TODO: determine which cases actually cause this to happen
305
- // if the element doesn't have the scroll set, see if it's possible to
306
- // set the scroll
307
- el[ scroll ] = 1;
308
- has = ( el[ scroll ] > 0 );
309
- el[ scroll ] = 0;
310
- return has;
311
- }
312
- });
313
-
314
- })( jQuery );
315
-
316
- (function( $, undefined ) {
317
-
318
- var uuid = 0,
319
- slice = Array.prototype.slice,
320
- _cleanData = $.cleanData;
321
- $.cleanData = function( elems ) {
322
- for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
323
- try {
324
- $( elem ).triggerHandler( "remove" );
325
- // http://bugs.jquery.com/ticket/8235
326
- } catch( e ) {}
327
- }
328
- _cleanData( elems );
329
- };
330
-
331
- $.widget = function( name, base, prototype ) {
332
- var fullName, existingConstructor, constructor, basePrototype,
333
- // proxiedPrototype allows the provided prototype to remain unmodified
334
- // so that it can be used as a mixin for multiple widgets (#8876)
335
- proxiedPrototype = {},
336
- namespace = name.split( "." )[ 0 ];
337
-
338
- name = name.split( "." )[ 1 ];
339
- fullName = namespace + "-" + name;
340
-
341
- if ( !prototype ) {
342
- prototype = base;
343
- base = $.Widget;
344
- }
345
-
346
- // create selector for plugin
347
- $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
348
- return !!$.data( elem, fullName );
349
- };
350
-
351
- $[ namespace ] = $[ namespace ] || {};
352
- existingConstructor = $[ namespace ][ name ];
353
- constructor = $[ namespace ][ name ] = function( options, element ) {
354
- // allow instantiation without "new" keyword
355
- if ( !this._createWidget ) {
356
- return new constructor( options, element );
357
- }
358
-
359
- // allow instantiation without initializing for simple inheritance
360
- // must use "new" keyword (the code above always passes args)
361
- if ( arguments.length ) {
362
- this._createWidget( options, element );
363
- }
364
- };
365
- // extend with the existing constructor to carry over any static properties
366
- $.extend( constructor, existingConstructor, {
367
- version: prototype.version,
368
- // copy the object used to create the prototype in case we need to
369
- // redefine the widget later
370
- _proto: $.extend( {}, prototype ),
371
- // track widgets that inherit from this widget in case this widget is
372
- // redefined after a widget inherits from it
373
- _childConstructors: []
374
- });
375
-
376
- basePrototype = new base();
377
- // we need to make the options hash a property directly on the new instance
378
- // otherwise we'll modify the options hash on the prototype that we're
379
- // inheriting from
380
- basePrototype.options = $.widget.extend( {}, basePrototype.options );
381
- $.each( prototype, function( prop, value ) {
382
- if ( !$.isFunction( value ) ) {
383
- proxiedPrototype[ prop ] = value;
384
- return;
385
- }
386
- proxiedPrototype[ prop ] = (function() {
387
- var _super = function() {
388
- return base.prototype[ prop ].apply( this, arguments );
389
- },
390
- _superApply = function( args ) {
391
- return base.prototype[ prop ].apply( this, args );
392
- };
393
- return function() {
394
- var __super = this._super,
395
- __superApply = this._superApply,
396
- returnValue;
397
-
398
- this._super = _super;
399
- this._superApply = _superApply;
400
-
401
- returnValue = value.apply( this, arguments );
402
-
403
- this._super = __super;
404
- this._superApply = __superApply;
405
-
406
- return returnValue;
407
- };
408
- })();
409
- });
410
- constructor.prototype = $.widget.extend( basePrototype, {
411
- // TODO: remove support for widgetEventPrefix
412
- // always use the name + a colon as the prefix, e.g., draggable:start
413
- // don't prefix for widgets that aren't DOM-based
414
- widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
415
- }, proxiedPrototype, {
416
- constructor: constructor,
417
- namespace: namespace,
418
- widgetName: name,
419
- widgetFullName: fullName
420
- });
421
-
422
- // If this widget is being redefined then we need to find all widgets that
423
- // are inheriting from it and redefine all of them so that they inherit from
424
- // the new version of this widget. We're essentially trying to replace one
425
- // level in the prototype chain.
426
- if ( existingConstructor ) {
427
- $.each( existingConstructor._childConstructors, function( i, child ) {
428
- var childPrototype = child.prototype;
429
-
430
- // redefine the child widget using the same prototype that was
431
- // originally used, but inherit from the new version of the base
432
- $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
433
- });
434
- // remove the list of existing child constructors from the old constructor
435
- // so the old child constructors can be garbage collected
436
- delete existingConstructor._childConstructors;
437
- } else {
438
- base._childConstructors.push( constructor );
439
- }
440
-
441
- $.widget.bridge( name, constructor );
442
- };
443
-
444
- $.widget.extend = function( target ) {
445
- var input = slice.call( arguments, 1 ),
446
- inputIndex = 0,
447
- inputLength = input.length,
448
- key,
449
- value;
450
- for ( ; inputIndex < inputLength; inputIndex++ ) {
451
- for ( key in input[ inputIndex ] ) {
452
- value = input[ inputIndex ][ key ];
453
- if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
454
- // Clone objects
455
- if ( $.isPlainObject( value ) ) {
456
- target[ key ] = $.isPlainObject( target[ key ] ) ?
457
- $.widget.extend( {}, target[ key ], value ) :
458
- // Don't extend strings, arrays, etc. with objects
459
- $.widget.extend( {}, value );
460
- // Copy everything else by reference
461
- } else {
462
- target[ key ] = value;
463
- }
464
- }
465
- }
466
- }
467
- return target;
468
- };
469
-
470
- $.widget.bridge = function( name, object ) {
471
- var fullName = object.prototype.widgetFullName || name;
472
- $.fn[ name ] = function( options ) {
473
- var isMethodCall = typeof options === "string",
474
- args = slice.call( arguments, 1 ),
475
- returnValue = this;
476
-
477
- // allow multiple hashes to be passed on init
478
- options = !isMethodCall && args.length ?
479
- $.widget.extend.apply( null, [ options ].concat(args) ) :
480
- options;
481
-
482
- if ( isMethodCall ) {
483
- this.each(function() {
484
- var methodValue,
485
- instance = $.data( this, fullName );
486
- if ( !instance ) {
487
- return $.error( "cannot call methods on " + name + " prior to initialization; " +
488
- "attempted to call method '" + options + "'" );
489
- }
490
- if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
491
- return $.error( "no such method '" + options + "' for " + name + " widget instance" );
492
- }
493
- methodValue = instance[ options ].apply( instance, args );
494
- if ( methodValue !== instance && methodValue !== undefined ) {
495
- returnValue = methodValue && methodValue.jquery ?
496
- returnValue.pushStack( methodValue.get() ) :
497
- methodValue;
498
- return false;
499
- }
500
- });
501
- } else {
502
- this.each(function() {
503
- var instance = $.data( this, fullName );
504
- if ( instance ) {
505
- instance.option( options || {} )._init();
506
- } else {
507
- $.data( this, fullName, new object( options, this ) );
508
- }
509
- });
510
- }
511
-
512
- return returnValue;
513
- };
514
- };
515
-
516
- $.Widget = function( /* options, element */ ) {};
517
- $.Widget._childConstructors = [];
518
-
519
- $.Widget.prototype = {
520
- widgetName: "widget",
521
- widgetEventPrefix: "",
522
- defaultElement: "<div>",
523
- options: {
524
- disabled: false,
525
-
526
- // callbacks
527
- create: null
528
- },
529
- _createWidget: function( options, element ) {
530
- element = $( element || this.defaultElement || this )[ 0 ];
531
- this.element = $( element );
532
- this.uuid = uuid++;
533
- this.eventNamespace = "." + this.widgetName + this.uuid;
534
- this.options = $.widget.extend( {},
535
- this.options,
536
- this._getCreateOptions(),
537
- options );
538
-
539
- this.bindings = $();
540
- this.hoverable = $();
541
- this.focusable = $();
542
-
543
- if ( element !== this ) {
544
- $.data( element, this.widgetFullName, this );
545
- this._on( true, this.element, {
546
- remove: function( event ) {
547
- if ( event.target === element ) {
548
- this.destroy();
549
- }
550
- }
551
- });
552
- this.document = $( element.style ?
553
- // element within the document
554
- element.ownerDocument :
555
- // element is window or document
556
- element.document || element );
557
- this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
558
- }
559
-
560
- this._create();
561
- this._trigger( "create", null, this._getCreateEventData() );
562
- this._init();
563
- },
564
- _getCreateOptions: $.noop,
565
- _getCreateEventData: $.noop,
566
- _create: $.noop,
567
- _init: $.noop,
568
-
569
- destroy: function() {
570
- this._destroy();
571
- // we can probably remove the unbind calls in 2.0
572
- // all event bindings should go through this._on()
573
- this.element
574
- .unbind( this.eventNamespace )
575
- // 1.9 BC for #7810
576
- // TODO remove dual storage
577
- .removeData( this.widgetName )
578
- .removeData( this.widgetFullName )
579
- // support: jquery <1.6.3
580
- // http://bugs.jquery.com/ticket/9413
581
- .removeData( $.camelCase( this.widgetFullName ) );
582
- this.widget()
583
- .unbind( this.eventNamespace )
584
- .removeAttr( "aria-disabled" )
585
- .removeClass(
586
- this.widgetFullName + "-disabled " +
587
- "ui-state-disabled" );
588
-
589
- // clean up events and states
590
- this.bindings.unbind( this.eventNamespace );
591
- this.hoverable.removeClass( "ui-state-hover" );
592
- this.focusable.removeClass( "ui-state-focus" );
593
- },
594
- _destroy: $.noop,
595
-
596
- widget: function() {
597
- return this.element;
598
- },
599
-
600
- option: function( key, value ) {
601
- var options = key,
602
- parts,
603
- curOption,
604
- i;
605
-
606
- if ( arguments.length === 0 ) {
607
- // don't return a reference to the internal hash
608
- return $.widget.extend( {}, this.options );
609
- }
610
-
611
- if ( typeof key === "string" ) {
612
- // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
613
- options = {};
614
- parts = key.split( "." );
615
- key = parts.shift();
616
- if ( parts.length ) {
617
- curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
618
- for ( i = 0; i < parts.length - 1; i++ ) {
619
- curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
620
- curOption = curOption[ parts[ i ] ];
621
- }
622
- key = parts.pop();
623
- if ( arguments.length === 1 ) {
624
- return curOption[ key ] === undefined ? null : curOption[ key ];
625
- }
626
- curOption[ key ] = value;
627
- } else {
628
- if ( arguments.length === 1 ) {
629
- return this.options[ key ] === undefined ? null : this.options[ key ];
630
- }
631
- options[ key ] = value;
632
- }
633
- }
634
-
635
- this._setOptions( options );
636
-
637
- return this;
638
- },
639
- _setOptions: function( options ) {
640
- var key;
641
-
642
- for ( key in options ) {
643
- this._setOption( key, options[ key ] );
644
- }
645
-
646
- return this;
647
- },
648
- _setOption: function( key, value ) {
649
- this.options[ key ] = value;
650
-
651
- if ( key === "disabled" ) {
652
- this.widget()
653
- .toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
654
- .attr( "aria-disabled", value );
655
- this.hoverable.removeClass( "ui-state-hover" );
656
- this.focusable.removeClass( "ui-state-focus" );
657
- }
658
-
659
- return this;
660
- },
661
-
662
- enable: function() {
663
- return this._setOption( "disabled", false );
664
- },
665
- disable: function() {
666
- return this._setOption( "disabled", true );
667
- },
668
-
669
- _on: function( suppressDisabledCheck, element, handlers ) {
670
- var delegateElement,
671
- instance = this;
672
-
673
- // no suppressDisabledCheck flag, shuffle arguments
674
- if ( typeof suppressDisabledCheck !== "boolean" ) {
675
- handlers = element;
676
- element = suppressDisabledCheck;
677
- suppressDisabledCheck = false;
678
- }
679
-
680
- // no element argument, shuffle and use this.element
681
- if ( !handlers ) {
682
- handlers = element;
683
- element = this.element;
684
- delegateElement = this.widget();
685
- } else {
686
- // accept selectors, DOM elements
687
- element = delegateElement = $( element );
688
- this.bindings = this.bindings.add( element );
689
- }
690
-
691
- $.each( handlers, function( event, handler ) {
692
- function handlerProxy() {
693
- // allow widgets to customize the disabled handling
694
- // - disabled as an array instead of boolean
695
- // - disabled class as method for disabling individual parts
696
- if ( !suppressDisabledCheck &&
697
- ( instance.options.disabled === true ||
698
- $( this ).hasClass( "ui-state-disabled" ) ) ) {
699
- return;
700
- }
701
- return ( typeof handler === "string" ? instance[ handler ] : handler )
702
- .apply( instance, arguments );
703
- }
704
-
705
- // copy the guid so direct unbinding works
706
- if ( typeof handler !== "string" ) {
707
- handlerProxy.guid = handler.guid =
708
- handler.guid || handlerProxy.guid || $.guid++;
709
- }
710
-
711
- var match = event.match( /^(\w+)\s*(.*)$/ ),
712
- eventName = match[1] + instance.eventNamespace,
713
- selector = match[2];
714
- if ( selector ) {
715
- delegateElement.delegate( selector, eventName, handlerProxy );
716
- } else {
717
- element.bind( eventName, handlerProxy );
718
- }
719
- });
720
- },
721
-
722
- _off: function( element, eventName ) {
723
- eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
724
- element.unbind( eventName ).undelegate( eventName );
725
- },
726
-
727
- _delay: function( handler, delay ) {
728
- function handlerProxy() {
729
- return ( typeof handler === "string" ? instance[ handler ] : handler )
730
- .apply( instance, arguments );
731
- }
732
- var instance = this;
733
- return setTimeout( handlerProxy, delay || 0 );
734
- },
735
-
736
- _hoverable: function( element ) {
737
- this.hoverable = this.hoverable.add( element );
738
- this._on( element, {
739
- mouseenter: function( event ) {
740
- $( event.currentTarget ).addClass( "ui-state-hover" );
741
- },
742
- mouseleave: function( event ) {
743
- $( event.currentTarget ).removeClass( "ui-state-hover" );
744
- }
745
- });
746
- },
747
-
748
- _focusable: function( element ) {
749
- this.focusable = this.focusable.add( element );
750
- this._on( element, {
751
- focusin: function( event ) {
752
- $( event.currentTarget ).addClass( "ui-state-focus" );
753
- },
754
- focusout: function( event ) {
755
- $( event.currentTarget ).removeClass( "ui-state-focus" );
756
- }
757
- });
758
- },
759
-
760
- _trigger: function( type, event, data ) {
761
- var prop, orig,
762
- callback = this.options[ type ];
763
-
764
- data = data || {};
765
- event = $.Event( event );
766
- event.type = ( type === this.widgetEventPrefix ?
767
- type :
768
- this.widgetEventPrefix + type ).toLowerCase();
769
- // the original event may come from any element
770
- // so we need to reset the target on the new event
771
- event.target = this.element[ 0 ];
772
-
773
- // copy original event properties over to the new event
774
- orig = event.originalEvent;
775
- if ( orig ) {
776
- for ( prop in orig ) {
777
- if ( !( prop in event ) ) {
778
- event[ prop ] = orig[ prop ];
779
- }
780
- }
781
- }
782
-
783
- this.element.trigger( event, data );
784
- return !( $.isFunction( callback ) &&
785
- callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
786
- event.isDefaultPrevented() );
787
- }
788
- };
789
-
790
- $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
791
- $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
792
- if ( typeof options === "string" ) {
793
- options = { effect: options };
794
- }
795
- var hasOptions,
796
- effectName = !options ?
797
- method :
798
- options === true || typeof options === "number" ?
799
- defaultEffect :
800
- options.effect || defaultEffect;
801
- options = options || {};
802
- if ( typeof options === "number" ) {
803
- options = { duration: options };
804
- }
805
- hasOptions = !$.isEmptyObject( options );
806
- options.complete = callback;
807
- if ( options.delay ) {
808
- element.delay( options.delay );
809
- }
810
- if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
811
- element[ method ]( options );
812
- } else if ( effectName !== method && element[ effectName ] ) {
813
- element[ effectName ]( options.duration, options.easing, callback );
814
- } else {
815
- element.queue(function( next ) {
816
- $( this )[ method ]();
817
- if ( callback ) {
818
- callback.call( element[ 0 ] );
819
- }
820
- next();
821
- });
822
- }
823
- };
824
- });
825
-
826
- })( jQuery );
827
-
828
- (function( $, undefined ) {
829
-
830
- var mouseHandled = false;
831
- $( document ).mouseup( function() {
832
- mouseHandled = false;
833
- });
834
-
835
- $.widget("ui.mouse", {
836
- version: "1.10.4",
837
- options: {
838
- cancel: "input,textarea,button,select,option",
839
- distance: 1,
840
- delay: 0
841
- },
842
- _mouseInit: function() {
843
- var that = this;
844
-
845
- this.element
846
- .bind("mousedown."+this.widgetName, function(event) {
847
- return that._mouseDown(event);
848
- })
849
- .bind("click."+this.widgetName, function(event) {
850
- if (true === $.data(event.target, that.widgetName + ".preventClickEvent")) {
851
- $.removeData(event.target, that.widgetName + ".preventClickEvent");
852
- event.stopImmediatePropagation();
853
- return false;
854
- }
855
- });
856
-
857
- this.started = false;
858
- },
859
-
860
- // TODO: make sure destroying one instance of mouse doesn't mess with
861
- // other instances of mouse
862
- _mouseDestroy: function() {
863
- this.element.unbind("."+this.widgetName);
864
- if ( this._mouseMoveDelegate ) {
865
- $(document)
866
- .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
867
- .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
868
- }
869
- },
870
-
871
- _mouseDown: function(event) {
872
- // don't let more than one widget handle mouseStart
873
- if( mouseHandled ) { return; }
874
-
875
- // we may have missed mouseup (out of window)
876
- (this._mouseStarted && this._mouseUp(event));
877
-
878
- this._mouseDownEvent = event;
879
-
880
- var that = this,
881
- btnIsLeft = (event.which === 1),
882
- // event.target.nodeName works around a bug in IE 8 with
883
- // disabled inputs (#7620)
884
- elIsCancel = (typeof this.options.cancel === "string" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);
885
- if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
886
- return true;
887
- }
888
-
889
- this.mouseDelayMet = !this.options.delay;
890
- if (!this.mouseDelayMet) {
891
- this._mouseDelayTimer = setTimeout(function() {
892
- that.mouseDelayMet = true;
893
- }, this.options.delay);
894
- }
895
-
896
- if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
897
- this._mouseStarted = (this._mouseStart(event) !== false);
898
- if (!this._mouseStarted) {
899
- event.preventDefault();
900
- return true;
901
- }
902
- }
903
-
904
- // Click event may never have fired (Gecko & Opera)
905
- if (true === $.data(event.target, this.widgetName + ".preventClickEvent")) {
906
- $.removeData(event.target, this.widgetName + ".preventClickEvent");
907
- }
908
-
909
- // these delegates are required to keep context
910
- this._mouseMoveDelegate = function(event) {
911
- return that._mouseMove(event);
912
- };
913
- this._mouseUpDelegate = function(event) {
914
- return that._mouseUp(event);
915
- };
916
- $(document)
917
- .bind("mousemove."+this.widgetName, this._mouseMoveDelegate)
918
- .bind("mouseup."+this.widgetName, this._mouseUpDelegate);
919
-
920
- event.preventDefault();
921
-
922
- mouseHandled = true;
923
- return true;
924
- },
925
-
926
- _mouseMove: function(event) {
927
- // IE mouseup check - mouseup happened when mouse was out of window
928
- if ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {
929
- return this._mouseUp(event);
930
- }
931
-
932
- if (this._mouseStarted) {
933
- this._mouseDrag(event);
934
- return event.preventDefault();
935
- }
936
-
937
- if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
938
- this._mouseStarted =
939
- (this._mouseStart(this._mouseDownEvent, event) !== false);
940
- (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
941
- }
942
-
943
- return !this._mouseStarted;
944
- },
945
-
946
- _mouseUp: function(event) {
947
- $(document)
948
- .unbind("mousemove."+this.widgetName, this._mouseMoveDelegate)
949
- .unbind("mouseup."+this.widgetName, this._mouseUpDelegate);
950
-
951
- if (this._mouseStarted) {
952
- this._mouseStarted = false;
953
-
954
- if (event.target === this._mouseDownEvent.target) {
955
- $.data(event.target, this.widgetName + ".preventClickEvent", true);
956
- }
957
-
958
- this._mouseStop(event);
959
- }
960
-
961
- return false;
962
- },
963
-
964
- _mouseDistanceMet: function(event) {
965
- return (Math.max(
966
- Math.abs(this._mouseDownEvent.pageX - event.pageX),
967
- Math.abs(this._mouseDownEvent.pageY - event.pageY)
968
- ) >= this.options.distance
969
- );
970
- },
971
-
972
- _mouseDelayMet: function(/* event */) {
973
- return this.mouseDelayMet;
974
- },
975
-
976
- // These are placeholder methods, to be overriden by extending plugin
977
- _mouseStart: function(/* event */) {},
978
- _mouseDrag: function(/* event */) {},
979
- _mouseStop: function(/* event */) {},
980
- _mouseCapture: function(/* event */) { return true; }
981
- });
982
-
983
- })(jQuery);
984
-
985
- (function( $, undefined ) {
986
-
987
- $.widget("ui.draggable", $.ui.mouse, {
988
- version: "1.10.4",
989
- widgetEventPrefix: "drag",
990
- options: {
991
- addClasses: true,
992
- appendTo: "parent",
993
- axis: false,
994
- connectToSortable: false,
995
- containment: false,
996
- cursor: "auto",
997
- cursorAt: false,
998
- grid: false,
999
- handle: false,
1000
- helper: "original",
1001
- iframeFix: false,
1002
- opacity: false,
1003
- refreshPositions: false,
1004
- revert: false,
1005
- revertDuration: 500,
1006
- scope: "default",
1007
- scroll: true,
1008
- scrollSensitivity: 20,
1009
- scrollSpeed: 20,
1010
- snap: false,
1011
- snapMode: "both",
1012
- snapTolerance: 20,
1013
- stack: false,
1014
- zIndex: false,
1015
-
1016
- // callbacks
1017
- drag: null,
1018
- start: null,
1019
- stop: null
1020
- },
1021
- _create: function() {
1022
-
1023
- if (this.options.helper === "original" && !(/^(?:r|a|f)/).test(this.element.css("position"))) {
1024
- this.element[0].style.position = "relative";
1025
- }
1026
- if (this.options.addClasses){
1027
- this.element.addClass("ui-draggable");
1028
- }
1029
- if (this.options.disabled){
1030
- this.element.addClass("ui-draggable-disabled");
1031
- }
1032
-
1033
- this._mouseInit();
1034
-
1035
- },
1036
-
1037
- _destroy: function() {
1038
- this.element.removeClass( "ui-draggable ui-draggable-dragging ui-draggable-disabled" );
1039
- this._mouseDestroy();
1040
- },
1041
-
1042
- _mouseCapture: function(event) {
1043
-
1044
- var o = this.options;
1045
-
1046
- // among others, prevent a drag on a resizable-handle
1047
- if (this.helper || o.disabled || $(event.target).closest(".ui-resizable-handle").length > 0) {
1048
- return false;
1049
- }
1050
-
1051
- //Quit if we're not on a valid handle
1052
- this.handle = this._getHandle(event);
1053
- if (!this.handle) {
1054
- return false;
1055
- }
1056
-
1057
- $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {
1058
- $("<div class='ui-draggable-iframeFix' style='background: #fff;'></div>")
1059
- .css({
1060
- width: this.offsetWidth+"px", height: this.offsetHeight+"px",
1061
- position: "absolute", opacity: "0.001", zIndex: 1000
1062
- })
1063
- .css($(this).offset())
1064
- .appendTo("body");
1065
- });
1066
-
1067
- return true;
1068
-
1069
- },
1070
-
1071
- _mouseStart: function(event) {
1072
-
1073
- var o = this.options;
1074
-
1075
- //Create and append the visible helper
1076
- this.helper = this._createHelper(event);
1077
-
1078
- this.helper.addClass("ui-draggable-dragging");
1079
-
1080
- //Cache the helper size
1081
- this._cacheHelperProportions();
1082
-
1083
- //If ddmanager is used for droppables, set the global draggable
1084
- if($.ui.ddmanager) {
1085
- $.ui.ddmanager.current = this;
1086
- }
1087
-
1088
- /*
1089
- * - Position generation -
1090
- * This block generates everything position related - it's the core of draggables.
1091
- */
1092
-
1093
- //Cache the margins of the original element
1094
- this._cacheMargins();
1095
-
1096
- //Store the helper's css position
1097
- this.cssPosition = this.helper.css( "position" );
1098
- this.scrollParent = this.helper.scrollParent();
1099
- this.offsetParent = this.helper.offsetParent();
1100
- this.offsetParentCssPosition = this.offsetParent.css( "position" );
1101
-
1102
- //The element's absolute position on the page minus margins
1103
- this.offset = this.positionAbs = this.element.offset();
1104
- this.offset = {
1105
- top: this.offset.top - this.margins.top,
1106
- left: this.offset.left - this.margins.left
1107
- };
1108
-
1109
- //Reset scroll cache
1110
- this.offset.scroll = false;
1111
-
1112
- $.extend(this.offset, {
1113
- click: { //Where the click happened, relative to the element
1114
- left: event.pageX - this.offset.left,
1115
- top: event.pageY - this.offset.top
1116
- },
1117
- parent: this._getParentOffset(),
1118
- relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
1119
- });
1120
-
1121
- //Generate the original position
1122
- this.originalPosition = this.position = this._generatePosition(event);
1123
- this.originalPageX = event.pageX;
1124
- this.originalPageY = event.pageY;
1125
-
1126
- //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1127
- (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
1128
-
1129
- //Set a containment if given in the options
1130
- this._setContainment();
1131
-
1132
- //Trigger event + callbacks
1133
- if(this._trigger("start", event) === false) {
1134
- this._clear();
1135
- return false;
1136
- }
1137
-
1138
- //Recache the helper size
1139
- this._cacheHelperProportions();
1140
-
1141
- //Prepare the droppable offsets
1142
- if ($.ui.ddmanager && !o.dropBehaviour) {
1143
- $.ui.ddmanager.prepareOffsets(this, event);
1144
- }
1145
-
1146
-
1147
- this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position
1148
-
1149
- //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
1150
- if ( $.ui.ddmanager ) {
1151
- $.ui.ddmanager.dragStart(this, event);
1152
- }
1153
-
1154
- return true;
1155
- },
1156
-
1157
- _mouseDrag: function(event, noPropagation) {
1158
- // reset any necessary cached properties (see #5009)
1159
- if ( this.offsetParentCssPosition === "fixed" ) {
1160
- this.offset.parent = this._getParentOffset();
1161
- }
1162
-
1163
- //Compute the helpers position
1164
- this.position = this._generatePosition(event);
1165
- this.positionAbs = this._convertPositionTo("absolute");
1166
-
1167
- //Call plugins and callbacks and use the resulting position if something is returned
1168
- if (!noPropagation) {
1169
- var ui = this._uiHash();
1170
- if(this._trigger("drag", event, ui) === false) {
1171
- this._mouseUp({});
1172
- return false;
1173
- }
1174
- this.position = ui.position;
1175
- }
1176
-
1177
- if(!this.options.axis || this.options.axis !== "y") {
1178
- this.helper[0].style.left = this.position.left+"px";
1179
- }
1180
- if(!this.options.axis || this.options.axis !== "x") {
1181
- this.helper[0].style.top = this.position.top+"px";
1182
- }
1183
- if($.ui.ddmanager) {
1184
- $.ui.ddmanager.drag(this, event);
1185
- }
1186
-
1187
- return false;
1188
- },
1189
-
1190
- _mouseStop: function(event) {
1191
-
1192
- //If we are using droppables, inform the manager about the drop
1193
- var that = this,
1194
- dropped = false;
1195
- if ($.ui.ddmanager && !this.options.dropBehaviour) {
1196
- dropped = $.ui.ddmanager.drop(this, event);
1197
- }
1198
-
1199
- //if a drop comes from outside (a sortable)
1200
- if(this.dropped) {
1201
- dropped = this.dropped;
1202
- this.dropped = false;
1203
- }
1204
-
1205
- //if the original element is no longer in the DOM don't bother to continue (see #8269)
1206
- if ( this.options.helper === "original" && !$.contains( this.element[ 0 ].ownerDocument, this.element[ 0 ] ) ) {
1207
- return false;
1208
- }
1209
-
1210
- if((this.options.revert === "invalid" && !dropped) || (this.options.revert === "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {
1211
- $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {
1212
- if(that._trigger("stop", event) !== false) {
1213
- that._clear();
1214
- }
1215
- });
1216
- } else {
1217
- if(this._trigger("stop", event) !== false) {
1218
- this._clear();
1219
- }
1220
- }
1221
-
1222
- return false;
1223
- },
1224
-
1225
- _mouseUp: function(event) {
1226
- //Remove frame helpers
1227
- $("div.ui-draggable-iframeFix").each(function() {
1228
- this.parentNode.removeChild(this);
1229
- });
1230
-
1231
- //If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)
1232
- if( $.ui.ddmanager ) {
1233
- $.ui.ddmanager.dragStop(this, event);
1234
- }
1235
-
1236
- return $.ui.mouse.prototype._mouseUp.call(this, event);
1237
- },
1238
-
1239
- cancel: function() {
1240
-
1241
- if(this.helper.is(".ui-draggable-dragging")) {
1242
- this._mouseUp({});
1243
- } else {
1244
- this._clear();
1245
- }
1246
-
1247
- return this;
1248
-
1249
- },
1250
-
1251
- _getHandle: function(event) {
1252
- return this.options.handle ?
1253
- !!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1254
- true;
1255
- },
1256
-
1257
- _createHelper: function(event) {
1258
-
1259
- var o = this.options,
1260
- helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper === "clone" ? this.element.clone().removeAttr("id") : this.element);
1261
-
1262
- if(!helper.parents("body").length) {
1263
- helper.appendTo((o.appendTo === "parent" ? this.element[0].parentNode : o.appendTo));
1264
- }
1265
-
1266
- if(helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css("position"))) {
1267
- helper.css("position", "absolute");
1268
- }
1269
-
1270
- return helper;
1271
-
1272
- },
1273
-
1274
- _adjustOffsetFromHelper: function(obj) {
1275
- if (typeof obj === "string") {
1276
- obj = obj.split(" ");
1277
- }
1278
- if ($.isArray(obj)) {
1279
- obj = {left: +obj[0], top: +obj[1] || 0};
1280
- }
1281
- if ("left" in obj) {
1282
- this.offset.click.left = obj.left + this.margins.left;
1283
- }
1284
- if ("right" in obj) {
1285
- this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1286
- }
1287
- if ("top" in obj) {
1288
- this.offset.click.top = obj.top + this.margins.top;
1289
- }
1290
- if ("bottom" in obj) {
1291
- this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1292
- }
1293
- },
1294
-
1295
- _getParentOffset: function() {
1296
-
1297
- //Get the offsetParent and cache its position
1298
- var po = this.offsetParent.offset();
1299
-
1300
- // This is a special case where we need to modify a offset calculated on start, since the following happened:
1301
- // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
1302
- // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
1303
- // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
1304
- if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
1305
- po.left += this.scrollParent.scrollLeft();
1306
- po.top += this.scrollParent.scrollTop();
1307
- }
1308
-
1309
- //This needs to be actually done for all browsers, since pageX/pageY includes this information
1310
- //Ugly IE fix
1311
- if((this.offsetParent[0] === document.body) ||
1312
- (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
1313
- po = { top: 0, left: 0 };
1314
- }
1315
-
1316
- return {
1317
- top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
1318
- left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
1319
- };
1320
-
1321
- },
1322
-
1323
- _getRelativeOffset: function() {
1324
-
1325
- if(this.cssPosition === "relative") {
1326
- var p = this.element.position();
1327
- return {
1328
- top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
1329
- left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
1330
- };
1331
- } else {
1332
- return { top: 0, left: 0 };
1333
- }
1334
-
1335
- },
1336
-
1337
- _cacheMargins: function() {
1338
- this.margins = {
1339
- left: (parseInt(this.element.css("marginLeft"),10) || 0),
1340
- top: (parseInt(this.element.css("marginTop"),10) || 0),
1341
- right: (parseInt(this.element.css("marginRight"),10) || 0),
1342
- bottom: (parseInt(this.element.css("marginBottom"),10) || 0)
1343
- };
1344
- },
1345
-
1346
- _cacheHelperProportions: function() {
1347
- this.helperProportions = {
1348
- width: this.helper.outerWidth(),
1349
- height: this.helper.outerHeight()
1350
- };
1351
- },
1352
-
1353
- _setContainment: function() {
1354
-
1355
- var over, c, ce,
1356
- o = this.options;
1357
-
1358
- if ( !o.containment ) {
1359
- this.containment = null;
1360
- return;
1361
- }
1362
-
1363
- if ( o.containment === "window" ) {
1364
- this.containment = [
1365
- $( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1366
- $( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1367
- $( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,
1368
- $( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1369
- ];
1370
- return;
1371
- }
1372
-
1373
- if ( o.containment === "document") {
1374
- this.containment = [
1375
- 0,
1376
- 0,
1377
- $( document ).width() - this.helperProportions.width - this.margins.left,
1378
- ( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top
1379
- ];
1380
- return;
1381
- }
1382
-
1383
- if ( o.containment.constructor === Array ) {
1384
- this.containment = o.containment;
1385
- return;
1386
- }
1387
-
1388
- if ( o.containment === "parent" ) {
1389
- o.containment = this.helper[ 0 ].parentNode;
1390
- }
1391
-
1392
- c = $( o.containment );
1393
- ce = c[ 0 ];
1394
-
1395
- if( !ce ) {
1396
- return;
1397
- }
1398
-
1399
- over = c.css( "overflow" ) !== "hidden";
1400
-
1401
- this.containment = [
1402
- ( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
1403
- ( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) + ( parseInt( c.css( "paddingTop" ), 10 ) || 0 ) ,
1404
- ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) - ( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) - this.helperProportions.width - this.margins.left - this.margins.right,
1405
- ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) - ( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) - ( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) - this.helperProportions.height - this.margins.top - this.margins.bottom
1406
- ];
1407
- this.relative_container = c;
1408
- },
1409
-
1410
- _convertPositionTo: function(d, pos) {
1411
-
1412
- if(!pos) {
1413
- pos = this.position;
1414
- }
1415
-
1416
- var mod = d === "absolute" ? 1 : -1,
1417
- scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent;
1418
-
1419
- //Cache the scroll
1420
- if (!this.offset.scroll) {
1421
- this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1422
- }
1423
-
1424
- return {
1425
- top: (
1426
- pos.top + // The absolute mouse position
1427
- this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
1428
- this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
1429
- ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top ) * mod )
1430
- ),
1431
- left: (
1432
- pos.left + // The absolute mouse position
1433
- this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
1434
- this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
1435
- ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left ) * mod )
1436
- )
1437
- };
1438
-
1439
- },
1440
-
1441
- _generatePosition: function(event) {
1442
-
1443
- var containment, co, top, left,
1444
- o = this.options,
1445
- scroll = this.cssPosition === "absolute" && !( this.scrollParent[ 0 ] !== document && $.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ? this.offsetParent : this.scrollParent,
1446
- pageX = event.pageX,
1447
- pageY = event.pageY;
1448
-
1449
- //Cache the scroll
1450
- if (!this.offset.scroll) {
1451
- this.offset.scroll = {top : scroll.scrollTop(), left : scroll.scrollLeft()};
1452
- }
1453
-
1454
- /*
1455
- * - Position constraining -
1456
- * Constrain the position to a mix of grid, containment.
1457
- */
1458
-
1459
- // If we are not dragging yet, we won't check for options
1460
- if ( this.originalPosition ) {
1461
- if ( this.containment ) {
1462
- if ( this.relative_container ){
1463
- co = this.relative_container.offset();
1464
- containment = [
1465
- this.containment[ 0 ] + co.left,
1466
- this.containment[ 1 ] + co.top,
1467
- this.containment[ 2 ] + co.left,
1468
- this.containment[ 3 ] + co.top
1469
- ];
1470
- }
1471
- else {
1472
- containment = this.containment;
1473
- }
1474
-
1475
- if(event.pageX - this.offset.click.left < containment[0]) {
1476
- pageX = containment[0] + this.offset.click.left;
1477
- }
1478
- if(event.pageY - this.offset.click.top < containment[1]) {
1479
- pageY = containment[1] + this.offset.click.top;
1480
- }
1481
- if(event.pageX - this.offset.click.left > containment[2]) {
1482
- pageX = containment[2] + this.offset.click.left;
1483
- }
1484
- if(event.pageY - this.offset.click.top > containment[3]) {
1485
- pageY = containment[3] + this.offset.click.top;
1486
- }
1487
- }
1488
-
1489
- if(o.grid) {
1490
- //Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)
1491
- top = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;
1492
- pageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
1493
-
1494
- left = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;
1495
- pageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
1496
- }
1497
-
1498
- }
1499
-
1500
- return {
1501
- top: (
1502
- pageY - // The absolute mouse position
1503
- this.offset.click.top - // Click offset (relative to the element)
1504
- this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
1505
- this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
1506
- ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : this.offset.scroll.top )
1507
- ),
1508
- left: (
1509
- pageX - // The absolute mouse position
1510
- this.offset.click.left - // Click offset (relative to the element)
1511
- this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
1512
- this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
1513
- ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : this.offset.scroll.left )
1514
- )
1515
- };
1516
-
1517
- },
1518
-
1519
- _clear: function() {
1520
- this.helper.removeClass("ui-draggable-dragging");
1521
- if(this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {
1522
- this.helper.remove();
1523
- }
1524
- this.helper = null;
1525
- this.cancelHelperRemoval = false;
1526
- },
1527
-
1528
- // From now on bulk stuff - mainly helpers
1529
-
1530
- _trigger: function(type, event, ui) {
1531
- ui = ui || this._uiHash();
1532
- $.ui.plugin.call(this, type, [event, ui]);
1533
- //The absolute position has to be recalculated after plugins
1534
- if(type === "drag") {
1535
- this.positionAbs = this._convertPositionTo("absolute");
1536
- }
1537
- return $.Widget.prototype._trigger.call(this, type, event, ui);
1538
- },
1539
-
1540
- plugins: {},
1541
-
1542
- _uiHash: function() {
1543
- return {
1544
- helper: this.helper,
1545
- position: this.position,
1546
- originalPosition: this.originalPosition,
1547
- offset: this.positionAbs
1548
- };
1549
- }
1550
-
1551
- });
1552
-
1553
- $.ui.plugin.add("draggable", "connectToSortable", {
1554
- start: function(event, ui) {
1555
-
1556
- var inst = $(this).data("ui-draggable"), o = inst.options,
1557
- uiSortable = $.extend({}, ui, { item: inst.element });
1558
- inst.sortables = [];
1559
- $(o.connectToSortable).each(function() {
1560
- var sortable = $.data(this, "ui-sortable");
1561
- if (sortable && !sortable.options.disabled) {
1562
- inst.sortables.push({
1563
- instance: sortable,
1564
- shouldRevert: sortable.options.revert
1565
- });
1566
- sortable.refreshPositions(); // Call the sortable's refreshPositions at drag start to refresh the containerCache since the sortable container cache is used in drag and needs to be up to date (this will ensure it's initialised as well as being kept in step with any changes that might have happened on the page).
1567
- sortable._trigger("activate", event, uiSortable);
1568
- }
1569
- });
1570
-
1571
- },
1572
- stop: function(event, ui) {
1573
-
1574
- //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper
1575
- var inst = $(this).data("ui-draggable"),
1576
- uiSortable = $.extend({}, ui, { item: inst.element });
1577
-
1578
- $.each(inst.sortables, function() {
1579
- if(this.instance.isOver) {
1580
-
1581
- this.instance.isOver = 0;
1582
-
1583
- inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance
1584
- this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)
1585
-
1586
- //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: "valid/invalid"
1587
- if(this.shouldRevert) {
1588
- this.instance.options.revert = this.shouldRevert;
1589
- }
1590
-
1591
- //Trigger the stop of the sortable
1592
- this.instance._mouseStop(event);
1593
-
1594
- this.instance.options.helper = this.instance.options._helper;
1595
-
1596
- //If the helper has been the original item, restore properties in the sortable
1597
- if(inst.options.helper === "original") {
1598
- this.instance.currentItem.css({ top: "auto", left: "auto" });
1599
- }
1600
-
1601
- } else {
1602
- this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance
1603
- this.instance._trigger("deactivate", event, uiSortable);
1604
- }
1605
-
1606
- });
1607
-
1608
- },
1609
- drag: function(event, ui) {
1610
-
1611
- var inst = $(this).data("ui-draggable"), that = this;
1612
-
1613
- $.each(inst.sortables, function() {
1614
-
1615
- var innermostIntersecting = false,
1616
- thisSortable = this;
1617
-
1618
- //Copy over some variables to allow calling the sortable's native _intersectsWith
1619
- this.instance.positionAbs = inst.positionAbs;
1620
- this.instance.helperProportions = inst.helperProportions;
1621
- this.instance.offset.click = inst.offset.click;
1622
-
1623
- if(this.instance._intersectsWith(this.instance.containerCache)) {
1624
- innermostIntersecting = true;
1625
- $.each(inst.sortables, function () {
1626
- this.instance.positionAbs = inst.positionAbs;
1627
- this.instance.helperProportions = inst.helperProportions;
1628
- this.instance.offset.click = inst.offset.click;
1629
- if (this !== thisSortable &&
1630
- this.instance._intersectsWith(this.instance.containerCache) &&
1631
- $.contains(thisSortable.instance.element[0], this.instance.element[0])
1632
- ) {
1633
- innermostIntersecting = false;
1634
- }
1635
- return innermostIntersecting;
1636
- });
1637
- }
1638
-
1639
-
1640
- if(innermostIntersecting) {
1641
- //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once
1642
- if(!this.instance.isOver) {
1643
-
1644
- this.instance.isOver = 1;
1645
- //Now we fake the start of dragging for the sortable instance,
1646
- //by cloning the list group item, appending it to the sortable and using it as inst.currentItem
1647
- //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)
1648
- this.instance.currentItem = $(that).clone().removeAttr("id").appendTo(this.instance.element).data("ui-sortable-item", true);
1649
- this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it
1650
- this.instance.options.helper = function() { return ui.helper[0]; };
1651
-
1652
- event.target = this.instance.currentItem[0];
1653
- this.instance._mouseCapture(event, true);
1654
- this.instance._mouseStart(event, true, true);
1655
-
1656
- //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes
1657
- this.instance.offset.click.top = inst.offset.click.top;
1658
- this.instance.offset.click.left = inst.offset.click.left;
1659
- this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;
1660
- this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;
1661
-
1662
- inst._trigger("toSortable", event);
1663
- inst.dropped = this.instance.element; //draggable revert needs that
1664
- //hack so receive/update callbacks work (mostly)
1665
- inst.currentItem = inst.element;
1666
- this.instance.fromOutside = inst;
1667
-
1668
- }
1669
-
1670
- //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable
1671
- if(this.instance.currentItem) {
1672
- this.instance._mouseDrag(event);
1673
- }
1674
-
1675
- } else {
1676
-
1677
- //If it doesn't intersect with the sortable, and it intersected before,
1678
- //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval
1679
- if(this.instance.isOver) {
1680
-
1681
- this.instance.isOver = 0;
1682
- this.instance.cancelHelperRemoval = true;
1683
-
1684
- //Prevent reverting on this forced stop
1685
- this.instance.options.revert = false;
1686
-
1687
- // The out event needs to be triggered independently
1688
- this.instance._trigger("out", event, this.instance._uiHash(this.instance));
1689
-
1690
- this.instance._mouseStop(event, true);
1691
- this.instance.options.helper = this.instance.options._helper;
1692
-
1693
- //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size
1694
- this.instance.currentItem.remove();
1695
- if(this.instance.placeholder) {
1696
- this.instance.placeholder.remove();
1697
- }
1698
-
1699
- inst._trigger("fromSortable", event);
1700
- inst.dropped = false; //draggable revert needs that
1701
- }
1702
-
1703
- }
1704
-
1705
- });
1706
-
1707
- }
1708
- });
1709
-
1710
- $.ui.plugin.add("draggable", "cursor", {
1711
- start: function() {
1712
- var t = $("body"), o = $(this).data("ui-draggable").options;
1713
- if (t.css("cursor")) {
1714
- o._cursor = t.css("cursor");
1715
- }
1716
- t.css("cursor", o.cursor);
1717
- },
1718
- stop: function() {
1719
- var o = $(this).data("ui-draggable").options;
1720
- if (o._cursor) {
1721
- $("body").css("cursor", o._cursor);
1722
- }
1723
- }
1724
- });
1725
-
1726
- $.ui.plugin.add("draggable", "opacity", {
1727
- start: function(event, ui) {
1728
- var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1729
- if(t.css("opacity")) {
1730
- o._opacity = t.css("opacity");
1731
- }
1732
- t.css("opacity", o.opacity);
1733
- },
1734
- stop: function(event, ui) {
1735
- var o = $(this).data("ui-draggable").options;
1736
- if(o._opacity) {
1737
- $(ui.helper).css("opacity", o._opacity);
1738
- }
1739
- }
1740
- });
1741
-
1742
- $.ui.plugin.add("draggable", "scroll", {
1743
- start: function() {
1744
- var i = $(this).data("ui-draggable");
1745
- if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1746
- i.overflowOffset = i.scrollParent.offset();
1747
- }
1748
- },
1749
- drag: function( event ) {
1750
-
1751
- var i = $(this).data("ui-draggable"), o = i.options, scrolled = false;
1752
-
1753
- if(i.scrollParent[0] !== document && i.scrollParent[0].tagName !== "HTML") {
1754
-
1755
- if(!o.axis || o.axis !== "x") {
1756
- if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
1757
- i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;
1758
- } else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity) {
1759
- i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;
1760
- }
1761
- }
1762
-
1763
- if(!o.axis || o.axis !== "y") {
1764
- if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
1765
- i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;
1766
- } else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity) {
1767
- i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;
1768
- }
1769
- }
1770
-
1771
- } else {
1772
-
1773
- if(!o.axis || o.axis !== "x") {
1774
- if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
1775
- scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
1776
- } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
1777
- scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
1778
- }
1779
- }
1780
-
1781
- if(!o.axis || o.axis !== "y") {
1782
- if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
1783
- scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
1784
- } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
1785
- scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
1786
- }
1787
- }
1788
-
1789
- }
1790
-
1791
- if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
1792
- $.ui.ddmanager.prepareOffsets(i, event);
1793
- }
1794
-
1795
- }
1796
- });
1797
-
1798
- $.ui.plugin.add("draggable", "snap", {
1799
- start: function() {
1800
-
1801
- var i = $(this).data("ui-draggable"),
1802
- o = i.options;
1803
-
1804
- i.snapElements = [];
1805
-
1806
- $(o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap).each(function() {
1807
- var $t = $(this),
1808
- $o = $t.offset();
1809
- if(this !== i.element[0]) {
1810
- i.snapElements.push({
1811
- item: this,
1812
- width: $t.outerWidth(), height: $t.outerHeight(),
1813
- top: $o.top, left: $o.left
1814
- });
1815
- }
1816
- });
1817
-
1818
- },
1819
- drag: function(event, ui) {
1820
-
1821
- var ts, bs, ls, rs, l, r, t, b, i, first,
1822
- inst = $(this).data("ui-draggable"),
1823
- o = inst.options,
1824
- d = o.snapTolerance,
1825
- x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
1826
- y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
1827
-
1828
- for (i = inst.snapElements.length - 1; i >= 0; i--){
1829
-
1830
- l = inst.snapElements[i].left;
1831
- r = l + inst.snapElements[i].width;
1832
- t = inst.snapElements[i].top;
1833
- b = t + inst.snapElements[i].height;
1834
-
1835
- if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {
1836
- if(inst.snapElements[i].snapping) {
1837
- (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1838
- }
1839
- inst.snapElements[i].snapping = false;
1840
- continue;
1841
- }
1842
-
1843
- if(o.snapMode !== "inner") {
1844
- ts = Math.abs(t - y2) <= d;
1845
- bs = Math.abs(b - y1) <= d;
1846
- ls = Math.abs(l - x2) <= d;
1847
- rs = Math.abs(r - x1) <= d;
1848
- if(ts) {
1849
- ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1850
- }
1851
- if(bs) {
1852
- ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;
1853
- }
1854
- if(ls) {
1855
- ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;
1856
- }
1857
- if(rs) {
1858
- ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;
1859
- }
1860
- }
1861
-
1862
- first = (ts || bs || ls || rs);
1863
-
1864
- if(o.snapMode !== "outer") {
1865
- ts = Math.abs(t - y1) <= d;
1866
- bs = Math.abs(b - y2) <= d;
1867
- ls = Math.abs(l - x1) <= d;
1868
- rs = Math.abs(r - x2) <= d;
1869
- if(ts) {
1870
- ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;
1871
- }
1872
- if(bs) {
1873
- ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;
1874
- }
1875
- if(ls) {
1876
- ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;
1877
- }
1878
- if(rs) {
1879
- ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;
1880
- }
1881
- }
1882
-
1883
- if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {
1884
- (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));
1885
- }
1886
- inst.snapElements[i].snapping = (ts || bs || ls || rs || first);
1887
-
1888
- }
1889
-
1890
- }
1891
- });
1892
-
1893
- $.ui.plugin.add("draggable", "stack", {
1894
- start: function() {
1895
- var min,
1896
- o = this.data("ui-draggable").options,
1897
- group = $.makeArray($(o.stack)).sort(function(a,b) {
1898
- return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);
1899
- });
1900
-
1901
- if (!group.length) { return; }
1902
-
1903
- min = parseInt($(group[0]).css("zIndex"), 10) || 0;
1904
- $(group).each(function(i) {
1905
- $(this).css("zIndex", min + i);
1906
- });
1907
- this.css("zIndex", (min + group.length));
1908
- }
1909
- });
1910
-
1911
- $.ui.plugin.add("draggable", "zIndex", {
1912
- start: function(event, ui) {
1913
- var t = $(ui.helper), o = $(this).data("ui-draggable").options;
1914
- if(t.css("zIndex")) {
1915
- o._zIndex = t.css("zIndex");
1916
- }
1917
- t.css("zIndex", o.zIndex);
1918
- },
1919
- stop: function(event, ui) {
1920
- var o = $(this).data("ui-draggable").options;
1921
- if(o._zIndex) {
1922
- $(ui.helper).css("zIndex", o._zIndex);
1923
- }
1924
- }
1925
- });
1926
-
1927
- })(jQuery);
1928
-
1929
- (function( $, undefined ) {
1930
-
1931
- function isOverAxis( x, reference, size ) {
1932
- return ( x > reference ) && ( x < ( reference + size ) );
1933
- }
1934
-
1935
- $.widget("ui.droppable", {
1936
- version: "1.10.4",
1937
- widgetEventPrefix: "drop",
1938
- options: {
1939
- accept: "*",
1940
- activeClass: false,
1941
- addClasses: true,
1942
- greedy: false,
1943
- hoverClass: false,
1944
- scope: "default",
1945
- tolerance: "intersect",
1946
-
1947
- // callbacks
1948
- activate: null,
1949
- deactivate: null,
1950
- drop: null,
1951
- out: null,
1952
- over: null
1953
- },
1954
- _create: function() {
1955
-
1956
- var proportions,
1957
- o = this.options,
1958
- accept = o.accept;
1959
-
1960
- this.isover = false;
1961
- this.isout = true;
1962
-
1963
- this.accept = $.isFunction(accept) ? accept : function(d) {
1964
- return d.is(accept);
1965
- };
1966
-
1967
- this.proportions = function( /* valueToWrite */ ) {
1968
- if ( arguments.length ) {
1969
- // Store the droppable's proportions
1970
- proportions = arguments[ 0 ];
1971
- } else {
1972
- // Retrieve or derive the droppable's proportions
1973
- return proportions ?
1974
- proportions :
1975
- proportions = {
1976
- width: this.element[ 0 ].offsetWidth,
1977
- height: this.element[ 0 ].offsetHeight
1978
- };
1979
- }
1980
- };
1981
-
1982
- // Add the reference and positions to the manager
1983
- $.ui.ddmanager.droppables[o.scope] = $.ui.ddmanager.droppables[o.scope] || [];
1984
- $.ui.ddmanager.droppables[o.scope].push(this);
1985
-
1986
- (o.addClasses && this.element.addClass("ui-droppable"));
1987
-
1988
- },
1989
-
1990
- _destroy: function() {
1991
- var i = 0,
1992
- drop = $.ui.ddmanager.droppables[this.options.scope];
1993
-
1994
- for ( ; i < drop.length; i++ ) {
1995
- if ( drop[i] === this ) {
1996
- drop.splice(i, 1);
1997
- }
1998
- }
1999
-
2000
- this.element.removeClass("ui-droppable ui-droppable-disabled");
2001
- },
2002
-
2003
- _setOption: function(key, value) {
2004
-
2005
- if(key === "accept") {
2006
- this.accept = $.isFunction(value) ? value : function(d) {
2007
- return d.is(value);
2008
- };
2009
- }
2010
- $.Widget.prototype._setOption.apply(this, arguments);
2011
- },
2012
-
2013
- _activate: function(event) {
2014
- var draggable = $.ui.ddmanager.current;
2015
- if(this.options.activeClass) {
2016
- this.element.addClass(this.options.activeClass);
2017
- }
2018
- if(draggable){
2019
- this._trigger("activate", event, this.ui(draggable));
2020
- }
2021
- },
2022
-
2023
- _deactivate: function(event) {
2024
- var draggable = $.ui.ddmanager.current;
2025
- if(this.options.activeClass) {
2026
- this.element.removeClass(this.options.activeClass);
2027
- }
2028
- if(draggable){
2029
- this._trigger("deactivate", event, this.ui(draggable));
2030
- }
2031
- },
2032
-
2033
- _over: function(event) {
2034
-
2035
- var draggable = $.ui.ddmanager.current;
2036
-
2037
- // Bail if draggable and droppable are same element
2038
- if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2039
- return;
2040
- }
2041
-
2042
- if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2043
- if(this.options.hoverClass) {
2044
- this.element.addClass(this.options.hoverClass);
2045
- }
2046
- this._trigger("over", event, this.ui(draggable));
2047
- }
2048
-
2049
- },
2050
-
2051
- _out: function(event) {
2052
-
2053
- var draggable = $.ui.ddmanager.current;
2054
-
2055
- // Bail if draggable and droppable are same element
2056
- if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2057
- return;
2058
- }
2059
-
2060
- if (this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2061
- if(this.options.hoverClass) {
2062
- this.element.removeClass(this.options.hoverClass);
2063
- }
2064
- this._trigger("out", event, this.ui(draggable));
2065
- }
2066
-
2067
- },
2068
-
2069
- _drop: function(event,custom) {
2070
-
2071
- var draggable = custom || $.ui.ddmanager.current,
2072
- childrenIntersection = false;
2073
-
2074
- // Bail if draggable and droppable are same element
2075
- if (!draggable || (draggable.currentItem || draggable.element)[0] === this.element[0]) {
2076
- return false;
2077
- }
2078
-
2079
- this.element.find(":data(ui-droppable)").not(".ui-draggable-dragging").each(function() {
2080
- var inst = $.data(this, "ui-droppable");
2081
- if(
2082
- inst.options.greedy &&
2083
- !inst.options.disabled &&
2084
- inst.options.scope === draggable.options.scope &&
2085
- inst.accept.call(inst.element[0], (draggable.currentItem || draggable.element)) &&
2086
- $.ui.intersect(draggable, $.extend(inst, { offset: inst.element.offset() }), inst.options.tolerance)
2087
- ) { childrenIntersection = true; return false; }
2088
- });
2089
- if(childrenIntersection) {
2090
- return false;
2091
- }
2092
-
2093
- if(this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2094
- if(this.options.activeClass) {
2095
- this.element.removeClass(this.options.activeClass);
2096
- }
2097
- if(this.options.hoverClass) {
2098
- this.element.removeClass(this.options.hoverClass);
2099
- }
2100
- this._trigger("drop", event, this.ui(draggable));
2101
- return this.element;
2102
- }
2103
-
2104
- return false;
2105
-
2106
- },
2107
-
2108
- ui: function(c) {
2109
- return {
2110
- draggable: (c.currentItem || c.element),
2111
- helper: c.helper,
2112
- position: c.position,
2113
- offset: c.positionAbs
2114
- };
2115
- }
2116
-
2117
- });
2118
-
2119
- $.ui.intersect = function(draggable, droppable, toleranceMode) {
2120
-
2121
- if (!droppable.offset) {
2122
- return false;
2123
- }
2124
-
2125
- var draggableLeft, draggableTop,
2126
- x1 = (draggable.positionAbs || draggable.position.absolute).left,
2127
- y1 = (draggable.positionAbs || draggable.position.absolute).top,
2128
- x2 = x1 + draggable.helperProportions.width,
2129
- y2 = y1 + draggable.helperProportions.height,
2130
- l = droppable.offset.left,
2131
- t = droppable.offset.top,
2132
- r = l + droppable.proportions().width,
2133
- b = t + droppable.proportions().height;
2134
-
2135
- switch (toleranceMode) {
2136
- case "fit":
2137
- return (l <= x1 && x2 <= r && t <= y1 && y2 <= b);
2138
- case "intersect":
2139
- return (l < x1 + (draggable.helperProportions.width / 2) && // Right Half
2140
- x2 - (draggable.helperProportions.width / 2) < r && // Left Half
2141
- t < y1 + (draggable.helperProportions.height / 2) && // Bottom Half
2142
- y2 - (draggable.helperProportions.height / 2) < b ); // Top Half
2143
- case "pointer":
2144
- draggableLeft = ((draggable.positionAbs || draggable.position.absolute).left + (draggable.clickOffset || draggable.offset.click).left);
2145
- draggableTop = ((draggable.positionAbs || draggable.position.absolute).top + (draggable.clickOffset || draggable.offset.click).top);
2146
- return isOverAxis( draggableTop, t, droppable.proportions().height ) && isOverAxis( draggableLeft, l, droppable.proportions().width );
2147
- case "touch":
2148
- return (
2149
- (y1 >= t && y1 <= b) || // Top edge touching
2150
- (y2 >= t && y2 <= b) || // Bottom edge touching
2151
- (y1 < t && y2 > b) // Surrounded vertically
2152
- ) && (
2153
- (x1 >= l && x1 <= r) || // Left edge touching
2154
- (x2 >= l && x2 <= r) || // Right edge touching
2155
- (x1 < l && x2 > r) // Surrounded horizontally
2156
- );
2157
- default:
2158
- return false;
2159
- }
2160
-
2161
- };
2162
-
2163
- /*
2164
- This manager tracks offsets of draggables and droppables
2165
- */
2166
- $.ui.ddmanager = {
2167
- current: null,
2168
- droppables: { "default": [] },
2169
- prepareOffsets: function(t, event) {
2170
-
2171
- var i, j,
2172
- m = $.ui.ddmanager.droppables[t.options.scope] || [],
2173
- type = event ? event.type : null, // workaround for #2317
2174
- list = (t.currentItem || t.element).find(":data(ui-droppable)").addBack();
2175
-
2176
- droppablesLoop: for (i = 0; i < m.length; i++) {
2177
-
2178
- //No disabled and non-accepted
2179
- if(m[i].options.disabled || (t && !m[i].accept.call(m[i].element[0],(t.currentItem || t.element)))) {
2180
- continue;
2181
- }
2182
-
2183
- // Filter out elements in the current dragged item
2184
- for (j=0; j < list.length; j++) {
2185
- if(list[j] === m[i].element[0]) {
2186
- m[i].proportions().height = 0;
2187
- continue droppablesLoop;
2188
- }
2189
- }
2190
-
2191
- m[i].visible = m[i].element.css("display") !== "none";
2192
- if(!m[i].visible) {
2193
- continue;
2194
- }
2195
-
2196
- //Activate the droppable if used directly from draggables
2197
- if(type === "mousedown") {
2198
- m[i]._activate.call(m[i], event);
2199
- }
2200
-
2201
- m[ i ].offset = m[ i ].element.offset();
2202
- m[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });
2203
-
2204
- }
2205
-
2206
- },
2207
- drop: function(draggable, event) {
2208
-
2209
- var dropped = false;
2210
- // Create a copy of the droppables in case the list changes during the drop (#9116)
2211
- $.each(($.ui.ddmanager.droppables[draggable.options.scope] || []).slice(), function() {
2212
-
2213
- if(!this.options) {
2214
- return;
2215
- }
2216
- if (!this.options.disabled && this.visible && $.ui.intersect(draggable, this, this.options.tolerance)) {
2217
- dropped = this._drop.call(this, event) || dropped;
2218
- }
2219
-
2220
- if (!this.options.disabled && this.visible && this.accept.call(this.element[0],(draggable.currentItem || draggable.element))) {
2221
- this.isout = true;
2222
- this.isover = false;
2223
- this._deactivate.call(this, event);
2224
- }
2225
-
2226
- });
2227
- return dropped;
2228
-
2229
- },
2230
- dragStart: function( draggable, event ) {
2231
- //Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)
2232
- draggable.element.parentsUntil( "body" ).bind( "scroll.droppable", function() {
2233
- if( !draggable.options.refreshPositions ) {
2234
- $.ui.ddmanager.prepareOffsets( draggable, event );
2235
- }
2236
- });
2237
- },
2238
- drag: function(draggable, event) {
2239
-
2240
- //If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.
2241
- if(draggable.options.refreshPositions) {
2242
- $.ui.ddmanager.prepareOffsets(draggable, event);
2243
- }
2244
-
2245
- //Run through all droppables and check their positions based on specific tolerance options
2246
- $.each($.ui.ddmanager.droppables[draggable.options.scope] || [], function() {
2247
-
2248
- if(this.options.disabled || this.greedyChild || !this.visible) {
2249
- return;
2250
- }
2251
-
2252
- var parentInstance, scope, parent,
2253
- intersects = $.ui.intersect(draggable, this, this.options.tolerance),
2254
- c = !intersects && this.isover ? "isout" : (intersects && !this.isover ? "isover" : null);
2255
- if(!c) {
2256
- return;
2257
- }
2258
-
2259
- if (this.options.greedy) {
2260
- // find droppable parents with same scope
2261
- scope = this.options.scope;
2262
- parent = this.element.parents(":data(ui-droppable)").filter(function () {
2263
- return $.data(this, "ui-droppable").options.scope === scope;
2264
- });
2265
-
2266
- if (parent.length) {
2267
- parentInstance = $.data(parent[0], "ui-droppable");
2268
- parentInstance.greedyChild = (c === "isover");
2269
- }
2270
- }
2271
-
2272
- // we just moved into a greedy child
2273
- if (parentInstance && c === "isover") {
2274
- parentInstance.isover = false;
2275
- parentInstance.isout = true;
2276
- parentInstance._out.call(parentInstance, event);
2277
- }
2278
-
2279
- this[c] = true;
2280
- this[c === "isout" ? "isover" : "isout"] = false;
2281
- this[c === "isover" ? "_over" : "_out"].call(this, event);
2282
-
2283
- // we just moved out of a greedy child
2284
- if (parentInstance && c === "isout") {
2285
- parentInstance.isout = false;
2286
- parentInstance.isover = true;
2287
- parentInstance._over.call(parentInstance, event);
2288
- }
2289
- });
2290
-
2291
- },
2292
- dragStop: function( draggable, event ) {
2293
- draggable.element.parentsUntil( "body" ).unbind( "scroll.droppable" );
2294
- //Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)
2295
- if( !draggable.options.refreshPositions ) {
2296
- $.ui.ddmanager.prepareOffsets( draggable, event );
2297
- }
2298
- }
2299
- };
2300
-
2301
- })(jQuery);
2302
-
2303
- (function( $, undefined ) {
2304
-
2305
- function num(v) {
2306
- return parseInt(v, 10) || 0;
2307
- }
2308
-
2309
- function isNumber(value) {
2310
- return !isNaN(parseInt(value, 10));
2311
- }
2312
-
2313
- $.widget("ui.resizable", $.ui.mouse, {
2314
- version: "1.10.4",
2315
- widgetEventPrefix: "resize",
2316
- options: {
2317
- alsoResize: false,
2318
- animate: false,
2319
- animateDuration: "slow",
2320
- animateEasing: "swing",
2321
- aspectRatio: false,
2322
- autoHide: false,
2323
- containment: false,
2324
- ghost: false,
2325
- grid: false,
2326
- handles: "e,s,se",
2327
- helper: false,
2328
- maxHeight: null,
2329
- maxWidth: null,
2330
- minHeight: 10,
2331
- minWidth: 10,
2332
- // See #7960
2333
- zIndex: 90,
2334
-
2335
- // callbacks
2336
- resize: null,
2337
- start: null,
2338
- stop: null
2339
- },
2340
- _create: function() {
2341
-
2342
- var n, i, handle, axis, hname,
2343
- that = this,
2344
- o = this.options;
2345
- this.element.addClass("ui-resizable");
2346
-
2347
- $.extend(this, {
2348
- _aspectRatio: !!(o.aspectRatio),
2349
- aspectRatio: o.aspectRatio,
2350
- originalElement: this.element,
2351
- _proportionallyResizeElements: [],
2352
- _helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
2353
- });
2354
-
2355
- //Wrap the element if it cannot hold child nodes
2356
- if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)) {
2357
-
2358
- //Create a wrapper element and set the wrapper to the new current internal element
2359
- this.element.wrap(
2360
- $("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({
2361
- position: this.element.css("position"),
2362
- width: this.element.outerWidth(),
2363
- height: this.element.outerHeight(),
2364
- top: this.element.css("top"),
2365
- left: this.element.css("left")
2366
- })
2367
- );
2368
-
2369
- //Overwrite the original this.element
2370
- this.element = this.element.parent().data(
2371
- "ui-resizable", this.element.data("ui-resizable")
2372
- );
2373
-
2374
- this.elementIsWrapper = true;
2375
-
2376
- //Move margins to the wrapper
2377
- this.element.css({ marginLeft: this.originalElement.css("marginLeft"), marginTop: this.originalElement.css("marginTop"), marginRight: this.originalElement.css("marginRight"), marginBottom: this.originalElement.css("marginBottom") });
2378
- this.originalElement.css({ marginLeft: 0, marginTop: 0, marginRight: 0, marginBottom: 0});
2379
-
2380
- //Prevent Safari textarea resize
2381
- this.originalResizeStyle = this.originalElement.css("resize");
2382
- this.originalElement.css("resize", "none");
2383
-
2384
- //Push the actual element to our proportionallyResize internal array
2385
- this._proportionallyResizeElements.push(this.originalElement.css({ position: "static", zoom: 1, display: "block" }));
2386
-
2387
- // avoid IE jump (hard set the margin)
2388
- this.originalElement.css({ margin: this.originalElement.css("margin") });
2389
-
2390
- // fix handlers offset
2391
- this._proportionallyResize();
2392
-
2393
- }
2394
-
2395
- this.handles = o.handles || (!$(".ui-resizable-handle", this.element).length ? "e,s,se" : { n: ".ui-resizable-n", e: ".ui-resizable-e", s: ".ui-resizable-s", w: ".ui-resizable-w", se: ".ui-resizable-se", sw: ".ui-resizable-sw", ne: ".ui-resizable-ne", nw: ".ui-resizable-nw" });
2396
- if(this.handles.constructor === String) {
2397
-
2398
- if ( this.handles === "all") {
2399
- this.handles = "n,e,s,w,se,sw,ne,nw";
2400
- }
2401
-
2402
- n = this.handles.split(",");
2403
- this.handles = {};
2404
-
2405
- for(i = 0; i < n.length; i++) {
2406
-
2407
- handle = $.trim(n[i]);
2408
- hname = "ui-resizable-"+handle;
2409
- axis = $("<div class='ui-resizable-handle " + hname + "'></div>");
2410
-
2411
- // Apply zIndex to all handles - see #7960
2412
- axis.css({ zIndex: o.zIndex });
2413
-
2414
- //TODO : What's going on here?
2415
- if ("se" === handle) {
2416
- axis.addClass("ui-icon ui-icon-gripsmall-diagonal-se");
2417
- }
2418
-
2419
- //Insert into internal handles object and append to element
2420
- this.handles[handle] = ".ui-resizable-"+handle;
2421
- this.element.append(axis);
2422
- }
2423
-
2424
- }
2425
-
2426
- this._renderAxis = function(target) {
2427
-
2428
- var i, axis, padPos, padWrapper;
2429
-
2430
- target = target || this.element;
2431
-
2432
- for(i in this.handles) {
2433
-
2434
- if(this.handles[i].constructor === String) {
2435
- this.handles[i] = $(this.handles[i], this.element).show();
2436
- }
2437
-
2438
- //Apply pad to wrapper element, needed to fix axis position (textarea, inputs, scrolls)
2439
- if (this.elementIsWrapper && this.originalElement[0].nodeName.match(/textarea|input|select|button/i)) {
2440
-
2441
- axis = $(this.handles[i], this.element);
2442
-
2443
- //Checking the correct pad and border
2444
- padWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();
2445
-
2446
- //The padding type i have to apply...
2447
- padPos = [ "padding",
2448
- /ne|nw|n/.test(i) ? "Top" :
2449
- /se|sw|s/.test(i) ? "Bottom" :
2450
- /^e$/.test(i) ? "Right" : "Left" ].join("");
2451
-
2452
- target.css(padPos, padWrapper);
2453
-
2454
- this._proportionallyResize();
2455
-
2456
- }
2457
-
2458
- //TODO: What's that good for? There's not anything to be executed left
2459
- if(!$(this.handles[i]).length) {
2460
- continue;
2461
- }
2462
- }
2463
- };
2464
-
2465
- //TODO: make renderAxis a prototype function
2466
- this._renderAxis(this.element);
2467
-
2468
- this._handles = $(".ui-resizable-handle", this.element)
2469
- .disableSelection();
2470
-
2471
- //Matching axis name
2472
- this._handles.mouseover(function() {
2473
- if (!that.resizing) {
2474
- if (this.className) {
2475
- axis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);
2476
- }
2477
- //Axis, default = se
2478
- that.axis = axis && axis[1] ? axis[1] : "se";
2479
- }
2480
- });
2481
-
2482
- //If we want to auto hide the elements
2483
- if (o.autoHide) {
2484
- this._handles.hide();
2485
- $(this.element)
2486
- .addClass("ui-resizable-autohide")
2487
- .mouseenter(function() {
2488
- if (o.disabled) {
2489
- return;
2490
- }
2491
- $(this).removeClass("ui-resizable-autohide");
2492
- that._handles.show();
2493
- })
2494
- .mouseleave(function(){
2495
- if (o.disabled) {
2496
- return;
2497
- }
2498
- if (!that.resizing) {
2499
- $(this).addClass("ui-resizable-autohide");
2500
- that._handles.hide();
2501
- }
2502
- });
2503
- }
2504
-
2505
- //Initialize the mouse interaction
2506
- this._mouseInit();
2507
-
2508
- },
2509
-
2510
- _destroy: function() {
2511
-
2512
- this._mouseDestroy();
2513
-
2514
- var wrapper,
2515
- _destroy = function(exp) {
2516
- $(exp).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing")
2517
- .removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove();
2518
- };
2519
-
2520
- //TODO: Unwrap at same DOM position
2521
- if (this.elementIsWrapper) {
2522
- _destroy(this.element);
2523
- wrapper = this.element;
2524
- this.originalElement.css({
2525
- position: wrapper.css("position"),
2526
- width: wrapper.outerWidth(),
2527
- height: wrapper.outerHeight(),
2528
- top: wrapper.css("top"),
2529
- left: wrapper.css("left")
2530
- }).insertAfter( wrapper );
2531
- wrapper.remove();
2532
- }
2533
-
2534
- this.originalElement.css("resize", this.originalResizeStyle);
2535
- _destroy(this.originalElement);
2536
-
2537
- return this;
2538
- },
2539
-
2540
- _mouseCapture: function(event) {
2541
- var i, handle,
2542
- capture = false;
2543
-
2544
- for (i in this.handles) {
2545
- handle = $(this.handles[i])[0];
2546
- if (handle === event.target || $.contains(handle, event.target)) {
2547
- capture = true;
2548
- }
2549
- }
2550
-
2551
- return !this.options.disabled && capture;
2552
- },
2553
-
2554
- _mouseStart: function(event) {
2555
-
2556
- var curleft, curtop, cursor,
2557
- o = this.options,
2558
- iniPos = this.element.position(),
2559
- el = this.element;
2560
-
2561
- this.resizing = true;
2562
-
2563
- // bugfix for http://dev.jquery.com/ticket/1749
2564
- if ( (/absolute/).test( el.css("position") ) ) {
2565
- el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
2566
- } else if (el.is(".ui-draggable")) {
2567
- el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
2568
- }
2569
-
2570
- this._renderProxy();
2571
-
2572
- curleft = num(this.helper.css("left"));
2573
- curtop = num(this.helper.css("top"));
2574
-
2575
- if (o.containment) {
2576
- curleft += $(o.containment).scrollLeft() || 0;
2577
- curtop += $(o.containment).scrollTop() || 0;
2578
- }
2579
-
2580
- //Store needed variables
2581
- this.offset = this.helper.offset();
2582
- this.position = { left: curleft, top: curtop };
2583
- this.size = this._helper ? { width: this.helper.width(), height: this.helper.height() } : { width: el.width(), height: el.height() };
2584
- this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
2585
- this.originalPosition = { left: curleft, top: curtop };
2586
- this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
2587
- this.originalMousePosition = { left: event.pageX, top: event.pageY };
2588
-
2589
- //Aspect Ratio
2590
- this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);
2591
-
2592
- cursor = $(".ui-resizable-" + this.axis).css("cursor");
2593
- $("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
2594
-
2595
- el.addClass("ui-resizable-resizing");
2596
- this._propagate("start", event);
2597
- return true;
2598
- },
2599
-
2600
- _mouseDrag: function(event) {
2601
-
2602
- //Increase performance, avoid regex
2603
- var data,
2604
- el = this.helper, props = {},
2605
- smp = this.originalMousePosition,
2606
- a = this.axis,
2607
- prevTop = this.position.top,
2608
- prevLeft = this.position.left,
2609
- prevWidth = this.size.width,
2610
- prevHeight = this.size.height,
2611
- dx = (event.pageX-smp.left)||0,
2612
- dy = (event.pageY-smp.top)||0,
2613
- trigger = this._change[a];
2614
-
2615
- if (!trigger) {
2616
- return false;
2617
- }
2618
-
2619
- // Calculate the attrs that will be change
2620
- data = trigger.apply(this, [event, dx, dy]);
2621
-
2622
- // Put this in the mouseDrag handler since the user can start pressing shift while resizing
2623
- this._updateVirtualBoundaries(event.shiftKey);
2624
- if (this._aspectRatio || event.shiftKey) {
2625
- data = this._updateRatio(data, event);
2626
- }
2627
-
2628
- data = this._respectSize(data, event);
2629
-
2630
- this._updateCache(data);
2631
-
2632
- // plugins callbacks need to be called first
2633
- this._propagate("resize", event);
2634
-
2635
- if (this.position.top !== prevTop) {
2636
- props.top = this.position.top + "px";
2637
- }
2638
- if (this.position.left !== prevLeft) {
2639
- props.left = this.position.left + "px";
2640
- }
2641
- if (this.size.width !== prevWidth) {
2642
- props.width = this.size.width + "px";
2643
- }
2644
- if (this.size.height !== prevHeight) {
2645
- props.height = this.size.height + "px";
2646
- }
2647
- el.css(props);
2648
-
2649
- if (!this._helper && this._proportionallyResizeElements.length) {
2650
- this._proportionallyResize();
2651
- }
2652
-
2653
- // Call the user callback if the element was resized
2654
- if ( ! $.isEmptyObject(props) ) {
2655
- this._trigger("resize", event, this.ui());
2656
- }
2657
-
2658
- return false;
2659
- },
2660
-
2661
- _mouseStop: function(event) {
2662
-
2663
- this.resizing = false;
2664
- var pr, ista, soffseth, soffsetw, s, left, top,
2665
- o = this.options, that = this;
2666
-
2667
- if(this._helper) {
2668
-
2669
- pr = this._proportionallyResizeElements;
2670
- ista = pr.length && (/textarea/i).test(pr[0].nodeName);
2671
- soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
2672
- soffsetw = ista ? 0 : that.sizeDiff.width;
2673
-
2674
- s = { width: (that.helper.width() - soffsetw), height: (that.helper.height() - soffseth) };
2675
- left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
2676
- top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2677
-
2678
- if (!o.animate) {
2679
- this.element.css($.extend(s, { top: top, left: left }));
2680
- }
2681
-
2682
- that.helper.height(that.size.height);
2683
- that.helper.width(that.size.width);
2684
-
2685
- if (this._helper && !o.animate) {
2686
- this._proportionallyResize();
2687
- }
2688
- }
2689
-
2690
- $("body").css("cursor", "auto");
2691
-
2692
- this.element.removeClass("ui-resizable-resizing");
2693
-
2694
- this._propagate("stop", event);
2695
-
2696
- if (this._helper) {
2697
- this.helper.remove();
2698
- }
2699
-
2700
- return false;
2701
-
2702
- },
2703
-
2704
- _updateVirtualBoundaries: function(forceAspectRatio) {
2705
- var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
2706
- o = this.options;
2707
-
2708
- b = {
2709
- minWidth: isNumber(o.minWidth) ? o.minWidth : 0,
2710
- maxWidth: isNumber(o.maxWidth) ? o.maxWidth : Infinity,
2711
- minHeight: isNumber(o.minHeight) ? o.minHeight : 0,
2712
- maxHeight: isNumber(o.maxHeight) ? o.maxHeight : Infinity
2713
- };
2714
-
2715
- if(this._aspectRatio || forceAspectRatio) {
2716
- // We want to create an enclosing box whose aspect ration is the requested one
2717
- // First, compute the "projected" size for each dimension based on the aspect ratio and other dimension
2718
- pMinWidth = b.minHeight * this.aspectRatio;
2719
- pMinHeight = b.minWidth / this.aspectRatio;
2720
- pMaxWidth = b.maxHeight * this.aspectRatio;
2721
- pMaxHeight = b.maxWidth / this.aspectRatio;
2722
-
2723
- if(pMinWidth > b.minWidth) {
2724
- b.minWidth = pMinWidth;
2725
- }
2726
- if(pMinHeight > b.minHeight) {
2727
- b.minHeight = pMinHeight;
2728
- }
2729
- if(pMaxWidth < b.maxWidth) {
2730
- b.maxWidth = pMaxWidth;
2731
- }
2732
- if(pMaxHeight < b.maxHeight) {
2733
- b.maxHeight = pMaxHeight;
2734
- }
2735
- }
2736
- this._vBoundaries = b;
2737
- },
2738
-
2739
- _updateCache: function(data) {
2740
- this.offset = this.helper.offset();
2741
- if (isNumber(data.left)) {
2742
- this.position.left = data.left;
2743
- }
2744
- if (isNumber(data.top)) {
2745
- this.position.top = data.top;
2746
- }
2747
- if (isNumber(data.height)) {
2748
- this.size.height = data.height;
2749
- }
2750
- if (isNumber(data.width)) {
2751
- this.size.width = data.width;
2752
- }
2753
- },
2754
-
2755
- _updateRatio: function( data ) {
2756
-
2757
- var cpos = this.position,
2758
- csize = this.size,
2759
- a = this.axis;
2760
-
2761
- if (isNumber(data.height)) {
2762
- data.width = (data.height * this.aspectRatio);
2763
- } else if (isNumber(data.width)) {
2764
- data.height = (data.width / this.aspectRatio);
2765
- }
2766
-
2767
- if (a === "sw") {
2768
- data.left = cpos.left + (csize.width - data.width);
2769
- data.top = null;
2770
- }
2771
- if (a === "nw") {
2772
- data.top = cpos.top + (csize.height - data.height);
2773
- data.left = cpos.left + (csize.width - data.width);
2774
- }
2775
-
2776
- return data;
2777
- },
2778
-
2779
- _respectSize: function( data ) {
2780
-
2781
- var o = this._vBoundaries,
2782
- a = this.axis,
2783
- ismaxw = isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width), ismaxh = isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),
2784
- isminw = isNumber(data.width) && o.minWidth && (o.minWidth > data.width), isminh = isNumber(data.height) && o.minHeight && (o.minHeight > data.height),
2785
- dw = this.originalPosition.left + this.originalSize.width,
2786
- dh = this.position.top + this.size.height,
2787
- cw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);
2788
- if (isminw) {
2789
- data.width = o.minWidth;
2790
- }
2791
- if (isminh) {
2792
- data.height = o.minHeight;
2793
- }
2794
- if (ismaxw) {
2795
- data.width = o.maxWidth;
2796
- }
2797
- if (ismaxh) {
2798
- data.height = o.maxHeight;
2799
- }
2800
-
2801
- if (isminw && cw) {
2802
- data.left = dw - o.minWidth;
2803
- }
2804
- if (ismaxw && cw) {
2805
- data.left = dw - o.maxWidth;
2806
- }
2807
- if (isminh && ch) {
2808
- data.top = dh - o.minHeight;
2809
- }
2810
- if (ismaxh && ch) {
2811
- data.top = dh - o.maxHeight;
2812
- }
2813
-
2814
- // fixing jump error on top/left - bug #2330
2815
- if (!data.width && !data.height && !data.left && data.top) {
2816
- data.top = null;
2817
- } else if (!data.width && !data.height && !data.top && data.left) {
2818
- data.left = null;
2819
- }
2820
-
2821
- return data;
2822
- },
2823
-
2824
- _proportionallyResize: function() {
2825
-
2826
- if (!this._proportionallyResizeElements.length) {
2827
- return;
2828
- }
2829
-
2830
- var i, j, borders, paddings, prel,
2831
- element = this.helper || this.element;
2832
-
2833
- for ( i=0; i < this._proportionallyResizeElements.length; i++) {
2834
-
2835
- prel = this._proportionallyResizeElements[i];
2836
-
2837
- if (!this.borderDif) {
2838
- this.borderDif = [];
2839
- borders = [prel.css("borderTopWidth"), prel.css("borderRightWidth"), prel.css("borderBottomWidth"), prel.css("borderLeftWidth")];
2840
- paddings = [prel.css("paddingTop"), prel.css("paddingRight"), prel.css("paddingBottom"), prel.css("paddingLeft")];
2841
-
2842
- for ( j = 0; j < borders.length; j++ ) {
2843
- this.borderDif[ j ] = ( parseInt( borders[ j ], 10 ) || 0 ) + ( parseInt( paddings[ j ], 10 ) || 0 );
2844
- }
2845
- }
2846
-
2847
- prel.css({
2848
- height: (element.height() - this.borderDif[0] - this.borderDif[2]) || 0,
2849
- width: (element.width() - this.borderDif[1] - this.borderDif[3]) || 0
2850
- });
2851
-
2852
- }
2853
-
2854
- },
2855
-
2856
- _renderProxy: function() {
2857
-
2858
- var el = this.element, o = this.options;
2859
- this.elementOffset = el.offset();
2860
-
2861
- if(this._helper) {
2862
-
2863
- this.helper = this.helper || $("<div style='overflow:hidden;'></div>");
2864
-
2865
- this.helper.addClass(this._helper).css({
2866
- width: this.element.outerWidth() - 1,
2867
- height: this.element.outerHeight() - 1,
2868
- position: "absolute",
2869
- left: this.elementOffset.left +"px",
2870
- top: this.elementOffset.top +"px",
2871
- zIndex: ++o.zIndex //TODO: Don't modify option
2872
- });
2873
-
2874
- this.helper
2875
- .appendTo("body")
2876
- .disableSelection();
2877
-
2878
- } else {
2879
- this.helper = this.element;
2880
- }
2881
-
2882
- },
2883
-
2884
- _change: {
2885
- e: function(event, dx) {
2886
- return { width: this.originalSize.width + dx };
2887
- },
2888
- w: function(event, dx) {
2889
- var cs = this.originalSize, sp = this.originalPosition;
2890
- return { left: sp.left + dx, width: cs.width - dx };
2891
- },
2892
- n: function(event, dx, dy) {
2893
- var cs = this.originalSize, sp = this.originalPosition;
2894
- return { top: sp.top + dy, height: cs.height - dy };
2895
- },
2896
- s: function(event, dx, dy) {
2897
- return { height: this.originalSize.height + dy };
2898
- },
2899
- se: function(event, dx, dy) {
2900
- return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2901
- },
2902
- sw: function(event, dx, dy) {
2903
- return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2904
- },
2905
- ne: function(event, dx, dy) {
2906
- return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
2907
- },
2908
- nw: function(event, dx, dy) {
2909
- return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
2910
- }
2911
- },
2912
-
2913
- _propagate: function(n, event) {
2914
- $.ui.plugin.call(this, n, [event, this.ui()]);
2915
- (n !== "resize" && this._trigger(n, event, this.ui()));
2916
- },
2917
-
2918
- plugins: {},
2919
-
2920
- ui: function() {
2921
- return {
2922
- originalElement: this.originalElement,
2923
- element: this.element,
2924
- helper: this.helper,
2925
- position: this.position,
2926
- size: this.size,
2927
- originalSize: this.originalSize,
2928
- originalPosition: this.originalPosition
2929
- };
2930
- }
2931
-
2932
- });
2933
-
2934
- /*
2935
- * Resizable Extensions
2936
- */
2937
-
2938
- $.ui.plugin.add("resizable", "animate", {
2939
-
2940
- stop: function( event ) {
2941
- var that = $(this).data("ui-resizable"),
2942
- o = that.options,
2943
- pr = that._proportionallyResizeElements,
2944
- ista = pr.length && (/textarea/i).test(pr[0].nodeName),
2945
- soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height,
2946
- soffsetw = ista ? 0 : that.sizeDiff.width,
2947
- style = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },
2948
- left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null,
2949
- top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;
2950
-
2951
- that.element.animate(
2952
- $.extend(style, top && left ? { top: top, left: left } : {}), {
2953
- duration: o.animateDuration,
2954
- easing: o.animateEasing,
2955
- step: function() {
2956
-
2957
- var data = {
2958
- width: parseInt(that.element.css("width"), 10),
2959
- height: parseInt(that.element.css("height"), 10),
2960
- top: parseInt(that.element.css("top"), 10),
2961
- left: parseInt(that.element.css("left"), 10)
2962
- };
2963
-
2964
- if (pr && pr.length) {
2965
- $(pr[0]).css({ width: data.width, height: data.height });
2966
- }
2967
-
2968
- // propagating resize, and updating values for each animation step
2969
- that._updateCache(data);
2970
- that._propagate("resize", event);
2971
-
2972
- }
2973
- }
2974
- );
2975
- }
2976
-
2977
- });
2978
-
2979
- $.ui.plugin.add("resizable", "containment", {
2980
-
2981
- start: function() {
2982
- var element, p, co, ch, cw, width, height,
2983
- that = $(this).data("ui-resizable"),
2984
- o = that.options,
2985
- el = that.element,
2986
- oc = o.containment,
2987
- ce = (oc instanceof $) ? oc.get(0) : (/parent/.test(oc)) ? el.parent().get(0) : oc;
2988
-
2989
- if (!ce) {
2990
- return;
2991
- }
2992
-
2993
- that.containerElement = $(ce);
2994
-
2995
- if (/document/.test(oc) || oc === document) {
2996
- that.containerOffset = { left: 0, top: 0 };
2997
- that.containerPosition = { left: 0, top: 0 };
2998
-
2999
- that.parentData = {
3000
- element: $(document), left: 0, top: 0,
3001
- width: $(document).width(), height: $(document).height() || document.body.parentNode.scrollHeight
3002
- };
3003
- }
3004
-
3005
- // i'm a node, so compute top, left, right, bottom
3006
- else {
3007
- element = $(ce);
3008
- p = [];
3009
- $([ "Top", "Right", "Left", "Bottom" ]).each(function(i, name) { p[i] = num(element.css("padding" + name)); });
3010
-
3011
- that.containerOffset = element.offset();
3012
- that.containerPosition = element.position();
3013
- that.containerSize = { height: (element.innerHeight() - p[3]), width: (element.innerWidth() - p[1]) };
3014
-
3015
- co = that.containerOffset;
3016
- ch = that.containerSize.height;
3017
- cw = that.containerSize.width;
3018
- width = ($.ui.hasScroll(ce, "left") ? ce.scrollWidth : cw );
3019
- height = ($.ui.hasScroll(ce) ? ce.scrollHeight : ch);
3020
-
3021
- that.parentData = {
3022
- element: ce, left: co.left, top: co.top, width: width, height: height
3023
- };
3024
- }
3025
- },
3026
-
3027
- resize: function( event ) {
3028
- var woset, hoset, isParent, isOffsetRelative,
3029
- that = $(this).data("ui-resizable"),
3030
- o = that.options,
3031
- co = that.containerOffset, cp = that.position,
3032
- pRatio = that._aspectRatio || event.shiftKey,
3033
- cop = { top:0, left:0 }, ce = that.containerElement;
3034
-
3035
- if (ce[0] !== document && (/static/).test(ce.css("position"))) {
3036
- cop = co;
3037
- }
3038
-
3039
- if (cp.left < (that._helper ? co.left : 0)) {
3040
- that.size.width = that.size.width + (that._helper ? (that.position.left - co.left) : (that.position.left - cop.left));
3041
- if (pRatio) {
3042
- that.size.height = that.size.width / that.aspectRatio;
3043
- }
3044
- that.position.left = o.helper ? co.left : 0;
3045
- }
3046
-
3047
- if (cp.top < (that._helper ? co.top : 0)) {
3048
- that.size.height = that.size.height + (that._helper ? (that.position.top - co.top) : that.position.top);
3049
- if (pRatio) {
3050
- that.size.width = that.size.height * that.aspectRatio;
3051
- }
3052
- that.position.top = that._helper ? co.top : 0;
3053
- }
3054
-
3055
- that.offset.left = that.parentData.left+that.position.left;
3056
- that.offset.top = that.parentData.top+that.position.top;
3057
-
3058
- woset = Math.abs( (that._helper ? that.offset.left - cop.left : (that.offset.left - cop.left)) + that.sizeDiff.width );
3059
- hoset = Math.abs( (that._helper ? that.offset.top - cop.top : (that.offset.top - co.top)) + that.sizeDiff.height );
3060
-
3061
- isParent = that.containerElement.get(0) === that.element.parent().get(0);
3062
- isOffsetRelative = /relative|absolute/.test(that.containerElement.css("position"));
3063
-
3064
- if ( isParent && isOffsetRelative ) {
3065
- woset -= Math.abs( that.parentData.left );
3066
- }
3067
-
3068
- if (woset + that.size.width >= that.parentData.width) {
3069
- that.size.width = that.parentData.width - woset;
3070
- if (pRatio) {
3071
- that.size.height = that.size.width / that.aspectRatio;
3072
- }
3073
- }
3074
-
3075
- if (hoset + that.size.height >= that.parentData.height) {
3076
- that.size.height = that.parentData.height - hoset;
3077
- if (pRatio) {
3078
- that.size.width = that.size.height * that.aspectRatio;
3079
- }
3080
- }
3081
- },
3082
-
3083
- stop: function(){
3084
- var that = $(this).data("ui-resizable"),
3085
- o = that.options,
3086
- co = that.containerOffset,
3087
- cop = that.containerPosition,
3088
- ce = that.containerElement,
3089
- helper = $(that.helper),
3090
- ho = helper.offset(),
3091
- w = helper.outerWidth() - that.sizeDiff.width,
3092
- h = helper.outerHeight() - that.sizeDiff.height;
3093
-
3094
- if (that._helper && !o.animate && (/relative/).test(ce.css("position"))) {
3095
- $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3096
- }
3097
-
3098
- if (that._helper && !o.animate && (/static/).test(ce.css("position"))) {
3099
- $(this).css({ left: ho.left - cop.left - co.left, width: w, height: h });
3100
- }
3101
-
3102
- }
3103
- });
3104
-
3105
- $.ui.plugin.add("resizable", "alsoResize", {
3106
-
3107
- start: function () {
3108
- var that = $(this).data("ui-resizable"),
3109
- o = that.options,
3110
- _store = function (exp) {
3111
- $(exp).each(function() {
3112
- var el = $(this);
3113
- el.data("ui-resizable-alsoresize", {
3114
- width: parseInt(el.width(), 10), height: parseInt(el.height(), 10),
3115
- left: parseInt(el.css("left"), 10), top: parseInt(el.css("top"), 10)
3116
- });
3117
- });
3118
- };
3119
-
3120
- if (typeof(o.alsoResize) === "object" && !o.alsoResize.parentNode) {
3121
- if (o.alsoResize.length) { o.alsoResize = o.alsoResize[0]; _store(o.alsoResize); }
3122
- else { $.each(o.alsoResize, function (exp) { _store(exp); }); }
3123
- }else{
3124
- _store(o.alsoResize);
3125
- }
3126
- },
3127
-
3128
- resize: function (event, ui) {
3129
- var that = $(this).data("ui-resizable"),
3130
- o = that.options,
3131
- os = that.originalSize,
3132
- op = that.originalPosition,
3133
- delta = {
3134
- height: (that.size.height - os.height) || 0, width: (that.size.width - os.width) || 0,
3135
- top: (that.position.top - op.top) || 0, left: (that.position.left - op.left) || 0
3136
- },
3137
-
3138
- _alsoResize = function (exp, c) {
3139
- $(exp).each(function() {
3140
- var el = $(this), start = $(this).data("ui-resizable-alsoresize"), style = {},
3141
- css = c && c.length ? c : el.parents(ui.originalElement[0]).length ? ["width", "height"] : ["width", "height", "top", "left"];
3142
-
3143
- $.each(css, function (i, prop) {
3144
- var sum = (start[prop]||0) + (delta[prop]||0);
3145
- if (sum && sum >= 0) {
3146
- style[prop] = sum || null;
3147
- }
3148
- });
3149
-
3150
- el.css(style);
3151
- });
3152
- };
3153
-
3154
- if (typeof(o.alsoResize) === "object" && !o.alsoResize.nodeType) {
3155
- $.each(o.alsoResize, function (exp, c) { _alsoResize(exp, c); });
3156
- }else{
3157
- _alsoResize(o.alsoResize);
3158
- }
3159
- },
3160
-
3161
- stop: function () {
3162
- $(this).removeData("resizable-alsoresize");
3163
- }
3164
- });
3165
-
3166
- $.ui.plugin.add("resizable", "ghost", {
3167
-
3168
- start: function() {
3169
-
3170
- var that = $(this).data("ui-resizable"), o = that.options, cs = that.size;
3171
-
3172
- that.ghost = that.originalElement.clone();
3173
- that.ghost
3174
- .css({ opacity: 0.25, display: "block", position: "relative", height: cs.height, width: cs.width, margin: 0, left: 0, top: 0 })
3175
- .addClass("ui-resizable-ghost")
3176
- .addClass(typeof o.ghost === "string" ? o.ghost : "");
3177
-
3178
- that.ghost.appendTo(that.helper);
3179
-
3180
- },
3181
-
3182
- resize: function(){
3183
- var that = $(this).data("ui-resizable");
3184
- if (that.ghost) {
3185
- that.ghost.css({ position: "relative", height: that.size.height, width: that.size.width });
3186
- }
3187
- },
3188
-
3189
- stop: function() {
3190
- var that = $(this).data("ui-resizable");
3191
- if (that.ghost && that.helper) {
3192
- that.helper.get(0).removeChild(that.ghost.get(0));
3193
- }
3194
- }
3195
-
3196
- });
3197
-
3198
- $.ui.plugin.add("resizable", "grid", {
3199
-
3200
- resize: function() {
3201
- var that = $(this).data("ui-resizable"),
3202
- o = that.options,
3203
- cs = that.size,
3204
- os = that.originalSize,
3205
- op = that.originalPosition,
3206
- a = that.axis,
3207
- grid = typeof o.grid === "number" ? [o.grid, o.grid] : o.grid,
3208
- gridX = (grid[0]||1),
3209
- gridY = (grid[1]||1),
3210
- ox = Math.round((cs.width - os.width) / gridX) * gridX,
3211
- oy = Math.round((cs.height - os.height) / gridY) * gridY,
3212
- newWidth = os.width + ox,
3213
- newHeight = os.height + oy,
3214
- isMaxWidth = o.maxWidth && (o.maxWidth < newWidth),
3215
- isMaxHeight = o.maxHeight && (o.maxHeight < newHeight),
3216
- isMinWidth = o.minWidth && (o.minWidth > newWidth),
3217
- isMinHeight = o.minHeight && (o.minHeight > newHeight);
3218
-
3219
- o.grid = grid;
3220
-
3221
- if (isMinWidth) {
3222
- newWidth = newWidth + gridX;
3223
- }
3224
- if (isMinHeight) {
3225
- newHeight = newHeight + gridY;
3226
- }
3227
- if (isMaxWidth) {
3228
- newWidth = newWidth - gridX;
3229
- }
3230
- if (isMaxHeight) {
3231
- newHeight = newHeight - gridY;
3232
- }
3233
-
3234
- if (/^(se|s|e)$/.test(a)) {
3235
- that.size.width = newWidth;
3236
- that.size.height = newHeight;
3237
- } else if (/^(ne)$/.test(a)) {
3238
- that.size.width = newWidth;
3239
- that.size.height = newHeight;
3240
- that.position.top = op.top - oy;
3241
- } else if (/^(sw)$/.test(a)) {
3242
- that.size.width = newWidth;
3243
- that.size.height = newHeight;
3244
- that.position.left = op.left - ox;
3245
- } else {
3246
- if ( newHeight - gridY > 0 ) {
3247
- that.size.height = newHeight;
3248
- that.position.top = op.top - oy;
3249
- } else {
3250
- that.size.height = gridY;
3251
- that.position.top = op.top + os.height - gridY;
3252
- }
3253
- if ( newWidth - gridX > 0 ) {
3254
- that.size.width = newWidth;
3255
- that.position.left = op.left - ox;
3256
- } else {
3257
- that.size.width = gridX;
3258
- that.position.left = op.left + os.width - gridX;
3259
- }
3260
- }
3261
- }
3262
-
3263
- });
3264
-
3265
- })(jQuery);
3266
-
3267
- (function( $, undefined ) {
3268
-
3269
- $.widget("ui.selectable", $.ui.mouse, {
3270
- version: "1.10.4",
3271
- options: {
3272
- appendTo: "body",
3273
- autoRefresh: true,
3274
- distance: 0,
3275
- filter: "*",
3276
- tolerance: "touch",
3277
-
3278
- // callbacks
3279
- selected: null,
3280
- selecting: null,
3281
- start: null,
3282
- stop: null,
3283
- unselected: null,
3284
- unselecting: null
3285
- },
3286
- _create: function() {
3287
- var selectees,
3288
- that = this;
3289
-
3290
- this.element.addClass("ui-selectable");
3291
-
3292
- this.dragged = false;
3293
-
3294
- // cache selectee children based on filter
3295
- this.refresh = function() {
3296
- selectees = $(that.options.filter, that.element[0]);
3297
- selectees.addClass("ui-selectee");
3298
- selectees.each(function() {
3299
- var $this = $(this),
3300
- pos = $this.offset();
3301
- $.data(this, "selectable-item", {
3302
- element: this,
3303
- $element: $this,
3304
- left: pos.left,
3305
- top: pos.top,
3306
- right: pos.left + $this.outerWidth(),
3307
- bottom: pos.top + $this.outerHeight(),
3308
- startselected: false,
3309
- selected: $this.hasClass("ui-selected"),
3310
- selecting: $this.hasClass("ui-selecting"),
3311
- unselecting: $this.hasClass("ui-unselecting")
3312
- });
3313
- });
3314
- };
3315
- this.refresh();
3316
-
3317
- this.selectees = selectees.addClass("ui-selectee");
3318
-
3319
- this._mouseInit();
3320
-
3321
- this.helper = $("<div class='ui-selectable-helper'></div>");
3322
- },
3323
-
3324
- _destroy: function() {
3325
- this.selectees
3326
- .removeClass("ui-selectee")
3327
- .removeData("selectable-item");
3328
- this.element
3329
- .removeClass("ui-selectable ui-selectable-disabled");
3330
- this._mouseDestroy();
3331
- },
3332
-
3333
- _mouseStart: function(event) {
3334
- var that = this,
3335
- options = this.options;
3336
-
3337
- this.opos = [event.pageX, event.pageY];
3338
-
3339
- if (this.options.disabled) {
3340
- return;
3341
- }
3342
-
3343
- this.selectees = $(options.filter, this.element[0]);
3344
-
3345
- this._trigger("start", event);
3346
-
3347
- $(options.appendTo).append(this.helper);
3348
- // position helper (lasso)
3349
- this.helper.css({
3350
- "left": event.pageX,
3351
- "top": event.pageY,
3352
- "width": 0,
3353
- "height": 0
3354
- });
3355
-
3356
- if (options.autoRefresh) {
3357
- this.refresh();
3358
- }
3359
-
3360
- this.selectees.filter(".ui-selected").each(function() {
3361
- var selectee = $.data(this, "selectable-item");
3362
- selectee.startselected = true;
3363
- if (!event.metaKey && !event.ctrlKey) {
3364
- selectee.$element.removeClass("ui-selected");
3365
- selectee.selected = false;
3366
- selectee.$element.addClass("ui-unselecting");
3367
- selectee.unselecting = true;
3368
- // selectable UNSELECTING callback
3369
- that._trigger("unselecting", event, {
3370
- unselecting: selectee.element
3371
- });
3372
- }
3373
- });
3374
-
3375
- $(event.target).parents().addBack().each(function() {
3376
- var doSelect,
3377
- selectee = $.data(this, "selectable-item");
3378
- if (selectee) {
3379
- doSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass("ui-selected");
3380
- selectee.$element
3381
- .removeClass(doSelect ? "ui-unselecting" : "ui-selected")
3382
- .addClass(doSelect ? "ui-selecting" : "ui-unselecting");
3383
- selectee.unselecting = !doSelect;
3384
- selectee.selecting = doSelect;
3385
- selectee.selected = doSelect;
3386
- // selectable (UN)SELECTING callback
3387
- if (doSelect) {
3388
- that._trigger("selecting", event, {
3389
- selecting: selectee.element
3390
- });
3391
- } else {
3392
- that._trigger("unselecting", event, {
3393
- unselecting: selectee.element
3394
- });
3395
- }
3396
- return false;
3397
- }
3398
- });
3399
-
3400
- },
3401
-
3402
- _mouseDrag: function(event) {
3403
-
3404
- this.dragged = true;
3405
-
3406
- if (this.options.disabled) {
3407
- return;
3408
- }
3409
-
3410
- var tmp,
3411
- that = this,
3412
- options = this.options,
3413
- x1 = this.opos[0],
3414
- y1 = this.opos[1],
3415
- x2 = event.pageX,
3416
- y2 = event.pageY;
3417
-
3418
- if (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }
3419
- if (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }
3420
- this.helper.css({left: x1, top: y1, width: x2-x1, height: y2-y1});
3421
-
3422
- this.selectees.each(function() {
3423
- var selectee = $.data(this, "selectable-item"),
3424
- hit = false;
3425
-
3426
- //prevent helper from being selected if appendTo: selectable
3427
- if (!selectee || selectee.element === that.element[0]) {
3428
- return;
3429
- }
3430
-
3431
- if (options.tolerance === "touch") {
3432
- hit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );
3433
- } else if (options.tolerance === "fit") {
3434
- hit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);
3435
- }
3436
-
3437
- if (hit) {
3438
- // SELECT
3439
- if (selectee.selected) {
3440
- selectee.$element.removeClass("ui-selected");
3441
- selectee.selected = false;
3442
- }
3443
- if (selectee.unselecting) {
3444
- selectee.$element.removeClass("ui-unselecting");
3445
- selectee.unselecting = false;
3446
- }
3447
- if (!selectee.selecting) {
3448
- selectee.$element.addClass("ui-selecting");
3449
- selectee.selecting = true;
3450
- // selectable SELECTING callback
3451
- that._trigger("selecting", event, {
3452
- selecting: selectee.element
3453
- });
3454
- }
3455
- } else {
3456
- // UNSELECT
3457
- if (selectee.selecting) {
3458
- if ((event.metaKey || event.ctrlKey) && selectee.startselected) {
3459
- selectee.$element.removeClass("ui-selecting");
3460
- selectee.selecting = false;
3461
- selectee.$element.addClass("ui-selected");
3462
- selectee.selected = true;
3463
- } else {
3464
- selectee.$element.removeClass("ui-selecting");
3465
- selectee.selecting = false;
3466
- if (selectee.startselected) {
3467
- selectee.$element.addClass("ui-unselecting");
3468
- selectee.unselecting = true;
3469
- }
3470
- // selectable UNSELECTING callback
3471
- that._trigger("unselecting", event, {
3472
- unselecting: selectee.element
3473
- });
3474
- }
3475
- }
3476
- if (selectee.selected) {
3477
- if (!event.metaKey && !event.ctrlKey && !selectee.startselected) {
3478
- selectee.$element.removeClass("ui-selected");
3479
- selectee.selected = false;
3480
-
3481
- selectee.$element.addClass("ui-unselecting");
3482
- selectee.unselecting = true;
3483
- // selectable UNSELECTING callback
3484
- that._trigger("unselecting", event, {
3485
- unselecting: selectee.element
3486
- });
3487
- }
3488
- }
3489
- }
3490
- });
3491
-
3492
- return false;
3493
- },
3494
-
3495
- _mouseStop: function(event) {
3496
- var that = this;
3497
-
3498
- this.dragged = false;
3499
-
3500
- $(".ui-unselecting", this.element[0]).each(function() {
3501
- var selectee = $.data(this, "selectable-item");
3502
- selectee.$element.removeClass("ui-unselecting");
3503
- selectee.unselecting = false;
3504
- selectee.startselected = false;
3505
- that._trigger("unselected", event, {
3506
- unselected: selectee.element
3507
- });
3508
- });
3509
- $(".ui-selecting", this.element[0]).each(function() {
3510
- var selectee = $.data(this, "selectable-item");
3511
- selectee.$element.removeClass("ui-selecting").addClass("ui-selected");
3512
- selectee.selecting = false;
3513
- selectee.selected = true;
3514
- selectee.startselected = true;
3515
- that._trigger("selected", event, {
3516
- selected: selectee.element
3517
- });
3518
- });
3519
- this._trigger("stop", event);
3520
-
3521
- this.helper.remove();
3522
-
3523
- return false;
3524
- }
3525
-
3526
- });
3527
-
3528
- })(jQuery);
3529
-
3530
- (function( $, undefined ) {
3531
-
3532
- function isOverAxis( x, reference, size ) {
3533
- return ( x > reference ) && ( x < ( reference + size ) );
3534
- }
3535
-
3536
- function isFloating(item) {
3537
- return (/left|right/).test(item.css("float")) || (/inline|table-cell/).test(item.css("display"));
3538
- }
3539
-
3540
- $.widget("ui.sortable", $.ui.mouse, {
3541
- version: "1.10.4",
3542
- widgetEventPrefix: "sort",
3543
- ready: false,
3544
- options: {
3545
- appendTo: "parent",
3546
- axis: false,
3547
- connectWith: false,
3548
- containment: false,
3549
- cursor: "auto",
3550
- cursorAt: false,
3551
- dropOnEmpty: true,
3552
- forcePlaceholderSize: false,
3553
- forceHelperSize: false,
3554
- grid: false,
3555
- handle: false,
3556
- helper: "original",
3557
- items: "> *",
3558
- opacity: false,
3559
- placeholder: false,
3560
- revert: false,
3561
- scroll: true,
3562
- scrollSensitivity: 20,
3563
- scrollSpeed: 20,
3564
- scope: "default",
3565
- tolerance: "intersect",
3566
- zIndex: 1000,
3567
-
3568
- // callbacks
3569
- activate: null,
3570
- beforeStop: null,
3571
- change: null,
3572
- deactivate: null,
3573
- out: null,
3574
- over: null,
3575
- receive: null,
3576
- remove: null,
3577
- sort: null,
3578
- start: null,
3579
- stop: null,
3580
- update: null
3581
- },
3582
- _create: function() {
3583
-
3584
- var o = this.options;
3585
- this.containerCache = {};
3586
- this.element.addClass("ui-sortable");
3587
-
3588
- //Get the items
3589
- this.refresh();
3590
-
3591
- //Let's determine if the items are being displayed horizontally
3592
- this.floating = this.items.length ? o.axis === "x" || isFloating(this.items[0].item) : false;
3593
-
3594
- //Let's determine the parent's offset
3595
- this.offset = this.element.offset();
3596
-
3597
- //Initialize mouse events for interaction
3598
- this._mouseInit();
3599
-
3600
- //We're ready to go
3601
- this.ready = true;
3602
-
3603
- },
3604
-
3605
- _destroy: function() {
3606
- this.element
3607
- .removeClass("ui-sortable ui-sortable-disabled");
3608
- this._mouseDestroy();
3609
-
3610
- for ( var i = this.items.length - 1; i >= 0; i-- ) {
3611
- this.items[i].item.removeData(this.widgetName + "-item");
3612
- }
3613
-
3614
- return this;
3615
- },
3616
-
3617
- _setOption: function(key, value){
3618
- if ( key === "disabled" ) {
3619
- this.options[ key ] = value;
3620
-
3621
- this.widget().toggleClass( "ui-sortable-disabled", !!value );
3622
- } else {
3623
- // Don't call widget base _setOption for disable as it adds ui-state-disabled class
3624
- $.Widget.prototype._setOption.apply(this, arguments);
3625
- }
3626
- },
3627
-
3628
- _mouseCapture: function(event, overrideHandle) {
3629
- var currentItem = null,
3630
- validHandle = false,
3631
- that = this;
3632
-
3633
- if (this.reverting) {
3634
- return false;
3635
- }
3636
-
3637
- if(this.options.disabled || this.options.type === "static") {
3638
- return false;
3639
- }
3640
-
3641
- //We have to refresh the items data once first
3642
- this._refreshItems(event);
3643
-
3644
- //Find out if the clicked node (or one of its parents) is a actual item in this.items
3645
- $(event.target).parents().each(function() {
3646
- if($.data(this, that.widgetName + "-item") === that) {
3647
- currentItem = $(this);
3648
- return false;
3649
- }
3650
- });
3651
- if($.data(event.target, that.widgetName + "-item") === that) {
3652
- currentItem = $(event.target);
3653
- }
3654
-
3655
- if(!currentItem) {
3656
- return false;
3657
- }
3658
- if(this.options.handle && !overrideHandle) {
3659
- $(this.options.handle, currentItem).find("*").addBack().each(function() {
3660
- if(this === event.target) {
3661
- validHandle = true;
3662
- }
3663
- });
3664
- if(!validHandle) {
3665
- return false;
3666
- }
3667
- }
3668
-
3669
- this.currentItem = currentItem;
3670
- this._removeCurrentsFromItems();
3671
- return true;
3672
-
3673
- },
3674
-
3675
- _mouseStart: function(event, overrideHandle, noActivation) {
3676
-
3677
- var i, body,
3678
- o = this.options;
3679
-
3680
- this.currentContainer = this;
3681
-
3682
- //We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
3683
- this.refreshPositions();
3684
-
3685
- //Create and append the visible helper
3686
- this.helper = this._createHelper(event);
3687
-
3688
- //Cache the helper size
3689
- this._cacheHelperProportions();
3690
-
3691
- /*
3692
- * - Position generation -
3693
- * This block generates everything position related - it's the core of draggables.
3694
- */
3695
-
3696
- //Cache the margins of the original element
3697
- this._cacheMargins();
3698
-
3699
- //Get the next scrolling parent
3700
- this.scrollParent = this.helper.scrollParent();
3701
-
3702
- //The element's absolute position on the page minus margins
3703
- this.offset = this.currentItem.offset();
3704
- this.offset = {
3705
- top: this.offset.top - this.margins.top,
3706
- left: this.offset.left - this.margins.left
3707
- };
3708
-
3709
- $.extend(this.offset, {
3710
- click: { //Where the click happened, relative to the element
3711
- left: event.pageX - this.offset.left,
3712
- top: event.pageY - this.offset.top
3713
- },
3714
- parent: this._getParentOffset(),
3715
- relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
3716
- });
3717
-
3718
- // Only after we got the offset, we can change the helper's position to absolute
3719
- // TODO: Still need to figure out a way to make relative sorting possible
3720
- this.helper.css("position", "absolute");
3721
- this.cssPosition = this.helper.css("position");
3722
-
3723
- //Generate the original position
3724
- this.originalPosition = this._generatePosition(event);
3725
- this.originalPageX = event.pageX;
3726
- this.originalPageY = event.pageY;
3727
-
3728
- //Adjust the mouse offset relative to the helper if "cursorAt" is supplied
3729
- (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));
3730
-
3731
- //Cache the former DOM position
3732
- this.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };
3733
-
3734
- //If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way
3735
- if(this.helper[0] !== this.currentItem[0]) {
3736
- this.currentItem.hide();
3737
- }
3738
-
3739
- //Create the placeholder
3740
- this._createPlaceholder();
3741
-
3742
- //Set a containment if given in the options
3743
- if(o.containment) {
3744
- this._setContainment();
3745
- }
3746
-
3747
- if( o.cursor && o.cursor !== "auto" ) { // cursor option
3748
- body = this.document.find( "body" );
3749
-
3750
- // support: IE
3751
- this.storedCursor = body.css( "cursor" );
3752
- body.css( "cursor", o.cursor );
3753
-
3754
- this.storedStylesheet = $( "<style>*{ cursor: "+o.cursor+" !important; }</style>" ).appendTo( body );
3755
- }
3756
-
3757
- if(o.opacity) { // opacity option
3758
- if (this.helper.css("opacity")) {
3759
- this._storedOpacity = this.helper.css("opacity");
3760
- }
3761
- this.helper.css("opacity", o.opacity);
3762
- }
3763
-
3764
- if(o.zIndex) { // zIndex option
3765
- if (this.helper.css("zIndex")) {
3766
- this._storedZIndex = this.helper.css("zIndex");
3767
- }
3768
- this.helper.css("zIndex", o.zIndex);
3769
- }
3770
-
3771
- //Prepare scrolling
3772
- if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3773
- this.overflowOffset = this.scrollParent.offset();
3774
- }
3775
-
3776
- //Call callbacks
3777
- this._trigger("start", event, this._uiHash());
3778
-
3779
- //Recache the helper size
3780
- if(!this._preserveHelperProportions) {
3781
- this._cacheHelperProportions();
3782
- }
3783
-
3784
-
3785
- //Post "activate" events to possible containers
3786
- if( !noActivation ) {
3787
- for ( i = this.containers.length - 1; i >= 0; i-- ) {
3788
- this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
3789
- }
3790
- }
3791
-
3792
- //Prepare possible droppables
3793
- if($.ui.ddmanager) {
3794
- $.ui.ddmanager.current = this;
3795
- }
3796
-
3797
- if ($.ui.ddmanager && !o.dropBehaviour) {
3798
- $.ui.ddmanager.prepareOffsets(this, event);
3799
- }
3800
-
3801
- this.dragging = true;
3802
-
3803
- this.helper.addClass("ui-sortable-helper");
3804
- this._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position
3805
- return true;
3806
-
3807
- },
3808
-
3809
- _mouseDrag: function(event) {
3810
- var i, item, itemElement, intersection,
3811
- o = this.options,
3812
- scrolled = false;
3813
-
3814
- //Compute the helpers position
3815
- this.position = this._generatePosition(event);
3816
- this.positionAbs = this._convertPositionTo("absolute");
3817
-
3818
- if (!this.lastPositionAbs) {
3819
- this.lastPositionAbs = this.positionAbs;
3820
- }
3821
-
3822
- //Do scrolling
3823
- if(this.options.scroll) {
3824
- if(this.scrollParent[0] !== document && this.scrollParent[0].tagName !== "HTML") {
3825
-
3826
- if((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {
3827
- this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;
3828
- } else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {
3829
- this.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;
3830
- }
3831
-
3832
- if((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {
3833
- this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;
3834
- } else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {
3835
- this.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;
3836
- }
3837
-
3838
- } else {
3839
-
3840
- if(event.pageY - $(document).scrollTop() < o.scrollSensitivity) {
3841
- scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);
3842
- } else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {
3843
- scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);
3844
- }
3845
-
3846
- if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {
3847
- scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);
3848
- } else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {
3849
- scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);
3850
- }
3851
-
3852
- }
3853
-
3854
- if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {
3855
- $.ui.ddmanager.prepareOffsets(this, event);
3856
- }
3857
- }
3858
-
3859
- //Regenerate the absolute position used for position checks
3860
- this.positionAbs = this._convertPositionTo("absolute");
3861
-
3862
- //Set the helper position
3863
- if(!this.options.axis || this.options.axis !== "y") {
3864
- this.helper[0].style.left = this.position.left+"px";
3865
- }
3866
- if(!this.options.axis || this.options.axis !== "x") {
3867
- this.helper[0].style.top = this.position.top+"px";
3868
- }
3869
-
3870
- //Rearrange
3871
- for (i = this.items.length - 1; i >= 0; i--) {
3872
-
3873
- //Cache variables and intersection, continue if no intersection
3874
- item = this.items[i];
3875
- itemElement = item.item[0];
3876
- intersection = this._intersectsWithPointer(item);
3877
- if (!intersection) {
3878
- continue;
3879
- }
3880
-
3881
- // Only put the placeholder inside the current Container, skip all
3882
- // items from other containers. This works because when moving
3883
- // an item from one container to another the
3884
- // currentContainer is switched before the placeholder is moved.
3885
- //
3886
- // Without this, moving items in "sub-sortables" can cause
3887
- // the placeholder to jitter beetween the outer and inner container.
3888
- if (item.instance !== this.currentContainer) {
3889
- continue;
3890
- }
3891
-
3892
- // cannot intersect with itself
3893
- // no useless actions that have been done before
3894
- // no action if the item moved is the parent of the item checked
3895
- if (itemElement !== this.currentItem[0] &&
3896
- this.placeholder[intersection === 1 ? "next" : "prev"]()[0] !== itemElement &&
3897
- !$.contains(this.placeholder[0], itemElement) &&
3898
- (this.options.type === "semi-dynamic" ? !$.contains(this.element[0], itemElement) : true)
3899
- ) {
3900
-
3901
- this.direction = intersection === 1 ? "down" : "up";
3902
-
3903
- if (this.options.tolerance === "pointer" || this._intersectsWithSides(item)) {
3904
- this._rearrange(event, item);
3905
- } else {
3906
- break;
3907
- }
3908
-
3909
- this._trigger("change", event, this._uiHash());
3910
- break;
3911
- }
3912
- }
3913
-
3914
- //Post events to containers
3915
- this._contactContainers(event);
3916
-
3917
- //Interconnect with droppables
3918
- if($.ui.ddmanager) {
3919
- $.ui.ddmanager.drag(this, event);
3920
- }
3921
-
3922
- //Call callbacks
3923
- this._trigger("sort", event, this._uiHash());
3924
-
3925
- this.lastPositionAbs = this.positionAbs;
3926
- return false;
3927
-
3928
- },
3929
-
3930
- _mouseStop: function(event, noPropagation) {
3931
-
3932
- if(!event) {
3933
- return;
3934
- }
3935
-
3936
- //If we are using droppables, inform the manager about the drop
3937
- if ($.ui.ddmanager && !this.options.dropBehaviour) {
3938
- $.ui.ddmanager.drop(this, event);
3939
- }
3940
-
3941
- if(this.options.revert) {
3942
- var that = this,
3943
- cur = this.placeholder.offset(),
3944
- axis = this.options.axis,
3945
- animation = {};
3946
-
3947
- if ( !axis || axis === "x" ) {
3948
- animation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollLeft);
3949
- }
3950
- if ( !axis || axis === "y" ) {
3951
- animation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === document.body ? 0 : this.offsetParent[0].scrollTop);
3952
- }
3953
- this.reverting = true;
3954
- $(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {
3955
- that._clear(event);
3956
- });
3957
- } else {
3958
- this._clear(event, noPropagation);
3959
- }
3960
-
3961
- return false;
3962
-
3963
- },
3964
-
3965
- cancel: function() {
3966
-
3967
- if(this.dragging) {
3968
-
3969
- this._mouseUp({ target: null });
3970
-
3971
- if(this.options.helper === "original") {
3972
- this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
3973
- } else {
3974
- this.currentItem.show();
3975
- }
3976
-
3977
- //Post deactivating events to containers
3978
- for (var i = this.containers.length - 1; i >= 0; i--){
3979
- this.containers[i]._trigger("deactivate", null, this._uiHash(this));
3980
- if(this.containers[i].containerCache.over) {
3981
- this.containers[i]._trigger("out", null, this._uiHash(this));
3982
- this.containers[i].containerCache.over = 0;
3983
- }
3984
- }
3985
-
3986
- }
3987
-
3988
- if (this.placeholder) {
3989
- //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
3990
- if(this.placeholder[0].parentNode) {
3991
- this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
3992
- }
3993
- if(this.options.helper !== "original" && this.helper && this.helper[0].parentNode) {
3994
- this.helper.remove();
3995
- }
3996
-
3997
- $.extend(this, {
3998
- helper: null,
3999
- dragging: false,
4000
- reverting: false,
4001
- _noFinalSort: null
4002
- });
4003
-
4004
- if(this.domPosition.prev) {
4005
- $(this.domPosition.prev).after(this.currentItem);
4006
- } else {
4007
- $(this.domPosition.parent).prepend(this.currentItem);
4008
- }
4009
- }
4010
-
4011
- return this;
4012
-
4013
- },
4014
-
4015
- serialize: function(o) {
4016
-
4017
- var items = this._getItemsAsjQuery(o && o.connected),
4018
- str = [];
4019
- o = o || {};
4020
-
4021
- $(items).each(function() {
4022
- var res = ($(o.item || this).attr(o.attribute || "id") || "").match(o.expression || (/(.+)[\-=_](.+)/));
4023
- if (res) {
4024
- str.push((o.key || res[1]+"[]")+"="+(o.key && o.expression ? res[1] : res[2]));
4025
- }
4026
- });
4027
-
4028
- if(!str.length && o.key) {
4029
- str.push(o.key + "=");
4030
- }
4031
-
4032
- return str.join("&");
4033
-
4034
- },
4035
-
4036
- toArray: function(o) {
4037
-
4038
- var items = this._getItemsAsjQuery(o && o.connected),
4039
- ret = [];
4040
-
4041
- o = o || {};
4042
-
4043
- items.each(function() { ret.push($(o.item || this).attr(o.attribute || "id") || ""); });
4044
- return ret;
4045
-
4046
- },
4047
-
4048
- /* Be careful with the following core functions */
4049
- _intersectsWith: function(item) {
4050
-
4051
- var x1 = this.positionAbs.left,
4052
- x2 = x1 + this.helperProportions.width,
4053
- y1 = this.positionAbs.top,
4054
- y2 = y1 + this.helperProportions.height,
4055
- l = item.left,
4056
- r = l + item.width,
4057
- t = item.top,
4058
- b = t + item.height,
4059
- dyClick = this.offset.click.top,
4060
- dxClick = this.offset.click.left,
4061
- isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),
4062
- isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),
4063
- isOverElement = isOverElementHeight && isOverElementWidth;
4064
-
4065
- if ( this.options.tolerance === "pointer" ||
4066
- this.options.forcePointerForContainers ||
4067
- (this.options.tolerance !== "pointer" && this.helperProportions[this.floating ? "width" : "height"] > item[this.floating ? "width" : "height"])
4068
- ) {
4069
- return isOverElement;
4070
- } else {
4071
-
4072
- return (l < x1 + (this.helperProportions.width / 2) && // Right Half
4073
- x2 - (this.helperProportions.width / 2) < r && // Left Half
4074
- t < y1 + (this.helperProportions.height / 2) && // Bottom Half
4075
- y2 - (this.helperProportions.height / 2) < b ); // Top Half
4076
-
4077
- }
4078
- },
4079
-
4080
- _intersectsWithPointer: function(item) {
4081
-
4082
- var isOverElementHeight = (this.options.axis === "x") || isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),
4083
- isOverElementWidth = (this.options.axis === "y") || isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),
4084
- isOverElement = isOverElementHeight && isOverElementWidth,
4085
- verticalDirection = this._getDragVerticalDirection(),
4086
- horizontalDirection = this._getDragHorizontalDirection();
4087
-
4088
- if (!isOverElement) {
4089
- return false;
4090
- }
4091
-
4092
- return this.floating ?
4093
- ( ((horizontalDirection && horizontalDirection === "right") || verticalDirection === "down") ? 2 : 1 )
4094
- : ( verticalDirection && (verticalDirection === "down" ? 2 : 1) );
4095
-
4096
- },
4097
-
4098
- _intersectsWithSides: function(item) {
4099
-
4100
- var isOverBottomHalf = isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),
4101
- isOverRightHalf = isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),
4102
- verticalDirection = this._getDragVerticalDirection(),
4103
- horizontalDirection = this._getDragHorizontalDirection();
4104
-
4105
- if (this.floating && horizontalDirection) {
4106
- return ((horizontalDirection === "right" && isOverRightHalf) || (horizontalDirection === "left" && !isOverRightHalf));
4107
- } else {
4108
- return verticalDirection && ((verticalDirection === "down" && isOverBottomHalf) || (verticalDirection === "up" && !isOverBottomHalf));
4109
- }
4110
-
4111
- },
4112
-
4113
- _getDragVerticalDirection: function() {
4114
- var delta = this.positionAbs.top - this.lastPositionAbs.top;
4115
- return delta !== 0 && (delta > 0 ? "down" : "up");
4116
- },
4117
-
4118
- _getDragHorizontalDirection: function() {
4119
- var delta = this.positionAbs.left - this.lastPositionAbs.left;
4120
- return delta !== 0 && (delta > 0 ? "right" : "left");
4121
- },
4122
-
4123
- refresh: function(event) {
4124
- this._refreshItems(event);
4125
- this.refreshPositions();
4126
- return this;
4127
- },
4128
-
4129
- _connectWith: function() {
4130
- var options = this.options;
4131
- return options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;
4132
- },
4133
-
4134
- _getItemsAsjQuery: function(connected) {
4135
-
4136
- var i, j, cur, inst,
4137
- items = [],
4138
- queries = [],
4139
- connectWith = this._connectWith();
4140
-
4141
- if(connectWith && connected) {
4142
- for (i = connectWith.length - 1; i >= 0; i--){
4143
- cur = $(connectWith[i]);
4144
- for ( j = cur.length - 1; j >= 0; j--){
4145
- inst = $.data(cur[j], this.widgetFullName);
4146
- if(inst && inst !== this && !inst.options.disabled) {
4147
- queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), inst]);
4148
- }
4149
- }
4150
- }
4151
- }
4152
-
4153
- queries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"), this]);
4154
-
4155
- function addItems() {
4156
- items.push( this );
4157
- }
4158
- for (i = queries.length - 1; i >= 0; i--){
4159
- queries[i][0].each( addItems );
4160
- }
4161
-
4162
- return $(items);
4163
-
4164
- },
4165
-
4166
- _removeCurrentsFromItems: function() {
4167
-
4168
- var list = this.currentItem.find(":data(" + this.widgetName + "-item)");
4169
-
4170
- this.items = $.grep(this.items, function (item) {
4171
- for (var j=0; j < list.length; j++) {
4172
- if(list[j] === item.item[0]) {
4173
- return false;
4174
- }
4175
- }
4176
- return true;
4177
- });
4178
-
4179
- },
4180
-
4181
- _refreshItems: function(event) {
4182
-
4183
- this.items = [];
4184
- this.containers = [this];
4185
-
4186
- var i, j, cur, inst, targetData, _queries, item, queriesLength,
4187
- items = this.items,
4188
- queries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],
4189
- connectWith = this._connectWith();
4190
-
4191
- if(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down
4192
- for (i = connectWith.length - 1; i >= 0; i--){
4193
- cur = $(connectWith[i]);
4194
- for (j = cur.length - 1; j >= 0; j--){
4195
- inst = $.data(cur[j], this.widgetFullName);
4196
- if(inst && inst !== this && !inst.options.disabled) {
4197
- queries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);
4198
- this.containers.push(inst);
4199
- }
4200
- }
4201
- }
4202
- }
4203
-
4204
- for (i = queries.length - 1; i >= 0; i--) {
4205
- targetData = queries[i][1];
4206
- _queries = queries[i][0];
4207
-
4208
- for (j=0, queriesLength = _queries.length; j < queriesLength; j++) {
4209
- item = $(_queries[j]);
4210
-
4211
- item.data(this.widgetName + "-item", targetData); // Data for target checking (mouse manager)
4212
-
4213
- items.push({
4214
- item: item,
4215
- instance: targetData,
4216
- width: 0, height: 0,
4217
- left: 0, top: 0
4218
- });
4219
- }
4220
- }
4221
-
4222
- },
4223
-
4224
- refreshPositions: function(fast) {
4225
-
4226
- //This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
4227
- if(this.offsetParent && this.helper) {
4228
- this.offset.parent = this._getParentOffset();
4229
- }
4230
-
4231
- var i, item, t, p;
4232
-
4233
- for (i = this.items.length - 1; i >= 0; i--){
4234
- item = this.items[i];
4235
-
4236
- //We ignore calculating positions of all connected containers when we're not over them
4237
- if(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {
4238
- continue;
4239
- }
4240
-
4241
- t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
4242
-
4243
- if (!fast) {
4244
- item.width = t.outerWidth();
4245
- item.height = t.outerHeight();
4246
- }
4247
-
4248
- p = t.offset();
4249
- item.left = p.left;
4250
- item.top = p.top;
4251
- }
4252
-
4253
- if(this.options.custom && this.options.custom.refreshContainers) {
4254
- this.options.custom.refreshContainers.call(this);
4255
- } else {
4256
- for (i = this.containers.length - 1; i >= 0; i--){
4257
- p = this.containers[i].element.offset();
4258
- this.containers[i].containerCache.left = p.left;
4259
- this.containers[i].containerCache.top = p.top;
4260
- this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
4261
- this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
4262
- }
4263
- }
4264
-
4265
- return this;
4266
- },
4267
-
4268
- _createPlaceholder: function(that) {
4269
- that = that || this;
4270
- var className,
4271
- o = that.options;
4272
-
4273
- if(!o.placeholder || o.placeholder.constructor === String) {
4274
- className = o.placeholder;
4275
- o.placeholder = {
4276
- element: function() {
4277
-
4278
- var nodeName = that.currentItem[0].nodeName.toLowerCase(),
4279
- element = $( "<" + nodeName + ">", that.document[0] )
4280
- .addClass(className || that.currentItem[0].className+" ui-sortable-placeholder")
4281
- .removeClass("ui-sortable-helper");
4282
-
4283
- if ( nodeName === "tr" ) {
4284
- that.currentItem.children().each(function() {
4285
- $( "<td>&#160;</td>", that.document[0] )
4286
- .attr( "colspan", $( this ).attr( "colspan" ) || 1 )
4287
- .appendTo( element );
4288
- });
4289
- } else if ( nodeName === "img" ) {
4290
- element.attr( "src", that.currentItem.attr( "src" ) );
4291
- }
4292
-
4293
- if ( !className ) {
4294
- element.css( "visibility", "hidden" );
4295
- }
4296
-
4297
- return element;
4298
- },
4299
- update: function(container, p) {
4300
-
4301
- // 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that
4302
- // 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified
4303
- if(className && !o.forcePlaceholderSize) {
4304
- return;
4305
- }
4306
-
4307
- //If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item
4308
- if(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css("paddingTop")||0, 10) - parseInt(that.currentItem.css("paddingBottom")||0, 10)); }
4309
- if(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css("paddingLeft")||0, 10) - parseInt(that.currentItem.css("paddingRight")||0, 10)); }
4310
- }
4311
- };
4312
- }
4313
-
4314
- //Create the placeholder
4315
- that.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));
4316
-
4317
- //Append it after the actual current item
4318
- that.currentItem.after(that.placeholder);
4319
-
4320
- //Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
4321
- o.placeholder.update(that, that.placeholder);
4322
-
4323
- },
4324
-
4325
- _contactContainers: function(event) {
4326
- var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, base, cur, nearBottom, floating,
4327
- innermostContainer = null,
4328
- innermostIndex = null;
4329
-
4330
- // get innermost container that intersects with item
4331
- for (i = this.containers.length - 1; i >= 0; i--) {
4332
-
4333
- // never consider a container that's located within the item itself
4334
- if($.contains(this.currentItem[0], this.containers[i].element[0])) {
4335
- continue;
4336
- }
4337
-
4338
- if(this._intersectsWith(this.containers[i].containerCache)) {
4339
-
4340
- // if we've already found a container and it's more "inner" than this, then continue
4341
- if(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {
4342
- continue;
4343
- }
4344
-
4345
- innermostContainer = this.containers[i];
4346
- innermostIndex = i;
4347
-
4348
- } else {
4349
- // container doesn't intersect. trigger "out" event if necessary
4350
- if(this.containers[i].containerCache.over) {
4351
- this.containers[i]._trigger("out", event, this._uiHash(this));
4352
- this.containers[i].containerCache.over = 0;
4353
- }
4354
- }
4355
-
4356
- }
4357
-
4358
- // if no intersecting containers found, return
4359
- if(!innermostContainer) {
4360
- return;
4361
- }
4362
-
4363
- // move the item into the container if it's not there already
4364
- if(this.containers.length === 1) {
4365
- if (!this.containers[innermostIndex].containerCache.over) {
4366
- this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4367
- this.containers[innermostIndex].containerCache.over = 1;
4368
- }
4369
- } else {
4370
-
4371
- //When entering a new container, we will find the item with the least distance and append our item near it
4372
- dist = 10000;
4373
- itemWithLeastDistance = null;
4374
- floating = innermostContainer.floating || isFloating(this.currentItem);
4375
- posProperty = floating ? "left" : "top";
4376
- sizeProperty = floating ? "width" : "height";
4377
- base = this.positionAbs[posProperty] + this.offset.click[posProperty];
4378
- for (j = this.items.length - 1; j >= 0; j--) {
4379
- if(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {
4380
- continue;
4381
- }
4382
- if(this.items[j].item[0] === this.currentItem[0]) {
4383
- continue;
4384
- }
4385
- if (floating && !isOverAxis(this.positionAbs.top + this.offset.click.top, this.items[j].top, this.items[j].height)) {
4386
- continue;
4387
- }
4388
- cur = this.items[j].item.offset()[posProperty];
4389
- nearBottom = false;
4390
- if(Math.abs(cur - base) > Math.abs(cur + this.items[j][sizeProperty] - base)){
4391
- nearBottom = true;
4392
- cur += this.items[j][sizeProperty];
4393
- }
4394
-
4395
- if(Math.abs(cur - base) < dist) {
4396
- dist = Math.abs(cur - base); itemWithLeastDistance = this.items[j];
4397
- this.direction = nearBottom ? "up": "down";
4398
- }
4399
- }
4400
-
4401
- //Check if dropOnEmpty is enabled
4402
- if(!itemWithLeastDistance && !this.options.dropOnEmpty) {
4403
- return;
4404
- }
4405
-
4406
- if(this.currentContainer === this.containers[innermostIndex]) {
4407
- return;
4408
- }
4409
-
4410
- itemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);
4411
- this._trigger("change", event, this._uiHash());
4412
- this.containers[innermostIndex]._trigger("change", event, this._uiHash(this));
4413
- this.currentContainer = this.containers[innermostIndex];
4414
-
4415
- //Update the placeholder
4416
- this.options.placeholder.update(this.currentContainer, this.placeholder);
4417
-
4418
- this.containers[innermostIndex]._trigger("over", event, this._uiHash(this));
4419
- this.containers[innermostIndex].containerCache.over = 1;
4420
- }
4421
-
4422
-
4423
- },
4424
-
4425
- _createHelper: function(event) {
4426
-
4427
- var o = this.options,
4428
- helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === "clone" ? this.currentItem.clone() : this.currentItem);
4429
-
4430
- //Add the helper to the DOM if that didn't happen already
4431
- if(!helper.parents("body").length) {
4432
- $(o.appendTo !== "parent" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);
4433
- }
4434
-
4435
- if(helper[0] === this.currentItem[0]) {
4436
- this._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css("position"), top: this.currentItem.css("top"), left: this.currentItem.css("left") };
4437
- }
4438
-
4439
- if(!helper[0].style.width || o.forceHelperSize) {
4440
- helper.width(this.currentItem.width());
4441
- }
4442
- if(!helper[0].style.height || o.forceHelperSize) {
4443
- helper.height(this.currentItem.height());
4444
- }
4445
-
4446
- return helper;
4447
-
4448
- },
4449
-
4450
- _adjustOffsetFromHelper: function(obj) {
4451
- if (typeof obj === "string") {
4452
- obj = obj.split(" ");
4453
- }
4454
- if ($.isArray(obj)) {
4455
- obj = {left: +obj[0], top: +obj[1] || 0};
4456
- }
4457
- if ("left" in obj) {
4458
- this.offset.click.left = obj.left + this.margins.left;
4459
- }
4460
- if ("right" in obj) {
4461
- this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
4462
- }
4463
- if ("top" in obj) {
4464
- this.offset.click.top = obj.top + this.margins.top;
4465
- }
4466
- if ("bottom" in obj) {
4467
- this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
4468
- }
4469
- },
4470
-
4471
- _getParentOffset: function() {
4472
-
4473
-
4474
- //Get the offsetParent and cache its position
4475
- this.offsetParent = this.helper.offsetParent();
4476
- var po = this.offsetParent.offset();
4477
-
4478
- // This is a special case where we need to modify a offset calculated on start, since the following happened:
4479
- // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent
4480
- // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that
4481
- // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag
4482
- if(this.cssPosition === "absolute" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {
4483
- po.left += this.scrollParent.scrollLeft();
4484
- po.top += this.scrollParent.scrollTop();
4485
- }
4486
-
4487
- // This needs to be actually done for all browsers, since pageX/pageY includes this information
4488
- // with an ugly IE fix
4489
- if( this.offsetParent[0] === document.body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === "html" && $.ui.ie)) {
4490
- po = { top: 0, left: 0 };
4491
- }
4492
-
4493
- return {
4494
- top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),
4495
- left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)
4496
- };
4497
-
4498
- },
4499
-
4500
- _getRelativeOffset: function() {
4501
-
4502
- if(this.cssPosition === "relative") {
4503
- var p = this.currentItem.position();
4504
- return {
4505
- top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),
4506
- left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()
4507
- };
4508
- } else {
4509
- return { top: 0, left: 0 };
4510
- }
4511
-
4512
- },
4513
-
4514
- _cacheMargins: function() {
4515
- this.margins = {
4516
- left: (parseInt(this.currentItem.css("marginLeft"),10) || 0),
4517
- top: (parseInt(this.currentItem.css("marginTop"),10) || 0)
4518
- };
4519
- },
4520
-
4521
- _cacheHelperProportions: function() {
4522
- this.helperProportions = {
4523
- width: this.helper.outerWidth(),
4524
- height: this.helper.outerHeight()
4525
- };
4526
- },
4527
-
4528
- _setContainment: function() {
4529
-
4530
- var ce, co, over,
4531
- o = this.options;
4532
- if(o.containment === "parent") {
4533
- o.containment = this.helper[0].parentNode;
4534
- }
4535
- if(o.containment === "document" || o.containment === "window") {
4536
- this.containment = [
4537
- 0 - this.offset.relative.left - this.offset.parent.left,
4538
- 0 - this.offset.relative.top - this.offset.parent.top,
4539
- $(o.containment === "document" ? document : window).width() - this.helperProportions.width - this.margins.left,
4540
- ($(o.containment === "document" ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top
4541
- ];
4542
- }
4543
-
4544
- if(!(/^(document|window|parent)$/).test(o.containment)) {
4545
- ce = $(o.containment)[0];
4546
- co = $(o.containment).offset();
4547
- over = ($(ce).css("overflow") !== "hidden");
4548
-
4549
- this.containment = [
4550
- co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,
4551
- co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,
4552
- co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,
4553
- co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top
4554
- ];
4555
- }
4556
-
4557
- },
4558
-
4559
- _convertPositionTo: function(d, pos) {
4560
-
4561
- if(!pos) {
4562
- pos = this.position;
4563
- }
4564
- var mod = d === "absolute" ? 1 : -1,
4565
- scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,
4566
- scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4567
-
4568
- return {
4569
- top: (
4570
- pos.top + // The absolute mouse position
4571
- this.offset.relative.top * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
4572
- this.offset.parent.top * mod - // The offsetParent's offset without borders (offset + border)
4573
- ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)
4574
- ),
4575
- left: (
4576
- pos.left + // The absolute mouse position
4577
- this.offset.relative.left * mod + // Only for relative positioned nodes: Relative offset from element to offset parent
4578
- this.offset.parent.left * mod - // The offsetParent's offset without borders (offset + border)
4579
- ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)
4580
- )
4581
- };
4582
-
4583
- },
4584
-
4585
- _generatePosition: function(event) {
4586
-
4587
- var top, left,
4588
- o = this.options,
4589
- pageX = event.pageX,
4590
- pageY = event.pageY,
4591
- scroll = this.cssPosition === "absolute" && !(this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
4592
-
4593
- // This is another very weird special case that only happens for relative elements:
4594
- // 1. If the css position is relative
4595
- // 2. and the scroll parent is the document or similar to the offset parent
4596
- // we have to refresh the relative offset during the scroll so there are no jumps
4597
- if(this.cssPosition === "relative" && !(this.scrollParent[0] !== document && this.scrollParent[0] !== this.offsetParent[0])) {
4598
- this.offset.relative = this._getRelativeOffset();
4599
- }
4600
-
4601
- /*
4602
- * - Position constraining -
4603
- * Constrain the position to a mix of grid, containment.
4604
- */
4605
-
4606
- if(this.originalPosition) { //If we are not dragging yet, we won't check for options
4607
-
4608
- if(this.containment) {
4609
- if(event.pageX - this.offset.click.left < this.containment[0]) {
4610
- pageX = this.containment[0] + this.offset.click.left;
4611
- }
4612
- if(event.pageY - this.offset.click.top < this.containment[1]) {
4613
- pageY = this.containment[1] + this.offset.click.top;
4614
- }
4615
- if(event.pageX - this.offset.click.left > this.containment[2]) {
4616
- pageX = this.containment[2] + this.offset.click.left;
4617
- }
4618
- if(event.pageY - this.offset.click.top > this.containment[3]) {
4619
- pageY = this.containment[3] + this.offset.click.top;
4620
- }
4621
- }
4622
-
4623
- if(o.grid) {
4624
- top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
4625
- pageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;
4626
-
4627
- left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
4628
- pageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
4629
- }
4630
-
4631
- }
4632
-
4633
- return {
4634
- top: (
4635
- pageY - // The absolute mouse position
4636
- this.offset.click.top - // Click offset (relative to the element)
4637
- this.offset.relative.top - // Only for relative positioned nodes: Relative offset from element to offset parent
4638
- this.offset.parent.top + // The offsetParent's offset without borders (offset + border)
4639
- ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
4640
- ),
4641
- left: (
4642
- pageX - // The absolute mouse position
4643
- this.offset.click.left - // Click offset (relative to the element)
4644
- this.offset.relative.left - // Only for relative positioned nodes: Relative offset from element to offset parent
4645
- this.offset.parent.left + // The offsetParent's offset without borders (offset + border)
4646
- ( ( this.cssPosition === "fixed" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
4647
- )
4648
- };
4649
-
4650
- },
4651
-
4652
- _rearrange: function(event, i, a, hardRefresh) {
4653
-
4654
- a ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === "down" ? i.item[0] : i.item[0].nextSibling));
4655
-
4656
- //Various things done here to improve the performance:
4657
- // 1. we create a setTimeout, that calls refreshPositions
4658
- // 2. on the instance, we have a counter variable, that get's higher after every append
4659
- // 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same
4660
- // 4. this lets only the last addition to the timeout stack through
4661
- this.counter = this.counter ? ++this.counter : 1;
4662
- var counter = this.counter;
4663
-
4664
- this._delay(function() {
4665
- if(counter === this.counter) {
4666
- this.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove
4667
- }
4668
- });
4669
-
4670
- },
4671
-
4672
- _clear: function(event, noPropagation) {
4673
-
4674
- this.reverting = false;
4675
- // We delay all events that have to be triggered to after the point where the placeholder has been removed and
4676
- // everything else normalized again
4677
- var i,
4678
- delayedTriggers = [];
4679
-
4680
- // We first have to update the dom position of the actual currentItem
4681
- // Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)
4682
- if(!this._noFinalSort && this.currentItem.parent().length) {
4683
- this.placeholder.before(this.currentItem);
4684
- }
4685
- this._noFinalSort = null;
4686
-
4687
- if(this.helper[0] === this.currentItem[0]) {
4688
- for(i in this._storedCSS) {
4689
- if(this._storedCSS[i] === "auto" || this._storedCSS[i] === "static") {
4690
- this._storedCSS[i] = "";
4691
- }
4692
- }
4693
- this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper");
4694
- } else {
4695
- this.currentItem.show();
4696
- }
4697
-
4698
- if(this.fromOutside && !noPropagation) {
4699
- delayedTriggers.push(function(event) { this._trigger("receive", event, this._uiHash(this.fromOutside)); });
4700
- }
4701
- if((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(".ui-sortable-helper")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {
4702
- delayedTriggers.push(function(event) { this._trigger("update", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed
4703
- }
4704
-
4705
- // Check if the items Container has Changed and trigger appropriate
4706
- // events.
4707
- if (this !== this.currentContainer) {
4708
- if(!noPropagation) {
4709
- delayedTriggers.push(function(event) { this._trigger("remove", event, this._uiHash()); });
4710
- delayedTriggers.push((function(c) { return function(event) { c._trigger("receive", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
4711
- delayedTriggers.push((function(c) { return function(event) { c._trigger("update", event, this._uiHash(this)); }; }).call(this, this.currentContainer));
4712
- }
4713
- }
4714
-
4715
-
4716
- //Post events to containers
4717
- function delayEvent( type, instance, container ) {
4718
- return function( event ) {
4719
- container._trigger( type, event, instance._uiHash( instance ) );
4720
- };
4721
- }
4722
- for (i = this.containers.length - 1; i >= 0; i--){
4723
- if (!noPropagation) {
4724
- delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
4725
- }
4726
- if(this.containers[i].containerCache.over) {
4727
- delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
4728
- this.containers[i].containerCache.over = 0;
4729
- }
4730
- }
4731
-
4732
- //Do what was originally in plugins
4733
- if ( this.storedCursor ) {
4734
- this.document.find( "body" ).css( "cursor", this.storedCursor );
4735
- this.storedStylesheet.remove();
4736
- }
4737
- if(this._storedOpacity) {
4738
- this.helper.css("opacity", this._storedOpacity);
4739
- }
4740
- if(this._storedZIndex) {
4741
- this.helper.css("zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex);
4742
- }
4743
-
4744
- this.dragging = false;
4745
- if(this.cancelHelperRemoval) {
4746
- if(!noPropagation) {
4747
- this._trigger("beforeStop", event, this._uiHash());
4748
- for (i=0; i < delayedTriggers.length; i++) {
4749
- delayedTriggers[i].call(this, event);
4750
- } //Trigger all delayed events
4751
- this._trigger("stop", event, this._uiHash());
4752
- }
4753
-
4754
- this.fromOutside = false;
4755
- return false;
4756
- }
4757
-
4758
- if(!noPropagation) {
4759
- this._trigger("beforeStop", event, this._uiHash());
4760
- }
4761
-
4762
- //$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!
4763
- this.placeholder[0].parentNode.removeChild(this.placeholder[0]);
4764
-
4765
- if(this.helper[0] !== this.currentItem[0]) {
4766
- this.helper.remove();
4767
- }
4768
- this.helper = null;
4769
-
4770
- if(!noPropagation) {
4771
- for (i=0; i < delayedTriggers.length; i++) {
4772
- delayedTriggers[i].call(this, event);
4773
- } //Trigger all delayed events
4774
- this._trigger("stop", event, this._uiHash());
4775
- }
4776
-
4777
- this.fromOutside = false;
4778
- return true;
4779
-
4780
- },
4781
-
4782
- _trigger: function() {
4783
- if ($.Widget.prototype._trigger.apply(this, arguments) === false) {
4784
- this.cancel();
4785
- }
4786
- },
4787
-
4788
- _uiHash: function(_inst) {
4789
- var inst = _inst || this;
4790
- return {
4791
- helper: inst.helper,
4792
- placeholder: inst.placeholder || $([]),
4793
- position: inst.position,
4794
- originalPosition: inst.originalPosition,
4795
- offset: inst.positionAbs,
4796
- item: inst.currentItem,
4797
- sender: _inst ? _inst.element : null
4798
- };
4799
- }
4800
-
4801
- });
4802
-
4803
- })(jQuery);
4804
-
4805
- (function($, undefined) {
4806
-
4807
- var dataSpace = "ui-effects-";
4808
-
4809
- $.effects = {
4810
- effect: {}
4811
- };
4812
-
4813
- /*!
4814
- * jQuery Color Animations v2.1.2
4815
- * https://github.com/jquery/jquery-color
4816
- *
4817
- * Copyright 2013 jQuery Foundation and other contributors
4818
- * Released under the MIT license.
4819
- * http://jquery.org/license
4820
- *
4821
- * Date: Wed Jan 16 08:47:09 2013 -0600
4822
- */
4823
- (function( jQuery, undefined ) {
4824
-
4825
- var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
4826
-
4827
- // plusequals test for += 100 -= 100
4828
- rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
4829
- // a set of RE's that can match strings and generate color tuples.
4830
- stringParsers = [{
4831
- re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4832
- parse: function( execResult ) {
4833
- return [
4834
- execResult[ 1 ],
4835
- execResult[ 2 ],
4836
- execResult[ 3 ],
4837
- execResult[ 4 ]
4838
- ];
4839
- }
4840
- }, {
4841
- re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4842
- parse: function( execResult ) {
4843
- return [
4844
- execResult[ 1 ] * 2.55,
4845
- execResult[ 2 ] * 2.55,
4846
- execResult[ 3 ] * 2.55,
4847
- execResult[ 4 ]
4848
- ];
4849
- }
4850
- }, {
4851
- // this regex ignores A-F because it's compared against an already lowercased string
4852
- re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
4853
- parse: function( execResult ) {
4854
- return [
4855
- parseInt( execResult[ 1 ], 16 ),
4856
- parseInt( execResult[ 2 ], 16 ),
4857
- parseInt( execResult[ 3 ], 16 )
4858
- ];
4859
- }
4860
- }, {
4861
- // this regex ignores A-F because it's compared against an already lowercased string
4862
- re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
4863
- parse: function( execResult ) {
4864
- return [
4865
- parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
4866
- parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
4867
- parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
4868
- ];
4869
- }
4870
- }, {
4871
- re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
4872
- space: "hsla",
4873
- parse: function( execResult ) {
4874
- return [
4875
- execResult[ 1 ],
4876
- execResult[ 2 ] / 100,
4877
- execResult[ 3 ] / 100,
4878
- execResult[ 4 ]
4879
- ];
4880
- }
4881
- }],
4882
-
4883
- // jQuery.Color( )
4884
- color = jQuery.Color = function( color, green, blue, alpha ) {
4885
- return new jQuery.Color.fn.parse( color, green, blue, alpha );
4886
- },
4887
- spaces = {
4888
- rgba: {
4889
- props: {
4890
- red: {
4891
- idx: 0,
4892
- type: "byte"
4893
- },
4894
- green: {
4895
- idx: 1,
4896
- type: "byte"
4897
- },
4898
- blue: {
4899
- idx: 2,
4900
- type: "byte"
4901
- }
4902
- }
4903
- },
4904
-
4905
- hsla: {
4906
- props: {
4907
- hue: {
4908
- idx: 0,
4909
- type: "degrees"
4910
- },
4911
- saturation: {
4912
- idx: 1,
4913
- type: "percent"
4914
- },
4915
- lightness: {
4916
- idx: 2,
4917
- type: "percent"
4918
- }
4919
- }
4920
- }
4921
- },
4922
- propTypes = {
4923
- "byte": {
4924
- floor: true,
4925
- max: 255
4926
- },
4927
- "percent": {
4928
- max: 1
4929
- },
4930
- "degrees": {
4931
- mod: 360,
4932
- floor: true
4933
- }
4934
- },
4935
- support = color.support = {},
4936
-
4937
- // element for support tests
4938
- supportElem = jQuery( "<p>" )[ 0 ],
4939
-
4940
- // colors = jQuery.Color.names
4941
- colors,
4942
-
4943
- // local aliases of functions called often
4944
- each = jQuery.each;
4945
-
4946
- // determine rgba support immediately
4947
- supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
4948
- support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
4949
-
4950
- // define cache name and alpha properties
4951
- // for rgba and hsla spaces
4952
- each( spaces, function( spaceName, space ) {
4953
- space.cache = "_" + spaceName;
4954
- space.props.alpha = {
4955
- idx: 3,
4956
- type: "percent",
4957
- def: 1
4958
- };
4959
- });
4960
-
4961
- function clamp( value, prop, allowEmpty ) {
4962
- var type = propTypes[ prop.type ] || {};
4963
-
4964
- if ( value == null ) {
4965
- return (allowEmpty || !prop.def) ? null : prop.def;
4966
- }
4967
-
4968
- // ~~ is an short way of doing floor for positive numbers
4969
- value = type.floor ? ~~value : parseFloat( value );
4970
-
4971
- // IE will pass in empty strings as value for alpha,
4972
- // which will hit this case
4973
- if ( isNaN( value ) ) {
4974
- return prop.def;
4975
- }
4976
-
4977
- if ( type.mod ) {
4978
- // we add mod before modding to make sure that negatives values
4979
- // get converted properly: -10 -> 350
4980
- return (value + type.mod) % type.mod;
4981
- }
4982
-
4983
- // for now all property types without mod have min and max
4984
- return 0 > value ? 0 : type.max < value ? type.max : value;
4985
- }
4986
-
4987
- function stringParse( string ) {
4988
- var inst = color(),
4989
- rgba = inst._rgba = [];
4990
-
4991
- string = string.toLowerCase();
4992
-
4993
- each( stringParsers, function( i, parser ) {
4994
- var parsed,
4995
- match = parser.re.exec( string ),
4996
- values = match && parser.parse( match ),
4997
- spaceName = parser.space || "rgba";
4998
-
4999
- if ( values ) {
5000
- parsed = inst[ spaceName ]( values );
5001
-
5002
- // if this was an rgba parse the assignment might happen twice
5003
- // oh well....
5004
- inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
5005
- rgba = inst._rgba = parsed._rgba;
5006
-
5007
- // exit each( stringParsers ) here because we matched
5008
- return false;
5009
- }
5010
- });
5011
-
5012
- // Found a stringParser that handled it
5013
- if ( rgba.length ) {
5014
-
5015
- // if this came from a parsed string, force "transparent" when alpha is 0
5016
- // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
5017
- if ( rgba.join() === "0,0,0,0" ) {
5018
- jQuery.extend( rgba, colors.transparent );
5019
- }
5020
- return inst;
5021
- }
5022
-
5023
- // named colors
5024
- return colors[ string ];
5025
- }
5026
-
5027
- color.fn = jQuery.extend( color.prototype, {
5028
- parse: function( red, green, blue, alpha ) {
5029
- if ( red === undefined ) {
5030
- this._rgba = [ null, null, null, null ];
5031
- return this;
5032
- }
5033
- if ( red.jquery || red.nodeType ) {
5034
- red = jQuery( red ).css( green );
5035
- green = undefined;
5036
- }
5037
-
5038
- var inst = this,
5039
- type = jQuery.type( red ),
5040
- rgba = this._rgba = [];
5041
-
5042
- // more than 1 argument specified - assume ( red, green, blue, alpha )
5043
- if ( green !== undefined ) {
5044
- red = [ red, green, blue, alpha ];
5045
- type = "array";
5046
- }
5047
-
5048
- if ( type === "string" ) {
5049
- return this.parse( stringParse( red ) || colors._default );
5050
- }
5051
-
5052
- if ( type === "array" ) {
5053
- each( spaces.rgba.props, function( key, prop ) {
5054
- rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
5055
- });
5056
- return this;
5057
- }
5058
-
5059
- if ( type === "object" ) {
5060
- if ( red instanceof color ) {
5061
- each( spaces, function( spaceName, space ) {
5062
- if ( red[ space.cache ] ) {
5063
- inst[ space.cache ] = red[ space.cache ].slice();
5064
- }
5065
- });
5066
- } else {
5067
- each( spaces, function( spaceName, space ) {
5068
- var cache = space.cache;
5069
- each( space.props, function( key, prop ) {
5070
-
5071
- // if the cache doesn't exist, and we know how to convert
5072
- if ( !inst[ cache ] && space.to ) {
5073
-
5074
- // if the value was null, we don't need to copy it
5075
- // if the key was alpha, we don't need to copy it either
5076
- if ( key === "alpha" || red[ key ] == null ) {
5077
- return;
5078
- }
5079
- inst[ cache ] = space.to( inst._rgba );
5080
- }
5081
-
5082
- // this is the only case where we allow nulls for ALL properties.
5083
- // call clamp with alwaysAllowEmpty
5084
- inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
5085
- });
5086
-
5087
- // everything defined but alpha?
5088
- if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
5089
- // use the default of 1
5090
- inst[ cache ][ 3 ] = 1;
5091
- if ( space.from ) {
5092
- inst._rgba = space.from( inst[ cache ] );
5093
- }
5094
- }
5095
- });
5096
- }
5097
- return this;
5098
- }
5099
- },
5100
- is: function( compare ) {
5101
- var is = color( compare ),
5102
- same = true,
5103
- inst = this;
5104
-
5105
- each( spaces, function( _, space ) {
5106
- var localCache,
5107
- isCache = is[ space.cache ];
5108
- if (isCache) {
5109
- localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
5110
- each( space.props, function( _, prop ) {
5111
- if ( isCache[ prop.idx ] != null ) {
5112
- same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
5113
- return same;
5114
- }
5115
- });
5116
- }
5117
- return same;
5118
- });
5119
- return same;
5120
- },
5121
- _space: function() {
5122
- var used = [],
5123
- inst = this;
5124
- each( spaces, function( spaceName, space ) {
5125
- if ( inst[ space.cache ] ) {
5126
- used.push( spaceName );
5127
- }
5128
- });
5129
- return used.pop();
5130
- },
5131
- transition: function( other, distance ) {
5132
- var end = color( other ),
5133
- spaceName = end._space(),
5134
- space = spaces[ spaceName ],
5135
- startColor = this.alpha() === 0 ? color( "transparent" ) : this,
5136
- start = startColor[ space.cache ] || space.to( startColor._rgba ),
5137
- result = start.slice();
5138
-
5139
- end = end[ space.cache ];
5140
- each( space.props, function( key, prop ) {
5141
- var index = prop.idx,
5142
- startValue = start[ index ],
5143
- endValue = end[ index ],
5144
- type = propTypes[ prop.type ] || {};
5145
-
5146
- // if null, don't override start value
5147
- if ( endValue === null ) {
5148
- return;
5149
- }
5150
- // if null - use end
5151
- if ( startValue === null ) {
5152
- result[ index ] = endValue;
5153
- } else {
5154
- if ( type.mod ) {
5155
- if ( endValue - startValue > type.mod / 2 ) {
5156
- startValue += type.mod;
5157
- } else if ( startValue - endValue > type.mod / 2 ) {
5158
- startValue -= type.mod;
5159
- }
5160
- }
5161
- result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
5162
- }
5163
- });
5164
- return this[ spaceName ]( result );
5165
- },
5166
- blend: function( opaque ) {
5167
- // if we are already opaque - return ourself
5168
- if ( this._rgba[ 3 ] === 1 ) {
5169
- return this;
5170
- }
5171
-
5172
- var rgb = this._rgba.slice(),
5173
- a = rgb.pop(),
5174
- blend = color( opaque )._rgba;
5175
-
5176
- return color( jQuery.map( rgb, function( v, i ) {
5177
- return ( 1 - a ) * blend[ i ] + a * v;
5178
- }));
5179
- },
5180
- toRgbaString: function() {
5181
- var prefix = "rgba(",
5182
- rgba = jQuery.map( this._rgba, function( v, i ) {
5183
- return v == null ? ( i > 2 ? 1 : 0 ) : v;
5184
- });
5185
-
5186
- if ( rgba[ 3 ] === 1 ) {
5187
- rgba.pop();
5188
- prefix = "rgb(";
5189
- }
5190
-
5191
- return prefix + rgba.join() + ")";
5192
- },
5193
- toHslaString: function() {
5194
- var prefix = "hsla(",
5195
- hsla = jQuery.map( this.hsla(), function( v, i ) {
5196
- if ( v == null ) {
5197
- v = i > 2 ? 1 : 0;
5198
- }
5199
-
5200
- // catch 1 and 2
5201
- if ( i && i < 3 ) {
5202
- v = Math.round( v * 100 ) + "%";
5203
- }
5204
- return v;
5205
- });
5206
-
5207
- if ( hsla[ 3 ] === 1 ) {
5208
- hsla.pop();
5209
- prefix = "hsl(";
5210
- }
5211
- return prefix + hsla.join() + ")";
5212
- },
5213
- toHexString: function( includeAlpha ) {
5214
- var rgba = this._rgba.slice(),
5215
- alpha = rgba.pop();
5216
-
5217
- if ( includeAlpha ) {
5218
- rgba.push( ~~( alpha * 255 ) );
5219
- }
5220
-
5221
- return "#" + jQuery.map( rgba, function( v ) {
5222
-
5223
- // default to 0 when nulls exist
5224
- v = ( v || 0 ).toString( 16 );
5225
- return v.length === 1 ? "0" + v : v;
5226
- }).join("");
5227
- },
5228
- toString: function() {
5229
- return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
5230
- }
5231
- });
5232
- color.fn.parse.prototype = color.fn;
5233
-
5234
- // hsla conversions adapted from:
5235
- // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
5236
-
5237
- function hue2rgb( p, q, h ) {
5238
- h = ( h + 1 ) % 1;
5239
- if ( h * 6 < 1 ) {
5240
- return p + (q - p) * h * 6;
5241
- }
5242
- if ( h * 2 < 1) {
5243
- return q;
5244
- }
5245
- if ( h * 3 < 2 ) {
5246
- return p + (q - p) * ((2/3) - h) * 6;
5247
- }
5248
- return p;
5249
- }
5250
-
5251
- spaces.hsla.to = function ( rgba ) {
5252
- if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
5253
- return [ null, null, null, rgba[ 3 ] ];
5254
- }
5255
- var r = rgba[ 0 ] / 255,
5256
- g = rgba[ 1 ] / 255,
5257
- b = rgba[ 2 ] / 255,
5258
- a = rgba[ 3 ],
5259
- max = Math.max( r, g, b ),
5260
- min = Math.min( r, g, b ),
5261
- diff = max - min,
5262
- add = max + min,
5263
- l = add * 0.5,
5264
- h, s;
5265
-
5266
- if ( min === max ) {
5267
- h = 0;
5268
- } else if ( r === max ) {
5269
- h = ( 60 * ( g - b ) / diff ) + 360;
5270
- } else if ( g === max ) {
5271
- h = ( 60 * ( b - r ) / diff ) + 120;
5272
- } else {
5273
- h = ( 60 * ( r - g ) / diff ) + 240;
5274
- }
5275
-
5276
- // chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
5277
- // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
5278
- if ( diff === 0 ) {
5279
- s = 0;
5280
- } else if ( l <= 0.5 ) {
5281
- s = diff / add;
5282
- } else {
5283
- s = diff / ( 2 - add );
5284
- }
5285
- return [ Math.round(h) % 360, s, l, a == null ? 1 : a ];
5286
- };
5287
-
5288
- spaces.hsla.from = function ( hsla ) {
5289
- if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
5290
- return [ null, null, null, hsla[ 3 ] ];
5291
- }
5292
- var h = hsla[ 0 ] / 360,
5293
- s = hsla[ 1 ],
5294
- l = hsla[ 2 ],
5295
- a = hsla[ 3 ],
5296
- q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
5297
- p = 2 * l - q;
5298
-
5299
- return [
5300
- Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
5301
- Math.round( hue2rgb( p, q, h ) * 255 ),
5302
- Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
5303
- a
5304
- ];
5305
- };
5306
-
5307
-
5308
- each( spaces, function( spaceName, space ) {
5309
- var props = space.props,
5310
- cache = space.cache,
5311
- to = space.to,
5312
- from = space.from;
5313
-
5314
- // makes rgba() and hsla()
5315
- color.fn[ spaceName ] = function( value ) {
5316
-
5317
- // generate a cache for this space if it doesn't exist
5318
- if ( to && !this[ cache ] ) {
5319
- this[ cache ] = to( this._rgba );
5320
- }
5321
- if ( value === undefined ) {
5322
- return this[ cache ].slice();
5323
- }
5324
-
5325
- var ret,
5326
- type = jQuery.type( value ),
5327
- arr = ( type === "array" || type === "object" ) ? value : arguments,
5328
- local = this[ cache ].slice();
5329
-
5330
- each( props, function( key, prop ) {
5331
- var val = arr[ type === "object" ? key : prop.idx ];
5332
- if ( val == null ) {
5333
- val = local[ prop.idx ];
5334
- }
5335
- local[ prop.idx ] = clamp( val, prop );
5336
- });
5337
-
5338
- if ( from ) {
5339
- ret = color( from( local ) );
5340
- ret[ cache ] = local;
5341
- return ret;
5342
- } else {
5343
- return color( local );
5344
- }
5345
- };
5346
-
5347
- // makes red() green() blue() alpha() hue() saturation() lightness()
5348
- each( props, function( key, prop ) {
5349
- // alpha is included in more than one space
5350
- if ( color.fn[ key ] ) {
5351
- return;
5352
- }
5353
- color.fn[ key ] = function( value ) {
5354
- var vtype = jQuery.type( value ),
5355
- fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
5356
- local = this[ fn ](),
5357
- cur = local[ prop.idx ],
5358
- match;
5359
-
5360
- if ( vtype === "undefined" ) {
5361
- return cur;
5362
- }
5363
-
5364
- if ( vtype === "function" ) {
5365
- value = value.call( this, cur );
5366
- vtype = jQuery.type( value );
5367
- }
5368
- if ( value == null && prop.empty ) {
5369
- return this;
5370
- }
5371
- if ( vtype === "string" ) {
5372
- match = rplusequals.exec( value );
5373
- if ( match ) {
5374
- value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
5375
- }
5376
- }
5377
- local[ prop.idx ] = value;
5378
- return this[ fn ]( local );
5379
- };
5380
- });
5381
- });
5382
-
5383
- // add cssHook and .fx.step function for each named hook.
5384
- // accept a space separated string of properties
5385
- color.hook = function( hook ) {
5386
- var hooks = hook.split( " " );
5387
- each( hooks, function( i, hook ) {
5388
- jQuery.cssHooks[ hook ] = {
5389
- set: function( elem, value ) {
5390
- var parsed, curElem,
5391
- backgroundColor = "";
5392
-
5393
- if ( value !== "transparent" && ( jQuery.type( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) {
5394
- value = color( parsed || value );
5395
- if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
5396
- curElem = hook === "backgroundColor" ? elem.parentNode : elem;
5397
- while (
5398
- (backgroundColor === "" || backgroundColor === "transparent") &&
5399
- curElem && curElem.style
5400
- ) {
5401
- try {
5402
- backgroundColor = jQuery.css( curElem, "backgroundColor" );
5403
- curElem = curElem.parentNode;
5404
- } catch ( e ) {
5405
- }
5406
- }
5407
-
5408
- value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
5409
- backgroundColor :
5410
- "_default" );
5411
- }
5412
-
5413
- value = value.toRgbaString();
5414
- }
5415
- try {
5416
- elem.style[ hook ] = value;
5417
- } catch( e ) {
5418
- // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit'
5419
- }
5420
- }
5421
- };
5422
- jQuery.fx.step[ hook ] = function( fx ) {
5423
- if ( !fx.colorInit ) {
5424
- fx.start = color( fx.elem, hook );
5425
- fx.end = color( fx.end );
5426
- fx.colorInit = true;
5427
- }
5428
- jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
5429
- };
5430
- });
5431
-
5432
- };
5433
-
5434
- color.hook( stepHooks );
5435
-
5436
- jQuery.cssHooks.borderColor = {
5437
- expand: function( value ) {
5438
- var expanded = {};
5439
-
5440
- each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
5441
- expanded[ "border" + part + "Color" ] = value;
5442
- });
5443
- return expanded;
5444
- }
5445
- };
5446
-
5447
- // Basic color names only.
5448
- // Usage of any of the other color names requires adding yourself or including
5449
- // jquery.color.svg-names.js.
5450
- colors = jQuery.Color.names = {
5451
- // 4.1. Basic color keywords
5452
- aqua: "#00ffff",
5453
- black: "#000000",
5454
- blue: "#0000ff",
5455
- fuchsia: "#ff00ff",
5456
- gray: "#808080",
5457
- green: "#008000",
5458
- lime: "#00ff00",
5459
- maroon: "#800000",
5460
- navy: "#000080",
5461
- olive: "#808000",
5462
- purple: "#800080",
5463
- red: "#ff0000",
5464
- silver: "#c0c0c0",
5465
- teal: "#008080",
5466
- white: "#ffffff",
5467
- yellow: "#ffff00",
5468
-
5469
- // 4.2.3. "transparent" color keyword
5470
- transparent: [ null, null, null, 0 ],
5471
-
5472
- _default: "#ffffff"
5473
- };
5474
-
5475
- })( jQuery );
5476
-
5477
-
5478
- /******************************************************************************/
5479
- /****************************** CLASS ANIMATIONS ******************************/
5480
- /******************************************************************************/
5481
- (function() {
5482
-
5483
- var classAnimationActions = [ "add", "remove", "toggle" ],
5484
- shorthandStyles = {
5485
- border: 1,
5486
- borderBottom: 1,
5487
- borderColor: 1,
5488
- borderLeft: 1,
5489
- borderRight: 1,
5490
- borderTop: 1,
5491
- borderWidth: 1,
5492
- margin: 1,
5493
- padding: 1
5494
- };
5495
-
5496
- $.each([ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) {
5497
- $.fx.step[ prop ] = function( fx ) {
5498
- if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
5499
- jQuery.style( fx.elem, prop, fx.end );
5500
- fx.setAttr = true;
5501
- }
5502
- };
5503
- });
5504
-
5505
- function getElementStyles( elem ) {
5506
- var key, len,
5507
- style = elem.ownerDocument.defaultView ?
5508
- elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
5509
- elem.currentStyle,
5510
- styles = {};
5511
-
5512
- if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
5513
- len = style.length;
5514
- while ( len-- ) {
5515
- key = style[ len ];
5516
- if ( typeof style[ key ] === "string" ) {
5517
- styles[ $.camelCase( key ) ] = style[ key ];
5518
- }
5519
- }
5520
- // support: Opera, IE <9
5521
- } else {
5522
- for ( key in style ) {
5523
- if ( typeof style[ key ] === "string" ) {
5524
- styles[ key ] = style[ key ];
5525
- }
5526
- }
5527
- }
5528
-
5529
- return styles;
5530
- }
5531
-
5532
-
5533
- function styleDifference( oldStyle, newStyle ) {
5534
- var diff = {},
5535
- name, value;
5536
-
5537
- for ( name in newStyle ) {
5538
- value = newStyle[ name ];
5539
- if ( oldStyle[ name ] !== value ) {
5540
- if ( !shorthandStyles[ name ] ) {
5541
- if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
5542
- diff[ name ] = value;
5543
- }
5544
- }
5545
- }
5546
- }
5547
-
5548
- return diff;
5549
- }
5550
-
5551
- // support: jQuery <1.8
5552
- if ( !$.fn.addBack ) {
5553
- $.fn.addBack = function( selector ) {
5554
- return this.add( selector == null ?
5555
- this.prevObject : this.prevObject.filter( selector )
5556
- );
5557
- };
5558
- }
5559
-
5560
- $.effects.animateClass = function( value, duration, easing, callback ) {
5561
- var o = $.speed( duration, easing, callback );
5562
-
5563
- return this.queue( function() {
5564
- var animated = $( this ),
5565
- baseClass = animated.attr( "class" ) || "",
5566
- applyClassChange,
5567
- allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
5568
-
5569
- // map the animated objects to store the original styles.
5570
- allAnimations = allAnimations.map(function() {
5571
- var el = $( this );
5572
- return {
5573
- el: el,
5574
- start: getElementStyles( this )
5575
- };
5576
- });
5577
-
5578
- // apply class change
5579
- applyClassChange = function() {
5580
- $.each( classAnimationActions, function(i, action) {
5581
- if ( value[ action ] ) {
5582
- animated[ action + "Class" ]( value[ action ] );
5583
- }
5584
- });
5585
- };
5586
- applyClassChange();
5587
-
5588
- // map all animated objects again - calculate new styles and diff
5589
- allAnimations = allAnimations.map(function() {
5590
- this.end = getElementStyles( this.el[ 0 ] );
5591
- this.diff = styleDifference( this.start, this.end );
5592
- return this;
5593
- });
5594
-
5595
- // apply original class
5596
- animated.attr( "class", baseClass );
5597
-
5598
- // map all animated objects again - this time collecting a promise
5599
- allAnimations = allAnimations.map(function() {
5600
- var styleInfo = this,
5601
- dfd = $.Deferred(),
5602
- opts = $.extend({}, o, {
5603
- queue: false,
5604
- complete: function() {
5605
- dfd.resolve( styleInfo );
5606
- }
5607
- });
5608
-
5609
- this.el.animate( this.diff, opts );
5610
- return dfd.promise();
5611
- });
5612
-
5613
- // once all animations have completed:
5614
- $.when.apply( $, allAnimations.get() ).done(function() {
5615
-
5616
- // set the final class
5617
- applyClassChange();
5618
-
5619
- // for each animated element,
5620
- // clear all css properties that were animated
5621
- $.each( arguments, function() {
5622
- var el = this.el;
5623
- $.each( this.diff, function(key) {
5624
- el.css( key, "" );
5625
- });
5626
- });
5627
-
5628
- // this is guarnteed to be there if you use jQuery.speed()
5629
- // it also handles dequeuing the next anim...
5630
- o.complete.call( animated[ 0 ] );
5631
- });
5632
- });
5633
- };
5634
-
5635
- $.fn.extend({
5636
- addClass: (function( orig ) {
5637
- return function( classNames, speed, easing, callback ) {
5638
- return speed ?
5639
- $.effects.animateClass.call( this,
5640
- { add: classNames }, speed, easing, callback ) :
5641
- orig.apply( this, arguments );
5642
- };
5643
- })( $.fn.addClass ),
5644
-
5645
- removeClass: (function( orig ) {
5646
- return function( classNames, speed, easing, callback ) {
5647
- return arguments.length > 1 ?
5648
- $.effects.animateClass.call( this,
5649
- { remove: classNames }, speed, easing, callback ) :
5650
- orig.apply( this, arguments );
5651
- };
5652
- })( $.fn.removeClass ),
5653
-
5654
- toggleClass: (function( orig ) {
5655
- return function( classNames, force, speed, easing, callback ) {
5656
- if ( typeof force === "boolean" || force === undefined ) {
5657
- if ( !speed ) {
5658
- // without speed parameter
5659
- return orig.apply( this, arguments );
5660
- } else {
5661
- return $.effects.animateClass.call( this,
5662
- (force ? { add: classNames } : { remove: classNames }),
5663
- speed, easing, callback );
5664
- }
5665
- } else {
5666
- // without force parameter
5667
- return $.effects.animateClass.call( this,
5668
- { toggle: classNames }, force, speed, easing );
5669
- }
5670
- };
5671
- })( $.fn.toggleClass ),
5672
-
5673
- switchClass: function( remove, add, speed, easing, callback) {
5674
- return $.effects.animateClass.call( this, {
5675
- add: add,
5676
- remove: remove
5677
- }, speed, easing, callback );
5678
- }
5679
- });
5680
-
5681
- })();
5682
-
5683
- /******************************************************************************/
5684
- /*********************************** EFFECTS **********************************/
5685
- /******************************************************************************/
5686
-
5687
- (function() {
5688
-
5689
- $.extend( $.effects, {
5690
- version: "1.10.4",
5691
-
5692
- // Saves a set of properties in a data storage
5693
- save: function( element, set ) {
5694
- for( var i=0; i < set.length; i++ ) {
5695
- if ( set[ i ] !== null ) {
5696
- element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
5697
- }
5698
- }
5699
- },
5700
-
5701
- // Restores a set of previously saved properties from a data storage
5702
- restore: function( element, set ) {
5703
- var val, i;
5704
- for( i=0; i < set.length; i++ ) {
5705
- if ( set[ i ] !== null ) {
5706
- val = element.data( dataSpace + set[ i ] );
5707
- // support: jQuery 1.6.2
5708
- // http://bugs.jquery.com/ticket/9917
5709
- // jQuery 1.6.2 incorrectly returns undefined for any falsy value.
5710
- // We can't differentiate between "" and 0 here, so we just assume
5711
- // empty string since it's likely to be a more common value...
5712
- if ( val === undefined ) {
5713
- val = "";
5714
- }
5715
- element.css( set[ i ], val );
5716
- }
5717
- }
5718
- },
5719
-
5720
- setMode: function( el, mode ) {
5721
- if (mode === "toggle") {
5722
- mode = el.is( ":hidden" ) ? "show" : "hide";
5723
- }
5724
- return mode;
5725
- },
5726
-
5727
- // Translates a [top,left] array into a baseline value
5728
- // this should be a little more flexible in the future to handle a string & hash
5729
- getBaseline: function( origin, original ) {
5730
- var y, x;
5731
- switch ( origin[ 0 ] ) {
5732
- case "top": y = 0; break;
5733
- case "middle": y = 0.5; break;
5734
- case "bottom": y = 1; break;
5735
- default: y = origin[ 0 ] / original.height;
5736
- }
5737
- switch ( origin[ 1 ] ) {
5738
- case "left": x = 0; break;
5739
- case "center": x = 0.5; break;
5740
- case "right": x = 1; break;
5741
- default: x = origin[ 1 ] / original.width;
5742
- }
5743
- return {
5744
- x: x,
5745
- y: y
5746
- };
5747
- },
5748
-
5749
- // Wraps the element around a wrapper that copies position properties
5750
- createWrapper: function( element ) {
5751
-
5752
- // if the element is already wrapped, return it
5753
- if ( element.parent().is( ".ui-effects-wrapper" )) {
5754
- return element.parent();
5755
- }
5756
-
5757
- // wrap the element
5758
- var props = {
5759
- width: element.outerWidth(true),
5760
- height: element.outerHeight(true),
5761
- "float": element.css( "float" )
5762
- },
5763
- wrapper = $( "<div></div>" )
5764
- .addClass( "ui-effects-wrapper" )
5765
- .css({
5766
- fontSize: "100%",
5767
- background: "transparent",
5768
- border: "none",
5769
- margin: 0,
5770
- padding: 0
5771
- }),
5772
- // Store the size in case width/height are defined in % - Fixes #5245
5773
- size = {
5774
- width: element.width(),
5775
- height: element.height()
5776
- },
5777
- active = document.activeElement;
5778
-
5779
- // support: Firefox
5780
- // Firefox incorrectly exposes anonymous content
5781
- // https://bugzilla.mozilla.org/show_bug.cgi?id=561664
5782
- try {
5783
- active.id;
5784
- } catch( e ) {
5785
- active = document.body;
5786
- }
5787
-
5788
- element.wrap( wrapper );
5789
-
5790
- // Fixes #7595 - Elements lose focus when wrapped.
5791
- if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5792
- $( active ).focus();
5793
- }
5794
-
5795
- wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element
5796
-
5797
- // transfer positioning properties to the wrapper
5798
- if ( element.css( "position" ) === "static" ) {
5799
- wrapper.css({ position: "relative" });
5800
- element.css({ position: "relative" });
5801
- } else {
5802
- $.extend( props, {
5803
- position: element.css( "position" ),
5804
- zIndex: element.css( "z-index" )
5805
- });
5806
- $.each([ "top", "left", "bottom", "right" ], function(i, pos) {
5807
- props[ pos ] = element.css( pos );
5808
- if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
5809
- props[ pos ] = "auto";
5810
- }
5811
- });
5812
- element.css({
5813
- position: "relative",
5814
- top: 0,
5815
- left: 0,
5816
- right: "auto",
5817
- bottom: "auto"
5818
- });
5819
- }
5820
- element.css(size);
5821
-
5822
- return wrapper.css( props ).show();
5823
- },
5824
-
5825
- removeWrapper: function( element ) {
5826
- var active = document.activeElement;
5827
-
5828
- if ( element.parent().is( ".ui-effects-wrapper" ) ) {
5829
- element.parent().replaceWith( element );
5830
-
5831
- // Fixes #7595 - Elements lose focus when wrapped.
5832
- if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
5833
- $( active ).focus();
5834
- }
5835
- }
5836
-
5837
-
5838
- return element;
5839
- },
5840
-
5841
- setTransition: function( element, list, factor, value ) {
5842
- value = value || {};
5843
- $.each( list, function( i, x ) {
5844
- var unit = element.cssUnit( x );
5845
- if ( unit[ 0 ] > 0 ) {
5846
- value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
5847
- }
5848
- });
5849
- return value;
5850
- }
5851
- });
5852
-
5853
- // return an effect options object for the given parameters:
5854
- function _normalizeArguments( effect, options, speed, callback ) {
5855
-
5856
- // allow passing all options as the first parameter
5857
- if ( $.isPlainObject( effect ) ) {
5858
- options = effect;
5859
- effect = effect.effect;
5860
- }
5861
-
5862
- // convert to an object
5863
- effect = { effect: effect };
5864
-
5865
- // catch (effect, null, ...)
5866
- if ( options == null ) {
5867
- options = {};
5868
- }
5869
-
5870
- // catch (effect, callback)
5871
- if ( $.isFunction( options ) ) {
5872
- callback = options;
5873
- speed = null;
5874
- options = {};
5875
- }
5876
-
5877
- // catch (effect, speed, ?)
5878
- if ( typeof options === "number" || $.fx.speeds[ options ] ) {
5879
- callback = speed;
5880
- speed = options;
5881
- options = {};
5882
- }
5883
-
5884
- // catch (effect, options, callback)
5885
- if ( $.isFunction( speed ) ) {
5886
- callback = speed;
5887
- speed = null;
5888
- }
5889
-
5890
- // add options to effect
5891
- if ( options ) {
5892
- $.extend( effect, options );
5893
- }
5894
-
5895
- speed = speed || options.duration;
5896
- effect.duration = $.fx.off ? 0 :
5897
- typeof speed === "number" ? speed :
5898
- speed in $.fx.speeds ? $.fx.speeds[ speed ] :
5899
- $.fx.speeds._default;
5900
-
5901
- effect.complete = callback || options.complete;
5902
-
5903
- return effect;
5904
- }
5905
-
5906
- function standardAnimationOption( option ) {
5907
- // Valid standard speeds (nothing, number, named speed)
5908
- if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
5909
- return true;
5910
- }
5911
-
5912
- // Invalid strings - treat as "normal" speed
5913
- if ( typeof option === "string" && !$.effects.effect[ option ] ) {
5914
- return true;
5915
- }
5916
-
5917
- // Complete callback
5918
- if ( $.isFunction( option ) ) {
5919
- return true;
5920
- }
5921
-
5922
- // Options hash (but not naming an effect)
5923
- if ( typeof option === "object" && !option.effect ) {
5924
- return true;
5925
- }
5926
-
5927
- // Didn't match any standard API
5928
- return false;
5929
- }
5930
-
5931
- $.fn.extend({
5932
- effect: function( /* effect, options, speed, callback */ ) {
5933
- var args = _normalizeArguments.apply( this, arguments ),
5934
- mode = args.mode,
5935
- queue = args.queue,
5936
- effectMethod = $.effects.effect[ args.effect ];
5937
-
5938
- if ( $.fx.off || !effectMethod ) {
5939
- // delegate to the original method (e.g., .show()) if possible
5940
- if ( mode ) {
5941
- return this[ mode ]( args.duration, args.complete );
5942
- } else {
5943
- return this.each( function() {
5944
- if ( args.complete ) {
5945
- args.complete.call( this );
5946
- }
5947
- });
5948
- }
5949
- }
5950
-
5951
- function run( next ) {
5952
- var elem = $( this ),
5953
- complete = args.complete,
5954
- mode = args.mode;
5955
-
5956
- function done() {
5957
- if ( $.isFunction( complete ) ) {
5958
- complete.call( elem[0] );
5959
- }
5960
- if ( $.isFunction( next ) ) {
5961
- next();
5962
- }
5963
- }
5964
-
5965
- // If the element already has the correct final state, delegate to
5966
- // the core methods so the internal tracking of "olddisplay" works.
5967
- if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
5968
- elem[ mode ]();
5969
- done();
5970
- } else {
5971
- effectMethod.call( elem[0], args, done );
5972
- }
5973
- }
5974
-
5975
- return queue === false ? this.each( run ) : this.queue( queue || "fx", run );
5976
- },
5977
-
5978
- show: (function( orig ) {
5979
- return function( option ) {
5980
- if ( standardAnimationOption( option ) ) {
5981
- return orig.apply( this, arguments );
5982
- } else {
5983
- var args = _normalizeArguments.apply( this, arguments );
5984
- args.mode = "show";
5985
- return this.effect.call( this, args );
5986
- }
5987
- };
5988
- })( $.fn.show ),
5989
-
5990
- hide: (function( orig ) {
5991
- return function( option ) {
5992
- if ( standardAnimationOption( option ) ) {
5993
- return orig.apply( this, arguments );
5994
- } else {
5995
- var args = _normalizeArguments.apply( this, arguments );
5996
- args.mode = "hide";
5997
- return this.effect.call( this, args );
5998
- }
5999
- };
6000
- })( $.fn.hide ),
6001
-
6002
- toggle: (function( orig ) {
6003
- return function( option ) {
6004
- if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
6005
- return orig.apply( this, arguments );
6006
- } else {
6007
- var args = _normalizeArguments.apply( this, arguments );
6008
- args.mode = "toggle";
6009
- return this.effect.call( this, args );
6010
- }
6011
- };
6012
- })( $.fn.toggle ),
6013
-
6014
- // helper functions
6015
- cssUnit: function(key) {
6016
- var style = this.css( key ),
6017
- val = [];
6018
-
6019
- $.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
6020
- if ( style.indexOf( unit ) > 0 ) {
6021
- val = [ parseFloat( style ), unit ];
6022
- }
6023
- });
6024
- return val;
6025
- }
6026
- });
6027
-
6028
- })();
6029
-
6030
- /******************************************************************************/
6031
- /*********************************** EASING ***********************************/
6032
- /******************************************************************************/
6033
-
6034
- (function() {
6035
-
6036
- // based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
6037
-
6038
- var baseEasings = {};
6039
-
6040
- $.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
6041
- baseEasings[ name ] = function( p ) {
6042
- return Math.pow( p, i + 2 );
6043
- };
6044
- });
6045
-
6046
- $.extend( baseEasings, {
6047
- Sine: function ( p ) {
6048
- return 1 - Math.cos( p * Math.PI / 2 );
6049
- },
6050
- Circ: function ( p ) {
6051
- return 1 - Math.sqrt( 1 - p * p );
6052
- },
6053
- Elastic: function( p ) {
6054
- return p === 0 || p === 1 ? p :
6055
- -Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );
6056
- },
6057
- Back: function( p ) {
6058
- return p * p * ( 3 * p - 2 );
6059
- },
6060
- Bounce: function ( p ) {
6061
- var pow2,
6062
- bounce = 4;
6063
-
6064
- while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
6065
- return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
6066
- }
6067
- });
6068
-
6069
- $.each( baseEasings, function( name, easeIn ) {
6070
- $.easing[ "easeIn" + name ] = easeIn;
6071
- $.easing[ "easeOut" + name ] = function( p ) {
6072
- return 1 - easeIn( 1 - p );
6073
- };
6074
- $.easing[ "easeInOut" + name ] = function( p ) {
6075
- return p < 0.5 ?
6076
- easeIn( p * 2 ) / 2 :
6077
- 1 - easeIn( p * -2 + 2 ) / 2;
6078
- };
6079
- });
6080
-
6081
- })();
6082
-
6083
- })(jQuery);
6084
-
6085
- (function( $, undefined ) {
6086
-
6087
- var uid = 0,
6088
- hideProps = {},
6089
- showProps = {};
6090
-
6091
- hideProps.height = hideProps.paddingTop = hideProps.paddingBottom =
6092
- hideProps.borderTopWidth = hideProps.borderBottomWidth = "hide";
6093
- showProps.height = showProps.paddingTop = showProps.paddingBottom =
6094
- showProps.borderTopWidth = showProps.borderBottomWidth = "show";
6095
-
6096
- $.widget( "ui.accordion", {
6097
- version: "1.10.4",
6098
- options: {
6099
- active: 0,
6100
- animate: {},
6101
- collapsible: false,
6102
- event: "click",
6103
- header: "> li > :first-child,> :not(li):even",
6104
- heightStyle: "auto",
6105
- icons: {
6106
- activeHeader: "ui-icon-triangle-1-s",
6107
- header: "ui-icon-triangle-1-e"
6108
- },
6109
-
6110
- // callbacks
6111
- activate: null,
6112
- beforeActivate: null
6113
- },
6114
-
6115
- _create: function() {
6116
- var options = this.options;
6117
- this.prevShow = this.prevHide = $();
6118
- this.element.addClass( "ui-accordion ui-widget ui-helper-reset" )
6119
- // ARIA
6120
- .attr( "role", "tablist" );
6121
-
6122
- // don't allow collapsible: false and active: false / null
6123
- if ( !options.collapsible && (options.active === false || options.active == null) ) {
6124
- options.active = 0;
6125
- }
6126
-
6127
- this._processPanels();
6128
- // handle negative values
6129
- if ( options.active < 0 ) {
6130
- options.active += this.headers.length;
6131
- }
6132
- this._refresh();
6133
- },
6134
-
6135
- _getCreateEventData: function() {
6136
- return {
6137
- header: this.active,
6138
- panel: !this.active.length ? $() : this.active.next(),
6139
- content: !this.active.length ? $() : this.active.next()
6140
- };
6141
- },
6142
-
6143
- _createIcons: function() {
6144
- var icons = this.options.icons;
6145
- if ( icons ) {
6146
- $( "<span>" )
6147
- .addClass( "ui-accordion-header-icon ui-icon " + icons.header )
6148
- .prependTo( this.headers );
6149
- this.active.children( ".ui-accordion-header-icon" )
6150
- .removeClass( icons.header )
6151
- .addClass( icons.activeHeader );
6152
- this.headers.addClass( "ui-accordion-icons" );
6153
- }
6154
- },
6155
-
6156
- _destroyIcons: function() {
6157
- this.headers
6158
- .removeClass( "ui-accordion-icons" )
6159
- .children( ".ui-accordion-header-icon" )
6160
- .remove();
6161
- },
6162
-
6163
- _destroy: function() {
6164
- var contents;
6165
-
6166
- // clean up main element
6167
- this.element
6168
- .removeClass( "ui-accordion ui-widget ui-helper-reset" )
6169
- .removeAttr( "role" );
6170
-
6171
- // clean up headers
6172
- this.headers
6173
- .removeClass( "ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top" )
6174
- .removeAttr( "role" )
6175
- .removeAttr( "aria-expanded" )
6176
- .removeAttr( "aria-selected" )
6177
- .removeAttr( "aria-controls" )
6178
- .removeAttr( "tabIndex" )
6179
- .each(function() {
6180
- if ( /^ui-accordion/.test( this.id ) ) {
6181
- this.removeAttribute( "id" );
6182
- }
6183
- });
6184
- this._destroyIcons();
6185
-
6186
- // clean up content panels
6187
- contents = this.headers.next()
6188
- .css( "display", "" )
6189
- .removeAttr( "role" )
6190
- .removeAttr( "aria-hidden" )
6191
- .removeAttr( "aria-labelledby" )
6192
- .removeClass( "ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled" )
6193
- .each(function() {
6194
- if ( /^ui-accordion/.test( this.id ) ) {
6195
- this.removeAttribute( "id" );
6196
- }
6197
- });
6198
- if ( this.options.heightStyle !== "content" ) {
6199
- contents.css( "height", "" );
6200
- }
6201
- },
6202
-
6203
- _setOption: function( key, value ) {
6204
- if ( key === "active" ) {
6205
- // _activate() will handle invalid values and update this.options
6206
- this._activate( value );
6207
- return;
6208
- }
6209
-
6210
- if ( key === "event" ) {
6211
- if ( this.options.event ) {
6212
- this._off( this.headers, this.options.event );
6213
- }
6214
- this._setupEvents( value );
6215
- }
6216
-
6217
- this._super( key, value );
6218
-
6219
- // setting collapsible: false while collapsed; open first panel
6220
- if ( key === "collapsible" && !value && this.options.active === false ) {
6221
- this._activate( 0 );
6222
- }
6223
-
6224
- if ( key === "icons" ) {
6225
- this._destroyIcons();
6226
- if ( value ) {
6227
- this._createIcons();
6228
- }
6229
- }
6230
-
6231
- // #5332 - opacity doesn't cascade to positioned elements in IE
6232
- // so we need to add the disabled class to the headers and panels
6233
- if ( key === "disabled" ) {
6234
- this.headers.add( this.headers.next() )
6235
- .toggleClass( "ui-state-disabled", !!value );
6236
- }
6237
- },
6238
-
6239
- _keydown: function( event ) {
6240
- if ( event.altKey || event.ctrlKey ) {
6241
- return;
6242
- }
6243
-
6244
- var keyCode = $.ui.keyCode,
6245
- length = this.headers.length,
6246
- currentIndex = this.headers.index( event.target ),
6247
- toFocus = false;
6248
-
6249
- switch ( event.keyCode ) {
6250
- case keyCode.RIGHT:
6251
- case keyCode.DOWN:
6252
- toFocus = this.headers[ ( currentIndex + 1 ) % length ];
6253
- break;
6254
- case keyCode.LEFT:
6255
- case keyCode.UP:
6256
- toFocus = this.headers[ ( currentIndex - 1 + length ) % length ];
6257
- break;
6258
- case keyCode.SPACE:
6259
- case keyCode.ENTER:
6260
- this._eventHandler( event );
6261
- break;
6262
- case keyCode.HOME:
6263
- toFocus = this.headers[ 0 ];
6264
- break;
6265
- case keyCode.END:
6266
- toFocus = this.headers[ length - 1 ];
6267
- break;
6268
- }
6269
-
6270
- if ( toFocus ) {
6271
- $( event.target ).attr( "tabIndex", -1 );
6272
- $( toFocus ).attr( "tabIndex", 0 );
6273
- toFocus.focus();
6274
- event.preventDefault();
6275
- }
6276
- },
6277
-
6278
- _panelKeyDown : function( event ) {
6279
- if ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {
6280
- $( event.currentTarget ).prev().focus();
6281
- }
6282
- },
6283
-
6284
- refresh: function() {
6285
- var options = this.options;
6286
- this._processPanels();
6287
-
6288
- // was collapsed or no panel
6289
- if ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {
6290
- options.active = false;
6291
- this.active = $();
6292
- // active false only when collapsible is true
6293
- } else if ( options.active === false ) {
6294
- this._activate( 0 );
6295
- // was active, but active panel is gone
6296
- } else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
6297
- // all remaining panel are disabled
6298
- if ( this.headers.length === this.headers.find(".ui-state-disabled").length ) {
6299
- options.active = false;
6300
- this.active = $();
6301
- // activate previous panel
6302
- } else {
6303
- this._activate( Math.max( 0, options.active - 1 ) );
6304
- }
6305
- // was active, active panel still exists
6306
- } else {
6307
- // make sure active index is correct
6308
- options.active = this.headers.index( this.active );
6309
- }
6310
-
6311
- this._destroyIcons();
6312
-
6313
- this._refresh();
6314
- },
6315
-
6316
- _processPanels: function() {
6317
- this.headers = this.element.find( this.options.header )
6318
- .addClass( "ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" );
6319
-
6320
- this.headers.next()
6321
- .addClass( "ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" )
6322
- .filter(":not(.ui-accordion-content-active)")
6323
- .hide();
6324
- },
6325
-
6326
- _refresh: function() {
6327
- var maxHeight,
6328
- options = this.options,
6329
- heightStyle = options.heightStyle,
6330
- parent = this.element.parent(),
6331
- accordionId = this.accordionId = "ui-accordion-" +
6332
- (this.element.attr( "id" ) || ++uid);
6333
-
6334
- this.active = this._findActive( options.active )
6335
- .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" )
6336
- .removeClass( "ui-corner-all" );
6337
- this.active.next()
6338
- .addClass( "ui-accordion-content-active" )
6339
- .show();
6340
-
6341
- this.headers
6342
- .attr( "role", "tab" )
6343
- .each(function( i ) {
6344
- var header = $( this ),
6345
- headerId = header.attr( "id" ),
6346
- panel = header.next(),
6347
- panelId = panel.attr( "id" );
6348
- if ( !headerId ) {
6349
- headerId = accordionId + "-header-" + i;
6350
- header.attr( "id", headerId );
6351
- }
6352
- if ( !panelId ) {
6353
- panelId = accordionId + "-panel-" + i;
6354
- panel.attr( "id", panelId );
6355
- }
6356
- header.attr( "aria-controls", panelId );
6357
- panel.attr( "aria-labelledby", headerId );
6358
- })
6359
- .next()
6360
- .attr( "role", "tabpanel" );
6361
-
6362
- this.headers
6363
- .not( this.active )
6364
- .attr({
6365
- "aria-selected": "false",
6366
- "aria-expanded": "false",
6367
- tabIndex: -1
6368
- })
6369
- .next()
6370
- .attr({
6371
- "aria-hidden": "true"
6372
- })
6373
- .hide();
6374
-
6375
- // make sure at least one header is in the tab order
6376
- if ( !this.active.length ) {
6377
- this.headers.eq( 0 ).attr( "tabIndex", 0 );
6378
- } else {
6379
- this.active.attr({
6380
- "aria-selected": "true",
6381
- "aria-expanded": "true",
6382
- tabIndex: 0
6383
- })
6384
- .next()
6385
- .attr({
6386
- "aria-hidden": "false"
6387
- });
6388
- }
6389
-
6390
- this._createIcons();
6391
-
6392
- this._setupEvents( options.event );
6393
-
6394
- if ( heightStyle === "fill" ) {
6395
- maxHeight = parent.height();
6396
- this.element.siblings( ":visible" ).each(function() {
6397
- var elem = $( this ),
6398
- position = elem.css( "position" );
6399
-
6400
- if ( position === "absolute" || position === "fixed" ) {
6401
- return;
6402
- }
6403
- maxHeight -= elem.outerHeight( true );
6404
- });
6405
-
6406
- this.headers.each(function() {
6407
- maxHeight -= $( this ).outerHeight( true );
6408
- });
6409
-
6410
- this.headers.next()
6411
- .each(function() {
6412
- $( this ).height( Math.max( 0, maxHeight -
6413
- $( this ).innerHeight() + $( this ).height() ) );
6414
- })
6415
- .css( "overflow", "auto" );
6416
- } else if ( heightStyle === "auto" ) {
6417
- maxHeight = 0;
6418
- this.headers.next()
6419
- .each(function() {
6420
- maxHeight = Math.max( maxHeight, $( this ).css( "height", "" ).height() );
6421
- })
6422
- .height( maxHeight );
6423
- }
6424
- },
6425
-
6426
- _activate: function( index ) {
6427
- var active = this._findActive( index )[ 0 ];
6428
-
6429
- // trying to activate the already active panel
6430
- if ( active === this.active[ 0 ] ) {
6431
- return;
6432
- }
6433
-
6434
- // trying to collapse, simulate a click on the currently active header
6435
- active = active || this.active[ 0 ];
6436
-
6437
- this._eventHandler({
6438
- target: active,
6439
- currentTarget: active,
6440
- preventDefault: $.noop
6441
- });
6442
- },
6443
-
6444
- _findActive: function( selector ) {
6445
- return typeof selector === "number" ? this.headers.eq( selector ) : $();
6446
- },
6447
-
6448
- _setupEvents: function( event ) {
6449
- var events = {
6450
- keydown: "_keydown"
6451
- };
6452
- if ( event ) {
6453
- $.each( event.split(" "), function( index, eventName ) {
6454
- events[ eventName ] = "_eventHandler";
6455
- });
6456
- }
6457
-
6458
- this._off( this.headers.add( this.headers.next() ) );
6459
- this._on( this.headers, events );
6460
- this._on( this.headers.next(), { keydown: "_panelKeyDown" });
6461
- this._hoverable( this.headers );
6462
- this._focusable( this.headers );
6463
- },
6464
-
6465
- _eventHandler: function( event ) {
6466
- var options = this.options,
6467
- active = this.active,
6468
- clicked = $( event.currentTarget ),
6469
- clickedIsActive = clicked[ 0 ] === active[ 0 ],
6470
- collapsing = clickedIsActive && options.collapsible,
6471
- toShow = collapsing ? $() : clicked.next(),
6472
- toHide = active.next(),
6473
- eventData = {
6474
- oldHeader: active,
6475
- oldPanel: toHide,
6476
- newHeader: collapsing ? $() : clicked,
6477
- newPanel: toShow
6478
- };
6479
-
6480
- event.preventDefault();
6481
-
6482
- if (
6483
- // click on active header, but not collapsible
6484
- ( clickedIsActive && !options.collapsible ) ||
6485
- // allow canceling activation
6486
- ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
6487
- return;
6488
- }
6489
-
6490
- options.active = collapsing ? false : this.headers.index( clicked );
6491
-
6492
- // when the call to ._toggle() comes after the class changes
6493
- // it causes a very odd bug in IE 8 (see #6720)
6494
- this.active = clickedIsActive ? $() : clicked;
6495
- this._toggle( eventData );
6496
-
6497
- // switch classes
6498
- // corner classes on the previously active header stay after the animation
6499
- active.removeClass( "ui-accordion-header-active ui-state-active" );
6500
- if ( options.icons ) {
6501
- active.children( ".ui-accordion-header-icon" )
6502
- .removeClass( options.icons.activeHeader )
6503
- .addClass( options.icons.header );
6504
- }
6505
-
6506
- if ( !clickedIsActive ) {
6507
- clicked
6508
- .removeClass( "ui-corner-all" )
6509
- .addClass( "ui-accordion-header-active ui-state-active ui-corner-top" );
6510
- if ( options.icons ) {
6511
- clicked.children( ".ui-accordion-header-icon" )
6512
- .removeClass( options.icons.header )
6513
- .addClass( options.icons.activeHeader );
6514
- }
6515
-
6516
- clicked
6517
- .next()
6518
- .addClass( "ui-accordion-content-active" );
6519
- }
6520
- },
6521
-
6522
- _toggle: function( data ) {
6523
- var toShow = data.newPanel,
6524
- toHide = this.prevShow.length ? this.prevShow : data.oldPanel;
6525
-
6526
- // handle activating a panel during the animation for another activation
6527
- this.prevShow.add( this.prevHide ).stop( true, true );
6528
- this.prevShow = toShow;
6529
- this.prevHide = toHide;
6530
-
6531
- if ( this.options.animate ) {
6532
- this._animate( toShow, toHide, data );
6533
- } else {
6534
- toHide.hide();
6535
- toShow.show();
6536
- this._toggleComplete( data );
6537
- }
6538
-
6539
- toHide.attr({
6540
- "aria-hidden": "true"
6541
- });
6542
- toHide.prev().attr( "aria-selected", "false" );
6543
- // if we're switching panels, remove the old header from the tab order
6544
- // if we're opening from collapsed state, remove the previous header from the tab order
6545
- // if we're collapsing, then keep the collapsing header in the tab order
6546
- if ( toShow.length && toHide.length ) {
6547
- toHide.prev().attr({
6548
- "tabIndex": -1,
6549
- "aria-expanded": "false"
6550
- });
6551
- } else if ( toShow.length ) {
6552
- this.headers.filter(function() {
6553
- return $( this ).attr( "tabIndex" ) === 0;
6554
- })
6555
- .attr( "tabIndex", -1 );
6556
- }
6557
-
6558
- toShow
6559
- .attr( "aria-hidden", "false" )
6560
- .prev()
6561
- .attr({
6562
- "aria-selected": "true",
6563
- tabIndex: 0,
6564
- "aria-expanded": "true"
6565
- });
6566
- },
6567
-
6568
- _animate: function( toShow, toHide, data ) {
6569
- var total, easing, duration,
6570
- that = this,
6571
- adjust = 0,
6572
- down = toShow.length &&
6573
- ( !toHide.length || ( toShow.index() < toHide.index() ) ),
6574
- animate = this.options.animate || {},
6575
- options = down && animate.down || animate,
6576
- complete = function() {
6577
- that._toggleComplete( data );
6578
- };
6579
-
6580
- if ( typeof options === "number" ) {
6581
- duration = options;
6582
- }
6583
- if ( typeof options === "string" ) {
6584
- easing = options;
6585
- }
6586
- // fall back from options to animation in case of partial down settings
6587
- easing = easing || options.easing || animate.easing;
6588
- duration = duration || options.duration || animate.duration;
6589
-
6590
- if ( !toHide.length ) {
6591
- return toShow.animate( showProps, duration, easing, complete );
6592
- }
6593
- if ( !toShow.length ) {
6594
- return toHide.animate( hideProps, duration, easing, complete );
6595
- }
6596
-
6597
- total = toShow.show().outerHeight();
6598
- toHide.animate( hideProps, {
6599
- duration: duration,
6600
- easing: easing,
6601
- step: function( now, fx ) {
6602
- fx.now = Math.round( now );
6603
- }
6604
- });
6605
- toShow
6606
- .hide()
6607
- .animate( showProps, {
6608
- duration: duration,
6609
- easing: easing,
6610
- complete: complete,
6611
- step: function( now, fx ) {
6612
- fx.now = Math.round( now );
6613
- if ( fx.prop !== "height" ) {
6614
- adjust += fx.now;
6615
- } else if ( that.options.heightStyle !== "content" ) {
6616
- fx.now = Math.round( total - toHide.outerHeight() - adjust );
6617
- adjust = 0;
6618
- }
6619
- }
6620
- });
6621
- },
6622
-
6623
- _toggleComplete: function( data ) {
6624
- var toHide = data.oldPanel;
6625
-
6626
- toHide
6627
- .removeClass( "ui-accordion-content-active" )
6628
- .prev()
6629
- .removeClass( "ui-corner-top" )
6630
- .addClass( "ui-corner-all" );
6631
-
6632
- // Work around for rendering bug in IE (#5421)
6633
- if ( toHide.length ) {
6634
- toHide.parent()[0].className = toHide.parent()[0].className;
6635
- }
6636
- this._trigger( "activate", null, data );
6637
- }
6638
- });
6639
-
6640
- })( jQuery );
6641
-
6642
- (function( $, undefined ) {
6643
-
6644
- $.widget( "ui.autocomplete", {
6645
- version: "1.10.4",
6646
- defaultElement: "<input>",
6647
- options: {
6648
- appendTo: null,
6649
- autoFocus: false,
6650
- delay: 300,
6651
- minLength: 1,
6652
- position: {
6653
- my: "left top",
6654
- at: "left bottom",
6655
- collision: "none"
6656
- },
6657
- source: null,
6658
-
6659
- // callbacks
6660
- change: null,
6661
- close: null,
6662
- focus: null,
6663
- open: null,
6664
- response: null,
6665
- search: null,
6666
- select: null
6667
- },
6668
-
6669
- requestIndex: 0,
6670
- pending: 0,
6671
-
6672
- _create: function() {
6673
- // Some browsers only repeat keydown events, not keypress events,
6674
- // so we use the suppressKeyPress flag to determine if we've already
6675
- // handled the keydown event. #7269
6676
- // Unfortunately the code for & in keypress is the same as the up arrow,
6677
- // so we use the suppressKeyPressRepeat flag to avoid handling keypress
6678
- // events when we know the keydown event was used to modify the
6679
- // search term. #7799
6680
- var suppressKeyPress, suppressKeyPressRepeat, suppressInput,
6681
- nodeName = this.element[0].nodeName.toLowerCase(),
6682
- isTextarea = nodeName === "textarea",
6683
- isInput = nodeName === "input";
6684
-
6685
- this.isMultiLine =
6686
- // Textareas are always multi-line
6687
- isTextarea ? true :
6688
- // Inputs are always single-line, even if inside a contentEditable element
6689
- // IE also treats inputs as contentEditable
6690
- isInput ? false :
6691
- // All other element types are determined by whether or not they're contentEditable
6692
- this.element.prop( "isContentEditable" );
6693
-
6694
- this.valueMethod = this.element[ isTextarea || isInput ? "val" : "text" ];
6695
- this.isNewMenu = true;
6696
-
6697
- this.element
6698
- .addClass( "ui-autocomplete-input" )
6699
- .attr( "autocomplete", "off" );
6700
-
6701
- this._on( this.element, {
6702
- keydown: function( event ) {
6703
- if ( this.element.prop( "readOnly" ) ) {
6704
- suppressKeyPress = true;
6705
- suppressInput = true;
6706
- suppressKeyPressRepeat = true;
6707
- return;
6708
- }
6709
-
6710
- suppressKeyPress = false;
6711
- suppressInput = false;
6712
- suppressKeyPressRepeat = false;
6713
- var keyCode = $.ui.keyCode;
6714
- switch( event.keyCode ) {
6715
- case keyCode.PAGE_UP:
6716
- suppressKeyPress = true;
6717
- this._move( "previousPage", event );
6718
- break;
6719
- case keyCode.PAGE_DOWN:
6720
- suppressKeyPress = true;
6721
- this._move( "nextPage", event );
6722
- break;
6723
- case keyCode.UP:
6724
- suppressKeyPress = true;
6725
- this._keyEvent( "previous", event );
6726
- break;
6727
- case keyCode.DOWN:
6728
- suppressKeyPress = true;
6729
- this._keyEvent( "next", event );
6730
- break;
6731
- case keyCode.ENTER:
6732
- case keyCode.NUMPAD_ENTER:
6733
- // when menu is open and has focus
6734
- if ( this.menu.active ) {
6735
- // #6055 - Opera still allows the keypress to occur
6736
- // which causes forms to submit
6737
- suppressKeyPress = true;
6738
- event.preventDefault();
6739
- this.menu.select( event );
6740
- }
6741
- break;
6742
- case keyCode.TAB:
6743
- if ( this.menu.active ) {
6744
- this.menu.select( event );
6745
- }
6746
- break;
6747
- case keyCode.ESCAPE:
6748
- if ( this.menu.element.is( ":visible" ) ) {
6749
- this._value( this.term );
6750
- this.close( event );
6751
- // Different browsers have different default behavior for escape
6752
- // Single press can mean undo or clear
6753
- // Double press in IE means clear the whole form
6754
- event.preventDefault();
6755
- }
6756
- break;
6757
- default:
6758
- suppressKeyPressRepeat = true;
6759
- // search timeout should be triggered before the input value is changed
6760
- this._searchTimeout( event );
6761
- break;
6762
- }
6763
- },
6764
- keypress: function( event ) {
6765
- if ( suppressKeyPress ) {
6766
- suppressKeyPress = false;
6767
- if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
6768
- event.preventDefault();
6769
- }
6770
- return;
6771
- }
6772
- if ( suppressKeyPressRepeat ) {
6773
- return;
6774
- }
6775
-
6776
- // replicate some key handlers to allow them to repeat in Firefox and Opera
6777
- var keyCode = $.ui.keyCode;
6778
- switch( event.keyCode ) {
6779
- case keyCode.PAGE_UP:
6780
- this._move( "previousPage", event );
6781
- break;
6782
- case keyCode.PAGE_DOWN:
6783
- this._move( "nextPage", event );
6784
- break;
6785
- case keyCode.UP:
6786
- this._keyEvent( "previous", event );
6787
- break;
6788
- case keyCode.DOWN:
6789
- this._keyEvent( "next", event );
6790
- break;
6791
- }
6792
- },
6793
- input: function( event ) {
6794
- if ( suppressInput ) {
6795
- suppressInput = false;
6796
- event.preventDefault();
6797
- return;
6798
- }
6799
- this._searchTimeout( event );
6800
- },
6801
- focus: function() {
6802
- this.selectedItem = null;
6803
- this.previous = this._value();
6804
- },
6805
- blur: function( event ) {
6806
- if ( this.cancelBlur ) {
6807
- delete this.cancelBlur;
6808
- return;
6809
- }
6810
-
6811
- clearTimeout( this.searching );
6812
- this.close( event );
6813
- this._change( event );
6814
- }
6815
- });
6816
-
6817
- this._initSource();
6818
- this.menu = $( "<ul>" )
6819
- .addClass( "ui-autocomplete ui-front" )
6820
- .appendTo( this._appendTo() )
6821
- .menu({
6822
- // disable ARIA support, the live region takes care of that
6823
- role: null
6824
- })
6825
- .hide()
6826
- .data( "ui-menu" );
6827
-
6828
- this._on( this.menu.element, {
6829
- mousedown: function( event ) {
6830
- // prevent moving focus out of the text field
6831
- event.preventDefault();
6832
-
6833
- // IE doesn't prevent moving focus even with event.preventDefault()
6834
- // so we set a flag to know when we should ignore the blur event
6835
- this.cancelBlur = true;
6836
- this._delay(function() {
6837
- delete this.cancelBlur;
6838
- });
6839
-
6840
- // clicking on the scrollbar causes focus to shift to the body
6841
- // but we can't detect a mouseup or a click immediately afterward
6842
- // so we have to track the next mousedown and close the menu if
6843
- // the user clicks somewhere outside of the autocomplete
6844
- var menuElement = this.menu.element[ 0 ];
6845
- if ( !$( event.target ).closest( ".ui-menu-item" ).length ) {
6846
- this._delay(function() {
6847
- var that = this;
6848
- this.document.one( "mousedown", function( event ) {
6849
- if ( event.target !== that.element[ 0 ] &&
6850
- event.target !== menuElement &&
6851
- !$.contains( menuElement, event.target ) ) {
6852
- that.close();
6853
- }
6854
- });
6855
- });
6856
- }
6857
- },
6858
- menufocus: function( event, ui ) {
6859
- // support: Firefox
6860
- // Prevent accidental activation of menu items in Firefox (#7024 #9118)
6861
- if ( this.isNewMenu ) {
6862
- this.isNewMenu = false;
6863
- if ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {
6864
- this.menu.blur();
6865
-
6866
- this.document.one( "mousemove", function() {
6867
- $( event.target ).trigger( event.originalEvent );
6868
- });
6869
-
6870
- return;
6871
- }
6872
- }
6873
-
6874
- var item = ui.item.data( "ui-autocomplete-item" );
6875
- if ( false !== this._trigger( "focus", event, { item: item } ) ) {
6876
- // use value to match what will end up in the input, if it was a key event
6877
- if ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {
6878
- this._value( item.value );
6879
- }
6880
- } else {
6881
- // Normally the input is populated with the item's value as the
6882
- // menu is navigated, causing screen readers to notice a change and
6883
- // announce the item. Since the focus event was canceled, this doesn't
6884
- // happen, so we update the live region so that screen readers can
6885
- // still notice the change and announce it.
6886
- this.liveRegion.text( item.value );
6887
- }
6888
- },
6889
- menuselect: function( event, ui ) {
6890
- var item = ui.item.data( "ui-autocomplete-item" ),
6891
- previous = this.previous;
6892
-
6893
- // only trigger when focus was lost (click on menu)
6894
- if ( this.element[0] !== this.document[0].activeElement ) {
6895
- this.element.focus();
6896
- this.previous = previous;
6897
- // #6109 - IE triggers two focus events and the second
6898
- // is asynchronous, so we need to reset the previous
6899
- // term synchronously and asynchronously :-(
6900
- this._delay(function() {
6901
- this.previous = previous;
6902
- this.selectedItem = item;
6903
- });
6904
- }
6905
-
6906
- if ( false !== this._trigger( "select", event, { item: item } ) ) {
6907
- this._value( item.value );
6908
- }
6909
- // reset the term after the select event
6910
- // this allows custom select handling to work properly
6911
- this.term = this._value();
6912
-
6913
- this.close( event );
6914
- this.selectedItem = item;
6915
- }
6916
- });
6917
-
6918
- this.liveRegion = $( "<span>", {
6919
- role: "status",
6920
- "aria-live": "polite"
6921
- })
6922
- .addClass( "ui-helper-hidden-accessible" )
6923
- .insertBefore( this.element );
6924
-
6925
- // turning off autocomplete prevents the browser from remembering the
6926
- // value when navigating through history, so we re-enable autocomplete
6927
- // if the page is unloaded before the widget is destroyed. #7790
6928
- this._on( this.window, {
6929
- beforeunload: function() {
6930
- this.element.removeAttr( "autocomplete" );
6931
- }
6932
- });
6933
- },
6934
-
6935
- _destroy: function() {
6936
- clearTimeout( this.searching );
6937
- this.element
6938
- .removeClass( "ui-autocomplete-input" )
6939
- .removeAttr( "autocomplete" );
6940
- this.menu.element.remove();
6941
- this.liveRegion.remove();
6942
- },
6943
-
6944
- _setOption: function( key, value ) {
6945
- this._super( key, value );
6946
- if ( key === "source" ) {
6947
- this._initSource();
6948
- }
6949
- if ( key === "appendTo" ) {
6950
- this.menu.element.appendTo( this._appendTo() );
6951
- }
6952
- if ( key === "disabled" && value && this.xhr ) {
6953
- this.xhr.abort();
6954
- }
6955
- },
6956
-
6957
- _appendTo: function() {
6958
- var element = this.options.appendTo;
6959
-
6960
- if ( element ) {
6961
- element = element.jquery || element.nodeType ?
6962
- $( element ) :
6963
- this.document.find( element ).eq( 0 );
6964
- }
6965
-
6966
- if ( !element ) {
6967
- element = this.element.closest( ".ui-front" );
6968
- }
6969
-
6970
- if ( !element.length ) {
6971
- element = this.document[0].body;
6972
- }
6973
-
6974
- return element;
6975
- },
6976
-
6977
- _initSource: function() {
6978
- var array, url,
6979
- that = this;
6980
- if ( $.isArray(this.options.source) ) {
6981
- array = this.options.source;
6982
- this.source = function( request, response ) {
6983
- response( $.ui.autocomplete.filter( array, request.term ) );
6984
- };
6985
- } else if ( typeof this.options.source === "string" ) {
6986
- url = this.options.source;
6987
- this.source = function( request, response ) {
6988
- if ( that.xhr ) {
6989
- that.xhr.abort();
6990
- }
6991
- that.xhr = $.ajax({
6992
- url: url,
6993
- data: request,
6994
- dataType: "json",
6995
- success: function( data ) {
6996
- response( data );
6997
- },
6998
- error: function() {
6999
- response( [] );
7000
- }
7001
- });
7002
- };
7003
- } else {
7004
- this.source = this.options.source;
7005
- }
7006
- },
7007
-
7008
- _searchTimeout: function( event ) {
7009
- clearTimeout( this.searching );
7010
- this.searching = this._delay(function() {
7011
- // only search if the value has changed
7012
- if ( this.term !== this._value() ) {
7013
- this.selectedItem = null;
7014
- this.search( null, event );
7015
- }
7016
- }, this.options.delay );
7017
- },
7018
-
7019
- search: function( value, event ) {
7020
- value = value != null ? value : this._value();
7021
-
7022
- // always save the actual value, not the one passed as an argument
7023
- this.term = this._value();
7024
-
7025
- if ( value.length < this.options.minLength ) {
7026
- return this.close( event );
7027
- }
7028
-
7029
- if ( this._trigger( "search", event ) === false ) {
7030
- return;
7031
- }
7032
-
7033
- return this._search( value );
7034
- },
7035
-
7036
- _search: function( value ) {
7037
- this.pending++;
7038
- this.element.addClass( "ui-autocomplete-loading" );
7039
- this.cancelSearch = false;
7040
-
7041
- this.source( { term: value }, this._response() );
7042
- },
7043
-
7044
- _response: function() {
7045
- var index = ++this.requestIndex;
7046
-
7047
- return $.proxy(function( content ) {
7048
- if ( index === this.requestIndex ) {
7049
- this.__response( content );
7050
- }
7051
-
7052
- this.pending--;
7053
- if ( !this.pending ) {
7054
- this.element.removeClass( "ui-autocomplete-loading" );
7055
- }
7056
- }, this );
7057
- },
7058
-
7059
- __response: function( content ) {
7060
- if ( content ) {
7061
- content = this._normalize( content );
7062
- }
7063
- this._trigger( "response", null, { content: content } );
7064
- if ( !this.options.disabled && content && content.length && !this.cancelSearch ) {
7065
- this._suggest( content );
7066
- this._trigger( "open" );
7067
- } else {
7068
- // use ._close() instead of .close() so we don't cancel future searches
7069
- this._close();
7070
- }
7071
- },
7072
-
7073
- close: function( event ) {
7074
- this.cancelSearch = true;
7075
- this._close( event );
7076
- },
7077
-
7078
- _close: function( event ) {
7079
- if ( this.menu.element.is( ":visible" ) ) {
7080
- this.menu.element.hide();
7081
- this.menu.blur();
7082
- this.isNewMenu = true;
7083
- this._trigger( "close", event );
7084
- }
7085
- },
7086
-
7087
- _change: function( event ) {
7088
- if ( this.previous !== this._value() ) {
7089
- this._trigger( "change", event, { item: this.selectedItem } );
7090
- }
7091
- },
7092
-
7093
- _normalize: function( items ) {
7094
- // assume all items have the right format when the first item is complete
7095
- if ( items.length && items[0].label && items[0].value ) {
7096
- return items;
7097
- }
7098
- return $.map( items, function( item ) {
7099
- if ( typeof item === "string" ) {
7100
- return {
7101
- label: item,
7102
- value: item
7103
- };
7104
- }
7105
- return $.extend({
7106
- label: item.label || item.value,
7107
- value: item.value || item.label
7108
- }, item );
7109
- });
7110
- },
7111
-
7112
- _suggest: function( items ) {
7113
- var ul = this.menu.element.empty();
7114
- this._renderMenu( ul, items );
7115
- this.isNewMenu = true;
7116
- this.menu.refresh();
7117
-
7118
- // size and position menu
7119
- ul.show();
7120
- this._resizeMenu();
7121
- ul.position( $.extend({
7122
- of: this.element
7123
- }, this.options.position ));
7124
-
7125
- if ( this.options.autoFocus ) {
7126
- this.menu.next();
7127
- }
7128
- },
7129
-
7130
- _resizeMenu: function() {
7131
- var ul = this.menu.element;
7132
- ul.outerWidth( Math.max(
7133
- // Firefox wraps long text (possibly a rounding bug)
7134
- // so we add 1px to avoid the wrapping (#7513)
7135
- ul.width( "" ).outerWidth() + 1,
7136
- this.element.outerWidth()
7137
- ) );
7138
- },
7139
-
7140
- _renderMenu: function( ul, items ) {
7141
- var that = this;
7142
- $.each( items, function( index, item ) {
7143
- that._renderItemData( ul, item );
7144
- });
7145
- },
7146
-
7147
- _renderItemData: function( ul, item ) {
7148
- return this._renderItem( ul, item ).data( "ui-autocomplete-item", item );
7149
- },
7150
-
7151
- _renderItem: function( ul, item ) {
7152
- return $( "<li>" )
7153
- .append( $( "<a>" ).text( item.label ) )
7154
- .appendTo( ul );
7155
- },
7156
-
7157
- _move: function( direction, event ) {
7158
- if ( !this.menu.element.is( ":visible" ) ) {
7159
- this.search( null, event );
7160
- return;
7161
- }
7162
- if ( this.menu.isFirstItem() && /^previous/.test( direction ) ||
7163
- this.menu.isLastItem() && /^next/.test( direction ) ) {
7164
- this._value( this.term );
7165
- this.menu.blur();
7166
- return;
7167
- }
7168
- this.menu[ direction ]( event );
7169
- },
7170
-
7171
- widget: function() {
7172
- return this.menu.element;
7173
- },
7174
-
7175
- _value: function() {
7176
- return this.valueMethod.apply( this.element, arguments );
7177
- },
7178
-
7179
- _keyEvent: function( keyEvent, event ) {
7180
- if ( !this.isMultiLine || this.menu.element.is( ":visible" ) ) {
7181
- this._move( keyEvent, event );
7182
-
7183
- // prevents moving cursor to beginning/end of the text field in some browsers
7184
- event.preventDefault();
7185
- }
7186
- }
7187
- });
7188
-
7189
- $.extend( $.ui.autocomplete, {
7190
- escapeRegex: function( value ) {
7191
- return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
7192
- },
7193
- filter: function(array, term) {
7194
- var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" );
7195
- return $.grep( array, function(value) {
7196
- return matcher.test( value.label || value.value || value );
7197
- });
7198
- }
7199
- });
7200
-
7201
-
7202
- // live region extension, adding a `messages` option
7203
- // NOTE: This is an experimental API. We are still investigating
7204
- // a full solution for string manipulation and internationalization.
7205
- $.widget( "ui.autocomplete", $.ui.autocomplete, {
7206
- options: {
7207
- messages: {
7208
- noResults: "No search results.",
7209
- results: function( amount ) {
7210
- return amount + ( amount > 1 ? " results are" : " result is" ) +
7211
- " available, use up and down arrow keys to navigate.";
7212
- }
7213
- }
7214
- },
7215
-
7216
- __response: function( content ) {
7217
- var message;
7218
- this._superApply( arguments );
7219
- if ( this.options.disabled || this.cancelSearch ) {
7220
- return;
7221
- }
7222
- if ( content && content.length ) {
7223
- message = this.options.messages.results( content.length );
7224
- } else {
7225
- message = this.options.messages.noResults;
7226
- }
7227
- this.liveRegion.text( message );
7228
- }
7229
- });
7230
-
7231
- }( jQuery ));
7232
-
7233
- (function( $, undefined ) {
7234
-
7235
- var lastActive,
7236
- baseClasses = "ui-button ui-widget ui-state-default ui-corner-all",
7237
- typeClasses = "ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only",
7238
- formResetHandler = function() {
7239
- var form = $( this );
7240
- setTimeout(function() {
7241
- form.find( ":ui-button" ).button( "refresh" );
7242
- }, 1 );
7243
- },
7244
- radioGroup = function( radio ) {
7245
- var name = radio.name,
7246
- form = radio.form,
7247
- radios = $( [] );
7248
- if ( name ) {
7249
- name = name.replace( /'/g, "\\'" );
7250
- if ( form ) {
7251
- radios = $( form ).find( "[name='" + name + "']" );
7252
- } else {
7253
- radios = $( "[name='" + name + "']", radio.ownerDocument )
7254
- .filter(function() {
7255
- return !this.form;
7256
- });
7257
- }
7258
- }
7259
- return radios;
7260
- };
7261
-
7262
- $.widget( "ui.button", {
7263
- version: "1.10.4",
7264
- defaultElement: "<button>",
7265
- options: {
7266
- disabled: null,
7267
- text: true,
7268
- label: null,
7269
- icons: {
7270
- primary: null,
7271
- secondary: null
7272
- }
7273
- },
7274
- _create: function() {
7275
- this.element.closest( "form" )
7276
- .unbind( "reset" + this.eventNamespace )
7277
- .bind( "reset" + this.eventNamespace, formResetHandler );
7278
-
7279
- if ( typeof this.options.disabled !== "boolean" ) {
7280
- this.options.disabled = !!this.element.prop( "disabled" );
7281
- } else {
7282
- this.element.prop( "disabled", this.options.disabled );
7283
- }
7284
-
7285
- this._determineButtonType();
7286
- this.hasTitle = !!this.buttonElement.attr( "title" );
7287
-
7288
- var that = this,
7289
- options = this.options,
7290
- toggleButton = this.type === "checkbox" || this.type === "radio",
7291
- activeClass = !toggleButton ? "ui-state-active" : "";
7292
-
7293
- if ( options.label === null ) {
7294
- options.label = (this.type === "input" ? this.buttonElement.val() : this.buttonElement.html());
7295
- }
7296
-
7297
- this._hoverable( this.buttonElement );
7298
-
7299
- this.buttonElement
7300
- .addClass( baseClasses )
7301
- .attr( "role", "button" )
7302
- .bind( "mouseenter" + this.eventNamespace, function() {
7303
- if ( options.disabled ) {
7304
- return;
7305
- }
7306
- if ( this === lastActive ) {
7307
- $( this ).addClass( "ui-state-active" );
7308
- }
7309
- })
7310
- .bind( "mouseleave" + this.eventNamespace, function() {
7311
- if ( options.disabled ) {
7312
- return;
7313
- }
7314
- $( this ).removeClass( activeClass );
7315
- })
7316
- .bind( "click" + this.eventNamespace, function( event ) {
7317
- if ( options.disabled ) {
7318
- event.preventDefault();
7319
- event.stopImmediatePropagation();
7320
- }
7321
- });
7322
-
7323
- // Can't use _focusable() because the element that receives focus
7324
- // and the element that gets the ui-state-focus class are different
7325
- this._on({
7326
- focus: function() {
7327
- this.buttonElement.addClass( "ui-state-focus" );
7328
- },
7329
- blur: function() {
7330
- this.buttonElement.removeClass( "ui-state-focus" );
7331
- }
7332
- });
7333
-
7334
- if ( toggleButton ) {
7335
- this.element.bind( "change" + this.eventNamespace, function() {
7336
- that.refresh();
7337
- });
7338
- }
7339
-
7340
- if ( this.type === "checkbox" ) {
7341
- this.buttonElement.bind( "click" + this.eventNamespace, function() {
7342
- if ( options.disabled ) {
7343
- return false;
7344
- }
7345
- });
7346
- } else if ( this.type === "radio" ) {
7347
- this.buttonElement.bind( "click" + this.eventNamespace, function() {
7348
- if ( options.disabled ) {
7349
- return false;
7350
- }
7351
- $( this ).addClass( "ui-state-active" );
7352
- that.buttonElement.attr( "aria-pressed", "true" );
7353
-
7354
- var radio = that.element[ 0 ];
7355
- radioGroup( radio )
7356
- .not( radio )
7357
- .map(function() {
7358
- return $( this ).button( "widget" )[ 0 ];
7359
- })
7360
- .removeClass( "ui-state-active" )
7361
- .attr( "aria-pressed", "false" );
7362
- });
7363
- } else {
7364
- this.buttonElement
7365
- .bind( "mousedown" + this.eventNamespace, function() {
7366
- if ( options.disabled ) {
7367
- return false;
7368
- }
7369
- $( this ).addClass( "ui-state-active" );
7370
- lastActive = this;
7371
- that.document.one( "mouseup", function() {
7372
- lastActive = null;
7373
- });
7374
- })
7375
- .bind( "mouseup" + this.eventNamespace, function() {
7376
- if ( options.disabled ) {
7377
- return false;
7378
- }
7379
- $( this ).removeClass( "ui-state-active" );
7380
- })
7381
- .bind( "keydown" + this.eventNamespace, function(event) {
7382
- if ( options.disabled ) {
7383
- return false;
7384
- }
7385
- if ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {
7386
- $( this ).addClass( "ui-state-active" );
7387
- }
7388
- })
7389
- // see #8559, we bind to blur here in case the button element loses
7390
- // focus between keydown and keyup, it would be left in an "active" state
7391
- .bind( "keyup" + this.eventNamespace + " blur" + this.eventNamespace, function() {
7392
- $( this ).removeClass( "ui-state-active" );
7393
- });
7394
-
7395
- if ( this.buttonElement.is("a") ) {
7396
- this.buttonElement.keyup(function(event) {
7397
- if ( event.keyCode === $.ui.keyCode.SPACE ) {
7398
- // TODO pass through original event correctly (just as 2nd argument doesn't work)
7399
- $( this ).click();
7400
- }
7401
- });
7402
- }
7403
- }
7404
-
7405
- // TODO: pull out $.Widget's handling for the disabled option into
7406
- // $.Widget.prototype._setOptionDisabled so it's easy to proxy and can
7407
- // be overridden by individual plugins
7408
- this._setOption( "disabled", options.disabled );
7409
- this._resetButton();
7410
- },
7411
-
7412
- _determineButtonType: function() {
7413
- var ancestor, labelSelector, checked;
7414
-
7415
- if ( this.element.is("[type=checkbox]") ) {
7416
- this.type = "checkbox";
7417
- } else if ( this.element.is("[type=radio]") ) {
7418
- this.type = "radio";
7419
- } else if ( this.element.is("input") ) {
7420
- this.type = "input";
7421
- } else {
7422
- this.type = "button";
7423
- }
7424
-
7425
- if ( this.type === "checkbox" || this.type === "radio" ) {
7426
- // we don't search against the document in case the element
7427
- // is disconnected from the DOM
7428
- ancestor = this.element.parents().last();
7429
- labelSelector = "label[for='" + this.element.attr("id") + "']";
7430
- this.buttonElement = ancestor.find( labelSelector );
7431
- if ( !this.buttonElement.length ) {
7432
- ancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();
7433
- this.buttonElement = ancestor.filter( labelSelector );
7434
- if ( !this.buttonElement.length ) {
7435
- this.buttonElement = ancestor.find( labelSelector );
7436
- }
7437
- }
7438
- this.element.addClass( "ui-helper-hidden-accessible" );
7439
-
7440
- checked = this.element.is( ":checked" );
7441
- if ( checked ) {
7442
- this.buttonElement.addClass( "ui-state-active" );
7443
- }
7444
- this.buttonElement.prop( "aria-pressed", checked );
7445
- } else {
7446
- this.buttonElement = this.element;
7447
- }
7448
- },
7449
-
7450
- widget: function() {
7451
- return this.buttonElement;
7452
- },
7453
-
7454
- _destroy: function() {
7455
- this.element
7456
- .removeClass( "ui-helper-hidden-accessible" );
7457
- this.buttonElement
7458
- .removeClass( baseClasses + " ui-state-active " + typeClasses )
7459
- .removeAttr( "role" )
7460
- .removeAttr( "aria-pressed" )
7461
- .html( this.buttonElement.find(".ui-button-text").html() );
7462
-
7463
- if ( !this.hasTitle ) {
7464
- this.buttonElement.removeAttr( "title" );
7465
- }
7466
- },
7467
-
7468
- _setOption: function( key, value ) {
7469
- this._super( key, value );
7470
- if ( key === "disabled" ) {
7471
- this.element.prop( "disabled", !!value );
7472
- if ( value ) {
7473
- this.buttonElement.removeClass( "ui-state-focus" );
7474
- }
7475
- return;
7476
- }
7477
- this._resetButton();
7478
- },
7479
-
7480
- refresh: function() {
7481
- //See #8237 & #8828
7482
- var isDisabled = this.element.is( "input, button" ) ? this.element.is( ":disabled" ) : this.element.hasClass( "ui-button-disabled" );
7483
-
7484
- if ( isDisabled !== this.options.disabled ) {
7485
- this._setOption( "disabled", isDisabled );
7486
- }
7487
- if ( this.type === "radio" ) {
7488
- radioGroup( this.element[0] ).each(function() {
7489
- if ( $( this ).is( ":checked" ) ) {
7490
- $( this ).button( "widget" )
7491
- .addClass( "ui-state-active" )
7492
- .attr( "aria-pressed", "true" );
7493
- } else {
7494
- $( this ).button( "widget" )
7495
- .removeClass( "ui-state-active" )
7496
- .attr( "aria-pressed", "false" );
7497
- }
7498
- });
7499
- } else if ( this.type === "checkbox" ) {
7500
- if ( this.element.is( ":checked" ) ) {
7501
- this.buttonElement
7502
- .addClass( "ui-state-active" )
7503
- .attr( "aria-pressed", "true" );
7504
- } else {
7505
- this.buttonElement
7506
- .removeClass( "ui-state-active" )
7507
- .attr( "aria-pressed", "false" );
7508
- }
7509
- }
7510
- },
7511
-
7512
- _resetButton: function() {
7513
- if ( this.type === "input" ) {
7514
- if ( this.options.label ) {
7515
- this.element.val( this.options.label );
7516
- }
7517
- return;
7518
- }
7519
- var buttonElement = this.buttonElement.removeClass( typeClasses ),
7520
- buttonText = $( "<span></span>", this.document[0] )
7521
- .addClass( "ui-button-text" )
7522
- .html( this.options.label )
7523
- .appendTo( buttonElement.empty() )
7524
- .text(),
7525
- icons = this.options.icons,
7526
- multipleIcons = icons.primary && icons.secondary,
7527
- buttonClasses = [];
7528
-
7529
- if ( icons.primary || icons.secondary ) {
7530
- if ( this.options.text ) {
7531
- buttonClasses.push( "ui-button-text-icon" + ( multipleIcons ? "s" : ( icons.primary ? "-primary" : "-secondary" ) ) );
7532
- }
7533
-
7534
- if ( icons.primary ) {
7535
- buttonElement.prepend( "<span class='ui-button-icon-primary ui-icon " + icons.primary + "'></span>" );
7536
- }
7537
-
7538
- if ( icons.secondary ) {
7539
- buttonElement.append( "<span class='ui-button-icon-secondary ui-icon " + icons.secondary + "'></span>" );
7540
- }
7541
-
7542
- if ( !this.options.text ) {
7543
- buttonClasses.push( multipleIcons ? "ui-button-icons-only" : "ui-button-icon-only" );
7544
-
7545
- if ( !this.hasTitle ) {
7546
- buttonElement.attr( "title", $.trim( buttonText ) );
7547
- }
7548
- }
7549
- } else {
7550
- buttonClasses.push( "ui-button-text-only" );
7551
- }
7552
- buttonElement.addClass( buttonClasses.join( " " ) );
7553
- }
7554
- });
7555
-
7556
- $.widget( "ui.buttonset", {
7557
- version: "1.10.4",
7558
- options: {
7559
- items: "button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)"
7560
- },
7561
-
7562
- _create: function() {
7563
- this.element.addClass( "ui-buttonset" );
7564
- },
7565
-
7566
- _init: function() {
7567
- this.refresh();
7568
- },
7569
-
7570
- _setOption: function( key, value ) {
7571
- if ( key === "disabled" ) {
7572
- this.buttons.button( "option", key, value );
7573
- }
7574
-
7575
- this._super( key, value );
7576
- },
7577
-
7578
- refresh: function() {
7579
- var rtl = this.element.css( "direction" ) === "rtl";
7580
-
7581
- this.buttons = this.element.find( this.options.items )
7582
- .filter( ":ui-button" )
7583
- .button( "refresh" )
7584
- .end()
7585
- .not( ":ui-button" )
7586
- .button()
7587
- .end()
7588
- .map(function() {
7589
- return $( this ).button( "widget" )[ 0 ];
7590
- })
7591
- .removeClass( "ui-corner-all ui-corner-left ui-corner-right" )
7592
- .filter( ":first" )
7593
- .addClass( rtl ? "ui-corner-right" : "ui-corner-left" )
7594
- .end()
7595
- .filter( ":last" )
7596
- .addClass( rtl ? "ui-corner-left" : "ui-corner-right" )
7597
- .end()
7598
- .end();
7599
- },
7600
-
7601
- _destroy: function() {
7602
- this.element.removeClass( "ui-buttonset" );
7603
- this.buttons
7604
- .map(function() {
7605
- return $( this ).button( "widget" )[ 0 ];
7606
- })
7607
- .removeClass( "ui-corner-left ui-corner-right" )
7608
- .end()
7609
- .button( "destroy" );
7610
- }
7611
- });
7612
-
7613
- }( jQuery ) );
7614
-
7615
- (function( $, undefined ) {
7616
-
7617
- $.extend($.ui, { datepicker: { version: "1.10.4" } });
7618
-
7619
- var PROP_NAME = "datepicker",
7620
- instActive;
7621
-
7622
- /* Date picker manager.
7623
- Use the singleton instance of this class, $.datepicker, to interact with the date picker.
7624
- Settings for (groups of) date pickers are maintained in an instance object,
7625
- allowing multiple different settings on the same page. */
7626
-
7627
- function Datepicker() {
7628
- this._curInst = null; // The current instance in use
7629
- this._keyEvent = false; // If the last event was a key event
7630
- this._disabledInputs = []; // List of date picker inputs that have been disabled
7631
- this._datepickerShowing = false; // True if the popup picker is showing , false if not
7632
- this._inDialog = false; // True if showing within a "dialog", false if not
7633
- this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
7634
- this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
7635
- this._appendClass = "ui-datepicker-append"; // The name of the append marker class
7636
- this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
7637
- this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
7638
- this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
7639
- this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
7640
- this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
7641
- this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
7642
- this.regional = []; // Available regional settings, indexed by language code
7643
- this.regional[""] = { // Default regional settings
7644
- closeText: "Done", // Display text for close link
7645
- prevText: "Prev", // Display text for previous month link
7646
- nextText: "Next", // Display text for next month link
7647
- currentText: "Today", // Display text for current month link
7648
- monthNames: ["January","February","March","April","May","June",
7649
- "July","August","September","October","November","December"], // Names of months for drop-down and formatting
7650
- monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
7651
- dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
7652
- dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
7653
- dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
7654
- weekHeader: "Wk", // Column header for week of the year
7655
- dateFormat: "mm/dd/yy", // See format options on parseDate
7656
- firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
7657
- isRTL: false, // True if right-to-left language, false if left-to-right
7658
- showMonthAfterYear: false, // True if the year select precedes month, false for month then year
7659
- yearSuffix: "" // Additional text to append to the year in the month headers
7660
- };
7661
- this._defaults = { // Global defaults for all the date picker instances
7662
- showOn: "focus", // "focus" for popup on focus,
7663
- // "button" for trigger button, or "both" for either
7664
- showAnim: "fadeIn", // Name of jQuery animation for popup
7665
- showOptions: {}, // Options for enhanced animations
7666
- defaultDate: null, // Used when field is blank: actual date,
7667
- // +/-number for offset from today, null for today
7668
- appendText: "", // Display text following the input box, e.g. showing the format
7669
- buttonText: "...", // Text for trigger button
7670
- buttonImage: "", // URL for trigger button image
7671
- buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
7672
- hideIfNoPrevNext: false, // True to hide next/previous month links
7673
- // if not applicable, false to just disable them
7674
- navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
7675
- gotoCurrent: false, // True if today link goes back to current selection instead
7676
- changeMonth: false, // True if month can be selected directly, false if only prev/next
7677
- changeYear: false, // True if year can be selected directly, false if only prev/next
7678
- yearRange: "c-10:c+10", // Range of years to display in drop-down,
7679
- // either relative to today's year (-nn:+nn), relative to currently displayed year
7680
- // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
7681
- showOtherMonths: false, // True to show dates in other months, false to leave blank
7682
- selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
7683
- showWeek: false, // True to show week of the year, false to not show it
7684
- calculateWeek: this.iso8601Week, // How to calculate the week of the year,
7685
- // takes a Date and returns the number of the week for it
7686
- shortYearCutoff: "+10", // Short year values < this are in the current century,
7687
- // > this are in the previous century,
7688
- // string value starting with "+" for current year + value
7689
- minDate: null, // The earliest selectable date, or null for no limit
7690
- maxDate: null, // The latest selectable date, or null for no limit
7691
- duration: "fast", // Duration of display/closure
7692
- beforeShowDay: null, // Function that takes a date and returns an array with
7693
- // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
7694
- // [2] = cell title (optional), e.g. $.datepicker.noWeekends
7695
- beforeShow: null, // Function that takes an input field and
7696
- // returns a set of custom settings for the date picker
7697
- onSelect: null, // Define a callback function when a date is selected
7698
- onChangeMonthYear: null, // Define a callback function when the month or year is changed
7699
- onClose: null, // Define a callback function when the datepicker is closed
7700
- numberOfMonths: 1, // Number of months to show at a time
7701
- showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
7702
- stepMonths: 1, // Number of months to step back/forward
7703
- stepBigMonths: 12, // Number of months to step back/forward for the big links
7704
- altField: "", // Selector for an alternate field to store selected dates into
7705
- altFormat: "", // The date format to use for the alternate field
7706
- constrainInput: true, // The input is constrained by the current date format
7707
- showButtonPanel: false, // True to show button panel, false to not show it
7708
- autoSize: false, // True to size the input for the date format, false to leave as is
7709
- disabled: false // The initial disabled state
7710
- };
7711
- $.extend(this._defaults, this.regional[""]);
7712
- this.dpDiv = bindHover($("<div id='" + this._mainDivId + "' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>"));
7713
- }
7714
-
7715
- $.extend(Datepicker.prototype, {
7716
- /* Class name added to elements to indicate already configured with a date picker. */
7717
- markerClassName: "hasDatepicker",
7718
-
7719
- //Keep track of the maximum number of rows displayed (see #7043)
7720
- maxRows: 4,
7721
-
7722
- // TODO rename to "widget" when switching to widget factory
7723
- _widgetDatepicker: function() {
7724
- return this.dpDiv;
7725
- },
7726
-
7727
- /* Override the default settings for all instances of the date picker.
7728
- * @param settings object - the new settings to use as defaults (anonymous object)
7729
- * @return the manager object
7730
- */
7731
- setDefaults: function(settings) {
7732
- extendRemove(this._defaults, settings || {});
7733
- return this;
7734
- },
7735
-
7736
- /* Attach the date picker to a jQuery selection.
7737
- * @param target element - the target input field or division or span
7738
- * @param settings object - the new settings to use for this date picker instance (anonymous)
7739
- */
7740
- _attachDatepicker: function(target, settings) {
7741
- var nodeName, inline, inst;
7742
- nodeName = target.nodeName.toLowerCase();
7743
- inline = (nodeName === "div" || nodeName === "span");
7744
- if (!target.id) {
7745
- this.uuid += 1;
7746
- target.id = "dp" + this.uuid;
7747
- }
7748
- inst = this._newInst($(target), inline);
7749
- inst.settings = $.extend({}, settings || {});
7750
- if (nodeName === "input") {
7751
- this._connectDatepicker(target, inst);
7752
- } else if (inline) {
7753
- this._inlineDatepicker(target, inst);
7754
- }
7755
- },
7756
-
7757
- /* Create a new instance object. */
7758
- _newInst: function(target, inline) {
7759
- var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
7760
- return {id: id, input: target, // associated target
7761
- selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
7762
- drawMonth: 0, drawYear: 0, // month being drawn
7763
- inline: inline, // is datepicker inline or not
7764
- dpDiv: (!inline ? this.dpDiv : // presentation div
7765
- bindHover($("<div class='" + this._inlineClass + " ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>")))};
7766
- },
7767
-
7768
- /* Attach the date picker to an input field. */
7769
- _connectDatepicker: function(target, inst) {
7770
- var input = $(target);
7771
- inst.append = $([]);
7772
- inst.trigger = $([]);
7773
- if (input.hasClass(this.markerClassName)) {
7774
- return;
7775
- }
7776
- this._attachments(input, inst);
7777
- input.addClass(this.markerClassName).keydown(this._doKeyDown).
7778
- keypress(this._doKeyPress).keyup(this._doKeyUp);
7779
- this._autoSize(inst);
7780
- $.data(target, PROP_NAME, inst);
7781
- //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
7782
- if( inst.settings.disabled ) {
7783
- this._disableDatepicker( target );
7784
- }
7785
- },
7786
-
7787
- /* Make attachments based on settings. */
7788
- _attachments: function(input, inst) {
7789
- var showOn, buttonText, buttonImage,
7790
- appendText = this._get(inst, "appendText"),
7791
- isRTL = this._get(inst, "isRTL");
7792
-
7793
- if (inst.append) {
7794
- inst.append.remove();
7795
- }
7796
- if (appendText) {
7797
- inst.append = $("<span class='" + this._appendClass + "'>" + appendText + "</span>");
7798
- input[isRTL ? "before" : "after"](inst.append);
7799
- }
7800
-
7801
- input.unbind("focus", this._showDatepicker);
7802
-
7803
- if (inst.trigger) {
7804
- inst.trigger.remove();
7805
- }
7806
-
7807
- showOn = this._get(inst, "showOn");
7808
- if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
7809
- input.focus(this._showDatepicker);
7810
- }
7811
- if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
7812
- buttonText = this._get(inst, "buttonText");
7813
- buttonImage = this._get(inst, "buttonImage");
7814
- inst.trigger = $(this._get(inst, "buttonImageOnly") ?
7815
- $("<img/>").addClass(this._triggerClass).
7816
- attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
7817
- $("<button type='button'></button>").addClass(this._triggerClass).
7818
- html(!buttonImage ? buttonText : $("<img/>").attr(
7819
- { src:buttonImage, alt:buttonText, title:buttonText })));
7820
- input[isRTL ? "before" : "after"](inst.trigger);
7821
- inst.trigger.click(function() {
7822
- if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
7823
- $.datepicker._hideDatepicker();
7824
- } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
7825
- $.datepicker._hideDatepicker();
7826
- $.datepicker._showDatepicker(input[0]);
7827
- } else {
7828
- $.datepicker._showDatepicker(input[0]);
7829
- }
7830
- return false;
7831
- });
7832
- }
7833
- },
7834
-
7835
- /* Apply the maximum length for the date format. */
7836
- _autoSize: function(inst) {
7837
- if (this._get(inst, "autoSize") && !inst.inline) {
7838
- var findMax, max, maxI, i,
7839
- date = new Date(2009, 12 - 1, 20), // Ensure double digits
7840
- dateFormat = this._get(inst, "dateFormat");
7841
-
7842
- if (dateFormat.match(/[DM]/)) {
7843
- findMax = function(names) {
7844
- max = 0;
7845
- maxI = 0;
7846
- for (i = 0; i < names.length; i++) {
7847
- if (names[i].length > max) {
7848
- max = names[i].length;
7849
- maxI = i;
7850
- }
7851
- }
7852
- return maxI;
7853
- };
7854
- date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
7855
- "monthNames" : "monthNamesShort"))));
7856
- date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
7857
- "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
7858
- }
7859
- inst.input.attr("size", this._formatDate(inst, date).length);
7860
- }
7861
- },
7862
-
7863
- /* Attach an inline date picker to a div. */
7864
- _inlineDatepicker: function(target, inst) {
7865
- var divSpan = $(target);
7866
- if (divSpan.hasClass(this.markerClassName)) {
7867
- return;
7868
- }
7869
- divSpan.addClass(this.markerClassName).append(inst.dpDiv);
7870
- $.data(target, PROP_NAME, inst);
7871
- this._setDate(inst, this._getDefaultDate(inst), true);
7872
- this._updateDatepicker(inst);
7873
- this._updateAlternate(inst);
7874
- //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
7875
- if( inst.settings.disabled ) {
7876
- this._disableDatepicker( target );
7877
- }
7878
- // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
7879
- // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
7880
- inst.dpDiv.css( "display", "block" );
7881
- },
7882
-
7883
- /* Pop-up the date picker in a "dialog" box.
7884
- * @param input element - ignored
7885
- * @param date string or Date - the initial date to display
7886
- * @param onSelect function - the function to call when a date is selected
7887
- * @param settings object - update the dialog date picker instance's settings (anonymous object)
7888
- * @param pos int[2] - coordinates for the dialog's position within the screen or
7889
- * event - with x/y coordinates or
7890
- * leave empty for default (screen centre)
7891
- * @return the manager object
7892
- */
7893
- _dialogDatepicker: function(input, date, onSelect, settings, pos) {
7894
- var id, browserWidth, browserHeight, scrollX, scrollY,
7895
- inst = this._dialogInst; // internal instance
7896
-
7897
- if (!inst) {
7898
- this.uuid += 1;
7899
- id = "dp" + this.uuid;
7900
- this._dialogInput = $("<input type='text' id='" + id +
7901
- "' style='position: absolute; top: -100px; width: 0px;'/>");
7902
- this._dialogInput.keydown(this._doKeyDown);
7903
- $("body").append(this._dialogInput);
7904
- inst = this._dialogInst = this._newInst(this._dialogInput, false);
7905
- inst.settings = {};
7906
- $.data(this._dialogInput[0], PROP_NAME, inst);
7907
- }
7908
- extendRemove(inst.settings, settings || {});
7909
- date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
7910
- this._dialogInput.val(date);
7911
-
7912
- this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
7913
- if (!this._pos) {
7914
- browserWidth = document.documentElement.clientWidth;
7915
- browserHeight = document.documentElement.clientHeight;
7916
- scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
7917
- scrollY = document.documentElement.scrollTop || document.body.scrollTop;
7918
- this._pos = // should use actual width/height below
7919
- [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
7920
- }
7921
-
7922
- // move input on screen for focus, but hidden behind dialog
7923
- this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
7924
- inst.settings.onSelect = onSelect;
7925
- this._inDialog = true;
7926
- this.dpDiv.addClass(this._dialogClass);
7927
- this._showDatepicker(this._dialogInput[0]);
7928
- if ($.blockUI) {
7929
- $.blockUI(this.dpDiv);
7930
- }
7931
- $.data(this._dialogInput[0], PROP_NAME, inst);
7932
- return this;
7933
- },
7934
-
7935
- /* Detach a datepicker from its control.
7936
- * @param target element - the target input field or division or span
7937
- */
7938
- _destroyDatepicker: function(target) {
7939
- var nodeName,
7940
- $target = $(target),
7941
- inst = $.data(target, PROP_NAME);
7942
-
7943
- if (!$target.hasClass(this.markerClassName)) {
7944
- return;
7945
- }
7946
-
7947
- nodeName = target.nodeName.toLowerCase();
7948
- $.removeData(target, PROP_NAME);
7949
- if (nodeName === "input") {
7950
- inst.append.remove();
7951
- inst.trigger.remove();
7952
- $target.removeClass(this.markerClassName).
7953
- unbind("focus", this._showDatepicker).
7954
- unbind("keydown", this._doKeyDown).
7955
- unbind("keypress", this._doKeyPress).
7956
- unbind("keyup", this._doKeyUp);
7957
- } else if (nodeName === "div" || nodeName === "span") {
7958
- $target.removeClass(this.markerClassName).empty();
7959
- }
7960
- },
7961
-
7962
- /* Enable the date picker to a jQuery selection.
7963
- * @param target element - the target input field or division or span
7964
- */
7965
- _enableDatepicker: function(target) {
7966
- var nodeName, inline,
7967
- $target = $(target),
7968
- inst = $.data(target, PROP_NAME);
7969
-
7970
- if (!$target.hasClass(this.markerClassName)) {
7971
- return;
7972
- }
7973
-
7974
- nodeName = target.nodeName.toLowerCase();
7975
- if (nodeName === "input") {
7976
- target.disabled = false;
7977
- inst.trigger.filter("button").
7978
- each(function() { this.disabled = false; }).end().
7979
- filter("img").css({opacity: "1.0", cursor: ""});
7980
- } else if (nodeName === "div" || nodeName === "span") {
7981
- inline = $target.children("." + this._inlineClass);
7982
- inline.children().removeClass("ui-state-disabled");
7983
- inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
7984
- prop("disabled", false);
7985
- }
7986
- this._disabledInputs = $.map(this._disabledInputs,
7987
- function(value) { return (value === target ? null : value); }); // delete entry
7988
- },
7989
-
7990
- /* Disable the date picker to a jQuery selection.
7991
- * @param target element - the target input field or division or span
7992
- */
7993
- _disableDatepicker: function(target) {
7994
- var nodeName, inline,
7995
- $target = $(target),
7996
- inst = $.data(target, PROP_NAME);
7997
-
7998
- if (!$target.hasClass(this.markerClassName)) {
7999
- return;
8000
- }
8001
-
8002
- nodeName = target.nodeName.toLowerCase();
8003
- if (nodeName === "input") {
8004
- target.disabled = true;
8005
- inst.trigger.filter("button").
8006
- each(function() { this.disabled = true; }).end().
8007
- filter("img").css({opacity: "0.5", cursor: "default"});
8008
- } else if (nodeName === "div" || nodeName === "span") {
8009
- inline = $target.children("." + this._inlineClass);
8010
- inline.children().addClass("ui-state-disabled");
8011
- inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
8012
- prop("disabled", true);
8013
- }
8014
- this._disabledInputs = $.map(this._disabledInputs,
8015
- function(value) { return (value === target ? null : value); }); // delete entry
8016
- this._disabledInputs[this._disabledInputs.length] = target;
8017
- },
8018
-
8019
- /* Is the first field in a jQuery collection disabled as a datepicker?
8020
- * @param target element - the target input field or division or span
8021
- * @return boolean - true if disabled, false if enabled
8022
- */
8023
- _isDisabledDatepicker: function(target) {
8024
- if (!target) {
8025
- return false;
8026
- }
8027
- for (var i = 0; i < this._disabledInputs.length; i++) {
8028
- if (this._disabledInputs[i] === target) {
8029
- return true;
8030
- }
8031
- }
8032
- return false;
8033
- },
8034
-
8035
- /* Retrieve the instance data for the target control.
8036
- * @param target element - the target input field or division or span
8037
- * @return object - the associated instance data
8038
- * @throws error if a jQuery problem getting data
8039
- */
8040
- _getInst: function(target) {
8041
- try {
8042
- return $.data(target, PROP_NAME);
8043
- }
8044
- catch (err) {
8045
- throw "Missing instance data for this datepicker";
8046
- }
8047
- },
8048
-
8049
- /* Update or retrieve the settings for a date picker attached to an input field or division.
8050
- * @param target element - the target input field or division or span
8051
- * @param name object - the new settings to update or
8052
- * string - the name of the setting to change or retrieve,
8053
- * when retrieving also "all" for all instance settings or
8054
- * "defaults" for all global defaults
8055
- * @param value any - the new value for the setting
8056
- * (omit if above is an object or to retrieve a value)
8057
- */
8058
- _optionDatepicker: function(target, name, value) {
8059
- var settings, date, minDate, maxDate,
8060
- inst = this._getInst(target);
8061
-
8062
- if (arguments.length === 2 && typeof name === "string") {
8063
- return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
8064
- (inst ? (name === "all" ? $.extend({}, inst.settings) :
8065
- this._get(inst, name)) : null));
8066
- }
8067
-
8068
- settings = name || {};
8069
- if (typeof name === "string") {
8070
- settings = {};
8071
- settings[name] = value;
8072
- }
8073
-
8074
- if (inst) {
8075
- if (this._curInst === inst) {
8076
- this._hideDatepicker();
8077
- }
8078
-
8079
- date = this._getDateDatepicker(target, true);
8080
- minDate = this._getMinMaxDate(inst, "min");
8081
- maxDate = this._getMinMaxDate(inst, "max");
8082
- extendRemove(inst.settings, settings);
8083
- // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
8084
- if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
8085
- inst.settings.minDate = this._formatDate(inst, minDate);
8086
- }
8087
- if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
8088
- inst.settings.maxDate = this._formatDate(inst, maxDate);
8089
- }
8090
- if ( "disabled" in settings ) {
8091
- if ( settings.disabled ) {
8092
- this._disableDatepicker(target);
8093
- } else {
8094
- this._enableDatepicker(target);
8095
- }
8096
- }
8097
- this._attachments($(target), inst);
8098
- this._autoSize(inst);
8099
- this._setDate(inst, date);
8100
- this._updateAlternate(inst);
8101
- this._updateDatepicker(inst);
8102
- }
8103
- },
8104
-
8105
- // change method deprecated
8106
- _changeDatepicker: function(target, name, value) {
8107
- this._optionDatepicker(target, name, value);
8108
- },
8109
-
8110
- /* Redraw the date picker attached to an input field or division.
8111
- * @param target element - the target input field or division or span
8112
- */
8113
- _refreshDatepicker: function(target) {
8114
- var inst = this._getInst(target);
8115
- if (inst) {
8116
- this._updateDatepicker(inst);
8117
- }
8118
- },
8119
-
8120
- /* Set the dates for a jQuery selection.
8121
- * @param target element - the target input field or division or span
8122
- * @param date Date - the new date
8123
- */
8124
- _setDateDatepicker: function(target, date) {
8125
- var inst = this._getInst(target);
8126
- if (inst) {
8127
- this._setDate(inst, date);
8128
- this._updateDatepicker(inst);
8129
- this._updateAlternate(inst);
8130
- }
8131
- },
8132
-
8133
- /* Get the date(s) for the first entry in a jQuery selection.
8134
- * @param target element - the target input field or division or span
8135
- * @param noDefault boolean - true if no default date is to be used
8136
- * @return Date - the current date
8137
- */
8138
- _getDateDatepicker: function(target, noDefault) {
8139
- var inst = this._getInst(target);
8140
- if (inst && !inst.inline) {
8141
- this._setDateFromField(inst, noDefault);
8142
- }
8143
- return (inst ? this._getDate(inst) : null);
8144
- },
8145
-
8146
- /* Handle keystrokes. */
8147
- _doKeyDown: function(event) {
8148
- var onSelect, dateStr, sel,
8149
- inst = $.datepicker._getInst(event.target),
8150
- handled = true,
8151
- isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
8152
-
8153
- inst._keyEvent = true;
8154
- if ($.datepicker._datepickerShowing) {
8155
- switch (event.keyCode) {
8156
- case 9: $.datepicker._hideDatepicker();
8157
- handled = false;
8158
- break; // hide on tab out
8159
- case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
8160
- $.datepicker._currentClass + ")", inst.dpDiv);
8161
- if (sel[0]) {
8162
- $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
8163
- }
8164
-
8165
- onSelect = $.datepicker._get(inst, "onSelect");
8166
- if (onSelect) {
8167
- dateStr = $.datepicker._formatDate(inst);
8168
-
8169
- // trigger custom callback
8170
- onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
8171
- } else {
8172
- $.datepicker._hideDatepicker();
8173
- }
8174
-
8175
- return false; // don't submit the form
8176
- case 27: $.datepicker._hideDatepicker();
8177
- break; // hide on escape
8178
- case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8179
- -$.datepicker._get(inst, "stepBigMonths") :
8180
- -$.datepicker._get(inst, "stepMonths")), "M");
8181
- break; // previous month/year on page up/+ ctrl
8182
- case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8183
- +$.datepicker._get(inst, "stepBigMonths") :
8184
- +$.datepicker._get(inst, "stepMonths")), "M");
8185
- break; // next month/year on page down/+ ctrl
8186
- case 35: if (event.ctrlKey || event.metaKey) {
8187
- $.datepicker._clearDate(event.target);
8188
- }
8189
- handled = event.ctrlKey || event.metaKey;
8190
- break; // clear on ctrl or command +end
8191
- case 36: if (event.ctrlKey || event.metaKey) {
8192
- $.datepicker._gotoToday(event.target);
8193
- }
8194
- handled = event.ctrlKey || event.metaKey;
8195
- break; // current on ctrl or command +home
8196
- case 37: if (event.ctrlKey || event.metaKey) {
8197
- $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
8198
- }
8199
- handled = event.ctrlKey || event.metaKey;
8200
- // -1 day on ctrl or command +left
8201
- if (event.originalEvent.altKey) {
8202
- $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8203
- -$.datepicker._get(inst, "stepBigMonths") :
8204
- -$.datepicker._get(inst, "stepMonths")), "M");
8205
- }
8206
- // next month/year on alt +left on Mac
8207
- break;
8208
- case 38: if (event.ctrlKey || event.metaKey) {
8209
- $.datepicker._adjustDate(event.target, -7, "D");
8210
- }
8211
- handled = event.ctrlKey || event.metaKey;
8212
- break; // -1 week on ctrl or command +up
8213
- case 39: if (event.ctrlKey || event.metaKey) {
8214
- $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
8215
- }
8216
- handled = event.ctrlKey || event.metaKey;
8217
- // +1 day on ctrl or command +right
8218
- if (event.originalEvent.altKey) {
8219
- $.datepicker._adjustDate(event.target, (event.ctrlKey ?
8220
- +$.datepicker._get(inst, "stepBigMonths") :
8221
- +$.datepicker._get(inst, "stepMonths")), "M");
8222
- }
8223
- // next month/year on alt +right
8224
- break;
8225
- case 40: if (event.ctrlKey || event.metaKey) {
8226
- $.datepicker._adjustDate(event.target, +7, "D");
8227
- }
8228
- handled = event.ctrlKey || event.metaKey;
8229
- break; // +1 week on ctrl or command +down
8230
- default: handled = false;
8231
- }
8232
- } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
8233
- $.datepicker._showDatepicker(this);
8234
- } else {
8235
- handled = false;
8236
- }
8237
-
8238
- if (handled) {
8239
- event.preventDefault();
8240
- event.stopPropagation();
8241
- }
8242
- },
8243
-
8244
- /* Filter entered characters - based on date format. */
8245
- _doKeyPress: function(event) {
8246
- var chars, chr,
8247
- inst = $.datepicker._getInst(event.target);
8248
-
8249
- if ($.datepicker._get(inst, "constrainInput")) {
8250
- chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
8251
- chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
8252
- return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
8253
- }
8254
- },
8255
-
8256
- /* Synchronise manual entry and field/alternate field. */
8257
- _doKeyUp: function(event) {
8258
- var date,
8259
- inst = $.datepicker._getInst(event.target);
8260
-
8261
- if (inst.input.val() !== inst.lastVal) {
8262
- try {
8263
- date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
8264
- (inst.input ? inst.input.val() : null),
8265
- $.datepicker._getFormatConfig(inst));
8266
-
8267
- if (date) { // only if valid
8268
- $.datepicker._setDateFromField(inst);
8269
- $.datepicker._updateAlternate(inst);
8270
- $.datepicker._updateDatepicker(inst);
8271
- }
8272
- }
8273
- catch (err) {
8274
- }
8275
- }
8276
- return true;
8277
- },
8278
-
8279
- /* Pop-up the date picker for a given input field.
8280
- * If false returned from beforeShow event handler do not show.
8281
- * @param input element - the input field attached to the date picker or
8282
- * event - if triggered by focus
8283
- */
8284
- _showDatepicker: function(input) {
8285
- input = input.target || input;
8286
- if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
8287
- input = $("input", input.parentNode)[0];
8288
- }
8289
-
8290
- if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
8291
- return;
8292
- }
8293
-
8294
- var inst, beforeShow, beforeShowSettings, isFixed,
8295
- offset, showAnim, duration;
8296
-
8297
- inst = $.datepicker._getInst(input);
8298
- if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
8299
- $.datepicker._curInst.dpDiv.stop(true, true);
8300
- if ( inst && $.datepicker._datepickerShowing ) {
8301
- $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
8302
- }
8303
- }
8304
-
8305
- beforeShow = $.datepicker._get(inst, "beforeShow");
8306
- beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
8307
- if(beforeShowSettings === false){
8308
- return;
8309
- }
8310
- extendRemove(inst.settings, beforeShowSettings);
8311
-
8312
- inst.lastVal = null;
8313
- $.datepicker._lastInput = input;
8314
- $.datepicker._setDateFromField(inst);
8315
-
8316
- if ($.datepicker._inDialog) { // hide cursor
8317
- input.value = "";
8318
- }
8319
- if (!$.datepicker._pos) { // position below input
8320
- $.datepicker._pos = $.datepicker._findPos(input);
8321
- $.datepicker._pos[1] += input.offsetHeight; // add the height
8322
- }
8323
-
8324
- isFixed = false;
8325
- $(input).parents().each(function() {
8326
- isFixed |= $(this).css("position") === "fixed";
8327
- return !isFixed;
8328
- });
8329
-
8330
- offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
8331
- $.datepicker._pos = null;
8332
- //to avoid flashes on Firefox
8333
- inst.dpDiv.empty();
8334
- // determine sizing offscreen
8335
- inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
8336
- $.datepicker._updateDatepicker(inst);
8337
- // fix width for dynamic number of date pickers
8338
- // and adjust position before showing
8339
- offset = $.datepicker._checkOffset(inst, offset, isFixed);
8340
- inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
8341
- "static" : (isFixed ? "fixed" : "absolute")), display: "none",
8342
- left: offset.left + "px", top: offset.top + "px"});
8343
-
8344
- if (!inst.inline) {
8345
- showAnim = $.datepicker._get(inst, "showAnim");
8346
- duration = $.datepicker._get(inst, "duration");
8347
- inst.dpDiv.zIndex($(input).zIndex()+1);
8348
- $.datepicker._datepickerShowing = true;
8349
-
8350
- if ( $.effects && $.effects.effect[ showAnim ] ) {
8351
- inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
8352
- } else {
8353
- inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
8354
- }
8355
-
8356
- if ( $.datepicker._shouldFocusInput( inst ) ) {
8357
- inst.input.focus();
8358
- }
8359
-
8360
- $.datepicker._curInst = inst;
8361
- }
8362
- },
8363
-
8364
- /* Generate the date picker content. */
8365
- _updateDatepicker: function(inst) {
8366
- this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
8367
- instActive = inst; // for delegate hover events
8368
- inst.dpDiv.empty().append(this._generateHTML(inst));
8369
- this._attachHandlers(inst);
8370
- inst.dpDiv.find("." + this._dayOverClass + " a").mouseover();
8371
-
8372
- var origyearshtml,
8373
- numMonths = this._getNumberOfMonths(inst),
8374
- cols = numMonths[1],
8375
- width = 17;
8376
-
8377
- inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
8378
- if (cols > 1) {
8379
- inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
8380
- }
8381
- inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
8382
- "Class"]("ui-datepicker-multi");
8383
- inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
8384
- "Class"]("ui-datepicker-rtl");
8385
-
8386
- if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
8387
- inst.input.focus();
8388
- }
8389
-
8390
- // deffered render of the years select (to avoid flashes on Firefox)
8391
- if( inst.yearshtml ){
8392
- origyearshtml = inst.yearshtml;
8393
- setTimeout(function(){
8394
- //assure that inst.yearshtml didn't change.
8395
- if( origyearshtml === inst.yearshtml && inst.yearshtml ){
8396
- inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
8397
- }
8398
- origyearshtml = inst.yearshtml = null;
8399
- }, 0);
8400
- }
8401
- },
8402
-
8403
- // #6694 - don't focus the input if it's already focused
8404
- // this breaks the change event in IE
8405
- // Support: IE and jQuery <1.9
8406
- _shouldFocusInput: function( inst ) {
8407
- return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
8408
- },
8409
-
8410
- /* Check positioning to remain on screen. */
8411
- _checkOffset: function(inst, offset, isFixed) {
8412
- var dpWidth = inst.dpDiv.outerWidth(),
8413
- dpHeight = inst.dpDiv.outerHeight(),
8414
- inputWidth = inst.input ? inst.input.outerWidth() : 0,
8415
- inputHeight = inst.input ? inst.input.outerHeight() : 0,
8416
- viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
8417
- viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
8418
-
8419
- offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
8420
- offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
8421
- offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
8422
-
8423
- // now check if datepicker is showing outside window viewport - move to a better place if so.
8424
- offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
8425
- Math.abs(offset.left + dpWidth - viewWidth) : 0);
8426
- offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
8427
- Math.abs(dpHeight + inputHeight) : 0);
8428
-
8429
- return offset;
8430
- },
8431
-
8432
- /* Find an object's position on the screen. */
8433
- _findPos: function(obj) {
8434
- var position,
8435
- inst = this._getInst(obj),
8436
- isRTL = this._get(inst, "isRTL");
8437
-
8438
- while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
8439
- obj = obj[isRTL ? "previousSibling" : "nextSibling"];
8440
- }
8441
-
8442
- position = $(obj).offset();
8443
- return [position.left, position.top];
8444
- },
8445
-
8446
- /* Hide the date picker from view.
8447
- * @param input element - the input field attached to the date picker
8448
- */
8449
- _hideDatepicker: function(input) {
8450
- var showAnim, duration, postProcess, onClose,
8451
- inst = this._curInst;
8452
-
8453
- if (!inst || (input && inst !== $.data(input, PROP_NAME))) {
8454
- return;
8455
- }
8456
-
8457
- if (this._datepickerShowing) {
8458
- showAnim = this._get(inst, "showAnim");
8459
- duration = this._get(inst, "duration");
8460
- postProcess = function() {
8461
- $.datepicker._tidyDialog(inst);
8462
- };
8463
-
8464
- // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
8465
- if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
8466
- inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
8467
- } else {
8468
- inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
8469
- (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
8470
- }
8471
-
8472
- if (!showAnim) {
8473
- postProcess();
8474
- }
8475
- this._datepickerShowing = false;
8476
-
8477
- onClose = this._get(inst, "onClose");
8478
- if (onClose) {
8479
- onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
8480
- }
8481
-
8482
- this._lastInput = null;
8483
- if (this._inDialog) {
8484
- this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
8485
- if ($.blockUI) {
8486
- $.unblockUI();
8487
- $("body").append(this.dpDiv);
8488
- }
8489
- }
8490
- this._inDialog = false;
8491
- }
8492
- },
8493
-
8494
- /* Tidy up after a dialog display. */
8495
- _tidyDialog: function(inst) {
8496
- inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
8497
- },
8498
-
8499
- /* Close date picker if clicked elsewhere. */
8500
- _checkExternalClick: function(event) {
8501
- if (!$.datepicker._curInst) {
8502
- return;
8503
- }
8504
-
8505
- var $target = $(event.target),
8506
- inst = $.datepicker._getInst($target[0]);
8507
-
8508
- if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
8509
- $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
8510
- !$target.hasClass($.datepicker.markerClassName) &&
8511
- !$target.closest("." + $.datepicker._triggerClass).length &&
8512
- $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
8513
- ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
8514
- $.datepicker._hideDatepicker();
8515
- }
8516
- },
8517
-
8518
- /* Adjust one of the date sub-fields. */
8519
- _adjustDate: function(id, offset, period) {
8520
- var target = $(id),
8521
- inst = this._getInst(target[0]);
8522
-
8523
- if (this._isDisabledDatepicker(target[0])) {
8524
- return;
8525
- }
8526
- this._adjustInstDate(inst, offset +
8527
- (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
8528
- period);
8529
- this._updateDatepicker(inst);
8530
- },
8531
-
8532
- /* Action for current link. */
8533
- _gotoToday: function(id) {
8534
- var date,
8535
- target = $(id),
8536
- inst = this._getInst(target[0]);
8537
-
8538
- if (this._get(inst, "gotoCurrent") && inst.currentDay) {
8539
- inst.selectedDay = inst.currentDay;
8540
- inst.drawMonth = inst.selectedMonth = inst.currentMonth;
8541
- inst.drawYear = inst.selectedYear = inst.currentYear;
8542
- } else {
8543
- date = new Date();
8544
- inst.selectedDay = date.getDate();
8545
- inst.drawMonth = inst.selectedMonth = date.getMonth();
8546
- inst.drawYear = inst.selectedYear = date.getFullYear();
8547
- }
8548
- this._notifyChange(inst);
8549
- this._adjustDate(target);
8550
- },
8551
-
8552
- /* Action for selecting a new month/year. */
8553
- _selectMonthYear: function(id, select, period) {
8554
- var target = $(id),
8555
- inst = this._getInst(target[0]);
8556
-
8557
- inst["selected" + (period === "M" ? "Month" : "Year")] =
8558
- inst["draw" + (period === "M" ? "Month" : "Year")] =
8559
- parseInt(select.options[select.selectedIndex].value,10);
8560
-
8561
- this._notifyChange(inst);
8562
- this._adjustDate(target);
8563
- },
8564
-
8565
- /* Action for selecting a day. */
8566
- _selectDay: function(id, month, year, td) {
8567
- var inst,
8568
- target = $(id);
8569
-
8570
- if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
8571
- return;
8572
- }
8573
-
8574
- inst = this._getInst(target[0]);
8575
- inst.selectedDay = inst.currentDay = $("a", td).html();
8576
- inst.selectedMonth = inst.currentMonth = month;
8577
- inst.selectedYear = inst.currentYear = year;
8578
- this._selectDate(id, this._formatDate(inst,
8579
- inst.currentDay, inst.currentMonth, inst.currentYear));
8580
- },
8581
-
8582
- /* Erase the input field and hide the date picker. */
8583
- _clearDate: function(id) {
8584
- var target = $(id);
8585
- this._selectDate(target, "");
8586
- },
8587
-
8588
- /* Update the input field with the selected date. */
8589
- _selectDate: function(id, dateStr) {
8590
- var onSelect,
8591
- target = $(id),
8592
- inst = this._getInst(target[0]);
8593
-
8594
- dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
8595
- if (inst.input) {
8596
- inst.input.val(dateStr);
8597
- }
8598
- this._updateAlternate(inst);
8599
-
8600
- onSelect = this._get(inst, "onSelect");
8601
- if (onSelect) {
8602
- onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
8603
- } else if (inst.input) {
8604
- inst.input.trigger("change"); // fire the change event
8605
- }
8606
-
8607
- if (inst.inline){
8608
- this._updateDatepicker(inst);
8609
- } else {
8610
- this._hideDatepicker();
8611
- this._lastInput = inst.input[0];
8612
- if (typeof(inst.input[0]) !== "object") {
8613
- inst.input.focus(); // restore focus
8614
- }
8615
- this._lastInput = null;
8616
- }
8617
- },
8618
-
8619
- /* Update any alternate field to synchronise with the main field. */
8620
- _updateAlternate: function(inst) {
8621
- var altFormat, date, dateStr,
8622
- altField = this._get(inst, "altField");
8623
-
8624
- if (altField) { // update alternate field too
8625
- altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
8626
- date = this._getDate(inst);
8627
- dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
8628
- $(altField).each(function() { $(this).val(dateStr); });
8629
- }
8630
- },
8631
-
8632
- /* Set as beforeShowDay function to prevent selection of weekends.
8633
- * @param date Date - the date to customise
8634
- * @return [boolean, string] - is this date selectable?, what is its CSS class?
8635
- */
8636
- noWeekends: function(date) {
8637
- var day = date.getDay();
8638
- return [(day > 0 && day < 6), ""];
8639
- },
8640
-
8641
- /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
8642
- * @param date Date - the date to get the week for
8643
- * @return number - the number of the week within the year that contains this date
8644
- */
8645
- iso8601Week: function(date) {
8646
- var time,
8647
- checkDate = new Date(date.getTime());
8648
-
8649
- // Find Thursday of this week starting on Monday
8650
- checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
8651
-
8652
- time = checkDate.getTime();
8653
- checkDate.setMonth(0); // Compare with Jan 1
8654
- checkDate.setDate(1);
8655
- return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
8656
- },
8657
-
8658
- /* Parse a string value into a date object.
8659
- * See formatDate below for the possible formats.
8660
- *
8661
- * @param format string - the expected format of the date
8662
- * @param value string - the date in the above format
8663
- * @param settings Object - attributes include:
8664
- * shortYearCutoff number - the cutoff year for determining the century (optional)
8665
- * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
8666
- * dayNames string[7] - names of the days from Sunday (optional)
8667
- * monthNamesShort string[12] - abbreviated names of the months (optional)
8668
- * monthNames string[12] - names of the months (optional)
8669
- * @return Date - the extracted date value or null if value is blank
8670
- */
8671
- parseDate: function (format, value, settings) {
8672
- if (format == null || value == null) {
8673
- throw "Invalid arguments";
8674
- }
8675
-
8676
- value = (typeof value === "object" ? value.toString() : value + "");
8677
- if (value === "") {
8678
- return null;
8679
- }
8680
-
8681
- var iFormat, dim, extra,
8682
- iValue = 0,
8683
- shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
8684
- shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
8685
- new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
8686
- dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8687
- dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8688
- monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8689
- monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8690
- year = -1,
8691
- month = -1,
8692
- day = -1,
8693
- doy = -1,
8694
- literal = false,
8695
- date,
8696
- // Check whether a format character is doubled
8697
- lookAhead = function(match) {
8698
- var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8699
- if (matches) {
8700
- iFormat++;
8701
- }
8702
- return matches;
8703
- },
8704
- // Extract a number from the string value
8705
- getNumber = function(match) {
8706
- var isDoubled = lookAhead(match),
8707
- size = (match === "@" ? 14 : (match === "!" ? 20 :
8708
- (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
8709
- digits = new RegExp("^\\d{1," + size + "}"),
8710
- num = value.substring(iValue).match(digits);
8711
- if (!num) {
8712
- throw "Missing number at position " + iValue;
8713
- }
8714
- iValue += num[0].length;
8715
- return parseInt(num[0], 10);
8716
- },
8717
- // Extract a name from the string value and convert to an index
8718
- getName = function(match, shortNames, longNames) {
8719
- var index = -1,
8720
- names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
8721
- return [ [k, v] ];
8722
- }).sort(function (a, b) {
8723
- return -(a[1].length - b[1].length);
8724
- });
8725
-
8726
- $.each(names, function (i, pair) {
8727
- var name = pair[1];
8728
- if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
8729
- index = pair[0];
8730
- iValue += name.length;
8731
- return false;
8732
- }
8733
- });
8734
- if (index !== -1) {
8735
- return index + 1;
8736
- } else {
8737
- throw "Unknown name at position " + iValue;
8738
- }
8739
- },
8740
- // Confirm that a literal character matches the string value
8741
- checkLiteral = function() {
8742
- if (value.charAt(iValue) !== format.charAt(iFormat)) {
8743
- throw "Unexpected literal at position " + iValue;
8744
- }
8745
- iValue++;
8746
- };
8747
-
8748
- for (iFormat = 0; iFormat < format.length; iFormat++) {
8749
- if (literal) {
8750
- if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8751
- literal = false;
8752
- } else {
8753
- checkLiteral();
8754
- }
8755
- } else {
8756
- switch (format.charAt(iFormat)) {
8757
- case "d":
8758
- day = getNumber("d");
8759
- break;
8760
- case "D":
8761
- getName("D", dayNamesShort, dayNames);
8762
- break;
8763
- case "o":
8764
- doy = getNumber("o");
8765
- break;
8766
- case "m":
8767
- month = getNumber("m");
8768
- break;
8769
- case "M":
8770
- month = getName("M", monthNamesShort, monthNames);
8771
- break;
8772
- case "y":
8773
- year = getNumber("y");
8774
- break;
8775
- case "@":
8776
- date = new Date(getNumber("@"));
8777
- year = date.getFullYear();
8778
- month = date.getMonth() + 1;
8779
- day = date.getDate();
8780
- break;
8781
- case "!":
8782
- date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
8783
- year = date.getFullYear();
8784
- month = date.getMonth() + 1;
8785
- day = date.getDate();
8786
- break;
8787
- case "'":
8788
- if (lookAhead("'")){
8789
- checkLiteral();
8790
- } else {
8791
- literal = true;
8792
- }
8793
- break;
8794
- default:
8795
- checkLiteral();
8796
- }
8797
- }
8798
- }
8799
-
8800
- if (iValue < value.length){
8801
- extra = value.substr(iValue);
8802
- if (!/^\s+/.test(extra)) {
8803
- throw "Extra/unparsed characters found in date: " + extra;
8804
- }
8805
- }
8806
-
8807
- if (year === -1) {
8808
- year = new Date().getFullYear();
8809
- } else if (year < 100) {
8810
- year += new Date().getFullYear() - new Date().getFullYear() % 100 +
8811
- (year <= shortYearCutoff ? 0 : -100);
8812
- }
8813
-
8814
- if (doy > -1) {
8815
- month = 1;
8816
- day = doy;
8817
- do {
8818
- dim = this._getDaysInMonth(year, month - 1);
8819
- if (day <= dim) {
8820
- break;
8821
- }
8822
- month++;
8823
- day -= dim;
8824
- } while (true);
8825
- }
8826
-
8827
- date = this._daylightSavingAdjust(new Date(year, month - 1, day));
8828
- if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
8829
- throw "Invalid date"; // E.g. 31/02/00
8830
- }
8831
- return date;
8832
- },
8833
-
8834
- /* Standard date formats. */
8835
- ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
8836
- COOKIE: "D, dd M yy",
8837
- ISO_8601: "yy-mm-dd",
8838
- RFC_822: "D, d M y",
8839
- RFC_850: "DD, dd-M-y",
8840
- RFC_1036: "D, d M y",
8841
- RFC_1123: "D, d M yy",
8842
- RFC_2822: "D, d M yy",
8843
- RSS: "D, d M y", // RFC 822
8844
- TICKS: "!",
8845
- TIMESTAMP: "@",
8846
- W3C: "yy-mm-dd", // ISO 8601
8847
-
8848
- _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
8849
- Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
8850
-
8851
- /* Format a date object into a string value.
8852
- * The format can be combinations of the following:
8853
- * d - day of month (no leading zero)
8854
- * dd - day of month (two digit)
8855
- * o - day of year (no leading zeros)
8856
- * oo - day of year (three digit)
8857
- * D - day name short
8858
- * DD - day name long
8859
- * m - month of year (no leading zero)
8860
- * mm - month of year (two digit)
8861
- * M - month name short
8862
- * MM - month name long
8863
- * y - year (two digit)
8864
- * yy - year (four digit)
8865
- * @ - Unix timestamp (ms since 01/01/1970)
8866
- * ! - Windows ticks (100ns since 01/01/0001)
8867
- * "..." - literal text
8868
- * '' - single quote
8869
- *
8870
- * @param format string - the desired format of the date
8871
- * @param date Date - the date value to format
8872
- * @param settings Object - attributes include:
8873
- * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
8874
- * dayNames string[7] - names of the days from Sunday (optional)
8875
- * monthNamesShort string[12] - abbreviated names of the months (optional)
8876
- * monthNames string[12] - names of the months (optional)
8877
- * @return string - the date in the above format
8878
- */
8879
- formatDate: function (format, date, settings) {
8880
- if (!date) {
8881
- return "";
8882
- }
8883
-
8884
- var iFormat,
8885
- dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
8886
- dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
8887
- monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
8888
- monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
8889
- // Check whether a format character is doubled
8890
- lookAhead = function(match) {
8891
- var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8892
- if (matches) {
8893
- iFormat++;
8894
- }
8895
- return matches;
8896
- },
8897
- // Format a number, with leading zero if necessary
8898
- formatNumber = function(match, value, len) {
8899
- var num = "" + value;
8900
- if (lookAhead(match)) {
8901
- while (num.length < len) {
8902
- num = "0" + num;
8903
- }
8904
- }
8905
- return num;
8906
- },
8907
- // Format a name, short or long as requested
8908
- formatName = function(match, value, shortNames, longNames) {
8909
- return (lookAhead(match) ? longNames[value] : shortNames[value]);
8910
- },
8911
- output = "",
8912
- literal = false;
8913
-
8914
- if (date) {
8915
- for (iFormat = 0; iFormat < format.length; iFormat++) {
8916
- if (literal) {
8917
- if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8918
- literal = false;
8919
- } else {
8920
- output += format.charAt(iFormat);
8921
- }
8922
- } else {
8923
- switch (format.charAt(iFormat)) {
8924
- case "d":
8925
- output += formatNumber("d", date.getDate(), 2);
8926
- break;
8927
- case "D":
8928
- output += formatName("D", date.getDay(), dayNamesShort, dayNames);
8929
- break;
8930
- case "o":
8931
- output += formatNumber("o",
8932
- Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
8933
- break;
8934
- case "m":
8935
- output += formatNumber("m", date.getMonth() + 1, 2);
8936
- break;
8937
- case "M":
8938
- output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
8939
- break;
8940
- case "y":
8941
- output += (lookAhead("y") ? date.getFullYear() :
8942
- (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
8943
- break;
8944
- case "@":
8945
- output += date.getTime();
8946
- break;
8947
- case "!":
8948
- output += date.getTime() * 10000 + this._ticksTo1970;
8949
- break;
8950
- case "'":
8951
- if (lookAhead("'")) {
8952
- output += "'";
8953
- } else {
8954
- literal = true;
8955
- }
8956
- break;
8957
- default:
8958
- output += format.charAt(iFormat);
8959
- }
8960
- }
8961
- }
8962
- }
8963
- return output;
8964
- },
8965
-
8966
- /* Extract all possible characters from the date format. */
8967
- _possibleChars: function (format) {
8968
- var iFormat,
8969
- chars = "",
8970
- literal = false,
8971
- // Check whether a format character is doubled
8972
- lookAhead = function(match) {
8973
- var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
8974
- if (matches) {
8975
- iFormat++;
8976
- }
8977
- return matches;
8978
- };
8979
-
8980
- for (iFormat = 0; iFormat < format.length; iFormat++) {
8981
- if (literal) {
8982
- if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
8983
- literal = false;
8984
- } else {
8985
- chars += format.charAt(iFormat);
8986
- }
8987
- } else {
8988
- switch (format.charAt(iFormat)) {
8989
- case "d": case "m": case "y": case "@":
8990
- chars += "0123456789";
8991
- break;
8992
- case "D": case "M":
8993
- return null; // Accept anything
8994
- case "'":
8995
- if (lookAhead("'")) {
8996
- chars += "'";
8997
- } else {
8998
- literal = true;
8999
- }
9000
- break;
9001
- default:
9002
- chars += format.charAt(iFormat);
9003
- }
9004
- }
9005
- }
9006
- return chars;
9007
- },
9008
-
9009
- /* Get a setting value, defaulting if necessary. */
9010
- _get: function(inst, name) {
9011
- return inst.settings[name] !== undefined ?
9012
- inst.settings[name] : this._defaults[name];
9013
- },
9014
-
9015
- /* Parse existing date and initialise date picker. */
9016
- _setDateFromField: function(inst, noDefault) {
9017
- if (inst.input.val() === inst.lastVal) {
9018
- return;
9019
- }
9020
-
9021
- var dateFormat = this._get(inst, "dateFormat"),
9022
- dates = inst.lastVal = inst.input ? inst.input.val() : null,
9023
- defaultDate = this._getDefaultDate(inst),
9024
- date = defaultDate,
9025
- settings = this._getFormatConfig(inst);
9026
-
9027
- try {
9028
- date = this.parseDate(dateFormat, dates, settings) || defaultDate;
9029
- } catch (event) {
9030
- dates = (noDefault ? "" : dates);
9031
- }
9032
- inst.selectedDay = date.getDate();
9033
- inst.drawMonth = inst.selectedMonth = date.getMonth();
9034
- inst.drawYear = inst.selectedYear = date.getFullYear();
9035
- inst.currentDay = (dates ? date.getDate() : 0);
9036
- inst.currentMonth = (dates ? date.getMonth() : 0);
9037
- inst.currentYear = (dates ? date.getFullYear() : 0);
9038
- this._adjustInstDate(inst);
9039
- },
9040
-
9041
- /* Retrieve the default date shown on opening. */
9042
- _getDefaultDate: function(inst) {
9043
- return this._restrictMinMax(inst,
9044
- this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
9045
- },
9046
-
9047
- /* A date may be specified as an exact value or a relative one. */
9048
- _determineDate: function(inst, date, defaultDate) {
9049
- var offsetNumeric = function(offset) {
9050
- var date = new Date();
9051
- date.setDate(date.getDate() + offset);
9052
- return date;
9053
- },
9054
- offsetString = function(offset) {
9055
- try {
9056
- return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
9057
- offset, $.datepicker._getFormatConfig(inst));
9058
- }
9059
- catch (e) {
9060
- // Ignore
9061
- }
9062
-
9063
- var date = (offset.toLowerCase().match(/^c/) ?
9064
- $.datepicker._getDate(inst) : null) || new Date(),
9065
- year = date.getFullYear(),
9066
- month = date.getMonth(),
9067
- day = date.getDate(),
9068
- pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
9069
- matches = pattern.exec(offset);
9070
-
9071
- while (matches) {
9072
- switch (matches[2] || "d") {
9073
- case "d" : case "D" :
9074
- day += parseInt(matches[1],10); break;
9075
- case "w" : case "W" :
9076
- day += parseInt(matches[1],10) * 7; break;
9077
- case "m" : case "M" :
9078
- month += parseInt(matches[1],10);
9079
- day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9080
- break;
9081
- case "y": case "Y" :
9082
- year += parseInt(matches[1],10);
9083
- day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
9084
- break;
9085
- }
9086
- matches = pattern.exec(offset);
9087
- }
9088
- return new Date(year, month, day);
9089
- },
9090
- newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
9091
- (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
9092
-
9093
- newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
9094
- if (newDate) {
9095
- newDate.setHours(0);
9096
- newDate.setMinutes(0);
9097
- newDate.setSeconds(0);
9098
- newDate.setMilliseconds(0);
9099
- }
9100
- return this._daylightSavingAdjust(newDate);
9101
- },
9102
-
9103
- /* Handle switch to/from daylight saving.
9104
- * Hours may be non-zero on daylight saving cut-over:
9105
- * > 12 when midnight changeover, but then cannot generate
9106
- * midnight datetime, so jump to 1AM, otherwise reset.
9107
- * @param date (Date) the date to check
9108
- * @return (Date) the corrected date
9109
- */
9110
- _daylightSavingAdjust: function(date) {
9111
- if (!date) {
9112
- return null;
9113
- }
9114
- date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
9115
- return date;
9116
- },
9117
-
9118
- /* Set the date(s) directly. */
9119
- _setDate: function(inst, date, noChange) {
9120
- var clear = !date,
9121
- origMonth = inst.selectedMonth,
9122
- origYear = inst.selectedYear,
9123
- newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
9124
-
9125
- inst.selectedDay = inst.currentDay = newDate.getDate();
9126
- inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
9127
- inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
9128
- if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
9129
- this._notifyChange(inst);
9130
- }
9131
- this._adjustInstDate(inst);
9132
- if (inst.input) {
9133
- inst.input.val(clear ? "" : this._formatDate(inst));
9134
- }
9135
- },
9136
-
9137
- /* Retrieve the date(s) directly. */
9138
- _getDate: function(inst) {
9139
- var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
9140
- this._daylightSavingAdjust(new Date(
9141
- inst.currentYear, inst.currentMonth, inst.currentDay)));
9142
- return startDate;
9143
- },
9144
-
9145
- /* Attach the onxxx handlers. These are declared statically so
9146
- * they work with static code transformers like Caja.
9147
- */
9148
- _attachHandlers: function(inst) {
9149
- var stepMonths = this._get(inst, "stepMonths"),
9150
- id = "#" + inst.id.replace( /\\\\/g, "\\" );
9151
- inst.dpDiv.find("[data-handler]").map(function () {
9152
- var handler = {
9153
- prev: function () {
9154
- $.datepicker._adjustDate(id, -stepMonths, "M");
9155
- },
9156
- next: function () {
9157
- $.datepicker._adjustDate(id, +stepMonths, "M");
9158
- },
9159
- hide: function () {
9160
- $.datepicker._hideDatepicker();
9161
- },
9162
- today: function () {
9163
- $.datepicker._gotoToday(id);
9164
- },
9165
- selectDay: function () {
9166
- $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
9167
- return false;
9168
- },
9169
- selectMonth: function () {
9170
- $.datepicker._selectMonthYear(id, this, "M");
9171
- return false;
9172
- },
9173
- selectYear: function () {
9174
- $.datepicker._selectMonthYear(id, this, "Y");
9175
- return false;
9176
- }
9177
- };
9178
- $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
9179
- });
9180
- },
9181
-
9182
- /* Generate the HTML for the current state of the date picker. */
9183
- _generateHTML: function(inst) {
9184
- var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
9185
- controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
9186
- monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
9187
- selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
9188
- cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
9189
- printDate, dRow, tbody, daySettings, otherMonth, unselectable,
9190
- tempDate = new Date(),
9191
- today = this._daylightSavingAdjust(
9192
- new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
9193
- isRTL = this._get(inst, "isRTL"),
9194
- showButtonPanel = this._get(inst, "showButtonPanel"),
9195
- hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
9196
- navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
9197
- numMonths = this._getNumberOfMonths(inst),
9198
- showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
9199
- stepMonths = this._get(inst, "stepMonths"),
9200
- isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
9201
- currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
9202
- new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
9203
- minDate = this._getMinMaxDate(inst, "min"),
9204
- maxDate = this._getMinMaxDate(inst, "max"),
9205
- drawMonth = inst.drawMonth - showCurrentAtPos,
9206
- drawYear = inst.drawYear;
9207
-
9208
- if (drawMonth < 0) {
9209
- drawMonth += 12;
9210
- drawYear--;
9211
- }
9212
- if (maxDate) {
9213
- maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
9214
- maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
9215
- maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
9216
- while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
9217
- drawMonth--;
9218
- if (drawMonth < 0) {
9219
- drawMonth = 11;
9220
- drawYear--;
9221
- }
9222
- }
9223
- }
9224
- inst.drawMonth = drawMonth;
9225
- inst.drawYear = drawYear;
9226
-
9227
- prevText = this._get(inst, "prevText");
9228
- prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
9229
- this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
9230
- this._getFormatConfig(inst)));
9231
-
9232
- prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
9233
- "<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'" +
9234
- " title='" + prevText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>" :
9235
- (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='"+ prevText +"'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "e" : "w") + "'>" + prevText + "</span></a>"));
9236
-
9237
- nextText = this._get(inst, "nextText");
9238
- nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
9239
- this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
9240
- this._getFormatConfig(inst)));
9241
-
9242
- next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
9243
- "<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'" +
9244
- " title='" + nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>" :
9245
- (hideIfNoPrevNext ? "" : "<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='"+ nextText + "'><span class='ui-icon ui-icon-circle-triangle-" + ( isRTL ? "w" : "e") + "'>" + nextText + "</span></a>"));
9246
-
9247
- currentText = this._get(inst, "currentText");
9248
- gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
9249
- currentText = (!navigationAsDateFormat ? currentText :
9250
- this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
9251
-
9252
- controls = (!inst.inline ? "<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>" +
9253
- this._get(inst, "closeText") + "</button>" : "");
9254
-
9255
- buttonPanel = (showButtonPanel) ? "<div class='ui-datepicker-buttonpane ui-widget-content'>" + (isRTL ? controls : "") +
9256
- (this._isInRange(inst, gotoDate) ? "<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'" +
9257
- ">" + currentText + "</button>" : "") + (isRTL ? "" : controls) + "</div>" : "";
9258
-
9259
- firstDay = parseInt(this._get(inst, "firstDay"),10);
9260
- firstDay = (isNaN(firstDay) ? 0 : firstDay);
9261
-
9262
- showWeek = this._get(inst, "showWeek");
9263
- dayNames = this._get(inst, "dayNames");
9264
- dayNamesMin = this._get(inst, "dayNamesMin");
9265
- monthNames = this._get(inst, "monthNames");
9266
- monthNamesShort = this._get(inst, "monthNamesShort");
9267
- beforeShowDay = this._get(inst, "beforeShowDay");
9268
- showOtherMonths = this._get(inst, "showOtherMonths");
9269
- selectOtherMonths = this._get(inst, "selectOtherMonths");
9270
- defaultDate = this._getDefaultDate(inst);
9271
- html = "";
9272
- dow;
9273
- for (row = 0; row < numMonths[0]; row++) {
9274
- group = "";
9275
- this.maxRows = 4;
9276
- for (col = 0; col < numMonths[1]; col++) {
9277
- selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
9278
- cornerClass = " ui-corner-all";
9279
- calender = "";
9280
- if (isMultiMonth) {
9281
- calender += "<div class='ui-datepicker-group";
9282
- if (numMonths[1] > 1) {
9283
- switch (col) {
9284
- case 0: calender += " ui-datepicker-group-first";
9285
- cornerClass = " ui-corner-" + (isRTL ? "right" : "left"); break;
9286
- case numMonths[1]-1: calender += " ui-datepicker-group-last";
9287
- cornerClass = " ui-corner-" + (isRTL ? "left" : "right"); break;
9288
- default: calender += " ui-datepicker-group-middle"; cornerClass = ""; break;
9289
- }
9290
- }
9291
- calender += "'>";
9292
- }
9293
- calender += "<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix" + cornerClass + "'>" +
9294
- (/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : "") +
9295
- (/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : "") +
9296
- this._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,
9297
- row > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers
9298
- "</div><table class='ui-datepicker-calendar'><thead>" +
9299
- "<tr>";
9300
- thead = (showWeek ? "<th class='ui-datepicker-week-col'>" + this._get(inst, "weekHeader") + "</th>" : "");
9301
- for (dow = 0; dow < 7; dow++) { // days of the week
9302
- day = (dow + firstDay) % 7;
9303
- thead += "<th" + ((dow + firstDay + 6) % 7 >= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
9304
- "<span title='" + dayNames[day] + "'>" + dayNamesMin[day] + "</span></th>";
9305
- }
9306
- calender += thead + "</tr></thead><tbody>";
9307
- daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
9308
- if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
9309
- inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
9310
- }
9311
- leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
9312
- curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
9313
- numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
9314
- this.maxRows = numRows;
9315
- printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
9316
- for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
9317
- calender += "<tr>";
9318
- tbody = (!showWeek ? "" : "<td class='ui-datepicker-week-col'>" +
9319
- this._get(inst, "calculateWeek")(printDate) + "</td>");
9320
- for (dow = 0; dow < 7; dow++) { // create date picker days
9321
- daySettings = (beforeShowDay ?
9322
- beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
9323
- otherMonth = (printDate.getMonth() !== drawMonth);
9324
- unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
9325
- (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
9326
- tbody += "<td class='" +
9327
- ((dow + firstDay + 6) % 7 >= 5 ? " ui-datepicker-week-end" : "") + // highlight weekends
9328
- (otherMonth ? " ui-datepicker-other-month" : "") + // highlight days from other months
9329
- ((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key
9330
- (defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?
9331
- // or defaultDate is current printedDate and defaultDate is selectedDate
9332
- " " + this._dayOverClass : "") + // highlight selected day
9333
- (unselectable ? " " + this._unselectableClass + " ui-state-disabled": "") + // highlight unselectable days
9334
- (otherMonth && !showOtherMonths ? "" : " " + daySettings[1] + // highlight custom dates
9335
- (printDate.getTime() === currentDate.getTime() ? " " + this._currentClass : "") + // highlight selected day
9336
- (printDate.getTime() === today.getTime() ? " ui-datepicker-today" : "")) + "'" + // highlight today (if different)
9337
- ((!otherMonth || showOtherMonths) && daySettings[2] ? " title='" + daySettings[2].replace(/'/g, "&#39;") + "'" : "") + // cell title
9338
- (unselectable ? "" : " data-handler='selectDay' data-event='click' data-month='" + printDate.getMonth() + "' data-year='" + printDate.getFullYear() + "'") + ">" + // actions
9339
- (otherMonth && !showOtherMonths ? "&#xa0;" : // display for other months
9340
- (unselectable ? "<span class='ui-state-default'>" + printDate.getDate() + "</span>" : "<a class='ui-state-default" +
9341
- (printDate.getTime() === today.getTime() ? " ui-state-highlight" : "") +
9342
- (printDate.getTime() === currentDate.getTime() ? " ui-state-active" : "") + // highlight selected day
9343
- (otherMonth ? " ui-priority-secondary" : "") + // distinguish dates from other months
9344
- "' href='#'>" + printDate.getDate() + "</a>")) + "</td>"; // display selectable date
9345
- printDate.setDate(printDate.getDate() + 1);
9346
- printDate = this._daylightSavingAdjust(printDate);
9347
- }
9348
- calender += tbody + "</tr>";
9349
- }
9350
- drawMonth++;
9351
- if (drawMonth > 11) {
9352
- drawMonth = 0;
9353
- drawYear++;
9354
- }
9355
- calender += "</tbody></table>" + (isMultiMonth ? "</div>" +
9356
- ((numMonths[0] > 0 && col === numMonths[1]-1) ? "<div class='ui-datepicker-row-break'></div>" : "") : "");
9357
- group += calender;
9358
- }
9359
- html += group;
9360
- }
9361
- html += buttonPanel;
9362
- inst._keyEvent = false;
9363
- return html;
9364
- },
9365
-
9366
- /* Generate the month and year header. */
9367
- _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
9368
- secondary, monthNames, monthNamesShort) {
9369
-
9370
- var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
9371
- changeMonth = this._get(inst, "changeMonth"),
9372
- changeYear = this._get(inst, "changeYear"),
9373
- showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
9374
- html = "<div class='ui-datepicker-title'>",
9375
- monthHtml = "";
9376
-
9377
- // month selection
9378
- if (secondary || !changeMonth) {
9379
- monthHtml += "<span class='ui-datepicker-month'>" + monthNames[drawMonth] + "</span>";
9380
- } else {
9381
- inMinYear = (minDate && minDate.getFullYear() === drawYear);
9382
- inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
9383
- monthHtml += "<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>";
9384
- for ( month = 0; month < 12; month++) {
9385
- if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
9386
- monthHtml += "<option value='" + month + "'" +
9387
- (month === drawMonth ? " selected='selected'" : "") +
9388
- ">" + monthNamesShort[month] + "</option>";
9389
- }
9390
- }
9391
- monthHtml += "</select>";
9392
- }
9393
-
9394
- if (!showMonthAfterYear) {
9395
- html += monthHtml + (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "");
9396
- }
9397
-
9398
- // year selection
9399
- if ( !inst.yearshtml ) {
9400
- inst.yearshtml = "";
9401
- if (secondary || !changeYear) {
9402
- html += "<span class='ui-datepicker-year'>" + drawYear + "</span>";
9403
- } else {
9404
- // determine range of years to display
9405
- years = this._get(inst, "yearRange").split(":");
9406
- thisYear = new Date().getFullYear();
9407
- determineYear = function(value) {
9408
- var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
9409
- (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
9410
- parseInt(value, 10)));
9411
- return (isNaN(year) ? thisYear : year);
9412
- };
9413
- year = determineYear(years[0]);
9414
- endYear = Math.max(year, determineYear(years[1] || ""));
9415
- year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
9416
- endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
9417
- inst.yearshtml += "<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>";
9418
- for (; year <= endYear; year++) {
9419
- inst.yearshtml += "<option value='" + year + "'" +
9420
- (year === drawYear ? " selected='selected'" : "") +
9421
- ">" + year + "</option>";
9422
- }
9423
- inst.yearshtml += "</select>";
9424
-
9425
- html += inst.yearshtml;
9426
- inst.yearshtml = null;
9427
- }
9428
- }
9429
-
9430
- html += this._get(inst, "yearSuffix");
9431
- if (showMonthAfterYear) {
9432
- html += (secondary || !(changeMonth && changeYear) ? "&#xa0;" : "") + monthHtml;
9433
- }
9434
- html += "</div>"; // Close datepicker_header
9435
- return html;
9436
- },
9437
-
9438
- /* Adjust one of the date sub-fields. */
9439
- _adjustInstDate: function(inst, offset, period) {
9440
- var year = inst.drawYear + (period === "Y" ? offset : 0),
9441
- month = inst.drawMonth + (period === "M" ? offset : 0),
9442
- day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
9443
- date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
9444
-
9445
- inst.selectedDay = date.getDate();
9446
- inst.drawMonth = inst.selectedMonth = date.getMonth();
9447
- inst.drawYear = inst.selectedYear = date.getFullYear();
9448
- if (period === "M" || period === "Y") {
9449
- this._notifyChange(inst);
9450
- }
9451
- },
9452
-
9453
- /* Ensure a date is within any min/max bounds. */
9454
- _restrictMinMax: function(inst, date) {
9455
- var minDate = this._getMinMaxDate(inst, "min"),
9456
- maxDate = this._getMinMaxDate(inst, "max"),
9457
- newDate = (minDate && date < minDate ? minDate : date);
9458
- return (maxDate && newDate > maxDate ? maxDate : newDate);
9459
- },
9460
-
9461
- /* Notify change of month/year. */
9462
- _notifyChange: function(inst) {
9463
- var onChange = this._get(inst, "onChangeMonthYear");
9464
- if (onChange) {
9465
- onChange.apply((inst.input ? inst.input[0] : null),
9466
- [inst.selectedYear, inst.selectedMonth + 1, inst]);
9467
- }
9468
- },
9469
-
9470
- /* Determine the number of months to show. */
9471
- _getNumberOfMonths: function(inst) {
9472
- var numMonths = this._get(inst, "numberOfMonths");
9473
- return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
9474
- },
9475
-
9476
- /* Determine the current maximum date - ensure no time components are set. */
9477
- _getMinMaxDate: function(inst, minMax) {
9478
- return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
9479
- },
9480
-
9481
- /* Find the number of days in a given month. */
9482
- _getDaysInMonth: function(year, month) {
9483
- return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
9484
- },
9485
-
9486
- /* Find the day of the week of the first of a month. */
9487
- _getFirstDayOfMonth: function(year, month) {
9488
- return new Date(year, month, 1).getDay();
9489
- },
9490
-
9491
- /* Determines if we should allow a "next/prev" month display change. */
9492
- _canAdjustMonth: function(inst, offset, curYear, curMonth) {
9493
- var numMonths = this._getNumberOfMonths(inst),
9494
- date = this._daylightSavingAdjust(new Date(curYear,
9495
- curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
9496
-
9497
- if (offset < 0) {
9498
- date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
9499
- }
9500
- return this._isInRange(inst, date);
9501
- },
9502
-
9503
- /* Is the given date in the accepted range? */
9504
- _isInRange: function(inst, date) {
9505
- var yearSplit, currentYear,
9506
- minDate = this._getMinMaxDate(inst, "min"),
9507
- maxDate = this._getMinMaxDate(inst, "max"),
9508
- minYear = null,
9509
- maxYear = null,
9510
- years = this._get(inst, "yearRange");
9511
- if (years){
9512
- yearSplit = years.split(":");
9513
- currentYear = new Date().getFullYear();
9514
- minYear = parseInt(yearSplit[0], 10);
9515
- maxYear = parseInt(yearSplit[1], 10);
9516
- if ( yearSplit[0].match(/[+\-].*/) ) {
9517
- minYear += currentYear;
9518
- }
9519
- if ( yearSplit[1].match(/[+\-].*/) ) {
9520
- maxYear += currentYear;
9521
- }
9522
- }
9523
-
9524
- return ((!minDate || date.getTime() >= minDate.getTime()) &&
9525
- (!maxDate || date.getTime() <= maxDate.getTime()) &&
9526
- (!minYear || date.getFullYear() >= minYear) &&
9527
- (!maxYear || date.getFullYear() <= maxYear));
9528
- },
9529
-
9530
- /* Provide the configuration settings for formatting/parsing. */
9531
- _getFormatConfig: function(inst) {
9532
- var shortYearCutoff = this._get(inst, "shortYearCutoff");
9533
- shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
9534
- new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
9535
- return {shortYearCutoff: shortYearCutoff,
9536
- dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
9537
- monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
9538
- },
9539
-
9540
- /* Format the given date for display. */
9541
- _formatDate: function(inst, day, month, year) {
9542
- if (!day) {
9543
- inst.currentDay = inst.selectedDay;
9544
- inst.currentMonth = inst.selectedMonth;
9545
- inst.currentYear = inst.selectedYear;
9546
- }
9547
- var date = (day ? (typeof day === "object" ? day :
9548
- this._daylightSavingAdjust(new Date(year, month, day))) :
9549
- this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
9550
- return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
9551
- }
9552
- });
9553
-
9554
- /*
9555
- * Bind hover events for datepicker elements.
9556
- * Done via delegate so the binding only occurs once in the lifetime of the parent div.
9557
- * Global instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
9558
- */
9559
- function bindHover(dpDiv) {
9560
- var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
9561
- return dpDiv.delegate(selector, "mouseout", function() {
9562
- $(this).removeClass("ui-state-hover");
9563
- if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9564
- $(this).removeClass("ui-datepicker-prev-hover");
9565
- }
9566
- if (this.className.indexOf("ui-datepicker-next") !== -1) {
9567
- $(this).removeClass("ui-datepicker-next-hover");
9568
- }
9569
- })
9570
- .delegate(selector, "mouseover", function(){
9571
- if (!$.datepicker._isDisabledDatepicker( instActive.inline ? dpDiv.parent()[0] : instActive.input[0])) {
9572
- $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
9573
- $(this).addClass("ui-state-hover");
9574
- if (this.className.indexOf("ui-datepicker-prev") !== -1) {
9575
- $(this).addClass("ui-datepicker-prev-hover");
9576
- }
9577
- if (this.className.indexOf("ui-datepicker-next") !== -1) {
9578
- $(this).addClass("ui-datepicker-next-hover");
9579
- }
9580
- }
9581
- });
9582
- }
9583
-
9584
- /* jQuery extend now ignores nulls! */
9585
- function extendRemove(target, props) {
9586
- $.extend(target, props);
9587
- for (var name in props) {
9588
- if (props[name] == null) {
9589
- target[name] = props[name];
9590
- }
9591
- }
9592
- return target;
9593
- }
9594
-
9595
- /* Invoke the datepicker functionality.
9596
- @param options string - a command, optionally followed by additional parameters or
9597
- Object - settings for attaching new datepicker functionality
9598
- @return jQuery object */
9599
- $.fn.datepicker = function(options){
9600
-
9601
- /* Verify an empty collection wasn't passed - Fixes #6976 */
9602
- if ( !this.length ) {
9603
- return this;
9604
- }
9605
-
9606
- /* Initialise the date picker. */
9607
- if (!$.datepicker.initialized) {
9608
- $(document).mousedown($.datepicker._checkExternalClick);
9609
- $.datepicker.initialized = true;
9610
- }
9611
-
9612
- /* Append datepicker main container to body if not exist. */
9613
- if ($("#"+$.datepicker._mainDivId).length === 0) {
9614
- $("body").append($.datepicker.dpDiv);
9615
- }
9616
-
9617
- var otherArgs = Array.prototype.slice.call(arguments, 1);
9618
- if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
9619
- return $.datepicker["_" + options + "Datepicker"].
9620
- apply($.datepicker, [this[0]].concat(otherArgs));
9621
- }
9622
- if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
9623
- return $.datepicker["_" + options + "Datepicker"].
9624
- apply($.datepicker, [this[0]].concat(otherArgs));
9625
- }
9626
- return this.each(function() {
9627
- typeof options === "string" ?
9628
- $.datepicker["_" + options + "Datepicker"].
9629
- apply($.datepicker, [this].concat(otherArgs)) :
9630
- $.datepicker._attachDatepicker(this, options);
9631
- });
9632
- };
9633
-
9634
- $.datepicker = new Datepicker(); // singleton instance
9635
- $.datepicker.initialized = false;
9636
- $.datepicker.uuid = new Date().getTime();
9637
- $.datepicker.version = "1.10.4";
9638
-
9639
- })(jQuery);
9640
-
9641
- (function( $, undefined ) {
9642
-
9643
- var sizeRelatedOptions = {
9644
- buttons: true,
9645
- height: true,
9646
- maxHeight: true,
9647
- maxWidth: true,
9648
- minHeight: true,
9649
- minWidth: true,
9650
- width: true
9651
- },
9652
- resizableRelatedOptions = {
9653
- maxHeight: true,
9654
- maxWidth: true,
9655
- minHeight: true,
9656
- minWidth: true
9657
- };
9658
-
9659
- $.widget( "ui.dialog", {
9660
- version: "1.10.4",
9661
- options: {
9662
- appendTo: "body",
9663
- autoOpen: true,
9664
- buttons: [],
9665
- closeOnEscape: true,
9666
- closeText: "close",
9667
- dialogClass: "",
9668
- draggable: true,
9669
- hide: null,
9670
- height: "auto",
9671
- maxHeight: null,
9672
- maxWidth: null,
9673
- minHeight: 150,
9674
- minWidth: 150,
9675
- modal: false,
9676
- position: {
9677
- my: "center",
9678
- at: "center",
9679
- of: window,
9680
- collision: "fit",
9681
- // Ensure the titlebar is always visible
9682
- using: function( pos ) {
9683
- var topOffset = $( this ).css( pos ).offset().top;
9684
- if ( topOffset < 0 ) {
9685
- $( this ).css( "top", pos.top - topOffset );
9686
- }
9687
- }
9688
- },
9689
- resizable: true,
9690
- show: null,
9691
- title: null,
9692
- width: 300,
9693
-
9694
- // callbacks
9695
- beforeClose: null,
9696
- close: null,
9697
- drag: null,
9698
- dragStart: null,
9699
- dragStop: null,
9700
- focus: null,
9701
- open: null,
9702
- resize: null,
9703
- resizeStart: null,
9704
- resizeStop: null
9705
- },
9706
-
9707
- _create: function() {
9708
- this.originalCss = {
9709
- display: this.element[0].style.display,
9710
- width: this.element[0].style.width,
9711
- minHeight: this.element[0].style.minHeight,
9712
- maxHeight: this.element[0].style.maxHeight,
9713
- height: this.element[0].style.height
9714
- };
9715
- this.originalPosition = {
9716
- parent: this.element.parent(),
9717
- index: this.element.parent().children().index( this.element )
9718
- };
9719
- this.originalTitle = this.element.attr("title");
9720
- this.options.title = this.options.title || this.originalTitle;
9721
-
9722
- this._createWrapper();
9723
-
9724
- this.element
9725
- .show()
9726
- .removeAttr("title")
9727
- .addClass("ui-dialog-content ui-widget-content")
9728
- .appendTo( this.uiDialog );
9729
-
9730
- this._createTitlebar();
9731
- this._createButtonPane();
9732
-
9733
- if ( this.options.draggable && $.fn.draggable ) {
9734
- this._makeDraggable();
9735
- }
9736
- if ( this.options.resizable && $.fn.resizable ) {
9737
- this._makeResizable();
9738
- }
9739
-
9740
- this._isOpen = false;
9741
- },
9742
-
9743
- _init: function() {
9744
- if ( this.options.autoOpen ) {
9745
- this.open();
9746
- }
9747
- },
9748
-
9749
- _appendTo: function() {
9750
- var element = this.options.appendTo;
9751
- if ( element && (element.jquery || element.nodeType) ) {
9752
- return $( element );
9753
- }
9754
- return this.document.find( element || "body" ).eq( 0 );
9755
- },
9756
-
9757
- _destroy: function() {
9758
- var next,
9759
- originalPosition = this.originalPosition;
9760
-
9761
- this._destroyOverlay();
9762
-
9763
- this.element
9764
- .removeUniqueId()
9765
- .removeClass("ui-dialog-content ui-widget-content")
9766
- .css( this.originalCss )
9767
- // Without detaching first, the following becomes really slow
9768
- .detach();
9769
-
9770
- this.uiDialog.stop( true, true ).remove();
9771
-
9772
- if ( this.originalTitle ) {
9773
- this.element.attr( "title", this.originalTitle );
9774
- }
9775
-
9776
- next = originalPosition.parent.children().eq( originalPosition.index );
9777
- // Don't try to place the dialog next to itself (#8613)
9778
- if ( next.length && next[0] !== this.element[0] ) {
9779
- next.before( this.element );
9780
- } else {
9781
- originalPosition.parent.append( this.element );
9782
- }
9783
- },
9784
-
9785
- widget: function() {
9786
- return this.uiDialog;
9787
- },
9788
-
9789
- disable: $.noop,
9790
- enable: $.noop,
9791
-
9792
- close: function( event ) {
9793
- var activeElement,
9794
- that = this;
9795
-
9796
- if ( !this._isOpen || this._trigger( "beforeClose", event ) === false ) {
9797
- return;
9798
- }
9799
-
9800
- this._isOpen = false;
9801
- this._destroyOverlay();
9802
-
9803
- if ( !this.opener.filter(":focusable").focus().length ) {
9804
-
9805
- // support: IE9
9806
- // IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
9807
- try {
9808
- activeElement = this.document[ 0 ].activeElement;
9809
-
9810
- // Support: IE9, IE10
9811
- // If the <body> is blurred, IE will switch windows, see #4520
9812
- if ( activeElement && activeElement.nodeName.toLowerCase() !== "body" ) {
9813
-
9814
- // Hiding a focused element doesn't trigger blur in WebKit
9815
- // so in case we have nothing to focus on, explicitly blur the active element
9816
- // https://bugs.webkit.org/show_bug.cgi?id=47182
9817
- $( activeElement ).blur();
9818
- }
9819
- } catch ( error ) {}
9820
- }
9821
-
9822
- this._hide( this.uiDialog, this.options.hide, function() {
9823
- that._trigger( "close", event );
9824
- });
9825
- },
9826
-
9827
- isOpen: function() {
9828
- return this._isOpen;
9829
- },
9830
-
9831
- moveToTop: function() {
9832
- this._moveToTop();
9833
- },
9834
-
9835
- _moveToTop: function( event, silent ) {
9836
- var moved = !!this.uiDialog.nextAll(":visible").insertBefore( this.uiDialog ).length;
9837
- if ( moved && !silent ) {
9838
- this._trigger( "focus", event );
9839
- }
9840
- return moved;
9841
- },
9842
-
9843
- open: function() {
9844
- var that = this;
9845
- if ( this._isOpen ) {
9846
- if ( this._moveToTop() ) {
9847
- this._focusTabbable();
9848
- }
9849
- return;
9850
- }
9851
-
9852
- this._isOpen = true;
9853
- this.opener = $( this.document[0].activeElement );
9854
-
9855
- this._size();
9856
- this._position();
9857
- this._createOverlay();
9858
- this._moveToTop( null, true );
9859
- this._show( this.uiDialog, this.options.show, function() {
9860
- that._focusTabbable();
9861
- that._trigger("focus");
9862
- });
9863
-
9864
- this._trigger("open");
9865
- },
9866
-
9867
- _focusTabbable: function() {
9868
- // Set focus to the first match:
9869
- // 1. First element inside the dialog matching [autofocus]
9870
- // 2. Tabbable element inside the content element
9871
- // 3. Tabbable element inside the buttonpane
9872
- // 4. The close button
9873
- // 5. The dialog itself
9874
- var hasFocus = this.element.find("[autofocus]");
9875
- if ( !hasFocus.length ) {
9876
- hasFocus = this.element.find(":tabbable");
9877
- }
9878
- if ( !hasFocus.length ) {
9879
- hasFocus = this.uiDialogButtonPane.find(":tabbable");
9880
- }
9881
- if ( !hasFocus.length ) {
9882
- hasFocus = this.uiDialogTitlebarClose.filter(":tabbable");
9883
- }
9884
- if ( !hasFocus.length ) {
9885
- hasFocus = this.uiDialog;
9886
- }
9887
- hasFocus.eq( 0 ).focus();
9888
- },
9889
-
9890
- _keepFocus: function( event ) {
9891
- function checkFocus() {
9892
- var activeElement = this.document[0].activeElement,
9893
- isActive = this.uiDialog[0] === activeElement ||
9894
- $.contains( this.uiDialog[0], activeElement );
9895
- if ( !isActive ) {
9896
- this._focusTabbable();
9897
- }
9898
- }
9899
- event.preventDefault();
9900
- checkFocus.call( this );
9901
- // support: IE
9902
- // IE <= 8 doesn't prevent moving focus even with event.preventDefault()
9903
- // so we check again later
9904
- this._delay( checkFocus );
9905
- },
9906
-
9907
- _createWrapper: function() {
9908
- this.uiDialog = $("<div>")
9909
- .addClass( "ui-dialog ui-widget ui-widget-content ui-corner-all ui-front " +
9910
- this.options.dialogClass )
9911
- .hide()
9912
- .attr({
9913
- // Setting tabIndex makes the div focusable
9914
- tabIndex: -1,
9915
- role: "dialog"
9916
- })
9917
- .appendTo( this._appendTo() );
9918
-
9919
- this._on( this.uiDialog, {
9920
- keydown: function( event ) {
9921
- if ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&
9922
- event.keyCode === $.ui.keyCode.ESCAPE ) {
9923
- event.preventDefault();
9924
- this.close( event );
9925
- return;
9926
- }
9927
-
9928
- // prevent tabbing out of dialogs
9929
- if ( event.keyCode !== $.ui.keyCode.TAB ) {
9930
- return;
9931
- }
9932
- var tabbables = this.uiDialog.find(":tabbable"),
9933
- first = tabbables.filter(":first"),
9934
- last = tabbables.filter(":last");
9935
-
9936
- if ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {
9937
- first.focus( 1 );
9938
- event.preventDefault();
9939
- } else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {
9940
- last.focus( 1 );
9941
- event.preventDefault();
9942
- }
9943
- },
9944
- mousedown: function( event ) {
9945
- if ( this._moveToTop( event ) ) {
9946
- this._focusTabbable();
9947
- }
9948
- }
9949
- });
9950
-
9951
- // We assume that any existing aria-describedby attribute means
9952
- // that the dialog content is marked up properly
9953
- // otherwise we brute force the content as the description
9954
- if ( !this.element.find("[aria-describedby]").length ) {
9955
- this.uiDialog.attr({
9956
- "aria-describedby": this.element.uniqueId().attr("id")
9957
- });
9958
- }
9959
- },
9960
-
9961
- _createTitlebar: function() {
9962
- var uiDialogTitle;
9963
-
9964
- this.uiDialogTitlebar = $("<div>")
9965
- .addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix")
9966
- .prependTo( this.uiDialog );
9967
- this._on( this.uiDialogTitlebar, {
9968
- mousedown: function( event ) {
9969
- // Don't prevent click on close button (#8838)
9970
- // Focusing a dialog that is partially scrolled out of view
9971
- // causes the browser to scroll it into view, preventing the click event
9972
- if ( !$( event.target ).closest(".ui-dialog-titlebar-close") ) {
9973
- // Dialog isn't getting focus when dragging (#8063)
9974
- this.uiDialog.focus();
9975
- }
9976
- }
9977
- });
9978
-
9979
- // support: IE
9980
- // Use type="button" to prevent enter keypresses in textboxes from closing the
9981
- // dialog in IE (#9312)
9982
- this.uiDialogTitlebarClose = $( "<button type='button'></button>" )
9983
- .button({
9984
- label: this.options.closeText,
9985
- icons: {
9986
- primary: "ui-icon-closethick"
9987
- },
9988
- text: false
9989
- })
9990
- .addClass("ui-dialog-titlebar-close")
9991
- .appendTo( this.uiDialogTitlebar );
9992
- this._on( this.uiDialogTitlebarClose, {
9993
- click: function( event ) {
9994
- event.preventDefault();
9995
- this.close( event );
9996
- }
9997
- });
9998
-
9999
- uiDialogTitle = $("<span>")
10000
- .uniqueId()
10001
- .addClass("ui-dialog-title")
10002
- .prependTo( this.uiDialogTitlebar );
10003
- this._title( uiDialogTitle );
10004
-
10005
- this.uiDialog.attr({
10006
- "aria-labelledby": uiDialogTitle.attr("id")
10007
- });
10008
- },
10009
-
10010
- _title: function( title ) {
10011
- if ( !this.options.title ) {
10012
- title.html("&#160;");
10013
- }
10014
- title.text( this.options.title );
10015
- },
10016
-
10017
- _createButtonPane: function() {
10018
- this.uiDialogButtonPane = $("<div>")
10019
- .addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix");
10020
-
10021
- this.uiButtonSet = $("<div>")
10022
- .addClass("ui-dialog-buttonset")
10023
- .appendTo( this.uiDialogButtonPane );
10024
-
10025
- this._createButtons();
10026
- },
10027
-
10028
- _createButtons: function() {
10029
- var that = this,
10030
- buttons = this.options.buttons;
10031
-
10032
- // if we already have a button pane, remove it
10033
- this.uiDialogButtonPane.remove();
10034
- this.uiButtonSet.empty();
10035
-
10036
- if ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {
10037
- this.uiDialog.removeClass("ui-dialog-buttons");
10038
- return;
10039
- }
10040
-
10041
- $.each( buttons, function( name, props ) {
10042
- var click, buttonOptions;
10043
- props = $.isFunction( props ) ?
10044
- { click: props, text: name } :
10045
- props;
10046
- // Default to a non-submitting button
10047
- props = $.extend( { type: "button" }, props );
10048
- // Change the context for the click callback to be the main element
10049
- click = props.click;
10050
- props.click = function() {
10051
- click.apply( that.element[0], arguments );
10052
- };
10053
- buttonOptions = {
10054
- icons: props.icons,
10055
- text: props.showText
10056
- };
10057
- delete props.icons;
10058
- delete props.showText;
10059
- $( "<button></button>", props )
10060
- .button( buttonOptions )
10061
- .appendTo( that.uiButtonSet );
10062
- });
10063
- this.uiDialog.addClass("ui-dialog-buttons");
10064
- this.uiDialogButtonPane.appendTo( this.uiDialog );
10065
- },
10066
-
10067
- _makeDraggable: function() {
10068
- var that = this,
10069
- options = this.options;
10070
-
10071
- function filteredUi( ui ) {
10072
- return {
10073
- position: ui.position,
10074
- offset: ui.offset
10075
- };
10076
- }
10077
-
10078
- this.uiDialog.draggable({
10079
- cancel: ".ui-dialog-content, .ui-dialog-titlebar-close",
10080
- handle: ".ui-dialog-titlebar",
10081
- containment: "document",
10082
- start: function( event, ui ) {
10083
- $( this ).addClass("ui-dialog-dragging");
10084
- that._blockFrames();
10085
- that._trigger( "dragStart", event, filteredUi( ui ) );
10086
- },
10087
- drag: function( event, ui ) {
10088
- that._trigger( "drag", event, filteredUi( ui ) );
10089
- },
10090
- stop: function( event, ui ) {
10091
- options.position = [
10092
- ui.position.left - that.document.scrollLeft(),
10093
- ui.position.top - that.document.scrollTop()
10094
- ];
10095
- $( this ).removeClass("ui-dialog-dragging");
10096
- that._unblockFrames();
10097
- that._trigger( "dragStop", event, filteredUi( ui ) );
10098
- }
10099
- });
10100
- },
10101
-
10102
- _makeResizable: function() {
10103
- var that = this,
10104
- options = this.options,
10105
- handles = options.resizable,
10106
- // .ui-resizable has position: relative defined in the stylesheet
10107
- // but dialogs have to use absolute or fixed positioning
10108
- position = this.uiDialog.css("position"),
10109
- resizeHandles = typeof handles === "string" ?
10110
- handles :
10111
- "n,e,s,w,se,sw,ne,nw";
10112
-
10113
- function filteredUi( ui ) {
10114
- return {
10115
- originalPosition: ui.originalPosition,
10116
- originalSize: ui.originalSize,
10117
- position: ui.position,
10118
- size: ui.size
10119
- };
10120
- }
10121
-
10122
- this.uiDialog.resizable({
10123
- cancel: ".ui-dialog-content",
10124
- containment: "document",
10125
- alsoResize: this.element,
10126
- maxWidth: options.maxWidth,
10127
- maxHeight: options.maxHeight,
10128
- minWidth: options.minWidth,
10129
- minHeight: this._minHeight(),
10130
- handles: resizeHandles,
10131
- start: function( event, ui ) {
10132
- $( this ).addClass("ui-dialog-resizing");
10133
- that._blockFrames();
10134
- that._trigger( "resizeStart", event, filteredUi( ui ) );
10135
- },
10136
- resize: function( event, ui ) {
10137
- that._trigger( "resize", event, filteredUi( ui ) );
10138
- },
10139
- stop: function( event, ui ) {
10140
- options.height = $( this ).height();
10141
- options.width = $( this ).width();
10142
- $( this ).removeClass("ui-dialog-resizing");
10143
- that._unblockFrames();
10144
- that._trigger( "resizeStop", event, filteredUi( ui ) );
10145
- }
10146
- })
10147
- .css( "position", position );
10148
- },
10149
-
10150
- _minHeight: function() {
10151
- var options = this.options;
10152
-
10153
- return options.height === "auto" ?
10154
- options.minHeight :
10155
- Math.min( options.minHeight, options.height );
10156
- },
10157
-
10158
- _position: function() {
10159
- // Need to show the dialog to get the actual offset in the position plugin
10160
- var isVisible = this.uiDialog.is(":visible");
10161
- if ( !isVisible ) {
10162
- this.uiDialog.show();
10163
- }
10164
- this.uiDialog.position( this.options.position );
10165
- if ( !isVisible ) {
10166
- this.uiDialog.hide();
10167
- }
10168
- },
10169
-
10170
- _setOptions: function( options ) {
10171
- var that = this,
10172
- resize = false,
10173
- resizableOptions = {};
10174
-
10175
- $.each( options, function( key, value ) {
10176
- that._setOption( key, value );
10177
-
10178
- if ( key in sizeRelatedOptions ) {
10179
- resize = true;
10180
- }
10181
- if ( key in resizableRelatedOptions ) {
10182
- resizableOptions[ key ] = value;
10183
- }
10184
- });
10185
-
10186
- if ( resize ) {
10187
- this._size();
10188
- this._position();
10189
- }
10190
- if ( this.uiDialog.is(":data(ui-resizable)") ) {
10191
- this.uiDialog.resizable( "option", resizableOptions );
10192
- }
10193
- },
10194
-
10195
- _setOption: function( key, value ) {
10196
- var isDraggable, isResizable,
10197
- uiDialog = this.uiDialog;
10198
-
10199
- if ( key === "dialogClass" ) {
10200
- uiDialog
10201
- .removeClass( this.options.dialogClass )
10202
- .addClass( value );
10203
- }
10204
-
10205
- if ( key === "disabled" ) {
10206
- return;
10207
- }
10208
-
10209
- this._super( key, value );
10210
-
10211
- if ( key === "appendTo" ) {
10212
- this.uiDialog.appendTo( this._appendTo() );
10213
- }
10214
-
10215
- if ( key === "buttons" ) {
10216
- this._createButtons();
10217
- }
10218
-
10219
- if ( key === "closeText" ) {
10220
- this.uiDialogTitlebarClose.button({
10221
- // Ensure that we always pass a string
10222
- label: "" + value
10223
- });
10224
- }
10225
-
10226
- if ( key === "draggable" ) {
10227
- isDraggable = uiDialog.is(":data(ui-draggable)");
10228
- if ( isDraggable && !value ) {
10229
- uiDialog.draggable("destroy");
10230
- }
10231
-
10232
- if ( !isDraggable && value ) {
10233
- this._makeDraggable();
10234
- }
10235
- }
10236
-
10237
- if ( key === "position" ) {
10238
- this._position();
10239
- }
10240
-
10241
- if ( key === "resizable" ) {
10242
- // currently resizable, becoming non-resizable
10243
- isResizable = uiDialog.is(":data(ui-resizable)");
10244
- if ( isResizable && !value ) {
10245
- uiDialog.resizable("destroy");
10246
- }
10247
-
10248
- // currently resizable, changing handles
10249
- if ( isResizable && typeof value === "string" ) {
10250
- uiDialog.resizable( "option", "handles", value );
10251
- }
10252
-
10253
- // currently non-resizable, becoming resizable
10254
- if ( !isResizable && value !== false ) {
10255
- this._makeResizable();
10256
- }
10257
- }
10258
-
10259
- if ( key === "title" ) {
10260
- this._title( this.uiDialogTitlebar.find(".ui-dialog-title") );
10261
- }
10262
- },
10263
-
10264
- _size: function() {
10265
- // If the user has resized the dialog, the .ui-dialog and .ui-dialog-content
10266
- // divs will both have width and height set, so we need to reset them
10267
- var nonContentHeight, minContentHeight, maxContentHeight,
10268
- options = this.options;
10269
-
10270
- // Reset content sizing
10271
- this.element.show().css({
10272
- width: "auto",
10273
- minHeight: 0,
10274
- maxHeight: "none",
10275
- height: 0
10276
- });
10277
-
10278
- if ( options.minWidth > options.width ) {
10279
- options.width = options.minWidth;
10280
- }
10281
-
10282
- // reset wrapper sizing
10283
- // determine the height of all the non-content elements
10284
- nonContentHeight = this.uiDialog.css({
10285
- height: "auto",
10286
- width: options.width
10287
- })
10288
- .outerHeight();
10289
- minContentHeight = Math.max( 0, options.minHeight - nonContentHeight );
10290
- maxContentHeight = typeof options.maxHeight === "number" ?
10291
- Math.max( 0, options.maxHeight - nonContentHeight ) :
10292
- "none";
10293
-
10294
- if ( options.height === "auto" ) {
10295
- this.element.css({
10296
- minHeight: minContentHeight,
10297
- maxHeight: maxContentHeight,
10298
- height: "auto"
10299
- });
10300
- } else {
10301
- this.element.height( Math.max( 0, options.height - nonContentHeight ) );
10302
- }
10303
-
10304
- if (this.uiDialog.is(":data(ui-resizable)") ) {
10305
- this.uiDialog.resizable( "option", "minHeight", this._minHeight() );
10306
- }
10307
- },
10308
-
10309
- _blockFrames: function() {
10310
- this.iframeBlocks = this.document.find( "iframe" ).map(function() {
10311
- var iframe = $( this );
10312
-
10313
- return $( "<div>" )
10314
- .css({
10315
- position: "absolute",
10316
- width: iframe.outerWidth(),
10317
- height: iframe.outerHeight()
10318
- })
10319
- .appendTo( iframe.parent() )
10320
- .offset( iframe.offset() )[0];
10321
- });
10322
- },
10323
-
10324
- _unblockFrames: function() {
10325
- if ( this.iframeBlocks ) {
10326
- this.iframeBlocks.remove();
10327
- delete this.iframeBlocks;
10328
- }
10329
- },
10330
-
10331
- _allowInteraction: function( event ) {
10332
- if ( $( event.target ).closest(".ui-dialog").length ) {
10333
- return true;
10334
- }
10335
-
10336
- // TODO: Remove hack when datepicker implements
10337
- // the .ui-front logic (#8989)
10338
- return !!$( event.target ).closest(".ui-datepicker").length;
10339
- },
10340
-
10341
- _createOverlay: function() {
10342
- if ( !this.options.modal ) {
10343
- return;
10344
- }
10345
-
10346
- var that = this,
10347
- widgetFullName = this.widgetFullName;
10348
- if ( !$.ui.dialog.overlayInstances ) {
10349
- // Prevent use of anchors and inputs.
10350
- // We use a delay in case the overlay is created from an
10351
- // event that we're going to be cancelling. (#2804)
10352
- this._delay(function() {
10353
- // Handle .dialog().dialog("close") (#4065)
10354
- if ( $.ui.dialog.overlayInstances ) {
10355
- this.document.bind( "focusin.dialog", function( event ) {
10356
- if ( !that._allowInteraction( event ) ) {
10357
- event.preventDefault();
10358
- $(".ui-dialog:visible:last .ui-dialog-content")
10359
- .data( widgetFullName )._focusTabbable();
10360
- }
10361
- });
10362
- }
10363
- });
10364
- }
10365
-
10366
- this.overlay = $("<div>")
10367
- .addClass("ui-widget-overlay ui-front")
10368
- .appendTo( this._appendTo() );
10369
- this._on( this.overlay, {
10370
- mousedown: "_keepFocus"
10371
- });
10372
- $.ui.dialog.overlayInstances++;
10373
- },
10374
-
10375
- _destroyOverlay: function() {
10376
- if ( !this.options.modal ) {
10377
- return;
10378
- }
10379
-
10380
- if ( this.overlay ) {
10381
- $.ui.dialog.overlayInstances--;
10382
-
10383
- if ( !$.ui.dialog.overlayInstances ) {
10384
- this.document.unbind( "focusin.dialog" );
10385
- }
10386
- this.overlay.remove();
10387
- this.overlay = null;
10388
- }
10389
- }
10390
- });
10391
-
10392
- $.ui.dialog.overlayInstances = 0;
10393
-
10394
- // DEPRECATED
10395
- if ( $.uiBackCompat !== false ) {
10396
- // position option with array notation
10397
- // just override with old implementation
10398
- $.widget( "ui.dialog", $.ui.dialog, {
10399
- _position: function() {
10400
- var position = this.options.position,
10401
- myAt = [],
10402
- offset = [ 0, 0 ],
10403
- isVisible;
10404
-
10405
- if ( position ) {
10406
- if ( typeof position === "string" || (typeof position === "object" && "0" in position ) ) {
10407
- myAt = position.split ? position.split(" ") : [ position[0], position[1] ];
10408
- if ( myAt.length === 1 ) {
10409
- myAt[1] = myAt[0];
10410
- }
10411
-
10412
- $.each( [ "left", "top" ], function( i, offsetPosition ) {
10413
- if ( +myAt[ i ] === myAt[ i ] ) {
10414
- offset[ i ] = myAt[ i ];
10415
- myAt[ i ] = offsetPosition;
10416
- }
10417
- });
10418
-
10419
- position = {
10420
- my: myAt[0] + (offset[0] < 0 ? offset[0] : "+" + offset[0]) + " " +
10421
- myAt[1] + (offset[1] < 0 ? offset[1] : "+" + offset[1]),
10422
- at: myAt.join(" ")
10423
- };
10424
- }
10425
-
10426
- position = $.extend( {}, $.ui.dialog.prototype.options.position, position );
10427
- } else {
10428
- position = $.ui.dialog.prototype.options.position;
10429
- }
10430
-
10431
- // need to show the dialog to get the actual offset in the position plugin
10432
- isVisible = this.uiDialog.is(":visible");
10433
- if ( !isVisible ) {
10434
- this.uiDialog.show();
10435
- }
10436
- this.uiDialog.position( position );
10437
- if ( !isVisible ) {
10438
- this.uiDialog.hide();
10439
- }
10440
- }
10441
- });
10442
- }
10443
-
10444
- }( jQuery ) );
10445
-
10446
- (function( $, undefined ) {
10447
-
10448
- var rvertical = /up|down|vertical/,
10449
- rpositivemotion = /up|left|vertical|horizontal/;
10450
-
10451
- $.effects.effect.blind = function( o, done ) {
10452
- // Create element
10453
- var el = $( this ),
10454
- props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10455
- mode = $.effects.setMode( el, o.mode || "hide" ),
10456
- direction = o.direction || "up",
10457
- vertical = rvertical.test( direction ),
10458
- ref = vertical ? "height" : "width",
10459
- ref2 = vertical ? "top" : "left",
10460
- motion = rpositivemotion.test( direction ),
10461
- animation = {},
10462
- show = mode === "show",
10463
- wrapper, distance, margin;
10464
-
10465
- // if already wrapped, the wrapper's properties are my property. #6245
10466
- if ( el.parent().is( ".ui-effects-wrapper" ) ) {
10467
- $.effects.save( el.parent(), props );
10468
- } else {
10469
- $.effects.save( el, props );
10470
- }
10471
- el.show();
10472
- wrapper = $.effects.createWrapper( el ).css({
10473
- overflow: "hidden"
10474
- });
10475
-
10476
- distance = wrapper[ ref ]();
10477
- margin = parseFloat( wrapper.css( ref2 ) ) || 0;
10478
-
10479
- animation[ ref ] = show ? distance : 0;
10480
- if ( !motion ) {
10481
- el
10482
- .css( vertical ? "bottom" : "right", 0 )
10483
- .css( vertical ? "top" : "left", "auto" )
10484
- .css({ position: "absolute" });
10485
-
10486
- animation[ ref2 ] = show ? margin : distance + margin;
10487
- }
10488
-
10489
- // start at 0 if we are showing
10490
- if ( show ) {
10491
- wrapper.css( ref, 0 );
10492
- if ( ! motion ) {
10493
- wrapper.css( ref2, margin + distance );
10494
- }
10495
- }
10496
-
10497
- // Animate
10498
- wrapper.animate( animation, {
10499
- duration: o.duration,
10500
- easing: o.easing,
10501
- queue: false,
10502
- complete: function() {
10503
- if ( mode === "hide" ) {
10504
- el.hide();
10505
- }
10506
- $.effects.restore( el, props );
10507
- $.effects.removeWrapper( el );
10508
- done();
10509
- }
10510
- });
10511
-
10512
- };
10513
-
10514
- })(jQuery);
10515
-
10516
- (function( $, undefined ) {
10517
-
10518
- $.effects.effect.bounce = function( o, done ) {
10519
- var el = $( this ),
10520
- props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10521
-
10522
- // defaults:
10523
- mode = $.effects.setMode( el, o.mode || "effect" ),
10524
- hide = mode === "hide",
10525
- show = mode === "show",
10526
- direction = o.direction || "up",
10527
- distance = o.distance,
10528
- times = o.times || 5,
10529
-
10530
- // number of internal animations
10531
- anims = times * 2 + ( show || hide ? 1 : 0 ),
10532
- speed = o.duration / anims,
10533
- easing = o.easing,
10534
-
10535
- // utility:
10536
- ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10537
- motion = ( direction === "up" || direction === "left" ),
10538
- i,
10539
- upAnim,
10540
- downAnim,
10541
-
10542
- // we will need to re-assemble the queue to stack our animations in place
10543
- queue = el.queue(),
10544
- queuelen = queue.length;
10545
-
10546
- // Avoid touching opacity to prevent clearType and PNG issues in IE
10547
- if ( show || hide ) {
10548
- props.push( "opacity" );
10549
- }
10550
-
10551
- $.effects.save( el, props );
10552
- el.show();
10553
- $.effects.createWrapper( el ); // Create Wrapper
10554
-
10555
- // default distance for the BIGGEST bounce is the outer Distance / 3
10556
- if ( !distance ) {
10557
- distance = el[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
10558
- }
10559
-
10560
- if ( show ) {
10561
- downAnim = { opacity: 1 };
10562
- downAnim[ ref ] = 0;
10563
-
10564
- // if we are showing, force opacity 0 and set the initial position
10565
- // then do the "first" animation
10566
- el.css( "opacity", 0 )
10567
- .css( ref, motion ? -distance * 2 : distance * 2 )
10568
- .animate( downAnim, speed, easing );
10569
- }
10570
-
10571
- // start at the smallest distance if we are hiding
10572
- if ( hide ) {
10573
- distance = distance / Math.pow( 2, times - 1 );
10574
- }
10575
-
10576
- downAnim = {};
10577
- downAnim[ ref ] = 0;
10578
- // Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
10579
- for ( i = 0; i < times; i++ ) {
10580
- upAnim = {};
10581
- upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10582
-
10583
- el.animate( upAnim, speed, easing )
10584
- .animate( downAnim, speed, easing );
10585
-
10586
- distance = hide ? distance * 2 : distance / 2;
10587
- }
10588
-
10589
- // Last Bounce when Hiding
10590
- if ( hide ) {
10591
- upAnim = { opacity: 0 };
10592
- upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
10593
-
10594
- el.animate( upAnim, speed, easing );
10595
- }
10596
-
10597
- el.queue(function() {
10598
- if ( hide ) {
10599
- el.hide();
10600
- }
10601
- $.effects.restore( el, props );
10602
- $.effects.removeWrapper( el );
10603
- done();
10604
- });
10605
-
10606
- // inject all the animations we just queued to be first in line (after "inprogress")
10607
- if ( queuelen > 1) {
10608
- queue.splice.apply( queue,
10609
- [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10610
- }
10611
- el.dequeue();
10612
-
10613
- };
10614
-
10615
- })(jQuery);
10616
-
10617
- (function( $, undefined ) {
10618
-
10619
- $.effects.effect.clip = function( o, done ) {
10620
- // Create element
10621
- var el = $( this ),
10622
- props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10623
- mode = $.effects.setMode( el, o.mode || "hide" ),
10624
- show = mode === "show",
10625
- direction = o.direction || "vertical",
10626
- vert = direction === "vertical",
10627
- size = vert ? "height" : "width",
10628
- position = vert ? "top" : "left",
10629
- animation = {},
10630
- wrapper, animate, distance;
10631
-
10632
- // Save & Show
10633
- $.effects.save( el, props );
10634
- el.show();
10635
-
10636
- // Create Wrapper
10637
- wrapper = $.effects.createWrapper( el ).css({
10638
- overflow: "hidden"
10639
- });
10640
- animate = ( el[0].tagName === "IMG" ) ? wrapper : el;
10641
- distance = animate[ size ]();
10642
-
10643
- // Shift
10644
- if ( show ) {
10645
- animate.css( size, 0 );
10646
- animate.css( position, distance / 2 );
10647
- }
10648
-
10649
- // Create Animation Object:
10650
- animation[ size ] = show ? distance : 0;
10651
- animation[ position ] = show ? 0 : distance / 2;
10652
-
10653
- // Animate
10654
- animate.animate( animation, {
10655
- queue: false,
10656
- duration: o.duration,
10657
- easing: o.easing,
10658
- complete: function() {
10659
- if ( !show ) {
10660
- el.hide();
10661
- }
10662
- $.effects.restore( el, props );
10663
- $.effects.removeWrapper( el );
10664
- done();
10665
- }
10666
- });
10667
-
10668
- };
10669
-
10670
- })(jQuery);
10671
-
10672
- (function( $, undefined ) {
10673
-
10674
- $.effects.effect.drop = function( o, done ) {
10675
-
10676
- var el = $( this ),
10677
- props = [ "position", "top", "bottom", "left", "right", "opacity", "height", "width" ],
10678
- mode = $.effects.setMode( el, o.mode || "hide" ),
10679
- show = mode === "show",
10680
- direction = o.direction || "left",
10681
- ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
10682
- motion = ( direction === "up" || direction === "left" ) ? "pos" : "neg",
10683
- animation = {
10684
- opacity: show ? 1 : 0
10685
- },
10686
- distance;
10687
-
10688
- // Adjust
10689
- $.effects.save( el, props );
10690
- el.show();
10691
- $.effects.createWrapper( el );
10692
-
10693
- distance = o.distance || el[ ref === "top" ? "outerHeight": "outerWidth" ]( true ) / 2;
10694
-
10695
- if ( show ) {
10696
- el
10697
- .css( "opacity", 0 )
10698
- .css( ref, motion === "pos" ? -distance : distance );
10699
- }
10700
-
10701
- // Animation
10702
- animation[ ref ] = ( show ?
10703
- ( motion === "pos" ? "+=" : "-=" ) :
10704
- ( motion === "pos" ? "-=" : "+=" ) ) +
10705
- distance;
10706
-
10707
- // Animate
10708
- el.animate( animation, {
10709
- queue: false,
10710
- duration: o.duration,
10711
- easing: o.easing,
10712
- complete: function() {
10713
- if ( mode === "hide" ) {
10714
- el.hide();
10715
- }
10716
- $.effects.restore( el, props );
10717
- $.effects.removeWrapper( el );
10718
- done();
10719
- }
10720
- });
10721
- };
10722
-
10723
- })(jQuery);
10724
-
10725
- (function( $, undefined ) {
10726
-
10727
- $.effects.effect.explode = function( o, done ) {
10728
-
10729
- var rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,
10730
- cells = rows,
10731
- el = $( this ),
10732
- mode = $.effects.setMode( el, o.mode || "hide" ),
10733
- show = mode === "show",
10734
-
10735
- // show and then visibility:hidden the element before calculating offset
10736
- offset = el.show().css( "visibility", "hidden" ).offset(),
10737
-
10738
- // width and height of a piece
10739
- width = Math.ceil( el.outerWidth() / cells ),
10740
- height = Math.ceil( el.outerHeight() / rows ),
10741
- pieces = [],
10742
-
10743
- // loop
10744
- i, j, left, top, mx, my;
10745
-
10746
- // children animate complete:
10747
- function childComplete() {
10748
- pieces.push( this );
10749
- if ( pieces.length === rows * cells ) {
10750
- animComplete();
10751
- }
10752
- }
10753
-
10754
- // clone the element for each row and cell.
10755
- for( i = 0; i < rows ; i++ ) { // ===>
10756
- top = offset.top + i * height;
10757
- my = i - ( rows - 1 ) / 2 ;
10758
-
10759
- for( j = 0; j < cells ; j++ ) { // |||
10760
- left = offset.left + j * width;
10761
- mx = j - ( cells - 1 ) / 2 ;
10762
-
10763
- // Create a clone of the now hidden main element that will be absolute positioned
10764
- // within a wrapper div off the -left and -top equal to size of our pieces
10765
- el
10766
- .clone()
10767
- .appendTo( "body" )
10768
- .wrap( "<div></div>" )
10769
- .css({
10770
- position: "absolute",
10771
- visibility: "visible",
10772
- left: -j * width,
10773
- top: -i * height
10774
- })
10775
-
10776
- // select the wrapper - make it overflow: hidden and absolute positioned based on
10777
- // where the original was located +left and +top equal to the size of pieces
10778
- .parent()
10779
- .addClass( "ui-effects-explode" )
10780
- .css({
10781
- position: "absolute",
10782
- overflow: "hidden",
10783
- width: width,
10784
- height: height,
10785
- left: left + ( show ? mx * width : 0 ),
10786
- top: top + ( show ? my * height : 0 ),
10787
- opacity: show ? 0 : 1
10788
- }).animate({
10789
- left: left + ( show ? 0 : mx * width ),
10790
- top: top + ( show ? 0 : my * height ),
10791
- opacity: show ? 1 : 0
10792
- }, o.duration || 500, o.easing, childComplete );
10793
- }
10794
- }
10795
-
10796
- function animComplete() {
10797
- el.css({
10798
- visibility: "visible"
10799
- });
10800
- $( pieces ).remove();
10801
- if ( !show ) {
10802
- el.hide();
10803
- }
10804
- done();
10805
- }
10806
- };
10807
-
10808
- })(jQuery);
10809
-
10810
- (function( $, undefined ) {
10811
-
10812
- $.effects.effect.fade = function( o, done ) {
10813
- var el = $( this ),
10814
- mode = $.effects.setMode( el, o.mode || "toggle" );
10815
-
10816
- el.animate({
10817
- opacity: mode
10818
- }, {
10819
- queue: false,
10820
- duration: o.duration,
10821
- easing: o.easing,
10822
- complete: done
10823
- });
10824
- };
10825
-
10826
- })( jQuery );
10827
-
10828
- (function( $, undefined ) {
10829
-
10830
- $.effects.effect.fold = function( o, done ) {
10831
-
10832
- // Create element
10833
- var el = $( this ),
10834
- props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
10835
- mode = $.effects.setMode( el, o.mode || "hide" ),
10836
- show = mode === "show",
10837
- hide = mode === "hide",
10838
- size = o.size || 15,
10839
- percent = /([0-9]+)%/.exec( size ),
10840
- horizFirst = !!o.horizFirst,
10841
- widthFirst = show !== horizFirst,
10842
- ref = widthFirst ? [ "width", "height" ] : [ "height", "width" ],
10843
- duration = o.duration / 2,
10844
- wrapper, distance,
10845
- animation1 = {},
10846
- animation2 = {};
10847
-
10848
- $.effects.save( el, props );
10849
- el.show();
10850
-
10851
- // Create Wrapper
10852
- wrapper = $.effects.createWrapper( el ).css({
10853
- overflow: "hidden"
10854
- });
10855
- distance = widthFirst ?
10856
- [ wrapper.width(), wrapper.height() ] :
10857
- [ wrapper.height(), wrapper.width() ];
10858
-
10859
- if ( percent ) {
10860
- size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
10861
- }
10862
- if ( show ) {
10863
- wrapper.css( horizFirst ? {
10864
- height: 0,
10865
- width: size
10866
- } : {
10867
- height: size,
10868
- width: 0
10869
- });
10870
- }
10871
-
10872
- // Animation
10873
- animation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;
10874
- animation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;
10875
-
10876
- // Animate
10877
- wrapper
10878
- .animate( animation1, duration, o.easing )
10879
- .animate( animation2, duration, o.easing, function() {
10880
- if ( hide ) {
10881
- el.hide();
10882
- }
10883
- $.effects.restore( el, props );
10884
- $.effects.removeWrapper( el );
10885
- done();
10886
- });
10887
-
10888
- };
10889
-
10890
- })(jQuery);
10891
-
10892
- (function( $, undefined ) {
10893
-
10894
- $.effects.effect.highlight = function( o, done ) {
10895
- var elem = $( this ),
10896
- props = [ "backgroundImage", "backgroundColor", "opacity" ],
10897
- mode = $.effects.setMode( elem, o.mode || "show" ),
10898
- animation = {
10899
- backgroundColor: elem.css( "backgroundColor" )
10900
- };
10901
-
10902
- if (mode === "hide") {
10903
- animation.opacity = 0;
10904
- }
10905
-
10906
- $.effects.save( elem, props );
10907
-
10908
- elem
10909
- .show()
10910
- .css({
10911
- backgroundImage: "none",
10912
- backgroundColor: o.color || "#ffff99"
10913
- })
10914
- .animate( animation, {
10915
- queue: false,
10916
- duration: o.duration,
10917
- easing: o.easing,
10918
- complete: function() {
10919
- if ( mode === "hide" ) {
10920
- elem.hide();
10921
- }
10922
- $.effects.restore( elem, props );
10923
- done();
10924
- }
10925
- });
10926
- };
10927
-
10928
- })(jQuery);
10929
-
10930
- (function( $, undefined ) {
10931
-
10932
- $.effects.effect.pulsate = function( o, done ) {
10933
- var elem = $( this ),
10934
- mode = $.effects.setMode( elem, o.mode || "show" ),
10935
- show = mode === "show",
10936
- hide = mode === "hide",
10937
- showhide = ( show || mode === "hide" ),
10938
-
10939
- // showing or hiding leaves of the "last" animation
10940
- anims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
10941
- duration = o.duration / anims,
10942
- animateTo = 0,
10943
- queue = elem.queue(),
10944
- queuelen = queue.length,
10945
- i;
10946
-
10947
- if ( show || !elem.is(":visible")) {
10948
- elem.css( "opacity", 0 ).show();
10949
- animateTo = 1;
10950
- }
10951
-
10952
- // anims - 1 opacity "toggles"
10953
- for ( i = 1; i < anims; i++ ) {
10954
- elem.animate({
10955
- opacity: animateTo
10956
- }, duration, o.easing );
10957
- animateTo = 1 - animateTo;
10958
- }
10959
-
10960
- elem.animate({
10961
- opacity: animateTo
10962
- }, duration, o.easing);
10963
-
10964
- elem.queue(function() {
10965
- if ( hide ) {
10966
- elem.hide();
10967
- }
10968
- done();
10969
- });
10970
-
10971
- // We just queued up "anims" animations, we need to put them next in the queue
10972
- if ( queuelen > 1 ) {
10973
- queue.splice.apply( queue,
10974
- [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
10975
- }
10976
- elem.dequeue();
10977
- };
10978
-
10979
- })(jQuery);
10980
-
10981
- (function( $, undefined ) {
10982
-
10983
- $.effects.effect.puff = function( o, done ) {
10984
- var elem = $( this ),
10985
- mode = $.effects.setMode( elem, o.mode || "hide" ),
10986
- hide = mode === "hide",
10987
- percent = parseInt( o.percent, 10 ) || 150,
10988
- factor = percent / 100,
10989
- original = {
10990
- height: elem.height(),
10991
- width: elem.width(),
10992
- outerHeight: elem.outerHeight(),
10993
- outerWidth: elem.outerWidth()
10994
- };
10995
-
10996
- $.extend( o, {
10997
- effect: "scale",
10998
- queue: false,
10999
- fade: true,
11000
- mode: mode,
11001
- complete: done,
11002
- percent: hide ? percent : 100,
11003
- from: hide ?
11004
- original :
11005
- {
11006
- height: original.height * factor,
11007
- width: original.width * factor,
11008
- outerHeight: original.outerHeight * factor,
11009
- outerWidth: original.outerWidth * factor
11010
- }
11011
- });
11012
-
11013
- elem.effect( o );
11014
- };
11015
-
11016
- $.effects.effect.scale = function( o, done ) {
11017
-
11018
- // Create element
11019
- var el = $( this ),
11020
- options = $.extend( true, {}, o ),
11021
- mode = $.effects.setMode( el, o.mode || "effect" ),
11022
- percent = parseInt( o.percent, 10 ) ||
11023
- ( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === "hide" ? 0 : 100 ) ),
11024
- direction = o.direction || "both",
11025
- origin = o.origin,
11026
- original = {
11027
- height: el.height(),
11028
- width: el.width(),
11029
- outerHeight: el.outerHeight(),
11030
- outerWidth: el.outerWidth()
11031
- },
11032
- factor = {
11033
- y: direction !== "horizontal" ? (percent / 100) : 1,
11034
- x: direction !== "vertical" ? (percent / 100) : 1
11035
- };
11036
-
11037
- // We are going to pass this effect to the size effect:
11038
- options.effect = "size";
11039
- options.queue = false;
11040
- options.complete = done;
11041
-
11042
- // Set default origin and restore for show/hide
11043
- if ( mode !== "effect" ) {
11044
- options.origin = origin || ["middle","center"];
11045
- options.restore = true;
11046
- }
11047
-
11048
- options.from = o.from || ( mode === "show" ? {
11049
- height: 0,
11050
- width: 0,
11051
- outerHeight: 0,
11052
- outerWidth: 0
11053
- } : original );
11054
- options.to = {
11055
- height: original.height * factor.y,
11056
- width: original.width * factor.x,
11057
- outerHeight: original.outerHeight * factor.y,
11058
- outerWidth: original.outerWidth * factor.x
11059
- };
11060
-
11061
- // Fade option to support puff
11062
- if ( options.fade ) {
11063
- if ( mode === "show" ) {
11064
- options.from.opacity = 0;
11065
- options.to.opacity = 1;
11066
- }
11067
- if ( mode === "hide" ) {
11068
- options.from.opacity = 1;
11069
- options.to.opacity = 0;
11070
- }
11071
- }
11072
-
11073
- // Animate
11074
- el.effect( options );
11075
-
11076
- };
11077
-
11078
- $.effects.effect.size = function( o, done ) {
11079
-
11080
- // Create element
11081
- var original, baseline, factor,
11082
- el = $( this ),
11083
- props0 = [ "position", "top", "bottom", "left", "right", "width", "height", "overflow", "opacity" ],
11084
-
11085
- // Always restore
11086
- props1 = [ "position", "top", "bottom", "left", "right", "overflow", "opacity" ],
11087
-
11088
- // Copy for children
11089
- props2 = [ "width", "height", "overflow" ],
11090
- cProps = [ "fontSize" ],
11091
- vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
11092
- hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
11093
-
11094
- // Set options
11095
- mode = $.effects.setMode( el, o.mode || "effect" ),
11096
- restore = o.restore || mode !== "effect",
11097
- scale = o.scale || "both",
11098
- origin = o.origin || [ "middle", "center" ],
11099
- position = el.css( "position" ),
11100
- props = restore ? props0 : props1,
11101
- zero = {
11102
- height: 0,
11103
- width: 0,
11104
- outerHeight: 0,
11105
- outerWidth: 0
11106
- };
11107
-
11108
- if ( mode === "show" ) {
11109
- el.show();
11110
- }
11111
- original = {
11112
- height: el.height(),
11113
- width: el.width(),
11114
- outerHeight: el.outerHeight(),
11115
- outerWidth: el.outerWidth()
11116
- };
11117
-
11118
- if ( o.mode === "toggle" && mode === "show" ) {
11119
- el.from = o.to || zero;
11120
- el.to = o.from || original;
11121
- } else {
11122
- el.from = o.from || ( mode === "show" ? zero : original );
11123
- el.to = o.to || ( mode === "hide" ? zero : original );
11124
- }
11125
-
11126
- // Set scaling factor
11127
- factor = {
11128
- from: {
11129
- y: el.from.height / original.height,
11130
- x: el.from.width / original.width
11131
- },
11132
- to: {
11133
- y: el.to.height / original.height,
11134
- x: el.to.width / original.width
11135
- }
11136
- };
11137
-
11138
- // Scale the css box
11139
- if ( scale === "box" || scale === "both" ) {
11140
-
11141
- // Vertical props scaling
11142
- if ( factor.from.y !== factor.to.y ) {
11143
- props = props.concat( vProps );
11144
- el.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );
11145
- el.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );
11146
- }
11147
-
11148
- // Horizontal props scaling
11149
- if ( factor.from.x !== factor.to.x ) {
11150
- props = props.concat( hProps );
11151
- el.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );
11152
- el.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );
11153
- }
11154
- }
11155
-
11156
- // Scale the content
11157
- if ( scale === "content" || scale === "both" ) {
11158
-
11159
- // Vertical props scaling
11160
- if ( factor.from.y !== factor.to.y ) {
11161
- props = props.concat( cProps ).concat( props2 );
11162
- el.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );
11163
- el.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );
11164
- }
11165
- }
11166
-
11167
- $.effects.save( el, props );
11168
- el.show();
11169
- $.effects.createWrapper( el );
11170
- el.css( "overflow", "hidden" ).css( el.from );
11171
-
11172
- // Adjust
11173
- if (origin) { // Calculate baseline shifts
11174
- baseline = $.effects.getBaseline( origin, original );
11175
- el.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;
11176
- el.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;
11177
- el.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;
11178
- el.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;
11179
- }
11180
- el.css( el.from ); // set top & left
11181
-
11182
- // Animate
11183
- if ( scale === "content" || scale === "both" ) { // Scale the children
11184
-
11185
- // Add margins/font-size
11186
- vProps = vProps.concat([ "marginTop", "marginBottom" ]).concat(cProps);
11187
- hProps = hProps.concat([ "marginLeft", "marginRight" ]);
11188
- props2 = props0.concat(vProps).concat(hProps);
11189
-
11190
- el.find( "*[width]" ).each( function(){
11191
- var child = $( this ),
11192
- c_original = {
11193
- height: child.height(),
11194
- width: child.width(),
11195
- outerHeight: child.outerHeight(),
11196
- outerWidth: child.outerWidth()
11197
- };
11198
- if (restore) {
11199
- $.effects.save(child, props2);
11200
- }
11201
-
11202
- child.from = {
11203
- height: c_original.height * factor.from.y,
11204
- width: c_original.width * factor.from.x,
11205
- outerHeight: c_original.outerHeight * factor.from.y,
11206
- outerWidth: c_original.outerWidth * factor.from.x
11207
- };
11208
- child.to = {
11209
- height: c_original.height * factor.to.y,
11210
- width: c_original.width * factor.to.x,
11211
- outerHeight: c_original.height * factor.to.y,
11212
- outerWidth: c_original.width * factor.to.x
11213
- };
11214
-
11215
- // Vertical props scaling
11216
- if ( factor.from.y !== factor.to.y ) {
11217
- child.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );
11218
- child.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );
11219
- }
11220
-
11221
- // Horizontal props scaling
11222
- if ( factor.from.x !== factor.to.x ) {
11223
- child.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );
11224
- child.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );
11225
- }
11226
-
11227
- // Animate children
11228
- child.css( child.from );
11229
- child.animate( child.to, o.duration, o.easing, function() {
11230
-
11231
- // Restore children
11232
- if ( restore ) {
11233
- $.effects.restore( child, props2 );
11234
- }
11235
- });
11236
- });
11237
- }
11238
-
11239
- // Animate
11240
- el.animate( el.to, {
11241
- queue: false,
11242
- duration: o.duration,
11243
- easing: o.easing,
11244
- complete: function() {
11245
- if ( el.to.opacity === 0 ) {
11246
- el.css( "opacity", el.from.opacity );
11247
- }
11248
- if( mode === "hide" ) {
11249
- el.hide();
11250
- }
11251
- $.effects.restore( el, props );
11252
- if ( !restore ) {
11253
-
11254
- // we need to calculate our new positioning based on the scaling
11255
- if ( position === "static" ) {
11256
- el.css({
11257
- position: "relative",
11258
- top: el.to.top,
11259
- left: el.to.left
11260
- });
11261
- } else {
11262
- $.each([ "top", "left" ], function( idx, pos ) {
11263
- el.css( pos, function( _, str ) {
11264
- var val = parseInt( str, 10 ),
11265
- toRef = idx ? el.to.left : el.to.top;
11266
-
11267
- // if original was "auto", recalculate the new value from wrapper
11268
- if ( str === "auto" ) {
11269
- return toRef + "px";
11270
- }
11271
-
11272
- return val + toRef + "px";
11273
- });
11274
- });
11275
- }
11276
- }
11277
-
11278
- $.effects.removeWrapper( el );
11279
- done();
11280
- }
11281
- });
11282
-
11283
- };
11284
-
11285
- })(jQuery);
11286
-
11287
- (function( $, undefined ) {
11288
-
11289
- $.effects.effect.shake = function( o, done ) {
11290
-
11291
- var el = $( this ),
11292
- props = [ "position", "top", "bottom", "left", "right", "height", "width" ],
11293
- mode = $.effects.setMode( el, o.mode || "effect" ),
11294
- direction = o.direction || "left",
11295
- distance = o.distance || 20,
11296
- times = o.times || 3,
11297
- anims = times * 2 + 1,
11298
- speed = Math.round(o.duration/anims),
11299
- ref = (direction === "up" || direction === "down") ? "top" : "left",
11300
- positiveMotion = (direction === "up" || direction === "left"),
11301
- animation = {},
11302
- animation1 = {},
11303
- animation2 = {},
11304
- i,
11305
-
11306
- // we will need to re-assemble the queue to stack our animations in place
11307
- queue = el.queue(),
11308
- queuelen = queue.length;
11309
-
11310
- $.effects.save( el, props );
11311
- el.show();
11312
- $.effects.createWrapper( el );
11313
-
11314
- // Animation
11315
- animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
11316
- animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
11317
- animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
11318
-
11319
- // Animate
11320
- el.animate( animation, speed, o.easing );
11321
-
11322
- // Shakes
11323
- for ( i = 1; i < times; i++ ) {
11324
- el.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );
11325
- }
11326
- el
11327
- .animate( animation1, speed, o.easing )
11328
- .animate( animation, speed / 2, o.easing )
11329
- .queue(function() {
11330
- if ( mode === "hide" ) {
11331
- el.hide();
11332
- }
11333
- $.effects.restore( el, props );
11334
- $.effects.removeWrapper( el );
11335
- done();
11336
- });
11337
-
11338
- // inject all the animations we just queued to be first in line (after "inprogress")
11339
- if ( queuelen > 1) {
11340
- queue.splice.apply( queue,
11341
- [ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );
11342
- }
11343
- el.dequeue();
11344
-
11345
- };
11346
-
11347
- })(jQuery);
11348
-
11349
- (function( $, undefined ) {
11350
-
11351
- $.effects.effect.slide = function( o, done ) {
11352
-
11353
- // Create element
11354
- var el = $( this ),
11355
- props = [ "position", "top", "bottom", "left", "right", "width", "height" ],
11356
- mode = $.effects.setMode( el, o.mode || "show" ),
11357
- show = mode === "show",
11358
- direction = o.direction || "left",
11359
- ref = (direction === "up" || direction === "down") ? "top" : "left",
11360
- positiveMotion = (direction === "up" || direction === "left"),
11361
- distance,
11362
- animation = {};
11363
-
11364
- // Adjust
11365
- $.effects.save( el, props );
11366
- el.show();
11367
- distance = o.distance || el[ ref === "top" ? "outerHeight" : "outerWidth" ]( true );
11368
-
11369
- $.effects.createWrapper( el ).css({
11370
- overflow: "hidden"
11371
- });
11372
-
11373
- if ( show ) {
11374
- el.css( ref, positiveMotion ? (isNaN(distance) ? "-" + distance : -distance) : distance );
11375
- }
11376
-
11377
- // Animation
11378
- animation[ ref ] = ( show ?
11379
- ( positiveMotion ? "+=" : "-=") :
11380
- ( positiveMotion ? "-=" : "+=")) +
11381
- distance;
11382
-
11383
- // Animate
11384
- el.animate( animation, {
11385
- queue: false,
11386
- duration: o.duration,
11387
- easing: o.easing,
11388
- complete: function() {
11389
- if ( mode === "hide" ) {
11390
- el.hide();
11391
- }
11392
- $.effects.restore( el, props );
11393
- $.effects.removeWrapper( el );
11394
- done();
11395
- }
11396
- });
11397
- };
11398
-
11399
- })(jQuery);
11400
-
11401
- (function( $, undefined ) {
11402
-
11403
- $.effects.effect.transfer = function( o, done ) {
11404
- var elem = $( this ),
11405
- target = $( o.to ),
11406
- targetFixed = target.css( "position" ) === "fixed",
11407
- body = $("body"),
11408
- fixTop = targetFixed ? body.scrollTop() : 0,
11409
- fixLeft = targetFixed ? body.scrollLeft() : 0,
11410
- endPosition = target.offset(),
11411
- animation = {
11412
- top: endPosition.top - fixTop ,
11413
- left: endPosition.left - fixLeft ,
11414
- height: target.innerHeight(),
11415
- width: target.innerWidth()
11416
- },
11417
- startPosition = elem.offset(),
11418
- transfer = $( "<div class='ui-effects-transfer'></div>" )
11419
- .appendTo( document.body )
11420
- .addClass( o.className )
11421
- .css({
11422
- top: startPosition.top - fixTop ,
11423
- left: startPosition.left - fixLeft ,
11424
- height: elem.innerHeight(),
11425
- width: elem.innerWidth(),
11426
- position: targetFixed ? "fixed" : "absolute"
11427
- })
11428
- .animate( animation, o.duration, o.easing, function() {
11429
- transfer.remove();
11430
- done();
11431
- });
11432
- };
11433
-
11434
- })(jQuery);
11435
-
11436
- (function( $, undefined ) {
11437
-
11438
- $.widget( "ui.menu", {
11439
- version: "1.10.4",
11440
- defaultElement: "<ul>",
11441
- delay: 300,
11442
- options: {
11443
- icons: {
11444
- submenu: "ui-icon-carat-1-e"
11445
- },
11446
- menus: "ul",
11447
- position: {
11448
- my: "left top",
11449
- at: "right top"
11450
- },
11451
- role: "menu",
11452
-
11453
- // callbacks
11454
- blur: null,
11455
- focus: null,
11456
- select: null
11457
- },
11458
-
11459
- _create: function() {
11460
- this.activeMenu = this.element;
11461
- // flag used to prevent firing of the click handler
11462
- // as the event bubbles up through nested menus
11463
- this.mouseHandled = false;
11464
- this.element
11465
- .uniqueId()
11466
- .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11467
- .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
11468
- .attr({
11469
- role: this.options.role,
11470
- tabIndex: 0
11471
- })
11472
- // need to catch all clicks on disabled menu
11473
- // not possible through _on
11474
- .bind( "click" + this.eventNamespace, $.proxy(function( event ) {
11475
- if ( this.options.disabled ) {
11476
- event.preventDefault();
11477
- }
11478
- }, this ));
11479
-
11480
- if ( this.options.disabled ) {
11481
- this.element
11482
- .addClass( "ui-state-disabled" )
11483
- .attr( "aria-disabled", "true" );
11484
- }
11485
-
11486
- this._on({
11487
- // Prevent focus from sticking to links inside menu after clicking
11488
- // them (focus should always stay on UL during navigation).
11489
- "mousedown .ui-menu-item > a": function( event ) {
11490
- event.preventDefault();
11491
- },
11492
- "click .ui-state-disabled > a": function( event ) {
11493
- event.preventDefault();
11494
- },
11495
- "click .ui-menu-item:has(a)": function( event ) {
11496
- var target = $( event.target ).closest( ".ui-menu-item" );
11497
- if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
11498
- this.select( event );
11499
-
11500
- // Only set the mouseHandled flag if the event will bubble, see #9469.
11501
- if ( !event.isPropagationStopped() ) {
11502
- this.mouseHandled = true;
11503
- }
11504
-
11505
- // Open submenu on click
11506
- if ( target.has( ".ui-menu" ).length ) {
11507
- this.expand( event );
11508
- } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
11509
-
11510
- // Redirect focus to the menu
11511
- this.element.trigger( "focus", [ true ] );
11512
-
11513
- // If the active item is on the top level, let it stay active.
11514
- // Otherwise, blur the active item since it is no longer visible.
11515
- if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
11516
- clearTimeout( this.timer );
11517
- }
11518
- }
11519
- }
11520
- },
11521
- "mouseenter .ui-menu-item": function( event ) {
11522
- var target = $( event.currentTarget );
11523
- // Remove ui-state-active class from siblings of the newly focused menu item
11524
- // to avoid a jump caused by adjacent elements both having a class with a border
11525
- target.siblings().children( ".ui-state-active" ).removeClass( "ui-state-active" );
11526
- this.focus( event, target );
11527
- },
11528
- mouseleave: "collapseAll",
11529
- "mouseleave .ui-menu": "collapseAll",
11530
- focus: function( event, keepActiveItem ) {
11531
- // If there's already an active item, keep it active
11532
- // If not, activate the first item
11533
- var item = this.active || this.element.children( ".ui-menu-item" ).eq( 0 );
11534
-
11535
- if ( !keepActiveItem ) {
11536
- this.focus( event, item );
11537
- }
11538
- },
11539
- blur: function( event ) {
11540
- this._delay(function() {
11541
- if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
11542
- this.collapseAll( event );
11543
- }
11544
- });
11545
- },
11546
- keydown: "_keydown"
11547
- });
11548
-
11549
- this.refresh();
11550
-
11551
- // Clicks outside of a menu collapse any open menus
11552
- this._on( this.document, {
11553
- click: function( event ) {
11554
- if ( !$( event.target ).closest( ".ui-menu" ).length ) {
11555
- this.collapseAll( event );
11556
- }
11557
-
11558
- // Reset the mouseHandled flag
11559
- this.mouseHandled = false;
11560
- }
11561
- });
11562
- },
11563
-
11564
- _destroy: function() {
11565
- // Destroy (sub)menus
11566
- this.element
11567
- .removeAttr( "aria-activedescendant" )
11568
- .find( ".ui-menu" ).addBack()
11569
- .removeClass( "ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons" )
11570
- .removeAttr( "role" )
11571
- .removeAttr( "tabIndex" )
11572
- .removeAttr( "aria-labelledby" )
11573
- .removeAttr( "aria-expanded" )
11574
- .removeAttr( "aria-hidden" )
11575
- .removeAttr( "aria-disabled" )
11576
- .removeUniqueId()
11577
- .show();
11578
-
11579
- // Destroy menu items
11580
- this.element.find( ".ui-menu-item" )
11581
- .removeClass( "ui-menu-item" )
11582
- .removeAttr( "role" )
11583
- .removeAttr( "aria-disabled" )
11584
- .children( "a" )
11585
- .removeUniqueId()
11586
- .removeClass( "ui-corner-all ui-state-hover" )
11587
- .removeAttr( "tabIndex" )
11588
- .removeAttr( "role" )
11589
- .removeAttr( "aria-haspopup" )
11590
- .children().each( function() {
11591
- var elem = $( this );
11592
- if ( elem.data( "ui-menu-submenu-carat" ) ) {
11593
- elem.remove();
11594
- }
11595
- });
11596
-
11597
- // Destroy menu dividers
11598
- this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
11599
- },
11600
-
11601
- _keydown: function( event ) {
11602
- var match, prev, character, skip, regex,
11603
- preventDefault = true;
11604
-
11605
- function escape( value ) {
11606
- return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
11607
- }
11608
-
11609
- switch ( event.keyCode ) {
11610
- case $.ui.keyCode.PAGE_UP:
11611
- this.previousPage( event );
11612
- break;
11613
- case $.ui.keyCode.PAGE_DOWN:
11614
- this.nextPage( event );
11615
- break;
11616
- case $.ui.keyCode.HOME:
11617
- this._move( "first", "first", event );
11618
- break;
11619
- case $.ui.keyCode.END:
11620
- this._move( "last", "last", event );
11621
- break;
11622
- case $.ui.keyCode.UP:
11623
- this.previous( event );
11624
- break;
11625
- case $.ui.keyCode.DOWN:
11626
- this.next( event );
11627
- break;
11628
- case $.ui.keyCode.LEFT:
11629
- this.collapse( event );
11630
- break;
11631
- case $.ui.keyCode.RIGHT:
11632
- if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
11633
- this.expand( event );
11634
- }
11635
- break;
11636
- case $.ui.keyCode.ENTER:
11637
- case $.ui.keyCode.SPACE:
11638
- this._activate( event );
11639
- break;
11640
- case $.ui.keyCode.ESCAPE:
11641
- this.collapse( event );
11642
- break;
11643
- default:
11644
- preventDefault = false;
11645
- prev = this.previousFilter || "";
11646
- character = String.fromCharCode( event.keyCode );
11647
- skip = false;
11648
-
11649
- clearTimeout( this.filterTimer );
11650
-
11651
- if ( character === prev ) {
11652
- skip = true;
11653
- } else {
11654
- character = prev + character;
11655
- }
11656
-
11657
- regex = new RegExp( "^" + escape( character ), "i" );
11658
- match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11659
- return regex.test( $( this ).children( "a" ).text() );
11660
- });
11661
- match = skip && match.index( this.active.next() ) !== -1 ?
11662
- this.active.nextAll( ".ui-menu-item" ) :
11663
- match;
11664
-
11665
- // If no matches on the current filter, reset to the last character pressed
11666
- // to move down the menu to the first item that starts with that character
11667
- if ( !match.length ) {
11668
- character = String.fromCharCode( event.keyCode );
11669
- regex = new RegExp( "^" + escape( character ), "i" );
11670
- match = this.activeMenu.children( ".ui-menu-item" ).filter(function() {
11671
- return regex.test( $( this ).children( "a" ).text() );
11672
- });
11673
- }
11674
-
11675
- if ( match.length ) {
11676
- this.focus( event, match );
11677
- if ( match.length > 1 ) {
11678
- this.previousFilter = character;
11679
- this.filterTimer = this._delay(function() {
11680
- delete this.previousFilter;
11681
- }, 1000 );
11682
- } else {
11683
- delete this.previousFilter;
11684
- }
11685
- } else {
11686
- delete this.previousFilter;
11687
- }
11688
- }
11689
-
11690
- if ( preventDefault ) {
11691
- event.preventDefault();
11692
- }
11693
- },
11694
-
11695
- _activate: function( event ) {
11696
- if ( !this.active.is( ".ui-state-disabled" ) ) {
11697
- if ( this.active.children( "a[aria-haspopup='true']" ).length ) {
11698
- this.expand( event );
11699
- } else {
11700
- this.select( event );
11701
- }
11702
- }
11703
- },
11704
-
11705
- refresh: function() {
11706
- var menus,
11707
- icon = this.options.icons.submenu,
11708
- submenus = this.element.find( this.options.menus );
11709
-
11710
- this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
11711
-
11712
- // Initialize nested menus
11713
- submenus.filter( ":not(.ui-menu)" )
11714
- .addClass( "ui-menu ui-widget ui-widget-content ui-corner-all" )
11715
- .hide()
11716
- .attr({
11717
- role: this.options.role,
11718
- "aria-hidden": "true",
11719
- "aria-expanded": "false"
11720
- })
11721
- .each(function() {
11722
- var menu = $( this ),
11723
- item = menu.prev( "a" ),
11724
- submenuCarat = $( "<span>" )
11725
- .addClass( "ui-menu-icon ui-icon " + icon )
11726
- .data( "ui-menu-submenu-carat", true );
11727
-
11728
- item
11729
- .attr( "aria-haspopup", "true" )
11730
- .prepend( submenuCarat );
11731
- menu.attr( "aria-labelledby", item.attr( "id" ) );
11732
- });
11733
-
11734
- menus = submenus.add( this.element );
11735
-
11736
- // Don't refresh list items that are already adapted
11737
- menus.children( ":not(.ui-menu-item):has(a)" )
11738
- .addClass( "ui-menu-item" )
11739
- .attr( "role", "presentation" )
11740
- .children( "a" )
11741
- .uniqueId()
11742
- .addClass( "ui-corner-all" )
11743
- .attr({
11744
- tabIndex: -1,
11745
- role: this._itemRole()
11746
- });
11747
-
11748
- // Initialize unlinked menu-items containing spaces and/or dashes only as dividers
11749
- menus.children( ":not(.ui-menu-item)" ).each(function() {
11750
- var item = $( this );
11751
- // hyphen, em dash, en dash
11752
- if ( !/[^\-\u2014\u2013\s]/.test( item.text() ) ) {
11753
- item.addClass( "ui-widget-content ui-menu-divider" );
11754
- }
11755
- });
11756
-
11757
- // Add aria-disabled attribute to any disabled menu item
11758
- menus.children( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
11759
-
11760
- // If the active item has been removed, blur the menu
11761
- if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
11762
- this.blur();
11763
- }
11764
- },
11765
-
11766
- _itemRole: function() {
11767
- return {
11768
- menu: "menuitem",
11769
- listbox: "option"
11770
- }[ this.options.role ];
11771
- },
11772
-
11773
- _setOption: function( key, value ) {
11774
- if ( key === "icons" ) {
11775
- this.element.find( ".ui-menu-icon" )
11776
- .removeClass( this.options.icons.submenu )
11777
- .addClass( value.submenu );
11778
- }
11779
- this._super( key, value );
11780
- },
11781
-
11782
- focus: function( event, item ) {
11783
- var nested, focused;
11784
- this.blur( event, event && event.type === "focus" );
11785
-
11786
- this._scrollIntoView( item );
11787
-
11788
- this.active = item.first();
11789
- focused = this.active.children( "a" ).addClass( "ui-state-focus" );
11790
- // Only update aria-activedescendant if there's a role
11791
- // otherwise we assume focus is managed elsewhere
11792
- if ( this.options.role ) {
11793
- this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
11794
- }
11795
-
11796
- // Highlight active parent menu item, if any
11797
- this.active
11798
- .parent()
11799
- .closest( ".ui-menu-item" )
11800
- .children( "a:first" )
11801
- .addClass( "ui-state-active" );
11802
-
11803
- if ( event && event.type === "keydown" ) {
11804
- this._close();
11805
- } else {
11806
- this.timer = this._delay(function() {
11807
- this._close();
11808
- }, this.delay );
11809
- }
11810
-
11811
- nested = item.children( ".ui-menu" );
11812
- if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
11813
- this._startOpening(nested);
11814
- }
11815
- this.activeMenu = item.parent();
11816
-
11817
- this._trigger( "focus", event, { item: item } );
11818
- },
11819
-
11820
- _scrollIntoView: function( item ) {
11821
- var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
11822
- if ( this._hasScroll() ) {
11823
- borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
11824
- paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
11825
- offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
11826
- scroll = this.activeMenu.scrollTop();
11827
- elementHeight = this.activeMenu.height();
11828
- itemHeight = item.height();
11829
-
11830
- if ( offset < 0 ) {
11831
- this.activeMenu.scrollTop( scroll + offset );
11832
- } else if ( offset + itemHeight > elementHeight ) {
11833
- this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
11834
- }
11835
- }
11836
- },
11837
-
11838
- blur: function( event, fromFocus ) {
11839
- if ( !fromFocus ) {
11840
- clearTimeout( this.timer );
11841
- }
11842
-
11843
- if ( !this.active ) {
11844
- return;
11845
- }
11846
-
11847
- this.active.children( "a" ).removeClass( "ui-state-focus" );
11848
- this.active = null;
11849
-
11850
- this._trigger( "blur", event, { item: this.active } );
11851
- },
11852
-
11853
- _startOpening: function( submenu ) {
11854
- clearTimeout( this.timer );
11855
-
11856
- // Don't open if already open fixes a Firefox bug that caused a .5 pixel
11857
- // shift in the submenu position when mousing over the carat icon
11858
- if ( submenu.attr( "aria-hidden" ) !== "true" ) {
11859
- return;
11860
- }
11861
-
11862
- this.timer = this._delay(function() {
11863
- this._close();
11864
- this._open( submenu );
11865
- }, this.delay );
11866
- },
11867
-
11868
- _open: function( submenu ) {
11869
- var position = $.extend({
11870
- of: this.active
11871
- }, this.options.position );
11872
-
11873
- clearTimeout( this.timer );
11874
- this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
11875
- .hide()
11876
- .attr( "aria-hidden", "true" );
11877
-
11878
- submenu
11879
- .show()
11880
- .removeAttr( "aria-hidden" )
11881
- .attr( "aria-expanded", "true" )
11882
- .position( position );
11883
- },
11884
-
11885
- collapseAll: function( event, all ) {
11886
- clearTimeout( this.timer );
11887
- this.timer = this._delay(function() {
11888
- // If we were passed an event, look for the submenu that contains the event
11889
- var currentMenu = all ? this.element :
11890
- $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
11891
-
11892
- // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
11893
- if ( !currentMenu.length ) {
11894
- currentMenu = this.element;
11895
- }
11896
-
11897
- this._close( currentMenu );
11898
-
11899
- this.blur( event );
11900
- this.activeMenu = currentMenu;
11901
- }, this.delay );
11902
- },
11903
-
11904
- // With no arguments, closes the currently active menu - if nothing is active
11905
- // it closes all menus. If passed an argument, it will search for menus BELOW
11906
- _close: function( startMenu ) {
11907
- if ( !startMenu ) {
11908
- startMenu = this.active ? this.active.parent() : this.element;
11909
- }
11910
-
11911
- startMenu
11912
- .find( ".ui-menu" )
11913
- .hide()
11914
- .attr( "aria-hidden", "true" )
11915
- .attr( "aria-expanded", "false" )
11916
- .end()
11917
- .find( "a.ui-state-active" )
11918
- .removeClass( "ui-state-active" );
11919
- },
11920
-
11921
- collapse: function( event ) {
11922
- var newItem = this.active &&
11923
- this.active.parent().closest( ".ui-menu-item", this.element );
11924
- if ( newItem && newItem.length ) {
11925
- this._close();
11926
- this.focus( event, newItem );
11927
- }
11928
- },
11929
-
11930
- expand: function( event ) {
11931
- var newItem = this.active &&
11932
- this.active
11933
- .children( ".ui-menu " )
11934
- .children( ".ui-menu-item" )
11935
- .first();
11936
-
11937
- if ( newItem && newItem.length ) {
11938
- this._open( newItem.parent() );
11939
-
11940
- // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
11941
- this._delay(function() {
11942
- this.focus( event, newItem );
11943
- });
11944
- }
11945
- },
11946
-
11947
- next: function( event ) {
11948
- this._move( "next", "first", event );
11949
- },
11950
-
11951
- previous: function( event ) {
11952
- this._move( "prev", "last", event );
11953
- },
11954
-
11955
- isFirstItem: function() {
11956
- return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
11957
- },
11958
-
11959
- isLastItem: function() {
11960
- return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
11961
- },
11962
-
11963
- _move: function( direction, filter, event ) {
11964
- var next;
11965
- if ( this.active ) {
11966
- if ( direction === "first" || direction === "last" ) {
11967
- next = this.active
11968
- [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
11969
- .eq( -1 );
11970
- } else {
11971
- next = this.active
11972
- [ direction + "All" ]( ".ui-menu-item" )
11973
- .eq( 0 );
11974
- }
11975
- }
11976
- if ( !next || !next.length || !this.active ) {
11977
- next = this.activeMenu.children( ".ui-menu-item" )[ filter ]();
11978
- }
11979
-
11980
- this.focus( event, next );
11981
- },
11982
-
11983
- nextPage: function( event ) {
11984
- var item, base, height;
11985
-
11986
- if ( !this.active ) {
11987
- this.next( event );
11988
- return;
11989
- }
11990
- if ( this.isLastItem() ) {
11991
- return;
11992
- }
11993
- if ( this._hasScroll() ) {
11994
- base = this.active.offset().top;
11995
- height = this.element.height();
11996
- this.active.nextAll( ".ui-menu-item" ).each(function() {
11997
- item = $( this );
11998
- return item.offset().top - base - height < 0;
11999
- });
12000
-
12001
- this.focus( event, item );
12002
- } else {
12003
- this.focus( event, this.activeMenu.children( ".ui-menu-item" )
12004
- [ !this.active ? "first" : "last" ]() );
12005
- }
12006
- },
12007
-
12008
- previousPage: function( event ) {
12009
- var item, base, height;
12010
- if ( !this.active ) {
12011
- this.next( event );
12012
- return;
12013
- }
12014
- if ( this.isFirstItem() ) {
12015
- return;
12016
- }
12017
- if ( this._hasScroll() ) {
12018
- base = this.active.offset().top;
12019
- height = this.element.height();
12020
- this.active.prevAll( ".ui-menu-item" ).each(function() {
12021
- item = $( this );
12022
- return item.offset().top - base + height > 0;
12023
- });
12024
-
12025
- this.focus( event, item );
12026
- } else {
12027
- this.focus( event, this.activeMenu.children( ".ui-menu-item" ).first() );
12028
- }
12029
- },
12030
-
12031
- _hasScroll: function() {
12032
- return this.element.outerHeight() < this.element.prop( "scrollHeight" );
12033
- },
12034
-
12035
- select: function( event ) {
12036
- // TODO: It should never be possible to not have an active item at this
12037
- // point, but the tests don't trigger mouseenter before click.
12038
- this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
12039
- var ui = { item: this.active };
12040
- if ( !this.active.has( ".ui-menu" ).length ) {
12041
- this.collapseAll( event, true );
12042
- }
12043
- this._trigger( "select", event, ui );
12044
- }
12045
- });
12046
-
12047
- }( jQuery ));
12048
-
12049
- (function( $, undefined ) {
12050
-
12051
- $.ui = $.ui || {};
12052
-
12053
- var cachedScrollbarWidth,
12054
- max = Math.max,
12055
- abs = Math.abs,
12056
- round = Math.round,
12057
- rhorizontal = /left|center|right/,
12058
- rvertical = /top|center|bottom/,
12059
- roffset = /[\+\-]\d+(\.[\d]+)?%?/,
12060
- rposition = /^\w+/,
12061
- rpercent = /%$/,
12062
- _position = $.fn.position;
12063
-
12064
- function getOffsets( offsets, width, height ) {
12065
- return [
12066
- parseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),
12067
- parseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )
12068
- ];
12069
- }
12070
-
12071
- function parseCss( element, property ) {
12072
- return parseInt( $.css( element, property ), 10 ) || 0;
12073
- }
12074
-
12075
- function getDimensions( elem ) {
12076
- var raw = elem[0];
12077
- if ( raw.nodeType === 9 ) {
12078
- return {
12079
- width: elem.width(),
12080
- height: elem.height(),
12081
- offset: { top: 0, left: 0 }
12082
- };
12083
- }
12084
- if ( $.isWindow( raw ) ) {
12085
- return {
12086
- width: elem.width(),
12087
- height: elem.height(),
12088
- offset: { top: elem.scrollTop(), left: elem.scrollLeft() }
12089
- };
12090
- }
12091
- if ( raw.preventDefault ) {
12092
- return {
12093
- width: 0,
12094
- height: 0,
12095
- offset: { top: raw.pageY, left: raw.pageX }
12096
- };
12097
- }
12098
- return {
12099
- width: elem.outerWidth(),
12100
- height: elem.outerHeight(),
12101
- offset: elem.offset()
12102
- };
12103
- }
12104
-
12105
- $.position = {
12106
- scrollbarWidth: function() {
12107
- if ( cachedScrollbarWidth !== undefined ) {
12108
- return cachedScrollbarWidth;
12109
- }
12110
- var w1, w2,
12111
- div = $( "<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>" ),
12112
- innerDiv = div.children()[0];
12113
-
12114
- $( "body" ).append( div );
12115
- w1 = innerDiv.offsetWidth;
12116
- div.css( "overflow", "scroll" );
12117
-
12118
- w2 = innerDiv.offsetWidth;
12119
-
12120
- if ( w1 === w2 ) {
12121
- w2 = div[0].clientWidth;
12122
- }
12123
-
12124
- div.remove();
12125
-
12126
- return (cachedScrollbarWidth = w1 - w2);
12127
- },
12128
- getScrollInfo: function( within ) {
12129
- var overflowX = within.isWindow || within.isDocument ? "" :
12130
- within.element.css( "overflow-x" ),
12131
- overflowY = within.isWindow || within.isDocument ? "" :
12132
- within.element.css( "overflow-y" ),
12133
- hasOverflowX = overflowX === "scroll" ||
12134
- ( overflowX === "auto" && within.width < within.element[0].scrollWidth ),
12135
- hasOverflowY = overflowY === "scroll" ||
12136
- ( overflowY === "auto" && within.height < within.element[0].scrollHeight );
12137
- return {
12138
- width: hasOverflowY ? $.position.scrollbarWidth() : 0,
12139
- height: hasOverflowX ? $.position.scrollbarWidth() : 0
12140
- };
12141
- },
12142
- getWithinInfo: function( element ) {
12143
- var withinElement = $( element || window ),
12144
- isWindow = $.isWindow( withinElement[0] ),
12145
- isDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;
12146
- return {
12147
- element: withinElement,
12148
- isWindow: isWindow,
12149
- isDocument: isDocument,
12150
- offset: withinElement.offset() || { left: 0, top: 0 },
12151
- scrollLeft: withinElement.scrollLeft(),
12152
- scrollTop: withinElement.scrollTop(),
12153
- width: isWindow ? withinElement.width() : withinElement.outerWidth(),
12154
- height: isWindow ? withinElement.height() : withinElement.outerHeight()
12155
- };
12156
- }
12157
- };
12158
-
12159
- $.fn.position = function( options ) {
12160
- if ( !options || !options.of ) {
12161
- return _position.apply( this, arguments );
12162
- }
12163
-
12164
- // make a copy, we don't want to modify arguments
12165
- options = $.extend( {}, options );
12166
-
12167
- var atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,
12168
- target = $( options.of ),
12169
- within = $.position.getWithinInfo( options.within ),
12170
- scrollInfo = $.position.getScrollInfo( within ),
12171
- collision = ( options.collision || "flip" ).split( " " ),
12172
- offsets = {};
12173
-
12174
- dimensions = getDimensions( target );
12175
- if ( target[0].preventDefault ) {
12176
- // force left top to allow flipping
12177
- options.at = "left top";
12178
- }
12179
- targetWidth = dimensions.width;
12180
- targetHeight = dimensions.height;
12181
- targetOffset = dimensions.offset;
12182
- // clone to reuse original targetOffset later
12183
- basePosition = $.extend( {}, targetOffset );
12184
-
12185
- // force my and at to have valid horizontal and vertical positions
12186
- // if a value is missing or invalid, it will be converted to center
12187
- $.each( [ "my", "at" ], function() {
12188
- var pos = ( options[ this ] || "" ).split( " " ),
12189
- horizontalOffset,
12190
- verticalOffset;
12191
-
12192
- if ( pos.length === 1) {
12193
- pos = rhorizontal.test( pos[ 0 ] ) ?
12194
- pos.concat( [ "center" ] ) :
12195
- rvertical.test( pos[ 0 ] ) ?
12196
- [ "center" ].concat( pos ) :
12197
- [ "center", "center" ];
12198
- }
12199
- pos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : "center";
12200
- pos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : "center";
12201
-
12202
- // calculate offsets
12203
- horizontalOffset = roffset.exec( pos[ 0 ] );
12204
- verticalOffset = roffset.exec( pos[ 1 ] );
12205
- offsets[ this ] = [
12206
- horizontalOffset ? horizontalOffset[ 0 ] : 0,
12207
- verticalOffset ? verticalOffset[ 0 ] : 0
12208
- ];
12209
-
12210
- // reduce to just the positions without the offsets
12211
- options[ this ] = [
12212
- rposition.exec( pos[ 0 ] )[ 0 ],
12213
- rposition.exec( pos[ 1 ] )[ 0 ]
12214
- ];
12215
- });
12216
-
12217
- // normalize collision option
12218
- if ( collision.length === 1 ) {
12219
- collision[ 1 ] = collision[ 0 ];
12220
- }
12221
-
12222
- if ( options.at[ 0 ] === "right" ) {
12223
- basePosition.left += targetWidth;
12224
- } else if ( options.at[ 0 ] === "center" ) {
12225
- basePosition.left += targetWidth / 2;
12226
- }
12227
-
12228
- if ( options.at[ 1 ] === "bottom" ) {
12229
- basePosition.top += targetHeight;
12230
- } else if ( options.at[ 1 ] === "center" ) {
12231
- basePosition.top += targetHeight / 2;
12232
- }
12233
-
12234
- atOffset = getOffsets( offsets.at, targetWidth, targetHeight );
12235
- basePosition.left += atOffset[ 0 ];
12236
- basePosition.top += atOffset[ 1 ];
12237
-
12238
- return this.each(function() {
12239
- var collisionPosition, using,
12240
- elem = $( this ),
12241
- elemWidth = elem.outerWidth(),
12242
- elemHeight = elem.outerHeight(),
12243
- marginLeft = parseCss( this, "marginLeft" ),
12244
- marginTop = parseCss( this, "marginTop" ),
12245
- collisionWidth = elemWidth + marginLeft + parseCss( this, "marginRight" ) + scrollInfo.width,
12246
- collisionHeight = elemHeight + marginTop + parseCss( this, "marginBottom" ) + scrollInfo.height,
12247
- position = $.extend( {}, basePosition ),
12248
- myOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );
12249
-
12250
- if ( options.my[ 0 ] === "right" ) {
12251
- position.left -= elemWidth;
12252
- } else if ( options.my[ 0 ] === "center" ) {
12253
- position.left -= elemWidth / 2;
12254
- }
12255
-
12256
- if ( options.my[ 1 ] === "bottom" ) {
12257
- position.top -= elemHeight;
12258
- } else if ( options.my[ 1 ] === "center" ) {
12259
- position.top -= elemHeight / 2;
12260
- }
12261
-
12262
- position.left += myOffset[ 0 ];
12263
- position.top += myOffset[ 1 ];
12264
-
12265
- // if the browser doesn't support fractions, then round for consistent results
12266
- if ( !$.support.offsetFractions ) {
12267
- position.left = round( position.left );
12268
- position.top = round( position.top );
12269
- }
12270
-
12271
- collisionPosition = {
12272
- marginLeft: marginLeft,
12273
- marginTop: marginTop
12274
- };
12275
-
12276
- $.each( [ "left", "top" ], function( i, dir ) {
12277
- if ( $.ui.position[ collision[ i ] ] ) {
12278
- $.ui.position[ collision[ i ] ][ dir ]( position, {
12279
- targetWidth: targetWidth,
12280
- targetHeight: targetHeight,
12281
- elemWidth: elemWidth,
12282
- elemHeight: elemHeight,
12283
- collisionPosition: collisionPosition,
12284
- collisionWidth: collisionWidth,
12285
- collisionHeight: collisionHeight,
12286
- offset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],
12287
- my: options.my,
12288
- at: options.at,
12289
- within: within,
12290
- elem : elem
12291
- });
12292
- }
12293
- });
12294
-
12295
- if ( options.using ) {
12296
- // adds feedback as second argument to using callback, if present
12297
- using = function( props ) {
12298
- var left = targetOffset.left - position.left,
12299
- right = left + targetWidth - elemWidth,
12300
- top = targetOffset.top - position.top,
12301
- bottom = top + targetHeight - elemHeight,
12302
- feedback = {
12303
- target: {
12304
- element: target,
12305
- left: targetOffset.left,
12306
- top: targetOffset.top,
12307
- width: targetWidth,
12308
- height: targetHeight
12309
- },
12310
- element: {
12311
- element: elem,
12312
- left: position.left,
12313
- top: position.top,
12314
- width: elemWidth,
12315
- height: elemHeight
12316
- },
12317
- horizontal: right < 0 ? "left" : left > 0 ? "right" : "center",
12318
- vertical: bottom < 0 ? "top" : top > 0 ? "bottom" : "middle"
12319
- };
12320
- if ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {
12321
- feedback.horizontal = "center";
12322
- }
12323
- if ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {
12324
- feedback.vertical = "middle";
12325
- }
12326
- if ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {
12327
- feedback.important = "horizontal";
12328
- } else {
12329
- feedback.important = "vertical";
12330
- }
12331
- options.using.call( this, props, feedback );
12332
- };
12333
- }
12334
-
12335
- elem.offset( $.extend( position, { using: using } ) );
12336
- });
12337
- };
12338
-
12339
- $.ui.position = {
12340
- fit: {
12341
- left: function( position, data ) {
12342
- var within = data.within,
12343
- withinOffset = within.isWindow ? within.scrollLeft : within.offset.left,
12344
- outerWidth = within.width,
12345
- collisionPosLeft = position.left - data.collisionPosition.marginLeft,
12346
- overLeft = withinOffset - collisionPosLeft,
12347
- overRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,
12348
- newOverRight;
12349
-
12350
- // element is wider than within
12351
- if ( data.collisionWidth > outerWidth ) {
12352
- // element is initially over the left side of within
12353
- if ( overLeft > 0 && overRight <= 0 ) {
12354
- newOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;
12355
- position.left += overLeft - newOverRight;
12356
- // element is initially over right side of within
12357
- } else if ( overRight > 0 && overLeft <= 0 ) {
12358
- position.left = withinOffset;
12359
- // element is initially over both left and right sides of within
12360
- } else {
12361
- if ( overLeft > overRight ) {
12362
- position.left = withinOffset + outerWidth - data.collisionWidth;
12363
- } else {
12364
- position.left = withinOffset;
12365
- }
12366
- }
12367
- // too far left -> align with left edge
12368
- } else if ( overLeft > 0 ) {
12369
- position.left += overLeft;
12370
- // too far right -> align with right edge
12371
- } else if ( overRight > 0 ) {
12372
- position.left -= overRight;
12373
- // adjust based on position and margin
12374
- } else {
12375
- position.left = max( position.left - collisionPosLeft, position.left );
12376
- }
12377
- },
12378
- top: function( position, data ) {
12379
- var within = data.within,
12380
- withinOffset = within.isWindow ? within.scrollTop : within.offset.top,
12381
- outerHeight = data.within.height,
12382
- collisionPosTop = position.top - data.collisionPosition.marginTop,
12383
- overTop = withinOffset - collisionPosTop,
12384
- overBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,
12385
- newOverBottom;
12386
-
12387
- // element is taller than within
12388
- if ( data.collisionHeight > outerHeight ) {
12389
- // element is initially over the top of within
12390
- if ( overTop > 0 && overBottom <= 0 ) {
12391
- newOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;
12392
- position.top += overTop - newOverBottom;
12393
- // element is initially over bottom of within
12394
- } else if ( overBottom > 0 && overTop <= 0 ) {
12395
- position.top = withinOffset;
12396
- // element is initially over both top and bottom of within
12397
- } else {
12398
- if ( overTop > overBottom ) {
12399
- position.top = withinOffset + outerHeight - data.collisionHeight;
12400
- } else {
12401
- position.top = withinOffset;
12402
- }
12403
- }
12404
- // too far up -> align with top
12405
- } else if ( overTop > 0 ) {
12406
- position.top += overTop;
12407
- // too far down -> align with bottom edge
12408
- } else if ( overBottom > 0 ) {
12409
- position.top -= overBottom;
12410
- // adjust based on position and margin
12411
- } else {
12412
- position.top = max( position.top - collisionPosTop, position.top );
12413
- }
12414
- }
12415
- },
12416
- flip: {
12417
- left: function( position, data ) {
12418
- var within = data.within,
12419
- withinOffset = within.offset.left + within.scrollLeft,
12420
- outerWidth = within.width,
12421
- offsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,
12422
- collisionPosLeft = position.left - data.collisionPosition.marginLeft,
12423
- overLeft = collisionPosLeft - offsetLeft,
12424
- overRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,
12425
- myOffset = data.my[ 0 ] === "left" ?
12426
- -data.elemWidth :
12427
- data.my[ 0 ] === "right" ?
12428
- data.elemWidth :
12429
- 0,
12430
- atOffset = data.at[ 0 ] === "left" ?
12431
- data.targetWidth :
12432
- data.at[ 0 ] === "right" ?
12433
- -data.targetWidth :
12434
- 0,
12435
- offset = -2 * data.offset[ 0 ],
12436
- newOverRight,
12437
- newOverLeft;
12438
-
12439
- if ( overLeft < 0 ) {
12440
- newOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;
12441
- if ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {
12442
- position.left += myOffset + atOffset + offset;
12443
- }
12444
- }
12445
- else if ( overRight > 0 ) {
12446
- newOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;
12447
- if ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {
12448
- position.left += myOffset + atOffset + offset;
12449
- }
12450
- }
12451
- },
12452
- top: function( position, data ) {
12453
- var within = data.within,
12454
- withinOffset = within.offset.top + within.scrollTop,
12455
- outerHeight = within.height,
12456
- offsetTop = within.isWindow ? within.scrollTop : within.offset.top,
12457
- collisionPosTop = position.top - data.collisionPosition.marginTop,
12458
- overTop = collisionPosTop - offsetTop,
12459
- overBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,
12460
- top = data.my[ 1 ] === "top",
12461
- myOffset = top ?
12462
- -data.elemHeight :
12463
- data.my[ 1 ] === "bottom" ?
12464
- data.elemHeight :
12465
- 0,
12466
- atOffset = data.at[ 1 ] === "top" ?
12467
- data.targetHeight :
12468
- data.at[ 1 ] === "bottom" ?
12469
- -data.targetHeight :
12470
- 0,
12471
- offset = -2 * data.offset[ 1 ],
12472
- newOverTop,
12473
- newOverBottom;
12474
- if ( overTop < 0 ) {
12475
- newOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;
12476
- if ( ( position.top + myOffset + atOffset + offset) > overTop && ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) ) {
12477
- position.top += myOffset + atOffset + offset;
12478
- }
12479
- }
12480
- else if ( overBottom > 0 ) {
12481
- newOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;
12482
- if ( ( position.top + myOffset + atOffset + offset) > overBottom && ( newOverTop > 0 || abs( newOverTop ) < overBottom ) ) {
12483
- position.top += myOffset + atOffset + offset;
12484
- }
12485
- }
12486
- }
12487
- },
12488
- flipfit: {
12489
- left: function() {
12490
- $.ui.position.flip.left.apply( this, arguments );
12491
- $.ui.position.fit.left.apply( this, arguments );
12492
- },
12493
- top: function() {
12494
- $.ui.position.flip.top.apply( this, arguments );
12495
- $.ui.position.fit.top.apply( this, arguments );
12496
- }
12497
- }
12498
- };
12499
-
12500
- // fraction support test
12501
- (function () {
12502
- var testElement, testElementParent, testElementStyle, offsetLeft, i,
12503
- body = document.getElementsByTagName( "body" )[ 0 ],
12504
- div = document.createElement( "div" );
12505
-
12506
- //Create a "fake body" for testing based on method used in jQuery.support
12507
- testElement = document.createElement( body ? "div" : "body" );
12508
- testElementStyle = {
12509
- visibility: "hidden",
12510
- width: 0,
12511
- height: 0,
12512
- border: 0,
12513
- margin: 0,
12514
- background: "none"
12515
- };
12516
- if ( body ) {
12517
- $.extend( testElementStyle, {
12518
- position: "absolute",
12519
- left: "-1000px",
12520
- top: "-1000px"
12521
- });
12522
- }
12523
- for ( i in testElementStyle ) {
12524
- testElement.style[ i ] = testElementStyle[ i ];
12525
- }
12526
- testElement.appendChild( div );
12527
- testElementParent = body || document.documentElement;
12528
- testElementParent.insertBefore( testElement, testElementParent.firstChild );
12529
-
12530
- div.style.cssText = "position: absolute; left: 10.7432222px;";
12531
-
12532
- offsetLeft = $( div ).offset().left;
12533
- $.support.offsetFractions = offsetLeft > 10 && offsetLeft < 11;
12534
-
12535
- testElement.innerHTML = "";
12536
- testElementParent.removeChild( testElement );
12537
- })();
12538
-
12539
- }( jQuery ) );
12540
-
12541
- (function( $, undefined ) {
12542
-
12543
- $.widget( "ui.progressbar", {
12544
- version: "1.10.4",
12545
- options: {
12546
- max: 100,
12547
- value: 0,
12548
-
12549
- change: null,
12550
- complete: null
12551
- },
12552
-
12553
- min: 0,
12554
-
12555
- _create: function() {
12556
- // Constrain initial value
12557
- this.oldValue = this.options.value = this._constrainedValue();
12558
-
12559
- this.element
12560
- .addClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12561
- .attr({
12562
- // Only set static values, aria-valuenow and aria-valuemax are
12563
- // set inside _refreshValue()
12564
- role: "progressbar",
12565
- "aria-valuemin": this.min
12566
- });
12567
-
12568
- this.valueDiv = $( "<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>" )
12569
- .appendTo( this.element );
12570
-
12571
- this._refreshValue();
12572
- },
12573
-
12574
- _destroy: function() {
12575
- this.element
12576
- .removeClass( "ui-progressbar ui-widget ui-widget-content ui-corner-all" )
12577
- .removeAttr( "role" )
12578
- .removeAttr( "aria-valuemin" )
12579
- .removeAttr( "aria-valuemax" )
12580
- .removeAttr( "aria-valuenow" );
12581
-
12582
- this.valueDiv.remove();
12583
- },
12584
-
12585
- value: function( newValue ) {
12586
- if ( newValue === undefined ) {
12587
- return this.options.value;
12588
- }
12589
-
12590
- this.options.value = this._constrainedValue( newValue );
12591
- this._refreshValue();
12592
- },
12593
-
12594
- _constrainedValue: function( newValue ) {
12595
- if ( newValue === undefined ) {
12596
- newValue = this.options.value;
12597
- }
12598
-
12599
- this.indeterminate = newValue === false;
12600
-
12601
- // sanitize value
12602
- if ( typeof newValue !== "number" ) {
12603
- newValue = 0;
12604
- }
12605
-
12606
- return this.indeterminate ? false :
12607
- Math.min( this.options.max, Math.max( this.min, newValue ) );
12608
- },
12609
-
12610
- _setOptions: function( options ) {
12611
- // Ensure "value" option is set after other values (like max)
12612
- var value = options.value;
12613
- delete options.value;
12614
-
12615
- this._super( options );
12616
-
12617
- this.options.value = this._constrainedValue( value );
12618
- this._refreshValue();
12619
- },
12620
-
12621
- _setOption: function( key, value ) {
12622
- if ( key === "max" ) {
12623
- // Don't allow a max less than min
12624
- value = Math.max( this.min, value );
12625
- }
12626
-
12627
- this._super( key, value );
12628
- },
12629
-
12630
- _percentage: function() {
12631
- return this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );
12632
- },
12633
-
12634
- _refreshValue: function() {
12635
- var value = this.options.value,
12636
- percentage = this._percentage();
12637
-
12638
- this.valueDiv
12639
- .toggle( this.indeterminate || value > this.min )
12640
- .toggleClass( "ui-corner-right", value === this.options.max )
12641
- .width( percentage.toFixed(0) + "%" );
12642
-
12643
- this.element.toggleClass( "ui-progressbar-indeterminate", this.indeterminate );
12644
-
12645
- if ( this.indeterminate ) {
12646
- this.element.removeAttr( "aria-valuenow" );
12647
- if ( !this.overlayDiv ) {
12648
- this.overlayDiv = $( "<div class='ui-progressbar-overlay'></div>" ).appendTo( this.valueDiv );
12649
- }
12650
- } else {
12651
- this.element.attr({
12652
- "aria-valuemax": this.options.max,
12653
- "aria-valuenow": value
12654
- });
12655
- if ( this.overlayDiv ) {
12656
- this.overlayDiv.remove();
12657
- this.overlayDiv = null;
12658
- }
12659
- }
12660
-
12661
- if ( this.oldValue !== value ) {
12662
- this.oldValue = value;
12663
- this._trigger( "change" );
12664
- }
12665
- if ( value === this.options.max ) {
12666
- this._trigger( "complete" );
12667
- }
12668
- }
12669
- });
12670
-
12671
- })( jQuery );
12672
-
12673
- (function( $, undefined ) {
12674
-
12675
- // number of pages in a slider
12676
- // (how many times can you page up/down to go through the whole range)
12677
- var numPages = 5;
12678
-
12679
- $.widget( "ui.slider", $.ui.mouse, {
12680
- version: "1.10.4",
12681
- widgetEventPrefix: "slide",
12682
-
12683
- options: {
12684
- animate: false,
12685
- distance: 0,
12686
- max: 100,
12687
- min: 0,
12688
- orientation: "horizontal",
12689
- range: false,
12690
- step: 1,
12691
- value: 0,
12692
- values: null,
12693
-
12694
- // callbacks
12695
- change: null,
12696
- slide: null,
12697
- start: null,
12698
- stop: null
12699
- },
12700
-
12701
- _create: function() {
12702
- this._keySliding = false;
12703
- this._mouseSliding = false;
12704
- this._animateOff = true;
12705
- this._handleIndex = null;
12706
- this._detectOrientation();
12707
- this._mouseInit();
12708
-
12709
- this.element
12710
- .addClass( "ui-slider" +
12711
- " ui-slider-" + this.orientation +
12712
- " ui-widget" +
12713
- " ui-widget-content" +
12714
- " ui-corner-all");
12715
-
12716
- this._refresh();
12717
- this._setOption( "disabled", this.options.disabled );
12718
-
12719
- this._animateOff = false;
12720
- },
12721
-
12722
- _refresh: function() {
12723
- this._createRange();
12724
- this._createHandles();
12725
- this._setupEvents();
12726
- this._refreshValue();
12727
- },
12728
-
12729
- _createHandles: function() {
12730
- var i, handleCount,
12731
- options = this.options,
12732
- existingHandles = this.element.find( ".ui-slider-handle" ).addClass( "ui-state-default ui-corner-all" ),
12733
- handle = "<a class='ui-slider-handle ui-state-default ui-corner-all' href='#'></a>",
12734
- handles = [];
12735
-
12736
- handleCount = ( options.values && options.values.length ) || 1;
12737
-
12738
- if ( existingHandles.length > handleCount ) {
12739
- existingHandles.slice( handleCount ).remove();
12740
- existingHandles = existingHandles.slice( 0, handleCount );
12741
- }
12742
-
12743
- for ( i = existingHandles.length; i < handleCount; i++ ) {
12744
- handles.push( handle );
12745
- }
12746
-
12747
- this.handles = existingHandles.add( $( handles.join( "" ) ).appendTo( this.element ) );
12748
-
12749
- this.handle = this.handles.eq( 0 );
12750
-
12751
- this.handles.each(function( i ) {
12752
- $( this ).data( "ui-slider-handle-index", i );
12753
- });
12754
- },
12755
-
12756
- _createRange: function() {
12757
- var options = this.options,
12758
- classes = "";
12759
-
12760
- if ( options.range ) {
12761
- if ( options.range === true ) {
12762
- if ( !options.values ) {
12763
- options.values = [ this._valueMin(), this._valueMin() ];
12764
- } else if ( options.values.length && options.values.length !== 2 ) {
12765
- options.values = [ options.values[0], options.values[0] ];
12766
- } else if ( $.isArray( options.values ) ) {
12767
- options.values = options.values.slice(0);
12768
- }
12769
- }
12770
-
12771
- if ( !this.range || !this.range.length ) {
12772
- this.range = $( "<div></div>" )
12773
- .appendTo( this.element );
12774
-
12775
- classes = "ui-slider-range" +
12776
- // note: this isn't the most fittingly semantic framework class for this element,
12777
- // but worked best visually with a variety of themes
12778
- " ui-widget-header ui-corner-all";
12779
- } else {
12780
- this.range.removeClass( "ui-slider-range-min ui-slider-range-max" )
12781
- // Handle range switching from true to min/max
12782
- .css({
12783
- "left": "",
12784
- "bottom": ""
12785
- });
12786
- }
12787
-
12788
- this.range.addClass( classes +
12789
- ( ( options.range === "min" || options.range === "max" ) ? " ui-slider-range-" + options.range : "" ) );
12790
- } else {
12791
- if ( this.range ) {
12792
- this.range.remove();
12793
- }
12794
- this.range = null;
12795
- }
12796
- },
12797
-
12798
- _setupEvents: function() {
12799
- var elements = this.handles.add( this.range ).filter( "a" );
12800
- this._off( elements );
12801
- this._on( elements, this._handleEvents );
12802
- this._hoverable( elements );
12803
- this._focusable( elements );
12804
- },
12805
-
12806
- _destroy: function() {
12807
- this.handles.remove();
12808
- if ( this.range ) {
12809
- this.range.remove();
12810
- }
12811
-
12812
- this.element
12813
- .removeClass( "ui-slider" +
12814
- " ui-slider-horizontal" +
12815
- " ui-slider-vertical" +
12816
- " ui-widget" +
12817
- " ui-widget-content" +
12818
- " ui-corner-all" );
12819
-
12820
- this._mouseDestroy();
12821
- },
12822
-
12823
- _mouseCapture: function( event ) {
12824
- var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
12825
- that = this,
12826
- o = this.options;
12827
-
12828
- if ( o.disabled ) {
12829
- return false;
12830
- }
12831
-
12832
- this.elementSize = {
12833
- width: this.element.outerWidth(),
12834
- height: this.element.outerHeight()
12835
- };
12836
- this.elementOffset = this.element.offset();
12837
-
12838
- position = { x: event.pageX, y: event.pageY };
12839
- normValue = this._normValueFromMouse( position );
12840
- distance = this._valueMax() - this._valueMin() + 1;
12841
- this.handles.each(function( i ) {
12842
- var thisDistance = Math.abs( normValue - that.values(i) );
12843
- if (( distance > thisDistance ) ||
12844
- ( distance === thisDistance &&
12845
- (i === that._lastChangedValue || that.values(i) === o.min ))) {
12846
- distance = thisDistance;
12847
- closestHandle = $( this );
12848
- index = i;
12849
- }
12850
- });
12851
-
12852
- allowed = this._start( event, index );
12853
- if ( allowed === false ) {
12854
- return false;
12855
- }
12856
- this._mouseSliding = true;
12857
-
12858
- this._handleIndex = index;
12859
-
12860
- closestHandle
12861
- .addClass( "ui-state-active" )
12862
- .focus();
12863
-
12864
- offset = closestHandle.offset();
12865
- mouseOverHandle = !$( event.target ).parents().addBack().is( ".ui-slider-handle" );
12866
- this._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {
12867
- left: event.pageX - offset.left - ( closestHandle.width() / 2 ),
12868
- top: event.pageY - offset.top -
12869
- ( closestHandle.height() / 2 ) -
12870
- ( parseInt( closestHandle.css("borderTopWidth"), 10 ) || 0 ) -
12871
- ( parseInt( closestHandle.css("borderBottomWidth"), 10 ) || 0) +
12872
- ( parseInt( closestHandle.css("marginTop"), 10 ) || 0)
12873
- };
12874
-
12875
- if ( !this.handles.hasClass( "ui-state-hover" ) ) {
12876
- this._slide( event, index, normValue );
12877
- }
12878
- this._animateOff = true;
12879
- return true;
12880
- },
12881
-
12882
- _mouseStart: function() {
12883
- return true;
12884
- },
12885
-
12886
- _mouseDrag: function( event ) {
12887
- var position = { x: event.pageX, y: event.pageY },
12888
- normValue = this._normValueFromMouse( position );
12889
-
12890
- this._slide( event, this._handleIndex, normValue );
12891
-
12892
- return false;
12893
- },
12894
-
12895
- _mouseStop: function( event ) {
12896
- this.handles.removeClass( "ui-state-active" );
12897
- this._mouseSliding = false;
12898
-
12899
- this._stop( event, this._handleIndex );
12900
- this._change( event, this._handleIndex );
12901
-
12902
- this._handleIndex = null;
12903
- this._clickOffset = null;
12904
- this._animateOff = false;
12905
-
12906
- return false;
12907
- },
12908
-
12909
- _detectOrientation: function() {
12910
- this.orientation = ( this.options.orientation === "vertical" ) ? "vertical" : "horizontal";
12911
- },
12912
-
12913
- _normValueFromMouse: function( position ) {
12914
- var pixelTotal,
12915
- pixelMouse,
12916
- percentMouse,
12917
- valueTotal,
12918
- valueMouse;
12919
-
12920
- if ( this.orientation === "horizontal" ) {
12921
- pixelTotal = this.elementSize.width;
12922
- pixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );
12923
- } else {
12924
- pixelTotal = this.elementSize.height;
12925
- pixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );
12926
- }
12927
-
12928
- percentMouse = ( pixelMouse / pixelTotal );
12929
- if ( percentMouse > 1 ) {
12930
- percentMouse = 1;
12931
- }
12932
- if ( percentMouse < 0 ) {
12933
- percentMouse = 0;
12934
- }
12935
- if ( this.orientation === "vertical" ) {
12936
- percentMouse = 1 - percentMouse;
12937
- }
12938
-
12939
- valueTotal = this._valueMax() - this._valueMin();
12940
- valueMouse = this._valueMin() + percentMouse * valueTotal;
12941
-
12942
- return this._trimAlignValue( valueMouse );
12943
- },
12944
-
12945
- _start: function( event, index ) {
12946
- var uiHash = {
12947
- handle: this.handles[ index ],
12948
- value: this.value()
12949
- };
12950
- if ( this.options.values && this.options.values.length ) {
12951
- uiHash.value = this.values( index );
12952
- uiHash.values = this.values();
12953
- }
12954
- return this._trigger( "start", event, uiHash );
12955
- },
12956
-
12957
- _slide: function( event, index, newVal ) {
12958
- var otherVal,
12959
- newValues,
12960
- allowed;
12961
-
12962
- if ( this.options.values && this.options.values.length ) {
12963
- otherVal = this.values( index ? 0 : 1 );
12964
-
12965
- if ( ( this.options.values.length === 2 && this.options.range === true ) &&
12966
- ( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )
12967
- ) {
12968
- newVal = otherVal;
12969
- }
12970
-
12971
- if ( newVal !== this.values( index ) ) {
12972
- newValues = this.values();
12973
- newValues[ index ] = newVal;
12974
- // A slide can be canceled by returning false from the slide callback
12975
- allowed = this._trigger( "slide", event, {
12976
- handle: this.handles[ index ],
12977
- value: newVal,
12978
- values: newValues
12979
- } );
12980
- otherVal = this.values( index ? 0 : 1 );
12981
- if ( allowed !== false ) {
12982
- this.values( index, newVal );
12983
- }
12984
- }
12985
- } else {
12986
- if ( newVal !== this.value() ) {
12987
- // A slide can be canceled by returning false from the slide callback
12988
- allowed = this._trigger( "slide", event, {
12989
- handle: this.handles[ index ],
12990
- value: newVal
12991
- } );
12992
- if ( allowed !== false ) {
12993
- this.value( newVal );
12994
- }
12995
- }
12996
- }
12997
- },
12998
-
12999
- _stop: function( event, index ) {
13000
- var uiHash = {
13001
- handle: this.handles[ index ],
13002
- value: this.value()
13003
- };
13004
- if ( this.options.values && this.options.values.length ) {
13005
- uiHash.value = this.values( index );
13006
- uiHash.values = this.values();
13007
- }
13008
-
13009
- this._trigger( "stop", event, uiHash );
13010
- },
13011
-
13012
- _change: function( event, index ) {
13013
- if ( !this._keySliding && !this._mouseSliding ) {
13014
- var uiHash = {
13015
- handle: this.handles[ index ],
13016
- value: this.value()
13017
- };
13018
- if ( this.options.values && this.options.values.length ) {
13019
- uiHash.value = this.values( index );
13020
- uiHash.values = this.values();
13021
- }
13022
-
13023
- //store the last changed value index for reference when handles overlap
13024
- this._lastChangedValue = index;
13025
-
13026
- this._trigger( "change", event, uiHash );
13027
- }
13028
- },
13029
-
13030
- value: function( newValue ) {
13031
- if ( arguments.length ) {
13032
- this.options.value = this._trimAlignValue( newValue );
13033
- this._refreshValue();
13034
- this._change( null, 0 );
13035
- return;
13036
- }
13037
-
13038
- return this._value();
13039
- },
13040
-
13041
- values: function( index, newValue ) {
13042
- var vals,
13043
- newValues,
13044
- i;
13045
-
13046
- if ( arguments.length > 1 ) {
13047
- this.options.values[ index ] = this._trimAlignValue( newValue );
13048
- this._refreshValue();
13049
- this._change( null, index );
13050
- return;
13051
- }
13052
-
13053
- if ( arguments.length ) {
13054
- if ( $.isArray( arguments[ 0 ] ) ) {
13055
- vals = this.options.values;
13056
- newValues = arguments[ 0 ];
13057
- for ( i = 0; i < vals.length; i += 1 ) {
13058
- vals[ i ] = this._trimAlignValue( newValues[ i ] );
13059
- this._change( null, i );
13060
- }
13061
- this._refreshValue();
13062
- } else {
13063
- if ( this.options.values && this.options.values.length ) {
13064
- return this._values( index );
13065
- } else {
13066
- return this.value();
13067
- }
13068
- }
13069
- } else {
13070
- return this._values();
13071
- }
13072
- },
13073
-
13074
- _setOption: function( key, value ) {
13075
- var i,
13076
- valsLength = 0;
13077
-
13078
- if ( key === "range" && this.options.range === true ) {
13079
- if ( value === "min" ) {
13080
- this.options.value = this._values( 0 );
13081
- this.options.values = null;
13082
- } else if ( value === "max" ) {
13083
- this.options.value = this._values( this.options.values.length-1 );
13084
- this.options.values = null;
13085
- }
13086
- }
13087
-
13088
- if ( $.isArray( this.options.values ) ) {
13089
- valsLength = this.options.values.length;
13090
- }
13091
-
13092
- $.Widget.prototype._setOption.apply( this, arguments );
13093
-
13094
- switch ( key ) {
13095
- case "orientation":
13096
- this._detectOrientation();
13097
- this.element
13098
- .removeClass( "ui-slider-horizontal ui-slider-vertical" )
13099
- .addClass( "ui-slider-" + this.orientation );
13100
- this._refreshValue();
13101
- break;
13102
- case "value":
13103
- this._animateOff = true;
13104
- this._refreshValue();
13105
- this._change( null, 0 );
13106
- this._animateOff = false;
13107
- break;
13108
- case "values":
13109
- this._animateOff = true;
13110
- this._refreshValue();
13111
- for ( i = 0; i < valsLength; i += 1 ) {
13112
- this._change( null, i );
13113
- }
13114
- this._animateOff = false;
13115
- break;
13116
- case "min":
13117
- case "max":
13118
- this._animateOff = true;
13119
- this._refreshValue();
13120
- this._animateOff = false;
13121
- break;
13122
- case "range":
13123
- this._animateOff = true;
13124
- this._refresh();
13125
- this._animateOff = false;
13126
- break;
13127
- }
13128
- },
13129
-
13130
- //internal value getter
13131
- // _value() returns value trimmed by min and max, aligned by step
13132
- _value: function() {
13133
- var val = this.options.value;
13134
- val = this._trimAlignValue( val );
13135
-
13136
- return val;
13137
- },
13138
-
13139
- //internal values getter
13140
- // _values() returns array of values trimmed by min and max, aligned by step
13141
- // _values( index ) returns single value trimmed by min and max, aligned by step
13142
- _values: function( index ) {
13143
- var val,
13144
- vals,
13145
- i;
13146
-
13147
- if ( arguments.length ) {
13148
- val = this.options.values[ index ];
13149
- val = this._trimAlignValue( val );
13150
-
13151
- return val;
13152
- } else if ( this.options.values && this.options.values.length ) {
13153
- // .slice() creates a copy of the array
13154
- // this copy gets trimmed by min and max and then returned
13155
- vals = this.options.values.slice();
13156
- for ( i = 0; i < vals.length; i+= 1) {
13157
- vals[ i ] = this._trimAlignValue( vals[ i ] );
13158
- }
13159
-
13160
- return vals;
13161
- } else {
13162
- return [];
13163
- }
13164
- },
13165
-
13166
- // returns the step-aligned value that val is closest to, between (inclusive) min and max
13167
- _trimAlignValue: function( val ) {
13168
- if ( val <= this._valueMin() ) {
13169
- return this._valueMin();
13170
- }
13171
- if ( val >= this._valueMax() ) {
13172
- return this._valueMax();
13173
- }
13174
- var step = ( this.options.step > 0 ) ? this.options.step : 1,
13175
- valModStep = (val - this._valueMin()) % step,
13176
- alignValue = val - valModStep;
13177
-
13178
- if ( Math.abs(valModStep) * 2 >= step ) {
13179
- alignValue += ( valModStep > 0 ) ? step : ( -step );
13180
- }
13181
-
13182
- // Since JavaScript has problems with large floats, round
13183
- // the final value to 5 digits after the decimal point (see #4124)
13184
- return parseFloat( alignValue.toFixed(5) );
13185
- },
13186
-
13187
- _valueMin: function() {
13188
- return this.options.min;
13189
- },
13190
-
13191
- _valueMax: function() {
13192
- return this.options.max;
13193
- },
13194
-
13195
- _refreshValue: function() {
13196
- var lastValPercent, valPercent, value, valueMin, valueMax,
13197
- oRange = this.options.range,
13198
- o = this.options,
13199
- that = this,
13200
- animate = ( !this._animateOff ) ? o.animate : false,
13201
- _set = {};
13202
-
13203
- if ( this.options.values && this.options.values.length ) {
13204
- this.handles.each(function( i ) {
13205
- valPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;
13206
- _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13207
- $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13208
- if ( that.options.range === true ) {
13209
- if ( that.orientation === "horizontal" ) {
13210
- if ( i === 0 ) {
13211
- that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate );
13212
- }
13213
- if ( i === 1 ) {
13214
- that.range[ animate ? "animate" : "css" ]( { width: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13215
- }
13216
- } else {
13217
- if ( i === 0 ) {
13218
- that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate );
13219
- }
13220
- if ( i === 1 ) {
13221
- that.range[ animate ? "animate" : "css" ]( { height: ( valPercent - lastValPercent ) + "%" }, { queue: false, duration: o.animate } );
13222
- }
13223
- }
13224
- }
13225
- lastValPercent = valPercent;
13226
- });
13227
- } else {
13228
- value = this.value();
13229
- valueMin = this._valueMin();
13230
- valueMax = this._valueMax();
13231
- valPercent = ( valueMax !== valueMin ) ?
13232
- ( value - valueMin ) / ( valueMax - valueMin ) * 100 :
13233
- 0;
13234
- _set[ this.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%";
13235
- this.handle.stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate );
13236
-
13237
- if ( oRange === "min" && this.orientation === "horizontal" ) {
13238
- this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { width: valPercent + "%" }, o.animate );
13239
- }
13240
- if ( oRange === "max" && this.orientation === "horizontal" ) {
13241
- this.range[ animate ? "animate" : "css" ]( { width: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13242
- }
13243
- if ( oRange === "min" && this.orientation === "vertical" ) {
13244
- this.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { height: valPercent + "%" }, o.animate );
13245
- }
13246
- if ( oRange === "max" && this.orientation === "vertical" ) {
13247
- this.range[ animate ? "animate" : "css" ]( { height: ( 100 - valPercent ) + "%" }, { queue: false, duration: o.animate } );
13248
- }
13249
- }
13250
- },
13251
-
13252
- _handleEvents: {
13253
- keydown: function( event ) {
13254
- var allowed, curVal, newVal, step,
13255
- index = $( event.target ).data( "ui-slider-handle-index" );
13256
-
13257
- switch ( event.keyCode ) {
13258
- case $.ui.keyCode.HOME:
13259
- case $.ui.keyCode.END:
13260
- case $.ui.keyCode.PAGE_UP:
13261
- case $.ui.keyCode.PAGE_DOWN:
13262
- case $.ui.keyCode.UP:
13263
- case $.ui.keyCode.RIGHT:
13264
- case $.ui.keyCode.DOWN:
13265
- case $.ui.keyCode.LEFT:
13266
- event.preventDefault();
13267
- if ( !this._keySliding ) {
13268
- this._keySliding = true;
13269
- $( event.target ).addClass( "ui-state-active" );
13270
- allowed = this._start( event, index );
13271
- if ( allowed === false ) {
13272
- return;
13273
- }
13274
- }
13275
- break;
13276
- }
13277
-
13278
- step = this.options.step;
13279
- if ( this.options.values && this.options.values.length ) {
13280
- curVal = newVal = this.values( index );
13281
- } else {
13282
- curVal = newVal = this.value();
13283
- }
13284
-
13285
- switch ( event.keyCode ) {
13286
- case $.ui.keyCode.HOME:
13287
- newVal = this._valueMin();
13288
- break;
13289
- case $.ui.keyCode.END:
13290
- newVal = this._valueMax();
13291
- break;
13292
- case $.ui.keyCode.PAGE_UP:
13293
- newVal = this._trimAlignValue( curVal + ( (this._valueMax() - this._valueMin()) / numPages ) );
13294
- break;
13295
- case $.ui.keyCode.PAGE_DOWN:
13296
- newVal = this._trimAlignValue( curVal - ( (this._valueMax() - this._valueMin()) / numPages ) );
13297
- break;
13298
- case $.ui.keyCode.UP:
13299
- case $.ui.keyCode.RIGHT:
13300
- if ( curVal === this._valueMax() ) {
13301
- return;
13302
- }
13303
- newVal = this._trimAlignValue( curVal + step );
13304
- break;
13305
- case $.ui.keyCode.DOWN:
13306
- case $.ui.keyCode.LEFT:
13307
- if ( curVal === this._valueMin() ) {
13308
- return;
13309
- }
13310
- newVal = this._trimAlignValue( curVal - step );
13311
- break;
13312
- }
13313
-
13314
- this._slide( event, index, newVal );
13315
- },
13316
- click: function( event ) {
13317
- event.preventDefault();
13318
- },
13319
- keyup: function( event ) {
13320
- var index = $( event.target ).data( "ui-slider-handle-index" );
13321
-
13322
- if ( this._keySliding ) {
13323
- this._keySliding = false;
13324
- this._stop( event, index );
13325
- this._change( event, index );
13326
- $( event.target ).removeClass( "ui-state-active" );
13327
- }
13328
- }
13329
- }
13330
-
13331
- });
13332
-
13333
- }(jQuery));
13334
-
13335
- (function( $ ) {
13336
-
13337
- function modifier( fn ) {
13338
- return function() {
13339
- var previous = this.element.val();
13340
- fn.apply( this, arguments );
13341
- this._refresh();
13342
- if ( previous !== this.element.val() ) {
13343
- this._trigger( "change" );
13344
- }
13345
- };
13346
- }
13347
-
13348
- $.widget( "ui.spinner", {
13349
- version: "1.10.4",
13350
- defaultElement: "<input>",
13351
- widgetEventPrefix: "spin",
13352
- options: {
13353
- culture: null,
13354
- icons: {
13355
- down: "ui-icon-triangle-1-s",
13356
- up: "ui-icon-triangle-1-n"
13357
- },
13358
- incremental: true,
13359
- max: null,
13360
- min: null,
13361
- numberFormat: null,
13362
- page: 10,
13363
- step: 1,
13364
-
13365
- change: null,
13366
- spin: null,
13367
- start: null,
13368
- stop: null
13369
- },
13370
-
13371
- _create: function() {
13372
- // handle string values that need to be parsed
13373
- this._setOption( "max", this.options.max );
13374
- this._setOption( "min", this.options.min );
13375
- this._setOption( "step", this.options.step );
13376
-
13377
- // Only format if there is a value, prevents the field from being marked
13378
- // as invalid in Firefox, see #9573.
13379
- if ( this.value() !== "" ) {
13380
- // Format the value, but don't constrain.
13381
- this._value( this.element.val(), true );
13382
- }
13383
-
13384
- this._draw();
13385
- this._on( this._events );
13386
- this._refresh();
13387
-
13388
- // turning off autocomplete prevents the browser from remembering the
13389
- // value when navigating through history, so we re-enable autocomplete
13390
- // if the page is unloaded before the widget is destroyed. #7790
13391
- this._on( this.window, {
13392
- beforeunload: function() {
13393
- this.element.removeAttr( "autocomplete" );
13394
- }
13395
- });
13396
- },
13397
-
13398
- _getCreateOptions: function() {
13399
- var options = {},
13400
- element = this.element;
13401
-
13402
- $.each( [ "min", "max", "step" ], function( i, option ) {
13403
- var value = element.attr( option );
13404
- if ( value !== undefined && value.length ) {
13405
- options[ option ] = value;
13406
- }
13407
- });
13408
-
13409
- return options;
13410
- },
13411
-
13412
- _events: {
13413
- keydown: function( event ) {
13414
- if ( this._start( event ) && this._keydown( event ) ) {
13415
- event.preventDefault();
13416
- }
13417
- },
13418
- keyup: "_stop",
13419
- focus: function() {
13420
- this.previous = this.element.val();
13421
- },
13422
- blur: function( event ) {
13423
- if ( this.cancelBlur ) {
13424
- delete this.cancelBlur;
13425
- return;
13426
- }
13427
-
13428
- this._stop();
13429
- this._refresh();
13430
- if ( this.previous !== this.element.val() ) {
13431
- this._trigger( "change", event );
13432
- }
13433
- },
13434
- mousewheel: function( event, delta ) {
13435
- if ( !delta ) {
13436
- return;
13437
- }
13438
- if ( !this.spinning && !this._start( event ) ) {
13439
- return false;
13440
- }
13441
-
13442
- this._spin( (delta > 0 ? 1 : -1) * this.options.step, event );
13443
- clearTimeout( this.mousewheelTimer );
13444
- this.mousewheelTimer = this._delay(function() {
13445
- if ( this.spinning ) {
13446
- this._stop( event );
13447
- }
13448
- }, 100 );
13449
- event.preventDefault();
13450
- },
13451
- "mousedown .ui-spinner-button": function( event ) {
13452
- var previous;
13453
-
13454
- // We never want the buttons to have focus; whenever the user is
13455
- // interacting with the spinner, the focus should be on the input.
13456
- // If the input is focused then this.previous is properly set from
13457
- // when the input first received focus. If the input is not focused
13458
- // then we need to set this.previous based on the value before spinning.
13459
- previous = this.element[0] === this.document[0].activeElement ?
13460
- this.previous : this.element.val();
13461
- function checkFocus() {
13462
- var isActive = this.element[0] === this.document[0].activeElement;
13463
- if ( !isActive ) {
13464
- this.element.focus();
13465
- this.previous = previous;
13466
- // support: IE
13467
- // IE sets focus asynchronously, so we need to check if focus
13468
- // moved off of the input because the user clicked on the button.
13469
- this._delay(function() {
13470
- this.previous = previous;
13471
- });
13472
- }
13473
- }
13474
-
13475
- // ensure focus is on (or stays on) the text field
13476
- event.preventDefault();
13477
- checkFocus.call( this );
13478
-
13479
- // support: IE
13480
- // IE doesn't prevent moving focus even with event.preventDefault()
13481
- // so we set a flag to know when we should ignore the blur event
13482
- // and check (again) if focus moved off of the input.
13483
- this.cancelBlur = true;
13484
- this._delay(function() {
13485
- delete this.cancelBlur;
13486
- checkFocus.call( this );
13487
- });
13488
-
13489
- if ( this._start( event ) === false ) {
13490
- return;
13491
- }
13492
-
13493
- this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13494
- },
13495
- "mouseup .ui-spinner-button": "_stop",
13496
- "mouseenter .ui-spinner-button": function( event ) {
13497
- // button will add ui-state-active if mouse was down while mouseleave and kept down
13498
- if ( !$( event.currentTarget ).hasClass( "ui-state-active" ) ) {
13499
- return;
13500
- }
13501
-
13502
- if ( this._start( event ) === false ) {
13503
- return false;
13504
- }
13505
- this._repeat( null, $( event.currentTarget ).hasClass( "ui-spinner-up" ) ? 1 : -1, event );
13506
- },
13507
- // TODO: do we really want to consider this a stop?
13508
- // shouldn't we just stop the repeater and wait until mouseup before
13509
- // we trigger the stop event?
13510
- "mouseleave .ui-spinner-button": "_stop"
13511
- },
13512
-
13513
- _draw: function() {
13514
- var uiSpinner = this.uiSpinner = this.element
13515
- .addClass( "ui-spinner-input" )
13516
- .attr( "autocomplete", "off" )
13517
- .wrap( this._uiSpinnerHtml() )
13518
- .parent()
13519
- // add buttons
13520
- .append( this._buttonHtml() );
13521
-
13522
- this.element.attr( "role", "spinbutton" );
13523
-
13524
- // button bindings
13525
- this.buttons = uiSpinner.find( ".ui-spinner-button" )
13526
- .attr( "tabIndex", -1 )
13527
- .button()
13528
- .removeClass( "ui-corner-all" );
13529
-
13530
- // IE 6 doesn't understand height: 50% for the buttons
13531
- // unless the wrapper has an explicit height
13532
- if ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&
13533
- uiSpinner.height() > 0 ) {
13534
- uiSpinner.height( uiSpinner.height() );
13535
- }
13536
-
13537
- // disable spinner if element was already disabled
13538
- if ( this.options.disabled ) {
13539
- this.disable();
13540
- }
13541
- },
13542
-
13543
- _keydown: function( event ) {
13544
- var options = this.options,
13545
- keyCode = $.ui.keyCode;
13546
-
13547
- switch ( event.keyCode ) {
13548
- case keyCode.UP:
13549
- this._repeat( null, 1, event );
13550
- return true;
13551
- case keyCode.DOWN:
13552
- this._repeat( null, -1, event );
13553
- return true;
13554
- case keyCode.PAGE_UP:
13555
- this._repeat( null, options.page, event );
13556
- return true;
13557
- case keyCode.PAGE_DOWN:
13558
- this._repeat( null, -options.page, event );
13559
- return true;
13560
- }
13561
-
13562
- return false;
13563
- },
13564
-
13565
- _uiSpinnerHtml: function() {
13566
- return "<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>";
13567
- },
13568
-
13569
- _buttonHtml: function() {
13570
- return "" +
13571
- "<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>" +
13572
- "<span class='ui-icon " + this.options.icons.up + "'>&#9650;</span>" +
13573
- "</a>" +
13574
- "<a class='ui-spinner-button ui-spinner-down ui-corner-br'>" +
13575
- "<span class='ui-icon " + this.options.icons.down + "'>&#9660;</span>" +
13576
- "</a>";
13577
- },
13578
-
13579
- _start: function( event ) {
13580
- if ( !this.spinning && this._trigger( "start", event ) === false ) {
13581
- return false;
13582
- }
13583
-
13584
- if ( !this.counter ) {
13585
- this.counter = 1;
13586
- }
13587
- this.spinning = true;
13588
- return true;
13589
- },
13590
-
13591
- _repeat: function( i, steps, event ) {
13592
- i = i || 500;
13593
-
13594
- clearTimeout( this.timer );
13595
- this.timer = this._delay(function() {
13596
- this._repeat( 40, steps, event );
13597
- }, i );
13598
-
13599
- this._spin( steps * this.options.step, event );
13600
- },
13601
-
13602
- _spin: function( step, event ) {
13603
- var value = this.value() || 0;
13604
-
13605
- if ( !this.counter ) {
13606
- this.counter = 1;
13607
- }
13608
-
13609
- value = this._adjustValue( value + step * this._increment( this.counter ) );
13610
-
13611
- if ( !this.spinning || this._trigger( "spin", event, { value: value } ) !== false) {
13612
- this._value( value );
13613
- this.counter++;
13614
- }
13615
- },
13616
-
13617
- _increment: function( i ) {
13618
- var incremental = this.options.incremental;
13619
-
13620
- if ( incremental ) {
13621
- return $.isFunction( incremental ) ?
13622
- incremental( i ) :
13623
- Math.floor( i*i*i/50000 - i*i/500 + 17*i/200 + 1 );
13624
- }
13625
-
13626
- return 1;
13627
- },
13628
-
13629
- _precision: function() {
13630
- var precision = this._precisionOf( this.options.step );
13631
- if ( this.options.min !== null ) {
13632
- precision = Math.max( precision, this._precisionOf( this.options.min ) );
13633
- }
13634
- return precision;
13635
- },
13636
-
13637
- _precisionOf: function( num ) {
13638
- var str = num.toString(),
13639
- decimal = str.indexOf( "." );
13640
- return decimal === -1 ? 0 : str.length - decimal - 1;
13641
- },
13642
-
13643
- _adjustValue: function( value ) {
13644
- var base, aboveMin,
13645
- options = this.options;
13646
-
13647
- // make sure we're at a valid step
13648
- // - find out where we are relative to the base (min or 0)
13649
- base = options.min !== null ? options.min : 0;
13650
- aboveMin = value - base;
13651
- // - round to the nearest step
13652
- aboveMin = Math.round(aboveMin / options.step) * options.step;
13653
- // - rounding is based on 0, so adjust back to our base
13654
- value = base + aboveMin;
13655
-
13656
- // fix precision from bad JS floating point math
13657
- value = parseFloat( value.toFixed( this._precision() ) );
13658
-
13659
- // clamp the value
13660
- if ( options.max !== null && value > options.max) {
13661
- return options.max;
13662
- }
13663
- if ( options.min !== null && value < options.min ) {
13664
- return options.min;
13665
- }
13666
-
13667
- return value;
13668
- },
13669
-
13670
- _stop: function( event ) {
13671
- if ( !this.spinning ) {
13672
- return;
13673
- }
13674
-
13675
- clearTimeout( this.timer );
13676
- clearTimeout( this.mousewheelTimer );
13677
- this.counter = 0;
13678
- this.spinning = false;
13679
- this._trigger( "stop", event );
13680
- },
13681
-
13682
- _setOption: function( key, value ) {
13683
- if ( key === "culture" || key === "numberFormat" ) {
13684
- var prevValue = this._parse( this.element.val() );
13685
- this.options[ key ] = value;
13686
- this.element.val( this._format( prevValue ) );
13687
- return;
13688
- }
13689
-
13690
- if ( key === "max" || key === "min" || key === "step" ) {
13691
- if ( typeof value === "string" ) {
13692
- value = this._parse( value );
13693
- }
13694
- }
13695
- if ( key === "icons" ) {
13696
- this.buttons.first().find( ".ui-icon" )
13697
- .removeClass( this.options.icons.up )
13698
- .addClass( value.up );
13699
- this.buttons.last().find( ".ui-icon" )
13700
- .removeClass( this.options.icons.down )
13701
- .addClass( value.down );
13702
- }
13703
-
13704
- this._super( key, value );
13705
-
13706
- if ( key === "disabled" ) {
13707
- if ( value ) {
13708
- this.element.prop( "disabled", true );
13709
- this.buttons.button( "disable" );
13710
- } else {
13711
- this.element.prop( "disabled", false );
13712
- this.buttons.button( "enable" );
13713
- }
13714
- }
13715
- },
13716
-
13717
- _setOptions: modifier(function( options ) {
13718
- this._super( options );
13719
- this._value( this.element.val() );
13720
- }),
13721
-
13722
- _parse: function( val ) {
13723
- if ( typeof val === "string" && val !== "" ) {
13724
- val = window.Globalize && this.options.numberFormat ?
13725
- Globalize.parseFloat( val, 10, this.options.culture ) : +val;
13726
- }
13727
- return val === "" || isNaN( val ) ? null : val;
13728
- },
13729
-
13730
- _format: function( value ) {
13731
- if ( value === "" ) {
13732
- return "";
13733
- }
13734
- return window.Globalize && this.options.numberFormat ?
13735
- Globalize.format( value, this.options.numberFormat, this.options.culture ) :
13736
- value;
13737
- },
13738
-
13739
- _refresh: function() {
13740
- this.element.attr({
13741
- "aria-valuemin": this.options.min,
13742
- "aria-valuemax": this.options.max,
13743
- // TODO: what should we do with values that can't be parsed?
13744
- "aria-valuenow": this._parse( this.element.val() )
13745
- });
13746
- },
13747
-
13748
- // update the value without triggering change
13749
- _value: function( value, allowAny ) {
13750
- var parsed;
13751
- if ( value !== "" ) {
13752
- parsed = this._parse( value );
13753
- if ( parsed !== null ) {
13754
- if ( !allowAny ) {
13755
- parsed = this._adjustValue( parsed );
13756
- }
13757
- value = this._format( parsed );
13758
- }
13759
- }
13760
- this.element.val( value );
13761
- this._refresh();
13762
- },
13763
-
13764
- _destroy: function() {
13765
- this.element
13766
- .removeClass( "ui-spinner-input" )
13767
- .prop( "disabled", false )
13768
- .removeAttr( "autocomplete" )
13769
- .removeAttr( "role" )
13770
- .removeAttr( "aria-valuemin" )
13771
- .removeAttr( "aria-valuemax" )
13772
- .removeAttr( "aria-valuenow" );
13773
- this.uiSpinner.replaceWith( this.element );
13774
- },
13775
-
13776
- stepUp: modifier(function( steps ) {
13777
- this._stepUp( steps );
13778
- }),
13779
- _stepUp: function( steps ) {
13780
- if ( this._start() ) {
13781
- this._spin( (steps || 1) * this.options.step );
13782
- this._stop();
13783
- }
13784
- },
13785
-
13786
- stepDown: modifier(function( steps ) {
13787
- this._stepDown( steps );
13788
- }),
13789
- _stepDown: function( steps ) {
13790
- if ( this._start() ) {
13791
- this._spin( (steps || 1) * -this.options.step );
13792
- this._stop();
13793
- }
13794
- },
13795
-
13796
- pageUp: modifier(function( pages ) {
13797
- this._stepUp( (pages || 1) * this.options.page );
13798
- }),
13799
-
13800
- pageDown: modifier(function( pages ) {
13801
- this._stepDown( (pages || 1) * this.options.page );
13802
- }),
13803
-
13804
- value: function( newVal ) {
13805
- if ( !arguments.length ) {
13806
- return this._parse( this.element.val() );
13807
- }
13808
- modifier( this._value ).call( this, newVal );
13809
- },
13810
-
13811
- widget: function() {
13812
- return this.uiSpinner;
13813
- }
13814
- });
13815
-
13816
- }( jQuery ) );
13817
-
13818
- (function( $, undefined ) {
13819
-
13820
- var tabId = 0,
13821
- rhash = /#.*$/;
13822
-
13823
- function getNextTabId() {
13824
- return ++tabId;
13825
- }
13826
-
13827
- function isLocal( anchor ) {
13828
- // support: IE7
13829
- // IE7 doesn't normalize the href property when set via script (#9317)
13830
- anchor = anchor.cloneNode( false );
13831
-
13832
- return anchor.hash.length > 1 &&
13833
- decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
13834
- decodeURIComponent( location.href.replace( rhash, "" ) );
13835
- }
13836
-
13837
- $.widget( "ui.tabs", {
13838
- version: "1.10.4",
13839
- delay: 300,
13840
- options: {
13841
- active: null,
13842
- collapsible: false,
13843
- event: "click",
13844
- heightStyle: "content",
13845
- hide: null,
13846
- show: null,
13847
-
13848
- // callbacks
13849
- activate: null,
13850
- beforeActivate: null,
13851
- beforeLoad: null,
13852
- load: null
13853
- },
13854
-
13855
- _create: function() {
13856
- var that = this,
13857
- options = this.options;
13858
-
13859
- this.running = false;
13860
-
13861
- this.element
13862
- .addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
13863
- .toggleClass( "ui-tabs-collapsible", options.collapsible )
13864
- // Prevent users from focusing disabled tabs via click
13865
- .delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
13866
- if ( $( this ).is( ".ui-state-disabled" ) ) {
13867
- event.preventDefault();
13868
- }
13869
- })
13870
- // support: IE <9
13871
- // Preventing the default action in mousedown doesn't prevent IE
13872
- // from focusing the element, so if the anchor gets focused, blur.
13873
- // We don't have to worry about focusing the previously focused
13874
- // element since clicking on a non-focusable element should focus
13875
- // the body anyway.
13876
- .delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
13877
- if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
13878
- this.blur();
13879
- }
13880
- });
13881
-
13882
- this._processTabs();
13883
- options.active = this._initialActive();
13884
-
13885
- // Take disabling tabs via class attribute from HTML
13886
- // into account and update option properly.
13887
- if ( $.isArray( options.disabled ) ) {
13888
- options.disabled = $.unique( options.disabled.concat(
13889
- $.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
13890
- return that.tabs.index( li );
13891
- })
13892
- ) ).sort();
13893
- }
13894
-
13895
- // check for length avoids error when initializing empty list
13896
- if ( this.options.active !== false && this.anchors.length ) {
13897
- this.active = this._findActive( options.active );
13898
- } else {
13899
- this.active = $();
13900
- }
13901
-
13902
- this._refresh();
13903
-
13904
- if ( this.active.length ) {
13905
- this.load( options.active );
13906
- }
13907
- },
13908
-
13909
- _initialActive: function() {
13910
- var active = this.options.active,
13911
- collapsible = this.options.collapsible,
13912
- locationHash = location.hash.substring( 1 );
13913
-
13914
- if ( active === null ) {
13915
- // check the fragment identifier in the URL
13916
- if ( locationHash ) {
13917
- this.tabs.each(function( i, tab ) {
13918
- if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
13919
- active = i;
13920
- return false;
13921
- }
13922
- });
13923
- }
13924
-
13925
- // check for a tab marked active via a class
13926
- if ( active === null ) {
13927
- active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
13928
- }
13929
-
13930
- // no active tab, set to false
13931
- if ( active === null || active === -1 ) {
13932
- active = this.tabs.length ? 0 : false;
13933
- }
13934
- }
13935
-
13936
- // handle numbers: negative, out of range
13937
- if ( active !== false ) {
13938
- active = this.tabs.index( this.tabs.eq( active ) );
13939
- if ( active === -1 ) {
13940
- active = collapsible ? false : 0;
13941
- }
13942
- }
13943
-
13944
- // don't allow collapsible: false and active: false
13945
- if ( !collapsible && active === false && this.anchors.length ) {
13946
- active = 0;
13947
- }
13948
-
13949
- return active;
13950
- },
13951
-
13952
- _getCreateEventData: function() {
13953
- return {
13954
- tab: this.active,
13955
- panel: !this.active.length ? $() : this._getPanelForTab( this.active )
13956
- };
13957
- },
13958
-
13959
- _tabKeydown: function( event ) {
13960
- var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
13961
- selectedIndex = this.tabs.index( focusedTab ),
13962
- goingForward = true;
13963
-
13964
- if ( this._handlePageNav( event ) ) {
13965
- return;
13966
- }
13967
-
13968
- switch ( event.keyCode ) {
13969
- case $.ui.keyCode.RIGHT:
13970
- case $.ui.keyCode.DOWN:
13971
- selectedIndex++;
13972
- break;
13973
- case $.ui.keyCode.UP:
13974
- case $.ui.keyCode.LEFT:
13975
- goingForward = false;
13976
- selectedIndex--;
13977
- break;
13978
- case $.ui.keyCode.END:
13979
- selectedIndex = this.anchors.length - 1;
13980
- break;
13981
- case $.ui.keyCode.HOME:
13982
- selectedIndex = 0;
13983
- break;
13984
- case $.ui.keyCode.SPACE:
13985
- // Activate only, no collapsing
13986
- event.preventDefault();
13987
- clearTimeout( this.activating );
13988
- this._activate( selectedIndex );
13989
- return;
13990
- case $.ui.keyCode.ENTER:
13991
- // Toggle (cancel delayed activation, allow collapsing)
13992
- event.preventDefault();
13993
- clearTimeout( this.activating );
13994
- // Determine if we should collapse or activate
13995
- this._activate( selectedIndex === this.options.active ? false : selectedIndex );
13996
- return;
13997
- default:
13998
- return;
13999
- }
14000
-
14001
- // Focus the appropriate tab, based on which key was pressed
14002
- event.preventDefault();
14003
- clearTimeout( this.activating );
14004
- selectedIndex = this._focusNextTab( selectedIndex, goingForward );
14005
-
14006
- // Navigating with control key will prevent automatic activation
14007
- if ( !event.ctrlKey ) {
14008
- // Update aria-selected immediately so that AT think the tab is already selected.
14009
- // Otherwise AT may confuse the user by stating that they need to activate the tab,
14010
- // but the tab will already be activated by the time the announcement finishes.
14011
- focusedTab.attr( "aria-selected", "false" );
14012
- this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
14013
-
14014
- this.activating = this._delay(function() {
14015
- this.option( "active", selectedIndex );
14016
- }, this.delay );
14017
- }
14018
- },
14019
-
14020
- _panelKeydown: function( event ) {
14021
- if ( this._handlePageNav( event ) ) {
14022
- return;
14023
- }
14024
-
14025
- // Ctrl+up moves focus to the current tab
14026
- if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
14027
- event.preventDefault();
14028
- this.active.focus();
14029
- }
14030
- },
14031
-
14032
- // Alt+page up/down moves focus to the previous/next tab (and activates)
14033
- _handlePageNav: function( event ) {
14034
- if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
14035
- this._activate( this._focusNextTab( this.options.active - 1, false ) );
14036
- return true;
14037
- }
14038
- if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
14039
- this._activate( this._focusNextTab( this.options.active + 1, true ) );
14040
- return true;
14041
- }
14042
- },
14043
-
14044
- _findNextTab: function( index, goingForward ) {
14045
- var lastTabIndex = this.tabs.length - 1;
14046
-
14047
- function constrain() {
14048
- if ( index > lastTabIndex ) {
14049
- index = 0;
14050
- }
14051
- if ( index < 0 ) {
14052
- index = lastTabIndex;
14053
- }
14054
- return index;
14055
- }
14056
-
14057
- while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
14058
- index = goingForward ? index + 1 : index - 1;
14059
- }
14060
-
14061
- return index;
14062
- },
14063
-
14064
- _focusNextTab: function( index, goingForward ) {
14065
- index = this._findNextTab( index, goingForward );
14066
- this.tabs.eq( index ).focus();
14067
- return index;
14068
- },
14069
-
14070
- _setOption: function( key, value ) {
14071
- if ( key === "active" ) {
14072
- // _activate() will handle invalid values and update this.options
14073
- this._activate( value );
14074
- return;
14075
- }
14076
-
14077
- if ( key === "disabled" ) {
14078
- // don't use the widget factory's disabled handling
14079
- this._setupDisabled( value );
14080
- return;
14081
- }
14082
-
14083
- this._super( key, value);
14084
-
14085
- if ( key === "collapsible" ) {
14086
- this.element.toggleClass( "ui-tabs-collapsible", value );
14087
- // Setting collapsible: false while collapsed; open first panel
14088
- if ( !value && this.options.active === false ) {
14089
- this._activate( 0 );
14090
- }
14091
- }
14092
-
14093
- if ( key === "event" ) {
14094
- this._setupEvents( value );
14095
- }
14096
-
14097
- if ( key === "heightStyle" ) {
14098
- this._setupHeightStyle( value );
14099
- }
14100
- },
14101
-
14102
- _tabId: function( tab ) {
14103
- return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
14104
- },
14105
-
14106
- _sanitizeSelector: function( hash ) {
14107
- return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
14108
- },
14109
-
14110
- refresh: function() {
14111
- var options = this.options,
14112
- lis = this.tablist.children( ":has(a[href])" );
14113
-
14114
- // get disabled tabs from class attribute from HTML
14115
- // this will get converted to a boolean if needed in _refresh()
14116
- options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
14117
- return lis.index( tab );
14118
- });
14119
-
14120
- this._processTabs();
14121
-
14122
- // was collapsed or no tabs
14123
- if ( options.active === false || !this.anchors.length ) {
14124
- options.active = false;
14125
- this.active = $();
14126
- // was active, but active tab is gone
14127
- } else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
14128
- // all remaining tabs are disabled
14129
- if ( this.tabs.length === options.disabled.length ) {
14130
- options.active = false;
14131
- this.active = $();
14132
- // activate previous tab
14133
- } else {
14134
- this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
14135
- }
14136
- // was active, active tab still exists
14137
- } else {
14138
- // make sure active index is correct
14139
- options.active = this.tabs.index( this.active );
14140
- }
14141
-
14142
- this._refresh();
14143
- },
14144
-
14145
- _refresh: function() {
14146
- this._setupDisabled( this.options.disabled );
14147
- this._setupEvents( this.options.event );
14148
- this._setupHeightStyle( this.options.heightStyle );
14149
-
14150
- this.tabs.not( this.active ).attr({
14151
- "aria-selected": "false",
14152
- tabIndex: -1
14153
- });
14154
- this.panels.not( this._getPanelForTab( this.active ) )
14155
- .hide()
14156
- .attr({
14157
- "aria-expanded": "false",
14158
- "aria-hidden": "true"
14159
- });
14160
-
14161
- // Make sure one tab is in the tab order
14162
- if ( !this.active.length ) {
14163
- this.tabs.eq( 0 ).attr( "tabIndex", 0 );
14164
- } else {
14165
- this.active
14166
- .addClass( "ui-tabs-active ui-state-active" )
14167
- .attr({
14168
- "aria-selected": "true",
14169
- tabIndex: 0
14170
- });
14171
- this._getPanelForTab( this.active )
14172
- .show()
14173
- .attr({
14174
- "aria-expanded": "true",
14175
- "aria-hidden": "false"
14176
- });
14177
- }
14178
- },
14179
-
14180
- _processTabs: function() {
14181
- var that = this;
14182
-
14183
- this.tablist = this._getList()
14184
- .addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14185
- .attr( "role", "tablist" );
14186
-
14187
- this.tabs = this.tablist.find( "> li:has(a[href])" )
14188
- .addClass( "ui-state-default ui-corner-top" )
14189
- .attr({
14190
- role: "tab",
14191
- tabIndex: -1
14192
- });
14193
-
14194
- this.anchors = this.tabs.map(function() {
14195
- return $( "a", this )[ 0 ];
14196
- })
14197
- .addClass( "ui-tabs-anchor" )
14198
- .attr({
14199
- role: "presentation",
14200
- tabIndex: -1
14201
- });
14202
-
14203
- this.panels = $();
14204
-
14205
- this.anchors.each(function( i, anchor ) {
14206
- var selector, panel, panelId,
14207
- anchorId = $( anchor ).uniqueId().attr( "id" ),
14208
- tab = $( anchor ).closest( "li" ),
14209
- originalAriaControls = tab.attr( "aria-controls" );
14210
-
14211
- // inline tab
14212
- if ( isLocal( anchor ) ) {
14213
- selector = anchor.hash;
14214
- panel = that.element.find( that._sanitizeSelector( selector ) );
14215
- // remote tab
14216
- } else {
14217
- panelId = that._tabId( tab );
14218
- selector = "#" + panelId;
14219
- panel = that.element.find( selector );
14220
- if ( !panel.length ) {
14221
- panel = that._createPanel( panelId );
14222
- panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
14223
- }
14224
- panel.attr( "aria-live", "polite" );
14225
- }
14226
-
14227
- if ( panel.length) {
14228
- that.panels = that.panels.add( panel );
14229
- }
14230
- if ( originalAriaControls ) {
14231
- tab.data( "ui-tabs-aria-controls", originalAriaControls );
14232
- }
14233
- tab.attr({
14234
- "aria-controls": selector.substring( 1 ),
14235
- "aria-labelledby": anchorId
14236
- });
14237
- panel.attr( "aria-labelledby", anchorId );
14238
- });
14239
-
14240
- this.panels
14241
- .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14242
- .attr( "role", "tabpanel" );
14243
- },
14244
-
14245
- // allow overriding how to find the list for rare usage scenarios (#7715)
14246
- _getList: function() {
14247
- return this.tablist || this.element.find( "ol,ul" ).eq( 0 );
14248
- },
14249
-
14250
- _createPanel: function( id ) {
14251
- return $( "<div>" )
14252
- .attr( "id", id )
14253
- .addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
14254
- .data( "ui-tabs-destroy", true );
14255
- },
14256
-
14257
- _setupDisabled: function( disabled ) {
14258
- if ( $.isArray( disabled ) ) {
14259
- if ( !disabled.length ) {
14260
- disabled = false;
14261
- } else if ( disabled.length === this.anchors.length ) {
14262
- disabled = true;
14263
- }
14264
- }
14265
-
14266
- // disable tabs
14267
- for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
14268
- if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
14269
- $( li )
14270
- .addClass( "ui-state-disabled" )
14271
- .attr( "aria-disabled", "true" );
14272
- } else {
14273
- $( li )
14274
- .removeClass( "ui-state-disabled" )
14275
- .removeAttr( "aria-disabled" );
14276
- }
14277
- }
14278
-
14279
- this.options.disabled = disabled;
14280
- },
14281
-
14282
- _setupEvents: function( event ) {
14283
- var events = {
14284
- click: function( event ) {
14285
- event.preventDefault();
14286
- }
14287
- };
14288
- if ( event ) {
14289
- $.each( event.split(" "), function( index, eventName ) {
14290
- events[ eventName ] = "_eventHandler";
14291
- });
14292
- }
14293
-
14294
- this._off( this.anchors.add( this.tabs ).add( this.panels ) );
14295
- this._on( this.anchors, events );
14296
- this._on( this.tabs, { keydown: "_tabKeydown" } );
14297
- this._on( this.panels, { keydown: "_panelKeydown" } );
14298
-
14299
- this._focusable( this.tabs );
14300
- this._hoverable( this.tabs );
14301
- },
14302
-
14303
- _setupHeightStyle: function( heightStyle ) {
14304
- var maxHeight,
14305
- parent = this.element.parent();
14306
-
14307
- if ( heightStyle === "fill" ) {
14308
- maxHeight = parent.height();
14309
- maxHeight -= this.element.outerHeight() - this.element.height();
14310
-
14311
- this.element.siblings( ":visible" ).each(function() {
14312
- var elem = $( this ),
14313
- position = elem.css( "position" );
14314
-
14315
- if ( position === "absolute" || position === "fixed" ) {
14316
- return;
14317
- }
14318
- maxHeight -= elem.outerHeight( true );
14319
- });
14320
-
14321
- this.element.children().not( this.panels ).each(function() {
14322
- maxHeight -= $( this ).outerHeight( true );
14323
- });
14324
-
14325
- this.panels.each(function() {
14326
- $( this ).height( Math.max( 0, maxHeight -
14327
- $( this ).innerHeight() + $( this ).height() ) );
14328
- })
14329
- .css( "overflow", "auto" );
14330
- } else if ( heightStyle === "auto" ) {
14331
- maxHeight = 0;
14332
- this.panels.each(function() {
14333
- maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
14334
- }).height( maxHeight );
14335
- }
14336
- },
14337
-
14338
- _eventHandler: function( event ) {
14339
- var options = this.options,
14340
- active = this.active,
14341
- anchor = $( event.currentTarget ),
14342
- tab = anchor.closest( "li" ),
14343
- clickedIsActive = tab[ 0 ] === active[ 0 ],
14344
- collapsing = clickedIsActive && options.collapsible,
14345
- toShow = collapsing ? $() : this._getPanelForTab( tab ),
14346
- toHide = !active.length ? $() : this._getPanelForTab( active ),
14347
- eventData = {
14348
- oldTab: active,
14349
- oldPanel: toHide,
14350
- newTab: collapsing ? $() : tab,
14351
- newPanel: toShow
14352
- };
14353
-
14354
- event.preventDefault();
14355
-
14356
- if ( tab.hasClass( "ui-state-disabled" ) ||
14357
- // tab is already loading
14358
- tab.hasClass( "ui-tabs-loading" ) ||
14359
- // can't switch durning an animation
14360
- this.running ||
14361
- // click on active header, but not collapsible
14362
- ( clickedIsActive && !options.collapsible ) ||
14363
- // allow canceling activation
14364
- ( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
14365
- return;
14366
- }
14367
-
14368
- options.active = collapsing ? false : this.tabs.index( tab );
14369
-
14370
- this.active = clickedIsActive ? $() : tab;
14371
- if ( this.xhr ) {
14372
- this.xhr.abort();
14373
- }
14374
-
14375
- if ( !toHide.length && !toShow.length ) {
14376
- $.error( "jQuery UI Tabs: Mismatching fragment identifier." );
14377
- }
14378
-
14379
- if ( toShow.length ) {
14380
- this.load( this.tabs.index( tab ), event );
14381
- }
14382
- this._toggle( event, eventData );
14383
- },
14384
-
14385
- // handles show/hide for selecting tabs
14386
- _toggle: function( event, eventData ) {
14387
- var that = this,
14388
- toShow = eventData.newPanel,
14389
- toHide = eventData.oldPanel;
14390
-
14391
- this.running = true;
14392
-
14393
- function complete() {
14394
- that.running = false;
14395
- that._trigger( "activate", event, eventData );
14396
- }
14397
-
14398
- function show() {
14399
- eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
14400
-
14401
- if ( toShow.length && that.options.show ) {
14402
- that._show( toShow, that.options.show, complete );
14403
- } else {
14404
- toShow.show();
14405
- complete();
14406
- }
14407
- }
14408
-
14409
- // start out by hiding, then showing, then completing
14410
- if ( toHide.length && this.options.hide ) {
14411
- this._hide( toHide, this.options.hide, function() {
14412
- eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14413
- show();
14414
- });
14415
- } else {
14416
- eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
14417
- toHide.hide();
14418
- show();
14419
- }
14420
-
14421
- toHide.attr({
14422
- "aria-expanded": "false",
14423
- "aria-hidden": "true"
14424
- });
14425
- eventData.oldTab.attr( "aria-selected", "false" );
14426
- // If we're switching tabs, remove the old tab from the tab order.
14427
- // If we're opening from collapsed state, remove the previous tab from the tab order.
14428
- // If we're collapsing, then keep the collapsing tab in the tab order.
14429
- if ( toShow.length && toHide.length ) {
14430
- eventData.oldTab.attr( "tabIndex", -1 );
14431
- } else if ( toShow.length ) {
14432
- this.tabs.filter(function() {
14433
- return $( this ).attr( "tabIndex" ) === 0;
14434
- })
14435
- .attr( "tabIndex", -1 );
14436
- }
14437
-
14438
- toShow.attr({
14439
- "aria-expanded": "true",
14440
- "aria-hidden": "false"
14441
- });
14442
- eventData.newTab.attr({
14443
- "aria-selected": "true",
14444
- tabIndex: 0
14445
- });
14446
- },
14447
-
14448
- _activate: function( index ) {
14449
- var anchor,
14450
- active = this._findActive( index );
14451
-
14452
- // trying to activate the already active panel
14453
- if ( active[ 0 ] === this.active[ 0 ] ) {
14454
- return;
14455
- }
14456
-
14457
- // trying to collapse, simulate a click on the current active header
14458
- if ( !active.length ) {
14459
- active = this.active;
14460
- }
14461
-
14462
- anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
14463
- this._eventHandler({
14464
- target: anchor,
14465
- currentTarget: anchor,
14466
- preventDefault: $.noop
14467
- });
14468
- },
14469
-
14470
- _findActive: function( index ) {
14471
- return index === false ? $() : this.tabs.eq( index );
14472
- },
14473
-
14474
- _getIndex: function( index ) {
14475
- // meta-function to give users option to provide a href string instead of a numerical index.
14476
- if ( typeof index === "string" ) {
14477
- index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
14478
- }
14479
-
14480
- return index;
14481
- },
14482
-
14483
- _destroy: function() {
14484
- if ( this.xhr ) {
14485
- this.xhr.abort();
14486
- }
14487
-
14488
- this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
14489
-
14490
- this.tablist
14491
- .removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
14492
- .removeAttr( "role" );
14493
-
14494
- this.anchors
14495
- .removeClass( "ui-tabs-anchor" )
14496
- .removeAttr( "role" )
14497
- .removeAttr( "tabIndex" )
14498
- .removeUniqueId();
14499
-
14500
- this.tabs.add( this.panels ).each(function() {
14501
- if ( $.data( this, "ui-tabs-destroy" ) ) {
14502
- $( this ).remove();
14503
- } else {
14504
- $( this )
14505
- .removeClass( "ui-state-default ui-state-active ui-state-disabled " +
14506
- "ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
14507
- .removeAttr( "tabIndex" )
14508
- .removeAttr( "aria-live" )
14509
- .removeAttr( "aria-busy" )
14510
- .removeAttr( "aria-selected" )
14511
- .removeAttr( "aria-labelledby" )
14512
- .removeAttr( "aria-hidden" )
14513
- .removeAttr( "aria-expanded" )
14514
- .removeAttr( "role" );
14515
- }
14516
- });
14517
-
14518
- this.tabs.each(function() {
14519
- var li = $( this ),
14520
- prev = li.data( "ui-tabs-aria-controls" );
14521
- if ( prev ) {
14522
- li
14523
- .attr( "aria-controls", prev )
14524
- .removeData( "ui-tabs-aria-controls" );
14525
- } else {
14526
- li.removeAttr( "aria-controls" );
14527
- }
14528
- });
14529
-
14530
- this.panels.show();
14531
-
14532
- if ( this.options.heightStyle !== "content" ) {
14533
- this.panels.css( "height", "" );
14534
- }
14535
- },
14536
-
14537
- enable: function( index ) {
14538
- var disabled = this.options.disabled;
14539
- if ( disabled === false ) {
14540
- return;
14541
- }
14542
-
14543
- if ( index === undefined ) {
14544
- disabled = false;
14545
- } else {
14546
- index = this._getIndex( index );
14547
- if ( $.isArray( disabled ) ) {
14548
- disabled = $.map( disabled, function( num ) {
14549
- return num !== index ? num : null;
14550
- });
14551
- } else {
14552
- disabled = $.map( this.tabs, function( li, num ) {
14553
- return num !== index ? num : null;
14554
- });
14555
- }
14556
- }
14557
- this._setupDisabled( disabled );
14558
- },
14559
-
14560
- disable: function( index ) {
14561
- var disabled = this.options.disabled;
14562
- if ( disabled === true ) {
14563
- return;
14564
- }
14565
-
14566
- if ( index === undefined ) {
14567
- disabled = true;
14568
- } else {
14569
- index = this._getIndex( index );
14570
- if ( $.inArray( index, disabled ) !== -1 ) {
14571
- return;
14572
- }
14573
- if ( $.isArray( disabled ) ) {
14574
- disabled = $.merge( [ index ], disabled ).sort();
14575
- } else {
14576
- disabled = [ index ];
14577
- }
14578
- }
14579
- this._setupDisabled( disabled );
14580
- },
14581
-
14582
- load: function( index, event ) {
14583
- index = this._getIndex( index );
14584
- var that = this,
14585
- tab = this.tabs.eq( index ),
14586
- anchor = tab.find( ".ui-tabs-anchor" ),
14587
- panel = this._getPanelForTab( tab ),
14588
- eventData = {
14589
- tab: tab,
14590
- panel: panel
14591
- };
14592
-
14593
- // not remote
14594
- if ( isLocal( anchor[ 0 ] ) ) {
14595
- return;
14596
- }
14597
-
14598
- this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
14599
-
14600
- // support: jQuery <1.8
14601
- // jQuery <1.8 returns false if the request is canceled in beforeSend,
14602
- // but as of 1.8, $.ajax() always returns a jqXHR object.
14603
- if ( this.xhr && this.xhr.statusText !== "canceled" ) {
14604
- tab.addClass( "ui-tabs-loading" );
14605
- panel.attr( "aria-busy", "true" );
14606
-
14607
- this.xhr
14608
- .success(function( response ) {
14609
- // support: jQuery <1.8
14610
- // http://bugs.jquery.com/ticket/11778
14611
- setTimeout(function() {
14612
- panel.html( response );
14613
- that._trigger( "load", event, eventData );
14614
- }, 1 );
14615
- })
14616
- .complete(function( jqXHR, status ) {
14617
- // support: jQuery <1.8
14618
- // http://bugs.jquery.com/ticket/11778
14619
- setTimeout(function() {
14620
- if ( status === "abort" ) {
14621
- that.panels.stop( false, true );
14622
- }
14623
-
14624
- tab.removeClass( "ui-tabs-loading" );
14625
- panel.removeAttr( "aria-busy" );
14626
-
14627
- if ( jqXHR === that.xhr ) {
14628
- delete that.xhr;
14629
- }
14630
- }, 1 );
14631
- });
14632
- }
14633
- },
14634
-
14635
- _ajaxSettings: function( anchor, event, eventData ) {
14636
- var that = this;
14637
- return {
14638
- url: anchor.attr( "href" ),
14639
- beforeSend: function( jqXHR, settings ) {
14640
- return that._trigger( "beforeLoad", event,
14641
- $.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
14642
- }
14643
- };
14644
- },
14645
-
14646
- _getPanelForTab: function( tab ) {
14647
- var id = $( tab ).attr( "aria-controls" );
14648
- return this.element.find( this._sanitizeSelector( "#" + id ) );
14649
- }
14650
- });
14651
-
14652
- })( jQuery );
14653
-
14654
- (function( $ ) {
14655
-
14656
- var increments = 0;
14657
-
14658
- function addDescribedBy( elem, id ) {
14659
- var describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ );
14660
- describedby.push( id );
14661
- elem
14662
- .data( "ui-tooltip-id", id )
14663
- .attr( "aria-describedby", $.trim( describedby.join( " " ) ) );
14664
- }
14665
-
14666
- function removeDescribedBy( elem ) {
14667
- var id = elem.data( "ui-tooltip-id" ),
14668
- describedby = (elem.attr( "aria-describedby" ) || "").split( /\s+/ ),
14669
- index = $.inArray( id, describedby );
14670
- if ( index !== -1 ) {
14671
- describedby.splice( index, 1 );
14672
- }
14673
-
14674
- elem.removeData( "ui-tooltip-id" );
14675
- describedby = $.trim( describedby.join( " " ) );
14676
- if ( describedby ) {
14677
- elem.attr( "aria-describedby", describedby );
14678
- } else {
14679
- elem.removeAttr( "aria-describedby" );
14680
- }
14681
- }
14682
-
14683
- $.widget( "ui.tooltip", {
14684
- version: "1.10.4",
14685
- options: {
14686
- content: function() {
14687
- // support: IE<9, Opera in jQuery <1.7
14688
- // .text() can't accept undefined, so coerce to a string
14689
- var title = $( this ).attr( "title" ) || "";
14690
- // Escape title, since we're going from an attribute to raw HTML
14691
- return $( "<a>" ).text( title ).html();
14692
- },
14693
- hide: true,
14694
- // Disabled elements have inconsistent behavior across browsers (#8661)
14695
- items: "[title]:not([disabled])",
14696
- position: {
14697
- my: "left top+15",
14698
- at: "left bottom",
14699
- collision: "flipfit flip"
14700
- },
14701
- show: true,
14702
- tooltipClass: null,
14703
- track: false,
14704
-
14705
- // callbacks
14706
- close: null,
14707
- open: null
14708
- },
14709
-
14710
- _create: function() {
14711
- this._on({
14712
- mouseover: "open",
14713
- focusin: "open"
14714
- });
14715
-
14716
- // IDs of generated tooltips, needed for destroy
14717
- this.tooltips = {};
14718
- // IDs of parent tooltips where we removed the title attribute
14719
- this.parents = {};
14720
-
14721
- if ( this.options.disabled ) {
14722
- this._disable();
14723
- }
14724
- },
14725
-
14726
- _setOption: function( key, value ) {
14727
- var that = this;
14728
-
14729
- if ( key === "disabled" ) {
14730
- this[ value ? "_disable" : "_enable" ]();
14731
- this.options[ key ] = value;
14732
- // disable element style changes
14733
- return;
14734
- }
14735
-
14736
- this._super( key, value );
14737
-
14738
- if ( key === "content" ) {
14739
- $.each( this.tooltips, function( id, element ) {
14740
- that._updateContent( element );
14741
- });
14742
- }
14743
- },
14744
-
14745
- _disable: function() {
14746
- var that = this;
14747
-
14748
- // close open tooltips
14749
- $.each( this.tooltips, function( id, element ) {
14750
- var event = $.Event( "blur" );
14751
- event.target = event.currentTarget = element[0];
14752
- that.close( event, true );
14753
- });
14754
-
14755
- // remove title attributes to prevent native tooltips
14756
- this.element.find( this.options.items ).addBack().each(function() {
14757
- var element = $( this );
14758
- if ( element.is( "[title]" ) ) {
14759
- element
14760
- .data( "ui-tooltip-title", element.attr( "title" ) )
14761
- .attr( "title", "" );
14762
- }
14763
- });
14764
- },
14765
-
14766
- _enable: function() {
14767
- // restore title attributes
14768
- this.element.find( this.options.items ).addBack().each(function() {
14769
- var element = $( this );
14770
- if ( element.data( "ui-tooltip-title" ) ) {
14771
- element.attr( "title", element.data( "ui-tooltip-title" ) );
14772
- }
14773
- });
14774
- },
14775
-
14776
- open: function( event ) {
14777
- var that = this,
14778
- target = $( event ? event.target : this.element )
14779
- // we need closest here due to mouseover bubbling,
14780
- // but always pointing at the same event target
14781
- .closest( this.options.items );
14782
-
14783
- // No element to show a tooltip for or the tooltip is already open
14784
- if ( !target.length || target.data( "ui-tooltip-id" ) ) {
14785
- return;
14786
- }
14787
-
14788
- if ( target.attr( "title" ) ) {
14789
- target.data( "ui-tooltip-title", target.attr( "title" ) );
14790
- }
14791
-
14792
- target.data( "ui-tooltip-open", true );
14793
-
14794
- // kill parent tooltips, custom or native, for hover
14795
- if ( event && event.type === "mouseover" ) {
14796
- target.parents().each(function() {
14797
- var parent = $( this ),
14798
- blurEvent;
14799
- if ( parent.data( "ui-tooltip-open" ) ) {
14800
- blurEvent = $.Event( "blur" );
14801
- blurEvent.target = blurEvent.currentTarget = this;
14802
- that.close( blurEvent, true );
14803
- }
14804
- if ( parent.attr( "title" ) ) {
14805
- parent.uniqueId();
14806
- that.parents[ this.id ] = {
14807
- element: this,
14808
- title: parent.attr( "title" )
14809
- };
14810
- parent.attr( "title", "" );
14811
- }
14812
- });
14813
- }
14814
-
14815
- this._updateContent( target, event );
14816
- },
14817
-
14818
- _updateContent: function( target, event ) {
14819
- var content,
14820
- contentOption = this.options.content,
14821
- that = this,
14822
- eventType = event ? event.type : null;
14823
-
14824
- if ( typeof contentOption === "string" ) {
14825
- return this._open( event, target, contentOption );
14826
- }
14827
-
14828
- content = contentOption.call( target[0], function( response ) {
14829
- // ignore async response if tooltip was closed already
14830
- if ( !target.data( "ui-tooltip-open" ) ) {
14831
- return;
14832
- }
14833
- // IE may instantly serve a cached response for ajax requests
14834
- // delay this call to _open so the other call to _open runs first
14835
- that._delay(function() {
14836
- // jQuery creates a special event for focusin when it doesn't
14837
- // exist natively. To improve performance, the native event
14838
- // object is reused and the type is changed. Therefore, we can't
14839
- // rely on the type being correct after the event finished
14840
- // bubbling, so we set it back to the previous value. (#8740)
14841
- if ( event ) {
14842
- event.type = eventType;
14843
- }
14844
- this._open( event, target, response );
14845
- });
14846
- });
14847
- if ( content ) {
14848
- this._open( event, target, content );
14849
- }
14850
- },
14851
-
14852
- _open: function( event, target, content ) {
14853
- var tooltip, events, delayedShow,
14854
- positionOption = $.extend( {}, this.options.position );
14855
-
14856
- if ( !content ) {
14857
- return;
14858
- }
14859
-
14860
- // Content can be updated multiple times. If the tooltip already
14861
- // exists, then just update the content and bail.
14862
- tooltip = this._find( target );
14863
- if ( tooltip.length ) {
14864
- tooltip.find( ".ui-tooltip-content" ).html( content );
14865
- return;
14866
- }
14867
-
14868
- // if we have a title, clear it to prevent the native tooltip
14869
- // we have to check first to avoid defining a title if none exists
14870
- // (we don't want to cause an element to start matching [title])
14871
- //
14872
- // We use removeAttr only for key events, to allow IE to export the correct
14873
- // accessible attributes. For mouse events, set to empty string to avoid
14874
- // native tooltip showing up (happens only when removing inside mouseover).
14875
- if ( target.is( "[title]" ) ) {
14876
- if ( event && event.type === "mouseover" ) {
14877
- target.attr( "title", "" );
14878
- } else {
14879
- target.removeAttr( "title" );
14880
- }
14881
- }
14882
-
14883
- tooltip = this._tooltip( target );
14884
- addDescribedBy( target, tooltip.attr( "id" ) );
14885
- tooltip.find( ".ui-tooltip-content" ).html( content );
14886
-
14887
- function position( event ) {
14888
- positionOption.of = event;
14889
- if ( tooltip.is( ":hidden" ) ) {
14890
- return;
14891
- }
14892
- tooltip.position( positionOption );
14893
- }
14894
- if ( this.options.track && event && /^mouse/.test( event.type ) ) {
14895
- this._on( this.document, {
14896
- mousemove: position
14897
- });
14898
- // trigger once to override element-relative positioning
14899
- position( event );
14900
- } else {
14901
- tooltip.position( $.extend({
14902
- of: target
14903
- }, this.options.position ) );
14904
- }
14905
-
14906
- tooltip.hide();
14907
-
14908
- this._show( tooltip, this.options.show );
14909
- // Handle tracking tooltips that are shown with a delay (#8644). As soon
14910
- // as the tooltip is visible, position the tooltip using the most recent
14911
- // event.
14912
- if ( this.options.show && this.options.show.delay ) {
14913
- delayedShow = this.delayedShow = setInterval(function() {
14914
- if ( tooltip.is( ":visible" ) ) {
14915
- position( positionOption.of );
14916
- clearInterval( delayedShow );
14917
- }
14918
- }, $.fx.interval );
14919
- }
14920
-
14921
- this._trigger( "open", event, { tooltip: tooltip } );
14922
-
14923
- events = {
14924
- keyup: function( event ) {
14925
- if ( event.keyCode === $.ui.keyCode.ESCAPE ) {
14926
- var fakeEvent = $.Event(event);
14927
- fakeEvent.currentTarget = target[0];
14928
- this.close( fakeEvent, true );
14929
- }
14930
- },
14931
- remove: function() {
14932
- this._removeTooltip( tooltip );
14933
- }
14934
- };
14935
- if ( !event || event.type === "mouseover" ) {
14936
- events.mouseleave = "close";
14937
- }
14938
- if ( !event || event.type === "focusin" ) {
14939
- events.focusout = "close";
14940
- }
14941
- this._on( true, target, events );
14942
- },
14943
-
14944
- close: function( event ) {
14945
- var that = this,
14946
- target = $( event ? event.currentTarget : this.element ),
14947
- tooltip = this._find( target );
14948
-
14949
- // disabling closes the tooltip, so we need to track when we're closing
14950
- // to avoid an infinite loop in case the tooltip becomes disabled on close
14951
- if ( this.closing ) {
14952
- return;
14953
- }
14954
-
14955
- // Clear the interval for delayed tracking tooltips
14956
- clearInterval( this.delayedShow );
14957
-
14958
- // only set title if we had one before (see comment in _open())
14959
- if ( target.data( "ui-tooltip-title" ) ) {
14960
- target.attr( "title", target.data( "ui-tooltip-title" ) );
14961
- }
14962
-
14963
- removeDescribedBy( target );
14964
-
14965
- tooltip.stop( true );
14966
- this._hide( tooltip, this.options.hide, function() {
14967
- that._removeTooltip( $( this ) );
14968
- });
14969
-
14970
- target.removeData( "ui-tooltip-open" );
14971
- this._off( target, "mouseleave focusout keyup" );
14972
- // Remove 'remove' binding only on delegated targets
14973
- if ( target[0] !== this.element[0] ) {
14974
- this._off( target, "remove" );
14975
- }
14976
- this._off( this.document, "mousemove" );
14977
-
14978
- if ( event && event.type === "mouseleave" ) {
14979
- $.each( this.parents, function( id, parent ) {
14980
- $( parent.element ).attr( "title", parent.title );
14981
- delete that.parents[ id ];
14982
- });
14983
- }
14984
-
14985
- this.closing = true;
14986
- this._trigger( "close", event, { tooltip: tooltip } );
14987
- this.closing = false;
14988
- },
14989
-
14990
- _tooltip: function( element ) {
14991
- var id = "ui-tooltip-" + increments++,
14992
- tooltip = $( "<div>" )
14993
- .attr({
14994
- id: id,
14995
- role: "tooltip"
14996
- })
14997
- .addClass( "ui-tooltip ui-widget ui-corner-all ui-widget-content " +
14998
- ( this.options.tooltipClass || "" ) );
14999
- $( "<div>" )
15000
- .addClass( "ui-tooltip-content" )
15001
- .appendTo( tooltip );
15002
- tooltip.appendTo( this.document[0].body );
15003
- this.tooltips[ id ] = element;
15004
- return tooltip;
15005
- },
15006
-
15007
- _find: function( target ) {
15008
- var id = target.data( "ui-tooltip-id" );
15009
- return id ? $( "#" + id ) : $();
15010
- },
15011
-
15012
- _removeTooltip: function( tooltip ) {
15013
- tooltip.remove();
15014
- delete this.tooltips[ tooltip.attr( "id" ) ];
15015
- },
15016
-
15017
- _destroy: function() {
15018
- var that = this;
15019
-
15020
- // close open tooltips
15021
- $.each( this.tooltips, function( id, element ) {
15022
- // Delegate to close method to handle common cleanup
15023
- var event = $.Event( "blur" );
15024
- event.target = event.currentTarget = element[0];
15025
- that.close( event, true );
15026
-
15027
- // Remove immediately; destroying an open tooltip doesn't use the
15028
- // hide animation
15029
- $( "#" + id ).remove();
15030
-
15031
- // Restore the title
15032
- if ( element.data( "ui-tooltip-title" ) ) {
15033
- element.attr( "title", element.data( "ui-tooltip-title" ) );
15034
- element.removeData( "ui-tooltip-title" );
15035
- }
15036
- });
15037
- }
15038
- });
15039
-
15040
- }( jQuery ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
readme.txt CHANGED
@@ -4,8 +4,8 @@ Donate link: http://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id
4
  Plugin link: http://www.wp-studio.net/how-it-works
5
  Tags: language translator, google translator, language translate, google, google language translator, translation, translate, multi language
6
  Requires at least: 2.9
7
- Tested up to: 4.0
8
- stable tag: 4.0.9
9
 
10
  Welcome to Google Language Translator! This plugin allows you to insert the Google Language Translator tool anywhere on your website using shortcode.
11
 
@@ -46,6 +46,13 @@ A: Yes! Add the "notranslate" class to the HTML element containing your text. Fo
46
 
47
  == Changelog ==
48
 
 
 
 
 
 
 
 
49
  4.0.9
50
  - Replaced: incorrect Catalonian flag image, with the correct image. I apologize for any inconvenience.
51
  - Fixed: Floating Widget issue - previously it loaded 2 times when shortcode was added, which caused it not to work.
4
  Plugin link: http://www.wp-studio.net/how-it-works
5
  Tags: language translator, google translator, language translate, google, google language translator, translation, translate, multi language
6
  Requires at least: 2.9
7
+ Tested up to: 4.3
8
+ stable tag: 5.0.0
9
 
10
  Welcome to Google Language Translator! This plugin allows you to insert the Google Language Translator tool anywhere on your website using shortcode.
11
 
46
 
47
  == Changelog ==
48
 
49
+ 5.0.0
50
+ - Removed the translation management option from the Settings page (Google no longer offers translation management feature).
51
+ - Wordpress security updates added to the settings page [wp_nonce_field()].
52
+ - Removed 3 outside Javascript files - these files are now called upon directly from Wordpress CMS.
53
+ - Unpacked flags.js p,a,c,k,e,r code. Unknowingly, this method of coding violated Wordpress plugin policy.
54
+ - Updated pricing display for GLT Premium. It was displaying $15 previously, but the price had increased since the last update.
55
+
56
  4.0.9
57
  - Replaced: incorrect Catalonian flag image, with the correct image. I apologize for any inconvenience.
58
  - Fixed: Floating Widget issue - previously it loaded 2 times when shortcode was added, which caused it not to work.