Child Theme Configurator - Version 2.0.3

Version Description

  • Added logic conditions in preview class to help prevent Analyzer from failing in some cases
  • Enabled theme zip file export for any selected theme independent of theme currently loaded in Configurator
  • Fixed bugs present with servers not running Apache with SuExec
  • Fixed issue with Windows servers that do not return C: with filesystem paths
Download this release

Release Info

Developer lilaeamedia
Plugin Icon 128x128 Child Theme Configurator
Version 2.0.3
Comparing to
See all releases

Code changes from version 2.0.2 to 2.0.3

child-theme-configurator.php CHANGED
@@ -6,10 +6,10 @@ if ( !defined( 'ABSPATH' ) ) exit;
6
  Plugin Name: Child Theme Configurator
7
  Plugin URI: http://www.childthemeconfigurator.com
8
  Description: When using the Customizer is not enough - Create child themes and customize styles, templates, functions and more.
9
- Version: 2.0.2
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com
12
- Text Domain: chld_thm_cfg
13
  Domain Path: /lang
14
  License: GPLv2
15
  Copyright (C) 2014-2016 Lilaea Media
6
  Plugin Name: Child Theme Configurator
7
  Plugin URI: http://www.childthemeconfigurator.com
8
  Description: When using the Customizer is not enough - Create child themes and customize styles, templates, functions and more.
9
+ Version: 2.0.3
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com
12
+ Text Domain: child-theme-configurator
13
  Domain Path: /lang
14
  License: GPLv2
15
  Copyright (C) 2014-2016 Lilaea Media
includes/class-ctc-admin.php CHANGED
@@ -6,7 +6,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
6
  Class: Child_Theme_Configurator
7
  Plugin URI: http://www.childthemeconfigurator.com/
8
  Description: Main Controller Class
