diff options
Diffstat (limited to 'sca-cpp/trunk/modules/js/htdocs/ui.js')
-rw-r--r-- | sca-cpp/trunk/modules/js/htdocs/ui.js | 543 |
1 files changed, 268 insertions, 275 deletions
diff --git a/sca-cpp/trunk/modules/js/htdocs/ui.js b/sca-cpp/trunk/modules/js/htdocs/ui.js index 7c079e3089..d8628f6dd0 100644 --- a/sca-cpp/trunk/modules/js/htdocs/ui.js +++ b/sca-cpp/trunk/modules/js/htdocs/ui.js @@ -24,167 +24,11 @@ var ui = {}; /** - * Build a portable <a href> tag. - */ -ui.ahref = function(loc, target, html) { - if (target == '_blank') - return '<a href="' + loc + '" target="_blank">' + html + '</a>'; - return '<a href="javascript:void(0)" onclick="ui.navigate(\'' + loc + '\', \'' + target + '\');">' + html + '</a>'; -}; - -/** - * Build a menu bar. - */ -ui.menu = function(name, href, target) { - function Menu(n, h, t) { - this.name = n; - this.href = h; - this.target = isNil(t)? '_parent' : t; - - this.content = function() { - function complete(uri) { - var h = uri.indexOf('#'); - if (h != -1) - return complete(uri.substr(0, h)); - var q = uri.indexOf('?'); - if (q != -1) - return complete(uri.substr(0, q)); - if (uri.match('.*\.html$')) - return uri; - if (uri.match('.*/$')) - return uri + 'index.html'; - return uri + '/index.html'; - } - - if (complete(this.href) != complete(window.top.location.pathname)) - return ui.ahref(this.href, this.target, '<span class="tbaramenu">' + this.name + '</span>'); - return ui.ahref(this.href, this.target, '<span class="tbarsmenu">' + this.name + '</span>'); - }; - } - return new Menu(name, href, target); -}; - -ui.menubar = function(left, right) { - var bar = '<table cellpadding="0" cellspacing="0" width="100%" class="tbar"><tr>' + - '<td class="dtbar"><table border="0" cellspacing="0" cellpadding="0"><tr>'; - for (i in left) - bar = bar + '<td class="ltbar">' + left[i].content() + '</td>' - - bar = bar + '</tr></table></td>' + - '<td class="dtbar"><table border="0" cellpadding="0" cellspacing="0" align="right"><tr>'; - for (i in right) - bar = bar + '<td class="' + (i == 0? 'dtbar' : 'rtbar') + '">' + right[i].content() + '</td>' - - bar = bar + '</tr></table></td></tr></table>'; - return bar; -}; - -/** - * Autocomplete / suggest support for input fields - * To use it declare a 'suggest' function as follows: - * function suggestItems() { - * return new Array('abc', 'def', 'ghi'); - * } - * then hook it to an input field as follows: - * suggest(document.yourForm.yourInputField, suggestItems); - */ -ui.selectSuggestion = function(node, value) { - for (;;) { - node = node.parentNode; - if (node.tagName.toLowerCase() == 'div') - break; - } - node.selectSuggestion(value); -}; - -ui.hilightSuggestion = function(node, over) { - if (over) - node.className = 'suggestHilighted'; - node.className = 'suggestItem'; -}; - -ui.suggest = function(input, suggestFunction) { - input.suggest = suggestFunction; - - input.selectSuggestion = function(value) { - this.hideSuggestDiv(); - this.value = value; - } - - input.hideSuggestDiv = function() { - if (this.suggestDiv != null) { - this.suggestDiv.style.visibility = 'hidden'; - } - } - - input.showSuggestDiv = function() { - if (this.suggestDiv == null) { - this.suggestDiv = document.createElement('div'); - this.suggestDiv.input = this; - this.suggestDiv.className = 'suggest'; - input.parentNode.insertBefore(this.suggestDiv, input); - this.suggestDiv.style.visibility = 'hidden'; - this.suggestDiv.style.zIndex = '99'; - - this.suggestDiv.selectSuggestion = function(value) { - this.input.selectSuggestion(value); - } - } - - var values = this.suggest(); - var items = ''; - for (var i = 0; i < values.length; i++) { - if (values[i].indexOf(this.value) == -1) - continue; - if (items.length == 0) - items += '<table class="suggestTable">'; - items += '<tr><td class="suggestItem" ' + - 'onmouseover="ui.hilightSuggestion(this, true)" onmouseout="ui.hilightSuggestion(this, false)" ' + - 'onmousedown="ui.selectSuggestion(this, \'' + values[i] + '\')">' + values[i] + '</td></tr>'; - } - if (items.length != 0) - items += '</table>'; - this.suggestDiv.innerHTML = items; - - if (items.length != 0) { - var node = input; - var left = 0; - var top = 0; - for (;;) { - left += node.offsetLeft; - top += node.offsetTop; - node = node.offsetParent; - if (node.tagName.toLowerCase() == 'body') - break; - } - this.suggestDiv.style.left = left; - this.suggestDiv.style.top = top + input.offsetHeight; - this.suggestDiv.style.visibility = 'visible'; - } else - this.suggestDiv.style.visibility = 'hidden'; - } - - input.onkeydown = function(event) { - this.showSuggestDiv(); - }; - - input.onkeyup = function(event) { - this.showSuggestDiv(); - }; - - input.onmousedown = function(event) { - this.showSuggestDiv(); - }; - - input.onblur = function(event) { - setTimeout(function() { input.hideSuggestDiv(); }, 50); - }; -}; - -/** * Return a child element of a node with the given id. */ ui.elementByID = function(node, id) { + if (node.skipNode == true) + return null; for (var i in node.childNodes) { var child = node.childNodes[i]; if (child.id == id) @@ -200,20 +44,46 @@ ui.elementByID = function(node, id) { * Return the current document, or a child element with the given id. */ function $(id) { - if (id == document) { - if (!isNil(document.widget)) - return document.widget; + if (id == document) return document; - } return ui.elementByID($(document), id); }; /** - * Return a dictionary of the query parameters. + * Return the query string of a URL. + */ +ui.query = function(url) { + var u = '' + url; + var q = u.indexOf('?'); + return q >= 0? u.substring(q + 1) : ''; +}; + +/** + * Return the fragment part of a URL. + */ +ui.fragment = function(url) { + var u = '' + url; + var h = u.indexOf('#'); + return h >= 0? u.substring(h + 1) : ''; +}; + +/** + * Return the path and parameters of a URL. */ -ui.queryParams = function() { +ui.pathandparams = function(url) { + var u = '' + url; + var ds = u.indexOf('//'); + var u2 = ds > 0? u.substring(ds + 2) : u; + var s = u2.indexOf('/'); + return s > 0? u2.substring(s) : ''; +}; + +/** + * Return a dictionary of query parameters in a URL. + */ +ui.queryParams = function(url) { var qp = new Array(); - var qs = window.location.search.substring(1).split('&'); + var qs = ui.query(url).split('&'); for (var i = 0; i < qs.length; i++) { var e = qs[i].indexOf('='); if (e > 0) @@ -223,11 +93,11 @@ ui.queryParams = function() { }; /** - * Return a dictionary of the fragment parameters. + * Return a dictionary of fragment parameters in a URL. */ -ui.fragmentParams = function() { +ui.fragmentParams = function(url) { var qp = new Array(); - var qs = window.location.hash.substring(1).split('&'); + var qs = ui.fragment(url).split('&'); for (var i = 0; i < qs.length; i++) { var e = qs[i].indexOf('='); if (e > 0) @@ -237,6 +107,55 @@ ui.fragmentParams = function() { }; /** + * Convert a base64-encoded image to a data URL. + */ +ui.b64img = function(b64) { + return 'data:image/png;base64,' + b64; +}; + +/** + * Declare a CSS stylesheet. + */ +ui.declareCSS = function(s) { + var e = document.createElement('style'); + e.type = 'text/css'; + e.textContent = s; + return e; +}; + +/** + * Declare a script. + */ +ui.declareScript = function(s) { + var e = document.createElement('script'); + e.type = 'text/javascript'; + e.text = s; + return e; +}; + +/** + * Return the scripts elements under a given element. + */ +ui.innerScripts = function(e) { + return map(function(s) { return s.text; }, nodeList(e.getElementsByTagName('script'))); +}; + +/** + * Evaluate a script. + */ +ui.evalScript = function(s) { + return eval('(function() {\n' + s + '\n})();'); +}; + +/** + * Include a script. + */ +ui.includeScript = function(s) { + log('include', s); + return eval(s); +}; + +/** * Return true if the client is a mobile device. */ ui.mobiledetected = false; @@ -252,145 +171,117 @@ ui.isMobile = function() { }; /** - * Initialize a document's body. + * Convert a host name to a home page title. */ -ui.pagetransitions = false; +ui.hometitle = function(host) { + if (!isNil(window.top.config.hometitle)) + return window.top.config.hometitle; + var h = reverse(host.split('.')); + var d = isNil(cdr(h))? car(h) : cadr(h); + return d.substr(0, 1).toUpperCase() + d.substr(1); +}; -ui.initbody = function() { - if (ui.isMobile()) { - //log('init', window.location); +/** + * Convert a host name to a window title. + */ +ui.windowtitle = function(host) { + if (!isNil(window.top.config.windowtitle)) + return window.top.config.windowtitle; + var h = reverse(host.split('.')); + var d = isNil(cdr(h))? car(h) : cadr(h); + return d.substr(0, 1).toUpperCase() + d.substr(1); +}; - // Position the main body div off screen - if (ui.pagetransitions) { - var bdiv = $('bodydiv'); - if (!isNil(bdiv)) { - bdiv.className = 'bodydivloading'; - } - } +/** + * Convert a CSS position to a numeric position. + */ +ui.numpos = function(p) { + return p == ''? 0 : Number(p.substr(0, p.length - 2)); +}; - // Install orientation handler - document.body.onorientationchange = ui.onorientationchange; - } - return true; -} +/** + * Convert a numeric position to a CSS pixel position. + */ +ui.pixpos = function(p) { + return p + 'px'; +}; /** * Reload the current document when orientation changes. */ ui.onorientationchange = function() { - window.open(window.location, '_self'); + window.location.reload(); return true; } /** - * Post process a document after it's loaded. - */ -ui.onload = function() { - - // Save the current page location in local storage - // (except for login and logout pages) - var path = document.location.pathname; - if (path.indexOf('/login/') != 0 && path.indexOf('/logout/') != 0) - localStorage.setItem('ui.lastvisited', '' + document.location); - - // Make the document body visible - //log('visible', $('bodydiv').className); - document.body.style.visibility = 'visible'; - - if (ui.pagetransitions && ui.isMobile()) { - //log('onload', window.location); - - // Slide the main body div in - setTimeout(function() { - var bdiv = $('bodydiv'); - if (!isNil(bdiv)) { - function transitionend(e) { - bdiv.removeEventListener('webkitTransitionEnd', transitionend, false); - bdiv.removeEventListener('transitionend', transitionend, false); - bdiv.className = 'bodydiv'; - //log('loadtransitionend', window.location); - }; - bdiv.addEventListener('webkitTransitionEnd', transitionend, false); - bdiv.addEventListener('transitionend', transitionend, false); - //log('loadtransitionstart', window.location); - bdiv.className = 'bodydivloaded'; - } - }, 0); - } - return true; -}; - -/** * Navigate to a new document. */ ui.navigate = function(url, win) { + log('navigate', url, win); - function opendoc(url, win) { - if (win == '_reload') { - window.location = url; - return window.location.reload(); - } - return window.open(url, win); + // Open a new window + if (win == '_blank') + return window.top.open(url, win); + + // Open a new document in the current window + if (win == '_self') + return window.top.open(url, win); + + // Reload the current window + if (win == '_reload') { + window.top.location = url; + return window.top.location.reload(); } - if (ui.pagetransitions && ui.isMobile() && win != '_blank') { - - // Slide the main body div out, then open the new document - var bdiv = $('bodydiv'); - if (!isNil(bdiv)) { - function transitionend(e) { - bdiv.removeEventListener('webkitTransitionEnd', transitionend, false); - bdiv.removeEventListener('transitionend', transitionend, false); - //log('navigatetransitionend', window.location); - return opendoc(url, win); - }; - bdiv.addEventListener('webkitTransitionEnd', transitionend, false); - bdiv.addEventListener('transitionend', transitionend, false); - //log('navigatetransitionstart', window.location); - bdiv.className = 'bodydivunloaded'; - return true; - } + // Let the current top window handle the navigation + if (win == '_view') { + if (!window.top.onnavigate) + return window.top.open(url, '_self'); + return window.top.onnavigate(url); } - return opendoc(url, win); + return window.top.open(url, win); } /** - * Pre process a document just before it's unloaded. + * Build a portable <a href> tag. */ -ui.onbeforeunload = function() { +ui.ahref = function(loc, target, html) { + if (target == '_blank') + return '<a href="' + loc + '" target="_blank">' + html + '</a>'; + return '<a href="javascript:void(0)" onclick="ui.navigate(\'' + loc + '\', \'' + target + '\');">' + html + '</a>'; +}; - if (ui.pagetransitions && ui.isMobile()) { - - // Slide the main body div out - var bdiv = $('bodydiv'); - if (!isNil(bdiv)) - bdiv.className = 'bodydivunloaded'; +/** + * Build a menu bar. + */ +ui.menu = function(name, href, target, hilight) { + function Menu() { + this.content = function() { + if (hilight) + return ui.ahref(href, target, '<span class="tbarsmenu">' + name + '</span>'); + return ui.ahref(href, target, '<span class="tbaramenu">' + name + '</span>'); + }; } + return new Menu(); }; +ui.menubar = function(left, right) { + var bar = '<table cellpadding="0" cellspacing="0" width="100%" class="tbar"><tr>' + + '<td class="dtbar"><table border="0" cellspacing="0" cellpadding="0"><tr>'; + for (i in left) + bar = bar + '<td class="ltbar">' + left[i].content() + '</td>' -/** - * Return the last visited page. - */ -ui.lastvisited = function() { - return localStorage.getItem('ui.lastvisited'); -} - -/** - * Convert a CSS position to a numeric position. - */ -ui.numpos = function(p) { - return p == ''? 0 : Number(p.substr(0, p.length - 2)); -}; + bar = bar + '</tr></table></td>' + + '<td class="dtbar"><table border="0" cellpadding="0" cellspacing="0" align="right"><tr>'; + for (i in right) + bar = bar + '<td class="' + (i == 0? 'dtbar' : 'rtbar') + '">' + right[i].content() + '</td>' -/** - * Convert a numeric position to a CSS pixel position. - */ -ui.pixpos = function(p) { - return p + 'px'; + bar = bar + '</tr></table></td></tr></table>'; + return bar; }; - + /** * Convert a list of elements to an HTML table. */ @@ -473,3 +364,105 @@ ui.datalist = function(l) { return '<table class="datatable ' + (window.name == 'dataFrame'? ' databg' : '') + '" style="width: 100%;">' + rows(l, 0) + '</table>'; } +/** + * Autocomplete / suggest support for input fields + * To use it declare a 'suggest' function as follows: + * function suggestItems() { + * return new Array('abc', 'def', 'ghi'); + * } + * then hook it to an input field as follows: + * suggest(document.yourForm.yourInputField, suggestItems); + */ +ui.selectSuggestion = function(node, value) { + for (;;) { + node = node.parentNode; + if (node.tagName.toLowerCase() == 'div') + break; + } + node.selectSuggestion(value); +}; + +ui.hilightSuggestion = function(node, over) { + if (over) + node.className = 'suggestHilighted'; + node.className = 'suggestItem'; +}; + +ui.suggest = function(input, suggestFunction) { + input.suggest = suggestFunction; + + input.selectSuggestion = function(value) { + this.hideSuggestDiv(); + this.value = value; + } + + input.hideSuggestDiv = function() { + if (this.suggestDiv != null) { + this.suggestDiv.style.visibility = 'hidden'; + } + } + + input.showSuggestDiv = function() { + if (this.suggestDiv == null) { + this.suggestDiv = document.createElement('div'); + this.suggestDiv.input = this; + this.suggestDiv.className = 'suggest'; + input.parentNode.insertBefore(this.suggestDiv, input); + this.suggestDiv.style.visibility = 'hidden'; + this.suggestDiv.style.zIndex = '99'; + + this.suggestDiv.selectSuggestion = function(value) { + this.input.selectSuggestion(value); + } + } + + var values = this.suggest(); + var items = ''; + for (var i = 0; i < values.length; i++) { + if (values[i].indexOf(this.value) == -1) + continue; + if (items.length == 0) + items += '<table class="suggestTable">'; + items += '<tr><td class="suggestItem" ' + + 'onmouseover="ui.hilightSuggestion(this, true)" onmouseout="ui.hilightSuggestion(this, false)" ' + + 'onmousedown="ui.selectSuggestion(this, \'' + values[i] + '\')">' + values[i] + '</td></tr>'; + } + if (items.length != 0) + items += '</table>'; + this.suggestDiv.innerHTML = items; + + if (items.length != 0) { + var node = input; + var left = 0; + var top = 0; + for (;;) { + left += node.offsetLeft; + top += node.offsetTop; + node = node.offsetParent; + if (node.tagName.toLowerCase() == 'body') + break; + } + this.suggestDiv.style.left = left; + this.suggestDiv.style.top = top + input.offsetHeight; + this.suggestDiv.style.visibility = 'visible'; + } else + this.suggestDiv.style.visibility = 'hidden'; + } + + input.onkeydown = function(event) { + this.showSuggestDiv(); + }; + + input.onkeyup = function(event) { + this.showSuggestDiv(); + }; + + input.onmousedown = function(event) { + this.showSuggestDiv(); + }; + + input.onblur = function(event) { + setTimeout(function() { input.hideSuggestDiv(); }, 50); + }; +}; + |