CSS & JavaScript Toolbox - Version 11.4

Version Description

  • Removed: Auxiliary and Advanced tabs are removed for CJT new installs. Existing CJT users with active code blocks still get them
  • Enhancement: All mouse hover-over popups are faster and more responsive
Download this release

Release Info

Developer wipeoutmedia
Plugin Icon 128x128 CSS & JavaScript Toolbox
Version 11.4
Comparing to
See all releases

Code changes from version 11.3 to 11.4

Files changed (50) hide show
  1. controllers/setup.php +26 -16
  2. css-js-toolbox.php +25 -1
  3. framework/CouplingHookAttacher.php +139 -70
  4. framework/css/images/beautify.png +0 -0
  5. framework/css/images/close-panel.png +0 -0
  6. framework/css/images/editor-edit.png +0 -0
  7. framework/css/images/editor-file.png +0 -0
  8. framework/css/images/editor-settings.png +0 -0
  9. framework/css/images/font-large.png +0 -0
  10. framework/css/images/font-reset.png +0 -0
  11. framework/css/images/font-size.png +0 -0
  12. framework/css/images/font-small.png +0 -0
  13. framework/css/images/maximise-editor.png +0 -0
  14. framework/css/images/minify.png +0 -0
  15. framework/css/images/minimise-editor.png +0 -0
  16. framework/css/images/open-panel.png +0 -0
  17. framework/css/images/save-editor-options.png +0 -0
  18. framework/css/images/theme.png +0 -0
  19. framework/css/toolbox.css +76 -0
  20. framework/extensions/extensions.class.php +2 -3
  21. framework/js/ace/ext-prompt.js +2782 -0
  22. framework/js/ui/jquery.toolbox/jquery.toolbox.js +11 -15
  23. framework/mvc/controller.inc.php +67 -67
  24. readme.txt +51 -134
  25. views/blocks/block/public/css/block.css +38 -8
  26. views/blocks/block/public/images/toolbox/cancel-restore.png +0 -0
  27. views/blocks/block/public/images/toolbox/restore.png +0 -0
  28. views/blocks/block/public/js/jquery.block/jquery.block.js +4 -4
  29. views/blocks/block/public/js/optional/revision/revision.js +39 -33
  30. views/blocks/block/tmpl/templates/editor-toolbox.html.tmpl +64 -3
  31. views/blocks/block/tmpl/templates/toolbox.html.tmpl +140 -130
  32. views/blocks/cjt-block/public/css/block.css +41 -1
  33. views/blocks/cjt-block/public/js/jquery.assignpanel/jquery.assignpanel.js +8 -6
  34. views/blocks/cjt-block/public/js/jquery.block/jquery.block.js +20 -18
  35. views/blocks/cjt-block/tmpl/templates/assign-panel/default.html.tmpl +95 -51
  36. views/blocks/cjt-block/tmpl/templates/assign-panel/templates/advanced.html.tmpl +4 -2
  37. views/blocks/cjt-block/tmpl/templates/assign-panel/templates/promo-plus.html.tmpl +8 -0
  38. views/blocks/cjt-block/tmpl/templates/assign-panel/templates/tab.html.tmpl +65 -36
  39. views/blocks/manager/public/css/blocks.css +20 -0
  40. views/blocks/manager/public/images/toolbox/activate-all.png +0 -0
  41. views/blocks/manager/public/images/toolbox/close-all.png +0 -0
  42. views/blocks/manager/public/images/toolbox/deactivate-all.png +0 -0
  43. views/blocks/manager/public/images/toolbox/open-all.png +0 -0
  44. views/blocks/manager/public/images/toolbox/revert-state.png +0 -0
  45. views/blocks/manager/public/js/blocks-page/blocks-page.js +55 -55
  46. views/blocks/manager/tmpl/blocks.html.tmpl +7 -4
  47. views/blocks/manager/tmpl/toolbox.html.tmpl +31 -8
  48. views/installer/install/tmpl/default.html.tmpl +10 -0
  49. views/plus-promo/tmpl/default.html.tmpl +29 -0
  50. views/plus-promo/view.php +66 -0
controllers/setup.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
  /**
3
- *
4
  */
5
 
6
  // Disallow direct access.
@@ -10,42 +10,52 @@ defined('ABSPATH') or die("Access denied");
10
  cssJSToolbox::import('framework:mvc:controller-ajax.inc.php');
11
 
12
  /**
13
- *
14
  */
15
  class CJTsetupController extends CJTAjaxController {
16
-
17
  /**
18
  * put your comment there...
19
- *
20
  * @var mixed
21
  */
22
  protected $controllerInfo = array('model' => 'setup');
23
-
24
  /**
25
  * put your comment there...
26
- *
27
  */
28
  public function __construct() {
29
  parent::__construct();
30
  // Register actions!
31
  $this->registryAction('activationFormView');
32
- $this->registryAction('getState');
 
33
  $this->registryAction('license');
34
  $this->registryAction('reset');
35
  }
36
-
37
  /**
38
  * Display Activation form!
39
- *
40
  */
41
  protected function activationFormViewAction() {
42
  // Display activation for for the requested component!
43
  parent::displayAction();
44
  }
45
-
 
 
 
 
 
 
 
 
 
46
  /**
47
  * put your comment there...
48
- *
49
  */
50
  protected function getStateAction() {
51
  # Get component product types
@@ -53,10 +63,10 @@ class CJTsetupController extends CJTAjaxController {
53
  # Return license state back
54
  $this->response = $this->model->getStateStruct($licenseTypes);
55
  }
56
-
57
  /**
58
  * put your comment there...
59
- *
60
  */
61
  protected function licenseAction() {
62
  // Read request parameters!
@@ -74,10 +84,10 @@ class CJTsetupController extends CJTAjaxController {
74
  // Return state object includes (component, license, edd response [and action only if valid])
75
  $this->response = $state;
76
  }
77
-
78
  /**
79
  * put your comment there...
80
- *
81
  */
82
  protected function resetAction() {
83
  // Initializing!
@@ -94,5 +104,5 @@ class CJTsetupController extends CJTAjaxController {
94
  $state['response']['item_name'] = $state['component']['name'];
95
  $this->response = $state;
96
  }
97
-
98
  } // End class.
1
  <?php
2
  /**
3
+ *
4
  */
5
 
6
  // Disallow direct access.
10
  cssJSToolbox::import('framework:mvc:controller-ajax.inc.php');
11
 
12
  /**
13
+ *
14
  */
15
  class CJTsetupController extends CJTAjaxController {
16
+
17
  /**
18
  * put your comment there...
19
+ *
20
  * @var mixed
21
  */
22
  protected $controllerInfo = array('model' => 'setup');
23
+
24
  /**
25
  * put your comment there...
26
+ *
27
  */
28
  public function __construct() {
29
  parent::__construct();
30
  // Register actions!
31
  $this->registryAction('activationFormView');
32
+ $this->registryAction('promoTextView');
33
+ $this->registryAction('getState');
34
  $this->registryAction('license');
35
  $this->registryAction('reset');
36
  }
37
+
38
  /**
39
  * Display Activation form!
40
+ *
41
  */
42
  protected function activationFormViewAction() {
43
  // Display activation for for the requested component!
44
  parent::displayAction();
45
  }
46
+
47
+ /**
48
+ * Display CJT Promo form!
49
+ *
50
+ */
51
+ protected function promoTextViewAction() {
52
+ // Display activation for for the requested component!
53
+ parent::displayAction();
54
+ }
55
+
56
  /**
57
  * put your comment there...
58
+ *
59
  */
60
  protected function getStateAction() {
61
  # Get component product types
63
  # Return license state back
64
  $this->response = $this->model->getStateStruct($licenseTypes);
65
  }
66
+
67
  /**
68
  * put your comment there...
69
+ *
70
  */
71
  protected function licenseAction() {
72
  // Read request parameters!
84
  // Return state object includes (component, license, edd response [and action only if valid])
85
  $this->response = $state;
86
  }
87
+
88
  /**
89
  * put your comment there...
90
+ *
91
  */
92
  protected function resetAction() {
93
  // Initializing!
104
  $state['response']['item_name'] = $state['component']['name'];
105
  $this->response = $state;
106
  }
107
+
108
  } // End class.
css-js-toolbox.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: CSS & JavaScript Toolbox
4
  Plugin URI: https://css-javascript-toolbox.com/
5
  Description: Easily add CSS, JavaScript, HTML and PHP code to unique CJT code blocks and assign them anywhere on your website.
6
- Version: 11.3
7
  Author: Wipeout Media
8
  Author URI: https://css-javascript-toolbox.com
9
  License:
@@ -389,4 +389,28 @@ if ( version_compare( phpversion(), 7, '>=' ) ) {
389
  CJTPlugin::getInstance();
390
  } else {
391
  add_action( 'admin_notices', 'deprecatedPHPCheck' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
392
  }
3
  Plugin Name: CSS & JavaScript Toolbox
4
  Plugin URI: https://css-javascript-toolbox.com/
5
  Description: Easily add CSS, JavaScript, HTML and PHP code to unique CJT code blocks and assign them anywhere on your website.
6
+ Version: 11.4
7
  Author: Wipeout Media
8
  Author URI: https://css-javascript-toolbox.com
9
  License:
389
  CJTPlugin::getInstance();
390
  } else {
391
  add_action( 'admin_notices', 'deprecatedPHPCheck' );
392
+ }
393
+
394
+ add_action( 'upgrader_process_complete', 'upgradeCheck',10, 2 );
395
+
396
+ function upgradeCheck( $upgrader_object, $options ) {
397
+ $CJTPluginPath = plugin_basename( __FILE__ );
398
+
399
+ global $wpdb;
400
+ $table_name = $wpdb->base_prefix.'cjtoolbox_blocks';
401
+ $query = $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $table_name ) );
402
+ $preCheck = get_option( '__existing_cjt_user' );
403
+
404
+ if ( $options['action'] == 'update' && $options['type'] == 'plugin' ) {
405
+ foreach( $options['plugins'] as $each_plugin ) {
406
+ if ( $each_plugin == $CJTPluginPath ) {
407
+ $preCheck = get_option( '__existing_cjt_user' );
408
+
409
+ // Only create it once.
410
+ if ( empty( $preCheck ) ) {
411
+ update_option( '__existing_cjt_user', $wpdb->get_var( $query ) === $table_name ? 'true' : 'false' );
412
+ }
413
+ }
414
+ }
415
+ }
416
  }
framework/CouplingHookAttacher.php CHANGED
@@ -1,218 +1,287 @@
1
  <?php
2
  /**
3
- *
4
  */
5
 
6
 
7
  /**
8
- *
9
  */
10
  final class CJTBlocksCouplingHookAttacher {
11
-
12
-
13
  const GROUP = 'cjt';
14
-
15
  /**
16
  * put your comment there...
17
- *
18
  * @var mixed
19
  */
20
  public $callback;
21
-
22
  /**
23
  * put your comment there...
24
- *
25
  * @var mixed
26
  */
27
  public $filters;
28
-
29
  /**
30
  * put your comment there...
31
- *
32
  * @var mixed
33
  */
34
  private $filtersMap = array();
35
-
36
  /**
37
  * put your comment there...
38
- *
39
  * @var mixed
40
  */
41
  public $groupMap = array();
42
-
43
  /**
44
  * put your comment there...
45
- *
46
  * @var mixed
47
  */
48
  public $textMap = array();
49
-
50
  /**
51
- *
52
  */
53
  public $typeHandler = null;
54
-
55
  /**
56
  * put your comment there...
57
- *
58
  * @param mixed $callback
59
  * @return CJTBlocksCouplingHookAttacher
60
  */
61
  public function __construct($callback) {
62
-
63
  $this->typeHandler = $this;
64
  $this->callback = $callback;
65
-
66
  // Initialize filters
67
  $this->filters = array(
68
-
69
  // Unattched hooks are attached (dynamically) to either Backend or Frontend by the coupling controller
70
- 'unattached' => array(
71
-
72
- /* Database location map name */ /* Wordpress Hook name Part */
73
  'header' => array(
74
  'name' => 'head',
75
  'handler' => $this->callback,
76
  'title' => cssJSToolbox::getText('Header'),
77
- 'text' => cssJSToolbox::getText('Put Block code right before the HTML </header> tag'),
78
  'group' => self::GROUP,
79
  ),
80
  'footer' => array(
81
  'name' => 'footer',
82
  'handler' => $this->callback,
83
  'title' => cssJSToolbox::getText('Footer'),
84
- 'text' => cssJSToolbox::getText('Put Block code at the end of the page'),
85
  'group' => self::GROUP,
86
  ),
87
  ),
88
  );
89
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  do_action(CJTPluggableHelper::ACTION_BLOCKS_COUPLING_INIT_ATTACHER, $this);
91
-
92
  // Generate filters map even if not bind done yet
93
  // so that filter names can be used elsewhere
94
  $this->generateMap();
95
  }
96
-
97
  /**
98
  * Bind all obtained (through the map) filters to Wordpress hooks
99
- *
100
  */
101
  public function & bind() {
102
-
103
  foreach ($this->filtersMap as $hookFullName => $hooks) {
104
-
105
  foreach ($hooks as $hook) {
106
-
107
  add_filter($hookFullName, $hook['handler'], 30);
108
  }
109
 
110
  }
111
-
112
  return $this;
113
  }
114
-
115
  /**
116
  * Generate Hook names by adding the passed prefix to the hook name(s)
117
- *
118
  * @param mixed $hooks
119
  * @param mixed $prefix
120
  */
121
  public function genHooks($hooks, $prefix = '') {
122
-
123
- // Bind hooks strighatly
124
  foreach ($hooks as $locationName => $hook) {
125
-
126
  // Create filters map
127
  $hookFullName = "{$prefix}{$hook['name']}";
128
-
129
  $hook['locationName'] = $locationName;
130
  $this->filtersMap[$hookFullName][$locationName] = $hook;
131
-
132
  // Generate localized text map
133
  $this->textMap[$hook['locationName']]['title'] = $hook['title'];
134
  $this->textMap[$hook['locationName']]['text'] = $hook['text'];
135
-
136
  // Make Group map
137
  $this->groupMap[$hook['group']][] = $hook['locationName'];
138
  }
139
-
140
  }
141
-
142
  /**
143
  * Generate unattached hook names by adding either (wp_ or admin_ prefix to the hook name(s)
144
- *
145
  * @param mixed $filters
146
  * @return CJTBlocksCouplingHookAttacher
147
  */
148
  public function & genUnattachedHooks($filters) {
149
-
150
  $this->genHooks($filters, is_admin() ? 'admin_' : 'wp_');
151
-
152
  return $this;
153
  }
154
-
155
  /**
156
  * Generate all filter names by calling the FILTER-TYPE-HANDLER method
157
- *
158
  */
159
  public function generateMap() {
160
-
161
  $typeHandler = $this->typeHandler;
162
-
163
  foreach ($this->filters as $typeName => $filters) {
164
-
165
  $typeName = ucfirst($typeName);
166
-
167
  $attacherMethodName = "gen{$typeName}Hooks";
168
-
169
  $typeHandler->$attacherMethodName($filters);
170
  }
171
  }
172
-
173
  /**
174
  * put your comment there...
175
- *
176
  */
177
  public function getFiltersList() {
178
-
179
  return $this->filtersMap;
180
-
181
  }
182
-
183
  /**
184
  * put your comment there...
185
- *
186
  * @param mixed $group
187
  */
188
  public function getGroupMap($group) {
189
-
190
  return $this->groupMap[$group];
191
  }
192
-
193
  /**
194
  * put your comment there...
195
- *
196
  * @param mixed $filter
197
  */
198
  public function getHooksByFilterName($filterName) {
199
-
200
  return $this->filtersMap[$filterName];
201
-
202
  }
203
-
204
  /**
205
  * put your comment there...
206
- *
207
  * @param mixed $locationName
208
  */
209
  public function getHookText($locationName, $prop = 'text') {
210
-
211
  $text = isset($this->textMap[$locationName]) ?
212
  $this->textMap[$locationName][$prop] :
213
  '';
214
-
215
  return $text;
216
  }
217
-
218
  }
1
  <?php
2
  /**
3
+ *
4
  */
5
 
6
 
7
  /**
8
+ *
9
  */
10
  final class CJTBlocksCouplingHookAttacher {
11
+
12
+
13
  const GROUP = 'cjt';
14
+
15
  /**
16
  * put your comment there...
17
+ *
18
  * @var mixed
19
  */
20
  public $callback;
21
+
22
  /**
23
  * put your comment there...
24
+ *
25
  * @var mixed
26
  */
27
  public $filters;
28
+
29
  /**
30
  * put your comment there...
31
+ *
32
  * @var mixed
33
  */
34
  private $filtersMap = array();
35
+
36
  /**
37
  * put your comment there...
38
+ *
39
  * @var mixed
40
  */
41
  public $groupMap = array();
42
+
43
  /**
44
  * put your comment there...
45
+ *
46
  * @var mixed
47
  */
48
  public $textMap = array();
49
+
50
  /**
51
+ *
52
  */
53
  public $typeHandler = null;
54
+
55
  /**
56
  * put your comment there...
57
+ *
58
  * @param mixed $callback
59
  * @return CJTBlocksCouplingHookAttacher
60
  */
61
  public function __construct($callback) {
62
+
63
  $this->typeHandler = $this;
64
  $this->callback = $callback;
65
+
66
  // Initialize filters
67
  $this->filters = array(
68
+
69
  // Unattched hooks are attached (dynamically) to either Backend or Frontend by the coupling controller
70
+ 'unattached' => array(
71
+
72
+ /* Database location map name */ /* Wordpress Hook name Part */
73
  'header' => array(
74
  'name' => 'head',
75
  'handler' => $this->callback,
76
  'title' => cssJSToolbox::getText('Header'),
77
+ 'text' => cssJSToolbox::getText('Puts your code right before the HTML </header> tag'),
78
  'group' => self::GROUP,
79
  ),
80
  'footer' => array(
81
  'name' => 'footer',
82
  'handler' => $this->callback,
83
  'title' => cssJSToolbox::getText('Footer'),
84
+ 'text' => cssJSToolbox::getText('Puts your code at the end of the page'),
85
  'group' => self::GROUP,
86
  ),
87
  ),
88
  );
89
+
90
+ if ( ! class_exists( 'CJTPlus' ) ) {
91
+ $this->filters['unattached'] = array_merge( $this->filters['unattached'], [
92
+ 'wp_body_open' => array(
93
+ 'name' => 'wp_body_open',
94
+ 'handler' => '',
95
+ 'title' => cssJSToolbox::getText('Body Open'),
96
+ 'text' => cssJSToolbox::getText('Puts your code right after the HTML tag'),
97
+ 'group' => self::GROUP,
98
+ 'disabled' => true,
99
+ ),
100
+ 'before_the_content' => array(
101
+ 'name' => 'the_content',
102
+ 'handler' => '',
103
+ 'title' => cssJSToolbox::getText('Before Post Content'),
104
+ 'text' => cssJSToolbox::getText('Puts your code before the post content'),
105
+ 'group' => self::GROUP,
106
+ 'disabled' => true,
107
+ ),
108
+ 'after_the_content' => array(
109
+ 'name' => 'the_content',
110
+ 'handler' => '',
111
+ 'title' => cssJSToolbox::getText('After Post Content'),
112
+ 'text' => cssJSToolbox::getText('Puts your code after the post content'),
113
+ 'group' => self::GROUP,
114
+ 'disabled' => true,
115
+ ),
116
+ 'before_the_excerpt' => array(
117
+ 'name' => 'the_excerpt',
118
+ 'handler' => '',
119
+ 'title' => cssJSToolbox::getText('Before Post Excerpt'),
120
+ 'text' => cssJSToolbox::getText('Puts your code just before the post excerpt'),
121
+ 'group' => self::GROUP,
122
+ 'disabled' => true,
123
+ ),
124
+ 'after_the_excerpt' => array(
125
+ 'name' => 'the_excerpt',
126
+ 'handler' => '',
127
+ 'title' => cssJSToolbox::getText('After Post Excerpt'),
128
+ 'text' => cssJSToolbox::getText('Puts your code after the post excerpt'),
129
+ 'group' => self::GROUP,
130
+ 'disabled' => true,
131
+ ),
132
+ 'loop_start' => array(
133
+ 'name' => 'loop_start',
134
+ 'handler' => '',
135
+ 'title' => cssJSToolbox::getText('Before Posts List'),
136
+ 'text' => cssJSToolbox::getText('Puts your code right before the posts list, or before the post when the posts query result is a single post'),
137
+ 'group' => self::GROUP,
138
+ 'disabled' => true,
139
+ ),
140
+ 'loop_end' => array(
141
+ 'name' => 'loop_end',
142
+ 'handler' => '',
143
+ 'title' => cssJSToolbox::getText('After Posts List'),
144
+ 'text' => cssJSToolbox::getText('Puts your code right after the posts list, or after the post when the posts query result is a single post'),
145
+ 'group' => self::GROUP,
146
+ 'disabled' => true,
147
+ ),
148
+ 'the_post' => array(
149
+ 'name' => 'the_post',
150
+ 'handler' => '',
151
+ 'title' => cssJSToolbox::getText('Before Post'),
152
+ 'text' => cssJSToolbox::getText('Puts your code right before the post'),
153
+ 'group' => self::GROUP,
154
+ 'disabled' => true,
155
+ ),
156
+ ] );
157
+ }
158
+
159
  do_action(CJTPluggableHelper::ACTION_BLOCKS_COUPLING_INIT_ATTACHER, $this);
160
+
161
  // Generate filters map even if not bind done yet
162
  // so that filter names can be used elsewhere
163
  $this->generateMap();
164
  }
165
+
166
  /**
167
  * Bind all obtained (through the map) filters to Wordpress hooks
168
+ *
169
  */
170
  public function & bind() {
171
+
172
  foreach ($this->filtersMap as $hookFullName => $hooks) {
173
+
174
  foreach ($hooks as $hook) {
175
+
176
  add_filter($hookFullName, $hook['handler'], 30);
177
  }
178
 
179
  }
180
+
181
  return $this;
182
  }
183
+
184
  /**
185
  * Generate Hook names by adding the passed prefix to the hook name(s)
186
+ *
187
  * @param mixed $hooks
188
  * @param mixed $prefix
189
  */
190
  public function genHooks($hooks, $prefix = '') {
191
+
192
+ // Bind hooks strighatly
193
  foreach ($hooks as $locationName => $hook) {
194
+
195
  // Create filters map
196
  $hookFullName = "{$prefix}{$hook['name']}";
197
+
198
  $hook['locationName'] = $locationName;
199
  $this->filtersMap[$hookFullName][$locationName] = $hook;
200
+
201
  // Generate localized text map
202
  $this->textMap[$hook['locationName']]['title'] = $hook['title'];
203
  $this->textMap[$hook['locationName']]['text'] = $hook['text'];
204
+
205
  // Make Group map
206
  $this->groupMap[$hook['group']][] = $hook['locationName'];
207
  }
208
+
209
  }
210
+
211
  /**
212
  * Generate unattached hook names by adding either (wp_ or admin_ prefix to the hook name(s)
213
+ *
214
  * @param mixed $filters
215
  * @return CJTBlocksCouplingHookAttacher
216
  */
217
  public function & genUnattachedHooks($filters) {
218
+
219
  $this->genHooks($filters, is_admin() ? 'admin_' : 'wp_');
220
+
221
  return $this;
222
  }
223
+
224
  /**
225
  * Generate all filter names by calling the FILTER-TYPE-HANDLER method
226
+ *
227
  */
228
  public function generateMap() {
229
+
230
  $typeHandler = $this->typeHandler;
231
+
232
  foreach ($this->filters as $typeName => $filters) {
233
+
234
  $typeName = ucfirst($typeName);
235
+
236
  $attacherMethodName = "gen{$typeName}Hooks";
237
+
238
  $typeHandler->$attacherMethodName($filters);
239
  }
240
  }
241
+
242
  /**
243
  * put your comment there...
244
+ *
245
  */
246
  public function getFiltersList() {
247
+
248
  return $this->filtersMap;
249
+
250
  }
251
+
252
  /**
253
  * put your comment there...
254
+ *
255
  * @param mixed $group
256
  */
257
  public function getGroupMap($group) {
258
+
259
  return $this->groupMap[$group];
260
  }
261
+
262
  /**
263
  * put your comment there...
264
+ *
265
  * @param mixed $filter
266
  */
267
  public function getHooksByFilterName($filterName) {
268
+
269
  return $this->filtersMap[$filterName];
270
+
271
  }
272
+
273
  /**
274
  * put your comment there...
275
+ *
276
  * @param mixed $locationName
277
  */
278
  public function getHookText($locationName, $prop = 'text') {
279
+
280
  $text = isset($this->textMap[$locationName]) ?
281
  $this->textMap[$locationName][$prop] :
282
  '';
283
+
284
  return $text;
285
  }
286
+
287
  }
framework/css/images/beautify.png ADDED
Binary file
framework/css/images/close-panel.png ADDED
Binary file
framework/css/images/editor-edit.png ADDED
Binary file
framework/css/images/editor-file.png ADDED
Binary file
framework/css/images/editor-settings.png ADDED
Binary file
framework/css/images/font-large.png ADDED
Binary file
framework/css/images/font-reset.png ADDED
Binary file
framework/css/images/font-size.png ADDED
Binary file
framework/css/images/font-small.png ADDED
Binary file
framework/css/images/maximise-editor.png ADDED
Binary file
framework/css/images/minify.png ADDED
Binary file
framework/css/images/minimise-editor.png ADDED
Binary file
framework/css/images/open-panel.png ADDED
Binary file
framework/css/images/save-editor-options.png ADDED
Binary file
framework/css/images/theme.png ADDED
Binary file
framework/css/toolbox.css CHANGED
@@ -50,6 +50,9 @@
50
  display: flex;
51
  align-items: center;
52
  }
 
 
 
