mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
226 lines
5.1 KiB
JavaScript
226 lines
5.1 KiB
JavaScript
|
/**
|
||
|
* plugin.js
|
||
|
*
|
||
|
* Released under LGPL License.
|
||
|
* Copyright (c) 1999-2015 Ephox Corp. All rights reserved
|
||
|
*
|
||
|
* License: http://www.tinymce.com/license
|
||
|
* Contributing: http://www.tinymce.com/contributing
|
||
|
*/
|
||
|
|
||
|
/*global tinymce:true */
|
||
|
|
||
|
tinymce.PluginManager.add('layer', function(editor) {
|
||
|
function getParentLayer(node) {
|
||
|
do {
|
||
|
if (node.className && node.className.indexOf('mceItemLayer') != -1) {
|
||
|
return node;
|
||
|
}
|
||
|
} while ((node = node.parentNode));
|
||
|
}
|
||
|
|
||
|
function visualAid(e) {
|
||
|
var dom = editor.dom;
|
||
|
|
||
|
tinymce.each(dom.select('div,p', e), function(e) {
|
||
|
if (/^(absolute|relative|fixed)$/i.test(e.style.position)) {
|
||
|
if (e.hasVisual) {
|
||
|
dom.addClass(e, 'mceItemVisualAid');
|
||
|
} else {
|
||
|
dom.removeClass(e, 'mceItemVisualAid');
|
||
|
}
|
||
|
|
||
|
dom.addClass(e, 'mceItemLayer');
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
function move(d) {
|
||
|
var i, z = [], le = getParentLayer(editor.selection.getNode()), ci = -1, fi = -1, nl;
|
||
|
|
||
|
nl = [];
|
||
|
tinymce.walk(editor.getBody(), function(n) {
|
||
|
if (n.nodeType == 1 && /^(absolute|relative|static)$/i.test(n.style.position)) {
|
||
|
nl.push(n);
|
||
|
}
|
||
|
}, 'childNodes');
|
||
|
|
||
|
// Find z-indexes
|
||
|
for (i = 0; i < nl.length; i++) {
|
||
|
z[i] = nl[i].style.zIndex ? parseInt(nl[i].style.zIndex, 10) : 0;
|
||
|
|
||
|
if (ci < 0 && nl[i] == le) {
|
||
|
ci = i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (d < 0) {
|
||
|
// Move back
|
||
|
|
||
|
// Try find a lower one
|
||
|
for (i = 0; i < z.length; i++) {
|
||
|
if (z[i] < z[ci]) {
|
||
|
fi = i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (fi > -1) {
|
||
|
nl[ci].style.zIndex = z[fi];
|
||
|
nl[fi].style.zIndex = z[ci];
|
||
|
} else {
|
||
|
if (z[ci] > 0) {
|
||
|
nl[ci].style.zIndex = z[ci] - 1;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
// Move forward
|
||
|
|
||
|
// Try find a higher one
|
||
|
for (i = 0; i < z.length; i++) {
|
||
|
if (z[i] > z[ci]) {
|
||
|
fi = i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (fi > -1) {
|
||
|
nl[ci].style.zIndex = z[fi];
|
||
|
nl[fi].style.zIndex = z[ci];
|
||
|
} else {
|
||
|
nl[ci].style.zIndex = z[ci] + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
editor.execCommand('mceRepaint');
|
||
|
}
|
||
|
|
||
|
function insertLayer() {
|
||
|
var dom = editor.dom, p = dom.getPos(dom.getParent(editor.selection.getNode(), '*'));
|
||
|
var body = editor.getBody();
|
||
|
|
||
|
editor.dom.add(body, 'div', {
|
||
|
style: {
|
||
|
position: 'absolute',
|
||
|
left: p.x,
|
||
|
top: (p.y > 20 ? p.y : 20),
|
||
|
width: 100,
|
||
|
height: 100
|
||
|
},
|
||
|
'class': 'mceItemVisualAid mceItemLayer'
|
||
|
}, editor.selection.getContent() || editor.getLang('layer.content'));
|
||
|
|
||
|
// Workaround for IE where it messes up the JS engine if you insert a layer on IE 6,7
|
||
|
if (tinymce.Env.ie) {
|
||
|
dom.setHTML(body, body.innerHTML);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function toggleAbsolute() {
|
||
|
var le = getParentLayer(editor.selection.getNode());
|
||
|
|
||
|
if (!le) {
|
||
|
le = editor.dom.getParent(editor.selection.getNode(), 'DIV,P,IMG');
|
||
|
}
|
||
|
|
||
|
if (le) {
|
||
|
if (le.style.position.toLowerCase() == "absolute") {
|
||
|
editor.dom.setStyles(le, {
|
||
|
position: '',
|
||
|
left: '',
|
||
|
top: '',
|
||
|
width: '',
|
||
|
height: ''
|
||
|
});
|
||
|
|
||
|
editor.dom.removeClass(le, 'mceItemVisualAid');
|
||
|
editor.dom.removeClass(le, 'mceItemLayer');
|
||
|
} else {
|
||
|
if (!le.style.left) {
|
||
|
le.style.left = 20 + 'px';
|
||
|
}
|
||
|
|
||
|
if (!le.style.top) {
|
||
|
le.style.top = 20 + 'px';
|
||
|
}
|
||
|
|
||
|
if (!le.style.width) {
|
||
|
le.style.width = le.width ? (le.width + 'px') : '100px';
|
||
|
}
|
||
|
|
||
|
if (!le.style.height) {
|
||
|
le.style.height = le.height ? (le.height + 'px') : '100px';
|
||
|
}
|
||
|
|
||
|
le.style.position = "absolute";
|
||
|
|
||
|
editor.dom.setAttrib(le, 'data-mce-style', '');
|
||
|
editor.addVisual(editor.getBody());
|
||
|
}
|
||
|
|
||
|
editor.execCommand('mceRepaint');
|
||
|
editor.nodeChanged();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Register commands
|
||
|
editor.addCommand('mceInsertLayer', insertLayer);
|
||
|
|
||
|
editor.addCommand('mceMoveForward', function() {
|
||
|
move(1);
|
||
|
});
|
||
|
|
||
|
editor.addCommand('mceMoveBackward', function() {
|
||
|
move(-1);
|
||
|
});
|
||
|
|
||
|
editor.addCommand('mceMakeAbsolute', function() {
|
||
|
toggleAbsolute();
|
||
|
});
|
||
|
|
||
|
// Register buttons
|
||
|
editor.addButton('moveforward', {title: 'layer.forward_desc', cmd: 'mceMoveForward'});
|
||
|
editor.addButton('movebackward', {title: 'layer.backward_desc', cmd: 'mceMoveBackward'});
|
||
|
editor.addButton('absolute', {title: 'layer.absolute_desc', cmd: 'mceMakeAbsolute'});
|
||
|
editor.addButton('insertlayer', {title: 'layer.insertlayer_desc', cmd: 'mceInsertLayer'});
|
||
|
|
||
|
editor.on('init', function() {
|
||
|
if (tinymce.Env.ie) {
|
||
|
editor.getDoc().execCommand('2D-Position', false, true);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Remove serialized styles when selecting a layer since it might be changed by a drag operation
|
||
|
editor.on('mouseup', function(e) {
|
||
|
var layer = getParentLayer(e.target);
|
||
|
|
||
|
if (layer) {
|
||
|
editor.dom.setAttrib(layer, 'data-mce-style', '');
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// Fixes edit focus issues with layers on Gecko
|
||
|
// This will enable designMode while inside a layer and disable it when outside
|
||
|
editor.on('mousedown', function(e) {
|
||
|
var node = e.target, doc = editor.getDoc(), parent;
|
||
|
|
||
|
if (tinymce.Env.gecko) {
|
||
|
if (getParentLayer(node)) {
|
||
|
if (doc.designMode !== 'on') {
|
||
|
doc.designMode = 'on';
|
||
|
|
||
|
// Repaint caret
|
||
|
node = doc.body;
|
||
|
parent = node.parentNode;
|
||
|
parent.removeChild(node);
|
||
|
parent.appendChild(node);
|
||
|
}
|
||
|
} else if (doc.designMode == 'on') {
|
||
|
doc.designMode = 'off';
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
editor.on('NodeChange', visualAid);
|
||
|
});
|