Utility for running PHP code inside the browser (Laravel package)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
php-sandbox/src/assets/php-console.js

261 lines
6.1 KiB

/*jslint browser: true */
/*global ace, jQuery */
/**
* PHP Console
*
* A web-based php sandbox
*
* Copyright (C)
* 2010, Jordi Boggiano <j.boggiano@seld.be>
* 2015, Ondřej Hruška <ondra@ondrovo.com>
*
* Licensed under the new BSD License
* See the LICENSE file for details
*
* Source on Github http://github.com/MightyPork/php-sandbox
*/
(function (require, $, ace) {
"use strict";
var updateStatusBar,
handleSubmit,
initializeAce,
handleAjaxError,
options,
editor,
Storage;
options = {
tabsize: 4,
editor: 'editor'
};
Storage = new function() {
this.saves = JSON.parse(localStorage.sbxSaves || '{}');
this.active = localStorage.sbxActiveSlot || 'Scratch';
this.getCode = function () {
this._populSlot();
this._persist();
return this.saves[this.active];
};
this._persist = function () {
localStorage.sbxActiveSlot = this.active;
localStorage.sbxSaves = JSON.stringify(this.saves);
};
this.setCode = function(code) {
this.saves[this.active] = code;
this._persist();
};
this.deleteSave = function() {
delete this.saves[this.active];
var first = 'Scratch';
for (first in this.saves) break;
this.selectSlot(first);
};
this.storeCurrentCode = function () {
var code = editor.getSession().getValue();
this.setCode(code);
};
this._populSlot = function () {
if (typeof(this.saves[this.active]) == 'undefined') {
this.saves[this.active] = window.defcode;
}
};
this.selectSlot = function(name) {
this.active = name;
this._populSlot();
this._persist();
initSlotSelect();
editor.getSession().setValue(Storage.getCode());
};
};
/**
* updates the text of the status bar
*/
updateStatusBar = function (e) {
var cursor_position = editor.getCursorPosition();
$('.statusbar .position').text('@ ' + (1 + cursor_position.row) + ':' + (1+cursor_position.column));
};
/**
* does an async request to eval the php code and displays the result
*/
handleSubmit = function (e) {
e.preventDefault();
//$('div.output').html('<img src="loader.gif" class="loader" alt="" /> Loading ...'); /* loader sucks */
// store session
Storage.storeCurrentCode();
// eval server-side
jQuery.ajax ({
url: '?js=1',
type: "POST",
data: JSON.stringify({code: editor.getSession().getValue()}),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (res, status, jqXHR) {
if (res.memory || res.duration) {
$('.statusbar .runtime-info').text('Load: ' + res.memory + ' MB, ' + res.duration + ' ms');
} else {
$('.statusbar .runtime-info').text('');
}
var out = res.output;
if (out.match(/#end-php-console-output#$/)) {
out = out.substring(0, out.length - 24);
$('div.output').text(out);
} else {
$('div.output').text(out + "\n\n*** Script ended unexpectedly. ***");
}
},
error: function (event, jqxhr, settings, exception) {
var txt = event.responseText;
var is_dd = txt.indexOf('Sfdump = window.Sfdump') != -1;
var err = txt.indexOf('error') != -1 && txt.indexOf('file') != -1 && txt.indexOf('line') != -1;
if (is_dd && !err) {
$('div.output').html(event.responseText);
} else {
$('div.output').html("<p><em>Error occured while posting your code.</em></p>" + event.responseText);
}
}
});
};
initializeAce = function () {
var PhpMode, code, storedCode;
// reload last session
code = Storage.getCode();
$('#' + options.editor).replaceWith('<div id="' + options.editor + '" class="' + options.editor + '"></div>');
$('#' + options.editor).text(code);
editor = ace.edit(options.editor);
editor.$blockScrolling = Infinity;
editor.focus();
editor.gotoLine(3, 0);
editor.setTheme("ace/theme/monokai");
editor.setOptions({
showPrintMargin: false,
fontSize: '18px',
enableBasicAutocompletion: true
});
// set mode
PhpMode = require("ace/mode/php").Mode;
editor.getSession().setMode(new PhpMode());
// tab size
if (options.tabsize) {
editor.getSession().setTabSize(options.tabsize);
editor.getSession().setUseSoftTabs(true);
} else {
editor.getSession().setUseSoftTabs(false);
}
// events
editor.getSession().selection.on('changeCursor', updateStatusBar);
// commands
editor.commands.addCommand({
name: 'submitForm',
bindKey: {
win: 'Ctrl-Return|Alt-Return',
mac: 'Command-Return|Alt-Return'
},
exec: function (editor) {
$('form').submit();
}
});
};
var initSlotSelect = function () {
var $ss = $('#saves').empty();
$.each(Storage.saves, function(k, v) {
var $opt = $('<option>');
$opt.attr('value', k);
$opt.text(k);
if (Storage.active == k) $opt.attr('selected', true);
$ss.append($opt);
});
};
$.console = function (settings) {
$.extend(options, settings);
$(function () {
$(document).ready(initializeAce);
$('form').on('submit', handleSubmit);
// make sure the slot is ready
Storage.getCode();
initSlotSelect();
// Change slot (reload text)
$('#saves').on('change', function () {
Storage.storeCurrentCode();
Storage.selectSlot($(this).val());
editor.focus();
});
// New slot
$('#btn-new').on('click', function () {
var name = prompt("New slot name", moment().format('Y-MM-DD h:mm:ss'));
if (name === null) return;
Storage.selectSlot(name);
// cursor to the bottom
editor.getSession().selection.moveCursorFileEnd();
editor.focus();
});
// Delete slot
$('#btn-del').on('click', function () {
if (!confirm("Delete save "+Storage.active+"?")) return;
Storage.deleteSave();
editor.focus();
});
// Rename
$('#btn-ren').on('click', function () {
var name = prompt("New name for slot " + Storage.active);
if (name === null) return;
if (typeof Storage.saves[name] != 'undefined') {
alert("Name already used!");
return;
}
Storage.saves[name] = Storage.saves[Storage.active];
delete Storage.saves[Storage.active];
Storage.selectSlot(name);
editor.focus();
});
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
}
});
});
};
}(ace.require, jQuery, ace));