9
- Version: 2.0.2
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: child-theme-configurator
@@ -82,6 +82,7 @@ class ChildThemeConfiguratorAdmin {
82
  'theme_image_submit',
83
  'theme_screenshot_submit',
84
  'export_child_zip',
 
85
  'reset_permission',
86
  'templates_writable_submit',
87
  'set_writable',
@@ -128,7 +129,7 @@ class ChildThemeConfiguratorAdmin {
128
  $this->ui = new ChildThemeConfiguratorUI();
129
  // initialize help
130
  $this->ui->render_help_content();
131
- }
132
 
133
  function render() {
134
  $this->ui->render();
@@ -184,7 +185,7 @@ class ChildThemeConfiguratorAdmin {
184
  if ( ! $this->check_theme_exists( $this->get( 'child' ) )
185
  || ! $this->check_theme_exists( $this->get( 'parnt' ) ) ):
186
  $this->debug( 'theme does not exist', __FUNCTION__ );
187
- add_action( 'admin_notices', array( $this, 'config_notice' ) );
188
  $this->css = new ChildThemeConfiguratorCSS();
189
  $this->css->enqueue = 'enqueue';
190
  endif;
@@ -204,7 +205,7 @@ class ChildThemeConfiguratorAdmin {
204
  $this->css );
205
  // check file permissions
206
  if ( !is_writable( $stylesheet ) && !$this->fs )
207
- add_action( 'admin_notices', array( $this, 'writable_notice' ) );
208
  if ( $fsize = $this->get( 'fsize' ) ):
209
  $test = filesize( $stylesheet );
210
  $this->debug( 'filesize saved: ' . $fsize . ' current: ' . $test, __FUNCTION__ );
@@ -215,7 +216,7 @@ class ChildThemeConfiguratorAdmin {
215
  if ( !$this->get( 'enqueue' ) ):
216
  $this->debug( 'no enqueue:', __FUNCTION__ );
217
 
218
- add_action( 'admin_notices', array( $this, 'enqueue_notice' ) );
219
  endif;
220
  endif;
221
  if ( !$this->seen_upgrade_notice() ):
@@ -227,14 +228,14 @@ class ChildThemeConfiguratorAdmin {
227
  if ( $this->get( 'max_sel' ) ):
228
  $this->debug( 'Max selectors exceeded.', __FUNCTION__ );
229
  //$this->errors[] = __( 'Maximum number of styles exceeded.', 'child-theme-configurator' );
230
- add_action( 'admin_notices', array( $this, 'max_styles_notice' ) );
231
  endif;
232
  */
233
  // check if file ownership is messed up from old version or other plugin
234
  // by comparing owner of plugin to owner of child theme:
235
  if ( fileowner( $this->css->get_child_target( '' ) ) != fileowner( CHLD_THM_CFG_DIR ) )
236
- add_action( 'admin_notices', array( $this, 'owner_notice' ) );
237
- endif;
238
  }
239
 
240
  function cache_debug() {
@@ -368,12 +369,6 @@ class ChildThemeConfiguratorAdmin {
368
  // reset debug log
369
  delete_site_transient( CHLD_THM_CFG_OPTIONS . '_debug' );
370
  // zip export does not require filesystem access so check that first
371
- if ( 'export_child_zip' == $actionfield ):
372
- $this->export_zip();
373
- // if we get here the zip failed
374
- $this->errors[] = __( 'Zip file creation failed.', 'child-theme-configurator' );
375
- // all other actions require filesystem access
376
- else:
377
  // handle uploaded file before checking filesystem
378
  if ( 'theme_image_submit' == $actionfield && isset( $_FILES[ 'ctc_theme_image' ] ) ):
379
  $this->handle_file_upload( 'ctc_theme_image', $this->imgmimes );
@@ -387,6 +382,12 @@ class ChildThemeConfiguratorAdmin {
387
  $msg = FALSE;
388
  // we have filesystem access so proceed with specific actions
389
  switch( $actionfield ):
 
 
 
 
 
 
390
  case 'load_styles':
391
  // main child theme setup function
392
  $msg = $this->setup_child_theme();
@@ -478,7 +479,6 @@ class ChildThemeConfiguratorAdmin {
478
  $msg = '8&tab=file_options';
479
  endswitch;
480
  endif; // end filesystem condition
481
- endif; // end zip export condition
482
  if ( empty( $this->errors ) && empty( $this->fs_prompt ) ):
483
  $this->processdone = TRUE;
484
  //die( '<pre><code><small>' . print_r( $_POST, TRUE ) . '</small></code></pre>' );
@@ -560,7 +560,7 @@ class ChildThemeConfiguratorAdmin {
560
  if ( FALSE === $this->verify_child_dir( $child ) ):
561
  // if it returns false then it could not create directory.
562
  $this->errors[] = __( 'Your theme directories are not writable.', 'child-theme-configurator' );
563
- add_action( 'admin_notices', array( $this, 'writable_notice' ) );
564
  return FALSE;
565
  endif;
566
 
@@ -723,7 +723,7 @@ class ChildThemeConfiguratorAdmin {
723
  if ( FALSE === $this->css->write_css() ):
724
  //$this->debug( print_r( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ), TRUE ), __FUNCTION__ );
725
  $this->errors[] = __( 'Your stylesheet is not writable.', 'child-theme-configurator' );
726
- add_action( 'admin_notices', array( $this, 'writable_notice' ) );
727
  return FALSE;
728
  endif;
729
  // get files to reload templates in new css object
@@ -984,7 +984,7 @@ defined( 'CHLD_THM_CFG_IGNORE_PARENT' ) or define( 'CHLD_THM_CFG_IGNORE_PARENT',
984
  $this->debug( 'No functions file, creating...', __FUNCTION__ );
985
  $this->add_base_files( $this );
986
  endif;
987
- endif;
988
  // get_contents_array returns extra linefeeds so just split it ourself
989
  $markerdata = explode( "\n", $wp_filesystem->get_contents( $this->fspath( $filename ) ) );
990
  endif;
@@ -992,10 +992,10 @@ defined( 'CHLD_THM_CFG_IGNORE_PARENT' ) or define( 'CHLD_THM_CFG_IGNORE_PARENT',
992
  $externals = array();
993
  $phpopen = 0;
994
  $in_comment = 0;
995
- $foundit = FALSE;
996
- if ( $markerdata ):
997
- $state = TRUE;
998
- foreach ( $markerdata as $n => $markerline ):
999
  // remove double slash comment to end of line
1000
  $str = preg_replace( "/\/\/.*$/", '', $markerline );
1001
  preg_match_all("/(<\?|\?>|\*\/|\/\*)/", $str, $matches );
@@ -1012,21 +1012,21 @@ defined( 'CHLD_THM_CFG_IGNORE_PARENT' ) or define( 'CHLD_THM_CFG_IGNORE_PARENT',
1012
  endif;
1013
  endforeach;
1014
  endif;
1015
- if ( strpos( $markerline, '// BEGIN ' . $marker ) !== FALSE )
1016
- $state = FALSE;
1017
- if ( $state ):
1018
- if ( $n + 1 < count( $markerdata ) )
1019
- $newfile .= "{$markerline}\n";
1020
- else
1021
- $newfile .= "{$markerline}";
1022
  elseif ( $getexternals ):
1023
  // look for existing external stylesheets and add to imports config data
1024
  if ( preg_match( "/wp_enqueue_style.+?'chld_thm_cfg_ext\d+'.+?'(.+?)'/", $markerline, $matches ) ):
1025
  $this->debug( 'external link found : ' . $matches[ 1 ] );
1026
  $this->convert_enqueue_to_import( $matches[ 1 ] );
1027
  endif;
1028
- endif;
1029
- if ( strpos( $markerline, '// END ' . $marker ) !== FALSE ):
1030
  if ( 'reset' != $this->childtype ):
1031
  $newfile .= "// BEGIN {$marker}\n";
1032
  if ( is_array( $insertion ) )
@@ -1034,15 +1034,15 @@ defined( 'CHLD_THM_CFG_IGNORE_PARENT' ) or define( 'CHLD_THM_CFG_IGNORE_PARENT',
1034
  $newfile .= "{$insertline}\n";
1035
  $newfile .= "// END {$marker}\n";
1036
  endif;
1037
- $state = TRUE;
1038
- $foundit = TRUE;
1039
- endif;
1040
- endforeach;
1041
  else:
1042
  $this->debug( 'Could not parse functions file', __FUNCTION__ );
1043
  return FALSE;
1044
  endif;
1045
- if ( $foundit ):
1046
  $this->debug( 'Found marker, replaced inline', __FUNCTION__ );
1047
  else:
1048
  if ( 'reset' != $this->childtype ):
@@ -1291,7 +1291,7 @@ defined( 'CHLD_THM_CFG_IGNORE_PARENT' ) or define( 'CHLD_THM_CFG_IGNORE_PARENT',
1291
  if ( $file && $wp_filesystem->chmod( $this->fspath( $file ), 0666 ) ) return;
1292
  endif;
1293
  $this->errors[] = __( 'Could not set write permissions.', 'child-theme-configurator' );
1294
- add_action( 'admin_notices', array( $this, 'writable_notice' ) );
1295
  return FALSE;
1296
  }
1297
 
@@ -1392,7 +1392,7 @@ defined( 'CHLD_THM_CFG_IGNORE_PARENT' ) or define( 'CHLD_THM_CFG_IGNORE_PARENT',
1392
  endif;
1393
  if ( count( $errors ) ):
1394
  $this->errors[] = __( 'There were errors while resetting permissions.', 'child-theme-configurator' ) ;
1395
- add_action( 'admin_notices', array( $this, 'writable_notice' ) );
1396
  endif;
1397
  }
1398
 
@@ -1436,31 +1436,62 @@ defined( 'CHLD_THM_CFG_IGNORE_PARENT' ) or define( 'CHLD_THM_CFG_IGNORE_PARENT',
1436
  $this->errors[] = __( 'Could not upload file.', 'child-theme-configurator' );
1437
  }
1438
 
 
 
 
 
1439
  function export_zip() {
1440
- if ( ( $child = $this->get( 'child' ) )
1441
- && ( $dir = $this->css->is_file_ok( dirname( $this->css->get_child_target( 'style.css' ) ), 'search' ) )
1442
- && ( $version = preg_replace( "%[^\w\.\-]%", '', $this->get( 'version' ) ) ) ):
1443
- // use php system upload dir to store temp files so that we can use pclzip
 
 
 
 
 
 
 
 
1444
  $tmpdir = ini_get( 'upload_tmp_dir' ) ? ini_get( 'upload_tmp_dir' ) : sys_get_temp_dir();
1445
- $file = trailingslashit( $tmpdir ) . $child . '-' . $version . '.zip';
1446
- mbstring_binary_safe_encoding();
 
 
 
 
 
 
 
 
 
1447
 
 
 
 
1448
  require_once( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
1449
 
1450
  $archive = new PclZip( $file );
1451
- if ( $archive->create( $dir, PCLZIP_OPT_REMOVE_PATH, dirname( $dir ) ) == 0 ) return FALSE;
1452
- reset_mbstring_encoding();
1453
- header( 'Content-Description: File Transfer' );
1454
- header( 'Content-Type: application/octet-stream' );
1455
- header( 'Content-Length: ' . filesize( $file ) );
1456
- header( 'Content-Disposition: attachment; filename=' . basename( $file ) );
1457
- header( 'Expires: 0' );
1458
- header( 'Cache-Control: must-revalidate' );
1459
- header( 'Pragma: public' );
1460
- readfile( $file );
1461
- unlink( $file );
1462
- die();
 
 
 
 
 
 
1463
  endif;
 
1464
  }
1465
 
1466
  /*
@@ -1547,9 +1578,12 @@ defined( 'CHLD_THM_CFG_IGNORE_PARENT' ) or define( 'CHLD_THM_CFG_IGNORE_PARENT',
1547
 
1548
  // backwards compatability < WP 3.9
1549
  function normalize_path( $path ) {
1550
- $path = str_replace( '\\', '/', $path );
1551
- $path = preg_replace( '|/+|','/', $path );
1552
- return $path;
 
 
 
1553
  }
1554
 
1555
  // case insensitive theme search
@@ -1792,9 +1826,9 @@ defined( 'CHLD_THM_CFG_IGNORE_PARENT' ) or define( 'CHLD_THM_CFG_IGNORE_PARENT',
1792
  $found_header = 0;
1793
  $headerdone = 0;
1794
  $newheader = '';
1795
- if ( $headerdata ):
1796
  $this->debug( 'parsing header...', __FUNCTION__ );
1797
- foreach ( $headerdata as $n => $headerline ):
1798
  preg_match_all("/(\*\/|\/\*)/", $headerline, $matches );
1799
  if ( $matches ):
1800
  foreach ( $matches[1] as $token ):
@@ -1973,7 +2007,7 @@ defined( 'CHLD_THM_CFG_IGNORE_PARENT' ) or define( 'CHLD_THM_CFG_IGNORE_PARENT',
1973
  endif;
1974
  if ( !preg_match( "/^style([\-\.]min)?\.css$/", $deparray[ 1 ] ) ):
1975
  // bootstrap wastes memory among other resources
1976
- if ( !preg_match( "/bootstrap/i", $deparray[ 0 ] ) && !preg_match( "/bootstrap/i", $deparray[ 1 ] ) )
1977
  $this->css->addl_css[] = sanitize_text_field( $deparray[ 1 ] );
1978
  endif;
1979
  endforeach;
@@ -1983,7 +2017,7 @@ defined( 'CHLD_THM_CFG_IGNORE_PARENT' ) or define( 'CHLD_THM_CFG_IGNORE_PARENT',
1983
  endif;
1984
  if ( 'separate' == $this->get( 'handling' ) || !empty( $analysis->{ $baseline }->signals->ctc_child_loaded ) ):
1985
  if ( !preg_match( "/^style([\-\.]min)?\.css$/", $deparray[ 1 ] ) ):
1986
- if ( !preg_match( "/bootstrap/", $deparray[ 0 ] ) && !preg_match( "/bootstrap/", $deparray[ 1 ] ) )
1987
  $this->css->addl_css[] = sanitize_text_field( $deparray[ 1 ] );
1988
  endif;
1989
  endif;
6
  Class: Child_Theme_Configurator
7
  Plugin URI: http://www.childthemeconfigurator.com/
8
  Description: Main Controller Class
9
+ Version: 2.0.3
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: child-theme-configurator
82
  'theme_image_submit',
83
  'theme_screenshot_submit',
84
  'export_child_zip',
85
+ 'export_theme',
86
  'reset_permission',
87
  'templates_writable_submit',
88
  'set_writable',
129
  $this->ui = new ChildThemeConfiguratorUI();
130
  // initialize help
131
  $this->ui->render_help_content();
132
+ }
133
 
134
  function render() {
135
  $this->ui->render();
185
  if ( ! $this->check_theme_exists( $this->get( 'child' ) )
186
  || ! $this->check_theme_exists( $this->get( 'parnt' ) ) ):
187
  $this->debug( 'theme does not exist', __FUNCTION__ );
188
+ add_action( 'admin_notices', array( $this, 'config_notice' ) );
189
  $this->css = new ChildThemeConfiguratorCSS();
190
  $this->css->enqueue = 'enqueue';
191
  endif;
205
  $this->css );
206
  // check file permissions
207
  if ( !is_writable( $stylesheet ) && !$this->fs )
208
+ add_action( 'admin_notices', array( $this, 'writable_notice' ) );
209
  if ( $fsize = $this->get( 'fsize' ) ):
210
  $test = filesize( $stylesheet );
211
  $this->debug( 'filesize saved: ' . $fsize . ' current: ' . $test, __FUNCTION__ );
216
  if ( !$this->get( 'enqueue' ) ):
217
  $this->debug( 'no enqueue:', __FUNCTION__ );
218
 
219
+ add_action( 'admin_notices', array( $this, 'enqueue_notice' ) );
220
  endif;
221
  endif;
222
  if ( !$this->seen_upgrade_notice() ):
228
  if ( $this->get( 'max_sel' ) ):
229
  $this->debug( 'Max selectors exceeded.', __FUNCTION__ );
230
  //$this->errors[] = __( 'Maximum number of styles exceeded.', 'child-theme-configurator' );
231
+ add_action( 'admin_notices', array( $this, 'max_styles_notice' ) );
232
  endif;
233
  */
234
  // check if file ownership is messed up from old version or other plugin
235
  // by comparing owner of plugin to owner of child theme:
236
  if ( fileowner( $this->css->get_child_target( '' ) ) != fileowner( CHLD_THM_CFG_DIR ) )
237
+ add_action( 'admin_notices', array( $this, 'owner_notice' ) );
238
+ endif;
239
  }
240
 
241
  function cache_debug() {
369
  // reset debug log
370
  delete_site_transient( CHLD_THM_CFG_OPTIONS . '_debug' );
371
  // zip export does not require filesystem access so check that first
 
 
 
 
 
 
372
  // handle uploaded file before checking filesystem
373
  if ( 'theme_image_submit' == $actionfield && isset( $_FILES[ 'ctc_theme_image' ] ) ):
374
  $this->handle_file_upload( 'ctc_theme_image', $this->imgmimes );
382
  $msg = FALSE;
383
  // we have filesystem access so proceed with specific actions
384
  switch( $actionfield ):
385
+ case 'export_child_zip':
386
+ case 'export_theme':
387
+ $this->export_zip();
388
+ // if we get here the zip failed
389
+ $this->errors[] = __( 'Zip file creation failed.', 'child-theme-configurator' );
390
+ break;
391
  case 'load_styles':
392
  // main child theme setup function
393
  $msg = $this->setup_child_theme();
479
  $msg = '8&tab=file_options';
480
  endswitch;
481
  endif; // end filesystem condition
 
482
  if ( empty( $this->errors ) && empty( $this->fs_prompt ) ):
483
  $this->processdone = TRUE;
484
  //die( '<pre><code><small>' . print_r( $_POST, TRUE ) . '</small></code></pre>' );
560
  if ( FALSE === $this->verify_child_dir( $child ) ):
561
  // if it returns false then it could not create directory.
562
  $this->errors[] = __( 'Your theme directories are not writable.', 'child-theme-configurator' );
563
+ add_action( 'admin_notices', array( $this, 'writable_notice' ) );
564
  return FALSE;
565
  endif;
566
 
723
  if ( FALSE === $this->css->write_css() ):
724
  //$this->debug( print_r( debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS ), TRUE ), __FUNCTION__ );
725
  $this->errors[] = __( 'Your stylesheet is not writable.', 'child-theme-configurator' );
726
+ add_action( 'admin_notices', array( $this, 'writable_notice' ) );
727
  return FALSE;
728
  endif;
729
  // get files to reload templates in new css object
984
  $this->debug( 'No functions file, creating...', __FUNCTION__ );
985
  $this->add_base_files( $this );
986
  endif;
987
+ endif;
988
  // get_contents_array returns extra linefeeds so just split it ourself
989
  $markerdata = explode( "\n", $wp_filesystem->get_contents( $this->fspath( $filename ) ) );
990
  endif;
992
  $externals = array();
993
  $phpopen = 0;
994
  $in_comment = 0;
995
+ $foundit = FALSE;
996
+ if ( $markerdata ):
997
+ $state = TRUE;
998
+ foreach ( $markerdata as $n => $markerline ):
999
  // remove double slash comment to end of line
1000
  $str = preg_replace( "/\/\/.*$/", '', $markerline );
1001
  preg_match_all("/(<\?|\?>|\*\/|\/\*)/", $str, $matches );
1012
  endif;
1013
  endforeach;
1014
  endif;
1015
+ if ( strpos( $markerline, '// BEGIN ' . $marker ) !== FALSE )
1016
+ $state = FALSE;
1017
+ if ( $state ):
1018
+ if ( $n + 1 < count( $markerdata ) )
1019
+ $newfile .= "{$markerline}\n";
1020
+ else
1021
+ $newfile .= "{$markerline}";
1022
  elseif ( $getexternals ):
1023
  // look for existing external stylesheets and add to imports config data
1024
  if ( preg_match( "/wp_enqueue_style.+?'chld_thm_cfg_ext\d+'.+?'(.+?)'/", $markerline, $matches ) ):
1025
  $this->debug( 'external link found : ' . $matches[ 1 ] );
1026
  $this->convert_enqueue_to_import( $matches[ 1 ] );
1027
  endif;
1028
+ endif;
1029
+ if ( strpos( $markerline, '// END ' . $marker ) !== FALSE ):
1030
  if ( 'reset' != $this->childtype ):
1031
  $newfile .= "// BEGIN {$marker}\n";
1032
  if ( is_array( $insertion ) )
1034
  $newfile .= "{$insertline}\n";
1035
  $newfile .= "// END {$marker}\n";
1036
  endif;
1037
+ $state = TRUE;
1038
+ $foundit = TRUE;
1039
+ endif;
1040
+ endforeach;
1041
  else:
1042
  $this->debug( 'Could not parse functions file', __FUNCTION__ );
1043
  return FALSE;
1044
  endif;
1045
+ if ( $foundit ):
1046
  $this->debug( 'Found marker, replaced inline', __FUNCTION__ );
1047
  else:
1048
  if ( 'reset' != $this->childtype ):
1291
  if ( $file && $wp_filesystem->chmod( $this->fspath( $file ), 0666 ) ) return;
1292
  endif;
1293
  $this->errors[] = __( 'Could not set write permissions.', 'child-theme-configurator' );
1294
+ add_action( 'admin_notices', array( $this, 'writable_notice' ) );
1295
  return FALSE;
1296
  }
1297
 
1392
  endif;
1393
  if ( count( $errors ) ):
1394
  $this->errors[] = __( 'There were errors while resetting permissions.', 'child-theme-configurator' ) ;
1395
+ add_action( 'admin_notices', array( $this, 'writable_notice' ) );
1396
  endif;
1397
  }
1398
 
1436
  $this->errors[] = __( 'Could not upload file.', 'child-theme-configurator' );
1437
  }
1438
 
1439
+ /**
1440
+ * exports theme as zip archive.
1441
+ * As of version 2.03, parent themes can be exported as well
1442
+ */
1443
  function export_zip() {
1444
+ $version = '';
1445
+ if ( empty( $_POST[ 'ctc_export_theme' ] ) ):
1446
+ $template = $this->get( 'child' );
1447
+ $version = preg_replace( "%[^\w\.\-]%", '', $this->get( 'version' ) );
1448
+ else:
1449
+ $template = sanitize_text_field( $_POST[ 'ctc_export_theme' ] );
1450
+ if ( ( $theme = wp_get_theme( $template ) ) && is_object( $theme ) )
1451
+ $version = preg_replace( "%\.\d{10}$%", '', $theme->Version );
1452
+ endif;
1453
+ // make sure directory exists and is in themes folder
1454
+ if ( ( $dir = $this->css->is_file_ok( trailingslashit( get_theme_root() ) . $template, 'search' ) ) ):
1455
+ // Try to use php system upload dir to store temp files first
1456
  $tmpdir = ini_get( 'upload_tmp_dir' ) ? ini_get( 'upload_tmp_dir' ) : sys_get_temp_dir();
1457
+ if ( !is_writable( $tmpdir ) ):
1458
+ // try uploads directory
1459
+ $uploads = wp_upload_dir();
1460
+ $tmpdir = $uploads[ 'basedir' ];
1461
+ if ( !is_writable( $tmpdir ) ):
1462
+ $this->errors[] = __( 'No writable temp directory.', 'child-theme-configurator' );
1463
+ return FALSE;
1464
+ endif;
1465
+ endif;
1466
+ $file = trailingslashit( $tmpdir ) . $template . ( empty( $version ) ? '' : '-' . $version ) . '.zip';
1467
+ if ( file_exists( $file ) ) unlink ( $file );
1468
 
1469
+ mbstring_binary_safe_encoding();
1470
+
1471
+ // PclZip ships with WordPress
1472
  require_once( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
1473
 
1474
  $archive = new PclZip( $file );
1475
+ if ( $response = $archive->create( $dir, PCLZIP_OPT_REMOVE_PATH, dirname( $dir ) ) ):
1476
+
1477
+ reset_mbstring_encoding();
1478
+ header( 'Content-Description: File Transfer' );
1479
+ header( 'Content-Type: application/octet-stream' );
1480
+ header( 'Content-Length: ' . filesize( $file ) );
1481
+ header( 'Content-Disposition: attachment; filename=' . basename( $file ) );
1482
+ header( 'Expires: 0' );
1483
+ header( 'Cache-Control: must-revalidate' );
1484
+ header( 'Pragma: public' );
1485
+ readfile( $file );
1486
+ unlink( $file );
1487
+ die();
1488
+ else:
1489
+ $this->errors[] = __( 'PclZip returned zero bytes.', 'child-theme-configurator' );
1490
+ endif;
1491
+ else:
1492
+ $this->errors = __( 'Invalid theme root directory.', 'child-theme-configurator' );
1493
  endif;
1494
+
1495
  }
1496
 
1497
  /*
1578
 
1579
  // backwards compatability < WP 3.9
1580
  function normalize_path( $path ) {
1581
+ $path = str_replace( '\\', '/', $path );
1582
+ // accommodates windows NT paths without C: prefix
1583
+ $path = substr( $path, 0, 1 ) . preg_replace( '|/+|','/', substr( $path, 1 ) );
1584
+ if ( ':' === substr( $path, 1, 1 ) )
1585
+ $path = ucfirst( $path );
1586
+ return $path;
1587
  }
1588
 
1589
  // case insensitive theme search
1826
  $found_header = 0;
1827
  $headerdone = 0;
1828
  $newheader = '';
1829
+ if ( $headerdata ):
1830
  $this->debug( 'parsing header...', __FUNCTION__ );
1831
+ foreach ( $headerdata as $n => $headerline ):
1832
  preg_match_all("/(\*\/|\/\*)/", $headerline, $matches );
1833
  if ( $matches ):
1834
  foreach ( $matches[1] as $token ):
2007
  endif;
2008
  if ( !preg_match( "/^style([\-\.]min)?\.css$/", $deparray[ 1 ] ) ):
2009
  // bootstrap wastes memory among other resources
2010
+ //if ( !preg_match( "/bootstrap/i", $deparray[ 0 ] ) && !preg_match( "/bootstrap/i", $deparray[ 1 ] ) )
2011
  $this->css->addl_css[] = sanitize_text_field( $deparray[ 1 ] );
2012
  endif;
2013
  endforeach;
2017
  endif;
2018
  if ( 'separate' == $this->get( 'handling' ) || !empty( $analysis->{ $baseline }->signals->ctc_child_loaded ) ):
2019
  if ( !preg_match( "/^style([\-\.]min)?\.css$/", $deparray[ 1 ] ) ):
2020
+ //if ( !preg_match( "/bootstrap/", $deparray[ 0 ] ) && !preg_match( "/bootstrap/", $deparray[ 1 ] ) )
2021
  $this->css->addl_css[] = sanitize_text_field( $deparray[ 1 ] );
2022
  endif;
2023
  endif;
includes/class-ctc-css.php CHANGED
@@ -6,7 +6,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
6
  Class: ChildThemeConfiguratorCSS
7
  Plugin URI: http://www.childthemeconfigurator.com/
8
  Description: Handles all CSS input, output, parsing, normalization and storage
9
- Version: 2.0.2
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
6
  Class: ChildThemeConfiguratorCSS
7
  Plugin URI: http://www.childthemeconfigurator.com/
8
  Description: Handles all CSS input, output, parsing, normalization and storage
9
+ Version: 2.0.3
10
  Author: Lilaea Media
11
  Author URI: http://www.lilaeamedia.com/
12
  Text Domain: chld_thm_cfg
includes/class-ctc-preview.php CHANGED
@@ -24,6 +24,10 @@ ini_set( 'display_errors', 1 );
24
  // check for manipulations
25
  if ( validate_file( $_GET[ 'template' ] ) )
26
  return;
 
 
 
 
27
  // replace future get_template calls with preview template
28
  add_filter( 'template', 'ChildThemeConfiguratorPreview::preview_theme_template_filter' );
29
 
@@ -39,6 +43,10 @@ ini_set( 'display_errors', 1 );
39
  // swap out theme mods with preview theme mods
40
  add_filter( 'pre_option_theme_mods_' . get_option( 'stylesheet' ),
41
  'ChildThemeConfiguratorPreview::preview_mods' );
 
 
 
 
42
  // impossibly high priority to test for stylesheets loaded after wp_head()
43
  add_action( 'wp_print_styles', 'ChildThemeConfiguratorPreview::test_css', 999999 );
44
  // pass the wp_styles queue back to use for stylesheet handle verification
@@ -130,15 +138,34 @@ ini_set( 'display_errors', 1 );
130
  call_user_func_array( $funcarr[ 'function' ], array() );
131
  endforeach;
132
  // report the priority, and any handles that were added
133
- echo $priority . ',' . implode( ",", $wp_styles->queue ) . LF;
 
134
  endif;
135
  endforeach;
136
  echo 'END CTC IRREGULAR' . LF;
137
  echo '*/]]></script>' . LF;
138
  }
 
 
 
 
 
 
 
 
 
 
 
139
  }
140
 
141
  // replace core preview function with CTCP function for quick preview
142
  remove_action( 'setup_theme', 'preview_theme' );
143
  add_action( 'setup_theme', 'ChildThemeConfiguratorPreview::preview_theme' );
144
-
 
 
 
 
 
 
 
24
  // check for manipulations
25
  if ( validate_file( $_GET[ 'template' ] ) )
26
  return;
27
+ global $wp_customize;
28
+ // require_once ABSPATH . WPINC . '/class-wp-customize-manager.php';
29
+ $wp_customize = new WP_Customize_Manager();
30
+
31
  // replace future get_template calls with preview template
32
  add_filter( 'template', 'ChildThemeConfiguratorPreview::preview_theme_template_filter' );
33
 
43
  // swap out theme mods with preview theme mods
44
  add_filter( 'pre_option_theme_mods_' . get_option( 'stylesheet' ),
45
  'ChildThemeConfiguratorPreview::preview_mods' );
46
+ //add_filter( 'woocommerce_unforce_ssl_checkout', 'ChildThemeConfiguratorPreview::woocommerce_unforce_ssl_checkout', 1000 );
47
+ // Run wp_redirect_status late to make sure we override the status last.
48
+ add_action( 'wp_redirect_status', 'ChildThemeConfiguratorPreview::redirect_status', 1000 );
49
+
50
  // impossibly high priority to test for stylesheets loaded after wp_head()
51
  add_action( 'wp_print_styles', 'ChildThemeConfiguratorPreview::test_css', 999999 );
52
  // pass the wp_styles queue back to use for stylesheet handle verification
138
  call_user_func_array( $funcarr[ 'function' ], array() );
139
  endforeach;
140
  // report the priority, and any handles that were added
141
+ if ( !empty( $wp_styles->queue ) )
142
+ echo $priority . ',' . implode( ",", $wp_styles->queue ) . LF;
143
  endif;
144
  endforeach;
145
  echo 'END CTC IRREGULAR' . LF;
146
  echo '*/]]></script>' . LF;
147
  }
148
+ /**
149
+ * Prevents AJAX requests from following redirects when previewing a theme
150
+ * by issuing a 200 response instead of a 30x.
151
+ */
152
+ static function redirect_status( $status ) {
153
+ return 200;
154
+ }
155
+
156
+ static function woocommerce_unforce_ssl_checkout( $bool ){
157
+ return FALSE;
158
+ }
159
  }
160
 
161
  // replace core preview function with CTCP function for quick preview
162
  remove_action( 'setup_theme', 'preview_theme' );
163
  add_action( 'setup_theme', 'ChildThemeConfiguratorPreview::preview_theme' );
164
+
165
+ if ( !class_exists( 'WP_Customize_Manager' ) ) {
166
+ final class WP_Customize_Manager {
167
+ function is_preview() {
168
+ return TRUE;
169
+ }
170
+ }
171
+ }
includes/class-ctc-ui.php CHANGED
@@ -5,7 +5,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
5
  Class: Child_Theme_Configurator_UI
6
  Plugin URI: http://www.childthemeconfigurator.com/
7
  Description: Handles the plugin User Interface
8
- Version: 2.0.2
9
  Author: Lilaea Media
10
  Author URI: http://www.lilaeamedia.com/
11
  Text Domain: chld_thm_cfg
@@ -182,9 +182,9 @@ class ChildThemeConfiguratorUI {
182
  }
183
 
184
  function render_help_content() {
185
- global $wp_version;
186
- if ( version_compare( $wp_version, '3.3' ) >= 0 ):
187
- $screen = get_current_screen();
188
 
189
  // load help content via output buffer so we can use plain html for updates
190
  // then use regex to parse for help tab parameter values
@@ -203,7 +203,7 @@ class ChildThemeConfiguratorUI {
203
  preg_match( $regex_sidebar, $help_raw, $sidebar );
204
  preg_match_all( $regex_tab, $help_raw, $tabs );
205
 
206
- // Add help tabs
207
  if ( isset( $tabs[ 1 ] ) ):
208
  $priority = 0;
209
  while( count( $tabs[ 1 ] ) ):
@@ -211,12 +211,12 @@ class ChildThemeConfiguratorUI {
211
  $title = array_shift( $tabs[ 2 ] );
212
  $content = array_shift( $tabs[ 3 ] );
213
  $tab = array(
214
- 'id' => $id,
215
- 'title' => $title,
216
- 'content' => $content,
217
  'priority' => ++$priority,
218
  );
219
- $screen->add_help_tab( $tab );
220
  endwhile;
221
  endif;
222
  if ( isset( $sidebar[ 1 ] ) )
@@ -312,8 +312,8 @@ class ChildThemeConfiguratorUI {
312
  'anlz1_txt' => __( 'Updating', 'child-theme-configurator' ),
313
  'anlz2_txt' => __( 'Checking', 'child-theme-configurator' ),
314
  'anlz3_txt' => __( 'The theme "%s" generated unexpected PHP debug output.', 'child-theme-configurator' ),
315
- 'anlz4_txt' => __( 'The theme "%s" could not be analyzed.', 'child-theme-configurator' ),
316
- 'anlz5_txt' => __( '<p>Please try temporarily disabling plugins that <strong>minify CSS</strong> or that <strong>force redirects between HTTP and HTTPS</strong>.</p>', 'child-theme-configurator' ),
317
  'anlz6_txt' => __( 'Show Debug Output', 'child-theme-configurator' ),
318
  'anlz7_txt' => __( "<p>You may not be able to use this Theme as a Child Theme while these conditions exist.</p><p>It is possible that this theme has specific requirements to work correctly as a child theme. Check your theme's documentation for more information.</p><p>Please make sure you are using the latest version of this theme. If so, please contact this Theme's author and report the error list above.</p>", 'child-theme-configurator' ),
319
  'anlz8_txt' => __( 'Do Not Activate "%s"! A PHP FATAL ERROR has been detected.', 'child-theme-configurator' ),
@@ -360,7 +360,7 @@ class ChildThemeConfiguratorUI {
360
 
361
  case 'writable': ?>
362
 
363
- <div class="ctc-section-toggle" id="ctc_perm_options"><?php _e( 'The child theme is in read-only mode and Child Theme Configurator cannot apply changes. Click to see options', 'child-theme-configurator' ); ?></div><div class="ctc-section-toggle-content" id="ctc_perm_options_content"><p><ol><?php
364
  $ctcpage = apply_filters( 'chld_thm_cfg_admin_page', CHLD_THM_CFG_MENU );
365
  if ( 'WIN' != substr( strtoupper( PHP_OS ), 0, 3 ) ):
366
  _e( '<li>Temporarily set write permissions by clicking the button below. When you are finished editing, revert to read-only by clicking "Make read-only" under the "Files" tab.</li>', 'child-theme-configurator' );
@@ -381,9 +381,10 @@ class ChildThemeConfiguratorUI {
381
  case 'owner':
382
 
383
  $ctcpage = apply_filters( 'chld_thm_cfg_admin_page', CHLD_THM_CFG_MENU ); // FIXME? ?>
384
- <p><?php _e( 'This Child Theme is not owned by your website account. It may have been created by a prior version of this plugin or by another program. Moving forward, it must be owned by your website account to make changes. Child Theme Configurator will attempt to correct this when you click the button below.', 'child-theme-configurator' ) ?></p>
385
- <form action="?page=<?php echo $ctcpage; ?>" method="post"><?php
386
- wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) );
 
387
  break;
388
 
389
 
@@ -419,16 +420,12 @@ class ChildThemeConfiguratorUI {
419
 
420
  <?php if ( $child ): ?>
421
  <div class="clearfix">
422
- <div style="width:67%;float:left;margin:0">
423
  <?php endif; ?>
424
  <h3><?php _e( 'This version of Child Theme Configurator includes significant updates.', 'child-theme-configurator' ); ?></h3>
425
  <p class="howto"><?php _e( 'A lot of time and testing has gone into this release but there are always edge cases. If you have any questions, please', 'child-theme-configurator' ); ?> <a href="<?php echo LILAEAMEDIA_URL; ?>/contact" target="_blank"><?php _e( 'Contact Us.', 'child-theme-configurator' ); ?></a></p>
426
  <p class="howto"><?php _e( 'For more information, please open the Help tab at the top right or ', 'child-theme-configurator' ) ?> <a href="http://www.childthemeconfigurator.com/tutorial-videos/" target="_blank"><?php _e( 'click here to view the latest videos.', 'child-theme-configurator' ); ?></a></p>
427
  <?php if ( $child ): ?>
428
- <p><?php _e( 'It is a good idea to save a Zip Archive of your Child Theme before using this version for the first time (click the button to the right to download). Remember you can always export your child themes from the "Files" Tab.', 'child-theme-configurator' ); ?></p>
429
- </div>
430
- <div style="width:33%;margin:0;float:left;text-align:center"><h3><?php _e( 'Backup Child Theme', 'child-theme-configurator' ); ?></h3>
431
- <?php include ( CHLD_THM_CFG_DIR . '/includes/forms/zipform.php' ); ?></div>
432
  </div>
433
  <?php endif; ?>
434
  <?php endswitch; ?>
5
  Class: Child_Theme_Configurator_UI
6
  Plugin URI: http://www.childthemeconfigurator.com/
7
  Description: Handles the plugin User Interface
8
+ Version: 2.0.3
9
  Author: Lilaea Media
10
  Author URI: http://www.lilaeamedia.com/
11
  Text Domain: chld_thm_cfg
182
  }
183
 
184
  function render_help_content() {
185
+ global $wp_version;
186
+ if ( version_compare( $wp_version, '3.3' ) >= 0 ):
187
+ $screen = get_current_screen();
188
 
189
  // load help content via output buffer so we can use plain html for updates
190
  // then use regex to parse for help tab parameter values
203
  preg_match( $regex_sidebar, $help_raw, $sidebar );
204
  preg_match_all( $regex_tab, $help_raw, $tabs );
205
 
206
+ // Add help tabs
207
  if ( isset( $tabs[ 1 ] ) ):
208
  $priority = 0;
209
  while( count( $tabs[ 1 ] ) ):
211
  $title = array_shift( $tabs[ 2 ] );
212
  $content = array_shift( $tabs[ 3 ] );
213
  $tab = array(
214
+ 'id' => $id,
215
+ 'title' => $title,
216
+ 'content' => $content,
217
  'priority' => ++$priority,
218
  );
219
+ $screen->add_help_tab( $tab );
220
  endwhile;
221
  endif;
222
  if ( isset( $sidebar[ 1 ] ) )
312
  'anlz1_txt' => __( 'Updating', 'child-theme-configurator' ),
313
  'anlz2_txt' => __( 'Checking', 'child-theme-configurator' ),
314
  'anlz3_txt' => __( 'The theme "%s" generated unexpected PHP debug output.', 'child-theme-configurator' ),
315
+ 'anlz4_txt' => __( 'The theme "%s" could not be analyzed because the preview did not render correctly.', 'child-theme-configurator' ),
316
+ 'anlz5_txt' => __( '<p>You can still generate a child theme by manually selecting the settings below, but there will be no baseline styles available in the Configurator.</strong></p><p>You might try temporarily disabling plugins that <strong>minify CSS</strong> or that <strong>force redirects between HTTP and HTTPS</strong> and try analyzing again.</p>', 'child-theme-configurator' ),
317
  'anlz6_txt' => __( 'Show Debug Output', 'child-theme-configurator' ),
318
  'anlz7_txt' => __( "<p>You may not be able to use this Theme as a Child Theme while these conditions exist.</p><p>It is possible that this theme has specific requirements to work correctly as a child theme. Check your theme's documentation for more information.</p><p>Please make sure you are using the latest version of this theme. If so, please contact this Theme's author and report the error list above.</p>", 'child-theme-configurator' ),
319
  'anlz8_txt' => __( 'Do Not Activate "%s"! A PHP FATAL ERROR has been detected.', 'child-theme-configurator' ),
360
 
361
  case 'writable': ?>
362
 
363
+ <p class="ctc-section-toggle" id="ctc_perm_options"><?php _e( 'The child theme is in read-only mode and Child Theme Configurator cannot apply changes. Click to see options', 'child-theme-configurator' ); ?></p><div class="ctc-section-toggle-content" id="ctc_perm_options_content"><p><ol><?php
364
  $ctcpage = apply_filters( 'chld_thm_cfg_admin_page', CHLD_THM_CFG_MENU );
365
  if ( 'WIN' != substr( strtoupper( PHP_OS ), 0, 3 ) ):
366
  _e( '<li>Temporarily set write permissions by clicking the button below. When you are finished editing, revert to read-only by clicking "Make read-only" under the "Files" tab.</li>', 'child-theme-configurator' );
381
  case 'owner':
382
 
383
  $ctcpage = apply_filters( 'chld_thm_cfg_admin_page', CHLD_THM_CFG_MENU ); // FIXME? ?>
384
+ <p><?php _e( 'This Child Theme has incorrect ownership permissions. Child Theme Configurator will attempt to correct this when you click the button below.', 'child-theme-configurator' ) ?></p>
385
+ <p><form action="?page=<?php echo $ctcpage; ?>" method="post"><?php
386
+ wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ); ?>
387
+ <input name="ctc_reset_permission" class="button" type="submit" value="<?php _e( 'Correct Child Theme Permissions', 'child-theme-configurator' ); ?>"/></form></p><?php
388
  break;
389
 
390
 
420
 
421
  <?php if ( $child ): ?>
422
  <div class="clearfix">
 
423
  <?php endif; ?>
424
  <h3><?php _e( 'This version of Child Theme Configurator includes significant updates.', 'child-theme-configurator' ); ?></h3>
425
  <p class="howto"><?php _e( 'A lot of time and testing has gone into this release but there are always edge cases. If you have any questions, please', 'child-theme-configurator' ); ?> <a href="<?php echo LILAEAMEDIA_URL; ?>/contact" target="_blank"><?php _e( 'Contact Us.', 'child-theme-configurator' ); ?></a></p>
426
  <p class="howto"><?php _e( 'For more information, please open the Help tab at the top right or ', 'child-theme-configurator' ) ?> <a href="http://www.childthemeconfigurator.com/tutorial-videos/" target="_blank"><?php _e( 'click here to view the latest videos.', 'child-theme-configurator' ); ?></a></p>
427
  <?php if ( $child ): ?>
428
+ <p><?php _e( 'It is a good idea to save a Zip Archive of your Child Theme before using this version for the first time. Click "Export Zip" ( see Step 3, below ) to backup your themes.', 'child-theme-configurator' ); ?></p>
 
 
 
429
  </div>
430
  <?php endif; ?>
431
  <?php endswitch; ?>
includes/class-ctc.php CHANGED
@@ -11,7 +11,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
11
  if ( version_compare( $wp_version, CHLD_THM_CFG_MIN_WP_VERSION ) < 0 ):
12
  add_action( 'admin_notices', 'ChildthemeConfigurator::version_notice' );
13
  return;
14
- endif;
15
  // setup admin hooks
16
  if ( is_multisite() )
17
  add_action( 'network_admin_menu', 'ChildThemeConfigurator::network_admin' );
@@ -35,7 +35,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
35
  }
36
  static function lang() {
37
  // initialize languages
38
- load_plugin_textdomain( 'child-theme-configurator', FALSE, basename( CHLD_THM_CFG_DIR ) . '/lang' );
39
  }
40
  static function save() {
41
  // ajax write
@@ -94,7 +94,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
94
  define( 'LILAEAMEDIA_URL', "http://www.lilaeamedia.com" );
95
  defined( 'CHLD_THM_CFG_DOCS_URL' ) or
96
  define( 'CHLD_THM_CFG_DOCS_URL', "http://www.childthemeconfigurator.com" );
97
- define( 'CHLD_THM_CFG_VERSION', '2.0.2' );
98
  define( 'CHLD_THM_CFG_PREV_VERSION', '1.7.9.1' );
99
  define( 'CHLD_THM_CFG_MIN_WP_VERSION', '3.7' );
100
  defined( 'CHLD_THM_CFG_BPSEL' ) or
11
  if ( version_compare( $wp_version, CHLD_THM_CFG_MIN_WP_VERSION ) < 0 ):
12
  add_action( 'admin_notices', 'ChildthemeConfigurator::version_notice' );
13
  return;
14
+ endif;
15
  // setup admin hooks
16
  if ( is_multisite() )
17
  add_action( 'network_admin_menu', 'ChildThemeConfigurator::network_admin' );
35
  }
36
  static function lang() {
37
  // initialize languages
38
+ load_plugin_textdomain( 'child-theme-configurator', FALSE, basename( CHLD_THM_CFG_DIR ) . '/lang' );
39
  }
40
  static function save() {
41
  // ajax write
94
  define( 'LILAEAMEDIA_URL', "http://www.lilaeamedia.com" );
95
  defined( 'CHLD_THM_CFG_DOCS_URL' ) or
96
  define( 'CHLD_THM_CFG_DOCS_URL', "http://www.childthemeconfigurator.com" );
97
+ define( 'CHLD_THM_CFG_VERSION', '2.0.3' );
98
  define( 'CHLD_THM_CFG_PREV_VERSION', '1.7.9.1' );
99
  define( 'CHLD_THM_CFG_MIN_WP_VERSION', '3.7' );
100
  defined( 'CHLD_THM_CFG_BPSEL' ) or
includes/forms/files.php CHANGED
@@ -55,7 +55,7 @@ if ( !defined( 'ABSPATH' ) ) exit;
55
  <div class="ctc-input-row clearfix" id="input_row_screenshot">
56
  <div class="ctc-input-cell"> <strong>
57
  <?php _e( 'Export Child Theme as Zip Archive', 'child-theme-configurator' ); ?>
58
- </strong> </div>
59
  <div class="ctc-input-cell-wide"><?php
60
  include ( CHLD_THM_CFG_DIR . '/includes/forms/zipform.php' );
61
  ?></div>
55
  <div class="ctc-input-row clearfix" id="input_row_screenshot">
56
  <div class="ctc-input-cell"> <strong>
57
  <?php _e( 'Export Child Theme as Zip Archive', 'child-theme-configurator' ); ?>
58
+ </strong> <p class="howto"><?php _e( 'Click "Export Zip" to save a backup of the currently loaded child theme. You can export any of your themes from the Parent/Child tab.' ); ?></p></div>
59
  <div class="ctc-input-cell-wide"><?php
60
  include ( CHLD_THM_CFG_DIR . '/includes/forms/zipform.php' );
61
  ?></div>
includes/forms/parent-child.php CHANGED
@@ -74,22 +74,26 @@ if ( !defined( 'ABSPATH' ) ) exit;
74
  </div>
75
  <div class="ctc-input-row clearfix ctc-themeonly-container<?php echo $disabledclass; ?>" id="input_row_new_theme_option" style="display:none">
76
  <div class="ctc-input-cell" style="clear:both"><span class="ctc-step ctc-step-number">2</span>
77
- <strong class="shift">
78
  <?php _e( 'Select a Parent Theme:', 'child-theme-configurator' ); ?>
79
- </strong> </div>
 
 
80
  <div class="ctc-input-cell" >
81
  <?php $this->render_theme_menu( 'parnt', $this->ctc()->get_current_parent() ); ?>
82
  <input type="button" class="button button-primary ctc-analyze-theme" value="<?php _e( 'Analyze', 'child-theme-configurator' ); ?>" />
83
  </div>
84
- <div class="ctc-input-cell"><span class="ctc-analyze-howto"><span class="ctc-step ctc-step-number">3</span><strong><?php _e( 'Analyze Parent Theme', 'child-theme-configurator' ); ?></strong><p class="howto indent"><?php _e( 'Click "Analyze" to determine stylesheet dependencies and other potential issues.', 'child-theme-configurator' ); ?></p></span></div>
85
  <div class="ctc-input-cell clear">&nbsp;</div>
86
  <div class="ctc-input-cell-wide ctc-analysis" id="parnt_analysis_notice">&nbsp;</div>
87
  </div>
88
  <?php if ( '' == $hidechild ): ?>
89
  <div class="ctc-input-row clearfix ctc-themeonly-container<?php echo $disabledclass; ?>" id="input_row_existing_theme_option" style="display:none">
90
- <div class="ctc-input-cell"><span class="ctc-step ctc-step-number">2</span><strong class="shift">
91
  <?php _e( 'Select a Child Theme:', 'child-theme-configurator' ); ?>
92
- </strong> </div>
 
 
93
  <div class="ctc-input-cell">
94
  <?php $this->render_theme_menu( 'child', $this->ctc()->get_current_child() ); ?>
95
  <input type="button" class="button button-primary ctc-analyze-theme" value="<?php _e( 'Analyze', 'child-theme-configurator' ); ?>" />
74
  </div>
75
  <div class="ctc-input-row clearfix ctc-themeonly-container<?php echo $disabledclass; ?>" id="input_row_new_theme_option" style="display:none">
76
  <div class="ctc-input-cell" style="clear:both"><span class="ctc-step ctc-step-number">2</span>
77
+ <strong>
78
  <?php _e( 'Select a Parent Theme:', 'child-theme-configurator' ); ?>
79
+ </strong>
80
+ <p class="howto indent"><a href="#" class="ctc-backup-theme"><?php _e( 'Click here to save a backup of the selected theme.', 'child-theme-configurator' ); ?></a></p>
81
+ </div>
82
  <div class="ctc-input-cell" >
83
  <?php $this->render_theme_menu( 'parnt', $this->ctc()->get_current_parent() ); ?>
84
  <input type="button" class="button button-primary ctc-analyze-theme" value="<?php _e( 'Analyze', 'child-theme-configurator' ); ?>" />
85
  </div>
86
+ <div class="ctc-input-cell"><span class="ctc-analyze-howto"><span class="ctc-step ctc-step-number">3</span><strong><?php _e( 'Analyze Parent Theme', 'child-theme-configurator' ); ?></strong><p class="howto indent"><?php _e( 'Click "Analyze" to determine stylesheet dependencies and other potential issues.' ); ?></p></span></div>
87
  <div class="ctc-input-cell clear">&nbsp;</div>
88
  <div class="ctc-input-cell-wide ctc-analysis" id="parnt_analysis_notice">&nbsp;</div>
89
  </div>
90
  <?php if ( '' == $hidechild ): ?>
91
  <div class="ctc-input-row clearfix ctc-themeonly-container<?php echo $disabledclass; ?>" id="input_row_existing_theme_option" style="display:none">
92
+ <div class="ctc-input-cell"><span class="ctc-step ctc-step-number">2</span><strong>
93
  <?php _e( 'Select a Child Theme:', 'child-theme-configurator' ); ?>
94
+ </strong>
95
+ <p class="howto indent"><a href="#" class="ctc-backup-theme"><?php _e( 'Click here to save a backup of the selected theme.', 'child-theme-configurator' ); ?></a></p>
96
+ </div>
97
  <div class="ctc-input-cell">
98
  <?php $this->render_theme_menu( 'child', $this->ctc()->get_current_child() ); ?>
99
  <input type="button" class="button button-primary ctc-analyze-theme" value="<?php _e( 'Analyze', 'child-theme-configurator' ); ?>" />
includes/forms/zipform.php CHANGED
@@ -1,10 +1,9 @@
1
  <?php
2
  if ( !defined( 'ABSPATH' ) ) exit;
3
  ?>
4
- <form method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>">
5
  <?php wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ); ?>
6
- <input class="ctc_submit button button-primary"
7
- name="ctc_export_child_zip" type="submit"
8
- value="<?php _e( 'Export Zip', 'child-theme-configurator' ); ?>" />
9
  </form>
10
 
1
  <?php
2
  if ( !defined( 'ABSPATH' ) ) exit;
3
  ?>
4
+ <form id="ctc_export_theme_form" method="post" action="?page=<?php echo CHLD_THM_CFG_MENU; ?>">
5
  <?php wp_nonce_field( apply_filters( 'chld_thm_cfg_action', 'ctc_update' ) ); ?>
6
+ <input class="ctc_submit button button-primary" name="ctc_export_child_zip" type="submit" value="<?php _e( 'Export Zip', 'child-theme-configurator' ); ?>" />
7
+ <input type="hidden" id="ctc_export_theme" name="ctc_export_theme" value="" />
 
8
  </form>
9
 
includes/help/de_DE.php CHANGED
@@ -127,13 +127,13 @@ if ( !defined( 'ABSPATH' ) ) exit;
127
 
128
  <p>Wenn Sie andere Optionen setzen wollen, können Sie diese nach dem Aktivieren des Kind-Themas aktivieren, oder mittels der Live-Vorschau unter Design > Themen.</p>
129
  <ul class="instructions">
130
- <li><strong>Menüs: </strong> Gehen Sie zu Design > Menüs und klicken Sie den "Position"-Tab. Standardmäßig wird das Primärmenü die Verknüpfungen automatisch aus den bestehenden Seiten erstellen. Wählen Sie Ihr angepasstes Menü aus der Auswahlliste und klicken Sie "Neues Menü benutzen". Dies ersetzt das Standardmenü und Sie sehen die korrekten Verknüpfungen.</li>
131
 
132
- <li><strong>Header (Kopf): </strong> Gehen Sie zu Design > Header. Einige Themen zeigen standardmäßig den Titel und die Tagline Ihrer "Allgemeinen Einstellungen". Wählen Sie "Bild auswählen" und finden Sie einen "Kopf" aus der Medienbibliothek oder mittels Hochladen. Dies ersetzt den Standard mit dem angepassten Bild.</li>
133
 
134
- <li><strong>Hintergrund: </strong> Gehen Sie zu Design > Hintergrund und wählen Sie ein neues Hintergrundbild oder eine Farbe.</li>
135
 
136
- <li><strong>Optionen: </strong> Jedes Thema behandelt Optionen speziell/anders. Meistens erstellen Sie einen Satz Optionen und speichern ihn in der Wordpress-Datenbank. Einige Optionen sind spezifisch für das aktive Thema (oder Kind-Thema), und einige nur für das Eltern-Thema bestimmt (d.h. das Kind-Thema kann sie NICHT übersteuern). Sie müssen sich beim Themen-Autor erkundigen, welche auf welche Art funktionieren.</li>
137
  </ul>
138
  </p>
139
  <h5 id="existing_parent">Wie verschiebe ich bereits gemachte Änderungen an meinem Thema in mein Kind-Thema?</h5>
127
 
128
  <p>Wenn Sie andere Optionen setzen wollen, können Sie diese nach dem Aktivieren des Kind-Themas aktivieren, oder mittels der Live-Vorschau unter Design > Themen.</p>
129
  <ul class="instructions">
130
+ <li><strong>Menüs: </strong> Gehen Sie zu Design > Menüs und klicken Sie den "Position"-Tab. Standardmäßig wird das Primärmenü die Verknüpfungen automatisch aus den bestehenden Seiten erstellen. Wählen Sie Ihr angepasstes Menü aus der Auswahlliste und klicken Sie "Neues Menü benutzen". Dies ersetzt das Standardmenü und Sie sehen die korrekten Verknüpfungen.</li>
131
 
132
+ <li><strong>Header (Kopf): </strong> Gehen Sie zu Design > Header. Einige Themen zeigen standardmäßig den Titel und die Tagline Ihrer "Allgemeinen Einstellungen". Wählen Sie "Bild auswählen" und finden Sie einen "Kopf" aus der Medienbibliothek oder mittels Hochladen. Dies ersetzt den Standard mit dem angepassten Bild.</li>
133
 
134
+ <li><strong>Hintergrund: </strong> Gehen Sie zu Design > Hintergrund und wählen Sie ein neues Hintergrundbild oder eine Farbe.</li>
135
 
136
+ <li><strong>Optionen: </strong> Jedes Thema behandelt Optionen speziell/anders. Meistens erstellen Sie einen Satz Optionen und speichern ihn in der Wordpress-Datenbank. Einige Optionen sind spezifisch für das aktive Thema (oder Kind-Thema), und einige nur für das Eltern-Thema bestimmt (d.h. das Kind-Thema kann sie NICHT übersteuern). Sie müssen sich beim Themen-Autor erkundigen, welche auf welche Art funktionieren.</li>
137
  </ul>
138
  </p>
139
  <h5 id="existing_parent">Wie verschiebe ich bereits gemachte Änderungen an meinem Thema in mein Kind-Thema?</h5>
includes/help/en_US.php CHANGED
@@ -127,13 +127,13 @@ if ( !defined( 'ABSPATH' ) ) exit;
127
 
128
  <p>If you want to set different options you can either apply them after you activate the child theme, or by using the "Live Preview" under Appearance > Themes.</p>
129
  <ul class="instructions">
130
- <li><strong>Menus: </strong> Go to Appearance > Menus and click the "Locations" tab. By default, the primary menu will generate the links automatically from the existing pages. Select your customized Menu from the dropdown and click "Use New Menu." This will replace the default menu and you will see the correct links.</li>
131
 
132
- <li><strong>Header: </strong> Go to Appearance > Header. Some themes will show the "Title" and "Tagline" from your "General Settings" by default. Click "Choose Image" and find the header from the Media Library or upload a new image. This will replace default with your custom image.</li>
133
 
134
- <li><strong>Background: </strong> Go to Appearance > Background and choose a new background color or image.</li>
135
 
136
- <li><strong>Options: </strong> Every theme handles options in its own way. Most often, they will create a set of options and store them in the WordPress database. Some options are specific to the active theme (or child theme), and some are specific to the parent theme only (meaning the child theme CANNOT override them). You will have to find out from the theme author which are which.</li>
137
  </ul>
138
  </p>
139
  <h5 id="existing_parent">How do I move changes I have already made to my theme into a Child Theme?</h5>
127
 
128
  <p>If you want to set different options you can either apply them after you activate the child theme, or by using the "Live Preview" under Appearance > Themes.</p>
129
  <ul class="instructions">
130
+ <li><strong>Menus: </strong> Go to Appearance > Menus and click the "Locations" tab. By default, the primary menu will generate the links automatically from the existing pages. Select your customized Menu from the dropdown and click "Use New Menu." This will replace the default menu and you will see the correct links.</li>
131
 
132
+ <li><strong>Header: </strong> Go to Appearance > Header. Some themes will show the "Title" and "Tagline" from your "General Settings" by default. Click "Choose Image" and find the header from the Media Library or upload a new image. This will replace default with your custom image.</li>
133
 
134
+ <li><strong>Background: </strong> Go to Appearance > Background and choose a new background color or image.</li>
135
 
136
+ <li><strong>Options: </strong> Every theme handles options in its own way. Most often, they will create a set of options and store them in the WordPress database. Some options are specific to the active theme (or child theme), and some are specific to the parent theme only (meaning the child theme CANNOT override them). You will have to find out from the theme author which are which.</li>
137
  </ul>
138
  </p>
139
  <h5 id="existing_parent">How do I move changes I have already made to my theme into a Child Theme?</h5>
js/chldthmcfg.js CHANGED
@@ -2,7 +2,7 @@
2
  * Script: chldthmcfg.js
3
  * Plugin URI: http://www.childthemeconfigurator.com/
4
  * Description: Handles jQuery, AJAX and other UI
5
- * Version: 2.0.2
6
  * Author: Lilaea Media
7
  * Author URI: http://www.lilaeamedia.com/
8
  * License: GPLv2
@@ -1103,7 +1103,7 @@
1103
  } ).done( function( response ) {
1104
  //console.log( response );
1105
  self.handle_success( obj, response );
1106
- } ).fail( function( jxr, status, err ) {
1107
  //console.log( status );
1108
  //console.log( err );
1109
  self.handle_failure( obj );
@@ -1363,7 +1363,7 @@
1363
  preview: function( res ) {
1364
  $( '#view_' + res.key + '_options_panel' ).text( res.data );
1365
  },
1366
- dismiss: function( res ) {
1367
  //console.log( 'dismiss came home!' );
1368
  //console.log( res );
1369
  //var self = this;
@@ -1561,7 +1561,20 @@
1561
  $( '#ctc_new_selectors' ).val( $( '#ctc_new_selectors' ).val() + "\n" + txt + " {\n\n}" );
1562
  }
1563
  } );
1564
-
 
 
 
 
 
 
 
 
 
 
 
 
 
1565
  $( '#ctc_configtype' ).on( 'change', function( ) {
1566
  var val = $( this ).val();
1567
  if ( self.is_empty( val ) || 'theme' === val ) {
@@ -1748,10 +1761,10 @@
1748
  $.get( url, function( data ) {
1749
 
1750
  //if ( 'child' === template ) {
1751
- //console.log( data );
1752
  //}
1753
  // retrieve enqueued stylesheet ids
1754
- if ( ( queue = data.match( /BEGIN WP QUEUE\n([\n\w\-\.]*?)\nEND WP QUEUE/ ) ) ) {
1755
  analysis.queue = queue[ 1 ].split(/\n/);
1756
  //console.log( 'QUEUE:' );
1757
  //console.log( analysis.queue );
@@ -1761,7 +1774,7 @@
1761
  //analysis.signals.failure = 1;
1762
  //console.log( 'NO QUEUE' );
1763
  }
1764
- if ( ( queue = data.match( /BEGIN CTC IRREGULAR\n([\n\w\-\.,]*?)\nEND CTC IRREGULAR/ ) ) ) {
1765
  analysis.irreg = queue[ 1 ].split(/\n/);
1766
  } else {
1767
  analysis.irreg = [];
@@ -1793,9 +1806,10 @@
1793
  analysis.signals.err_php = 1;
1794
  if ( errstr.match( /Fatal error/i ) ) {
1795
  analysis.signals.err_fatal = 1;
1796
- } else if ( errstr.match( /(FileNotFoundException|Failed opening|failed to open stream)/i ) ) {
1797
- analysis.signals.err_fnf = 1;
1798
- }
 
1799
  }
1800
  while ( ( csslink = regex_link.exec( data ) ) ) {
1801
  var stylesheetid = self.trmcss( csslink[ 2 ] ),
@@ -1892,8 +1906,10 @@
1892
  data = null; // send page to garbage
1893
  self.analysis[ template ] = analysis;
1894
  $( document ).trigger( 'analysisdone' );
1895
- } ).fail( function(){
 
1896
  analysis.signals.failure = 1;
 
1897
  self.analysis[ template ] = analysis;
1898
  $( document ).trigger( 'analysisdone' );
1899
  } );
@@ -1933,8 +1949,8 @@
1933
  ( self.analysis[ template ].signals.thm_noqueue && !self.phperr[ template ].length ) ) {
1934
  notice.notices.push( {
1935
  headline: $.chldthmcfg.getxt( 'anlz4', name ),
1936
- msg: $.chldthmcfg.getxt( 'anlz5' ),
1937
- style: 'error'
1938
  } );
1939
  } else {
1940
  // test errors
@@ -2203,12 +2219,12 @@
2203
  data: data,
2204
  //dataType: 'json',
2205
  type: 'POST'
2206
- } ).done( function( response ) {
2207
  //console.log( 'resubmit done:' );
2208
  //console.log( response );
2209
  self.hide_loading();
2210
  self.do_analysis();
2211
- } ).fail( function( xhr, status, err ) {
2212
  //self.do_analysis();
2213
  self.hide_loading();
2214
  //console.log( status + ' ' + err );
2
  * Script: chldthmcfg.js
3
  * Plugin URI: http://www.childthemeconfigurator.com/
4
  * Description: Handles jQuery, AJAX and other UI
5
+ * Version: 2.0.3
6
  * Author: Lilaea Media
7
  * Author URI: http://www.lilaeamedia.com/
8
  * License: GPLv2
1103
  } ).done( function( response ) {
1104
  //console.log( response );
1105
  self.handle_success( obj, response );
1106
+ } ).fail( function() { // jxr, status, err ) {
1107
  //console.log( status );
1108
  //console.log( err );
1109
  self.handle_failure( obj );
1363
  preview: function( res ) {
1364
  $( '#view_' + res.key + '_options_panel' ).text( res.data );
1365
  },
1366
+ dismiss: function() { // res ) {
1367
  //console.log( 'dismiss came home!' );
1368
  //console.log( res );
1369
  //var self = this;
1561
  $( '#ctc_new_selectors' ).val( $( '#ctc_new_selectors' ).val() + "\n" + txt + " {\n\n}" );
1562
  }
1563
  } );
1564
+ // save theme as zip
1565
+ $( '#ctc_main' ).on( 'click', '.ctc-backup-theme', function( e ) {
1566
+ e.preventDefault();
1567
+ // copy selected theme to zip export form
1568
+ if ( self.existing ){
1569
+ $( '#ctc_export_theme' ).val( self.currchild );
1570
+ } else {
1571
+ $( '#ctc_export_theme' ).val( self.currparnt );
1572
+ }
1573
+ //console.log( 'backup clicked - theme: ' + $( '#ctc_export_theme' ).val() );
1574
+ // submit form
1575
+ $( '#ctc_export_theme_form' ).submit();
1576
+ // submit form
1577
+ } );
1578
  $( '#ctc_configtype' ).on( 'change', function( ) {
1579
  var val = $( this ).val();
1580
  if ( self.is_empty( val ) || 'theme' === val ) {
1761
  $.get( url, function( data ) {
1762
 
1763
  //if ( 'child' === template ) {
1764
+ //console.log( data );
1765
  //}
1766
  // retrieve enqueued stylesheet ids
1767
+ if ( ( queue = data.match( /BEGIN WP QUEUE\n([\s\S]*?)\nEND WP QUEUE/ ) ) ) {
1768
  analysis.queue = queue[ 1 ].split(/\n/);
1769
  //console.log( 'QUEUE:' );
1770
  //console.log( analysis.queue );
1774
  //analysis.signals.failure = 1;
1775
  //console.log( 'NO QUEUE' );
1776
  }
1777
+ if ( ( queue = data.match( /BEGIN CTC IRREGULAR\n([\s\S]*?)\nEND CTC IRREGULAR/ ) ) ) {
1778
  analysis.irreg = queue[ 1 ].split(/\n/);
1779
  } else {
1780
  analysis.irreg = [];
1806
  analysis.signals.err_php = 1;
1807
  if ( errstr.match( /Fatal error/i ) ) {
1808
  analysis.signals.err_fatal = 1;
1809
+ }
1810
+ //else if ( errstr.match( /(FileNotFoundException|Failed opening|failed to open stream)/i ) ) {
1811
+ //analysis.signals.err_fnf = 1;
1812
+ //}
1813
  }
1814
  while ( ( csslink = regex_link.exec( data ) ) ) {
1815
  var stylesheetid = self.trmcss( csslink[ 2 ] ),
1906
  data = null; // send page to garbage
1907
  self.analysis[ template ] = analysis;
1908
  $( document ).trigger( 'analysisdone' );
1909
+ } ).fail( function( xhr, status, err ){
1910
+ //console.log( xhr );
1911
  analysis.signals.failure = 1;
1912
+ analysis.signals.xhrerr = err;
1913
  self.analysis[ template ] = analysis;
1914
  $( document ).trigger( 'analysisdone' );
1915
  } );
1949
  ( self.analysis[ template ].signals.thm_noqueue && !self.phperr[ template ].length ) ) {
1950
  notice.notices.push( {
1951
  headline: $.chldthmcfg.getxt( 'anlz4', name ),
1952
+ msg: $.chldthmcfg.getxt( 'anlz5' ), // + self.analysis[ template ].signals.xhrerr,
1953
+ style: 'notice-warning'
1954
  } );
1955
  } else {
1956
  // test errors
2219
  data: data,
2220
  //dataType: 'json',
2221
  type: 'POST'
2222
+ } ).done( function() { // response ) {
2223
  //console.log( 'resubmit done:' );
2224
  //console.log( response );
2225
  self.hide_loading();
2226
  self.do_analysis();
2227
+ } ).fail( function() { // xhr, status, err ) {
2228
  //self.do_analysis();
2229
  self.hide_loading();
2230
  //console.log( status + ' ' + err );
js/chldthmcfg.min.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e){"use strict";e.chldthmcfg={escquo:function(e){var t=this;return t.is_empty(e)?e:e.toString().replace(/"/g,"&quot;")},getxt:function(e,t){var c=window.ctcAjax[e+"_txt"];return c?(t&&(c=c.replace(/%s/,t)),c):""},frascii:function(e){var t=parseInt(e),c=String.fromCharCode(t);return c},toascii:function(e){var t=e.charCodeAt(0);return t},is_empty:function(e,t){if("undefined"==typeof e||!1===e||null===e||""===e)return!0;if("undefined"!=typeof t&&"0"===e||0===e)return!0;if(!0===e||"string"==typeof e||"number"==typeof e)return!1;if("object"==typeof e){for(var c in e)if(e.hasOwnProperty(c))return!1;return!0}return!1},theme_exists:function(t,c){var n=!1;return e.each(window.ctcAjax.themes,function(i,s){return e.each(s,function(e,s){return s=null,e.toLowerCase()!==t.toLowerCase()||"parnt"!==i&&"new"!==c?void 0:(n=!0,!1)}),n?!1:void 0}),n},validate:function(){var t=this,c=/[^\w\-]/,n=e("#ctc_child_template").length?e("#ctc_child_template").val().toString().replace(c):"",i=e("#ctc_theme_child").length?e("#ctc_theme_child").val().toString().replace(c):n,s=e("input[name=ctc_child_type]:checked").val(),a=[];return"new"===s&&(i=n),t.theme_exists(i,s)&&a.push(t.getxt("theme_exists").toString().replace(/%s/,i)),t.is_empty(i)&&a.push(t.getxt("inval_theme")),a.length?(t.set_notice({error:a}),!1):"reset"===s?confirm(t.getxt("load"))?!0:!1:!0},autogen_slugs:function(){if(e("#ctc_theme_parnt").length){for(var t=this,c=e("#ctc_theme_parnt").val(),n=c+"-child",i=n,s=window.ctcAjax.themes.parnt[c].Name+" Child",a="",l="",r="00";t.theme_exists(i,"new");)a=t.is_empty(a)?2:a+1,l=r.substring(0,r.length-a.toString().length)+a.toString(),i=n+l;t.testslug=i,t.testname=s+(l.length?" "+l:"")}},focus_panel:function(t){var c=t+"_panel";e(".nav-tab").removeClass("nav-tab-active"),e(".ctc-option-panel").removeClass("ctc-option-panel-active"),e(t).addClass("nav-tab-active"),e(".ctc-option-panel-container").scrollTop(0),e(c).addClass("ctc-option-panel-active")},selector_input_toggle:function(t){var c,n=this;e("#ctc_rewrite_selector").length?(c=e("#ctc_rewrite_selector_orig").val(),e("#ctc_sel_ovrd_selector_selected").text(c),e(t).text(n.getxt("rename"))):(c=e("#ctc_sel_ovrd_selector_selected").text(),e("#ctc_sel_ovrd_selector_selected").html('<textarea id="ctc_rewrite_selector" name="ctc_rewrite_selector" autocomplete="off"></textarea><input id="ctc_rewrite_selector_orig" name="ctc_rewrite_selector_orig" type="hidden" value="'+n.escquo(c)+'"/>'),e("#ctc_rewrite_selector").val(c),e(t).text(n.getxt("cancel")))},coalesce_inputs:function(t){var c=this,n=e(t).attr("id"),i=/^(ctc_(ovrd|\d+)_(parent|child)_([0-9a-z\-]+)_(\d+?)(_(\d+))?)(_\w+)?$/,s=e(t).parents(".ctc-selector-row, .ctc-parent-row").first(),a=s.find(".ctc-swatch").first(),l={parent:{},child:{}},r={parent:{origin:"",start:"",end:""},child:{origin:"",start:"",end:""}},o={child:!1,parent:!1},_={};return s.find(".ctc-parent-value, .ctc-child-value").each(function(){var t,s,a=e(this).attr("id"),d=a.toString().match(i),u=d[2],h=d[3],p="undefined"==typeof d[4]?"":d[4],m=d[7],g=d[5],f="undefined"==typeof d[7]?"":d[8],v="parent"===h?e(this).text().replace(/!$/,""):"seq"!==p&&"ctc_delete_query_selector"===n?"":e(this).val(),y="seq"===p?!1:"ctc_"+u+"_child_"+p+"_i_"+g+"_"+m;if("child"===h&&(c.is_empty(e(this).data("color"))||(v=c.color_text(e(this).data("color")),e(this).data("color",null)),_[a]=v,y&&(_[y]=e("#"+y).is(":checked")?1:0)),""!==v)if(c.is_empty(f))if(t=p.toString().match(/^border(\-(top|right|bottom|left))?$/)&&!v.match(/none/)){var w=new RegExp(c.border_regx+c.color_regx,"i");s=v.toString().match(w),c.is_empty(s)||(s.shift(),l[h][p+"-width"]=s.shift()||"",s.shift(),l[h][p+"-style"]=s.shift()||"",l[h][p+"-color"]=s.shift()||"")}else if("background-image"!==p||v.match(/none/))"seq"!==p&&(l[h][p]=v);else if(v.toString().match(/url\(/))l[h]["background-image"]=c.image_url(h,v);else{var x=new RegExp(c.grad_regx+c.color_regx+c.color_regx,"i");s=v.toString().match(x),!c.is_empty(s)&&s.length>2?(s.shift(),r[h].origin=s.shift()||"top",r[h].start=s.shift()||"transparent",r[h].end=s.shift()||"transparent",o[h]=!0):l[h]["background-image"]=v}else switch(f){case"_border_width":l[h][p+"-width"]="none"===v?0:v;break;case"_border_style":l[h][p+"-style"]=v;break;case"_border_color":l[h][p+"-color"]=v;break;case"_background_url":l[h]["background-image"]=c.image_url(h,v);break;case"_background_color":l[h]["background-color"]=v;break;case"_background_color1":r[h].start=v,o[h]=!0;break;case"_background_color2":r[h].end=v,o[h]=!0;break;case"_background_origin":r[h].origin=v,o[h]=!0}}),"undefined"==typeof a||c.is_empty(a.attr("id"))||(a.removeAttr("style"),o.parent&&a.ctcgrad(r.parent.origin,[r.parent.start,r.parent.end]),a.css(l.parent),a.attr("id").toString().match(/parent/)||(o.child&&a.ctcgrad(r.child.origin,[r.child.start,r.child.end]),a.css(l.child)),a.css({"z-index":-1})),_},decode_value:function(e,t){t="undefined"==typeof t?"":t;var c,n=this,i={orig:t,names:[""],values:[t]};if(e.toString().match(/^border(\-(top|right|bottom|left))?$/)){var s,a=new RegExp(n.border_regx+"("+n.color_regx+")?","i");c=t.toString().match(a),n.is_empty(c)&&(c=[]),i.names=["_border_width","_border_style","_border_color"],s=c.shift(),i.values[0]=c.shift()||"",c.shift(),i.values[1]=c.shift()||"",c.shift(),i.values[2]=c.shift()||""}else if(e.toString().match(/^background\-image/))if(i.names=["_background_url","_background_origin","_background_color1","_background_color2"],i.values=["","","",""],n.is_empty(t)||t.toString().match(/(url|none)/))i.values[0]=t;else{var l,r;c=t.toString().split(/:/),i.values[1]=c.shift()||"",i.values[2]=c.shift()||"",l=c.shift()||"",i.values[3]=c.shift()||"",r=c.shift()||"",i.orig=[i.values[1],i.values[2],i.values[3]].join(" ")}return i},image_url:function(e,t){var c,n=this,i=t.toString().match(/url\(['" ]*(.+?)['" ]*\)/),s=n.is_empty(i)?null:i[1],a=window.ctcAjax.theme_uri+"/"+("parent"===e?window.ctcAjax.parnt:window.ctcAjax.child)+"/";return s?c=s.toString().match(/^(data:|https?:|\/)/)?t:"url("+a+s+")":!1},setup_menus:function(){var e=this;e.setup_query_menu(),e.setup_selector_menu(),e.setup_rule_menu(),e.setup_new_rule_menu(),e.load_queries(),e.load_rules(),e.set_query(e.currquery)},load_queries:function(){var e=this;e.query_css("queries",null)},load_selectors:function(){var e=this;e.query_css("selectors",e.currquery)},load_rules:function(){var e=this;e.query_css("rules",null)},load_selector_values:function(){var e=this;e.query_css("qsid",e.currqsid)},get_queries:function(t,c){var n=[],i=new RegExp(e.ui.autocomplete.escapeRegex(t.term),"i");e.chldthmcfg.is_empty(this.element.data("menu"))?n.push({label:window.ctcAjax.nosels_txt,value:null}):e.each(this.element.data("menu"),function(e,t){i.test(t)&&n.push({label:t,value:t})}),c(n)},get_selectors:function(t,c){var n=[],i=new RegExp(e.ui.autocomplete.escapeRegex(t.term),"i");e.chldthmcfg.is_empty(this.element.data("menu"))?n.push({label:window.ctcAjax.nosels_txt,value:null}):e.each(this.element.data("menu"),function(e,t){i.test(e)&&n.push({label:e,value:t})}),c(n)},get_rules:function(t,c){var n=[],i=new RegExp(e.ui.autocomplete.escapeRegex(t.term),"i");e.chldthmcfg.is_empty(this.element.data("menu"))?n.push({label:window.ctcAjax.nosels_txt,value:null}):e.each(this.element.data("menu"),function(e,t){i.test(e)&&n.push({label:e,value:t})}),c(n)},get_filtered_rules:function(t,c){var n=[],i=new RegExp(e.ui.autocomplete.escapeRegex(t.term),"i");e.each(e("#ctc_rule_menu").data("menu"),function(e,t){i.test(e)&&n.push({label:e,value:t})}),c(n)},merge_ruleval_arrays:function(t,c,n){var i=this,s={},a=n?c.child.pop():null;return e.each(["parnt","child"],function(t,l){i.is_empty(c[l])||e.each(c[l],function(e,t){n?parseInt(t[2])>=parseInt(a[2])&&(a[2]=parseInt(t[2])+1):(i.is_empty(s[t[2]])&&(s[t[2]]={}),s[t[2]][l]=t)})}),n&&(s[a[2]]={parnt:[],child:a}),s},input_row:function(t,c,n,i,s){var a=this,l="";if(!a.is_empty(i)&&!a.is_empty(i.value)&&!a.is_empty(i.value[c])){var r=i.value[c],o=a.merge_ruleval_arrays(c,r,s);e.each(o,function(s,r){var o=a.decode_value(c,a.is_empty(r.parnt)?"":r.parnt[0]),_=a.is_empty(r.parnt)||a.is_empty(r.parnt[1],1)?0:1,d=a.decode_value(c,a.is_empty(r.child)?"":r.child[0]),u=a.is_empty(r.child)||a.is_empty(r.child[1],1)?0:1;if(l+='<div class="ctc-'+("ovrd"===n?"input":"selector")+'-row clearfix"><div class="ctc-input-cell">',l+="ovrd"===n?c.replace(/\d+/g,a.frascii):i.selector+'<br/><a href="#" class="ctc-selector-edit" id="ctc_selector_edit_'+t+'" >'+a.getxt("edit")+"</a> "+(a.is_empty(o.orig)?a.getxt("child_only"):""),l+='</div><div class="ctc-parent-value ctc-input-cell"'+("ovrd"!==n?' style="display:none"':"")+' id="ctc_'+n+"_parent_"+c+"_"+t+"_"+s+'">'+(a.is_empty(o.orig)?"[no value]":o.orig+(_?a.getxt("important"):""))+'</div><div class="ctc-input-cell">',!a.is_empty(o.names)){e.each(o.names,function(e,i){i=a.is_empty(i)?"":i,l+='<div class="ctc-child-input-cell clear">';var r,o="ctc_"+n+"_child_"+c+"_"+t+"_"+s+i;!1===(r=d.values.shift())&&(r=""),l+=(a.is_empty(i)?"":a.getxt(i)+":<br/>")+'<input type="text" id="'+o+'" name="'+o+'" class="ctc-child-value'+((i+c).toString().match(/color/)?" color-picker":"")+(i.toString().match(/url/)?" ctc-input-wide":"")+'" value="'+a.escquo(r)+'" /></div>'});var h="ctc_"+n+"_child_"+c+"_i_"+t+"_"+s;l+='<label for="'+h+'"><input type="checkbox" id="'+h+'" name="'+h+'" value="1" '+(u?"checked":"")+" />"+a.getxt("important")+"</label>"}l+="</div>","ovrd"!==n&&(l+='<div class="ctc-swatch ctc-specific" id="ctc_child_'+c+"_"+t+"_"+s+'_swatch">'+a.getxt("swatch")+'</div><div class="ctc-child-input-cell ctc-button-cell" id="ctc_save_'+c+"_"+t+"_"+s+'_cell"><input type="button" class="button ctc-save-input" id="ctc_save_'+c+"_"+t+"_"+s+'" name="ctc_save_'+c+"_"+t+"_"+s+'" value="Save" /></div>'),l+="</div><!-- end input row -->\n"})}return l},scrolltop:function(){e("html, body, .ctc-option-panel-container").animate({scrollTop:0})},css_preview:function(e){var t=this;(e=e.match(/(child|parnt)/)[1])||(e="child"),t.query_css("preview",e)},setup_iris:function(e){var t=this;t.setup_spectrum(e)},setup_spectrum:function(t){var c=this,n=!c.is_empty(window.ctcAjax.palette);try{e(t).spectrum({showInput:!0,allowEmpty:!0,showAlpha:!0,showInitial:!0,preferredFormat:"hex",clickoutFiresChange:!0,move:function(n){e(t).data("color",n),c.coalesce_inputs(t)},showPalette:n?!0:!1,showSelectionPalette:n?!0:!1,palette:[],maxSelectionSize:36,localStorageKey:"ctc-palette."+window.ctcAjax.child,hideAfterPaletteSelect:!0}).on("change",function(){c.coalesce_inputs(this)}).on("keyup",function(){var t=this,n=c.addhash(e(this).val());e(t).val(n),clearTimeout(e(this).data("spectrumTimer")),e(this).data("spectrumTimer",setTimeout(function(){c.coalesce_inputs(t),e(t).spectrum("set",n)},500))})}catch(i){c.jquery_exception(i,"Spectrum Color Picker")}},addhash:function(e){return e.replace(/^#?([a-f0-9]{3,6}.*)/,"#$1")},color_text:function(e){var t=this;return t.is_empty(e)?"":e.getAlpha()<1?e.toRgbString():e.toHexString()},setup_query_menu:function(){var t=this;try{e("#ctc_sel_ovrd_query").autocomplete({source:t.get_queries,minLength:0,selectFirst:!0,autoFocus:!0,select:function(e,c){return t.set_query(c.item.value),!1},focus:function(e){e.preventDefault()}}).data("menu",{})}catch(c){t.jquery_exception(c,"Query Menu")}},setup_selector_menu:function(){var t=this;try{e("#ctc_sel_ovrd_selector").autocomplete({source:t.get_selectors,selectFirst:!0,autoFocus:!0,select:function(e,c){return t.set_selector(c.item.value,c.item.label),!1},focus:function(e){e.preventDefault()}}).data("menu",{})}catch(c){t.jquery_exception(c,"Selector Menu")}},setup_rule_menu:function(){var t=this;try{e("#ctc_rule_menu").autocomplete({source:t.get_rules,selectFirst:!0,autoFocus:!0,select:function(e,c){return t.set_rule(c.item.value,c.item.label),!1},focus:function(e){e.preventDefault()}}).data("menu",{})}catch(c){t.jquery_exception(c,"Property Menu")}},setup_new_rule_menu:function(){var t=this;try{e("#ctc_new_rule_menu").autocomplete({source:t.get_filtered_rules,selectFirst:!0,autoFocus:!0,select:function(c,n){c.preventDefault();var i,s,a=n.item.label.replace(/[^\w\-]/g,t.toascii);return t.is_empty(t.currdata.value)&&(t.currdata.value={}),t.is_empty(t.currdata.value[n.item.label])&&(t.currdata.value[n.item.label]={}),t.is_empty(t.currdata.value[n.item.label].child)&&(t.currdata.value[n.item.label].child=[]),t.currdata.value[n.item.label].child.push(["",0,1,1]),i=e(t.input_row(t.currqsid,a,"ovrd",t.currdata,!0)),e("#ctc_sel_ovrd_rule_inputs").append(i),e("#ctc_new_rule_menu").val(""),i.find('input[type="text"]').each(function(c,n){s||(s=n),e(n).hasClass("color-picker")&&t.setup_spectrum(n)}),s&&e(s).focus(),!1},focus:function(e){e.preventDefault()}}).data("menu",{})}catch(c){t.jquery_exception(c,"New Property Menu")}},set_theme_params:function(t,c){e("#ctc_child_author").val(window.ctcAjax.themes[t][c].Author),e("#ctc_child_version").val(window.ctcAjax.themes[t][c].Version),e("#ctc_child_authoruri").val(window.ctcAjax.themes[t][c].AuthorURI),e("#ctc_child_themeuri").val(window.ctcAjax.themes[t][c].ThemeURI),e("#ctc_child_descr").val(window.ctcAjax.themes[t][c].Descr),e("#ctc_child_tags").val(window.ctcAjax.themes[t][c].Tags)},update_form:function(){var t,c=this;e("#input_row_stylesheet_handling_container,#input_row_parent_handling_container,#ctc_additional_css_files_container,#input_row_new_theme_slug,#input_row_duplicate_theme_slug,#ctc_copy_theme_mods,#ctc_child_header_parameters,#ctc_configure_submit,#input_row_theme_slug").slideUp("fast"),e("#ctc_configure_submit .ctc-step").text("9"),e("#ctc_theme_child").length&&!e("#ctc_child_type_new").is(":checked")?(t=e("#ctc_theme_child").val(),c.existing=1,c.currparnt=window.ctcAjax.themes.child[t].Template,c.autogen_slugs(),e("#ctc_theme_parnt").val(c.currparnt),e("#ctc_theme_parnt-button .ui-selectmenu-text").text(window.ctcAjax.themes.parnt[c.currparnt].Name),c.set_theme_params("child",t),e("#ctc_child_type_duplicate").is(":checked")?(e("#ctc_child_template").val(c.testslug),e("#ctc_child_name").val(c.testname),e(".ctc-analyze-theme, .ctc-analyze-howto").show(),e("#ctc_load_styles").val("Duplicate Child Theme")):e("#ctc_child_type_reset").is(":checked")?(e("#ctc_configure_submit .ctc-step").text("3"),e("#ctc_configure_submit").slideDown("fast"),e("#theme_slug_container").text(t),e(".ctc-analyze-theme, .ctc-analyze-howto").hide(),e("#ctc_enqueue_none").prop("checked",!0),e("#ctc_load_styles").val("Reset Child Theme to Previous State")):(e("#ctc_child_template").val(""),e("#theme_slug_container").text(t),e(".ctc-analyze-theme, .ctc-analyze-howto").show(),e("#ctc_child_name").val(window.ctcAjax.themes.child[t].Name),e("#ctc_load_styles").val("Configure Child Theme")),e("#input_row_existing_theme_option").slideDown("fast"),e("#input_row_new_theme_option").slideUp("fast")):(c.existing=0,c.autogen_slugs(),e("#ctc_theme_parnt").val(c.currparnt),e("#ctc_theme_parnt-button .ui-selectmenu-text").text(window.ctcAjax.themes.parnt[c.currparnt].Name),c.set_theme_params("parnt",c.currparnt),e("#input_row_existing_theme_option,#input_row_duplicate_theme_container,#input_row_theme_slug").slideUp("fast"),e("#input_row_new_theme_option").slideDown("fast"),e("#ctc_child_name").val(c.testname),e("#ctc_child_template").val(c.testslug),e(".ctc-analyze-theme, .ctc-analyze-howto").show(),e("#ctc_load_styles").val("Create New Child Theme"))},set_notice:function(t){var c,n=this,i="";n.is_empty(t)||e.each(t,function(t,c){i+='<div class="'+t+' notice is-dismissible dashicons-before"><ul>\n',e(c).each(function(e,t){i+="<li>"+t.toString()+"</li>\n"}),i+="</ul></div>"}),c=e(i),e("#ctc_error_notice").html(c),n.bind_dismiss(c),e("html, body").animate({scrollTop:0},"slow")},set_parent_menu:function(e){var t=this;t.currparnt=e.value,t.update_form()},set_child_menu:function(e){var t=this;t.currchild=e.value,t.update_form()},set_query:function(t){var c=this;return c.is_empty(t)?!1:(c.currquery=t,e("#ctc_sel_ovrd_query").val(""),e("#ctc_sel_ovrd_query_selected").text(t),e("#ctc_sel_ovrd_selector").val(""),e("#ctc_sel_ovrd_selector_selected").html("&nbsp;"),c.load_selectors(),void c.scrolltop())},set_selector:function(t,c){var n=this;return c=null,n.is_empty(t)?!1:(e("#ctc_sel_ovrd_selector").val(""),n.currqsid=t,n.reload=!1,n.load_selector_values(),void n.scrolltop())},set_rule:function(t,c){var n=this;return n.is_empty(t)?!1:(e("#ctc_rule_menu").val(""),e("#ctc_rule_menu_selected").text(c),e(".ctc-rewrite-toggle").text(n.getxt("rename")),e("#ctc_rule_value_inputs, #ctc_input_row_rule_header").show(),n.query_css("rule_val",t),void n.scrolltop())},set_qsid:function(t){var c=this;c.currqsid=e(t).attr("id").match(/_(\d+)$/)[1],c.focus_panel("#query_selector_options"),c.reload=!0,c.load_selector_values()},query_css:function(t,c,n){var i=this,s={ctc_query_obj:t,ctc_query_key:c},a="#ctc_status_"+t+("val_qry"===t?"_"+c:"");"object"==typeof n&&e.each(n,function(e,t){s["ctc_query_"+e]=t}),e(".query-icon,.ctc-status-icon").remove(),e(a+" .ctc-status-icon").remove(),e(a).append('<span class="ctc-status-icon spinner is-active query-icon"></span>'),s.action=i.is_empty(e("#ctc_action").val())||"plugin"!==e("#ctc_action").val()?"ctc_query":"ctc_plgqry",s._wpnonce=e("#_wpnonce").val(),i.ajax_post(t,s)},save:function(t){var c,n,i,s,a,l=this,r={},o=e(t).attr("id");e(t).prop("disabled",!0),e(".ctc-query-icon,.ctc-status-icon").remove(),e(t).parent(".ctc-textarea-button-cell, .ctc-button-cell").append('<span class="ctc-status-icon spinner save-icon"></span>'),o.match(/ctc_configtype/)?(e(t).parents(".ctc-input-row").first().append('<span class="ctc-status-icon spinner save-icon"></span>'),r.ctc_configtype=e(t).val()):(c=e("#ctc_new_selectors"))&&"ctc_save_new_selectors"===e(t).attr("id")?(r.ctc_new_selectors=c.val(),(n=e("#ctc_sel_ovrd_query_selected"))&&(r.ctc_sel_ovrd_query=n.text()),l.reload=!0):(i=e("#ctc_child_imports"))&&"ctc_save_imports"===o?r.ctc_child_imports=i.val():"ctc_is_debug"===o?r.ctc_is_debug=e("#ctc_is_debug").is(":checked")?1:0:r=l.coalesce_inputs(t),e(".save-icon").addClass("is-active"),e("#ctc_sel_ovrd_selector_selected").find("#ctc_rewrite_selector").each(function(){s=e("#ctc_rewrite_selector").val(),a=e("#ctc_rewrite_selector_orig").val(),l.is_empty(s)||!s.toString().match(/\w/)?s=a:(r.ctc_rewrite_selector=s,l.reload=!0),e(".ctc-rewrite-toggle").text(l.getxt("rename")),e("#ctc_sel_ovrd_selector_selected").html(s)}),r.action=l.is_empty(e("#ctc_action").val())||"plugin"!==e("#ctc_action").val()?"ctc_update":"ctc_plugin",r._wpnonce=e("#_wpnonce").val(),l.ajax_post("qsid",r)},ajax_post:function(t,c,n){var i=this;e.ajax({url:window.ctcAjax.ajaxurl,data:c,dataType:i.is_empty(n)?"json":n,type:"POST"}).done(function(e){i.handle_success(t,e)}).fail(function(){i.handle_failure(t)}).always(function(){i.jqueryerr.length&&i.jquery_notice()})},handle_failure:function(t){var c=this;e(".query-icon, .save-icon").removeClass("spinner").addClass("failure"),e("input[type=submit], input[type=button], input[type=checkbox],.ctc-delete-input").prop("disabled",!1),e(".ajax-pending").removeClass("ajax-pending"),"preview"===t&&e("#view_parnt_options_panel,#view_child_options_panel").text(c.getxt("css_fail"))},handle_success:function(t,c){var n=this;e(".query-icon, .save-icon").removeClass("spinner"),e(".ajax-pending").removeClass("ajax-pending"),n.is_empty(c)?n.handle_failure(t):(e("#ctc_new_selectors").val(""),e(".query-icon, .save-icon").addClass("success"),e("input[type=submit], input[type=button], input[type=checkbox],.ctc-delete-input").prop("disabled",!1),e(c).each(function(){"function"==typeof n.update[this.obj]&&n.update[this.obj].call(n,this)}))},jquery_exception:function(e,t){var c=this,n=c.is_empty(e.lineNumber)?"":" line: "+e.lineNumber,i=c.is_empty(e.fileName)?"":" "+e.fileName.split(/\?/)[0];c.jqueryerr.push("<code><small>"+t+": "+e.message+i+n+"</small></code>")},jquery_notice:function(t){t=null;var c=this,n=[],i=[];c.jqueryerr.length&&(e("input[type=submit], input[type=button]").prop("disabled",!0),e("script").each(function(){var t=e(this).prop("src");c.is_empty(t)||!t.match(/jquery(\.min|\.js|\-?ui)/i)||t.match(/load\-scripts.php/)||n.push("<code><small>"+t.split(/\?/)[0]+"</small></code>")}),i.push("<strong>"+c.getxt("js")+"</strong> "+c.getxt("contact")),i.push(c.jqueryerr.join("<br/>")),n.length&&i.push(c.getxt("jquery")+"<br/>"+n.join("<br/>")),i.push(c.getxt("plugin"))),c.set_notice({error:i})},update:{qsid:function(t){var c,n,i,s,a=this;a.currqsid=t.key,a.currdata=t.data,e("#ctc_sel_ovrd_qsid").val(a.currqsid),a.is_empty(a.currdata.seq)?e("#ctc_child_load_order_container").empty():(c="ctc_ovrd_child_seq_"+a.currqsid,i=parseInt(a.currdata.seq),n='<input type="text" id="'+c+'" name="'+c+'" class="ctc-child-value" value="'+i+'" />',e("#ctc_child_load_order_container").html(n)),a.is_empty(a.currdata.value)?(s=!0,e("#ctc_sel_ovrd_rule_inputs").empty()):(s=!1,n="",e.each(a.currdata.value,function(e,t){t=null,n+=a.input_row(a.currqsid,e,"ovrd",a.currdata)}),e("#ctc_sel_ovrd_rule_inputs").html(n).find(".color-picker").each(function(){a.setup_spectrum(this)}),a.coalesce_inputs("#ctc_child_all_0_swatch")),a.reload&&(a.load_queries(),a.set_query(a.currdata.query),a.load_rules()),e("#ctc_sel_ovrd_selector_selected").text(a.currdata.selector),e(".ctc-rewrite-toggle").text(a.getxt("rename")),e(".ctc-rewrite-toggle").show(),s?e("#ctc_sel_ovrd_rule_header,#ctc_sel_ovrd_new_rule,#ctc_sel_ovrd_rule_inputs_container,#ctc_sel_ovrd_rule_inputs").hide():e("#ctc_sel_ovrd_rule_header,#ctc_sel_ovrd_new_rule,#ctc_sel_ovrd_rule_inputs_container,#ctc_sel_ovrd_rule_inputs").show()},rule_val:function(t){var c=this,n=e("#ctc_rule_menu_selected").text(),i='<div class="ctc-input-row clearfix" id="ctc_rule_row_'+n+'">\n';c.is_empty(t.data)||(e.each(t.data,function(e,t){var s=c.decode_value(n,t);i+='<div class="ctc-parent-row clearfix" id="ctc_rule_row_'+n+"_"+e+'">\n<div class="ctc-input-cell ctc-parent-value" id="ctc_'+e+"_parent_"+n+"_"+e+'">'+s.orig+'</div>\n<div class="ctc-input-cell">\n<div class="ctc-swatch ctc-specific" id="ctc_'+e+"_parent_"+n+"_"+e+'_swatch">'+c.getxt("swatch")+'</div></div>\n<div class="ctc-input-cell"><a href="#" class="ctc-selector-handle" id="ctc_selector_'+n+"_"+e+'">'+c.getxt("selector")+'</a></div>\n<div id="ctc_selector_'+n+"_"+e+'_container" class="ctc-selector-container">\n<a href="#" id="ctc_selector_'+n+"_"+e+'_close" class="ctc-selector-handle ctc-exit" title="'+c.getxt("close")+'"></a><div id="ctc_selector_'+n+"_"+e+'_inner_container" class="ctc-selector-inner-container clearfix">\n<div id="ctc_status_val_qry_'+e+'"></div>\n<div id="ctc_selector_'+n+"_"+e+'_rows"></div>\n</div></div></div>\n'}),i+="</div>\n"),e("#ctc_rule_value_inputs").html(i).find(".ctc-swatch").each(function(){c.coalesce_inputs(this)})},val_qry:function(t){var c,n,i=this,s="";i.is_empty(t.data)||e.each(t.data,function(n,a){c=n,e.each(a,function(c,a){s+='<h4 class="ctc-query-heading">'+c+"</h4>\n",i.is_empty(a)||e.each(a,function(e,c){s+=i.input_row(e,n,t.key,c)})})}),n="#ctc_selector_"+c+"_"+t.key+"_rows",e(n).html(s).find(".color-picker").each(function(){i.setup_spectrum(this)}),e(n).find(".ctc-swatch").each(function(){i.coalesce_inputs(this)})},queries:function(t){e("#ctc_sel_ovrd_query").data("menu",t.data)},selectors:function(t){e("#ctc_sel_ovrd_selector").data("menu",t.data)},rules:function(t){e("#ctc_rule_menu").data("menu",t.data)},debug:function(t){e("#ctc_debug_container").html(t.data)},preview:function(t){e("#view_"+t.key+"_options_panel").text(t.data)},dismiss:function(){}},bind_dismiss:function(t){var c=this,n=e(t),i=e('<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>'),s=window.commonL10n.dismiss||"";i.find(".screen-reader-text").text(s),n.append(i),i.on("click.wp-dismiss-notice",function(e){e.preventDefault(),c.dismiss_notice(t)})},dismiss_notice:function(t){e(t).fadeTo(100,0,function(){e(this).slideUp(100,function(){e(this).remove()})})},reset_handling:function(){e("#parnt_analysis_notice .notice, #child_analysis_notice .notice").slideUp(),e("#ctc_enqueue_enqueue").prop("checked",!0),e("#ctc_handling_primary").prop("checked",!0),e("#ctc_ignoreparnt").prop("checked",!1),e("#ctc_repairheader").prop("checked",!1)},init:function(){var t=this;if(!e("#ctc_theme_parnt").is("input")){try{e.widget("ctc.themeMenu",e.ui.selectmenu,{_renderItem:function(t,c){var n=e("<li>"),i=c.value.replace(/[^\w\-]/,"");return e("#ctc_theme_option_"+i).detach().appendTo(n),n.appendTo(t)}})}catch(c){t.jquery_exception(c,"Theme Menu")}try{e("#ctc_theme_parnt").themeMenu({select:function(e,c){t.reset_handling(),t.set_parent_menu(c.item)}})}catch(c){"function"==typeof themeMenu?e("#ctc_theme_parnt").themeMenu("destroy"):e("#ctc_theme_parnt-button").remove(),t.jquery_exception(c,"Parent Theme Menu")}if(t.is_empty(window.ctcAjax.themes.child))e("#ctc_child_name").length&&(e("#ctc_child_name").val(t.testname),e("#ctc_child_template").val(t.testslug));else try{e("#ctc_theme_child").themeMenu({select:function(e,c){t.reset_handling(),t.set_child_menu(c.item)}})}catch(c){"function"==typeof themeMenu?e("#ctc_theme_child").themeMenu("destroy"):e("#ctc_theme_child-button").remove(),t.jquery_exception(c,"Child Theme Menu")}}t.currparnt=e("#ctc_theme_parnt").val(),t.currchild=e("#ctc_theme_child").length?e("#ctc_theme_child").val():"",e("#ctc_main").on("click",".ctc-section-toggle",function(t){t.preventDefault(),e(this).parents(".ctc-input-row, .notice-warning, .updated, .error").first().find(".ctc-section-toggle").each(function(){e(this).toggleClass("open")});var c=e(this).attr("id").replace(/\d$/,"")+"_content";return e("#"+c).stop().slideToggle("fast"),!1}),e("#ctc_main").on("click",".ctc-upgrade-notice .notice-dismiss",function(){var c={action:"ctc_dismiss",_wpnonce:e("#_wpnonce").val()};t.ajax_post("dismiss",c)}),t.is_empty(t.jqueryerr)&&(e("#ctc_main").on("click",".ctc-selector-handle",function(c){if(c.preventDefault(),e(this).hasClass("ajax-pending"))return!1;e(this).addClass("ajax-pending");var n,i,s=e(this).attr("id").toString().replace("_close",""),a=s.toString().match(/_([^_]+)_(\d+)$/);e("#"+s+"_container").is(":hidden")&&(t.is_empty(a[1])||t.is_empty(a[2])||(n=a[1],i=a[2],t.query_css("val_qry",i,{rule:n}))),e("#"+s+"_container").fadeToggle("fast"),e(".ctc-selector-container").not("#"+s+"_container").fadeOut("fast")}),e("#ctc_main").on("click",".ctc-save-input[type=button], .ctc-delete-input",function(c){return c.preventDefault(),e(this).hasClass("ajax-pending")?!1:(e(this).addClass("ajax-pending"),t.save(this),!1)}),e("#ctc_main").on("keydown",".ctc-selector-container .ctc-child-value[type=text]",function(c){if(13===c.which){var n=e(this).parents(".ctc-selector-row").find(".ctc-save-input[type=button]").first();if(n.length)return c.preventDefault(),n.hasClass("ajax-pending")?!1:(n.addClass("ajax-pending"),t.save(n),!1)}}),e("#ctc_main").on("click",".ctc-selector-edit",function(c){return c.preventDefault(),e(this).hasClass("ajax-pending")?!1:(e(this).addClass("ajax-pending"),void t.set_qsid(this))}),e("#ctc_main").on("click",".ctc-rewrite-toggle",function(e){e.preventDefault(),t.selector_input_toggle(this)}),e("#ctc_main").on("click","#ctc_copy_selector",function(){var c=e("#ctc_sel_ovrd_selector_selected").text().trim();t.is_empty(c)||e("#ctc_new_selectors").val(e("#ctc_new_selectors").val()+"\n"+c+" {\n\n}")}),e("#ctc_configtype").on("change",function(){var c=e(this).val();if(t.is_empty(c)||"theme"===c){e(".ctc-theme-only, .ctc-themeonly-container").removeClass("ctc-disabled"),e(".ctc-theme-only, .ctc-themeonly-container input").prop("disabled",!1);try{e("#ctc_theme_parnt, #ctc_theme_child").themeMenu("enable")}catch(n){t.jquery_exception(n,"Theme Menu")}}else{e(".ctc-theme-only, .ctc-themeonly-container").addClass("ctc-disabled"),e(".ctc-theme-only, .ctc-themeonly-container input").prop("disabled",!0);try{e("#ctc_theme_parnt, #ctc_theme_child").themeMenu("disable")}catch(n){t.jquery_exception(n,"Theme Menu")}}}),e(".nav-tab").on("click",function(c){c.preventDefault(),e(".ctc-query-icon,.ctc-status-icon").remove();var n="#"+e(this).attr("id");t.focus_panel(n)}),e("#view_child_options, #view_parnt_options").on("click",function(){return e(this).hasClass("ajax-pending")?!1:(e(this).addClass("ajax-pending"),void t.css_preview(e(this).attr("id")))}),e("#ctc_load_form").on("submit",function(){return t.validate()}),e("#ctc_query_selector_form").on("submit",function(c){c.preventDefault();var n=e("#ctc_save_query_selector");return n.hasClass("ajax-pending")?!1:(n.addClass("ajax-pending"),t.save(n),!1)}),e("#ctc_rule_value_form").on("submit",function(e){return e.preventDefault(),!1}),e("#ctc_child_type_new,#ctc_child_type_existing,#ctc_child_type_duplicate,#ctc_child_type_reset").on("focus click",function(){t.reset_handling(),t.update_form()}),e("#ctc_is_debug").on("change",function(){t.save(this)}),e(".ctc-live-preview").on("click",function(t){return t.stopImmediatePropagation(),t.preventDefault(),document.location=e(this).prop("href"),!1}),t.setup_menus(),e("input[type=submit], input[type=button]").prop("disabled",!1),t.scrolltop(),t.update_form()),t.jqueryerr.length&&t.jquery_notice()},testslug:"",testname:"",reload:!1,currquery:"base",currqsid:null,currdata:{},currparnt:"",currchild:"",existing:!1,jqueryerr:[],color_regx:"\\s+(\\#[a-f0-9]{3,6}|rgba?\\([\\d., ]+?\\)|hsla?\\([\\d%., ]+?\\)|[a-z]+)",border_regx:"(\\w+)(\\s+(\\w+))?",grad_regx:"(\\w+)"},e.chldthmanalyze={escrgx:function(e){return e.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")},trmcss:function(e){return"undefined"==typeof e?"":e.replace(/\-css$/,"")},show_loading:function(t){var c=e.chldthmcfg.existing?"child":"parnt",n="child"===c?e.chldthmcfg.currchild:e.chldthmcfg.currparnt,i=window.ctcAjax.themes[c][n].Name,s='<strong class="ctc_analyze_loading"><span class="spinner is-active"></span>'+e.chldthmcfg.getxt(t?"anlz1":"anlz2")+" "+i+"...</strong>";self.noticediv="",e("#"+c+"_analysis_notice").html(s)},hide_loading:function(){e(".ctc_analyze_loading").fadeTo(200,0,function(){e(this).slideUp(200,function(){e(this).remove()})})},setssl:function(e){return e.replace(/^https?/,window.ctcAjax.ssl?"https":"http")},analyze_theme:function(t){var c,n,i,s=this,a=Math.floor(e.now()/1e3),l="child"===t?e.chldthmcfg.currchild:e.chldthmcfg.currparnt,r="&template="+e.chldthmcfg.currparnt+"&stylesheet="+l+"&now="+a,o=s.setssl(window.ctcAjax.homeurl),_=window.ctcAjax.theme_uri.replace(/^https?:\/\//,""),d=o+r,u=s.escrgx(e.chldthmcfg.currparnt)+("child"===t?"|"+s.escrgx(l):""),h=new RegExp("<link( rel=[\"']stylesheet[\"'] id=['\"]([^'\"]+?)['\"])?[^>]+?"+s.escrgx(_)+"/("+u+")/([^\"']+\\.css)(\\?[^\"']+)?[\"'][^>]+>","gi"),p=/<br \/>\n[^\n]+?(fatal|strict|notice|warning|error)[\s\S]+?<br \/>/gi,m=0,g=0,f={deps:[[],[]],signals:{},queue:[],irreg:[]};e.get(d,function(a){for((n=a.match(/BEGIN WP QUEUE\n([\n\w\-\.]*?)\nEND WP QUEUE/))?f.queue=n[1].split(/\n/):(f.queue=[],f.signals.thm_noqueue=1),(n=a.match(/BEGIN CTC IRREGULAR\n([\n\w\-\.,]*?)\nEND CTC IRREGULAR/))?f.irreg=n[1].split(/\n/):f.irreg=[],a.match(/CHLD_THM_CFG_IGNORE_PARENT/)&&(f.signals.thm_ignoreparnt=1),a.match(/IS_CTC_THEME/)&&(f.signals.thm_is_ctc=1),a.match(/NO_CTC_STYLES/)&&(f.signals.thm_no_styles=1),a.match(/HAS_CTC_IMPORT/)&&(f.signals.thm_has_import=1),a=a.replace(/<!\-\-[\s\S]*?\-\->/g,"");c=p.exec(a);){var l=c[0].replace(/<.*?>/g,"");s.phperr[t].push(l),f.signals.err_php=1,l.match(/Fatal error/i)?f.signals.err_fatal=1:l.match(/(FileNotFoundException|Failed opening|failed to open stream)/i)&&(f.signals.err_fnf=1)}for(;i=h.exec(a);){var r=s.trmcss(i[2]),o=i[3],_=i[4],d=e.chldthmcfg.currparnt===o?"parnt":"child",u=0;if(""===r||-1===e.inArray(r,f.queue))u=1;else if(0===r.indexOf("chld_thm_cfg")){_.match(/^ctc\-style([\-\.]min)?\.css$/)?(m=1,f.signals.ctc_sep_loaded=1):_.match(/^ctc\-genesis([\-\.]min)?\.css$/)?(m=1,f.signals.ctc_gen_loaded=1):r.match(/$chld_thm_cfg_ext/)?(f.signals.ctc_ext_loaded=1,f.deps[m].push([r,_])):"chld_thm_cfg_child"===r?(f.signals.ctc_child_loaded=1,
2
- f.deps[m].push([r,_])):"chld_thm_cfg_parent"===r&&(f.signals.ctc_parnt_loaded=1,f.deps[m].push([r,_]),m&&(f.signals.ctc_parnt_reorder=1));continue}if(_.match(/^style([\-\.]min)?\.css$/))m=1,"parnt"===d?f.signals.thm_parnt_loaded=u?"thm_unregistered":r:f.signals.thm_child_loaded=u?"thm_unregistered":r,u?g?(f.signals.thm_past_wphead=1,f.deps[m].push(["thm_past_wphead",_])):(f.signals.thm_unregistered=1,f.deps[m].push(["thm_unregistered",_])):f.deps[m].push([r,_]);else if("ctc-test.css"===_)g=1;else{var v=null;u&&(v="dep_unregistered"),g&&(v=m?"css_past_wphead":"dep_past_wphead"),v&&(f.signals[v]=1,r=v),f.deps[m].push([r,_])}}m||(f.signals.thm_notheme=1),a=null,s.analysis[t]=f,e(document).trigger("analysisdone")}).fail(function(){f.signals.failure=1,s.analysis[t]=f,e(document).trigger("analysisdone")})},css_notice:function(){var t,c=this,n=e.chldthmcfg.existing?"child":"parnt",i="child"===n?e.chldthmcfg.currchild:e.chldthmcfg.currparnt,s=window.ctcAjax.themes[n][i].Name,a="",l={notices:[]},r={style:"notice-warning",headline:e.chldthmcfg.getxt("anlz3",s),errlist:""},o=0,_={};if(e(window.ctcAjax.addl_css).each(function(t,c){e("#ctc_stylesheet_files .ctc_checkbox").each(function(){c===e(this).val()&&e(this).prop("checked",!0)})}),c.analysis[n].signals.failure||c.analysis[n].signals.thm_noqueue&&!c.phperr[n].length)l.notices.push({headline:e.chldthmcfg.getxt("anlz4",s),msg:e.chldthmcfg.getxt("anlz5"),style:"error"});else{if(c.phperr[n].length&&(e.each(c.phperr[n],function(t,c){c.match(/Fatal error/i)&&(r.style="error",r.headline=e.chldthmcfg.getxt("anlz8",s)),r.errlist+=c+"\n"}),r.msg='<div style="background-color:#ffeebb;padding:6px"><div class="ctc-section-toggle" id="ctc_analysis_errs">'+e.chldthmcfg.getxt("anlz6")+'</div><div id="ctc_analysis_errs_content" style="display:none"><textarea>'+r.errlist+"</textarea></div></div>"+e.chldthmcfg.getxt("anlz7"),l.notices.push(r)),(c.analysis[n].signals.thm_past_wphead||c.analysis[n].signals.dep_past_wphead)&&(l.notices.push({headline:e.chldthmcfg.getxt("anlz9"),style:"notice-warning",msg:e.chldthmcfg.getxt("anlz10")}),e("#ctc_repairheader").prop("checked",!0),e("#ctc_repairheader_container").show()),c.analysis[n].signals.thm_unregistered&&(c.analysis[n].signals.ctc_child_loaded||c.analysis[n].signals.ctc_sep_loaded||(l.notices.push({headline:e.chldthmcfg.getxt("anlz11"),style:"notice-warning",msg:e.chldthmcfg.getxt("anlz12")}),e("#ctc_repairheader_container").show(),e("#ctc_repairheader").prop("checked",!0))),"child"===n&&(c.analysis.child.signals.ctc_parnt_reorder&&(o=1),c.analysis.child.signals.ctc_child_loaded||c.analysis.child.signals.ctc_sep_loaded||c.analysis.child.signals.thm_child_loaded||(l.notices.push({headline:e.chldthmcfg.getxt("anlz13"),style:"notice-warning",msg:e.chldthmcfg.getxt("anlz14")}),o=1),c.analysis[n].signals.ctc_gen_loaded&&l.notices.push({headline:e.chldthmcfg.getxt("anlz31"),msg:e.chldthmcfg.getxt("anlz32"),style:"notice-warning"}),c.analysis.parnt.signals.thm_no_styles||c.analysis.child.signals.ctc_gen_loaded||c.analysis.child.signals.thm_parnt_loaded||c.analysis.child.signals.ctc_parnt_loaded||c.analysis.child.signals.thm_ignoreparnt||c.analysis.child.signals.thm_has_import||(l.notices.push({headline:e.chldthmcfg.getxt("anlz15"),style:"notice-warning",msg:e.chldthmcfg.getxt("anlz16")}),o=1),c.analysis.child.signals.thm_unregistered&&c.analysis.child.signals.thm_child_loaded&&"thm_unregistered"===c.analysis.child.signals.thm_child_loaded&&c.analysis.child.signals.ctc_child_loaded&&c.analysis.child.signals.ctc_parnt_loaded&&(l.notices.push({headline:e.chldthmcfg.getxt("anlz28"),style:"notice-warning",msg:e.chldthmcfg.getxt("anlz29")}),e("#ctc_repairheader_container").show(),e("#ctc_repairheader").prop("checked",!0)),c.analysis.child.signals.thm_is_ctc||e("#ctc_child_type_duplicate").is(":checked")||l.notices.push({headline:e.chldthmcfg.getxt("anlz19"),msg:e.chldthmcfg.getxt("anlz20"),style:"notice-warning"})),(c.analysis[n].signals.ctc_sep_loaded||c.analysis[n].signals.ctc_gen_loaded)&&e("#ctc_handling_separate").prop("checked",!0),l.notices.length||l.notices.push({headline:""+("child"===n?e.chldthmcfg.getxt("anlz17"):e.chldthmcfg.getxt("anlz18")),style:"updated",msg:""}),"child"===n&&c.analysis.child.signals.thm_has_import&&(l.notices.push({headline:e.chldthmcfg.getxt("anlz21"),msg:e.chldthmcfg.getxt("anlz22"),style:"notice-warning"}),e("#ctc_enqueue_import").prop("checked",!0)),c.analysis[n].signals.thm_ignoreparnt||c.analysis[n].signals.ctc_gen_loaded?(e("#ctc_ignoreparnt").prop("checked",!0),e("#ctc_enqueue_none").is(":checked")||(e("#ctc_enqueue_none").prop("checked",!0),o=1,_.ctc_enqueue="none")):e("#ctc_ignoreparnt").prop("checked",!1),c.analysis[n].signals.thm_keepdeps?e("#ctc_keepdeps").prop("checked",!0):e("#ctc_keepdeps").prop("checked",!1),!c.analysis[n].signals.ctc_sep_loaded&&!c.analysis[n].signals.ctc_gen_loaded&&!c.analysis[n].signals.ctc_child_loaded&&!c.analysis[n].signals.thm_unregistered&&!c.analysis[n].signals.thm_past_wphead&&c.analysis[n].deps[1].length){var d="";e.each(c.analysis[n].deps[1],function(e,t){t[1].match(/^style([\-\.]min)?\.css$/)||(d+="<li>"+t[1]+"</li>\n")}),""!==d&&(d="<ul class='howto' style='padding-left:1em'>\n"+d+"</ul>\n",l.notices.push({headline:e.chldthmcfg.getxt("anlz23"),msg:d+e.chldthmcfg.getxt("anlz24"),style:"updated"}))}"child"===n&&c.analysis[n].signals.thm_parnt_loaded&&(l.notices.push({headline:e.chldthmcfg.getxt("anlz25"),msg:e.chldthmcfg.getxt("anlz26"),style:"updated"}),e("#ctc_enqueue_none").prop("checked",!0),o=1,_.ctc_enqueue="none"),c.analysis.parnt.signals.thm_no_styles&&(l.notices.push({headline:e.chldthmcfg.getxt("anlz27"),msg:e.chldthmcfg.getxt("anlz26"),style:"updated"}),e("#ctc_enqueue_none").prop("checked",!0),o=1,_.ctc_enqueue="none")}return a=encodeURIComponent(JSON.stringify(c.analysis)),e('input[name="ctc_analysis"]').val(a),_.ctc_analysis=a,c.is_success()&&o&&!c.resubmitting?(c.resubmitting=1,void c.resubmit(_)):(c.resubmitting=0,c.hide_loading(),e.each(l.notices,function(t,c){var i=e('<div class="'+c.style+' notice is-dismissible dashicons-before" ><h4>'+c.headline+"</h4>"+c.msg+"</div>");e.chldthmcfg.bind_dismiss(i),i.hide().appendTo("#"+n+"_analysis_notice").slideDown()}),e("#ctc_is_debug").is(":checked")&&(t='<div style="background-color:#ddd;padding:6px"><div class="ctc-section-toggle" id="ctc_analysis_obj">'+e.chldthmcfg.getxt("anlz30")+'</div><div id="ctc_analysis_obj_content" style="display:none"><textarea style="font-family:monospace;font-size:10px">'+JSON.stringify(c.analysis,null,2)+"</textarea></div></div>",e(t).appendTo("#"+n+"_analysis_notice")),e("#ctc_child_type_reset").is(":checked")||(e("#input_row_stylesheet_handling_container,#input_row_parent_handling_container,#ctc_child_header_parameters,#ctc_configure_submit").slideDown("fast"),e("#ctc_child_type_duplicate").is(":checked")?(e("#ctc_configure_submit .ctc-step").text("8"),e("#ctc_copy_theme_mods").find("input").prop("checked",!1)):(e("#ctc_configure_submit .ctc-step").text("9"),e("#ctc_copy_theme_mods").slideDown("fast")),e("#ctc_child_type_duplicate").is(":checked")||e("#ctc_child_type_new").is(":checked")?(e("#input_row_theme_slug").hide(),e("#input_row_new_theme_slug").slideDown("fast")):(e("#input_row_new_theme_slug").hide(),e("#input_row_theme_slug").slideDown("fast"))),void 0)},resubmit:function(t){var c=this;c.hide_loading(),c.show_loading(!0),t.action="ctc_update",t._wpnonce=e("#_wpnonce").val(),e.ajax({url:window.ctcAjax.ajaxurl,data:t,type:"POST"}).done(function(){c.hide_loading(),c.do_analysis()}).fail(function(){c.hide_loading()})},do_analysis:function(){var t=this;t.analysis={parnt:{},child:{}},t.phperr={parnt:[],child:[]},t.done=0,t.show_loading(!1),t.analyze_theme("parnt"),e.chldthmcfg.existing&&t.analyze_theme("child")},init:function(){var t=this;e(document).on("analysisdone",function(){t.done++,t.done>e.chldthmcfg.existing&&(t.done=0,t.css_notice())}),e("#ctc_main").on("click",".ctc-analyze-theme",function(){t.is_success()&&e.chldthmcfg.dismiss_notice(e(".ctc-success-response").parent(".notice")),t.do_analysis()}),(t.is_success()||window.ctcAjax.pluginmode)&&t.do_analysis()},analysis:{},done:0,resubmitting:0,is_success:function(){return e(".ctc-success-response").length}},e("#request-filesystem-credentials-form").length||(e.chldthmcfg.init(),e.chldthmanalyze.init())}(jQuery);
1
+ !function(e){"use strict";e.chldthmcfg={escquo:function(e){var t=this;return t.is_empty(e)?e:e.toString().replace(/"/g,"&quot;")},getxt:function(e,t){var c=window.ctcAjax[e+"_txt"];return c?(t&&(c=c.replace(/%s/,t)),c):""},frascii:function(e){var t=parseInt(e),c=String.fromCharCode(t);return c},toascii:function(e){var t=e.charCodeAt(0);return t},is_empty:function(e,t){if("undefined"==typeof e||!1===e||null===e||""===e)return!0;if("undefined"!=typeof t&&"0"===e||0===e)return!0;if(!0===e||"string"==typeof e||"number"==typeof e)return!1;if("object"==typeof e){for(var c in e)if(e.hasOwnProperty(c))return!1;return!0}return!1},theme_exists:function(t,c){var n=!1;return e.each(window.ctcAjax.themes,function(i,s){return e.each(s,function(e,s){return s=null,e.toLowerCase()!==t.toLowerCase()||"parnt"!==i&&"new"!==c?void 0:(n=!0,!1)}),n?!1:void 0}),n},validate:function(){var t=this,c=/[^\w\-]/,n=e("#ctc_child_template").length?e("#ctc_child_template").val().toString().replace(c):"",i=e("#ctc_theme_child").length?e("#ctc_theme_child").val().toString().replace(c):n,s=e("input[name=ctc_child_type]:checked").val(),a=[];return"new"===s&&(i=n),t.theme_exists(i,s)&&a.push(t.getxt("theme_exists").toString().replace(/%s/,i)),t.is_empty(i)&&a.push(t.getxt("inval_theme")),a.length?(t.set_notice({error:a}),!1):"reset"===s?!!confirm(t.getxt("load")):!0},autogen_slugs:function(){if(e("#ctc_theme_parnt").length){for(var t=this,c=e("#ctc_theme_parnt").val(),n=c+"-child",i=n,s=window.ctcAjax.themes.parnt[c].Name+" Child",a="",r="",l="00";t.theme_exists(i,"new");)a=t.is_empty(a)?2:a+1,r=l.substring(0,l.length-a.toString().length)+a.toString(),i=n+r;t.testslug=i,t.testname=s+(r.length?" "+r:"")}},focus_panel:function(t){var c=t+"_panel";e(".nav-tab").removeClass("nav-tab-active"),e(".ctc-option-panel").removeClass("ctc-option-panel-active"),e(t).addClass("nav-tab-active"),e(".ctc-option-panel-container").scrollTop(0),e(c).addClass("ctc-option-panel-active")},selector_input_toggle:function(t){var c,n=this;e("#ctc_rewrite_selector").length?(c=e("#ctc_rewrite_selector_orig").val(),e("#ctc_sel_ovrd_selector_selected").text(c),e(t).text(n.getxt("rename"))):(c=e("#ctc_sel_ovrd_selector_selected").text(),e("#ctc_sel_ovrd_selector_selected").html('<textarea id="ctc_rewrite_selector" name="ctc_rewrite_selector" autocomplete="off"></textarea><input id="ctc_rewrite_selector_orig" name="ctc_rewrite_selector_orig" type="hidden" value="'+n.escquo(c)+'"/>'),e("#ctc_rewrite_selector").val(c),e(t).text(n.getxt("cancel")))},coalesce_inputs:function(t){var c=this,n=e(t).attr("id"),i=/^(ctc_(ovrd|\d+)_(parent|child)_([0-9a-z\-]+)_(\d+?)(_(\d+))?)(_\w+)?$/,s=e(t).parents(".ctc-selector-row, .ctc-parent-row").first(),a=s.find(".ctc-swatch").first(),r={parent:{},child:{}},l={parent:{origin:"",start:"",end:""},child:{origin:"",start:"",end:""}},o={child:!1,parent:!1},_={};return s.find(".ctc-parent-value, .ctc-child-value").each(function(){var t,s,a=e(this).attr("id"),d=a.toString().match(i),u=d[2],h=d[3],p="undefined"==typeof d[4]?"":d[4],m=d[7],g=d[5],f="undefined"==typeof d[7]?"":d[8],v="parent"===h?e(this).text().replace(/!$/,""):"seq"!==p&&"ctc_delete_query_selector"===n?"":e(this).val(),y="seq"===p?!1:"ctc_"+u+"_child_"+p+"_i_"+g+"_"+m;if("child"===h&&(c.is_empty(e(this).data("color"))||(v=c.color_text(e(this).data("color")),e(this).data("color",null)),_[a]=v,y&&(_[y]=e("#"+y).is(":checked")?1:0)),""!==v)if(c.is_empty(f))if(t=p.toString().match(/^border(\-(top|right|bottom|left))?$/)&&!v.match(/none/)){var w=new RegExp(c.border_regx+c.color_regx,"i");s=v.toString().match(w),c.is_empty(s)||(s.shift(),r[h][p+"-width"]=s.shift()||"",s.shift(),r[h][p+"-style"]=s.shift()||"",r[h][p+"-color"]=s.shift()||"")}else if("background-image"!==p||v.match(/none/))"seq"!==p&&(r[h][p]=v);else if(v.toString().match(/url\(/))r[h]["background-image"]=c.image_url(h,v);else{var x=new RegExp(c.grad_regx+c.color_regx+c.color_regx,"i");s=v.toString().match(x),!c.is_empty(s)&&s.length>2?(s.shift(),l[h].origin=s.shift()||"top",l[h].start=s.shift()||"transparent",l[h].end=s.shift()||"transparent",o[h]=!0):r[h]["background-image"]=v}else switch(f){case"_border_width":r[h][p+"-width"]="none"===v?0:v;break;case"_border_style":r[h][p+"-style"]=v;break;case"_border_color":r[h][p+"-color"]=v;break;case"_background_url":r[h]["background-image"]=c.image_url(h,v);break;case"_background_color":r[h]["background-color"]=v;break;case"_background_color1":l[h].start=v,o[h]=!0;break;case"_background_color2":l[h].end=v,o[h]=!0;break;case"_background_origin":l[h].origin=v,o[h]=!0}}),"undefined"==typeof a||c.is_empty(a.attr("id"))||(a.removeAttr("style"),o.parent&&a.ctcgrad(l.parent.origin,[l.parent.start,l.parent.end]),a.css(r.parent),a.attr("id").toString().match(/parent/)||(o.child&&a.ctcgrad(l.child.origin,[l.child.start,l.child.end]),a.css(r.child)),a.css({"z-index":-1})),_},decode_value:function(e,t){t="undefined"==typeof t?"":t;var c,n=this,i={orig:t,names:[""],values:[t]};if(e.toString().match(/^border(\-(top|right|bottom|left))?$/)){var s,a=new RegExp(n.border_regx+"("+n.color_regx+")?","i");c=t.toString().match(a),n.is_empty(c)&&(c=[]),i.names=["_border_width","_border_style","_border_color"],s=c.shift(),i.values[0]=c.shift()||"",c.shift(),i.values[1]=c.shift()||"",c.shift(),i.values[2]=c.shift()||""}else if(e.toString().match(/^background\-image/))if(i.names=["_background_url","_background_origin","_background_color1","_background_color2"],i.values=["","","",""],n.is_empty(t)||t.toString().match(/(url|none)/))i.values[0]=t;else{var r,l;c=t.toString().split(/:/),i.values[1]=c.shift()||"",i.values[2]=c.shift()||"",r=c.shift()||"",i.values[3]=c.shift()||"",l=c.shift()||"",i.orig=[i.values[1],i.values[2],i.values[3]].join(" ")}return i},image_url:function(e,t){var c,n=this,i=t.toString().match(/url\(['" ]*(.+?)['" ]*\)/),s=n.is_empty(i)?null:i[1],a=window.ctcAjax.theme_uri+"/"+("parent"===e?window.ctcAjax.parnt:window.ctcAjax.child)+"/";return s?c=s.toString().match(/^(data:|https?:|\/)/)?t:"url("+a+s+")":!1},setup_menus:function(){var e=this;e.setup_query_menu(),e.setup_selector_menu(),e.setup_rule_menu(),e.setup_new_rule_menu(),e.load_queries(),e.load_rules(),e.set_query(e.currquery)},load_queries:function(){var e=this;e.query_css("queries",null)},load_selectors:function(){var e=this;e.query_css("selectors",e.currquery)},load_rules:function(){var e=this;e.query_css("rules",null)},load_selector_values:function(){var e=this;e.query_css("qsid",e.currqsid)},get_queries:function(t,c){var n=[],i=new RegExp(e.ui.autocomplete.escapeRegex(t.term),"i");e.chldthmcfg.is_empty(this.element.data("menu"))?n.push({label:window.ctcAjax.nosels_txt,value:null}):e.each(this.element.data("menu"),function(e,t){i.test(t)&&n.push({label:t,value:t})}),c(n)},get_selectors:function(t,c){var n=[],i=new RegExp(e.ui.autocomplete.escapeRegex(t.term),"i");e.chldthmcfg.is_empty(this.element.data("menu"))?n.push({label:window.ctcAjax.nosels_txt,value:null}):e.each(this.element.data("menu"),function(e,t){i.test(e)&&n.push({label:e,value:t})}),c(n)},get_rules:function(t,c){var n=[],i=new RegExp(e.ui.autocomplete.escapeRegex(t.term),"i");e.chldthmcfg.is_empty(this.element.data("menu"))?n.push({label:window.ctcAjax.nosels_txt,value:null}):e.each(this.element.data("menu"),function(e,t){i.test(e)&&n.push({label:e,value:t})}),c(n)},get_filtered_rules:function(t,c){var n=[],i=new RegExp(e.ui.autocomplete.escapeRegex(t.term),"i");e.each(e("#ctc_rule_menu").data("menu"),function(e,t){i.test(e)&&n.push({label:e,value:t})}),c(n)},merge_ruleval_arrays:function(t,c,n){var i=this,s={},a=n?c.child.pop():null;return e.each(["parnt","child"],function(t,r){i.is_empty(c[r])||e.each(c[r],function(e,t){n?parseInt(t[2])>=parseInt(a[2])&&(a[2]=parseInt(t[2])+1):(i.is_empty(s[t[2]])&&(s[t[2]]={}),s[t[2]][r]=t)})}),n&&(s[a[2]]={parnt:[],child:a}),s},input_row:function(t,c,n,i,s){var a=this,r="";if(!a.is_empty(i)&&!a.is_empty(i.value)&&!a.is_empty(i.value[c])){var l=i.value[c],o=a.merge_ruleval_arrays(c,l,s);e.each(o,function(s,l){var o=a.decode_value(c,a.is_empty(l.parnt)?"":l.parnt[0]),_=a.is_empty(l.parnt)||a.is_empty(l.parnt[1],1)?0:1,d=a.decode_value(c,a.is_empty(l.child)?"":l.child[0]),u=a.is_empty(l.child)||a.is_empty(l.child[1],1)?0:1;if(r+='<div class="ctc-'+("ovrd"===n?"input":"selector")+'-row clearfix"><div class="ctc-input-cell">',r+="ovrd"===n?c.replace(/\d+/g,a.frascii):i.selector+'<br/><a href="#" class="ctc-selector-edit" id="ctc_selector_edit_'+t+'" >'+a.getxt("edit")+"</a> "+(a.is_empty(o.orig)?a.getxt("child_only"):""),r+='</div><div class="ctc-parent-value ctc-input-cell"'+("ovrd"!==n?' style="display:none"':"")+' id="ctc_'+n+"_parent_"+c+"_"+t+"_"+s+'">'+(a.is_empty(o.orig)?"[no value]":o.orig+(_?a.getxt("important"):""))+'</div><div class="ctc-input-cell">',!a.is_empty(o.names)){e.each(o.names,function(e,i){i=a.is_empty(i)?"":i,r+='<div class="ctc-child-input-cell clear">';var l,o="ctc_"+n+"_child_"+c+"_"+t+"_"+s+i;!1===(l=d.values.shift())&&(l=""),r+=(a.is_empty(i)?"":a.getxt(i)+":<br/>")+'<input type="text" id="'+o+'" name="'+o+'" class="ctc-child-value'+((i+c).toString().match(/color/)?" color-picker":"")+(i.toString().match(/url/)?" ctc-input-wide":"")+'" value="'+a.escquo(l)+'" /></div>'});var h="ctc_"+n+"_child_"+c+"_i_"+t+"_"+s;r+='<label for="'+h+'"><input type="checkbox" id="'+h+'" name="'+h+'" value="1" '+(u?"checked":"")+" />"+a.getxt("important")+"</label>"}r+="</div>","ovrd"!==n&&(r+='<div class="ctc-swatch ctc-specific" id="ctc_child_'+c+"_"+t+"_"+s+'_swatch">'+a.getxt("swatch")+'</div><div class="ctc-child-input-cell ctc-button-cell" id="ctc_save_'+c+"_"+t+"_"+s+'_cell"><input type="button" class="button ctc-save-input" id="ctc_save_'+c+"_"+t+"_"+s+'" name="ctc_save_'+c+"_"+t+"_"+s+'" value="Save" /></div>'),r+="</div><!-- end input row -->\n"})}return r},scrolltop:function(){e("html, body, .ctc-option-panel-container").animate({scrollTop:0})},css_preview:function(e){var t=this;(e=e.match(/(child|parnt)/)[1])||(e="child"),t.query_css("preview",e)},setup_iris:function(e){var t=this;t.setup_spectrum(e)},setup_spectrum:function(t){var c=this,n=!c.is_empty(window.ctcAjax.palette);try{e(t).spectrum({showInput:!0,allowEmpty:!0,showAlpha:!0,showInitial:!0,preferredFormat:"hex",clickoutFiresChange:!0,move:function(n){e(t).data("color",n),c.coalesce_inputs(t)},showPalette:!!n,showSelectionPalette:!!n,palette:[],maxSelectionSize:36,localStorageKey:"ctc-palette."+window.ctcAjax.child,hideAfterPaletteSelect:!0}).on("change",function(){c.coalesce_inputs(this)}).on("keyup",function(){var t=this,n=c.addhash(e(this).val());e(t).val(n),clearTimeout(e(this).data("spectrumTimer")),e(this).data("spectrumTimer",setTimeout(function(){c.coalesce_inputs(t),e(t).spectrum("set",n)},500))})}catch(i){c.jquery_exception(i,"Spectrum Color Picker")}},addhash:function(e){return e.replace(/^#?([a-f0-9]{3,6}.*)/,"#$1")},color_text:function(e){var t=this;return t.is_empty(e)?"":e.getAlpha()<1?e.toRgbString():e.toHexString()},setup_query_menu:function(){var t=this;try{e("#ctc_sel_ovrd_query").autocomplete({source:t.get_queries,minLength:0,selectFirst:!0,autoFocus:!0,select:function(e,c){return t.set_query(c.item.value),!1},focus:function(e){e.preventDefault()}}).data("menu",{})}catch(c){t.jquery_exception(c,"Query Menu")}},setup_selector_menu:function(){var t=this;try{e("#ctc_sel_ovrd_selector").autocomplete({source:t.get_selectors,selectFirst:!0,autoFocus:!0,select:function(e,c){return t.set_selector(c.item.value,c.item.label),!1},focus:function(e){e.preventDefault()}}).data("menu",{})}catch(c){t.jquery_exception(c,"Selector Menu")}},setup_rule_menu:function(){var t=this;try{e("#ctc_rule_menu").autocomplete({source:t.get_rules,selectFirst:!0,autoFocus:!0,select:function(e,c){return t.set_rule(c.item.value,c.item.label),!1},focus:function(e){e.preventDefault()}}).data("menu",{})}catch(c){t.jquery_exception(c,"Property Menu")}},setup_new_rule_menu:function(){var t=this;try{e("#ctc_new_rule_menu").autocomplete({source:t.get_filtered_rules,selectFirst:!0,autoFocus:!0,select:function(c,n){c.preventDefault();var i,s,a=n.item.label.replace(/[^\w\-]/g,t.toascii);return t.is_empty(t.currdata.value)&&(t.currdata.value={}),t.is_empty(t.currdata.value[n.item.label])&&(t.currdata.value[n.item.label]={}),t.is_empty(t.currdata.value[n.item.label].child)&&(t.currdata.value[n.item.label].child=[]),t.currdata.value[n.item.label].child.push(["",0,1,1]),i=e(t.input_row(t.currqsid,a,"ovrd",t.currdata,!0)),e("#ctc_sel_ovrd_rule_inputs").append(i),e("#ctc_new_rule_menu").val(""),i.find('input[type="text"]').each(function(c,n){s||(s=n),e(n).hasClass("color-picker")&&t.setup_spectrum(n)}),s&&e(s).focus(),!1},focus:function(e){e.preventDefault()}}).data("menu",{})}catch(c){t.jquery_exception(c,"New Property Menu")}},set_theme_params:function(t,c){e("#ctc_child_author").val(window.ctcAjax.themes[t][c].Author),e("#ctc_child_version").val(window.ctcAjax.themes[t][c].Version),e("#ctc_child_authoruri").val(window.ctcAjax.themes[t][c].AuthorURI),e("#ctc_child_themeuri").val(window.ctcAjax.themes[t][c].ThemeURI),e("#ctc_child_descr").val(window.ctcAjax.themes[t][c].Descr),e("#ctc_child_tags").val(window.ctcAjax.themes[t][c].Tags)},update_form:function(){var t,c=this;e("#input_row_stylesheet_handling_container,#input_row_parent_handling_container,#ctc_additional_css_files_container,#input_row_new_theme_slug,#input_row_duplicate_theme_slug,#ctc_copy_theme_mods,#ctc_child_header_parameters,#ctc_configure_submit,#input_row_theme_slug").slideUp("fast"),e("#ctc_configure_submit .ctc-step").text("9"),e("#ctc_theme_child").length&&!e("#ctc_child_type_new").is(":checked")?(t=e("#ctc_theme_child").val(),c.existing=1,c.currparnt=window.ctcAjax.themes.child[t].Template,c.autogen_slugs(),e("#ctc_theme_parnt").val(c.currparnt),e("#ctc_theme_parnt-button .ui-selectmenu-text").text(window.ctcAjax.themes.parnt[c.currparnt].Name),c.set_theme_params("child",t),e("#ctc_child_type_duplicate").is(":checked")?(e("#ctc_child_template").val(c.testslug),e("#ctc_child_name").val(c.testname),e(".ctc-analyze-theme, .ctc-analyze-howto").show(),e("#ctc_load_styles").val("Duplicate Child Theme")):e("#ctc_child_type_reset").is(":checked")?(e("#ctc_configure_submit .ctc-step").text("3"),e("#ctc_configure_submit").slideDown("fast"),e("#theme_slug_container").text(t),e(".ctc-analyze-theme, .ctc-analyze-howto").hide(),e("#ctc_enqueue_none").prop("checked",!0),e("#ctc_load_styles").val("Reset Child Theme to Previous State")):(e("#ctc_child_template").val(""),e("#theme_slug_container").text(t),e(".ctc-analyze-theme, .ctc-analyze-howto").show(),e("#ctc_child_name").val(window.ctcAjax.themes.child[t].Name),e("#ctc_load_styles").val("Configure Child Theme")),e("#input_row_existing_theme_option").slideDown("fast"),e("#input_row_new_theme_option").slideUp("fast")):(c.existing=0,c.autogen_slugs(),e("#ctc_theme_parnt").val(c.currparnt),e("#ctc_theme_parnt-button .ui-selectmenu-text").text(window.ctcAjax.themes.parnt[c.currparnt].Name),c.set_theme_params("parnt",c.currparnt),e("#input_row_existing_theme_option,#input_row_duplicate_theme_container,#input_row_theme_slug").slideUp("fast"),e("#input_row_new_theme_option").slideDown("fast"),e("#ctc_child_name").val(c.testname),e("#ctc_child_template").val(c.testslug),e(".ctc-analyze-theme, .ctc-analyze-howto").show(),e("#ctc_load_styles").val("Create New Child Theme"))},set_notice:function(t){var c,n=this,i="";n.is_empty(t)||e.each(t,function(t,c){i+='<div class="'+t+' notice is-dismissible dashicons-before"><ul>\n',e(c).each(function(e,t){i+="<li>"+t.toString()+"</li>\n"}),i+="</ul></div>"}),c=e(i),e("#ctc_error_notice").html(c),n.bind_dismiss(c),e("html, body").animate({scrollTop:0},"slow")},set_parent_menu:function(e){var t=this;t.currparnt=e.value,t.update_form()},set_child_menu:function(e){var t=this;t.currchild=e.value,t.update_form()},set_query:function(t){var c=this;return c.is_empty(t)?!1:(c.currquery=t,e("#ctc_sel_ovrd_query").val(""),e("#ctc_sel_ovrd_query_selected").text(t),e("#ctc_sel_ovrd_selector").val(""),e("#ctc_sel_ovrd_selector_selected").html("&nbsp;"),c.load_selectors(),void c.scrolltop())},set_selector:function(t,c){var n=this;return c=null,n.is_empty(t)?!1:(e("#ctc_sel_ovrd_selector").val(""),n.currqsid=t,n.reload=!1,n.load_selector_values(),void n.scrolltop())},set_rule:function(t,c){var n=this;return n.is_empty(t)?!1:(e("#ctc_rule_menu").val(""),e("#ctc_rule_menu_selected").text(c),e(".ctc-rewrite-toggle").text(n.getxt("rename")),e("#ctc_rule_value_inputs, #ctc_input_row_rule_header").show(),n.query_css("rule_val",t),void n.scrolltop())},set_qsid:function(t){var c=this;c.currqsid=e(t).attr("id").match(/_(\d+)$/)[1],c.focus_panel("#query_selector_options"),c.reload=!0,c.load_selector_values()},query_css:function(t,c,n){var i=this,s={ctc_query_obj:t,ctc_query_key:c},a="#ctc_status_"+t+("val_qry"===t?"_"+c:"");"object"==typeof n&&e.each(n,function(e,t){s["ctc_query_"+e]=t}),e(".query-icon,.ctc-status-icon").remove(),e(a+" .ctc-status-icon").remove(),e(a).append('<span class="ctc-status-icon spinner is-active query-icon"></span>'),s.action=i.is_empty(e("#ctc_action").val())||"plugin"!==e("#ctc_action").val()?"ctc_query":"ctc_plgqry",s._wpnonce=e("#_wpnonce").val(),i.ajax_post(t,s)},save:function(t){var c,n,i,s,a,r=this,l={},o=e(t).attr("id");e(t).prop("disabled",!0),e(".ctc-query-icon,.ctc-status-icon").remove(),e(t).parent(".ctc-textarea-button-cell, .ctc-button-cell").append('<span class="ctc-status-icon spinner save-icon"></span>'),o.match(/ctc_configtype/)?(e(t).parents(".ctc-input-row").first().append('<span class="ctc-status-icon spinner save-icon"></span>'),l.ctc_configtype=e(t).val()):(c=e("#ctc_new_selectors"))&&"ctc_save_new_selectors"===e(t).attr("id")?(l.ctc_new_selectors=c.val(),(n=e("#ctc_sel_ovrd_query_selected"))&&(l.ctc_sel_ovrd_query=n.text()),r.reload=!0):(i=e("#ctc_child_imports"))&&"ctc_save_imports"===o?l.ctc_child_imports=i.val():"ctc_is_debug"===o?l.ctc_is_debug=e("#ctc_is_debug").is(":checked")?1:0:l=r.coalesce_inputs(t),e(".save-icon").addClass("is-active"),e("#ctc_sel_ovrd_selector_selected").find("#ctc_rewrite_selector").each(function(){s=e("#ctc_rewrite_selector").val(),a=e("#ctc_rewrite_selector_orig").val(),r.is_empty(s)||!s.toString().match(/\w/)?s=a:(l.ctc_rewrite_selector=s,r.reload=!0),e(".ctc-rewrite-toggle").text(r.getxt("rename")),e("#ctc_sel_ovrd_selector_selected").html(s)}),l.action=r.is_empty(e("#ctc_action").val())||"plugin"!==e("#ctc_action").val()?"ctc_update":"ctc_plugin",l._wpnonce=e("#_wpnonce").val(),r.ajax_post("qsid",l)},ajax_post:function(t,c,n){var i=this;e.ajax({url:window.ctcAjax.ajaxurl,data:c,dataType:i.is_empty(n)?"json":n,type:"POST"}).done(function(e){i.handle_success(t,e)}).fail(function(){i.handle_failure(t)}).always(function(){i.jqueryerr.length&&i.jquery_notice()})},handle_failure:function(t){var c=this;e(".query-icon, .save-icon").removeClass("spinner").addClass("failure"),e("input[type=submit], input[type=button], input[type=checkbox],.ctc-delete-input").prop("disabled",!1),e(".ajax-pending").removeClass("ajax-pending"),"preview"===t&&e("#view_parnt_options_panel,#view_child_options_panel").text(c.getxt("css_fail"))},handle_success:function(t,c){var n=this;e(".query-icon, .save-icon").removeClass("spinner"),e(".ajax-pending").removeClass("ajax-pending"),n.is_empty(c)?n.handle_failure(t):(e("#ctc_new_selectors").val(""),e(".query-icon, .save-icon").addClass("success"),e("input[type=submit], input[type=button], input[type=checkbox],.ctc-delete-input").prop("disabled",!1),e(c).each(function(){"function"==typeof n.update[this.obj]&&n.update[this.obj].call(n,this)}))},jquery_exception:function(e,t){var c=this,n=c.is_empty(e.lineNumber)?"":" line: "+e.lineNumber,i=c.is_empty(e.fileName)?"":" "+e.fileName.split(/\?/)[0];c.jqueryerr.push("<code><small>"+t+": "+e.message+i+n+"</small></code>")},jquery_notice:function(t){t=null;var c=this,n=[],i=[];c.jqueryerr.length&&(e("input[type=submit], input[type=button]").prop("disabled",!0),e("script").each(function(){var t=e(this).prop("src");c.is_empty(t)||!t.match(/jquery(\.min|\.js|\-?ui)/i)||t.match(/load\-scripts.php/)||n.push("<code><small>"+t.split(/\?/)[0]+"</small></code>")}),i.push("<strong>"+c.getxt("js")+"</strong> "+c.getxt("contact")),i.push(c.jqueryerr.join("<br/>")),n.length&&i.push(c.getxt("jquery")+"<br/>"+n.join("<br/>")),i.push(c.getxt("plugin"))),c.set_notice({error:i})},update:{qsid:function(t){var c,n,i,s,a=this;a.currqsid=t.key,a.currdata=t.data,e("#ctc_sel_ovrd_qsid").val(a.currqsid),a.is_empty(a.currdata.seq)?e("#ctc_child_load_order_container").empty():(c="ctc_ovrd_child_seq_"+a.currqsid,i=parseInt(a.currdata.seq),n='<input type="text" id="'+c+'" name="'+c+'" class="ctc-child-value" value="'+i+'" />',e("#ctc_child_load_order_container").html(n)),a.is_empty(a.currdata.value)?(s=!0,e("#ctc_sel_ovrd_rule_inputs").empty()):(s=!1,n="",e.each(a.currdata.value,function(e,t){t=null,n+=a.input_row(a.currqsid,e,"ovrd",a.currdata)}),e("#ctc_sel_ovrd_rule_inputs").html(n).find(".color-picker").each(function(){a.setup_spectrum(this)}),a.coalesce_inputs("#ctc_child_all_0_swatch")),a.reload&&(a.load_queries(),a.set_query(a.currdata.query),a.load_rules()),e("#ctc_sel_ovrd_selector_selected").text(a.currdata.selector),e(".ctc-rewrite-toggle").text(a.getxt("rename")),e(".ctc-rewrite-toggle").show(),s?e("#ctc_sel_ovrd_rule_header,#ctc_sel_ovrd_new_rule,#ctc_sel_ovrd_rule_inputs_container,#ctc_sel_ovrd_rule_inputs").hide():e("#ctc_sel_ovrd_rule_header,#ctc_sel_ovrd_new_rule,#ctc_sel_ovrd_rule_inputs_container,#ctc_sel_ovrd_rule_inputs").show()},rule_val:function(t){var c=this,n=e("#ctc_rule_menu_selected").text(),i='<div class="ctc-input-row clearfix" id="ctc_rule_row_'+n+'">\n';c.is_empty(t.data)||(e.each(t.data,function(e,t){var s=c.decode_value(n,t);i+='<div class="ctc-parent-row clearfix" id="ctc_rule_row_'+n+"_"+e+'">\n<div class="ctc-input-cell ctc-parent-value" id="ctc_'+e+"_parent_"+n+"_"+e+'">'+s.orig+'</div>\n<div class="ctc-input-cell">\n<div class="ctc-swatch ctc-specific" id="ctc_'+e+"_parent_"+n+"_"+e+'_swatch">'+c.getxt("swatch")+'</div></div>\n<div class="ctc-input-cell"><a href="#" class="ctc-selector-handle" id="ctc_selector_'+n+"_"+e+'">'+c.getxt("selector")+'</a></div>\n<div id="ctc_selector_'+n+"_"+e+'_container" class="ctc-selector-container">\n<a href="#" id="ctc_selector_'+n+"_"+e+'_close" class="ctc-selector-handle ctc-exit" title="'+c.getxt("close")+'"></a><div id="ctc_selector_'+n+"_"+e+'_inner_container" class="ctc-selector-inner-container clearfix">\n<div id="ctc_status_val_qry_'+e+'"></div>\n<div id="ctc_selector_'+n+"_"+e+'_rows"></div>\n</div></div></div>\n'}),i+="</div>\n"),e("#ctc_rule_value_inputs").html(i).find(".ctc-swatch").each(function(){c.coalesce_inputs(this)})},val_qry:function(t){var c,n,i=this,s="";i.is_empty(t.data)||e.each(t.data,function(n,a){c=n,e.each(a,function(c,a){s+='<h4 class="ctc-query-heading">'+c+"</h4>\n",i.is_empty(a)||e.each(a,function(e,c){s+=i.input_row(e,n,t.key,c)})})}),n="#ctc_selector_"+c+"_"+t.key+"_rows",e(n).html(s).find(".color-picker").each(function(){i.setup_spectrum(this)}),e(n).find(".ctc-swatch").each(function(){i.coalesce_inputs(this)})},queries:function(t){e("#ctc_sel_ovrd_query").data("menu",t.data)},selectors:function(t){e("#ctc_sel_ovrd_selector").data("menu",t.data)},rules:function(t){e("#ctc_rule_menu").data("menu",t.data)},debug:function(t){e("#ctc_debug_container").html(t.data)},preview:function(t){e("#view_"+t.key+"_options_panel").text(t.data)},dismiss:function(){}},bind_dismiss:function(t){var c=this,n=e(t),i=e('<button type="button" class="notice-dismiss"><span class="screen-reader-text"></span></button>'),s=window.commonL10n.dismiss||"";i.find(".screen-reader-text").text(s),n.append(i),i.on("click.wp-dismiss-notice",function(e){e.preventDefault(),c.dismiss_notice(t)})},dismiss_notice:function(t){e(t).fadeTo(100,0,function(){e(this).slideUp(100,function(){e(this).remove()})})},reset_handling:function(){e("#parnt_analysis_notice .notice, #child_analysis_notice .notice").slideUp(),e("#ctc_enqueue_enqueue").prop("checked",!0),e("#ctc_handling_primary").prop("checked",!0),e("#ctc_ignoreparnt").prop("checked",!1),e("#ctc_repairheader").prop("checked",!1)},init:function(){var t=this;if(!e("#ctc_theme_parnt").is("input")){try{e.widget("ctc.themeMenu",e.ui.selectmenu,{_renderItem:function(t,c){var n=e("<li>"),i=c.value.replace(/[^\w\-]/,"");return e("#ctc_theme_option_"+i).detach().appendTo(n),n.appendTo(t)}})}catch(c){t.jquery_exception(c,"Theme Menu")}try{e("#ctc_theme_parnt").themeMenu({select:function(e,c){t.reset_handling(),t.set_parent_menu(c.item)}})}catch(c){"function"==typeof themeMenu?e("#ctc_theme_parnt").themeMenu("destroy"):e("#ctc_theme_parnt-button").remove(),t.jquery_exception(c,"Parent Theme Menu")}if(t.is_empty(window.ctcAjax.themes.child))e("#ctc_child_name").length&&(e("#ctc_child_name").val(t.testname),e("#ctc_child_template").val(t.testslug));else try{e("#ctc_theme_child").themeMenu({select:function(e,c){t.reset_handling(),t.set_child_menu(c.item)}})}catch(c){"function"==typeof themeMenu?e("#ctc_theme_child").themeMenu("destroy"):e("#ctc_theme_child-button").remove(),t.jquery_exception(c,"Child Theme Menu")}}t.currparnt=e("#ctc_theme_parnt").val(),t.currchild=e("#ctc_theme_child").length?e("#ctc_theme_child").val():"",e("#ctc_main").on("click",".ctc-section-toggle",function(t){t.preventDefault(),e(this).parents(".ctc-input-row, .notice-warning, .updated, .error").first().find(".ctc-section-toggle").each(function(){e(this).toggleClass("open")});var c=e(this).attr("id").replace(/\d$/,"")+"_content";return e("#"+c).stop().slideToggle("fast"),!1}),e("#ctc_main").on("click",".ctc-upgrade-notice .notice-dismiss",function(){var c={action:"ctc_dismiss",_wpnonce:e("#_wpnonce").val()};t.ajax_post("dismiss",c)}),t.is_empty(t.jqueryerr)&&(e("#ctc_main").on("click",".ctc-selector-handle",function(c){if(c.preventDefault(),e(this).hasClass("ajax-pending"))return!1;e(this).addClass("ajax-pending");var n,i,s=e(this).attr("id").toString().replace("_close",""),a=s.toString().match(/_([^_]+)_(\d+)$/);e("#"+s+"_container").is(":hidden")&&(t.is_empty(a[1])||t.is_empty(a[2])||(n=a[1],i=a[2],t.query_css("val_qry",i,{rule:n}))),e("#"+s+"_container").fadeToggle("fast"),e(".ctc-selector-container").not("#"+s+"_container").fadeOut("fast")}),e("#ctc_main").on("click",".ctc-save-input[type=button], .ctc-delete-input",function(c){return c.preventDefault(),e(this).hasClass("ajax-pending")?!1:(e(this).addClass("ajax-pending"),t.save(this),!1)}),e("#ctc_main").on("keydown",".ctc-selector-container .ctc-child-value[type=text]",function(c){if(13===c.which){var n=e(this).parents(".ctc-selector-row").find(".ctc-save-input[type=button]").first();if(n.length)return c.preventDefault(),n.hasClass("ajax-pending")?!1:(n.addClass("ajax-pending"),t.save(n),!1)}}),e("#ctc_main").on("click",".ctc-selector-edit",function(c){return c.preventDefault(),e(this).hasClass("ajax-pending")?!1:(e(this).addClass("ajax-pending"),void t.set_qsid(this))}),e("#ctc_main").on("click",".ctc-rewrite-toggle",function(e){e.preventDefault(),t.selector_input_toggle(this)}),e("#ctc_main").on("click","#ctc_copy_selector",function(){var c=e("#ctc_sel_ovrd_selector_selected").text().trim();t.is_empty(c)||e("#ctc_new_selectors").val(e("#ctc_new_selectors").val()+"\n"+c+" {\n\n}")}),e("#ctc_main").on("click",".ctc-backup-theme",function(c){c.preventDefault(),t.existing?e("#ctc_export_theme").val(t.currchild):e("#ctc_export_theme").val(t.currparnt),e("#ctc_export_theme_form").submit()}),e("#ctc_configtype").on("change",function(){var c=e(this).val();if(t.is_empty(c)||"theme"===c){e(".ctc-theme-only, .ctc-themeonly-container").removeClass("ctc-disabled"),e(".ctc-theme-only, .ctc-themeonly-container input").prop("disabled",!1);try{e("#ctc_theme_parnt, #ctc_theme_child").themeMenu("enable")}catch(n){t.jquery_exception(n,"Theme Menu")}}else{e(".ctc-theme-only, .ctc-themeonly-container").addClass("ctc-disabled"),e(".ctc-theme-only, .ctc-themeonly-container input").prop("disabled",!0);try{e("#ctc_theme_parnt, #ctc_theme_child").themeMenu("disable")}catch(n){t.jquery_exception(n,"Theme Menu")}}}),e(".nav-tab").on("click",function(c){c.preventDefault(),e(".ctc-query-icon,.ctc-status-icon").remove();var n="#"+e(this).attr("id");t.focus_panel(n)}),e("#view_child_options, #view_parnt_options").on("click",function(){return e(this).hasClass("ajax-pending")?!1:(e(this).addClass("ajax-pending"),void t.css_preview(e(this).attr("id")))}),e("#ctc_load_form").on("submit",function(){return t.validate()}),e("#ctc_query_selector_form").on("submit",function(c){c.preventDefault();var n=e("#ctc_save_query_selector");return n.hasClass("ajax-pending")?!1:(n.addClass("ajax-pending"),t.save(n),!1)}),e("#ctc_rule_value_form").on("submit",function(e){return e.preventDefault(),!1}),e("#ctc_child_type_new,#ctc_child_type_existing,#ctc_child_type_duplicate,#ctc_child_type_reset").on("focus click",function(){t.reset_handling(),t.update_form()}),e("#ctc_is_debug").on("change",function(){t.save(this)}),e(".ctc-live-preview").on("click",function(t){return t.stopImmediatePropagation(),t.preventDefault(),document.location=e(this).prop("href"),!1}),t.setup_menus(),e("input[type=submit], input[type=button]").prop("disabled",!1),t.scrolltop(),t.update_form()),t.jqueryerr.length&&t.jquery_notice()},testslug:"",testname:"",reload:!1,currquery:"base",currqsid:null,currdata:{},currparnt:"",currchild:"",existing:!1,jqueryerr:[],color_regx:"\\s+(\\#[a-f0-9]{3,6}|rgba?\\([\\d., ]+?\\)|hsla?\\([\\d%., ]+?\\)|[a-z]+)",border_regx:"(\\w+)(\\s+(\\w+))?",grad_regx:"(\\w+)"},e.chldthmanalyze={escrgx:function(e){return e.replace(/([.*+?^${}()|\[\]\/\\])/g,"\\$1")},trmcss:function(e){return"undefined"==typeof e?"":e.replace(/\-css$/,"")},show_loading:function(t){var c=e.chldthmcfg.existing?"child":"parnt",n="child"===c?e.chldthmcfg.currchild:e.chldthmcfg.currparnt,i=window.ctcAjax.themes[c][n].Name,s='<strong class="ctc_analyze_loading"><span class="spinner is-active"></span>'+e.chldthmcfg.getxt(t?"anlz1":"anlz2")+" "+i+"...</strong>";self.noticediv="",e("#"+c+"_analysis_notice").html(s)},hide_loading:function(){e(".ctc_analyze_loading").fadeTo(200,0,function(){e(this).slideUp(200,function(){e(this).remove()})})},setssl:function(e){return e.replace(/^https?/,window.ctcAjax.ssl?"https":"http")},analyze_theme:function(t){var c,n,i,s=this,a=Math.floor(e.now()/1e3),r="child"===t?e.chldthmcfg.currchild:e.chldthmcfg.currparnt,l="&template="+e.chldthmcfg.currparnt+"&stylesheet="+r+"&now="+a,o=s.setssl(window.ctcAjax.homeurl),_=window.ctcAjax.theme_uri.replace(/^https?:\/\//,""),d=o+l,u=s.escrgx(e.chldthmcfg.currparnt)+("child"===t?"|"+s.escrgx(r):""),h=new RegExp("<link( rel=[\"']stylesheet[\"'] id=['\"]([^'\"]+?)['\"])?[^>]+?"+s.escrgx(_)+"/("+u+")/([^\"']+\\.css)(\\?[^\"']+)?[\"'][^>]+>","gi"),p=/<br \/>\n[^\n]+?(fatal|strict|notice|warning|error)[\s\S]+?<br \/>/gi,m=0,g=0,f={deps:[[],[]],signals:{},queue:[],irreg:[]};e.get(d,function(a){for((n=a.match(/BEGIN WP QUEUE\n([\s\S]*?)\nEND WP QUEUE/))?f.queue=n[1].split(/\n/):(f.queue=[],f.signals.thm_noqueue=1),(n=a.match(/BEGIN CTC IRREGULAR\n([\s\S]*?)\nEND CTC IRREGULAR/))?f.irreg=n[1].split(/\n/):f.irreg=[],a.match(/CHLD_THM_CFG_IGNORE_PARENT/)&&(f.signals.thm_ignoreparnt=1),a.match(/IS_CTC_THEME/)&&(f.signals.thm_is_ctc=1),a.match(/NO_CTC_STYLES/)&&(f.signals.thm_no_styles=1),a.match(/HAS_CTC_IMPORT/)&&(f.signals.thm_has_import=1),a=a.replace(/<!\-\-[\s\S]*?\-\->/g,"");c=p.exec(a);){var r=c[0].replace(/<.*?>/g,"");s.phperr[t].push(r),f.signals.err_php=1,r.match(/Fatal error/i)&&(f.signals.err_fatal=1)}for(;i=h.exec(a);){var l=s.trmcss(i[2]),o=i[3],_=i[4],d=e.chldthmcfg.currparnt===o?"parnt":"child",u=0;if(""===l||-1===e.inArray(l,f.queue))u=1;else if(0===l.indexOf("chld_thm_cfg")){_.match(/^ctc\-style([\-\.]min)?\.css$/)?(m=1,f.signals.ctc_sep_loaded=1):_.match(/^ctc\-genesis([\-\.]min)?\.css$/)?(m=1,f.signals.ctc_gen_loaded=1):l.match(/$chld_thm_cfg_ext/)?(f.signals.ctc_ext_loaded=1,
2
+ f.deps[m].push([l,_])):"chld_thm_cfg_child"===l?(f.signals.ctc_child_loaded=1,f.deps[m].push([l,_])):"chld_thm_cfg_parent"===l&&(f.signals.ctc_parnt_loaded=1,f.deps[m].push([l,_]),m&&(f.signals.ctc_parnt_reorder=1));continue}if(_.match(/^style([\-\.]min)?\.css$/))m=1,"parnt"===d?f.signals.thm_parnt_loaded=u?"thm_unregistered":l:f.signals.thm_child_loaded=u?"thm_unregistered":l,u?g?(f.signals.thm_past_wphead=1,f.deps[m].push(["thm_past_wphead",_])):(f.signals.thm_unregistered=1,f.deps[m].push(["thm_unregistered",_])):f.deps[m].push([l,_]);else if("ctc-test.css"===_)g=1;else{var v=null;u&&(v="dep_unregistered"),g&&(v=m?"css_past_wphead":"dep_past_wphead"),v&&(f.signals[v]=1,l=v),f.deps[m].push([l,_])}}m||(f.signals.thm_notheme=1),a=null,s.analysis[t]=f,e(document).trigger("analysisdone")}).fail(function(c,n,i){f.signals.failure=1,f.signals.xhrerr=i,s.analysis[t]=f,e(document).trigger("analysisdone")})},css_notice:function(){var t,c=this,n=e.chldthmcfg.existing?"child":"parnt",i="child"===n?e.chldthmcfg.currchild:e.chldthmcfg.currparnt,s=window.ctcAjax.themes[n][i].Name,a="",r={notices:[]},l={style:"notice-warning",headline:e.chldthmcfg.getxt("anlz3",s),errlist:""},o=0,_={};if(e(window.ctcAjax.addl_css).each(function(t,c){e("#ctc_stylesheet_files .ctc_checkbox").each(function(){c===e(this).val()&&e(this).prop("checked",!0)})}),c.analysis[n].signals.failure||c.analysis[n].signals.thm_noqueue&&!c.phperr[n].length)r.notices.push({headline:e.chldthmcfg.getxt("anlz4",s),msg:e.chldthmcfg.getxt("anlz5"),style:"notice-warning"});else{if(c.phperr[n].length&&(e.each(c.phperr[n],function(t,c){c.match(/Fatal error/i)&&(l.style="error",l.headline=e.chldthmcfg.getxt("anlz8",s)),l.errlist+=c+"\n"}),l.msg='<div style="background-color:#ffeebb;padding:6px"><div class="ctc-section-toggle" id="ctc_analysis_errs">'+e.chldthmcfg.getxt("anlz6")+'</div><div id="ctc_analysis_errs_content" style="display:none"><textarea>'+l.errlist+"</textarea></div></div>"+e.chldthmcfg.getxt("anlz7"),r.notices.push(l)),(c.analysis[n].signals.thm_past_wphead||c.analysis[n].signals.dep_past_wphead)&&(r.notices.push({headline:e.chldthmcfg.getxt("anlz9"),style:"notice-warning",msg:e.chldthmcfg.getxt("anlz10")}),e("#ctc_repairheader").prop("checked",!0),e("#ctc_repairheader_container").show()),c.analysis[n].signals.thm_unregistered&&(c.analysis[n].signals.ctc_child_loaded||c.analysis[n].signals.ctc_sep_loaded||(r.notices.push({headline:e.chldthmcfg.getxt("anlz11"),style:"notice-warning",msg:e.chldthmcfg.getxt("anlz12")}),e("#ctc_repairheader_container").show(),e("#ctc_repairheader").prop("checked",!0))),"child"===n&&(c.analysis.child.signals.ctc_parnt_reorder&&(o=1),c.analysis.child.signals.ctc_child_loaded||c.analysis.child.signals.ctc_sep_loaded||c.analysis.child.signals.thm_child_loaded||(r.notices.push({headline:e.chldthmcfg.getxt("anlz13"),style:"notice-warning",msg:e.chldthmcfg.getxt("anlz14")}),o=1),c.analysis[n].signals.ctc_gen_loaded&&r.notices.push({headline:e.chldthmcfg.getxt("anlz31"),msg:e.chldthmcfg.getxt("anlz32"),style:"notice-warning"}),c.analysis.parnt.signals.thm_no_styles||c.analysis.child.signals.ctc_gen_loaded||c.analysis.child.signals.thm_parnt_loaded||c.analysis.child.signals.ctc_parnt_loaded||c.analysis.child.signals.thm_ignoreparnt||c.analysis.child.signals.thm_has_import||(r.notices.push({headline:e.chldthmcfg.getxt("anlz15"),style:"notice-warning",msg:e.chldthmcfg.getxt("anlz16")}),o=1),c.analysis.child.signals.thm_unregistered&&c.analysis.child.signals.thm_child_loaded&&"thm_unregistered"===c.analysis.child.signals.thm_child_loaded&&c.analysis.child.signals.ctc_child_loaded&&c.analysis.child.signals.ctc_parnt_loaded&&(r.notices.push({headline:e.chldthmcfg.getxt("anlz28"),style:"notice-warning",msg:e.chldthmcfg.getxt("anlz29")}),e("#ctc_repairheader_container").show(),e("#ctc_repairheader").prop("checked",!0)),c.analysis.child.signals.thm_is_ctc||e("#ctc_child_type_duplicate").is(":checked")||r.notices.push({headline:e.chldthmcfg.getxt("anlz19"),msg:e.chldthmcfg.getxt("anlz20"),style:"notice-warning"})),(c.analysis[n].signals.ctc_sep_loaded||c.analysis[n].signals.ctc_gen_loaded)&&e("#ctc_handling_separate").prop("checked",!0),r.notices.length||r.notices.push({headline:""+("child"===n?e.chldthmcfg.getxt("anlz17"):e.chldthmcfg.getxt("anlz18")),style:"updated",msg:""}),"child"===n&&c.analysis.child.signals.thm_has_import&&(r.notices.push({headline:e.chldthmcfg.getxt("anlz21"),msg:e.chldthmcfg.getxt("anlz22"),style:"notice-warning"}),e("#ctc_enqueue_import").prop("checked",!0)),c.analysis[n].signals.thm_ignoreparnt||c.analysis[n].signals.ctc_gen_loaded?(e("#ctc_ignoreparnt").prop("checked",!0),e("#ctc_enqueue_none").is(":checked")||(e("#ctc_enqueue_none").prop("checked",!0),o=1,_.ctc_enqueue="none")):e("#ctc_ignoreparnt").prop("checked",!1),c.analysis[n].signals.thm_keepdeps?e("#ctc_keepdeps").prop("checked",!0):e("#ctc_keepdeps").prop("checked",!1),!c.analysis[n].signals.ctc_sep_loaded&&!c.analysis[n].signals.ctc_gen_loaded&&!c.analysis[n].signals.ctc_child_loaded&&!c.analysis[n].signals.thm_unregistered&&!c.analysis[n].signals.thm_past_wphead&&c.analysis[n].deps[1].length){var d="";e.each(c.analysis[n].deps[1],function(e,t){t[1].match(/^style([\-\.]min)?\.css$/)||(d+="<li>"+t[1]+"</li>\n")}),""!==d&&(d="<ul class='howto' style='padding-left:1em'>\n"+d+"</ul>\n",r.notices.push({headline:e.chldthmcfg.getxt("anlz23"),msg:d+e.chldthmcfg.getxt("anlz24"),style:"updated"}))}"child"===n&&c.analysis[n].signals.thm_parnt_loaded&&(r.notices.push({headline:e.chldthmcfg.getxt("anlz25"),msg:e.chldthmcfg.getxt("anlz26"),style:"updated"}),e("#ctc_enqueue_none").prop("checked",!0),o=1,_.ctc_enqueue="none"),c.analysis.parnt.signals.thm_no_styles&&(r.notices.push({headline:e.chldthmcfg.getxt("anlz27"),msg:e.chldthmcfg.getxt("anlz26"),style:"updated"}),e("#ctc_enqueue_none").prop("checked",!0),o=1,_.ctc_enqueue="none")}return a=encodeURIComponent(JSON.stringify(c.analysis)),e('input[name="ctc_analysis"]').val(a),_.ctc_analysis=a,c.is_success()&&o&&!c.resubmitting?(c.resubmitting=1,void c.resubmit(_)):(c.resubmitting=0,c.hide_loading(),e.each(r.notices,function(t,c){var i=e('<div class="'+c.style+' notice is-dismissible dashicons-before" ><h4>'+c.headline+"</h4>"+c.msg+"</div>");e.chldthmcfg.bind_dismiss(i),i.hide().appendTo("#"+n+"_analysis_notice").slideDown()}),e("#ctc_is_debug").is(":checked")&&(t='<div style="background-color:#ddd;padding:6px"><div class="ctc-section-toggle" id="ctc_analysis_obj">'+e.chldthmcfg.getxt("anlz30")+'</div><div id="ctc_analysis_obj_content" style="display:none"><textarea style="font-family:monospace;font-size:10px">'+JSON.stringify(c.analysis,null,2)+"</textarea></div></div>",e(t).appendTo("#"+n+"_analysis_notice")),e("#ctc_child_type_reset").is(":checked")||(e("#input_row_stylesheet_handling_container,#input_row_parent_handling_container,#ctc_child_header_parameters,#ctc_configure_submit").slideDown("fast"),e("#ctc_child_type_duplicate").is(":checked")?(e("#ctc_configure_submit .ctc-step").text("8"),e("#ctc_copy_theme_mods").find("input").prop("checked",!1)):(e("#ctc_configure_submit .ctc-step").text("9"),e("#ctc_copy_theme_mods").slideDown("fast")),e("#ctc_child_type_duplicate").is(":checked")||e("#ctc_child_type_new").is(":checked")?(e("#input_row_theme_slug").hide(),e("#input_row_new_theme_slug").slideDown("fast")):(e("#input_row_new_theme_slug").hide(),e("#input_row_theme_slug").slideDown("fast"))),void 0)},resubmit:function(t){var c=this;c.hide_loading(),c.show_loading(!0),t.action="ctc_update",t._wpnonce=e("#_wpnonce").val(),e.ajax({url:window.ctcAjax.ajaxurl,data:t,type:"POST"}).done(function(){c.hide_loading(),c.do_analysis()}).fail(function(){c.hide_loading()})},do_analysis:function(){var t=this;t.analysis={parnt:{},child:{}},t.phperr={parnt:[],child:[]},t.done=0,t.show_loading(!1),t.analyze_theme("parnt"),e.chldthmcfg.existing&&t.analyze_theme("child")},init:function(){var t=this;e(document).on("analysisdone",function(){t.done++,t.done>e.chldthmcfg.existing&&(t.done=0,t.css_notice())}),e("#ctc_main").on("click",".ctc-analyze-theme",function(){t.is_success()&&e.chldthmcfg.dismiss_notice(e(".ctc-success-response").parent(".notice")),t.do_analysis()}),(t.is_success()||window.ctcAjax.pluginmode)&&t.do_analysis()},analysis:{},done:0,resubmitting:0,is_success:function(){return e(".ctc-success-response").length}},e("#request-filesystem-credentials-form").length||(e.chldthmcfg.init(),e.chldthmanalyze.init())}(jQuery);
js/ctcgrad.js CHANGED
@@ -5,199 +5,199 @@
5
  * Licensed under the GPLv2 license.
6
  */
7
  (function( $, undef ){
8
- var _html, nonGradientIE, gradientType, vendorPrefixes, _css, Iris, UA, isIE, IEVersion;
9
- UA = navigator.userAgent.toLowerCase();
10
- isIE = navigator.appName === 'Microsoft Internet Explorer';
11
- IEVersion = isIE ? parseFloat( UA.match( /msie ([0-9]{1,}[\.0-9]{0,})/ )[1] ) : 0;
12
- nonGradientIE = ( isIE && IEVersion < 10 );
13
- // we don't bother with an unprefixed version, as it has a different syntax
14
- vendorPrefixes = ['-moz-', '-webkit-', '-o-', '-ms-' ];
15
- testGradientType();
16
-
17
- // Bail for IE <= 7
18
- if ( nonGradientIE && IEVersion <= 7 ) {
19
- $.fn.ctcgrad = $.noop;
20
- $.support.ctcgrad = false;
21
- return;
22
- }
23
-
24
- $.support.ctcgrad = true;
25
-
26
- function testGradientType() {
27
- var el, base;
28
- if ( nonGradientIE ) {
29
- gradientType = 'filter';
30
- }
31
- else {
32
- el = $('<div id="ctcgrad-gradtest" />');
33
- base = "linear-gradient(top,#fff,#000)";
34
- $.each( vendorPrefixes, function( i, val ){
35
- el.css( 'backgroundImage', val + base );
36
- if ( el.css( 'backgroundImage').match('gradient') ) {
37
- gradientType = i;
38
- return false;
39
- }
40
- });
41
- // check for legacy webkit gradient syntax
42
- if ( gradientType === false ) {
43
- el.css( 'background', '-webkit-gradient(linear,0% 0%,0% 100%,from(#fff),to(#000))' );
44
- if ( el.css( 'backgroundImage').match('gradient') )
45
- gradientType = 'webkit';
46
- }
47
- el.remove();
48
- }
49
-
50
- }
51
-
52
- /**
53
- * Only for CSS3 gradients. oldIE will use a separate function.
54
- *
55
- * Accepts as many color stops as necessary from 2nd arg on, or 2nd
56
- * arg can be an array of color stops
57
- *
58
- * @param {string} origin Gradient origin - top bottom left right (n)deg
59
- * @return {string} Appropriate CSS3 gradient string for use in
60
- */
61
- function createGradient( origin, stops ) {
62
- origin = ( origin.match(/(\d+deg|top|left|bottom|right)( (top|left|bottom|right))?/) ? origin : 'top');
63
- stops = $.isArray( stops ) ? stops : Array.prototype.slice.call(arguments, 1);
64
- if ( gradientType === 'webkit' )
65
- return legacyWebkitGradient( origin, stops );
66
- else
67
- return vendorPrefixes[gradientType] + 'linear-gradient(' + origin + ', ' + stops.join(', ') + ')';
68
- }
69
-
70
- /**
71
- * Stupid gradients for a stupid browser.
72
- */
73
- function stupidIEGradient( origin, stops ) {
74
- var type, self, lastIndex, filter, startPosProp, endPosProp, dimensionProp, template, html, filterVal;
75
-
76
- origin = ( origin === 'left' ) ? 'left' : 'top';
77
- stops = $.isArray( stops ) ? stops : Array.prototype.slice.call(arguments, 1);
78
- // 8 hex: AARRGGBB
79
- // GradientType: 0 vertical, 1 horizontal
80
- type = ( origin === 'top' ) ? 0 : 1;
81
- self = $( this );
82
- lastIndex = stops.length - 1;
83
- filter = 'filter';
84
- startPosProp = ( type === 1 ) ? 'left' : 'top';
85
- endPosProp = ( type === 1 ) ? 'right' : 'bottom';
86
- dimensionProp = ( type === 1 ) ? 'height' : 'width';
87
- // need a positioning context
88
- if ( self.css('position') === 'static' )
89
- self.css( {position: 'relative' } );
90
-
91
- stops = fillColorStops( stops );
92
- $.each(stops, function( i, startColor ) {
93
- var endColor, endStop;
94
-
95
- // we want two at a time. if we're on the last pair, bail.
96
- if ( i === lastIndex )
97
- return false;
98
-
99
- endColor = stops[ i + 1 ];
100
- //if our pairs are at the same color stop, moving along.
101
- if ( startColor.stop === endColor.stop )
102
- return;
103
-
104
- endStop = 100 - parseFloat( endColor.stop ) + '%';
105
- startColor.octoHex = new Color( startColor.color ).toIEOctoHex();
106
- endColor.octoHex = new Color( endColor.color ).toIEOctoHex();
107
-
108
- filterVal = "progid:DXImageTransform.Microsoft.Gradient(GradientType=" + type + ", StartColorStr='" + startColor.octoHex + "', EndColorStr='" + endColor.octoHex + "')";
109
- });
110
  return filterVal;
111
- }
112
-
113
- function legacyWebkitGradient( origin, colorList ) {
114
- var stops = [];
115
- origin = ( origin === 'top' ) ? '0% 0%,0% 100%,' : '0% 100%,100% 100%,';
116
- colorList = fillColorStops( colorList );
117
- $.each( colorList, function( i, val ){
118
- stops.push( 'color-stop(' + ( parseFloat( val.stop ) / 100 ) + ', ' + val.color + ')' );
119
- });
120
- return '-webkit-gradient(linear,' + origin + stops.join(',') + ')';
121
- }
122
-
123
- function fillColorStops( colorList ) {
124
- var colors = [],
125
- percs = [],
126
- newColorList = [],
127
- lastIndex = colorList.length - 1;
128
-
129
- $.each( colorList, function( index, val ) {
130
- var color = val,
131
- perc = false,
132
- match = val.match(/1?[0-9]{1,2}%$/);
133
-
134
- if ( match ) {
135
- color = val.replace(/\s?1?[0-9]{1,2}%$/, '');
136
- perc = match.shift();
137
- }
138
- colors.push( color );
139
- percs.push( perc );
140
- });
141
-
142
- // back fill first and last
143
- if ( percs[0] === false )
144
- percs[0] = '0%';
145
-
146
- if ( percs[lastIndex] === false )
147
- percs[lastIndex] = '100%';
148
-
149
- percs = backFillColorStops( percs );
150
-
151
- $.each( percs, function( i ){
152
- newColorList[i] = { color: colors[i], stop: percs[i] };
153
- });
154
- return newColorList;
155
- }
156
-
157
- function backFillColorStops( stops ) {
158
- var first = 0,
159
- last = stops.length - 1,
160
- i = 0,
161
- foundFirst = false,
162
- incr,
163
- steps,
164
- step,
165
- firstVal;
166
-
167
- if ( stops.length <= 2 || $.inArray( false, stops ) < 0 ) {
168
- return stops;
169
- }
170
- while ( i < stops.length - 1 ) {
171
- if ( ! foundFirst && stops[i] === false ) {
172
- first = i - 1;
173
- foundFirst = true;
174
- } else if ( foundFirst && stops[i] !== false ) {
175
- last = i;
176
- i = stops.length;
177
- }
178
- i++;
179
- }
180
- steps = last - first;
181
- firstVal = parseInt( stops[first].replace('%'), 10 );
182
- incr = ( parseFloat( stops[last].replace('%') ) - firstVal ) / steps;
183
- i = first + 1;
184
- step = 1;
185
- while ( i < last ) {
186
- stops[i] = ( firstVal + ( step * incr ) ) + '%';
187
- step++;
188
- i++;
189
- }
190
- return backFillColorStops( stops );
191
- }
192
-
193
- $.fn.ctcgrad = function( origin ) {
194
- var args = arguments;
195
- // this'll be oldishIE
196
- if ( nonGradientIE )
197
  $(this).css('filter',
198
- stupidIEGradient.apply( this, args ));
199
- else // new hotness
200
- $( this ).css( 'backgroundImage', createGradient.apply( this, args ) );
201
- };
202
 
203
  }( jQuery ));
5
  * Licensed under the GPLv2 license.
6
  */
7
  (function( $, undef ){
8
+ var _html, nonGradientIE, gradientType, vendorPrefixes, _css, Iris, UA, isIE, IEVersion;
9
+ UA = navigator.userAgent.toLowerCase();
10
+ isIE = navigator.appName === 'Microsoft Internet Explorer';
11
+ IEVersion = isIE ? parseFloat( UA.match( /msie ([0-9]{1,}[\.0-9]{0,})/ )[1] ) : 0;
12
+ nonGradientIE = ( isIE && IEVersion < 10 );
13
+ // we don't bother with an unprefixed version, as it has a different syntax
14
+ vendorPrefixes = ['-moz-', '-webkit-', '-o-', '-ms-' ];
15
+ testGradientType();
16
+
17
+ // Bail for IE <= 7
18
+ if ( nonGradientIE && IEVersion <= 7 ) {
19
+ $.fn.ctcgrad = $.noop;
20
+ $.support.ctcgrad = false;
21
+ return;
22
+ }
23
+
24
+ $.support.ctcgrad = true;
25
+
26
+ function testGradientType() {
27
+ var el, base;
28
+ if ( nonGradientIE ) {
29
+ gradientType = 'filter';
30
+ }
31
+ else {
32
+ el = $('<div id="ctcgrad-gradtest" />');
33
+ base = "linear-gradient(top,#fff,#000)";
34
+ $.each( vendorPrefixes, function( i, val ){
35
+ el.css( 'backgroundImage', val + base );
36
+ if ( el.css( 'backgroundImage').match('gradient') ) {
37
+ gradientType = i;
38
+ return false;
39
+ }
40
+ });
41
+ // check for legacy webkit gradient syntax
42
+ if ( gradientType === false ) {
43
+ el.css( 'background', '-webkit-gradient(linear,0% 0%,0% 100%,from(#fff),to(#000))' );
44
+ if ( el.css( 'backgroundImage').match('gradient') )
45
+ gradientType = 'webkit';
46
+ }
47
+ el.remove();
48
+ }
49
+
50
+ }
51
+
52
+ /**
53
+ * Only for CSS3 gradients. oldIE will use a separate function.
54
+ *
55
+ * Accepts as many color stops as necessary from 2nd arg on, or 2nd
56
+ * arg can be an array of color stops
57
+ *
58
+ * @param {string} origin Gradient origin - top bottom left right (n)deg
59
+ * @return {string} Appropriate CSS3 gradient string for use in
60
+ */
61
+ function createGradient( origin, stops ) {
62
+ origin = ( origin.match(/(\d+deg|top|left|bottom|right)( (top|left|bottom|right))?/) ? origin : 'top');
63
+ stops = $.isArray( stops ) ? stops : Array.prototype.slice.call(arguments, 1);
64
+ if ( gradientType === 'webkit' )
65
+ return legacyWebkitGradient( origin, stops );
66
+ else
67
+ return vendorPrefixes[gradientType] + 'linear-gradient(' + origin + ', ' + stops.join(', ') + ')';
68
+ }
69
+
70
+ /**
71
+ * Stupid gradients for a stupid browser.
72
+ */
73
+ function stupidIEGradient( origin, stops ) {
74
+ var type, self, lastIndex, filter, startPosProp, endPosProp, dimensionProp, template, html, filterVal;
75
+
76
+ origin = ( origin === 'left' ) ? 'left' : 'top';
77
+ stops = $.isArray( stops ) ? stops : Array.prototype.slice.call(arguments, 1);
78
+ // 8 hex: AARRGGBB
79
+ // GradientType: 0 vertical, 1 horizontal
80
+ type = ( origin === 'top' ) ? 0 : 1;
81
+ self = $( this );
82
+ lastIndex = stops.length - 1;
83
+ filter = 'filter';
84
+ startPosProp = ( type === 1 ) ? 'left' : 'top';
85
+ endPosProp = ( type === 1 ) ? 'right' : 'bottom';
86
+ dimensionProp = ( type === 1 ) ? 'height' : 'width';
87
+ // need a positioning context
88
+ if ( self.css('position') === 'static' )
89
+ self.css( {position: 'relative' } );
90
+
91
+ stops = fillColorStops( stops );
92
+ $.each(stops, function( i, startColor ) {
93
+ var endColor, endStop;
94
+
95
+ // we want two at a time. if we're on the last pair, bail.
96
+ if ( i === lastIndex )
97
+ return false;
98
+
99
+ endColor = stops[ i + 1 ];
100
+ //if our pairs are at the same color stop, moving along.
101
+ if ( startColor.stop === endColor.stop )
102
+ return;
103
+
104
+ endStop = 100 - parseFloat( endColor.stop ) + '%';
105
+ startColor.octoHex = new Color( startColor.color ).toIEOctoHex();
106
+ endColor.octoHex = new Color( endColor.color ).toIEOctoHex();
107
+
108
+ filterVal = "progid:DXImageTransform.Microsoft.Gradient(GradientType=" + type + ", StartColorStr='" + startColor.octoHex + "', EndColorStr='" + endColor.octoHex + "')";
109
+ });
110
  return filterVal;
111
+ }
112
+
113
+ function legacyWebkitGradient( origin, colorList ) {
114
+ var stops = [];
115
+ origin = ( origin === 'top' ) ? '0% 0%,0% 100%,' : '0% 100%,100% 100%,';
116
+ colorList = fillColorStops( colorList );
117
+ $.each( colorList, function( i, val ){
118
+ stops.push( 'color-stop(' + ( parseFloat( val.stop ) / 100 ) + ', ' + val.color + ')' );
119
+ });
120
+ return '-webkit-gradient(linear,' + origin + stops.join(',') + ')';
121
+ }
122
+
123
+ function fillColorStops( colorList ) {
124
+ var colors = [],
125
+ percs = [],
126
+ newColorList = [],
127
+ lastIndex = colorList.length - 1;
128
+
129
+ $.each( colorList, function( index, val ) {
130
+ var color = val,
131
+ perc = false,
132
+ match = val.match(/1?[0-9]{1,2}%$/);
133
+
134
+ if ( match ) {
135
+ color = val.replace(/\s?1?[0-9]{1,2}%$/, '');
136
+ perc = match.shift();
137
+ }
138
+ colors.push( color );
139
+ percs.push( perc );
140
+ });
141
+
142
+ // back fill first and last
143
+ if ( percs[0] === false )
144
+ percs[0] = '0%';
145
+
146
+ if ( percs[lastIndex] === false )
147
+ percs[lastIndex] = '100%';
148
+
149
+ percs = backFillColorStops( percs );
150
+
151
+ $.each( percs, function( i ){
152
+ newColorList[i] = { color: colors[i], stop: percs[i] };
153
+ });
154
+ return newColorList;
155
+ }
156
+
157
+ function backFillColorStops( stops ) {
158
+ var first = 0,
159
+ last = stops.length - 1,
160
+ i = 0,
161
+ foundFirst = false,
162
+ incr,
163
+ steps,
164
+ step,
165
+ firstVal;
166
+
167
+ if ( stops.length <= 2 || $.inArray( false, stops ) < 0 ) {
168
+ return stops;
169
+ }
170
+ while ( i < stops.length - 1 ) {
171
+ if ( ! foundFirst && stops[i] === false ) {
172
+ first = i - 1;
173
+ foundFirst = true;
174
+ } else if ( foundFirst && stops[i] !== false ) {
175
+ last = i;
176
+ i = stops.length;
177
+ }
178
+ i++;
179
+ }
180
+ steps = last - first;
181
+ firstVal = parseInt( stops[first].replace('%'), 10 );
182
+ incr = ( parseFloat( stops[last].replace('%') ) - firstVal ) / steps;
183
+ i = first + 1;
184
+ step = 1;
185
+ while ( i < last ) {
186
+ stops[i] = ( firstVal + ( step * incr ) ) + '%';
187
+ step++;
188
+ i++;
189
+ }
190
+ return backFillColorStops( stops );
191
+ }
192
+
193
+ $.fn.ctcgrad = function( origin ) {
194
+ var args = arguments;
195
+ // this'll be oldishIE
196
+ if ( nonGradientIE )
197
  $(this).css('filter',
198
+ stupidIEGradient.apply( this, args ));
199
+ else // new hotness
200
+ $( this ).css( 'backgroundImage', createGradient.apply( this, args ) );
201
+ };
202
 
203
  }( jQuery ));
js/jquery-ui-selectmenu.js CHANGED
@@ -4,15 +4,15 @@
4
  * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
5
 
6
  (function( factory ) {
7
- if ( typeof define === "function" && define.amd ) {
8
 
9
- // AMD. Register as an anonymous module.
10
- define([ "jquery" ], factory );
11
- } else {
12
 
13
- // Browser globals
14
- factory( jQuery );
15
- }
16
  }(function( $ ) {
17
 
18
 
@@ -29,219 +29,219 @@
29
 
30
 
31
  var widget_uuid = 0,
32
- widget_slice = Array.prototype.slice;
33
 
34
  $.cleanData = (function( orig ) {
35
- return function( elems ) {
36
- var events, elem, i;
37
- for ( i = 0; (elem = elems[i]) != null; i++ ) {
38
- try {
39
-
40
- // Only trigger remove when necessary to save time
41
- events = $._data( elem, "events" );
42
- if ( events && events.remove ) {
43
- $( elem ).triggerHandler( "remove" );
44
- }
45
-
46
- // http://bugs.jquery.com/ticket/8235
47
- } catch ( e ) {}
48
- }
49
- orig( elems );
50
- };
51
  })( $.cleanData );
52
 
53
  $.widget = function( name, base, prototype ) {
54
- var fullName, existingConstructor, constructor, basePrototype,
55
- // proxiedPrototype allows the provided prototype to remain unmodified
56
- // so that it can be used as a mixin for multiple widgets (#8876)
57
- proxiedPrototype = {},
58
- namespace = name.split( "." )[ 0 ];
59
-
60
- name = name.split( "." )[ 1 ];
61
- fullName = namespace + "-" + name;
62
-
63
- if ( !prototype ) {
64
- prototype = base;
65
- base = $.Widget;
66
- }
67
-
68
- // create selector for plugin
69
- $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
70
- return !!$.data( elem, fullName );
71
- };
72
-
73
- $[ namespace ] = $[ namespace ] || {};
74
- existingConstructor = $[ namespace ][ name ];
75
- constructor = $[ namespace ][ name ] = function( options, element ) {
76
- // allow instantiation without "new" keyword
77
- if ( !this._createWidget ) {
78
- return new constructor( options, element );
79
- }
80
-
81
- // allow instantiation without initializing for simple inheritance
82
- // must use "new" keyword (the code above always passes args)
83
- if ( arguments.length ) {
84
- this._createWidget( options, element );
85
- }
86
- };
87
- // extend with the existing constructor to carry over any static properties
88
- $.extend( constructor, existingConstructor, {
89
- version: prototype.version,
90
- // copy the object used to create the prototype in case we need to
91
- // redefine the widget later
92
- _proto: $.extend( {}, prototype ),
93
- // track widgets that inherit from this widget in case this widget is
94
- // redefined after a widget inherits from it
95
- _childConstructors: []
96
- });
97
-
98
- basePrototype = new base();
99
- // we need to make the options hash a property directly on the new instance
100
- // otherwise we'll modify the options hash on the prototype that we're
101
- // inheriting from
102
- basePrototype.options = $.widget.extend( {}, basePrototype.options );
103
- $.each( prototype, function( prop, value ) {
104
- if ( !$.isFunction( value ) ) {
105
- proxiedPrototype[ prop ] = value;
106
- return;
107
- }
108
- proxiedPrototype[ prop ] = (function() {
109
- var _super = function() {
110
- return base.prototype[ prop ].apply( this, arguments );
111
- },
112
- _superApply = function( args ) {
113
- return base.prototype[ prop ].apply( this, args );
114
- };
115
- return function() {
116
- var __super = this._super,
117
- __superApply = this._superApply,
118
- returnValue;
119
-
120
- this._super = _super;
121
- this._superApply = _superApply;
122
-
123
- returnValue = value.apply( this, arguments );
124
-
125
- this._super = __super;
126
- this._superApply = __superApply;
127
-
128
- return returnValue;
129
- };
130
- })();
131
- });
132
- constructor.prototype = $.widget.extend( basePrototype, {
133
- // TODO: remove support for widgetEventPrefix
134
- // always use the name + a colon as the prefix, e.g., draggable:start
135
- // don't prefix for widgets that aren't DOM-based
136
- widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
137
- }, proxiedPrototype, {
138
- constructor: constructor,
139
- namespace: namespace,
140
- widgetName: name,
141
- widgetFullName: fullName
142
- });
143
-
144
- // If this widget is being redefined then we need to find all widgets that
145
- // are inheriting from it and redefine all of them so that they inherit from
146
- // the new version of this widget. We're essentially trying to replace one
147
- // level in the prototype chain.
148
- if ( existingConstructor ) {
149
- $.each( existingConstructor._childConstructors, function( i, child ) {
150
- var childPrototype = child.prototype;
151
-
152
- // redefine the child widget using the same prototype that was
153
- // originally used, but inherit from the new version of the base
154
- $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
155
- });
156
- // remove the list of existing child constructors from the old constructor
157
- // so the old child constructors can be garbage collected
158
- delete existingConstructor._childConstructors;
159
- } else {
160
- base._childConstructors.push( constructor );
161
- }
162
-
163
- $.widget.bridge( name, constructor );
164
-
165
- return constructor;
166
  };
167
 
168
  $.widget.extend = function( target ) {
169
- var input = widget_slice.call( arguments, 1 ),
170
- inputIndex = 0,
171
- inputLength = input.length,
172
- key,
173
- value;
174
- for ( ; inputIndex < inputLength; inputIndex++ ) {
175
- for ( key in input[ inputIndex ] ) {
176
- value = input[ inputIndex ][ key ];
177
- if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
178
- // Clone objects
179
- if ( $.isPlainObject( value ) ) {
180
- target[ key ] = $.isPlainObject( target[ key ] ) ?
181
- $.widget.extend( {}, target[ key ], value ) :
182
- // Don't extend strings, arrays, etc. with objects
183
- $.widget.extend( {}, value );
184
- // Copy everything else by reference
185
- } else {
186
- target[ key ] = value;
187
- }
188
- }
189
- }
190
- }
191
- return target;
192
  };
193
 
194
  $.widget.bridge = function( name, object ) {
195
- var fullName = object.prototype.widgetFullName || name;
196
- $.fn[ name ] = function( options ) {
197
- var isMethodCall = typeof options === "string",
198
- args = widget_slice.call( arguments, 1 ),
199
- returnValue = this;
200
-
201
- // allow multiple hashes to be passed on init
202
- options = !isMethodCall && args.length ?
203
- $.widget.extend.apply( null, [ options ].concat(args) ) :
204
- options;
205
-
206
- if ( isMethodCall ) {
207
- this.each(function() {
208
- var methodValue,
209
- instance = $.data( this, fullName );
210
- if ( options === "instance" ) {
211
- returnValue = instance;
212
- return false;
213
- }
214
- if ( !instance ) {
215
- return $.error( "cannot call methods on " + name + " prior to initialization; " +
216
- "attempted to call method '" + options + "'" );
217
- }
218
- if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
219
- return $.error( "no such method '" + options + "' for " + name + " widget instance" );
220
- }
221
- methodValue = instance[ options ].apply( instance, args );
222
- if ( methodValue !== instance && methodValue !== undefined ) {
223
- returnValue = methodValue && methodValue.jquery ?
224
- returnValue.pushStack( methodValue.get() ) :
225
- methodValue;
226
- return false;
227
- }
228
- });
229
- } else {
230
- this.each(function() {
231
- var instance = $.data( this, fullName );
232
- if ( instance ) {
233
- instance.option( options || {} );
234
- if ( instance._init ) {
235
- instance._init();
236
- }
237
- } else {
238
- $.data( this, fullName, new object( options, this ) );
239
- }
240
- });
241
- }
242
-
243
- return returnValue;
244
- };
245
  };
246
 
247
  $.Widget = function( /* options, element */ ) {};
@@ -250,316 +250,316 @@ $.Widget = function( /* options, element */ ) {};
250
  $.Widget._childConstructors = [];
251
 
252
  $.Widget.prototype = {
253
- widgetName: "widget",
254
- widgetEventPrefix: "",
255
- defaultElement: "<div>",
256
- options: {
257
- disabled: false,
258
-
259
- // callbacks
260
- create: null
261
- },
262
- _createWidget: function( options, element ) {
263
- element = $( element || this.defaultElement || this )[ 0 ];
264
- this.element = $( element );
265
- this.uuid = widget_uuid++;
266
- this.eventNamespace = "." + this.widgetName + this.uuid;
267
-
268
- this.bindings = $();
269
- this.hoverable = $();
270
- this.focusable = $();
271
-
272
- if ( element !== this ) {
273
- $.data( element, this.widgetFullName, this );
274
- this._on( true, this.element, {
275
- remove: function( event ) {
276
- if ( event.target === element ) {
277
- this.destroy();
278
- }
279
- }
280
- });
281
- this.document = $( element.style ?
282
- // element within the document
283
- element.ownerDocument :
284
- // element is window or document
285
- element.document || element );
286
- this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
287
- }
288
-
289
- this.options = $.widget.extend( {},
290
- this.options,
291
- this._getCreateOptions(),
292
- options );
293
-
294
- this._create();
295
- this._trigger( "create", null, this._getCreateEventData() );
296
- this._init();
297
- },
298
- _getCreateOptions: $.noop,
299
- _getCreateEventData: $.noop,
300
- _create: $.noop,
301
- _init: $.noop,
302
-
303
- destroy: function() {
304
- this._destroy();
305
- // we can probably remove the unbind calls in 2.0
306
- // all event bindings should go through this._on()
307
- this.element
308
- .unbind( this.eventNamespace )
309
- .removeData( this.widgetFullName )
310
- // support: jquery <1.6.4
311
- // http://bugs.jquery.com/ticket/9413
312
- .removeData( $.camelCase( this.widgetFullName ) );
313
- this.widget()
314
- .unbind( this.eventNamespace )
315
- .removeAttr( "aria-disabled" )
316
- .removeClass(
317
- this.widgetFullName + "-disabled " +
318
- "ui-state-disabled" );
319
-
320
- // clean up events and states
321
- this.bindings.unbind( this.eventNamespace );
322
- this.hoverable.removeClass( "ui-state-hover" );
323
- this.focusable.removeClass( "ui-state-focus" );
324
- },
325
- _destroy: $.noop,
326
-
327
- widget: function() {
328
- return this.element;
329
- },
330
-
331
- option: function( key, value ) {
332
- var options = key,
333
- parts,
334
- curOption,
335
- i;
336
-
337
- if ( arguments.length === 0 ) {
338
- // don't return a reference to the internal hash
339
- return $.widget.extend( {}, this.options );
340
- }
341
-
342
- if ( typeof key === "string" ) {
343
- // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
344
- options = {};
345
- parts = key.split( "." );
346
- key = parts.shift();
347
- if ( parts.length ) {
348
- curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
349
- for ( i = 0; i < parts.length - 1; i++ ) {
350
- curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
351
- curOption = curOption[ parts[ i ] ];
352
- }
353
- key = parts.pop();
354
- if ( arguments.length === 1 ) {
355
- return curOption[ key ] === undefined ? null : curOption[ key ];
356
- }
357
- curOption[ key ] = value;
358
- } else {
359
- if ( arguments.length === 1 ) {
360
- return this.options[ key ] === undefined ? null : this.options[ key ];
361
- }
362
- options[ key ] = value;
363
- }
364
- }
365
-
366
- this._setOptions( options );
367
-
368
- return this;
369
- },
370
- _setOptions: function( options ) {
371
- var key;
372
-
373
- for ( key in options ) {
374
- this._setOption( key, options[ key ] );
375
- }
376
-
377
- return this;
378
- },
379
- _setOption: function( key, value ) {
380
- this.options[ key ] = value;
381
-
382
- if ( key === "disabled" ) {
383
- this.widget()
384
- .toggleClass( this.widgetFullName + "-disabled", !!value );
385
-
386
- // If the widget is becoming disabled, then nothing is interactive
387
- if ( value ) {
388
- this.hoverable.removeClass( "ui-state-hover" );
389
- this.focusable.removeClass( "ui-state-focus" );
390
- }
391
- }
392
-
393
- return this;
394
- },
395
-
396
- enable: function() {
397
- return this._setOptions({ disabled: false });
398
- },
399
- disable: function() {
400
- return this._setOptions({ disabled: true });
401
- },
402
-
403
- _on: function( suppressDisabledCheck, element, handlers ) {
404
- var delegateElement,
405
- instance = this;
406
-
407
- // no suppressDisabledCheck flag, shuffle arguments
408
- if ( typeof suppressDisabledCheck !== "boolean" ) {
409
- handlers = element;
410
- element = suppressDisabledCheck;
411
- suppressDisabledCheck = false;
412
- }
413
-
414
- // no element argument, shuffle and use this.element
415
- if ( !handlers ) {
416
- handlers = element;
417
- element = this.element;
418
- delegateElement = this.widget();
419
- } else {
420
- element = delegateElement = $( element );
421
- this.bindings = this.bindings.add( element );
422
- }
423
-
424
- $.each( handlers, function( event, handler ) {
425
- function handlerProxy() {
426
- // allow widgets to customize the disabled handling
427
- // - disabled as an array instead of boolean
428
- // - disabled class as method for disabling individual parts
429
- if ( !suppressDisabledCheck &&
430
- ( instance.options.disabled === true ||
431
- $( this ).hasClass( "ui-state-disabled" ) ) ) {
432
- return;
433
- }
434
- return ( typeof handler === "string" ? instance[ handler ] : handler )
435
- .apply( instance, arguments );
436
- }
437
-
438
- // copy the guid so direct unbinding works
439
- if ( typeof handler !== "string" ) {
440
- handlerProxy.guid = handler.guid =
441
- handler.guid || handlerProxy.guid || $.guid++;
442
- }
443
-
444
- var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
445
- eventName = match[1] + instance.eventNamespace,
446
- selector = match[2];
447
- if ( selector ) {
448
- delegateElement.delegate( selector, eventName, handlerProxy );
449
- } else {
450
- element.bind( eventName, handlerProxy );
451
- }
452
- });
453
- },
454
-
455
- _off: function( element, eventName ) {
456
- eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
457
- this.eventNamespace;
458
- element.unbind( eventName ).undelegate( eventName );
459
-
460
- // Clear the stack to avoid memory leaks (#10056)
461
- this.bindings = $( this.bindings.not( element ).get() );
462
- this.focusable = $( this.focusable.not( element ).get() );
463
- this.hoverable = $( this.hoverable.not( element ).get() );
464
- },
465
-
466
- _delay: function( handler, delay ) {
467
- function handlerProxy() {
468
- return ( typeof handler === "string" ? instance[ handler ] : handler )
469
- .apply( instance, arguments );
470
- }
471
- var instance = this;
472
- return setTimeout( handlerProxy, delay || 0 );
473
- },
474
-
475
- _hoverable: function( element ) {
476
- this.hoverable = this.hoverable.add( element );
477
- this._on( element, {
478
- mouseenter: function( event ) {
479
- $( event.currentTarget ).addClass( "ui-state-hover" );
480
- },
481
- mouseleave: function( event ) {
482
- $( event.currentTarget ).removeClass( "ui-state-hover" );
483
- }
484
- });
485
- },
486
-
487
- _focusable: function( element ) {
488
- this.focusable = this.focusable.add( element );
489
- this._on( element, {
490
- focusin: function( event ) {
491
- $( event.currentTarget ).addClass( "ui-state-focus" );
492
- },
493
- focusout: function( event ) {
494
- $( event.currentTarget ).removeClass( "ui-state-focus" );
495
- }
496
- });
497
- },
498
-
499
- _trigger: function( type, event, data ) {
500
- var prop, orig,
501
- callback = this.options[ type ];
502
-
503
- data = data || {};
504
- event = $.Event( event );
505
- event.type = ( type === this.widgetEventPrefix ?
506
- type :
507
- this.widgetEventPrefix + type ).toLowerCase();
508
- // the original event may come from any element
509
- // so we need to reset the target on the new event
510
- event.target = this.element[ 0 ];
511
-
512
- // copy original event properties over to the new event
513
- orig = event.originalEvent;
514
- if ( orig ) {
515
- for ( prop in orig ) {
516
- if ( !( prop in event ) ) {
517
- event[ prop ] = orig[ prop ];
518
- }
519
- }
520
- }
521
-
522
- this.element.trigger( event, data );
523
- return !( $.isFunction( callback ) &&
524
- callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
525
- event.isDefaultPrevented() );
526
- }
527
  };
528
 
529
  $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
530
- $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
531
- if ( typeof options === "string" ) {
532
- options = { effect: options };
533
- }
534
- var hasOptions,
535
- effectName = !options ?
536
- method :
537
- options === true || typeof options === "number" ?
538
- defaultEffect :
539
- options.effect || defaultEffect;
540
- options = options || {};
541
- if ( typeof options === "number" ) {
542
- options = { duration: options };
543
- }
544
- hasOptions = !$.isEmptyObject( options );
545
- options.complete = callback;
546
- if ( options.delay ) {
547
- element.delay( options.delay );
548
- }
549
- if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
550
- element[ method ]( options );
551
- } else if ( effectName !== method && element[ effectName ] ) {
552
- element[ effectName ]( options.duration, options.easing, callback );
553
- } else {
554
- element.queue(function( next ) {
555
- $( this )[ method ]();
556
- if ( callback ) {
557
- callback.call( element[ 0 ] );
558
- }
559
- next();
560
- });
561
- }
562
- };
563
  });
564
 
565
  var widget = $.widget;
@@ -580,621 +580,621 @@ var widget = $.widget;
580
 
581
 
582
  var menu = $.widget( "ui.menu", {
583
- version: "1.11.2",
584
- defaultElement: "<ul>",
585
- delay: 300,
586
- options: {
587
- icons: {
588
- submenu: "ui-icon-carat-1-e"
589
- },
590
- items: "> *",
591
- menus: "ul",
592
- position: {
593
- my: "left-1 top",
594
- at: "right top"
595
- },
596
- role: "menu",
597
-
598
- // callbacks
599
- blur: null,
600
- focus: null,
601
- select: null
602
- },
603
-
604
- _create: function() {
605
- this.activeMenu = this.element;
606
-
607
- // Flag used to prevent firing of the click handler
608
- // as the event bubbles up through nested menus
609
- this.mouseHandled = false;
610
- this.element
611
- .uniqueId()
612
- .addClass( "ui-menu ui-widget ui-widget-content" )
613
- .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
614
- .attr({
615
- role: this.options.role,
616
- tabIndex: 0
617
- });
618
-
619
- if ( this.options.disabled ) {
620
- this.element
621
- .addClass( "ui-state-disabled" )
622
- .attr( "aria-disabled", "true" );
623
- }
624
-
625
- this._on({
626
- // Prevent focus from sticking to links inside menu after clicking
627
- // them (focus should always stay on UL during navigation).
628
- "mousedown .ui-menu-item": function( event ) {
629
- event.preventDefault();
630
- },
631
- "click .ui-menu-item": function( event ) {
632
- var target = $( event.target );
633
- if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
634
- this.select( event );
635
-
636
- // Only set the mouseHandled flag if the event will bubble, see #9469.
637
- if ( !event.isPropagationStopped() ) {
638
- this.mouseHandled = true;
639
- }
640
-
641
- // Open submenu on click
642
- if ( target.has( ".ui-menu" ).length ) {
643
- this.expand( event );
644
- } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
645
-
646
- // Redirect focus to the menu
647
- this.element.trigger( "focus", [ true ] );
648
-
649
- // If the active item is on the top level, let it stay active.
650
- // Otherwise, blur the active item since it is no longer visible.
651
- if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
652
- clearTimeout( this.timer );
653
- }
654
- }
655
- }
656
- },
657
- "mouseenter .ui-menu-item": function( event ) {
658
- // Ignore mouse events while typeahead is active, see #10458.
659
- // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
660
- // is over an item in the menu
661
- if ( this.previousFilter ) {
662
- return;
663
- }
664
- var target = $( event.currentTarget );
665
- // Remove ui-state-active class from siblings of the newly focused menu item
666
- // to avoid a jump caused by adjacent elements both having a class with a border
667
- target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
668
- this.focus( event, target );
669
- },
670
- mouseleave: "collapseAll",
671
- "mouseleave .ui-menu": "collapseAll",
672
- focus: function( event, keepActiveItem ) {
673
- // If there's already an active item, keep it active
674
- // If not, activate the first item
675
- var item = this.active || this.element.find( this.options.items ).eq( 0 );
676
-
677
- if ( !keepActiveItem ) {
678
- this.focus( event, item );
679
- }
680
- },
681
- blur: function( event ) {
682
- this._delay(function() {
683
- if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
684
- this.collapseAll( event );
685
- }
686
- });
687
- },
688
- keydown: "_keydown"
689
- });
690
-
691
- this.refresh();
692
-
693
- // Clicks outside of a menu collapse any open menus
694
- this._on( this.document, {
695
- click: function( event ) {
696
- if ( this._closeOnDocumentClick( event ) ) {
697
- this.collapseAll( event );
698
- }
699
-
700
- // Reset the mouseHandled flag
701
- this.mouseHandled = false;
702
- }
703
- });
704
- },
705
-
706
- _destroy: function() {
707
- // Destroy (sub)menus
708
- this.element
709
- .removeAttr( "aria-activedescendant" )
710
- .find( ".ui-menu" ).addBack()
711
- .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
712
- .removeAttr( "role" )
713
- .removeAttr( "tabIndex" )
714
- .removeAttr( "aria-labelledby" )
715
- .removeAttr( "aria-expanded" )
716
- .removeAttr( "aria-hidden" )
717
- .removeAttr( "aria-disabled" )
718
- .removeUniqueId()
719
- .show();
720
-
721
- // Destroy menu items
722
- this.element.find( ".ui-menu-item" )
723
- .removeClass( "ui-menu-item" )
724
- .removeAttr( "role" )
725
- .removeAttr( "aria-disabled" )
726
- .removeUniqueId()
727
- .removeClass( "ui-state-hover" )
728
- .removeAttr( "tabIndex" )
729
- .removeAttr( "role" )
730
- .removeAttr( "aria-haspopup" )
731
- .children().each( function() {
732
- var elem = $( this );
733
- if ( elem.data( "ui-menu-submenu-carat" ) ) {
734
- elem.remove();
735
- }
736
- });
737
-
738
- // Destroy menu dividers
739
- this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
740
- },
741
-
742
- _keydown: function( event ) {
743
- var match, prev, character, skip,
744
- preventDefault = true;
745
-
746
- switch ( event.keyCode ) {
747
- case $.ui.keyCode.PAGE_UP:
748
- this.previousPage( event );
749
- break;
750
- case $.ui.keyCode.PAGE_DOWN:
751
- this.nextPage( event );
752
- break;
753
- case $.ui.keyCode.HOME:
754
- this._move( "first", "first", event );
755
- break;
756
- case $.ui.keyCode.END:
757
- this._move( "last", "last", event );
758
- break;
759
- case $.ui.keyCode.UP:
760
- this.previous( event );
761
- break;
762
- case $.ui.keyCode.DOWN:
763
- this.next( event );
764
- break;
765
- case $.ui.keyCode.LEFT:
766
- this.collapse( event );
767
- break;
768
- case $.ui.keyCode.RIGHT:
769
- if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
770
- this.expand( event );
771
- }
772
- break;
773
- case $.ui.keyCode.ENTER:
774
- case $.ui.keyCode.SPACE:
775
- this._activate( event );
776
- break;
777
- case $.ui.keyCode.ESCAPE:
778
- this.collapse( event );
779
- break;
780
- default:
781
- preventDefault = false;
782
- prev = this.previousFilter || "";
783
- character = String.fromCharCode( event.keyCode );
784
- skip = false;
785
-
786
- clearTimeout( this.filterTimer );
787
-
788
- if ( character === prev ) {
789
- skip = true;
790
- } else {
791
- character = prev + character;
792
- }
793
-
794
- match = this._filterMenuItems( character );
795
- match = skip && match.index( this.active.next() ) !== -1 ?
796
- this.active.nextAll( ".ui-menu-item" ) :
797
- match;
798
-
799
- // If no matches on the current filter, reset to the last character pressed
800
- // to move down the menu to the first item that starts with that character
801
- if ( !match.length ) {
802
- character = String.fromCharCode( event.keyCode );
803
- match = this._filterMenuItems( character );
804
- }
805
-
806
- if ( match.length ) {
807
- this.focus( event, match );
808
- this.previousFilter = character;
809
- this.filterTimer = this._delay(function() {
810
- delete this.previousFilter;
811
- }, 1000 );
812
- } else {
813
- delete this.previousFilter;
814
- }
815
- }
816
-
817
- if ( preventDefault ) {
818
- event.preventDefault();
819
- }
820
- },
821
-
822
- _activate: function( event ) {
823
- if ( !this.active.is( ".ui-state-disabled" ) ) {
824
- if ( this.active.is( "[aria-haspopup='true']" ) ) {
825
- this.expand( event );
826
- } else {
827
- this.select( event );
828
- }
829
- }
830
- },
831
-
832
- refresh: function() {
833
- var menus, items,
834
- that = this,
835
- icon = this.options.icons.submenu,
836
- submenus = this.element.find( this.options.menus );
837
-
838
- this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
839
-
840
- // Initialize nested menus
841
- submenus.filter( ":not(.ui-menu)" )
842
- .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
843
- .hide()
844
- .attr({
845
- role: this.options.role,
846
- "aria-hidden": "true",
847
- "aria-expanded": "false"
848
- })
849
- .each(function() {
850
- var menu = $( this ),
851
- item = menu.parent(),
852
- submenuCarat = $( "<span>" )
853
- .addClass( "ui-menu-icon ui-icon " + icon )
854
- .data( "ui-menu-submenu-carat", true );
855
-
856
- item
857
- .attr( "aria-haspopup", "true" )
858
- .prepend( submenuCarat );
859
- menu.attr( "aria-labelledby", item.attr( "id" ) );
860
- });
861
-
862
- menus = submenus.add( this.element );
863
- items = menus.find( this.options.items );
864
-
865
- // Initialize menu-items containing spaces and/or dashes only as dividers
866
- items.not( ".ui-menu-item" ).each(function() {
867
- var item = $( this );
868
- if ( that._isDivider( item ) ) {
869
- item.addClass( "ui-widget-content ui-menu-divider" );
870
- }
871
- });
872
-
873
- // Don't refresh list items that are already adapted
874
- items.not( ".ui-menu-item, .ui-menu-divider" )
875
- .addClass( "ui-menu-item" )
876
- .uniqueId()
877
- .attr({
878
- tabIndex: -1,
879
- role: this._itemRole()
880
- });
881
-
882
- // Add aria-disabled attribute to any disabled menu item
883
- items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
884
-
885
- // If the active item has been removed, blur the menu
886
- if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
887
- this.blur();
888
- }
889
- },
890
-
891
- _itemRole: function() {
892
- return {
893
- menu: "menuitem",
894
- listbox: "option"
895
- }[ this.options.role ];
896
- },
897
-
898
- _setOption: function( key, value ) {
899
- if ( key === "icons" ) {
900
- this.element.find( ".ui-menu-icon" )
901
- .removeClass( this.options.icons.submenu )
902
- .addClass( value.submenu );
903
- }
904
- if ( key === "disabled" ) {
905
- this.element
906
- .toggleClass( "ui-state-disabled", !!value )
907
- .attr( "aria-disabled", value );
908
- }
909
- this._super( key, value );
910
- },
911
-
912
- focus: function( event, item ) {
913
- var nested, focused;
914
- this.blur( event, event && event.type === "focus" );
915
-
916
- this._scrollIntoView( item );
917
-
918
- this.active = item.first();
919
- focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
920
- // Only update aria-activedescendant if there's a role
921
- // otherwise we assume focus is managed elsewhere
922
- if ( this.options.role ) {
923
- this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
924
- }
925
-
926
- // Highlight active parent menu item, if any
927
- this.active
928
- .parent()
929
- .closest( ".ui-menu-item" )
930
- .addClass( "ui-state-active" );
931
-
932
- if ( event && event.type === "keydown" ) {
933
- this._close();
934
- } else {
935
- this.timer = this._delay(function() {
936
- this._close();
937
- }, this.delay );
938
- }
939
-
940
- nested = item.children( ".ui-menu" );
941
- if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
942
- this._startOpening(nested);
943
- }
944
- this.activeMenu = item.parent();
945
-
946
- this._trigger( "focus", event, { item: item } );
947
- },
948
-
949
- _scrollIntoView: function( item ) {
950
- var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
951
- if ( this._hasScroll() ) {
952
- borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
953
- paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
954
- offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
955
- scroll = this.activeMenu.scrollTop();
956
- elementHeight = this.activeMenu.height();
957
- itemHeight = item.outerHeight();
958
-
959
- if ( offset < 0 ) {
960
- this.activeMenu.scrollTop( scroll + offset );
961
- } else if ( offset + itemHeight > elementHeight ) {
962
- this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
963
- }
964
- }
965
- },
966
-
967
- blur: function( event, fromFocus ) {
968
- if ( !fromFocus ) {
969
- clearTimeout( this.timer );
970
- }
971
-
972
- if ( !this.active ) {
973
- return;
974
- }
975
-
976
- this.active.removeClass( "ui-state-focus" );
977
- this.active = null;
978
-
979
- this._trigger( "blur", event, { item: this.active } );
980
- },
981
-
982
- _startOpening: function( submenu ) {
983
- clearTimeout( this.timer );
984
-
985
- // Don't open if already open fixes a Firefox bug that caused a .5 pixel
986
- // shift in the submenu position when mousing over the carat icon
987
- if ( submenu.attr( "aria-hidden" ) !== "true" ) {
988
- return;
989
- }
990
-
991
- this.timer = this._delay(function() {
992
- this._close();
993
- this._open( submenu );
994
- }, this.delay );
995
- },
996
-
997
- _open: function( submenu ) {
998
- var position = $.extend({
999
- of: this.active
1000
- }, this.options.position );
1001
-
1002
- clearTimeout( this.timer );
1003
- this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
1004
- .hide()
1005
- .attr( "aria-hidden", "true" );
1006
-
1007
- submenu
1008
- .show()
1009
- .removeAttr( "aria-hidden" )
1010
- .attr( "aria-expanded", "true" )
1011
- .position( position );
1012
- },
1013
-
1014
- collapseAll: function( event, all ) {
1015
- clearTimeout( this.timer );
1016
- this.timer = this._delay(function() {
1017
- // If we were passed an event, look for the submenu that contains the event
1018
- var currentMenu = all ? this.element :
1019
- $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
1020
-
1021
- // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
1022
- if ( !currentMenu.length ) {
1023
- currentMenu = this.element;
1024
- }
1025
-
1026
- this._close( currentMenu );
1027
-
1028
- this.blur( event );
1029
- this.activeMenu = currentMenu;
1030
- }, this.delay );
1031
- },
1032
-
1033
- // With no arguments, closes the currently active menu - if nothing is active
1034
- // it closes all menus. If passed an argument, it will search for menus BELOW
1035
- _close: function( startMenu ) {
1036
- if ( !startMenu ) {
1037
- startMenu = this.active ? this.active.parent() : this.element;
1038
- }
1039
-
1040
- startMenu
1041
- .find( ".ui-menu" )
1042
- .hide()
1043
- .attr( "aria-hidden", "true" )
1044
- .attr( "aria-expanded", "false" )
1045
- .end()
1046
- .find( ".ui-state-active" ).not( ".ui-state-focus" )
1047
- .removeClass( "ui-state-active" );
1048
- },
1049
-
1050
- _closeOnDocumentClick: function( event ) {
1051
- return !$( event.target ).closest( ".ui-menu" ).length;
1052
- },
1053
-
1054
- _isDivider: function( item ) {
1055
-
1056
- // Match hyphen, em dash, en dash
1057
- return !/[^\-\u2014\u2013\s]/.test( item.text() );
1058
- },
1059
-
1060
- collapse: function( event ) {
1061
- var newItem = this.active &&
1062
- this.active.parent().closest( ".ui-menu-item", this.element );
1063
- if ( newItem && newItem.length ) {
1064
- this._close();
1065
- this.focus( event, newItem );
1066
- }
1067
- },
1068
-
1069
- expand: function( event ) {
1070
- var newItem = this.active &&
1071
- this.active
1072
- .children( ".ui-menu " )
1073
- .find( this.options.items )
1074
- .first();
1075
-
1076
- if ( newItem && newItem.length ) {
1077
- this._open( newItem.parent() );
1078
-
1079
- // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
1080
- this._delay(function() {
1081
- this.focus( event, newItem );
1082
- });
1083
- }
1084
- },
1085
-
1086
- next: function( event ) {
1087
- this._move( "next", "first", event );
1088
- },
1089
-
1090
- previous: function( event ) {
1091
- this._move( "prev", "last", event );
1092
- },
1093
-
1094
- isFirstItem: function() {
1095
- return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
1096
- },
1097
-
1098
- isLastItem: function() {
1099
- return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
1100
- },
1101
-
1102
- _move: function( direction, filter, event ) {
1103
- var next;
1104
- if ( this.active ) {
1105
- if ( direction === "first" || direction === "last" ) {
1106
- next = this.active
1107
- [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
1108
- .eq( -1 );
1109
- } else {
1110
- next = this.active
1111
- [ direction + "All" ]( ".ui-menu-item" )
1112
- .eq( 0 );
1113
- }
1114
- }
1115
- if ( !next || !next.length || !this.active ) {
1116
- next = this.activeMenu.find( this.options.items )[ filter ]();
1117
- }
1118
-
1119
- this.focus( event, next );
1120
- },
1121
-
1122
- nextPage: function( event ) {
1123
- var item, base, height;
1124
-
1125
- if ( !this.active ) {
1126
- this.next( event );
1127
- return;
1128
- }
1129
- if ( this.isLastItem() ) {
1130
- return;
1131
- }
1132
- if ( this._hasScroll() ) {
1133
- base = this.active.offset().top;
1134
- height = this.element.height();
1135
- this.active.nextAll( ".ui-menu-item" ).each(function() {
1136
- item = $( this );
1137
- return item.offset().top - base - height < 0;
1138
- });
1139
-
1140
- this.focus( event, item );
1141
- } else {
1142
- this.focus( event, this.activeMenu.find( this.options.items )
1143
- [ !this.active ? "first" : "last" ]() );
1144
- }
1145
- },
1146
-
1147
- previousPage: function( event ) {
1148
- var item, base, height;
1149
- if ( !this.active ) {
1150
- this.next( event );
1151
- return;
1152
- }
1153
- if ( this.isFirstItem() ) {
1154
- return;
1155
- }
1156
- if ( this._hasScroll() ) {
1157
- base = this.active.offset().top;
1158
- height = this.element.height();
1159
- this.active.prevAll( ".ui-menu-item" ).each(function() {
1160
- item = $( this );
1161
- return item.offset().top - base + height > 0;
1162
- });
1163
-
1164
- this.focus( event, item );
1165
- } else {
1166
- this.focus( event, this.activeMenu.find( this.options.items ).first() );
1167
- }
1168
- },
1169
-
1170
- _hasScroll: function() {
1171
- return this.element.outerHeight() < this.element.prop( "scrollHeight" );
1172
- },
1173
-
1174
- select: function( event ) {
1175
- // TODO: It should never be possible to not have an active item at this
1176
- // point, but the tests don't trigger mouseenter before click.
1177
- this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
1178
- var ui = { item: this.active };
1179
- if ( !this.active.has( ".ui-menu" ).length ) {
1180
- this.collapseAll( event, true );
1181
- }
1182
- this._trigger( "select", event, ui );
1183
- },
1184
-
1185
- _filterMenuItems: function(character) {
1186
- var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
1187
- regex = new RegExp( "^" + escapedCharacter, "i" );
1188
-
1189
- return this.activeMenu
1190
- .find( this.options.items )
1191
-
1192
- // Only match on items, not dividers or other content (#10571)
1193
- .filter( ".ui-menu-item" )
1194
- .filter(function() {
1195
- return regex.test( $.trim( $( this ).text() ) );
1196
- });
1197
- }
1198
  });
