diff --git a/doc/connect_remote.html b/doc/connect_remote.html
index 73d9a13..1dfb7c7 100644
--- a/doc/connect_remote.html
+++ b/doc/connect_remote.html
@@ -32,6 +32,7 @@
ol{
text-align: left;
width: fit-content;
+ width: -moz-fit-content;
margin:0 auto;
}
ul li{list-style-position: inside;}
diff --git a/doc/localhost.html b/doc/localhost.html
index c897934..a884601 100644
--- a/doc/localhost.html
+++ b/doc/localhost.html
@@ -32,6 +32,7 @@
ol,ul{
text-align: left;
width: fit-content;
+ width: -moz-fit-content;
margin:0 auto;
}
ul li{list-style-position: inside;}
diff --git a/licenses.html b/licenses.html
index 6bf75c4..5605ab1 100644
--- a/licenses.html
+++ b/licenses.html
@@ -35,7 +35,7 @@
-
![Scroll bottom](res/icon.jpg)
+
DB:
diff --git a/php/100.php b/php/100.php
index e443f30..889fd33 100644
--- a/php/100.php
+++ b/php/100.php
@@ -4,17 +4,16 @@
* Login
*/
- $LOCALHOST=(($_SERVER["SERVER_ADDR"]=="::1" || $_SERVER["SERVER_ADDR"]=="127.0.0.1") ? true:false); // Turn true to allow localhost connections.
- //$LOCALHOST=true; // Enable this line and comment the previous one to allow localhost access.
- error_reporting(E_ALL ^ E_WARNING); // Supress warnings, comment to debug.
+ require("config.php");
+ if(!$DEBUG_MODE){error_reporting(E_ALL ^ E_WARNING);} // Supress warnings
session_start();
require("conn.php");
$h=$_REQUEST["h"];
$hn=$h;
- if(!$LOCALHOST){
+ if(!$_CONFIG["allow_localhost"]){
if($h == "localhost"){die("For security reasons, conections to 'localhost' are bloqued. Learn more about localhost
here.
Return");}
}
$u=$_REQUEST["u"];
@@ -31,6 +30,6 @@
die("
[System] Conection failed - ".mysqli_connect_errno()."
".mysqli_connect_error()."
Return");
}
- //header('Location: ../main');
+ //header('Location: ../main'); // This won't work on some servers
die('
');
?>
diff --git a/php/101.php b/php/101.php
index a5e65ec..4846a8a 100644
--- a/php/101.php
+++ b/php/101.php
@@ -4,7 +4,9 @@
* Used by AJAX JavaScript to execute an SQL query and return its result.
*/
- error_reporting(E_ALL ^ E_WARNING); // Supress warnings, comment to debug.
+
+ require("config.php");
+ if(!$DEBUG_MODE){error_reporting(E_ALL ^ E_WARNING);} // Supress warnings
session_start();
require("conn.php");
diff --git a/php/102.php b/php/102.php
index 426ad5a..ba958a7 100644
--- a/php/102.php
+++ b/php/102.php
@@ -4,10 +4,11 @@
* Log out
*/
+
session_start();
session_unset();
- //header('Location: ../login');
+ //header('Location: ../login'); // This won't work on some servers
die('
');
?>
diff --git a/php/103.php b/php/103.php
index 0083ddc..8c75a91 100644
--- a/php/103.php
+++ b/php/103.php
@@ -4,7 +4,9 @@
* Returns the hintOptions[table] for the code editor using AJAX.
*/
- error_reporting(E_ALL ^ E_WARNING); // Supress warnings, comment to debug.
+
+ require("config.php");
+ if(!$DEBUG_MODE){error_reporting(E_ALL ^ E_WARNING);} // Supress warnings
session_start();
require("conn.php");
diff --git a/php/config.php b/php/config.php
new file mode 100644
index 0000000..ef977a6
--- /dev/null
+++ b/php/config.php
@@ -0,0 +1,14 @@
+
diff --git a/script.js b/script.js
index 8158208..0e7265c 100644
--- a/script.js
+++ b/script.js
@@ -1,4 +1,4 @@
-var cardHTML = '
';
+var cardHTML = '
';
var defaults = {
lineNumbers: true,
matchBrackets: true,
@@ -12,11 +12,16 @@ var defaults = {
lineWrapping: true,
hintOptions: {}
};
+var snippets=[];
+var snippetsHTML="";
var G_TEXTAREA=null;
function CopyBtn(btn_elem){
var textarea = btn_elem.parentElement.children[0];
- navigator.clipboard.writeText(textarea.value);
+ copyTextToClipboard(textarea.value);
+}
+function CopySnippet(this_elm){
+ copyTextToClipboard(snippets[this_elm.value][1]);
}
function SelectNext(btn_elem,ind){
var elm = btn_elem.parentElement.children[ind];
@@ -30,6 +35,7 @@ function RunQuery(){
G_TEXTAREA.setAttribute("readonly","true");
table.parentElement.style.backgroundColor="var(--color2)";
G_TEXTAREA.parentElement.lastChild.setAttribute("onclick","CopyBtn(this)");
+ G_TEXTAREA.parentElement.lastChild.previousSibling.setAttribute("disabled","true");
G_TEXTAREA.parentElement.lastChild.value="Copy";
ExecQuery(val,table.children[1].children[1],table.children[2].children[1]);
@@ -44,14 +50,29 @@ function InstantiateCard(){
G_TEXTAREA = document.querySelector(".card:last-child textarea");
window.editor = CodeMirror.fromTextArea(G_TEXTAREA, defaults);
- ScrollBottom();
+
+ if(snippetsHTML==""){ // Never loaded snippets.txt
+ G_TEXTAREA.parentElement.lastChild.previousSibling.style.display="none";
+ GetSnippets();
+
+ // Wait 100 milliseconds.
+ setTimeout(function () {
+ if(snippetsHTML!=""){
+ G_TEXTAREA.parentElement.lastChild.previousSibling.innerHTML = snippetsHTML;
+ G_TEXTAREA.parentElement.lastChild.previousSibling.style.display="inline";
+ }
+ }, 100);
+ }else{
+ G_TEXTAREA.parentElement.lastChild.previousSibling.innerHTML = snippetsHTML;
+ }
AutocompletChanged();
GetTableHint();
+ ScrollBottom();
}
function ExecQuery(sqlstr,resulte,rawr){
- console.log(sqlstr);
+ console.debug("SQL: "+sqlstr);
if (sqlstr.length == 0) {
InstantiateCard();
} else {
@@ -62,7 +83,7 @@ function ExecQuery(sqlstr,resulte,rawr){
if (this.readyState == 4 && this.status == 200) {
var res=this.responseText;
- console.log(res);
+ console.debug("RAW: "+res);
rawr.innerHTML=escapeHtml(res);
resulte.parentElement.style.display="table-row";
@@ -75,11 +96,10 @@ function ExecQuery(sqlstr,resulte,rawr){
InstantiateCard();
return;
}
- console.log(resarray);
+ console.debug("Parsed: "+resarray);
var pres="";
for (var i = 0; i < resarray.length; i++) {
- console.log(typeof resarray[i]);
if(typeof resarray[i]==="boolean" || resarray[i].length==0){
pres+="
No result.
";
}else if(typeof resarray[i] !== "object"){
@@ -125,9 +145,8 @@ function AutocompletChanged(){
if(document.getElementById("totalCompletion").checked){
window.editor.on("keyup", function (cm, event) {
var cr=cm.getCursor();
- var pr_char=cm.getLine(cr["line"]).charCodeAt([cr["ch"]]-1); // Character before cursor.
-
- if(pr_char===undefined || pr_char<48 || pr_char===59){return false;} // Not autocomplete if its <"0", OR ; " '
+ var pr_char=cm.getLine(cr["line"]).charAt([cr["ch"]]-1); // Character before cursor.
+ if(pr_char===undefined || (pr_char!="." && !(/^[a-zA-Z0-9]+$/).test(pr_char))){return false;} // Not autocomplete if its not alfanumeric.
if (!cm.state.completionActive && event.keyCode != 13) {
CodeMirror.commands.autocomplete(cm, null, {completeSingle: false});
@@ -157,6 +176,51 @@ function GetTableHint(){
}
}
}
+function GetSnippets(){
+ var xmlhttp = new XMLHttpRequest();
+ xmlhttp.onreadystatechange = function() {
+ if (this.readyState == 4 && this.status == 200) {
+ var res=this.responseText;
+ res=res.split("\n");
+
+ for (var i = 0; i < res.length; i++) {
+ if(res[i].toString().trim()==="---"){continue;}
+
+ res[i]=res[i].split("::");
+ if(res[i].length<2){
+ res.splice(i, 1);
+ continue;
+ }
+
+ res[i][1]=res[i][1].replace(/\\n/g,"\n").replace(/\\t/g,"\t");
+ }
+
+ snippets=res;
+
+ snippetsHTML='
';
+ var groupclosing=false;
+ for (var i = 0; i < snippets.length; i++) {
+ if(snippets[i].toString().trim()==="---"){
+ snippetsHTML+='
';
+ continue;
+ }else if(snippets[i][0]===""){
+ if(groupclosing){snippetsHTML+="
";}
+
+ snippetsHTML+='
';
+ snippetsHTML+='
";}
+ snippetsHTML+='
';
+ }
+ };
+ xmlhttp.open("GET", "snippets.txt", true);
+ xmlhttp.send();
+}
/* EXTRAS */
@@ -187,3 +251,30 @@ function escapeHtml(text) {
return text.replace(/[&<>"']/g, function(m) { return map[m]; });
}
+function copyTextToClipboard(text) {
+ if (!navigator.clipboard) {
+ var textArea = document.createElement("textarea");
+ textArea.value = text;
+
+ // Avoid scrolling to bottom
+ textArea.style.position = "fixed";
+ textArea.style.top = "0";
+ textArea.style.left = "0";
+
+ document.body.appendChild(textArea);
+ textArea.focus();
+ textArea.select();
+
+ try {
+ document.execCommand('copy');
+ } catch (err) {
+ console.error('Fallback: Oops, unable to copy', err);
+ }
+
+ document.body.removeChild(textArea);
+ return;
+ }
+ navigator.clipboard.writeText(text).then(function() {}, function(err) {
+ console.error('Async: Could not copy text. ', err);
+ });
+}
diff --git a/snippets.txt b/snippets.txt
new file mode 100644
index 0000000..c6c70fb
--- /dev/null
+++ b/snippets.txt
@@ -0,0 +1,28 @@
+::General
+Select *::SELECT * FROM table_name;
+Select::SELECT column1, column2, columnN\nFROM table_name\nWHERE condition;
+Update::UPDATE table_name\nSET column1=value, column2=value, columnN=value\nWHERE condition;
+Insert into::INSERT INTO table_name (column1,column2,columnN)\nVALUES (value1,value2,valueN);
+Delete::DELETE FROM table_name\nWHERE 0; -- Change this
+::Database
+Show databases::SHOW DATABASES;
+Create database::CREATE DATABASE database_name;
+Drop database::DROP DATABASE database_name;
+::Table
+Show tables::SHOW TABLES;
+Create table::CREATE TABLE table_name (\n\tid int PRIMARY KEY,\n\tcolumn2 datatype,\n\tcolumn3 datatype,\n\tcolumnN datatype\n);
+Drop table::DROP TABLE table_name;
+Truncate table::TRUNCATE TABLE table_name;
+---
+Show columns::SELECT ORDINAL_POSITION AS "N", COLUMN_NAME AS "Column Name", COLUMN_TYPE AS "Datatype", COLUMN_KEY AS "Key", EXTRA\nFROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = N'table_name';
+Add column::ALTER TABLE table_name\nADD column_name datatype;
+Drop column::ALTER TABLE table_name\nDROP COLUMN column_name;
+Modify column::ALTER TABLE table_name\nMODIFY COLUMN column_name datatype;
+::Users
+Show users::SELECT User, Host, CASE\n WHEN Password="" THEN "NO" ELSE "YES"\nEND AS "Using password" FROM mysql.user;
+Create user::CREATE USER 'username'@'localhost' IDENTIFIED BY 'user_password'; -- This user will not have any privileges. Use GRANT to assign them.
+Grant privileges::GRANT INSERT, UPDATE, DELETE, ... /* For all privileges use: ALL PRIVILEGES */\nON table_name\nTO username@localhost;
+Drop user::DROP USER 'username'@'localhost';
+::Misc
+Set autoincrement::ALTER TABLE table_name AUTO_INCREMENT=100;
+CASE Statement::CASE\n\tWHEN condition1 THEN result1\n\tWHEN condition2 THEN result2\n\tWHEN conditionN THEN resultN\n\tELSE result\nEND
diff --git a/style.css b/style.css
index fbfd853..a9e14f3 100644
--- a/style.css
+++ b/style.css
@@ -64,6 +64,14 @@ tt{
background-color:rgba(0,0,0,0.05);
border-radius: 3px;
}
+optgroup{font-weight: bold;font-style: normal;}
+select option[disabled]{
+ font-weight: bold;
+ color:red;
+}
+select option.separator{
+ font-size: 0.25em;
+}
.center{text-align: center;}
.mono{font-family: 'Roboto',monospace;}
@@ -77,12 +85,16 @@ input[type="text"],input[type="password"]{
}
.button{
font-family: sans-serif;
- padding:6px 12px;
+ padding:0.5em 1em;
cursor:pointer;
}
+.button.little{
+ font-size:10px;
+}
+
.tip{
border-bottom: 1px dotted var(--aux2);
- font-family: monospace;
+ font-family: 'Roboto',monospace;
}
#top{height:32px;}
@@ -102,9 +114,10 @@ input[type="text"],input[type="password"]{
margin-right: 6px;
vertical-align: middle;
}
+#topbar hr{cursor:default;}
#topbar span{
cursor: text;
- font-family: monospace;
+ font-family: 'Roboto',monospace;
margin-right: 12px;
user-select: text;
}
@@ -131,6 +144,7 @@ input[type="text"],input[type="password"]{
background-color: var(--color44);
box-shadow: 0 9px 20px 0px #000;
margin:16px;
+ overflow-x: auto;
}
.card table{
width:100%;