mikuli.cz

:)
git clone https://git.sr.ht/~ashymad/mikuli.cz
Log | Files | Refs

commit 4609608c5ac6637439774487cff29a93339dca8a
parent 2be8f7ff0e90761eb0b8930a30682db72d39378f
Author: markseu <mark2011@mayberg.se>
Date:   Sat,  4 Nov 2017 17:11:34 +0100

System update (refactoring)

Diffstat:
Msystem/plugins/edit.css | 33+++++++++++++++------------------
Msystem/plugins/edit.js | 217+++++++++++++++++++++++++++++++++++++++----------------------------------------
Msystem/plugins/edit.php | 191++++++++++++++++++++++++++++++++++++++-----------------------------------------
3 files changed, 212 insertions(+), 229 deletions(-)

diff --git a/system/plugins/edit.css b/system/plugins/edit.css @@ -2,26 +2,27 @@ /* Copyright (c) 2013-2017 Datenstrom, https://datenstrom.se */ /* This file may be used and distributed under the terms of the public license. */ -.yellow-bar { position:relative; overflow:hidden; height:2em; margin-bottom:10px; } +.yellow-bar { position:relative; overflow:hidden; line-height:2em; margin-bottom:10px; } .yellow-bar-left { display:block; float:left; } .yellow-bar-right { display:block; float:right; } .yellow-bar-right a { margin-left:1em; } .yellow-bar-right #yellow-pane-create-link { padding:0 0.5em; } .yellow-bar-right #yellow-pane-delete-link { padding:0 0.5em; } +.yellow-bar-banner { clear:both; } .yellow-body-modal-open { overflow:hidden; } - .yellow-pane { - position:absolute; display:none; z-index:100; - margin:10px 0; padding:10px; + position:absolute; display:none; z-index:100; padding:10px; background-color:#fff; color:#000; border:1px solid #bbb; border-radius:4px; box-shadow:2px 4px 10px rgba(0, 0, 0, 0.2); } -.yellow-pane h1 { color:#000; } +.yellow-pane h1 { color:#000; font-size:2em; margin:0 1em; } .yellow-pane p { margin:0.5em; } -.yellow-pane ul { list-style:none; margin:0 0.5em; padding:0; } .yellow-pane div { overflow:hidden; } -.yellow-close { display:block; float:right; padding:0 0.5em; font-size:1.1em; color:#bbb; text-decoration:none; } +.yellow-close { + position:absolute; + top:0.4em; right:0.8em; cursor:pointer; + font-size:1.2em; color:#bbb; text-decoration:none; } .yellow-close:hover { color:#000; text-decoration:none; } .yellow-arrow { position:absolute; top:0; left:0; } .yellow-arrow:after, .yellow-arrow:before { @@ -43,7 +44,10 @@ border-width:11px; margin-left:-11px; } - +.yellow-dropdown { list-style:none; margin:0; padding:0; } +.yellow-dropdown span { display:block; margin:0; padding:0.25em 1em; } +.yellow-dropdown a { display:block; padding:0.2em 1em; text-decoration:none; } +.yellow-dropdown a:hover { color:#fff; background-color:#18e; text-decoration:none; } .yellow-form-control { margin:0; padding:2px 4px; display:inline-block; @@ -64,6 +68,7 @@ outline-offset:-2px; font-size:0.9em; font-family:inherit; font-weight:normal; line-height:1; text-align:center; text-decoration:none; + box-sizing:border-box; } .yellow-btn:hover, .yellow-btn:focus, .yellow-btn:active { color:#333333; @@ -79,7 +84,6 @@ .yellow-btn-delete:hover, .yellow-btn-delete:focus, .yellow-btn-delete:active { color:#ffffff; } #yellow-pane-login { text-align:center; white-space:nowrap; } -#yellow-pane-login h1 { margin:0 1em; font-size:2em; } #yellow-pane-login .yellow-form-control { width:15em; box-sizing:border-box; } #yellow-pane-login .yellow-btn { width:15em; margin:1em 1em 0.5em 0; } #yellow-pane-login-fields { width:15em; text-align:left; margin:0 auto; } @@ -87,7 +91,6 @@ #yellow-pane-login-buttons p { margin:0; } #yellow-pane-signup { text-align:center; white-space:nowrap; } -#yellow-pane-signup h1 { margin:0 1em; font-size:2em; } #yellow-pane-signup .yellow-form-control { width:15em; box-sizing:border-box; } #yellow-pane-signup .yellow-btn { width:15em; margin:1em 1em 0.5em 0; } #yellow-pane-signup-status { margin:0.5em 0; display:inline-block; } @@ -95,7 +98,6 @@ #yellow-pane-signup-buttons { margin-top:-0.5em; } #yellow-pane-recover { text-align:center; white-space:nowrap; } -#yellow-pane-recover h1 { margin:0 1em; font-size:2em; } #yellow-pane-recover .yellow-form-control { width:15em; box-sizing:border-box; } #yellow-pane-recover .yellow-btn { width:15em; margin:1em 1em 0.5em 0; } #yellow-pane-recover-status { margin:0.5em 0; display:inline-block; } @@ -103,7 +105,6 @@ #yellow-pane-recover-buttons { margin-top:-0.5em; } #yellow-pane-settings { text-align:center; white-space:nowrap; } -#yellow-pane-settings h1 { margin:0 1em; font-size:2em; } #yellow-pane-settings .yellow-form-control { width:15em; box-sizing:border-box; } #yellow-pane-settings .yellow-btn { width:15em; margin:1em 1em 0.5em 0; } #yellow-pane-settings-status { margin:0.5em 0; display:inline-block; } @@ -111,19 +112,15 @@ #yellow-pane-settings-buttons { margin-top:-0.5em; } #yellow-pane-version { text-align:center; white-space:nowrap; } -#yellow-pane-version h1 { margin:0 1em; font-size:2em; } #yellow-pane-version .yellow-btn { width:15em; margin:1em 1em 0.5em 0; } #yellow-pane-version-status { margin:0.5em 0; display:inline-block; } #yellow-pane-version-fields { text-align:center; margin:0.5em 0; } #yellow-pane-version-buttons { margin-top:-0.5em; } -#yellow-pane-edit { } -#yellow-pane-edit h1 { margin:0 0 10px 0; font-size:2em; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; } +#yellow-pane-edit h1 { margin:0 0 10px 0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; } #yellow-pane-edit-page { padding:5px; outline:none; resize:none; } #yellow-pane-edit-buttons { margin-top:5px; } #yellow-pane-edit-buttons input { margin-right:10px; } #yellow-pane-edit-help { float:right; } -#yellow-pane-user { cursor:pointer; } -#yellow-pane-user a { text-decoration:none; } -#yellow-pane-user a:hover { text-decoration:underline; } +#yellow-pane-user { padding:10px 0; } diff --git a/system/plugins/edit.js b/system/plugins/edit.js @@ -6,8 +6,9 @@ var yellow = { action: function(action, status, args) { yellow.edit.action(action, status, args); }, onLoad: function() { yellow.edit.load(); }, - onClick: function(e) { yellow.edit.hidePanesOnClick(e.target); }, - onKeydown: function(e) { yellow.edit.hidePanesOnKeydown(e.keyCode); }, + onClickAction: function(e) { yellow.edit.clickAction(e); }, + onClick: function(e) { yellow.edit.click(e); }, + onKeydown: function(e) { yellow.edit.keydown(e); }, onUpdate: function() { yellow.edit.updatePane(yellow.edit.paneId, yellow.edit.paneAction, yellow.edit.paneStatus); }, onResize: function() { yellow.edit.resizePane(yellow.edit.paneId, yellow.edit.paneAction, yellow.edit.paneStatus); } }; @@ -20,6 +21,19 @@ yellow.edit = paneStatus: 0, //current pane status intervalId: 0, //timer interval ID + // Handle initialisation + load: function() + { + var body = document.getElementsByTagName("body")[0]; + if(body && body.firstChild && !document.getElementById("yellow-bar")) + { + this.createBar("yellow-bar"); + this.createPane("yellow-pane-edit", "none", "none"); + this.action(yellow.page.action, yellow.page.status); + clearInterval(this.intervalId); + } + }, + // Handle action action: function(action, status, args) { @@ -49,17 +63,29 @@ yellow.edit = } }, - // Load interface - load: function() + // Handle action clicked + clickAction: function(e) { - var body = document.getElementsByTagName("body")[0]; - if(body && body.firstChild && !document.getElementById("yellow-bar")) + e.stopPropagation(); + e.preventDefault(); + var element = e.target; + for(; element; element=element.parentNode) { - this.createBar("yellow-bar"); - this.createPane("yellow-pane-edit", "none", "none"); - this.action(yellow.page.action, yellow.page.status); - clearInterval(this.intervalId); + if(element.tagName=="A") break; } + this.action(element.getAttribute("data-action"), element.getAttribute("data-status"), element.getAttribute("data-args")); + }, + + // Handle mouse clicked + click: function(e) + { + if(this.paneId && !document.getElementById(this.paneId).contains(e.target)) this.hidePane(this.paneId); + }, + + // Handle keyboard + keydown: function(e) + { + if(this.paneId && e.keyCode==27) this.hidePane(this.paneId); }, // Create bar @@ -75,20 +101,24 @@ yellow.edit = yellow.toolbox.addEvent(document, "keydown", yellow.onKeydown); yellow.toolbox.addEvent(window, "resize", yellow.onResize); } + var elementDiv = document.createElement("div"); + elementDiv.setAttribute("id", barId+"-content"); if(yellow.config.userName) { - elementBar.innerHTML = + elementDiv.innerHTML = "<div class=\"yellow-bar-left\">"+ - "<a href=\"#\" onclick=\"yellow.action('edit'); return false;\" id=\"yellow-pane-edit-link\">"+this.getText("Edit")+"</a>"+ + "<a href=\"#\" id=\"yellow-pane-edit-link\" data-action=\"edit\">"+this.getText("Edit")+"</a>"+ "</div>"+ "<div class=\"yellow-bar-right\">"+ - "<a href=\"#\" onclick=\"yellow.action('create'); return false;\" id=\"yellow-pane-create-link\">"+this.getText("Create")+"</a>"+ - "<a href=\"#\" onclick=\"yellow.action('delete'); return false;\" id=\"yellow-pane-delete-link\">"+this.getText("Delete")+"</a>"+ - "<a href=\"#\" onclick=\"yellow.action('user'); return false;\" id=\"yellow-pane-user-link\">"+yellow.toolbox.encodeHtml(yellow.config.userName)+"</a>"+ - "</div>"; + "<a href=\"#\" id=\"yellow-pane-create-link\" data-action=\"create\">"+this.getText("Create")+"</a>"+ + "<a href=\"#\" id=\"yellow-pane-delete-link\" data-action=\"delete\">"+this.getText("Delete")+"</a>"+ + "<a href=\"#\" id=\"yellow-pane-user-link\" data-action=\"user\">"+yellow.toolbox.encodeHtml(yellow.config.userName)+"</a>"+ + "</div>"+ + "<div class=\"yellow-bar-banner\"></div>"; } + elementBar.appendChild(elementDiv); yellow.toolbox.insertBefore(elementBar, document.getElementsByTagName("body")[0].firstChild); - return elementBar; + this.bindActions(elementBar); }, // Create pane @@ -101,8 +131,7 @@ yellow.edit = elementPane.style.display = "none"; if(paneId=="yellow-pane-edit") { - yellow.toolbox.addEvent(elementPane, "keyup", yellow.onUpdate); - yellow.toolbox.addEvent(elementPane, "change", yellow.onUpdate); + yellow.toolbox.addEvent(elementPane, "input", yellow.onUpdate); } if(paneId=="yellow-pane-edit" || paneId=="yellow-pane-user") { @@ -118,7 +147,7 @@ yellow.edit = case "yellow-pane-login": elementDiv.innerHTML = "<form method=\"post\">"+ - "<a href=\"#\" onclick=\"yellow.action('close'); return false;\" class=\"yellow-close\">x</a>"+ + "<a href=\"#\" class=\"yellow-close\" data-action=\"close\">x</a>"+ "<h1>"+this.getText("LoginTitle")+"</h1>"+ "<div id=\"yellow-pane-login-fields\">"+ "<input type=\"hidden\" name=\"action\" value=\"login\" />"+ @@ -127,15 +156,15 @@ yellow.edit = "<p><input class=\"yellow-btn\" type=\"submit\" value=\""+this.getText("LoginButton")+"\" /></p>"+ "</div>"+ "<div id=\"yellow-pane-login-buttons\">"+ - "<p><a href=\"#\" onclick=\"yellow.action('recover'); return false;\" id=\"yellow-pane-login-recover\">"+this.getText("LoginRecover")+"</a><p>"+ - "<p><a href=\"#\" onclick=\"yellow.action('signup'); return false;\" id=\"yellow-pane-login-signup\">"+this.getText("LoginSignup")+"</a><p>"+ + "<p><a href=\"#\" id=\"yellow-pane-login-recover\" data-action=\"recover\">"+this.getText("LoginRecover")+"</a><p>"+ + "<p><a href=\"#\" id=\"yellow-pane-login-signup\" data-action=\"signup\">"+this.getText("LoginSignup")+"</a><p>"+ "</div>"+ "</form>"; break; case "yellow-pane-signup": elementDiv.innerHTML = "<form method=\"post\">"+ - "<a href=\"#\" onclick=\"yellow.action('close'); return false;\" class=\"yellow-close\">x</a>"+ + "<a href=\"#\" class=\"yellow-close\" data-action=\"close\">x</a>"+ "<h1>"+this.getText("SignupTitle")+"</h1>"+ "<div id=\"yellow-pane-signup-status\" class=\""+paneStatus+"\">"+this.getText(paneAction+"Status", "", paneStatus)+"</div>"+ "<div id=\"yellow-pane-signup-fields\">"+ @@ -146,14 +175,14 @@ yellow.edit = "<p><input class=\"yellow-btn\" type=\"submit\" value=\""+this.getText("SignupButton")+"\" /></p>"+ "</div>"+ "<div id=\"yellow-pane-signup-buttons\">"+ - "<p><input class=\"yellow-btn\" type=\"button\" onclick=\"yellow.action('close'); return false;\" value=\""+this.getText("OkButton")+"\" /></p>"+ + "<p><a href=\"#\" class=\"yellow-btn\" data-action=\"close\">"+this.getText("OkButton")+"</a></p>"+ "</div>"+ "</form>"; break; case "yellow-pane-recover": elementDiv.innerHTML = "<form method=\"post\">"+ - "<a href=\"#\" onclick=\"yellow.action('close'); return false;\" class=\"yellow-close\">x</a>"+ + "<a href=\"#\" class=\"yellow-close\" data-action=\"close\">x</a>"+ "<h1>"+this.getText("RecoverTitle")+"</h1>"+ "<div id=\"yellow-pane-recover-status\" class=\""+paneStatus+"\">"+this.getText(paneAction+"Status", "", paneStatus)+"</div>"+ "<div id=\"yellow-pane-recover-fields-first\">"+ @@ -166,63 +195,76 @@ yellow.edit = "<p><input class=\"yellow-btn\" type=\"submit\" value=\""+this.getText("OkButton")+"\" /></p>"+ "</div>"+ "<div id=\"yellow-pane-recover-buttons\">"+ - "<p><input class=\"yellow-btn\" type=\"button\" onclick=\"yellow.action('close'); return false;\" value=\""+this.getText("OkButton")+"\" /></p>"+ + "<p><a href=\"#\" class=\"yellow-btn\" data-action=\"close\">"+this.getText("OkButton")+"</a></p>"+ "</div>"+ "</form>"; break; case "yellow-pane-settings": + var rawDataLanguages = ""; + if(yellow.config.serverLanguages && Object.keys(yellow.config.serverLanguages).length>1) + { + rawDataLanguages += "<p>"; + for(var language in yellow.config.serverLanguages) + { + var checked = language==this.getRequest("language") ? " checked=\"checked\"" : ""; + rawDataLanguages += "<label for=\"yellow-pane-settings-"+language+"\"><input type=\"radio\" name=\"language\" id=\"yellow-pane-settings-"+language+"\" value=\""+language+"\""+checked+"> "+yellow.toolbox.encodeHtml(yellow.config.serverLanguages[language])+"</label><br />"; + } + rawDataLanguages += "</p>"; + } elementDiv.innerHTML = "<form method=\"post\">"+ - "<a href=\"#\" onclick=\"yellow.action('close'); return false;\" class=\"yellow-close\">x</a>"+ + "<a href=\"#\" class=\"yellow-close\" data-action=\"close\">x</a>"+ "<h1 id=\"yellow-pane-settings-title\">"+this.getText("SettingsTitle")+"</h1>"+ "<div id=\"yellow-pane-settings-status\" class=\""+paneStatus+"\">"+this.getText(paneAction+"Status", "", paneStatus)+"</div>"+ "<div id=\"yellow-pane-settings-fields\">"+ "<input type=\"hidden\" name=\"action\" value=\"settings\" />"+ "<p><label for=\"yellow-pane-settings-name\">"+this.getText("SignupName")+"</label><br /><input class=\"yellow-form-control\" name=\"name\" id=\"yellow-pane-settings-name\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("name"))+"\" /></p>"+ "<p><label for=\"yellow-pane-settings-email\">"+this.getText("SignupEmail")+"</label><br /><input class=\"yellow-form-control\" name=\"email\" id=\"yellow-pane-settings-email\" maxlength=\"64\" value=\""+yellow.toolbox.encodeHtml(this.getRequest("email"))+"\" /></p>"+ - "<p><label for=\"yellow-pane-settings-password\">"+this.getText("SignupPassword")+"</label><br /><input class=\"yellow-form-control\" type=\"password\" name=\"password\" id=\"yellow-pane-settings-password\" maxlength=\"64\" value=\"\" /></p>"+this.getLanguages(paneId)+ + "<p><label for=\"yellow-pane-settings-password\">"+this.getText("SignupPassword")+"</label><br /><input class=\"yellow-form-control\" type=\"password\" name=\"password\" id=\"yellow-pane-settings-password\" maxlength=\"64\" value=\"\" /></p>"+rawDataLanguages+ "<p><input class=\"yellow-btn\" type=\"submit\" value=\""+this.getText("OkButton")+"\" /></p>"+ "</div>"+ "<div id=\"yellow-pane-settings-buttons\">"+ - "<p><input class=\"yellow-btn\" type=\"button\" onclick=\"yellow.action('close'); return false;\" value=\""+this.getText("OkButton")+"\" /></p>"+ + "<p><a href=\"#\" class=\"yellow-btn\" data-action=\"close\">"+this.getText("OkButton")+"</a></p>"+ "</div>"+ "</form>"; break; case "yellow-pane-version": elementDiv.innerHTML = "<form method=\"post\">"+ - "<a href=\"#\" onclick=\"yellow.action('close'); return false;\" class=\"yellow-close\">x</a>"+ + "<a href=\"#\" class=\"yellow-close\" data-action=\"close\">x</a>"+ "<h1 id=\"yellow-pane-version-title\">"+yellow.toolbox.encodeHtml(yellow.config.serverVersion)+"</h1>"+ "<div id=\"yellow-pane-version-status\" class=\""+paneStatus+"\">"+this.getText("VersionStatus", "", paneStatus)+"</div>"+ "<div id=\"yellow-pane-version-fields\">"+yellow.page.rawDataOutput+"</div>"+ "<div id=\"yellow-pane-version-buttons\">"+ - "<p><input class=\"yellow-btn\" type=\"button\" onclick=\"yellow.action('close'); return false;\" value=\""+this.getText("OkButton")+"\" /></p>"+ + "<p><a href=\"#\" class=\"yellow-btn\" data-action=\"close\">"+this.getText("OkButton")+"</a></p>"+ "</div>"+ "</form>"; break; case "yellow-pane-edit": elementDiv.innerHTML = "<form method=\"post\">"+ - "<a href=\"#\" onclick=\"yellow.action('close'); return false;\" class=\"yellow-close\">x</a>"+ + "<a href=\"#\" class=\"yellow-close\" data-action=\"close\">x</a>"+ "<h1 id=\"yellow-pane-edit-title\">"+this.getText("Edit")+"</h1>"+ "<textarea id=\"yellow-pane-edit-page\" class=\"yellow-form-control\" name=\"rawdataedit\"></textarea>"+ "<div id=\"yellow-pane-edit-buttons\">"+ - "<input id=\"yellow-pane-edit-send\" class=\"yellow-btn\" type=\"button\" onclick=\"yellow.action('send'); return false;\" value=\""+this.getText("EditButton")+"\" />"+ + "<a href=\"#\" id=\"yellow-pane-edit-send\" class=\"yellow-btn\" data-action=\"send\">"+this.getText("EditButton")+"</a>"+ "<a href=\""+this.getText("MarkdownHelpUrl", "yellow")+"\" target=\"_blank\" id=\"yellow-pane-edit-help\">"+this.getText("MarkdownHelp")+"</a>" + "</div>"+ "</form>"; break; case "yellow-pane-user": elementDiv.innerHTML = - "<p>"+yellow.toolbox.encodeHtml(yellow.config.userEmail)+"</p>"+ - "<p><a href=\"#\" onclick=\"yellow.action('settings'); return false;\">"+this.getText("SettingsTitle")+"</a></p>" + - "<p><a href=\"#\" onclick=\"yellow.action('help'); return false;\">"+this.getText("UserHelp")+"</a></p>" + - "<p><a href=\"#\" onclick=\"yellow.action('logout'); return false;\">"+this.getText("UserLogout")+"</a></p>"; + "<ul class=\"yellow-dropdown\">"+ + "<li><span>"+yellow.toolbox.encodeHtml(yellow.config.userEmail)+"</span></li>"+ + "<li><a href=\"#\" data-action=\"settings\">"+this.getText("SettingsTitle")+"</a></li>" + + "<li><a href=\"#\" data-action=\"help\">"+this.getText("UserHelp")+"</a></li>" + + "<li><a href=\"#\" data-action=\"logout\">"+this.getText("UserLogout")+"</a></li>"+ + "</ul>"; break; } elementPane.appendChild(elementDiv); yellow.toolbox.insertAfter(elementPane, document.getElementsByTagName("body")[0].firstChild); - return elementPane; + this.bindActions(elementPane); }, // Update pane @@ -261,7 +303,7 @@ yellow.edit = yellow.toolbox.setVisible(document.getElementById("yellow-pane-settings-buttons"), !showFields); if(paneStatus=="none") { - document.getElementById("yellow-pane-settings-status").innerHTML = "<a href=\"#\" onclick=\"yellow.action('version'); return false;\">"+this.getText("VersionTitle")+"</a>"; + document.getElementById("yellow-pane-settings-status").innerHTML = "<a href=\"#\" data-action=\"version\">"+this.getText("VersionTitle")+"</a>"; document.getElementById("yellow-pane-settings-name").value = yellow.config.userName; document.getElementById("yellow-pane-settings-email").value = yellow.config.userEmail; document.getElementById("yellow-pane-settings-"+yellow.config.userLanguage).checked = true; @@ -276,7 +318,7 @@ yellow.edit = } if(paneStatus=="updates" && yellow.config.userWebmaster) { - document.getElementById("yellow-pane-version-status").innerHTML = "<a href=\"#\" onclick=\"yellow.action('update'); return false;\">"+this.getText("VersionUpdateNormal")+"</a>"; + document.getElementById("yellow-pane-version-status").innerHTML = "<a href=\"#\" data-action=\"update\">"+this.getText("VersionUpdateNormal")+"</a>"; } break; case "yellow-pane-edit": @@ -294,28 +336,28 @@ yellow.edit = document.getElementById("yellow-pane-edit-page").value = string; yellow.toolbox.setCursorPosition(document.getElementById("yellow-pane-edit-page"), 0); } - paneAction = this.getPaneAction(paneId, paneAction); var key, className, readOnly; - switch(paneAction) + switch(this.getAction(paneId, paneAction)) { case "create": key = "CreateButton"; className = "yellow-btn yellow-btn-create"; readOnly = false; break; case "edit": key = "EditButton"; className = "yellow-btn yellow-btn-edit"; readOnly = false; break; case "delete": key = "DeleteButton"; className = "yellow-btn yellow-btn-delete"; readOnly = false; break; case "": key = "CancelButton"; className = "yellow-btn yellow-btn-cancel"; readOnly = true; break; } - document.getElementById("yellow-pane-edit-send").value = this.getText(key); + document.getElementById("yellow-pane-edit-send").innerHTML = this.getText(key); document.getElementById("yellow-pane-edit-send").className = className; document.getElementById("yellow-pane-edit-page").readOnly = readOnly; break; } + this.bindActions(document.getElementById(paneId)); }, // Resize pane resizePane: function(paneId, paneAction, paneStatus) { - var elementBar = document.getElementById("yellow-bar"); + var elementBar = document.getElementById("yellow-bar-content"); var paneLeft = yellow.toolbox.getOuterLeft(elementBar); - var paneTop = yellow.toolbox.getOuterTop(elementBar) + yellow.toolbox.getOuterHeight(elementBar); + var paneTop = yellow.toolbox.getOuterTop(elementBar) + yellow.toolbox.getOuterHeight(elementBar) + 10; var paneWidth = yellow.toolbox.getOuterWidth(elementBar); var paneHeight = yellow.toolbox.getWindowHeight() - paneTop - yellow.toolbox.getOuterHeight(elementBar); switch(paneId) @@ -362,8 +404,8 @@ yellow.edit = if(this.paneId!=paneId || this.paneAction!=paneAction) { this.hidePane(this.paneId); + if(!document.getElementById(paneId)) this.createPane(paneId, paneAction, paneStatus); var element = document.getElementById(paneId); - if(!element) element = this.createPane(paneId, paneAction, paneStatus); if(!yellow.toolbox.isVisible(element)) { if(yellow.config.debug) console.log("yellow.edit.showPane id:"+paneId); @@ -390,7 +432,6 @@ yellow.edit = var element = document.getElementById(paneId); if(yellow.toolbox.isVisible(element)) { - if(yellow.config.debug) console.log("yellow.edit.hidePane id:"+paneId); yellow.toolbox.removeClass(document.body, "yellow-body-modal-open"); yellow.toolbox.removeValue("meta[name=viewport]", "content", ", maximum-scale=1, user-scalable=0"); yellow.toolbox.setVisible(element, false); @@ -401,44 +442,13 @@ yellow.edit = } }, - // Hide all panes - hidePanes: function() - { - for(var element=document.getElementById("yellow-bar"); element; element=element.nextSibling) - { - if(element.className && element.className.indexOf("yellow-pane")>=0) - { - this.hidePane(element.getAttribute("id")); - } - } - }, - - // Hide all panes on mouse click outside - hidePanesOnClick: function(element) - { - for(;element; element=element.parentNode) - { - if(element.className) - { - if(element.className.indexOf("yellow-pane")>=0 || element.className.indexOf("yellow-bar-")>=0) return; - } - } - this.hidePanes(); - }, - - // Hide all panes on ESC key - hidePanesOnKeydown: function(keycode) - { - if(keycode==27) this.hidePanes(); - }, - // Send pane sendPane: function(paneId, paneAction, paneStatus, paneArgs) { if(yellow.config.debug) console.log("yellow.edit.sendPane id:"+paneId); if(paneId=="yellow-pane-edit") { - paneAction = this.getPaneAction(paneId, paneAction); + paneAction = this.getAction(paneId, paneAction); if(paneAction) { var args = {}; @@ -465,42 +475,33 @@ yellow.edit = } }, - // Return pane action - getPaneAction: function(paneId, paneAction) + // Bind actions to links + bindActions: function(element) { - if(paneId=="yellow-pane-edit") + var elements = element.getElementsByTagName("a"); + for(var i=0, l=elements.length; i<l; i++) { - var string = document.getElementById("yellow-pane-edit-page").value; - var paneActionOld = paneAction; - switch(paneAction) - { - case "create": paneAction = "create"; break; - case "edit": paneAction = string ? "edit" : "delete"; break; - case "delete": paneAction = "delete"; break; - } - if(yellow.page.statusCode==424 && paneActionOld!="delete") paneAction = "create"; - if(yellow.config.userRestrictions) paneAction = ""; + if(elements[i].getAttribute("data-action")) elements[i].onclick = yellow.onClickAction; } - return paneAction; }, - // Return language selection - getLanguages: function(paneId) + // Return action + getAction: function(paneId, paneAction) { - var languages = ""; - if(yellow.config.serverLanguages && yellow.toolbox.getLength(yellow.config.serverLanguages)>1) + if(paneId=="yellow-pane-edit") { - languages += "<p>"; - for(var language in yellow.config.serverLanguages) + switch(paneAction) { - var checked = language==this.getRequest("language") ? " checked=\"checked\"" : ""; - languages += "<label for=\""+paneId+"-"+language+"\"><input type=\"radio\" name=\"language\" id=\""+paneId+"-"+language+"\" value=\""+language+"\""+checked+"> "+yellow.toolbox.encodeHtml(yellow.config.serverLanguages[language])+"</label><br />"; + case "create": action = "create"; break; + case "edit": action = document.getElementById("yellow-pane-edit-page").value ? "edit" : "delete"; break; + case "delete": action = "delete"; break; } - languages += "</p>"; + if(yellow.page.statusCode==424 && paneAction!="delete") action = "create"; + if(yellow.config.userRestrictions) action = ""; } - return languages; + return action; }, - + // Return request string getRequest: function(key, prefix) { @@ -573,12 +574,6 @@ yellow.toolbox = element.removeEventListener(type, handler, false); }, - // Return element length - getLength: function(element) - { - return Object.keys ? Object.keys(element).length : 0; - }, - // Return element width in pixel getWidth: function(element) { @@ -672,7 +667,7 @@ yellow.toolbox = // Return element CSS property getStyle: function(element, property) { - return window.getComputedStyle(element, null).getPropertyValue(property); + return window.getComputedStyle(element).getPropertyValue(property); }, // Return element CSS padding and border diff --git a/system/plugins/edit.php b/system/plugins/edit.php @@ -5,7 +5,7 @@ class YellowEdit { - const VERSION = "0.7.4"; + const VERSION = "0.7.5"; var $yellow; //access to API var $response; //web response var $users; //user accounts @@ -134,8 +134,11 @@ class YellowEdit if($path=="all") { $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - if(!$this->users->clean($fileNameUser)) $statusCode = 500; - if($statusCode==500) echo "ERROR cleaning configuration: Can't write file '$fileNameUser'!\n"; + if(!$this->users->clean($fileNameUser)) + { + $statusCode = 500; + echo "ERROR cleaning configuration: Can't write file '$fileNameUser'!\n"; + } } return $statusCode; } @@ -215,7 +218,7 @@ class YellowEdit case "reconfirm": $statusCode = $this->processRequestReconfirm($scheme, $address, $base, $location, $fileName); break; case "change": $statusCode = $this->processRequestChange($scheme, $address, $base, $location, $fileName); break; } - if($this->response->action=="fail") $this->processFail($scheme, $address, $base); + $this->checkUserFailed($scheme, $address, $base, $location, $fileName); } return $statusCode; } @@ -230,14 +233,12 @@ class YellowEdit } else { if($this->yellow->lookup->isRedirectLocation($location)) { - $statusCode = 301; $location = $this->yellow->lookup->isFileLocation($location) ? "$location/" : "/".$this->yellow->getRequestLanguage()."/"; $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location); - $this->yellow->sendStatus($statusCode, $location); + $statusCode = $this->yellow->sendStatus(301, $location); } else { - $statusCode = $this->response->isUserRestrictions() ? 404 : 424; - $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); - $this->yellow->page->error($statusCode); + $this->yellow->page->error($this->response->isUserRestrictions() ? 404 : 424); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); } } return $statusCode; @@ -252,18 +253,15 @@ class YellowEdit $home = $this->users->getHome($this->response->userEmail); if(substru($location, 0, strlenu($home))==$home) { - $statusCode = 303; $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location); - $this->yellow->sendStatus($statusCode, $location); + $statusCode = $this->yellow->sendStatus(303, $location); } else { - $statusCode = 302; $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $home); - $this->yellow->sendStatus($statusCode, $location); + $statusCode = $this->yellow->sendStatus(302, $location); } } else { - $statusCode = 500; - $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); - $this->yellow->page->error($statusCode, "Can't write file '$fileNameUser'!"); + $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); } return $statusCode; } @@ -271,14 +269,13 @@ class YellowEdit // Process request for user logout function processRequestLogout($scheme, $address, $base, $location, $fileName) { - $statusCode = 302; $this->response->userEmail = ""; $this->response->destroyCookie($scheme, $address, $base); $location = $this->yellow->lookup->normaliseUrl( $this->yellow->config->get("serverScheme"), $this->yellow->config->get("serverAddress"), $this->yellow->config->get("serverBase"), $location); - $this->yellow->sendStatus($statusCode, $location); + $statusCode = $this->yellow->sendStatus(302, $location); return $statusCode; } @@ -457,9 +454,8 @@ class YellowEdit } if($this->response->status=="done") { - $statusCode = 303; $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location); - $this->yellow->sendStatus($statusCode, $location); + $statusCode = $this->yellow->sendStatus(303, $location); } else { $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); } @@ -559,7 +555,7 @@ class YellowEdit { if(!is_null($dataModified[$key]) && !is_null($dataLatest[$key])) { - $rawData = $this->yellow->text->getTextHtml("editVersionUpdateModified", $this->response->language)." - <a href=\"#\" onclick=\"yellow.action('update','update','".$this->yellow->toolbox->normaliseArgs("option:force/feature:$key")."'); return false;\">".$this->yellow->text->getTextHtml("editVersionUpdateForce", $this->response->language)."</a>"; + $rawData = $this->yellow->text->getTextHtml("editVersionUpdateModified", $this->response->language)." - <a href=\"#\" data-action=\"update\" data-status=\"update\" data-args=\"".$this->yellow->toolbox->normaliseArgs("option:force/feature:$key")."\">".$this->yellow->text->getTextHtml("editVersionUpdateForce", $this->response->language)."</a>"; $rawData = preg_replace("/@software/i", htmlspecialchars("$key $dataLatest[$key]"), $rawData); if(!empty($this->response->rawDataOutput)) $this->response->rawDataOutput .= "<br />\n"; $this->response->rawDataOutput .= $rawData; @@ -590,9 +586,8 @@ class YellowEdit $statusCode = $this->yellow->command("update", $option, $feature); if($statusCode==200) { - $statusCode = 303; $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location); - $this->yellow->sendStatus($statusCode, $location); + $statusCode = $this->yellow->sendStatus(303, $location); } } return $statusCode; @@ -602,27 +597,24 @@ class YellowEdit function processRequestCreate($scheme, $address, $base, $location, $fileName) { $statusCode = 0; - if(!$this->response->isUserRestrictions() && !empty($_POST["rawdataedit"])) + if(!$this->response->isUserRestrictions() && !empty($_REQUEST["rawdataedit"])) { - $this->response->rawDataSource = $this->response->rawDataEdit = rawurldecode($_POST["rawdatasource"]); - $rawData = rawurldecode($_POST["rawdataedit"]); + $this->response->rawDataSource = $this->response->rawDataEdit = rawurldecode($_REQUEST["rawdatasource"]); + $rawData = rawurldecode($_REQUEST["rawdataedit"]); $page = $this->response->getPageNew($scheme, $address, $base, $location, $fileName, $rawData); if(!$page->isError()) { if($this->yellow->toolbox->createFile($page->fileName, $page->rawData, true)) { - $statusCode = 303; $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $page->location); - $this->yellow->sendStatus($statusCode, $location); + $statusCode = $this->yellow->sendStatus(303, $location); } else { - $statusCode = 500; - $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); - $this->yellow->page->error($statusCode, "Can't write file '$page->fileName'!"); + $this->yellow->page->error(500, "Can't write file '$page->fileName'!"); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); } } else { - $statusCode = 500; - $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); - $this->yellow->page->error($statusCode, $page->get("pageError")); + $this->yellow->page->error(500, $page->get("pageError")); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); } } return $statusCode; @@ -632,10 +624,10 @@ class YellowEdit function processRequestEdit($scheme, $address, $base, $location, $fileName) { $statusCode = 0; - if(!$this->response->isUserRestrictions() && !empty($_POST["rawdataedit"])) + if(!$this->response->isUserRestrictions() && !empty($_REQUEST["rawdataedit"])) { - $this->response->rawDataSource = rawurldecode($_POST["rawdatasource"]); - $this->response->rawDataEdit = rawurldecode($_POST["rawdataedit"]); + $this->response->rawDataSource = rawurldecode($_REQUEST["rawdatasource"]); + $this->response->rawDataEdit = rawurldecode($_REQUEST["rawdataedit"]); $page = $this->response->getPageEdit($scheme, $address, $base, $location, $fileName, $this->response->rawDataSource, $this->response->rawDataEdit, $this->yellow->toolbox->readFile($fileName)); if(!$page->isError()) @@ -643,18 +635,15 @@ class YellowEdit if($this->yellow->toolbox->renameFile($fileName, $page->fileName, true) && $this->yellow->toolbox->createFile($page->fileName, $page->rawData)) { - $statusCode = 303; $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $page->location); - $this->yellow->sendStatus($statusCode, $location); + $statusCode = $this->yellow->sendStatus(303, $location); } else { - $statusCode = 500; - $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); - $this->yellow->page->error($statusCode, "Can't write file '$page->fileName'!"); + $this->yellow->page->error(500, "Can't write file '$page->fileName'!"); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); } } else { - $statusCode = 500; - $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); - $this->yellow->page->error($statusCode, $page->get("pageError")); + $this->yellow->page->error(500, $page->get("pageError")); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); } } return $statusCode; @@ -666,7 +655,7 @@ class YellowEdit $statusCode = 0; if(!$this->response->isUserRestrictions() && is_file($fileName)) { - $this->response->rawDataSource = $this->response->rawDataEdit = rawurldecode($_POST["rawdatasource"]); + $this->response->rawDataSource = $this->response->rawDataEdit = rawurldecode($_REQUEST["rawdatasource"]); $page = $this->response->getPageDelete($scheme, $address, $base, $location, $fileName, $this->response->rawDataSource); if(!$page->isError()) { @@ -674,62 +663,29 @@ class YellowEdit { if($this->yellow->toolbox->deleteFile($fileName, $this->yellow->config->get("trashDir"))) { - $statusCode = 303; $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location); - $this->yellow->sendStatus($statusCode, $location); + $statusCode = $this->yellow->sendStatus(303, $location); } else { - $statusCode = 500; - $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); - $this->yellow->page->error($statusCode, "Can't delete file '$fileName'!"); + $this->yellow->page->error(500, "Can't delete file '$fileName'!"); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); } } else { if($this->yellow->toolbox->deleteDirectory(dirname($fileName), $this->yellow->config->get("trashDir"))) { - $statusCode = 303; $location = $this->yellow->lookup->normaliseUrl($scheme, $address, $base, $location); - $this->yellow->sendStatus($statusCode, $location); + $statusCode = $this->yellow->sendStatus(303, $location); } else { - $statusCode = 500; - $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); - $this->yellow->page->error($statusCode, "Can't delete file '$fileName'!"); + $this->yellow->page->error(500, "Can't delete file '$fileName'!"); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); } } } else { - $statusCode = 500; - $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); - $this->yellow->page->error($statusCode, $page->get("pageError")); + $this->yellow->page->error(500, $page->get("pageError")); + $statusCode = $this->yellow->processRequest($scheme, $address, $base, $location, $fileName, false); } } return $statusCode; } - - // Process login failed - function processFail($scheme, $address, $base) - { - $email = $this->response->email; - if($this->users->isExisting($email)) - { - $modified = $this->users->getModified($email); - $errors = $this->users->getErrors($email)+1; - $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); - $status = $this->users->update($fileNameUser, $email, "", "", "", "", $modified, $errors) ? "ok" : "error"; - if($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); - if($errors==$this->yellow->config->get("editBruteForceProtection")) - { - if($status=="ok") - { - $status = $this->users->update($fileNameUser, $email, "", "", "", "inactive", $modified, $errors) ? "ok" : "error"; - if($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); - } - if($status=="ok") - { - $status = $this->response->sendMail($scheme, $address, $base, $email, "reactivate") ? "done" : "error"; - if($status=="error") $this->yellow->page->error(500, "Can't send email on this server!"); - } - } - } - $this->yellow->page->error(430); - } // Check request function checkRequest($location) @@ -748,8 +704,9 @@ class YellowEdit $password = $_POST["password"]; if($this->users->checkUser($email, $password)) { - $this->response->createCookie($scheme, $address, $base, $email); + $session = $this->response->createCookie($scheme, $address, $base, $email); $this->response->userEmail = $email; + $this->response->userSession = $session; $this->response->userRestrictions = $this->getUserRestrictions($email, $location, $fileName); $this->response->language = $this->getUserLanguage($email); } else { @@ -761,6 +718,7 @@ class YellowEdit if($this->users->checkCookie($email, $session)) { $this->response->userEmail = $email; + $this->response->userSession = $session; $this->response->userRestrictions = $this->getUserRestrictions($email, $location, $fileName); $this->response->language = $this->getUserLanguage($email); } else { @@ -771,6 +729,37 @@ class YellowEdit return $this->response->isUser(); } + // Check user failed + function checkUserFailed($scheme, $address, $base, $location, $fileName) + { + if($this->response->action=="fail") + { + $email = $this->response->email; + if($this->users->isExisting($email)) + { + $modified = $this->users->getModified($email); + $errors = $this->users->getErrors($email)+1; + $fileNameUser = $this->yellow->config->get("configDir").$this->yellow->config->get("editUserFile"); + $status = $this->users->update($fileNameUser, $email, "", "", "", "", $modified, $errors) ? "ok" : "error"; + if($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); + if($errors==$this->yellow->config->get("editBruteForceProtection")) + { + if($status=="ok") + { + $status = $this->users->update($fileNameUser, $email, "", "", "", "inactive", $modified, $errors) ? "ok" : "error"; + if($status=="error") $this->yellow->page->error(500, "Can't write file '$fileNameUser'!"); + } + if($status=="ok") + { + $status = $this->response->sendMail($scheme, $address, $base, $email, "reactivate") ? "done" : "error"; + if($status=="error") $this->yellow->page->error(500, "Can't send email on this server!"); + } + } + } + $this->yellow->page->error(430); + } + } + // Return user account changes function getUserAccount($email, $password, $action) { @@ -826,6 +815,7 @@ class YellowResponse var $yellow; //access to API var $plugin; //access to plugin var $userEmail; //user email + var $userSession; //user session var $userRestrictions; //user can change page? (boolean) var $active; //location is active? (boolean) var $rawDataSource; //raw data of page for comparison @@ -1077,6 +1067,7 @@ class YellowResponse $session = $this->plugin->users->createSession($email); $timeout = $this->yellow->config->get("editLoginSessionTimeout"); setcookie("login", "$email,$session", $timeout ? time()+$timeout : 0, "$base/", "", $scheme=="https"); + return $session; } // Destroy browser cookie @@ -1085,18 +1076,6 @@ class YellowResponse setcookie("login", "", time()-60*60, "$base/", "", $scheme=="https"); } - // Edit content file - function editContentFile($page, $action) - { - if(!$page->isError()) - { - foreach($this->yellow->plugins->plugins as $key=>$value) - { - if(method_exists($value["obj"], "onEditContentFile")) $value["obj"]->onEditContentFile($page, $action); - } - } - } - // Send mail to user function sendMail($scheme, $address, $base, $email, $action) { @@ -1137,6 +1116,18 @@ class YellowResponse return mail($mailTo, $mailSubject, $mailMessage, $mailHeaders); } + // Edit content file + function editContentFile($page, $action) + { + if(!$page->isError()) + { + foreach($this->yellow->plugins->plugins as $key=>$value) + { + if(method_exists($value["obj"], "onEditContentFile")) $value["obj"]->onEditContentFile($page, $action); + } + } + } + // Check if active function isActive() {