code_manager.js
3 years ago
code_manager_dashboard.js
3 years ago
code_manager_listmode.js
3 years ago
code_manager_message.js
3 years ago
code_manager_tabmode.js
3 years ago
notify.min.js
3 years 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 + " ".repeat( maxLength - obj[key].code_name.length) + " − " + 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("Shortcode copied to clipboard", "info")" |
| 156 | data-clipboard-text="[cmruncode id="${cm_editors[tab].tab_code_index}"]" |
| 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("Shortcode copied to clipboard", "info")" |
| 164 | data-clipboard-text="[cmruncode name="${code_name}"]" |
| 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 | ' ' + |
| 275 | '<select id="tab-' + tabs + '-code_type" class="cm_tooltip" title="Select code type">' + |
| 276 | code_types + |
| 277 | '</select>' + |
| 278 | ' ' + |
| 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, '</textarea>').replace(/&(?!amp;)/g, '&') + |
| 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(/<\/textarea>/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 |