Merge pull request #2298 from YuriPet/master
authorHannu Nyman <hannu.nyman@iki.fi>
Fri, 16 Nov 2018 21:00:02 +0000 (23:00 +0200)
committerGitHub <noreply@github.com>
Fri, 16 Nov 2018 21:00:02 +0000 (23:00 +0200)
luci-base: update Ukrainian translation

modules/luci-base/htdocs/luci-static/resources/xhr.js
modules/luci-base/luasrc/dispatcher.lua
modules/luci-mod-system/luasrc/model/cbi/admin_system/fstab.lua
themes/luci-theme-bootstrap/htdocs/luci-static/bootstrap/cascade.css

index 25a90e7254ffbcccb203c55e068b7dc8840ca0b2..8292fcdb6ce6d94b60f212fa082c99752aa68ea8 100644 (file)
@@ -1,24 +1,65 @@
 /*
  * xhr.js - XMLHttpRequest helper class
- * (c) 2008-2010 Jo-Philipp Wich
+ * (c) 2008-2018 Jo-Philipp Wich <jo@mein.io>
  */
 
-XHR = function()
-{
-       this.reinit = function()
-       {
-               if (window.XMLHttpRequest) {
-                       this._xmlHttp = new XMLHttpRequest();
+XHR.prototype = {
+       _encode: function(obj) {
+               obj = obj ? obj : { };
+               obj['_'] = Math.random();
+
+               if (typeof obj == 'object') {
+                       var code = '';
+                       var self = this;
+
+                       for (var k in obj)
+                               code += (code ? '&' : '') +
+                                       k + '=' + encodeURIComponent(obj[k]);
+
+                       return code;
                }
-               else if (window.ActiveXObject) {
-                       this._xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
+
+               return obj;
+       },
+
+       _response: function(callback, ts) {
+               if (this._xmlHttp.readyState !== 4)
+                       return;
+
+               var status = this._xmlHttp.status,
+                   login = this._xmlHttp.getResponseHeader("X-LuCI-Login-Required"),
+                   type = this._xmlHttp.getResponseHeader("Content-Type"),
+                   json = null;
+
+               if (status === 403 && login === 'yes') {
+                       XHR.halt();
+
+                       showModal(_('Session expired'), [
+                               E('div', { class: 'alert-message warning' },
+                                       _('A new login is required since the authentication session expired.')),
+                               E('div', { class: 'right' },
+                                       E('div', {
+                                               class: 'btn primary',
+                                               click: function() {
+                                                       var loc = window.location;
+                                                       window.location = loc.protocol + '//' + loc.host + loc.pathname + loc.search;
+                                               }
+                                       }, _('To login…')))
+                       ]);
                }
-               else {
-                       alert("xhr.js: XMLHttpRequest is not supported by this browser!");
+               else if (type && type.toLowerCase().match(/^application\/json\b/)) {
+                       try {
+                               json = JSON.parse(this._xmlHttp.responseText);
+                       }
+                       catch(e) {
+                               json = null;
+                       }
                }
-       }
 
-       this.busy = function() {
+               callback(this._xmlHttp, json, Date.now() - ts);
+       },
+
+       busy: function() {
                if (!this._xmlHttp)
                        return false;
 
@@ -32,20 +73,18 @@ XHR = function()
                        default:
                                return false;
                }
-       }
+       },
 
-       this.abort = function() {
+       abort: function() {
                if (this.busy())
                        this._xmlHttp.abort();
-       }
+       },
 
-       this.get = function(url,data,callback,timeout)
-       {
-               this.reinit();
+       get: function(url, data, callback, timeout) {
+               this._xmlHttp = new XMLHttpRequest();
 
-               var ts   = Date.now();
-               var xhr  = this._xmlHttp;
-               var code = this._encode(data);
+               var xhr = this._xmlHttp,
+                   code = this._encode(data);
 
                url = location.protocol + '//' + location.host + url;
 
@@ -60,83 +99,51 @@ XHR = function()
                if (!isNaN(timeout))
                        xhr.timeout = timeout;
 
-               xhr.onreadystatechange = function()
-               {
-                       if (xhr.readyState == 4) {
-                               var json = null;
-                               if (xhr.getResponseHeader("Content-Type") == "application/json") {
-                                       try { json = JSON.parse(xhr.responseText); }
-                                       catch(e) { json = null; }
-                               }
-
-                               callback(xhr, json, Date.now() - ts);
-                       }
-               }
-
+               xhr.onreadystatechange = this._response.bind(this, callback, Date.now());
                xhr.send(null);
-       }
-
-       this.post = function(url,data,callback,timeout)
-       {
-               this.reinit();
+       },
 
-               var ts   = Date.now();
-               var xhr  = this._xmlHttp;
-               var code = this._encode(data);
+       post: function(url, data, callback, timeout) {
+               this._xmlHttp = new XMLHttpRequest();
 
-               xhr.onreadystatechange = function()
-               {
-                       if (xhr.readyState == 4) {
-                               var json = null;
-                               if (xhr.getResponseHeader("Content-Type") == "application/json") {
-                                       try { json = JSON.parse(xhr.responseText); }
-                                       catch(e) { json = null; }
-                               }
-
-                               callback(xhr, json, Date.now() - ts);
-                       }
-               }
+               var xhr = this._xmlHttp,
+                   code = this._encode(data);
 
                xhr.open('POST', url, true);
 
                if (!isNaN(timeout))
                        xhr.timeout = timeout;
 
+               xhr.onreadystatechange = this._response.bind(this, callback, Date.now());
                xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
                xhr.send(code);
-       }
+       },
 
-       this.cancel = function()
-       {
-               this._xmlHttp.onreadystatechange = function(){};
+       cancel: function() {
+               this._xmlHttp.onreadystatechange = function() {};
                this._xmlHttp.abort();
-       }
+       },
 
-       this.send_form = function(form,callback,extra_values)
-       {
+       send_form: function(form, callback, extra_values) {
                var code = '';
 
-               for (var i = 0; i < form.elements.length; i++)
-               {
+               for (var i = 0; i < form.elements.length; i++) {
                        var e = form.elements[i];
 
-                       if (e.options)
-                       {
+                       if (e.options) {
                                code += (code ? '&' : '') +
                                        form.elements[i].name + '=' + encodeURIComponent(
                                                e.options[e.selectedIndex].value
                                        );
                        }
-                       else if (e.length)
-                       {
+                       else if (e.length) {
                                for (var j = 0; j < e.length; j++)
                                        if (e[j].name) {
                                                code += (code ? '&' : '') +
                                                        e[j].name + '=' + encodeURIComponent(e[j].value);
                                        }
                        }
-                       else
-                       {
+                       else {
                                code += (code ? '&' : '') +
                                        e.name + '=' + encodeURIComponent(e.value);
                        }
@@ -147,46 +154,25 @@ XHR = function()
                                code += (code ? '&' : '') +
                                        key + '=' + encodeURIComponent(extra_values[key]);
 
-               return(
-                       (form.method == 'get')
-                               ? this.get(form.getAttribute('action'), code, callback)
-                               : this.post(form.getAttribute('action'), code, callback)
-               );
-       }
-
-       this._encode = function(obj)
-       {
-               obj = obj ? obj : { };
-               obj['_'] = Math.random();
-
-               if (typeof obj == 'object')
-               {
-                       var code = '';
-                       var self = this;
-
-                       for (var k in obj)
-                               code += (code ? '&' : '') +
-                                       k + '=' + encodeURIComponent(obj[k]);
-
-                       return code;
-               }
-
-               return obj;
+               return (form.method == 'get'
+                       ? this.get(form.getAttribute('action'), code, callback)
+                       : this.post(form.getAttribute('action'), code, callback));
        }
 }
 
-XHR.get = function(url, data, callback)
-{
+XHR.get = function(url, data, callback) {
        (new XHR()).get(url, data, callback);
 }
 
-XHR.poll = function(interval, url, data, callback, post)
-{
+XHR.post = function(url, data, callback) {
+       (new XHR()).post(url, data, callback);
+}
+
+XHR.poll = function(interval, url, data, callback, post) {
        if (isNaN(interval) || interval < 1)
                interval = 5;
 
-       if (!XHR._q)
-       {
+       if (!XHR._q) {
                XHR._t = 0;
                XHR._q = [ ];
                XHR._r = function() {
@@ -213,8 +199,7 @@ XHR.poll = function(interval, url, data, callback, post)
        return e;
 }
 
-XHR.stop = function(e)
-{
+XHR.stop = function(e) {
        for (var i = 0; XHR._q && XHR._q[i]; i++) {
                if (XHR._q[i] === e) {
                        e.xhr.cancel();
@@ -226,10 +211,8 @@ XHR.stop = function(e)
        return false;
 }
 
-XHR.halt = function()
-{
-       if (XHR._i)
-       {
+XHR.halt = function() {
+       if (XHR._i) {
                /* show & set poll indicator */
                try {
                        document.getElementById('xhr_poll_status').style.display = '';
@@ -242,10 +225,8 @@ XHR.halt = function()
        }
 }
 
-XHR.run = function()
-{
-       if (XHR._r && !XHR._i)
-       {
+XHR.run = function() {
+       if (XHR._r && !XHR._i) {
                /* show & set poll indicator */
                try {
                        document.getElementById('xhr_poll_status').style.display = '';
@@ -260,9 +241,10 @@ XHR.run = function()
        }
 }
 
-XHR.running = function()
-{
+XHR.running = function() {
        return !!(XHR._r && XHR._i);
 }
 
+function XHR() {}
+
 document.addEventListener('DOMContentLoaded', XHR.run);
index 1e610e748919edd1601e5026ea12f62755b3bfe9..c4066a25920c26ff2c9d7113405096866238bcff 100644 (file)
@@ -417,6 +417,7 @@ function dispatch(request)
                                context.path = {}
 
                                http.status(403, "Forbidden")
+                               http.header("X-LuCI-Login-Required", "yes")
                                tmpl.render(track.sysauth_template or "sysauth", {
                                        duser = default_user,
                                        fuser = user
@@ -433,6 +434,7 @@ function dispatch(request)
 
                if not sid or not sdat then
                        http.status(403, "Forbidden")
+                       http.header("X-LuCI-Login-Required", "yes")
                        return
                end
 
index 6f0921fdcfac417b5f35ab5e2019d767cced3895..4a31146a03e13cf735865e9b5067dcd85df82780 100644 (file)
@@ -117,14 +117,14 @@ function used.cfgvalue(self, section)
 end
 
 unmount = v:option(Button, "unmount", translate("Unmount"))
+function unmount.cfgvalue(self, section)
+       return non_system_mounts[section].umount
+end
+
 unmount.render = function(self, section, scope)
-       if non_system_mounts[section].umount then
-               self.title = translate("Unmount")
-               self.inputstyle = "remove"
-               Button.render(self, section, scope)
-       else
-               luci.http.write("&#160;")
-       end
+       self.title = translate("Unmount")
+       self.inputstyle = "remove"
+       Button.render(self, section, scope)
 end
 
 unmount.write = function(self, section)
index 35ea815009025fa270f036c0c41d88d7bda910ae..5f9d7e6034e48360813f77372282cdcb3f5085b1 100644 (file)
@@ -387,20 +387,20 @@ form .cbi-tab-descr {
 }
 
 form .clearfix,
-form .cbi-value {
+.cbi-value {
        margin-bottom: 18px;
        zoom: 1;
 }
 
 form .clearfix:before, form .clearfix:after,
-form .cbi-value:before, form .cbi-value:after  {
+.cbi-value:before, .cbi-value:after  {
        display: table;
        content: "";
        zoom: 1;
 }
 
 form .clearfix:after,
-form .cbi-value:after {
+.cbi-value:after {
        clear: both;
 }
 
@@ -415,11 +415,11 @@ textarea {
 }
 
 form .input,
-form .cbi-value-field {
+.cbi-value-field {
        margin-left: 200px;
 }
 
-form .cbi-value label.cbi-value-title {
+.cbi-value label.cbi-value-title {
        padding-top: 6px;
        font-size: 13px;
        line-height: 18px;
@@ -1770,19 +1770,6 @@ a.label:hover {
 /* LuCI specific items */
 .hidden { display: none }
 
-#memtotal > div,
-#memfree > div,
-#memcache > div,
-#membuff > div,
-#conns > div  {
-         border: 1px solid #ccc;
-         border-radius: 3px 3px 3px 3px;
-         color: #808080;
-         display: inline-block;
-         font-size: 13px;
-         line-height: 18px;
-}
-
 #xhr_poll_status {
          cursor: pointer;
 }