1199
 
1200
 
@@ -1211,590 +1211,590 @@ var menu = $.widget( "ui.menu", {
1211
 
1212
 
1213
  var selectmenu = $.widget( "ui.selectmenu", {
1214
- version: "1.11.2",
1215
- defaultElement: "<select>",
1216
- options: {
1217
- appendTo: null,
1218
- disabled: null,
1219
- icons: {
1220
- button: "ui-icon-triangle-1-s"
1221
- },
1222
- position: {
1223
- my: "left top",
1224
- at: "left bottom",
1225
- collision: "none"
1226
- },
1227
- width: null,
1228
-
1229
- // callbacks
1230
- change: null,
1231
- close: null,
1232
- focus: null,
1233
- open: null,
1234
- select: null
1235
- },
1236
-
1237
- _create: function() {
1238
- var selectmenuId = this.element.uniqueId().attr( "id" );
1239
- this.ids = {
1240
- element: selectmenuId,
1241
- button: selectmenuId + "-button",
1242
- menu: selectmenuId + "-menu"
1243
- };
1244
-
1245
- this._drawButton();
1246
- this._drawMenu();
1247
-
1248
- if ( this.options.disabled ) {
1249
- this.disable();
1250
- }
1251
- },
1252
-
1253
- _drawButton: function() {
1254
- var that = this,
1255
- tabindex = this.element.attr( "tabindex" );
1256
-
1257
- // Associate existing label with the new button
1258
- this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
1259
- this._on( this.label, {
1260
- click: function( event ) {
1261
- this.button.focus();
1262
- event.preventDefault();
1263
- }
1264
- });
1265
-
1266
- // Hide original select element
1267
- this.element.hide();
1268
-
1269
- // Create button
1270
- this.button = $( "<span>", {
1271
- "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
1272
- tabindex: tabindex || this.options.disabled ? -1 : 0,
1273
- id: this.ids.button,
1274
- role: "combobox",
1275
- "aria-expanded": "false",
1276
- "aria-autocomplete": "list",
1277
- "aria-owns": this.ids.menu,
1278
- "aria-haspopup": "true"
1279
- })
1280
- .insertAfter( this.element );
1281
-
1282
- $( "<span>", {
1283
- "class": "ui-icon " + this.options.icons.button
1284
- })
1285
- .prependTo( this.button );
1286
-
1287
- this.buttonText = $( "<span>", {
1288
- "class": "ui-selectmenu-text"
1289
- })
1290
- .appendTo( this.button );
1291
-
1292
- this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
1293
- this._resizeButton();
1294
-
1295
- this._on( this.button, this._buttonEvents );
1296
- this.button.one( "focusin", function() {
1297
-
1298
- // Delay rendering the menu items until the button receives focus.
1299
- // The menu may have already been rendered via a programmatic open.
1300
- if ( !that.menuItems ) {
1301
- that._refreshMenu();
1302
- }
1303
- });
1304
- this._hoverable( this.button );
1305
- this._focusable( this.button );
1306
- },
1307
-
1308
- _drawMenu: function() {
1309
- var that = this;
1310
-
1311
- // Create menu
1312
- this.menu = $( "<ul>", {
1313
- "aria-hidden": "true",
1314
- "aria-labelledby": this.ids.button,
1315
- id: this.ids.menu
1316
- });
1317
-
1318
- // Wrap menu
1319
- this.menuWrap = $( "<div>", {
1320
- "class": "ui-selectmenu-menu ui-front"
1321
- })
1322
- .append( this.menu )
1323
- .appendTo( this._appendTo() );
1324
-
1325
- // Initialize menu widget
1326
- this.menuInstance = this.menu
1327
- .menu({
1328
- role: "listbox",
1329
- select: function( event, ui ) {
1330
- event.preventDefault();
1331
-
1332
- // support: IE8
1333
- // If the item was selected via a click, the text selection
1334
- // will be destroyed in IE
1335
- that._setSelection();
1336
-
1337
- that._select( ui.item.data( "ui-selectmenu-item" ), event );
1338
- },
1339
- focus: function( event, ui ) {
1340
- var item = ui.item.data( "ui-selectmenu-item" );
1341
-
1342
- // Prevent inital focus from firing and check if its a newly focused item
1343
- if ( that.focusIndex != null && item.index !== that.focusIndex ) {
1344
- that._trigger( "focus", event, { item: item } );
1345
- if ( !that.isOpen ) {
1346
- that._select( item, event );
1347
- }
1348
- }
1349
- that.focusIndex = item.index;
1350
-
1351
- that.button.attr( "aria-activedescendant",
1352
- that.menuItems.eq( item.index ).attr( "id" ) );
1353
- }
1354
- })
1355
- .menu( "instance" );
1356
-
1357
- // Adjust menu styles to dropdown
1358
- this.menu
1359
- .addClass( "ui-corner-bottom" )
1360
- .removeClass( "ui-corner-all" );
1361
-
1362
- // Don't close the menu on mouseleave
1363
- this.menuInstance._off( this.menu, "mouseleave" );
1364
-
1365
- // Cancel the menu's collapseAll on document click
1366
- this.menuInstance._closeOnDocumentClick = function() {
1367
- return false;
1368
- };
1369
-
1370
- // Selects often contain empty items, but never contain dividers
1371
- this.menuInstance._isDivider = function() {
1372
- return false;
1373
- };
1374
- },
1375
-
1376
- refresh: function() {
1377
- this._refreshMenu();
1378
- this._setText( this.buttonText, this._getSelectedItem().text() );
1379
- if ( !this.options.width ) {
1380
- this._resizeButton();
1381
- }
1382
- },
1383
-
1384
- _refreshMenu: function() {
1385
- this.menu.empty();
1386
-
1387
- var item,
1388
- options = this.element.find( "option" );
1389
-
1390
- if ( !options.length ) {
1391
- return;
1392
- }
1393
-
1394
- this._parseOptions( options );
1395
- this._renderMenu( this.menu, this.items );
1396
-
1397
- this.menuInstance.refresh();
1398
- this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
1399
-
1400
- item = this._getSelectedItem();
1401
-
1402
- // Update the menu to have the correct item focused
1403
- this.menuInstance.focus( null, item );
1404
- this._setAria( item.data( "ui-selectmenu-item" ) );
1405
-
1406
- // Set disabled state
1407
- this._setOption( "disabled", this.element.prop( "disabled" ) );
1408
- },
1409
-
1410
- open: function( event ) {
1411
- if ( this.options.disabled ) {
1412
- return;
1413
- }
1414
-
1415
- // If this is the first time the menu is being opened, render the items
1416
- if ( !this.menuItems ) {
1417
- this._refreshMenu();
1418
- } else {
1419
-
1420
- // Menu clears focus on close, reset focus to selected item
1421
- this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
1422
- this.menuInstance.focus( null, this._getSelectedItem() );
1423
- }
1424
-
1425
- this.isOpen = true;
1426
- this._toggleAttr();
1427
- this._resizeMenu();
1428
- this._position();
1429
-
1430
- this._on( this.document, this._documentClick );
1431
-
1432
- this._trigger( "open", event );
1433
- },
1434
-
1435
- _position: function() {
1436
- this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
1437
- },
1438
-
1439
- close: function( event ) {
1440
- if ( !this.isOpen ) {
1441
- return;
1442
- }
1443
-
1444
- this.isOpen = false;
1445
- this._toggleAttr();
1446
-
1447
- this.range = null;
1448
- this._off( this.document );
1449
-
1450
- this._trigger( "close", event );
1451
- },
1452
-
1453
- widget: function() {
1454
- return this.button;
1455
- },
1456
-
1457
- menuWidget: function() {
1458
- return this.menu;
1459
- },
1460
-
1461
- _renderMenu: function( ul, items ) {
1462
- var that = this,
1463
- currentOptgroup = "";
1464
-
1465
- $.each( items, function( index, item ) {
1466
- if ( item.optgroup !== currentOptgroup ) {
1467
- $( "<li>", {
1468
- "class": "ui-selectmenu-optgroup ui-menu-divider" +
1469
- ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
1470
- " ui-state-disabled" :
1471
- "" ),
1472
- text: item.optgroup
1473
- })
1474
- .appendTo( ul );
1475
-
1476
- currentOptgroup = item.optgroup;
1477
- }
1478
-
1479
- that._renderItemData( ul, item );
1480
- });
1481
- },
1482
-
1483
- _renderItemData: function( ul, item ) {
1484
- return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
1485
- },
1486
-
1487
- _renderItem: function( ul, item ) {
1488
- var li = $( "<li>" );
1489
-
1490
- if ( item.disabled ) {
1491
- li.addClass( "ui-state-disabled" );
1492
- }
1493
- this._setText( li, item.label );
1494
-
1495
- return li.appendTo( ul );
1496
- },
1497
-
1498
- _setText: function( element, value ) {
1499
- if ( value ) {
1500
- element.text( value );
1501
- } else {
1502
- element.html( "&#160;" );
1503
- }
1504
- },
1505
-
1506
- _move: function( direction, event ) {
1507
- var item, next,
1508
- filter = ".ui-menu-item";
1509
-
1510
- if ( this.isOpen ) {
1511
- item = this.menuItems.eq( this.focusIndex );
1512
- } else {
1513
- item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
1514
- filter += ":not(.ui-state-disabled)";
1515
- }
1516
-
1517
- if ( direction === "first" || direction === "last" ) {
1518
- next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
1519
- } else {
1520
- next = item[ direction + "All" ]( filter ).eq( 0 );
1521
- }
1522
-
1523
- if ( next.length ) {
1524
- this.menuInstance.focus( event, next );
1525
- }
1526
- },
1527
-
1528
- _getSelectedItem: function() {
1529
- return this.menuItems.eq( this.element[ 0 ].selectedIndex );
1530
- },
1531
-
1532
- _toggle: function( event ) {
1533
- this[ this.isOpen ? "close" : "open" ]( event );
1534
- },
1535
-
1536
- _setSelection: function() {
1537
- var selection;
1538
-
1539
- if ( !this.range ) {
1540
- return;
1541
- }
1542
-
1543
- if ( window.getSelection ) {
1544
- selection = window.getSelection();
1545
- selection.removeAllRanges();
1546
- selection.addRange( this.range );
1547
-
1548
- // support: IE8
1549
- } else {
1550
- this.range.select();
1551
- }
1552
-
1553
- // support: IE
1554
- // Setting the text selection kills the button focus in IE, but
1555
- // restoring the focus doesn't kill the selection.
1556
- this.button.focus();
1557
- },
1558
-
1559
- _documentClick: {
1560
- mousedown: function( event ) {
1561
- if ( !this.isOpen ) {
1562
- return;
1563
- }
1564
-
1565
- if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
1566
- this.close( event );
1567
- }
1568
- }
1569
- },
1570
-
1571
- _buttonEvents: {
1572
-
1573
- // Prevent text selection from being reset when interacting with the selectmenu (#10144)
1574
- mousedown: function() {
1575
- var selection;
1576
-
1577
- if ( window.getSelection ) {
1578
- selection = window.getSelection();
1579
- if ( selection.rangeCount ) {
1580
- this.range = selection.getRangeAt( 0 );
1581
- }
1582
-
1583
- // support: IE8
1584
- } else {
1585
- this.range = document.selection.createRange();
1586
- }
1587
- },
1588
-
1589
- click: function( event ) {
1590
- this._setSelection();
1591
- this._toggle( event );
1592
- },
1593
-
1594
- keydown: function( event ) {
1595
- var preventDefault = true;
1596
- switch ( event.keyCode ) {
1597
- case $.ui.keyCode.TAB:
1598
- case $.ui.keyCode.ESCAPE:
1599
- this.close( event );
1600
- preventDefault = false;
1601
- break;
1602
- case $.ui.keyCode.ENTER:
1603
- if ( this.isOpen ) {
1604
- this._selectFocusedItem( event );
1605
- }
1606
- break;
1607
- case $.ui.keyCode.UP:
1608
- if ( event.altKey ) {
1609
- this._toggle( event );
1610
- } else {
1611
- this._move( "prev", event );
1612
- }
1613
- break;
1614
- case $.ui.keyCode.DOWN:
1615
- if ( event.altKey ) {
1616
- this._toggle( event );
1617
- } else {
1618
- this._move( "next", event );
1619
- }
1620
- break;
1621
- case $.ui.keyCode.SPACE:
1622
- if ( this.isOpen ) {
1623
- this._selectFocusedItem( event );
1624
- } else {
1625
- this._toggle( event );
1626
- }
1627
- break;
1628
- case $.ui.keyCode.LEFT:
1629
- this._move( "prev", event );
1630
- break;
1631
- case $.ui.keyCode.RIGHT:
1632
- this._move( "next", event );
1633
- break;
1634
- case $.ui.keyCode.HOME:
1635
- case $.ui.keyCode.PAGE_UP:
1636
- this._move( "first", event );
1637
- break;
1638
- case $.ui.keyCode.END:
1639
- case $.ui.keyCode.PAGE_DOWN:
1640
- this._move( "last", event );
1641
- break;
1642
- default:
1643
- this.menu.trigger( event );
1644
- preventDefault = false;
1645
- }
1646
-
1647
- if ( preventDefault ) {
1648
- event.preventDefault();
1649
- }
1650
- }
1651
- },
1652
-
1653
- _selectFocusedItem: function( event ) {
1654
- var item = this.menuItems.eq( this.focusIndex );
1655
- if ( !item.hasClass( "ui-state-disabled" ) ) {
1656
- this._select( item.data( "ui-selectmenu-item" ), event );
1657
- }
1658
- },
1659
-
1660
- _select: function( item, event ) {
1661
- var oldIndex = this.element[ 0 ].selectedIndex;
1662
-
1663
- // Change native select element
1664
- this.element[ 0 ].selectedIndex = item.index;
1665
- this._setText( this.buttonText, item.label );
1666
- this._setAria( item );
1667
- this._trigger( "select", event, { item: item } );
1668
-
1669
- if ( item.index !== oldIndex ) {
1670
- this._trigger( "change", event, { item: item } );
1671
- }
1672
-
1673
- this.close( event );
1674
- },
1675
-
1676
- _setAria: function( item ) {
1677
- var id = this.menuItems.eq( item.index ).attr( "id" );
1678
-
1679
- this.button.attr({
1680
- "aria-labelledby": id,
1681
- "aria-activedescendant": id
1682
- });
1683
- this.menu.attr( "aria-activedescendant", id );
1684
- },
1685
-
1686
- _setOption: function( key, value ) {
1687
- if ( key === "icons" ) {
1688
- this.button.find( "span.ui-icon" )
1689
- .removeClass( this.options.icons.button )
1690
- .addClass( value.button );
1691
- }
1692
-
1693
- this._super( key, value );
1694
-
1695
- if ( key === "appendTo" ) {
1696
- this.menuWrap.appendTo( this._appendTo() );
1697
- }
1698
-
1699
- if ( key === "disabled" ) {
1700
- this.menuInstance.option( "disabled", value );
1701
- this.button
1702
- .toggleClass( "ui-state-disabled", value )
1703
- .attr( "aria-disabled", value );
1704
-
1705
- this.element.prop( "disabled", value );
1706
- if ( value ) {
1707
- this.button.attr( "tabindex", -1 );
1708
- this.close();
1709
- } else {
1710
- this.button.attr( "tabindex", 0 );
1711
- }
1712
- }
1713
-
1714
- if ( key === "width" ) {
1715
- this._resizeButton();
1716
- }
1717
- },
1718
-
1719
- _appendTo: function() {
1720
- var element = this.options.appendTo;
1721
-
1722
- if ( element ) {
1723
- element = element.jquery || element.nodeType ?
1724
- $( element ) :
1725
- this.document.find( element ).eq( 0 );
1726
- }
1727
-
1728
- if ( !element || !element[ 0 ] ) {
1729
- element = this.element.closest( ".ui-front" );
1730
- }
1731
-
1732
- if ( !element.length ) {
1733
- element = this.document[ 0 ].body;
1734
- }
1735
-
1736
- return element;
1737
- },
1738
-
1739
- _toggleAttr: function() {
1740
- this.button
1741
- .toggleClass( "ui-corner-top", this.isOpen )
1742
- .toggleClass( "ui-corner-all", !this.isOpen )
1743
- .attr( "aria-expanded", this.isOpen );
1744
- this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
1745
- this.menu.attr( "aria-hidden", !this.isOpen );
1746
- },
1747
-
1748
- _resizeButton: function() {
1749
- var width = this.options.width;
1750
-
1751
- if ( !width ) {
1752
- width = this.element.show().outerWidth();
1753
- this.element.hide();
1754
- }
1755
-
1756
- this.button.outerWidth( width );
1757
- },
1758
-
1759
- _resizeMenu: function() {
1760
- this.menu.outerWidth( Math.max(
1761
- this.button.outerWidth(),
1762
-
1763
- // support: IE10
1764
- // IE10 wraps long text (possibly a rounding bug)
1765
- // so we add 1px to avoid the wrapping
1766
- this.menu.width( "" ).outerWidth() + 1
1767
- ) );
1768
- },
1769
-
1770
- _getCreateOptions: function() {
1771
- return { disabled: this.element.prop( "disabled" ) };
1772
- },
1773
-
1774
- _parseOptions: function( options ) {
1775
- var data = [];
1776
- options.each(function( index, item ) {
1777
- var option = $( item ),
1778
- optgroup = option.parent( "optgroup" );
1779
- data.push({
1780
- element: option,
1781
- index: index,
1782
- value: option.attr( "value" ),
1783
- label: option.text(),
1784
- optgroup: optgroup.attr( "label" ) || "",
1785
- disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
1786
- });
1787
- });
1788
- this.items = data;
1789
- },
1790
-
1791
- _destroy: function() {
1792
- this.menuWrap.remove();
1793
- this.button.remove();
1794
- this.element.show();
1795
- this.element.removeUniqueId();
1796
- this.label.attr( "for", this.ids.element );
1797
- }
1798
  });
