CSS & JavaScript Toolbox - Version 11.5

Version Description

  • Compatibility: PHP version 8+
  • Compatibility: MySQL version 8+
  • Fix: Duplicate ID issue, which on rare occasions was fetching the 'revision block' ID for a newly created block causing an error for duplicate entry
  • Enhancement: If the 'wp-content' directory is renamed to something different (e.g. 'content'), CJT will now find any custom content directories and install correctly
Download this release

Release Info

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

Code changes from version 11.4 to 11.5

controllers/auto-upgrade.php CHANGED
@@ -1,26 +1,26 @@
1
  <?php
2
  /**
3
- *
4
  */
5
 
6
  // Disallow direct access.
7
  defined('ABSPATH') or die("Access denied");
8
 
9
  /**
10
- *
11
  */
12
  class CJTAutoUpgradeController extends CJTController {
13
-
14
  /**
15
  * put your comment there...
16
- *
17
  * @var mixed
18
  */
19
  protected $controllerInfo = array('model' => 'setup');
20
-
21
  /**
22
  * put your comment there...
23
- *
24
  */
25
  protected function enableAction() {
26
  // Initializing!
@@ -40,11 +40,11 @@ class CJTAutoUpgradeController extends CJTController {
40
  $updateSrcServer = (string) $extDef->license->attributes()->updateSrc;
41
  if (!$updateSrcServer || ($updateSrcServer == 'CJT')) {
42
  // Initializingn vars for a single state/component!
43
- $pluginFile = ABSPATH . PLUGINDIR . '/' . $state['component']['pluginBase'];
44
  $license =& $state['license'];
45
  // Set EDD Automatic Updater!
46
  try {
47
- CJTStoreUpdate::autoUpgrade( $name, $license[ 'key' ], $pluginFile );
48
  }
49
  catch ( CJTServicesAPICallException $exception ) {
50
  die( 'CJT AUTO-UPGRADE EXCAPTION!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' );
1
  <?php
2
  /**
3
+ *
4
  */
5
 
6
  // Disallow direct access.
7
  defined('ABSPATH') or die("Access denied");
8
 
9
  /**
10
+ *
11
  */
12
  class CJTAutoUpgradeController extends CJTController {
13
+
14
  /**
15
  * put your comment there...
16
+ *
17
  * @var mixed
18
  */
19
  protected $controllerInfo = array('model' => 'setup');
20
+
21
  /**
22
  * put your comment there...
23
+ *
24
  */
25
  protected function enableAction() {
26
  // Initializing!
40
  $updateSrcServer = (string) $extDef->license->attributes()->updateSrc;
41
  if (!$updateSrcServer || ($updateSrcServer == 'CJT')) {
42
  // Initializingn vars for a single state/component!
43
+ $pluginFile = WP_PLUGIN_DIR . '/' . $state['component']['pluginBase'];
44
  $license =& $state['license'];
45
  // Set EDD Automatic Updater!
46
  try {
47
+ CJTStoreUpdate::autoUpgrade( $name, $license[ 'key' ], $pluginFile );
48
  }
49
  catch ( CJTServicesAPICallException $exception ) {
50
  die( 'CJT AUTO-UPGRADE EXCAPTION!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!' );
controllers/blocks-ajax.php CHANGED
@@ -198,7 +198,7 @@ class CJTBlocksAjaxController extends CJTAjaxController {
198
  // make sure we're save.
199
  if ( is_array( $blocksToSave ) && ! empty( $blocksToSave ) )
200
  {
201
-
202
  foreach ( $blocksToSave as $id => $postedblockPartialData )
203
  {
204
  // Push block id into block data.
@@ -220,7 +220,7 @@ class CJTBlocksAjaxController extends CJTAjaxController {
220
 
221
  // Send the changes properties back to client.
222
  $updatedBlockData = $this->model->getBlock($id, null, array('*'), ARRAY_A);
223
-
224
  foreach ( $updatedBlockData as $property => $value )
225
  {
226
  $response[ $id ][ $property ][ 'value' ] = $value;
@@ -236,7 +236,7 @@ class CJTBlocksAjaxController extends CJTAjaxController {
236
  // Save changes.
237
  $this->model->save();
238
 
239
- // Return
240
  // Set response.
241
  $this->response = $response;
242
 
198
  // make sure we're save.
199
  if ( is_array( $blocksToSave ) && ! empty( $blocksToSave ) )
200
  {
201
+
202
  foreach ( $blocksToSave as $id => $postedblockPartialData )
203
  {
204
  // Push block id into block data.
220
 
221
  // Send the changes properties back to client.
222
  $updatedBlockData = $this->model->getBlock($id, null, array('*'), ARRAY_A);
223
+
224
  foreach ( $updatedBlockData as $property => $value )
225
  {
226
  $response[ $id ][ $property ][ 'value' ] = $value;
236
  // Save changes.
237
  $this->model->save();
238
 
239
+ // Return
240
  // Set response.
241
  $this->response = $response;
242
 
css-js-toolbox.class.php CHANGED
@@ -84,42 +84,42 @@ class cssJSToolbox extends CJTHookableClass
84
  *
85
  * @var mixed
86
  */
87
- protected static $ongettext = array( 'parameters' => array( 'text' ) );
88
 
89
  /**
90
  * put your comment there...
91
  *
92
  * @var mixed
93
  */
94
- protected static $onimport = array( 'parameters' => array( 'vpaths' ) );
95
 
96
  /**
97
  * put your comment there...
98
  *
99
  * @var mixed
100
  */
101
- protected static $oninstantiate = array( 'parameters' => array( 'instance' ) );
102
 
103
  /**
104
  * put your comment there...
105
  *
106
  * @var mixed
107
  */
108
- protected $onloadconfiguration = array( 'parameters' => array( 'configuration' ) );
109
 
110
  /**
111
  * put your comment there...
112
  *
113
  * @var mixed
114
  */
115
- protected $onloaddbdriver = array( 'parameters' => array( 'dbdriver' ) );
116
 
117
  /**
118
  * put your comment there...
119
  *
120
  * @var mixed
121
  */
122
- protected static $onresolvepath = array( 'parameters' => array( 'path', 'vpath' ) );
123
 
124
  /**
125
  * put your comment there...
84
  *
85
  * @var mixed
86
  */
87
+ protected static $ongettext = [ 'parameters' => [ 'text' ] ];
88
 
89
  /**
90
  * put your comment there...
91
  *
92
  * @var mixed
93
  */
94
+ protected static $onimport = [ 'parameters' => [ 'vpaths' ] ];
95
 
96
  /**
97
  * put your comment there...
98
  *
99
  * @var mixed
100
  */
101
+ protected static $oninstantiate = [ 'parameters' => [ 'instance' ] ];
102
 
103
  /**
104
  * put your comment there...
105
  *
106
  * @var mixed
107
  */
108
+ protected $onloadconfiguration = [ 'parameters' => [ 'configuration' ] ];
109
 
110
  /**
111
  * put your comment there...
112
  *
113
  * @var mixed
114
  */
115
+ protected $onloaddbdriver = [ 'parameters' => [ 'dbdriver' ] ];
116
 
117
  /**
118
  * put your comment there...
119
  *
120
  * @var mixed
121
  */
122
+ protected static $onresolvepath = [ 'parameters' => [ 'path', 'vpath' ] ];
123
 
124
  /**
125
  * put your comment there...
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.4
7
  Author: Wipeout Media
8
  Author URI: https://css-javascript-toolbox.com
9
  License:
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.5
7
  Author: Wipeout Media
8
  Author URI: https://css-javascript-toolbox.com
9
  License:
framework/db/mysql/xtable.inc.php CHANGED
@@ -1,136 +1,136 @@
1
  <?php
2
  /**
3
- *
4
  */
5
 
6
  // Disallow direct access.
7
  defined('ABSPATH') or die("Access denied");
8
 
9
  /**
10
- *
11
  */
12
  abstract class CJTxTable extends CJTHookableClass {
13
-
14
  /**
15
  * put your comment there...
16
- *
17
  * @var mixed
18
  */
19
  protected $dbDriver;
20
-
21
  /**
22
  * put your comment there...
23
- *
24
  * @var mixed
25
  */
26
  private $fields;
27
-
28
  /**
29
  * put your comment there...
30
- *
31
  * @var mixed
32
  */
33
  protected $item;
34
-
35
  /**
36
  * put your comment there...
37
- *
38
  * @var mixed
39
  */
40
  protected $key;
41
-
42
  /**
43
- *
44
  */
45
  private $name;
46
-
47
  /**
48
  * put your comment there...
49
- *
50
  * @var mixed
51
  */
52
  protected $onconcatquery = array('parameters' => array('query'));
53
-
54
  /**
55
  * put your comment there...
56
- *
57
  * @var mixed
58
  */
59
  protected $ondelete = array('parameters' => array('query', 'key'));
60
 
61
  /**
62
  * put your comment there...
63
- *
64
  * @var mixed
65
  */
66
  protected $ongetdata = array('parameters' => array('item'));
67
 
68
  /**
69
  * put your comment there...
70
- *
71
  * @var mixed
72
  */
73
  protected $ongetfield = array('parameters' => array('value', 'name'));
74
 
75
  /**
76
  * put your comment there...
77
- *
78
  * @var mixed
79
  */
80
  protected static $onimport = array('parameters' => array('type'));
81
-
82
  /**
83
  * put your comment there...
84
- *
85
  * @var mixed
86
  */
87
  protected static $oninstantiate = array('parameters' => array('args'));
88
-
89
  /**
90
  * put your comment there...
91
- *
92
  * @var mixed
93
  */
94
  protected $oninsert = array('parameters' => array('query'));
95
 
96
  /**
97
  * put your comment there...
98
- *
99
  * @var mixed
100
  */
101
  protected $oninserted = array('hookType' => CJTWordpressEvents::HOOK_ACTION);
102
-
103
  /**
104
  * put your comment there...
105
- *
106
  * @var mixed
107
  */
108
  protected $onloadquery = array('parameters' => array('query'));
109
-
110
  /**
111
  * put your comment there...
112
- *
113
  * @var mixed
114
  */
115
  protected $onsetfield = array('parameters' => array('property'));
116
-
117
  /**
118
  * put your comment there...
119
- *
120
  * @var mixed
121
  */
122
  protected $onupdate = array('parameters' => array('query'));
123
 
124
  /**
125
  * put your comment there...
126
- *
127
  * @var mixed
128
  */
129
  protected $onupdated = array('hookType' => CJTWordpressEvents::HOOK_ACTION);
130
-
131
  /**
132
  * put your comment there...
133
- *
134
  * @param mixed $table
135
  * @return CJTxTable
136
  */
@@ -146,12 +146,12 @@ abstract class CJTxTable extends CJTHookableClass {
146
  // Read table fields.
147
  $this->fields = $this->dbDriver->getColumns($this->table());
148
  }
149
-
150
  /**
151
  * DELETE!
152
- *
153
  * THIS METHOD SUPPORT COMPOUND KEYS!
154
- *
155
  */
156
  public function delete($key = null) {
157
  // building DELETE query!
@@ -161,15 +161,15 @@ abstract class CJTxTable extends CJTHookableClass {
161
  if ($query = $this->ondelete($query, $key)) {
162
  $query = "{$query['from']} {$query['where']}";
163
  // Delete record.
164
- $this->dbDriver->delete($query)->processQueue();
165
  }
166
  // Chaining!
167
  return $this;
168
  }
169
-
170
  /**
171
  * put your comment there...
172
- *
173
  */
174
  public function fetchAll() {
175
  // Get query.
@@ -180,7 +180,7 @@ abstract class CJTxTable extends CJTHookableClass {
180
 
181
  /**
182
  * put your comment there...
183
- *
184
  * @param mixed $field
185
  */
186
  public function get($field) {
@@ -188,18 +188,18 @@ abstract class CJTxTable extends CJTHookableClass {
188
  $value = (is_object($this->item) && property_exists($this->item, $field)) ? $this->item->{$field} : null;
189
  return $this->ongetfield($value, $field);
190
  }
191
-
192
  /**
193
  * put your comment there...
194
- *
195
  */
196
  public function getData() {
197
  return $this->ongetdata($this->item);
198
  }
199
-
200
  /**
201
  * put your comment there...
202
- *
203
  * @param mixed $object
204
  * @param mixed $dbDriver
205
  * @return CJTxTable
@@ -220,10 +220,10 @@ abstract class CJTxTable extends CJTHookableClass {
220
  }
221
  return $table;
222
  }
223
-
224
  /**
225
  * put your comment there...
226
- *
227
  * @param mixed $query
228
  */
229
  protected function getLoadQuery($query = null) {
@@ -255,7 +255,7 @@ abstract class CJTxTable extends CJTHookableClass {
255
 
256
  /**
257
  * put your comment there...
258
- *
259
  * @param mixed $tableKey
260
  */
261
  public function getKey($tableKey = null) {
@@ -265,18 +265,18 @@ abstract class CJTxTable extends CJTHookableClass {
265
  $key = array_intersect_key(((array) $this->item), array_flip($tableKey));
266
  return $key;
267
  }
268
-
269
  /**
270
  * put your comment there...
271
- *
272
  */
273
  public function getTableKey() {
274
- return $this->key;
275
  }
276
-
277
  /**
278
  * put your comment there...
279
- *
280
  * @param mixed
281
  */
282
  public static function import($type) {
@@ -285,13 +285,13 @@ abstract class CJTxTable extends CJTHookableClass {
285
  // Implort table file.
286
  cssJSToolbox::import("tables:{$type}.php");
287
  }
288
-
289
  /**
290
  * put your comment there...
291
- *
292
  * @param mixed $tableKey
293
  */
294
- public function isValidKey($tableKey = null) {
295
  $isValid = false;
296
  // Get key!
297
  $key = $this->getKey($tableKey);
@@ -304,13 +304,13 @@ abstract class CJTxTable extends CJTHookableClass {
304
  }
305
  return $isValid;
306
  }
307
-
308
 
309
 
310
  /**
311
  * Load record into table!
312
- *
313
- * @param mixed
314
  */
315
  public function load($query = null) {
316
  try {
@@ -326,10 +326,10 @@ abstract class CJTxTable extends CJTHookableClass {
326
  // Chaining.
327
  return $this;
328
  }
329
-
330
  /**
331
  * put your comment there...
332
- *
333
  * @param mixed $values
334
  */
335
  public function loadAsKey($values) {
@@ -338,9 +338,9 @@ abstract class CJTxTable extends CJTHookableClass {
338
 
339
  /**
340
  * put your comment there...
341
- *
342
  * @todo Delete method and use CJTMYSQLQuery instead.
343
- *
344
  * @param mixed $parameters
345
  */
346
  protected function prepareQueryParameters($parameters, $operators = array(), $defaultOperator = '=', $excludeNulls = true) {
@@ -358,15 +358,15 @@ abstract class CJTxTable extends CJTHookableClass {
358
  // Get name-value operator.
359
  $operator = isset($operators[$name]) ? $operators[$name] : $defaultOperator;
360
  $prepared[] = "`{$name}`{$operator}{$value}";
361
- }
362
  }
363
  }
364
  return $prepared;
365
  }
366
-
367
  /**
368
  * THIS METHOD STILL DOESNT SUPPORT COMPOUND KEYS!!
369
- *
370
  * @param mixed $forceInsert
371
  * @param mixed $updateIdField
372
  * @return CJTxTable
@@ -383,7 +383,7 @@ abstract class CJTxTable extends CJTHookableClass {
383
  $query = "UPDATE {$this->table()} SET {$fieldsList} WHERE {$condition}";
384
  if ($query = $this->onupdate($query)) {
385
  $this->dbDriver->update($query)
386
- ->processQueue();
387
  $this->onupdated();
388
  }
389
  }
@@ -398,10 +398,10 @@ abstract class CJTxTable extends CJTHookableClass {
398
  }
399
  return $this;
400
  }
401
-
402
  /**
403
  * put your comment there...
404
- *
405
  * @param mixed $prop
406
  * @param mixed $value
407
  */
@@ -410,10 +410,10 @@ abstract class CJTxTable extends CJTHookableClass {
410
  $this->item->{$prop} = $value;
411
  return $this;
412
  }
413
-
414
  /**
415
  * put your comment there...
416
- *
417
  * @param mixed $data
418
  */
419
  public function setData($data) {
@@ -430,7 +430,7 @@ abstract class CJTxTable extends CJTHookableClass {
430
 
431
  /**
432
  * put your comment there...
433
- *
434
  * @param mixed $item
435
  * @return CJTxTable
436
  */
@@ -442,27 +442,27 @@ abstract class CJTxTable extends CJTHookableClass {
442
  // Set internal item object!
443
  $this->item = $item;
444
  // Chaining!
445
- return $this;
446
  }
447
-
448
  /**
449
  * put your comment there...
450
- *
451
  * @param mixed $key
452
  */
453
  public function setTableKey($key) {
454
  $this->key = $key;
455
- return $this;
456
  }
457
-
458
  /**
459
  * put your comment there...
460
- *
461
  */
462
  public function table() {
463
  return $this->name;
464
  }
465
-
466
  } // End class.
467
 
468
  // Hookable.
1
  <?php
2
  /**
3
+ *
4
  */
5
 
6
  // Disallow direct access.
7
  defined('ABSPATH') or die("Access denied");
8
 
9
  /**
10
+ *
11
  */
12
  abstract class CJTxTable extends CJTHookableClass {
13
+
14
  /**
15
  * put your comment there...
16
+ *
17
  * @var mixed
18
  */
19
  protected $dbDriver;
20
+
21
  /**
22
  * put your comment there...
23
+ *
24
  * @var mixed
25
  */
26
  private $fields;
27
+
28
  /**
29
  * put your comment there...
30
+ *
31
  * @var mixed
32
  */
33
  protected $item;
34
+
35
  /**
36
  * put your comment there...
37
+ *
38
  * @var mixed
39
  */
40
  protected $key;
41
+
42
  /**
43
+ *
44
  */
45
  private $name;
46
+
47
  /**
48
  * put your comment there...
49
+ *
50
  * @var mixed
51
  */
52
  protected $onconcatquery = array('parameters' => array('query'));
53
+
54
  /**
55
  * put your comment there...
56
+ *
57
  * @var mixed
58
  */
59
  protected $ondelete = array('parameters' => array('query', 'key'));
60
 
61
  /**
62
  * put your comment there...
63
+ *
64
  * @var mixed
65
  */
66
  protected $ongetdata = array('parameters' => array('item'));
67
 
68
  /**
69
  * put your comment there...
70
+ *
71
  * @var mixed
72
  */
73
  protected $ongetfield = array('parameters' => array('value', 'name'));
74
 
75
  /**
76
  * put your comment there...
77
+ *
78
  * @var mixed
79
  */
80
  protected static $onimport = array('parameters' => array('type'));
81
+
82
  /**
83
  * put your comment there...
84
+ *
85
  * @var mixed
86
  */
87
  protected static $oninstantiate = array('parameters' => array('args'));
88
+
89
  /**
90
  * put your comment there...
91
+ *
92
  * @var mixed
93
  */
94
  protected $oninsert = array('parameters' => array('query'));
95
 
96
  /**
97
  * put your comment there...
98
+ *
99
  * @var mixed
100
  */
101
  protected $oninserted = array('hookType' => CJTWordpressEvents::HOOK_ACTION);
102
+
103
  /**
104
  * put your comment there...
105
+ *
106
  * @var mixed
107
  */
108
  protected $onloadquery = array('parameters' => array('query'));
109
+
110
  /**
111
  * put your comment there...
112
+ *
113
  * @var mixed
114
  */
115
  protected $onsetfield = array('parameters' => array('property'));
116
+
117
  /**
118
  * put your comment there...
119
+ *
120
  * @var mixed
121
  */
122
  protected $onupdate = array('parameters' => array('query'));
123
 
124
  /**
125
  * put your comment there...
126
+ *
127
  * @var mixed
128
  */
129
  protected $onupdated = array('hookType' => CJTWordpressEvents::HOOK_ACTION);
130
+
131
  /**
132
  * put your comment there...
133
+ *
134
  * @param mixed $table
135
  * @return CJTxTable
136
  */
146
  // Read table fields.
147
  $this->fields = $this->dbDriver->getColumns($this->table());
148
  }
149
+
150
  /**
151
  * DELETE!
152
+ *
153
  * THIS METHOD SUPPORT COMPOUND KEYS!
154
+ *
155
  */
156
  public function delete($key = null) {
157
  // building DELETE query!
161
  if ($query = $this->ondelete($query, $key)) {
162
  $query = "{$query['from']} {$query['where']}";
163
  // Delete record.
164
+ $this->dbDriver->delete($query)->processQueue();
165
  }
166
  // Chaining!
167
  return $this;
168
  }
169
+
170
  /**
171
  * put your comment there...
172
+ *
173
  */
174
  public function fetchAll() {
175
  // Get query.
180
 
181
  /**
182
  * put your comment there...
183
+ *
184
  * @param mixed $field
185
  */
186
  public function get($field) {
188
  $value = (is_object($this->item) && property_exists($this->item, $field)) ? $this->item->{$field} : null;
189
  return $this->ongetfield($value, $field);
190
  }
191
+
192
  /**
193
  * put your comment there...
194
+ *
195
  */
196
  public function getData() {
197
  return $this->ongetdata($this->item);
198
  }
199
+
200
  /**
201
  * put your comment there...
202
+ *
203
  * @param mixed $object
204
  * @param mixed $dbDriver
205
  * @return CJTxTable
220
  }
221
  return $table;
222
  }
223
+
224
  /**
225
  * put your comment there...
226
+ *
227
  * @param mixed $query
228
  */
229
  protected function getLoadQuery($query = null) {
255
 
256
  /**
257
  * put your comment there...
258
+ *
259
  * @param mixed $tableKey
260
  */
261
  public function getKey($tableKey = null) {
265
  $key = array_intersect_key(((array) $this->item), array_flip($tableKey));
266
  return $key;
267
  }
268
+
269
  /**
270
  * put your comment there...
271
+ *
272
  */
273
  public function getTableKey() {
274
+ return $this->key;
275
  }
276
+
277
  /**
278
  * put your comment there...
279
+ *
280
  * @param mixed
281
  */
282
  public static function import($type) {
285
  // Implort table file.
286
  cssJSToolbox::import("tables:{$type}.php");
287
  }
288
+
289
  /**
290
  * put your comment there...
291
+ *
292
  * @param mixed $tableKey
293
  */
294
+ public function isValidKey($tableKey = null) {
295
  $isValid = false;
296
  // Get key!
297
  $key = $this->getKey($tableKey);
304
  }
305
  return $isValid;
306
  }
307
+
308
 
309
 
310
  /**
311
  * Load record into table!
312
+ *
313
+ * @param mixed
314
  */
315
  public function load($query = null) {
316
  try {
326
  // Chaining.
327
  return $this;
328
  }
329
+
330
  /**
331
  * put your comment there...
332
+ *
333
  * @param mixed $values
334
  */
335
  public function loadAsKey($values) {
338
 
339
  /**
340
  * put your comment there...
341
+ *
342
  * @todo Delete method and use CJTMYSQLQuery instead.
343
+ *
344
  * @param mixed $parameters
345
  */
346
  protected function prepareQueryParameters($parameters, $operators = array(), $defaultOperator = '=', $excludeNulls = true) {
358
  // Get name-value operator.
359
  $operator = isset($operators[$name]) ? $operators[$name] : $defaultOperator;
360
  $prepared[] = "`{$name}`{$operator}{$value}";
361
+ }
362
  }
363
  }
364
  return $prepared;
365
  }
366
+
367
  /**
368
  * THIS METHOD STILL DOESNT SUPPORT COMPOUND KEYS!!
369
+ *
370
  * @param mixed $forceInsert
371
  * @param mixed $updateIdField
372
  * @return CJTxTable
383
  $query = "UPDATE {$this->table()} SET {$fieldsList} WHERE {$condition}";
384
  if ($query = $this->onupdate($query)) {
385
  $this->dbDriver->update($query)
386
+ ->processQueue();
387
  $this->onupdated();
388
  }
389
  }
398
  }
399
  return $this;
400
  }
401
+
402
  /**
403
  * put your comment there...
404
+ *
405
  * @param mixed $prop
406
  * @param mixed $value
407
  */
410
  $this->item->{$prop} = $value;
411
  return $this;
412
  }
413
+
414
  /**
415
  * put your comment there...
416
+ *
417
  * @param mixed $data
418
  */
419
  public function setData($data) {
430
 
431
  /**
432
  * put your comment there...
433
+ *
434
  * @param mixed $item
435
  * @return CJTxTable
436
  */
442
  // Set internal item object!
443
  $this->item = $item;
444
  // Chaining!
445
+ return $this;
446
  }
447
+
448
  /**
449
  * put your comment there...
450
+ *
451
  * @param mixed $key
452
  */
453
  public function setTableKey($key) {
454
  $this->key = $key;
455
+ return $this;
456
  }
457
+
458
  /**
459
  * put your comment there...
460
+ *
461
  */
462
  public function table() {
463
  return $this->name;
464
  }
465
+
466
  } // End class.
467
 
468
  // Hookable.
framework/events/observers/observer.observer.php CHANGED
@@ -1,83 +1,83 @@
1
  <?php
2
  /**
3
- *
4
  */
5
 
6
  //Import dependencies.
7
  require_once 'observer.interface.php';
8
 
9
  /**
10
- *
11
  */
12
  abstract class CJTObserver implements CJTIObserver {
13
 
14
  /**
15
- *
16
  */
17
  const CALLBACK_CLASS = 0;
18
-
19
  /**
20
- *
21
  */
22
  const CALLBACK_METHOD = 1;
23
-
24
  /**
25
- *
26
  */
27
  const REDIRECT_MODE_PERMANENT = 0;
28
-
29
  /**
30
  * put your comment there...
31
- *
32
  * @var mixed
33
  */
34
  protected $callback;
35
-
36
  /**
37
  * put your comment there...
38
- *
39
  * @var mixed
40
  */
41
  protected $filter;
42
-
43
  /**
44
  * put your comment there...
45
- *
46
  * @var mixed
47
  */
48
  protected $key;
49
-
50
  /**
51
  * put your comment there...
52
- *
53
  * @var mixed
54
  */
55
  protected $name;
56
-
57
  /**
58
  * put your comment there...
59
- *
60
  * @var mixed
61
  */
62
  protected $param;
63
-
64
  /**
65
  * put your comment there...
66
- *
67
  * @var mixed
68
  */
69
  protected $params;
70
-
71
  /**
72
  * put your comment there...
73
- *
74
  * @var mixed
75
  */
76
  protected $subject;
77
-
78
  /**
79
  * put your comment there...
80
- *
81
  * @param mixed $name
82
  * @return CJTObserver
83
  */
@@ -85,28 +85,28 @@ abstract class CJTObserver implements CJTIObserver {
85
  $this->name = $name;
86
  $this->filter = $filter;
87
  }
88
-
89
  /**
90
  * put your comment there...
91
- *
92
  */
93
  public function getCallback($component = self::CALLBACK_CLASS) {
94
  $component = ($component !== null) ? $this->callback[$component] : $this->callback;
95
  return $component;
96
  }
97
-
98
  /**
99
  * put your comment there...
100
- *
101
  * @param mixed $name
102
  */
103
  public function getFilter($name) {
104
- return $this->filter[$name];
105
  }
106
-
107
  /**
108
  * put your comment there...
109
- *
110
  * @param mixed $observer
111
  */
112
  public static function getInstance($subject, $callback) {
@@ -142,18 +142,18 @@ abstract class CJTObserver implements CJTIObserver {
142
  }
143
  return $observer;
144
  }
145
-
146
  /**
147
  * put your comment there...
148
- *
149
  */
150
  public function getKey() {
151
- return $this->key;
152
  }
153
-
154
  /**
155
  * put your comment there...
156
- *
157
  */
158
  public function getName() {
159
  return $this->name;
@@ -161,31 +161,31 @@ abstract class CJTObserver implements CJTIObserver {
161
 
162
  /**
163
  * put your comment there...
164
- *
165
  */
166
  public function getParam() {
167
- return $this->param;
168
  }
169
-
170
  /**
171
  * put your comment there...
172
- *
173
  */
174
  public function getSubject() {
175
- return $this->subject;
176
  }
177
-
178
  /**
179
  * put your comment there...
180
- *
181
  */
182
  public function getTarget() {
183
  return $this->getSubject()->getTarget();
184
  }
185
-
186
  /**
187
  * put your comment there...
188
- *
189
  * @param mixed $subject
190
  * @param mixed $callback
191
  */
@@ -197,10 +197,10 @@ abstract class CJTObserver implements CJTIObserver {
197
  // Chain!
198
  return $this;
199
  }
200
-
201
  /**
202
  * put your comment there...
203
- *
204
  * @param mixed $callback
205
  * @param mixed $mode
206
  */
@@ -222,16 +222,16 @@ abstract class CJTObserver implements CJTIObserver {
222
  }
223
  return $this->redirectReturn();
224
  }
225
-
226
  /**
227
  * put your comment there...
228
- *
229
  */
230
  protected abstract function redirectReturn();
231
-
232
  /**
233
  * put your comment there...
234
- *
235
  */
236
  public function trigger() {
237
  $this->params = func_get_args();
@@ -239,5 +239,5 @@ abstract class CJTObserver implements CJTIObserver {
239
  $return = call_user_func_array($this->callback, $this->params);
240
  return $return;
241
  }
242
-
243
  } // End class
1
  <?php
2
  /**
3
+ *
4
  */
5
 
6
  //Import dependencies.
7
  require_once 'observer.interface.php';
8
 
9
  /**
10
+ *
11
  */
12
  abstract class CJTObserver implements CJTIObserver {
13
 
14
  /**
15
+ *
16
  */
17
  const CALLBACK_CLASS = 0;
18
+
19
  /**
20
+ *
21
  */
22
  const CALLBACK_METHOD = 1;
23
+
24
  /**
25
+ *
26
  */
27
  const REDIRECT_MODE_PERMANENT = 0;
28
+
29
  /**
30
  * put your comment there...
31
+ *
32
  * @var mixed
33
  */
34
  protected $callback;
35
+
36
  /**
37
  * put your comment there...
38
+ *
39
  * @var mixed
40
  */
41
  protected $filter;
42
+
43
  /**
44
  * put your comment there...
45
+ *
46
  * @var mixed
47
  */
48
  protected $key;
49
+
50
  /**
51
  * put your comment there...
52
+ *
53
  * @var mixed
54
  */
55
  protected $name;
56
+
57
  /**
58
  * put your comment there...
59
+ *
60
  * @var mixed
61
  */
62
  protected $param;
63
+
64
  /**
65
  * put your comment there...
66
+ *
67
  * @var mixed
68
  */
69
  protected $params;
70
+
71
  /**
72
  * put your comment there...
73
+ *
74
  * @var mixed
75
  */
76
  protected $subject;
77
+
78
  /**
79
  * put your comment there...
80
+ *
81
  * @param mixed $name
82
  * @return CJTObserver
83
  */
85
  $this->name = $name;
86
  $this->filter = $filter;
87
  }
88
+
89
  /**
90
  * put your comment there...
91
+ *
92
  */
93
  public function getCallback($component = self::CALLBACK_CLASS) {
94
  $component = ($component !== null) ? $this->callback[$component] : $this->callback;
95
  return $component;
96
  }
97
+
98
  /**
99
  * put your comment there...
100
+ *
101
  * @param mixed $name
102
  */
103
  public function getFilter($name) {
104
+ return $this->filter[$name];
105
  }
106
+
107
  /**
108
  * put your comment there...
109
+ *
110
  * @param mixed $observer
111
  */
112
  public static function getInstance($subject, $callback) {
142
  }
143
  return $observer;
144
  }
145
+
146
  /**
147
  * put your comment there...
148
+ *
149
  */
150
  public function getKey() {
151
+ return $this->key;
152
  }
153
+
154
  /**
155
  * put your comment there...
156
+ *
157
  */
158
  public function getName() {
159
  return $this->name;
161
 
162
  /**
163
  * put your comment there...
164
+ *
165
  */
166
  public function getParam() {
167
+ return $this->param;
168
  }
169
+
170
  /**
171
  * put your comment there...
172
+ *
173
  */
174
  public function getSubject() {
175
+ return $this->subject;
176
  }
177
+
178
  /**
179
  * put your comment there...
180
+ *
181
  */
182
  public function getTarget() {
183
  return $this->getSubject()->getTarget();
184
  }
185
+
186
  /**
187
  * put your comment there...
188
+ *
189
  * @param mixed $subject
190
  * @param mixed $callback
191
  */
197
  // Chain!
198
  return $this;
199
  }
200
+
201
  /**
202
  * put your comment there...
203
+ *
204
  * @param mixed $callback
205
  * @param mixed $mode
206
  */
222
  }
223
  return $this->redirectReturn();
224
  }
225
+
226
  /**
227
  * put your comment there...
228
+ *
229
  */
230
  protected abstract function redirectReturn();
231
+
232
  /**
233
  * put your comment there...
234
+ *
235
  */
236
  public function trigger() {
237
  $this->params = func_get_args();
239
  $return = call_user_func_array($this->callback, $this->params);
240
  return $return;
241
  }
242
+
243
  } // End class
framework/events/subjects/subject.subject.php CHANGED
@@ -224,7 +224,7 @@ abstract class CJTEESubject implements CJTEEISubject, Countable, ArrayAccess {
224
  if ($this->processFilter($observer)) {
225
  // Pass observer referecne along with user params!!
226
  $this->result['params']['observer'] = $observer;
227
- $this->result['return'] = call_user_func_array(array($observer, 'trigger'), $this->result['params']);
228
  // Prepare parameters based on the previous call result!
229
  $this->prepareResultParameters();
230
  }
224
  if ($this->processFilter($observer)) {
225
  // Pass observer referecne along with user params!!
226
  $this->result['params']['observer'] = $observer;
227
+ $this->result['return'] = call_user_func_array( [ $observer, 'trigger' ], array_values( $this->result['params'] ) );
228
  // Prepare parameters based on the previous call result!
229
  $this->prepareResultParameters();
230
  }
framework/extensions/extensions.class.php CHANGED
@@ -294,7 +294,7 @@ class CJTExtensions extends CJTHookableClass {
294
  // Filters!
295
  extract($this->onload($extension, compact('class', 'extension')));
296
  // Build Extension plugin path
297
- $pluginPath = ABSPATH . PLUGINDIR . "/{$extension['name']}";
298
  // Set runtime variables.
299
  $this->extensions[$class]['runtime']['classFile'] = "{$pluginPath}/{$extension['name']}.class.php";
300
  // Load definition.
294
  // Filters!
295
  extract($this->onload($extension, compact('class', 'extension')));
296
  // Build Extension plugin path
297
+ $pluginPath = WP_PLUGIN_DIR . "/{$extension['name']}";
298
  // Set runtime variables.
299
  $this->extensions[$class]['runtime']['classFile'] = "{$pluginPath}/{$extension['name']}.class.php";
300
  // Load definition.
framework/extensions/package/extension.php CHANGED
@@ -1,30 +1,30 @@
1
  <?php
2
  /**
3
- *
4
  */
5
 
6
  /**
7
- *
8
  */
9
  abstract class CJT_Framework_Extensions_Package_Extension extends CJTHookableClass {
10
 
11
  /**
12
  * put your comment there...
13
- *
14
  * @var mixed
15
  */
16
  protected $extension;
17
-
18
  /**
19
  * put your comment there...
20
- *
21
  * @var mixed
22
  */
23
  protected $extensionClass;
24
-
25
  /**
26
  * put your comment there...
27
- *
28
  * @param mixed $extension
29
  * @return CJT_Framework_Extensions_Package_Extension
30
  */
@@ -36,7 +36,7 @@ abstract class CJT_Framework_Extensions_Package_Extension extends CJTHookableCla
36
 
37
  /**
38
  * Uninstaller for all Package Extension
39
- *
40
  * @param mixed $method
41
  * @param mixed $params
42
  * @return CJTWordpressEvents
@@ -61,7 +61,7 @@ abstract class CJT_Framework_Extensions_Package_Extension extends CJTHookableCla
61
 
62
  /**
63
  * put your comment there...
64
- *
65
  */
66
  public function _checkInstallationState() {
67
  # Initialize
@@ -69,14 +69,14 @@ abstract class CJT_Framework_Extensions_Package_Extension extends CJTHookableCla
69
  $extension =& $this->extension;
70
  $extensionDeDoc =& $extension['defDoc'];
71
  $extensionState = new CJT_Framework_Extensions_Package_State_Extension($extensionDeDoc);
72
- # Upgrade and Install is the same both
73
  # required checking the packages inside
74
  # Package-Extension is a only a wrapper for packages inside!
75
  if ($extensionState->getState() != CJT_Framework_Extensions_Package_State_Extension::INSTALLED) {
76
  # Initialize
77
  $packageFileModel = CJTModel::getInstance('package-file');
78
  $packageModel = CJTModel::getInstance('package');
79
- $extensionDir = ABSPATH . PLUGINDIR . DIRECTORY_SEPARATOR . $extension['dir'];
80
  $packagesFolderPath = $extensionDir . DIRECTORY_SEPARATOR . ((string) $extensionDeDoc->packages->attributes()->folder);
81
  # Getting packages state
82
  $extensionPackagesState = new CJT_Framework_Extensions_Package_State_Packages($extensionDeDoc);
@@ -114,13 +114,13 @@ abstract class CJT_Framework_Extensions_Package_Extension extends CJTHookableCla
114
  # Upgrade extension state
115
  $extensionState->upgrade($extension['defFile']);
116
  # Register uninstaller
117
- register_uninstall_hook($extension['pluginFile'], array(__CLASS__, "uninstall_{$extensionClass}"));
118
  }
119
  }
120
 
121
  /**
122
  * put your comment there...
123
- *
124
  */
125
  public function _extensionDeactivated() {
126
  # Initialize
@@ -133,31 +133,31 @@ abstract class CJT_Framework_Extensions_Package_Extension extends CJTHookableCla
133
 
134
  /**
135
  * put your comment there...
136
- *
137
  */
138
  public function getInvolved() {
139
- # Check installation state
140
  if (CJTPlugin::getInstance()->isInstalled()) {
141
  # INitialize
142
  $extensionClass = $this->extensionClass;
143
  $extension =& $this->extension;
144
- $extensionFile = ABSPATH . PLUGINDIR . DIRECTORY_SEPARATOR . $extension['dir'] . DIRECTORY_SEPARATOR . $extension['file'];
145
  # Load/install extensions packages hook
146
- add_action('init', array($this, '_checkInstallationState'));
147
  # Deactivation hooks
148
  register_deactivation_hook($extensionFile, array($this, '_extensionDeactivated'));
149
  }
150
  }
151
-
152
  /**
153
  * put your comment there...
154
- *
155
  * @param mixed $class
156
  */
157
  public static function getPluginExtensionClass($object) {
158
  return str_replace('_Plugin', '', get_class($object));
159
  }
160
-
161
  } # End class
162
 
163
  // Hiookable!
1
  <?php
2
  /**
3
+ *
4
  */
5
 
6
  /**
7
+ *
8
  */
9
  abstract class CJT_Framework_Extensions_Package_Extension extends CJTHookableClass {
10
 
11
  /**
12
  * put your comment there...
13
+ *
14
  * @var mixed
15
  */
16
  protected $extension;
17
+
18
  /**
19
  * put your comment there...
20
+ *
21
  * @var mixed
22
  */
23
  protected $extensionClass;
24
+
25
  /**
26
  * put your comment there...
27
+ *
28
  * @param mixed $extension
29
  * @return CJT_Framework_Extensions_Package_Extension
30
  */
36
 
37
  /**
38
  * Uninstaller for all Package Extension
39
+ *
40
  * @param mixed $method
41
  * @param mixed $params
42
  * @return CJTWordpressEvents
61
 
62
  /**
63
  * put your comment there...
64
+ *
65
  */
66
  public function _checkInstallationState() {
67
  # Initialize
69
  $extension =& $this->extension;
70
  $extensionDeDoc =& $extension['defDoc'];
71
  $extensionState = new CJT_Framework_Extensions_Package_State_Extension($extensionDeDoc);
72
+ # Upgrade and Install is the same both
73
  # required checking the packages inside
74
  # Package-Extension is a only a wrapper for packages inside!
75
  if ($extensionState->getState() != CJT_Framework_Extensions_Package_State_Extension::INSTALLED) {
76
  # Initialize
77
  $packageFileModel = CJTModel::getInstance('package-file');
78
  $packageModel = CJTModel::getInstance('package');
79
+ $extensionDir = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $extension['dir'];
80
  $packagesFolderPath = $extensionDir . DIRECTORY_SEPARATOR . ((string) $extensionDeDoc->packages->attributes()->folder);
81
  # Getting packages state
82
  $extensionPackagesState = new CJT_Framework_Extensions_Package_State_Packages($extensionDeDoc);
114
  # Upgrade extension state
115
  $extensionState->upgrade($extension['defFile']);
116
  # Register uninstaller
117
+ register_uninstall_hook($extension['pluginFile'], array(__CLASS__, "uninstall_{$extensionClass}"));
118
  }
119
  }
120
 
121
  /**
122
  * put your comment there...
123
+ *
124
  */
125
  public function _extensionDeactivated() {
126
  # Initialize
133
 
134
  /**
135
  * put your comment there...
136
+ *
137
  */
138
  public function getInvolved() {
139
+ # Check installation state
140
  if (CJTPlugin::getInstance()->isInstalled()) {
141
  # INitialize
142
  $extensionClass = $this->extensionClass;
143
  $extension =& $this->extension;
144
+ $extensionFile = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $extension['dir'] . DIRECTORY_SEPARATOR . $extension['file'];
145
  # Load/install extensions packages hook
146
+ add_action('init', array($this, '_checkInstallationState'));
147
  # Deactivation hooks
148
  register_deactivation_hook($extensionFile, array($this, '_extensionDeactivated'));
149
  }
150
  }
151
+
152
  /**
153
  * put your comment there...
154
+ *
155
  * @param mixed $class
156
  */
157
  public static function getPluginExtensionClass($object) {
158
  return str_replace('_Plugin', '', get_class($object));
159
  }
160
+
161
  } # End class
162
 
163
  // Hiookable!
framework/extensions/package/state/extension.php CHANGED
@@ -1,73 +1,73 @@
1
  <?php
2
  /**
3
- *
4
  */
5
 
6
  /**
7
- *
8
  */
9
  class CJT_Framework_Extensions_Package_State_Extension {
10
 
11
  /**
12
- *
13
  */
14
  const INSTALLED = 3;
15
-
16
  /**
17
- *
18
  */
19
  const NOT_INSTALLED = 1;
20
-
21
  /**
22
- *
23
  */
24
  const UPGRADE = 2;
25
-
26
  /**
27
  * put your comment there...
28
- *
29
  * @var mixed
30
  */
31
  protected $data;
32
-
33
  /**
34
  * put your comment there...
35
- *
36
  * @var mixed
37
  */
38
  protected $dbOptionName;
39
-
40
  /**
41
  * put your comment there...
42
- *
43
  * @var mixed
44
  */
45
  protected $extDefDoc;
46
-
47
  /**
48
  * put your comment there...
49
- *
50
  * @var mixed
51
  */
52
  protected $name;
53
-
54
  /**
55
  * put your comment there...
56
- *
57
  * @var mixed
58
  */
59
  protected $newVersion;
60
-
61
  /**
62
  * put your comment there...
63
- *
64
  * @var mixed
65
  */
66
  protected $state;
67
-
68
  /**
69
  * put your comment there...
70
- *
71
  * @param mixed $name
72
  * @return CJT_Framework_Extensions_Package_InfoStructure
73
  */
@@ -86,7 +86,7 @@ class CJT_Framework_Extensions_Package_State_Extension {
86
 
87
  /**
88
  * put your comment there...
89
- *
90
  * @param mixed $extensionClass
91
  */
92
  public static function create($extensionClass) {
@@ -95,7 +95,7 @@ class CJT_Framework_Extensions_Package_State_Extension {
95
  # Reading cached state
96
  $state = get_option($dbOptionName);
97
  # Getting extension defFile
98
- $defFile = ABSPATH . PLUGINDIR . DIRECTORY_SEPARATOR . $state['defFile'];
99
  $deDoc = new SimpleXMLElement(file_get_contents($defFile));
100
  # Returns new instance
101
  return new CJT_Framework_Extensions_Package_State_Extension($deDoc);
@@ -103,7 +103,7 @@ class CJT_Framework_Extensions_Package_State_Extension {
103
 
104
  /**
105
  * put your comment there...
106
- *
107
  */
108
  public function clearInstallInfo() {
109
  return delete_option($this->dbOptionName);
@@ -111,7 +111,7 @@ class CJT_Framework_Extensions_Package_State_Extension {
111
 
112
  /**
113
  * put your comment there...
114
- *
115
  * @param mixed $name
116
  */
117
  protected function getDBVar($name) {
@@ -120,7 +120,7 @@ class CJT_Framework_Extensions_Package_State_Extension {
120
 
121
  /**
122
  * put your comment there...
123
- *
124
  * @param mixed $extensionClass
125
  */
126
  protected static function getDbOptionName($extensionClass) {
@@ -129,23 +129,23 @@ class CJT_Framework_Extensions_Package_State_Extension {
129
 
130
  /**
131
  * put your comment there...
132
- *
133
  */
134
  public function & getExtensionDeDoc() {
135
  return $this->extDefDoc;
136
  }
137
-
138
  /**
139
  * put your comment there...
140
- *
141
  */
142
  protected function getInstalledVersion() {
143
  return $this->getDBVar('version');
144
  }
145
-
146
  /**
147
  * put your comment there...
148
- *
149
  */
150
  public function getState() {
151
  # Initialize
@@ -176,7 +176,7 @@ class CJT_Framework_Extensions_Package_State_Extension {
176
  }
177
  /**
178
  * put your comment there...
179
- *
180
  * @param mixed $pluginFile
181
  * @return bool
182
  */
1
  <?php
2
  /**
3
+ *
4
  */
5
 
6
  /**
7
+ *
8
  */
9
  class CJT_Framework_Extensions_Package_State_Extension {
10
 
11
  /**
12
+ *
13
  */
14
  const INSTALLED = 3;
15
+
16
  /**
17
+ *
18
  */
19
  const NOT_INSTALLED = 1;
20
+
21
  /**
22
+ *
23
  */
24
  const UPGRADE = 2;
25
+
26
  /**
27
  * put your comment there...
28
+ *
29
  * @var mixed
30
  */
31
  protected $data;
32
+
33
  /**
34
  * put your comment there...
35
+ *
36
  * @var mixed
37
  */
38
  protected $dbOptionName;
39
+
40
  /**
41
  * put your comment there...
42
+ *
43
  * @var mixed
44
  */
45
  protected $extDefDoc;
46
+
47
  /**
48
  * put your comment there...
49
+ *
50
  * @var mixed
51
  */
52
  protected $name;
53
+
54
  /**
55
  * put your comment there...
56
+ *
57
  * @var mixed
58
  */
59
  protected $newVersion;
60
+
61
  /**
62
  * put your comment there...
63
+ *
64
  * @var mixed
65
  */
66
  protected $state;
67
+
68
  /**
69
  * put your comment there...
70
+ *
71
  * @param mixed $name
72
  * @return CJT_Framework_Extensions_Package_InfoStructure
73
  */
86
 
87
  /**
88
  * put your comment there...
89
+ *
90
  * @param mixed $extensionClass
91
  */
92
  public static function create($extensionClass) {
95
  # Reading cached state
96
  $state = get_option($dbOptionName);
97
  # Getting extension defFile
98
+ $defFile = WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $state['defFile'];
99
  $deDoc = new SimpleXMLElement(file_get_contents($defFile));
100
  # Returns new instance
101
  return new CJT_Framework_Extensions_Package_State_Extension($deDoc);
103
 
104
  /**
105
  * put your comment there...
106
+ *
107
  */
108
  public function clearInstallInfo() {
109
  return delete_option($this->dbOptionName);
111
 
112
  /**
113
  * put your comment there...
114
+ *
115
  * @param mixed $name
116
  */
117
  protected function getDBVar($name) {
120
 
121
  /**
122
  * put your comment there...
123
+ *
124
  * @param mixed $extensionClass
125
  */
126
  protected static function getDbOptionName($extensionClass) {
129
 
130
  /**
131
  * put your comment there...
132
+ *
133
  */
134
  public function & getExtensionDeDoc() {
135
  return $this->extDefDoc;
136
  }
137
+
138
  /**
139
  * put your comment there...
140
+ *
141
  */
142
  protected function getInstalledVersion() {
143
  return $this->getDBVar('version');
144
  }
145
+
146
  /**
147
  * put your comment there...
148
+ *
149
  */
150
  public function getState() {
151
  # Initialize
176
  }
177
  /**
178
  * put your comment there...
179
+ *
180
  * @param mixed $pluginFile
181
  * @return bool
182
  */
framework/js/ajax/cjt-server-queue/cjt-server-queue.js CHANGED
@@ -14,7 +14,7 @@ var CJTServerQueue;
14
  /*
15
  * JQuery wrapper for the CJTServerQueue object.
16
  */
17
- (function($) {
18
 
19
  /*
20
  * Abstract base class for Ajax Queue classes.
@@ -33,21 +33,21 @@ var CJTServerQueue;
33
  * @author Ahmed Said
34
  * @version 6
35
  */
36
- CJTServerQueue = function() {
37
 
38
  /*
39
  * Operation Action.
40
  *
41
  * @var string
42
  */
43
- this.action = null;
44
 
45
  /*
46
  * Controller map name.
47
  *
48
  * @var string
49
  */
50
- this.controller = null;
51
 
52
  /*
53
  * Queue object unique identifier.
@@ -55,7 +55,7 @@ var CJTServerQueue;
55
  * @internal
56
  * @var string
57
  */
58
- this.key = '';
59
 
60
  /*
61
  * Lock or Unlock queue object allow and disallow sending
@@ -63,7 +63,7 @@ var CJTServerQueue;
63
  *
64
  * @var boolean
65
  */
66
- this.locked = false;
67
 
68
  /*
69
  * Operations queue.
@@ -73,9 +73,9 @@ var CJTServerQueue;
73
  *
74
  * @var object
75
  */
76
- this.queue = [];
77
 
78
- this.errors = [];
79
 
80
  /*
81
  * Derived classed constructor.
@@ -87,14 +87,14 @@ var CJTServerQueue;
87
  * @param string Queue key.
88
  * @return void
89
  */
90
- this._init = function(controller, action, key) {
91
- this.controller = controller;
92
- this.action = action;
93
- this.key = key;
94
  // Reset prototype copy vars.
95
- this.queue = [];
96
- this.locked = false;
97
- }
98
 
99
  /*
100
  * Add request to the queue.
@@ -117,11 +117,11 @@ var CJTServerQueue;
117
  * @param string Queue type.
118
  * @return CJTServer.getDeferredObject.promise()
119
  */
120
- this.add = function (data, context, type) {
121
  // Check for special characters in block name.
122
- if (data.property === 'name') {
123
- if (!data.value.match(/^[A-Za-z0-9\!\#\@\$\&\*\(\)\[\]\x20\-\_\+\?\:\;\.]{1,50}$/)) {
124
- alert('The block name cannot contain special characters. Please use A-Z, 0-9, -, _ and space characters only.')
125
 
126
  this.errors = data.value
127
  } else {
@@ -129,17 +129,17 @@ var CJTServerQueue;
129
  }
130
  }
131
 
132
- if (this.errors.length <= 0) {
133
  var queue = {
134
  deferred: CJTServer.getDeferredObject(),
135
  data: data,
136
  context: context,
137
- type: ((type == undefined) ? 'queue' : type)
138
- };
139
- var promise = queue.deferred.promise();
140
  // Add queue object to the queue.
141
- this.queue.push(queue);
142
- return promise;
143
  } else {
144
  return CJTServer.getDeferredObject().promise()
145
  }
@@ -154,8 +154,8 @@ var CJTServerQueue;
154
  *
155
  * @return void
156
  */
157
- this.clear = function() {
158
- this.queue = [];
159
  }
160
 
161
  /*
@@ -171,29 +171,29 @@ var CJTServerQueue;
171
  * @param object Response Object to pass to the callbacks.
172
  * @return void
173
  */
174
- this.dispatch = function(state, response) {
175
- var method = state + 'With';
176
- var serverQueue = this; // To use inside .each().
177
- var queueParams = null;
178
- $(this.queue).each(function(index, queue) {
179
- // If rejected don't call getResponseParameters() to avoid error
180
- // This is a temporary solution for version 6.0 to be releases!
181
- // Get queue parameters based on queue type.
182
- if ((state == 'reject') || (queue.type == 'endpoint')) {
183
- // endpoint type queue is queue to handle the typical/native
184
- // ajax response without setting up response parameters.
185
- queueParams = [response];
186
- }
187
- else if (queue.type == 'queue') {
188
  // Customize response data based on derivded class.
189
- queueParams = serverQueue.getResponseParameters(response, queue.data)
190
  }
191
- queue.deferred[method](queue.context, queueParams);
192
  // Always call completed callbacks.
193
- queue.deferred.completeDeferred.resolveWith(queue.context, queueParams);
194
- });
195
  // Clear queue.
196
- this.clear();
197
  }
198
 
199
  /*
@@ -205,8 +205,8 @@ var CJTServerQueue;
205
  *
206
  * @return void
207
  */
208
- this.lock = function() {
209
- this.locked = true;
210
  }
211
 
212
  /*
@@ -215,8 +215,8 @@ var CJTServerQueue;
215
  * @param CJTServerQueue Queue object to merge to this queue.
216
  * @return void
217
  */
218
- this.merge = function(serverQueue) {
219
- this.queue = $.merge(this.queue, serverQueue.queue);
220
  }
221
 
222
  /*
@@ -230,34 +230,34 @@ var CJTServerQueue;
230
  * @param object Data to pass along with the queue data.
231
  * @return CJTServer.getDeferredObject.promise()
232
  */
233
- this.send = function(method, data) {
234
- var ajaxPromise = null;
235
  // Process only of not locked.
236
 
237
- if (!this.locked && this.errors.length <= 0) {
238
- var queue = this; // To be used inside .each().
239
  // Merge data param with derived class data for the final request.
240
  // But first mask usre data param is passed.
241
- data = (data != undefined) ? data : {};
242
- data = $.extend(data, this.getData());
243
  // Send request to CJTServer object.
244
- ajaxPromise = CJTServer.send(this.controller, this.action, data, method)
245
- .success(
246
- function(response) {
247
- queue.dispatch('resolve', response);
248
- }
249
- )
250
- .error(
251
- function(response) {
252
- queue.dispatch('reject', response);
253
- }
254
- );
255
  }
256
  else {
257
  // Use Dummy Deferred object in case the object is locked.
258
- ajaxPromise = this.add(data, undefined, 'endpoint');
259
  }
260
- return ajaxPromise;
261
  }
262
 
263
  /*
@@ -265,10 +265,10 @@ var CJTServerQueue;
265
  *
266
  * @return void
267
  */
268
- this.unlock = function() {
269
- this.locked = false;
270
  }
271
 
272
  } // End class.
273
 
274
- })(jQuery);
14
  /*
15
  * JQuery wrapper for the CJTServerQueue object.
16
  */
17
+ ( function ( $ ) {
18
 
19
  /*
20
  * Abstract base class for Ajax Queue classes.
33
  * @author Ahmed Said
34
  * @version 6
35
  */
36
+ CJTServerQueue = function () {
37
 
38
  /*
39
  * Operation Action.
40
  *
41
  * @var string
42
  */
43
+ this.action = null
44
 
45
  /*
46
  * Controller map name.
47
  *
48
  * @var string
49
  */
50
+ this.controller = null
51
 
52
  /*
53
  * Queue object unique identifier.
55
  * @internal
56
  * @var string
57
  */
58
+ this.key = ''
59
 
60
  /*
61
  * Lock or Unlock queue object allow and disallow sending
63
  *
64
  * @var boolean
65
  */
66
+ this.locked = false
67
 
68
  /*
69
  * Operations queue.
73
  *
74
  * @var object
75
  */
76
+ this.queue = []
77
 
78
+ this.errors = []
79
 
80
  /*
81
  * Derived classed constructor.
87
  * @param string Queue key.
88
  * @return void
89
  */
90
+ this._init = function ( controller, action, key ) {
91
+ this.controller = controller
92
+ this.action = action
93
+ this.key = key
94
  // Reset prototype copy vars.
95
+ this.queue = []
96
+ this.locked = false
97
+ }
98
 
99
  /*
100
  * Add request to the queue.
117
  * @param string Queue type.
118
  * @return CJTServer.getDeferredObject.promise()
119
  */
120
+ this.add = function ( data, context, type ) {
121
  // Check for special characters in block name.
122
+ if ( data.property === 'name' ) {
123
+ if ( !data.value.match( /^[A-Za-z0-9\!\#\@\$\&\*\(\)\[\]\x20\-\_\+\?\:\;\.]{1,50}$/ ) ) {
124
+ alert( 'The block name cannot contain special characters. Please use A-Z, 0-9, -, _ and space characters only.' )
125
 
126
  this.errors = data.value
127
  } else {
129
  }
130
  }
131
 
132
+ if ( this.errors.length <= 0 ) {
133
  var queue = {
134
  deferred: CJTServer.getDeferredObject(),
135
  data: data,
136
  context: context,
137
+ type: ( ( type == undefined ) ? 'queue' : type )
138
+ }
139
+ var promise = queue.deferred.promise()
140
  // Add queue object to the queue.
141
+ this.queue.push( queue )
142
+ return promise
143
  } else {
144
  return CJTServer.getDeferredObject().promise()
145
  }
154
  *
155
  * @return void
156
  */
157
+ this.clear = function () {
158
+ this.queue = []
159
  }
160
 
161
  /*
171
  * @param object Response Object to pass to the callbacks.
172
  * @return void
173
  */
174
+ this.dispatch = function ( state, response ) {
175
+ var method = state + 'With'
176
+ var serverQueue = this // To use inside .each().
177
+ var queueParams = null
178
+ $( this.queue ).each( function ( index, queue ) {
179
+ // If rejected don't call getResponseParameters() to avoid error
180
+ // This is a temporary solution for version 6.0 to be releases!
181
+ // Get queue parameters based on queue type.
182
+ if ( ( state == 'reject' ) || ( queue.type == 'endpoint' ) ) {
183
+ // endpoint type queue is queue to handle the typical/native
184
+ // ajax response without setting up response parameters.
185
+ queueParams = [ response ]
186
+ }
187
+ else if ( queue.type == 'queue' ) {
188
  // Customize response data based on derivded class.
189
+ queueParams = serverQueue.getResponseParameters( response, queue.data )
190
  }
191
+ queue.deferred[ method ]( queue.context, queueParams )
192
  // Always call completed callbacks.
193
+ queue.deferred.completeDeferred.resolveWith( queue.context, queueParams )
194
+ } )
195
  // Clear queue.
196
+ this.clear()
197
  }
198
 
199
  /*
205
  *
206
  * @return void
207
  */
208
+ this.lock = function () {
209
+ this.locked = true
210
  }
211
 
212
  /*
215
  * @param CJTServerQueue Queue object to merge to this queue.
216
  * @return void
217
  */
218
+ this.merge = function ( serverQueue ) {
219
+ this.queue = $.merge( this.queue, serverQueue.queue )
220
  }
221
 
222
  /*
230
  * @param object Data to pass along with the queue data.
231
  * @return CJTServer.getDeferredObject.promise()
232
  */
233
+ this.send = function ( method, data ) {
234
+ var ajaxPromise = null
235
  // Process only of not locked.
236
 
237
+ if ( !this.locked && this.errors.length <= 0 ) {
238
+ var queue = this // To be used inside .each().
239
  // Merge data param with derived class data for the final request.
240
  // But first mask usre data param is passed.
241
+ data = ( data != undefined ) ? data : {}
242
+ data = $.extend( data, this.getData() )
243
  // Send request to CJTServer object.
244
+ ajaxPromise = CJTServer.send( this.controller, this.action, data, method )
245
+ .success(
246
+ function ( response ) {
247
+ queue.dispatch( 'resolve', response )
248
+ }
249
+ )
250
+ .error(
251
+ function ( response ) {
252
+ queue.dispatch( 'reject', response )
253
+ }
254
+ )
255
  }
256
  else {
257
  // Use Dummy Deferred object in case the object is locked.
258
+ ajaxPromise = this.add( data, undefined, 'endpoint' )
259
  }
260
+ return ajaxPromise
261
  }
262
 
263
  /*
265
  *
266
  * @return void
267
  */
268
+ this.unlock = function () {
269
+ this.locked = false
270
  }
271
 
272
  } // End class.
273
 
274
+ } )( jQuery )
models/blocks.php CHANGED
@@ -57,7 +57,7 @@ class CJTBlocksModel {
57
  $codeFile = new CJTBlockFilesTable($this->dbDriver);
58
  // Get new id if not specified.
59
  if (!isset($block['id']) || !$block['id']) {
60
- $block['id'] = $blocks->getNextId();
61
  }
62
  // Backward compatibility for old block style
63
  // that has code field inside blocks table.
@@ -112,7 +112,8 @@ class CJTBlocksModel {
112
  $block->owner = get_current_user_id();
113
  $block->masterFile = $activeFileId; // Only the revisioned code file would be exists and must be
114
  // used as the masterFile!
115
- $block->id = $blocks->getNextId(); // Get new id for revision rrecord.
 
116
  // Add block data.
117
  $blocks->insert($block);
118
  // Get block pins and insert pins for the revision block.
57
  $codeFile = new CJTBlockFilesTable($this->dbDriver);
58
  // Get new id if not specified.
59
  if (!isset($block['id']) || !$block['id']) {
60
+ $block['id'] = $blocks->getNextIdNEW();
61
  }
62
  // Backward compatibility for old block style
63
  // that has code field inside blocks table.
112
  $block->owner = get_current_user_id();
113
  $block->masterFile = $activeFileId; // Only the revisioned code file would be exists and must be
114
  // used as the masterFile!
115
+ //$block->id = $blocks->getNextId(); // Get new id for revision rrecord.
116
+ $block->id = $blocks->getNextIdNEW(); // Get new id for revision rrecord.
117
  // Add block data.
118
  $blocks->insert($block);
119
  // Get block pins and insert pins for the revision block.
models/setup.php CHANGED
@@ -50,7 +50,7 @@ class CJTSetupModel {
50
  // Add action to the state object!
51
  $state['action'] = $action;
52
  // Cache Plugin data!
53
- $state['plugin'] = get_plugin_data(ABSPATH . PLUGINDIR . "/{$component['pluginBase']}", false);
54
  // Cache object!
55
  $cache[$component['name']] = $state;
56
  update_option(self::LICENSES_CACHE, $cache);
50
  // Add action to the state object!
51
  $state['action'] = $action;
52
  // Cache Plugin data!
53
+ $state['plugin'] = get_plugin_data(WP_PLUGIN_DIR . "/{$component['pluginBase']}", false);
54
  // Cache object!
55
  $cache[$component['name']] = $state;
56
  update_option(self::LICENSES_CACHE, $cache);
models/uninstall.php CHANGED
@@ -50,7 +50,7 @@ class CJTUninstallModel {
50
  public function fileSystem() {
51
  global $wp_filesystem;
52
  // Getting directory list!
53
- $wpContentDir = 'wp-content';
54
  $fSConfig = cssJSToolbox::$config->fileSystem;
55
  // Directories to create!
56
  $directories = array(
@@ -59,7 +59,7 @@ class CJTUninstallModel {
59
  );
60
  // Delete all directories!
61
  foreach ($directories as $dir) {
62
- $wp_filesystem->delete(ABSPATH . "/{$dir}", true);
63
  }
64
  // Chaining!
65
  return $this;
50
  public function fileSystem() {
51
  global $wp_filesystem;
52
  // Getting directory list!
53
+ $wpContentDir = WP_CONTENT_DIR;
54
  $fSConfig = cssJSToolbox::$config->fileSystem;
55
  // Directories to create!
56
  $directories = array(
59
  );
60
  // Delete all directories!
61
  foreach ($directories as $dir) {
62
+ $wp_filesystem->delete($dir, true);
63
  }
64
  // Chaining!
65
  return $this;
readme.txt CHANGED
@@ -2,43 +2,45 @@
2
  Contributors: wipeoutmedia
3
  Author URL: https://css-javascript-toolbox.com
4
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=EWDWF75JHT9Q6
5
- Tags: CSS, JavaScript, JS, PHP, HTML, scripts, code, snippets, hooks, header, footer, widget, sidebar, shortcode, Gutenberg, code block, ads, AdSense, Analytics, GA, advertising, Google, chat, YouTube, Vimeo
6
  License: GPLv2 or later
7
  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.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
@@ -65,7 +67,65 @@ https://www.youtube.com/watch?v=vYAKePVgJqE
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
@@ -370,6 +430,8 @@ Fix: Fatal error: 'break' not in the 'loop' or 'switch' context in /path/to/wp-c
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
 
 
2
  Contributors: wipeoutmedia
3
  Author URL: https://css-javascript-toolbox.com
4
  Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=EWDWF75JHT9Q6
5
+ Tags: snippets, css, javascript, php, scripts, code, functions, html
6
  License: GPLv2 or later
7
  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.8.2
11
+ Stable tag: 11.5
12
 
13
+ Add code snippets (CSS, JavaScript, HTML, PHP) to your site and choose where it goes. Feel confident with 10 years of security & reliability.
 
14
 
15
  == Description ==
16
+ Thank you for taking a look at our code snippet plugin. I believe it will do exactly what you are wanting.
 
17
 
18
+ ### IDEAL FOR: ###
19
+ * **Front-end modifications** (without modifying theme files)
20
+ * **Adding functionality** (without modifying functions.php)
21
+ * **Adding widgets, code snippets/scripts** (e.g. Google Analytics)
22
+ * **Fast site development** (without the need for FTP)
23
+
24
+ CJT is built on the concept of a code block. Each code block contains its own editor for writing/adding your snippets; and an assignment panel so you can click the sections of your website you want the code to go.
25
+
26
+ It was designed for super-fast development without any cumbersome page refreshing. That means you can add as many code blocks as you need and see all of your code and assignments in one dashboard. Don't worry, it has been optimised to handle 100's of code blocks and thousands of assignments (i.e. Pages, Posts, Categories, Custom Posts, etc).
27
 
28
  ### FEATURES: ###
29
+ * Easy to use 'code blocks' interface
30
  * Powerful code editor
31
+ * Intuitive assignment panel (click where your code goes)
32
  * Code/script library management
33
+ * Add code to the header or footer hook
34
+ * **PREMIUM** Add code to entire website, all posts, etc
35
+ * **PREMIUM** Add code via shortcodes, widgets, Gutenburg blocks, etc
36
+ * **PREMIUM** Add code via tags, URLs, regular expressions
37
+ * **PREMIUM** 8 additional hooks for more precise assignments
38
+ * **PREMIUM** Invert feature (run code everywhere but ...)
39
+ * **PREMIUM** Editor tools (code auto complete, beautify/minify, etc)
40
+ * **PREMIUM** Code revisions system
41
+ * **PREMIUM** Backup and export/import system
42
+
43
+ [Save 75% for our PREMIUM CSS & JavaScript Toolbox PLUS](https://css-javascript-toolbox.com/?utm_source=cjt_free_on_wordpress&utm_medium=readme_txt_description&utm_campaign=click_for_premium_link)
 
44
 
45
  ### OVERVIEW VIDEO ###
46
  https://www.youtube.com/watch?v=vYAKePVgJqE
67
  13. Assignment Panel Inverter
68
  14. Code Block Information
69
 
70
+ == Frequently Asked Questions ==
71
+ = Why was the CJT plugin developed and what is it used for? =
72
+ The CJT plugin was created to help website authors write or add 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. Some typical examples can include changing the look of a specific page by adding some CSS code; adding functionality to a page with PHP; or making a page more interactive by adding some JavaScript.
73
+
74
+ = What is a CJT 'code block'? =
75
+ The CJT code block is the most fundamental unit for writing code and to associate it with specific Wordpress requests via the assignment panel.
76
+
77
+ = What is the assignment panel? =
78
+ 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. These assignments include: Pages, Posts, Custom Posts, Tags, and Categories. Auxiliary sections such as 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. Advanced sections such as URLs, or Regular Expressions (Regex).
79
+
80
+ = I have noticed a bunch of question marks appear during mouse hover - what are they? =
81
+ These are premium features, which are only available for our CJT PLUS plugin. [Click here to purchase a license for any of our premium CJT PLUS products](https://css-javascript-toolbox.com/pricing).
82
+
83
+ = Can you select more than one item from the assignment panel? =
84
+ Yes. You can select any number of items you need, there is no limitation regarding this.
85
+
86
+ = Can you assign multiple blocks to the same items from the assignment panel? =
87
+ 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.
88
+
89
+ = What is Pages, Posts, Categories and Custom Posts tabs? =
90
+ These lists with checkboxes represent all of your WordPress Pages, Posts, Categories and Custom Posts that your entire website contains. It also supports sub-pages and sub-categories, which you will find in there.
91
+
92
+ = What is the Auxiliary tab? =
93
+ 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 to be used, you will find them pre-defined in the Auxiliary tab. In the Auxiliary tab you can find things like: Entire Website, Blog Index, Author, 404 error, Front-end, Admin backend and much more!
94
+
95
+ = Is it better to use the URLs tab, or select items if found through other tabs? =
96
+ 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.
97
+
98
+ = What is the Advanced Expressions tab? =
99
+ 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.
100
+
101
+ = Can I move the blocks around? =
102
+ 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.
103
+
104
+ = Is a code block saved after I click 'Create' in 'Create New Code Block' form? =
105
+ Yes. The block is created and saved in your database. In order to discard the block, you have to delete it, then click the 'Save All Changes' button.
106
+
107
+ = After shuffling the order of the code blocks using drag-and-drop, is the new code block order immediately saved? =
108
+ No. In order to save the code blocks order, you need to click the 'Save All Changes' button.
109
+
110
+ = Is a code block permanently deleted from the blocks list page after a code block delete icon is clicked? =
111
+ No. After you delete a code block, you then need to click the 'Save All Changes' button.
112
+
113
+ = I'm using the URLs tab and my code is not working? =
114
+ Make sure you have copied and pasted the Page, Post, or Category URL exactly as it appears in the browser address bar. For example, you may have inadvertently included an extra forward slash at the end of your URL.
115
+
116
+ = Why use the Hook switch in the code block bar? =
117
+ The hook location feature gives you further control over the outputting of your CSS and JavaScript code. This is useful in case overriding another plugins' CSS code is required. Also, it's sometimes better to put your JavaScript code in the footer to avoid slowing down your page load.
118
+
119
+ = I received a weird error, what do I do now? =
120
+ 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 then [purchase a license for any of our premium CJT PLUS products](https://css-javascript-toolbox.com/pricing).
121
+
122
  == Changelog ==
123
+ = 11.5 =
124
+ * Compatibility: PHP version 8+
125
+ * Compatibility: MySQL version 8+
126
+ * Fix: Duplicate ID issue, which on rare occasions was fetching the 'revision block' ID for a newly created block causing an error for duplicate entry
127
+ * Enhancement: If the 'wp-content' directory is renamed to something different (e.g. 'content'), CJT will now find any custom content directories and install correctly
128
+
129
  = 11.4 =
130
  * Removed: Auxiliary and Advanced tabs are removed for CJT new installs. Existing CJT users with active code blocks still get them
131
  * Enhancement: All mouse hover-over popups are faster and more responsive
430
  * Launch: This is the very first release of CSS & JavaScript Toolbox
431
 
432
  == Upgrade Notice ==
433
+ = 11.5 =
434
+ * Compatibility: PHP version 8+
435
+ * Compatibility: MySQL version 8+
436
+ * Fix: Duplicate ID issue, which on rare occasions was fetching the 'revision block' ID for a newly created block causing an error for duplicate entry
437
+ * Enhancement: If the 'wp-content' directory is renamed to something different (e.g. 'content'), CJT will now find any custom content directories and install correctly
tables/blocks.php CHANGED
@@ -12,29 +12,29 @@ defined('ABSPATH') or die("Access denied");
12
  require_once CJTOOLBOX_FRAMEWORK . '/db/mysql/table.inc.php';
13
 
14
  /**
15
- *
16
  * @deprecated Use CJTBlockTable instead!
17
  */
18
  class CJTBlocksTable extends CJTTable {
19
-
20
  /** */
21
  const BLOCK_META_BOX_ID_META_NAME = '__CJT-BLOCK-ID';
22
-
23
  /** */
24
  const BLOCK_META_BOX_STATUS_META_NAME = '__CJT-BLOCK-STATUS';
25
-
26
  /**
27
  * put your comment there...
28
- *
29
  */
30
  public function __construct(&$dbDriver) {
31
  // Inirialize parent class.
32
  parent::__construct($dbDriver, cssJSToolbox::$config->database->tables->blocks);
33
  }
34
-
35
  /**
36
  * put your comment there...
37
- *
38
  * @param mixed $ids
39
  */
40
  public function delete($ids = array()) {
@@ -45,10 +45,10 @@ class CJTBlocksTable extends CJTTable {
45
  $query = "DELETE FROM {$this->table}{$where};";
46
  $this->dbDriver->delete($query);
47
  }
48
-
49
  /**
50
  * put your comment there...
51
- *
52
  * @param mixed $ids
53
  * @param mixed $fields
54
  * @param mixed $filters
@@ -104,7 +104,20 @@ class CJTBlocksTable extends CJTTable {
104
  }
105
  return $blocks;
106
  }
107
-
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  /**
109
  * Override Parent::getNextId().
110
  */
@@ -117,7 +130,7 @@ class CJTBlocksTable extends CJTTable {
117
  FROM {$postMetaTable}
118
  WHERE meta_key = '{$postMetaName}';";
119
  // Get all ids.
120
- $reservedIds = array_keys($this->dbDriver->select($query, OBJECT_K));
121
  // Find a unique Id for the new block.
122
  do {
123
  // Increase by one until finding new unique id.
@@ -126,10 +139,10 @@ class CJTBlocksTable extends CJTTable {
126
  // Return new id.
127
  return $nextId;
128
  }
129
-
130
  /**
131
  * put your comment there...
132
- *
133
  */
134
  public function insert($data) {
135
  // Prepare New Record data.
@@ -139,10 +152,10 @@ class CJTBlocksTable extends CJTTable {
139
  $query = "INSERT INTO {$this->table} SET {$data};";
140
  $this->dbDriver->insert($query);
141
  }
142
-
143
  /**
144
  * put your comment there...
145
- *
146
  * @param mixed $data
147
  */
148
  public function update($block) {
@@ -160,5 +173,5 @@ class CJTBlocksTable extends CJTTable {
160
  }
161
  return $this;
162
  }
163
-
164
  } // End class.
12
  require_once CJTOOLBOX_FRAMEWORK . '/db/mysql/table.inc.php';
13
 
14
  /**
15
+ *
16
  * @deprecated Use CJTBlockTable instead!
17
  */
18
  class CJTBlocksTable extends CJTTable {
19
+
20
  /** */
21
  const BLOCK_META_BOX_ID_META_NAME = '__CJT-BLOCK-ID';
22
+
23
  /** */
24
  const BLOCK_META_BOX_STATUS_META_NAME = '__CJT-BLOCK-STATUS';
25
+
26
  /**
27
  * put your comment there...
28
+ *
29
  */
30
  public function __construct(&$dbDriver) {
31
  // Inirialize parent class.
32
  parent::__construct($dbDriver, cssJSToolbox::$config->database->tables->blocks);
33
  }
34
+
35
  /**
36
  * put your comment there...
37
+ *
38
  * @param mixed $ids
39
  */
40
  public function delete($ids = array()) {
45
  $query = "DELETE FROM {$this->table}{$where};";
46
  $this->dbDriver->delete($query);
47
  }
48
+
49
  /**
50
  * put your comment there...
51
+ *
52
  * @param mixed $ids
53
  * @param mixed $fields
54
  * @param mixed $filters
104
  }
105
  return $blocks;
106
  }
107
+
108
+ public function getNextIdNEW($offset = 0)
109
+ {
110
+ // Get post meta table name.
111
+ $blocksTable = $this->dbDriver->getTableName('cjtoolbox_blocks');
112
+
113
+ // Get all reserved blocks/metaboxes id associated with posts.
114
+ $postMetaName = self::BLOCK_META_BOX_ID_META_NAME;
115
+ $query = "SELECT id FROM {$blocksTable} ORDER BY id DESC LIMIT 1;";
116
+ // Get all ids.
117
+ $currentID = current( array_keys( $this->dbDriver->select($query) ) );
118
+
119
+ return $currentID + 1;
120
+ }
121
  /**
122
  * Override Parent::getNextId().
123
  */
130
  FROM {$postMetaTable}
131
  WHERE meta_key = '{$postMetaName}';";
132
  // Get all ids.
133
+ $reservedIds = array_keys($this->dbDriver->select($query, OBJECT_K));
134
  // Find a unique Id for the new block.
135
  do {
136
  // Increase by one until finding new unique id.
139
  // Return new id.
140
  return $nextId;
141
  }
142
+
143
  /**
144
  * put your comment there...
145
+ *
146
  */
147
  public function insert($data) {
148
  // Prepare New Record data.
152
  $query = "INSERT INTO {$this->table} SET {$data};";
153
  $this->dbDriver->insert($query);
154
  }
155
+
156
  /**
157
  * put your comment there...
158
+ *
159
  * @param mixed $data
160
  */
161
  public function update($block) {
173
  }
174
  return $this;
175
  }
176
+
177
  } // End class.
views/blocks/block/public/js/block/block.js CHANGED
@@ -12,7 +12,7 @@ var CJTBlockBase;
12
  /**
13
  * JQuery wrapper for the CJTBlock class.
14
  */
15
- (function($) {
16
 
17
  /**
18
  * Flags values.
@@ -20,9 +20,9 @@ var CJTBlockBase;
20
  * @var object
21
  */
22
  var flags = {
23
- location : ['header', 'footer'],
24
- state : ['active', 'inactive']
25
- };
26
 
27
  /**
28
  * Provide simple access to single block properties.
@@ -31,33 +31,33 @@ var CJTBlockBase;
31
  * @version 6
32
  * @param DOMElement Block element.
33
  */
34
- CJTBlockBase = function() {
35
 
36
  /**
37
  *
38
  *
39
  *
40
  */
41
- this.aceEditor = null;
42
 
43
  /**
44
  *
45
  */
46
- this.blockPlugin = null;
47
 
48
  /**
49
  * Block JQuery object.
50
  *
51
  * @var JQuery object.
52
  */
53
- this.box = null;
54
 
55
  /**
56
  * Block id.
57
  *
58
  * @var integer
59
  */
60
- this.id = 0;
61
 
62
  /**
63
  * Blocks property that allowed to be read or write.
@@ -70,53 +70,53 @@ var CJTBlockBase;
70
  *
71
  * @var object
72
  */
73
- this.properties = {};
74
 
75
  /**
76
  *
77
  */
78
- this.addProperties = function(properties) {
79
  // Prepare properties, add them to model list.
80
- $.each(properties, $.proxy(
81
- function(name, propertyDefinition) {
82
  // Add flag checker method to property object.
83
- propertyDefinition.flag = function(flag) {
84
- var flagIndex = this.flags.indexOf(flag);
85
- return (flagIndex == -1) ? false : true;
86
- };
87
  // Add name to the property object.
88
- propertyDefinition.name = name;
89
  // Place block id in the selector.
90
- if (propertyDefinition.selector != undefined) {
91
- propertyDefinition.selector = propertyDefinition.selector.replace('{blockId}', this.id);
92
  }
93
  // If OM is supported bind it.
94
- if (propertyDefinition.om !== undefined) {
95
- propertyDefinition.om.bind(this.blockPlugin, propertyDefinition);
96
  }
97
  // Cache property object.
98
- this.properties[name] = propertyDefinition;
99
- }, this)
100
- );
101
- };
102
 
103
  /**
104
  * put your comment there...
105
  *
106
  * @param element
107
  */
108
- this.CJTBlockBase = function(blockPlugin, element, properties) {
109
  // Initialize.
110
- this.blockPlugin = blockPlugin;
111
- this.box = $(element);
112
- this.id = parseInt(this.box.find('input:hidden[name="blocks[]"]').val());
113
- this.properties = {};
114
  // Define base properties.
115
- properties.name = {om : new CJTBlockPropertyHTMLNodeOM(), flags: 'rws', selector : 'input:text[name="cjtoolbox[{blockId}][name]"]'};
116
- properties.location = {om : new CJTBlockPropertyHTMLNodeOM(), flags: 'rw', selector : 'input:hidden[name="cjtoolbox[{blockId}][location]"]'};
117
- properties.state = {om : new CJTBlockPropertyHTMLNodeOM(), flags: 'rw', selector : 'input:hidden[name="cjtoolbox[{blockId}][state]"]'};
118
  // Initialize ALL (BASE, DERIVDED) properties.
119
- this.addProperties(properties);
120
  }
121
 
122
  /**
@@ -125,71 +125,71 @@ var CJTBlockBase;
125
  * @param string Property name.
126
  * @return mixed
127
  */
128
- this.get = function(name, _default) {
129
  // Initialize.
130
- var value = null;
131
- var property = this.property(name);
132
  // Check member variables first.
133
- if (this[name] != undefined) {
134
- value = this[name];
135
  }
136
  // There are two types of properties, cookie and element.
137
- else if (property.flag('c')) {
138
  // Get cookie value.
139
- var cookieName = name + '-' + this.id;
140
- value = $.cookies.get(cookieName);
141
  }
142
  else { // Not cookies, it may be saved through JS object or inside HTML elements.
143
  // Custom implemetation.
144
- switch (name) {
145
  case 'code': // Code is through ACE-Editor Object.
146
- value = this.aceEditor.getSession().getValue();
147
- break;
148
  default: // Get property value from html elements.
149
- value = property.om.get();
150
- break;
151
  }
152
  }
153
  // If empty and _default is provided, return _default.
154
- if (!value && (_default != undefined)) {
155
- value = _default;
156
  }
157
  // Returns
158
- return value;
159
  }
160
 
161
  /**
162
  *
163
  */
164
- this.getDIFields = function() {
165
  // Initialize.
166
- var diFields = null;
167
  // Query DIFields selectors nodes.
168
- diFields = this.box.find(this.getDIProperties().selector.join(','));
169
  // Returns diFields
170
- return diFields;
171
  }
172
 
173
  /**
174
  *
175
  */
176
- this.getDIProperties = function() {
177
  // Initialize.
178
- var diProperties = {selector : [], list : {}};
179
  // Collect DIFields from the properties list.
180
- $.each(this.properties, $.proxy(
181
- function(name, property) {
182
  // All fields with 's' flag is a DIField.
183
- if (property.flag('s')) {
184
  // Add property to the list.
185
- diProperties.list[name] = property;
186
  // Add the selector as well.
187
- diProperties.selector.push(property.selector);
188
  }
189
- }, this)
190
- );
191
  // Return DIProperties.
192
- return diProperties;
193
  }
194
 
195
  /**
@@ -202,42 +202,42 @@ var CJTBlockBase;
202
  * @param string Operation name.
203
  * @return CJTBlocksServerQueue Operation queue object.
204
  */
205
- this.getOperationQueue = function(operation) {
206
- var name = (operation + '-operation-' + this.get('id').toString());
207
- var queue = CJTBlocksPage.server.getQueue('Blocks', name, 'blocksPage', 'save_blocks');
208
- return queue;
209
  }
210
 
211
  /**
212
  *
213
  */
214
- this.loadBase = function(properties) {
215
  // Enable ACE Editor.
216
- this.aceEditor = ace.edit('editor-' + this.id);
217
  // Add ACE Editor Propety definition.
218
- properties.code = {om : new CJTBlockPropertyACEEditor(), flags: 'rws', selector : 'div#editor-{blockId}'};
219
- properties.editorLang = {flags: 'rwc'};
220
- properties.editorTheme = {flags: 'rwc'};
221
- properties.aceEditorMenuSettings = {flags: 'rwc'};
222
  // Initialize ALL (BASE, DERIVDED) properties.
223
- this.addProperties(properties);
224
  // Create bridge through "code" field
225
  // so that div element can set/get aceEditor real object.
226
- var codeDiv = $(this.property('code').selector).get(0);
227
- codeDiv.getValue = function() {
228
- return this.aceEditor.getSession().getValue();
229
- };
230
  // Define aceEditor extension method for setting Editor Text with the possibility
231
  // of UNDO.
232
- this.aceEditor.setValuePossibleUndo = function(value) {
233
  // Directly clear using setValue('') prevent 'undo' action!
234
  // Select all text.
235
- this.selectAll();
236
  // Replace content with empty string!
237
- this.getSession().replace(this.getSelectionRange(), value);
238
- this.focus();
239
- };
240
- };
241
 
242
  /**
243
  * @internal
@@ -247,12 +247,12 @@ var CJTBlockBase;
247
  * @param string Property name.
248
  * @return object Property selector object.
249
  */
250
- this.property = function(name) {
251
- // Get property object from the cache.
252
- var property = this.properties[name];
253
- // Returns property cached object used to
254
- // get and set property values.
255
- return property;
256
  }
257
 
258
  /**
@@ -263,42 +263,42 @@ var CJTBlockBase;
263
  * @param {string} Property value.
264
  * @return CJTServer.getDeferredObject().promise()
265
  */
266
- this.set = function(name, newValue) {
267
  // In case (value != newValue) is FALSE
268
  // return Dummy Promise object.
269
- var promise = CJTServer.getDeferredObject().promise();
270
- var property = this.property(name);
271
  // There are two types of properties, cookie and element.
272
- if (property.flag('c')) {
273
- var expires = new Date((new Date()).getTime() + ((30 * 24 * 60 * 60) * 1000)); // Live for 1 month.
274
  // Set cookie value.
275
- var cookieName = name + '-' + this.id;
276
- $.cookies.set(cookieName, newValue, {expiresAt : expires});
277
  }
278
  else {
279
  // Get element value.
280
- var element = this.box.find(property.selector);
281
- var value = element.val();
282
  // Update only if not same.
283
- if ((newValue != undefined) && (value != newValue)) {
284
  // Update on the server.
285
  var data = {
286
- id : this.get('id'),
287
- property : name,
288
- value : newValue
289
- };
290
  // Save property at the server.
291
- queue = this.getOperationQueue(name);
292
- promise = queue.add(data)
293
- .success(
294
- function(rProperty) {
295
- // Change local value to new value.
296
- element.val(rProperty.value);
297
- }
298
- );
299
  }
300
  }
301
- return promise;
302
  }
303
 
304
  /**
@@ -311,9 +311,13 @@ var CJTBlockBase;
311
  *
312
  * @return jqxhr
313
  */
314
- this.sync = function(name, data) {
315
- var ajaxPromise = this.getOperationQueue(name).send('post', data);
316
- return ajaxPromise;
 
 
 
 
317
  }
318
 
319
  /**
@@ -328,21 +332,21 @@ var CJTBlockBase;
328
  * @param [mixed] Force flag value to newValue.
329
  * @return CJTServer.getDeferredObject().promise()
330
  */
331
- this.switchFlag = function(flag, newValue) {
332
- var promise;
333
  // Automatically switch the value if not specified.
334
- if (newValue == undefined) {
335
- var value = this.get(flag);
336
- var possibleValues = flags[flag];
337
- var currentIndex = possibleValues.indexOf(value);
338
  //// Truth Table ////
339
  // currentIndex(0) XOR 1 = 1
340
  // currentIndex(1) XOR 1 = 0
341
- var newIndex = currentIndex ^ 1;
342
- var newValue = possibleValues[newIndex];
343
  }
344
- promise = this.set(flag, newValue);
345
- return promise;
346
  }
347
 
348
  /**
@@ -350,25 +354,25 @@ var CJTBlockBase;
350
  *
351
  * @return void
352
  */
353
- this.queueDIFields = function() {
354
  // Initialize.
355
- var dIFields = this.getDIProperties().list;
356
- var queue = this.getOperationQueue('saveDIFields');
357
- var blockId = this.get('id');
358
  // For every field create queue request as a single property for the block.
359
- $.each(dIFields, $.proxy(
360
- function(name) {
361
  var field = {
362
- id : blockId,
363
- property : name,
364
- value : this.get(name)
365
- };
366
  // Add to queue list.
367
- queue.add(field);
368
- }, this)
369
- );
370
  }
371
 
372
  } // End class.
373
 
374
- })(jQuery);
12
  /**
13
  * JQuery wrapper for the CJTBlock class.
14
  */
15
+ ( function ( $ ) {
16
 
17
  /**
18
  * Flags values.
20
  * @var object
21
  */
22
  var flags = {
23
+ location: [ 'header', 'footer' ],
24
+ state: [ 'active', 'inactive' ]
25
+ }
26
 
27
  /**
28
  * Provide simple access to single block properties.
31
  * @version 6
32
  * @param DOMElement Block element.
33
  */
34
+ CJTBlockBase = function () {
35
 
36
  /**
37
  *
38
  *
39
  *
40
  */
41
+ this.aceEditor = null
42
 
43
  /**
44
  *
45
  */
46
+ this.blockPlugin = null
47
 
48
  /**
49
  * Block JQuery object.
50
  *
51
  * @var JQuery object.
52
  */
53
+ this.box = null
54
 
55
  /**
56
  * Block id.
57
  *
58
  * @var integer
59
  */
60
+ this.id = 0
61
 
62
  /**
63
  * Blocks property that allowed to be read or write.
70
  *
71
  * @var object
72
  */
73
+ this.properties = {}
74
 
75
  /**
76
  *
77
  */
78
+ this.addProperties = function ( properties ) {
79
  // Prepare properties, add them to model list.
80
+ $.each( properties, $.proxy(
81
+ function ( name, propertyDefinition ) {
82
  // Add flag checker method to property object.
83
+ propertyDefinition.flag = function ( flag ) {
84
+ var flagIndex = this.flags.indexOf( flag )
85
+ return ( flagIndex == -1 ) ? false : true
86
+ }
87
  // Add name to the property object.
88
+ propertyDefinition.name = name
89
  // Place block id in the selector.
90
+ if ( propertyDefinition.selector != undefined ) {
91
+ propertyDefinition.selector = propertyDefinition.selector.replace( '{blockId}', this.id )
92
  }
93
  // If OM is supported bind it.
94
+ if ( propertyDefinition.om !== undefined ) {
95
+ propertyDefinition.om.bind( this.blockPlugin, propertyDefinition )
96
  }
97
  // Cache property object.
98
+ this.properties[ name ] = propertyDefinition
99
+ }, this )
100
+ )
101
+ }
102
 
103
  /**
104
  * put your comment there...
105
  *
106
  * @param element
107
  */
108
+ this.CJTBlockBase = function ( blockPlugin, element, properties ) {
109
  // Initialize.
110
+ this.blockPlugin = blockPlugin
111
+ this.box = $( element )
112
+ this.id = parseInt( this.box.find( 'input:hidden[name="blocks[]"]' ).val() )
113
+ this.properties = {}
114
  // Define base properties.
115
+ properties.name = { om: new CJTBlockPropertyHTMLNodeOM(), flags: 'rws', selector: 'input:text[name="cjtoolbox[{blockId}][name]"]' }
116
+ properties.location = { om: new CJTBlockPropertyHTMLNodeOM(), flags: 'rw', selector: 'input:hidden[name="cjtoolbox[{blockId}][location]"]' }
117
+ properties.state = { om: new CJTBlockPropertyHTMLNodeOM(), flags: 'rw', selector: 'input:hidden[name="cjtoolbox[{blockId}][state]"]' }
118
  // Initialize ALL (BASE, DERIVDED) properties.
119
+ this.addProperties( properties )
120
  }
121
 
122
  /**
125
  * @param string Property name.
126
  * @return mixed
127
  */
128
+ this.get = function ( name, _default ) {
129
  // Initialize.
130
+ var value = null
131
+ var property = this.property( name )
132
  // Check member variables first.
133
+ if ( this[ name ] != undefined ) {
134
+ value = this[ name ]
135
  }
136
  // There are two types of properties, cookie and element.
137
+ else if ( property.flag( 'c' ) ) {
138
  // Get cookie value.
139
+ var cookieName = name + '-' + this.id
140
+ value = $.cookies.get( cookieName )
141
  }
142
  else { // Not cookies, it may be saved through JS object or inside HTML elements.
143
  // Custom implemetation.
144
+ switch ( name ) {
145
  case 'code': // Code is through ACE-Editor Object.
146
+ value = this.aceEditor.getSession().getValue()
147
+ break
148
  default: // Get property value from html elements.
149
+ value = property.om.get()
150
+ break
151
  }
152
  }
153
  // If empty and _default is provided, return _default.
154
+ if ( !value && ( _default != undefined ) ) {
155
+ value = _default
156
  }
157
  // Returns
158
+ return value
159
  }
160
 
161
  /**
162
  *
163
  */
164
+ this.getDIFields = function () {
165
  // Initialize.
166
+ var diFields = null
167
  // Query DIFields selectors nodes.
168
+ diFields = this.box.find( this.getDIProperties().selector.join( ',' ) )
169
  // Returns diFields
170
+ return diFields
171
  }
172
 
173
  /**
174
  *
175
  */
176
+ this.getDIProperties = function () {
177
  // Initialize.
178
+ var diProperties = { selector: [], list: {} }
179
  // Collect DIFields from the properties list.
180
+ $.each( this.properties, $.proxy(
181
+ function ( name, property ) {
182
  // All fields with 's' flag is a DIField.
183
+ if ( property.flag( 's' ) ) {
184
  // Add property to the list.
185
+ diProperties.list[ name ] = property
186
  // Add the selector as well.
187
+ diProperties.selector.push( property.selector )
188
  }
189
+ }, this )
190
+ )
191
  // Return DIProperties.
192
+ return diProperties
193
  }
194
 
195
  /**
202
  * @param string Operation name.
203
  * @return CJTBlocksServerQueue Operation queue object.
204
  */
205
+ this.getOperationQueue = function ( operation ) {
206
+ var name = ( operation + '-operation-' + this.get( 'id' ).toString() )
207
+ var queue = CJTBlocksPage.server.getQueue( 'Blocks', name, 'blocksPage', 'save_blocks' )
208
+ return queue
209
  }
210
 
211
  /**
212
  *
213
  */
214
+ this.loadBase = function ( properties ) {
215
  // Enable ACE Editor.
216
+ this.aceEditor = ace.edit( 'editor-' + this.id )
217
  // Add ACE Editor Propety definition.
218
+ properties.code = { om: new CJTBlockPropertyACEEditor(), flags: 'rws', selector: 'div#editor-{blockId}' }
219
+ properties.editorLang = { flags: 'rwc' }
220
+ properties.editorTheme = { flags: 'rwc' }
221
+ properties.aceEditorMenuSettings = { flags: 'rwc' }
222
  // Initialize ALL (BASE, DERIVDED) properties.
223
+ this.addProperties( properties )
224
  // Create bridge through "code" field
225
  // so that div element can set/get aceEditor real object.
226
+ var codeDiv = $( this.property( 'code' ).selector ).get( 0 )
227
+ codeDiv.getValue = function () {
228
+ return this.aceEditor.getSession().getValue()
229
+ }
230
  // Define aceEditor extension method for setting Editor Text with the possibility
231
  // of UNDO.
232
+ this.aceEditor.setValuePossibleUndo = function ( value ) {
233
  // Directly clear using setValue('') prevent 'undo' action!
234
  // Select all text.
235
+ this.selectAll()
236
  // Replace content with empty string!
237
+ this.getSession().replace( this.getSelectionRange(), value )
238
+ this.focus()
239
+ }
240
+ }
241
 
242
  /**
243
  * @internal
247
  * @param string Property name.
248
  * @return object Property selector object.
249
  */
250
+ this.property = function ( name ) {
251
+ // Get property object from the cache.
252
+ var property = this.properties[ name ]
253
+ // Returns property cached object used to
254
+ // get and set property values.
255
+ return property
256
  }
257
 
258
  /**
263
  * @param {string} Property value.
264
  * @return CJTServer.getDeferredObject().promise()
265
  */
266
+ this.set = function ( name, newValue ) {
267
  // In case (value != newValue) is FALSE
268
  // return Dummy Promise object.
269
+ var promise = CJTServer.getDeferredObject().promise()
270
+ var property = this.property( name )
271
  // There are two types of properties, cookie and element.
272
+ if ( property.flag( 'c' ) ) {
273
+ var expires = new Date( ( new Date() ).getTime() + ( ( 30 * 24 * 60 * 60 ) * 1000 ) ) // Live for 1 month.
274
  // Set cookie value.
275
+ var cookieName = name + '-' + this.id
276
+ $.cookies.set( cookieName, newValue, { expiresAt: expires } )
277
  }
278
  else {
279
  // Get element value.
280
+ var element = this.box.find( property.selector )
281
+ var value = element.val()
282
  // Update only if not same.
283
+ if ( ( newValue != undefined ) && ( value != newValue ) ) {
284
  // Update on the server.
285
  var data = {
286
+ id: this.get( 'id' ),
287
+ property: name,
288
+ value: newValue
289
+ }
290
  // Save property at the server.
291
+ queue = this.getOperationQueue( name )
292
+ promise = queue.add( data )
293
+ .success(
294
+ function ( rProperty ) {
295
+ // Change local value to new value.
296
+ element.val( rProperty.value )
297
+ }
298
+ )
299
  }
300
  }
301
+ return promise
302
  }
303
 
304
  /**
311
  *
312
  * @return jqxhr
313
  */
314
+ this.sync = function ( name, data ) {
315
+ if ( !data ) {
316
+ data = {}
317
+ }
318
+
319
+ var ajaxPromise = this.getOperationQueue( name ).send( 'post', data )
320
+ return ajaxPromise
321
  }
322
 
323
  /**
332
  * @param [mixed] Force flag value to newValue.
333
  * @return CJTServer.getDeferredObject().promise()
334
  */
335
+ this.switchFlag = function ( flag, newValue ) {
336
+ var promise
337
  // Automatically switch the value if not specified.
338
+ if ( newValue == undefined ) {
339
+ var value = this.get( flag )
340
+ var possibleValues = flags[ flag ]
341
+ var currentIndex = possibleValues.indexOf( value )
342
  //// Truth Table ////
343
  // currentIndex(0) XOR 1 = 1
344
  // currentIndex(1) XOR 1 = 0
345
+ var newIndex = currentIndex ^ 1
346
+ var newValue = possibleValues[ newIndex ]
347
  }
348
+ promise = this.set( flag, newValue )
349
+ return promise
350
  }
351
 
352
  /**
354
  *
355
  * @return void
356
  */
357
+ this.queueDIFields = function () {
358
  // Initialize.
359
+ var dIFields = this.getDIProperties().list
360
+ var queue = this.getOperationQueue( 'saveDIFields' )
361
+ var blockId = this.get( 'id' )
362
  // For every field create queue request as a single property for the block.
363
+ $.each( dIFields, $.proxy(
364
+ function ( name ) {
365
  var field = {
366
+ id: blockId,
367
+ property: name,
368
+ value: this.get( name )
369
+ }
370
  // Add to queue list.
371
+ queue.add( field )
372
+ }, this )
373
+ )
374
  }
375
 
376
  } // End class.
377
 
378
+ } )( jQuery )
views/blocks/block/public/js/jquery.block/jquery.block.js CHANGED
@@ -7,261 +7,261 @@
7
  /**
8
  * JQuery wrapper for the CJTBlockPlugin object.
9
  */
10
- (function($) {
11
 
12
- /**
13
- * put your comment there...
14
- *
15
- */
16
- $.fn.CJTPLSHooksDropdown = function(arg) {
17
 
18
- var result = this;
19
- var args = arguments;
20
 
21
- this.each(
22
 
23
- function() {
24
 
25
- // Initialize the Plugin only once for each element on the chain
26
- if (this.CJTPLSHooksDropdown) {
27
 
28
- result = this.CJTPLSHooksDropdown[arg].call($this, args);
29
 
30
- return;
31
- }
32
 
33
- // Prepare PLugin vars
34
- var $this = $(this);
35
 
36
- options = arg;
37
 
38
- // Initialize NEW Dropdown jQuery Plugin for the HTML element
39
- this.CJTPLSHooksDropdown = new function() {
40
 
41
- // Initialize object vars
42
- var listValueElement;
43
- var listElement;
44
- var listElements;
45
 
46
- /**
47
- * put your comment there...
48
- *
49
- */
50
- var getItemValue = function(link) {
51
 
52
- var hookName = link.prop('href').match(/#(.+)/)[1];
53
 
54
- return hookName
55
- };
56
 
57
- /**
58
- * put your comment there...
59
- *
60
- */
61
- var init = function() {
62
 
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
 
70
- function() {
71
 
72
- listElement.toggle();
73
 
74
- return false;
75
- }
76
- );
77
 
78
- // list elements click event
79
- listElements.find('a').click(
80
 
81
- function(event) {
82
 
83
- var link = $(this);
84
 
85
- // Reflect selected value
86
- var hookName = getItemValue(link);
87
 
88
- listValueElement.text(link.text());
89
 
90
- // Set selected value CSS
91
- listElements.removeClass('selected');
92
- link.parent().addClass('selected');
93
 
94
- // ITem selection event
95
- $this.trigger('change', [$this, hookName, link]);
96
 
97
- return false;
98
- }
99
- );
100
 
101
- // Initially select the selected element
102
- listValueElement.text(listElements.filter('.selected').find('a').text());
103
 
104
- };
105
 
106
- /**
107
- *
108
- */
109
- this.getOptions = function() {
110
 
111
- return options;
112
- };
113
 
114
- /**
115
- *
116
- */
117
- this.setValue = function(args) {
118
 
119
- listElements.find('a').each(
120
 
121
- function() {
122
 
123
- var link = $(this);
124
- var hookName = getItemValue(link);
125
 
126
- if (hookName == args[1]) {
127
 
128
- listValueElement.text(link.text());
129
 
130
- listElements.removeClass('selected');
131
- link.parent().addClass('selected');
132
 
133
- return false;
134
- }
135
 
136
- }
137
 
138
- );
139
 
140
- };
141
 
142
- this.toggle = function() {
143
 
144
- listElement.toggle();
145
 
146
- };
147
 
148
- // Initialize on construction
149
- init();
150
 
151
- };
152
 
153
- }
154
- );
155
 
156
- // Chaining
157
- return result;
158
- };
159
 
160
  /**
161
  *
162
  */
163
- var notifySaveChangesProto = function(block) {
164
 
165
  /**
166
  * put your comment there...
167
  *
168
  * @param block
169
  */
170
- this.initDIFields = function() {
171
  // Initialize notification saqve change singlton object.
172
- block.changes = [];
173
 
174
  // Initialize vars.
175
- var model = block.block;
176
- var aceEditor = model.aceEditor;
177
- var fields = model.getDIFields();
178
 
179
  /**
180
- * Create common interface for ace editor to
181
- * be accessed like other HTML elements.
182
- *
183
- *
184
  * Bind method for bind events like HTML Elements +
185
- * Method to get hash copy from stored content.
186
  */
187
- aceEditor.type = 'aceEditor'; // Required for _oncontentchanged to behave correctly.
188
- aceEditor.bind = function(e, h) {
189
 
190
- this.getSession().doc.on(e, h);
191
  }
192
- aceEditor.cjtSyncInputField = function() {
193
 
194
- this.cjtBlockSyncValue = hex_md5(this.getSession().getValue());
195
  }
196
 
197
  // Hack jQuery Object by pushing
198
  // ace Editor into fields list, increase length by 1.
199
- fields[fields.length++] = aceEditor;
200
 
201
  // For all fields call cjtSyncInputField and give a unique id.
202
- $.each(fields, $.proxy(
203
 
204
- function(index, field) {
205
 
206
- this.initElement(field);
207
 
208
- }, this)
209
 
210
- );
211
 
212
- // Notify Changes for Block name when key pressed
213
- model.box.find('input:text.block-name').on('keyup', $.proxy(block._oncontentchanged, block));
214
 
215
  // Chaining.
216
- return this;
217
  },
218
 
219
- /**
220
- * put your comment there...
221
- *
222
- * @param element
223
- */
224
- this.initElement = function(field) {
225
 
226
- // Assign weight number used to identify the field.
227
- field.cjtBlockFieldId = CJTBlocksPage.blocks.getUFI();
228
 
229
- // Create default cjtSyncInputField method if not exists.
230
- if (field.cjtSyncInputField == undefined) {
231
 
232
- if (field.type == 'checkbox') {
233
 
234
- field.cjtSyncInputField = function() {
235
 
236
- this.cjtBlockSyncValue = $(this).prop('checked');
237
 
238
- }
239
 
240
- }
241
- else {
242
 
243
- field.cjtSyncInputField = function() {
244
 
245
- this.cjtBlockSyncValue = this.value;
246
- }
247
 
248
- }
249
 
250
- // Create interface to "bind" too.
251
- field.bind = function(e, h) {
252
 
253
- $(this).bind(e, h);
254
- }
255
 
256
- }
257
 
258
- // Sync field.
259
- field.cjtSyncInputField();
260
 
261
- // Bind to change event.
262
- field.bind('change', $.proxy(block._oncontentchanged, block));
263
- }
264
- };
265
 
266
  /**
267
  * Default block features and options.
@@ -269,10 +269,10 @@
269
  * @var object
270
  */
271
  var defaultOptions = {
272
- showObjectsPanel : true,
273
- calculatePinPoint : 1,
274
- restoreRevision : {fields : ['code']}
275
- };
276
 
277
  /**
278
  * Element to loads for each block.
@@ -283,10 +283,10 @@
283
  * @var object
284
  */
285
  var autoLoadElements = {
286
- editBlockName : 'div.edit-block-name',
287
- blockName : 'span.block-name',
288
- insideMetabox : 'div.inside'
289
- };
290
 
291
  /**
292
  * Block jQuery Plugin.
@@ -296,149 +296,149 @@
296
  * @version 6
297
  * @Author Ahmed Said
298
  */
299
- CJTBlockPluginBase = function() {
300
 
301
  /**
302
  * Block model for accessing block properties.
303
  *
304
  * @var CJTBlock
305
  */
306
- this.block;
307
 
308
  /**
309
  *
310
  *
311
  */
312
- this.changes;
313
 
314
  /**
315
  *
316
  */
317
- this.defaultDocks;
318
 
319
- /**
320
- *
321
- */
322
- this.editBlockActionsToolbox;
323
 
324
  /**
325
  *
326
  */
327
- this.editorToolbox;
328
 
329
  /**
330
  * Commonly accessed elements stored here.
331
  *
332
  * @var object
333
  */
334
- this.elements;
335
 
336
  /**
337
  *
338
  */
339
- this.extraDocks = [];
340
 
341
  /**
342
  * Block features and options.
343
  *
344
  * @var object
345
  */
346
- this.features;
347
 
348
- /**
349
- *
350
- */
351
- this.editorLangsToolbox;
352
 
353
- /**
354
- *
355
- */
356
- this.flaggedActionsToolbox;
357
 
358
- /**
359
- *
360
- */
361
- this.hooksDropdown;
362
 
363
- /**
364
- *
365
- */
366
- this.infoBar;
367
 
368
  /**
369
  *
370
  */
371
- this.internalChanging = false;
372
 
373
  /**
374
  *
375
  *
376
  *
377
  */
378
- this.toolbox = null;
379
 
380
  // Block Plugins
381
- CJTBlockObjectPluginDockModule.plug(this);
382
 
383
- /**
384
- *
385
- */
386
- this._onclosepanelwindow = function(event) {
387
 
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
395
- assignPanel.show();
396
 
397
- // Hide close button
398
- $(event.target).hide();
399
 
400
- return false;
401
- };
402
 
403
  /**
404
  *
405
  *
406
  */
407
- this._oncontentchanged = function(event) {
408
  // Dont process internal changes.
409
- if (this.internalChanging) {
410
- return;
411
  }
412
  // Initialize.
413
- var element;
414
- var id; // Give every field an id for tracing change.
415
- var newValue; // Field new value.
416
- var enable; // Used to enable/disable save button
417
- // based on detected changes.
418
- var isFieldChanged;
419
- var isChanged;
420
- var syncValue; // This is the value stored in server.
421
  // Get value, id and sync value based on the input field type.
422
- if (event.target == undefined) { // Ace editor event system don't
423
- element = this.block.aceEditor;
424
  // pass aceEditor object as context!
425
- newValue = hex_md5(element.getSession().getValue());
426
  }
427
  else { // All HTML native types.
428
- element = event.target;
429
  // Use field "value" property for getting new
430
  // context except checkboxes uses checked property.
431
- newValue = (element.type == 'checkbox') ? newValue = $(element).prop('checked') : element.value;
432
  }
433
- id = element.cjtBlockFieldId;
434
- syncValue = element.cjtBlockSyncValue;
435
  // Detect if value is changes.
436
- isFieldChanged = (newValue != syncValue);
437
- isChanged = CJTBlocksPage.blocks.calculateChanges(this.changes, id, isFieldChanged);
438
  // Enable button is there is a change not saved yet, disable it if not.
439
- this.editBlockActionsToolbox.buttons.save.enable(isChanged);
440
  // Notify blocks page.
441
- CJTBlocksPage.blockContentChanged(this.block.id, isChanged);
442
  }
443
 
444
  /**
@@ -447,20 +447,20 @@
447
  * The method delete the block from the UI but not permenant from the server.
448
  * Save all Changes should be called in order to save deleted blocks.
449
  */
450
- this._ondelete = function() {
451
  // Conformation message.
452
- var confirmMessage = CJTJqueryBlockI18N.confirmDelete;
453
  // Show Block name!
454
- confirmMessage = confirmMessage.replace('%s', this.block.get('name'));
455
  // Confirm deletion!
456
- if (confirm(confirmMessage)) {
457
 
458
- this.block.box.trigger('BeforeDeleteBlock', [this]);
459
 
460
  // Delete block.
461
- CJTBlocksPage.deleteBlocks(this.block.box);
462
 
463
- this.block.box.trigger('BlockDeleted', [this]);
464
  }
465
  }
466
 
@@ -470,28 +470,28 @@
470
  *
471
  *
472
  */
473
- this._ondisplayrevisions = function(event) {
474
 
475
  // Restore revision only when block is opened.
476
- if (this.block.box.hasClass('closed')) {
477
- return false;
478
  }
479
  // Initialize form request.
480
  var revisionsFormParams = {
481
- id : this.block.get('id'),
482
- activeFileId : this.codeFile.file.activeFileId
483
- };
484
- var url = CJTBlocksPage.server.getRequestURL('block', 'get_revisions', revisionsFormParams);
485
 
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);
493
 
494
- return false;
495
  }
496
 
497
  /**
@@ -500,128 +500,128 @@
500
  *
501
  *
502
  */
503
- this._ongetinfo = function(event) {
504
 
505
- var sections = {
506
- 'info' : 'info',
507
- 'assignment-info' : 'assignment'
508
- };
509
 
510
- var windowName = $(event.target).prop('href').match(/#(.+)/)[1];
511
- var sectionName = sections[windowName];
512
 
513
  // Server request.
514
  var requestData = {
515
 
516
  // Server paramerers.
517
- id : this.block.get('id'),
518
- show_section : sectionName
519
- };
520
 
521
- var url = CJTBlocksPage.server.getRequestURL('block', 'get_info_view', requestData);
522
 
523
- this.showPanelGenericWindow(event, url);
524
- };
525
 
526
  /**
527
  *
528
  */
529
- this._onlookuptemplates = function(event) {
530
 
531
  // Initialize.
532
- var panelWnd = this.block.box.find('.cjt-panel-item.cjt-panel-window-templates-lookup');
533
- var frameHeight = parseInt(panelWnd.css('height'));
534
- var blockId = this.block.get('id');
535
- var iframe = panelWnd.find('iframe');
536
- var iframeHeight = frameHeight - 35
537
 
538
- // Stay inactive if the toolbox is didsabled, as the toolbox
539
- // has no class for enable/disable state we might use on of its buttons
540
- if (this.toolbox.buttons['location-switch'].jButton.hasClass('cjttbs-disabled')) {
541
 
542
- return;
543
- }
544
 
545
- this._onPaneledItems(event);
546
 
547
- iframe.css('height', iframeHeight);
548
 
549
- if (!CJTToolBox.forms.templatesLookupForm[blockId]) {
550
- CJTToolBox.forms.templatesLookupForm[blockId] = {};
551
  }
552
- var lookupForm = CJTToolBox.forms.templatesLookupForm[blockId];
553
  // This method will fired only once when the
554
  // Templates popup button is hovered for the first time.
555
- if (!iframe.get(0).__cjt_loaded) {
556
- var request = {blockId : blockId};
557
  // Pass block object to the form when loaded.
558
- lookupForm.inputs = {blockPlugin : this, block : this.block, button : $(event.target), height : iframeHeight};
559
  // Set frame Source to templates lookup view URL.
560
- var templatesLookupViewURL = CJTBlocksPage.server.getRequestURL('templatesLookup', 'display', request);
561
- iframe.prop('src', templatesLookupViewURL);
562
  // Mark loaded.
563
- iframe.get(0).__cjt_loaded = true;
564
  }
565
  else {
566
  // Pass frame height when refreshed.
567
- lookupForm.inputs.height = iframeHeight;
568
- lookupForm.form.refresh();
569
  }
570
  /** @TODO Tell Block toolbox to deatach/unbind popup callback */
571
- return true; // Tell CJTToolBox to Show Popup menu as normal.
572
  }
573
 
574
- /**
575
- *
576
- */
577
- this._onPaneledItems = function(event) {
578
 
579
- var link = $(event.target);
580
- var windowName = link.prop('href').match(/#(.+)/)[1];
581
- var panelWindow = this.block.box.find('.cjt-panel-item.cjt-panel-window-' + windowName);
582
- var panelArea = this.block.box.find('.cjpageblock');
583
 
584
- // Hide all panel windows
585
- panelArea.find('.cjt-panel-item').hide();
586
 
587
- // Display panel
588
- panelWindow.show();
589
 
590
- // Display Close button
591
- panelArea.find('.close-panel-window').show();
592
- };
593
 
594
 
595
  /**
596
  * Don't show popup menus if Block is minimized!
597
  */
598
- this._onpopupmenu = function(targetElement, button) {
599
- var show = true;
600
- if (this.block.box.hasClass('closed')) {
601
- show = false;
602
  }
603
  else {
604
  // Some Popup forms need to be re-sized if fullscree is On!
605
- if (button.params.fitToScreen == true) {
606
- this.dock(targetElement, 25);
607
  }
608
  }
609
- return show;
610
  }
611
 
612
  /**
613
  *
614
  */
615
- this._onpostboxopened = function() {
616
  // If aceEditor is undefined then the
617
  // block is no loaded yet,
618
  // loads it.
619
- if (this.block.aceEditor == undefined) {
620
- this._onload();
621
  }
622
  else {
623
  // Update ACE Editor region.
624
- this.block.aceEditor.resize();
625
  }
626
  }
627
 
@@ -632,103 +632,103 @@
632
  * @see CJTBlock.saveDIFields method for more details about fields.
633
  *
634
  */
635
- this._onsavechanges = function() {
636
 
637
- var saveButton = this.editBlockActionsToolbox.buttons['save'];
638
 
639
  // Dont save unless there is a change!
640
- if (saveButton.jButton.hasClass('cjttbs-disabled')) {
641
  // Return REsolved Dummy Object for standarizing sake!
642
- return CJTBlocksPage.server.getDeferredObject().resolve().promise();
643
  }
644
 
645
  // Queue User Direct Interact fields (code, etc...).
646
- var data = {calculatePinPoint : this.features.calculatePinPoint, createRevision : 1};
647
 
648
  // Push DiFields inside Ajax queue.
649
- this.block.queueDIFields();
650
 
651
  // Add code file flags to the queue.
652
- var queue = this.block.getOperationQueue('saveDIFields');
653
- queue.add({id : this.block.get('id'), property : 'activeFileId', value : this.codeFile.file.activeFileId});
654
 
655
  // But save button into load state (Inactive and Showing loading icon).
656
- if (this.block.get('name').match(/^[A-Za-z0-9\!\#\@\$\&\*\(\)\[\]\x20\-\_\+\?\:\;\.]{1,50}$/)) {
657
- saveButton.loading(true);
658
- this.enable(false);
659
 
660
- this.block.box.trigger('PreSaveBlock', [this]);
661
  }
662
 
663
  // Send request to server.
664
- return this.block.sync('saveDIFields', data)
665
 
666
- .success($.proxy(
667
 
668
- function(response) {
669
 
670
- var responseBlockData = response[this.block.get('id')];
671
 
672
- // Stop loading effect and disable the button.
673
- saveButton.loading(false, false);
674
 
675
- // Sync fields with server value.
676
- // This refrssh required for notifying saving
677
- // change to detect changes.
678
- var diFields = this.block.getDIFields();
679
- // Push aceEditor into diFields list.
680
- diFields[diFields.length++] = this.block.aceEditor;
681
- diFields.each(
682
- function() {
683
- this.cjtSyncInputField();
684
- }
685
- );
686
 
687
- // Reset changes list.
688
- this.changes = [];
689
 
690
- // Tell blocks page that block is saved and has not changed yet.
691
- CJTBlocksPage.blockContentChanged(this.block.id, false);
692
 
693
- // Reflect Info bar updated information
694
- this.infoBar.find('.block-info-name>strong').text(responseBlockData.name.value);
695
- this.infoBar.find('.block-shortcode > input:text').val('[cjtoolbox name="' + responseBlockData.name.value + '"]');
696
 
697
- var blockModifiedDate = new Date(responseBlockData.lastModified.value);
698
 
699
- this.infoBar.find('.block-modified-date>strong').text(
700
- blockModifiedDate.getDate().toString().padStart(2, 0) + '-' +
701
- (blockModifiedDate.getMonth() + 1).toString().padStart(2, 0) + '-' +
702
- blockModifiedDate.getFullYear() + ', ' +
703
- blockModifiedDate.getHours() + ':' +
704
- blockModifiedDate.getMinutes()
705
- );
706
 
707
- // Fire BlockSaved event.
708
- this.onBlockSaved();
709
 
710
- this.block.box.trigger('BlockSaved', [this]);
711
 
712
- }, this)
713
- )
714
- .error($.proxy(
715
 
716
- function() {
717
 
718
- saveButton.loading(false);
719
 
720
- }, this)
721
 
722
- ).complete($.proxy(
723
 
724
- function(response) {
725
 
726
- // Enable block
727
- this.enable(true);
728
 
729
- }, this)
730
 
731
- );
732
 
733
  }
734
 
@@ -738,21 +738,21 @@
738
  *
739
  *
740
  */
741
- this._onswitcheditorlang = function(event, params) {
742
 
743
- var jLanguageSwitcher = this.block.box.find('.cjttbl-switch-editor-language');
744
- var languageSwitcher = jLanguageSwitcher.get(0);
745
 
746
  // Note: Event and params parameter is passed but unused,
747
  // we need only selectedValue.
748
  // Set editor mode.
749
- var editorMode = 'ace/mode/' + params.lang;
750
- this.block.aceEditor.getSession().setMode(editorMode);
751
 
752
  // Save editor language for block.
753
- this.block.set('editorLang', params.lang);
754
 
755
- jLanguageSwitcher.text(CJTJqueryBlockI18N['editorLang_' + params.lang]);
756
  }
757
 
758
  /**
@@ -761,41 +761,39 @@
761
  * @param event Javascript event object.
762
  * @param object Toolbox evenr parameters.
763
  */
764
- this._onswitchflag = function(event, params) {
765
-
766
- var promise;
767
- var target = $(event.target);
768
- var oldValue = this.block.get(params.flag);
769
- var flagButton = this.flaggedActionsToolbox.buttons[params.flag + '-switch'];
770
 
771
  // Put the Flag button into load state (Inactive + loading icon).
772
- flagButton.loading(true);
773
 
774
  // Switch flag state.
775
- this.block.switchFlag(params.flag, params.newValue).success($.proxy(
776
- function(rState) {
777
- var oldCSSClass = params.flag + '-' + oldValue;
778
- var newCSSClass = params.flag + '-' + rState.value;
779
- target.removeClass(oldCSSClass).addClass(newCSSClass)
780
- // Switch title based on current FLAG and the new VALUE.
781
- .attr('title', CJTJqueryBlockI18N[params.flag + '_' + rState.value + 'Title']);
782
- }, this)
783
- );
784
 
785
  // Update on server.
786
- promise = this.block.sync(params.flag)
787
 
788
- .complete($.proxy(
789
 
790
- function() {
 
791
 
792
- flagButton.loading(false);
793
 
794
- }, this)
795
 
796
- );
797
-
798
- return promise;
799
  }
800
 
801
  /**
@@ -804,24 +802,24 @@
804
  *
805
  *
806
  */
807
- this.enable = function(state) {
808
- var elements = this.block.box.find('input:checkbox,input:text, textarea, select');
809
- switch (state) {
810
  case true: // Enable block.
811
- elements.removeAttr('disabled');
812
- break;
813
  case false: // Disable block.
814
- elements.attr('disabled', 'disabled');
815
- break;
816
  }
817
 
818
- this.toolbox.enable(state);
819
- this.flaggedActionsToolbox.enable(state);
820
- this.editBlockActionsToolbox.buttons['delete'].enable(state);
821
 
822
  // Enable or Disable ACEEditor.
823
  // Enable = true then setReadnly = false and vise versa.
824
- this.block.aceEditor.setReadOnly(!state);
825
  }
826
 
827
  /**
@@ -829,8 +827,8 @@
829
  *
830
  * @return false.
831
  */
832
- this.focus = function() {
833
- this.block.aceEditor.focus();
834
  }
835
 
836
  /**
@@ -838,477 +836,475 @@
838
  *
839
  *
840
  */
841
- this.initCJTPluginBase = function(node, args) {
842
 
843
  // Initialize object properties!
844
- var model = this.block = new CJTBlock(this, node);
845
- this.features = $.extend(defaultOptions, args);
846
 
847
  // Initialize Events.
848
- this.onBlockSaved = function() {};
849
 
850
- // DOn't TOGGLE block when block name get/lost focus
851
- model.box.find('input:text.block-name').click(function(event) {event.stopPropagation();});
852
 
853
  // Load commonly used elements.
854
- this.elements = {};
855
- $.each(autoLoadElements, $.proxy(
856
- function(name, selector) {
857
- this.elements[name] = this.block.box.find(selector);
858
- }, this)
859
- );
860
 
861
  // Move edit-block-name edit area and tasks-bar outside Wordpress metabox "inside div".
862
- this.elements.insideMetabox.before(model.box.find('.edit-block-name, .block-toolbox'));
863
 
864
- /* Info bar won't be exists if the block is initially closed
865
- * this is just for the code to avoid writing more IF conditions
866
- * block info item will be queried again on the load method
867
- */
868
- this.infoBar = this.block.box.find('.cjt-info-bar');
869
 
870
- // HInitialize ooks dropdown list
871
- this.hooksDropdown = model.box.find('.hooks-dropdown').CJTPLSHooksDropdown({})
872
 
873
- /* Revert item value is failed to change location value */
874
- /* Reflect Hooks icon and text values when successfully changes hook */
875
- .on('change', $.proxy(
876
 
877
- function(event, dropdown, hookName, jItem) {
878
 
879
- var currentHookName = model.get('location');
880
 
881
- model.set('location', hookName).error($.proxy(
882
 
883
- function() {
884
 
885
- dropdown.CJTPLSHooksDropdown('setValue', currentHookName);
886
 
887
- }), this)
888
 
889
- .done($.proxy(
890
 
891
- function() {
892
 
893
- // Reflect Hook button status when hook changed
894
- this.toolbox.buttons['location-switch'].jButton
895
- .removeClass('location-' + currentHookName)
896
- .addClass('location-' + hookName)
897
 
898
- .prop('title', jItem.prop('title'))
899
- .text(jItem.text())
900
 
901
- .removeClass('bad-location-specified')
902
- .prev().removeClass('bad-location-specified')
903
 
904
- }, this)
905
- );
906
 
907
- model.sync('location');
908
 
909
- }, this)
910
 
911
- ).get(0).CJTPLSHooksDropdown;
912
 
913
  // Activate toolbox.
914
- this.toolbox = model.box.find('.block-toolbox').CJTToolBox({
915
- context : this,
916
- handlers : {
917
-
918
- 'assignment-info' : {callback : this._ongetinfo},
919
- 'block-info' : {callback : this._ongetinfo},
920
-
921
- 'location-switch' : {
922
- type : 'Popup',
923
- params : {
924
- _type : {
925
- targetElement : '.hooks-dropdown',
926
- setTargetPosition : false
927
- }
928
- }
929
- },
930
- 'templates' : {
931
- type : 'Popup',
932
- params : {
933
- _type : {
934
- onPopup : this._onpopupmenu,
935
- targetElement : '.templates',
936
- setTargetPosition : true
937
- }
938
- }
939
- },
940
- 'templates-lookup' : {callback : this._onlookuptemplates},
941
- 'templates-manager' : {callback : CJTBlocksPage._onmanagetemplates},
942
- 'code-files' : {callback : function() {}} /* This is dummy unless updated by code file controller object on the load method */
943
  }
944
- }).get(0).CJTToolBox;
945
 
946
- this.toolbox.buttons['templates'].jButton.click($.proxy(this._onlookuptemplates, this));
947
 
948
- // Editor Language Toolbox
949
- this.editorLangsToolbox = model.box.find('.cjt-toolbox.editor-langs-toolbox').CJTToolBox({
950
 
951
- context : this,
952
- handlers : {
953
 
954
- 'switch-editor-language' : {
955
- type : 'Popup',
956
- params : {
957
- // Parameters for PopupList type button.
958
- _type : {
959
- onPopup : this._onpopupmenu,
960
- targetElement : '.editor-langs',
961
- setTargetPosition : false
962
- }
963
- }
964
- },
965
 
966
- 'editor-language-css' : {callback : this._onswitcheditorlang, params : {lang : 'css'}},
967
- 'editor-language-html' : {callback : this._onswitcheditorlang, params : {lang : 'html'}},
968
- 'editor-language-javascript' : {callback : this._onswitcheditorlang, params : {lang : 'javascript'}},
969
- 'editor-language-php' : {callback : this._onswitcheditorlang, params : {lang : 'php'}}
970
 
971
- }
972
 
973
- }).get(0).CJTToolBox;
974
 
975
- // Disable Toolbox until block is loaded
976
- this.toolbox.enable(false);
977
- this.editorLangsToolbox.enable(false);
978
 
979
- // Move State and Location buttons to be before block name
980
- this.flaggedActionsToolbox = model.box.find('.cjt-toolbox.flagged-actions-toolbox')
981
- .insertBefore(model.box.find('.hndle .block-name'))
982
- .CJTToolBox({
983
 
984
- context : this,
985
- handlers : {
986
- 'state-switch' : {callback : this._onswitchflag, params : {flag : 'state'}},
987
- }
988
 
989
- }).get(0).CJTToolBox;
990
 
991
- // Move State and Location buttons to be before block name
992
- this.editBlockActionsToolbox = model.box.find('.cjt-toolbox.edit-block-toolbox')
993
- .insertAfter(model.box.find('.hndle .block-name'))
994
- .CJTToolBox({
995
 
996
- context : this,
997
- handlers : {
998
 
999
- 'save' : {callback : this._onsavechanges, params : {enable : false}},
1000
- 'delete' : {callback : this._ondelete},
1001
 
1002
- }
1003
 
1004
- }).get(0).CJTToolBox;
1005
 
1006
- // Initialized-event (Regardless if loaded or not)
1007
- this.block.box.trigger('Initialized', [this]);
1008
 
1009
  // If the code editor element is presented then
1010
  // the block is already opened and no need to load later.
1011
- if (model.box.find('.code-editor').length) {
1012
 
1013
- // Load nd Trigger Load events
1014
- this.loadTLE();
1015
 
1016
  }
1017
 
1018
  // Display block.
1019
  // !important: Blocks come from server response doesn't need this but the newly added blocks does.
1020
  // need sometime to be ready for display.
1021
- model.box.css({display : 'block'}).addClass('cjt-block');
1022
  }
1023
 
1024
- /**
1025
- *
1026
- */
1027
- this.initInfoBar = function() {
1028
 
1029
- this.infoBar = this.block.box.find('.cjt-info-bar');
1030
 
1031
- // Copy Shortcode
1032
- this.infoBar.find('.block-shortcode .copyshortcode').click($.proxy(
1033
 
1034
- function() {
1035
 
1036
- var shortcodeEle = this.infoBar.find('.block-shortcode input');
1037
 
1038
- shortcodeEle.focus();
1039
- shortcodeEle.select();
1040
 
1041
- document.execCommand('copy');
1042
 
1043
- return false;
1044
 
1045
- }, this)
1046
- );
1047
 
1048
- // Update Assignment count whenever the block is saved
1049
- this.block.box.on('BlockSaved', $.proxy(
1050
 
1051
- function() {
1052
 
1053
- CJTBlocksPage.server.send('block', 'getAllAssignment', {blockId : this.block.get('id')}).done($.proxy(
1054
 
1055
- function(response) {
1056
 
1057
- this.infoBar.find('.block-assignment-count .show-assignment-info').text(response);
1058
 
1059
- }, this)
1060
 
1061
- );
1062
 
1063
- }, this)
1064
 
1065
- );
1066
 
1067
 
1068
- // Editor Language
1069
- this.infoBar.find('.block-editor-lang strong').text(this.block.get('editorLang'));
1070
 
1071
- // Allow info bar to be extensible
1072
- this.block.box.trigger('InitInfoBar', [this, this.infoBar]);
1073
- };
1074
 
1075
  /**
1076
  *
1077
  */
1078
- this._onload = function() {
1079
  // Initialize.
1080
- var model = this.block;
1081
  // Show loading block progress.
1082
- var loadingPro = $('<div class="loading-block">' + CJTJqueryBlockI18N.loadingBlock + ' . . .</div>').prependTo(this.elements.insideMetabox.prepend());
1083
  // Retrieve Block HTML content.
1084
- CJTBlocksPage.server.send('blocksPage', 'loadBlock', {blockId : model.get('id'), isLoading : true})
1085
- .success($.proxy(
1086
- function(blockContent) {
1087
 
1088
- // Remove loading bloc progress.
1089
- loadingPro.remove();
1090
 
1091
- // Add block content
1092
- this.elements.insideMetabox.append(blockContent.content);
1093
 
1094
- // Load block.
1095
- this.loadTLE();
1096
 
1097
- }, this)
1098
- );
1099
- };
1100
 
1101
  /**
1102
  *
1103
  */
1104
- this.load = function()
1105
- {
1106
 
1107
- var model = this.block;
1108
 
1109
  // Broadcast block event
1110
- this.block.box.trigger( 'cjtBlockLoaded', [ this ] );
1111
 
1112
  // LOAD MODEL.
1113
- model.load();
1114
 
1115
  // Editor default options.
1116
- this.block.aceEditor.setOptions({showPrintMargin : false});
1117
 
1118
- // Initialize info bar
1119
- this.initInfoBar();
1120
 
1121
- // Enable HEader button Toolbox
1122
- this.toolbox.enable(true);
1123
- this.editorLangsToolbox.enable(true);
1124
 
1125
  // Initialize editor toolbox.
1126
- this.editorToolbox = model.box.find('.editor-toolbox').CJTToolBox({
1127
- context : this,
1128
- handlers : {}
1129
- }).get(0).CJTToolBox;
1130
 
1131
 
1132
  // Default to DOCK!!
1133
  this.defaultDocks = [
1134
- {
1135
- element : $(this.block.aceEditor.container),
1136
- pixels : 7
1137
- },
1138
- {
1139
- element : this.block.box.find('.cjpageblock .cjt-panel-genericwnd'),
1140
- pixels : 64
1141
- },
1142
- {
1143
- element : this.block.box.find('.cjt-panel-item.cjt-panel-window-templates-lookup')
1144
 
1145
- .on('CJTDockedItemResized',
1146
 
1147
- function(event, item) {
1148
 
1149
- if (CJTToolBox.forms.templatesLookupForm[model.get('id')] !== undefined) {
1150
 
1151
- item.height = item.height - 35;
1152
 
1153
- item.element.find('iframe').css('height', item.height);
1154
- CJTToolBox.forms.templatesLookupForm[model.get('id')].inputs.height = item.height;
1155
- CJTToolBox.forms.templatesLookupForm[model.get('id')].form.refresh();
1156
 
1157
- }
1158
 
1159
- }
1160
- )
1161
- .on('CJTBlockExitFullScreen',
1162
 
1163
- function(event, item) {
1164
 
1165
- if (CJTToolBox.forms.templatesLookupForm[model.get('id')] !== undefined) {
1166
 
1167
- var originalHeight = item.element.height();
1168
- var iframeHeight = originalHeight - 35;
1169
 
1170
- item.element.css('height', originalHeight);
1171
- item.element.find('iframe').css('height', iframeHeight);
1172
 
1173
- CJTToolBox.forms.templatesLookupForm[model.get('id')].inputs.height = iframeHeight;
1174
- CJTToolBox.forms.templatesLookupForm[model.get('id')].form.refresh();
1175
 
1176
- }
1177
 
1178
- }
1179
- ),
1180
- pixels : 27
1181
- }
1182
- ];
1183
 
1184
  // Show hidden toolbox buttons.
1185
- this.editorLangsToolbox.buttons['switch-editor-language'].jButton.removeClass('waitingToLoad');
1186
- this.block.box.find('.cjt-toolbox.block-toolbox').find('.waitingToLoad').removeClass('waitingToLoad');
1187
- this.editBlockActionsToolbox.buttons['save'].jButton.removeClass('waitingToLoad');
1188
 
1189
  // Register COMMAND-KEYS.
1190
- this.registerCommands();
1191
 
1192
  // Switch Block state if required, if state is empty nothing will happen.
1193
  // Until now only 'restore' state is supported to prevent saving restored block.
1194
- this.switchState(this.features.state);
1195
 
1196
  // Prepare input elements for notifying user changes.
1197
- this.notifySaveChanges = (new notifySaveChangesProto(this)).initDIFields();
1198
 
1199
  // Set theme object.
1200
 
1201
- this.theme = {};
1202
 
1203
- /*
1204
  this.theme.backgroundColor = 'white';
1205
  this.theme.color = 'black';
1206
- this.theme.altTextColor = 'snow';
1207
- */
1208
 
1209
  // LOAD EVENT.
1210
- if (this.onLoad !== undefined) {
1211
 
1212
- this.onLoad();
1213
  }
1214
 
1215
  // Block Code File.
1216
- this.codeFile = new CJTBlockFile(this);
1217
 
1218
- this.block.box.find('.cjpageblock a.close-panel-window').click($.proxy(this._onclosepanelwindow, this));
1219
 
1220
- this.block.box.trigger( 'cjtBlockPostLoading', [ this ] );
1221
  }
1222
 
1223
- /**
1224
- *
1225
- */
1226
- this.loadTLE = function() {
1227
 
1228
- this.block.box.trigger('BlockBeforeLoadProc', [this]);
1229
 
1230
- this.load();
1231
 
1232
- this.block.box.trigger('BlockAfterLoadProc', [this]);
1233
 
1234
- };
1235
 
1236
  /**
1237
  *
1238
  */
1239
- this.registerCommands = function() {
1240
- var editorCommands = this.block.aceEditor.commands;
1241
  var commands = [
1242
  {
1243
  name: 'Save-Changes',
1244
  bindKey: {
1245
- win : 'Ctrl-S',
1246
- mac : 'Command-J'
1247
  },
1248
- exec: $.proxy(this._onsavechanges, this)
1249
  }
1250
- ];
1251
  /** Add Our Ace Save, Full screen and Code-Auto-Completion commands */
1252
- editorCommands.addCommands(commands);
1253
  }
1254
 
1255
  /**
1256
  *
1257
  */
1258
- this.restoreRevision = function(revisionId, data) {
1259
  // Create new revision control action.
1260
- this.revisionControl = new CJTBlockOptionalRevision(this, data, revisionId);
1261
  // Display the revision + enter revision mode.
1262
- this.revisionControl.display();
1263
  }
1264
 
1265
  /**
1266
  *
1267
  */
1268
- this.setFeatures = function( features )
1269
- {
1270
- this.features = features;
1271
- };
1272
 
1273
- /**
1274
- *
1275
- */
1276
- this.showPanelGenericWindow = function(event, url) {
1277
 
1278
- var genericPanelWindow = $('.cjpageblock .cjt-panel-genericwnd');
1279
 
1280
- $.get(url).done($.proxy(
1281
 
1282
- function(content) {
1283
 
1284
- genericPanelWindow
1285
- .empty()
1286
- .append(content);
1287
 
1288
- this._onPaneledItems(event);
1289
 
1290
- }, this)
1291
 
1292
- );
1293
- };
1294
 
1295
  /*
1296
  *
1297
  *
1298
  *
1299
  */
1300
- this.switchState = function(state) {
1301
- switch (state) {
1302
  case 'restore':
1303
  // Hide block toolbox.
1304
- this.toolbox.jToolbox.hide();
1305
  // Disable all fields.
1306
- this.enable(false);
1307
  // Change state
1308
- this.state = 'restore';
1309
  default:
1310
- // Nothing for now
1311
- break;
1312
  }
1313
  }
1314
 
@@ -1317,24 +1313,24 @@
1317
  /**
1318
  * jQuery Plugin interface.
1319
  */
1320
- $.fn.CJTBlock = function(args) {
1321
  /**
1322
  * Process every block object.
1323
  */
1324
- return this.each(function() {
1325
 
1326
  // If this is the first time to be called for this element
1327
  // create new CJTBlockPlugin object for the this element.
1328
- if (this.CJTBlock == undefined) {
1329
- this.CJTBlock = new CJTBlockPlugin(this, args);
1330
  }
1331
  else {
1332
  // Otherwise change options
1333
- this.CJTBlock.setOptions(args);
1334
  }
1335
- return this;
1336
- });
1337
 
1338
  } // End Plugin class.
1339
 
1340
- })(jQuery);
7
  /**
8
  * JQuery wrapper for the CJTBlockPlugin object.
9
  */
10
+ ( function ( $ ) {
11
 
12
+ /**
13
+ * put your comment there...
14
+ *
15
+ */
16
+ $.fn.CJTPLSHooksDropdown = function ( arg ) {
17
 
18
+ var result = this
19
+ var args = arguments
20
 
21
+ this.each(
22
 
23
+ function () {
24
 
25
+ // Initialize the Plugin only once for each element on the chain
26
+ if ( this.CJTPLSHooksDropdown ) {
27
 
28
+ result = this.CJTPLSHooksDropdown[ arg ].call( $this, args )
29
 
30
+ return
31
+ }
32
 
33
+ // Prepare PLugin vars
34
+ var $this = $( this )
35
 
36
+ options = arg
37
 
38
+ // Initialize NEW Dropdown jQuery Plugin for the HTML element
39
+ this.CJTPLSHooksDropdown = new function () {
40
 
41
+ // Initialize object vars
42
+ var listValueElement
43
+ var listElement
44
+ var listElements
45
 
46
+ /**
47
+ * put your comment there...
48
+ *
49
+ */
50
+ var getItemValue = function ( link ) {
51
 
52
+ var hookName = link.prop( 'href' ).match( /#(.+)/ )[ 1 ]
53
 
54
+ return hookName
55
+ }
56
 
57
+ /**
58
+ * put your comment there...
59
+ *
60
+ */
61
+ var init = function () {
62
 
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
 
70
+ function () {
71
 
72
+ listElement.toggle()
73
 
74
+ return false
75
+ }
76
+ )
77
 
78
+ // list elements click event
79
+ listElements.find( 'a' ).click(
80
 
81
+ function ( event ) {
82
 
83
+ var link = $( this )
84
 
85
+ // Reflect selected value
86
+ var hookName = getItemValue( link )
87
 
88
+ listValueElement.text( link.text() )
89
 
90
+ // Set selected value CSS
91
+ listElements.removeClass( 'selected' )
92
+ link.parent().addClass( 'selected' )
93
 
94
+ // ITem selection event
95
+ $this.trigger( 'change', [ $this, hookName, link ] )
96
 
97
+ return false
98
+ }
99
+ )
100
 
101
+ // Initially select the selected element
102
+ listValueElement.text( listElements.filter( '.selected' ).find( 'a' ).text() )
103
 
104
+ }
105
 
106
+ /**
107
+ *
108
+ */
109
+ this.getOptions = function () {
110
 
111
+ return options
112
+ }
113
 
114
+ /**
115
+ *
116
+ */
117
+ this.setValue = function ( args ) {
118
 
119
+ listElements.find( 'a' ).each(
120
 
121
+ function () {
122
 
123
+ var link = $( this )
124
+ var hookName = getItemValue( link )
125
 
126
+ if ( hookName == args[ 1 ] ) {
127
 
128
+ listValueElement.text( link.text() )
129
 
130
+ listElements.removeClass( 'selected' )
131
+ link.parent().addClass( 'selected' )
132
 
133
+ return false
134
+ }
135
 
136
+ }
137
 
138
+ )
139
 
140
+ }
141
 
142
+ this.toggle = function () {
143
 
144
+ listElement.toggle()
145
 
146
+ }
147
 
148
+ // Initialize on construction
149
+ init()
150
 
151
+ }
152
 
153
+ }
154
+ )
155
 
156
+ // Chaining
157
+ return result
158
+ }
159
 
160
  /**
161
  *
162
  */
163
+ var notifySaveChangesProto = function ( block ) {
164
 
165
  /**
166
  * put your comment there...
167
  *
168
  * @param block
169
  */
170
+ this.initDIFields = function () {
171
  // Initialize notification saqve change singlton object.
172
+ block.changes = []
173
 
174
  // Initialize vars.
175
+ var model = block.block
176
+ var aceEditor = model.aceEditor
177
+ var fields = model.getDIFields()
178
 
179
  /**
180
+ * Create common interface for ace editor to
181
+ * be accessed like other HTML elements.
182
+ *
183
+ *
184
  * Bind method for bind events like HTML Elements +
185
+ * Method to get hash copy from stored content.
186
  */
187
+ aceEditor.type = 'aceEditor' // Required for _oncontentchanged to behave correctly.
188
+ aceEditor.bind = function ( e, h ) {
189
 
190
+ this.getSession().doc.on( e, h )
191
  }
192
+ aceEditor.cjtSyncInputField = function () {
193
 
194
+ this.cjtBlockSyncValue = hex_md5( this.getSession().getValue() )
195
  }
196
 
197
  // Hack jQuery Object by pushing
198
  // ace Editor into fields list, increase length by 1.
199
+ fields[ fields.length++ ] = aceEditor
200
 
201
  // For all fields call cjtSyncInputField and give a unique id.
202
+ $.each( fields, $.proxy(
203
 
204
+ function ( index, field ) {
205
 
206
+ this.initElement( field )
207
 
208
+ }, this )
209
 
210
+ )
211
 
212
+ // Notify Changes for Block name when key pressed
213
+ model.box.find( 'input:text.block-name' ).on( 'keyup', $.proxy( block._oncontentchanged, block ) )
214
 
215
  // Chaining.
216
+ return this
217
  },
218
 
219
+ /**
220
+ * put your comment there...
221
+ *
222
+ * @param element
223
+ */
224
+ this.initElement = function ( field ) {
225
 
226
+ // Assign weight number used to identify the field.
227
+ field.cjtBlockFieldId = CJTBlocksPage.blocks.getUFI()
228
 
229
+ // Create default cjtSyncInputField method if not exists.
230
+ if ( field.cjtSyncInputField == undefined ) {
231
 
232
+ if ( field.type == 'checkbox' ) {
233
 
234
+ field.cjtSyncInputField = function () {
235
 
236
+ this.cjtBlockSyncValue = $( this ).prop( 'checked' )
237
 
238
+ }
239
 
240
+ }
241
+ else {
242
 
243
+ field.cjtSyncInputField = function () {
244
 
245
+ this.cjtBlockSyncValue = this.value
246
+ }
247
 
248
+ }
249
 
250
+ // Create interface to "bind" too.
251
+ field.bind = function ( e, h ) {
252
 
253
+ $( this ).bind( e, h )
254
+ }
255
 
256
+ }
257
 
258
+ // Sync field.
259
+ field.cjtSyncInputField()
260
 
261
+ // Bind to change event.
262
+ field.bind( 'change', $.proxy( block._oncontentchanged, block ) )
263
+ }
264
+ }
265
 
266
  /**
267
  * Default block features and options.
269
  * @var object
270
  */
271
  var defaultOptions = {
272
+ showObjectsPanel: true,
273
+ calculatePinPoint: 1,
274
+ restoreRevision: { fields: [ 'code' ] }
275
+ }
276
 
277
  /**
278
  * Element to loads for each block.
283
  * @var object
284
  */
285
  var autoLoadElements = {
286
+ editBlockName: 'div.edit-block-name',
287
+ blockName: 'span.block-name',
288
+ insideMetabox: 'div.inside'
289
+ }
290
 
291
  /**
292
  * Block jQuery Plugin.
296
  * @version 6
297
  * @Author Ahmed Said
298
  */
299
+ CJTBlockPluginBase = function () {
300
 
301
  /**
302
  * Block model for accessing block properties.
303
  *
304
  * @var CJTBlock
305
  */
306
+ this.block
307
 
308
  /**
309
  *
310
  *
311
  */
312
+ this.changes
313
 
314
  /**
315
  *
316
  */
317
+ this.defaultDocks
318
 
319
+ /**
320
+ *
321
+ */
322
+ this.editBlockActionsToolbox
323
 
324
  /**
325
  *
326
  */
327
+ this.editorToolbox
328
 
329
  /**
330
  * Commonly accessed elements stored here.
331
  *
332
  * @var object
333
  */
334
+ this.elements
335
 
336
  /**
337
  *
338
  */
339
+ this.extraDocks = []
340
 
341
  /**
342
  * Block features and options.
343
  *
344
  * @var object
345
  */
346
+ this.features
347
 
348
+ /**
349
+ *
350
+ */
351
+ this.editorLangsToolbox
352
 
353
+ /**
354
+ *
355
+ */
356
+ this.flaggedActionsToolbox
357
 
358
+ /**
359
+ *
360
+ */
361
+ this.hooksDropdown
362
 
363
+ /**
364
+ *
365
+ */
366
+ this.infoBar
367
 
368
  /**
369
  *
370
  */
371
+ this.internalChanging = false
372
 
373
  /**
374
  *
375
  *
376
  *
377
  */
378
+ this.toolbox = null
379
 
380
  // Block Plugins
381
+ CJTBlockObjectPluginDockModule.plug( this )
382
 
383
+ /**
384
+ *
385
+ */
386
+ this._onclosepanelwindow = function ( event ) {
387
 
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
395
+ assignPanel.show()
396
 
397
+ // Hide close button
398
+ $( event.target ).hide()
399
 
400
+ return false
401
+ }
402
 
403
  /**
404
  *
405
  *
406
  */
407
+ this._oncontentchanged = function ( event ) {
408
  // Dont process internal changes.
409
+ if ( this.internalChanging ) {
410
+ return
411
  }
412
  // Initialize.
413
+ var element
414
+ var id // Give every field an id for tracing change.
415
+ var newValue // Field new value.
416
+ var enable // Used to enable/disable save button
417
+ // based on detected changes.
418
+ var isFieldChanged
419
+ var isChanged
420
+ var syncValue // This is the value stored in server.
421
  // Get value, id and sync value based on the input field type.
422
+ if ( event.target == undefined ) { // Ace editor event system don't
423
+ element = this.block.aceEditor
424
  // pass aceEditor object as context!
425
+ newValue = hex_md5( element.getSession().getValue() )
426
  }
427
  else { // All HTML native types.
428
+ element = event.target
429
  // Use field "value" property for getting new
430
  // context except checkboxes uses checked property.
431
+ newValue = ( element.type == 'checkbox' ) ? newValue = $( element ).prop( 'checked' ) : element.value
432
  }
433
+ id = element.cjtBlockFieldId
434
+ syncValue = element.cjtBlockSyncValue
435
  // Detect if value is changes.
436
+ isFieldChanged = ( newValue != syncValue )
437
+ isChanged = CJTBlocksPage.blocks.calculateChanges( this.changes, id, isFieldChanged )
438
  // Enable button is there is a change not saved yet, disable it if not.
439
+ this.editBlockActionsToolbox.buttons.save.enable( isChanged )
440
  // Notify blocks page.
441
+ CJTBlocksPage.blockContentChanged( this.block.id, isChanged )
442
  }
443
 
444
  /**
447
  * The method delete the block from the UI but not permenant from the server.
448
  * Save all Changes should be called in order to save deleted blocks.
449
  */
450
+ this._ondelete = function () {
451
  // Conformation message.
452
+ var confirmMessage = CJTJqueryBlockI18N.confirmDelete
453
  // Show Block name!
454
+ confirmMessage = confirmMessage.replace( '%s', this.block.get( 'name' ) )
455
  // Confirm deletion!
456
+ if ( confirm( confirmMessage ) ) {
457
 
458
+ this.block.box.trigger( 'BeforeDeleteBlock', [ this ] )
459
 
460
  // Delete block.
461
+ CJTBlocksPage.deleteBlocks( this.block.box )
462
 
463
+ this.block.box.trigger( 'BlockDeleted', [ this ] )
464
  }
465
  }
466
 
470
  *
471
  *
472
  */
473
+ this._ondisplayrevisions = function ( event ) {
474
 
475
  // Restore revision only when block is opened.
476
+ if ( this.block.box.hasClass( 'closed' ) ) {
477
+ return false
478
  }
479
  // Initialize form request.
480
  var revisionsFormParams = {
481
+ id: this.block.get( 'id' ),
482
+ activeFileId: this.codeFile.file.activeFileId
483
+ }
484
+ var url = CJTBlocksPage.server.getRequestURL( 'block', 'get_revisions', revisionsFormParams )
485
 
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 )
493
 
494
+ return false
495
  }
496
 
497
  /**
500
  *
501
  *
502
  */
503
+ this._ongetinfo = function ( event ) {
504
 
505
+ var sections = {
506
+ 'info': 'info',
507
+ 'assignment-info': 'assignment'
508
+ }
509
 
510
+ var windowName = $( event.target ).prop( 'href' ).match( /#(.+)/ )[ 1 ]
511
+ var sectionName = sections[ windowName ]
512
 
513
  // Server request.
514
  var requestData = {
515
 
516
  // Server paramerers.
517
+ id: this.block.get( 'id' ),
518
+ show_section: sectionName
519
+ }
520
 
521
+ var url = CJTBlocksPage.server.getRequestURL( 'block', 'get_info_view', requestData )
522
 
523
+ this.showPanelGenericWindow( event, url )
524
+ }
525
 
526
  /**
527
  *
528
  */
529
+ this._onlookuptemplates = function ( event ) {
530
 
531
  // Initialize.
532
+ var panelWnd = this.block.box.find( '.cjt-panel-item.cjt-panel-window-templates-lookup' )
533
+ var frameHeight = parseInt( panelWnd.css( 'height' ) )
534
+ var blockId = this.block.get( 'id' )
535
+ var iframe = panelWnd.find( 'iframe' )
536
+ var iframeHeight = frameHeight - 35
537
 
538
+ // Stay inactive if the toolbox is didsabled, as the toolbox
539
+ // has no class for enable/disable state we might use on of its buttons
540
+ if ( this.toolbox.buttons[ 'location-switch' ].jButton.hasClass( 'cjttbs-disabled' ) ) {
541
 
542
+ return
543
+ }
544
 
545
+ this._onPaneledItems( event )
546
 
547
+ iframe.css( 'height', iframeHeight )
548
 
549
+ if ( !CJTToolBox.forms.templatesLookupForm[ blockId ] ) {
550
+ CJTToolBox.forms.templatesLookupForm[ blockId ] = {}
551
  }
552
+ var lookupForm = CJTToolBox.forms.templatesLookupForm[ blockId ]
553
  // This method will fired only once when the
554
  // Templates popup button is hovered for the first time.
555
+ if ( !iframe.get( 0 ).__cjt_loaded ) {
556
+ var request = { blockId: blockId }
557
  // Pass block object to the form when loaded.
558
+ lookupForm.inputs = { blockPlugin: this, block: this.block, button: $( event.target ), height: iframeHeight }
559
  // Set frame Source to templates lookup view URL.
560
+ var templatesLookupViewURL = CJTBlocksPage.server.getRequestURL( 'templatesLookup', 'display', request )
561
+ iframe.prop( 'src', templatesLookupViewURL )
562
  // Mark loaded.
563
+ iframe.get( 0 ).__cjt_loaded = true
564
  }
565
  else {
566
  // Pass frame height when refreshed.
567
+ lookupForm.inputs.height = iframeHeight
568
+ lookupForm.form.refresh()
569
  }
570
  /** @TODO Tell Block toolbox to deatach/unbind popup callback */
571
+ return true // Tell CJTToolBox to Show Popup menu as normal.
572
  }
573
 
574
+ /**
575
+ *
576
+ */
577
+ this._onPaneledItems = function ( event ) {
578
 
579
+ var link = $( event.target )
580
+ var windowName = link.prop( 'href' ).match( /#(.+)/ )[ 1 ]
581
+ var panelWindow = this.block.box.find( '.cjt-panel-item.cjt-panel-window-' + windowName )
582
+ var panelArea = this.block.box.find( '.cjpageblock' )
583
 
584
+ // Hide all panel windows
585
+ panelArea.find( '.cjt-panel-item' ).hide()
586
 
587
+ // Display panel
588
+ panelWindow.show()
589
 
590
+ // Display Close button
591
+ panelArea.find( '.close-panel-window' ).show()
592
+ }
593
 
594
 
595
  /**
596
  * Don't show popup menus if Block is minimized!
597
  */
598
+ this._onpopupmenu = function ( targetElement, button ) {
599
+ var show = true
600
+ if ( this.block.box.hasClass( 'closed' ) ) {
601
+ show = false
602
  }
603
  else {
604
  // Some Popup forms need to be re-sized if fullscree is On!
605
+ if ( button.params.fitToScreen == true ) {
606
+ this.dock( targetElement, 25 )
607
  }
608
  }
609
+ return show
610
  }
611
 
612
  /**
613
  *
614
  */
615
+ this._onpostboxopened = function () {
616
  // If aceEditor is undefined then the
617
  // block is no loaded yet,
618
  // loads it.
619
+ if ( this.block.aceEditor == undefined ) {
620
+ this._onload()
621
  }
622
  else {
623
  // Update ACE Editor region.
624
+ this.block.aceEditor.resize()
625
  }
626
  }
627
 
632
  * @see CJTBlock.saveDIFields method for more details about fields.
633
  *
634
  */
635
+ this._onsavechanges = function () {
636
 
637
+ var saveButton = this.editBlockActionsToolbox.buttons[ 'save' ]
638
 
639
  // Dont save unless there is a change!
640
+ if ( saveButton.jButton.hasClass( 'cjttbs-disabled' ) ) {
641
  // Return REsolved Dummy Object for standarizing sake!
642
+ return CJTBlocksPage.server.getDeferredObject().resolve().promise()
643
  }
644
 
645
  // Queue User Direct Interact fields (code, etc...).
646
+ var data = { calculatePinPoint: this.features.calculatePinPoint, createRevision: 1 }
647
 
648
  // Push DiFields inside Ajax queue.
649
+ this.block.queueDIFields()
650
 
651
  // Add code file flags to the queue.
652
+ var queue = this.block.getOperationQueue( 'saveDIFields' )
653
+ queue.add( { id: this.block.get( 'id' ), property: 'activeFileId', value: this.codeFile.file.activeFileId } )
654
 
655
  // But save button into load state (Inactive and Showing loading icon).
656
+ if ( this.block.get( 'name' ).match( /^[A-Za-z0-9\!\#\@\$\&\*\(\)\[\]\x20\-\_\+\?\:\;\.]{1,50}$/ ) ) {
657
+ saveButton.loading( true )
658
+ this.enable( false )
659
 
660
+ this.block.box.trigger( 'PreSaveBlock', [ this ] )
661
  }
662
 
663
  // Send request to server.
664
+ return this.block.sync( 'saveDIFields', data )
665
 
666
+ .success( $.proxy(
667
 
668
+ function ( response ) {
669
 
670
+ var responseBlockData = response[ this.block.get( 'id' ) ]
671
 
672
+ // Stop loading effect and disable the button.
673
+ saveButton.loading( false, false )
674
 
675
+ // Sync fields with server value.
676
+ // This refrssh required for notifying saving
677
+ // change to detect changes.
678
+ var diFields = this.block.getDIFields()
679
+ // Push aceEditor into diFields list.
680
+ diFields[ diFields.length++ ] = this.block.aceEditor
681
+ diFields.each(
682
+ function () {
683
+ this.cjtSyncInputField()
684
+ }
685
+ )
686
 
687
+ // Reset changes list.
688
+ this.changes = []
689
 
690
+ // Tell blocks page that block is saved and has not changed yet.
691
+ CJTBlocksPage.blockContentChanged( this.block.id, false )
692
 
693
+ // Reflect Info bar updated information
694
+ this.infoBar.find( '.block-info-name>strong' ).text( responseBlockData.name.value )
695
+ this.infoBar.find( '.block-shortcode > input:text' ).val( '[cjtoolbox name="' + responseBlockData.name.value + '"]' )
696
 
697
+ var blockModifiedDate = new Date( responseBlockData.lastModified.value )
698
 
699
+ this.infoBar.find( '.block-modified-date>strong' ).text(
700
+ blockModifiedDate.getDate().toString().padStart( 2, 0 ) + '-' +
701
+ ( blockModifiedDate.getMonth() + 1 ).toString().padStart( 2, 0 ) + '-' +
702
+ blockModifiedDate.getFullYear() + ', ' +
703
+ blockModifiedDate.getHours() + ':' +
704
+ blockModifiedDate.getMinutes()
705
+ )
706
 
707
+ // Fire BlockSaved event.
708
+ this.onBlockSaved()
709
 
710
+ this.block.box.trigger( 'BlockSaved', [ this ] )
711
 
712
+ }, this )
713
+ )
714
+ .error( $.proxy(
715
 
716
+ function () {
717
 
718
+ saveButton.loading( false )
719
 
720
+ }, this )
721
 
722
+ ).complete( $.proxy(
723
 
724
+ function ( response ) {
725
 
726
+ // Enable block
727
+ this.enable( true )
728
 
729
+ }, this )
730
 
731
+ )
732
 
733
  }
734
 
738
  *
739
  *
740
  */
741
+ this._onswitcheditorlang = function ( event, params ) {
742
 
743
+ var jLanguageSwitcher = this.block.box.find( '.cjttbl-switch-editor-language' )
744
+ var languageSwitcher = jLanguageSwitcher.get( 0 )
745
 
746
  // Note: Event and params parameter is passed but unused,
747
  // we need only selectedValue.
748
  // Set editor mode.
749
+ var editorMode = 'ace/mode/' + params.lang
750
+ this.block.aceEditor.getSession().setMode( editorMode )
751
 
752
  // Save editor language for block.
753
+ this.block.set( 'editorLang', params.lang )
754
 
755
+ jLanguageSwitcher.text( CJTJqueryBlockI18N[ 'editorLang_' + params.lang ] )
756
  }
757
 
758
  /**
761
  * @param event Javascript event object.
762
  * @param object Toolbox evenr parameters.
763
  */
764
+ this._onswitchflag = function ( event, params ) {
765
+ var promise
766
+ var target = $( event.target )
767
+ var oldValue = this.block.get( params.flag )
768
+ var flagButton = this.flaggedActionsToolbox.buttons[ params.flag + '-switch' ]
 
769
 
770
  // Put the Flag button into load state (Inactive + loading icon).
771
+ flagButton.loading( true )
772
 
773
  // Switch flag state.
774
+ this.block.switchFlag( params.flag, params.newValue ).success( $.proxy(
775
+ function ( rState ) {
776
+ var oldCSSClass = params.flag + '-' + oldValue
777
+ var newCSSClass = params.flag + '-' + rState.value
778
+ target.removeClass( oldCSSClass ).addClass( newCSSClass )
779
+ // Switch title based on current FLAG and the new VALUE.
780
+ .attr( 'title', CJTJqueryBlockI18N[ params.flag + '_' + rState.value + 'Title' ] )
781
+ }, this )
782
+ )
783
 
784
  // Update on server.
785
+ promise = this.block.sync( params.flag )
786
 
787
+ .complete( $.proxy(
788
 
789
+ function () {
790
+ flagButton.loading( false )
791
 
792
+ }, this )
793
 
794
+ )
795
 
796
+ return promise
 
 
797
  }
798
 
799
  /**
802
  *
803
  *
804
  */
805
+ this.enable = function ( state ) {
806
+ var elements = this.block.box.find( 'input:checkbox,input:text, textarea, select' )
807
+ switch ( state ) {
808
  case true: // Enable block.
809
+ elements.removeAttr( 'disabled' )
810
+ break
811
  case false: // Disable block.
812
+ elements.attr( 'disabled', 'disabled' )
813
+ break
814
  }
815
 
816
+ this.toolbox.enable( state )
817
+ this.flaggedActionsToolbox.enable( state )
818
+ this.editBlockActionsToolbox.buttons[ 'delete' ].enable( state )
819
 
820
  // Enable or Disable ACEEditor.
821
  // Enable = true then setReadnly = false and vise versa.
822
+ this.block.aceEditor.setReadOnly( !state )
823
  }
824
 
825
  /**
827
  *
828
  * @return false.
829
  */
830
+ this.focus = function () {
831
+ this.block.aceEditor.focus()
832
  }
833
 
834
  /**
836
  *
837
  *
838
  */
839
+ this.initCJTPluginBase = function ( node, args ) {
840
 
841
  // Initialize object properties!
842
+ var model = this.block = new CJTBlock( this, node )
843
+ this.features = $.extend( defaultOptions, args )
844
 
845
  // Initialize Events.
846
+ this.onBlockSaved = function () { }
847
 
848
+ // DOn't TOGGLE block when block name get/lost focus
849
+ model.box.find( 'input:text.block-name' ).click( function ( event ) { event.stopPropagation() } )
850
 
851
  // Load commonly used elements.
852
+ this.elements = {}
853
+ $.each( autoLoadElements, $.proxy(
854
+ function ( name, selector ) {
855
+ this.elements[ name ] = this.block.box.find( selector )
856
+ }, this )
857
+ )
858
 
859
  // Move edit-block-name edit area and tasks-bar outside Wordpress metabox "inside div".
860
+ this.elements.insideMetabox.before( model.box.find( '.edit-block-name, .block-toolbox' ) )
861
 
862
+ /* Info bar won't be exists if the block is initially closed
863
+ * this is just for the code to avoid writing more IF conditions
864
+ * block info item will be queried again on the load method
865
+ */
866
+ this.infoBar = this.block.box.find( '.cjt-info-bar' )
867
 
868
+ // HInitialize ooks dropdown list
869
+ this.hooksDropdown = model.box.find( '.hooks-dropdown' ).CJTPLSHooksDropdown( {} )
870
 
871
+ /* Revert item value is failed to change location value */
872
+ /* Reflect Hooks icon and text values when successfully changes hook */
873
+ .on( 'change', $.proxy(
874
 
875
+ function ( event, dropdown, hookName, jItem ) {
876
 
877
+ var currentHookName = model.get( 'location' )
878
 
879
+ model.set( 'location', hookName ).error( $.proxy(
880
 
881
+ function () {
882
 
883
+ dropdown.CJTPLSHooksDropdown( 'setValue', currentHookName )
884
 
885
+ } ), this )
886
 
887
+ .done( $.proxy(
888
 
889
+ function () {
890
 
891
+ // Reflect Hook button status when hook changed
892
+ this.toolbox.buttons[ 'location-switch' ].jButton
893
+ .removeClass( 'location-' + currentHookName )
894
+ .addClass( 'location-' + hookName )
895
 
896
+ .prop( 'title', jItem.prop( 'title' ) )
897
+ .text( jItem.text() )
898
 
899
+ .removeClass( 'bad-location-specified' )
900
+ .prev().removeClass( 'bad-location-specified' )
901
 
902
+ }, this )
903
+ )
904
 
905
+ model.sync( 'location' )
906
 
907
+ }, this )
908
 
909
+ ).get( 0 ).CJTPLSHooksDropdown
910
 
911
  // Activate toolbox.
912
+ this.toolbox = model.box.find( '.block-toolbox' ).CJTToolBox( {
913
+ context: this,
914
+ handlers: {
915
+
916
+ 'assignment-info': { callback: this._ongetinfo },
917
+ 'block-info': { callback: this._ongetinfo },
918
+
919
+ 'location-switch': {
920
+ type: 'Popup',
921
+ params: {
922
+ _type: {
923
+ targetElement: '.hooks-dropdown',
924
+ setTargetPosition: false
925
+ }
926
+ }
927
+ },
928
+ 'templates': {
929
+ type: 'Popup',
930
+ params: {
931
+ _type: {
932
+ onPopup: this._onpopupmenu,
933
+ targetElement: '.templates',
934
+ setTargetPosition: true
935
+ }
936
+ }
937
+ },
938
+ 'templates-lookup': { callback: this._onlookuptemplates },
939
+ 'templates-manager': { callback: CJTBlocksPage._onmanagetemplates },
940
+ 'code-files': { callback: function () { } } /* This is dummy unless updated by code file controller object on the load method */
941
  }
942
+ } ).get( 0 ).CJTToolBox
943
 
944
+ this.toolbox.buttons[ 'templates' ].jButton.click( $.proxy( this._onlookuptemplates, this ) )
945
 
946
+ // Editor Language Toolbox
947
+ this.editorLangsToolbox = model.box.find( '.cjt-toolbox.editor-langs-toolbox' ).CJTToolBox( {
948
 
949
+ context: this,
950
+ handlers: {
951
 
952
+ 'switch-editor-language': {
953
+ type: 'Popup',
954
+ params: {
955
+ // Parameters for PopupList type button.
956
+ _type: {
957
+ onPopup: this._onpopupmenu,
958
+ targetElement: '.editor-langs',
959
+ setTargetPosition: false
960
+ }
961
+ }
962
+ },
963
 
964
+ 'editor-language-css': { callback: this._onswitcheditorlang, params: { lang: 'css' } },
965
+ 'editor-language-html': { callback: this._onswitcheditorlang, params: { lang: 'html' } },
966
+ 'editor-language-javascript': { callback: this._onswitcheditorlang, params: { lang: 'javascript' } },
967
+ 'editor-language-php': { callback: this._onswitcheditorlang, params: { lang: 'php' } }
968
 
969
+ }
970
 
971
+ } ).get( 0 ).CJTToolBox
972
 
973
+ // Disable Toolbox until block is loaded
974
+ this.toolbox.enable( false )
975
+ this.editorLangsToolbox.enable( false )
976
 
977
+ // Move State and Location buttons to be before block name
978
+ this.flaggedActionsToolbox = model.box.find( '.cjt-toolbox.flagged-actions-toolbox' )
979
+ .insertBefore( model.box.find( '.hndle .block-name' ) )
980
+ .CJTToolBox( {
981
 
982
+ context: this,
983
+ handlers: {
984
+ 'state-switch': { callback: this._onswitchflag, params: { flag: 'state' } },
985
+ }
986
 
987
+ } ).get( 0 ).CJTToolBox
988
 
989
+ // Move State and Location buttons to be before block name
990
+ this.editBlockActionsToolbox = model.box.find( '.cjt-toolbox.edit-block-toolbox' )
991
+ .insertAfter( model.box.find( '.hndle .block-name' ) )
992
+ .CJTToolBox( {
993
 
994
+ context: this,
995
+ handlers: {
996
 
997
+ 'save': { callback: this._onsavechanges, params: { enable: false } },
998
+ 'delete': { callback: this._ondelete },
999
 
1000
+ }
1001
 
1002
+ } ).get( 0 ).CJTToolBox
1003
 
1004
+ // Initialized-event (Regardless if loaded or not)
1005
+ this.block.box.trigger( 'Initialized', [ this ] )
1006
 
1007
  // If the code editor element is presented then
1008
  // the block is already opened and no need to load later.
1009
+ if ( model.box.find( '.code-editor' ).length ) {
1010
 
1011
+ // Load nd Trigger Load events
1012
+ this.loadTLE()
1013
 
1014
  }
1015
 
1016
  // Display block.
1017
  // !important: Blocks come from server response doesn't need this but the newly added blocks does.
1018
  // need sometime to be ready for display.
1019
+ model.box.css( { display: 'block' } ).addClass( 'cjt-block' )
1020
  }
1021
 
1022
+ /**
1023
+ *
1024
+ */
1025
+ this.initInfoBar = function () {
1026
 
1027
+ this.infoBar = this.block.box.find( '.cjt-info-bar' )
1028
 
1029
+ // Copy Shortcode
1030
+ this.infoBar.find( '.block-shortcode .copyshortcode' ).click( $.proxy(
1031
 
1032
+ function () {
1033
 
1034
+ var shortcodeEle = this.infoBar.find( '.block-shortcode input' )
1035
 
1036
+ shortcodeEle.focus()
1037
+ shortcodeEle.select()
1038
 
1039
+ document.execCommand( 'copy' )
1040
 
1041
+ return false
1042
 
1043
+ }, this )
1044
+ )
1045
 
1046
+ // Update Assignment count whenever the block is saved
1047
+ this.block.box.on( 'BlockSaved', $.proxy(
1048
 
1049
+ function () {
1050
 
1051
+ CJTBlocksPage.server.send( 'block', 'getAllAssignment', { blockId: this.block.get( 'id' ) } ).done( $.proxy(
1052
 
1053
+ function ( response ) {
1054
 
1055
+ this.infoBar.find( '.block-assignment-count .show-assignment-info' ).text( response )
1056
 
1057
+ }, this )
1058
 
1059
+ )
1060
 
1061
+ }, this )
1062
 
1063
+ )
1064
 
1065
 
1066
+ // Editor Language
1067
+ this.infoBar.find( '.block-editor-lang strong' ).text( this.block.get( 'editorLang' ) )
1068
 
1069
+ // Allow info bar to be extensible
1070
+ this.block.box.trigger( 'InitInfoBar', [ this, this.infoBar ] )
1071
+ }
1072
 
1073
  /**
1074
  *
1075
  */
1076
+ this._onload = function () {
1077
  // Initialize.
1078
+ var model = this.block
1079
  // Show loading block progress.
1080
+ var loadingPro = $( '<div class="loading-block">' + CJTJqueryBlockI18N.loadingBlock + ' . . .</div>' ).prependTo( this.elements.insideMetabox.prepend() )
1081
  // Retrieve Block HTML content.
1082
+ CJTBlocksPage.server.send( 'blocksPage', 'loadBlock', { blockId: model.get( 'id' ), isLoading: true } )
1083
+ .success( $.proxy(
1084
+ function ( blockContent ) {
1085
 
1086
+ // Remove loading bloc progress.
1087
+ loadingPro.remove()
1088
 
1089
+ // Add block content
1090
+ this.elements.insideMetabox.append( blockContent.content )
1091
 
1092
+ // Load block.
1093
+ this.loadTLE()
1094
 
1095
+ }, this )
1096
+ )
1097
+ }
1098
 
1099
  /**
1100
  *
1101
  */
1102
+ this.load = function () {
 
1103
 
1104
+ var model = this.block
1105
 
1106
  // Broadcast block event
1107
+ this.block.box.trigger( 'cjtBlockLoaded', [ this ] )
1108
 
1109
  // LOAD MODEL.
1110
+ model.load()
1111
 
1112
  // Editor default options.
1113
+ this.block.aceEditor.setOptions( { showPrintMargin: false } )
1114
 
1115
+ // Initialize info bar
1116
+ this.initInfoBar()
1117
 
1118
+ // Enable HEader button Toolbox
1119
+ this.toolbox.enable( true )
1120
+ this.editorLangsToolbox.enable( true )
1121
 
1122
  // Initialize editor toolbox.
1123
+ this.editorToolbox = model.box.find( '.editor-toolbox' ).CJTToolBox( {
1124
+ context: this,
1125
+ handlers: {}
1126
+ } ).get( 0 ).CJTToolBox
1127
 
1128
 
1129
  // Default to DOCK!!
1130
  this.defaultDocks = [
1131
+ {
1132
+ element: $( this.block.aceEditor.container ),
1133
+ pixels: 7
1134
+ },
1135
+ {
1136
+ element: this.block.box.find( '.cjpageblock .cjt-panel-genericwnd' ),
1137
+ pixels: 64
1138
+ },
1139
+ {
1140
+ element: this.block.box.find( '.cjt-panel-item.cjt-panel-window-templates-lookup' )
1141
 
1142
+ .on( 'CJTDockedItemResized',
1143
 
1144
+ function ( event, item ) {
1145
 
1146
+ if ( CJTToolBox.forms.templatesLookupForm[ model.get( 'id' ) ] !== undefined ) {
1147
 
1148
+ item.height = item.height - 35
1149
 
1150
+ item.element.find( 'iframe' ).css( 'height', item.height )
1151
+ CJTToolBox.forms.templatesLookupForm[ model.get( 'id' ) ].inputs.height = item.height
1152
+ CJTToolBox.forms.templatesLookupForm[ model.get( 'id' ) ].form.refresh()
1153
 
1154
+ }
1155
 
1156
+ }
1157
+ )
1158
+ .on( 'CJTBlockExitFullScreen',
1159
 
1160
+ function ( event, item ) {
1161
 
1162
+ if ( CJTToolBox.forms.templatesLookupForm[ model.get( 'id' ) ] !== undefined ) {
1163
 
1164
+ var originalHeight = item.element.height()
1165
+ var iframeHeight = originalHeight - 35
1166
 
1167
+ item.element.css( 'height', originalHeight )
1168
+ item.element.find( 'iframe' ).css( 'height', iframeHeight )
1169
 
1170
+ CJTToolBox.forms.templatesLookupForm[ model.get( 'id' ) ].inputs.height = iframeHeight
1171
+ CJTToolBox.forms.templatesLookupForm[ model.get( 'id' ) ].form.refresh()
1172
 
1173
+ }
1174
 
1175
+ }
1176
+ ),
1177
+ pixels: 27
1178
+ }
1179
+ ]
1180
 
1181
  // Show hidden toolbox buttons.
1182
+ this.editorLangsToolbox.buttons[ 'switch-editor-language' ].jButton.removeClass( 'waitingToLoad' )
1183
+ this.block.box.find( '.cjt-toolbox.block-toolbox' ).find( '.waitingToLoad' ).removeClass( 'waitingToLoad' )
1184
+ this.editBlockActionsToolbox.buttons[ 'save' ].jButton.removeClass( 'waitingToLoad' )
1185
 
1186
  // Register COMMAND-KEYS.
1187
+ this.registerCommands()
1188
 
1189
  // Switch Block state if required, if state is empty nothing will happen.
1190
  // Until now only 'restore' state is supported to prevent saving restored block.
1191
+ this.switchState( this.features.state )
1192
 
1193
  // Prepare input elements for notifying user changes.
1194
+ this.notifySaveChanges = ( new notifySaveChangesProto( this ) ).initDIFields()
1195
 
1196
  // Set theme object.
1197
 
1198
+ this.theme = {}
1199
 
1200
+ /*
1201
  this.theme.backgroundColor = 'white';
1202
  this.theme.color = 'black';
1203
+ this.theme.altTextColor = 'snow';
1204
+ */
1205
 
1206
  // LOAD EVENT.
1207
+ if ( this.onLoad !== undefined ) {
1208
 
1209
+ this.onLoad()
1210
  }
1211
 
1212
  // Block Code File.
1213
+ this.codeFile = new CJTBlockFile( this )
1214
 
1215
+ this.block.box.find( '.cjpageblock a.close-panel-window' ).click( $.proxy( this._onclosepanelwindow, this ) )
1216
 
1217
+ this.block.box.trigger( 'cjtBlockPostLoading', [ this ] )
1218
  }
1219
 
1220
+ /**
1221
+ *
1222
+ */
1223
+ this.loadTLE = function () {
1224
 
1225
+ this.block.box.trigger( 'BlockBeforeLoadProc', [ this ] )
1226
 
1227
+ this.load()
1228
 
1229
+ this.block.box.trigger( 'BlockAfterLoadProc', [ this ] )
1230
 
1231
+ }
1232
 
1233
  /**
1234
  *
1235
  */
1236
+ this.registerCommands = function () {
1237
+ var editorCommands = this.block.aceEditor.commands
1238
  var commands = [
1239
  {
1240
  name: 'Save-Changes',
1241
  bindKey: {
1242
+ win: 'Ctrl-S',
1243
+ mac: 'Command-J'
1244
  },
1245
+ exec: $.proxy( this._onsavechanges, this )
1246
  }
1247
+ ]
1248
  /** Add Our Ace Save, Full screen and Code-Auto-Completion commands */
1249
+ editorCommands.addCommands( commands )
1250
  }
1251
 
1252
  /**
1253
  *
1254
  */
1255
+ this.restoreRevision = function ( revisionId, data ) {
1256
  // Create new revision control action.
1257
+ this.revisionControl = new CJTBlockOptionalRevision( this, data, revisionId )
1258
  // Display the revision + enter revision mode.
1259
+ this.revisionControl.display()
1260
  }
1261
 
1262
  /**
1263
  *
1264
  */
1265
+ this.setFeatures = function ( features ) {
1266
+ this.features = features
1267
+ }
 
1268
 
1269
+ /**
1270
+ *
1271
+ */
1272
+ this.showPanelGenericWindow = function ( event, url ) {
1273
 
1274
+ var genericPanelWindow = $( '.cjpageblock .cjt-panel-genericwnd' )
1275
 
1276
+ $.get( url ).done( $.proxy(
1277
 
1278
+ function ( content ) {
1279
 
1280
+ genericPanelWindow
1281
+ .empty()
1282
+ .append( content )
1283
 
1284
+ this._onPaneledItems( event )
1285
 
1286
+ }, this )
1287
 
1288
+ )
1289
+ }
1290
 
1291
  /*
1292
  *
1293
  *
1294
  *
1295
  */
1296
+ this.switchState = function ( state ) {
1297
+ switch ( state ) {
1298
  case 'restore':
1299
  // Hide block toolbox.
1300
+ this.toolbox.jToolbox.hide()
1301
  // Disable all fields.
1302
+ this.enable( false )
1303
  // Change state
1304
+ this.state = 'restore'
1305
  default:
1306
+ // Nothing for now
1307
+ break
1308
  }
1309
  }
1310
 
1313
  /**
1314
  * jQuery Plugin interface.
1315
  */
1316
+ $.fn.CJTBlock = function ( args ) {
1317
  /**
1318
  * Process every block object.
1319
  */
1320
+ return this.each( function () {
1321
 
1322
  // If this is the first time to be called for this element
1323
  // create new CJTBlockPlugin object for the this element.
1324
+ if ( this.CJTBlock == undefined ) {
1325
+ this.CJTBlock = new CJTBlockPlugin( this, args )
1326
  }
1327
  else {
1328
  // Otherwise change options
1329
+ this.CJTBlock.setOptions( args )
1330
  }
1331
+ return this
1332
+ } )
1333
 
1334
  } // End Plugin class.
1335
 
1336
+ } )( jQuery )
views/blocks/manager/public/js/ajax-multioperation/ajax-multioperation.js CHANGED
@@ -6,7 +6,7 @@ var CJTBlocksAjaxMultiOperations;
6
  /**
7
  *
8
  */
9
- (function($) {
10
 
11
  /**
12
  *
@@ -15,113 +15,114 @@ var CJTBlocksAjaxMultiOperations;
15
  *
16
  */
17
  var operations = {
18
- save : {
19
- element : '.cjttbl-save',
20
- eventName : '_onsavechanges',
21
- queueName : 'saveDIFields'
22
  },
23
- switchLocation : {
24
- element : '.cjttbl-location-switch',
25
- eventName : '_onswitchflag',
26
- params : {flag : 'location'},
27
- queueName : 'location'
28
  },
29
- switchState : {
30
- element : '.cjttbl-state-switch',
31
- eventName : '_onswitchflag',
32
- params : {flag : 'state'},
33
- queueName : 'state'
34
  }
35
- };
36
-
37
  /**
38
  *
39
  *
40
  *
41
  *
42
  */
43
- CJTBlocksAjaxMultiOperations = function(controller, action) {
44
 
45
  /**
46
  *
47
  *
48
  *
49
  *
50
- */
51
- this.action = null;
52
-
53
  /**
54
  *
55
  *
56
  *
57
  *
58
  */
59
- this.controller = null;
60
-
61
  /**
62
  *
63
  *
64
  *
65
  *
66
  */
67
- this.queue = null;
68
-
69
  /**
70
  *
71
  *
72
  *
73
  *
74
  */
75
- this._init = function(controller, action) {
76
- this.controller = controller;
77
- this.action = action;
78
  }
79
-
80
  /**
81
  *
82
  *
83
  *
84
  *
85
- */
86
- this.trigger = function(operationName, params) {
87
  // Having queue for every multioperation allow executing multi-multioperations.
88
  // in the same time, e.g user can deactivate/activate all and then header/footer all
89
  // in the same time without interfering with each others.
90
- var multiOperationQueue = new CJTBlocksServerQueue(this.controller, this.action);
91
- var operation = operations[operationName];
92
  // Make sure operation.params is object.
93
- operation.params = (operation.params != undefined) ? operation.params : {};
94
  // Prepare event paramaters.
95
- var dummyEventObject = {};
96
- var eventParams = $.extend(operation.params, params);
97
  // For every block trigger switch state event.
98
- var blocks = CJTBlocksPage.blocks.getBlocks();
99
  blocks.each(
100
- function() {
101
- var block = $(this);
102
  // CJTBlock Plugin set a reference in oringal DOMNode.
103
- var cjtBlock = this.CJTBlock;
104
  // Inisde jquery Plugin we can find block model object.
105
- var queue = cjtBlock.block.getOperationQueue(operation.queueName);
106
  // Set it just if the original element is clicked.
107
- dummyEventObject.target = block.find(operation.element);
108
  // Lock the queue to prevent send the Ajax request for every single block.
109
  // We'll send it all at once.
110
- queue.lock();
111
  // Triger the event.
112
- cjtBlock[operation.eventName](dummyEventObject, eventParams);
113
  // Get single block queue into the internal queue.
114
- multiOperationQueue.merge(queue);
 
115
  // Delete single block queue.
116
- CJTServer.destroyQueue(queue);
117
  }
118
- );
119
- return multiOperationQueue;
120
  }
121
-
122
  // Initialize.
123
- this._init(controller, action);
124
-
125
  } // End class.
126
-
127
- })(jQuery);
6
  /**
7
  *
8
  */
9
+ ( function ( $ ) {
10
 
11
  /**
12
  *
15
  *
16
  */
17
  var operations = {
18
+ save: {
19
+ element: '.cjttbl-save',
20
+ eventName: '_onsavechanges',
21
+ queueName: 'saveDIFields'
22
  },
23
+ switchLocation: {
24
+ element: '.cjttbl-location-switch',
25
+ eventName: '_onswitchflag',
26
+ params: { flag: 'location' },
27
+ queueName: 'location'
28
  },
29
+ switchState: {
30
+ element: '.cjttbl-state-switch',
31
+ eventName: '_onswitchflag',
32
+ params: { flag: 'state' },
33
+ queueName: 'state'
34
  }
35
+ }
36
+
37
  /**
38
  *
39
  *
40
  *
41
  *
42
  */
43
+ CJTBlocksAjaxMultiOperations = function ( controller, action ) {
44
 
45
  /**
46
  *
47
  *
48
  *
49
  *
50
+ */
51
+ this.action = null
52
+
53
  /**
54
  *
55
  *
56
  *
57
  *
58
  */
59
+ this.controller = null
60
+
61
  /**
62
  *
63
  *
64
  *
65
  *
66
  */
67
+ this.queue = null
68
+
69
  /**
70
  *
71
  *
72
  *
73
  *
74
  */
75
+ this._init = function ( controller, action ) {
76
+ this.controller = controller
77
+ this.action = action
78
  }
79
+
80
  /**
81
  *
82
  *
83
  *
84
  *
85
+ */
86
+ this.trigger = function ( operationName, params ) {
87
  // Having queue for every multioperation allow executing multi-multioperations.
88
  // in the same time, e.g user can deactivate/activate all and then header/footer all
89
  // in the same time without interfering with each others.
90
+ var multiOperationQueue = new CJTBlocksServerQueue( this.controller, this.action )
91
+ var operation = operations[ operationName ]
92
  // Make sure operation.params is object.
93
+ operation.params = ( operation.params != undefined ) ? operation.params : {}
94
  // Prepare event paramaters.
95
+ var dummyEventObject = {}
96
+ var eventParams = $.extend( operation.params, params )
97
  // For every block trigger switch state event.
98
+ var blocks = CJTBlocksPage.blocks.getBlocks()
99
  blocks.each(
100
+ function () {
101
+ var block = $( this )
102
  // CJTBlock Plugin set a reference in oringal DOMNode.
103
+ var cjtBlock = this.CJTBlock
104
  // Inisde jquery Plugin we can find block model object.
105
+ var queue = cjtBlock.block.getOperationQueue( operation.queueName )
106
  // Set it just if the original element is clicked.
107
+ dummyEventObject.target = block.find( operation.element )
108
  // Lock the queue to prevent send the Ajax request for every single block.
109
  // We'll send it all at once.
110
+ queue.lock()
111
  // Triger the event.
112
+ cjtBlock[ operation.eventName ]( dummyEventObject, eventParams )
113
  // Get single block queue into the internal queue.
114
+ multiOperationQueue.merge( queue )
115
+
116
  // Delete single block queue.
117
+ CJTServer.destroyQueue( queue )
118
  }
119
+ )
120
+ return multiOperationQueue
121
  }
122
+
123
  // Initialize.
124
+ this._init( controller, action )
125
+
126
  } // End class.
127
+
128
+ } )( jQuery )
views/blocks/manager/public/js/blocks-page/blocks-page.js CHANGED
@@ -2,8 +2,8 @@
2
  *
3
  */
4
  var CJTToolBox = {
5
- forms : {templatesLookupForm : []}
6
- }; // Application name spaces structure.
7
 
8
  /*
9
  *
@@ -15,7 +15,7 @@ var CJTBlocksPage;
15
  *
16
  *
17
  */
18
- (function($){
19
 
20
  /*
21
  *
@@ -28,21 +28,21 @@ var CJTBlocksPage;
28
  *
29
  *
30
  */
31
- blocksContainer : null,
32
 
33
  /*
34
  *
35
  *
36
  *
37
  */
38
- blocksForm : null,
39
 
40
  /*
41
  *
42
  *
43
  *
44
  */
45
- blocks : null,
46
 
47
  /**
48
  *
@@ -51,99 +51,99 @@ var CJTBlocksPage;
51
  *
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
  /**
78
  *
79
  *
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
  *
108
  *
109
  */
110
- css : function(role, value) {
111
  this.toolboxes.each(
112
- function() {
113
- $(this).css(role, value);
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 = {};
130
  CJTBlocksPage.toolboxes.toolboxes.each(
131
- function(index) {
132
  // Get button object.
133
- var button = this.CJTToolBox.buttons[buttonName];
134
  // Dispatch button method.
135
- result[index] = button[method].apply(button, params);
136
  }
137
- );
138
- return result;
139
  }
140
- };
141
  // When created and params is passed vall dispatch.
142
- if (params != undefined) {
143
- dispatcher.dispatch(params);
144
  }
145
  // Return dispatched handle object.
146
- return dispatcher;
147
  },
148
 
149
  /**
@@ -151,13 +151,13 @@ var CJTBlocksPage;
151
  *
152
  *
153
  */
154
- enable : function(buttonName, enable) {
155
  this.toolboxes.each(
156
- function() {
157
- var button = this.CJTToolBox.buttons[buttonName];
158
- button.enable(enable);
159
  }
160
- );
161
  },
162
 
163
  /**
@@ -165,15 +165,15 @@ var CJTBlocksPage;
165
  *
166
  *
167
  */
168
- isEnabled : function(buttonName) {
169
- var isEnabled = true;
170
  this.toolboxes.each(
171
- function() {
172
- var button = this.CJTToolBox.buttons[buttonName];
173
- isEnabled &= button.isEnabled();
174
  }
175
- );
176
- return isEnabled;
177
  },
178
 
179
  /*
@@ -181,33 +181,33 @@ var CJTBlocksPage;
181
  *
182
  *
183
  */
184
- switchState : function(state) {
185
- var buttonsToHide;
186
- switch (state) {
187
  case 'restore':
188
  // Hide Add New Block, Save all changes, location tools and state tools buttons.
189
- buttonsToHide = ['save-changes', 'add-block', 'state-tools', 'location-tools'];
190
- break;
191
  default:
192
- // Hide Restore & Cancel Restore buttons.
193
- buttonsToHide = ['restore', 'cancel-restore'];
194
- break;
195
  }
196
  // Hide buttons.
197
  this.toolboxes.each(
198
  // Get all toolboxes.
199
- function(tbIndex, toolbox) {
200
  // Hide all buttons for each toolbox.
201
- $.each(buttonsToHide,
202
- function(btnIndex, buttonName) {
203
- var button = toolbox.CJTToolBox.buttons[buttonName];
204
- button.jButton.css('display', 'none');
205
  }
206
- );
207
  }
208
- );
209
  // Display Toolboxes.
210
- this.css('visibility', 'visible');
211
  }
212
  },
213
 
@@ -216,66 +216,66 @@ var CJTBlocksPage;
216
  *
217
  *
218
  */
219
- _onaddnew : function(event, params) {
220
  // Server request.
221
  var requestData = {
222
  // Server paramerers.
223
- viewName : 'blocks/new',
224
  // Thick box parameters.
225
- width : 450,
226
  height: 230,
227
- position : params.toolbox.position,
228
- TB_iframe : true // Must be last one Thickbox removes this and later params.
229
- };
230
- var url = CJTBlocksPage.server.getRequestURL('blocksPage', 'get_view', requestData);
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};
259
- var url = CJTBlocksPage.server.getRequestURL('templatesManager', 'display', params);
260
- tb_show(CJTBlocksPageI18N.manageTemplatesFormTitle, url);
261
  // Get thickbox form element.
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%',
271
- 'height' : ((jQuery(window).height() - 40) + 'px'),
272
- 'z-index' : 1000000
273
- });
274
  // Set Iframe style.
275
- thickboxForm.find('iframe').css({
276
- width : '100%',
277
- height : '100%'
278
- });
279
  },
280
 
281
  /**
@@ -284,48 +284,48 @@ var CJTBlocksPage;
284
  *
285
  *
286
  */
287
- _onmanagebackups : function() {
288
  // Server request.
289
  var requestData = {
290
  // Thick box parameters.
291
- width : 480,
292
  height: 400,
293
- TB_iframe : true // Must be last one Thickbox removes this and later params.
294
- };
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.
305
- var doRestore = confirm(CJTBlocksPageI18N.confirmRestoreBlocks);
306
- if (doRestore) {
307
  // Disable restore button for all toolboxes.
308
- var ibCancelRestore = CJTBlocksPage.toolboxes.getIButton('cancel-restore', 'enable', [false]);
309
  // SHow loading for restore buttons.
310
- var ibRestoreLoader = CJTBlocksPage.toolboxes.getIButton('restore', 'loading', [true, false]);
311
  // Send request to server.
312
- var requestData = {backupId : CJTBlocksPage.isRestore()};
313
- CJTBlocksPage.server.send('blocksBackups', 'restore', requestData)
314
- .success(
315
- function() {
316
- // Refresh the page without backupId parameter.
317
- CJTBlocksPage._oncancelrestore();
318
- }
319
- )
320
- .error(
321
- function() {
322
- // Notify user error.
323
- alert(CJTBlocksPageI18N.unableToRestoreBackup);
324
- // Stop loading progress.
325
- ibCancelRestore.dispatch([true]);
326
- ibRestoreLoader.dispatch([false, true]);
327
- }
328
- );
329
  }
330
  },
331
 
@@ -335,24 +335,24 @@ var CJTBlocksPage;
335
  *
336
  *
337
  */
338
- _onsavechanges : function() {
339
- var multiOperationServer = CJTBlocksPage.server.multiOperation;
340
  var data = {
341
- deletedBlocks : CJTBlocksPage.deletedBlocks,
342
- calculatePinPoint : 1,
343
- createRevision : 1
344
- };
345
  // Save block data.
346
- multiOperationServer.trigger('save').send('post', data).success(
347
- function() {
348
  // Reset deleted blocks array.
349
- CJTBlocksPage.deletedBlocks = [];
350
- CJTBlocksPage.changes = [];
351
- CJTBlocksPage.toolboxes.enable('save-changes', false);
352
  // Save blocks order.
353
- CJTBlocksPage.saveBlocksOrder();
354
  // Save closed postboxes.
355
- postboxes.save_state(CJTBlocksPage.pageId);
356
  }
357
  )
358
  },
@@ -361,13 +361,13 @@ var CJTBlocksPage;
361
  * put your comment there...
362
  *
363
  */
364
- _onupdateorder : function() {
365
- var container = CJTBlocksPage.blocksContainer;
366
- var orders = container.data('cjtOrders');
367
- var newOrders = container.sortable('toArray');
368
- var isChanged = (orders.join('') != newOrders.join(''));
369
  // Notify changes!
370
- CJTBlocksPage.blockContentChanged(0, isChanged);
371
  },
372
 
373
  /**
@@ -377,16 +377,16 @@ var CJTBlocksPage;
377
  *
378
  *
379
  */
380
- _onunload : function() {
381
  // If there is any deleted blocks or any block changed
382
  // notify user that there is a change need to be saved;
383
- if (!CJTBlocksPage.deletedBlocks.length) {
384
  // If there is no changes in any block save-changed button shouild be disabled.
385
- if (!CJTBlocksPage.toolboxes.isEnabled('save-changes')) {
386
- return;
387
  }
388
  }
389
- return CJTBlocksPageI18N.confirmNotSavedChanges;
390
  },
391
 
392
  /**
@@ -394,44 +394,44 @@ var CJTBlocksPage;
394
  *
395
  *
396
  */
397
- addBlock : function(position, content) {
398
- var sortable = CJTBlocksPage.blocksContainer;
399
  // New Block positions to jQuery methods mapping.
400
- var positions = {top : 'prepend', bottom : 'append'};
401
- var positionMethod = positions[position];
402
  // Apply toggling: The only way to apply postboxes it via postboxes.add_postbox_toggles method.
403
  // Method finding all .postbox elements and bind to click.
404
  // Exists .postbox(s) will bind to click event twice and the result is
405
  // not toggling. We need to remove .postbox of exists and apply only
406
  // to the newly added one.
407
- var currentBlocks = CJTBlocksPage.blocks.getBlocks();
408
- currentBlocks.removeClass('postbox').addClass('applying-postbox-to-new-block');
409
  // Add block to the selected position.
410
- sortable[positionMethod](content);
411
  // Note: Only new block will be returned because its the only one with .postbox class.
412
- var newAddedBlock = CJTBlocksPage.blocks.getBlocks().eq(0);
413
  // Add block element.
414
- var blockId =newAddedBlock.CJTBlock({}).get(0).CJTBlock.block.get('id');
415
  // SET ORDER: Add the new block as first or last Block without saving the unsave orders! //
416
  // JUST USE THE CURRENT HASHED (SAVED ON SERVER) + ADDING THE NEW BLOCK!
417
- var newBlockOrderName = CJTBlocksPage.blocks.getSortableName(blockId);
418
- var order = $.merge([], sortable.data('cjtOrders'));
419
- (position == 'top') ? order.unshift(newBlockOrderName) : order.push(newBlockOrderName);
420
- CJTBlocksPage.saveCustomOrder(order);
421
  // If this is the first block hide the intro and show normal sortable.
422
- if (!CJTBlocksPage.blocks.hasBlocks()) {
423
  // Remove intro text.
424
- CJTBlocksPage.intro.css({display : 'none'});
425
- CJTBlocksPage.blocksContainer.css({display : 'block'});
426
  // Set has block value.
427
- CJTBlocksPage.blocks.hasBlocks(true);
428
  }
429
  // Refresh toggling.
430
- postboxes.add_postbox_toggles('cjtoolbox');
431
- currentBlocks.removeClass('applying-postbox-to-new-block').addClass('postbox');
432
  // Put new block into focus.
433
- newAddedBlock.get(0).CJTBlock.focus();
434
- return newAddedBlock;
435
  },
436
 
437
  /**
@@ -441,10 +441,10 @@ var CJTBlocksPage;
441
  *
442
  *
443
  */
444
- blockContentChanged : function(id, isChanged) {
445
- var enable = CJTBlocksPage.blocks.calculateChanges(CJTBlocksPage.changes, id, isChanged);
446
  // Enable/Disable save button in all Toolboxes.
447
- CJTBlocksPage.toolboxes.enable('save-changes', enable);
448
  },
449
 
450
  /**
@@ -452,28 +452,28 @@ var CJTBlocksPage;
452
  *
453
  *
454
  */
455
- deleteBlocks : function(blocks) {
456
  // Delete block.
457
- $.each(blocks,
458
- function(index, block) {
459
- var blockPlg = block.CJTBlock;
460
- var blockId = blockPlg.block.get('id');
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);
468
  }
469
- );
470
  // If last block call _ondeleteall.
471
- var existsBlocks = CJTBlocksPage.blocks.getBlocks();
472
- if (existsBlocks.length == 0) {
473
- CJTBlocksPage.blocksContainer.css('display', 'none');
474
- CJTBlocksPage.intro.css('display', 'block');
475
  // Mark as has no blocks.
476
- CJTBlocksPage.blocks.hasBlocks(false);
477
  }
478
  },
479
 
@@ -482,9 +482,9 @@ var CJTBlocksPage;
482
  *
483
  *
484
  */
485
- getStateName : function() {
486
- var stateName = this.isRestore() ? 'restore' : '';
487
- return stateName;
488
  },
489
 
490
  /*
@@ -492,86 +492,86 @@ var CJTBlocksPage;
492
  *
493
  *
494
  */
495
- init : function() {
496
  // Initialize object vars.
497
- CJTBlocksPage.blocksForm = $('#cjtoolbox-blocks-page-form');
498
  // Prevent form submission, ALL is done through AJAX.
499
  // Pressing Enter in text fields might caused the whole page to be refreshed.
500
- CJTBlocksPage.blocksForm.get(0).onsubmit = function() {return false;}
501
- CJTBlocksPage.blocksContainer = $('div#normal-sortables');
502
- CJTBlocksPage.intro = CJTBlocksPage.blocksForm.find('#cjt-noblocks-intro');
503
- CJTBlocksPage.server = CJTServer;
504
- CJTBlocksPage.server.multiOperation = new CJTBlocksAjaxMultiOperations('blocksPage', 'save_blocks');
505
  // Initilize Global-Blocks Conponents.
506
- CJTBlockCodeFileView.initialize();
507
  // Make sure CJTBlocks is ready.
508
- CJTBlocksPage.blocks = new CJTBlocks();
509
  // Initialize Toolboxes.
510
- CJTBlocksPage.toolboxes.toolboxes = CJTBlocksPage.blocksForm.find('.cjt-toolbox-blocks').CJTToolBox({
511
- handlers : {
512
- 'state-tools' : {
513
- type : 'Popup',
514
- params : {_type : {targetElement : '.state-tools'}}
515
  },
516
- 'location-tools' : {
517
- type : 'Popup',
518
- params : {_type : {targetElement : '.location-tools'}}
519
  },
520
- 'admin-tools' : {
521
- type : 'Popup',
522
- params : {_type : {targetElement : '.admin-tools'}}
523
  },
524
- 'save-changes' : {callback : CJTBlocksPage._onsavechanges, params : {enable : false}},
525
- 'add-block' : {callback : CJTBlocksPage._onaddnew},
526
- 'restore' : {callback : CJTBlocksPage._onrestore},
527
- 'cancel-restore' : {callback : CJTBlocksPage._oncancelrestore},
528
- 'reset-order' : {callback : CJTBlocksPage._onresetorder},
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();
547
- CJTBlocksPage.loadingImage.css({
548
- display : 'none',
549
- position : 'absolute'
550
- });
551
  // If has no blocks hide normal sortable (it takes 50px as min-height).
552
- if (!CJTBlocksPage.blocks.hasBlocks()) {
553
- CJTBlocksPage.blocksContainer.css({display : 'none'});
554
  }
555
  // Show blocks.
556
- CJTBlocksPage.blocksForm.find('#post-body').css('display', 'block');
557
  //// Setup postboxes ////
558
- postboxes.add_postbox_toggles('cjtoolbox');
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;
566
- postboxes.save_order = function() {};
567
  // Notify block when postbox get opened.
568
- postboxes.pbshow = function(id) {
569
- $('#' + id).get(0).CJTBlock._onpostboxopened();
570
- };
571
  // When navigating away notify saving changes.
572
- window.onbeforeunload = CJTBlocksPage._onunload;
573
  // Switch blocks page state.
574
- CJTBlocksPage.switchState(CJTBlocksPage.getStateName());
575
  },
576
 
577
  /*
@@ -579,14 +579,14 @@ var CJTBlocksPage;
579
  *
580
  *
581
  */
582
- isRestore : function() {
583
  // If there is backupId parameter then this is a restore state.
584
- var regEx = /backupId=(\d+)/;
585
- var backupId = false;
586
- if (regEx.test(window.location.href)) {
587
- backupId = parseInt(window.location.href.match(regEx)[1]);
588
  }
589
- return backupId;
590
  },
591
 
592
  /*
@@ -594,56 +594,56 @@ var CJTBlocksPage;
594
  *
595
  *
596
  */
597
- main : function() {
598
  // Add indexOf function for IE7.
599
- if (Array.indexOf == undefined) {
600
- Array.prototype.indexOf = function(value) {
601
- var index = -1;
602
- var array = this;
603
- jQuery.each(array, function(sIndex, sValue) {
604
- if (sValue == value) {
605
- index = sIndex;
606
- return;
607
  }
608
- });
609
- return index;
610
  }
611
  }
612
- if (String.ucFirst == undefined) {
613
- String.prototype.ucFirst = function() {
614
- var newString = [];
615
- var words = this.split(' ');
616
- $(words).each(
617
- function(index, word) {
618
- newString.push(word.substr(0, 1).toUpperCase() + word.substr(1));
619
  }
620
  )
621
- newString = newString.join(' ');
622
- return newString;
623
  }
624
  }
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!!
634
  // We need to handle toArray method when called by postboxes.save_order method!
635
- var originalSortable = $.fn.sortable;
636
- $.fn.sortable = function(method) {
637
- if (method != 'toArray') {
638
- throw 'Dummy CJT::jquery.sortable Plugin: only toArray method is supported!';
639
- }
640
- // Return the passed order instead of the real order!
641
- return order;
642
- }
643
- // Save order.
644
- CJTBlocksPage.saveBlocksOrder();
645
- // Reset original sortable!
646
- $.fn.sortable = originalSortable;
647
  },
648
 
649
  /**
@@ -653,16 +653,16 @@ var CJTBlocksPage;
653
  *
654
  *
655
  */
656
- saveBlocksOrder : function() {
657
- var ordersArray = CJTBlocksPage.blocksContainer.sortable('toArray');
658
- var request = {order : ordersArray.join(',')};
659
  // Save Blocks order!
660
- CJTBlocksPage.server.send('blocksPage', 'saveOrder', request).success($.proxy(
661
- function() {
662
  // Refresh local cache order!
663
- CJTBlocksPage.blocksContainer.data('cjtOrders', ordersArray);
664
- }, this)
665
- );
666
  },
667
 
668
  /*
@@ -670,14 +670,14 @@ var CJTBlocksPage;
670
  *
671
  *
672
  */
673
- switchState : function(state) {
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.
2
  *
3
  */
4
  var CJTToolBox = {
5
+ forms: { templatesLookupForm: [] }
6
+ } // Application name spaces structure.
7
 
8
  /*
9
  *
15
  *
16
  *
17
  */
18
+ ( function ( $ ) {
19
 
20
  /*
21
  *
28
  *
29
  *
30
  */
31
+ blocksContainer: null,
32
 
33
  /*
34
  *
35
  *
36
  *
37
  */
38
+ blocksForm: null,
39
 
40
  /*
41
  *
42
  *
43
  *
44
  */
45
+ blocks: null,
46
 
47
  /**
48
  *
51
  *
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
  /**
78
  *
79
  *
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
  *
108
  *
109
  */
110
+ css: function ( role, value ) {
111
  this.toolboxes.each(
112
+ function () {
113
+ $( this ).css( role, value )
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 = {}
130
  CJTBlocksPage.toolboxes.toolboxes.each(
131
+ function ( index ) {
132
  // Get button object.
133
+ var button = this.CJTToolBox.buttons[ buttonName ]
134
  // Dispatch button method.
135
+ result[ index ] = button[ method ].apply( button, params )
136
  }
137
+ )
138
+ return result
139
  }
140
+ }
141
  // When created and params is passed vall dispatch.
142
+ if ( params != undefined ) {
143
+ dispatcher.dispatch( params )
144
  }
145
  // Return dispatched handle object.
146
+ return dispatcher
147
  },
148
 
149
  /**
151
  *
152
  *
153
  */
154
+ enable: function ( buttonName, enable ) {
155
  this.toolboxes.each(
156
+ function () {
157
+ var button = this.CJTToolBox.buttons[ buttonName ]
158
+ button.enable( enable )
159
  }
160
+ )
161
  },
162
 
163
  /**
165
  *
166
  *
167
  */
168
+ isEnabled: function ( buttonName ) {
169
+ var isEnabled = true
170
  this.toolboxes.each(
171
+ function () {
172
+ var button = this.CJTToolBox.buttons[ buttonName ]
173
+ isEnabled &= button.isEnabled()
174
  }
175
+ )
176
+ return isEnabled
177
  },
178
 
179
  /*
181
  *
182
  *
183
  */
184
+ switchState: function ( state ) {
185
+ var buttonsToHide
186
+ switch ( state ) {
187
  case 'restore':
188
  // Hide Add New Block, Save all changes, location tools and state tools buttons.
189
+ buttonsToHide = [ 'save-changes', 'add-block', 'state-tools', 'location-tools' ]
190
+ break
191
  default:
192
+ // Hide Restore & Cancel Restore buttons.
193
+ buttonsToHide = [ 'restore', 'cancel-restore' ]
194
+ break
195
  }
196
  // Hide buttons.
197
  this.toolboxes.each(
198
  // Get all toolboxes.
199
+ function ( tbIndex, toolbox ) {
200
  // Hide all buttons for each toolbox.
201
+ $.each( buttonsToHide,
202
+ function ( btnIndex, buttonName ) {
203
+ var button = toolbox.CJTToolBox.buttons[ buttonName ]
204
+ button.jButton.css( 'display', 'none' )
205
  }
206
+ )
207
  }
208
+ )
209
  // Display Toolboxes.
210
+ this.css( 'visibility', 'visible' )
211
  }
212
  },
213
 
216
  *
217
  *
218
  */
219
+ _onaddnew: function ( event, params ) {
220
  // Server request.
221
  var requestData = {
222
  // Server paramerers.
223
+ viewName: 'blocks/new',
224
  // Thick box parameters.
225
+ width: 450,
226
  height: 230,
227
+ position: params.toolbox.position,
228
+ TB_iframe: true // Must be last one Thickbox removes this and later params.
229
+ }
230
+ var url = CJTBlocksPage.server.getRequestURL( 'blocksPage', 'get_view', requestData )
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 }
259
+ var url = CJTBlocksPage.server.getRequestURL( 'templatesManager', 'display', params )
260
+ tb_show( CJTBlocksPageI18N.manageTemplatesFormTitle, url )
261
  // Get thickbox form element.
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%',
271
+ 'height': ( ( jQuery( window ).height() - 40 ) + 'px' ),
272
+ 'z-index': 1000000
273
+ } )
274
  // Set Iframe style.
275
+ thickboxForm.find( 'iframe' ).css( {
276
+ width: '100%',
277
+ height: '100%'
278
+ } )
279
  },
280
 
281
  /**
284
  *
285
  *
286
  */
287
+ _onmanagebackups: function () {
288
  // Server request.
289
  var requestData = {
290
  // Thick box parameters.
291
+ width: 480,
292
  height: 400,
293
+ TB_iframe: true // Must be last one Thickbox removes this and later params.
294
+ }
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.
305
+ var doRestore = confirm( CJTBlocksPageI18N.confirmRestoreBlocks )
306
+ if ( doRestore ) {
307
  // Disable restore button for all toolboxes.
308
+ var ibCancelRestore = CJTBlocksPage.toolboxes.getIButton( 'cancel-restore', 'enable', [ false ] )
309
  // SHow loading for restore buttons.
310
+ var ibRestoreLoader = CJTBlocksPage.toolboxes.getIButton( 'restore', 'loading', [ true, false ] )
311
  // Send request to server.
312
+ var requestData = { backupId: CJTBlocksPage.isRestore() }
313
+ CJTBlocksPage.server.send( 'blocksBackups', 'restore', requestData )
314
+ .success(
315
+ function () {
316
+ // Refresh the page without backupId parameter.
317
+ CJTBlocksPage._oncancelrestore()
318
+ }
319
+ )
320
+ .error(
321
+ function () {
322
+ // Notify user error.
323
+ alert( CJTBlocksPageI18N.unableToRestoreBackup )
324
+ // Stop loading progress.
325
+ ibCancelRestore.dispatch( [ true ] )
326
+ ibRestoreLoader.dispatch( [ false, true ] )
327
+ }
328
+ )
329
  }
330
  },
331
 
335
  *
336
  *
337
  */
338
+ _onsavechanges: function () {
339
+ var multiOperationServer = CJTBlocksPage.server.multiOperation
340
  var data = {
341
+ deletedBlocks: CJTBlocksPage.deletedBlocks,
342
+ calculatePinPoint: 1,
343
+ createRevision: 1
344
+ }
345
  // Save block data.
346
+ multiOperationServer.trigger( 'save' ).send( 'post', data ).success(
347
+ function () {
348
  // Reset deleted blocks array.
349
+ CJTBlocksPage.deletedBlocks = []
350
+ CJTBlocksPage.changes = []
351
+ CJTBlocksPage.toolboxes.enable( 'save-changes', false )
352
  // Save blocks order.
353
+ CJTBlocksPage.saveBlocksOrder()
354
  // Save closed postboxes.
355
+ postboxes.save_state( CJTBlocksPage.pageId )
356
  }
357
  )
358
  },
361
  * put your comment there...
362
  *
363
  */
364
+ _onupdateorder: function () {
365
+ var container = CJTBlocksPage.blocksContainer
366
+ var orders = container.data( 'cjtOrders' )
367
+ var newOrders = container.sortable( 'toArray' )
368
+ var isChanged = ( orders.join( '' ) != newOrders.join( '' ) )
369
  // Notify changes!
370
+ CJTBlocksPage.blockContentChanged( 0, isChanged )
371
  },
372
 
373
  /**
377
  *
378
  *
379
  */
380
+ _onunload: function () {
381
  // If there is any deleted blocks or any block changed
382
  // notify user that there is a change need to be saved;
383
+ if ( !CJTBlocksPage.deletedBlocks.length ) {
384
  // If there is no changes in any block save-changed button shouild be disabled.
385
+ if ( !CJTBlocksPage.toolboxes.isEnabled( 'save-changes' ) ) {
386
+ return
387
  }
388
  }
389
+ return CJTBlocksPageI18N.confirmNotSavedChanges
390
  },
391
 
392
  /**
394
  *
395
  *
396
  */
397
+ addBlock: function ( position, content ) {
398
+ var sortable = CJTBlocksPage.blocksContainer
399
  // New Block positions to jQuery methods mapping.
400
+ var positions = { top: 'prepend', bottom: 'append' }
401
+ var positionMethod = positions[ position ]
402
  // Apply toggling: The only way to apply postboxes it via postboxes.add_postbox_toggles method.
403
  // Method finding all .postbox elements and bind to click.
404
  // Exists .postbox(s) will bind to click event twice and the result is
405
  // not toggling. We need to remove .postbox of exists and apply only
406
  // to the newly added one.
407
+ var currentBlocks = CJTBlocksPage.blocks.getBlocks()
408
+ currentBlocks.removeClass( 'postbox' ).addClass( 'applying-postbox-to-new-block' )
409
  // Add block to the selected position.
410
+ sortable[ positionMethod ]( content )
411
  // Note: Only new block will be returned because its the only one with .postbox class.
412
+ var newAddedBlock = CJTBlocksPage.blocks.getBlocks().eq( 0 )
413
  // Add block element.
414
+ var blockId = newAddedBlock.CJTBlock( {} ).get( 0 ).CJTBlock.block.get( 'id' )
415
  // SET ORDER: Add the new block as first or last Block without saving the unsave orders! //
416
  // JUST USE THE CURRENT HASHED (SAVED ON SERVER) + ADDING THE NEW BLOCK!
417
+ var newBlockOrderName = CJTBlocksPage.blocks.getSortableName( blockId )
418
+ var order = $.merge( [], sortable.data( 'cjtOrders' ) );
419
+ ( position == 'top' ) ? order.unshift( newBlockOrderName ) : order.push( newBlockOrderName )
420
+ CJTBlocksPage.saveCustomOrder( order )
421
  // If this is the first block hide the intro and show normal sortable.
422
+ if ( !CJTBlocksPage.blocks.hasBlocks() ) {
423
  // Remove intro text.
424
+ CJTBlocksPage.intro.css( { display: 'none' } )
425
+ CJTBlocksPage.blocksContainer.css( { display: 'block' } )
426
  // Set has block value.
427
+ CJTBlocksPage.blocks.hasBlocks( true )
428
  }
429
  // Refresh toggling.
430
+ postboxes.add_postbox_toggles( 'cjtoolbox' )
431
+ currentBlocks.removeClass( 'applying-postbox-to-new-block' ).addClass( 'postbox' )
432
  // Put new block into focus.
433
+ newAddedBlock.get( 0 ).CJTBlock.focus()
434
+ return newAddedBlock
435
  },
436
 
437
  /**
441
  *
442
  *
443
  */
444
+ blockContentChanged: function ( id, isChanged ) {
445
+ var enable = CJTBlocksPage.blocks.calculateChanges( CJTBlocksPage.changes, id, isChanged )
446
  // Enable/Disable save button in all Toolboxes.
447
+ CJTBlocksPage.toolboxes.enable( 'save-changes', enable )
448
  },
449
 
450
  /**
452
  *
453
  *
454
  */
455
+ deleteBlocks: function ( blocks ) {
456
  // Delete block.
457
+ $.each( blocks,
458
+ function ( index, block ) {
459
+ var blockPlg = block.CJTBlock
460
+ var blockId = blockPlg.block.get( 'id' )
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 )
468
  }
469
+ )
470
  // If last block call _ondeleteall.
471
+ var existsBlocks = CJTBlocksPage.blocks.getBlocks()
472
+ if ( existsBlocks.length == 0 ) {
473
+ CJTBlocksPage.blocksContainer.css( 'display', 'none' )
474
+ CJTBlocksPage.intro.css( 'display', 'block' )
475
  // Mark as has no blocks.
476
+ CJTBlocksPage.blocks.hasBlocks( false )
477
  }
478
  },
479
 
482
  *
483
  *
484
  */
485
+ getStateName: function () {
486
+ var stateName = this.isRestore() ? 'restore' : ''
487
+ return stateName
488
  },
489
 
490
  /*
492
  *
493
  *
494
  */
495
+ init: function () {
496
  // Initialize object vars.
497
+ CJTBlocksPage.blocksForm = $( '#cjtoolbox-blocks-page-form' )
498
  // Prevent form submission, ALL is done through AJAX.
499
  // Pressing Enter in text fields might caused the whole page to be refreshed.
500
+ CJTBlocksPage.blocksForm.get( 0 ).onsubmit = function () { return false }
501
+ CJTBlocksPage.blocksContainer = $( 'div#normal-sortables' )
502
+ CJTBlocksPage.intro = CJTBlocksPage.blocksForm.find( '#cjt-noblocks-intro' )
503
+ CJTBlocksPage.server = CJTServer
504
+ CJTBlocksPage.server.multiOperation = new CJTBlocksAjaxMultiOperations( 'blocksPage', 'save_blocks' )
505
  // Initilize Global-Blocks Conponents.
506
+ CJTBlockCodeFileView.initialize()
507
  // Make sure CJTBlocks is ready.
508
+ CJTBlocksPage.blocks = new CJTBlocks()
509
  // Initialize Toolboxes.
510
+ CJTBlocksPage.toolboxes.toolboxes = CJTBlocksPage.blocksForm.find( '.cjt-toolbox-blocks' ).CJTToolBox( {
511
+ handlers: {
512
+ 'state-tools': {
513
+ type: 'Popup',
514
+ params: { _type: { targetElement: '.state-tools' } }
515
  },
516
+ 'location-tools': {
517
+ type: 'Popup',
518
+ params: { _type: { targetElement: '.location-tools' } }
519
  },
520
+ 'admin-tools': {
521
+ type: 'Popup',
522
+ params: { _type: { targetElement: '.admin-tools' } }
523
  },
524
+ 'save-changes': { callback: CJTBlocksPage._onsavechanges, params: { enable: false } },
525
+ 'add-block': { callback: CJTBlocksPage._onaddnew },
526
+ 'restore': { callback: CJTBlocksPage._onrestore },
527
+ 'cancel-restore': { callback: CJTBlocksPage._oncancelrestore },
528
+ 'reset-order': { callback: CJTBlocksPage._onresetorder },
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()
547
+ CJTBlocksPage.loadingImage.css( {
548
+ display: 'none',
549
+ position: 'absolute'
550
+ } )
551
  // If has no blocks hide normal sortable (it takes 50px as min-height).
552
+ if ( !CJTBlocksPage.blocks.hasBlocks() ) {
553
+ CJTBlocksPage.blocksContainer.css( { display: 'none' } )
554
  }
555
  // Show blocks.
556
+ CJTBlocksPage.blocksForm.find( '#post-body' ).css( 'display', 'block' )
557
  //// Setup postboxes ////
558
+ postboxes.add_postbox_toggles( 'cjtoolbox' )
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
566
+ postboxes.save_order = function () { }
567
  // Notify block when postbox get opened.
568
+ postboxes.pbshow = function ( id ) {
569
+ $( '#' + id ).get( 0 ).CJTBlock._onpostboxopened()
570
+ }
571
  // When navigating away notify saving changes.
572
+ window.onbeforeunload = CJTBlocksPage._onunload
573
  // Switch blocks page state.
574
+ CJTBlocksPage.switchState( CJTBlocksPage.getStateName() )
575
  },
576
 
577
  /*
579
  *
580
  *
581
  */
582
+ isRestore: function () {
583
  // If there is backupId parameter then this is a restore state.
584
+ var regEx = /backupId=(\d+)/
585
+ var backupId = false
586
+ if ( regEx.test( window.location.href ) ) {
587
+ backupId = parseInt( window.location.href.match( regEx )[ 1 ] )
588
  }
589
+ return backupId
590
  },
591
 
592
  /*
594
  *
595
  *
596
  */
597
+ main: function () {
598
  // Add indexOf function for IE7.
599
+ if ( Array.indexOf == undefined ) {
600
+ Array.prototype.indexOf = function ( value ) {
601
+ var index = -1
602
+ var array = this
603
+ jQuery.each( array, function ( sIndex, sValue ) {
604
+ if ( sValue == value ) {
605
+ index = sIndex
606
+ return
607
  }
608
+ } )
609
+ return index
610
  }
611
  }
612
+ if ( String.ucFirst == undefined ) {
613
+ String.prototype.ucFirst = function () {
614
+ var newString = []
615
+ var words = this.split( ' ' )
616
+ $( words ).each(
617
+ function ( index, word ) {
618
+ newString.push( word.substr( 0, 1 ).toUpperCase() + word.substr( 1 ) )
619
  }
620
  )
621
+ newString = newString.join( ' ' )
622
+ return newString
623
  }
624
  }
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!!
634
  // We need to handle toArray method when called by postboxes.save_order method!
635
+ var originalSortable = $.fn.sortable
636
+ $.fn.sortable = function ( method ) {
637
+ if ( method != 'toArray' ) {
638
+ throw 'Dummy CJT::jquery.sortable Plugin: only toArray method is supported!'
639
+ }
640
+ // Return the passed order instead of the real order!
641
+ return order
642
+ }
643
+ // Save order.
644
+ CJTBlocksPage.saveBlocksOrder()
645
+ // Reset original sortable!
646
+ $.fn.sortable = originalSortable
647
  },
648
 
649
  /**
653
  *
654
  *
655
  */
656
+ saveBlocksOrder: function () {
657
+ var ordersArray = CJTBlocksPage.blocksContainer.sortable( 'toArray' )
658
+ var request = { order: ordersArray.join( ',' ) }
659
  // Save Blocks order!
660
+ CJTBlocksPage.server.send( 'blocksPage', 'saveOrder', request ).success( $.proxy(
661
+ function () {
662
  // Refresh local cache order!
663
+ CJTBlocksPage.blocksContainer.data( 'cjtOrders', ordersArray )
664
+ }, this )
665
+ )
666
  },
667
 
668
  /*
670
  *
671
  *
672
  */
673
+ switchState: function ( state ) {
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/new/public/js/add-new-block/add-new-block.js CHANGED
@@ -9,14 +9,14 @@
9
  *
10
  *
11
  */
12
- (function($) {
13
 
14
  /**
15
  * CJTBlocksPage object Reference.
16
  *
17
  * @var CJTBlocksPage
18
  */
19
- CJTBlocksPage = window.parent.CJTBlocksPage;
20
 
21
  /**
22
  * Server New Block view actions/events.
@@ -33,22 +33,22 @@
33
  * put your comment there...
34
  *
35
  */
36
- errors : null,
37
 
38
  /**
39
  * New Block form element.
40
  *
41
  * @var jqObject
42
  */
43
- form : null,
44
 
45
  /**
46
  * Event handler for closing the form.
47
  *
48
  * return void
49
  */
50
- _oncancel : function() {
51
- window.parent.tb_remove();
52
  },
53
 
54
  /**
@@ -62,38 +62,38 @@
62
  *
63
  * return void
64
  */
65
- _onsave : function(event) {
66
- event.preventDefault();
67
- this.isValid().done($.proxy(
68
- function() {
69
  // Append form data to it.
70
- var formData = this.form.serializeObject();
71
  // Request parameters.
72
- var requestParams = $.extend({ids : CJTBlocksPage.blocks.getExistsIds(), viewName : 'cjt-block'}, formData);
73
  // Disable new form.
74
- this.form.find('input, select').prop('disabled', true);
75
  // Create block at the server.
76
- CJTBlocksPage.server.send('blocksPage', 'create_block', requestParams, 'get')
77
- .success($.proxy(
78
- function(response) {
79
- // Add new block to blocks page.
80
- newAddedBlock = CJTBlocksPage.addBlock(formData.position, response.view)
81
- // Close window.
82
- window.parent.tb_remove();
83
- }, this)
84
- // Request COMPLETE!
85
- ).complete($.proxy(
86
- function() {
87
- // Enable new form.
88
- this.form.find('input, select').prop('disabled', false);
89
- }, this)
90
- );
91
- }, this)
92
- ).fail($.proxy(
93
- function() {
94
- this.errors.show('width=380&height=170');
95
- }, this)
96
- );
97
  },
98
 
99
  /**
@@ -101,17 +101,17 @@
101
  *
102
  * return void
103
  */
104
- init : function() {
105
- this.form = $('form#cjtoolbox_new_block_form');
106
- this.errors = new CJTSimpleErrorDialog(this.form)
107
- .add('name', /^[A-Za-z0-9\!\#\@\$\&\*\(\)\[\]\x20\-\_\+\?\:\;\.]{1,50}$/, CJTAddNewBlockI18N.invalidName);
108
  // Actions handled by this object.
109
- var events = {'.save' : this._onsave, '.cancel' : this._oncancel};
110
- $.each(events, $.proxy(
111
- function(selector, handler) {
112
- this.form.find(selector).click($.proxy(handler, this));
113
- }, this)
114
- );
115
  },
116
 
117
  /**
@@ -119,44 +119,44 @@
119
  *
120
  * @returns boolean
121
  */
122
- isValid : function() {
123
- var promising = $.Deferred();
124
  // Client side validation
125
- if (!this.errors.validate().hasError()) {
126
  // Make sure that the Block name is not taked by antoher Block!
127
  var request = {
128
- returns : ['id'],
129
- filter : {field : 'name', value : this.form.prop('name').value}
130
- };
131
- CJTBlocksPage.server.send('block', 'getBlockBy', request)
132
- .success($.proxy(
133
- function(response) {
134
- // FAIL -- Name is being used by antoher Block!!!
135
- if (response.id) {
136
- var error = {
137
- name : this.errors.fetchFieldInfo('name').text,
138
- message: CJTAddNewBlockI18N.AlreadyInUse
139
- };
140
- this.errors.errors.push(error);
141
- promising.reject();
142
- }
143
- else {
144
- // Successed -- Name is not taken yet!
145
- promising.resolve();
146
- }
147
- }, this)
148
- );
149
  }
150
  else {
151
  // Client side validatiom faild!
152
- promising.reject();
153
  }
154
- return promising;
155
  }
156
 
157
  } // End class.
158
 
159
  // Bind when documet ready.
160
- $($.proxy(CJTNewBlock.init, CJTNewBlock));
161
 
162
- })(jQuery);
9
  *
10
  *
11
  */
12
+ ( function ( $ ) {
13
 
14
  /**
15
  * CJTBlocksPage object Reference.
16
  *
17
  * @var CJTBlocksPage
18
  */
19
+ CJTBlocksPage = window.parent.CJTBlocksPage
20
 
21
  /**
22
  * Server New Block view actions/events.
33
  * put your comment there...
34
  *
35
  */
36
+ errors: null,
37
 
38
  /**
39
  * New Block form element.
40
  *
41
  * @var jqObject
42
  */
43
+ form: null,
44
 
45
  /**
46
  * Event handler for closing the form.
47
  *
48
  * return void
49
  */
50
+ _oncancel: function () {
51
+ window.parent.tb_remove()
52
  },
53
 
54
  /**
62
  *
63
  * return void
64
  */
65
+ _onsave: function ( event ) {
66
+ event.preventDefault()
67
+ this.isValid().done( $.proxy(
68
+ function () {
69
  // Append form data to it.
70
+ var formData = this.form.serializeObject()
71
  // Request parameters.
72
+ var requestParams = $.extend( { ids: CJTBlocksPage.blocks.getExistsIds(), viewName: 'cjt-block' }, formData )
73
  // Disable new form.
74
+ this.form.find( 'input, select' ).prop( 'disabled', true )
75
  // Create block at the server.
76
+ CJTBlocksPage.server.send( 'blocksPage', 'create_block', requestParams, 'get' )
77
+ .success( $.proxy(
78
+ function ( response ) {
79
+ // Add new block to blocks page.
80
+ newAddedBlock = CJTBlocksPage.addBlock( formData.position, response.view )
81
+ // Close window.
82
+ window.parent.tb_remove()
83
+ }, this )
84
+ // Request COMPLETE!
85
+ ).complete( $.proxy(
86
+ function () {
87
+ // Enable new form.
88
+ this.form.find( 'input, select' ).prop( 'disabled', false )
89
+ }, this )
90
+ )
91
+ }, this )
92
+ ).fail( $.proxy(
93
+ function () {
94
+ this.errors.show( 'width=380&height=170' )
95
+ }, this )
96
+ )
97
  },
98
 
99
  /**
101
  *
102
  * return void
103
  */
104
+ init: function () {
105
+ this.form = $( 'form#cjtoolbox_new_block_form' )
106
+ this.errors = new CJTSimpleErrorDialog( this.form )
107
+ .add( 'name', /^[A-Za-z0-9\!\#\@\$\&\*\(\)\[\]\x20\-\_\+\?\:\;\.]{1,50}$/, CJTAddNewBlockI18N.invalidName )
108
  // Actions handled by this object.
109
+ var events = { '.save': this._onsave, '.cancel': this._oncancel }
110
+ $.each( events, $.proxy(
111
+ function ( selector, handler ) {
112
+ this.form.find( selector ).click( $.proxy( handler, this ) )
113
+ }, this )
114
+ )
115
  },
116
 
117
  /**
119
  *
120
  * @returns boolean
121
  */
122
+ isValid: function () {
123
+ var promising = $.Deferred()
124
  // Client side validation
125
+ if ( !this.errors.validate().hasError() ) {
126
  // Make sure that the Block name is not taked by antoher Block!
127
  var request = {
128
+ returns: [ 'id' ],
129
+ filter: { field: 'name', value: this.form.prop( 'name' ).value }
130
+ }
131
+ CJTBlocksPage.server.send( 'block', 'getBlockBy', request )
132
+ .success( $.proxy(
133
+ function ( response ) {
134
+ // FAIL -- Name is being used by antoher Block!!!
135
+ if ( response.id ) {
136
+ var error = {
137
+ name: this.errors.fetchFieldInfo( 'name' ).text,
138
+ message: CJTAddNewBlockI18N.AlreadyInUse
139
+ }
140
+ this.errors.errors.push( error )
141
+ promising.reject()
142
+ }
143
+ else {
144
+ // Successed -- Name is not taken yet!
145
+ promising.resolve()
146
+ }
147
+ }, this )
148
+ )
149
  }
150
  else {
151
  // Client side validatiom faild!
152
+ promising.reject()
153
  }
154
+ return promising
155
  }
156
 
157
  } // End class.
158
 
159
  // Bind when documet ready.
160
+ $( $.proxy( CJTNewBlock.init, CJTNewBlock ) )
161
 
162
+ } )( jQuery )