53
  .cjt-toolbox .icons-group a.l-127x23 {
54
  width: 105px;
55
  height: 23px;
@@ -58,11 +61,84 @@
58
  width: 45px;
59
  height: 27px;
60
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  .cjt-toolbox a.cjt-tb-link,
62
  .cjt-toolbox a.cjt-tb-link:hover,
63
  .cjt-toolbox a.cjt-tb-link:visited {
64
  color: #6C6B6B;
65
  }
 
 
 
 
 
66
  .cjt-toolbox a.cjt-tb-link:hover {
67
  opacity : 0.7;
68
  filter:alpha(opacity = 70%);
50
  display: flex;
51
  align-items: center;
52
  }
53
+ .cjt-toolbox .icons-group .popup-menu a.cjt-tb-text-link.cjt-promo-disabled {
54
+ align-items: unset;
55
+ }
56
  .cjt-toolbox .icons-group a.l-127x23 {
57
  width: 105px;
58
  height: 23px;
61
  width: 45px;
62
  height: 27px;
63
  }
64
+ .cjt-toolbox.cjt-promo-disabled a.cjt-tb-link {
65
+ margin: 5px 0 0 6px;
66
+ opacity: 0.5;
67
+ filter: grayscale(1);
68
+ cursor: help;
69
+ }
70
+ .cjt-toolbox.cjt-promo-disabled .ui-menu-item {
71
+ opacity: 0.5;
72
+ filter: grayscale(1);
73
+ }
74
+ .cjt-toolbox.cjt-promo-disabled .ui-menu-item a {
75
+ cursor: help;
76
+ }
77
+ .cjt-toolbox.cjt-promo-disabled a.cjttbl-toggle-objects-panel {
78
+ background-image: url(images/close-panel.png);
79
+ }
80
+ .cjt-toolbox.cjt-promo-disabled a.cjttbl-fullscreen {
81
+ background-image: url(images/maximise-editor.png);
82
+ }
83
+ .cjt-toolbox.cjt-promo-disabled .block-menu>li>a.toolbox-menu-file {
84
+ background-image: url(images/editor-file.png);
85
+ }
86
+ .cjt-toolbox.cjt-promo-disabled .block-menu>li>a.toolbox-menu-edit {
87
+ background-image: url(images/editor-edit.png);
88
+ }
89
+ .cjt-toolbox.cjt-promo-disabled .block-menu>li>a.toolbox-menu-settings {
90
+ background-image: url(images/editor-settings.png);
91
+ }
92
+ .cjt-toolbox.cjt-promo-disabled a.cjttbl-editor-theme {
93
+ background-image: url(images/theme.png);
94
+ }
95
+ .cjt-toolbox.cjt-promo-disabled a.cjttbl-beautify {
96
+ background-image: url(images/beautify.png);
97
+ }
98
+ .cjt-toolbox.cjt-promo-disabled a.cjttbl-minify {
99
+ background-image: url(images/minify.png);
100
+ }
101
+ .cjt-toolbox.cjt-promo-disabled a.cjttbl-fonts {
102
+ background-image: url(images/font-size.png);
103
+ }
104
+ .cjt-toolbox.cjt-promo-disabled a.cjttbl-save-editor-options {
105
+ background-image: url(images/save-editor-options.png);
106
+ }
107
+
108
+ .cjt-toolbox.cjt-promo-disabled .block-menu {
109
+ margin: 8px 0 0 -1px;
110
+ position: relative;
111
+ top: 5px;
112
+ width: 32px;
113
+ }
114
+ .cjt-toolbox.cjt-promo-disabled .block-menu>li {
115
+ text-align: center;
116
+ margin-left: 3px;
117
+ margin-bottom: 11px;
118
+ padding: 0;
119
+ }
120
+ .cjt-toolbox.cjt-promo-disabled .block-menu>li>a {
121
+ text-decoration: none;
122
+ display: inline-block;
123
+ border: none;
124
+ background-color: transparent !important;
125
+ width: 20px;
126
+ height: 22px;
127
+ }
128
+ .cjt-toolbox.cjt-promo-disabled .block-menu>li>a>span {
129
+ display: none;
130
+ }
131
+
132
  .cjt-toolbox a.cjt-tb-link,
133
  .cjt-toolbox a.cjt-tb-link:hover,
134
  .cjt-toolbox a.cjt-tb-link:visited {
135
  color: #6C6B6B;
136
  }
137
+ .cjt-toolbox a.cjt-tb-link.cjt-promo-disabled {
138
+ opacity: 0.5;
139
+ filter: grayscale(1);
140
+ cursor: help;
141
+ }
142
  .cjt-toolbox a.cjt-tb-link:hover {
143
  opacity : 0.7;
144
  filter:alpha(opacity = 70%);
framework/extensions/extensions.class.php CHANGED
@@ -329,9 +329,8 @@ class CJTExtensions extends CJTHookableClass {
329
  $addonVersion = get_plugin_data($extension['pluginFile'], false, false)['Version'];
330
  $currentVersion = get_plugin_data( CJTOOLBOX_PLUGIN_FILE )['Version'];
331
 
332
- if (version_compare($addonVersion,
333
- $currentVersion,
334
- $incomapatibleAddon[1])) {
335
 
336
  $extension['incompatibleMessage']['flag'] = $incomapatibleAddon[2];
337
  $extension['incompatibleMessage']['msg'] = $incomapatibleAddon[3];
329
  $addonVersion = get_plugin_data($extension['pluginFile'], false, false)['Version'];
330
  $currentVersion = get_plugin_data( CJTOOLBOX_PLUGIN_FILE )['Version'];
331
 
332
+ // Only show notice if addon version is less than 11.
333
+ if ( $addonVersion < 11) {
 
334
 
335
  $extension['incompatibleMessage']['flag'] = $incomapatibleAddon[2];
336
  $extension['incompatibleMessage']['msg'] = $incomapatibleAddon[3];
framework/js/ace/ext-prompt.js ADDED
@@ -0,0 +1,2782 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ace.define("ace/ext/menu_tools/get_editor_keyboard_shortcuts",["require","exports","module","ace/lib/keys"], function(require, exports, module) {
2
+ "use strict";
3
+ var keys = require("../../lib/keys");
4
+ module.exports.getEditorKeybordShortcuts = function(editor) {
5
+ var KEY_MODS = keys.KEY_MODS;
6
+ var keybindings = [];
7
+ var commandMap = {};
8
+ editor.keyBinding.$handlers.forEach(function(handler) {
9
+ var ckb = handler.commandKeyBinding;
10
+ for (var i in ckb) {
11
+ var key = i.replace(/(^|-)\w/g, function(x) { return x.toUpperCase(); });
12
+ var commands = ckb[i];
13
+ if (!Array.isArray(commands))
14
+ commands = [commands];
15
+ commands.forEach(function(command) {
16
+ if (typeof command != "string")
17
+ command = command.name;
18
+ if (commandMap[command]) {
19
+ commandMap[command].key += "|" + key;
20
+ } else {
21
+ commandMap[command] = {key: key, command: command};
22
+ keybindings.push(commandMap[command]);
23
+ }
24
+ });
25
+ }
26
+ });
27
+ return keybindings;
28
+ };
29
+
30
+ });
31
+
32
+ ace.define("ace/autocomplete/popup",["require","exports","module","ace/virtual_renderer","ace/editor","ace/range","ace/lib/event","ace/lib/lang","ace/lib/dom"], function(require, exports, module) {
33
+ "use strict";
34
+
35
+ var Renderer = require("../virtual_renderer").VirtualRenderer;
36
+ var Editor = require("../editor").Editor;
37
+ var Range = require("../range").Range;
38
+ var event = require("../lib/event");
39
+ var lang = require("../lib/lang");
40
+ var dom = require("../lib/dom");
41
+
42
+ var $singleLineEditor = function(el) {
43
+ var renderer = new Renderer(el);
44
+
45
+ renderer.$maxLines = 4;
46
+
47
+ var editor = new Editor(renderer);
48
+
49
+ editor.setHighlightActiveLine(false);
50
+ editor.setShowPrintMargin(false);
51
+ editor.renderer.setShowGutter(false);
52
+ editor.renderer.setHighlightGutterLine(false);
53
+
54
+ editor.$mouseHandler.$focusTimeout = 0;
55
+ editor.$highlightTagPending = true;
56
+
57
+ return editor;
58
+ };
59
+
60
+ var AcePopup = function(parentNode) {
61
+ var el = dom.createElement("div");
62
+ var popup = new $singleLineEditor(el);
63
+
64
+ if (parentNode)
65
+ parentNode.appendChild(el);
66
+ el.style.display = "none";
67
+ popup.renderer.content.style.cursor = "default";
68
+ popup.renderer.setStyle("ace_autocomplete");
69
+
70
+ popup.setOption("displayIndentGuides", false);
71
+ popup.setOption("dragDelay", 150);
72
+
73
+ var noop = function(){};
74
+
75
+ popup.focus = noop;
76
+ popup.$isFocused = true;
77
+
78
+ popup.renderer.$cursorLayer.restartTimer = noop;
79
+ popup.renderer.$cursorLayer.element.style.opacity = 0;
80
+
81
+ popup.renderer.$maxLines = 8;
82
+ popup.renderer.$keepTextAreaAtCursor = false;
83
+
84
+ popup.setHighlightActiveLine(false);
85
+ popup.session.highlight("");
86
+ popup.session.$searchHighlight.clazz = "ace_highlight-marker";
87
+
88
+ popup.on("mousedown", function(e) {
89
+ var pos = e.getDocumentPosition();
90
+ popup.selection.moveToPosition(pos);
91
+ selectionMarker.start.row = selectionMarker.end.row = pos.row;
92
+ e.stop();
93
+ });
94
+
95
+ var lastMouseEvent;
96
+ var hoverMarker = new Range(-1,0,-1,Infinity);
97
+ var selectionMarker = new Range(-1,0,-1,Infinity);
98
+ selectionMarker.id = popup.session.addMarker(selectionMarker, "ace_active-line", "fullLine");
99
+ popup.setSelectOnHover = function(val) {
100
+ if (!val) {
101
+ hoverMarker.id = popup.session.addMarker(hoverMarker, "ace_line-hover", "fullLine");
102
+ } else if (hoverMarker.id) {
103
+ popup.session.removeMarker(hoverMarker.id);
104
+ hoverMarker.id = null;
105
+ }
106
+ };
107
+ popup.setSelectOnHover(false);
108
+ popup.on("mousemove", function(e) {
109
+ if (!lastMouseEvent) {
110
+ lastMouseEvent = e;
111
+ return;
112
+ }
113
+ if (lastMouseEvent.x == e.x && lastMouseEvent.y == e.y) {
114
+ return;
115
+ }
116
+ lastMouseEvent = e;
117
+ lastMouseEvent.scrollTop = popup.renderer.scrollTop;
118
+ var row = lastMouseEvent.getDocumentPosition().row;
119
+ if (hoverMarker.start.row != row) {
120
+ if (!hoverMarker.id)
121
+ popup.setRow(row);
122
+ setHoverMarker(row);
123
+ }
124
+ });
125
+ popup.renderer.on("beforeRender", function() {
126
+ if (lastMouseEvent && hoverMarker.start.row != -1) {
127
+ lastMouseEvent.$pos = null;
128
+ var row = lastMouseEvent.getDocumentPosition().row;
129
+ if (!hoverMarker.id)
130
+ popup.setRow(row);
131
+ setHoverMarker(row, true);
132
+ }
133
+ });
134
+ popup.renderer.on("afterRender", function() {
135
+ var row = popup.getRow();
136
+ var t = popup.renderer.$textLayer;
137
+ var selected = t.element.childNodes[row - t.config.firstRow];
138
+ if (selected !== t.selectedNode && t.selectedNode)
139
+ dom.removeCssClass(t.selectedNode, "ace_selected");
140
+ t.selectedNode = selected;
141
+ if (selected)
142
+ dom.addCssClass(selected, "ace_selected");
143
+ });
144
+ var hideHoverMarker = function() { setHoverMarker(-1); };
145
+ var setHoverMarker = function(row, suppressRedraw) {
146
+ if (row !== hoverMarker.start.row) {
147
+ hoverMarker.start.row = hoverMarker.end.row = row;
148
+ if (!suppressRedraw)
149
+ popup.session._emit("changeBackMarker");
150
+ popup._emit("changeHoverMarker");
151
+ }
152
+ };
153
+ popup.getHoveredRow = function() {
154
+ return hoverMarker.start.row;
155
+ };
156
+
157
+ event.addListener(popup.container, "mouseout", hideHoverMarker);
158
+ popup.on("hide", hideHoverMarker);
159
+ popup.on("changeSelection", hideHoverMarker);
160
+
161
+ popup.session.doc.getLength = function() {
162
+ return popup.data.length;
163
+ };
164
+ popup.session.doc.getLine = function(i) {
165
+ var data = popup.data[i];
166
+ if (typeof data == "string")
167
+ return data;
168
+ return (data && data.value) || "";
169
+ };
170
+
171
+ var bgTokenizer = popup.session.bgTokenizer;
172
+ bgTokenizer.$tokenizeRow = function(row) {
173
+ var data = popup.data[row];
174
+ var tokens = [];
175
+ if (!data)
176
+ return tokens;
177
+ if (typeof data == "string")
178
+ data = {value: data};
179
+ var caption = data.caption || data.value || data.name;
180
+
181
+ function addToken(value, className) {
182
+ value && tokens.push({
183
+ type: (data.className || "") + (className || ""),
184
+ value: value
185
+ });
186
+ }
187
+
188
+ var lower = caption.toLowerCase();
189
+ var filterText = (popup.filterText || "").toLowerCase();
190
+ var lastIndex = 0;
191
+ var lastI = 0;
192
+ for (var i = 0; i <= filterText.length; i++) {
193
+ if (i != lastI && (data.matchMask & (1 << i) || i == filterText.length)) {
194
+ var sub = filterText.slice(lastI, i);
195
+ lastI = i;
196
+ var index = lower.indexOf(sub, lastIndex);
197
+ if (index == -1) continue;
198
+ addToken(caption.slice(lastIndex, index), "");
199
+ lastIndex = index + sub.length;
200
+ addToken(caption.slice(index, lastIndex), "completion-highlight");
201
+ }
202
+ }
203
+ addToken(caption.slice(lastIndex, caption.length), "");
204
+
205
+ if (data.meta)
206
+ tokens.push({type: "completion-meta", value: data.meta});
207
+ if (data.message)
208
+ tokens.push({type: "completion-message", value: data.message});
209
+
210
+ return tokens;
211
+ };
212
+ bgTokenizer.$updateOnChange = noop;
213
+ bgTokenizer.start = noop;
214
+
215
+ popup.session.$computeWidth = function() {
216
+ return this.screenWidth = 0;
217
+ };
218
+ popup.isOpen = false;
219
+ popup.isTopdown = false;
220
+ popup.autoSelect = true;
221
+ popup.filterText = "";
222
+
223
+ popup.data = [];
224
+ popup.setData = function(list, filterText) {
225
+ popup.filterText = filterText || "";
226
+ popup.setValue(lang.stringRepeat("\n", list.length), -1);
227
+ popup.data = list || [];
228
+ popup.setRow(0);
229
+ };
230
+ popup.getData = function(row) {
231
+ return popup.data[row];
232
+ };
233
+
234
+ popup.getRow = function() {
235
+ return selectionMarker.start.row;
236
+ };
237
+ popup.setRow = function(line) {
238
+ line = Math.max(this.autoSelect ? 0 : -1, Math.min(this.data.length, line));
239
+ if (selectionMarker.start.row != line) {
240
+ popup.selection.clearSelection();
241
+ selectionMarker.start.row = selectionMarker.end.row = line || 0;
242
+ popup.session._emit("changeBackMarker");
243
+ popup.moveCursorTo(line || 0, 0);
244
+ if (popup.isOpen)
245
+ popup._signal("select");
246
+ }
247
+ };
248
+
249
+ popup.on("changeSelection", function() {
250
+ if (popup.isOpen)
251
+ popup.setRow(popup.selection.lead.row);
252
+ popup.renderer.scrollCursorIntoView();
253
+ });
254
+
255
+ popup.hide = function() {
256
+ this.container.style.display = "none";
257
+ this._signal("hide");
258
+ popup.isOpen = false;
259
+ };
260
+ popup.show = function(pos, lineHeight, topdownOnly) {
261
+ var el = this.container;
262
+ var screenHeight = window.innerHeight;
263
+ var screenWidth = window.innerWidth;
264
+ var renderer = this.renderer;
265
+ var maxH = renderer.$maxLines * lineHeight * 1.4;
266
+ var top = pos.top + this.$borderSize;
267
+ var allowTopdown = top > screenHeight / 2 && !topdownOnly;
268
+ if (allowTopdown && top + lineHeight + maxH > screenHeight) {
269
+ renderer.$maxPixelHeight = top - 2 * this.$borderSize;
270
+ el.style.top = "";
271
+ el.style.bottom = screenHeight - top + "px";
272
+ popup.isTopdown = false;
273
+ } else {
274
+ top += lineHeight;
275
+ renderer.$maxPixelHeight = screenHeight - top - 0.2 * lineHeight;
276
+ el.style.top = top + "px";
277
+ el.style.bottom = "";
278
+ popup.isTopdown = true;
279
+ }
280
+
281
+ el.style.display = "";
282
+
283
+ var left = pos.left;
284
+ if (left + el.offsetWidth > screenWidth)
285
+ left = screenWidth - el.offsetWidth;
286
+
287
+ el.style.left = left + "px";
288
+
289
+ this._signal("show");
290
+ lastMouseEvent = null;
291
+ popup.isOpen = true;
292
+ };
293
+
294
+ popup.goTo = function(where) {
295
+ var row = this.getRow();
296
+ var max = this.session.getLength() - 1;
297
+
298
+ switch(where) {
299
+ case "up": row = row <= 0 ? max : row - 1; break;
300
+ case "down": row = row >= max ? -1 : row + 1; break;
301
+ case "start": row = 0; break;
302
+ case "end": row = max; break;
303
+ }
304
+
305
+ this.setRow(row);
306
+ };
307
+
308
+
309
+ popup.getTextLeftOffset = function() {
310
+ return this.$borderSize + this.renderer.$padding + this.$imageSize;
311
+ };
312
+
313
+ popup.$imageSize = 0;
314
+ popup.$borderSize = 1;
315
+
316
+ return popup;
317
+ };
318
+
319
+ dom.importCssString("\
320
+ .ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\
321
+ background-color: #CAD6FA;\
322
+ z-index: 1;\
323
+ }\
324
+ .ace_dark.ace_editor.ace_autocomplete .ace_marker-layer .ace_active-line {\
325
+ background-color: #3a674e;\
326
+ }\
327
+ .ace_editor.ace_autocomplete .ace_line-hover {\
328
+ border: 1px solid #abbffe;\
329
+ margin-top: -1px;\
330
+ background: rgba(233,233,253,0.4);\
331
+ position: absolute;\
332
+ z-index: 2;\
333
+ }\
334
+ .ace_dark.ace_editor.ace_autocomplete .ace_line-hover {\
335
+ border: 1px solid rgba(109, 150, 13, 0.8);\
336
+ background: rgba(58, 103, 78, 0.62);\
337
+ }\
338
+ .ace_completion-meta {\
339
+ opacity: 0.5;\
340
+ margin: 0.9em;\
341
+ }\
342
+ .ace_completion-message {\
343
+ color: blue;\
344
+ }\
345
+ .ace_editor.ace_autocomplete .ace_completion-highlight{\
346
+ color: #2d69c7;\
347
+ }\
348
+ .ace_dark.ace_editor.ace_autocomplete .ace_completion-highlight{\
349
+ color: #93ca12;\
350
+ }\
351
+ .ace_editor.ace_autocomplete {\
352
+ width: 300px;\
353
+ z-index: 200000;\
354
+ border: 1px lightgray solid;\
355
+ position: fixed;\
356
+ box-shadow: 2px 3px 5px rgba(0,0,0,.2);\
357
+ line-height: 1.4;\
358
+ background: #fefefe;\
359
+ color: #111;\
360
+ }\
361
+ .ace_dark.ace_editor.ace_autocomplete {\
362
+ border: 1px #484747 solid;\
363
+ box-shadow: 2px 3px 5px rgba(0, 0, 0, 0.51);\
364
+ line-height: 1.4;\
365
+ background: #25282c;\
366
+ color: #c1c1c1;\
367
+ }", "autocompletion.css");
368
+
369
+ exports.AcePopup = AcePopup;
370
+ exports.$singleLineEditor = $singleLineEditor;
371
+ });
372
+
373
+ ace.define("ace/autocomplete/util",["require","exports","module"], function(require, exports, module) {
374
+ "use strict";
375
+
376
+ exports.parForEach = function(array, fn, callback) {
377
+ var completed = 0;
378
+ var arLength = array.length;
379
+ if (arLength === 0)
380
+ callback();
381
+ for (var i = 0; i < arLength; i++) {
382
+ fn(array[i], function(result, err) {
383
+ completed++;
384
+ if (completed === arLength)
385
+ callback(result, err);
386
+ });
387
+ }
388
+ };
389
+
390
+ var ID_REGEX = /[a-zA-Z_0-9\$\-\u00A2-\u2000\u2070-\uFFFF]/;
391
+
392
+ exports.retrievePrecedingIdentifier = function(text, pos, regex) {
393
+ regex = regex || ID_REGEX;
394
+ var buf = [];
395
+ for (var i = pos-1; i >= 0; i--) {
396
+ if (regex.test(text[i]))
397
+ buf.push(text[i]);
398
+ else
399
+ break;
400
+ }
401
+ return buf.reverse().join("");
402
+ };
403
+
404
+ exports.retrieveFollowingIdentifier = function(text, pos, regex) {
405
+ regex = regex || ID_REGEX;
406
+ var buf = [];
407
+ for (var i = pos; i < text.length; i++) {
408
+ if (regex.test(text[i]))
409
+ buf.push(text[i]);
410
+ else
411
+ break;
412
+ }
413
+ return buf;
414
+ };
415
+
416
+ exports.getCompletionPrefix = function (editor) {
417
+ var pos = editor.getCursorPosition();
418
+ var line = editor.session.getLine(pos.row);
419
+ var prefix;
420
+ editor.completers.forEach(function(completer) {
421
+ if (completer.identifierRegexps) {
422
+ completer.identifierRegexps.forEach(function(identifierRegex) {
423
+ if (!prefix && identifierRegex)
424
+ prefix = this.retrievePrecedingIdentifier(line, pos.column, identifierRegex);
425
+ }.bind(this));
426
+ }
427
+ }.bind(this));
428
+ return prefix || this.retrievePrecedingIdentifier(line, pos.column);
429
+ };
430
+
431
+ });
432
+
433
+ ace.define("ace/snippets",["require","exports","module","ace/lib/oop","ace/lib/event_emitter","ace/lib/lang","ace/range","ace/range_list","ace/keyboard/hash_handler","ace/tokenizer","ace/clipboard","ace/lib/dom","ace/editor"], function(require, exports, module) {
434
+ "use strict";
435
+ var oop = require("./lib/oop");
436
+ var EventEmitter = require("./lib/event_emitter").EventEmitter;
437
+ var lang = require("./lib/lang");
438
+ var Range = require("./range").Range;
439
+ var RangeList = require("./range_list").RangeList;
440
+ var HashHandler = require("./keyboard/hash_handler").HashHandler;
441
+ var Tokenizer = require("./tokenizer").Tokenizer;
442
+ var clipboard = require("./clipboard");
443
+
444
+ var VARIABLES = {
445
+ CURRENT_WORD: function(editor) {
446
+ return editor.session.getTextRange(editor.session.getWordRange());
447
+ },
448
+ SELECTION: function(editor, name, indentation) {
449
+ var text = editor.session.getTextRange();
450
+ if (indentation)
451
+ return text.replace(/\n\r?([ \t]*\S)/g, "\n" + indentation + "$1");
452
+ return text;
453
+ },
454
+ CURRENT_LINE: function(editor) {
455
+ return editor.session.getLine(editor.getCursorPosition().row);
456
+ },
457
+ PREV_LINE: function(editor) {
458
+ return editor.session.getLine(editor.getCursorPosition().row - 1);
459
+ },
460
+ LINE_INDEX: function(editor) {
461
+ return editor.getCursorPosition().row;
462
+ },
463
+ LINE_NUMBER: function(editor) {
464
+ return editor.getCursorPosition().row + 1;
465
+ },
466
+ SOFT_TABS: function(editor) {
467
+ return editor.session.getUseSoftTabs() ? "YES" : "NO";
468
+ },
469
+ TAB_SIZE: function(editor) {
470
+ return editor.session.getTabSize();
471
+ },
472
+ CLIPBOARD: function(editor) {
473
+ return clipboard.getText && clipboard.getText();
474
+ },
475
+ FILENAME: function(editor) {
476
+ return /[^/\\]*$/.exec(this.FILEPATH(editor))[0];
477
+ },
478
+ FILENAME_BASE: function(editor) {
479
+ return /[^/\\]*$/.exec(this.FILEPATH(editor))[0].replace(/\.[^.]*$/, "");
480
+ },
481
+ DIRECTORY: function(editor) {
482
+ return this.FILEPATH(editor).replace(/[^/\\]*$/, "");
483
+ },
484
+ FILEPATH: function(editor) { return "/not implemented.txt"; },
485
+ WORKSPACE_NAME: function() { return "Unknown"; },
486
+ FULLNAME: function() { return "Unknown"; },
487
+ BLOCK_COMMENT_START: function(editor) {
488
+ var mode = editor.session.$mode || {};
489
+ return mode.blockComment && mode.blockComment.start || "";
490
+ },
491
+ BLOCK_COMMENT_END: function(editor) {
492
+ var mode = editor.session.$mode || {};
493
+ return mode.blockComment && mode.blockComment.end || "";
494
+ },
495
+ LINE_COMMENT: function(editor) {
496
+ var mode = editor.session.$mode || {};
497
+ return mode.lineCommentStart || "";
498
+ },
499
+ CURRENT_YEAR: date.bind(null, {year: "numeric"}),
500
+ CURRENT_YEAR_SHORT: date.bind(null, {year: "2-digit"}),
501
+ CURRENT_MONTH: date.bind(null, {month: "numeric"}),
502
+ CURRENT_MONTH_NAME: date.bind(null, {month: "long"}),
503
+ CURRENT_MONTH_NAME_SHORT: date.bind(null, {month: "short"}),
504
+ CURRENT_DATE: date.bind(null, {day: "2-digit"}),
505
+ CURRENT_DAY_NAME: date.bind(null, {weekday: "long"}),
506
+ CURRENT_DAY_NAME_SHORT: date.bind(null, {weekday: "short"}),
507
+ CURRENT_HOUR: date.bind(null, {hour: "2-digit", hour12: false}),
508
+ CURRENT_MINUTE: date.bind(null, {minute: "2-digit"}),
509
+ CURRENT_SECOND: date.bind(null, {second: "2-digit"})
510
+ };
511
+
512
+ VARIABLES.SELECTED_TEXT = VARIABLES.SELECTION;
513
+
514
+ function date(dateFormat) {
515
+ var str = new Date().toLocaleString("en-us", dateFormat);
516
+ return str.length == 1 ? "0" + str : str;
517
+ }
518
+
519
+ var SnippetManager = function() {
520
+ this.snippetMap = {};
521
+ this.snippetNameMap = {};
522
+ };
523
+
524
+ (function() {
525
+ oop.implement(this, EventEmitter);
526
+
527
+ this.getTokenizer = function() {
528
+ return SnippetManager.$tokenizer || this.createTokenizer();
529
+ };
530
+
531
+ this.createTokenizer = function() {
532
+ function TabstopToken(str) {
533
+ str = str.substr(1);
534
+ if (/^\d+$/.test(str))
535
+ return [{tabstopId: parseInt(str, 10)}];
536
+ return [{text: str}];
537
+ }
538
+ function escape(ch) {
539
+ return "(?:[^\\\\" + ch + "]|\\\\.)";
540
+ }
541
+ var formatMatcher = {
542
+ regex: "/(" + escape("/") + "+)/",
543
+ onMatch: function(val, state, stack) {
544
+ var ts = stack[0];
545
+ ts.fmtString = true;
546
+ ts.guard = val.slice(1, -1);
547
+ ts.flag = "";
548
+ return "";
549
+ },
550
+ next: "formatString"
551
+ };
552
+
553
+ SnippetManager.$tokenizer = new Tokenizer({
554
+ start: [
555
+ {regex: /\\./, onMatch: function(val, state, stack) {
556
+ var ch = val[1];
557
+ if (ch == "}" && stack.length) {
558
+ val = ch;
559
+ } else if ("`$\\".indexOf(ch) != -1) {
560
+ val = ch;
561
+ }
562
+ return [val];
563
+ }},
564
+ {regex: /}/, onMatch: function(val, state, stack) {
565
+ return [stack.length ? stack.shift() : val];
566
+ }},
567
+ {regex: /\$(?:\d+|\w+)/, onMatch: TabstopToken},
568
+ {regex: /\$\{[\dA-Z_a-z]+/, onMatch: function(str, state, stack) {
569
+ var t = TabstopToken(str.substr(1));
570
+ stack.unshift(t[0]);
571
+ return t;
572
+ }, next: "snippetVar"},
573
+ {regex: /\n/, token: "newline", merge: false}
574
+ ],
575
+ snippetVar: [
576
+ {regex: "\\|" + escape("\\|") + "*\\|", onMatch: function(val, state, stack) {
577
+ var choices = val.slice(1, -1).replace(/\\[,|\\]|,/g, function(operator) {
578
+ return operator.length == 2 ? operator[1] : "\x00";
579
+ }).split("\x00").map(function(value){
580
+ return {value: value};
581
+ });
582
+ stack[0].choices = choices;
583
+ return [choices[0]];
584
+ }, next: "start"},
585
+ formatMatcher,
586
+ {regex: "([^:}\\\\]|\\\\.)*:?", token: "", next: "start"}
587
+ ],
588
+ formatString: [
589
+ {regex: /:/, onMatch: function(val, state, stack) {
590
+ if (stack.length && stack[0].expectElse) {
591
+ stack[0].expectElse = false;
592
+ stack[0].ifEnd = {elseEnd: stack[0]};
593
+ return [stack[0].ifEnd];
594
+ }
595
+ return ":";
596
+ }},
597
+ {regex: /\\./, onMatch: function(val, state, stack) {
598
+ var ch = val[1];
599
+ if (ch == "}" && stack.length)
600
+ val = ch;
601
+ else if ("`$\\".indexOf(ch) != -1)
602
+ val = ch;
603
+ else if (ch == "n")
604
+ val = "\n";
605
+ else if (ch == "t")
606
+ val = "\t";
607
+ else if ("ulULE".indexOf(ch) != -1)
608
+ val = {changeCase: ch, local: ch > "a"};
609
+ return [val];
610
+ }},
611
+ {regex: "/\\w*}", onMatch: function(val, state, stack) {
612
+ var next = stack.shift();
613
+ if (next)
614
+ next.flag = val.slice(1, -1);
615
+ this.next = next && next.tabstopId ? "start" : "";
616
+ return [next || val];
617
+ }, next: "start"},
618
+ {regex: /\$(?:\d+|\w+)/, onMatch: function(val, state, stack) {
619
+ return [{text: val.slice(1)}];
620
+ }},
621
+ {regex: /\${\w+/, onMatch: function(val, state, stack) {
622
+ var token = {text: val.slice(2)};
623
+ stack.unshift(token);
624
+ return [token];
625
+ }, next: "formatStringVar"},
626
+ {regex: /\n/, token: "newline", merge: false},
627
+ {regex: /}/, onMatch: function(val, state, stack) {
628
+ var next = stack.shift();
629
+ this.next = next && next.tabstopId ? "start" : "";
630
+ return [next || val];
631
+ }, next: "start"}
632
+ ],
633
+ formatStringVar: [
634
+ {regex: /:\/\w+}/, onMatch: function(val, state, stack) {
635
+ var ts = stack[0];
636
+ ts.formatFunction = val.slice(2, -1);
637
+ return [stack.shift()];
638
+ }, next: "formatString"},
639
+ formatMatcher,
640
+ {regex: /:[\?\-+]?/, onMatch: function(val, state, stack) {
641
+ if (val[1] == "+")
642
+ stack[0].ifEnd = stack[0];
643
+ if (val[1] == "?")
644
+ stack[0].expectElse = true;
645
+ }, next: "formatString"},
646
+ {regex: "([^:}\\\\]|\\\\.)*:?", token: "", next: "formatString"}
647
+ ]
648
+ });
649
+ return SnippetManager.$tokenizer;
650
+ };
651
+
652
+ this.tokenizeTmSnippet = function(str, startState) {
653
+ return this.getTokenizer().getLineTokens(str, startState).tokens.map(function(x) {
654
+ return x.value || x;
655
+ });
656
+ };
657
+
658
+ this.getVariableValue = function(editor, name, indentation) {
659
+ if (/^\d+$/.test(name))
660
+ return (this.variables.__ || {})[name] || "";
661
+ if (/^[A-Z]\d+$/.test(name))
662
+ return (this.variables[name[0] + "__"] || {})[name.substr(1)] || "";
663
+
664
+ name = name.replace(/^TM_/, "");
665
+ if (!this.variables.hasOwnProperty(name))
666
+ return "";
667
+ var value = this.variables[name];
668
+ if (typeof value == "function")
669
+ value = this.variables[name](editor, name, indentation);
670
+ return value == null ? "" : value;
671
+ };
672
+
673
+ this.variables = VARIABLES;
674
+ this.tmStrFormat = function(str, ch, editor) {
675
+ if (!ch.fmt) return str;
676
+ var flag = ch.flag || "";
677
+ var re = ch.guard;
678
+ re = new RegExp(re, flag.replace(/[^gim]/g, ""));
679
+ var fmtTokens = typeof ch.fmt == "string" ? this.tokenizeTmSnippet(ch.fmt, "formatString") : ch.fmt;
680
+ var _self = this;
681
+ var formatted = str.replace(re, function() {
682
+ var oldArgs = _self.variables.__;
683
+ _self.variables.__ = [].slice.call(arguments);
684
+ var fmtParts = _self.resolveVariables(fmtTokens, editor);
685
+ var gChangeCase = "E";
686
+ for (var i = 0; i < fmtParts.length; i++) {
687
+ var ch = fmtParts[i];
688
+ if (typeof ch == "object") {
689
+ fmtParts[i] = "";
690
+ if (ch.changeCase && ch.local) {
691
+ var next = fmtParts[i + 1];
692
+ if (next && typeof next == "string") {
693
+ if (ch.changeCase == "u")
694
+ fmtParts[i] = next[0].toUpperCase();
695
+ else
696
+ fmtParts[i] = next[0].toLowerCase();
697
+ fmtParts[i + 1] = next.substr(1);
698
+ }
699
+ } else if (ch.changeCase) {
700
+ gChangeCase = ch.changeCase;
701
+ }
702
+ } else if (gChangeCase == "U") {
703
+ fmtParts[i] = ch.toUpperCase();
704
+ } else if (gChangeCase == "L") {
705
+ fmtParts[i] = ch.toLowerCase();
706
+ }
707
+ }
708
+ _self.variables.__ = oldArgs;
709
+ return fmtParts.join("");
710
+ });
711
+ return formatted;
712
+ };
713
+
714
+ this.tmFormatFunction = function(str, ch, editor) {
715
+ if (ch.formatFunction == "upcase")
716
+ return str.toUpperCase();
717
+ if (ch.formatFunction == "downcase")
718
+ return str.toLowerCase();
719
+ return str;
720
+ };
721
+
722
+ this.resolveVariables = function(snippet, editor) {
723
+ var result = [];
724
+ var indentation = "";
725
+ var afterNewLine = true;
726
+ for (var i = 0; i < snippet.length; i++) {
727
+ var ch = snippet[i];
728
+ if (typeof ch == "string") {
729
+ result.push(ch);
730
+ if (ch == "\n") {
731
+ afterNewLine = true;
732
+ indentation = "";
733
+ }
734
+ else if (afterNewLine) {
735
+ indentation = /^\t*/.exec(ch)[0];
736
+ afterNewLine = /\S/.test(ch);
737
+ }
738
+ continue;
739
+ }
740
+ if (!ch) continue;
741
+ afterNewLine = false;
742
+
743
+ if (ch.fmtString) {
744
+ var j = snippet.indexOf(ch, i + 1);
745
+ if (j == -1) j = snippet.length;
746
+ ch.fmt = snippet.slice(i + 1, j);
747
+ i = j;
748
+ }
749
+
750
+ if (ch.text) {
751
+ var value = this.getVariableValue(editor, ch.text, indentation) + "";
752
+ if (ch.fmtString)
753
+ value = this.tmStrFormat(value, ch, editor);
754
+ if (ch.formatFunction)
755
+ value = this.tmFormatFunction(value, ch, editor);
756
+
757
+ if (value && !ch.ifEnd) {
758
+ result.push(value);
759
+ gotoNext(ch);
760
+ } else if (!value && ch.ifEnd) {
761
+ gotoNext(ch.ifEnd);
762
+ }
763
+ } else if (ch.elseEnd) {
764
+ gotoNext(ch.elseEnd);
765
+ } else if (ch.tabstopId != null) {
766
+ result.push(ch);
767
+ } else if (ch.changeCase != null) {
768
+ result.push(ch);
769
+ }
770
+ }
771
+ function gotoNext(ch) {
772
+ var i1 = snippet.indexOf(ch, i + 1);
773
+ if (i1 != -1)
774
+ i = i1;
775
+ }
776
+ return result;
777
+ };
778
+
779
+ this.insertSnippetForSelection = function(editor, snippetText) {
780
+ var cursor = editor.getCursorPosition();
781
+ var line = editor.session.getLine(cursor.row);
782
+ var tabString = editor.session.getTabString();
783
+ var indentString = line.match(/^\s*/)[0];
784
+
785
+ if (cursor.column < indentString.length)
786
+ indentString = indentString.slice(0, cursor.column);
787
+
788
+ snippetText = snippetText.replace(/\r/g, "");
789
+ var tokens = this.tokenizeTmSnippet(snippetText);
790
+ tokens = this.resolveVariables(tokens, editor);
791
+ tokens = tokens.map(function(x) {
792
+ if (x == "\n")
793
+ return x + indentString;
794
+ if (typeof x == "string")
795
+ return x.replace(/\t/g, tabString);
796
+ return x;
797
+ });
798
+ var tabstops = [];
799
+ tokens.forEach(function(p, i) {
800
+ if (typeof p != "object")
801
+ return;
802
+ var id = p.tabstopId;
803
+ var ts = tabstops[id];
804
+ if (!ts) {
805
+ ts = tabstops[id] = [];
806
+ ts.index = id;
807
+ ts.value = "";
808
+ ts.parents = {};
809
+ }
810
+ if (ts.indexOf(p) !== -1)
811
+ return;
812
+ if (p.choices && !ts.choices)
813
+ ts.choices = p.choices;
814
+ ts.push(p);
815
+ var i1 = tokens.indexOf(p, i + 1);
816
+ if (i1 === -1)
817
+ return;
818
+
819
+ var value = tokens.slice(i + 1, i1);
820
+ var isNested = value.some(function(t) {return typeof t === "object";});
821
+ if (isNested && !ts.value) {
822
+ ts.value = value;
823
+ } else if (value.length && (!ts.value || typeof ts.value !== "string")) {
824
+ ts.value = value.join("");
825
+ }
826
+ });
827
+ tabstops.forEach(function(ts) {ts.length = 0;});
828
+ var expanding = {};
829
+ function copyValue(val) {
830
+ var copy = [];
831
+ for (var i = 0; i < val.length; i++) {
832
+ var p = val[i];
833
+ if (typeof p == "object") {
834
+ if (expanding[p.tabstopId])
835
+ continue;
836
+ var j = val.lastIndexOf(p, i - 1);
837
+ p = copy[j] || {tabstopId: p.tabstopId};
838
+ }
839
+ copy[i] = p;
840
+ }
841
+ return copy;
842
+ }
843
+ for (var i = 0; i < tokens.length; i++) {
844
+ var p = tokens[i];
845
+ if (typeof p != "object")
846
+ continue;
847
+ var id = p.tabstopId;
848
+ var ts = tabstops[id];
849
+ var i1 = tokens.indexOf(p, i + 1);
850
+ if (expanding[id]) {
851
+ if (expanding[id] === p) {
852
+ delete expanding[id];
853
+ Object.keys(expanding).forEach(function(parentId) {
854
+ ts.parents[parentId] = true;
855
+ });
856
+ }
857
+ continue;
858
+ }
859
+ expanding[id] = p;
860
+ var value = ts.value;
861
+ if (typeof value !== "string")
862
+ value = copyValue(value);
863
+ else if (p.fmt)
864
+ value = this.tmStrFormat(value, p, editor);
865
+ tokens.splice.apply(tokens, [i + 1, Math.max(0, i1 - i)].concat(value, p));
866
+
867
+ if (ts.indexOf(p) === -1)
868
+ ts.push(p);
869
+ }
870
+ var row = 0, column = 0;
871
+ var text = "";
872
+ tokens.forEach(function(t) {
873
+ if (typeof t === "string") {
874
+ var lines = t.split("\n");
875
+ if (lines.length > 1){
876
+ column = lines[lines.length - 1].length;
877
+ row += lines.length - 1;
878
+ } else
879
+ column += t.length;
880
+ text += t;
881
+ } else if (t) {
882
+ if (!t.start)
883
+ t.start = {row: row, column: column};
884
+ else
885
+ t.end = {row: row, column: column};
886
+ }
887
+ });
888
+ var range = editor.getSelectionRange();
889
+ var end = editor.session.replace(range, text);
890
+
891
+ var tabstopManager = new TabstopManager(editor);
892
+ var selectionId = editor.inVirtualSelectionMode && editor.selection.index;
893
+ tabstopManager.addTabstops(tabstops, range.start, end, selectionId);
894
+ };
895
+
896
+ this.insertSnippet = function(editor, snippetText) {
897
+ var self = this;
898
+ if (editor.inVirtualSelectionMode)
899
+ return self.insertSnippetForSelection(editor, snippetText);
900
+
901
+ editor.forEachSelection(function() {
902
+ self.insertSnippetForSelection(editor, snippetText);
903
+ }, null, {keepOrder: true});
904
+
905
+ if (editor.tabstopManager)
906
+ editor.tabstopManager.tabNext();
907
+ };
908
+
909
+ this.$getScope = function(editor) {
910
+ var scope = editor.session.$mode.$id || "";
911
+ scope = scope.split("/").pop();
912
+ if (scope === "html" || scope === "php") {
913
+ if (scope === "php" && !editor.session.$mode.inlinePhp)
914
+ scope = "html";
915
+ var c = editor.getCursorPosition();
916
+ var state = editor.session.getState(c.row);
917
+ if (typeof state === "object") {
918
+ state = state[0];
919
+ }
920
+ if (state.substring) {
921
+ if (state.substring(0, 3) == "js-")
922
+ scope = "javascript";
923
+ else if (state.substring(0, 4) == "css-")
924
+ scope = "css";
925
+ else if (state.substring(0, 4) == "php-")
926
+ scope = "php";
927
+ }
928
+ }
929
+
930
+ return scope;
931
+ };
932
+
933
+ this.getActiveScopes = function(editor) {
934
+ var scope = this.$getScope(editor);
935
+ var scopes = [scope];
936
+ var snippetMap = this.snippetMap;
937
+ if (snippetMap[scope] && snippetMap[scope].includeScopes) {
938
+ scopes.push.apply(scopes, snippetMap[scope].includeScopes);
939
+ }
940
+ scopes.push("_");
941
+ return scopes;
942
+ };
943
+
944
+ this.expandWithTab = function(editor, options) {
945
+ var self = this;
946
+ var result = editor.forEachSelection(function() {
947
+ return self.expandSnippetForSelection(editor, options);
948
+ }, null, {keepOrder: true});
949
+ if (result && editor.tabstopManager)
950
+ editor.tabstopManager.tabNext();
951
+ return result;
952
+ };
953
+
954
+ this.expandSnippetForSelection = function(editor, options) {
955
+ var cursor = editor.getCursorPosition();
956
+ var line = editor.session.getLine(cursor.row);
957
+ var before = line.substring(0, cursor.column);
958
+ var after = line.substr(cursor.column);
959
+
960
+ var snippetMap = this.snippetMap;
961
+ var snippet;
962
+ this.getActiveScopes(editor).some(function(scope) {
963
+ var snippets = snippetMap[scope];
964
+ if (snippets)
965
+ snippet = this.findMatchingSnippet(snippets, before, after);
966
+ return !!snippet;
967
+ }, this);
968
+ if (!snippet)
969
+ return false;
970
+ if (options && options.dryRun)
971
+ return true;
972
+ editor.session.doc.removeInLine(cursor.row,
973
+ cursor.column - snippet.replaceBefore.length,
974
+ cursor.column + snippet.replaceAfter.length
975
+ );
976
+
977
+ this.variables.M__ = snippet.matchBefore;
978
+ this.variables.T__ = snippet.matchAfter;
979
+ this.insertSnippetForSelection(editor, snippet.content);
980
+
981
+ this.variables.M__ = this.variables.T__ = null;
982
+ return true;
983
+ };
984
+
985
+ this.findMatchingSnippet = function(snippetList, before, after) {
986
+ for (var i = snippetList.length; i--;) {
987
+ var s = snippetList[i];
988
+ if (s.startRe && !s.startRe.test(before))
989
+ continue;
990
+ if (s.endRe && !s.endRe.test(after))
991
+ continue;
992
+ if (!s.startRe && !s.endRe)
993
+ continue;
994
+
995
+ s.matchBefore = s.startRe ? s.startRe.exec(before) : [""];
996
+ s.matchAfter = s.endRe ? s.endRe.exec(after) : [""];
997
+ s.replaceBefore = s.triggerRe ? s.triggerRe.exec(before)[0] : "";
998
+ s.replaceAfter = s.endTriggerRe ? s.endTriggerRe.exec(after)[0] : "";
999
+ return s;
1000
+ }
1001
+ };
1002
+
1003
+ this.snippetMap = {};
1004
+ this.snippetNameMap = {};
1005
+ this.register = function(snippets, scope) {
1006
+ var snippetMap = this.snippetMap;
1007
+ var snippetNameMap = this.snippetNameMap;
1008
+ var self = this;
1009
+
1010
+ if (!snippets)
1011
+ snippets = [];
1012
+
1013
+ function wrapRegexp(src) {
1014
+ if (src && !/^\^?\(.*\)\$?$|^\\b$/.test(src))
1015
+ src = "(?:" + src + ")";
1016
+
1017
+ return src || "";
1018
+ }
1019
+ function guardedRegexp(re, guard, opening) {
1020
+ re = wrapRegexp(re);
1021
+ guard = wrapRegexp(guard);
1022
+ if (opening) {
1023
+ re = guard + re;
1024
+ if (re && re[re.length - 1] != "$")
1025
+ re = re + "$";
1026
+ } else {
1027
+ re = re + guard;
1028
+ if (re && re[0] != "^")
1029
+ re = "^" + re;
1030
+ }
1031
+ return new RegExp(re);
1032
+ }
1033
+
1034
+ function addSnippet(s) {
1035
+ if (!s.scope)
1036
+ s.scope = scope || "_";
1037
+ scope = s.scope;
1038
+ if (!snippetMap[scope]) {
1039
+ snippetMap[scope] = [];
1040
+ snippetNameMap[scope] = {};
1041
+ }
1042
+
1043
+ var map = snippetNameMap[scope];
1044
+ if (s.name) {
1045
+ var old = map[s.name];
1046
+ if (old)
1047
+ self.unregister(old);
1048
+ map[s.name] = s;
1049
+ }
1050
+ snippetMap[scope].push(s);
1051
+
1052
+ if (s.prefix)
1053
+ s.tabTrigger = s.prefix;
1054
+
1055
+ if (!s.content && s.body)
1056
+ s.content = Array.isArray(s.body) ? s.body.join("\n") : s.body;
1057
+
1058
+ if (s.tabTrigger && !s.trigger) {
1059
+ if (!s.guard && /^\w/.test(s.tabTrigger))
1060
+ s.guard = "\\b";
1061
+ s.trigger = lang.escapeRegExp(s.tabTrigger);
1062
+ }
1063
+
1064
+ if (!s.trigger && !s.guard && !s.endTrigger && !s.endGuard)
1065
+ return;
1066
+
1067
+ s.startRe = guardedRegexp(s.trigger, s.guard, true);
1068
+ s.triggerRe = new RegExp(s.trigger);
1069
+
1070
+ s.endRe = guardedRegexp(s.endTrigger, s.endGuard, true);
1071
+ s.endTriggerRe = new RegExp(s.endTrigger);
1072
+ }
1073
+
1074
+ if (Array.isArray(snippets)) {
1075
+ snippets.forEach(addSnippet);
1076
+ } else {
1077
+ Object.keys(snippets).forEach(function(key) {
1078
+ addSnippet(snippets[key]);
1079
+ });
1080
+ }
1081
+
1082
+ this._signal("registerSnippets", {scope: scope});
1083
+ };
1084
+ this.unregister = function(snippets, scope) {
1085
+ var snippetMap = this.snippetMap;
1086
+ var snippetNameMap = this.snippetNameMap;
1087
+
1088
+ function removeSnippet(s) {
1089
+ var nameMap = snippetNameMap[s.scope||scope];
1090
+ if (nameMap && nameMap[s.name]) {
1091
+ delete nameMap[s.name];
1092
+ var map = snippetMap[s.scope||scope];
1093
+ var i = map && map.indexOf(s);
1094
+ if (i >= 0)
1095
+ map.splice(i, 1);
1096
+ }
1097
+ }
1098
+ if (snippets.content)
1099
+ removeSnippet(snippets);
1100
+ else if (Array.isArray(snippets))
1101
+ snippets.forEach(removeSnippet);
1102
+ };
1103
+ this.parseSnippetFile = function(str) {
1104
+ str = str.replace(/\r/g, "");
1105
+ var list = [], snippet = {};
1106
+ var re = /^#.*|^({[\s\S]*})\s*$|^(\S+) (.*)$|^((?:\n*\t.*)+)/gm;
1107
+ var m;
1108
+ while (m = re.exec(str)) {
1109
+ if (m[1]) {
1110
+ try {
1111
+ snippet = JSON.parse(m[1]);
1112
+ list.push(snippet);
1113
+ } catch (e) {}
1114
+ } if (m[4]) {
1115
+ snippet.content = m[4].replace(/^\t/gm, "");
1116
+ list.push(snippet);
1117
+ snippet = {};
1118
+ } else {
1119
+ var key = m[2], val = m[3];
1120
+ if (key == "regex") {
1121
+ var guardRe = /\/((?:[^\/\\]|\\.)*)|$/g;
1122
+ snippet.guard = guardRe.exec(val)[1];
1123
+ snippet.trigger = guardRe.exec(val)[1];
1124
+ snippet.endTrigger = guardRe.exec(val)[1];
1125
+ snippet.endGuard = guardRe.exec(val)[1];
1126
+ } else if (key == "snippet") {
1127
+ snippet.tabTrigger = val.match(/^\S*/)[0];
1128
+ if (!snippet.name)
1129
+ snippet.name = val;
1130
+ } else if (key) {
1131
+ snippet[key] = val;
1132
+ }
1133
+ }
1134
+ }
1135
+ return list;
1136
+ };
1137
+ this.getSnippetByName = function(name, editor) {
1138
+ var snippetMap = this.snippetNameMap;
1139
+ var snippet;
1140
+ this.getActiveScopes(editor).some(function(scope) {
1141
+ var snippets = snippetMap[scope];
1142
+ if (snippets)
1143
+ snippet = snippets[name];
1144
+ return !!snippet;
1145
+ }, this);
1146
+ return snippet;
1147
+ };
1148
+
1149
+ }).call(SnippetManager.prototype);
1150
+
1151
+
1152
+ var TabstopManager = function(editor) {
1153
+ if (editor.tabstopManager)
1154
+ return editor.tabstopManager;
1155
+ editor.tabstopManager = this;
1156
+ this.$onChange = this.onChange.bind(this);
1157
+ this.$onChangeSelection = lang.delayedCall(this.onChangeSelection.bind(this)).schedule;
1158
+ this.$onChangeSession = this.onChangeSession.bind(this);
1159
+ this.$onAfterExec = this.onAfterExec.bind(this);
1160
+ this.attach(editor);
1161
+ };
1162
+ (function() {
1163
+ this.attach = function(editor) {
1164
+ this.index = 0;
1165
+ this.ranges = [];
1166
+ this.tabstops = [];
1167
+ this.$openTabstops = null;
1168
+ this.selectedTabstop = null;
1169
+
1170
+ this.editor = editor;
1171
+ this.editor.on("change", this.$onChange);
1172
+ this.editor.on("changeSelection", this.$onChangeSelection);
1173
+ this.editor.on("changeSession", this.$onChangeSession);
1174
+ this.editor.commands.on("afterExec", this.$onAfterExec);
1175
+ this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
1176
+ };
1177
+ this.detach = function() {
1178
+ this.tabstops.forEach(this.removeTabstopMarkers, this);
1179
+ this.ranges = null;
1180
+ this.tabstops = null;
1181
+ this.selectedTabstop = null;
1182
+ this.editor.removeListener("change", this.$onChange);
1183
+ this.editor.removeListener("changeSelection", this.$onChangeSelection);
1184
+ this.editor.removeListener("changeSession", this.$onChangeSession);
1185
+ this.editor.commands.removeListener("afterExec", this.$onAfterExec);
1186
+ this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
1187
+ this.editor.tabstopManager = null;
1188
+ this.editor = null;
1189
+ };
1190
+
1191
+ this.onChange = function(delta) {
1192
+ var isRemove = delta.action[0] == "r";
1193
+ var selectedTabstop = this.selectedTabstop || {};
1194
+ var parents = selectedTabstop.parents || {};
1195
+ var tabstops = (this.tabstops || []).slice();
1196
+ for (var i = 0; i < tabstops.length; i++) {
1197
+ var ts = tabstops[i];
1198
+ var active = ts == selectedTabstop || parents[ts.index];
1199
+ ts.rangeList.$bias = active ? 0 : 1;
1200
+
1201
+ if (delta.action == "remove" && ts !== selectedTabstop) {
1202
+ var parentActive = ts.parents && ts.parents[selectedTabstop.index];
1203
+ var startIndex = ts.rangeList.pointIndex(delta.start, parentActive);
1204
+ startIndex = startIndex < 0 ? -startIndex - 1 : startIndex + 1;
1205
+ var endIndex = ts.rangeList.pointIndex(delta.end, parentActive);
1206
+ endIndex = endIndex < 0 ? -endIndex - 1 : endIndex - 1;
1207
+ var toRemove = ts.rangeList.ranges.slice(startIndex, endIndex);
1208
+ for (var j = 0; j < toRemove.length; j++)
1209
+ this.removeRange(toRemove[j]);
1210
+ }
1211
+ ts.rangeList.$onChange(delta);
1212
+ }
1213
+ var session = this.editor.session;
1214
+ if (!this.$inChange && isRemove && session.getLength() == 1 && !session.getValue())
1215
+ this.detach();
1216
+ };
1217
+ this.updateLinkedFields = function() {
1218
+ var ts = this.selectedTabstop;
1219
+ if (!ts || !ts.hasLinkedRanges || !ts.firstNonLinked)
1220
+ return;
1221
+ this.$inChange = true;
1222
+ var session = this.editor.session;
1223
+ var text = session.getTextRange(ts.firstNonLinked);
1224
+ for (var i = 0; i < ts.length; i++) {
1225
+ var range = ts[i];
1226
+ if (!range.linked)
1227
+ continue;
1228
+ var original = range.original;
1229
+ var fmt = exports.snippetManager.tmStrFormat(text, original, this.editor);
1230
+ session.replace(range, fmt);
1231
+ }
1232
+ this.$inChange = false;
1233
+ };
1234
+ this.onAfterExec = function(e) {
1235
+ if (e.command && !e.command.readOnly)
1236
+ this.updateLinkedFields();
1237
+ };
1238
+ this.onChangeSelection = function() {
1239
+ if (!this.editor)
1240
+ return;
1241
+ var lead = this.editor.selection.lead;
1242
+ var anchor = this.editor.selection.anchor;
1243
+ var isEmpty = this.editor.selection.isEmpty();
1244
+ for (var i = 0; i < this.ranges.length; i++) {
1245
+ if (this.ranges[i].linked)
1246
+ continue;
1247
+ var containsLead = this.ranges[i].contains(lead.row, lead.column);
1248
+ var containsAnchor = isEmpty || this.ranges[i].contains(anchor.row, anchor.column);
1249
+ if (containsLead && containsAnchor)
1250
+ return;
1251
+ }
1252
+ this.detach();
1253
+ };
1254
+ this.onChangeSession = function() {
1255
+ this.detach();
1256
+ };
1257
+ this.tabNext = function(dir) {
1258
+ var max = this.tabstops.length;
1259
+ var index = this.index + (dir || 1);
1260
+ index = Math.min(Math.max(index, 1), max);
1261
+ if (index == max)
1262
+ index = 0;
1263
+ this.selectTabstop(index);
1264
+ if (index === 0)
1265
+ this.detach();
1266
+ };
1267
+ this.selectTabstop = function(index) {
1268
+ this.$openTabstops = null;
1269
+ var ts = this.tabstops[this.index];
1270
+ if (ts)
1271
+ this.addTabstopMarkers(ts);
1272
+ this.index = index;
1273
+ ts = this.tabstops[this.index];
1274
+ if (!ts || !ts.length)
1275
+ return;
1276
+
1277
+ this.selectedTabstop = ts;
1278
+ var range = ts.firstNonLinked || ts;
1279
+ if (ts.choices) range.cursor = range.start;
1280
+ if (!this.editor.inVirtualSelectionMode) {
1281
+ var sel = this.editor.multiSelect;
1282
+ sel.toSingleRange(range);
1283
+ for (var i = 0; i < ts.length; i++) {
1284
+ if (ts.hasLinkedRanges && ts[i].linked)
1285
+ continue;
1286
+ sel.addRange(ts[i].clone(), true);
1287
+ }
1288
+ } else {
1289
+ this.editor.selection.fromOrientedRange(range);
1290
+ }
1291
+
1292
+ this.editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
1293
+ if (this.selectedTabstop && this.selectedTabstop.choices)
1294
+ this.editor.execCommand("startAutocomplete", {matches: this.selectedTabstop.choices});
1295
+ };
1296
+ this.addTabstops = function(tabstops, start, end) {
1297
+ var useLink = this.useLink || !this.editor.getOption("enableMultiselect");
1298
+
1299
+ if (!this.$openTabstops)
1300
+ this.$openTabstops = [];
1301
+ if (!tabstops[0]) {
1302
+ var p = Range.fromPoints(end, end);
1303
+ moveRelative(p.start, start);
1304
+ moveRelative(p.end, start);
1305
+ tabstops[0] = [p];
1306
+ tabstops[0].index = 0;
1307
+ }
1308
+
1309
+ var i = this.index;
1310
+ var arg = [i + 1, 0];
1311
+ var ranges = this.ranges;
1312
+ tabstops.forEach(function(ts, index) {
1313
+ var dest = this.$openTabstops[index] || ts;
1314
+
1315
+ for (var i = 0; i < ts.length; i++) {
1316
+ var p = ts[i];
1317
+ var range = Range.fromPoints(p.start, p.end || p.start);
1318
+ movePoint(range.start, start);
1319
+ movePoint(range.end, start);
1320
+ range.original = p;
1321
+ range.tabstop = dest;
1322
+ ranges.push(range);
1323
+ if (dest != ts)
1324
+ dest.unshift(range);
1325
+ else
1326
+ dest[i] = range;
1327
+ if (p.fmtString || (dest.firstNonLinked && useLink)) {
1328
+ range.linked = true;
1329
+ dest.hasLinkedRanges = true;
1330
+ } else if (!dest.firstNonLinked)
1331
+ dest.firstNonLinked = range;
1332
+ }
1333
+ if (!dest.firstNonLinked)
1334
+ dest.hasLinkedRanges = false;
1335
+ if (dest === ts) {
1336
+ arg.push(dest);
1337
+ this.$openTabstops[index] = dest;
1338
+ }
1339
+ this.addTabstopMarkers(dest);
1340
+ dest.rangeList = dest.rangeList || new RangeList();
1341
+ dest.rangeList.$bias = 0;
1342
+ dest.rangeList.addList(dest);
1343
+ }, this);
1344
+
1345
+ if (arg.length > 2) {
1346
+ if (this.tabstops.length)
1347
+ arg.push(arg.splice(2, 1)[0]);
1348
+ this.tabstops.splice.apply(this.tabstops, arg);
1349
+ }
1350
+ };
1351
+
1352
+ this.addTabstopMarkers = function(ts) {
1353
+ var session = this.editor.session;
1354
+ ts.forEach(function(range) {
1355
+ if (!range.markerId)
1356
+ range.markerId = session.addMarker(range, "ace_snippet-marker", "text");
1357
+ });
1358
+ };
1359
+ this.removeTabstopMarkers = function(ts) {
1360
+ var session = this.editor.session;
1361
+ ts.forEach(function(range) {
1362
+ session.removeMarker(range.markerId);
1363
+ range.markerId = null;
1364
+ });
1365
+ };
1366
+ this.removeRange = function(range) {
1367
+ var i = range.tabstop.indexOf(range);
1368
+ if (i != -1) range.tabstop.splice(i, 1);
1369
+ i = this.ranges.indexOf(range);
1370
+ if (i != -1) this.ranges.splice(i, 1);
1371
+ i = range.tabstop.rangeList.ranges.indexOf(range);
1372
+ if (i != -1) range.tabstop.splice(i, 1);
1373
+ this.editor.session.removeMarker(range.markerId);
1374
+ if (!range.tabstop.length) {
1375
+ i = this.tabstops.indexOf(range.tabstop);
1376
+ if (i != -1)
1377
+ this.tabstops.splice(i, 1);
1378
+ if (!this.tabstops.length)
1379
+ this.detach();
1380
+ }
1381
+ };
1382
+
1383
+ this.keyboardHandler = new HashHandler();
1384
+ this.keyboardHandler.bindKeys({
1385
+ "Tab": function(editor) {
1386
+ if (exports.snippetManager && exports.snippetManager.expandWithTab(editor))
1387
+ return;
1388
+ editor.tabstopManager.tabNext(1);
1389
+ editor.renderer.scrollCursorIntoView();
1390
+ },
1391
+ "Shift-Tab": function(editor) {
1392
+ editor.tabstopManager.tabNext(-1);
1393
+ editor.renderer.scrollCursorIntoView();
1394
+ },
1395
+ "Esc": function(editor) {
1396
+ editor.tabstopManager.detach();
1397
+ }
1398
+ });
1399
+ }).call(TabstopManager.prototype);
1400
+
1401
+
1402
+
1403
+ var movePoint = function(point, diff) {
1404
+ if (point.row == 0)
1405
+ point.column += diff.column;
1406
+ point.row += diff.row;
1407
+ };
1408
+
1409
+ var moveRelative = function(point, start) {
1410
+ if (point.row == start.row)
1411
+ point.column -= start.column;
1412
+ point.row -= start.row;
1413
+ };
1414
+
1415
+
1416
+ require("./lib/dom").importCssString("\
1417
+ .ace_snippet-marker {\
1418
+ -moz-box-sizing: border-box;\
1419
+ box-sizing: border-box;\
1420
+ background: rgba(194, 193, 208, 0.09);\
1421
+ border: 1px dotted rgba(211, 208, 235, 0.62);\
1422
+ position: absolute;\
1423
+ }");
1424
+
1425
+ exports.snippetManager = new SnippetManager();
1426
+
1427
+
1428
+ var Editor = require("./editor").Editor;
1429
+ (function() {
1430
+ this.insertSnippet = function(content, options) {
1431
+ return exports.snippetManager.insertSnippet(this, content, options);
1432
+ };
1433
+ this.expandSnippet = function(options) {
1434
+ return exports.snippetManager.expandWithTab(this, options);
1435
+ };
1436
+ }).call(Editor.prototype);
1437
+
1438
+ });
1439
+
1440
+ ace.define("ace/autocomplete",["require","exports","module","ace/keyboard/hash_handler","ace/autocomplete/popup","ace/autocomplete/util","ace/lib/lang","ace/lib/dom","ace/snippets","ace/config"], function(require, exports, module) {
1441
+ "use strict";
1442
+
1443
+ var HashHandler = require("./keyboard/hash_handler").HashHandler;
1444
+ var AcePopup = require("./autocomplete/popup").AcePopup;
1445
+ var util = require("./autocomplete/util");
1446
+ var lang = require("./lib/lang");
1447
+ var dom = require("./lib/dom");
1448
+ var snippetManager = require("./snippets").snippetManager;
1449
+ var config = require("./config");
1450
+
1451
+ var Autocomplete = function() {
1452
+ this.autoInsert = false;
1453
+ this.autoSelect = true;
1454
+ this.exactMatch = false;
1455
+ this.gatherCompletionsId = 0;
1456
+ this.keyboardHandler = new HashHandler();
1457
+ this.keyboardHandler.bindKeys(this.commands);
1458
+
1459
+ this.blurListener = this.blurListener.bind(this);
1460
+ this.changeListener = this.changeListener.bind(this);
1461
+ this.mousedownListener = this.mousedownListener.bind(this);
1462
+ this.mousewheelListener = this.mousewheelListener.bind(this);
1463
+
1464
+ this.changeTimer = lang.delayedCall(function() {
1465
+ this.updateCompletions(true);
1466
+ }.bind(this));
1467
+
1468
+ this.tooltipTimer = lang.delayedCall(this.updateDocTooltip.bind(this), 50);
1469
+ };
1470
+
1471
+ (function() {
1472
+
1473
+ this.$init = function() {
1474
+ this.popup = new AcePopup(document.body || document.documentElement);
1475
+ this.popup.on("click", function(e) {
1476
+ this.insertMatch();
1477
+ e.stop();
1478
+ }.bind(this));
1479
+ this.popup.focus = this.editor.focus.bind(this.editor);
1480
+ this.popup.on("show", this.tooltipTimer.bind(null, null));
1481
+ this.popup.on("select", this.tooltipTimer.bind(null, null));
1482
+ this.popup.on("changeHoverMarker", this.tooltipTimer.bind(null, null));
1483
+ return this.popup;
1484
+ };
1485
+
1486
+ this.getPopup = function() {
1487
+ return this.popup || this.$init();
1488
+ };
1489
+
1490
+ this.openPopup = function(editor, prefix, keepPopupPosition) {
1491
+ if (!this.popup)
1492
+ this.$init();
1493
+
1494
+ this.popup.autoSelect = this.autoSelect;
1495
+
1496
+ this.popup.setData(this.completions.filtered, this.completions.filterText);
1497
+
1498
+ editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
1499
+
1500
+ var renderer = editor.renderer;
1501
+ this.popup.setRow(this.autoSelect ? 0 : -1);
1502
+ if (!keepPopupPosition) {
1503
+ this.popup.setTheme(editor.getTheme());
1504
+ this.popup.setFontSize(editor.getFontSize());
1505
+
1506
+ var lineHeight = renderer.layerConfig.lineHeight;
1507
+
1508
+ var pos = renderer.$cursorLayer.getPixelPosition(this.base, true);
1509
+ pos.left -= this.popup.getTextLeftOffset();
1510
+
1511
+ var rect = editor.container.getBoundingClientRect();
1512
+ pos.top += rect.top - renderer.layerConfig.offset;
1513
+ pos.left += rect.left - editor.renderer.scrollLeft;
1514
+ pos.left += renderer.gutterWidth;
1515
+
1516
+ this.popup.show(pos, lineHeight);
1517
+ } else if (keepPopupPosition && !prefix) {
1518
+ this.detach();
1519
+ }
1520
+ this.changeTimer.cancel();
1521
+ };
1522
+
1523
+ this.detach = function() {
1524
+ this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
1525
+ this.editor.off("changeSelection", this.changeListener);
1526
+ this.editor.off("blur", this.blurListener);
1527
+ this.editor.off("mousedown", this.mousedownListener);
1528
+ this.editor.off("mousewheel", this.mousewheelListener);
1529
+ this.changeTimer.cancel();
1530
+ this.hideDocTooltip();
1531
+
1532
+ this.gatherCompletionsId += 1;
1533
+ if (this.popup && this.popup.isOpen)
1534
+ this.popup.hide();
1535
+
1536
+ if (this.base)
1537
+ this.base.detach();
1538
+ this.activated = false;
1539
+ this.completions = this.base = null;
1540
+ };
1541
+
1542
+ this.changeListener = function(e) {
1543
+ var cursor = this.editor.selection.lead;
1544
+ if (cursor.row != this.base.row || cursor.column < this.base.column) {
1545
+ this.detach();
1546
+ }
1547
+ if (this.activated)
1548
+ this.changeTimer.schedule();
1549
+ else
1550
+ this.detach();
1551
+ };
1552
+
1553
+ this.blurListener = function(e) {
1554
+ var el = document.activeElement;
1555
+ var text = this.editor.textInput.getElement();
1556
+ var fromTooltip = e.relatedTarget && this.tooltipNode && this.tooltipNode.contains(e.relatedTarget);
1557
+ var container = this.popup && this.popup.container;
1558
+ if (el != text && el.parentNode != container && !fromTooltip
1559
+ && el != this.tooltipNode && e.relatedTarget != text
1560
+ ) {
1561
+ this.detach();
1562
+ }
1563
+ };
1564
+
1565
+ this.mousedownListener = function(e) {
1566
+ this.detach();
1567
+ };
1568
+
1569
+ this.mousewheelListener = function(e) {
1570
+ this.detach();
1571
+ };
1572
+
1573
+ this.goTo = function(where) {
1574
+ this.popup.goTo(where);
1575
+ };
1576
+
1577
+ this.insertMatch = function(data, options) {
1578
+ if (!data)
1579
+ data = this.popup.getData(this.popup.getRow());
1580
+ if (!data)
1581
+ return false;
1582
+
1583
+ var completions = this.completions;
1584
+ this.editor.startOperation({command: {name: "insertMatch"}});
1585
+ if (data.completer && data.completer.insertMatch) {
1586
+ data.completer.insertMatch(this.editor, data);
1587
+ } else {
1588
+ if (completions.filterText) {
1589
+ var ranges = this.editor.selection.getAllRanges();
1590
+ for (var i = 0, range; range = ranges[i]; i++) {
1591
+ range.start.column -= completions.filterText.length;
1592
+ this.editor.session.remove(range);
1593
+ }
1594
+ }
1595
+ if (data.snippet)
1596
+ snippetManager.insertSnippet(this.editor, data.snippet);
1597
+ else
1598
+ this.editor.execCommand("insertstring", data.value || data);
1599
+ }
1600
+ if (this.completions == completions)
1601
+ this.detach();
1602
+ this.editor.endOperation();
1603
+ };
1604
+
1605
+
1606
+ this.commands = {
1607
+ "Up": function(editor) { editor.completer.goTo("up"); },
1608
+ "Down": function(editor) { editor.completer.goTo("down"); },
1609
+ "Ctrl-Up|Ctrl-Home": function(editor) { editor.completer.goTo("start"); },
1610
+ "Ctrl-Down|Ctrl-End": function(editor) { editor.completer.goTo("end"); },
1611
+
1612
+ "Esc": function(editor) { editor.completer.detach(); },
1613
+ "Return": function(editor) { return editor.completer.insertMatch(); },
1614
+ "Shift-Return": function(editor) { editor.completer.insertMatch(null, {deleteSuffix: true}); },
1615
+ "Tab": function(editor) {
1616
+ var result = editor.completer.insertMatch();
1617
+ if (!result && !editor.tabstopManager)
1618
+ editor.completer.goTo("down");
1619
+ else
1620
+ return result;
1621
+ },
1622
+
1623
+ "PageUp": function(editor) { editor.completer.popup.gotoPageUp(); },
1624
+ "PageDown": function(editor) { editor.completer.popup.gotoPageDown(); }
1625
+ };
1626
+
1627
+ this.gatherCompletions = function(editor, callback) {
1628
+ var session = editor.getSession();
1629
+ var pos = editor.getCursorPosition();
1630
+
1631
+ var prefix = util.getCompletionPrefix(editor);
1632
+
1633
+ this.base = session.doc.createAnchor(pos.row, pos.column - prefix.length);
1634
+ this.base.$insertRight = true;
1635
+
1636
+ var matches = [];
1637
+ var total = editor.completers.length;
1638
+ editor.completers.forEach(function(completer, i) {
1639
+ completer.getCompletions(editor, session, pos, prefix, function(err, results) {
1640
+ if (!err && results)
1641
+ matches = matches.concat(results);
1642
+ callback(null, {
1643
+ prefix: util.getCompletionPrefix(editor),
1644
+ matches: matches,
1645
+ finished: (--total === 0)
1646
+ });
1647
+ });
1648
+ });
1649
+ return true;
1650
+ };
1651
+
1652
+ this.showPopup = function(editor, options) {
1653
+ if (this.editor)
1654
+ this.detach();
1655
+
1656
+ this.activated = true;
1657
+
1658
+ this.editor = editor;
1659
+ if (editor.completer != this) {
1660
+ if (editor.completer)
1661
+ editor.completer.detach();
1662
+ editor.completer = this;
1663
+ }
1664
+
1665
+ editor.on("changeSelection", this.changeListener);
1666
+ editor.on("blur", this.blurListener);
1667
+ editor.on("mousedown", this.mousedownListener);
1668
+ editor.on("mousewheel", this.mousewheelListener);
1669
+
1670
+ this.updateCompletions(false, options);
1671
+ };
1672
+
1673
+ this.updateCompletions = function(keepPopupPosition, options) {
1674
+ if (keepPopupPosition && this.base && this.completions) {
1675
+ var pos = this.editor.getCursorPosition();
1676
+ var prefix = this.editor.session.getTextRange({start: this.base, end: pos});
1677
+ if (prefix == this.completions.filterText)
1678
+ return;
1679
+ this.completions.setFilter(prefix);
1680
+ if (!this.completions.filtered.length)
1681
+ return this.detach();
1682
+ if (this.completions.filtered.length == 1
1683
+ && this.completions.filtered[0].value == prefix
1684
+ && !this.completions.filtered[0].snippet)
1685
+ return this.detach();
1686
+ this.openPopup(this.editor, prefix, keepPopupPosition);
1687
+ return;
1688
+ }
1689
+
1690
+ if (options && options.matches) {
1691
+ var pos = this.editor.getSelectionRange().start;
1692
+ this.base = this.editor.session.doc.createAnchor(pos.row, pos.column);
1693
+ this.base.$insertRight = true;
1694
+ this.completions = new FilteredList(options.matches);
1695
+ return this.openPopup(this.editor, "", keepPopupPosition);
1696
+ }
1697
+ var _id = this.gatherCompletionsId;
1698
+ this.gatherCompletions(this.editor, function(err, results) {
1699
+ var detachIfFinished = function() {
1700
+ if (!results.finished) return;
1701
+ return this.detach();
1702
+ }.bind(this);
1703
+
1704
+ var prefix = results.prefix;
1705
+ var matches = results && results.matches;
1706
+
1707
+ if (!matches || !matches.length)
1708
+ return detachIfFinished();
1709
+ if (prefix.indexOf(results.prefix) !== 0 || _id != this.gatherCompletionsId)
1710
+ return;
1711
+
1712
+ this.completions = new FilteredList(matches);
1713
+
1714
+ if (this.exactMatch)
1715
+ this.completions.exactMatch = true;
1716
+
1717
+ this.completions.setFilter(prefix);
1718
+ var filtered = this.completions.filtered;
1719
+ if (!filtered.length)
1720
+ return detachIfFinished();
1721
+ if (filtered.length == 1 && filtered[0].value == prefix && !filtered[0].snippet)
1722
+ return detachIfFinished();
1723
+ if (this.autoInsert && filtered.length == 1 && results.finished)
1724
+ return this.insertMatch(filtered[0]);
1725
+
1726
+ this.openPopup(this.editor, prefix, keepPopupPosition);
1727
+ }.bind(this));
1728
+ };
1729
+
1730
+ this.cancelContextMenu = function() {
1731
+ this.editor.$mouseHandler.cancelContextMenu();
1732
+ };
1733
+
1734
+ this.updateDocTooltip = function() {
1735
+ var popup = this.popup;
1736
+ var all = popup.data;
1737
+ var selected = all && (all[popup.getHoveredRow()] || all[popup.getRow()]);
1738
+ var doc = null;
1739
+ if (!selected || !this.editor || !this.popup.isOpen)
1740
+ return this.hideDocTooltip();
1741
+ this.editor.completers.some(function(completer) {
1742
+ if (completer.getDocTooltip)
1743
+ doc = completer.getDocTooltip(selected);
1744
+ return doc;
1745
+ });
1746
+ if (!doc && typeof selected != "string")
1747
+ doc = selected;
1748
+
1749
+ if (typeof doc == "string")
1750
+ doc = {docText: doc};
1751
+ if (!doc || !(doc.docHTML || doc.docText))
1752
+ return this.hideDocTooltip();
1753
+ this.showDocTooltip(doc);
1754
+ };
1755
+
1756
+ this.showDocTooltip = function(item) {
1757
+ if (!this.tooltipNode) {
1758
+ this.tooltipNode = dom.createElement("div");
1759
+ this.tooltipNode.className = "ace_tooltip ace_doc-tooltip";
1760
+ this.tooltipNode.style.margin = 0;
1761
+ this.tooltipNode.style.pointerEvents = "auto";
1762
+ this.tooltipNode.tabIndex = -1;
1763
+ this.tooltipNode.onblur = this.blurListener.bind(this);
1764
+ this.tooltipNode.onclick = this.onTooltipClick.bind(this);
1765
+ }
1766
+
1767
+ var tooltipNode = this.tooltipNode;
1768
+ if (item.docHTML) {
1769
+ tooltipNode.innerHTML = item.docHTML;
1770
+ } else if (item.docText) {
1771
+ tooltipNode.textContent = item.docText;
1772
+ }
1773
+
1774
+ if (!tooltipNode.parentNode)
1775
+ document.body.appendChild(tooltipNode);
1776
+ var popup = this.popup;
1777
+ var rect = popup.container.getBoundingClientRect();
1778
+ tooltipNode.style.top = popup.container.style.top;
1779
+ tooltipNode.style.bottom = popup.container.style.bottom;
1780
+
1781
+ tooltipNode.style.display = "block";
1782
+ if (window.innerWidth - rect.right < 320) {
1783
+ if (rect.left < 320) {
1784
+ if(popup.isTopdown) {
1785
+ tooltipNode.style.top = rect.bottom + "px";
1786
+ tooltipNode.style.left = rect.left + "px";
1787
+ tooltipNode.style.right = "";
1788
+ tooltipNode.style.bottom = "";
1789
+ } else {
1790
+ tooltipNode.style.top = popup.container.offsetTop - tooltipNode.offsetHeight + "px";
1791
+ tooltipNode.style.left = rect.left + "px";
1792
+ tooltipNode.style.right = "";
1793
+ tooltipNode.style.bottom = "";
1794
+ }
1795
+ } else {
1796
+ tooltipNode.style.right = window.innerWidth - rect.left + "px";
1797
+ tooltipNode.style.left = "";
1798
+ }
1799
+ } else {
1800
+ tooltipNode.style.left = (rect.right + 1) + "px";
1801
+ tooltipNode.style.right = "";
1802
+ }
1803
+ };
1804
+
1805
+ this.hideDocTooltip = function() {
1806
+ this.tooltipTimer.cancel();
1807
+ if (!this.tooltipNode) return;
1808
+ var el = this.tooltipNode;
1809
+ if (!this.editor.isFocused() && document.activeElement == el)
1810
+ this.editor.focus();
1811
+ this.tooltipNode = null;
1812
+ if (el.parentNode)
1813
+ el.parentNode.removeChild(el);
1814
+ };
1815
+
1816
+ this.onTooltipClick = function(e) {
1817
+ var a = e.target;
1818
+ while (a && a != this.tooltipNode) {
1819
+ if (a.nodeName == "A" && a.href) {
1820
+ a.rel = "noreferrer";
1821
+ a.target = "_blank";
1822
+ break;
1823
+ }
1824
+ a = a.parentNode;
1825
+ }
1826
+ };
1827
+
1828
+ this.destroy = function() {
1829
+ this.detach();
1830
+ if (this.popup) {
1831
+ this.popup.destroy();
1832
+ var el = this.popup.container;
1833
+ if (el && el.parentNode)
1834
+ el.parentNode.removeChild(el);
1835
+ }
1836
+ if (this.editor && this.editor.completer == this)
1837
+ this.editor.completer == null;
1838
+ this.popup = null;
1839
+ };
1840
+
1841
+ }).call(Autocomplete.prototype);
1842
+
1843
+
1844
+ Autocomplete.for = function(editor) {
1845
+ if (editor.completer) {
1846
+ return editor.completer;
1847
+ }
1848
+ if (config.get("sharedPopups")) {
1849
+ if (!Autocomplete.$shared)
1850
+ Autocomplete.$sharedInstance = new Autocomplete();
1851
+ editor.completer = Autocomplete.$sharedInstance;
1852
+ } else {
1853
+ editor.completer = new Autocomplete();
1854
+ editor.once("destroy", function(e, editor) {
1855
+ editor.completer.destroy();
1856
+ });
1857
+ }
1858
+ return editor.completer;
1859
+ };
1860
+
1861
+ Autocomplete.startCommand = {
1862
+ name: "startAutocomplete",
1863
+ exec: function(editor, options) {
1864
+ var completer = Autocomplete.for(editor);
1865
+ completer.autoInsert = false;
1866
+ completer.autoSelect = true;
1867
+ completer.showPopup(editor, options);
1868
+ completer.cancelContextMenu();
1869
+ },
1870
+ bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space"
1871
+ };
1872
+
1873
+ var FilteredList = function(array, filterText) {
1874
+ this.all = array;
1875
+ this.filtered = array;
1876
+ this.filterText = filterText || "";
1877
+ this.exactMatch = false;
1878
+ };
1879
+ (function(){
1880
+ this.setFilter = function(str) {
1881
+ if (str.length > this.filterText && str.lastIndexOf(this.filterText, 0) === 0)
1882
+ var matches = this.filtered;
1883
+ else
1884
+ var matches = this.all;
1885
+
1886
+ this.filterText = str;
1887
+ matches = this.filterCompletions(matches, this.filterText);
1888
+ matches = matches.sort(function(a, b) {
1889
+ return b.exactMatch - a.exactMatch || b.$score - a.$score
1890
+ || (a.caption || a.value).localeCompare(b.caption || b.value);
1891
+ });
1892
+ var prev = null;
1893
+ matches = matches.filter(function(item){
1894
+ var caption = item.snippet || item.caption || item.value;
1895
+ if (caption === prev) return false;
1896
+ prev = caption;
1897
+ return true;
1898
+ });
1899
+
1900
+ this.filtered = matches;
1901
+ };
1902
+ this.filterCompletions = function(items, needle) {
1903
+ var results = [];
1904
+ var upper = needle.toUpperCase();
1905
+ var lower = needle.toLowerCase();
1906
+ loop: for (var i = 0, item; item = items[i]; i++) {
1907
+ var caption = item.caption || item.value || item.snippet;
1908
+ if (!caption) continue;
1909
+ var lastIndex = -1;
1910
+ var matchMask = 0;
1911
+ var penalty = 0;
1912
+ var index, distance;
1913
+
1914
+ if (this.exactMatch) {
1915
+ if (needle !== caption.substr(0, needle.length))
1916
+ continue loop;
1917
+ } else {
1918
+ var fullMatchIndex = caption.toLowerCase().indexOf(lower);
1919
+ if (fullMatchIndex > -1) {
1920
+ penalty = fullMatchIndex;
1921
+ } else {
1922
+ for (var j = 0; j < needle.length; j++) {
1923
+ var i1 = caption.indexOf(lower[j], lastIndex + 1);
1924
+ var i2 = caption.indexOf(upper[j], lastIndex + 1);
1925
+ index = (i1 >= 0) ? ((i2 < 0 || i1 < i2) ? i1 : i2) : i2;
1926
+ if (index < 0)
1927
+ continue loop;
1928
+ distance = index - lastIndex - 1;
1929
+ if (distance > 0) {
1930
+ if (lastIndex === -1)
1931
+ penalty += 10;
1932
+ penalty += distance;
1933
+ matchMask = matchMask | (1 << j);
1934
+ }
1935
+ lastIndex = index;
1936
+ }
1937
+ }
1938
+ }
1939
+ item.matchMask = matchMask;
1940
+ item.exactMatch = penalty ? 0 : 1;
1941
+ item.$score = (item.score || 0) - penalty;
1942
+ results.push(item);
1943
+ }
1944
+ return results;
1945
+ };
1946
+ }).call(FilteredList.prototype);
1947
+
1948
+ exports.Autocomplete = Autocomplete;
1949
+ exports.FilteredList = FilteredList;
1950
+
1951
+ });
1952
+
1953
+ ace.define("ace/ext/menu_tools/overlay_page",["require","exports","module","ace/lib/dom"], function(require, exports, module) {
1954
+ 'use strict';
1955
+ var dom = require("../../lib/dom");
1956
+ var cssText = "#ace_settingsmenu, #kbshortcutmenu {\
1957
+ background-color: #F7F7F7;\
1958
+ color: black;\
1959
+ box-shadow: -5px 4px 5px rgba(126, 126, 126, 0.55);\
1960
+ padding: 1em 0.5em 2em 1em;\
1961
+ overflow: auto;\
1962
+ position: absolute;\
1963
+ margin: 0;\
1964
+ bottom: 0;\
1965
+ right: 0;\
1966
+ top: 0;\
1967
+ z-index: 9991;\
1968
+ cursor: default;\
1969
+ }\
1970
+ .ace_dark #ace_settingsmenu, .ace_dark #kbshortcutmenu {\
1971
+ box-shadow: -20px 10px 25px rgba(126, 126, 126, 0.25);\
1972
+ background-color: rgba(255, 255, 255, 0.6);\
1973
+ color: black;\
1974
+ }\
1975
+ .ace_optionsMenuEntry:hover {\
1976
+ background-color: rgba(100, 100, 100, 0.1);\
1977
+ transition: all 0.3s\
1978
+ }\
1979
+ .ace_closeButton {\
1980
+ background: rgba(245, 146, 146, 0.5);\
1981
+ border: 1px solid #F48A8A;\
1982
+ border-radius: 50%;\
1983
+ padding: 7px;\
1984
+ position: absolute;\
1985
+ right: -8px;\
1986
+ top: -8px;\
1987
+ z-index: 100000;\
1988
+ }\
1989
+ .ace_closeButton{\
1990
+ background: rgba(245, 146, 146, 0.9);\
1991
+ }\
1992
+ .ace_optionsMenuKey {\
1993
+ color: darkslateblue;\
1994
+ font-weight: bold;\
1995
+ }\
1996
+ .ace_optionsMenuCommand {\
1997
+ color: darkcyan;\
1998
+ font-weight: normal;\
1999
+ }\
2000
+ .ace_optionsMenuEntry input, .ace_optionsMenuEntry button {\
2001
+ vertical-align: middle;\
2002
+ }\
2003
+ .ace_optionsMenuEntry button[ace_selected_button=true] {\
2004
+ background: #e7e7e7;\
2005
+ box-shadow: 1px 0px 2px 0px #adadad inset;\
2006
+ border-color: #adadad;\
2007
+ }\
2008
+ .ace_optionsMenuEntry button {\
2009
+ background: white;\
2010
+ border: 1px solid lightgray;\
2011
+ margin: 0px;\
2012
+ }\
2013
+ .ace_optionsMenuEntry button:hover{\
2014
+ background: #f0f0f0;\
2015
+ }";
2016
+ dom.importCssString(cssText);
2017
+
2018
+ module.exports.overlayPage = function overlayPage(editor, contentElement, callback) {
2019
+ var closer = document.createElement('div');
2020
+ var ignoreFocusOut = false;
2021
+
2022
+ function documentEscListener(e) {
2023
+ if (e.keyCode === 27) {
2024
+ close();
2025
+ }
2026
+ }
2027
+
2028
+ function close() {
2029
+ if (!closer) return;
2030
+ document.removeEventListener('keydown', documentEscListener);
2031
+ closer.parentNode.removeChild(closer);
2032
+ if (editor) {
2033
+ editor.focus();
2034
+ }
2035
+ closer = null;
2036
+ callback && callback();
2037
+ }
2038
+ function setIgnoreFocusOut(ignore) {
2039
+ ignoreFocusOut = ignore;
2040
+ if (ignore) {
2041
+ closer.style.pointerEvents = "none";
2042
+ contentElement.style.pointerEvents = "auto";
2043
+ }
2044
+ }
2045
+
2046
+ closer.style.cssText = 'margin: 0; padding: 0; ' +
2047
+ 'position: fixed; top:0; bottom:0; left:0; right:0;' +
2048
+ 'z-index: 9990; ' +
2049
+ (editor ? 'background-color: rgba(0, 0, 0, 0.3);' : '');
2050
+ closer.addEventListener('click', function(e) {
2051
+ if (!ignoreFocusOut) {
2052
+ close();
2053
+ }
2054
+ });
2055
+ document.addEventListener('keydown', documentEscListener);
2056
+
2057
+ contentElement.addEventListener('click', function (e) {
2058
+ e.stopPropagation();
2059
+ });
2060
+
2061
+ closer.appendChild(contentElement);
2062
+ document.body.appendChild(closer);
2063
+ if (editor) {
2064
+ editor.blur();
2065
+ }
2066
+ return {
2067
+ close: close,
2068
+ setIgnoreFocusOut: setIgnoreFocusOut
2069
+ };
2070
+ };
2071
+
2072
+ });
2073
+
2074
+ ace.define("ace/ext/modelist",["require","exports","module"], function(require, exports, module) {
2075
+ "use strict";
2076
+
2077
+ var modes = [];
2078
+ function getModeForPath(path) {
2079
+ var mode = modesByName.text;
2080
+ var fileName = path.split(/[\/\\]/).pop();
2081
+ for (var i = 0; i < modes.length; i++) {
2082
+ if (modes[i].supportsFile(fileName)) {
2083
+ mode = modes[i];
2084
+ break;
2085
+ }
2086
+ }
2087
+ return mode;
2088
+ }
2089
+
2090
+ var Mode = function(name, caption, extensions) {
2091
+ this.name = name;
2092
+ this.caption = caption;
2093
+ this.mode = "ace/mode/" + name;
2094
+ this.extensions = extensions;
2095
+ var re;
2096
+ if (/\^/.test(extensions)) {
2097
+ re = extensions.replace(/\|(\^)?/g, function(a, b){
2098
+ return "$|" + (b ? "^" : "^.*\\.");
2099
+ }) + "$";
2100
+ } else {
2101
+ re = "^.*\\.(" + extensions + ")$";
2102
+ }
2103
+
2104
+ this.extRe = new RegExp(re, "gi");
2105
+ };
2106
+
2107
+ Mode.prototype.supportsFile = function(filename) {
2108
+ return filename.match(this.extRe);
2109
+ };
2110
+ var supportedModes = {
2111
+ ABAP: ["abap"],
2112
+ ABC: ["abc"],
2113
+ ActionScript:["as"],
2114
+ ADA: ["ada|adb"],
2115
+ Alda: ["alda"],
2116
+ Apache_Conf: ["^htaccess|^htgroups|^htpasswd|^conf|htaccess|htgroups|htpasswd"],
2117
+ Apex: ["apex|cls|trigger|tgr"],
2118
+ AQL: ["aql"],
2119
+ AsciiDoc: ["asciidoc|adoc"],
2120
+ ASL: ["dsl|asl"],
2121
+ Assembly_x86:["asm|a"],
2122
+ AutoHotKey: ["ahk"],
2123
+ BatchFile: ["bat|cmd"],
2124
+ C_Cpp: ["cpp|c|cc|cxx|h|hh|hpp|ino"],
2125
+ C9Search: ["c9search_results"],
2126
+ Cirru: ["cirru|cr"],
2127
+ Clojure: ["clj|cljs"],
2128
+ Cobol: ["CBL|COB"],
2129
+ coffee: ["coffee|cf|cson|^Cakefile"],
2130
+ ColdFusion: ["cfm"],
2131
+ Crystal: ["cr"],
2132
+ CSharp: ["cs"],
2133
+ Csound_Document: ["csd"],
2134
+ Csound_Orchestra: ["orc"],
2135
+ Csound_Score: ["sco"],
2136
+ CSS: ["css"],
2137
+ Curly: ["curly"],
2138
+ D: ["d|di"],
2139
+ Dart: ["dart"],
2140
+ Diff: ["diff|patch"],
2141
+ Dockerfile: ["^Dockerfile"],
2142
+ Dot: ["dot"],
2143
+ Drools: ["drl"],
2144
+ Edifact: ["edi"],
2145
+ Eiffel: ["e|ge"],
2146
+ EJS: ["ejs"],
2147
+ Elixir: ["ex|exs"],
2148
+ Elm: ["elm"],
2149
+ Erlang: ["erl|hrl"],
2150
+ Forth: ["frt|fs|ldr|fth|4th"],
2151
+ Fortran: ["f|f90"],
2152
+ FSharp: ["fsi|fs|ml|mli|fsx|fsscript"],
2153
+ FSL: ["fsl"],
2154
+ FTL: ["ftl"],
2155
+ Gcode: ["gcode"],
2156
+ Gherkin: ["feature"],
2157
+ Gitignore: ["^.gitignore"],
2158
+ Glsl: ["glsl|frag|vert"],
2159
+ Gobstones: ["gbs"],
2160
+ golang: ["go"],
2161
+ GraphQLSchema: ["gql"],
2162
+ Groovy: ["groovy"],
2163
+ HAML: ["haml"],
2164
+ Handlebars: ["hbs|handlebars|tpl|mustache"],
2165
+ Haskell: ["hs"],
2166
+ Haskell_Cabal: ["cabal"],
2167
+ haXe: ["hx"],
2168
+ Hjson: ["hjson"],
2169
+ HTML: ["html|htm|xhtml|vue|we|wpy"],
2170
+ HTML_Elixir: ["eex|html.eex"],
2171
+ HTML_Ruby: ["erb|rhtml|html.erb"],
2172
+ INI: ["ini|conf|cfg|prefs"],
2173
+ Io: ["io"],
2174
+ Jack: ["jack"],
2175
+ Jade: ["jade|pug"],
2176
+ Java: ["java"],
2177
+ JavaScript: ["js|jsm|jsx"],
2178
+ JSON: ["json"],
2179
+ JSON5: ["json5"],
2180
+ JSONiq: ["jq"],
2181
+ JSP: ["jsp"],
2182
+ JSSM: ["jssm|jssm_state"],
2183
+ JSX: ["jsx"],
2184
+ Julia: ["jl"],
2185
+ Kotlin: ["kt|kts"],
2186
+ LaTeX: ["tex|latex|ltx|bib"],
2187
+ LESS: ["less"],
2188
+ Liquid: ["liquid"],
2189
+ Lisp: ["lisp"],
2190
+ LiveScript: ["ls"],
2191
+ LogiQL: ["logic|lql"],
2192
+ LSL: ["lsl"],
2193
+ Lua: ["lua"],
2194
+ LuaPage: ["lp"],
2195
+ Lucene: ["lucene"],
2196
+ Makefile: ["^Makefile|^GNUmakefile|^makefile|^OCamlMakefile|make"],
2197
+ Markdown: ["md|markdown"],
2198
+ Mask: ["mask"],
2199
+ MATLAB: ["matlab"],
2200
+ Maze: ["mz"],
2201
+ MediaWiki: ["wiki|mediawiki"],
2202
+ MEL: ["mel"],
2203
+ MIXAL: ["mixal"],
2204
+ MUSHCode: ["mc|mush"],
2205
+ MySQL: ["mysql"],
2206
+ Nginx: ["nginx|conf"],
2207
+ Nim: ["nim"],
2208
+ Nix: ["nix"],
2209
+ NSIS: ["nsi|nsh"],
2210
+ Nunjucks: ["nunjucks|nunjs|nj|njk"],
2211
+ ObjectiveC: ["m|mm"],
2212
+ OCaml: ["ml|mli"],
2213
+ Pascal: ["pas|p"],
2214
+ Perl: ["pl|pm"],
2215
+ Perl6: ["p6|pl6|pm6"],
2216
+ pgSQL: ["pgsql"],
2217
+ PHP: ["php|inc|phtml|shtml|php3|php4|php5|phps|phpt|aw|ctp|module"],
2218
+ PHP_Laravel_blade: ["blade.php"],
2219
+ Pig: ["pig"],
2220
+ Powershell: ["ps1"],
2221
+ Praat: ["praat|praatscript|psc|proc"],
2222
+ Prisma: ["prisma"],
2223
+ Prolog: ["plg|prolog"],
2224
+ Properties: ["properties"],
2225
+ Protobuf: ["proto"],
2226
+ Puppet: ["epp|pp"],
2227
+ Python: ["py"],
2228
+ QML: ["qml"],
2229
+ R: ["r"],
2230
+ Razor: ["cshtml|asp"],
2231
+ RDoc: ["Rd"],
2232
+ Red: ["red|reds"],
2233
+ RHTML: ["Rhtml"],
2234
+ RST: ["rst"],
2235
+ Ruby: ["rb|ru|gemspec|rake|^Guardfile|^Rakefile|^Gemfile"],
2236
+ Rust: ["rs"],
2237
+ SASS: ["sass"],
2238
+ SCAD: ["scad"],
2239
+ Scala: ["scala|sbt"],
2240
+ Scheme: ["scm|sm|rkt|oak|scheme"],
2241
+ SCSS: ["scss"],
2242
+ SH: ["sh|bash|^.bashrc"],
2243
+ SJS: ["sjs"],
2244
+ Slim: ["slim|skim"],
2245
+ Smarty: ["smarty|tpl"],
2246
+ snippets: ["snippets"],
2247
+ Soy_Template:["soy"],
2248
+ Space: ["space"],
2249
+ SQL: ["sql"],
2250
+ SQLServer: ["sqlserver"],
2251
+ Stylus: ["styl|stylus"],
2252
+ SVG: ["svg"],
2253
+ Swift: ["swift"],
2254
+ Tcl: ["tcl"],
2255
+ Terraform: ["tf", "tfvars", "terragrunt"],
2256
+ Tex: ["tex"],
2257
+ Text: ["txt"],
2258
+ Textile: ["textile"],
2259
+ Toml: ["toml"],
2260
+ TSX: ["tsx"],
2261
+ Twig: ["latte|twig|swig"],
2262
+ Typescript: ["ts|typescript|str"],
2263
+ Vala: ["vala"],
2264
+ VBScript: ["vbs|vb"],
2265
+ Velocity: ["vm"],
2266
+ Verilog: ["v|vh|sv|svh"],
2267
+ VHDL: ["vhd|vhdl"],
2268
+ Visualforce: ["vfp|component|page"],
2269
+ Wollok: ["wlk|wpgm|wtest"],
2270
+ XML: ["xml|rdf|rss|wsdl|xslt|atom|mathml|mml|xul|xbl|xaml"],
2271
+ XQuery: ["xq"],
2272
+ YAML: ["yaml|yml"],
2273
+ Zeek: ["zeek|bro"],
2274
+ Django: ["html"]
2275
+ };
2276
+
2277
+ var nameOverrides = {
2278
+ ObjectiveC: "Objective-C",
2279
+ CSharp: "C#",
2280
+ golang: "Go",
2281
+ C_Cpp: "C and C++",
2282
+ Csound_Document: "Csound Document",
2283
+ Csound_Orchestra: "Csound",
2284
+ Csound_Score: "Csound Score",
2285
+ coffee: "CoffeeScript",
2286
+ HTML_Ruby: "HTML (Ruby)",
2287
+ HTML_Elixir: "HTML (Elixir)",
2288
+ FTL: "FreeMarker",
2289
+ PHP_Laravel_blade: "PHP (Blade Template)",
2290
+ Perl6: "Perl 6",
2291
+ AutoHotKey: "AutoHotkey / AutoIt"
2292
+ };
2293
+ var modesByName = {};
2294
+ for (var name in supportedModes) {
2295
+ var data = supportedModes[name];
2296
+ var displayName = (nameOverrides[name] || name).replace(/_/g, " ");
2297
+ var filename = name.toLowerCase();
2298
+ var mode = new Mode(filename, displayName, data[0]);
2299
+ modesByName[filename] = mode;
2300
+ modes.push(mode);
2301
+ }
2302
+
2303
+ module.exports = {
2304
+ getModeForPath: getModeForPath,
2305
+ modes: modes,
2306
+ modesByName: modesByName
2307
+ };
2308
+
2309
+ });
2310
+
2311
+ ace.define("ace/ext/prompt",["require","exports","module","ace/range","ace/lib/dom","ace/ext/menu_tools/get_editor_keyboard_shortcuts","ace/autocomplete","ace/autocomplete/popup","ace/autocomplete/popup","ace/undomanager","ace/tokenizer","ace/ext/menu_tools/overlay_page","ace/ext/modelist"], function(require, exports, module) {
2312
+ "use strict";
2313
+
2314
+ var Range = require("../range").Range;
2315
+ var dom = require("../lib/dom");
2316
+ var shortcuts = require("../ext/menu_tools/get_editor_keyboard_shortcuts");
2317
+ var FilteredList= require("../autocomplete").FilteredList;
2318
+ var AcePopup = require('../autocomplete/popup').AcePopup;
2319
+ var $singleLineEditor = require('../autocomplete/popup').$singleLineEditor;
2320
+ var UndoManager = require("../undomanager").UndoManager;
2321
+ var Tokenizer = require("../tokenizer").Tokenizer;
2322
+ var overlayPage = require("./menu_tools/overlay_page").overlayPage;
2323
+ var modelist = require("./modelist");
2324
+ var openPrompt;
2325
+
2326
+ function prompt(editor, message, options, callback) {
2327
+ if (typeof message == "object") {
2328
+ return prompt(editor, "", message, options);
2329
+ }
2330
+ if (openPrompt) {
2331
+ var lastPrompt = openPrompt;
2332
+ editor = lastPrompt.editor;
2333
+ lastPrompt.close();
2334
+ if (lastPrompt.name && lastPrompt.name == options.name)
2335
+ return;
2336
+ }
2337
+ if (options.$type)
2338
+ return prompt[options.$type](editor, callback);
2339
+
2340
+ var cmdLine = $singleLineEditor();
2341
+ cmdLine.session.setUndoManager(new UndoManager());
2342
+
2343
+ var el = dom.buildDom(["div", {class: "ace_prompt_container" + (options.hasDescription ? " input-box-with-description" : "")}]);
2344
+ var overlay = overlayPage(editor, el, done);
2345
+ el.appendChild(cmdLine.container);
2346
+
2347
+ if (editor) {
2348
+ editor.cmdLine = cmdLine;
2349
+ cmdLine.setOption("fontSize", editor.getOption("fontSize"));
2350
+ }
2351
+ if (message) {
2352
+ cmdLine.setValue(message, 1);
2353
+ }
2354
+ if (options.selection) {
2355
+ cmdLine.selection.setRange({
2356
+ start: cmdLine.session.doc.indexToPosition(options.selection[0]),
2357
+ end: cmdLine.session.doc.indexToPosition(options.selection[1])
2358
+ });
2359
+ }
2360
+
2361
+ if (options.getCompletions) {
2362
+ var popup = new AcePopup();
2363
+ popup.renderer.setStyle("ace_autocomplete_inline");
2364
+ popup.container.style.display = "block";
2365
+ popup.container.style.maxWidth = "600px";
2366
+ popup.container.style.width = "100%";
2367
+ popup.container.style.marginTop = "3px";
2368
+ popup.renderer.setScrollMargin(2, 2, 0, 0);
2369
+ popup.autoSelect = false;
2370
+ popup.renderer.$maxLines = 15;
2371
+ popup.setRow(-1);
2372
+ popup.on("click", function(e) {
2373
+ var data = popup.getData(popup.getRow());
2374
+ if (!data.error) {
2375
+ cmdLine.setValue(data.value || data.name || data);
2376
+ accept();
2377
+ e.stop();
2378
+ }
2379
+ });
2380
+ el.appendChild(popup.container);
2381
+ updateCompletions();
2382
+ }
2383
+
2384
+ if (options.$rules) {
2385
+ var tokenizer = new Tokenizer(options.$rules);
2386
+ cmdLine.session.bgTokenizer.setTokenizer(tokenizer);
2387
+ }
2388
+
2389
+ if (options.placeholder) {
2390
+ cmdLine.setOption("placeholder", options.placeholder);
2391
+ }
2392
+
2393
+ if (options.hasDescription) {
2394
+ var promptTextContainer = dom.buildDom(["div", {class: "ace_prompt_text_container"}]);
2395
+ dom.buildDom(options.prompt || "Press 'Enter' to confirm or 'Escape' to cancel", promptTextContainer);
2396
+ el.appendChild(promptTextContainer);
2397
+ }
2398
+
2399
+ overlay.setIgnoreFocusOut(options.ignoreFocusOut);
2400
+
2401
+ function accept() {
2402
+ var val;
2403
+ if (popup && popup.getCursorPosition().row > 0) {
2404
+ val = valueFromRecentList();
2405
+ } else {
2406
+ val = cmdLine.getValue();
2407
+ }
2408
+ var curData = popup ? popup.getData(popup.getRow()) : val;
2409
+ if (curData && !curData.error) {
2410
+ done();
2411
+ options.onAccept && options.onAccept({
2412
+ value: val,
2413
+ item: curData
2414
+ }, cmdLine);
2415
+ }
2416
+ }
2417
+
2418
+ var keys = {
2419
+ "Enter": accept,
2420
+ "Esc|Shift-Esc": function() {
2421
+ options.onCancel && options.onCancel(cmdLine.getValue(), cmdLine);
2422
+ done();
2423
+ }
2424
+ };
2425
+
2426
+ if (popup) {
2427
+ Object.assign(keys, {
2428
+ "Up": function(editor) { popup.goTo("up"); valueFromRecentList();},
2429
+ "Down": function(editor) { popup.goTo("down"); valueFromRecentList();},
2430
+ "Ctrl-Up|Ctrl-Home": function(editor) { popup.goTo("start"); valueFromRecentList();},
2431
+ "Ctrl-Down|Ctrl-End": function(editor) { popup.goTo("end"); valueFromRecentList();},
2432
+ "Tab": function(editor) {
2433
+ popup.goTo("down"); valueFromRecentList();
2434
+ },
2435
+ "PageUp": function(editor) { popup.gotoPageUp(); valueFromRecentList();},
2436
+ "PageDown": function(editor) { popup.gotoPageDown(); valueFromRecentList();}
2437
+ });
2438
+ }
2439
+
2440
+ cmdLine.commands.bindKeys(keys);
2441
+
2442
+ function done() {
2443
+ overlay.close();
2444
+ callback && callback();
2445
+ openPrompt = null;
2446
+ }
2447
+
2448
+ cmdLine.on("input", function() {
2449
+ options.onInput && options.onInput();
2450
+ updateCompletions();
2451
+ });
2452
+
2453
+ function updateCompletions() {
2454
+ if (options.getCompletions) {
2455
+ var prefix;
2456
+ if (options.getPrefix) {
2457
+ prefix = options.getPrefix(cmdLine);
2458
+ }
2459
+
2460
+ var completions = options.getCompletions(cmdLine);
2461
+ popup.setData(completions, prefix);
2462
+ popup.resize(true);
2463
+ }
2464
+ }
2465
+
2466
+ function valueFromRecentList() {
2467
+ var current = popup.getData(popup.getRow());
2468
+ if (current && !current.error)
2469
+ return current.value || current.caption || current;
2470
+ }
2471
+
2472
+ cmdLine.resize(true);
2473
+ if (popup) {
2474
+ popup.resize(true);
2475
+ }
2476
+ cmdLine.focus();
2477
+
2478
+ openPrompt = {
2479
+ close: done,
2480
+ name: options.name,
2481
+ editor: editor
2482
+ };
2483
+ }
2484
+
2485
+ prompt.gotoLine = function(editor, callback) {
2486
+ function stringifySelection(selection) {
2487
+ if (!Array.isArray(selection))
2488
+ selection = [selection];
2489
+ return selection.map(function(r) {
2490
+ var cursor = r.isBackwards ? r.start: r.end;
2491
+ var anchor = r.isBackwards ? r.end: r.start;
2492
+ var row = anchor.row;
2493
+ var s = (row + 1) + ":" + anchor.column;
2494
+
2495
+ if (anchor.row == cursor.row) {
2496
+ if (anchor.column != cursor.column)
2497
+ s += ">" + ":" + cursor.column;
2498
+ } else {
2499
+ s += ">" + (cursor.row + 1) + ":" + cursor.column;
2500
+ }
2501
+ return s;
2502
+ }).reverse().join(", ");
2503
+ }
2504
+
2505
+ prompt(editor, ":" + stringifySelection(editor.selection.toJSON()), {
2506
+ name: "gotoLine",
2507
+ selection: [1, Number.MAX_VALUE],
2508
+ onAccept: function(data) {
2509
+ var value = data.value;
2510
+ var _history = prompt.gotoLine._history;
2511
+ if (!_history)
2512
+ prompt.gotoLine._history = _history = [];
2513
+ if (_history.indexOf(value) != -1)
2514
+ _history.splice(_history.indexOf(value), 1);
2515
+ _history.unshift(value);
2516
+ if (_history.length > 20) _history.length = 20;
2517
+
2518
+
2519
+ var pos = editor.getCursorPosition();
2520
+ var ranges = [];
2521
+ value.replace(/^:/, "").split(/,/).map(function(str) {
2522
+ var parts = str.split(/([<>:+-]|c?\d+)|[^c\d<>:+-]+/).filter(Boolean);
2523
+ var i = 0;
2524
+ function readPosition() {
2525
+ var c = parts[i++];
2526
+ if (!c) return;
2527
+ if (c[0] == "c") {
2528
+ var index = parseInt(c.slice(1)) || 0;
2529
+ return editor.session.doc.indexToPosition(index);
2530
+ }
2531
+ var row = pos.row;
2532
+ var column = 0;
2533
+ if (/\d/.test(c)) {
2534
+ row = parseInt(c) - 1;
2535
+ c = parts[i++];
2536
+ }
2537
+ if (c == ":") {
2538
+ c = parts[i++];
2539
+ if (/\d/.test(c)) {
2540
+ column = parseInt(c) || 0;
2541
+ }
2542
+ }
2543
+ return {row: row, column: column};
2544
+ }
2545
+ pos = readPosition();
2546
+ var range = Range.fromPoints(pos, pos);
2547
+ if (parts[i] == ">") {
2548
+ i++;
2549
+ range.end = readPosition();
2550
+ }
2551
+ else if (parts[i] == "<") {
2552
+ i++;
2553
+ range.start = readPosition();
2554
+ }
2555
+ ranges.unshift(range);
2556
+ });
2557
+ editor.selection.fromJSON(ranges);
2558
+ var scrollTop = editor.renderer.scrollTop;
2559
+ editor.renderer.scrollSelectionIntoView(
2560
+ editor.selection.anchor,
2561
+ editor.selection.cursor,
2562
+ 0.5
2563
+ );
2564
+ editor.renderer.animateScrolling(scrollTop);
2565
+ },
2566
+ history: function() {
2567
+ var undoManager = editor.session.getUndoManager();
2568
+ if (!prompt.gotoLine._history)
2569
+ return [];
2570
+ return prompt.gotoLine._history;
2571
+
2572
+ },
2573
+ getCompletions: function(cmdLine) {
2574
+ var value = cmdLine.getValue();
2575
+ var m = value.replace(/^:/, "").split(":");
2576
+ var row = Math.min(parseInt(m[0]) || 1, editor.session.getLength()) - 1;
2577
+ var line = editor.session.getLine(row);
2578
+ var current = value + " " + line;
2579
+ return [current].concat(this.history());
2580
+ },
2581
+ $rules: {
2582
+ start: [{
2583
+ regex: /\d+/,
2584
+ token: "string"
2585
+ }, {
2586
+ regex: /[:,><+\-c]/,
2587
+ token: "keyword"
2588
+ }]
2589
+ }
2590
+ });
2591
+ };
2592
+
2593
+ prompt.commands = function(editor, callback) {
2594
+ function normalizeName(name) {
2595
+ return (name || "").replace(/^./, function(x) {
2596
+ return x.toUpperCase(x);
2597
+ }).replace(/[a-z][A-Z]/g, function(x) {
2598
+ return x[0] + " " + x[1].toLowerCase(x);
2599
+ });
2600
+ }
2601
+ function getEditorCommandsByName(excludeCommands) {
2602
+ var commandsByName = [];
2603
+ var commandMap = {};
2604
+ editor.keyBinding.$handlers.forEach(function(handler) {
2605
+ var platform = handler.platform;
2606
+ var cbn = handler.byName;
2607
+ for (var i in cbn) {
2608
+ var key;
2609
+ if (cbn[i].bindKey && cbn[i].bindKey[platform] !== null) {
2610
+ key = cbn[i].bindKey["win"];
2611
+ } else {
2612
+ key = "";
2613
+ }
2614
+
2615
+ var commands = cbn[i];
2616
+ var description = commands.description || normalizeName(commands.name);
2617
+ if (!Array.isArray(commands))
2618
+ commands = [commands];
2619
+ commands.forEach(function(command) {
2620
+ if (typeof command != "string")
2621
+ command = command.name;
2622
+ var needle = excludeCommands.find(function(el) {
2623
+ return el === command;
2624
+ });
2625
+ if (!needle) {
2626
+ if (commandMap[command]) {
2627
+ commandMap[command].key += "|" + key;
2628
+ } else {
2629
+ commandMap[command] = {key: key, command: command, description: description};
2630
+ commandsByName.push(commandMap[command]);
2631
+ }
2632
+ }
2633
+ });
2634
+ }
2635
+ });
2636
+ return commandsByName;
2637
+ }
2638
+ var excludeCommandsList = ["insertstring", "inserttext", "setIndentation", "paste"];
2639
+ var shortcutsArray = getEditorCommandsByName(excludeCommandsList);
2640
+ shortcutsArray = shortcutsArray.map(function(item) {
2641
+ return {value: item.description, meta: item.key, command: item.command};
2642
+ });
2643
+ prompt(editor, "", {
2644
+ name: "commands",
2645
+ selection: [0, Number.MAX_VALUE],
2646
+ maxHistoryCount: 5,
2647
+ onAccept: function(data) {
2648
+ if (data.item) {
2649
+ var commandName = data.item.command;
2650
+ this.addToHistory(data.item);
2651
+
2652
+ editor.execCommand(commandName);
2653
+ }
2654
+ },
2655
+ addToHistory: function(item) {
2656
+ var history = this.history();
2657
+ history.unshift(item);
2658
+ delete item.message;
2659
+ for (var i = 1; i < history.length; i++) {
2660
+ if (history[i]["command"] == item.command ) {
2661
+ history.splice(i, 1);
2662
+ break;
2663
+ }
2664
+ }
2665
+ if (this.maxHistoryCount > 0 && history.length > this.maxHistoryCount) {
2666
+ history.splice(history.length - 1, 1);
2667
+ }
2668
+ prompt.commands.history = history;
2669
+ },
2670
+ history: function() {
2671
+ return prompt.commands.history || [];
2672
+ },
2673
+ getPrefix: function(cmdLine) {
2674
+ var currentPos = cmdLine.getCursorPosition();
2675
+ var filterValue = cmdLine.getValue();
2676
+ return filterValue.substring(0, currentPos.column);
2677
+ },
2678
+ getCompletions: function(cmdLine) {
2679
+ function getFilteredCompletions(commands, prefix) {
2680
+ var resultCommands = JSON.parse(JSON.stringify(commands));
2681
+
2682
+ var filtered = new FilteredList(resultCommands);
2683
+ return filtered.filterCompletions(resultCommands, prefix);
2684
+ }
2685
+
2686
+ function getUniqueCommandList(commands, usedCommands) {
2687
+ if (!usedCommands || !usedCommands.length) {
2688
+ return commands;
2689
+ }
2690
+ var excludeCommands = [];
2691
+ usedCommands.forEach(function(item) {
2692
+ excludeCommands.push(item.command);
2693
+ });
2694
+
2695
+ var resultCommands = [];
2696
+
2697
+ commands.forEach(function(item) {
2698
+ if (excludeCommands.indexOf(item.command) === -1) {
2699
+ resultCommands.push(item);
2700
+ }
2701
+ });
2702
+
2703
+ return resultCommands;
2704
+ }
2705
+
2706
+ var prefix = this.getPrefix(cmdLine);
2707
+ var recentlyUsedCommands = getFilteredCompletions(this.history(), prefix);
2708
+ var otherCommands = getUniqueCommandList(shortcutsArray, recentlyUsedCommands);
2709
+ otherCommands = getFilteredCompletions(otherCommands, prefix);
2710
+
2711
+ if (recentlyUsedCommands.length && otherCommands.length) {
2712
+ recentlyUsedCommands[0]["message"] = " Recently used";
2713
+ otherCommands[0]["message"] = " Other commands";
2714
+ }
2715
+
2716
+ var completions = recentlyUsedCommands.concat(otherCommands);
2717
+ return completions.length > 0 ? completions : [{
2718
+ value: "No matching commands",
2719
+ error: 1
2720
+ }];
2721
+ }
2722
+ });
2723
+ };
2724
+
2725
+ prompt.modes = function(editor, callback) {
2726
+ var modesArray = modelist.modes;
2727
+ modesArray = modesArray.map(function(item) {
2728
+ return {value: item.caption, mode: item.name};
2729
+ });
2730
+ prompt(editor, "", {
2731
+ name: "modes",
2732
+ selection: [0, Number.MAX_VALUE],
2733
+ onAccept: function(data) {
2734
+ if (data.item) {
2735
+ var modeName = "ace/mode/" + data.item.mode;
2736
+ editor.session.setMode(modeName);
2737
+ }
2738
+ },
2739
+ getPrefix: function(cmdLine) {
2740
+ var currentPos = cmdLine.getCursorPosition();
2741
+ var filterValue = cmdLine.getValue();
2742
+ return filterValue.substring(0, currentPos.column);
2743
+ },
2744
+ getCompletions: function(cmdLine) {
2745
+ function getFilteredCompletions(modes, prefix) {
2746
+ var resultCommands = JSON.parse(JSON.stringify(modes));
2747
+
2748
+ var filtered = new FilteredList(resultCommands);
2749
+ return filtered.filterCompletions(resultCommands, prefix);
2750
+ }
2751
+
2752
+ var prefix = this.getPrefix(cmdLine);
2753
+ var completions = getFilteredCompletions(modesArray, prefix);
2754
+ return completions.length > 0 ? completions : [{
2755
+ "caption": "No mode matching",
2756
+ "value": "No mode matching",
2757
+ "error": 1
2758
+ }];
2759
+ }
2760
+ });
2761
+ };
2762
+
2763
+ dom.importCssString(".ace_prompt_container {\
2764
+ max-width: 600px;\
2765
+ width: 100%;\
2766
+ margin: 20px auto;\
2767
+ padding: 3px;\
2768
+ background: white;\
2769
+ border-radius: 2px;\
2770
+ box-shadow: 0px 2px 3px 0px #555;\
2771
+ }");
2772
+
2773
+
2774
+ exports.prompt = prompt;
2775
+
2776
+ }); (function() {
2777
+ ace.require(["ace/ext/prompt"], function(m) {
2778
+ if (typeof module == "object" && typeof exports == "object" && module) {
2779
+ module.exports = m;
2780
+ }
2781
+ });
2782
+ })();
framework/js/ui/jquery.toolbox/jquery.toolbox.js CHANGED
@@ -249,7 +249,6 @@ var CJTToolBoxNS = new (function ($) {
249
 
250
  // Clear time out in case the mouse is out and entered again.
251
  // By mean don't close dialog if the mouse is out and quickly back again!
252
- clearTimeout(this.popupTimer);
253
 
254
  // Process only if target element is not visible yet.
255
  // This condition prevent Shaking!
@@ -257,7 +256,7 @@ var CJTToolBoxNS = new (function ($) {
257
  // Don't show the popup immediately when the mouse come over the button.
258
  // As our move the mouse and didnt decide yest which popup to open.
259
  // Stay for a while to make sure that this popup is desirable.
260
- this.popupTimer = setTimeout($.proxy(this.showPopup, this), 100);
261
  cbMouseOut = $.proxy(this._onmouseout, this);
262
  // Hide Popup if mouse out from button or the popup form!
263
  this.jButton.bind('mouseout.CJTButtonTouchMouseOut', cbMouseOut);
@@ -275,19 +274,16 @@ var CJTToolBoxNS = new (function ($) {
275
  // In all cases just clear the timeout timer.
276
  // It has no effect if the popup is already opened.
277
  // But it has effect if the Popup is not opened yet.
278
- clearTimeout(this.popupTimer);
279
  // Don't close the dialg once get out but give it a break!
280
- this.popupTimer = setTimeout($.proxy(function() {
281
- // Is the mouse still over button?
282
- var isOverButton = (event.relatedTarget === this.jButton.get(0));
283
- // Is mouse still over target element of any of its childs/descendants.
284
- var isOverElement = this.targetElement.find('*').andSelf().is(event.relatedTarget);
285
- // Is mouse is not over button or target element hide element and unbind events.
286
- if (!isOverButton && !isOverElement) {
287
- this.close();
288
- }
289
- }, this)
290
- , 400);
291
  }
292
 
293
  /**
@@ -650,7 +646,7 @@ var CJTToolBoxNS = new (function ($) {
650
  // Get button class from type var.
651
  var buttonType = (data.type != undefined) ? data.type : '';
652
  var buttonClassName = 'Button' + buttonType;
653
- var buttonClass = CJTToolBoxNS[buttonClassName];
654
  // Create button object.
655
  var button = CJTToolBox.buttons[name] = new buttonClass();
656
  // If no params object passed create empty one.
249
 
250
  // Clear time out in case the mouse is out and entered again.
251
  // By mean don't close dialog if the mouse is out and quickly back again!
 
252
 
253
  // Process only if target element is not visible yet.
254
  // This condition prevent Shaking!
256
  // Don't show the popup immediately when the mouse come over the button.
257
  // As our move the mouse and didnt decide yest which popup to open.
258
  // Stay for a while to make sure that this popup is desirable.
259
+ this.showPopup()
260
  cbMouseOut = $.proxy(this._onmouseout, this);
261
  // Hide Popup if mouse out from button or the popup form!
262
  this.jButton.bind('mouseout.CJTButtonTouchMouseOut', cbMouseOut);
274
  // In all cases just clear the timeout timer.
275
  // It has no effect if the popup is already opened.
276
  // But it has effect if the Popup is not opened yet.
277
+ //clearTimeout(this.popupTimer);
278
  // Don't close the dialg once get out but give it a break!
279
+ // Is the mouse still over button?
280
+ var isOverButton = (event.relatedTarget === this.jButton.get(0));
281
+ // Is mouse still over target element of any of its childs/descendants.
282
+ var isOverElement = this.targetElement.find('*').andSelf().is(event.relatedTarget);
283
+ // Is mouse is not over button or target element hide element and unbind events.
284
+ if (!isOverButton && !isOverElement) {
285
+ this.close();
286
+ }
 
 
 
287
  }
288
 
289
  /**
646
  // Get button class from type var.
647
  var buttonType = (data.type != undefined) ? data.type : '';
648
  var buttonClassName = 'Button' + buttonType;
649
+ var buttonClass = CJTToolBoxNS[ buttonClassName ];
650
  // Create button object.
651
  var button = CJTToolBox.buttons[name] = new buttonClass();
652
  // If no params object passed create empty one.
framework/mvc/controller.inc.php CHANGED
@@ -12,99 +12,99 @@ defined('ABSPATH') or die("Access denied");
12
  * CJT controller base class.
13
  */
14
  abstract class CJTController extends CJTHookableClass {
15
-
16
  /** */
17
  const NONCE_ACTION = 'cjtoolbox';
18
-
19
  /**
20
  * put your comment there...
21
- *
22
  * @var mixed
23
  */
24
  protected $action;
25
-
26
  /**
27
  * put your comment there...
28
- *
29
  * @var mixed
30
  */
31
  protected $controllerInfo = null;
32
-
33
  /**
34
  * put your comment there...
35
- *
36
  * @var mixed
37
  */
38
  protected $defaultAction = 'index';
39
-
40
  /**
41
  * put your comment there...
42
- *
43
  * @var mixed
44
  */
45
  protected $request;
46
-
47
  /**
48
  * put your comment there...
49
- *
50
  * @var mixed
51
  */
52
  protected $model = null;
53
 
54
  /**
55
  * put your comment there...
56
- *
57
  * @var mixed
58
  */
59
  protected $oncallback = array('parameters' => array('callback', 'action', 'args'));
60
-
61
  /**
62
  * put your comment there...
63
- *
64
  * @var mixed
65
  */
66
  protected $ongetactionname = array('parameters' => array('action'));
67
-
68
  /**
69
  * put your comment there...
70
- *
71
  * @var mixed
72
  */
73
  protected static $ongetclassname = array('parameters' => array('class', 'name', 'type'));
74
-
75
  /**
76
  * put your comment there...
77
- *
78
  * @var mixed
79
  */
80
  protected $ongetviewname = array('parameters' => array('view'));
81
-
82
  /**
83
  * put your comment there...
84
- *
85
  * @var mixed
86
  */
87
  protected static $onloadcontroller = array('parameters' => array('file', 'name'));
88
-
89
  /**
90
  * put your comment there...
91
- *
92
  * @var mixed
93
  */
94
  protected $view = null;
95
-
96
  /**
97
  * put your comment there...
98
- *
99
  * @param mixed $hasView
100
  * @param mixed $request
101
  * @param mixed $overrideControllerPath
102
  * @param mixed $overrideContollerPrefix
103
  * @return CJTController
104
  */
105
- public function __construct($hasView = null,
106
- $request = null,
107
- $overrideControllerPath = null,
108
  $overrideContollerPrefix = null) {
109
  // Initialize hookable!
110
  parent::__construct();
@@ -116,8 +116,8 @@ abstract class CJTController extends CJTHookableClass {
116
  if (!isset($this->controllerInfo['model_file'])) {
117
  $this->controllerInfo['model_file'] = null;
118
  }
119
- $this->model = CJTModel::create($this->controllerInfo['model'],
120
- $this->request,
121
  $this->controllerInfo['model_file'],
122
  dirname($overrideControllerPath),
123
  $overrideContollerPrefix);
@@ -129,8 +129,8 @@ abstract class CJTController extends CJTHookableClass {
129
  (isset($this->controllerInfo['view']) ? $this->controllerInfo['view'] : null)
130
  );
131
  if ($view) {
132
- $this->view = self::getView($view,
133
- null,
134
  dirname($overrideControllerPath),
135
  $overrideContollerPrefix)
136
  // Push data into view.
@@ -139,15 +139,15 @@ abstract class CJTController extends CJTHookableClass {
139
  }
140
  }
141
  }
142
-
143
  /**
144
  * put your comment there...
145
- *
146
  */
147
  public function _doAction() {
148
  // Force use of internal action untless its empty
149
  // then look for submitted action or get the default!
150
- $action = $this->action ? $this->action :
151
  (isset($_GET['action']) ? $_GET['action'] : $this->defaultAction);
152
  // filter action name!
153
  $action = $this->ongetactionname($action);
@@ -159,19 +159,19 @@ abstract class CJTController extends CJTHookableClass {
159
  call_user_func($callback);
160
  }
161
  }
162
-
163
  /**
164
  * put your comment there...
165
- *
166
  * @param mixed $name
167
  * @param mixed $hasView
168
  * @param mixed $request
169
  * @param mixed $overrideControllersPath
170
  * @param mixed $overrideControllersPrefix
171
  */
172
- public static function create($name,
173
- $hasView = null,
174
- $request = null,
175
  $overrideControllersPath = null,
176
  $overrideControllersPrefix = null) {
177
  // Import controller file.
@@ -183,10 +183,10 @@ abstract class CJTController extends CJTHookableClass {
183
  // Instantiate controller class.
184
  return new $class($hasView, $request, $overrideControllersPath, $overrideControllersPrefix);
185
  }
186
-
187
  /**
188
  * put your comment there...
189
- *
190
  * @deprecated Use cssJSToolbox::createSecurityToken
191
  */
192
  public function createSecurityToken() {
@@ -195,7 +195,7 @@ abstract class CJTController extends CJTHookableClass {
195
 
196
  /**
197
  * put your comment there...
198
- *
199
  */
200
  protected function displayAction() {
201
  // Get view layout!
@@ -208,27 +208,27 @@ abstract class CJTController extends CJTHookableClass {
208
 
209
  /**
210
  * put your comment there...
211
- *
212
  * @param mixed $name
213
  * @param mixed $hasView
214
  * @param mixed $request
215
  * @param mixed $overrideControllersPath
216
  */
217
  public static function getInstance($name,
218
- $hasView = null,
219
- $request = null,
220
  $overrideControllersPath = null,
221
  $overrideControllersPrefix = null) {
222
  return self::create($name, $hasView, $request, $overrideControllersPath, $overrideControllersPrefix);
223
  }
224
-
225
  /**
226
  * Use CJTModel::create instead.
227
- *
228
  * @deprecated No longer used.
229
  */
230
- public static function getModel($name,
231
- $params = array(),
232
  $file = null,
233
  $overrideModelsPath = null,
234
  $overrideModelsPrefix = null) {
@@ -248,7 +248,7 @@ abstract class CJTController extends CJTHookableClass {
248
  $model = new $modelClass($params);
249
  return $model;
250
  }
251
-
252
  /**
253
  * @deprecated No longer used.
254
  */
@@ -267,25 +267,25 @@ abstract class CJTController extends CJTHookableClass {
267
  $className = self::trigger('CJTController.getclassname', "{$prefix}{$sanitizedName}", $name, $type);
268
  return $className;
269
  }
270
-
271
  /**
272
  * put your comment there...
273
- *
274
  * @param mixed $name
275
  */
276
  public function getRequestParameter($name) {
277
- return isset($this->request[$name]) ? $this->request[$name] : null;
278
  }
279
-
280
  /**
281
- *
282
  * Use CJTView:create instrad.
283
- *
284
  * @deprecated
285
  */
286
- public static function getView($path,
287
- $params = null,
288
- $overrideViewsPath = null,
289
  $overrideViewsPrefix = null) {
290
  $view = null;
291
  // Import view file.
@@ -297,14 +297,14 @@ abstract class CJTController extends CJTHookableClass {
297
  $view = new $viewClass($viewInfo, $params);
298
  return $view;
299
  }
300
-
301
  /**
302
  * put your comment there...
303
- *
304
  */
305
  public static function getViewInfo($path, $overrideViewsPath = null, $overrideViewsPrefix = null) {
306
  // Plugin views Url
307
- $viewsUrl = $overrideViewsPath ?
308
  WP_PLUGIN_URL . '/' . basename(dirname($overrideViewsPath)) :
309
  CJTOOLBOX_VIEWS_URL;
310
  // Path to views dir.
@@ -322,20 +322,20 @@ abstract class CJTController extends CJTHookableClass {
322
  );
323
  return $viewInfo;
324
  }
325
-
326
  /**
327
  * put your comment there...
328
- *
329
  * @param mixed $action
330
  */
331
  public function setAction($action) {
332
  $this->action = $action;
333
  return $this;
334
  }
335
-
336
  /**
337
  * put your comment there...
338
- *
339
  * @param mixed $name
340
  * @param mixed $value
341
  */
@@ -343,7 +343,7 @@ abstract class CJTController extends CJTHookableClass {
343
  $this->request[$name] = $value;
344
  return $this;
345
  }
346
-
347
  } // End class.
348
 
349
  // Hookable!
12
  * CJT controller base class.
13
  */
14
  abstract class CJTController extends CJTHookableClass {
15
+
16
  /** */
17
  const NONCE_ACTION = 'cjtoolbox';
18
+
19
  /**
20
  * put your comment there...
21
+ *
22
  * @var mixed
23
  */
24
  protected $action;
25
+
26
  /**
27
  * put your comment there...
28
+ *
29
  * @var mixed
30
  */
31
  protected $controllerInfo = null;
32
+
33
  /**
34
  * put your comment there...
35
+ *
36
  * @var mixed
37
  */
38
  protected $defaultAction = 'index';
39
+
40
  /**
41
  * put your comment there...
42
+ *
43
  * @var mixed
44
  */
45
  protected $request;
46
+
47
  /**
48
  * put your comment there...
49
+ *
50
  * @var mixed
51
  */
52
  protected $model = null;
53
 
54
  /**
55
  * put your comment there...
56
+ *
57
  * @var mixed
58
  */
59
  protected $oncallback = array('parameters' => array('callback', 'action', 'args'));
60
+
61
  /**
62
  * put your comment there...
63
+ *
64
  * @var mixed
65
  */
66
  protected $ongetactionname = array('parameters' => array('action'));
67
+
68
  /**
69
  * put your comment there...
70
+ *
71
  * @var mixed
72
  */
73
  protected static $ongetclassname = array('parameters' => array('class', 'name', 'type'));
74
+
75
  /**
76
  * put your comment there...
77
+ *
78
  * @var mixed
79
  */
80
  protected $ongetviewname = array('parameters' => array('view'));
81
+
82
  /**
83
  * put your comment there...
84
+ *
85
  * @var mixed
86
  */
87
  protected static $onloadcontroller = array('parameters' => array('file', 'name'));
88
+
89
  /**
90
  * put your comment there...
91
+ *
92
  * @var mixed
93
  */
94
  protected $view = null;
95
+
96
  /**
97
  * put your comment there...
98
+ *
99
  * @param mixed $hasView
100
  * @param mixed $request
101
  * @param mixed $overrideControllerPath
102
  * @param mixed $overrideContollerPrefix
103
  * @return CJTController
104
  */
105
+ public function __construct($hasView = null,
106
+ $request = null,
107
+ $overrideControllerPath = null,
108
  $overrideContollerPrefix = null) {
109
  // Initialize hookable!
110
  parent::__construct();
116
  if (!isset($this->controllerInfo['model_file'])) {
117
  $this->controllerInfo['model_file'] = null;
118
  }
119
+ $this->model = CJTModel::create($this->controllerInfo['model'],
120
+ $this->request,
121
  $this->controllerInfo['model_file'],
122
  dirname($overrideControllerPath),
123
  $overrideContollerPrefix);
129
  (isset($this->controllerInfo['view']) ? $this->controllerInfo['view'] : null)
130
  );
131
  if ($view) {
132
+ $this->view = self::getView($view,
133
+ null,
134
  dirname($overrideControllerPath),
135
  $overrideContollerPrefix)
136
  // Push data into view.
139
  }
140
  }
141
  }
142
+
143
  /**
144
  * put your comment there...
145
+ *
146
  */
147
  public function _doAction() {
148
  // Force use of internal action untless its empty
149
  // then look for submitted action or get the default!
150
+ $action = $this->action ? $this->action :
151
  (isset($_GET['action']) ? $_GET['action'] : $this->defaultAction);
152
  // filter action name!
153
  $action = $this->ongetactionname($action);
159
  call_user_func($callback);
160
  }
161
  }
162
+
163
  /**
164
  * put your comment there...
165
+ *
166
  * @param mixed $name
167
  * @param mixed $hasView
168
  * @param mixed $request
169
  * @param mixed $overrideControllersPath
170
  * @param mixed $overrideControllersPrefix
171
  */
172
+ public static function create($name,
173
+ $hasView = null,
174
+ $request = null,
175
  $overrideControllersPath = null,
176
  $overrideControllersPrefix = null) {
177
  // Import controller file.
183
  // Instantiate controller class.
184
  return new $class($hasView, $request, $overrideControllersPath, $overrideControllersPrefix);
185
  }
186
+
187
  /**
188
  * put your comment there...
189
+ *
190
  * @deprecated Use cssJSToolbox::createSecurityToken
191
  */
192
  public function createSecurityToken() {
195
 
196
  /**
197
  * put your comment there...
198
+ *
199
  */
200
  protected function displayAction() {
201
  // Get view layout!
208
 
209
  /**
210
  * put your comment there...
211
+ *
212
  * @param mixed $name
213
  * @param mixed $hasView
214
  * @param mixed $request
215
  * @param mixed $overrideControllersPath
216
  */
217
  public static function getInstance($name,
218
+ $hasView = null,
219
+ $request = null,
220
  $overrideControllersPath = null,
221
  $overrideControllersPrefix = null) {
222
  return self::create($name, $hasView, $request, $overrideControllersPath, $overrideControllersPrefix);
223
  }
224
+
225
  /**
226
  * Use CJTModel::create instead.
227
+ *
228
  * @deprecated No longer used.
229
  */
230
+ public static function getModel($name,
231
+ $params = array(),
232
  $file = null,
233
  $overrideModelsPath = null,
234
  $overrideModelsPrefix = null) {
248
  $model = new $modelClass($params);
249
  return $model;
250
  }
251
+
252
  /**
253
  * @deprecated No longer used.
254
  */
267
  $className = self::trigger('CJTController.getclassname', "{$prefix}{$sanitizedName}", $name, $type);
268
  return $className;
269
  }
270
+
271
  /**
272
  * put your comment there...
273
+ *
274
  * @param mixed $name
275
  */
276
  public function getRequestParameter($name) {
277
+ return isset($this->request[$name]) ? $this->request[$name] : null;
278
  }
279
+
280
  /**
281
+ *
282
  * Use CJTView:create instrad.
283
+ *
284
  * @deprecated
285
  */
286
+ public static function getView($path,
287
+ $params = null,
288
+ $overrideViewsPath = null,
289
  $overrideViewsPrefix = null) {
290
  $view = null;
291
  // Import view file.
297
  $view = new $viewClass($viewInfo, $params);
298
  return $view;
299
  }
300
+
301
  /**
302
  * put your comment there...
303
+ *
304
  */
305
  public static function getViewInfo($path, $overrideViewsPath = null, $overrideViewsPrefix = null) {
306
  // Plugin views Url
307
+ $viewsUrl = $overrideViewsPath ?
308
  WP_PLUGIN_URL . '/' . basename(dirname($overrideViewsPath)) :
309
  CJTOOLBOX_VIEWS_URL;
310
  // Path to views dir.
322
  );
323
  return $viewInfo;
324
  }
325
+
326
  /**
327
  * put your comment there...
328
+ *
329
  * @param mixed $action
330
  */
331
  public function setAction($action) {
332
  $this->action = $action;
333
  return $this;
334
  }
335
+
336
  /**
337
  * put your comment there...
338
+ *
339
  * @param mixed $name
340
  * @param mixed $value
341
  */
343
  $this->request[$name] = $value;
344
  return $this;
345
  }
346
+
347
  } // End class.
348
 
349
  // Hookable!
readme.txt CHANGED
@@ -8,56 +8,40 @@ License URI: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
8
  Requires at least: 4.9 or higher
9
  Requires PHP: 7 or higher
10
  Tested up to: 5.7
11
- Stable tag: 11.3
12
 
13
- Add CSS, JavaScript, and even HTML and PHP to our unique code blocks, then choose exactly where you want the code to run. Supports Gutenberg.
 
14
 
15
  == Description ==
 
 
16
 
17
- Add CSS, JavaScript, and even HTML and PHP to our unique code blocks, then choose exactly where you want the code to run.
 
 
 
 
18
 
19
- ### WHY CJT? ###
20
- * Run your code on: Pages, Posts, Custom Posts, Tags, Categories
21
- * Run your code on common sections (e.g. Entire Website, Website Backend, All Pages, All Posts, Recent Posts, Blog Index, All Categories, Search Pages, All Archives, Tag Archives, Author Archives, Attachment Pages, 404 Error Pages)
22
- * Run your code via: URLs, or Regular Expressions (Regex)
23
- * Add front-end code without modifying your Theme files
24
- * Add functionality code without core file hacks or custom plugins
25
- * Embed scripts from GitHub, Code Canyon, JSFiddle, etc
26
- * Add visitor tracking, advertising and affiliate scripts
27
- * Embed social media channels or marketplace store widgets
28
- * Streamline your website development – whether solo or in a team
29
- * No need for FTP – just add your code, click save, see the change
30
 
31
  ### WHY GO PREMIUM? ###
 
 
 
 
 
 
 
 
32
 
33
- Our CJT PLUS premium plugin gives you more options, more tools, and more flexibility. [Click for CJT PLUS Mega Sale!!!](https://css-javascript-toolbox.com/pricing)
34
-
35
- ### BENEFITS OF CJT PLUS ###
36
- * NEW: 8 more Hooks added: Body Open, Before Post Content, After Post Content, Before Post, Excerpt, After Post Excerpt, Before Posts List, After Posts List, Before Post
37
- * NEW: Upgraded Code Block Toolbar
38
- * NEW: Upgraded Editor Toolbar
39
- * Add code blocks via Shortcodes (includes embedder)
40
- * Add code blocks via Widgets (e.g. for your sidebar or footer)
41
- * Add code blocks via Gutenberg blocks
42
- * Add code to Page/Post Metabox code blocks (Classic Editor)
43
- * Assignment Invert feature (e.g. run code everywhere but … )
44
- * Powerful editing with auto-formatting and syntax highlighting
45
- * Code beautify feature to tidy up your code
46
- * Code minify feature to compress code for performance
47
- * Light and dark editor themes to suits your style
48
- * Full-width and Full-screen modes for distraction-free editing
49
- * Code Auto Completion feature
50
- * Stacks of CSS, JS, PHP, and HTML code syntax or snippets
51
- * Revisions system to auto-backup your code blocks
52
- * Tested with over 100 code blocks and 1000’s of assignments
53
-
54
- We have kept the price very low for over 10 years, and with our mega sale on now, the price is even lower. [Click for CJT PLUS Mega Sale!!!](https://css-javascript-toolbox.com/pricing)
55
-
56
- ### WHAT'S NEW IN PLUS ###
57
- CJT and CJT PLUS used to only have two Hooks, one for the Header and the other for the Footer. We have added another 8 new Hooks for even more flexibility. For example, you may want to include an Ad script (e.g. Google AdSense Ads) before or after your Post Content. Before, you would have had to do workarounds with custom PHP code, or use cumbersome shortcodes in your post. Now this can be done automatically with Hooks.
58
-
59
- https://www.youtube.com/watch?v=aTq2wH16JNQ
60
 
 
 
61
 
62
  == Installation ==
63
  1. If you're upgrading from older versions its highly recommended to backup your database before upgrading.
@@ -65,82 +49,30 @@ https://www.youtube.com/watch?v=aTq2wH16JNQ
65
  3. Activate the plugin through the 'Plugins' menu in WordPress
66
  4. Click 'CSS & JavaScript Toolbox' link in the main navigation (left side of your Dashboard).
67
 
68
- == Frequently Asked Questions ==
69
- = Why was the CJT plugin developed and what is it used for? =
70
- The CJT plugin was created to help website authors write their own code. The plugin allows you to contribute to your Wordpress installation code via a simple web interface, where you can modify and extend the functionality and appearance of your website by writing code directly into CJT code blocks. A typical example of using the plugin can include changing the the way a specific Wordpress page is displayed, or making a page more interactive by adding some JavaScript (Dynamic HTML).
71
-
72
- = What is a CJT 'code block'? =
73
- The CJT code block is the basic unit for writing code and to associate it with specific Wordpress requests.
74
-
75
- = What is the Assignment Panel? =
76
- The Assignment Panel is a tabs window, which appears on the right side of the code block editor and is used to assign/apply the code block into specific requests.
77
-
78
- = Can you select more than one item from the Assignment Panel? =
79
- Yes. You can select any number of items you need, there is no limitation regarding this.
80
-
81
- = Can you assign multiple blocks to the same items from the Assignment Panel? =
82
- Yes. It's one of the most useful features that CJT supports as it allows you to manage/split your codes into several code blocks, allowing you to override code in a former (or lower ordered) code block.
83
-
84
- = What is Pages, Posts, Categories and Custom Posts tabs? =
85
- These lists with checkboxes represent all of your WordPress Pages, Posts, Categories and Custom Posts that your entire website contains. It also supports subpages and sub-categories, which you will also find in there.
86
-
87
- = What is the Auxiliary tab? =
88
- As there are a number of requests that are not available as normal Wordpress items (e.g. Pages, Posts, etc) but since it's commonly required and most likely be used, you will find them pre-defined in the Auxiliary tab. In the Auxiliary tab you can find pages like: Home, Blog Index, Author, 404 error, Tag, Archive, Entire website, Front-end, Admin backend and much more!
89
-
90
- = Is it better to use the URLs tab, or select items if found through other tabs? =
91
- Pages, Posts, Custom Posts and Categories tabs are created to simplify the assignment process for all types of users. Using URLs is great for fast performance as it requires less time to evaluate/identify the request! However, not all things can be done through the URLs tab. For example, applying a single block to a Category index page and all its sub-categories.
92
-
93
- = What is the Advanced Expressions tab? =
94
- The Advanced Expression tab allows you to fully control what requests to integrate into the code block by using Regular Expressions. In other words, allowing CJT users to define more requests to assign the code block to.
95
-
96
- = Can I move the blocks around? =
97
- Yes by hovering your mouse cursor over the code block title bar until it turns into a four-sided arrow, this allow you to move the blocks. Clicking the block title bar allows you to open and close the blocks.
98
-
99
- = Is block saved after I click 'Create' in 'Create New Code Block' form? =
100
- Yes. The block is created and saved in your database. In order to discard the block, you have to delete it.
101
-
102
- = Is block orders immediately saved after drag-and-drop block box? =
103
- No. In order to save blocks order you need to press 'Save All Changes' button.
104
-
105
- = Is block immediately deleted after removed from the blocks list page? =
106
- No. After delete block you need to click 'Save All Changes' button.
107
-
108
- = I'm using the URLs tab and my code is not working? =
109
- Make sure you have copied and pasted the Page, Post, or Category URL exactly as it appears in the address bar. For example, you may have inadvertently included an extra forward slash at the end of your URL.
110
-
111
- = Why use the Footer switch in Location/Hook? =
112
- Hook location feature gives you control over the location of outputting the CSS/JS code. This is useful in case overriding another plugins' CSS is required. Also sometimes its better to put your JS code in the footer to avoid slowing down your page load.
113
-
114
- = I received a weird error, what do I do now? =
115
- Due to the overwhelming amount of emails we get for users requesting support for our CJT plugins, we cannot provide support for the CJT Free plugin (hosted here on WordPress.org) at this stage unfortunately. If you wish to receive priority support, please visit our CJT website and [purchase a license for any of our products](https://css-javascript-toolbox.com/pricing).
116
-
117
  == Screenshots ==
118
- 1. Add your code, then assign where it goes
119
- 2. Create New Code Block dialog box
120
- 3. Master Admin Toolbar at top, and minimised Code Blocks below
121
- 4. Change editor language for syntax highlighting and error checking
122
- 5. Assigning WordPress Pages and sub-pages
123
- 6. Assigning WordPress Posts
124
- 7. Assigning Custom Posts
125
- 8. Assigning Categories and sub-categories
126
- 9. Auxiliary Assignments
127
- 10. Advanced Assignments (URLs and Regular Expressions)
128
- 11. Change State batch tools (CJT PLUS ONLY)
129
- 12. Change Location/Hook batch tools (CJT PLUS ONLY)
130
- 13. Delete and Backup Tools
131
- 14. Code-Files management within each Code Block (CJT PLUS ONLY)
132
- 15. Templates Manager form to store all of your Code Templates
133
- 16. Templates Lookup form to embed or link Code Templates to Code Blocks
134
- 17. Insert Code Block shortcodes via TinyMCE button (CJT PLUS ONLY)
135
- 18. Metabox Code Block at the Edit Page/Post level
136
- 19. Create backups of all your existing Code Blocks
137
- 20. Create/Restore Code Block revisions (CJT PLUS ONLY)
138
- 21. See Code Block information at a glance (CJT PLUS ONLY)
139
 
140
  == Changelog ==
 
 
 
 
141
  = 11.3 =
142
- * Fixed: URL Assignment tab is now working as expected.
143
- * Fixed: Inverter functionality was not being displayed in the frontend.
144
 
145
  = 11.2 =
146
  * Added: New links for CJT PLUS license validation
@@ -285,9 +217,9 @@ Fix: Fatal error: 'break' not in the 'loop' or 'switch' context in /path/to/wp-c
285
  * Feature: 'Load Local', 'Load Url' and 'Reload' to load Block Code from Local File, Url and Reload From Server respectively.
286
  * Feature: Save/Download Block Current Active Code File.
287
  * Feature: Undo, Redo, Find, Find Next, Find Previous, Replace, Goto Line, Goto Line Up, GoTo Line Down, GoTo Next Error, GoTo Previous Error, Fold, Fold All, UnFold, UnFold All, To Lower Case and To Upper Case Edit Menu functions added.
288
- * Feature: 'Settings' Edit Menu item for Fully Customize Code Editor Fonts, Show/Hide Print Margine, Keybinding Methods, Show/Hide Scroll, Scroll Speed, Readonly, Show/Hide Gutter, TAB Size, New Line Mode and much more!
289
  * Enhancement: Show/Hide StatusBar via View StatusBar Menu.
290
- * Enhancement: CJT Website is now support Full documentation Tutorials that expose many internal features/possibilities that can be achived by CJT.
291
  * Enhancement: Code Blocks disappeared after upgrading to Wordpress 3.9 and sever running PHP >= 5.5.
292
  * Enhancement: Packages Management System (BETA)
293
  * Enhancement: Define Shortcode Parameters by creating package and input their values from the CJT Shortcode Parameters form.
@@ -303,7 +235,7 @@ Fix: Fatal error: 'break' not in the 'loop' or 'switch' context in /path/to/wp-c
303
  * Remove: Block Revisions.
304
  * Remove: Blocks Backup and Restore.
305
  * Remove: Assignment Panel Select-Childs Checkboxes.
306
- * Remove: Minimize and Mazimize All.
307
  * Remove: Batch Process (Delete All and Delete Empty).
308
  * Remove: Output Location Switch (Header and Footer).
309
  * Remove: State Switch (Activate, Deactivate and Invert).
@@ -438,21 +370,6 @@ Fix: Fatal error: 'break' not in the 'loop' or 'switch' context in /path/to/wp-c
438
  * Launch: This is the very first release of CSS & JavaScript Toolbox
439
 
440
  == Upgrade Notice ==
441
- = 11.0 =
442
- * Added: 8 More Hooks (Body Open, Before Post Content, After Post Content, Before Post, Excerpt, After Post Excerpt, Before Posts List, After Posts List, Before Post
443
- * Enhancement: Assignments Panel
444
- * Enhancement: Templates Panel
445
- * Enhancement: Code Files Panel
446
- * Enhancement: Revisions Panel
447
- * Enhancement: Code Block Toolbar
448
- * Enhancement: Code Block InfoBar (added Shortcode copy feature)
449
- * Enhancement: Group Font Size Buttons
450
- * Enable/Disable: Toolbox menu when block is saved
451
- * Fix: Framework incompatibility version
452
- * Fix: Metabox Block InfoBar elements
453
- * Fix: Minifier was not working
454
- * Moved: Code Block Toolbar buttons
455
- * Moved: Code Block Toolbar editor menu (i.e. File, Edit, Settings) to Editor Toolbar as buttons
456
- * Removed: Clear Block (clears all Code Block code) Editor Toolbar button
457
- * Removed: Footer/Header All batch buttons
458
- * Show: Incompatible Hooks "Warning" Notice
8
  Requires at least: 4.9 or higher
9
  Requires PHP: 7 or higher
10
  Tested up to: 5.7
11
+ Stable tag: 11.4
12
 
13
+ Add CSS, JavaScript, HTML, PHP, and other content to your site.
14
+ Then choose exactly where on your site you want it to go.
15
 
16
  == Description ==
17
+ Add CSS, JavaScript, HTML, PHP, and other content to your site.
18
+ Then choose exactly where on your site you want it to go.
19
 
20
+ ### IDEAL FOR: ###
21
+ * Front-end modifications
22
+ * Adding functionality
23
+ * Adding widgets or code scripts
24
+ * Fast site development
25
 
26
+ ### FEATURES: ###
27
+ * Powerful code editor
28
+ * Assignment management system (choose where your code/content goes)
29
+ * Code/script library management
 
 
 
 
 
 
 
30
 
31
  ### WHY GO PREMIUM? ###
32
+ * Add code/content globally
33
+ * Add code/content via shortcodes, widgets, Gutenburg blocks, etc
34
+ * Add code/content via tags, URLs, regular expressions
35
+ * 8 additional hooks for more precise assignments
36
+ * Assignment invert feature (run code everywhere but...)
37
+ * More editor tools (code auto complete, beautify/minify, etc)
38
+ * Revisions system
39
+ * Backup and export/import system
40
 
41
+ [Click for Premium](https://css-javascript-toolbox.com/?utm_source=cjt_free_on_wordpress&utm_medium=readme_txt_description&utm_campaign=click_for_premium_link)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
+ ### OVERVIEW VIDEO ###
44
+ https://www.youtube.com/watch?v=vYAKePVgJqE
45
 
46
  == Installation ==
47
  1. If you're upgrading from older versions its highly recommended to backup your database before upgrading.
49
  3. Activate the plugin through the 'Plugins' menu in WordPress
50
  4. Click 'CSS & JavaScript Toolbox' link in the main navigation (left side of your Dashboard).
51
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52
  == Screenshots ==
53
+ 1. Code Block Editor
54
+ 2. Code Block Assignment Panel
55
+ 3. CJT Main Admin Toolbar
56
+ 4. Code Block Toolbar
57
+ 5. Code Block Editor Tools
58
+ 6. Assignment Panel for Pages
59
+ 7. Assignment Panel for Posts
60
+ 8. Assignment Panel for Categories
61
+ 9. Assignment Panel for Custom Posts
62
+ 10. Assignment Panel for Auxiliary Assignments
63
+ 11. Assignment Panel for Tags
64
+ 12. Assignment Panel for Advanced Assignments
65
+ 13. Assignment Panel Inverter
66
+ 14. Code Block Information
 
 
 
 
 
 
 
67
 
68
  == Changelog ==
69
+ = 11.4 =
70
+ * Removed: Auxiliary and Advanced tabs are removed for CJT new installs. Existing CJT users with active code blocks still get them
71
+ * Enhancement: All mouse hover-over popups are faster and more responsive
72
+
73
  = 11.3 =
74
+ * Fixed: URL Assignment tab is now working as expected
75
+ * Fixed: Inverter functionality was not being displayed in the frontend
76
 
77
  = 11.2 =
78
  * Added: New links for CJT PLUS license validation
217
  * Feature: 'Load Local', 'Load Url' and 'Reload' to load Block Code from Local File, Url and Reload From Server respectively.
218
  * Feature: Save/Download Block Current Active Code File.
219
  * Feature: Undo, Redo, Find, Find Next, Find Previous, Replace, Goto Line, Goto Line Up, GoTo Line Down, GoTo Next Error, GoTo Previous Error, Fold, Fold All, UnFold, UnFold All, To Lower Case and To Upper Case Edit Menu functions added.
220
+ * Feature: 'Settings' Edit Menu item for Fully Customize Code Editor Fonts, Show/Hide Print Margin, Keybinding Methods, Show/Hide Scroll, Scroll Speed, Readonly, Show/Hide Gutter, TAB Size, New Line Mode and much more!
221
  * Enhancement: Show/Hide StatusBar via View StatusBar Menu.
222
+ * Enhancement: CJT Website is now support Full documentation Tutorials that expose many internal features/possibilities that can be archived by CJT.
223
  * Enhancement: Code Blocks disappeared after upgrading to Wordpress 3.9 and sever running PHP >= 5.5.
224
  * Enhancement: Packages Management System (BETA)
225
  * Enhancement: Define Shortcode Parameters by creating package and input their values from the CJT Shortcode Parameters form.
235
  * Remove: Block Revisions.
236
  * Remove: Blocks Backup and Restore.
237
  * Remove: Assignment Panel Select-Childs Checkboxes.
238
+ * Remove: Minimize and Maximize All.
239
  * Remove: Batch Process (Delete All and Delete Empty).
240
  * Remove: Output Location Switch (Header and Footer).
241
  * Remove: State Switch (Activate, Deactivate and Invert).
370
  * Launch: This is the very first release of CSS & JavaScript Toolbox
371
 
372
  == Upgrade Notice ==
373
+ = 11.4 =
374
+ * Removed: Auxiliary and Advanced tabs are removed for CJT new installs. Existing CJT users with active code blocks still get them
375
+ * Enhancement: All mouse hover-over popups are faster and more responsive
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
views/blocks/block/public/css/block.css CHANGED
@@ -204,7 +204,18 @@ input[type="text"].block-name {
204
  .edit-block-toolbox a.cjttblSW-restore {
205
  background: url(../images/toolbox/restore.png);
206
  width: 50px !important;
207
- }
 
 
 
 
 
 
 
 
 
 
 
208
  .edit-block-toolbox a.cjttbl-cancel-restore {
209
  background: url(../images/toolbox/cancel-restore.png);
210
  background-position: left top !important;
@@ -221,7 +232,7 @@ input[type="text"].block-name {
221
  .edit-block-toolbox a.cjttblSW-restore,
222
  .edit-block-toolbox a.cjttbl-cancel-restore
223
  {
224
- width: 127px !important;
225
  text-align: center;
226
  padding-left: 0;
227
  padding-top: 4px;
@@ -264,6 +275,9 @@ input[type="text"].block-name {
264
  margin-left: 10px;
265
  display: none;
266
  }
 
 
 
267
 
268
  .cjt-toolbox.flagged-actions-toolbox {
269
  display: inline-block;
@@ -285,7 +299,7 @@ input[type="text"].block-name {
285
  input[type="text"].block-name {
286
  margin-left: 18px;
287
  }
288
- /* Edit Block name */
289
 
290
  .cjcontainer {/*min-width:700px;*/}
291
  .datablock {padding-top: 14px;}
@@ -308,7 +322,7 @@ input[type="text"].block-name {
308
  margin-top: -4px;
309
  padding: 0;
310
  }
311
-
312
  a.button-secondary { float:left; }
313
  .linklist textarea { width:245px; font-size:11px; height:190px; }
314
  .cjtitle { float:left; width:245px; }
@@ -323,7 +337,7 @@ body.fullscreen {overflow: hidden;} /** No scroll-bars */
323
  body.fullscreen #wpadminbar {display: none;} /** No admin menu */
324
  .postbox.fullscreen {
325
  position: fixed;
326
- z-index: 10000;
327
  top: 0px;
328
  left: 0px;
329
  width: 100%;
@@ -405,7 +419,7 @@ div[contains=setTheme]
405
  }
406
 
407
  .hooks-dropdown .hooks-dropdown-list li a:hover {
408
-
409
  }
410
  /* Hooks Dropdown - end */
411
 
@@ -432,9 +446,9 @@ div[contains=setTheme]
432
  .cjpageblock .cjt-panel-item>div {
433
  height: 93%;
434
  overflow: auto;
435
- width: 100%;
436
  }
437
-
438
  .postbox.cjt-block .cjt-info-bar a {
439
  font-weight: bold;
440
  }
@@ -482,4 +496,20 @@ div[contains=setTheme]
482
 
483
  .postbox.cjt-block form#block-revisions-form a:hover {
484
  color: #628ead !important;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
485
  }
204
  .edit-block-toolbox a.cjttblSW-restore {
205
  background: url(../images/toolbox/restore.png);
206
  width: 50px !important;
207
+ animation: blink-animation 1s steps(5, start) infinite;
208
+ }
209
+ @keyframes blink-animation {
210
+ to {
211
+ visibility: hidden;
212
+ }
213
+ }
214
+ @-webkit-keyframes blink-animation {
215
+ to {
216
+ visibility: hidden;
217
+ }
218
+ }
219
  .edit-block-toolbox a.cjttbl-cancel-restore {
220
  background: url(../images/toolbox/cancel-restore.png);
221
  background-position: left top !important;
232
  .edit-block-toolbox a.cjttblSW-restore,
233
  .edit-block-toolbox a.cjttbl-cancel-restore
234
  {
235
+ width: 100px !important;
236
  text-align: center;
237
  padding-left: 0;
238
  padding-top: 4px;
275
  margin-left: 10px;
276
  display: none;
277
  }
278
+ .cjt-toolbox.editor-toolbox.cjt-promo-disabled {
279
+ display: block;
280
+ }
281
 
282
  .cjt-toolbox.flagged-actions-toolbox {
283
  display: inline-block;
299
  input[type="text"].block-name {
300
  margin-left: 18px;
301
  }
302
+ /* Edit Block name */
303
 
304
  .cjcontainer {/*min-width:700px;*/}
305
  .datablock {padding-top: 14px;}
322
  margin-top: -4px;
323
  padding: 0;
324
  }
325
+
326
  a.button-secondary { float:left; }
327
  .linklist textarea { width:245px; font-size:11px; height:190px; }
328
  .cjtitle { float:left; width:245px; }
337
  body.fullscreen #wpadminbar {display: none;} /** No admin menu */
338
  .postbox.fullscreen {
339
  position: fixed;
340
+ z-index: 9990;
341
  top: 0px;
342
  left: 0px;
343
  width: 100%;
419
  }
420
 
421
  .hooks-dropdown .hooks-dropdown-list li a:hover {
422
+
423
  }
424
  /* Hooks Dropdown - end */
425
 
446
  .cjpageblock .cjt-panel-item>div {
447
  height: 93%;
448
  overflow: auto;
449
+ width: 100%;
450
  }
451
+
452
  .postbox.cjt-block .cjt-info-bar a {
453
  font-weight: bold;
454
  }
496
 
497
  .postbox.cjt-block form#block-revisions-form a:hover {
498
  color: #628ead !important;
499
+ }
500
+
501
+ .postbox.cjt-block .cjt-toolbox .icons-group li.cjt-promo-disabled a {
502
+ color: #cccccc !important;
503
+ cursor: help;
504
+ }
505
+ .postbox.cjt-block .cjt-toolbox .icons-group li.cjt-promo-disabled a:hover {
506
+ color: #cccccc !important;
507
+ }
508
+
509
+ .cjt-toolbox.block-toolbox .cjt-promo-disabled .cjt-tb-link.cjt-tb-text-link {
510
+ color: #cccccc !important;
511
+ cursor: help;
512
+ }
513
+ .postbox.cjt-block .cjt-toolbox.cjt-info-bar .icons-group .cjt-promo-disabled a:hover {
514
+ color: #cccccc !important;
515
  }
views/blocks/block/public/images/toolbox/cancel-restore.png CHANGED
Binary file
views/blocks/block/public/images/toolbox/restore.png CHANGED
Binary file
views/blocks/block/public/js/jquery.block/jquery.block.js CHANGED
@@ -63,7 +63,7 @@
63
  // Get list elements jQuery object
64
  listValueElement = $this.find('.value>a');
65
  listElement = $this.find('.hooks-dropdown-list');
66
- listElements = listElement.find('li');
67
 
68
  listValueElement.click(
69
 
@@ -388,7 +388,7 @@
388
  var assignPanel = this.block.box.find('.cjt-panel-item.cjt-panel-window-assignments');
389
  var panelWnds = this.block.box.find('.cjt-panel-item');
390
 
391
- // Make sure all panel windows are hidden
392
  panelWnds.hide();
393
 
394
  // Always display the assignment panel
@@ -486,7 +486,7 @@
486
  var genericPanelWindow = $('.cjpageblock .cjt-panel-genericwnd');
487
 
488
  genericPanelWindow
489
- .empty()
490
  .append('<iframe style="width:100%;height:100%;" src="' + url + '"></iframe>');
491
 
492
  this._onPaneledItems(event);
@@ -1282,7 +1282,7 @@
1282
  function(content) {
1283
 
1284
  genericPanelWindow
1285
- .empty()
1286
  .append(content);
1287
 
1288
  this._onPaneledItems(event);
63
  // Get list elements jQuery object
64
  listValueElement = $this.find('.value>a');
65
  listElement = $this.find('.hooks-dropdown-list');
66
+ listElements = listElement.find('li:not(.cjt-promo-disabled)');
67
 
68
  listValueElement.click(
69
 
388
  var assignPanel = this.block.box.find('.cjt-panel-item.cjt-panel-window-assignments');
389
  var panelWnds = this.block.box.find('.cjt-panel-item');
390
 
391
+ // Make sure all panel windows are hidden
392
  panelWnds.hide();
393
 
394
  // Always display the assignment panel
486
  var genericPanelWindow = $('.cjpageblock .cjt-panel-genericwnd');
487
 
488
  genericPanelWindow
489
+ .empty()
490
  .append('<iframe style="width:100%;height:100%;" src="' + url + '"></iframe>');
491
 
492
  this._onPaneledItems(event);
1282
  function(content) {
1283
 
1284
  genericPanelWindow
1285
+ .empty()
1286
  .append(content);
1287
 
1288
  this._onPaneledItems(event);
views/blocks/block/public/js/optional/revision/revision.js CHANGED
@@ -1,41 +1,41 @@
1
  /**
2
- *
3
  */
4
 
5
  var CJTBlockOptionalRevisionBase = null;
6
 
7
  /**
8
- *
9
  */
10
  (function($) {
11
-
12
  /**
13
  * put your comment there...
14
- *
15
  */
16
  CJTBlockOptionalRevisionBase = function() {
17
-
18
  /**
19
  * put your comment there...
20
- *
21
  * @type Boolean
22
  */
23
  this.block;
24
 
25
  /**
26
- *
27
  */
28
  this.original;
29
-
30
  /**
31
  * put your comment there...
32
- *
33
  * @type Boolean
34
  */
35
  this.revision;
36
 
37
  /**
38
- *
39
  */
40
  this.state;
41
 
@@ -43,20 +43,20 @@ var CJTBlockOptionalRevisionBase = null;
43
  * Switch state event
44
  */
45
  this.onBeforeSwitchState;
46
-
47
  /**
48
  * Switch state event
49
  */
50
  this.onDoneRestore;
51
-
52
  /**
53
  * Switch state event
54
  */
55
  this.onSwitchState;
56
-
57
  /**
58
  * put your comment there...
59
- *
60
  */
61
  this.CJTBlockOptionalRevisionBase = function(block, revision) {
62
  // Initialize instance.
@@ -71,9 +71,9 @@ var CJTBlockOptionalRevisionBase = null;
71
  }
72
 
73
  /**
74
- *
75
  */
76
- this.cancel = function() {
77
  // Initialize
78
  var block = this.block;
79
  var toolbox = block.toolbox;
@@ -96,13 +96,13 @@ var CJTBlockOptionalRevisionBase = null;
96
  );
97
  // Remove cancel button.
98
  editBlockToolbox.remove('cancel-restore');
99
-
100
  // Enable block components.
101
  block.enable(true);
102
  toolbox.enable(true);
103
  editBlockToolbox.enable(true);
104
  flaggedActionsToolbox.enable(true);
105
-
106
  // Set notification changes back.
107
  block.changes = this.original.changes;
108
  var isChanged = CJTBlocksPage.blocks.calculateChanges(block.changes, 0, false);
@@ -118,11 +118,15 @@ var CJTBlockOptionalRevisionBase = null;
118
  // Notify blocks page.
119
  CJTBlocksPage.blockContentChanged(block.block.id, isChanged);
120
  // Change state / Enter revision mode.
121
- this.onSwitchState(this.state = null);
 
 
 
 
122
  }
123
-
124
  /**
125
- *
126
  */
127
  this.display = function() {
128
  // Initialize.
@@ -134,7 +138,7 @@ var CJTBlockOptionalRevisionBase = null;
134
  var mdlBlock = block.block;
135
  var properties = block.features.restoreRevision.fields;
136
  var pom;
137
-
138
  // Before switch state event.
139
  this.onBeforeSwitchState();
140
  // Cache 'Changes' array, don't reference it from block.changes
@@ -155,13 +159,13 @@ var CJTBlockOptionalRevisionBase = null;
155
  block.changes = [];
156
  // Force Notification Changes to detect that current block has changes.
157
  CJTBlocksPage.blockContentChanged(mdlBlock.get('id'), true);
158
-
159
  // DISABLE-ALL toolbox buttons
160
  toolbox.enable(false); flaggedActionsToolbox.enable(false);
161
-
162
  // Hide all Panel Windows and Display only Asisgnment panel window
163
- block._onclosepanelwindow({target : block.block.box.find('.cjpageblock .close-panel-window')});
164
-
165
  // Except save button!
166
  saveButton.enable(true);
167
  saveButton._callback = saveButton.callback;
@@ -172,23 +176,25 @@ var CJTBlockOptionalRevisionBase = null;
172
  // Reflect new style
173
  .addClass('cjttblSW-restore');
174
  // Add cancel restore button.
175
- $('<a href="#" class="cjt-tb-link cjttbl-cancel-restore il-60x23"></a>')
176
- .text('Cancel')
177
- .insertBefore(saveButton.jButton);
 
 
178
  editBlockToolbox.add('cancel-restore', {callback : $.proxy(this.cancel, this)});
179
  // Disable block.
180
  block.enable(false);
181
  // Change state / Enter revision mode.
182
  this.onSwitchState(this.state = 'revision');
183
  }
184
-
185
  /**
186
- *
187
  */
188
  this.restore = function() {
189
  // Initialize.
190
  var block = this.block;
191
- var saveButton = block.editBlockActionsToolbox.buttons['save'];
192
  var server = CJTBlocksPage.server;
193
  var request = {rid : this.revision['id'], bid : block.block.get('id')};
194
  // Restore revision via server.
@@ -219,7 +225,7 @@ var CJTBlockOptionalRevisionBase = null;
219
  }, this)
220
  );
221
  }
222
-
223
  } // End Prototype.
224
 
225
  })(jQuery);
1
  /**
2
+ *
3
  */
4
 
5
  var CJTBlockOptionalRevisionBase = null;
6
 
7
  /**
8
+ *
9
  */
10
  (function($) {
11
+
12
  /**
13
  * put your comment there...
14
+ *
15
  */
16
  CJTBlockOptionalRevisionBase = function() {
17
+
18
  /**
19
  * put your comment there...
20
+ *
21
  * @type Boolean
22
  */
23
  this.block;
24
 
25
  /**
26
+ *
27
  */
28
  this.original;
29
+
30
  /**
31
  * put your comment there...
32
+ *
33
  * @type Boolean
34
  */
35
  this.revision;
36
 
37
  /**
38
+ *
39
  */
40
  this.state;
41
 
43
  * Switch state event
44
  */
45
  this.onBeforeSwitchState;
46
+
47
  /**
48
  * Switch state event
49
  */
50
  this.onDoneRestore;
51
+
52
  /**
53
  * Switch state event
54
  */
55
  this.onSwitchState;
56
+
57
  /**
58
  * put your comment there...
59
+ *
60
  */
61
  this.CJTBlockOptionalRevisionBase = function(block, revision) {
62
  // Initialize instance.
71
  }
72
 
73
  /**
74
+ *
75
  */
76
+ this.cancel = function () {
77
  // Initialize
78
  var block = this.block;
79
  var toolbox = block.toolbox;
96
  );
97
  // Remove cancel button.
98
  editBlockToolbox.remove('cancel-restore');
99
+
100
  // Enable block components.
101
  block.enable(true);
102
  toolbox.enable(true);
103
  editBlockToolbox.enable(true);
104
  flaggedActionsToolbox.enable(true);
105
+
106
  // Set notification changes back.
107
  block.changes = this.original.changes;
108
  var isChanged = CJTBlocksPage.blocks.calculateChanges(block.changes, 0, false);
118
  // Notify blocks page.
119
  CJTBlocksPage.blockContentChanged(block.block.id, isChanged);
120
  // Change state / Enter revision mode.
121
+ this.onSwitchState( this.state = null );
122
+ }
123
+
124
+ this.dem = function () {
125
+ // keep empty to keep revision window open
126
  }
127
+
128
  /**
129
+ *
130
  */
131
  this.display = function() {
132
  // Initialize.
138
  var mdlBlock = block.block;
139
  var properties = block.features.restoreRevision.fields;
140
  var pom;
141
+
142
  // Before switch state event.
143
  this.onBeforeSwitchState();
144
  // Cache 'Changes' array, don't reference it from block.changes
159
  block.changes = [];
160
  // Force Notification Changes to detect that current block has changes.
161
  CJTBlocksPage.blockContentChanged(mdlBlock.get('id'), true);
162
+
163
  // DISABLE-ALL toolbox buttons
164
  toolbox.enable(false); flaggedActionsToolbox.enable(false);
165
+
166
  // Hide all Panel Windows and Display only Asisgnment panel window
167
+ block._onclosepanelwindow = this.dem;
168
+
169
  // Except save button!
170
  saveButton.enable(true);
171
  saveButton._callback = saveButton.callback;
176
  // Reflect new style
177
  .addClass('cjttblSW-restore');
178
  // Add cancel restore button.
179
+ if ( $( '.cjt-tb-link.cjttbl-cancel-restore.il-60x23' ).length <= 0 ) {
180
+ $('<a href="#" class="cjt-tb-link cjttbl-cancel-restore il-60x23"></a>')
181
+ .text('Cancel')
182
+ .insertBefore(saveButton.jButton);
183
+ }
184
  editBlockToolbox.add('cancel-restore', {callback : $.proxy(this.cancel, this)});
185
  // Disable block.
186
  block.enable(false);
187
  // Change state / Enter revision mode.
188
  this.onSwitchState(this.state = 'revision');
189
  }
190
+
191
  /**
192
+ *
193
  */
194
  this.restore = function() {
195
  // Initialize.
196
  var block = this.block;
197
+ var saveButton = block.editBlockActionsToolbox.buttons['save'];
198
  var server = CJTBlocksPage.server;
199
  var request = {rid : this.revision['id'], bid : block.block.get('id')};
200
  // Restore revision via server.
225
  }, this)
226
  );
227
  }
228
+
229
  } // End Prototype.
230
 
231
  })(jQuery);
views/blocks/block/tmpl/templates/editor-toolbox.html.tmpl CHANGED
@@ -1,9 +1,70 @@
1
  <?php
 
2
  /**
3
- *
4
- */
5
 
6
  // Disallow direct access.
7
  defined('ABSPATH') or die('Restricted Access');
8
  ?>
9
- <div class="cjt-toolbox editor-toolbox"><div class="icons-group"></div></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+
3
  /**
4
+ *
5
+ */
6
 
7
  // Disallow direct access.
8
  defined('ABSPATH') or die('Restricted Access');
9
  ?>
10
+ <div class="cjt-toolbox editor-toolbox <?php echo !class_exists('CJTPlus') ? 'cjt-promo-disabled' : ''; ?>">
11
+ <div class="icons-group">
12
+ <?php if (!class_exists('CJTPlus')) : ?>
13
+ <a href="#" class="cjt-tb-link cjttbl-toggle-objects-panel" title="Switch code editor to fullwidth mode (hides assignment panel)"></a>
14
+ <a href="#" class="cjt-tb-link cjttbl-fullscreen" title="Switch code editor to fullscreen mode"></a>
15
+ <ul class="block-toolbox-menu block-menu ui-menu ui-widget ui-widget-content" id="ui-id-12" role="menu" tabindex="0">
16
+ <li class="ui-menu-item">
17
+ <a href="#file" class="toolbox-menu-file ui-menu-item-wrapper" aria-haspopup="true" id="ui-id-13" tabindex="-1" role="menuitem" title="Allows you to perform useful functions such as saving the code as a text file"><span class="ui-menu-icon ui-icon ui-icon-caret-1-e"></span></a>
18
+ <ul role="menu" aria-hidden="true" aria-expanded="false" class="ui-menu ui-widget ui-widget-content ui-front" style="display: none; background-color: rgb(255, 255, 255);">
19
+ <li id="cjteet-menu-file-reload" class="ui-menu-item"><a href="#load" title="Reload code file from server" id="ui-id-14" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">ReLoad</a></li>
20
+ <li id="cjteet-menu-file-loadfile" class="ui-menu-item"><a href="#load-file" title="Load local file into Editor" id="ui-id-15" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Load Local</a></li>
21
+ <li id="cjteet-menu-file-loadurl" class="ui-menu-item"><a href="#load-url" title="Load Url into Editor" id="ui-id-16" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Load Url</a></li>
22
+ <li class="ui-menu-divider ui-widget-content"></li>
23
+ <li id="cjteet-menu-file-save" class="ui-menu-item"><a href="#save" title="Save Code File" id="ui-id-17" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Save</a></li>
24
+ <li id="cjteet-menu-file-savefile" class="ui-menu-item"><a href="#save-file" title="Save Editor into local file" id="ui-id-18" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Save File</a></li>
25
+ <li class="ui-menu-divider ui-widget-content"></li>
26
+ <li id="cjteet-menu-file-delete" class="ui-menu-item"><a href="#deleteobject" title="Delete code unit" id="ui-id-19" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Delete</a></li>
27
+ </ul>
28
+ </li>
29
+ <li class="ui-menu-item">
30
+ <a href="#edit" class="toolbox-menu-edit ui-menu-item-wrapper" aria-haspopup="true" id="ui-id-20" tabindex="-1" role="menuitem" title="Bunch of cool code editor tools like undo, redo, find and replace, go to line, go to next error, and much more"><span class="ui-menu-icon ui-icon ui-icon-caret-1-e"></span></a>
31
+ <ul role="menu" aria-hidden="true" aria-expanded="false" class="ui-menu ui-widget ui-widget-content ui-front" style="display: none; background-color: rgb(255, 255, 255);">
32
+ <li class="ui-menu-item"><a href="#ace-undo" title="Undo changes" id="ui-id-21" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Undo</a></li>
33
+ <li class="ui-menu-item"><a href="#ace-redo" title="Redo changes" id="ui-id-22" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Redo</a></li>
34
+
35
+ <li class="ui-menu-item"><a href="#ace-find" title="Find all occurance of string" id="ui-id-23" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Find</a></li>
36
+ <li class="ui-menu-item"><a href="#ace-findnext" title="Find next occurance of string" id="ui-id-24" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Find Next</a></li>
37
+ <li class="ui-menu-item"><a href="#ace-findprevious" title="Find previous occurance of string" id="ui-id-25" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Find Previous</a></li>
38
+
39
+ <li class="ui-menu-item"><a href="#ace-replace" title="Replace all occurance of string with another string" id="ui-id-26" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Replace</a></li>
40
+
41
+ <li class="ui-menu-item"><a href="#ace-gotoline" title="Quickly go to line specified by number" id="ui-id-27" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Go To Line</a></li>
42
+ <li class="ui-menu-item"><a href="#ace-golineup" title="Move Editor cusror to next line" id="ui-id-28" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Go Line Up</a></li>
43
+ <li class="ui-menu-item"><a href="#ace-golinedown" title="Move Editor cusrsor to previous line" id="ui-id-29" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Go Line down</a></li>
44
+
45
+ <li class="ui-menu-item"><a href="#ace-goToNextError" id="ui-id-30" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Go To Next Error</a></li>
46
+ <li class="ui-menu-item"><a href="#ace-goToPreviousError" id="ui-id-31" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Go To Previous Error</a></li>
47
+
48
+ <li class="ui-menu-item"><a href="#ace-fold" title="Fold selected code units/blocks" id="ui-id-32" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Fold</a></li>
49
+ <li class="ui-menu-item"><a href="#ace-foldall" title="Fold all code units/blocks" id="ui-id-33" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Fold All</a></li>
50
+ <li class="ui-menu-item"><a href="#ace-unfold" title="UnFold selected code units/blocks" id="ui-id-34" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">UnFold</a></li>
51
+ <li class="ui-menu-item"><a href="#ace-unfoldall" title="UnFold all code units/blocks" id="ui-id-35" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">UnFold All</a></li>
52
+
53
+ <li class="ui-menu-item"><a href="#ace-tolowercase" title="Turns selected text into Lowercase characters" id="ui-id-36" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">To Lower Case</a></li>
54
+ <li class="ui-menu-item"><a href="#ace-touppercase" title="Turns selected text into Uppercase characters" id="ui-id-37" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">To Upper Case</a></li>
55
+
56
+ <li class="ui-menu-item"><a href="#ace-showSettingsMenu" title="Set Editor Settings/Options" id="ui-id-38" tabindex="-1" role="menuitem" class="ui-menu-item-wrapper">Settings</a></li>
57
+ </ul>
58
+ </li>
59
+ <li class="ui-menu-item">
60
+ <a href="#aceSettingsMenu-view" class="toolbox-menu-settings ui-menu-item-wrapper" id="ui-id-39" tabindex="-1" role="menuitem" title="Choose from over 32 adjustment settings to fine-tune your code editor to just the way you like it"><span>S</span></a>
61
+ </li>
62
+ </ul>
63
+ <a href="#" class="cjt-tb-link cjttbl-editor-theme" title="Choose from 32 editor themes for changing the editor background colour, syntax highlighting colour, and more"></a>
64
+ <a href="#" class="cjt-tb-link cjttbl-beautify" title="Beautifies your code to make it perfectly formatted. Great for code readability"></a>
65
+ <a href="#" class="cjt-tb-link cjttbl-minify" title="Minifies your code by removing white space. Great for code optimisation"></a>
66
+ <a href="#" class="cjt-tb-link cjttbl-fonts" title="Increase the font size; decrease the font size; or reset the font-size for the code editor"></a>
67
+ <a href="#" class="cjt-tb-link cjttbl-save-editor-options" title="Save any adjustments you made in the code editor settings?"></a>
68
+ <?php endif; ?>
69
+ </div>
70
+ </div>
views/blocks/block/tmpl/templates/toolbox.html.tmpl CHANGED
@@ -1,134 +1,144 @@
1
  <?php
2
 
3
- $hooksAttacher =& CJTBlocksCouplingController::theInstance()->getHooksAttacher();
4
-
5
- extract($this->getHookStatus());
6
-
 
 
 
7
  ?>
8
 
9
- <?php $this->ontoolbox($this); // Trigger On Toolbox Hook ?>
10
-
11
- <div class="cjt-toolbox flagged-actions-toolbox">
12
-
13
- <div class="icons-group">
14
- <?php do_action( CJTPluggableHelper::ACTION_BLOCK_TOOLBOX_TEMPLATE_INSIDE_BEFORE_FLAGS, $this ); ?>
15
- <a href="#" class="cjt-tb-link cjttbl-state-switch state-<?php echo $this->block->state ?>" title="<?php echo $this->localization["state_{$this->block->state}Title"] ?>"></a>
16
- <?php do_action( CJTPluggableHelper::ACTION_BLOCK_TOOLBOX_TEMPLATE_INSIDE_AFTER_FLAGS, $this ); ?>
17
- </div>
18
-
19
- </div>
20
-
21
- <div class="cjt-toolbox edit-block-toolbox">
22
-
23
- <div class="icons-group">
24
-
25
- <a href="#" class="cjt-tb-link cjttbl-save il-60x23" title="<?php echo cssJSToolbox::getText('Save changes to code block') ?>"><?php echo cssJSToolbox::getText('Save') ?></a>
26
- <a href="#" class="cjt-tb-link cjttbl-delete" title="<?php echo cssJSToolbox::getText('Delete code block') ?>"></a>
27
-
28
- </div>
29
-
30
- </div>
31
-
32
- <div class="cjt-info-bar cjt-info-bar-top cjt-toolbox block-toolbox">
33
-
34
- <div class="cjt-toolbox editor-langs-toolbox">
35
-
36
- <div class="icons-group big-bar">
37
-
38
- <span class="block-id">
39
- <span class="infobar-item-title"><?php echo cssJSToolbox::getText('Block ID:') ?> </span>
40
- <a href="#info" class="cjt-tb-link cjt-tb-text-link cjttbl-block-info"><?php echo $this->block->id; ?></a>
41
- </span>
42
-
43
- <div class="block-hook">
44
-
45
- <span class="infobar-item-title <?php echo $badLocationClass ?>"><?php echo cssJSToolbox::getText('Hook:') ?> </span>
46
-
47
- <a href="#" class="cjt-tb-link cjt-tb-text-link cjttbl-location-switch location-<?php echo $this->block->location ?> <?php echo $badLocationClass ?>" title="<?php echo $locationText ?>"><?php echo $locationTitle ?></a>
48
- <div class="popup-menu hooks-dropdown" style="display:none">
49
-
50
- <ul class="hooks-dropdown-list">
51
-
52
- <?php
53
-
54
- foreach($hooksAttacher->getFiltersList() as $hooks) :
55
-
56
- foreach ($hooks as $hook) :
57
-
58
- $isSelected = ($this->block->location == $hook['locationName']) ? "class='selected'" : '';
59
-
60
- ?>
61
-
62
- <li <?php echo $isSelected ?>>
63
-
64
- <a href="#<?php echo $hook['locationName'] ?>" title="<?php echo $hook['text'] ?>"><?php echo $hook['title'] ?></a>
65
-
66
- </li>
67
-
68
- <?php endforeach; ?>
69
-
70
- <?php endforeach; ?>
71
-
72
- </ul>
73
-
74
- </div>
75
-
76
- </div>
77
-
78
- <div class="block-editor-lang">
79
- <span class="infobar-item-title"><?php echo cssJSToolbox::getText('Editor:') ?> </span>
80
-
81
- <a href="#" class="cjt-tb-link cjt-tb-text-link cjttbl-switch-editor-language" title="<?php echo cssJSToolbox::getText('Set editing language for syntax highlighting') ?>">
82
- <?php echo $this->block->file->type ? $this->block->file->type : 'PHP' ?>
83
- </a>
84
-
85
- <div class="popup-menu editor-langs" style="display:none">
86
- <a href="#" class="cjt-tb-link cjt-tb-text-link cjttbl-editor-language-css" title="<?php echo cssJSToolbox::getText('Set editing language to CSS') ?>"><?php echo cssJSToolbox::getText('CSS') ?></a>
87
- <a href="#" class="cjt-tb-link cjt-tb-text-link cjttbl-editor-language-html" title="<?php echo cssJSToolbox::getText('Set editing language to HTML') ?>"><?php echo cssJSToolbox::getText('HTML') ?></a>
88
- <a href="#" class="cjt-tb-link cjt-tb-text-link cjttbl-editor-language-javascript" title="<?php echo cssJSToolbox::getText('Set editing language to JavaScript') ?>"><?php echo cssJSToolbox::getText('JavaScript') ?></a>
89
- <a href="#" class="cjt-tb-link cjt-tb-text-link cjttbl-editor-language-php" title="<?php echo cssJSToolbox::getText('Set editing language to PHP') ?>"><?php echo cssJSToolbox::getText('PHP') ?></a>
90
- </div>
91
-
92
- </div>
93
-
94
- <span class="block-assignment-count">
95
- <span class="infobar-item-title"><?php echo cssJSToolbox::getText('Assignments:') ?> </span>
96
- <strong>
97
- <a class="cjt-tb-link cjt-tb-text-link cjttbl-assignment-info show-assignment-info" href="#assignment-info">
98
- <?php echo count( $this->getAllAssignments() ); ?>
99
- </a>
100
- </strong>
101
- </span>
102
-
103
- <div class="templates-info">
104
- <span class="infobar-item-title"><?php echo cssJSToolbox::getText('Templates') ?> </span>
105
-
106
- <a href="#templates" class="cjt-tb-link cjt-tb-text-link cjttbl-templates" title="<?php echo cssJSToolbox::getText('Template Lookup - Embed or link templates to code blocks') ?>">
107
- <?php echo CJTBlockTemplatesModel::getLinkedTemplatesCount($this->block->id) ?>
108
- </a>
109
- <div class="popup-menu templates" style="display:none">
110
- <?php // FILTER MAY BE ?>
111
- <a href="#templates-lookup" class="cjt-tb-link cjt-tb-text-link cjttbl-templates-lookup" title="">
112
- <?php echo cssJSToolbox::getText('Embed / Link Templates') ?>
113
- </a>
114
- <?php do_action(CJTPluggableHelper::ACTION_BLOCK_INSIDE_TOOLBOX_TEMPLATES_MENU, $this) ?>
115
- <a href="#templates-manager" class="cjt-tb-link cjt-tb-text-link cjttbl-templates-manager" title="">
116
- <?php echo cssJSToolbox::getText('Templates Manager') ?>
117
- </a>
118
- <?php // FILTER MAY BE ?>
119
- </div>
120
-
121
- </div>
122
-
123
- <span class="block-code-files">
124
- <span class="infobar-item-title"><?php echo cssJSToolbox::getText('Files:') ?> </span>
125
- <a href="#code-files" class="cjt-tb-link cjt-tb-text-link cjttbl-code-files"><?php echo CJTBlocksModel::getCodeFilesCount($this->block->id) ?></a>
126
- </span>
127
-
128
- <?php do_action(CJTPluggableHelper::ACTION_BLOCK_INFO_BAR_TOP_END, $this) ?>
129
-
130
- </div>
131
-
132
- </div>
133
-
134
- </div>
 
 
 
 
 
 
 
1
  <?php
2
 
3
+ $hooksAttacher = &CJTBlocksCouplingController::theInstance()->getHooksAttacher();
4
+
5
+ extract($this->getHookStatus());
6
+
7
+ ?>
8
+
9
+ <?php $this->ontoolbox($this); // Trigger On Toolbox Hook
10
  ?>
11
 
12
+ <div class="cjt-toolbox flagged-actions-toolbox">
13
+
14
+ <div class="icons-group">
15
+ <?php do_action(CJTPluggableHelper::ACTION_BLOCK_TOOLBOX_TEMPLATE_INSIDE_BEFORE_FLAGS, $this); ?>
16
+ <a href="#" class="cjt-tb-link cjttbl-state-switch state-<?php echo $this->block->state ?>" title="<?php echo $this->localization["state_{$this->block->state}Title"] ?>"></a>
17
+ <?php do_action(CJTPluggableHelper::ACTION_BLOCK_TOOLBOX_TEMPLATE_INSIDE_AFTER_FLAGS, $this); ?>
18
+ </div>
19
+
20
+ </div>
21
+
22
+ <div class="cjt-toolbox edit-block-toolbox">
23
+
24
+ <div class="icons-group">
25
+
26
+ <a href="#" class="cjt-tb-link cjttbl-save il-60x23" title="<?php echo cssJSToolbox::getText('Save changes to code block') ?>"><?php echo cssJSToolbox::getText('Save') ?></a>
27
+ <a href="#" class="cjt-tb-link cjttbl-delete" title="<?php echo cssJSToolbox::getText('Delete code block') ?>"></a>
28
+
29
+ </div>
30
+
31
+ </div>
32
+
33
+ <div class="cjt-info-bar cjt-info-bar-top cjt-toolbox block-toolbox">
34
+
35
+ <div class="cjt-toolbox editor-langs-toolbox">
36
+
37
+ <div class="icons-group big-bar">
38
+
39
+ <span class="block-id">
40
+ <span class="infobar-item-title"><?php echo cssJSToolbox::getText('Block ID:') ?> </span>
41
+ <a href="#info" class="cjt-tb-link cjt-tb-text-link cjttbl-block-info"><?php echo $this->block->id; ?></a>
42
+ </span>
43
+
44
+ <div class="block-hook">
45
+
46
+ <span class="infobar-item-title <?php echo $badLocationClass ?>"><?php echo cssJSToolbox::getText('Hook:') ?> </span>
47
+
48
+ <a href="#" class="cjt-tb-link cjt-tb-text-link cjttbl-location-switch location-<?php echo $this->block->location ?> <?php echo $badLocationClass ?>" title="<?php echo $locationText ?>"><?php echo $locationTitle ?></a>
49
+ <div class="popup-menu hooks-dropdown" style="display:none">
50
+
51
+ <ul class="hooks-dropdown-list">
52
+
53
+ <?php
54
+
55
+ foreach ($hooksAttacher->getFiltersList() as $hooks) :
56
+
57
+ foreach ($hooks as $hook) :
58
+
59
+ $isSelected = ($this->block->location == $hook['locationName']) ? 'selected' : '';
60
+ $isDisabled = isset($hook['disabled']) && (bool) $hook['disabled'] === true && !class_exists('CJTPlus') ? 'cjt-promo-disabled' : '';
61
+ $listClass = empty($isSelected) && empty($isDisabled) ? '' : 'class=' . $isSelected . ' ' . $isDisabled;
62
+ ?>
63
+
64
+ <li <?php echo $listClass; ?>>
65
+
66
+ <a <?php echo empty($isDisabled) ? 'href="#' . $hook['locationName'] . '"' : ''; ?> title="<?php echo $hook['text'] ?>"><?php echo $hook['title'] ?></a>
67
+ </li>
68
+
69
+ <?php endforeach; ?>
70
+
71
+ <?php endforeach; ?>
72
+
73
+ </ul>
74
+
75
+ </div>
76
+
77
+ </div>
78
+
79
+ <div class="block-editor-lang">
80
+ <span class="infobar-item-title"><?php echo cssJSToolbox::getText('Editor:') ?> </span>
81
+
82
+ <a href="#" class="cjt-tb-link cjt-tb-text-link cjttbl-switch-editor-language" title="<?php echo cssJSToolbox::getText('Set editing language for syntax highlighting') ?>">
83
+ <?php echo $this->block->file->type ? $this->block->file->type : 'PHP' ?>
84
+ </a>
85
+
86
+ <div class="popup-menu editor-langs" style="display:none">
87
+ <a href="#" class="cjt-tb-link cjt-tb-text-link cjttbl-editor-language-css" title="<?php echo cssJSToolbox::getText('Set editing language to CSS') ?>"><?php echo cssJSToolbox::getText('CSS') ?></a>
88
+ <a href="#" class="cjt-tb-link cjt-tb-text-link cjttbl-editor-language-html" title="<?php echo cssJSToolbox::getText('Set editing language to HTML') ?>"><?php echo cssJSToolbox::getText('HTML') ?></a>
89
+ <a href="#" class="cjt-tb-link cjt-tb-text-link cjttbl-editor-language-javascript" title="<?php echo cssJSToolbox::getText('Set editing language to JavaScript') ?>"><?php echo cssJSToolbox::getText('JavaScript') ?></a>
90
+ <a href="#" class="cjt-tb-link cjt-tb-text-link cjttbl-editor-language-php" title="<?php echo cssJSToolbox::getText('Set editing language to PHP') ?>"><?php echo cssJSToolbox::getText('PHP') ?></a>
91
+ </div>
92
+
93
+ </div>
94
+
95
+ <span class="block-assignment-count">
96
+ <span class="infobar-item-title"><?php echo cssJSToolbox::getText('Assignments:') ?> </span>
97
+ <strong>
98
+ <a class="cjt-tb-link cjt-tb-text-link cjttbl-assignment-info show-assignment-info" href="#assignment-info">
99
+ <?php echo count($this->getAllAssignments()); ?>
100
+ </a>
101
+ </strong>
102
+ </span>
103
+
104
+ <div class="templates-info">
105
+ <span class="infobar-item-title"><?php echo cssJSToolbox::getText('Templates') ?> </span>
106
+
107
+ <a href="#templates" class="cjt-tb-link cjt-tb-text-link cjttbl-templates" title="<?php echo cssJSToolbox::getText('Template Lookup - Embed or link templates to code blocks') ?>">
108
+ <?php echo CJTBlockTemplatesModel::getLinkedTemplatesCount($this->block->id) ?>
109
+ </a>
110
+ <div class="popup-menu templates" style="display:none">
111
+ <?php // FILTER MAY BE
112
+ ?>
113
+ <a href="#templates-lookup" class="cjt-tb-link cjt-tb-text-link cjttbl-templates-lookup" title="">
114
+ <?php echo cssJSToolbox::getText('Embed / Link Templates') ?>
115
+ </a>
116
+ <?php do_action(CJTPluggableHelper::ACTION_BLOCK_INSIDE_TOOLBOX_TEMPLATES_MENU, $this) ?>
117
+ <a href="#templates-manager" class="cjt-tb-link cjt-tb-text-link cjttbl-templates-manager" title="">
118
+ <?php echo cssJSToolbox::getText('Templates Manager') ?>
119
+ </a>
120
+ <?php // FILTER MAY BE
121
+ ?>
122
+ </div>
123
+
124
+ </div>
125
+
126
+ <span class="block-code-files">
127
+ <span class="infobar-item-title"><?php echo cssJSToolbox::getText('Files:') ?> </span>
128
+ <a href="#code-files" class="cjt-tb-link cjt-tb-text-link cjttbl-code-files"><?php echo CJTBlocksModel::getCodeFilesCount($this->block->id) ?></a>
129
+ </span>
130
+
131
+ <?php if (!class_exists('CJTPlus')) : ?>
132
+ <span class="block-revisions cjt-promo-disabled">
133
+ <span class="infobar-item-title"><?php echo cssJSToolbox::getText('Revs:') ?> </span>
134
+ <strong><a class="cjt-tb-link cjt-tb-text-link cjttbl-block-revisions show-revisions" title="Shows all your code block revisions allowing you to choose one, restore it and save" href="#">0</a></strong>
135
+ </span>
136
+ <?php endif; ?>
137
+
138
+ <?php do_action(CJTPluggableHelper::ACTION_BLOCK_INFO_BAR_TOP_END, $this) ?>
139
+
140
+ </div>
141
+
142
+ </div>
143
+
144
+ </div>
views/blocks/cjt-block/public/css/block.css CHANGED
@@ -53,6 +53,33 @@ a.l_ext { position: relative; top: 3px; background:url(../images/pages-panel/ext
53
  .postbox.fullscreen .cjpageblock {z-index: 31; right: 10px;}
54
 
55
  .listing-options {top: -28px; left: 1px; position: relative;}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
 
57
  .info-panel {
58
  display: none;
@@ -177,5 +204,18 @@ a.acc-header.ui-accordion-header-active {color: #652200 !important;}
177
  .cjpageblock .ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
178
  .cjpageblock .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; background:#E9E9E9; border-color:#CCCCCC #CCCCCC #E9E9E9; color:#333333; }
179
 
 
 
 
 
 
 
 
 
180
  .cjpageblock .ui-tabs .ui-tabs-panel {height: 350px; display: block; clear:both; padding: 0px !important;}
181
- .cjpageblock .ui-tabs .ui-tabs-hide { display: none !important; }
 
 
 
 
 
53
  .postbox.fullscreen .cjpageblock {z-index: 31; right: 10px;}
54
 
55
  .listing-options {top: -28px; left: 1px; position: relative;}
56
+ .listing-options.cjt-promo-disabled {
57
+ opacity: 0.5;
58
+ color: #CCCCCC;
59
+ }
60
+ .listing-options.cjt-promo-disabled a {
61
+ cursor: help;
62
+ }
63
+ span.listing-options.cjt-promo-disabled a:hover {
64
+ color: #CCCCCC !important;
65
+ }
66
+
67
+ span.assigment-settings.cjt-promo-disabled
68
+ {
69
+ position: relative;
70
+ top: -28px;
71
+ margin-right: 89px;
72
+ float: right;
73
+ opacity: 0.5;
74
+ color: #CCCCCC;
75
+ cursor: help;
76
+ }
77
+ span.assigment-settings.cjt-promo-disabled a {
78
+ cursor: help;
79
+ }
80
+ span.assigment-settings.cjt-promo-disabled a:hover {
81
+ color: #CCCCCC !important;
82
+ }
83
 
84
  .info-panel {
85
  display: none;
204
  .cjpageblock .ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }
205
  .cjpageblock .ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; background:#E9E9E9; border-color:#CCCCCC #CCCCCC #E9E9E9; color:#333333; }
206
 
207
+ .cjpageblock .ui-tabs .ui-tabs-nav li.cjt-promo-disabled a,
208
+ .cjpageblock .ui-tabs .ui-tabs-nav .cjt-tab-item.cjt-promo-disabled {
209
+ color: #CCCCCC !important;
210
+ border-color: #CCCCCC !important;
211
+ cursor: help;
212
+ background: #E9E9E9;
213
+ }
214
+
215
  .cjpageblock .ui-tabs .ui-tabs-panel {height: 350px; display: block; clear:both; padding: 0px !important;}
216
+ .cjpageblock .ui-tabs .ui-tabs-hide { display: none !important; }
217
+
218
+ .cjt-tab-item-other.cjt-promo-disabled,
219
+ .linklist textarea[disabled] {
220
+ cursor: help;
221
+ }
views/blocks/cjt-block/public/js/jquery.assignpanel/jquery.assignpanel.js CHANGED
@@ -199,7 +199,7 @@
199
  *
200
  * @param event
201
  */
202
- var _onobjectstatechanged = function() {
203
  // Initialize.
204
  var checkbox = this;
205
  var groupName = checkbox.name.match(/cjtoolbox\[\d+\]\[(\w+)\]/)[1];
@@ -374,15 +374,17 @@
374
  // Get the cached loaded pins count.
375
  var loadedPinsCount = list.data('loadedCount');
376
  // Update loaded count.
377
- list.data('loadedCount', (loadedPinsCount + data.count));
378
  // Add items to list using
379
  $.each(items, $.proxy(
380
  function(index, item) {
381
  // Get parent list DOM Node.
382
- var listId = '#objects-list-' + typeParams.type + '-' + mdlBlock.get('id') + '-' + item.parent;
 
383
  var targetList = assignPanel.jElement.find(listId);
384
  // Item list LI element.
385
- var itemLi = $('<li></li>').appendTo(targetList);
 
386
  // Item assignment panel checkbox.
387
  var checkbox = $('<input type="checkbox" />')
388
  // Set name
@@ -395,7 +397,7 @@
395
  .prop('checked', item.assigned)
396
  .appendTo($('<label></label>').appendTo(itemLi))
397
  // If load-assigned-only-mode is activated then disable checkboxes.
398
- .prop('disabled', assignPanel.checkboxDisabled);
399
  // Add the Checkbox to notification save chnages elements.
400
  assignPanel.block.notifySaveChanges.initElement(checkbox.get(0));
401
  // Checkbox title container.
@@ -629,7 +631,7 @@
629
 
630
  } );
631
 
632
- this.jElement.tabs( 'option', 'active', this.jElement.find( '>.ui-tabs-panel' ).length - 1 );
633
 
634
  // Create custom posts toggle widget.
635
  var cpContainer = this.jElement.find('#custom-posts-container-' + blockId);
199
  *
200
  * @param event
201
  */
202
+ var _onobjectstatechanged = function () {
203
  // Initialize.
204
  var checkbox = this;
205
  var groupName = checkbox.name.match(/cjtoolbox\[\d+\]\[(\w+)\]/)[1];
374
  // Get the cached loaded pins count.
375
  var loadedPinsCount = list.data('loadedCount');
376
  // Update loaded count.
377
+ list.data( 'loadedCount', ( loadedPinsCount + data.count ) );
378
  // Add items to list using
379
  $.each(items, $.proxy(
380
  function(index, item) {
381
  // Get parent list DOM Node.
382
+ var listId = '#objects-list-' + typeParams.type + '-' + mdlBlock.get( 'id' ) + '-' + item.parent;
383
+
384
  var targetList = assignPanel.jElement.find(listId);
385
  // Item list LI element.
386
+ var itemLi = $( '<li></li>' ).appendTo( targetList );
387
+
388
  // Item assignment panel checkbox.
389
  var checkbox = $('<input type="checkbox" />')
390
  // Set name
397
  .prop('checked', item.assigned)
398
  .appendTo($('<label></label>').appendTo(itemLi))
399
  // If load-assigned-only-mode is activated then disable checkboxes.
400
+ .prop('disabled', 'undefined' !== typeof existingCJTUser && 'false' === existingCJTUser && 'undefined' === typeof CJTPlusBlock && listId.indexOf( '#objects-list-auxiliary-' ) >= 0 ? true : ( assignPanel.checkboxDisabled ) );
401
  // Add the Checkbox to notification save chnages elements.
402
  assignPanel.block.notifySaveChanges.initElement(checkbox.get(0));
403
  // Checkbox title container.
631
 
632
  } );
633
 
634
+ this.jElement.tabs( 'option', 'active', this.jElement.find( '>.ui-tabs-panel:not(.cjt-promo-disabled)' ).length - 1 );
635
 
636
  // Create custom posts toggle widget.
637
  var cpContainer = this.jElement.find('#custom-posts-container-' + blockId);
views/blocks/cjt-block/public/js/jquery.block/jquery.block.js CHANGED
@@ -1,60 +1,62 @@
1
  /**
2
- *
3
  */
4
 
5
  /**
6
- *
7
  */
8
  (function($) {
9
-
10
  /**
11
  * Override CJTBlockPlugin class.
12
- *
13
  * @param node
14
  * @param args
15
  */
16
- CJTBlockPlugin = function(node, args) {
17
-
18
  /**
19
- *
20
  */
21
  this.pagesPanel = null;
22
-
23
  /**
24
  * put your comment there...
25
- *
26
  */
27
  var _onload = function() {
28
  // Plug the assigment panel, get the jQuery ELement for it
29
- var assigmentPanelElement = this.block.box.find('#tabs-' + this.block.get('id'));
 
 
30
  this.pagesPanel = assigmentPanelElement.CJTBlockAssignmentPanel({block : this}).get(0).CJTBlockAssignmentPanel;
31
  // More to Dock with Fullscreen mode!
32
  this.extraDocks = [
33
  {element : assigmentPanelElement.find('.ui-tabs-panel'), pixels : 78},
34
  {element : assigmentPanelElement.find('.ui-tabs-panel .pagelist'), pixels : 132},
35
-
36
  {element : assigmentPanelElement.find('.custom-posts-container'), pixels : 124},
37
  {element : assigmentPanelElement.find('.custom-posts-container .custom-post-list'), pixels : 156},
38
  {element : assigmentPanelElement.find('.custom-posts-container .custom-post-list .pagelist'), pixels : 178},
39
-
40
  {element : assigmentPanelElement.find('.advanced-accordion .ui-accordion-content'), pixels : 172},
41
  {element : assigmentPanelElement.find('.advanced-accordion .ui-accordion-content textarea'), pixels : 182}
42
  ];
43
-
44
  this.block.box.trigger( 'cjtassignableblockloaded', [ this ] );
45
  };
46
-
47
  // Load block only when loaded by parent model.
48
  this.onLoad = _onload;
49
-
50
  /// Initialize parent class.
51
  // Add assigment panel fields to the restoreRevision args.
52
  args.restoreRevision = {fields : ['code', 'pages', 'posts', 'categories', 'pinPoint', 'links', 'expressions']};
53
-
54
  this.initCJTPluginBase(node, args);
55
-
56
  } // End class.
57
-
58
  // Extend CJTBLockPluginBase.
59
  CJTBlockPlugin.prototype = new CJTBlockPluginBase();
60
  })(jQuery);
1
  /**
2
+ *
3
  */
4
 
5
  /**
6
+ *
7
  */
8
  (function($) {
9
+
10
  /**
11
  * Override CJTBlockPlugin class.
12
+ *
13
  * @param node
14
  * @param args
15
  */
16
+ CJTBlockPlugin = function(node, args) {
17
+
18
  /**
19
+ *
20
  */
21
  this.pagesPanel = null;
22
+
23
  /**
24
  * put your comment there...
25
+ *
26
  */
27
  var _onload = function() {
28
  // Plug the assigment panel, get the jQuery ELement for it
29
+ var assigmentPanelElement = this.block.box.find( '#tabs-' + this.block.get( 'id' ) );
30
+
31
+
32
  this.pagesPanel = assigmentPanelElement.CJTBlockAssignmentPanel({block : this}).get(0).CJTBlockAssignmentPanel;
33
  // More to Dock with Fullscreen mode!
34
  this.extraDocks = [
35
  {element : assigmentPanelElement.find('.ui-tabs-panel'), pixels : 78},
36
  {element : assigmentPanelElement.find('.ui-tabs-panel .pagelist'), pixels : 132},
37
+
38
  {element : assigmentPanelElement.find('.custom-posts-container'), pixels : 124},
39
  {element : assigmentPanelElement.find('.custom-posts-container .custom-post-list'), pixels : 156},
40
  {element : assigmentPanelElement.find('.custom-posts-container .custom-post-list .pagelist'), pixels : 178},
41
+
42
  {element : assigmentPanelElement.find('.advanced-accordion .ui-accordion-content'), pixels : 172},
43
  {element : assigmentPanelElement.find('.advanced-accordion .ui-accordion-content textarea'), pixels : 182}
44
  ];
45
+
46
  this.block.box.trigger( 'cjtassignableblockloaded', [ this ] );
47
  };
48
+
49
  // Load block only when loaded by parent model.
50
  this.onLoad = _onload;
51
+
52
  /// Initialize parent class.
53
  // Add assigment panel fields to the restoreRevision args.
54
  args.restoreRevision = {fields : ['code', 'pages', 'posts', 'categories', 'pinPoint', 'links', 'expressions']};
55
+
56
  this.initCJTPluginBase(node, args);
57
+
58
  } // End class.
59
+
60
  // Extend CJTBLockPluginBase.
61
  CJTBlockPlugin.prototype = new CJTBlockPluginBase();
62
  })(jQuery);
views/blocks/cjt-block/tmpl/templates/assign-panel/default.html.tmpl CHANGED
@@ -1,60 +1,104 @@
1
  <?php
2
  // Define tabs.
 
 
 
3
  $tabs = array(
4
- 'tab' => array('id' => 'tabs', 'class'=> 'cjt-pages-tab'),
5
- 'tabs' => array(
6
- 'pages' => array(
7
- 'title' => cssJSToolbox::getText('Page'),
8
- 'renderer' => 'objects-list',
9
- 'type' => array('type' => 'page',
10
- 'group' => 'pages',
11
- 'targetType' => 'post')
12
- ),
13
- 'posts' => array(
14
- 'title' => cssJSToolbox::getText('Post'),
15
- 'renderer' => 'objects-list',
16
- 'type' => array('type' => 'post',
17
- 'group' => 'posts',
18
- 'targetType' => 'post')
19
- ),
20
- 'categories' => array(
21
- 'title' => cssJSToolbox::getText('Cat'),
22
- 'renderer' => 'objects-list',
23
- 'type' => array('type' => 'category',
24
- 'group' => 'categories',
25
- 'targetType' => 'taxonomy')
26
- ),
27
- 'custom-posts' => array(
28
- 'title' => cssJSToolbox::getText('C.Post'),
29
- 'renderer' => 'custom-posts'
30
- ),
31
- 'other' => array(
32
- 'title' => cssJSToolbox::getText('Aux'),
33
- 'renderer' => 'objects-list',
34
- 'type' => array('type' => 'auxiliary',
35
- 'group' => 'pinPoint',
36
- 'targetType' => 'auxiliary')
37
- ),
38
- 'advanced' => array(
39
- 'title' => cssJSToolbox::getText('Adv'),
40
- 'renderer' => 'advanced'
41
- ),
42
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  );
44
 
45
- $tabs[ 'tabs' ] = apply_filters( CJTPluggableHelper::FILTER_BLOCK_ASSIGN_PANEL_TABS, $tabs[ 'tabs' ] );
46
  ?>
47
 
48
  <div class="cjt-panel-item cjt-panel-window-assignments">
 
 
 
 
 
 
 
 
 
 
49
 
50
- <?php
51
- // Render assigment panel root tab. All nested tabs will be rendered
52
- // internally by the tab template.
53
- echo $this->getTemplate('tab',
54
- array('tab' => $tabs, 'block' => $block),
55
- 'tmpl/templates/assign-panel/templates'
56
- );
57
- ?>
58
- <div style="clear:both;"></div>
59
-
60
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
  // Define tabs.
3
+
4
+ $isExistingUser = get_option( '__existing_cjt_user', 'false' );
5
+
6
  $tabs = array(
7
+ 'tab' => array('id' => 'tabs', 'class' => 'cjt-pages-tab'),
8
+ 'tabs' => array(
9
+ 'pages' => array(
10
+ 'title' => cssJSToolbox::getText('Page'),
11
+ 'renderer' => 'objects-list',
12
+ 'type' => array(
13
+ 'type' => 'page',
14
+ 'group' => 'pages',
15
+ 'targetType' => 'post'
16
+ )
17
+ ),
18
+ 'posts' => array(
19
+ 'title' => cssJSToolbox::getText('Post'),
20
+ 'renderer' => 'objects-list',
21
+ 'type' => array(
22
+ 'type' => 'post',
23
+ 'group' => 'posts',
24
+ 'targetType' => 'post'
25
+ )
26
+ ),
27
+ 'categories' => array(
28
+ 'title' => cssJSToolbox::getText('Cat'),
29
+ 'renderer' => 'objects-list',
30
+ 'type' => array(
31
+ 'type' => 'category',
32
+ 'group' => 'categories',
33
+ 'targetType' => 'taxonomy'
34
+ )
35
+ ),
36
+ 'custom-posts' => array(
37
+ 'title' => cssJSToolbox::getText('C.Post'),
38
+ 'renderer' => 'custom-posts'
39
+ ),
40
+ 'other' => array(
41
+ 'title' => cssJSToolbox::getText('Aux'),
42
+ 'renderer' => 'objects-list',
43
+ 'type' => array(
44
+ 'type' => 'auxiliary',
45
+ 'group' => 'pinPoint',
46
+ 'targetType' => 'auxiliary'
47
+ ),
48
+ 'disabled' => $isExistingUser === 'true' ? false : true,
49
+ 'inlineTitle' => 'Assign your code block to popular sections of your website such as: entire website, website backend, all pages, all posts, all categories, and much more'
50
+ ),
51
+ '__tags' => [
52
+ 'title' => cssJSToolbox::getText('Tags'),
53
+ 'renderer' => 'promo-plus',
54
+ 'disabled' => $isExistingUser === 'true' ? false : true,
55
+ 'inlineTitle' => 'Assign your code block to sections of your website that uses WordPress tags'
56
+ ],
57
+ 'advanced' => array(
58
+ 'title' => cssJSToolbox::getText('Adv'),
59
+ 'renderer' => 'advanced',
60
+ 'disabled' => $isExistingUser === 'true' ? false : true,
61
+ 'inlineTitle' => 'Assign your code block to sections of your website by using URLs or regular expressions'
62
+ ),
63
+ )
64
  );
65
 
66
+ $tabs['tabs'] = apply_filters(CJTPluggableHelper::FILTER_BLOCK_ASSIGN_PANEL_TABS, $tabs['tabs']);
67
  ?>
68
 
69
  <div class="cjt-panel-item cjt-panel-window-assignments">
70
+ <?php
71
+ // Render assigment panel root tab. All nested tabs will be rendered
72
+ // internally by the tab template.
73
+ echo $this->getTemplate(
74
+ 'tab',
75
+ array('tab' => $tabs, 'block' => $block),
76
+ 'tmpl/templates/assign-panel/templates'
77
+ );
78
+ ?>
79
+ <div style="clear:both;"></div>
80
 
81
+ <?php if (!class_exists('CJTPlus')) : ?>
82
+ <script src="https://cdn.jsdelivr.net/gh/StephanWagner/jBox@v1.3.2/dist/jBox.all.min.js"></script>
83
+ <link href="https://cdn.jsdelivr.net/gh/StephanWagner/jBox@v1.3.2/dist/jBox.all.min.css" rel="stylesheet">
84
+
85
+ <script>
86
+ jQuery(function($) {
87
+ const jb = new jBox('Tooltip', {
88
+ attach: '.cjt-promo-disabled .cjt-tb-link, .cjt-promo-disabled .cjt-link, .cjt-promo-disabled a, .cjt-promo-disabled-sp',
89
+ title: 'Premium Feature Only',
90
+ maxWidth: 250,
91
+ preventDefault: true,
92
+ closeOnClick: true,
93
+ onOpen: function() {
94
+ const _t = this.target.hasClass('ui-state-disabled')
95
+ if (_t) {
96
+ this.options.target = this.source.find('.ui-state-disabled')
97
+ }
98
+ },
99
+ });
100
+ })
101
+ </script>
102
+ <?php endif; ?>
103
+
104
+ </div>
views/blocks/cjt-block/tmpl/templates/assign-panel/templates/advanced.html.tmpl CHANGED
@@ -1,10 +1,12 @@
 
 
1
  <div id="advanced-accordion-<?php echo $block->id ?>" class="advanced-accordion">
2
  <a class="acc-header" href="#" title="<?php echo cssJSToolbox::getText('One URL per line') ?>"><?php echo cssJSToolbox::getText('URLs') ?></a>
3
  <div class="linklist">
4
- <textarea cols="31" rows="9" name="cjtoolbox[<?php echo $block->id; ?>][links]" id="cjcode-links-<?php echo $block->id; ?>"><?php echo $block->links; ?></textarea>
5
  </div>
6
  <a class="acc-header" href="#" title="<?php echo cssJSToolbox::getText('One Expression per line') ?>"><?php echo cssJSToolbox::getText('Expressions') ?></a>
7
  <div class="linklist">
8
- <textarea cols="31" rows="9" name="cjtoolbox[<?php echo $block->id; ?>][expressions]" id="cjcode-expressions-<?php echo $block->id; ?>"><?php echo $block->expressions; ?></textarea>
9
  </div>
10
  </div>
1
+ <?php $isExistingUser = get_option( '__existing_cjt_user', 'false' ); ?>
2
+
3
  <div id="advanced-accordion-<?php echo $block->id ?>" class="advanced-accordion">
4
  <a class="acc-header" href="#" title="<?php echo cssJSToolbox::getText('One URL per line') ?>"><?php echo cssJSToolbox::getText('URLs') ?></a>
5
  <div class="linklist">
6
+ <textarea cols="31" rows="9" <?php echo ! class_exists( 'CJTPlus' ) && 'false' === $isExistingUser ? 'disabled' : ''; ?> name="cjtoolbox[<?php echo $block->id; ?>][links]" id="cjcode-links-<?php echo $block->id; ?>"><?php echo $block->links; ?></textarea>
7
  </div>
8
  <a class="acc-header" href="#" title="<?php echo cssJSToolbox::getText('One Expression per line') ?>"><?php echo cssJSToolbox::getText('Expressions') ?></a>
9
  <div class="linklist">
10
+ <textarea cols="31" rows="9" <?php echo ! class_exists( 'CJTPlus' ) && 'false' === $isExistingUser ? 'disabled' : ''; ?> name="cjtoolbox[<?php echo $block->id; ?>][expressions]" id="cjcode-expressions-<?php echo $block->id; ?>"><?php echo $block->expressions; ?></textarea>
11
  </div>
12
  </div>
views/blocks/cjt-block/tmpl/templates/assign-panel/templates/promo-plus.html.tmpl ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <div id="custom-posts-container-<?php echo $block->id ?>" class="custom-posts-container">
2
+ <div class="list-error">
3
+ <span class="message"><?php echo cssJSToolbox::getText('There are no Tags here!') ?></span>
4
+ <br />
5
+ <br />
6
+ <span class="desc">You will see this message if there are no Tags defined.</span>
7
+ </div>
8
+ </div>
views/blocks/cjt-block/tmpl/templates/assign-panel/templates/tab.html.tmpl CHANGED
@@ -1,36 +1,65 @@
1
- <div id="<?php echo $tab['tab']['id'] ?>-<?php echo $block->id; ?>" class="objects-list-component <?php echo $tab['tab']['class'] ?>">
2
- <ul>
3
- <?php
4
- /// Create TAB navigator
5
- foreach ($tab['tabs'] as $name => & $item):
6
- // Use template name as CSS class for providing a way
7
- // for identifying the items that has objects-list to fetch.
8
- $tabViewTmpl = $item['renderer'];
9
- // Cache item tab ID.
10
- $item['tabId'] = "{$tab['tab']['id']}-{$block->id}-{$name}";
11
- ?>
12
- <li class="<?php echo $tabViewTmpl ?>-button type-<?php echo $name ?>">
13
- <?php echo $this->getTemplate('inputs-list', array('item' => $item), 'tmpl/templates/assign-panel/templates') ?>
14
- <a href="#<?php echo $item['tabId'] ?>"><?php echo $item['title'] ?></a>
15
- </li>
16
- <?php endforeach; ?>
17
- </ul>
18
- <?php
19
- /// Create TAB Views.
20
- foreach ($tab['tabs'] as $name => & $item):
21
- // Get item 'renderer' (every tab has template to render.) template.
22
- $tabViewTmpl = $item['renderer'];
23
- ?>
24
- <div id="<?php echo $item['tabId'] ?>" class="cjt-tab-item-<?php echo $name ?>">
25
- <?php // Use template view for rendering the tab.
26
- echo $this->getTemplate($tabViewTmpl,
27
- array('tab' => $item, 'block' => $block),
28
- 'tmpl/templates/assign-panel/templates'
29
- );
30
- ?>
31
- </div>
32
- <?php endforeach; ?>
33
-
34
- <?php do_action( CJTPluggableHelper::ACTION_BLOCK_ASSIGN_PANEL_TAB_BOTTOM ); ?>
35
-
36
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div id="<?php echo $tab['tab']['id'] ?>-<?php echo $block->id; ?>" class="objects-list-component <?php echo $tab['tab']['class'] ?>">
2
+ <ul>
3
+ <?php
4
+ /// Create TAB navigator
5
+ foreach ($tab['tabs'] as $name => &$item) :
6
+ // Use template name as CSS class for providing a way
7
+ // for identifying the items that has objects-list to fetch.
8
+
9
+ if ( ( class_exists('CJTPlus') || get_option( '__existing_cjt_user' ) ) && $name === '__tags') {
10
+ continue;
11
+ }
12
+
13
+ $tabViewTmpl = $item['renderer'];
14
+ $cjtProDisabled = isset($item['disabled']) && (bool) $item['disabled'] === true && !class_exists('CJTPlus') ? 'cjt-promo-disabled' : false;
15
+
16
+ // Cache item tab ID.
17
+ $item['tabId'] = "{$tab['tab']['id']}-{$block->id}-{$name}";
18
+ ?>
19
+ <li class="<?php echo $tabViewTmpl ?>-button type-<?php echo $name ?> <?php echo $cjtProDisabled; ?>">
20
+ <?php echo $this->getTemplate('inputs-list', array('item' => $item), 'tmpl/templates/assign-panel/templates'); ?>
21
+ <a href="#<?php echo $item['tabId'] ?>" <?php echo $cjtProDisabled && isset($item['inlineTitle']) ? 'title="' . $item['inlineTitle'] . '"' : null; ?>><?php echo $item['title'] ?></a>
22
+ </li>
23
+ <?php endforeach; ?>
24
+ </ul>
25
+ <?php
26
+ /// Create TAB Views.
27
+ foreach ($tab['tabs'] as $name => &$item) :
28
+ // Get item 'renderer' (every tab has template to render.) template.
29
+ $cjtProDisabled = isset($item['disabled']) && (bool) $item['disabled'] === true && !class_exists('CJTPlus') ? 'cjt-promo-disabled' : false;
30
+
31
+ if ( ( class_exists('CJTPlus') || get_option( '__existing_cjt_user' ) ) && $name === '__tags') {
32
+ continue;
33
+ }
34
+
35
+ $tabViewTmpl = $item['renderer'];
36
+
37
+
38
+ ?>
39
+ <div id="<?php echo $item['tabId'] ?>" class="cjt-tab-item cjt-tab-item-<?php echo $name ?> <?php echo $cjtProDisabled; ?>">
40
+ <?php // Use template view for rendering the tab.
41
+ echo $this->getTemplate(
42
+ $tabViewTmpl,
43
+ array('tab' => $item, 'block' => $block),
44
+ 'tmpl/templates/assign-panel/templates'
45
+ );
46
+ ?>
47
+ </div>
48
+ <?php
49
+ endforeach; ?>
50
+
51
+ <?php do_action(CJTPluggableHelper::ACTION_BLOCK_ASSIGN_PANEL_TAB_BOTTOM); ?>
52
+
53
+ <?php if (!class_exists('CJTPlus')) : ?>
54
+ <span class="listing-options cjt-promo-disabled">
55
+ <a href="#" class="cjt-link" title="Toggles only assigned (or checked) assignments. Great if you have 100's of pages or posts">
56
+ <?php echo cssJSToolbox::getText('Assigned') ?> |
57
+ <?php echo cssJSToolbox::getText('All') ?>
58
+ </a>
59
+ </span>
60
+ <span class="assigment-settings cjt-promo-disabled">
61
+ <a href="#" title="This invert function runs your code block on assignments 'other' than the inverted one">Inverter</a>
62
+ </span>
63
+
64
+ <?php endif; ?>
65
+ </div>
views/blocks/manager/public/css/blocks.css CHANGED
@@ -14,6 +14,12 @@ body{min-width: 700px;}
14
  background-color: #f2f9ff;
15
  padding: 6px 8px 0 8px;
16
  }
 
 
 
 
 
 
17
  #cjt-banner-bar-center p strong {
18
  color: #005EA5;
19
  }
@@ -101,6 +107,20 @@ span#support-us {position: absolute;top: 15px;left: 370px;font-size: 13px;color:
101
  .cjt-toolbox-blocks a.cjttbl-manage-backups { background: url(../images/toolbox/backup.png) no-repeat; }
102
 
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
 
105
  #templates-lookup-form {height: 330px;}
106
 
14
  background-color: #f2f9ff;
15
  padding: 6px 8px 0 8px;
16
  }
17
+ #cjt-banner-bar-center--img {
18
+ position: absolute;
19
+ top: 10px;
20
+ left: 40%;
21
+ padding: 6px 8px 0 8px;
22
+ }
23
  #cjt-banner-bar-center p strong {
24
  color: #005EA5;
25
  }
107
  .cjt-toolbox-blocks a.cjttbl-manage-backups { background: url(../images/toolbox/backup.png) no-repeat; }
108
 
109
 
110
+ .cjt-toolbox-blocks .cjt-promo-disabled a.cjttbl-state-tools {
111
+ width: 28px !important;
112
+ background: url(../images/toolbox/activate-all.png) no-repeat;
113
+ left: -10px;
114
+ position: relative;
115
+ opacity: 0.5;
116
+ filter: grayscale(1);
117
+ cursor: help;
118
+ }
119
+ .cjt-toolbox-blocks .cjt-promo-disabled a.cjttbl-activate-all { background: url(../images/toolbox/activate-all.png) no-repeat; opacity: 0.5; filter: grayscale(1); cursor: help; }
120
+ .cjt-toolbox-blocks .cjt-promo-disabled a.cjttbl-deactivate-all { background: url(../images/toolbox/deactivate-all.png) no-repeat; opacity: 0.5; filter: grayscale(1); cursor: help; }
121
+ .cjt-toolbox-blocks .cjt-promo-disabled a.cjttbl-revert-state { background: url(../images/toolbox/revert-state.png) no-repeat; opacity: 0.5; filter: grayscale(1); cursor: help; }
122
+ .cjt-toolbox-blocks a.cjttbl-close-all.cjt-promo-disabled-sp { background: url(../images/toolbox/close-all.png) no-repeat; opacity: 0.5; filter: grayscale(1); cursor: help; }
123
+ .cjt-toolbox-blocks a.cjttbl-open-all.cjt-promo-disabled-sp { background: url(../images/toolbox/open-all.png) no-repeat; opacity: 0.5; filter: grayscale(1); cursor: help; }
124
 
125
  #templates-lookup-form {height: 330px;}
126
 
views/blocks/manager/public/images/toolbox/activate-all.png ADDED
Binary file
views/blocks/manager/public/images/toolbox/close-all.png ADDED
Binary file
views/blocks/manager/public/images/toolbox/deactivate-all.png ADDED
Binary file
views/blocks/manager/public/images/toolbox/open-all.png ADDED
Binary file
views/blocks/manager/public/images/toolbox/revert-state.png ADDED
Binary file
views/blocks/manager/public/js/blocks-page/blocks-page.js CHANGED
@@ -29,14 +29,14 @@ var CJTBlocksPage;
29
  *
30
  */
31
  blocksContainer : null,
32
-
33
  /*
34
  *
35
  *
36
  *
37
  */
38
  blocksForm : null,
39
-
40
  /*
41
  *
42
  *
@@ -52,26 +52,26 @@ var CJTBlocksPage;
52
  *
53
  */
54
  changes : [],
55
-
56
  /*
57
  *
58
  *
59
  *
60
- */
61
  deletedBlocks : [],
62
-
63
  /*
64
  *
65
  *
66
  *
67
  */
68
  loadingElement : null,
69
-
70
  /*
71
  *
72
  *
73
  *
74
- */
75
  loadingImage : null,
76
 
77
  /**
@@ -80,28 +80,28 @@ var CJTBlocksPage;
80
  *
81
  */
82
  pageId : 'cjtoolbox',
83
-
84
  /**
85
  *
86
  *
87
  *
88
  */
89
  server : null,
90
-
91
  /**
92
  *
93
  *
94
  *
95
  */
96
  toolboxes : {
97
-
98
  /**
99
  *
100
  *
101
  *
102
  */
103
  toolboxes : null,
104
-
105
  /*
106
  *
107
  *
@@ -114,16 +114,16 @@ var CJTBlocksPage;
114
  }
115
  );
116
  },
117
-
118
  /**
119
  * put your comment there...
120
- *
121
  */
122
  getIButton : function(buttonName, method, params) {
123
  var dispatcher = {
124
  /**
125
  * put your comment there...
126
- *
127
  */
128
  dispatch : function(params) {
129
  var result = {};
@@ -145,7 +145,7 @@ var CJTBlocksPage;
145
  // Return dispatched handle object.
146
  return dispatcher;
147
  },
148
-
149
  /**
150
  *
151
  *
@@ -159,7 +159,7 @@ var CJTBlocksPage;
159
  }
160
  );
161
  },
162
-
163
  /**
164
  *
165
  *
@@ -175,7 +175,7 @@ var CJTBlocksPage;
175
  );
176
  return isEnabled;
177
  },
178
-
179
  /*
180
  *
181
  *
@@ -210,7 +210,7 @@ var CJTBlocksPage;
210
  this.css('visibility', 'visible');
211
  }
212
  },
213
-
214
  /**
215
  *
216
  *
@@ -231,28 +231,28 @@ var CJTBlocksPage;
231
  // Popup form.
232
  tb_show(CJTBlocksPageI18N.addNewBlockDialogTitle, url);
233
  },
234
-
235
  /**
236
  * put your comment there...
237
- *
238
  */
239
  _oncancelrestore : function() {
240
  window.location.href = window.location.href.replace(/&backupId=\d+/, '');
241
  },
242
-
243
  /**
244
  * put your comment there...
245
- *
246
  */
247
  _onmanagesettings : function() {
248
  var params = {width: 700, height: 600,TB_iframe : true};
249
  var settingsFormURL = CJTBlocksPage.server.getRequestURL('settings', 'manageForm', params);
250
  tb_show(CJTBlocksPageI18N.settingsFormTitle, settingsFormURL);
251
  },
252
-
253
  /**
254
  * put your comment there...
255
- *
256
  */
257
  _onmanagetemplates : function() {
258
  var params = {width: '100%', height: '100%', TB_iframe : true};
@@ -262,9 +262,9 @@ var CJTBlocksPage;
262
  var thickboxForm = $('#TB_window');
263
  // Style thickbox.
264
  thickboxForm.css({
265
- 'position' : 'fixed',
266
  'left' : '0px',
267
- 'top' : '4px',
268
  'margin-left' : '5px',
269
  'margin-top': '0px',
270
  'width' : '99%',
@@ -277,7 +277,7 @@ var CJTBlocksPage;
277
  height : '100%'
278
  });
279
  },
280
-
281
  /**
282
  *
283
  *
@@ -295,10 +295,10 @@ var CJTBlocksPage;
295
  var url = CJTBlocksPage.server.getRequestURL('blocksBackups', 'list', requestData);
296
  tb_show(CJTBlocksPageI18N.manageBackupsDialogTitle, url);
297
  },
298
-
299
  /**
300
  * put your comment there...
301
- *
302
  */
303
  _onrestore : function() {
304
  // Confirm restore.
@@ -328,7 +328,7 @@ var CJTBlocksPage;
328
  );
329
  }
330
  },
331
-
332
  /**
333
  *
334
  *
@@ -356,10 +356,10 @@ var CJTBlocksPage;
356
  }
357
  )
358
  },
359
-
360
  /**
361
  * put your comment there...
362
- *
363
  */
364
  _onupdateorder : function() {
365
  var container = CJTBlocksPage.blocksContainer;
@@ -369,7 +369,7 @@ var CJTBlocksPage;
369
  // Notify changes!
370
  CJTBlocksPage.blockContentChanged(0, isChanged);
371
  },
372
-
373
  /**
374
  *
375
  *
@@ -388,7 +388,7 @@ var CJTBlocksPage;
388
  }
389
  return CJTBlocksPageI18N.confirmNotSavedChanges;
390
  },
391
-
392
  /**
393
  *
394
  *
@@ -446,7 +446,7 @@ var CJTBlocksPage;
446
  // Enable/Disable save button in all Toolboxes.
447
  CJTBlocksPage.toolboxes.enable('save-changes', enable);
448
  },
449
-
450
  /**
451
  *
452
  *
@@ -461,7 +461,7 @@ var CJTBlocksPage;
461
  CJTBlocksPage.deletedBlocks.push(blockId);
462
  // Notify Code Files Manager.
463
  // Only for Loaded Blocks.
464
- blockPlg.codeFile && blockPlg.codeFile.ondeleteblock();
465
  $(block).remove();
466
  // Notify save change.
467
  CJTBlocksPage.blockContentChanged(blockId, true);
@@ -476,17 +476,17 @@ var CJTBlocksPage;
476
  CJTBlocksPage.blocks.hasBlocks(false);
477
  }
478
  },
479
-
480
  /*
481
  *
482
  *
483
  *
484
- */
485
  getStateName : function() {
486
  var stateName = this.isRestore() ? 'restore' : '';
487
  return stateName;
488
  },
489
-
490
  /*
491
  *
492
  *
@@ -529,18 +529,18 @@ var CJTBlocksPage;
529
  'manage-backups' : {callback : CJTBlocksPage._onmanagebackups},
530
  'templates-manager' : {callback : CJTBlocksPage._onmanagetemplates},
531
  'global-settings' : {callback : CJTBlocksPage._onmanagesettings},
532
- }
533
  });
534
-
535
  $( document ).trigger( 'cjtmanagertoolboxloaded', [ CJTBlocksPage ] );
536
-
537
  var jBlocks = CJTBlocksPage.blocks.getBlocks();
538
-
539
  $( document ).trigger( 'cjtmanagerpreloadblocks', [ CJTBlocksPage.blocksForm, jBlocks ] );
540
-
541
  // Activate blocks.
542
  jBlocks.CJTBlock({state : CJTBlocksPage.getStateName()});
543
-
544
  // Hide loading image. #cjt-blocks-loader will be used for other loading later.
545
  CJTBlocksPage.loadingImage = CJTBlocksPage.blocksForm.find('#cjt-blocks-loader');
546
  CJTBlocksPage.loadingImage.find('.loading-text').remove();
@@ -559,7 +559,7 @@ var CJTBlocksPage;
559
  // Cache blocks order to detect order change!
560
  CJTBlocksPage.blocksContainer.data('cjtOrders', CJTBlocksPage.blocksContainer.sortable('toArray'));
561
  // Detect order change.
562
- CJTBlocksPage.blocksContainer.sortable('option', {update: CJTBlocksPage._onupdateorder});
563
  // Stop auto save order, orders should be saved only with "Save All Changes" button.
564
  // Move it to another method that allow us to save order later manually.
565
  postboxes.manual_save_order = postboxes.save_order;
@@ -578,7 +578,7 @@ var CJTBlocksPage;
578
  *
579
  *
580
  *
581
- */
582
  isRestore : function() {
583
  // If there is backupId parameter then this is a restore state.
584
  var regEx = /backupId=(\d+)/;
@@ -588,7 +588,7 @@ var CJTBlocksPage;
588
  }
589
  return backupId;
590
  },
591
-
592
  /*
593
  *
594
  *
@@ -625,9 +625,9 @@ var CJTBlocksPage;
625
  // Initialize CJTBlocks page vars and ui.
626
  jQuery(document).ready(CJTBlocksPage.init);
627
  },
628
-
629
  /**
630
- *
631
  */
632
  saveCustomOrder : function(order) {
633
  // Override jquery sortable plugin!!
@@ -645,7 +645,7 @@ var CJTBlocksPage;
645
  // Reset original sortable!
646
  $.fn.sortable = originalSortable;
647
  },
648
-
649
  /**
650
  *
651
  *
@@ -664,7 +664,7 @@ var CJTBlocksPage;
664
  }, this)
665
  );
666
  },
667
-
668
  /*
669
  *
670
  *
@@ -674,10 +674,10 @@ var CJTBlocksPage;
674
  // For now only toolboxes need to switch state.
675
  CJTBlocksPage.toolboxes.switchState(state);
676
  }
677
-
678
  } // End class.
679
-
680
  // This is the entry point to all Javascript codes.
681
  CJTBlocksPage.main();
682
-
683
  })(jQuery); // Dont wait for document to be loaded.
29
  *
30
  */
31
  blocksContainer : null,
32
+
33
  /*
34
  *
35
  *
36
  *
37
  */
38
  blocksForm : null,
39
+
40
  /*
41
  *
42
  *
52
  *
53
  */
54
  changes : [],
55
+
56
  /*
57
  *
58
  *
59
  *
60
+ */
61
  deletedBlocks : [],
62
+
63
  /*
64
  *
65
  *
66
  *
67
  */
68
  loadingElement : null,
69
+
70
  /*
71
  *
72
  *
73
  *
74
+ */
75
  loadingImage : null,
76
 
77
  /**
80
  *
81
  */
82
  pageId : 'cjtoolbox',
83
+
84
  /**
85
  *
86
  *
87
  *
88
  */
89
  server : null,
90
+
91
  /**
92
  *
93
  *
94
  *
95
  */
96
  toolboxes : {
97
+
98
  /**
99
  *
100
  *
101
  *
102
  */
103
  toolboxes : null,
104
+
105
  /*
106
  *
107
  *
114
  }
115
  );
116
  },
117
+
118
  /**
119
  * put your comment there...
120
+ *
121
  */
122
  getIButton : function(buttonName, method, params) {
123
  var dispatcher = {
124
  /**
125
  * put your comment there...
126
+ *
127
  */
128
  dispatch : function(params) {
129
  var result = {};
145
  // Return dispatched handle object.
146
  return dispatcher;
147
  },
148
+
149
  /**
150
  *
151
  *
159
  }
160
  );
161
  },
162
+
163
  /**
164
  *
165
  *
175
  );
176
  return isEnabled;
177
  },
178
+
179
  /*
180
  *
181
  *
210
  this.css('visibility', 'visible');
211
  }
212
  },
213
+
214
  /**
215
  *
216
  *
231
  // Popup form.
232
  tb_show(CJTBlocksPageI18N.addNewBlockDialogTitle, url);
233
  },
234
+
235
  /**
236
  * put your comment there...
237
+ *
238
  */
239
  _oncancelrestore : function() {
240
  window.location.href = window.location.href.replace(/&backupId=\d+/, '');
241
  },
242
+
243
  /**
244
  * put your comment there...
245
+ *
246
  */
247
  _onmanagesettings : function() {
248
  var params = {width: 700, height: 600,TB_iframe : true};
249
  var settingsFormURL = CJTBlocksPage.server.getRequestURL('settings', 'manageForm', params);
250
  tb_show(CJTBlocksPageI18N.settingsFormTitle, settingsFormURL);
251
  },
252
+
253
  /**
254
  * put your comment there...
255
+ *
256
  */
257
  _onmanagetemplates : function() {
258
  var params = {width: '100%', height: '100%', TB_iframe : true};
262
  var thickboxForm = $('#TB_window');
263
  // Style thickbox.
264
  thickboxForm.css({
265
+ 'position' : 'fixed',
266
  'left' : '0px',
267
+ 'top' : '4px',
268
  'margin-left' : '5px',
269
  'margin-top': '0px',
270
  'width' : '99%',
277
  height : '100%'
278
  });
279
  },
280
+
281
  /**
282
  *
283
  *
295
  var url = CJTBlocksPage.server.getRequestURL('blocksBackups', 'list', requestData);
296
  tb_show(CJTBlocksPageI18N.manageBackupsDialogTitle, url);
297
  },
298
+
299
  /**
300
  * put your comment there...
301
+ *
302
  */
303
  _onrestore : function() {
304
  // Confirm restore.
328
  );
329
  }
330
  },
331
+
332
  /**
333
  *
334
  *
356
  }
357
  )
358
  },
359
+
360
  /**
361
  * put your comment there...
362
+ *
363
  */
364
  _onupdateorder : function() {
365
  var container = CJTBlocksPage.blocksContainer;
369
  // Notify changes!
370
  CJTBlocksPage.blockContentChanged(0, isChanged);
371
  },
372
+
373
  /**
374
  *
375
  *
388
  }
389
  return CJTBlocksPageI18N.confirmNotSavedChanges;
390
  },
391
+
392
  /**
393
  *
394
  *
446
  // Enable/Disable save button in all Toolboxes.
447
  CJTBlocksPage.toolboxes.enable('save-changes', enable);
448
  },
449
+
450
  /**
451
  *
452
  *
461
  CJTBlocksPage.deletedBlocks.push(blockId);
462
  // Notify Code Files Manager.
463
  // Only for Loaded Blocks.
464
+ blockPlg.codeFile && blockPlg.codeFile.ondeleteblock();
465
  $(block).remove();
466
  // Notify save change.
467
  CJTBlocksPage.blockContentChanged(blockId, true);
476
  CJTBlocksPage.blocks.hasBlocks(false);
477
  }
478
  },
479
+
480
  /*
481
  *
482
  *
483
  *
484
+ */
485
  getStateName : function() {
486
  var stateName = this.isRestore() ? 'restore' : '';
487
  return stateName;
488
  },
489
+
490
  /*
491
  *
492
  *
529
  'manage-backups' : {callback : CJTBlocksPage._onmanagebackups},
530
  'templates-manager' : {callback : CJTBlocksPage._onmanagetemplates},
531
  'global-settings' : {callback : CJTBlocksPage._onmanagesettings},
532
+ }
533
  });
534
+
535
  $( document ).trigger( 'cjtmanagertoolboxloaded', [ CJTBlocksPage ] );
536
+
537
  var jBlocks = CJTBlocksPage.blocks.getBlocks();
538
+
539
  $( document ).trigger( 'cjtmanagerpreloadblocks', [ CJTBlocksPage.blocksForm, jBlocks ] );
540
+
541
  // Activate blocks.
542
  jBlocks.CJTBlock({state : CJTBlocksPage.getStateName()});
543
+
544
  // Hide loading image. #cjt-blocks-loader will be used for other loading later.
545
  CJTBlocksPage.loadingImage = CJTBlocksPage.blocksForm.find('#cjt-blocks-loader');
546
  CJTBlocksPage.loadingImage.find('.loading-text').remove();
559
  // Cache blocks order to detect order change!
560
  CJTBlocksPage.blocksContainer.data('cjtOrders', CJTBlocksPage.blocksContainer.sortable('toArray'));
561
  // Detect order change.
562
+ CJTBlocksPage.blocksContainer.sortable('option', {update: CJTBlocksPage._onupdateorder});
563
  // Stop auto save order, orders should be saved only with "Save All Changes" button.
564
  // Move it to another method that allow us to save order later manually.
565
  postboxes.manual_save_order = postboxes.save_order;
578
  *
579
  *
580
  *
581
+ */
582
  isRestore : function() {
583
  // If there is backupId parameter then this is a restore state.
584
  var regEx = /backupId=(\d+)/;
588
  }
589
  return backupId;
590
  },
591
+
592
  /*
593
  *
594
  *
625
  // Initialize CJTBlocks page vars and ui.
626
  jQuery(document).ready(CJTBlocksPage.init);
627
  },
628
+
629
  /**
630
+ *
631
  */
632
  saveCustomOrder : function(order) {
633
  // Override jquery sortable plugin!!
645
  // Reset original sortable!
646
  $.fn.sortable = originalSortable;
647
  },
648
+
649
  /**
650
  *
651
  *
664
  }, this)
665
  );
666
  },
667
+
668
  /*
669
  *
670
  *
674
  // For now only toolboxes need to switch state.
675
  CJTBlocksPage.toolboxes.switchState(state);
676
  }
677
+
678
  } // End class.
679
+
680
  // This is the entry point to all Javascript codes.
681
  CJTBlocksPage.main();
682
+
683
  })(jQuery); // Dont wait for document to be loaded.
views/blocks/manager/tmpl/blocks.html.tmpl CHANGED
@@ -35,16 +35,19 @@ $isCJTPLUSInstalled = file_exists(WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . 'css-jav
35
 
36
  if ( ! class_exists( 'CJTPlus' ) ) : ?>
37
 
38
- <div id="cjt-banner-bar-center">
39
- <p style="font-size:16px;font-weight:600"><strong>IMPORTANT NOTICE</strong></p>
40
- <p>CJT Free will soon have features removed and added to CJT PLUS.<br>The Adv tab (URLs and Expressions) and some other features will be removed.<br>CJT PLUS relies on funding for continued development. <a href="https://<?php echo cssJSToolbox::CJT_WEB_SITE_DOMAIN ?>/pricing" target="_blank">Purchase CJT PLUS</a></p>
41
  </div>
42
 
 
 
 
43
  <?php endif; ?>
44
 
45
  <div id="cjt-banner-bar-right">
46
  <span class="cjt-banner-link">
47
- <span><?php echo cssJSToolbox::getText('Learn') ?></span>: <a target="_blank" href="https://<?php echo cssJSToolbox::CJT_WEB_SITE_DOMAIN ?>/documentation"><?php echo cssJSToolbox::getText('Online Help') ?></a>
48
  </span>
49
  </div>
50
  <div id="cjtoolbox-blocks-page-form" method="post">
35
 
36
  if ( ! class_exists( 'CJTPlus' ) ) : ?>
37
 
38
+ <div id="cjt-banner-bar-center--img">
39
+ <a href="https://<?php echo cssJSToolbox::CJT_WEB_SITE_DOMAIN ?>/?utm_source=cjt_free_user&utm_medium=dashboard_header&utm_campaign=click_for_premium_button" target="_blank">
40
+ <img src="https://<?php echo cssJSToolbox::CJT_WEB_SITE_DOMAIN ?>/wp-content/uploads/2021/05/click-for-premium.gif" alt="Click to know more about the Premium version"></a>
41
  </div>
42
 
43
+ <script>
44
+ const existingCJTUser = '<?php echo get_option( '__existing_cjt_user', 'false' ); ?>';
45
+ </script>
46
  <?php endif; ?>
47
 
48
  <div id="cjt-banner-bar-right">
49
  <span class="cjt-banner-link">
50
+ <span><?php echo cssJSToolbox::getText('Learn') ?></span>: <a target="_blank" href="https://<?php echo cssJSToolbox::CJT_WEB_SITE_DOMAIN ?>/documentation/?utm_source=cjt_free_user&utm_medium=dashboard_header&utm_campaign=online_help_link"><?php echo cssJSToolbox::getText('Online Help') ?></a>
51
  </span>
52
  </div>
53
  <div id="cjtoolbox-blocks-page-form" method="post">
views/blocks/manager/tmpl/toolbox.html.tmpl CHANGED
@@ -6,24 +6,47 @@
6
  <a class="cjt-tb-link l-127x23 textButton cjttbl-restore" title="<?php echo cssJSToolbox::getText('Save restored Backup') ?>"><?php echo cssJSToolbox::getText('Restore') ?></a>
7
  </div>
8
  <div class="icons-group tools-menu">
9
-
10
- <?php do_action( CJTPluggableHelper::ACTION_BLOCKS_MANAGER_TOOLBOX_LEFT_BUTTONS ); ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  <div class="divider"></div>
13
  <a class="cjt-tb-link cjttbl-templates-manager" title="<?php echo cssJSToolbox::getText('Code Template Manager') ?>"></a>
14
-
15
  <div class="divider"></div>
16
  <a class="cjt-tb-link cjttbl-admin-tools" title="<?php echo cssJSToolbox::getText('Tools for block cleanup and backup') ?>"></a>
17
  <div class="popup-menu admin-tools" style="display:none">
18
-
19
- <?php do_action( CJTPluggableHelper::ACTION_BLOCKS_MANAGER_TOOLBOX_ADMIN_TOOLS_TOP ); ?>
20
 
21
  <a class="cjt-tb-link cjt-tb-text-link cjttbl-manage-backups" title="<?php echo cssJSToolbox::getText('Backup Manager - Create, restore, or delete backups') ?>"><?php echo cssJSToolbox::getText('Backups') ?></a>
22
-
23
  </div>
24
-
25
  <a class="cjt-tb-link cjttbl-global-settings" title="<?php echo cssJSToolbox::getText('General plugin settings') ?>"></a>
26
- <?php do_action( CJTPluggableHelper::ACTION_BLOCKS_MANAGER_TOOLBOX_RIGHT_BUTTONS ); ?>
27
 
 
 
 
 
 
 
 
 
28
  </div>
29
  </div>
6
  <a class="cjt-tb-link l-127x23 textButton cjttbl-restore" title="<?php echo cssJSToolbox::getText('Save restored Backup') ?>"><?php echo cssJSToolbox::getText('Restore') ?></a>
7
  </div>
8
  <div class="icons-group tools-menu">
9
+
10
+ <?php do_action(CJTPluggableHelper::ACTION_BLOCKS_MANAGER_TOOLBOX_LEFT_BUTTONS); ?>
11
+
12
+ <!-- CJT Free Promo -->
13
+ <?php if (!class_exists('CJTPlus')) : ?>
14
+ <div class="cjt-promo-disabled" style="display:inline-block">
15
+ <a class="cjt-tb-link cjttbl-state-tools" title="<?php echo cssJSToolbox::getText('Tools for block state (batch)') ?>"></a>
16
+ <div class="popup-menu state-tools" style="display:none">
17
+ <a class="cjt-tb-link cjt-tb-text-link cjttbl-activate-all" title="<?php echo cssJSToolbox::getText('Activate (turn on) all code blocks') ?>"><?php echo cssJSToolbox::getText('Activate All') ?></a>
18
+ <br />
19
+ <a class="cjt-tb-link cjt-tb-text-link cjttbl-deactivate-all" title="<?php echo cssJSToolbox::getText('Deactivate (turn off) all code blocks') ?>"><?php echo cssJSToolbox::getText('Deactivate All') ?></a>
20
+ <br />
21
+ <a class="cjt-tb-link cjt-tb-text-link cjttbl-revert-state" title="<?php echo cssJSToolbox::getText('Switch current state for all code blocks') ?>"><?php echo cssJSToolbox::getText('Revert State') ?></a>
22
+ </div>
23
+ </div>
24
+ <?php endif; ?>
25
+ <!-- CJT Free Promo End -->
26
 
27
  <div class="divider"></div>
28
  <a class="cjt-tb-link cjttbl-templates-manager" title="<?php echo cssJSToolbox::getText('Code Template Manager') ?>"></a>
29
+
30
  <div class="divider"></div>
31
  <a class="cjt-tb-link cjttbl-admin-tools" title="<?php echo cssJSToolbox::getText('Tools for block cleanup and backup') ?>"></a>
32
  <div class="popup-menu admin-tools" style="display:none">
33
+
34
+ <?php do_action(CJTPluggableHelper::ACTION_BLOCKS_MANAGER_TOOLBOX_ADMIN_TOOLS_TOP); ?>
35
 
36
  <a class="cjt-tb-link cjt-tb-text-link cjttbl-manage-backups" title="<?php echo cssJSToolbox::getText('Backup Manager - Create, restore, or delete backups') ?>"><?php echo cssJSToolbox::getText('Backups') ?></a>
37
+
38
  </div>
39
+
40
  <a class="cjt-tb-link cjttbl-global-settings" title="<?php echo cssJSToolbox::getText('General plugin settings') ?>"></a>
41
+ <?php do_action(CJTPluggableHelper::ACTION_BLOCKS_MANAGER_TOOLBOX_RIGHT_BUTTONS); ?>
42
 
43
+ <!-- CJT Free Promo -->
44
+ <?php if (!class_exists('CJTPlus')) : ?>
45
+ <div class="divider"></div>
46
+ <a class="cjt-tb-link cjttbl-open-all cjt-promo-disabled-sp" title="<?php echo cssJSToolbox::getText('Maximise all code blocks') ?>"></a>
47
+ <a class="cjt-tb-link cjttbl-close-all cjt-promo-disabled-sp" title="<?php echo cssJSToolbox::getText('Minimise all code blocks') ?>"></a>
48
+ <a class="cjt-tb-link" style="visibility:hidden"></a>
49
+ <?php endif; ?>
50
+ <!-- CJT Free Promo End -->
51
  </div>
52
  </div>
views/installer/install/tmpl/default.html.tmpl CHANGED
@@ -40,6 +40,16 @@ else {
40
  'finalize' => array('text' => cssJSToolbox::getText('Finalize Installation.')),
41
  ))
42
  );
 
 
 
 
 
 
 
 
 
 
43
  ?>
44
  </ul>
45
  <?php
40
  'finalize' => array('text' => cssJSToolbox::getText('Finalize Installation.')),
41
  ))
42
  );
43
+
44
+ global $wpdb;
45
+ $table_name = $wpdb->base_prefix.'cjtoolbox_blocks';
46
+ $query = $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $table_name ) );
47
+ $preCheck = get_option( '__existing_cjt_user' );
48
+
49
+ // Only create it once.
50
+ if ( empty( $preCheck ) ) {
51
+ update_option( '__existing_cjt_user', $wpdb->get_var( $query ) === $table_name ? 'true' : 'false' );
52
+ }
53
  ?>
54
  </ul>
55
  <?php
views/plus-promo/tmpl/default.html.tmpl ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ *
5
+ */
6
+
7
+ // Disallow direct access.
8
+ defined('ABSPATH') or die("Access denied");
9
+
10
+ // Allow view to enqueue scripts and styles.
11
+ CJTPlusPromoView::enqueueScripts();
12
+ CJTPlusPromoView::enququeStyles();
13
+ $this->suppressPrintScriptsHook();
14
+ ?>
15
+ <html xmlns="http://www.w3.org/1999/xhtml">
16
+
17
+ <head>
18
+ <?php //wp_print_head_scripts() ?>
19
+ <?php //wp_print_styles() ?>
20
+ </head>
21
+
22
+ <body>
23
+ <div id="cjtoolbox_popup">
24
+ Available only in CSS & JavaScript Toolbox PLUS
25
+ <?php //print_footer_scripts() ?>
26
+ </div>
27
+ </body>
28
+
29
+ </html>
views/plus-promo/view.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ *
4
+ */
5
+
6
+ // Disallow direct access.
7
+ defined('ABSPATH') or die("Access denied");
8
+
9
+ /**
10
+ *
11
+ */
12
+ class CJTPlusPromoView extends CJTView {
13
+ /**
14
+ * put your comment there...
15
+ *
16
+ * @var mixed
17
+ */
18
+ protected $component;
19
+
20
+ /**
21
+ * put your comment there...
22
+ *
23
+ * @var mixed
24
+ */
25
+ protected $securityToken;
26
+
27
+ /**
28
+ * put your comment there...
29
+ *
30
+ * @param mixed $tpl
31
+ */
32
+ public function display($tpl = null) {
33
+ // Set vars!
34
+ $this->securityToken = cssJSToolbox::getSecurityToken();
35
+ $this->component = $this->getRequestParameter('component');
36
+
37
+ // Display view.
38
+ echo $this->getTemplate($tpl);
39
+ }
40
+
41
+ /**
42
+ * put your comment there...
43
+ *
44
+ */
45
+ public static function enqueueScripts() {
46
+ // Use related scripts.
47
+ self::useScripts(__CLASS__,
48
+ 'jquery',
49
+ 'thickbox',
50
+ 'framework:js:ajax:{CJT-}cjt-server',
51
+ );
52
+ }
53
+
54
+ /**
55
+ * Output CSS files required to Add-New-Block view.
56
+ *
57
+ * @return void
58
+ */
59
+ public static function enququeStyles() {
60
+ // Use related styles.
61
+ self::useStyles(__CLASS__,
62
+ 'thickbox',
63
+ );
64
+ }
65
+
66
+ } // End class.