1799
 
1800
 
4
  * Copyright 2014 jQuery Foundation and other contributors; Licensed MIT */
5
 
6
  (function( factory ) {
7
+ if ( typeof define === "function" && define.amd ) {
8
 
9
+ // AMD. Register as an anonymous module.
10
+ define([ "jquery" ], factory );
11
+ } else {
12
 
13
+ // Browser globals
14
+ factory( jQuery );
15
+ }
16
  }(function( $ ) {
17
 
18
 
29
 
30
 
31
  var widget_uuid = 0,
32
+ widget_slice = Array.prototype.slice;
33
 
34
  $.cleanData = (function( orig ) {
35
+ return function( elems ) {
36
+ var events, elem, i;
37
+ for ( i = 0; (elem = elems[i]) != null; i++ ) {
38
+ try {
39
+
40
+ // Only trigger remove when necessary to save time
41
+ events = $._data( elem, "events" );
42
+ if ( events && events.remove ) {
43
+ $( elem ).triggerHandler( "remove" );
44
+ }
45
+
46
+ // http://bugs.jquery.com/ticket/8235
47
+ } catch ( e ) {}
48
+ }
49
+ orig( elems );
50
+ };
51
  })( $.cleanData );
52
 
53
  $.widget = function( name, base, prototype ) {
54
+ var fullName, existingConstructor, constructor, basePrototype,
55
+ // proxiedPrototype allows the provided prototype to remain unmodified
56
+ // so that it can be used as a mixin for multiple widgets (#8876)
57
+ proxiedPrototype = {},
58
+ namespace = name.split( "." )[ 0 ];
59
+
60
+ name = name.split( "." )[ 1 ];
61
+ fullName = namespace + "-" + name;
62
+
63
+ if ( !prototype ) {
64
+ prototype = base;
65
+ base = $.Widget;
66
+ }
67
+
68
+ // create selector for plugin
69
+ $.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
70
+ return !!$.data( elem, fullName );
71
+ };
72
+
73
+ $[ namespace ] = $[ namespace ] || {};
74
+ existingConstructor = $[ namespace ][ name ];
75
+ constructor = $[ namespace ][ name ] = function( options, element ) {
76
+ // allow instantiation without "new" keyword
77
+ if ( !this._createWidget ) {
78
+ return new constructor( options, element );
79
+ }
80
+
81
+ // allow instantiation without initializing for simple inheritance
82
+ // must use "new" keyword (the code above always passes args)
83
+ if ( arguments.length ) {
84
+ this._createWidget( options, element );
85
+ }
86
+ };
87
+ // extend with the existing constructor to carry over any static properties
88
+ $.extend( constructor, existingConstructor, {
89
+ version: prototype.version,
90
+ // copy the object used to create the prototype in case we need to
91
+ // redefine the widget later
92
+ _proto: $.extend( {}, prototype ),
93
+ // track widgets that inherit from this widget in case this widget is
94
+ // redefined after a widget inherits from it
95
+ _childConstructors: []
96
+ });
97
+
98
+ basePrototype = new base();
99
+ // we need to make the options hash a property directly on the new instance
100
+ // otherwise we'll modify the options hash on the prototype that we're
101
+ // inheriting from
102
+ basePrototype.options = $.widget.extend( {}, basePrototype.options );
103
+ $.each( prototype, function( prop, value ) {
104
+ if ( !$.isFunction( value ) ) {
105
+ proxiedPrototype[ prop ] = value;
106
+ return;
107
+ }
108
+ proxiedPrototype[ prop ] = (function() {
109
+ var _super = function() {
110
+ return base.prototype[ prop ].apply( this, arguments );
111
+ },
112
+ _superApply = function( args ) {
113
+ return base.prototype[ prop ].apply( this, args );
114
+ };
115
+ return function() {
116
+ var __super = this._super,
117
+ __superApply = this._superApply,
118
+ returnValue;
119
+
120
+ this._super = _super;
121
+ this._superApply = _superApply;
122
+
123
+ returnValue = value.apply( this, arguments );
124
+
125
+ this._super = __super;
126
+ this._superApply = __superApply;
127
+
128
+ return returnValue;
129
+ };
130
+ })();
131
+ });
132
+ constructor.prototype = $.widget.extend( basePrototype, {
133
+ // TODO: remove support for widgetEventPrefix
134
+ // always use the name + a colon as the prefix, e.g., draggable:start
135
+ // don't prefix for widgets that aren't DOM-based
136
+ widgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name
137
+ }, proxiedPrototype, {
138
+ constructor: constructor,
139
+ namespace: namespace,
140
+ widgetName: name,
141
+ widgetFullName: fullName
142
+ });
143
+
144
+ // If this widget is being redefined then we need to find all widgets that
145
+ // are inheriting from it and redefine all of them so that they inherit from
146
+ // the new version of this widget. We're essentially trying to replace one
147
+ // level in the prototype chain.
148
+ if ( existingConstructor ) {
149
+ $.each( existingConstructor._childConstructors, function( i, child ) {
150
+ var childPrototype = child.prototype;
151
+
152
+ // redefine the child widget using the same prototype that was
153
+ // originally used, but inherit from the new version of the base
154
+ $.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
155
+ });
156
+ // remove the list of existing child constructors from the old constructor
157
+ // so the old child constructors can be garbage collected
158
+ delete existingConstructor._childConstructors;
159
+ } else {
160
+ base._childConstructors.push( constructor );
161
+ }
162
+
163
+ $.widget.bridge( name, constructor );
164
+
165
+ return constructor;
166
  };
167
 
168
  $.widget.extend = function( target ) {
169
+ var input = widget_slice.call( arguments, 1 ),
170
+ inputIndex = 0,
171
+ inputLength = input.length,
172
+ key,
173
+ value;
174
+ for ( ; inputIndex < inputLength; inputIndex++ ) {
175
+ for ( key in input[ inputIndex ] ) {
176
+ value = input[ inputIndex ][ key ];
177
+ if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
178
+ // Clone objects
179
+ if ( $.isPlainObject( value ) ) {
180
+ target[ key ] = $.isPlainObject( target[ key ] ) ?
181
+ $.widget.extend( {}, target[ key ], value ) :
182
+ // Don't extend strings, arrays, etc. with objects
183
+ $.widget.extend( {}, value );
184
+ // Copy everything else by reference
185
+ } else {
186
+ target[ key ] = value;
187
+ }
188
+ }
189
+ }
190
+ }
191
+ return target;
192
  };
193
 
194
  $.widget.bridge = function( name, object ) {
195
+ var fullName = object.prototype.widgetFullName || name;
196
+ $.fn[ name ] = function( options ) {
197
+ var isMethodCall = typeof options === "string",
198
+ args = widget_slice.call( arguments, 1 ),
199
+ returnValue = this;
200
+
201
+ // allow multiple hashes to be passed on init
202
+ options = !isMethodCall && args.length ?
203
+ $.widget.extend.apply( null, [ options ].concat(args) ) :
204
+ options;
205
+
206
+ if ( isMethodCall ) {
207
+ this.each(function() {
208
+ var methodValue,
209
+ instance = $.data( this, fullName );
210
+ if ( options === "instance" ) {
211
+ returnValue = instance;
212
+ return false;
213
+ }
214
+ if ( !instance ) {
215
+ return $.error( "cannot call methods on " + name + " prior to initialization; " +
216
+ "attempted to call method '" + options + "'" );
217
+ }
218
+ if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
219
+ return $.error( "no such method '" + options + "' for " + name + " widget instance" );
220
+ }
221
+ methodValue = instance[ options ].apply( instance, args );
222
+ if ( methodValue !== instance && methodValue !== undefined ) {
223
+ returnValue = methodValue && methodValue.jquery ?
224
+ returnValue.pushStack( methodValue.get() ) :
225
+ methodValue;
226
+ return false;
227
+ }
228
+ });
229
+ } else {
230
+ this.each(function() {
231
+ var instance = $.data( this, fullName );
232
+ if ( instance ) {
233
+ instance.option( options || {} );
234
+ if ( instance._init ) {
235
+ instance._init();
236
+ }
237
+ } else {
238
+ $.data( this, fullName, new object( options, this ) );
239
+ }
240
+ });
241
+ }
242
+
243
+ return returnValue;
244
+ };
245
  };
