4 * Copyright 2009, Moxiecode Systems AB
5 * Released under LGPL License.
7 * License: http://tinymce.moxiecode.com/license
8 * Contributing: http://tinymce.moxiecode.com/contributing
12 function findParentLayer(node
) {
14 if (node
.className
&& node
.className
.indexOf('mceItemLayer') != -1) {
17 } while (node
= node
.parentNode
);
20 tinymce
.create('tinymce.plugins.Layer', {
21 init : function(ed
, url
) {
27 ed
.addCommand('mceInsertLayer', t
._insertLayer
, t
);
29 ed
.addCommand('mceMoveForward', function() {
33 ed
.addCommand('mceMoveBackward', function() {
37 ed
.addCommand('mceMakeAbsolute', function() {
42 ed
.addButton('moveforward', {title
: 'layer.forward_desc', cmd
: 'mceMoveForward'});
43 ed
.addButton('movebackward', {title
: 'layer.backward_desc', cmd
: 'mceMoveBackward'});
44 ed
.addButton('absolute', {title
: 'layer.absolute_desc', cmd
: 'mceMakeAbsolute'});
45 ed
.addButton('insertlayer', {title
: 'layer.insertlayer_desc', cmd
: 'mceInsertLayer'});
47 ed
.onInit
.add(function() {
51 ed
.getDoc().execCommand('2D-Position', false, true);
54 // Remove serialized styles when selecting a layer since it might be changed by a drag operation
55 ed
.onMouseUp
.add(function(ed
, e
) {
56 var layer
= findParentLayer(e
.target
);
59 ed
.dom
.setAttrib(layer
, 'data-mce-style', '');
63 // Fixes edit focus issues with layers on Gecko
64 // This will enable designMode while inside a layer and disable it when outside
65 ed
.onMouseDown
.add(function(ed
, e
) {
66 var node
= e
.target
, doc
= ed
.getDoc(), parent
;
68 if (tinymce
.isGecko
) {
69 if (findParentLayer(node
)) {
70 if (doc
.designMode
!== 'on') {
71 doc
.designMode
= 'on';
75 parent
= node
.parentNode
;
76 parent
.removeChild(node
);
77 parent
.appendChild(node
);
79 } else if (doc
.designMode
== 'on') {
80 doc
.designMode
= 'off';
85 ed
.onNodeChange
.add(t
._nodeChange
, t
);
86 ed
.onVisualAid
.add(t
._visualAid
, t
);
89 getInfo : function() {
92 author
: 'Moxiecode Systems AB',
93 authorurl
: 'http://tinymce.moxiecode.com',
94 infourl
: 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/layer',
95 version
: tinymce
.majorVersion
+ "." + tinymce
.minorVersion
101 _nodeChange : function(ed
, cm
, n
) {
104 le
= this._getParentLayer(n
);
105 p
= ed
.dom
.getParent(n
, 'DIV,P,IMG');
108 cm
.setDisabled('absolute', 1);
109 cm
.setDisabled('moveforward', 1);
110 cm
.setDisabled('movebackward', 1);
112 cm
.setDisabled('absolute', 0);
113 cm
.setDisabled('moveforward', !le
);
114 cm
.setDisabled('movebackward', !le
);
115 cm
.setActive('absolute', le
&& le
.style
.position
.toLowerCase() == "absolute");
121 _visualAid : function(ed
, e
, s
) {
124 tinymce
.each(dom
.select('div,p', e
), function(e
) {
125 if (/^(absolute|relative|fixed)$/i.test(e
.style
.position
)) {
127 dom
.addClass(e
, 'mceItemVisualAid');
129 dom
.removeClass(e
, 'mceItemVisualAid');
131 dom
.addClass(e
, 'mceItemLayer');
136 _move : function(d
) {
137 var ed
= this.editor
, i
, z
= [], le
= this._getParentLayer(ed
.selection
.getNode()), ci
= -1, fi
= -1, nl
;
140 tinymce
.walk(ed
.getBody(), function(n
) {
141 if (n
.nodeType
== 1 && /^(absolute|relative|static)$/i.test(n
.style
.position
))
146 for (i
=0; i
<nl
.length
; i
++) {
147 z
[i
] = nl
[i
].style
.zIndex
? parseInt(nl
[i
].style
.zIndex
) : 0;
149 if (ci
< 0 && nl
[i
] == le
)
156 // Try find a lower one
157 for (i
=0; i
<z
.length
; i
++) {
165 nl
[ci
].style
.zIndex
= z
[fi
];
166 nl
[fi
].style
.zIndex
= z
[ci
];
169 nl
[ci
].style
.zIndex
= z
[ci
] - 1;
174 // Try find a higher one
175 for (i
=0; i
<z
.length
; i
++) {
183 nl
[ci
].style
.zIndex
= z
[fi
];
184 nl
[fi
].style
.zIndex
= z
[ci
];
186 nl
[ci
].style
.zIndex
= z
[ci
] + 1;
189 ed
.execCommand('mceRepaint');
192 _getParentLayer : function(n
) {
193 return this.editor
.dom
.getParent(n
, function(n
) {
194 return n
.nodeType
== 1 && /^(absolute|relative|static)$/i.test(n
.style
.position
);
198 _insertLayer : function() {
199 var ed
= this.editor
, dom
= ed
.dom
, p
= dom
.getPos(dom
.getParent(ed
.selection
.getNode(), '*')), body
= ed
.getBody();
201 ed
.dom
.add(body
, 'div', {
203 position
: 'absolute',
205 top
: (p
.y
> 20 ? p
.y
: 20),
209 'class' : 'mceItemVisualAid mceItemLayer'
210 }, ed
.selection
.getContent() || ed
.getLang('layer.content'));
212 // Workaround for IE where it messes up the JS engine if you insert a layer on IE 6,7
214 dom
.setHTML(body
, body
.innerHTML
);
217 _toggleAbsolute : function() {
218 var ed
= this.editor
, le
= this._getParentLayer(ed
.selection
.getNode());
221 le
= ed
.dom
.getParent(ed
.selection
.getNode(), 'DIV,P,IMG');
224 if (le
.style
.position
.toLowerCase() == "absolute") {
225 ed
.dom
.setStyles(le
, {
233 ed
.dom
.removeClass(le
, 'mceItemVisualAid');
234 ed
.dom
.removeClass(le
, 'mceItemLayer');
236 if (le
.style
.left
== "")
237 le
.style
.left
= 20 + 'px';
239 if (le
.style
.top
== "")
240 le
.style
.top
= 20 + 'px';
242 if (le
.style
.width
== "")
243 le
.style
.width
= le
.width
? (le
.width
+ 'px') : '100px';
245 if (le
.style
.height
== "")
246 le
.style
.height
= le
.height
? (le
.height
+ 'px') : '100px';
248 le
.style
.position
= "absolute";
250 ed
.dom
.setAttrib(le
, 'data-mce-style', '');
251 ed
.addVisual(ed
.getBody());
254 ed
.execCommand('mceRepaint');
261 tinymce
.PluginManager
.add('layer', tinymce
.plugins
.Layer
);