web/data/cubicweb.htmlhelpers.js
changeset 0 b97547f5f1fa
child 29 7d14f1eadded
equal deleted inserted replaced
-1:000000000000 0:b97547f5f1fa
       
     1 CubicWeb.require('python.js');
       
     2 
       
     3 /* returns the document's baseURI. (baseuri() uses document.baseURI if
       
     4  * available and inspects the <base> tag manually otherwise.)
       
     5 */
       
     6 function baseuri() {
       
     7     var uri = document.baseURI;
       
     8     if (uri) { // some browsers don't define baseURI
       
     9 	return uri;
       
    10     }
       
    11     var basetags = document.getElementsByTagName('base');
       
    12     if (basetags.length) {
       
    13 	return getNodeAttribute(basetags[0], 'href');
       
    14     }
       
    15     return '';
       
    16 }
       
    17 
       
    18 function insertText(text, areaId) {
       
    19     var textarea = jQuery('#' + areaId);
       
    20     if (document.selection) { // IE
       
    21         var selLength;
       
    22         textarea.focus();
       
    23         sel = document.selection.createRange();
       
    24         selLength = sel.text.length;
       
    25         sel.text = text;
       
    26         sel.moveStart('character', selLength-text.length);
       
    27         sel.select();
       
    28     } else if (textarea.selectionStart || textarea.selectionStart == '0') { // mozilla
       
    29         var startPos = textarea.selectionStart;
       
    30         var endPos = textarea.selectionEnd;
       
    31 	// insert text so that it replaces the [startPos, endPos] part
       
    32         textarea.value = textarea.value.substring(0,startPos) + text + textarea.value.substring(endPos,textarea.value.length);
       
    33 	// set cursor pos at the end of the inserted text
       
    34         textarea.selectionStart = textarea.selectionEnd = startPos+text.length;
       
    35         textarea.focus();
       
    36     } else { // safety belt for other browsers
       
    37         textarea.value += text;
       
    38     }
       
    39 }
       
    40 
       
    41 /* taken from dojo toolkit */
       
    42 function setCaretPos(element, start, end){
       
    43     if(!end){ end = element.value.length; }  // NOTE: Strange - should be able to put caret at start of text?
       
    44     // Mozilla
       
    45     // parts borrowed from http://www.faqts.com/knowledge_base/view.phtml/aid/13562/fid/130
       
    46     if(element.setSelectionRange){
       
    47         element.focus();
       
    48         element.setSelectionRange(start, end);
       
    49     } else if(element.createTextRange){ // IE
       
    50         var range = element.createTextRange();
       
    51         with(range){
       
    52             collapse(true);
       
    53             moveEnd('character', end);
       
    54             moveStart('character', start);
       
    55             select();
       
    56         }
       
    57     } else { //otherwise try the event-creation hack (our own invention)
       
    58         // do we need these?
       
    59         element.value = element.value;
       
    60         element.blur();
       
    61         element.focus();
       
    62         // figure out how far back to go
       
    63         var dist = parseInt(element.value.length)-end;
       
    64         var tchar = String.fromCharCode(37);
       
    65         var tcc = tchar.charCodeAt(0);
       
    66         for(var x = 0; x < dist; x++){
       
    67             var te = document.createEvent("KeyEvents");
       
    68             te.initKeyEvent("keypress", true, true, null, false, false, false, false, tcc, tcc);
       
    69             element.dispatchEvent(te);
       
    70         }
       
    71     }
       
    72 }
       
    73 
       
    74 function setProgressMessage(label) {
       
    75     var body = document.getElementsByTagName('body')[0];
       
    76     body.appendChild(DIV({id: 'progress'}, label));
       
    77     jQuery('#progress').show();
       
    78 }
       
    79 
       
    80 function resetProgressMessage() {
       
    81     var body = document.getElementsByTagName('body')[0];
       
    82     jQuery('#progress').hide();
       
    83 }
       
    84 
       
    85 
       
    86 /* set body's cursor to 'progress'
       
    87  */
       
    88 function setProgressCursor() {
       
    89     var body = document.getElementsByTagName('body')[0];
       
    90     body.style.cursor = 'progress';
       
    91 }
       
    92 
       
    93 /*
       
    94  * reset body's cursor to default (mouse cursor). The main
       
    95  * purpose of this function is to be used as a callback in the
       
    96  * deferreds' callbacks chain.
       
    97  */
       
    98 function resetCursor(result) {
       
    99     var body = document.getElementsByTagName('body')[0];
       
   100     body.style.cursor = 'default';
       
   101     // pass result to next callback in the callback chain
       
   102     return result;
       
   103 }
       
   104 
       
   105 function updateMessage(msg) {
       
   106     var msgdiv = DIV({'class':'message'});
       
   107     // don't pass msg to DIV() directly because DIV will html escape it
       
   108     // and msg should alreay be html escaped at this point.
       
   109     msgdiv.innerHTML = msg;
       
   110     jQuery('#appMsg').removeClass('hidden').empty().append(msgdiv);
       
   111 }
       
   112 
       
   113 /* builds an url from an object (used as a dictionnary)
       
   114  * Notable difference with MochiKit's queryString: as_url does not
       
   115  * *url_quote* each value found in the dictionnary
       
   116  * 
       
   117  * >>> as_url({'rql' : "RQL", 'x': [1, 2], 'itemvid' : "oneline"})
       
   118  * rql=RQL&vid=list&itemvid=oneline&x=1&x=2
       
   119  */
       
   120 function as_url(props) {
       
   121     var chunks = [];
       
   122     for(key in props) {
       
   123 	var value = props[key];
       
   124 	// generate a list of couple key=value if key is multivalued
       
   125 	if (isArrayLike(value)) {
       
   126 	    for (var i=0; i<value.length;i++) {
       
   127 		chunks.push(key + '=' + value[i]);
       
   128 	    }
       
   129 	} else {
       
   130 	    chunks.push(key + '=' + value);
       
   131 	}
       
   132     }
       
   133     return chunks.join('&');
       
   134 }
       
   135 
       
   136 /* return selected value of a combo box if any 
       
   137  */
       
   138 function firstSelected(selectNode) {
       
   139     var selection = filter(attrgetter('selected'), selectNode.options);
       
   140     return (selection.length>0) ? getNodeAttribute(selection[0], 'value'):null;
       
   141 }
       
   142 
       
   143 /* toggle visibility of an element by its id
       
   144  */
       
   145 function toggleVisibility(elemId) {
       
   146     jqNode(elemId).toggleClass('hidden');
       
   147 }
       
   148 
       
   149 /*
       
   150  * return true (resp. false) if <element> (resp. doesn't) matches <properties>
       
   151  */
       
   152 function elementMatches(properties, element) {
       
   153     for (prop in properties) {
       
   154 	if (getNodeAttribute(element, prop) != properties[prop]) {
       
   155 	    return false;
       
   156 	}
       
   157     }
       
   158     return true;
       
   159 }
       
   160 
       
   161 /* returns the list of elements in the document matching the tag name
       
   162  * and the properties provided
       
   163  * 
       
   164  * @param tagName the tag's name
       
   165  * @param properties a js Object used as a dict
       
   166  * @return an iterator (if a *real* array is needed, you can use the
       
   167  *                      list() function)
       
   168  */
       
   169 function getElementsMatching(tagName, properties, /* optional */ parent) {
       
   170     var filterfunc = partial(elementMatches, properties);
       
   171     parent = parent || document;
       
   172     return filter(filterfunc, parent.getElementsByTagName(tagName));
       
   173 }
       
   174 
       
   175 /*
       
   176  * sets checked/unchecked status of checkboxes 
       
   177  */
       
   178 function setCheckboxesState(nameprefix, checked){
       
   179     // XXX: this looks in *all* the document for inputs
       
   180     var elements = getElementsMatching('input', {'type': "checkbox"});
       
   181     filterfunc = function(cb) { return nameprefix && cb.name.startsWith(nameprefix); };
       
   182     forEach(filter(filterfunc, elements), function(cb) {cb.checked=checked;});
       
   183 }
       
   184 
       
   185 function setCheckboxesState2(nameprefix, value, checked){
       
   186     // XXX: this looks in *all* the document for inputs
       
   187     var elements = getElementsMatching('input', {'type': "checkbox"});
       
   188     filterfunc = function(cb) { return nameprefix && cb.name.startsWith(nameprefix) && cb.value == value; };
       
   189     forEach(filter(filterfunc, elements), function(cb) {cb.checked=checked;});
       
   190 }
       
   191 
       
   192 /*
       
   193  * centers an HTML element on the screen
       
   194  */
       
   195 function centerElement(obj){
       
   196     var vpDim = getViewportDimensions();
       
   197     var elemDim = getElementDimensions(obj);
       
   198     setElementPosition(obj, {'x':((vpDim.w - elemDim.w)/2),
       
   199 			     'y':((vpDim.h - elemDim.h)/2)});
       
   200 }
       
   201 
       
   202 /* this function is a hack to build a dom node from html source */
       
   203 function html2dom(source) {
       
   204     var tmpNode = SPAN();
       
   205     tmpNode.innerHTML = source;
       
   206     if (tmpNode.childNodes.length == 1) {
       
   207 	return tmpNode.firstChild;
       
   208     }
       
   209     else {
       
   210 	// we leave the span node when `source` has no root node
       
   211 	// XXX This is cleary not the best solution, but css/html-wise,
       
   212 	///    a span not should not be too  much disturbing
       
   213 	return tmpNode;
       
   214     }
       
   215 }
       
   216 
       
   217 
       
   218 // *** HELPERS **************************************************** //
       
   219 function rql_for_eid(eid) { return 'Any X WHERE X eid ' + eid; }
       
   220 function isTextNode(domNode) { return domNode.nodeType == 3; }
       
   221 function isElementNode(domNode) { return domNode.nodeType == 1; }
       
   222 
       
   223 function changeLinkText(link, newText) {
       
   224     jQuery(link).text(newText);
       
   225 //    for (var i=0; i<link.childNodes.length; i++) {
       
   226 //	var node = link.childNodes[i];
       
   227 //	if (isTextNode(node)) {
       
   228 //	    swapDOM(node, document.createTextNode(newText));
       
   229 //	    break;
       
   230 //	}
       
   231 //    }
       
   232 }
       
   233 
       
   234 
       
   235 function autogrow(area) {
       
   236     if (area.scrollHeight > area.clientHeight && !window.opera) {
       
   237 	if (area.rows < 20) {
       
   238 	    area.rows += 2;
       
   239 	}
       
   240     }
       
   241 }
       
   242 
       
   243 //============= page loading events ==========================================//
       
   244 function roundedCornersOnLoad() {
       
   245     roundClass("div", "sideBox", {corners: "bottom", compact:false}); 
       
   246     roundClass("div", "boxTitle", {corners: "top",  compact:true}); 
       
   247     roundClass("div", "boxPrefTitle", {corners: "top",  compact:true}); 
       
   248     roundClass("div", "sideBoxTitle", {corners: "top",  compact:true}); 
       
   249     roundClass("th", "month", {corners: "top",  compact:true});
       
   250 }
       
   251 
       
   252 // jQuery(document).ready(roundedCornersOnLoad); 
       
   253 
       
   254 
       
   255 CubicWeb.provide('htmlhelpers.js');
       
   256