246
 
247
  $.Widget = function( /* options, element */ ) {};
250
  $.Widget._childConstructors = [];
251
 
252
  $.Widget.prototype = {
253
+ widgetName: "widget",
254
+ widgetEventPrefix: "",
255
+ defaultElement: "<div>",
256
+ options: {
257
+ disabled: false,
258
+
259
+ // callbacks
260
+ create: null
261
+ },
262
+ _createWidget: function( options, element ) {
263
+ element = $( element || this.defaultElement || this )[ 0 ];
264
+ this.element = $( element );
265
+ this.uuid = widget_uuid++;
266
+ this.eventNamespace = "." + this.widgetName + this.uuid;
267
+
268
+ this.bindings = $();
269
+ this.hoverable = $();
270
+ this.focusable = $();
271
+
272
+ if ( element !== this ) {
273
+ $.data( element, this.widgetFullName, this );
274
+ this._on( true, this.element, {
275
+ remove: function( event ) {
276
+ if ( event.target === element ) {
277
+ this.destroy();
278
+ }
279
+ }
280
+ });
281
+ this.document = $( element.style ?
282
+ // element within the document
283
+ element.ownerDocument :
284
+ // element is window or document
285
+ element.document || element );
286
+ this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
287
+ }
288
+
289
+ this.options = $.widget.extend( {},
290
+ this.options,
291
+ this._getCreateOptions(),
292
+ options );
293
+
294
+ this._create();
295
+ this._trigger( "create", null, this._getCreateEventData() );
296
+ this._init();
297
+ },
298
+ _getCreateOptions: $.noop,
299
+ _getCreateEventData: $.noop,
300
+ _create: $.noop,
301
+ _init: $.noop,
302
+
303
+ destroy: function() {
304
+ this._destroy();
305
+ // we can probably remove the unbind calls in 2.0
306
+ // all event bindings should go through this._on()
307
+ this.element
308
+ .unbind( this.eventNamespace )
309
+ .removeData( this.widgetFullName )
310
+ // support: jquery <1.6.4
311
+ // http://bugs.jquery.com/ticket/9413
312
+ .removeData( $.camelCase( this.widgetFullName ) );
313
+ this.widget()
314
+ .unbind( this.eventNamespace )
315
+ .removeAttr( "aria-disabled" )
316
+ .removeClass(
317
+ this.widgetFullName + "-disabled " +
318
+ "ui-state-disabled" );
319
+
320
+ // clean up events and states
321
+ this.bindings.unbind( this.eventNamespace );
322
+ this.hoverable.removeClass( "ui-state-hover" );
323
+ this.focusable.removeClass( "ui-state-focus" );
324
+ },
325
+ _destroy: $.noop,
326
+
327
+ widget: function() {
328
+ return this.element;
329
+ },
330
+
331
+ option: function( key, value ) {
332
+ var options = key,
333
+ parts,
334
+ curOption,
335
+ i;
336
+
337
+ if ( arguments.length === 0 ) {
338
+ // don't return a reference to the internal hash
339
+ return $.widget.extend( {}, this.options );
340
+ }
341
+
342
+ if ( typeof key === "string" ) {
343
+ // handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
344
+ options = {};
345
+ parts = key.split( "." );
346
+ key = parts.shift();
347
+ if ( parts.length ) {
348
+ curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
349
+ for ( i = 0; i < parts.length - 1; i++ ) {
350
+ curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
351
+ curOption = curOption[ parts[ i ] ];
352
+ }
353
+ key = parts.pop();
354
+ if ( arguments.length === 1 ) {
355
+ return curOption[ key ] === undefined ? null : curOption[ key ];
356
+ }
357
+ curOption[ key ] = value;
358
+ } else {
359
+ if ( arguments.length === 1 ) {
360
+ return this.options[ key ] === undefined ? null : this.options[ key ];
361
+ }
362
+ options[ key ] = value;
363
+ }
364
+ }
365
+
366
+ this._setOptions( options );
367
+
368
+ return this;
369
+ },
370
+ _setOptions: function( options ) {
371
+ var key;
372
+
373
+ for ( key in options ) {
374
+ this._setOption( key, options[ key ] );
375
+ }
376
+
377
+ return this;
378
+ },
379
+ _setOption: function( key, value ) {
380
+ this.options[ key ] = value;
381
+
382
+ if ( key === "disabled" ) {
383
+ this.widget()
384
+ .toggleClass( this.widgetFullName + "-disabled", !!value );
385
+
386
+ // If the widget is becoming disabled, then nothing is interactive
387
+ if ( value ) {
388
+ this.hoverable.removeClass( "ui-state-hover" );
389
+ this.focusable.removeClass( "ui-state-focus" );
390
+ }
391
+ }
392
+
393
+ return this;
394
+ },
395
+
396
+ enable: function() {
397
+ return this._setOptions({ disabled: false });
398
+ },
399
+ disable: function() {
400
+ return this._setOptions({ disabled: true });
401
+ },
402
+
403
+ _on: function( suppressDisabledCheck, element, handlers ) {
404
+ var delegateElement,
405
+ instance = this;
406
+
407
+ // no suppressDisabledCheck flag, shuffle arguments
408
+ if ( typeof suppressDisabledCheck !== "boolean" ) {
409
+ handlers = element;
410
+ element = suppressDisabledCheck;
411
+ suppressDisabledCheck = false;
412
+ }
413
+
414
+ // no element argument, shuffle and use this.element
415
+ if ( !handlers ) {
416
+ handlers = element;
417
+ element = this.element;
418
+ delegateElement = this.widget();
419
+ } else {
420
+ element = delegateElement = $( element );
421
+ this.bindings = this.bindings.add( element );
422
+ }
423
+
424
+ $.each( handlers, function( event, handler ) {
425
+ function handlerProxy() {
426
+ // allow widgets to customize the disabled handling
427
+ // - disabled as an array instead of boolean
428
+ // - disabled class as method for disabling individual parts
429
+ if ( !suppressDisabledCheck &&
430
+ ( instance.options.disabled === true ||
431
+ $( this ).hasClass( "ui-state-disabled" ) ) ) {
432
+ return;
433
+ }
434
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
435
+ .apply( instance, arguments );
436
+ }
437
+
438
+ // copy the guid so direct unbinding works
439
+ if ( typeof handler !== "string" ) {
440
+ handlerProxy.guid = handler.guid =
441
+ handler.guid || handlerProxy.guid || $.guid++;
442
+ }
443
+
444
+ var match = event.match( /^([\w:-]*)\s*(.*)$/ ),
445
+ eventName = match[1] + instance.eventNamespace,
446
+ selector = match[2];
447
+ if ( selector ) {
448
+ delegateElement.delegate( selector, eventName, handlerProxy );
449
+ } else {
450
+ element.bind( eventName, handlerProxy );
451
+ }
452
+ });
453
+ },
454
+
455
+ _off: function( element, eventName ) {
456
+ eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) +
457
+ this.eventNamespace;
458
+ element.unbind( eventName ).undelegate( eventName );
459
+
460
+ // Clear the stack to avoid memory leaks (#10056)
461
+ this.bindings = $( this.bindings.not( element ).get() );
462
+ this.focusable = $( this.focusable.not( element ).get() );
463
+ this.hoverable = $( this.hoverable.not( element ).get() );
464
+ },
465
+
466
+ _delay: function( handler, delay ) {
467
+ function handlerProxy() {
468
+ return ( typeof handler === "string" ? instance[ handler ] : handler )
469
+ .apply( instance, arguments );
470
+ }
471
+ var instance = this;
472
+ return setTimeout( handlerProxy, delay || 0 );
473
+ },
474
+
475
+ _hoverable: function( element ) {
476
+ this.hoverable = this.hoverable.add( element );
477
+ this._on( element, {
478
+ mouseenter: function( event ) {
479
+ $( event.currentTarget ).addClass( "ui-state-hover" );
480
+ },
481
+ mouseleave: function( event ) {
482
+ $( event.currentTarget ).removeClass( "ui-state-hover" );
483
+ }
484
+ });
485
+ },
486
+
487
+ _focusable: function( element ) {
488
+ this.focusable = this.focusable.add( element );
489
+ this._on( element, {
490
+ focusin: function( event ) {
491
+ $( event.currentTarget ).addClass( "ui-state-focus" );
492
+ },
493
+ focusout: function( event ) {
494
+ $( event.currentTarget ).removeClass( "ui-state-focus" );
495
+ }
496
+ });
497
+ },
498
+
499
+ _trigger: function( type, event, data ) {
500
+ var prop, orig,
501
+ callback = this.options[ type ];
502
+
503
+ data = data || {};
504
+ event = $.Event( event );
505
+ event.type = ( type === this.widgetEventPrefix ?
506
+ type :
507
+ this.widgetEventPrefix + type ).toLowerCase();
508
+ // the original event may come from any element
509
+ // so we need to reset the target on the new event
510
+ event.target = this.element[ 0 ];
511
+
512
+ // copy original event properties over to the new event
513
+ orig = event.originalEvent;
514
+ if ( orig ) {
515
+ for ( prop in orig ) {
516
+ if ( !( prop in event ) ) {
517
+ event[ prop ] = orig[ prop ];
518
+ }
519
+ }
520
+ }
521
+
522
+ this.element.trigger( event, data );
523
+ return !( $.isFunction( callback ) &&
524
+ callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
525
+ event.isDefaultPrevented() );
526
+ }
527
  };
