| 1 |
var autocompleting = false; |
| 2 |
var autocompletelength = 2; |
| 3 |
var editor = ''; |
| 4 |
|
| 5 |
var saved_editor_sessions = []; |
| 6 |
var saved_undo_manager = []; |
| 7 |
var last_added_editor_session = 0; |
| 8 |
var current_editor_session = 0; |
| 9 |
|
| 10 |
var EditSession = require('ace/edit_session').EditSession; |
| 11 |
var UndoManager = require('ace/undomanager').UndoManager; |
| 12 |
var Search = require("ace/search").Search; |
| 13 |
var TokenIterator = require("ace/token_iterator").TokenIterator; |
| 14 |
|
| 15 |
var oHandler; |
| 16 |
|
| 17 |
function onSessionChange(e) { |
| 18 |
|
| 19 |
//set the document as unsaved |
| 20 |
jQuery(".wpide_tab.active", "#wpide_toolbar").data( "unsaved", true); |
| 21 |
jQuery("#wpide_footer_message_unsaved").html("[ Document contains unsaved content ✎ ]").show(); |
| 22 |
|
| 23 |
if( editor.getSession().enable_autocomplete === false){ |
| 24 |
return; |
| 25 |
} |
| 26 |
|
| 27 |
//don't continue with autocomplete if /n entered |
| 28 |
try { |
| 29 |
if ( e.data.text.charCodeAt(0) === 10 ){ |
| 30 |
return; |
| 31 |
} |
| 32 |
}catch(error){} |
| 33 |
|
| 34 |
try { |
| 35 |
if ( e.data.action == 'removeText' ){ |
| 36 |
|
| 37 |
if (autocompleting) { |
| 38 |
autocompletelength = (autocompletelength - 1) ; |
| 39 |
}else{ |
| 40 |
return; |
| 41 |
} |
| 42 |
} |
| 43 |
}catch(error){} |
| 44 |
|
| 45 |
|
| 46 |
//get current cursor position |
| 47 |
range = editor.getSelectionRange(); |
| 48 |
//take note of selection row to compare with search |
| 49 |
cursor_row = range.start.row; |
| 50 |
|
| 51 |
try{ |
| 52 |
//quit autocomplete if we are writing a "string" |
| 53 |
var iterator = new TokenIterator(editor.getSession(), range.start.row, range.start.column); |
| 54 |
var current_token_type = iterator.getCurrentToken().type; |
| 55 |
if(current_token_type == "string" || current_token_type == "comment"){ |
| 56 |
return; |
| 57 |
} |
| 58 |
}catch(error){} |
| 59 |
|
| 60 |
if (range.start.column > 0){ |
| 61 |
|
| 62 |
//search for command text user has entered that we need to try match functions against |
| 63 |
var search = new Search().set({ |
| 64 |
needle: "[\\n \.\)\(]", |
| 65 |
backwards: true, |
| 66 |
wrap: false, |
| 67 |
caseSensitive: false, |
| 68 |
wholeWord: false, |
| 69 |
regExp: true |
| 70 |
}); |
| 71 |
//console.log(search.find(editor.getSession())); |
| 72 |
|
| 73 |
range = search.find(editor.getSession()); |
| 74 |
|
| 75 |
if (range) range.start.column++; |
| 76 |
|
| 77 |
}else{ //change this to look char position, if it's starting at 0 then do this |
| 78 |
|
| 79 |
range.start.column = 0; |
| 80 |
} |
| 81 |
|
| 82 |
if (! range || range.start.row < cursor_row ){ |
| 83 |
//forse the autocomplete check on this row starting at column 0 |
| 84 |
range = editor.getSelectionRange(); |
| 85 |
range.start.column = 0; |
| 86 |
} |
| 87 |
|
| 88 |
|
| 89 |
//console.log("search result - start row " + range.start.row + "-" + range.end.row + ", column " + range.start.column+ "-" + range.end.column); |
| 90 |
//console.log(editor.getSelection().getRange()); |
| 91 |
|
| 92 |
range.end.column = editor.getSession().getSelection().getCursor().column +1;//set end column as cursor pos |
| 93 |
|
| 94 |
//console.log("[ \.] based: " + editor.getSession().doc.getTextRange(range)); |
| 95 |
|
| 96 |
//no column lower than 1 thanks |
| 97 |
if (range.start.column < 1) { |
| 98 |
range.start.column = 0; |
| 99 |
} |
| 100 |
|
| 101 |
//console.log("after row " + range.start.row + "-" + range.end.row + ", column " + range.start.column+ "-" + range.end.column); |
| 102 |
//get the editor text based on that range |
| 103 |
var text = editor.getSession().doc.getTextRange(range); |
| 104 |
$quit_onchange = false; |
| 105 |
|
| 106 |
//console.log(text); |
| 107 |
|
| 108 |
//console.log("Searching for text \""+text+"\" length: "+ text.length); |
| 109 |
if (text.length < 3){ |
| 110 |
|
| 111 |
wpide_close_autocomplete(); |
| 112 |
return; |
| 113 |
} |
| 114 |
|
| 115 |
autocompletelength = text.length; |
| 116 |
|
| 117 |
//create the dropdown for autocomplete |
| 118 |
var sel = editor.getSelection(); |
| 119 |
var session = editor.getSession(); |
| 120 |
var lead = sel.getSelectionLead(); |
| 121 |
|
| 122 |
var pos = editor.renderer.textToScreenCoordinates(lead.row, lead.column); |
| 123 |
var ac = document.getElementById('ac'); // #ac is auto complete html select element |
| 124 |
|
| 125 |
|
| 126 |
|
| 127 |
if( typeof ac !== 'undefined' ){ |
| 128 |
|
| 129 |
//add editor click listener |
| 130 |
//editor clicks should hide the autocomplete dropdown |
| 131 |
editor.container.addEventListener('click', function(e){ |
| 132 |
|
| 133 |
wpide_close_autocomplete(); |
| 134 |
|
| 135 |
autocompleting=false; |
| 136 |
autocompletelength = 2; |
| 137 |
|
| 138 |
}, false); |
| 139 |
|
| 140 |
} //end - create initial autocomplete dropdown and related actions |
| 141 |
|
| 142 |
|
| 143 |
//calulate the editor container offset |
| 144 |
var obj=editor.container; |
| 145 |
|
| 146 |
var curleft = 0; |
| 147 |
var curtop = 0; |
| 148 |
|
| 149 |
if (obj.offsetParent) { |
| 150 |
|
| 151 |
do { |
| 152 |
curleft += obj.offsetLeft; |
| 153 |
curtop += obj.offsetTop; |
| 154 |
} while (obj = obj.offsetParent); |
| 155 |
|
| 156 |
} |
| 157 |
|
| 158 |
|
| 159 |
//position autocomplete |
| 160 |
ac.style.top= ((pos.pageY - curtop)+20) + "px"; |
| 161 |
ac.style.left= ((pos.pageX - curleft)+10) + "px"; |
| 162 |
ac.style.display='block'; |
| 163 |
ac.style.background='white'; |
| 164 |
|
| 165 |
|
| 166 |
//remove all options, starting a fresh list |
| 167 |
ac.options.length = 0; |
| 168 |
|
| 169 |
|
| 170 |
//loop through WP tags and check for a match |
| 171 |
if (autocomplete_wordpress){ |
| 172 |
var tag; |
| 173 |
for(i in autocomplete_wordpress) { |
| 174 |
//if(!html_tags.hasOwnProperty(i) ){ |
| 175 |
// continue; |
| 176 |
//} |
| 177 |
|
| 178 |
tag= i; |
| 179 |
//see if the tag is a match |
| 180 |
if( text !== tag.substr(0,text.length) ){ |
| 181 |
continue; |
| 182 |
} |
| 183 |
|
| 184 |
//add parentheses |
| 185 |
tag = tag + "()"; |
| 186 |
|
| 187 |
var option = document.createElement('option'); |
| 188 |
option.text = tag; |
| 189 |
option.value = tag; |
| 190 |
option.setAttribute('title', wpide_app_path + 'images/wpac.png');//path to icon image or wpac.png |
| 191 |
|
| 192 |
|
| 193 |
try { |
| 194 |
ac.add(option, null); // standards compliant; doesn't work in IE |
| 195 |
} |
| 196 |
catch(ex) { |
| 197 |
ac.add(option); // IE only |
| 198 |
} |
| 199 |
|
| 200 |
}//end for |
| 201 |
}//end php autocomplete |
| 202 |
|
| 203 |
//loop through PHP tags and check for a match |
| 204 |
if (autocomplete_php){ |
| 205 |
var tag; |
| 206 |
for(i in autocomplete_php) { |
| 207 |
//if(!html_tags.hasOwnProperty(i) ){ |
| 208 |
// continue; |
| 209 |
//} |
| 210 |
|
| 211 |
tag= i; |
| 212 |
//see if the tag is a match |
| 213 |
if( text !== tag.substr(0,text.length) ){ |
| 214 |
continue; |
| 215 |
} |
| 216 |
|
| 217 |
//add parentheses |
| 218 |
tag = tag + "()"; |
| 219 |
|
| 220 |
var option = document.createElement('option'); |
| 221 |
option.text = tag; |
| 222 |
option.value = tag; |
| 223 |
option.setAttribute('title', wpide_app_path + 'images/phpac.png');//path to icon image or wpac.png |
| 224 |
|
| 225 |
try { |
| 226 |
ac.add(option, null); // standards compliant; doesn't work in IE |
| 227 |
} |
| 228 |
catch(ex) { |
| 229 |
ac.add(option); // IE only |
| 230 |
} |
| 231 |
|
| 232 |
|
| 233 |
}//end for |
| 234 |
}//end php autocomplete |
| 235 |
|
| 236 |
|
| 237 |
//check for matches |
| 238 |
if ( ac.length === 0 ) { |
| 239 |
wpide_close_autocomplete(); |
| 240 |
} else { |
| 241 |
|
| 242 |
ac.selectedIndex=0; |
| 243 |
autocompleting=true; |
| 244 |
oHandler = jQuery("#ac").msDropDown({visibleRows:10, rowHeight:20}).data("dd"); |
| 245 |
|
| 246 |
jQuery("#ac_child").click(function(item){ |
| 247 |
//get the link node and pass to select AC item function |
| 248 |
if (typeof item.srcElement != 'undefined'){ |
| 249 |
var link_node = item.srcElement; //works on chrome |
| 250 |
}else{ |
| 251 |
var link_node = item.target; //works on Firefox etc |
| 252 |
} |
| 253 |
|
| 254 |
selectACitem(link_node); |
| 255 |
}); |
| 256 |
|
| 257 |
jQuery("#ac_child a").mouseover(function(item){ |
| 258 |
//show the code in the info panel |
| 259 |
|
| 260 |
//get the link ID |
| 261 |
if (typeof item.srcElement != 'undefined'){ |
| 262 |
var link_id = item.srcElement.id; //works on chrome |
| 263 |
}else{ |
| 264 |
var link_id = item.target.id; //works on Firefox etc |
| 265 |
} |
| 266 |
|
| 267 |
if (link_id == '') return; //if the link doesn't have an id it's not valid so just stop |
| 268 |
|
| 269 |
|
| 270 |
//if this command item is enabled |
| 271 |
if (jQuery("#"+link_id).hasClass("enabled")){ |
| 272 |
|
| 273 |
var selected_item_index = jQuery("#"+link_id).index(); |
| 274 |
|
| 275 |
if (selected_item_index > -1){ //if select item is valid |
| 276 |
|
| 277 |
//set the selected menu item |
| 278 |
oHandler.selectedIndex(selected_item_index); |
| 279 |
//show command help panel for this command |
| 280 |
wpide_function_help(); |
| 281 |
|
| 282 |
} |
| 283 |
} |
| 284 |
|
| 285 |
}); |
| 286 |
|
| 287 |
|
| 288 |
jQuery("#ac_child").css("z-index", "9999"); |
| 289 |
jQuery("#ac_child").css("background-color", "#ffffff"); |
| 290 |
jQuery("#ac_msdd").css("z-index", "9999"); |
| 291 |
jQuery("#ac_msdd").css("position", "absolute"); |
| 292 |
jQuery("#ac_msdd").css("top", ac.style.top); |
| 293 |
jQuery("#ac_msdd").css("left", ac.style.left); |
| 294 |
|
| 295 |
//show command help panel for this command |
| 296 |
wpide_function_help(); |
| 297 |
|
| 298 |
} |
| 299 |
|
| 300 |
} |
| 301 |
|
| 302 |
function token_test(){ |
| 303 |
|
| 304 |
var iterator = new TokenIterator(editor.getSession(), range.start.row, range.start.column); |
| 305 |
var current_token_type = iterator.getCurrentToken().type; |
| 306 |
return iterator.getCurrentToken(); |
| 307 |
} |
| 308 |
|
| 309 |
function wpide_close_autocomplete(){ |
| 310 |
if (typeof document.getElementById('ac') != 'undefined') document.getElementById('ac').style.display='none'; |
| 311 |
if (typeof oHandler != 'undefined') oHandler.close(); |
| 312 |
|
| 313 |
autocompleting = false; |
| 314 |
|
| 315 |
//clear the text in the command help panel |
| 316 |
//jQuery("#wpide_info_content").html(""); |
| 317 |
} |
| 318 |
|
| 319 |
function selectionChanged(e) { |
| 320 |
var selected_text = editor.getSession().doc.getTextRange(editor.getSelectionRange()); |
| 321 |
|
| 322 |
//check for hex colour match |
| 323 |
if ( selected_text.match('^#?([a-f]|[A-F]|[0-9]){3}(([a-f]|[A-F]|[0-9]){3})?$') != null ){ |
| 324 |
|
| 325 |
var therange = editor.getSelectionRange(); |
| 326 |
therange.end.column = therange.start.column; |
| 327 |
therange.start.column = therange.start.column-1; |
| 328 |
|
| 329 |
// only show color assist if the character before the selection indicates a hex color (#) |
| 330 |
if ( editor.getSession().doc.getTextRange( therange ) == "#" ){ |
| 331 |
jQuery("#wpide_color_assist").show(); |
| 332 |
} |
| 333 |
|
| 334 |
} |
| 335 |
} |
| 336 |
|
| 337 |
function wpide_function_help() { |
| 338 |
//mouse over |
| 339 |
|
| 340 |
try |
| 341 |
{ |
| 342 |
var selected_command_item = jQuery("#ac_child a.selected"); |
| 343 |
|
| 344 |
|
| 345 |
key = selected_command_item.find("span.ddTitleText").text().replace("()",""); |
| 346 |
|
| 347 |
//wordpress autocomplete |
| 348 |
if ( selected_command_item.find("img").attr("src").indexOf("wpac.png") >= 0){ |
| 349 |
|
| 350 |
if (autocomplete_wordpress[key].desc != undefined){ |
| 351 |
|
| 352 |
//compose the param info |
| 353 |
var param_text =""; |
| 354 |
for(i=0; i<autocomplete_wordpress[key].params.length; i++) { |
| 355 |
|
| 356 |
//wrap params in a span to highlight not required |
| 357 |
if (autocomplete_wordpress[key].params[i].required == "no"){ |
| 358 |
param_text = param_text + "<span class='wpide_func_arg_notrequired'>" + autocomplete_wordpress[key].params[i]['param'] + "<em>optional</em></span><br /> <br />"; |
| 359 |
}else{ |
| 360 |
param_text = param_text + autocomplete_wordpress[key].params[i]['param'] + "<br /> <br />"; |
| 361 |
} |
| 362 |
|
| 363 |
} |
| 364 |
//compose returns text |
| 365 |
if (autocomplete_wordpress[key].returns.length > 0){ |
| 366 |
returns_text = "<br /><br /><strong>Returns:</strong> " + autocomplete_wordpress[key].returns; |
| 367 |
}else{ |
| 368 |
returns_text = ""; |
| 369 |
} |
| 370 |
|
| 371 |
|
| 372 |
//output command info |
| 373 |
jQuery("#wpide_info_content").html( |
| 374 |
"<strong class='wpide_func_highlight_black'>Function: </strong><strong class='wpide_func_highlight'>" + key + "(</strong><br />" + |
| 375 |
"<span class='wpide_func_desc'>" + autocomplete_wordpress[key].desc + "</span><br /><br /><em class='wpide_func_params'>" + |
| 376 |
param_text + "</em>"+ |
| 377 |
"<strong class='wpide_func_highlight'>)</strong> " + |
| 378 |
returns_text + |
| 379 |
"<p><a href='http://codex.wordpress.org/Function_Reference/" + key + "' target='_blank'>See " + key + "() in the WordPress codex</a></p>" |
| 380 |
); |
| 381 |
} |
| 382 |
|
| 383 |
} |
| 384 |
|
| 385 |
//php autocomplete |
| 386 |
if ( selected_command_item.find("img").attr("src").indexOf("phpac.png") >= 0){ |
| 387 |
|
| 388 |
if (autocomplete_php[key].returns != undefined){ |
| 389 |
|
| 390 |
//params text |
| 391 |
var param_text =""; |
| 392 |
for(i=0; i<autocomplete_php[key].params.length; i++) { |
| 393 |
|
| 394 |
//wrap params in a span to highlight not required |
| 395 |
if (autocomplete_php[key].params[i].required == "no"){ |
| 396 |
param_text = param_text + "<span class='wpide_func_arg_notrequired'>" + autocomplete_php[key].params[i]['param'] + "<em>optional</em></span><br /> <br />"; |
| 397 |
}else{ |
| 398 |
param_text = param_text + autocomplete_php[key].params[i]['param'] + "<br /> <br />"; |
| 399 |
} |
| 400 |
|
| 401 |
} |
| 402 |
//compose returns text |
| 403 |
if (autocomplete_php[key].returns.length > 0){ |
| 404 |
returns_text = "<br /><br /><strong>Returns:</strong> " + autocomplete_php[key].returns; |
| 405 |
}else{ |
| 406 |
returns_text = ""; |
| 407 |
} |
| 408 |
|
| 409 |
jQuery("#wpide_info_content").html( |
| 410 |
"<strong class='wpide_func_highlight_black'>Function: </strong><strong class='wpide_func_highlight'>" + key + "(</strong><br />" + |
| 411 |
autocomplete_php[key].desc + "<br /><br /><em class='wpide_func_params'>" + |
| 412 |
param_text + "</em>" + |
| 413 |
"<strong class='wpide_func_highlight'>)</strong>" + |
| 414 |
returns_text + |
| 415 |
"<p><a href='http://php.net/manual/en/function." + key.replace(/_/g, "-") + ".php' target='_blank'>See " + key + "() in the PHP manual</a></p>" |
| 416 |
); |
| 417 |
|
| 418 |
} |
| 419 |
|
| 420 |
} |
| 421 |
|
| 422 |
|
| 423 |
|
| 424 |
} |
| 425 |
catch(err) |
| 426 |
{ |
| 427 |
//Handle errors here |
| 428 |
} |
| 429 |
|
| 430 |
} |
| 431 |
|
| 432 |
//open another file and add to editor |
| 433 |
function wpide_set_file_contents(file, callback_func){ |
| 434 |
"use strict"; |
| 435 |
|
| 436 |
//ajax call to get file contents we are about to edit |
| 437 |
var data = { action: 'wpide_get_file', filename: file, _wpnonce: jQuery('#_wpnonce').val(), _wp_http_referer: jQuery('#_wp_http_referer').val() }; |
| 438 |
|
| 439 |
jQuery.post(ajaxurl, data, function(response) { |
| 440 |
var the_path = file.replace(/^.*[\\\/]/, ''); |
| 441 |
var the_id = "wpide_tab_" + last_added_editor_session; |
| 442 |
|
| 443 |
//enable editor now we have a file open |
| 444 |
jQuery('#fancyeditordiv textarea').removeAttr("disabled"); |
| 445 |
|
| 446 |
jQuery("#wpide_toolbar_tabs").append('<span id="'+the_id+'" sessionrel="'+last_added_editor_session+'" title=" '+file+' " rel="'+file+'" class="wpide_tab">'+ the_path +'</a> <a class="close_tab" href="#">x</a> '); |
| 447 |
|
| 448 |
saved_editor_sessions[last_added_editor_session] = new EditSession(response);//set saved session |
| 449 |
saved_editor_sessions[last_added_editor_session].on('change', onSessionChange); |
| 450 |
saved_undo_manager[last_added_editor_session] = new UndoManager(editor.getSession().getUndoManager());//new undo manager for this session |
| 451 |
|
| 452 |
last_added_editor_session++; //increment session counter |
| 453 |
|
| 454 |
//add click event for the new tab. |
| 455 |
//We are actually clearing the click event and adding it again for all tab elements, it's the only way I could get the click handler listening on all dynamically added tabs |
| 456 |
jQuery(".wpide_tab").off('click').on("click", function(event){ |
| 457 |
event.preventDefault(); |
| 458 |
|
| 459 |
jQuery('input[name=filename]').val( jQuery(this).attr('rel') ); |
| 460 |
|
| 461 |
//save current editor into session |
| 462 |
//get old editor out of session and apply to editor |
| 463 |
var clicksesh = jQuery(this).attr('sessionrel'); //editor id number |
| 464 |
saved_editor_sessions[ clicksesh ].setUndoManager(saved_undo_manager[ clicksesh ]); |
| 465 |
editor.setSession( saved_editor_sessions[ clicksesh ] ); |
| 466 |
|
| 467 |
//set this tab as active |
| 468 |
jQuery(".wpide_tab").removeClass('active'); |
| 469 |
jQuery(this).addClass('active'); |
| 470 |
|
| 471 |
var currentFilename = jQuery(this).attr('rel'); |
| 472 |
var mode; |
| 473 |
|
| 474 |
//turn autocomplete off initially, then enable as needed |
| 475 |
editor.getSession().enable_autocomplete = false; |
| 476 |
|
| 477 |
//set the editor mode based on file name |
| 478 |
if (/\.css$/.test(currentFilename)) { |
| 479 |
mode = require("ace/mode/css").Mode; |
| 480 |
} |
| 481 |
else if (/\.less$/.test(currentFilename)) { |
| 482 |
mode = require("ace/mode/less").Mode; |
| 483 |
} |
| 484 |
else if (/\.js$/.test(currentFilename)) { |
| 485 |
mode = require("ace/mode/javascript").Mode; |
| 486 |
} |
| 487 |
else { |
| 488 |
mode = require("ace/mode/php").Mode; //default to PHP |
| 489 |
|
| 490 |
//only enable session change / auto complete for PHP |
| 491 |
if (/\.php$/.test(currentFilename)) |
| 492 |
editor.getSession().enable_autocomplete = true; |
| 493 |
} |
| 494 |
editor.getSession().setMode(new mode()); |
| 495 |
|
| 496 |
editor.getSession().on('change', onSessionChange); |
| 497 |
|
| 498 |
editor.getSession().selection.on('changeSelection', selectionChanged); |
| 499 |
|
| 500 |
editor.resize(); |
| 501 |
editor.focus(); |
| 502 |
//make a note of current editor |
| 503 |
current_editor_session = clicksesh; |
| 504 |
|
| 505 |
//hide/show the restore button if it's a php file and the restore url is set (i.e saved in this session) |
| 506 |
if ( /\.php$/i.test( currentFilename ) && jQuery(".wpide_tab.active", "#wpide_toolbar").data( "backup" ) != undefined ){ |
| 507 |
jQuery("#wpide_toolbar_buttons .button.restore").show(); |
| 508 |
}else{ |
| 509 |
jQuery("#wpide_toolbar_buttons .button.restore").hide(); |
| 510 |
} |
| 511 |
|
| 512 |
//show hide unsaved content message |
| 513 |
if ( jQuery(".wpide_tab.active", "#wpide_toolbar").data( "unsaved" ) ){ |
| 514 |
jQuery("#wpide_footer_message_unsaved").html("[ Document contains unsaved content ✎ ]").show(); |
| 515 |
}else{ |
| 516 |
jQuery("#wpide_footer_message_unsaved").hide(); |
| 517 |
} |
| 518 |
|
| 519 |
//show last saved message if it's been saved |
| 520 |
if ( jQuery(".wpide_tab.active", "#wpide_toolbar").data( "lastsave" ) != undefined){ |
| 521 |
jQuery("#wpide_footer_message_last_saved").html("<strong>Last saved: </strong>" + jQuery(".wpide_tab.active", "#wpide_toolbar").data( "lastsave" ) ).show(); |
| 522 |
}else{ |
| 523 |
jQuery("#wpide_footer_message_last_saved").hide(); |
| 524 |
} |
| 525 |
|
| 526 |
//hide the message if we have a fresh tab |
| 527 |
jQuery("#wpide_message").hide(); |
| 528 |
}); |
| 529 |
|
| 530 |
//add click event for tab close. |
| 531 |
//We are actually clearing the click event and adding it again for all tab elements, it's the only way I could get the click handler listening on all dynamically added tabs |
| 532 |
jQuery(".close_tab").off('click').on("click", function(event){ |
| 533 |
event.preventDefault(); |
| 534 |
var clicksesh = jQuery(this).parent().attr('sessionrel'); |
| 535 |
var activeFallback; |
| 536 |
|
| 537 |
//if the currently selected tab is being removed then remember to make the first tab active |
| 538 |
if ( jQuery("#wpide_tab_"+clicksesh).hasClass('active') ) { |
| 539 |
activeFallback = true; |
| 540 |
}else{ |
| 541 |
activeFallback = false; |
| 542 |
} |
| 543 |
|
| 544 |
//remove tab |
| 545 |
jQuery(this).parent().remove(); |
| 546 |
|
| 547 |
//clear session and undo |
| 548 |
saved_undo_manager[clicksesh] = undefined; |
| 549 |
saved_editor_sessions[clicksesh] = undefined; |
| 550 |
|
| 551 |
//Clear the active editor if all tabs closed or activate first tab if required since the active tab may have been deleted |
| 552 |
if (jQuery(".wpide_tab").length == 0){ |
| 553 |
editor.getSession().setValue( "" ); |
| 554 |
}else if ( activeFallback ){ |
| 555 |
jQuery( "#" + jQuery(".wpide_tab")[0].id ).click(); |
| 556 |
} |
| 557 |
|
| 558 |
}); |
| 559 |
|
| 560 |
jQuery("#"+the_id).click(); |
| 561 |
|
| 562 |
if (callback_func != null) { |
| 563 |
callback_func(response); |
| 564 |
} |
| 565 |
|
| 566 |
}); |
| 567 |
|
| 568 |
|
| 569 |
} |
| 570 |
|
| 571 |
function saveDocument() { |
| 572 |
//ajax call to save the file and generate a backup if needed |
| 573 |
var data = { action: 'wpide_save_file', filename: jQuery('input[name=filename]').val(), _wpnonce: jQuery('#_wpnonce').val(), _wp_http_referer: jQuery('#_wp_http_referer').val(), content: editor.getSession().getValue() }; |
| 574 |
jQuery.post(ajaxurl, data, function(response) { |
| 575 |
var regexchk=/^\".*\"$/; |
| 576 |
var saved_when = Date(); |
| 577 |
|
| 578 |
if ( regexchk.test(response) ){ |
| 579 |
//store the resulting backup file name just incase we need to restore later |
| 580 |
//temp note: you can then access the data like so jQuery(".wpide_tab.active", "#wpide_toolbar").data( "backup" ); |
| 581 |
user_nonce_addition = response.match(/:::(.*)\"$/)[1]; //need this to send with restore request |
| 582 |
jQuery(".wpide_tab.active", "#wpide_toolbar").data( "backup", response.replace(/(^\"|:::.*\"$)/g, "") ); |
| 583 |
jQuery(".wpide_tab.active", "#wpide_toolbar").data( "lastsave", saved_when ); |
| 584 |
jQuery(".wpide_tab.active", "#wpide_toolbar").data( "unsaved", false); |
| 585 |
|
| 586 |
if ( /\.php$/i.test( data.filename ) ) |
| 587 |
jQuery("#wpide_toolbar_buttons .button.restore").show(); |
| 588 |
|
| 589 |
jQuery("#wpide_footer_message_last_saved").html("<strong>Last saved: </strong>" + saved_when).show(); |
| 590 |
jQuery("#wpide_footer_message_unsaved").hide(); |
| 591 |
|
| 592 |
jQuery("#wpide_message").html('<strong>File saved ✔</strong>') |
| 593 |
.show() |
| 594 |
.delay(2000) |
| 595 |
.fadeOut(600); |
| 596 |
}else{ |
| 597 |
alert("error: " + response); |
| 598 |
} |
| 599 |
}); |
| 600 |
} |
| 601 |
|
| 602 |
//enter/return command |
| 603 |
function selectACitem (item) { |
| 604 |
if( document.getElementById('ac').style.display === 'block' && oHandler.visible() == 'block' ){ |
| 605 |
var ac_dropdwn = document.getElementById('ac'); |
| 606 |
var tag = ac_dropdwn.options[ac_dropdwn.selectedIndex].value; |
| 607 |
var sel = editor.selection.getRange(); |
| 608 |
var line = editor.getSession().getLine(sel.start.row); |
| 609 |
sel.start.column = sel.start.column - autocompletelength; |
| 610 |
|
| 611 |
if (item.length){ |
| 612 |
tag = item; //get tag from new msdropdown passed as arg |
| 613 |
}else{ |
| 614 |
tag = jQuery("#ac_msdd a.selected").children("span.ddTitleText").text(); //get tag from new msdropdown |
| 615 |
} |
| 616 |
|
| 617 |
//clean up the tag/command |
| 618 |
tag = tag.replace(")", ""); //remove end parenthesis |
| 619 |
|
| 620 |
//console.log(tag); |
| 621 |
editor.selection.setSelectionRange(sel); |
| 622 |
editor.insert(tag); |
| 623 |
|
| 624 |
wpide_close_autocomplete(); |
| 625 |
} else { |
| 626 |
editor.insert('\n'); |
| 627 |
} |
| 628 |
} |
| 629 |
|
| 630 |
|
| 631 |
jQuery(document).ready(function($) { |
| 632 |
$("#wpide_save").click(saveDocument); |
| 633 |
|
| 634 |
// drag and drop colour picker image |
| 635 |
$("#wpide_color_assist").on('drop', function(e) { |
| 636 |
e.preventDefault(); |
| 637 |
e.originalEvent.dataTransfer.items[0].getAsString(function(url){ |
| 638 |
|
| 639 |
$(".ImageColorPickerCanvas", $("#side-info-column") ).remove(); |
| 640 |
$("img", $("#wpide_color_assist")).attr('src', url ); |
| 641 |
|
| 642 |
}); |
| 643 |
}); |
| 644 |
|
| 645 |
$("#wpide_color_assist").on('dragover', function(e) { |
| 646 |
$(this).addClass("hover"); |
| 647 |
}).on('dragleave', function(e) { |
| 648 |
$(this).removeClass("hover"); |
| 649 |
}); |
| 650 |
|
| 651 |
|
| 652 |
//add div for ace editor to latch on to |
| 653 |
$('#template').prepend("<div style='width:80%;height:500px;margin-right:0!important;' id='fancyeditordiv'></div>"); |
| 654 |
//create the editor instance |
| 655 |
editor = ace.edit("fancyeditordiv"); |
| 656 |
//turn off print margin |
| 657 |
editor.setPrintMarginColumn(false); |
| 658 |
//set the editor theme |
| 659 |
editor.setTheme("ace/theme/dawn"); |
| 660 |
//get a copy of the initial file contents (the file being edited) |
| 661 |
//var intialData = $('#newcontent').val() |
| 662 |
var intialData = "Use the file manager to find a file you wish edit, click the file name to edit. \n\n"; |
| 663 |
|
| 664 |
|
| 665 |
//startup info - usefull for debugging |
| 666 |
var data = { action: 'wpide_startup_check', _wpnonce: jQuery('#_wpnonce').val(), _wp_http_referer: jQuery('#_wp_http_referer').val() }; |
| 667 |
|
| 668 |
jQuery.post(ajaxurl, data, function(response) { |
| 669 |
if (response == "-1"){ |
| 670 |
intialData = intialData + "Permission/security problem with ajax request. Refresh WPide and try again. \n\n"; |
| 671 |
}else{ |
| 672 |
intialData = intialData + response; |
| 673 |
} |
| 674 |
|
| 675 |
editor.getSession().setValue( intialData ); |
| 676 |
|
| 677 |
}); |
| 678 |
|
| 679 |
|
| 680 |
|
| 681 |
//make initial editor read only |
| 682 |
$('#fancyeditordiv textarea').attr("disabled", "disabled"); |
| 683 |
|
| 684 |
//use editors php mode |
| 685 |
var phpMode = require("ace/mode/php").Mode; |
| 686 |
editor.getSession().setMode(new phpMode()); |
| 687 |
|
| 688 |
//START AUTOCOMPLETE |
| 689 |
//create the autocomplete dropdown |
| 690 |
var ac = document.createElement('select'); |
| 691 |
ac.id = 'ac'; |
| 692 |
ac.name = 'ac'; |
| 693 |
ac.style.position='absolute'; |
| 694 |
ac.style.zIndex=100; |
| 695 |
ac.style.width='auto'; |
| 696 |
ac.style.display='none'; |
| 697 |
ac.style.height='auto'; |
| 698 |
ac.size=10; |
| 699 |
editor.container.appendChild(ac); |
| 700 |
|
| 701 |
//hook onto any change in editor contents |
| 702 |
editor.getSession().on('change', onSessionChange);//end editor change event |
| 703 |
|
| 704 |
|
| 705 |
|
| 706 |
//START COMMANDS |
| 707 |
|
| 708 |
//Key up command |
| 709 |
editor.commands.addCommand({ |
| 710 |
name: "up", |
| 711 |
bindKey: { |
| 712 |
win: "Up", |
| 713 |
mac: "Up", |
| 714 |
sender: "editor" |
| 715 |
}, |
| 716 |
|
| 717 |
exec: function(env, args, request) { |
| 718 |
if (oHandler && oHandler.visible() === 'block'){ |
| 719 |
oHandler.previous(); |
| 720 |
|
| 721 |
//show command help panel for this command |
| 722 |
wpide_function_help(); |
| 723 |
//console.log("handler is visible"); |
| 724 |
|
| 725 |
}else if( document.getElementById('ac').style.display === 'block' ) { |
| 726 |
var select=document.getElementById('ac'); |
| 727 |
if( select.selectedIndex === 0 ) { |
| 728 |
select.selectedIndex = select.options.length-1; |
| 729 |
} else { |
| 730 |
select.selectedIndex = select.selectedIndex-1; |
| 731 |
} |
| 732 |
//console.log("ac is visible"); |
| 733 |
} else { |
| 734 |
var range = editor.getSelectionRange(); |
| 735 |
editor.clearSelection(); |
| 736 |
editor.moveCursorTo(range.end.row - 1, range.end.column); |
| 737 |
} |
| 738 |
} |
| 739 |
}); |
| 740 |
|
| 741 |
|
| 742 |
//key down command |
| 743 |
editor.commands.addCommand({ |
| 744 |
name: "down", |
| 745 |
bindKey: { |
| 746 |
win: "Down", |
| 747 |
mac: "Down", |
| 748 |
sender: "editor" |
| 749 |
}, |
| 750 |
exec: function(env, args, request) { |
| 751 |
|
| 752 |
if (oHandler && oHandler.visible() === 'block'){ |
| 753 |
oHandler.next(); |
| 754 |
|
| 755 |
//show command help panel for this command |
| 756 |
wpide_function_help(); |
| 757 |
|
| 758 |
}else if ( document.getElementById('ac').style.display === 'block' ) { |
| 759 |
var select=document.getElementById('ac'); |
| 760 |
if ( select.selectedIndex === select.options.length-1 ) { |
| 761 |
select.selectedIndex=0; |
| 762 |
} else { |
| 763 |
select.selectedIndex=select.selectedIndex+1; |
| 764 |
} |
| 765 |
} else { |
| 766 |
var range = editor.getSelectionRange(); |
| 767 |
editor.clearSelection(); |
| 768 |
editor.moveCursorTo(range.end.row +1, range.end.column); |
| 769 |
} |
| 770 |
} |
| 771 |
}); |
| 772 |
|
| 773 |
|
| 774 |
|
| 775 |
editor.commands.addCommand({ |
| 776 |
name: "enter", |
| 777 |
bindKey: { |
| 778 |
win: "Return", |
| 779 |
mac: "Return", |
| 780 |
sender: "editor" |
| 781 |
}, |
| 782 |
exec: selectACitem |
| 783 |
}); |
| 784 |
|
| 785 |
// save command: |
| 786 |
editor.commands.addCommand({ |
| 787 |
name: "save", |
| 788 |
bindKey: { |
| 789 |
win: "Ctrl-S", |
| 790 |
mac: "Command-S", |
| 791 |
sender: "editor" |
| 792 |
}, |
| 793 |
exec: saveDocument |
| 794 |
}); |
| 795 |
|
| 796 |
//END COMMANDS |
| 797 |
|
| 798 |
|
| 799 |
//click action for new directory/file submit link |
| 800 |
$("#wpide_create_new_directory, #wpide_create_new_file").click(function(e){ |
| 801 |
e.preventDefault(); |
| 802 |
|
| 803 |
var data_input = jQuery(this).parent().find("input.has_data"); |
| 804 |
var item = eval('('+ data_input.attr("rel") +')'); |
| 805 |
|
| 806 |
//item.path file|directory |
| 807 |
var data = { action: 'wpide_create_new', path: item.path, type: item.type, file: data_input.val(), _wpnonce: jQuery('#_wpnonce').val(), _wp_http_referer: jQuery('#_wp_http_referer').val() }; |
| 808 |
|
| 809 |
jQuery.post(ajaxurl, data, function(response) { |
| 810 |
|
| 811 |
if (response == "1"){ |
| 812 |
//remove the file/dir name from the text input |
| 813 |
data_input.val(""); |
| 814 |
|
| 815 |
if ( jQuery("ul.jqueryFileTree a[rel='"+ item.path +"']").length == 0){ |
| 816 |
|
| 817 |
//if no parent then we are adding something to the wp-content folder so regenerate the whole filetree |
| 818 |
the_filetree(); |
| 819 |
|
| 820 |
} |
| 821 |
|
| 822 |
//click the parent once to hide |
| 823 |
jQuery("ul.jqueryFileTree a[rel='"+ item.path +"']").click(); |
| 824 |
|
| 825 |
//hide the parent input block |
| 826 |
data_input.parent().hide(); |
| 827 |
|
| 828 |
//click the parent once again to show with new folder and focus on this area |
| 829 |
jQuery("ul.jqueryFileTree a[rel='"+ item.path +"']").click(); |
| 830 |
jQuery("ul.jqueryFileTree a[rel='"+ item.path +"']").focus(); |
| 831 |
|
| 832 |
}else if (response == "-1"){ |
| 833 |
alert("Permission/security problem. Refresh WPide and try again."); |
| 834 |
}else{ |
| 835 |
alert(response); |
| 836 |
} |
| 837 |
|
| 838 |
|
| 839 |
}); |
| 840 |
|
| 841 |
}); |
| 842 |
|
| 843 |
});//end jquery load |
| 844 |
|