User:Subh83/JavaScriptTools/utilsDOMdynamics.js

/**************************************************** var UserSubh83_utilsDOMdynamics = true;
 * Created by Subhrajit Bhattacharya User:Subh83 *
 * Licensed under GNU-GPL v3.0                      *

// ================================================================ /*** DOM traversal/search utils ***/

function FindNodeUpLeftTree(elemin, tagnames) { // Given an element 'elemin', the function finds the first node with //   tag name in array 'tagnames' that is either a previous sibling, //   or a previous sibling of of any ancestor. var elem = elemin; for (var j=0; j<tagnames.length; j++) tagnames[j] = tagnames[j].toLowerCase; var prevelem; for (var i=0;i<=10000;i++) { if (elem.previousSibling) prevelem = elem.previousSibling; else if (elem.parentNode) prevelem = elem.parentNode; if (!prevelem.tagName) { elem = prevelem; continue; }       if (prevelem) { var tn = prevelem.tagName.toLowerCase; for (var j=0; j<tagnames.length; j++) if (tn==tagnames[j]) return prevelem; elem = prevelem; } else return false; } }

function FindNodeUpTree(elemin, tagnames) { // Given an element 'elemin', the function finds an ancestor with tag from 'tagnames' var elem = elemin; for (var j=0; j<tagnames.length; j++) tagnames[j] = tagnames[j].toLowerCase; var prevelem; for (var i=0;i<=10000;i++) { if (elem.parentNode) prevelem = elem.parentNode; if (!prevelem.tagName) { elem = prevelem; continue; }       if (prevelem) { var tn = prevelem.tagName.toLowerCase; for (var j=0; j0) return hElemAs[0]; }   return false; }

// ================================================================ /*** Poistioning/display utils ***/

function setMenuPosition (e, menudiv) { // Position 'menudiv' at mouse pointer position. var posx = e.clientX; var posy = e.clientY;

var w, h;   if (document.body && document.body.offsetWidth) { w = document.body.offsetWidth; h = document.body.offsetHeight; }   if (document.compatMode=='CSS1Compat' &&               document.documentElement &&                  document.documentElement.offsetWidth ) { w = document.documentElement.offsetWidth; h = document.documentElement.offsetHeight; }   if (window.innerWidth && window.innerHeight) { w = window.innerWidth; h = window.innerHeight; }

menudiv.style.position = "fixed"; if (posx < w/2) { menudiv.style.left = posx+"px"; menudiv.style.pixelLeft = posx+"px"; menudiv.style.right = "auto"; menudiv.style.pixelRight = "auto"; } else { menudiv.style.right = (w-posx)+"px"; menudiv.style.pixelRight = (w-posx)+"px"; menudiv.style.left = "auto"; menudiv.style.pixelLeft = "auto"; }

if (posy < h/2) { menudiv.style.top = posy+"px"; menudiv.style.pixelTop = posy+"px"; menudiv.style.bottom = "auto"; menudiv.style.pixelBottom = "auto"; } else { menudiv.style.bottom = (h-posy)+"px"; menudiv.style.pixelBottom = (h-posy)+"px"; menudiv.style.top = "auto"; menudiv.style.pixelTop = "auto"; } }

function ToggleElementDisplay(divID) { var theElem = document.getElementById(divID); if (theElem) { if (theElem.style.display=='none') { theElem.style.display='block'; return 1; } else { theElem.style.display='none'; return 0; } } }

// ================================================================ /*** Textarea, textbox selection & editing utils ***/

function selectRangeInTextarea(ctrl, start, end, autoscroll) { if(ctrl.setSelectionRange) { ctrl.focus; ctrl.setSelectionRange(start, end); }   else if (ctrl.createTextRange) { var range = ctrl.createTextRange; range.collapse(true); range.moveStart('character', start); range.moveEnd('character', end); range.select; }   if (typeof(autoscroll)=='undefined') autoscroll = true; if(autoscroll) ctrl.scrollTop = findScrollTopFromPos(ctrl, start, 2); ctrl.focus; }

function findScrollTopFromPos(ctrl, pos, topOffset) { if(typeof(topOffset)=='undefined') topOffset = 0; var reducingtext = ctrl.value; reducingtext.replace(/\t/g, "   ").replace(/\r\n|\n\r/g, "\n").replace(/\r/g, "\n"); var ColsNo = getTextareaNumberOfColumns(ctrl); var LineRegexS = "^.{0,"+ColsNo+"}?\\n|^.{0,"+ColsNo+"}\\s|.{0,"+ColsNo+"}"; var LineRegex = new RegExp(LineRegexS); var LineCount=0, CharCount=0, LinePos=0; while (CharCount<(ctrl.value.length-ColsNo-1)) { line = reducingtext.match(LineRegex); CharCount += line[0].length; if (CharCount<=pos) LinePos = LineCount; LineCount++; reducingtext = reducingtext.substring(line[0].length); }   return parseInt( ctrl.scrollHeight * Math.min(1,Math.max(0, ((LinePos-topOffset)/LineCount) )) ); }

function getTextareaNumberOfColumns(ctrl) { var fullWidth = ctrl.clientWidth; ctrl.style.width = 'auto'; while(ctrl.clientWidth < fullWidth) { ctrl.cols = ctrl.cols + 1; }   while (ctrl.clientWidth > fullWidth) { ctrl.cols = ctrl.cols - 1; }   return(ctrl.cols); }

function getSelectionInTextarea(ctrl) { var sel = new Object; if(ctrl.selectionStart) { sel.start = ctrl.selectionStart; sel.end = ctrl.selectionEnd; }   else if (document.selection) { var textRange = document.selection.createRange; sel.start = textRange.startOffset; sel.end = textRange.endOffset; }   if (typeof(sel.start)!='undefined') { sel.text = ctrl.value.substring(sel.start, sel.end); return sel; }   else { sel.start = 0; sel.end = 0; sel.text = 0; }   return sel; }

function updateSelectionInTextarea(ctrl, newtext, sel, newSelectionStartOffset, newSelectionLength) { if (typeof(sel)=='undefined') sel = getSelectionInTextarea(ctrl); var newcontent = ctrl.value.substring(0, sel.start) + newtext + ctrl.value.substring(sel.end); ctrl.value = newcontent;

var retsel = new Object; if(typeof(newSelectionStartOffset)=='undefined') newSelectionStartOffset = 0; if(typeof(newSelectionLength)=='undefined') newSelectionLength = newtext.length; retsel.start = sel.start + newSelectionStartOffset; retsel.end = sel.start + newSelectionStartOffset + newSelectionLength; retsel.text = newtext.substr(newSelectionStartOffset, newSelectionLength); return retsel; }

// ================================================================ /*** Event handling utils ***/

function AppendHandlerToEvent(theevent, newhandler, position, condition, finalEvalS) { // 'theevent' is a string. 'newhandler' is a function name or a string. // position is 'post' (default) or 'pre' // If 'condition' is provided, the function that is evaluated first must //      return the value of the 'condition' for the next function to be evaluated. // 'finalEvalS' is a string to be evaluated at the end of the combined handler execution. //      This is required for passing signals to browser's native handlers. It can contain //      variables 'retOld' and 'retNew'.

if (typeof(position)=='undefined') position='post'; if (typeof(finalEvalS)=='undefined') finalEvalS=""; eval("var oldhandler = " + theevent);

var evalStartS = theevent + " = function(e) {                                                      "; var oldEvalS =             "       if (oldhandler) {                                               " + "          if (typeof(oldhandler)=='string') eval('r='+oldhandler);    " + "          else r = oldhandler(e);                                     " + "          retOld = r;                                                 " + "      }                                                               ";

var condStartS = ""; condEndS = ""; if (typeof(condition)!='undefined') { condStartS = " if (r===condition) {"; condEndS = "}"; }

var newEvalS =             "       if (typeof(newhandler)=='string') eval('r='+newhandler);        " + "      else r = newhandler(e);                                         " + "      retNew = r;                                                     "; var evalEndS = finalEvalS + "  }                                                                   ";

if (position == 'post') var evalS = evalStartS + oldEvalS + condStartS + newEvalS + condEndS + evalEndS; else if (position == 'pre') var evalS = evalStartS + newEvalS + condStartS + oldEvalS + condEndS + evalEndS;

eval(evalS); }