528
 
529
  $.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
530
+ $.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
531
+ if ( typeof options === "string" ) {
532
+ options = { effect: options };
533
+ }
534
+ var hasOptions,
535
+ effectName = !options ?
536
+ method :
537
+ options === true || typeof options === "number" ?
538
+ defaultEffect :
539
+ options.effect || defaultEffect;
540
+ options = options || {};
541
+ if ( typeof options === "number" ) {
542
+ options = { duration: options };
543
+ }
544
+ hasOptions = !$.isEmptyObject( options );
545
+ options.complete = callback;
546
+ if ( options.delay ) {
547
+ element.delay( options.delay );
548
+ }
549
+ if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
550
+ element[ method ]( options );
551
+ } else if ( effectName !== method && element[ effectName ] ) {
552
+ element[ effectName ]( options.duration, options.easing, callback );
553
+ } else {
554
+ element.queue(function( next ) {
555
+ $( this )[ method ]();
556
+ if ( callback ) {
557
+ callback.call( element[ 0 ] );
558
+ }
559
+ next();
560
+ });
561
+ }
562
+ };
563
  });
564
 
565
  var widget = $.widget;
580
 
581
 
582
  var menu = $.widget( "ui.menu", {
583
+ version: "1.11.2",
584
+ defaultElement: "<ul>",
585
+ delay: 300,
586
+ options: {
587
+ icons: {
588
+ submenu: "ui-icon-carat-1-e"
589
+ },
590
+ items: "> *",
591
+ menus: "ul",
592
+ position: {
593
+ my: "left-1 top",
594
+ at: "right top"
595
+ },
596
+ role: "menu",
597
+
598
+ // callbacks
599
+ blur: null,
600
+ focus: null,
601
+ select: null
602
+ },
603
+
604
+ _create: function() {
605
+ this.activeMenu = this.element;
606
+
607
+ // Flag used to prevent firing of the click handler
608
+ // as the event bubbles up through nested menus
609
+ this.mouseHandled = false;
610
+ this.element
611
+ .uniqueId()
612
+ .addClass( "ui-menu ui-widget ui-widget-content" )
613
+ .toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length )
614
+ .attr({
615
+ role: this.options.role,
616
+ tabIndex: 0
617
+ });
618
+
619
+ if ( this.options.disabled ) {
620
+ this.element
621
+ .addClass( "ui-state-disabled" )
622
+ .attr( "aria-disabled", "true" );
623
+ }
624
+
625
+ this._on({
626
+ // Prevent focus from sticking to links inside menu after clicking
627
+ // them (focus should always stay on UL during navigation).
628
+ "mousedown .ui-menu-item": function( event ) {
629
+ event.preventDefault();
630
+ },
631
+ "click .ui-menu-item": function( event ) {
632
+ var target = $( event.target );
633
+ if ( !this.mouseHandled && target.not( ".ui-state-disabled" ).length ) {
634
+ this.select( event );
635
+
636
+ // Only set the mouseHandled flag if the event will bubble, see #9469.
637
+ if ( !event.isPropagationStopped() ) {
638
+ this.mouseHandled = true;
639
+ }
640
+
641
+ // Open submenu on click
642
+ if ( target.has( ".ui-menu" ).length ) {
643
+ this.expand( event );
644
+ } else if ( !this.element.is( ":focus" ) && $( this.document[ 0 ].activeElement ).closest( ".ui-menu" ).length ) {
645
+
646
+ // Redirect focus to the menu
647
+ this.element.trigger( "focus", [ true ] );
648
+
649
+ // If the active item is on the top level, let it stay active.
650
+ // Otherwise, blur the active item since it is no longer visible.
651
+ if ( this.active && this.active.parents( ".ui-menu" ).length === 1 ) {
652
+ clearTimeout( this.timer );
653
+ }
654
+ }
655
+ }
656
+ },
657
+ "mouseenter .ui-menu-item": function( event ) {
658
+ // Ignore mouse events while typeahead is active, see #10458.
659
+ // Prevents focusing the wrong item when typeahead causes a scroll while the mouse
660
+ // is over an item in the menu
661
+ if ( this.previousFilter ) {
662
+ return;
663
+ }
664
+ var target = $( event.currentTarget );
665
+ // Remove ui-state-active class from siblings of the newly focused menu item
666
+ // to avoid a jump caused by adjacent elements both having a class with a border
667
+ target.siblings( ".ui-state-active" ).removeClass( "ui-state-active" );
668
+ this.focus( event, target );
669
+ },
670
+ mouseleave: "collapseAll",
671
+ "mouseleave .ui-menu": "collapseAll",
672
+ focus: function( event, keepActiveItem ) {
673
+ // If there's already an active item, keep it active
674
+ // If not, activate the first item
675
+ var item = this.active || this.element.find( this.options.items ).eq( 0 );
676
+
677
+ if ( !keepActiveItem ) {
678
+ this.focus( event, item );
679
+ }
680
+ },
681
+ blur: function( event ) {
682
+ this._delay(function() {
683
+ if ( !$.contains( this.element[0], this.document[0].activeElement ) ) {
684
+ this.collapseAll( event );
685
+ }
686
+ });
687
+ },
688
+ keydown: "_keydown"
689
+ });
690
+
691
+ this.refresh();
692
+
693
+ // Clicks outside of a menu collapse any open menus
694
+ this._on( this.document, {
695
+ click: function( event ) {
696
+ if ( this._closeOnDocumentClick( event ) ) {
697
+ this.collapseAll( event );
698
+ }
699
+
700
+ // Reset the mouseHandled flag
701
+ this.mouseHandled = false;
702
+ }
703
+ });
704
+ },
705
+
706
+ _destroy: function() {
707
+ // Destroy (sub)menus
708
+ this.element
709
+ .removeAttr( "aria-activedescendant" )
710
+ .find( ".ui-menu" ).addBack()
711
+ .removeClass( "ui-menu ui-widget ui-widget-content ui-menu-icons ui-front" )
712
+ .removeAttr( "role" )
713
+ .removeAttr( "tabIndex" )
714
+ .removeAttr( "aria-labelledby" )
715
+ .removeAttr( "aria-expanded" )
716
+ .removeAttr( "aria-hidden" )
717
+ .removeAttr( "aria-disabled" )
718
+ .removeUniqueId()
719
+ .show();
720
+
721
+ // Destroy menu items
722
+ this.element.find( ".ui-menu-item" )
723
+ .removeClass( "ui-menu-item" )
724
+ .removeAttr( "role" )
725
+ .removeAttr( "aria-disabled" )
726
+ .removeUniqueId()
727
+ .removeClass( "ui-state-hover" )
728
+ .removeAttr( "tabIndex" )
729
+ .removeAttr( "role" )
730
+ .removeAttr( "aria-haspopup" )
731
+ .children().each( function() {
732
+ var elem = $( this );
733
+ if ( elem.data( "ui-menu-submenu-carat" ) ) {
734
+ elem.remove();
735
+ }
736
+ });
737
+
738
+ // Destroy menu dividers
739
+ this.element.find( ".ui-menu-divider" ).removeClass( "ui-menu-divider ui-widget-content" );
740
+ },
741
+
742
+ _keydown: function( event ) {
743
+ var match, prev, character, skip,
744
+ preventDefault = true;
745
+
746
+ switch ( event.keyCode ) {
747
+ case $.ui.keyCode.PAGE_UP:
748
+ this.previousPage( event );
749
+ break;
750
+ case $.ui.keyCode.PAGE_DOWN:
751
+ this.nextPage( event );
752
+ break;
753
+ case $.ui.keyCode.HOME:
754
+ this._move( "first", "first", event );
755
+ break;
756
+ case $.ui.keyCode.END:
757
+ this._move( "last", "last", event );
758
+ break;
759
+ case $.ui.keyCode.UP:
760
+ this.previous( event );
761
+ break;
762
+ case $.ui.keyCode.DOWN:
763
+ this.next( event );
764
+ break;
765
+ case $.ui.keyCode.LEFT:
766
+ this.collapse( event );
767
+ break;
768
+ case $.ui.keyCode.RIGHT:
769
+ if ( this.active && !this.active.is( ".ui-state-disabled" ) ) {
770
+ this.expand( event );
771
+ }
772
+ break;
773
+ case $.ui.keyCode.ENTER:
774
+ case $.ui.keyCode.SPACE:
775
+ this._activate( event );
776
+ break;
777
+ case $.ui.keyCode.ESCAPE:
778
+ this.collapse( event );
779
+ break;
780
+ default:
781
+ preventDefault = false;
782
+ prev = this.previousFilter || "";
783
+ character = String.fromCharCode( event.keyCode );
784
+ skip = false;
785
+
786
+ clearTimeout( this.filterTimer );
787
+
788
+ if ( character === prev ) {
789
+ skip = true;
790
+ } else {
791
+ character = prev + character;
792
+ }
793
+
794
+ match = this._filterMenuItems( character );
795
+ match = skip && match.index( this.active.next() ) !== -1 ?
796
+ this.active.nextAll( ".ui-menu-item" ) :
797
+ match;
798
+
799
+ // If no matches on the current filter, reset to the last character pressed
800
+ // to move down the menu to the first item that starts with that character
801
+ if ( !match.length ) {
802
+ character = String.fromCharCode( event.keyCode );
803
+ match = this._filterMenuItems( character );
804
+ }
805
+
806
+ if ( match.length ) {
807
+ this.focus( event, match );
808
+ this.previousFilter = character;
809
+ this.filterTimer = this._delay(function() {
810
+ delete this.previousFilter;
811
+ }, 1000 );
812
+ } else {
813
+ delete this.previousFilter;
814
+ }
815
+ }
816
+
817
+ if ( preventDefault ) {
818
+ event.preventDefault();
819
+ }
820
+ },
821
+
822
+ _activate: function( event ) {
823
+ if ( !this.active.is( ".ui-state-disabled" ) ) {
824
+ if ( this.active.is( "[aria-haspopup='true']" ) ) {
825
+ this.expand( event );
826
+ } else {
827
+ this.select( event );
828
+ }
829
+ }
830
+ },
831
+
832
+ refresh: function() {
833
+ var menus, items,
834
+ that = this,
835
+ icon = this.options.icons.submenu,
836
+ submenus = this.element.find( this.options.menus );
837
+
838
+ this.element.toggleClass( "ui-menu-icons", !!this.element.find( ".ui-icon" ).length );
839
+
840
+ // Initialize nested menus
841
+ submenus.filter( ":not(.ui-menu)" )
842
+ .addClass( "ui-menu ui-widget ui-widget-content ui-front" )
843
+ .hide()
844
+ .attr({
845
+ role: this.options.role,
846
+ "aria-hidden": "true",
847
+ "aria-expanded": "false"
848
+ })
849
+ .each(function() {
850
+ var menu = $( this ),
851
+ item = menu.parent(),
852
+ submenuCarat = $( "<span>" )
853
+ .addClass( "ui-menu-icon ui-icon " + icon )
854
+ .data( "ui-menu-submenu-carat", true );
855
+
856
+ item
857
+ .attr( "aria-haspopup", "true" )
858
+ .prepend( submenuCarat );
859
+ menu.attr( "aria-labelledby", item.attr( "id" ) );
860
+ });
861
+
862
+ menus = submenus.add( this.element );
863
+ items = menus.find( this.options.items );
864
+
865
+ // Initialize menu-items containing spaces and/or dashes only as dividers
866
+ items.not( ".ui-menu-item" ).each(function() {
867
+ var item = $( this );
868
+ if ( that._isDivider( item ) ) {
869
+ item.addClass( "ui-widget-content ui-menu-divider" );
870
+ }
871
+ });
872
+
873
+ // Don't refresh list items that are already adapted
874
+ items.not( ".ui-menu-item, .ui-menu-divider" )
875
+ .addClass( "ui-menu-item" )
876
+ .uniqueId()
877
+ .attr({
878
+ tabIndex: -1,
879
+ role: this._itemRole()
880
+ });
881
+
882
+ // Add aria-disabled attribute to any disabled menu item
883
+ items.filter( ".ui-state-disabled" ).attr( "aria-disabled", "true" );
884
+
885
+ // If the active item has been removed, blur the menu
886
+ if ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {
887
+ this.blur();
888
+ }
889
+ },
890
+
891
+ _itemRole: function() {
892
+ return {
893
+ menu: "menuitem",
894
+ listbox: "option"
895
+ }[ this.options.role ];
896
+ },
897
+
898
+ _setOption: function( key, value ) {
899
+ if ( key === "icons" ) {
900
+ this.element.find( ".ui-menu-icon" )
901
+ .removeClass( this.options.icons.submenu )
902
+ .addClass( value.submenu );
903
+ }
904
+ if ( key === "disabled" ) {
905
+ this.element
906
+ .toggleClass( "ui-state-disabled", !!value )
907
+ .attr( "aria-disabled", value );
908
+ }
909
+ this._super( key, value );
910
+ },
911
+
912
+ focus: function( event, item ) {
913
+ var nested, focused;
914
+ this.blur( event, event && event.type === "focus" );
915
+
916
+ this._scrollIntoView( item );
917
+
918
+ this.active = item.first();
919
+ focused = this.active.addClass( "ui-state-focus" ).removeClass( "ui-state-active" );
920
+ // Only update aria-activedescendant if there's a role
921
+ // otherwise we assume focus is managed elsewhere
922
+ if ( this.options.role ) {
923
+ this.element.attr( "aria-activedescendant", focused.attr( "id" ) );
924
+ }
925
+
926
+ // Highlight active parent menu item, if any
927
+ this.active
928
+ .parent()
929
+ .closest( ".ui-menu-item" )
930
+ .addClass( "ui-state-active" );
931
+
932
+ if ( event && event.type === "keydown" ) {
933
+ this._close();
934
+ } else {
935
+ this.timer = this._delay(function() {
936
+ this._close();
937
+ }, this.delay );
938
+ }
939
+
940
+ nested = item.children( ".ui-menu" );
941
+ if ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {
942
+ this._startOpening(nested);
943
+ }
944
+ this.activeMenu = item.parent();
945
+
946
+ this._trigger( "focus", event, { item: item } );
947
+ },
948
+
949
+ _scrollIntoView: function( item ) {
950
+ var borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;
951
+ if ( this._hasScroll() ) {
952
+ borderTop = parseFloat( $.css( this.activeMenu[0], "borderTopWidth" ) ) || 0;
953
+ paddingTop = parseFloat( $.css( this.activeMenu[0], "paddingTop" ) ) || 0;
954
+ offset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;
955
+ scroll = this.activeMenu.scrollTop();
956
+ elementHeight = this.activeMenu.height();
957
+ itemHeight = item.outerHeight();
958
+
959
+ if ( offset < 0 ) {
960
+ this.activeMenu.scrollTop( scroll + offset );
961
+ } else if ( offset + itemHeight > elementHeight ) {
962
+ this.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );
963
+ }
964
+ }
965
+ },
966
+
967
+ blur: function( event, fromFocus ) {
968
+ if ( !fromFocus ) {
969
+ clearTimeout( this.timer );
970
+ }
971
+
972
+ if ( !this.active ) {
973
+ return;
974
+ }
975
+
976
+ this.active.removeClass( "ui-state-focus" );
977
+ this.active = null;
978
+
979
+ this._trigger( "blur", event, { item: this.active } );
980
+ },
981
+
982
+ _startOpening: function( submenu ) {
983
+ clearTimeout( this.timer );
984
+
985
+ // Don't open if already open fixes a Firefox bug that caused a .5 pixel
986
+ // shift in the submenu position when mousing over the carat icon
987
+ if ( submenu.attr( "aria-hidden" ) !== "true" ) {
988
+ return;
989
+ }
990
+
991
+ this.timer = this._delay(function() {
992
+ this._close();
993
+ this._open( submenu );
994
+ }, this.delay );
995
+ },
996
+
997
+ _open: function( submenu ) {
998
+ var position = $.extend({
999
+ of: this.active
1000
+ }, this.options.position );
1001
+
1002
+ clearTimeout( this.timer );
1003
+ this.element.find( ".ui-menu" ).not( submenu.parents( ".ui-menu" ) )
1004
+ .hide()
1005
+ .attr( "aria-hidden", "true" );
1006
+
1007
+ submenu
1008
+ .show()
1009
+ .removeAttr( "aria-hidden" )
1010
+ .attr( "aria-expanded", "true" )
1011
+ .position( position );
1012
+ },
1013
+
1014
+ collapseAll: function( event, all ) {
1015
+ clearTimeout( this.timer );
1016
+ this.timer = this._delay(function() {
1017
+ // If we were passed an event, look for the submenu that contains the event
1018
+ var currentMenu = all ? this.element :
1019
+ $( event && event.target ).closest( this.element.find( ".ui-menu" ) );
1020
+
1021
+ // If we found no valid submenu ancestor, use the main menu to close all sub menus anyway
1022
+ if ( !currentMenu.length ) {
1023
+ currentMenu = this.element;
1024
+ }
1025
+
1026
+ this._close( currentMenu );
1027
+
1028
+ this.blur( event );
1029
+ this.activeMenu = currentMenu;
1030
+ }, this.delay );
1031
+ },
1032
+
1033
+ // With no arguments, closes the currently active menu - if nothing is active
1034
+ // it closes all menus. If passed an argument, it will search for menus BELOW
1035
+ _close: function( startMenu ) {
1036
+ if ( !startMenu ) {
1037
+ startMenu = this.active ? this.active.parent() : this.element;
1038
+ }
1039
+
1040
+ startMenu
1041
+ .find( ".ui-menu" )
1042
+ .hide()
1043
+ .attr( "aria-hidden", "true" )
1044
+ .attr( "aria-expanded", "false" )
1045
+ .end()
1046
+ .find( ".ui-state-active" ).not( ".ui-state-focus" )
1047
+ .removeClass( "ui-state-active" );
1048
+ },
1049
+
1050
+ _closeOnDocumentClick: function( event ) {
1051
+ return !$( event.target ).closest( ".ui-menu" ).length;
1052
+ },
1053
+
1054
+ _isDivider: function( item ) {
1055
+
1056
+ // Match hyphen, em dash, en dash
1057
+ return !/[^\-\u2014\u2013\s]/.test( item.text() );
1058
+ },
1059
+
1060
+ collapse: function( event ) {
1061
+ var newItem = this.active &&
1062
+ this.active.parent().closest( ".ui-menu-item", this.element );
1063
+ if ( newItem && newItem.length ) {
1064
+ this._close();
1065
+ this.focus( event, newItem );
1066
+ }
1067
+ },
1068
+
1069
+ expand: function( event ) {
1070
+ var newItem = this.active &&
1071
+ this.active
1072
+ .children( ".ui-menu " )
1073
+ .find( this.options.items )
1074
+ .first();
1075
+
1076
+ if ( newItem && newItem.length ) {
1077
+ this._open( newItem.parent() );
1078
+
1079
+ // Delay so Firefox will not hide activedescendant change in expanding submenu from AT
1080
+ this._delay(function() {
1081
+ this.focus( event, newItem );
1082
+ });
1083
+ }
1084
+ },
1085
+
1086
+ next: function( event ) {
1087
+ this._move( "next", "first", event );
1088
+ },
1089
+
1090
+ previous: function( event ) {
1091
+ this._move( "prev", "last", event );
1092
+ },
1093
+
1094
+ isFirstItem: function() {
1095
+ return this.active && !this.active.prevAll( ".ui-menu-item" ).length;
1096
+ },
1097
+
1098
+ isLastItem: function() {
1099
+ return this.active && !this.active.nextAll( ".ui-menu-item" ).length;
1100
+ },
1101
+
1102
+ _move: function( direction, filter, event ) {
1103
+ var next;
1104
+ if ( this.active ) {
1105
+ if ( direction === "first" || direction === "last" ) {
1106
+ next = this.active
1107
+ [ direction === "first" ? "prevAll" : "nextAll" ]( ".ui-menu-item" )
1108
+ .eq( -1 );
1109
+ } else {
1110
+ next = this.active
1111
+ [ direction + "All" ]( ".ui-menu-item" )
1112
+ .eq( 0 );
1113
+ }
1114
+ }
1115
+ if ( !next || !next.length || !this.active ) {
1116
+ next = this.activeMenu.find( this.options.items )[ filter ]();
1117
+ }
1118
+
1119
+ this.focus( event, next );
1120
+ },
1121
+
1122
+ nextPage: function( event ) {
1123
+ var item, base, height;
1124
+
1125
+ if ( !this.active ) {
1126
+ this.next( event );
1127
+ return;
1128
+ }
1129
+ if ( this.isLastItem() ) {
1130
+ return;
1131
+ }
1132
+ if ( this._hasScroll() ) {
1133
+ base = this.active.offset().top;
1134
+ height = this.element.height();
1135
+ this.active.nextAll( ".ui-menu-item" ).each(function() {
1136
+ item = $( this );
1137
+ return item.offset().top - base - height < 0;
1138
+ });
1139
+
1140
+ this.focus( event, item );
1141
+ } else {
1142
+ this.focus( event, this.activeMenu.find( this.options.items )
1143
+ [ !this.active ? "first" : "last" ]() );
1144
+ }
1145
+ },
1146
+
1147
+ previousPage: function( event ) {
1148
+ var item, base, height;
1149
+ if ( !this.active ) {
1150
+ this.next( event );
1151
+ return;
1152
+ }
1153
+ if ( this.isFirstItem() ) {
1154
+ return;
1155
+ }
1156
+ if ( this._hasScroll() ) {
1157
+ base = this.active.offset().top;
1158
+ height = this.element.height();
1159
+ this.active.prevAll( ".ui-menu-item" ).each(function() {
1160
+ item = $( this );
1161
+ return item.offset().top - base + height > 0;
1162
+ });
1163
+
1164
+ this.focus( event, item );
1165
+ } else {
1166
+ this.focus( event, this.activeMenu.find( this.options.items ).first() );
1167
+ }
1168
+ },
1169
+
1170
+ _hasScroll: function() {
1171
+ return this.element.outerHeight() < this.element.prop( "scrollHeight" );
1172
+ },
1173
+
1174
+ select: function( event ) {
1175
+ // TODO: It should never be possible to not have an active item at this
1176
+ // point, but the tests don't trigger mouseenter before click.
1177
+ this.active = this.active || $( event.target ).closest( ".ui-menu-item" );
1178
+ var ui = { item: this.active };
1179
+ if ( !this.active.has( ".ui-menu" ).length ) {
1180
+ this.collapseAll( event, true );
1181
+ }
1182
+ this._trigger( "select", event, ui );
1183
+ },
1184
+
1185
+ _filterMenuItems: function(character) {
1186
+ var escapedCharacter = character.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" ),
1187
+ regex = new RegExp( "^" + escapedCharacter, "i" );
1188
+
1189
+ return this.activeMenu
1190
+ .find( this.options.items )
1191
+
1192
+ // Only match on items, not dividers or other content (#10571)
1193
+ .filter( ".ui-menu-item" )
1194
+ .filter(function() {
1195
+ return regex.test( $.trim( $( this ).text() ) );
1196
+ });
1197
+ }
1198
  });
