Updated tiny-mce to most recent 3.4 version
[citadel.git] / webcit / tiny_mce / plugins / layer / editor_plugin_src.js
1 /**\r
2  * editor_plugin_src.js\r
3  *\r
4  * Copyright 2009, Moxiecode Systems AB\r
5  * Released under LGPL License.\r
6  *\r
7  * License: http://tinymce.moxiecode.com/license\r
8  * Contributing: http://tinymce.moxiecode.com/contributing\r
9  */\r
10 \r
11 (function() {\r
12         function findParentLayer(node) {\r
13                 do {\r
14                         if (node.className && node.className.indexOf('mceItemLayer') != -1) {\r
15                                 return node;\r
16                         }\r
17                 } while (node = node.parentNode);\r
18         };\r
19 \r
20         tinymce.create('tinymce.plugins.Layer', {\r
21                 init : function(ed, url) {\r
22                         var t = this;\r
23 \r
24                         t.editor = ed;\r
25 \r
26                         // Register commands\r
27                         ed.addCommand('mceInsertLayer', t._insertLayer, t);\r
28 \r
29                         ed.addCommand('mceMoveForward', function() {\r
30                                 t._move(1);\r
31                         });\r
32 \r
33                         ed.addCommand('mceMoveBackward', function() {\r
34                                 t._move(-1);\r
35                         });\r
36 \r
37                         ed.addCommand('mceMakeAbsolute', function() {\r
38                                 t._toggleAbsolute();\r
39                         });\r
40 \r
41                         // Register buttons\r
42                         ed.addButton('moveforward', {title : 'layer.forward_desc', cmd : 'mceMoveForward'});\r
43                         ed.addButton('movebackward', {title : 'layer.backward_desc', cmd : 'mceMoveBackward'});\r
44                         ed.addButton('absolute', {title : 'layer.absolute_desc', cmd : 'mceMakeAbsolute'});\r
45                         ed.addButton('insertlayer', {title : 'layer.insertlayer_desc', cmd : 'mceInsertLayer'});\r
46 \r
47                         ed.onInit.add(function() {\r
48                                 var dom = ed.dom;\r
49 \r
50                                 if (tinymce.isIE)\r
51                                         ed.getDoc().execCommand('2D-Position', false, true);\r
52                         });\r
53 \r
54                         // Remove serialized styles when selecting a layer since it might be changed by a drag operation\r
55                         ed.onMouseUp.add(function(ed, e) {\r
56                                 var layer = findParentLayer(e.target);\r
57         \r
58                                 if (layer) {\r
59                                         ed.dom.setAttrib(layer, 'data-mce-style', '');\r
60                                 }\r
61                         });\r
62 \r
63                         // Fixes edit focus issues with layers on Gecko\r
64                         // This will enable designMode while inside a layer and disable it when outside\r
65                         ed.onMouseDown.add(function(ed, e) {\r
66                                 var node = e.target, doc = ed.getDoc(), parent;\r
67 \r
68                                 if (tinymce.isGecko) {\r
69                                         if (findParentLayer(node)) {\r
70                                                 if (doc.designMode !== 'on') {\r
71                                                         doc.designMode = 'on';\r
72 \r
73                                                         // Repaint caret\r
74                                                         node = doc.body;\r
75                                                         parent = node.parentNode;\r
76                                                         parent.removeChild(node);\r
77                                                         parent.appendChild(node);\r
78                                                 }\r
79                                         } else if (doc.designMode == 'on') {\r
80                                                 doc.designMode = 'off';\r
81                                         }\r
82                                 }\r
83                         });\r
84 \r
85                         ed.onNodeChange.add(t._nodeChange, t);\r
86                         ed.onVisualAid.add(t._visualAid, t);\r
87                 },\r
88 \r
89                 getInfo : function() {\r
90                         return {\r
91                                 longname : 'Layer',\r
92                                 author : 'Moxiecode Systems AB',\r
93                                 authorurl : 'http://tinymce.moxiecode.com',\r
94                                 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/layer',\r
95                                 version : tinymce.majorVersion + "." + tinymce.minorVersion\r
96                         };\r
97                 },\r
98 \r
99                 // Private methods\r
100 \r
101                 _nodeChange : function(ed, cm, n) {\r
102                         var le, p;\r
103 \r
104                         le = this._getParentLayer(n);\r
105                         p = ed.dom.getParent(n, 'DIV,P,IMG');\r
106 \r
107                         if (!p) {\r
108                                 cm.setDisabled('absolute', 1);\r
109                                 cm.setDisabled('moveforward', 1);\r
110                                 cm.setDisabled('movebackward', 1);\r
111                         } else {\r
112                                 cm.setDisabled('absolute', 0);\r
113                                 cm.setDisabled('moveforward', !le);\r
114                                 cm.setDisabled('movebackward', !le);\r
115                                 cm.setActive('absolute', le && le.style.position.toLowerCase() == "absolute");\r
116                         }\r
117                 },\r
118 \r
119                 // Private methods\r
120 \r
121                 _visualAid : function(ed, e, s) {\r
122                         var dom = ed.dom;\r
123 \r
124                         tinymce.each(dom.select('div,p', e), function(e) {\r
125                                 if (/^(absolute|relative|fixed)$/i.test(e.style.position)) {\r
126                                         if (s)\r
127                                                 dom.addClass(e, 'mceItemVisualAid');\r
128                                         else\r
129                                                 dom.removeClass(e, 'mceItemVisualAid');\r
130 \r
131                                         dom.addClass(e, 'mceItemLayer');\r
132                                 }\r
133                         });\r
134                 },\r
135 \r
136                 _move : function(d) {\r
137                         var ed = this.editor, i, z = [], le = this._getParentLayer(ed.selection.getNode()), ci = -1, fi = -1, nl;\r
138 \r
139                         nl = [];\r
140                         tinymce.walk(ed.getBody(), function(n) {\r
141                                 if (n.nodeType == 1 && /^(absolute|relative|static)$/i.test(n.style.position))\r
142                                         nl.push(n); \r
143                         }, 'childNodes');\r
144 \r
145                         // Find z-indexes\r
146                         for (i=0; i<nl.length; i++) {\r
147                                 z[i] = nl[i].style.zIndex ? parseInt(nl[i].style.zIndex) : 0;\r
148 \r
149                                 if (ci < 0 && nl[i] == le)\r
150                                         ci = i;\r
151                         }\r
152 \r
153                         if (d < 0) {\r
154                                 // Move back\r
155 \r
156                                 // Try find a lower one\r
157                                 for (i=0; i<z.length; i++) {\r
158                                         if (z[i] < z[ci]) {\r
159                                                 fi = i;\r
160                                                 break;\r
161                                         }\r
162                                 }\r
163 \r
164                                 if (fi > -1) {\r
165                                         nl[ci].style.zIndex = z[fi];\r
166                                         nl[fi].style.zIndex = z[ci];\r
167                                 } else {\r
168                                         if (z[ci] > 0)\r
169                                                 nl[ci].style.zIndex = z[ci] - 1;\r
170                                 }\r
171                         } else {\r
172                                 // Move forward\r
173 \r
174                                 // Try find a higher one\r
175                                 for (i=0; i<z.length; i++) {\r
176                                         if (z[i] > z[ci]) {\r
177                                                 fi = i;\r
178                                                 break;\r
179                                         }\r
180                                 }\r
181 \r
182                                 if (fi > -1) {\r
183                                         nl[ci].style.zIndex = z[fi];\r
184                                         nl[fi].style.zIndex = z[ci];\r
185                                 } else\r
186                                         nl[ci].style.zIndex = z[ci] + 1;\r
187                         }\r
188 \r
189                         ed.execCommand('mceRepaint');\r
190                 },\r
191 \r
192                 _getParentLayer : function(n) {\r
193                         return this.editor.dom.getParent(n, function(n) {\r
194                                 return n.nodeType == 1 && /^(absolute|relative|static)$/i.test(n.style.position);\r
195                         });\r
196                 },\r
197 \r
198                 _insertLayer : function() {\r
199                         var ed = this.editor, dom = ed.dom, p = dom.getPos(dom.getParent(ed.selection.getNode(), '*')), body = ed.getBody();\r
200 \r
201                         ed.dom.add(body, 'div', {\r
202                                 style : {\r
203                                         position : 'absolute',\r
204                                         left : p.x,\r
205                                         top : (p.y > 20 ? p.y : 20),\r
206                                         width : 100,\r
207                                         height : 100\r
208                                 },\r
209                                 'class' : 'mceItemVisualAid mceItemLayer'\r
210                         }, ed.selection.getContent() || ed.getLang('layer.content'));\r
211 \r
212                         // Workaround for IE where it messes up the JS engine if you insert a layer on IE 6,7\r
213                         if (tinymce.isIE)\r
214                                 dom.setHTML(body, body.innerHTML);\r
215                 },\r
216 \r
217                 _toggleAbsolute : function() {\r
218                         var ed = this.editor, le = this._getParentLayer(ed.selection.getNode());\r
219 \r
220                         if (!le)\r
221                                 le = ed.dom.getParent(ed.selection.getNode(), 'DIV,P,IMG');\r
222 \r
223                         if (le) {\r
224                                 if (le.style.position.toLowerCase() == "absolute") {\r
225                                         ed.dom.setStyles(le, {\r
226                                                 position : '',\r
227                                                 left : '',\r
228                                                 top : '',\r
229                                                 width : '',\r
230                                                 height : ''\r
231                                         });\r
232 \r
233                                         ed.dom.removeClass(le, 'mceItemVisualAid');\r
234                                         ed.dom.removeClass(le, 'mceItemLayer');\r
235                                 } else {\r
236                                         if (le.style.left == "")\r
237                                                 le.style.left = 20 + 'px';\r
238 \r
239                                         if (le.style.top == "")\r
240                                                 le.style.top = 20 + 'px';\r
241 \r
242                                         if (le.style.width == "")\r
243                                                 le.style.width = le.width ? (le.width + 'px') : '100px';\r
244 \r
245                                         if (le.style.height == "")\r
246                                                 le.style.height = le.height ? (le.height + 'px') : '100px';\r
247 \r
248                                         le.style.position = "absolute";\r
249 \r
250                                         ed.dom.setAttrib(le, 'data-mce-style', '');\r
251                                         ed.addVisual(ed.getBody());\r
252                                 }\r
253 \r
254                                 ed.execCommand('mceRepaint');\r
255                                 ed.nodeChanged();\r
256                         }\r
257                 }\r
258         });\r
259 \r
260         // Register plugin\r
261         tinymce.PluginManager.add('layer', tinymce.plugins.Layer);\r
262 })();