PluginProbe ʕ •ᴥ•ʔ
Code Manager / 1.0.39
Code Manager v1.0.39
1.0.47 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.2 1.0.20 1.0.21 1.0.22 1.0.23 1.0.24 1.0.25 1.0.26 1.0.27 1.0.28 1.0.3 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 1.0.39 1.0.4 1.0.40 1.0.41 1.0.42 1.0.43 1.0.44 1.0.45 1.0.46 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9
code-manager / assets / js / code_manager_tabmode.js
code-manager / assets / js Last commit date
code_manager.js 1 year ago code_manager_dashboard.js 1 year ago code_manager_listmode.js 1 year ago code_manager_message.js 1 year ago code_manager_tabmode.js 1 year ago notify.min.js 1 year ago
code_manager_tabmode.js
895 lines
1 /**
2 * JavaScript code to build Code Manager IDE in tab mode
3 *
4 * @author Peter Schulz
5 * @since 1.0.0
6 */
7
8 const PHP_DEFAULT = '<?php\n\n?>';
9
10 var user_has_edited = {};
11
12 var current_url = window.location.href.split('?');
13 var default_url = current_url[0] + '?page=code_manager';
14
15 var href = window.location.href;
16 var pathname = href.substring(0, href.lastIndexOf('/')) + '/admin-ajax.php';
17
18 var tabs = 0;
19 var cm_editors = {};
20 var new_label_index = 0;
21
22 function option_in_code_list(option_value) {
23 found = false;
24 jQuery('#code_manager_code_list option').each(function() {
25 if (this.value === option_value) {
26 found = true;
27 return true;
28 }
29 });
30 return found;
31 }
32
33 function get_code_list(callback) {
34 jQuery.ajax({
35 method: 'POST',
36 url: pathname + '?action=code_manager_get_code_list',
37 data: {
38 wpnonce: wpnonce,
39 page: 'code_manager_post'
40 }
41 }).done(
42 function(msg) {
43 try {
44 obj = JSON.parse(msg);
45
46 if (Array.isArray(obj)) {
47 jQuery('#code_manager_code_list').empty();
48 maxLength = 0;
49 codeTypes = {};
50 // Determine max length
51 for (var key in obj) {
52 if (obj[key].code_name.length>maxLength) {
53 maxLength = obj[key].code_name.length;
54 }
55 }
56 // Add option - use monospace to right align code types
57 for (var key in obj) {
58 if (!is_code_edited(obj[key].code_id)) {
59 jQuery('#code_manager_code_list')
60 .append(
61 jQuery('<option>', {value: obj[key].code_id})
62 .html(obj[key].code_name + "&nbsp;".repeat( maxLength - obj[key].code_name.length) + "&nbsp;&nbsp;&minus;&nbsp;&nbsp;" + obj[key].code_type)
63 .attr('data-name', obj[key].code_name)
64 .attr('data-type', obj[key].code_type)
65 .attr('data-enabled', obj[key].code_enabled)
66 .attr('data-preview', obj[key].preview_enabled)
67 );
68 codeTypes[obj[key].code_type] = true;
69 }
70 }
71 // Update filters
72 jQuery("#code_manager_filter_code_type").empty();
73 jQuery("#code_manager_filter_code_type")
74 .append(
75 jQuery("<option>", {value: ""})
76 .html("Filter code type")
77 );
78
79 var code_types = "";
80 for (var code_group in code_manager_code_groups) {
81 code_types += '<optgroup label="' + code_group + '">';
82 code_manager_code_group = code_manager_code_groups[code_group];
83 for (var label in code_manager_code_group ) {
84 code_types +=
85 '<option class="hide" value="' + label + '">' +
86 code_manager_code_group[label] +
87 '</option>';
88 }
89 code_types += '</optgroup>';
90 }
91 jQuery("#code_manager_filter_code_type").append(code_types);
92 Object.keys(codeTypes).sort().forEach(function(codeType, index) {
93 jQuery("#code_manager_filter_code_type option[value='" + codeType + "']").removeClass("hide");
94 });
95 jQuery("#code_manager_filter_code_type option.hide").remove();
96 jQuery(jQuery("#code_manager_filter_code_type optgroup").each(function(index) {
97 if (jQuery(jQuery("#code_manager_filter_code_type optgroup")[index]).children().length===0) {
98 jQuery(jQuery("#code_manager_filter_code_type optgroup")[index]).remove();
99 }
100 }));
101
102 callback();
103 }
104 }
105 catch (e) {
106 if (msg.substr(0, 3) === 'ERR') {
107 jQuery.notify(msg, "error");
108 } else {
109 jQuery.notify(e, "error");
110 }
111 }
112 }
113 );
114 }
115
116 function is_code_edited(code_id) {
117 for (var editor in cm_editors) {
118 if (cm_editors[editor].tab_code_index==code_id) {
119 return true;
120 }
121 }
122 return false;
123 }
124
125 function get_code(code_id, code_name, code_type, code_enabled, preview_enabled) {
126 jQuery.ajax({
127 method: 'POST',
128 url: pathname + '?action=code_manager_get_code',
129 data: {
130 wpnonce: wpnonce_get_code,
131 code_id: code_id,
132 page: 'code_manager_post'
133 }
134 }).done(
135 function(msg) {
136 if (msg==='ERR-Not authorized') {
137 jQuery.notify('Not authorized', 'error');
138 } else if (msg==='ERR-Wrong arguments') {
139 jQuery.notify('Wrong arguments', 'error');
140 } else {
141 tab_load(code_id, code_name, code_type, msg, code_enabled, preview_enabled);
142 }
143 }
144 );
145 }
146
147 function set_copy_shortcode_link(tab) {
148 if (cm_editors[tab].tab_code_index!==-1 && jQuery("#tab-" + tab + "-code_type").val().includes("shortcode")) {
149 code_name = jQuery("#tab-" + tab + "-label").text();
150 jQuery("#tab-" + tab + "-shortcode_link").html(`
151 <a href="javascript:void(0)" class="dashicons dashicons-image-rotate" onclick="jQuery('#cm_copy_id${tab}').toggle(); jQuery('#cm_copy_name${tab}').toggle();" style="vertical-align:middle"></a>
152 <span id="cm_copy_id${tab}" style="display:none">
153 [cmruncode id="${cm_editors[tab].tab_code_index}"]
154 <a href="javascript:void(0)" class="dashicons dashicons-clipboard c2c"
155 onclick="jQuery.notify(&quot;Shortcode copied to clipboard&quot;, &quot;info&quot;)"
156 data-clipboard-text="[cmruncode id=&quot;${cm_editors[tab].tab_code_index}&quot;]"
157 title="Copy shortcode to clipboard" style="vertical-align:middle"
158 ></a>
159 </span>
160 <span id="cm_copy_name${tab}">
161 [cmruncode name="${code_name}"]
162 <a href="javascript:void(0)" class="dashicons dashicons-clipboard c2c"
163 onclick="jQuery.notify(&quot;Shortcode copied to clipboard&quot;, &quot;info&quot;)"
164 data-clipboard-text="[cmruncode name=&quot;${code_name}&quot;]"
165 title="Copy shortcode to clipboard" style="vertical-align:middle"
166 ></a>
167 </span>
168 `);
169 new ClipboardJS('.c2c');
170 } else {
171 jQuery("#tab-" + tab + "-shortcode_link").html('');
172 }
173 }
174
175 function tab_unselect() {
176 jQuery('.nav-tab-active').removeClass('nav-tab-active');
177 jQuery('.nav-tab-content').hide();
178 }
179
180 function tab_new(tab_label, code_id = -1, code_type = 'PHP Shortcode', code = '', code_enabled = 0, preview_enabled = 'false') {
181 tab_unselect();
182
183 code_types = '';
184 for (var code_group in code_manager_code_groups) {
185 code_types += '<optgroup label="' + code_group + '">';
186 code_manager_code_group = code_manager_code_groups[code_group];
187 for (var label in code_manager_code_group ) {
188 if (code_type===label) {
189 selected = ' selected';
190 } else {
191 selected = '';
192 }
193 code_types +=
194 '<option value="' + label + '"' + selected + '>' +
195 code_manager_code_group[label] +
196 '</option>';
197 }
198 code_types += '</optgroup>';
199 }
200
201 jQuery('#code_manager_taskbar_tabmode')
202 .append(
203 '<a id="tab-' + tabs + '" href="javascript:void(0)" class="nav-tab nav-tab-active" onclick="tab_clicked(' + tabs + ')" data-code-manager-tab="' + tabs + '">' +
204 '<span id="tab-' + tabs + '-label" contenteditable="true" class="code_manager_tab_label cm_tooltip" data-code-manager-tab="' + tabs + '" title="Double click to change code name">' + tab_label + '</span>' +
205 '<span id="tab-' + tabs + '-icon" class="dashicons dashicons-dismiss icon_close" onclick="tab_close(this,event,' + tabs + ')"></span>' +
206 '</a>'
207 );
208
209 var editorSettings = cm_settings;
210 if (code_type.includes('html')) {
211 // Load HTML settings
212 editorSettings = wp.codeEditor.defaultSettings ? _.clone( wp.codeEditor.defaultSettings ) : {};
213 editorSettings.codemirror = _.extend(
214 {},
215 editorSettings.codemirror,
216 {
217 mode: 'html',
218 }
219 );
220 } else if (code_type.includes('css')) {
221 // Load CSS settings
222 editorSettings = wp.codeEditor.defaultSettings ? _.clone( wp.codeEditor.defaultSettings ) : {};
223 editorSettings.codemirror = _.extend(
224 {},
225 editorSettings.codemirror,
226 {
227 mode: 'css',
228 }
229 );
230 } if (code_type.includes('javascript')) {
231 // Load JavaScript settings
232 editorSettings = wp.codeEditor.defaultSettings ? _.clone( wp.codeEditor.defaultSettings ) : {};
233 editorSettings.codemirror = _.extend(
234 {},
235 editorSettings.codemirror,
236 {
237 mode: 'javascript',
238 }
239 );
240 } else {
241 // Load PHP settings (default = cm_settings)
242 if (code==='') {
243 code = PHP_DEFAULT;
244 }
245 }
246
247 code_id_displayed = code_id==-1 ? 'new' : code_id;
248 code_is_enabled = code_enabled==0 ? '' : 'checked';
249 code_preview_enabled = preview_enabled=='false' ? '' : 'checked';
250
251 if (code_type.includes('file')) {
252 element_code_enabled =
253 '<select id="tab-' + tabs + '-cb-enable" ' + code_is_enabled + ' onchange="return tab_icon_enable(' + tabs + ')" title="Enable code" class="cm_tooltip" style="margin-right:15px">' +
254 '<option value="0">Disabled</option>' +
255 '<option value="1">Admin enabled</option>' +
256 '<option value="2">Public enabled</option>' +
257 '<option value="3">Both enabled</option>' +
258 '</select>';
259 } else {
260 element_code_enabled =
261 '<label class="cm_tooltip" style="padding-right:15px" title="Enable code">' +
262 '<input type="checkbox" id="tab-' + tabs + '-cb-enable" ' + code_is_enabled + ' onclick="return tab_icon_enable(' + tabs + ')" />' +
263 'Enable' +
264 '</label>';
265 }
266
267 jQuery('#code_manager_workspace_tabmode')
268 .append(
269 '<div id="tab-' + tabs + '-div" class="nav-tab-content">' +
270 '<div id="tab-' + tabs + '-taskbar" class="tab_task_bar">' +
271 '<a href="javascript:void(0)" class="button non-active cm_tooltip" id="tab-' + tabs + '-icon-save" disabled="true" onclick="tab_icon_save(' + tabs + ')" title="Save code">' +
272 '<span class="dashicons dashicons-yes-alt" style="padding-top: 4px;"></span>' +
273 '</a>' +
274 '&nbsp;' +
275 '<select id="tab-' + tabs + '-code_type" class="cm_tooltip" title="Select code type">' +
276 code_types +
277 '</select>' +
278 '&nbsp;' +
279 '<span>ID: ' +
280 '<span id="tab-' + tabs + '-code_id" style="font-weight: bold">' + code_id_displayed + '</span>' +
281 '</span>' +
282 '<span id="tab-' + tabs + '-shortcode_link" style="padding-left:10px"></span>' +
283 '<span style="float:right;line-height:2">' +
284 element_code_enabled +
285 '<label class="cm_tooltip" style="padding-right:5px" title="Enable preview mode for this code"><input type="checkbox" class="cm-cb-preview" id="tab-' + tabs + '-cb-preview"' + code_preview_enabled + ' onclick="return tab_icon_preview(' + tabs + ')" />Preview</label>' +
286 '<a href="javascript:void(0)"><i class="fas fa-redo cm_tooltip" style="font-size: 20px; vertical-align: middle" title="Refresh tab" onclick="return tab_refresh(' + tabs + ')"></i></a>' +
287 '</span>' +
288 '</div>' +
289 '<div id="tab-' + tabs + '-code" class="tab_code" data-code-manager-tab="' + tabs + '">' +
290 '<textarea id="tab-' + tabs + '-content">' +
291 code.replace(/<\/textarea>/g, '&lt;/textarea&gt;').replace(/&(?!amp;)/g, '&amp;') +
292 '</textarea>' +
293 '</div>' +
294 '</div>'
295 );
296
297 // Rewrite textarea closing tag if applicable
298 let textArea = jQuery("#tab-" + tabs + "-content").text();
299 jQuery("#tab-" + tabs + "-content").text(textArea.replace(/&lt;\/textarea&gt;/g, '<\/textarea>'));
300
301 var tab_editor = wp.codeEditor.initialize(jQuery('#tab-' + tabs + '-content'), editorSettings);
302
303 tab_editor.codemirror.focus();
304 tab_editor.codemirror.setCursor(1);
305 tab_editor.codemirror.setOption('tabindex', tabs);
306
307 var editor = {
308 tab_index: tabs,
309 tab_code_index: code_id,
310 tab_label: tab_label,
311 tab_editor: tab_editor
312 };
313 cm_editors[tabs] = editor;
314 user_has_edited[tabs] = false;
315
316 tab_editor.codemirror.on('change', function(cm_editor){
317 tab_changed(cm_editor.getOption('tabindex'));
318 });
319
320 // Enable tooltip
321 jQuery('.cm_tooltip').tooltip();
322
323 // Add shortcode link if applicable
324 set_copy_shortcode_link(tabs);
325
326 jQuery('#tab-' + tabs + '-code_type').on('focus', function(event) {
327 jQuery(this).data({current_value:jQuery(this).val()});
328 });
329
330 jQuery('#tab-' + tabs + '-code_type').on('change', {tab:tabs,cid:code_id}, function(event) {
331 if (event.data.cid===-1) {
332 if (jQuery('#tab-' + event.data.tab + '-code_type option:selected').text().toLowerCase().includes('php')) {
333 // Add php tags
334 if (cm_editors[event.data.tab].tab_editor.codemirror.getValue()==='') {
335 cm_editors[event.data.tab].tab_editor.codemirror.setValue(PHP_DEFAULT);
336 }
337 } else {
338 // Remove php tags (clear field)
339 if (cm_editors[event.data.tab].tab_editor.codemirror.getValue()===PHP_DEFAULT) {
340 cm_editors[event.data.tab].tab_editor.codemirror.setValue('');
341 }
342 }
343
344 tab_changed(event.data.tab);
345 return;
346 }
347
348 html = '<div>Are you sure you want to change the code type? Due to possible errors, this code will be disabled!</div>';
349 var dialog =
350 jQuery(html)
351 .data('current_element',jQuery(this))
352 .data('current_value',jQuery.data(this, 'current_value'))
353 .data('current_tab',event.data.tab)
354 .dialog({
355 dialogClass: 'no-close',
356 title: 'Change code type?',
357 buttons: {
358 'Yes': function() {
359 tab_changed(jQuery.data(this, 'current_tab'));
360 jQuery("#tab-" + event.data.tab + "-cb-enable").prop("checked", false);
361 set_copy_shortcode_link(event.data.tab);
362 dialog.dialog('destroy');
363 },
364 'No': function() {
365 jQuery(jQuery.data(this, 'current_element')).val(jQuery.data(this, 'current_value'));
366 dialog.dialog('destroy');
367 },
368 'Cancel': function() {
369 jQuery(jQuery.data(this, 'current_element')).val(jQuery.data(this, 'current_value'));
370 dialog.dialog('destroy');
371 }
372 }
373 });
374 });
375
376 jQuery('#tab-' + tabs + '-label').on('input', {tab:tabs}, function(event) {
377 tab_changed(event.data.tab);
378 });
379
380 jQuery('#tab-' + tabs + '-label').on('dblclick', function() {
381 var cell = this;
382 var range, selection;
383 if (document.body.createTextRange) {
384 range = document.body.createTextRange();
385 range.moveToElementText(cell);
386 range.select();
387 } else if (window.getSelection) {
388 selection = window.getSelection();
389 range = document.createRange();
390 range.selectNodeContents(cell);
391 selection.removeAllRanges();
392 selection.addRange(range);
393 }
394 });
395
396 tabs++;
397 }
398
399 function tab_changed(tabindex) {
400 user_has_edited[tabindex] = true;
401 jQuery('#tab-' + tabindex + '-icon').addClass('tab_unsaved_changes');
402 jQuery('#tab-' + tabindex + '-icon-save').removeClass('non-active').attr('disabled', false);
403 }
404
405 function activate_code_on_server(tab, val, txt) {
406 jQuery.ajax({
407 type: 'POST',
408 url: pathname + '?action=code_manager_activate_code',
409 data: {
410 code_id: cm_editors[tab].tab_code_index,
411 code_item_value: val,
412 wpnonce: wpnonce,
413 page: 'code_manager_post'
414 }
415 }).done(
416 function (msg) {
417 if ( msg.substr(0, 3) === 'UPD' ) {
418 jQuery.notify(txt, 'success');
419 } else {
420 jQuery.notify('Settings not saved', 'error');
421 }
422 }
423 ).fail(
424 function () {
425 jQuery.notify('The request could not be handled', 'error');
426 }
427 );
428
429 }
430
431 function tab_refresh(tab) {
432 if (cm_editors[tab].tab_code_index===-1) {
433 jQuery.notify('Code needs to be saved first', 'error');
434 } else {
435 jQuery.ajax({
436 method: 'POST',
437 url: pathname + '?action=code_manager_get_code',
438 data: {
439 wpnonce: wpnonce_get_code,
440 code_id: cm_editors[tab].tab_code_index,
441 page: 'code_manager_post',
442 wpda_action: 'all'
443 }
444 }).done(
445 function(json) {
446 cm_editors[tab].tab_label = json.code_name;
447
448 cm = cm_editors[tab].tab_editor.codemirror;
449 cm.setValue(json.code);
450 cm.save();
451
452 jQuery("#tab-" + tab + "-label").text(json.code_name);
453 jQuery("#tab-" + tab + "-code_type").val(json.code_type);
454 jQuery("#tab-" + tab + "-cb-enable").prop("checked", json.code_enabled==="1");
455
456 mark_tab_as_unchanged(cm);
457
458 set_copy_shortcode_link(tab);
459
460 jQuery.notify('Refresh completed', 'success');
461 }
462 );
463 jQuery.ajax({
464 method: 'POST',
465 url: pathname + '?action=code_manager_is_code_preview_enabled',
466 data: {
467 wpnonce: wpnonce_get_code,
468 code_id: cm_editors[tab].tab_code_index,
469 page: 'code_manager_post',
470 }
471 }).done(
472 function(data) {
473 jQuery("#tab-" + tab + "-cb-preview").prop("checked", data==="true");
474 }
475 );
476 }
477 }
478
479 function activate_preview_on_server(tab) {
480 jQuery.ajax({
481 method: 'POST',
482 url: pathname + '?action=code_manager_activate_code_preview',
483 data: {
484 wpnonce: wpnonce,
485 code_id: cm_editors[tab].tab_code_index,
486 page: 'code_manager_post'
487 }
488 }).done(
489 function(msg) {
490 if (msg==='OK') {
491 jQuery.notify('Preview activated', 'success');
492 } else {
493 jQuery.notify(msg, 'error');
494 }
495 }
496 );
497 }
498
499 function tab_open() {
500 removeIntro();
501 get_code_list(tab_open_callback);
502 }
503
504 function tab_open_callback() {
505 var dialog = jQuery(jQuery('#code_manager_open_frame')).dialog({
506 dialogClass: 'no-close',
507 width: "inherit",
508 resizable: false,
509 title: 'Select code from list',
510 buttons: {
511 'Open': function() {
512 var code_list = [];
513 jQuery('#code_manager_code_list option:selected').each(function() {
514 if (jQuery(this).is(":visible")) {
515 code_list.push(jQuery(this).val());
516 }
517 });
518 if (code_list.length===0) {
519 alert("Nothing selected!")
520 } else {
521 if (code_list[0]==='Loading data...') {
522 alert("Nothing selected!")
523 } else {
524 for (var i=0; i<code_list.length; i++) {
525 get_code(
526 code_list[i],
527 jQuery('#code_manager_code_list option[value=' + code_list[i] + ']').attr('data-name'),
528 jQuery('#code_manager_code_list option[value=' + code_list[i] + ']').attr('data-type'),
529 jQuery('#code_manager_code_list option[value=' + code_list[i] + ']').attr('data-enabled'),
530 jQuery('#code_manager_code_list option[value=' + code_list[i] + ']').attr('data-preview')
531 );
532 }
533 dialog.dialog('close');
534 }
535 }
536 },
537 'Cancel': function() {
538 dialog.dialog('close');
539 }
540 }
541 });
542
543 jQuery("#code_manager_code_list").unbind("dblclick");
544 jQuery("#code_manager_code_list").on("dblclick", function() {
545 tab = jQuery(this).val()[0];
546 get_code(
547 tab,
548 jQuery('#code_manager_code_list option[value=' + tab + ']').attr('data-name'),
549 jQuery('#code_manager_code_list option[value=' + tab + ']').attr('data-type'),
550 jQuery('#code_manager_code_list option[value=' + tab + ']').attr('data-enabled'),
551 jQuery('#code_manager_code_list option[value=' + tab + ']').attr('data-preview')
552 );
553 dialog.dialog('close');
554 });
555 }
556
557 function tab_close(elem, event, tab) {
558 if (user_has_edited[tab]===true) {
559 html = '<div>Your changes will not be saved!</div>';
560 var dialog = jQuery(html).dialog({
561 dialogClass: 'no-close',
562 title: 'Close tab?',
563 buttons: {
564 'Yes': function() {
565 close_tab(elem, tab);
566 dialog.dialog('destroy');
567 },
568 'No': function() {
569 dialog.dialog('destroy');
570 },
571 'Cancel': function() {
572 dialog.dialog('destroy');
573 }
574 }
575 });
576 } else {
577 close_tab(elem, tab);
578 }
579 event.stopPropagation();
580 }
581 function close_tab(elem, tab) {
582 jQuery(elem).parent().remove();
583 jQuery('#tab-' + tab + '-div').remove();
584
585 cm = cm_editors[tab].tab_editor.codemirror;
586 cm.setOption('mode', 'text/x-csrc');
587 cm.getWrapperElement().parentNode.removeChild(cm.getWrapperElement());
588 cm=null;
589 delete cm_editors[tab];
590 delete user_has_edited[tab];
591
592 if (!jQuery('.nav-tab-active').length) {
593 index_selected = -1;
594
595 for (editor in cm_editors) {
596 tab_index = cm_editors[editor].tab_editor.codemirror.getOption('tabindex');
597 if (index_selected>tab) {
598 break;
599 }
600 index_selected = tab_index;
601 }
602
603 if (index_selected>-1) {
604 tab_activate(index_selected);
605 }
606 }
607 }
608
609 function tab_activate(tab) {
610 jQuery('#tab-' + tab).addClass('nav-tab-active');
611 jQuery('#tab-' + tab + '-div').show();
612 }
613
614 function tab_load(code_id, tab_label, code_type, code, code_enabled, preview_enabled) {
615 tab_new(tab_label, code_id, code_type, code, code_enabled, preview_enabled);
616 }
617
618 function tab_clicked(tab) {
619 source_id = jQuery('.nav-tab-active').attr('data-code-manager-tab');
620 if (source_id===tab) {
621 return;
622 }
623
624 jQuery('.nav-tab-active').removeClass('nav-tab-active');
625 jQuery('.nav-tab-content').hide();
626 jQuery('#tab-' + tab).addClass('nav-tab-active');
627 jQuery('#tab-' + tab + '-div').show();
628 }
629
630 function tab_icon_save(tab) {
631 tab_label = jQuery('#tab-' + tab + '-label').text();
632 old_label = cm_editors[tab].tab_label;
633 if (old_label!==tab_label) {
634 code_name_exists(tab_label, old_label, tab)
635 } else {
636 save_code(tab);
637 }
638 }
639
640 function code_name_exists(code_name, old_label, tab) {
641 jQuery.ajax({
642 method: 'POST',
643 url: pathname + '?action=code_manager_code_name_exists',
644 data: {
645 wpnonce: wpnonce_get_code,
646 code_name: code_name,
647 page: 'code_manager_post'
648 }
649 }).done(
650 function(msg) {
651 if (msg!=='OK') {
652 jQuery.notify('Name already exists', 'error');
653 jQuery('#tab-' + tab + '-label').text(old_label);
654 } else {
655 save_code(tab);
656 }
657 }
658 );
659 }
660
661 function save_code(tab, successmsg = 'Code saved') {
662 if (user_has_edited[tab]===false) {
663 return;
664 }
665
666 cm = cm_editors[tab].tab_editor.codemirror;
667 cm.save();
668
669 jQuery.ajax({
670 method: 'POST',
671 url: pathname + '?action=code_manager_update_code',
672 data: {
673 wpnonce: wpnonce,
674 code_id: cm_editors[tab].tab_code_index>0 ? cm_editors[tab].tab_code_index : -1,
675 code_name: jQuery('#tab-' + tab + '-label').text(),
676 code_type: jQuery('#tab-' + tab + '-code_type').val(),
677 code: jQuery('#tab-' + tab + '-content').val(),
678 page: 'code_manager_post'
679 }
680 }).done(
681 function(msg) {
682 if ( msg.substr(0, 3) === 'UPD' ) {
683 jQuery.notify(successmsg, 'success');
684 mark_tab_as_unchanged(cm);
685 set_copy_shortcode_link(tab);
686 } else if ( msg.substr(0, 3) === 'INS' ) {
687 code_id = msg.substr(4);
688 cm_editors[tab].tab_code_index = code_id;
689 jQuery('#tab-' + tab + '-code_id').html(code_id);
690 set_copy_shortcode_link(tab);
691 jQuery.notify(successmsg, 'success');
692 mark_tab_as_unchanged(cm);
693 } else {
694 if (msg.length>50) {
695 errormsg = 'ERROR : ' + msg.substr(0,50) + '...';
696 } else {
697 errormsg = msg;
698 }
699 jQuery.notify(errormsg, 'error');
700 }
701 }
702 );
703 }
704
705 function mark_tab_as_unchanged(cm_editor) {
706 tabindex = cm_editor.getOption('tabindex');
707 user_has_edited[tabindex] = false;
708 jQuery('#tab-' + tabindex + '-icon').removeClass('tab_unsaved_changes');
709 jQuery('#tab-' + tabindex + '-icon-save').addClass('non-active').attr('disabled', true);
710 }
711
712 function tab_icon_enable(tab) {
713 if (cm_editors[tab].tab_code_index===-1) {
714 jQuery.notify('Your code must be saved before it can be enabled', 'info');
715 return false;
716 }
717
718 if (jQuery('#tab-' + tab + '-cb-enable').attr('type')==='checkbox') {
719 if (jQuery('#tab-' + tab + '-cb-enable').is(':checked')) {
720 val = '1';
721 txt = 'Code enabled';
722 } else {
723 val = '0';
724 txt = 'Code disabled';
725 }
726 } else {
727 val = jQuery('#tab-' + tab + '-cb-enable').val();
728 txt = 'Code ' + jQuery('#tab-' + tab + '-cb-enable :selected').text().toLowerCase();
729 }
730
731 activate_code_on_server(tab, val, txt);
732
733 return true;
734 }
735
736 function tab_icon_preview(tab) {
737 if (cm_editors[tab].tab_code_index===-1) {
738 jQuery.notify('Your code must be saved before it can be previewed', 'info');
739 return false;
740 }
741
742 if (jQuery('#tab-' + tab + '-cb-preview').is(':checked')) {
743 // Activate preview
744 activate_preview_on_server(tab);
745 } else {
746 // Deactivate preview
747 tab_icon_deactivate(tab);
748 }
749
750 return true;
751 }
752
753 function tab_icon_deactivate(tab) {
754 jQuery.ajax({
755 method: 'POST',
756 url: pathname + '?action=code_manager_deactivate_code_preview',
757 data: {
758 wpnonce: wpnonce,
759 code_id: cm_editors[tab].tab_code_index,
760 page: 'code_manager_post'
761 }
762 }).done(
763 function(msg) {
764 if ( msg === 'OK' ) {
765 jQuery.notify('Preview deactivated', 'success');
766 } else {
767 jQuery.notify(msg, 'error');
768 }
769 }
770 );
771 }
772
773 function unsaved_changes() {
774 has_edited = false;
775
776 for (var tabindex in user_has_edited) {
777 if (user_has_edited[tabindex]===true) {
778 has_edited = true;
779 }
780 }
781
782 return has_edited;
783 }
784
785 function reset_preview() {
786 jQuery.ajax({
787 type: 'POST',
788 url: pathname + '?action=code_manager_reset_preview',
789 data: {
790 wpnonce: wpnonce,
791 page: 'code_manager_post'
792 }
793 }).done(
794 function (msg) {
795 if ( msg === 'OK' ) {
796 jQuery.notify(msg, 'success');
797 jQuery('.cm-cb-preview').prop('checked', false);
798 } else {
799 jQuery.notify(msg, 'info');
800 }
801 }
802 ).fail(
803 function () {
804 jQuery.notify(msg, 'error');
805 }
806 );
807 }
808
809 function removeIntro() {
810 jQuery(".cm_tab_mode_intro").remove();
811 }
812
813 jQuery(function() {
814 jQuery('#code_manager_new').on('click', function(e) {
815 removeIntro();
816
817 var tabLabel = "New";
818 if (new_label_index>0) {
819 tabLabel += "_" + new_label_index;
820 }
821 tab_new(tabLabel, -1);
822 new_label_index++;
823 });
824
825 jQuery('#code_manager_open').on('click', function(e) {
826 tab_open();
827 });
828
829 jQuery('#code_manager_cancel_file').on('click', function() {
830 jQuery('#code_manager_open_frame').hide();
831 });
832
833 jQuery('#code_manager_taskbar_tabmode').sortable();
834
835 jQuery(window).on('keydown', function(event) {
836 if ((event.ctrlKey || event.metaKey) && String.fromCharCode(event.which).toLowerCase()==='s') {
837 if (
838 jQuery(event.target).hasClass('CodeMirror-code') ||
839 jQuery(event.target).hasClass('code_manager_tab_label')
840 ) {
841 if (jQuery(event.target).hasClass('CodeMirror-code')) {
842 tab_code = jQuery(event.target).closest('.tab_code');
843 tab = tab_code.attr('data-code-manager-tab');
844 } else {
845 tab = jQuery(event.target).attr('data-code-manager-tab');
846 }
847 if (typeof tab !== typeof undefined && tab !== false) {
848 save_code(tab);
849 event.preventDefault();
850 }
851 }
852 } else if (
853 (event.ctrlKey || event.metaKey) &&
854 String.fromCharCode(event.which).toLowerCase()==='v' &&
855 jQuery(event.target).hasClass('code_manager_tab_label')
856 ) {
857 event.preventDefault(); // Prevent ctrl-v on tab label
858 }
859 });
860
861 jQuery('.cm_menu_title').tooltip();
862 jQuery('#disable_preview').tooltip();
863 jQuery('#disable_preview').on('click', function() {
864 html = "<div>This turns of preview mode for all code IDs for all users. Do you want to continue?</div>";
865 var dialog = jQuery(html).dialog({
866 dialogClass: 'no-close',
867 title: 'Reset preview',
868 buttons: {
869 'Yes': function() {
870 dialog.dialog('destroy');
871 reset_preview();
872 },
873 'No': function() {
874 dialog.dialog('destroy');
875 },
876 'Cancel': function() {
877 dialog.dialog('destroy');
878 }
879 }
880 });
881 });
882
883 jQuery(window).on('beforeunload', function() {
884 if ( unsaved_changes() ) {
885 return 'Your changes will not be saved! Are you sure you want to leave this page?';
886 }
887 });
888
889 setTimeout(function() {
890 jQuery(".cm_tab_mode_intro").fadeOut(2000, function() {
891 removeIntro();
892 });
893 }, 4000);
894 });
895