From 14057d763b025967812420499f4866177674f176 Mon Sep 17 00:00:00 2001 From: Joel Kemp Date: Tue, 21 Jan 2014 10:31:21 -0500 Subject: [PATCH 1/3] Default to unsafe version on dev and sandbox on live --- eval/unsafe.php | 38 ++++++++++++++++++++++++++++++++++++++ scripts/phpepl.js | 24 ++++++++++++++++-------- scripts/phpepl.min.js | 2 +- 3 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 eval/unsafe.php diff --git a/eval/unsafe.php b/eval/unsafe.php new file mode 100644 index 0000000..d7f73df --- /dev/null +++ b/eval/unsafe.php @@ -0,0 +1,38 @@ +", " $result, + 'error' => $error + )); + + @ini_set('display_errors', $token); + @ini_set('log_errors', $inString); + + function getJsonOutput($options) { + $result = $options['result']; + $error = $options['error']; + return json_encode(array("result" => $result, "error" => $error)); + } +?> \ No newline at end of file diff --git a/scripts/phpepl.js b/scripts/phpepl.js index d2e22a4..05b907f 100644 --- a/scripts/phpepl.js +++ b/scripts/phpepl.js @@ -1,14 +1,22 @@ (function (window, document, $, moment) { 'use strict'; - // COMMON - var dev = 'http://localhost/eval/index.php', - live = 'http://phpepl.cloudcontrolled.com/eval/index.php', - - // Switch this to devURL if you want to code locally - evalURL = live, - - mixpanel= window.mixpanel || {}, + var + // Detect the port that localhost is running on + port = window.location.host.split(':')[1] || '80', + // No sandbox on your local server + devUnsafe = 'http://localhost:' + port + '/eval/unsafe.php', + // Sanboxed on your local server (really only for testing live locally) + dev = 'http://localhost:' + port + '/eval/index.php', + // Sandboxed on the remote (online) server + live = 'http://phpepl.cloudcontrolled.com/eval/index.php', + + // Safeguard to always use the live eval on the remote server + // and the unsafe dev version otherwise. + isLiveEnv = window.location.host === 'phpepl.cloudcontrolled.com', + evalURL = isLiveEnv ? live : devUnsafe, + + mixpanel = window.mixpanel || {}, editor; // HELPERS diff --git a/scripts/phpepl.min.js b/scripts/phpepl.min.js index 3b1e070..6241c2e 100644 --- a/scripts/phpepl.min.js +++ b/scripts/phpepl.min.js @@ -1 +1 @@ -(function(e,t,n,r){"use strict";var i="http://localhost/eval/index.php",s="http://phpepl.cloudcontrolled.com/eval/index.php",o=s,u=e.mixpanel||{},a,f=function(e){var t=!!arguments[1],i=n(".output span");i.html(e).removeClass("error");t&&i.addClass("error");n(".spinner").fadeOut("fast");n(".timestamp").find("span").html(r((new Date).getTime()).format("h:mm a"))},l=function(e){n(".CodeMirror-linenumber").each(function(){if(Number(n(this).html())===e){n(this).addClass("error-gutter");return}})},c=function(e){if(!e.length)return;var t=e,r=["\n",/
/g,//g,/<\/b>/g,/(Fatal error: +)/g],i,s,o,u;if(!e.toLowerCase().indexOf("fatal error"))return[e,1];n.each(r,function(e,n){t=t.replace(n,"")});i=t.split("in");s=i[0].trim();i=t.split("on");o=i[1].trim();t=(s+" on "+o).trim();u=o.split(" ");u=Number(u[1]);return[t,u]},h=function(e){return n.ajax({type:"POST",url:o,data:{code:e},dataType:"json"})},p=function(){var e=a.getValue();if(!e.length){f("Please supply some code...");return}n(".spinner").fadeIn("fast");u.track("Code Run",{code:e});h(e).done(function(e){if(!e)return;var t=e.result,n=e.error,r="";if(n){if(n.line&&n.message){l(n.line);r="Line "+n.line+": "}r+=n.message;f(r,!0);return}f(t)}).fail(function(e){if(!e)return;var t=c(e.responseText);f(t[0],!0);l(t[1]);u.track("Error",{error:e.responseText})})},d=function(){if(e.localStorage){var t=a.getValue();localStorage.setItem("code",t);n(".timestamp").find("span").html("Code Saved!");u.track("Code Saved")}},v=function(){if(e.localStorage){var t='echo "We\'re running php version: " . phpversion();',n=localStorage.getItem("code"),r=n?n:t;a.setValue(r)}};a=e.CodeMirror(n("#editor")[0],{lineNumbers:!0,matchBrackets:!0,mode:"text/x-php",indentUnit:2,tabSize:2,autofocus:!0,autoCloseBrackets:!0});v();n(".submit button").click(p);n(t).keydown(function(e){if(e.which===13&&(e.ctrlKey||e.metaKey)){p();e.preventDefault()}if(e.which===83&&(e.ctrlKey||e.metaKey)){d();e.preventDefault();u.track("Save Shortcut")}});n(e).unload(d)})(window,document,window.jQuery,window.moment); \ No newline at end of file +(function(e,t,n,r){"use strict";var i=e.location.host.split(":")[1]||"80",s="http://localhost:"+i+"/eval/unsafe.php",o="http://localhost:"+i+"/eval/index.php",u="http://phpepl.cloudcontrolled.com/eval/index.php",a=e.location.host==="phpepl.cloudcontrolled.com",f=a?u:s,l=e.mixpanel||{},c,h=function(e){var t=!!arguments[1],i=n(".output span");i.html(e).removeClass("error");t&&i.addClass("error");n(".spinner").fadeOut("fast");n(".timestamp").find("span").html(r((new Date).getTime()).format("h:mm a"))},p=function(e){n(".CodeMirror-linenumber").each(function(){if(Number(n(this).html())===e){n(this).addClass("error-gutter");return}})},d=function(e){if(!e.length)return;var t=e,r=["\n",/
/g,//g,/<\/b>/g,/(Fatal error: +)/g],i,s,o,u;if(!e.toLowerCase().indexOf("fatal error"))return[e,1];n.each(r,function(e,n){t=t.replace(n,"")});i=t.split("in");s=i[0].trim();i=t.split("on");o=i[1].trim();t=(s+" on "+o).trim();u=o.split(" ");u=Number(u[1]);return[t,u]},v=function(e){return n.ajax({type:"POST",url:f,data:{code:e},dataType:"json"})},m=function(){var e=c.getValue();if(!e.length){h("Please supply some code...");return}n(".spinner").fadeIn("fast");l.track("Code Run",{code:e});v(e).done(function(e){if(!e)return;var t=e.result,n=e.error,r="";if(n){if(n.line&&n.message){p(n.line);r="Line "+n.line+": "}r+=n.message;h(r,!0);return}h(t)}).fail(function(e){if(!e)return;var t=d(e.responseText);h(t[0],!0);p(t[1]);l.track("Error",{error:e.responseText})})},g=function(){if(e.localStorage){var t=c.getValue();localStorage.setItem("code",t);n(".timestamp").find("span").html("Code Saved!");l.track("Code Saved")}},y=function(){if(e.localStorage){var t='echo "We\'re running php version: " . phpversion();',n=localStorage.getItem("code"),r=n?n:t;c.setValue(r)}};c=e.CodeMirror(n("#editor")[0],{lineNumbers:!0,matchBrackets:!0,mode:"text/x-php",indentUnit:2,tabSize:2,autofocus:!0,autoCloseBrackets:!0});y();n(".submit button").click(m);n(t).keydown(function(e){if(e.which===13&&(e.ctrlKey||e.metaKey)){m();e.preventDefault()}if(e.which===83&&(e.ctrlKey||e.metaKey)){g();e.preventDefault();l.track("Save Shortcut")}});n(e).unload(g)})(window,document,window.jQuery,window.moment); \ No newline at end of file From e640e9fd6ae9b8cab8bf68326e450151377c78bf Mon Sep 17 00:00:00 2001 From: Joel Kemp Date: Tue, 21 Jan 2014 10:38:42 -0500 Subject: [PATCH 2/3] Styling and fork instructions --- css/styles.css | 2 +- css/styles.scss | 16 ++++++++++++---- index.haml | 15 ++++++++------- index.html | 3 +++ 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/css/styles.css b/css/styles.css index 7a24c40..1f40f05 100644 --- a/css/styles.css +++ b/css/styles.css @@ -1 +1 @@ -@-webkit-keyframes fade{0%{opacity:1}100%{opacity:0.25}}body{font-family:sans-serif}.container{width:75%;height:auto;margin:0 auto}.container .code{font-family:Courier}.container .header{width:100%;float:left;text-align:center;margin:0 0 5px 0}.container .header .title{width:100%;float:left}.container .header .title span{color:black;font-size:46px}.container .header .description{width:100%;float:left}.container .header .description span{color:black;font-size:17px;font-style:italic}.container .codebox{float:left;width:100%}.container .codebox .codebox-cont{width:80%;margin:0 auto}.container .codebox .codebox-cont #editor{font-size:17px;border:1px solid black;margin-bottom:10px}.container .codebox .codebox-cont #editor .CodeMirror{min-height:450px}.container .codebox .codebox-cont .output{float:left;width:100%;height:120px;position:relative;border:1px solid black;margin-bottom:10px;background-color:#eee;overflow:auto}.container .codebox .codebox-cont .output .spinner{position:absolute;display:none;top:8%;left:40%;width:100px;height:100px;margin:0 auto}.container .codebox .codebox-cont .output .spinner div{width:12%;height:26%;background:#000;position:absolute;left:44.5%;top:37%;opacity:0;-webkit-animation:fade 1s linear infinite;-webkit-border-radius:50px;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.2)}.container .codebox .codebox-cont .output .spinner div.bar1{-webkit-transform:rotate(0deg) translate(0, -142%);-webkit-animation-delay:0s}.container .codebox .codebox-cont .output .spinner div.bar2{-webkit-transform:rotate(30deg) translate(0, -142%);-webkit-animation-delay:-0.9167s}.container .codebox .codebox-cont .output .spinner div.bar3{-webkit-transform:rotate(60deg) translate(0, -142%);-webkit-animation-delay:-0.833s}.container .codebox .codebox-cont .output .spinner div.bar4{-webkit-transform:rotate(90deg) translate(0, -142%);-webkit-animation-delay:-0.75s}.container .codebox .codebox-cont .output .spinner div.bar5{-webkit-transform:rotate(120deg) translate(0, -142%);-webkit-animation-delay:-0.667s}.container .codebox .codebox-cont .output .spinner div.bar6{-webkit-transform:rotate(150deg) translate(0, -142%);-webkit-animation-delay:-0.5833s}.container .codebox .codebox-cont .output .spinner div.bar7{-webkit-transform:rotate(180deg) translate(0, -142%);-webkit-animation-delay:-0.5s}.container .codebox .codebox-cont .output .spinner div.bar8{-webkit-transform:rotate(210deg) translate(0, -142%);-webkit-animation-delay:-0.41667s}.container .codebox .codebox-cont .output .spinner div.bar9{-webkit-transform:rotate(240deg) translate(0, -142%);-webkit-animation-delay:-0.333s}.container .codebox .codebox-cont .output .spinner div.bar10{-webkit-transform:rotate(270deg) translate(0, -142%);-webkit-animation-delay:-0.25s}.container .codebox .codebox-cont .output .spinner div.bar11{-webkit-transform:rotate(300deg) translate(0, -142%);-webkit-animation-delay:-0.1667s}.container .codebox .codebox-cont .output .spinner div.bar12{-webkit-transform:rotate(330deg) translate(0, -142%);-webkit-animation-delay:-0.0833s}.container .codebox .codebox-cont .output .output-container{margin:5px 10px}.container .codebox .codebox-cont .output .output-container span{font-family:"Lucida Console", Monaco, monospace;color:black;font-size:16px}.container .codebox .codebox-cont .output .output-container span.error{color:red}.container .timestamp{height:21px;position:relative;text-align:right;right:-3px;top:-28px}.container .timestamp span{color:#888;font-size:15px;font-style:italic;margin-top:5px;margin-right:5px}.container .submit{width:100%;position:relative;float:left;text-align:center}.container .submit span{display:block;font-family:Courier;margin-bottom:5px}.container .submit button{width:150px;height:40px;cursor:pointer;border-radius:7px;border-top-radius:10px;-moz-border-radius-top:10px;-webkit-border-top-radius:10px;font-size:20px}.credits{width:100%;float:left;margin-top:5px;position:relative;text-align:center}.credits span,.credits a{font-style:italic;font-size:13px}.error-gutter{background-color:red} +@-webkit-keyframes fade{0%{opacity:1}100%{opacity:0.25}}body{font-family:sans-serif}.container{width:75%;height:auto;margin:0 auto}.container .code{font-family:Courier}.container .header{width:100%;float:left;text-align:center;margin:0 0 5px 0}.container .header .title{width:100%;float:left}.container .header .title span{color:black;font-size:46px}.container .header .description{width:100%;float:left}.container .header .description span{color:black;font-size:17px;font-style:italic}.container .codebox{float:left;width:100%}.container .codebox .codebox-cont{width:80%;margin:0 auto}.container .codebox .codebox-cont #editor{font-size:17px;border:1px solid black;margin-bottom:10px}.container .codebox .codebox-cont #editor .CodeMirror{min-height:450px}.container .codebox .codebox-cont .output{float:left;width:100%;height:120px;position:relative;border:1px solid black;margin-bottom:10px;background-color:#eee;overflow:auto}.container .codebox .codebox-cont .output .spinner{position:absolute;display:none;top:8%;left:40%;width:100px;height:100px;margin:0 auto}.container .codebox .codebox-cont .output .spinner div{width:12%;height:26%;background:#000;position:absolute;left:44.5%;top:37%;opacity:0;-webkit-animation:fade 1s linear infinite;-webkit-border-radius:50px;-webkit-box-shadow:0 0 3px rgba(0,0,0,0.2)}.container .codebox .codebox-cont .output .spinner div.bar1{-webkit-transform:rotate(0deg) translate(0, -142%);-webkit-animation-delay:0s}.container .codebox .codebox-cont .output .spinner div.bar2{-webkit-transform:rotate(30deg) translate(0, -142%);-webkit-animation-delay:-0.9167s}.container .codebox .codebox-cont .output .spinner div.bar3{-webkit-transform:rotate(60deg) translate(0, -142%);-webkit-animation-delay:-0.833s}.container .codebox .codebox-cont .output .spinner div.bar4{-webkit-transform:rotate(90deg) translate(0, -142%);-webkit-animation-delay:-0.75s}.container .codebox .codebox-cont .output .spinner div.bar5{-webkit-transform:rotate(120deg) translate(0, -142%);-webkit-animation-delay:-0.667s}.container .codebox .codebox-cont .output .spinner div.bar6{-webkit-transform:rotate(150deg) translate(0, -142%);-webkit-animation-delay:-0.5833s}.container .codebox .codebox-cont .output .spinner div.bar7{-webkit-transform:rotate(180deg) translate(0, -142%);-webkit-animation-delay:-0.5s}.container .codebox .codebox-cont .output .spinner div.bar8{-webkit-transform:rotate(210deg) translate(0, -142%);-webkit-animation-delay:-0.41667s}.container .codebox .codebox-cont .output .spinner div.bar9{-webkit-transform:rotate(240deg) translate(0, -142%);-webkit-animation-delay:-0.333s}.container .codebox .codebox-cont .output .spinner div.bar10{-webkit-transform:rotate(270deg) translate(0, -142%);-webkit-animation-delay:-0.25s}.container .codebox .codebox-cont .output .spinner div.bar11{-webkit-transform:rotate(300deg) translate(0, -142%);-webkit-animation-delay:-0.1667s}.container .codebox .codebox-cont .output .spinner div.bar12{-webkit-transform:rotate(330deg) translate(0, -142%);-webkit-animation-delay:-0.0833s}.container .codebox .codebox-cont .output .output-container{margin:5px 10px}.container .codebox .codebox-cont .output .output-container span{font-family:"Lucida Console", Monaco, monospace;color:black;font-size:16px}.container .codebox .codebox-cont .output .output-container span.error{color:red}.container .timestamp{height:21px;position:relative;text-align:right;right:-3px;top:-28px}.container .timestamp span{color:#888;font-size:15px;font-style:italic;margin-top:5px;margin-right:5px}.container .submit{width:100%;position:relative;float:left;text-align:center;margin-bottom:3px}.container .submit span{display:block;font-family:Courier;margin-bottom:5px}.container .submit button{width:150px;height:40px;cursor:pointer;border-radius:7px;border-top-radius:10px;-moz-border-radius-top:10px;-webkit-border-top-radius:10px;font-size:20px}.fork-info{width:100%;text-align:center}.fork-info span{font-style:italic;font-size:12px}.credits{width:100%;float:left;margin-top:5px;position:relative;text-align:center}.credits span,.credits a{font-style:italic;font-size:13px}.error-gutter{background-color:red} diff --git a/css/styles.scss b/css/styles.scss index 41cb09b..fed92a0 100644 --- a/css/styles.scss +++ b/css/styles.scss @@ -55,7 +55,7 @@ body { .codebox-cont { width: 80%; margin: 0 auto; - #editor { + #editor { font-size: 17px; border: 1px solid black; margin-bottom: 10px; @@ -92,7 +92,7 @@ body { -webkit-animation: fade 1s linear infinite; -webkit-border-radius: 50px; -webkit-box-shadow: 0 0 3px rgba(0,0,0,0.2); - &.bar1 {-webkit-transform:rotate(0deg) translate(0, -142%); -webkit-animation-delay: 0s;} + &.bar1 {-webkit-transform:rotate(0deg) translate(0, -142%); -webkit-animation-delay: 0s;} &.bar2 {-webkit-transform:rotate(30deg) translate(0, -142%); -webkit-animation-delay: -0.9167s;} &.bar3 {-webkit-transform:rotate(60deg) translate(0, -142%); -webkit-animation-delay: -0.833s;} &.bar4 {-webkit-transform:rotate(90deg) translate(0, -142%); -webkit-animation-delay: -0.75s;} @@ -108,7 +108,7 @@ body { } .output-container{ margin: 5px 10px; - span { + span { font-family: "Lucida Console", Monaco, monospace; color: black; font-size: 16px; @@ -141,6 +141,7 @@ body { position: relative; float: left; text-align: center; + margin-bottom: 3px; span { display: block; font-family: Courier; @@ -157,7 +158,14 @@ body { } } - +.fork-info { + width: 100%; + text-align: center; + span { + font-style: italic; + font-size: 12px; + } +} .credits { width: 100%; diff --git a/index.haml b/index.haml index af0a554..d9a9117 100644 --- a/index.haml +++ b/index.haml @@ -8,7 +8,7 @@ %title PHPepl: The PHP REPL %link{:rel => "stylesheet", :href => "lib/codemirror/lib/codemirror.css?ver=3.18"} %link{:rel => "stylesheet", :href => "css/styles.css?ver=1.2"} - :javascript + :javascript var _gaq = _gaq || []; _gaq.push(['_setAccount', 'UA-36055599-1']); _gaq.push(['_trackPageview']); @@ -18,13 +18,13 @@ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })(); - + (function(e,b){if(!b.__SV){var a,f,i,g;window.mixpanel=b;a=e.createElement("script");a.type="text/javascript";a.async=!0;a.src=("https:"===e.location.protocol?"https:":"http:")+'//cdn.mxpnl.com/libs/mixpanel-2.2.min.js';f=e.getElementsByTagName("script")[0];f.parentNode.insertBefore(a,f);b._i=[];b.init=function(a,e,d){function f(b,h){var a=h.split(".");2==a.length&&(b=b[a[0]],h=a[1]);b[h]=function(){b.push([h].concat(Array.prototype.slice.call(arguments,0)))}}var c=b;"undefined"!==typeof d?c=b[d]=[]:d="mixpanel";c.people=c.people||[];c.toString=function(b){var a="mixpanel";"mixpanel"!==d&&(a+="."+d);b||(a+=" (stub)");return a};c.people.toString=function(){return c.toString(1)+".people (stub)"};i="disable track track_pageview track_links track_forms register register_once alias unregister identify name_tag set_config people.set people.increment people.append people.track_charge".split(" ");for(g=0;g"https://twitter.com/mrjoelkemp", :class=>"twitter-follow-button" } Follow @mrjoelkemp :javascript @@ -66,7 +68,7 @@ %script{:src => "lib/jquery-1.8.2.min.js"} %script{:src => "lib/codemirror/lib/codemirror.js?ver=3.18"} %script{:src => "lib/codemirror/addon/edit/closebrackets.js"} - + %script{:src => "lib/codemirror/addon/edit/matchbrackets.js"} %script{:src => "lib/codemirror/mode/htmlmixed/htmlmixed.js"} %script{:src => "lib/codemirror/mode/xml/xml.js"} @@ -74,9 +76,8 @@ %script{:src => "lib/codemirror/mode/css/css.js"} %script{:src => "lib/codemirror/mode/clike/clike.js"} %script{:src => "lib/codemirror/mode/php/php.js"} - + %script{:src => "lib/moment/moment.min.js"} / %script{:src => "scripts/phpepl.js"} %script{:src => "scripts/phpepl.min.js?ver=1.3"} - \ No newline at end of file diff --git a/index.html b/index.html index 7f2e465..0980f37 100644 --- a/index.html +++ b/index.html @@ -67,6 +67,9 @@ ⌘ + Enter or Ctrl + Enter +
+ Fork the project and serve locally for an unsandboxed experience +