1199
 
1200
 
1211
 
1212
 
1213
  var selectmenu = $.widget( "ui.selectmenu", {
1214
+ version: "1.11.2",
1215
+ defaultElement: "<select>",
1216
+ options: {
1217
+ appendTo: null,
1218
+ disabled: null,
1219
+ icons: {
1220
+ button: "ui-icon-triangle-1-s"
1221
+ },
1222
+ position: {
1223
+ my: "left top",
1224
+ at: "left bottom",
1225
+ collision: "none"
1226
+ },
1227
+ width: null,
1228
+
1229
+ // callbacks
1230
+ change: null,
1231
+ close: null,
1232
+ focus: null,
1233
+ open: null,
1234
+ select: null
1235
+ },
1236
+
1237
+ _create: function() {
1238
+ var selectmenuId = this.element.uniqueId().attr( "id" );
1239
+ this.ids = {
1240
+ element: selectmenuId,
1241
+ button: selectmenuId + "-button",
1242
+ menu: selectmenuId + "-menu"
1243
+ };
1244
+
1245
+ this._drawButton();
1246
+ this._drawMenu();
1247
+
1248
+ if ( this.options.disabled ) {
1249
+ this.disable();
1250
+ }
1251
+ },
1252
+
1253
+ _drawButton: function() {
1254
+ var that = this,
1255
+ tabindex = this.element.attr( "tabindex" );
1256
+
1257
+ // Associate existing label with the new button
1258
+ this.label = $( "label[for='" + this.ids.element + "']" ).attr( "for", this.ids.button );
1259
+ this._on( this.label, {
1260
+ click: function( event ) {
1261
+ this.button.focus();
1262
+ event.preventDefault();
1263
+ }
1264
+ });
1265
+
1266
+ // Hide original select element
1267
+ this.element.hide();
1268
+
1269
+ // Create button
1270
+ this.button = $( "<span>", {
1271
+ "class": "ui-selectmenu-button ui-widget ui-state-default ui-corner-all",
1272
+ tabindex: tabindex || this.options.disabled ? -1 : 0,
1273
+ id: this.ids.button,
1274
+ role: "combobox",
1275
+ "aria-expanded": "false",
1276
+ "aria-autocomplete": "list",
1277
+ "aria-owns": this.ids.menu,
1278
+ "aria-haspopup": "true"
1279
+ })
1280
+ .insertAfter( this.element );
1281
+
1282
+ $( "<span>", {
1283
+ "class": "ui-icon " + this.options.icons.button
1284
+ })
1285
+ .prependTo( this.button );
1286
+
1287
+ this.buttonText = $( "<span>", {
1288
+ "class": "ui-selectmenu-text"
1289
+ })
1290
+ .appendTo( this.button );
1291
+
1292
+ this._setText( this.buttonText, this.element.find( "option:selected" ).text() );
1293
+ this._resizeButton();
1294
+
1295
+ this._on( this.button, this._buttonEvents );
1296
+ this.button.one( "focusin", function() {
1297
+
1298
+ // Delay rendering the menu items until the button receives focus.
1299
+ // The menu may have already been rendered via a programmatic open.
1300
+ if ( !that.menuItems ) {
1301
+ that._refreshMenu();
1302
+ }
1303
+ });
1304
+ this._hoverable( this.button );
1305
+ this._focusable( this.button );
1306
+ },
1307
+
1308
+ _drawMenu: function() {
1309
+ var that = this;
1310
+
1311
+ // Create menu
1312
+ this.menu = $( "<ul>", {
1313
+ "aria-hidden": "true",
1314
+ "aria-labelledby": this.ids.button,
1315
+ id: this.ids.menu
1316
+ });
1317
+
1318
+ // Wrap menu
1319
+ this.menuWrap = $( "<div>", {
1320
+ "class": "ui-selectmenu-menu ui-front"
1321
+ })
1322
+ .append( this.menu )
1323
+ .appendTo( this._appendTo() );
1324
+
1325
+ // Initialize menu widget
1326
+ this.menuInstance = this.menu
1327
+ .menu({
1328
+ role: "listbox",
1329
+ select: function( event, ui ) {
1330
+ event.preventDefault();
1331
+
1332
+ // support: IE8
1333
+ // If the item was selected via a click, the text selection
1334
+ // will be destroyed in IE
1335
+ that._setSelection();
1336
+
1337
+ that._select( ui.item.data( "ui-selectmenu-item" ), event );
1338
+ },
1339
+ focus: function( event, ui ) {
1340
+ var item = ui.item.data( "ui-selectmenu-item" );
1341
+
1342
+ // Prevent inital focus from firing and check if its a newly focused item
1343
+ if ( that.focusIndex != null && item.index !== that.focusIndex ) {
1344
+ that._trigger( "focus", event, { item: item } );
1345
+ if ( !that.isOpen ) {
1346
+ that._select( item, event );
1347
+ }
1348
+ }
1349
+ that.focusIndex = item.index;
1350
+
1351
+ that.button.attr( "aria-activedescendant",
1352
+ that.menuItems.eq( item.index ).attr( "id" ) );
1353
+ }
1354
+ })
1355
+ .menu( "instance" );
1356
+
1357
+ // Adjust menu styles to dropdown
1358
+ this.menu
1359
+ .addClass( "ui-corner-bottom" )
1360
+ .removeClass( "ui-corner-all" );
1361
+
1362
+ // Don't close the menu on mouseleave
1363
+ this.menuInstance._off( this.menu, "mouseleave" );
1364
+
1365
+ // Cancel the menu's collapseAll on document click
1366
+ this.menuInstance._closeOnDocumentClick = function() {
1367
+ return false;
1368
+ };
1369
+
1370
+ // Selects often contain empty items, but never contain dividers
1371
+ this.menuInstance._isDivider = function() {
1372
+ return false;
1373
+ };
1374
+ },
1375
+
1376
+ refresh: function() {
1377
+ this._refreshMenu();
1378
+ this._setText( this.buttonText, this._getSelectedItem().text() );
1379
+ if ( !this.options.width ) {
1380
+ this._resizeButton();
1381
+ }
1382
+ },
1383
+
1384
+ _refreshMenu: function() {
1385
+ this.menu.empty();
1386
+
1387
+ var item,
1388
+ options = this.element.find( "option" );
1389
+
1390
+ if ( !options.length ) {
1391
+ return;
1392
+ }
1393
+
1394
+ this._parseOptions( options );
1395
+ this._renderMenu( this.menu, this.items );
1396
+
1397
+ this.menuInstance.refresh();
1398
+ this.menuItems = this.menu.find( "li" ).not( ".ui-selectmenu-optgroup" );
1399
+
1400
+ item = this._getSelectedItem();
1401
+
1402
+ // Update the menu to have the correct item focused
1403
+ this.menuInstance.focus( null, item );
1404
+ this._setAria( item.data( "ui-selectmenu-item" ) );
1405
+
1406
+ // Set disabled state
1407
+ this._setOption( "disabled", this.element.prop( "disabled" ) );
1408
+ },
1409
+
1410
+ open: function( event ) {
1411
+ if ( this.options.disabled ) {
1412
+ return;
1413
+ }
1414
+
1415
+ // If this is the first time the menu is being opened, render the items
1416
+ if ( !this.menuItems ) {
1417
+ this._refreshMenu();
1418
+ } else {
1419
+
1420
+ // Menu clears focus on close, reset focus to selected item
1421
+ this.menu.find( ".ui-state-focus" ).removeClass( "ui-state-focus" );
1422
+ this.menuInstance.focus( null, this._getSelectedItem() );
1423
+ }
1424
+
1425
+ this.isOpen = true;
1426
+ this._toggleAttr();
1427
+ this._resizeMenu();
1428
+ this._position();
1429
+
1430
+ this._on( this.document, this._documentClick );
1431
+
1432
+ this._trigger( "open", event );
1433
+ },
1434
+
1435
+ _position: function() {
1436
+ this.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );
1437
+ },
1438
+
1439
+ close: function( event ) {
1440
+ if ( !this.isOpen ) {
1441
+ return;
1442
+ }
1443
+
1444
+ this.isOpen = false;
1445
+ this._toggleAttr();
1446
+
1447
+ this.range = null;
1448
+ this._off( this.document );
1449
+
1450
+ this._trigger( "close", event );
1451
+ },
1452
+
1453
+ widget: function() {
1454
+ return this.button;
1455
+ },
1456
+
1457
+ menuWidget: function() {
1458
+ return this.menu;
1459
+ },
1460
+
1461
+ _renderMenu: function( ul, items ) {
1462
+ var that = this,
1463
+ currentOptgroup = "";
1464
+
1465
+ $.each( items, function( index, item ) {
1466
+ if ( item.optgroup !== currentOptgroup ) {
1467
+ $( "<li>", {
1468
+ "class": "ui-selectmenu-optgroup ui-menu-divider" +
1469
+ ( item.element.parent( "optgroup" ).prop( "disabled" ) ?
1470
+ " ui-state-disabled" :
1471
+ "" ),
1472
+ text: item.optgroup
1473
+ })
1474
+ .appendTo( ul );
1475
+
1476
+ currentOptgroup = item.optgroup;
1477
+ }
1478
+
1479
+ that._renderItemData( ul, item );
1480
+ });
1481
+ },
1482
+
1483
+ _renderItemData: function( ul, item ) {
1484
+ return this._renderItem( ul, item ).data( "ui-selectmenu-item", item );
1485
+ },
1486
+
1487
+ _renderItem: function( ul, item ) {
1488
+ var li = $( "<li>" );
1489
+
1490
+ if ( item.disabled ) {
1491
+ li.addClass( "ui-state-disabled" );
1492
+ }
1493
+ this._setText( li, item.label );
1494
+
1495
+ return li.appendTo( ul );
1496
+ },
1497
+
1498
+ _setText: function( element, value ) {
1499
+ if ( value ) {
1500
+ element.text( value );
1501
+ } else {
1502
+ element.html( "&#160;" );
1503
+ }
1504
+ },
1505
+
1506
+ _move: function( direction, event ) {
1507
+ var item, next,
1508
+ filter = ".ui-menu-item";
1509
+
1510
+ if ( this.isOpen ) {
1511
+ item = this.menuItems.eq( this.focusIndex );
1512
+ } else {
1513
+ item = this.menuItems.eq( this.element[ 0 ].selectedIndex );
1514
+ filter += ":not(.ui-state-disabled)";
1515
+ }
1516
+
1517
+ if ( direction === "first" || direction === "last" ) {
1518
+ next = item[ direction === "first" ? "prevAll" : "nextAll" ]( filter ).eq( -1 );
1519
+ } else {
1520
+ next = item[ direction + "All" ]( filter ).eq( 0 );
1521
+ }
1522
+
1523
+ if ( next.length ) {
1524
+ this.menuInstance.focus( event, next );
1525
+ }
1526
+ },
1527
+
1528
+ _getSelectedItem: function() {
1529
+ return this.menuItems.eq( this.element[ 0 ].selectedIndex );
1530
+ },
1531
+
1532
+ _toggle: function( event ) {
1533
+ this[ this.isOpen ? "close" : "open" ]( event );
1534
+ },
1535
+
1536
+ _setSelection: function() {
1537
+ var selection;
1538
+
1539
+ if ( !this.range ) {
1540
+ return;
1541
+ }
1542
+
1543
+ if ( window.getSelection ) {
1544
+ selection = window.getSelection();
1545
+ selection.removeAllRanges();
1546
+ selection.addRange( this.range );
1547
+
1548
+ // support: IE8
1549
+ } else {
1550
+ this.range.select();
1551
+ }
1552
+
1553
+ // support: IE
1554
+ // Setting the text selection kills the button focus in IE, but
1555
+ // restoring the focus doesn't kill the selection.
1556
+ this.button.focus();
1557
+ },
1558
+
1559
+ _documentClick: {
1560
+ mousedown: function( event ) {
1561
+ if ( !this.isOpen ) {
1562
+ return;
1563
+ }
1564
+
1565
+ if ( !$( event.target ).closest( ".ui-selectmenu-menu, #" + this.ids.button ).length ) {
1566
+ this.close( event );
1567
+ }
1568
+ }
1569
+ },
1570
+
1571
+ _buttonEvents: {
1572
+
1573
+ // Prevent text selection from being reset when interacting with the selectmenu (#10144)
1574
+ mousedown: function() {
1575
+ var selection;
1576
+
1577
+ if ( window.getSelection ) {
1578
+ selection = window.getSelection();
1579
+ if ( selection.rangeCount ) {
1580
+ this.range = selection.getRangeAt( 0 );
1581
+ }
1582
+
1583
+ // support: IE8
1584
+ } else {
1585
+ this.range = document.selection.createRange();
1586
+ }
1587
+ },
1588
+
1589
+ click: function( event ) {
1590
+ this._setSelection();
1591
+ this._toggle( event );
1592
+ },
1593
+
1594
+ keydown: function( event ) {
1595
+ var preventDefault = true;
1596
+ switch ( event.keyCode ) {
1597
+ case $.ui.keyCode.TAB:
1598
+ case $.ui.keyCode.ESCAPE:
1599
+ this.close( event );
1600
+ preventDefault = false;
1601
+ break;
1602
+ case $.ui.keyCode.ENTER:
1603
+ if ( this.isOpen ) {
1604
+ this._selectFocusedItem( event );
1605
+ }
1606
+ break;
1607
+ case $.ui.keyCode.UP:
1608
+ if ( event.altKey ) {
1609
+ this._toggle( event );
1610
+ } else {
1611
+ this._move( "prev", event );
1612
+ }
1613
+ break;
1614
+ case $.ui.keyCode.DOWN:
1615
+ if ( event.altKey ) {
1616
+ this._toggle( event );
1617
+ } else {
1618
+ this._move( "next", event );
1619
+ }
1620
+ break;
1621
+ case $.ui.keyCode.SPACE:
1622
+ if ( this.isOpen ) {
1623
+ this._selectFocusedItem( event );
1624
+ } else {
1625
+ this._toggle( event );
1626
+ }
1627
+ break;
1628
+ case $.ui.keyCode.LEFT:
1629
+ this._move( "prev", event );
1630
+ break;
1631
+ case $.ui.keyCode.RIGHT:
1632
+ this._move( "next", event );
1633
+ break;
1634
+ case $.ui.keyCode.HOME:
1635
+ case $.ui.keyCode.PAGE_UP:
1636
+ this._move( "first", event );
1637
+ break;
1638
+ case $.ui.keyCode.END:
1639
+ case $.ui.keyCode.PAGE_DOWN:
1640
+ this._move( "last", event );
1641
+ break;
1642
+ default:
1643
+ this.menu.trigger( event );
1644
+ preventDefault = false;
1645
+ }
1646
+
1647
+ if ( preventDefault ) {
1648
+ event.preventDefault();
1649
+ }
1650
+ }
1651
+ },
1652
+
1653
+ _selectFocusedItem: function( event ) {
1654
+ var item = this.menuItems.eq( this.focusIndex );
1655
+ if ( !item.hasClass( "ui-state-disabled" ) ) {
1656
+ this._select( item.data( "ui-selectmenu-item" ), event );
1657
+ }
1658
+ },
1659
+
1660
+ _select: function( item, event ) {
1661
+ var oldIndex = this.element[ 0 ].selectedIndex;
1662
+
1663
+ // Change native select element
1664
+ this.element[ 0 ].selectedIndex = item.index;
1665
+ this._setText( this.buttonText, item.label );
1666
+ this._setAria( item );
1667
+ this._trigger( "select", event, { item: item } );
1668
+
1669
+ if ( item.index !== oldIndex ) {
1670
+ this._trigger( "change", event, { item: item } );
1671
+ }
1672
+
1673
+ this.close( event );
1674
+ },
1675
+
1676
+ _setAria: function( item ) {
1677
+ var id = this.menuItems.eq( item.index ).attr( "id" );
1678
+
1679
+ this.button.attr({
1680
+ "aria-labelledby": id,
1681
+ "aria-activedescendant": id
1682
+ });
1683
+ this.menu.attr( "aria-activedescendant", id );
1684
+ },
1685
+
1686
+ _setOption: function( key, value ) {
1687
+ if ( key === "icons" ) {
1688
+ this.button.find( "span.ui-icon" )
1689
+ .removeClass( this.options.icons.button )
1690
+ .addClass( value.button );
1691
+ }
1692
+
1693
+ this._super( key, value );
1694
+
1695
+ if ( key === "appendTo" ) {
1696
+ this.menuWrap.appendTo( this._appendTo() );
1697
+ }
1698
+
1699
+ if ( key === "disabled" ) {
1700
+ this.menuInstance.option( "disabled", value );
1701
+ this.button
1702
+ .toggleClass( "ui-state-disabled", value )
1703
+ .attr( "aria-disabled", value );
1704
+
1705
+ this.element.prop( "disabled", value );
1706
+ if ( value ) {
1707
+ this.button.attr( "tabindex", -1 );
1708
+ this.close();
1709
+ } else {
1710
+ this.button.attr( "tabindex", 0 );
1711
+ }
1712
+ }
1713
+
1714
+ if ( key === "width" ) {
1715
+ this._resizeButton();
1716
+ }
1717
+ },
1718
+
1719
+ _appendTo: function() {
1720
+ var element = this.options.appendTo;
1721
+
1722
+ if ( element ) {
1723
+ element = element.jquery || element.nodeType ?
1724
+ $( element ) :
1725
+ this.document.find( element ).eq( 0 );
1726
+ }
1727
+
1728
+ if ( !element || !element[ 0 ] ) {
1729
+ element = this.element.closest( ".ui-front" );
1730
+ }
1731
+
1732
+ if ( !element.length ) {
1733
+ element = this.document[ 0 ].body;
1734
+ }
1735
+
1736
+ return element;
1737
+ },
1738
+
1739
+ _toggleAttr: function() {
1740
+ this.button
1741
+ .toggleClass( "ui-corner-top", this.isOpen )
1742
+ .toggleClass( "ui-corner-all", !this.isOpen )
1743
+ .attr( "aria-expanded", this.isOpen );
1744
+ this.menuWrap.toggleClass( "ui-selectmenu-open", this.isOpen );
1745
+ this.menu.attr( "aria-hidden", !this.isOpen );
1746
+ },
1747
+
1748
+ _resizeButton: function() {
1749
+ var width = this.options.width;
1750
+
1751
+ if ( !width ) {
1752
+ width = this.element.show().outerWidth();
1753
+ this.element.hide();
1754
+ }
1755
+
1756
+ this.button.outerWidth( width );
1757
+ },
1758
+
1759
+ _resizeMenu: function() {
1760
+ this.menu.outerWidth( Math.max(
1761
+ this.button.outerWidth(),
1762
+
1763
+ // support: IE10
1764
+ // IE10 wraps long text (possibly a rounding bug)
1765
+ // so we add 1px to avoid the wrapping
1766
+ this.menu.width( "" ).outerWidth() + 1
1767
+ ) );
1768
+ },
1769
+
1770
+ _getCreateOptions: function() {
1771
+ return { disabled: this.element.prop( "disabled" ) };
1772
+ },
1773
+
1774
+ _parseOptions: function( options ) {
1775
+ var data = [];
1776
+ options.each(function( index, item ) {
1777
+ var option = $( item ),
1778
+ optgroup = option.parent( "optgroup" );
1779
+ data.push({
1780
+ element: option,
1781
+ index: index,
1782
+ value: option.attr( "value" ),
1783
+ label: option.text(),
1784
+ optgroup: optgroup.attr( "label" ) || "",
1785
+ disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
1786
+ });
1787
+ });
1788
+ this.items = data;
1789
+ },
1790
+
1791
+ _destroy: function() {
1792
+ this.menuWrap.remove();
1793
+ this.button.remove();
1794
+ this.element.show();
1795
+ this.element.removeUniqueId();
1796
+ this.label.attr( "for", this.ids.element );
1797
+ }
1798
  });
