3426fd19ccf40fd5c7219db41324d9cc58aee3e2
[redakcja.git] / project / static / js / elements_functions.js
1 /****\r
2  * This page contains some general usefull functions for javascript\r
3  *\r
4  ****/  \r
5         \r
6         \r
7         // need to redefine this functiondue to IE problem\r
8         function getAttribute( elm, aName ) {\r
9                 var aValue,taName,i;\r
10                 try{\r
11                         aValue = elm.getAttribute( aName );\r
12                 }catch(exept){}\r
13                 \r
14                 if( ! aValue ){\r
15                         for( i = 0; i < elm.attributes.length; i ++ ) {\r
16                                 taName = elm.attributes[i] .name.toLowerCase();\r
17                                 if( taName == aName ) {\r
18                                         aValue = elm.attributes[i] .value;\r
19                                         return aValue;\r
20                                 }\r
21                         }\r
22                 }\r
23                 return aValue;\r
24         };\r
25         \r
26         // need to redefine this function due to IE problem\r
27         function setAttribute( elm, attr, val ) {\r
28                 if(attr=="class"){\r
29                         elm.setAttribute("className", val);\r
30                         elm.setAttribute("class", val);\r
31                 }else{\r
32                         elm.setAttribute(attr, val);\r
33                 }\r
34         };\r
35         \r
36         /* return a child element\r
37                 elem: element we are searching in\r
38                 elem_type: type of the eleemnt we are searching (DIV, A, etc...)\r
39                 elem_attribute: attribute of the searched element that must match\r
40                 elem_attribute_match: value that elem_attribute must match\r
41                 option: "all" if must return an array of all children, otherwise return the first match element\r
42                 depth: depth of search (-1 or no set => unlimited)\r
43         */\r
44         function getChildren(elem, elem_type, elem_attribute, elem_attribute_match, option, depth)\r
45         {           \r
46                 if(!option)\r
47                         var option="single";\r
48                 if(!depth)\r
49                         var depth=-1;\r
50                 if(elem){\r
51                         var children= elem.childNodes;\r
52                         var result=null;\r
53                         var results= [];\r
54                         for (var x=0;x<children.length;x++) {\r
55                                 strTagName = new String(children[x].tagName);\r
56                                 children_class="?";\r
57                                 if(strTagName!= "undefined"){\r
58                                         child_attribute= getAttribute(children[x],elem_attribute);\r
59                                         if((strTagName.toLowerCase()==elem_type.toLowerCase() || elem_type=="") && (elem_attribute=="" || child_attribute==elem_attribute_match)){\r
60                                                 if(option=="all"){\r
61                                                         results.push(children[x]);\r
62                                                 }else{\r
63                                                         return children[x];\r
64                                                 }\r
65                                         }\r
66                                         if(depth!=0){\r
67                                                 result=getChildren(children[x], elem_type, elem_attribute, elem_attribute_match, option, depth-1);\r
68                                                 if(option=="all"){\r
69                                                         if(result.length>0){\r
70                                                                 results= results.concat(result);\r
71                                                         }\r
72                                                 }else if(result!=null){                                                                          \r
73                                                         return result;\r
74                                                 }\r
75                                         }\r
76                                 }\r
77                         }\r
78                         if(option=="all")\r
79                            return results;\r
80                 }\r
81                 return null;\r
82         };       \r
83         \r
84         function isChildOf(elem, parent){\r
85                 if(elem){\r
86                         if(elem==parent)\r
87                                 return true;\r
88                         while(elem.parentNode != 'undefined'){\r
89                                 return isChildOf(elem.parentNode, parent);\r
90                         }\r
91                 }\r
92                 return false;\r
93         };\r
94         \r
95         function getMouseX(e){\r
96 \r
97                 if(e!=null && typeof(e.pageX)!="undefined"){\r
98                         return e.pageX;\r
99                 }else{\r
100                         return (e!=null?e.x:event.x)+ document.documentElement.scrollLeft;\r
101                 }\r
102         };\r
103         \r
104         function getMouseY(e){\r
105                 if(e!=null && typeof(e.pageY)!="undefined"){\r
106                         return e.pageY;\r
107                 }else{\r
108                         return (e!=null?e.y:event.y)+ document.documentElement.scrollTop;\r
109                 }\r
110         };\r
111         \r
112         function calculeOffsetLeft(r){\r
113                 return calculeOffset(r,"offsetLeft")\r
114         };\r
115         \r
116         function calculeOffsetTop(r){\r
117                 return calculeOffset(r,"offsetTop")\r
118         };\r
119         \r
120         function calculeOffset(element,attr){\r
121                 var offset=0;\r
122                 while(element){\r
123                         offset+=element[attr];\r
124                         element=element.offsetParent\r
125                 }\r
126                 return offset;\r
127         };\r
128         \r
129         /** return the computed style\r
130          *      @param: elem: the reference to the element\r
131          *      @param: prop: the name of the css property       \r
132          */\r
133         function get_css_property(elem, prop)\r
134         {\r
135                 if(document.defaultView)\r
136                 {\r
137                         return document.defaultView.getComputedStyle(elem, null).getPropertyValue(prop);\r
138                 }\r
139                 else if(elem.currentStyle)\r
140                 {\r
141                         var prop = prop.replace(/-\D/gi, function(sMatch)\r
142                         {\r
143                                 return sMatch.charAt(sMatch.length - 1).toUpperCase();\r
144                         });\r
145                         return elem.currentStyle[prop];\r
146                 }\r
147                 else return null;\r
148         }\r
149         \r
150 /****\r
151  * Moving an element \r
152  ***/  \r
153         \r
154         var _mCE;       // currently moving element\r
155         \r
156         /* allow to move an element in a window\r
157                 e: the event\r
158                 id: the id of the element\r
159                 frame: the frame of the element \r
160                 ex of use:\r
161                         in html:        <img id='move_area_search_replace' onmousedown='return parent.start_move_element(event,"area_search_replace", parent.frames["this_frame_id"]);' .../>  \r
162                 or\r
163                         in javascript: document.getElementById("my_div").onmousedown= start_move_element\r
164         */\r
165         function start_move_element(e, id, frame){\r
166                 var elem_id=(e.target || e.srcElement).id;\r
167                 if(id)\r
168                         elem_id=id;             \r
169                 if(!frame)\r
170                         frame=window;\r
171                 if(frame.event)\r
172                         e=frame.event;\r
173                         \r
174                 _mCE= frame.document.getElementById(elem_id);\r
175                 _mCE.frame=frame;\r
176                 frame.document.onmousemove= move_element;\r
177                 frame.document.onmouseup= end_move_element;\r
178                 /*_mCE.onmousemove= move_element;\r
179                 _mCE.onmouseup= end_move_element;*/\r
180                 \r
181                 //alert(_mCE.frame.document.body.offsetHeight);\r
182                 \r
183                 mouse_x= getMouseX(e);\r
184                 mouse_y= getMouseY(e);\r
185                 //window.status=frame+ " elem: "+elem_id+" elem: "+ _mCE + " mouse_x: "+mouse_x;\r
186                 _mCE.start_pos_x = mouse_x - (_mCE.style.left.replace("px","") || calculeOffsetLeft(_mCE));\r
187                 _mCE.start_pos_y = mouse_y - (_mCE.style.top.replace("px","") || calculeOffsetTop(_mCE));\r
188                 return false;\r
189         };\r
190         \r
191         function end_move_element(e){\r
192                 _mCE.frame.document.onmousemove= "";\r
193                 _mCE.frame.document.onmouseup= "";              \r
194                 _mCE=null;\r
195         };\r
196         \r
197         function move_element(e){\r
198                 var newTop,newLeft,maxLeft;\r
199 \r
200                 if( _mCE.frame && _mCE.frame.event )\r
201                         e=_mCE.frame.event;\r
202                 newTop  = getMouseY(e) - _mCE.start_pos_y;\r
203                 newLeft = getMouseX(e) - _mCE.start_pos_x;\r
204                 \r
205                 maxLeft = _mCE.frame.document.body.offsetWidth- _mCE.offsetWidth;\r
206                 max_top = _mCE.frame.document.body.offsetHeight- _mCE.offsetHeight;\r
207                 newTop  = Math.min(Math.max(0, newTop), max_top);\r
208                 newLeft = Math.min(Math.max(0, newLeft), maxLeft);\r
209                 \r
210                 _mCE.style.top  = newTop+"px";\r
211                 _mCE.style.left = newLeft+"px";         \r
212                 return false;\r
213         };\r
214         \r
215 /***\r
216  * Managing a textarea (this part need the navigator infos from editAreaLoader\r
217  ***/ \r
218         \r
219         var nav= editAreaLoader.nav;\r
220         \r
221         // allow to get infos on the selection: array(start, end)\r
222         function getSelectionRange(textarea){\r
223                 return {"start": textarea.selectionStart, "end": textarea.selectionEnd};\r
224         };\r
225         \r
226         // allow to set the selection\r
227         function setSelectionRange(t, start, end){\r
228                 t.focus();\r
229                 \r
230                 start   = Math.max(0, Math.min(t.value.length, start));\r
231                 end             = Math.max(start, Math.min(t.value.length, end));\r
232         \r
233                 if( this.isOpera && this.isOpera < 9.6 ){       // Opera bug when moving selection start and selection end\r
234                         t.selectionEnd = 1;     \r
235                         t.selectionStart = 0;                   \r
236                         t.selectionEnd = 1;     \r
237                         t.selectionStart = 0;           \r
238                 }\r
239                 t.selectionStart        = start;\r
240                 t.selectionEnd          = end;          \r
241                 //textarea.setSelectionRange(start, end);\r
242                 \r
243                 if(isIE)\r
244                         set_IE_selection(t);\r
245         };\r
246 \r
247         \r
248         // set IE position in Firefox mode (textarea.selectionStart and textarea.selectionEnd). should work as a repeated task\r
249         function get_IE_selection(t){\r
250                 var d=document,div,range,stored_range,elem,scrollTop,relative_top,line_start,line_nb,range_start,range_end,tab;\r
251                 if(t && t.focused)\r
252                 {       \r
253                         if(!t.ea_line_height)\r
254                         {       // calculate the lineHeight\r
255                                 div= d.createElement("div");\r
256                                 div.style.fontFamily= get_css_property(t, "font-family");\r
257                                 div.style.fontSize= get_css_property(t, "font-size");\r
258                                 div.style.visibility= "hidden";                 \r
259                                 div.innerHTML="0";\r
260                                 d.body.appendChild(div);\r
261                                 t.ea_line_height= div.offsetHeight;\r
262                                 d.body.removeChild(div);\r
263                         }\r
264                         //t.focus();\r
265                         range = d.selection.createRange();\r
266                         try\r
267                         {\r
268                                 stored_range = range.duplicate();\r
269                                 stored_range.moveToElementText( t );\r
270                                 stored_range.setEndPoint( 'EndToEnd', range );\r
271                                 if(stored_range.parentElement() == t){\r
272                                         // the range don't take care of empty lines in the end of the selection\r
273                                         elem            = t;\r
274                                         scrollTop       = 0;\r
275                                         while(elem.parentNode){\r
276                                                 scrollTop+= elem.scrollTop;\r
277                                                 elem    = elem.parentNode;\r
278                                         }\r
279                                 \r
280                                 //      var scrollTop= t.scrollTop + document.body.scrollTop;\r
281                                         \r
282                                 //      var relative_top= range.offsetTop - calculeOffsetTop(t) + scrollTop;\r
283                                         relative_top= range.offsetTop - calculeOffsetTop(t)+ scrollTop;\r
284                                 //      alert("rangeoffset: "+ range.offsetTop +"\ncalcoffsetTop: "+ calculeOffsetTop(t) +"\nrelativeTop: "+ relative_top);\r
285                                         line_start      = Math.round((relative_top / t.ea_line_height) +1);\r
286                                         \r
287                                         line_nb         = Math.round(range.boundingHeight / t.ea_line_height);\r
288                                         \r
289                                         range_start     = stored_range.text.length - range.text.length;\r
290                                         tab     = t.value.substr(0, range_start).split("\n");                   \r
291                                         range_start     += (line_start - tab.length)*2;         // add missing empty lines to the selection\r
292                                         t.selectionStart = range_start;\r
293                                         \r
294                                         range_end       = t.selectionStart + range.text.length;\r
295                                         tab     = t.value.substr(0, range_start + range.text.length).split("\n");                       \r
296                                         range_end       += (line_start + line_nb - 1 - tab.length)*2;\r
297                                         t.selectionEnd = range_end;\r
298                                 }\r
299                         }\r
300                         catch(e){}\r
301                 }\r
302                 setTimeout("get_IE_selection(document.getElementById('"+ t.id +"'));", 50);\r
303         };\r
304         \r
305         function IE_textarea_focus(){\r
306                 event.srcElement.focused= true;\r
307         }\r
308         \r
309         function IE_textarea_blur(){\r
310                 event.srcElement.focused= false;\r
311         }\r
312         \r
313         // select the text for IE (take into account the \r difference)\r
314         function set_IE_selection( t ){\r
315                 var nbLineStart,nbLineStart,nbLineEnd,range;\r
316                 if(!window.closed){ \r
317                         nbLineStart=t.value.substr(0, t.selectionStart).split("\n").length - 1;\r
318                         nbLineEnd=t.value.substr(0, t.selectionEnd).split("\n").length - 1;\r
319                         try\r
320                         {\r
321                                 range = document.selection.createRange();\r
322                                 range.moveToElementText( t );\r
323                                 range.setEndPoint( 'EndToStart', range );\r
324                                 range.moveStart('character', t.selectionStart - nbLineStart);\r
325                                 range.moveEnd('character', t.selectionEnd - nbLineEnd - (t.selectionStart - nbLineStart)  );\r
326                                 range.select();\r
327                         }\r
328                         catch(e){}\r
329                 }\r
330         };\r
331         \r
332         \r
333         editAreaLoader.waiting_loading["elements_functions.js"]= "loaded";\r