334 lines
9.7 KiB
JavaScript
334 lines
9.7 KiB
JavaScript
/****
|
|
* This page contains some general usefull functions for javascript
|
|
*
|
|
****/
|
|
|
|
|
|
// need to redefine this functiondue to IE problem
|
|
function getAttribute( elm, aName ) {
|
|
var aValue,taName,i;
|
|
try{
|
|
aValue = elm.getAttribute( aName );
|
|
}catch(exept){}
|
|
|
|
if( ! aValue ){
|
|
for( i = 0; i < elm.attributes.length; i ++ ) {
|
|
taName = elm.attributes[i] .name.toLowerCase();
|
|
if( taName == aName ) {
|
|
aValue = elm.attributes[i] .value;
|
|
return aValue;
|
|
}
|
|
}
|
|
}
|
|
return aValue;
|
|
};
|
|
|
|
// need to redefine this function due to IE problem
|
|
function setAttribute( elm, attr, val ) {
|
|
if(attr=="class"){
|
|
elm.setAttribute("className", val);
|
|
elm.setAttribute("class", val);
|
|
}else{
|
|
elm.setAttribute(attr, val);
|
|
}
|
|
};
|
|
|
|
/* return a child element
|
|
elem: element we are searching in
|
|
elem_type: type of the eleemnt we are searching (DIV, A, etc...)
|
|
elem_attribute: attribute of the searched element that must match
|
|
elem_attribute_match: value that elem_attribute must match
|
|
option: "all" if must return an array of all children, otherwise return the first match element
|
|
depth: depth of search (-1 or no set => unlimited)
|
|
*/
|
|
function getChildren(elem, elem_type, elem_attribute, elem_attribute_match, option, depth)
|
|
{
|
|
if(!option)
|
|
var option="single";
|
|
if(!depth)
|
|
var depth=-1;
|
|
if(elem){
|
|
var children= elem.childNodes;
|
|
var result=null;
|
|
var results= [];
|
|
for (var x=0;x<children.length;x++) {
|
|
strTagName = new String(children[x].tagName);
|
|
children_class="?";
|
|
if(strTagName!= "undefined"){
|
|
child_attribute= getAttribute(children[x],elem_attribute);
|
|
if((strTagName.toLowerCase()==elem_type.toLowerCase() || elem_type=="") && (elem_attribute=="" || child_attribute==elem_attribute_match)){
|
|
if(option=="all"){
|
|
results.push(children[x]);
|
|
}else{
|
|
return children[x];
|
|
}
|
|
}
|
|
if(depth!=0){
|
|
result=getChildren(children[x], elem_type, elem_attribute, elem_attribute_match, option, depth-1);
|
|
if(option=="all"){
|
|
if(result.length>0){
|
|
results= results.concat(result);
|
|
}
|
|
}else if(result!=null){
|
|
return result;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(option=="all")
|
|
return results;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
function isChildOf(elem, parent){
|
|
if(elem){
|
|
if(elem==parent)
|
|
return true;
|
|
while(elem.parentNode != 'undefined'){
|
|
return isChildOf(elem.parentNode, parent);
|
|
}
|
|
}
|
|
return false;
|
|
};
|
|
|
|
function getMouseX(e){
|
|
|
|
if(e!=null && typeof(e.pageX)!="undefined"){
|
|
return e.pageX;
|
|
}else{
|
|
return (e!=null?e.x:event.x)+ document.documentElement.scrollLeft;
|
|
}
|
|
};
|
|
|
|
function getMouseY(e){
|
|
if(e!=null && typeof(e.pageY)!="undefined"){
|
|
return e.pageY;
|
|
}else{
|
|
return (e!=null?e.y:event.y)+ document.documentElement.scrollTop;
|
|
}
|
|
};
|
|
|
|
function calculeOffsetLeft(r){
|
|
return calculeOffset(r,"offsetLeft")
|
|
};
|
|
|
|
function calculeOffsetTop(r){
|
|
return calculeOffset(r,"offsetTop")
|
|
};
|
|
|
|
function calculeOffset(element,attr){
|
|
var offset=0;
|
|
while(element){
|
|
offset+=element[attr];
|
|
element=element.offsetParent
|
|
}
|
|
return offset;
|
|
};
|
|
|
|
/** return the computed style
|
|
* @param: elem: the reference to the element
|
|
* @param: prop: the name of the css property
|
|
*/
|
|
function get_css_property(elem, prop)
|
|
{
|
|
if(document.defaultView)
|
|
{
|
|
return document.defaultView.getComputedStyle(elem, null).getPropertyValue(prop);
|
|
}
|
|
else if(elem.currentStyle)
|
|
{
|
|
var prop = prop.replace(/-\D/gi, function(sMatch)
|
|
{
|
|
return sMatch.charAt(sMatch.length - 1).toUpperCase();
|
|
});
|
|
return elem.currentStyle[prop];
|
|
}
|
|
else return null;
|
|
}
|
|
|
|
/****
|
|
* Moving an element
|
|
***/
|
|
|
|
var _mCE; // currently moving element
|
|
|
|
/* allow to move an element in a window
|
|
e: the event
|
|
id: the id of the element
|
|
frame: the frame of the element
|
|
ex of use:
|
|
in html: <img id='move_area_search_replace' onmousedown='return parent.start_move_element(event,"area_search_replace", parent.frames["this_frame_id"]);' .../>
|
|
or
|
|
in javascript: document.getElementById("my_div").onmousedown= start_move_element
|
|
*/
|
|
function start_move_element(e, id, frame){
|
|
var elem_id=(e.target || e.srcElement).id;
|
|
if(id)
|
|
elem_id=id;
|
|
if(!frame)
|
|
frame=window;
|
|
if(frame.event)
|
|
e=frame.event;
|
|
|
|
_mCE= frame.document.getElementById(elem_id);
|
|
_mCE.frame=frame;
|
|
frame.document.onmousemove= move_element;
|
|
frame.document.onmouseup= end_move_element;
|
|
/*_mCE.onmousemove= move_element;
|
|
_mCE.onmouseup= end_move_element;*/
|
|
|
|
//alert(_mCE.frame.document.body.offsetHeight);
|
|
|
|
mouse_x= getMouseX(e);
|
|
mouse_y= getMouseY(e);
|
|
//window.status=frame+ " elem: "+elem_id+" elem: "+ _mCE + " mouse_x: "+mouse_x;
|
|
_mCE.start_pos_x = mouse_x - (_mCE.style.left.replace("px","") || calculeOffsetLeft(_mCE));
|
|
_mCE.start_pos_y = mouse_y - (_mCE.style.top.replace("px","") || calculeOffsetTop(_mCE));
|
|
return false;
|
|
};
|
|
|
|
function end_move_element(e){
|
|
_mCE.frame.document.onmousemove= "";
|
|
_mCE.frame.document.onmouseup= "";
|
|
_mCE=null;
|
|
};
|
|
|
|
function move_element(e){
|
|
var newTop,newLeft,maxLeft;
|
|
|
|
if( _mCE.frame && _mCE.frame.event )
|
|
e=_mCE.frame.event;
|
|
newTop = getMouseY(e) - _mCE.start_pos_y;
|
|
newLeft = getMouseX(e) - _mCE.start_pos_x;
|
|
|
|
maxLeft = _mCE.frame.document.body.offsetWidth- _mCE.offsetWidth;
|
|
max_top = _mCE.frame.document.body.offsetHeight- _mCE.offsetHeight;
|
|
newTop = Math.min(Math.max(0, newTop), max_top);
|
|
newLeft = Math.min(Math.max(0, newLeft), maxLeft);
|
|
|
|
_mCE.style.top = newTop+"px";
|
|
_mCE.style.left = newLeft+"px";
|
|
return false;
|
|
};
|
|
|
|
/***
|
|
* Managing a textarea (this part need the navigator infos from editAreaLoader
|
|
***/
|
|
|
|
var nav= editAreaLoader.nav;
|
|
|
|
// allow to get infos on the selection: array(start, end)
|
|
function getSelectionRange(textarea){
|
|
return {"start": textarea.selectionStart, "end": textarea.selectionEnd};
|
|
};
|
|
|
|
// allow to set the selection
|
|
function setSelectionRange(t, start, end){
|
|
t.focus();
|
|
|
|
start = Math.max(0, Math.min(t.value.length, start));
|
|
end = Math.max(start, Math.min(t.value.length, end));
|
|
|
|
if( this.isOpera && this.isOpera < 9.6 ){ // Opera bug when moving selection start and selection end
|
|
t.selectionEnd = 1;
|
|
t.selectionStart = 0;
|
|
t.selectionEnd = 1;
|
|
t.selectionStart = 0;
|
|
}
|
|
t.selectionStart = start;
|
|
t.selectionEnd = end;
|
|
//textarea.setSelectionRange(start, end);
|
|
|
|
if(isIE)
|
|
set_IE_selection(t);
|
|
};
|
|
|
|
|
|
// set IE position in Firefox mode (textarea.selectionStart and textarea.selectionEnd). should work as a repeated task
|
|
function get_IE_selection(t){
|
|
var d=document,div,range,stored_range,elem,scrollTop,relative_top,line_start,line_nb,range_start,range_end,tab;
|
|
if(t && t.focused)
|
|
{
|
|
if(!t.ea_line_height)
|
|
{ // calculate the lineHeight
|
|
div= d.createElement("div");
|
|
div.style.fontFamily= get_css_property(t, "font-family");
|
|
div.style.fontSize= get_css_property(t, "font-size");
|
|
div.style.visibility= "hidden";
|
|
div.innerHTML="0";
|
|
d.body.appendChild(div);
|
|
t.ea_line_height= div.offsetHeight;
|
|
d.body.removeChild(div);
|
|
}
|
|
//t.focus();
|
|
range = d.selection.createRange();
|
|
try
|
|
{
|
|
stored_range = range.duplicate();
|
|
stored_range.moveToElementText( t );
|
|
stored_range.setEndPoint( 'EndToEnd', range );
|
|
if(stored_range.parentElement() == t){
|
|
// the range don't take care of empty lines in the end of the selection
|
|
elem = t;
|
|
scrollTop = 0;
|
|
while(elem.parentNode){
|
|
scrollTop+= elem.scrollTop;
|
|
elem = elem.parentNode;
|
|
}
|
|
|
|
// var scrollTop= t.scrollTop + document.body.scrollTop;
|
|
|
|
// var relative_top= range.offsetTop - calculeOffsetTop(t) + scrollTop;
|
|
relative_top= range.offsetTop - calculeOffsetTop(t)+ scrollTop;
|
|
// alert("rangeoffset: "+ range.offsetTop +"\ncalcoffsetTop: "+ calculeOffsetTop(t) +"\nrelativeTop: "+ relative_top);
|
|
line_start = Math.round((relative_top / t.ea_line_height) +1);
|
|
|
|
line_nb = Math.round(range.boundingHeight / t.ea_line_height);
|
|
|
|
range_start = stored_range.text.length - range.text.length;
|
|
tab = t.value.substr(0, range_start).split("\n");
|
|
range_start += (line_start - tab.length)*2; // add missing empty lines to the selection
|
|
t.selectionStart = range_start;
|
|
|
|
range_end = t.selectionStart + range.text.length;
|
|
tab = t.value.substr(0, range_start + range.text.length).split("\n");
|
|
range_end += (line_start + line_nb - 1 - tab.length)*2;
|
|
t.selectionEnd = range_end;
|
|
}
|
|
}
|
|
catch(e){}
|
|
}
|
|
setTimeout("get_IE_selection(document.getElementById('"+ t.id +"'));", 50);
|
|
};
|
|
|
|
function IE_textarea_focus(){
|
|
event.srcElement.focused= true;
|
|
}
|
|
|
|
function IE_textarea_blur(){
|
|
event.srcElement.focused= false;
|
|
}
|
|
|
|
// select the text for IE (take into account the \r difference)
|
|
function set_IE_selection( t ){
|
|
var nbLineStart,nbLineStart,nbLineEnd,range;
|
|
if(!window.closed){
|
|
nbLineStart=t.value.substr(0, t.selectionStart).split("\n").length - 1;
|
|
nbLineEnd=t.value.substr(0, t.selectionEnd).split("\n").length - 1;
|
|
try
|
|
{
|
|
range = document.selection.createRange();
|
|
range.moveToElementText( t );
|
|
range.setEndPoint( 'EndToStart', range );
|
|
range.moveStart('character', t.selectionStart - nbLineStart);
|
|
range.moveEnd('character', t.selectionEnd - nbLineEnd - (t.selectionStart - nbLineStart) );
|
|
range.select();
|
|
}
|
|
catch(e){}
|
|
}
|
|
};
|
|
|
|
|
|
editAreaLoader.waiting_loading["elements_functions.js"]= "loaded";
|