1799
 
1800
 
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: lilaeamedia
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8QE5YJ8WE96AJ
4
  Tags: child theme, child themes, custom styles, customize styles, customize theme, CSS, responsive, css editor, child theme generator, child theme creator, style, stylesheet, customizer, childtheme, childthemes
5
  Requires at least: 3.9
6
- Tested up to: 4.5
7
- Stable tag: 2.0.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -288,6 +288,12 @@ https://www.youtube.com/watch?v=iBiiAgsK4G4
288
 
289
  == Changelog ==
290
 
 
 
 
 
 
 
291
  = 2.0.2 =
292
  * Automatically set priority of enqueue hook based on value from parent theme
293
  * Made file scan routine more efficient
3
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=8QE5YJ8WE96AJ
4
  Tags: child theme, child themes, custom styles, customize styles, customize theme, CSS, responsive, css editor, child theme generator, child theme creator, style, stylesheet, customizer, childtheme, childthemes
5
  Requires at least: 3.9
6
+ Tested up to: 4.5.2
7
+ Stable tag: 2.0.3
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
288
 
289
  == Changelog ==
290
 
291
+ = 2.0.3 =
292
+ * Added logic conditions in preview class to help prevent Analyzer from failing in some cases
293
+ * Enabled theme zip file export for any selected theme independent of theme currently loaded in Configurator
294
+ * Fixed bugs present with servers not running Apache with SuExec
295
+ * Fixed issue with Windows servers that do not return C: with filesystem paths
296
+
297
  = 2.0.2 =
298
  * Automatically set priority of enqueue hook based on value from parent theme
299
  * Made file scan routine more efficient