diff options
Diffstat (limited to 'sca-cpp/trunk/modules/edit/htdocs/page/page.js')
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/page/page.js | 165 |
1 files changed, 112 insertions, 53 deletions
diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/page.js b/sca-cpp/trunk/modules/edit/htdocs/page/page.js index 25f6399075..4628ec1235 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/page/page.js +++ b/sca-cpp/trunk/modules/edit/htdocs/page/page.js @@ -20,56 +20,66 @@ /** * Page editing functions. */ -var page = new Object(); +var page = {}; if (ui.isIE()) { /** - * Init a page editor. + * Init a page editor. IE-specific implementation. */ page.initpage = function(elem) { - page.dragging = null; - function draggable(n) { - if (n == elem) - return null; - if (n.id != '') - return n; - if (n.covered) - return n.covered; - return draggable(n.parentNode); - } - - function bringtotop(n) { - n.parentNode.appendChild(n); - n.cover.parentNode.appendChild(n.cover); - } + // Keep track of the current dragged element + page.dragging = null; + /** + * Handle a mouse down event. + */ elem.onmousedown = function() { window.event.returnValue = false; - page.dragging = draggable(window.event.srcElement); + + // Find a draggable element + page.dragging = page.draggable(window.event.srcElement, elem); if (page.dragging == null) return false; - bringtotop(page.dragging); + + // Bring it to the top + page.bringtotop(page.dragging); + + // Save the mouse position page.dragX = window.event.clientX; page.dragY = window.event.clientY; elem.setCapture(); return false; }; + /** + * Handle a mouse up event. + */ elem.onmouseup = function() { if (page.dragging == null) return false; + + // Discard element dragged out of page area + if (ui.csspos(page.dragging.style.left) < 350 && page.dragging.id.substring(0, 8) != 'palette:') + page.dragging.parentNode.removeChild(page.dragging); + + // Forget current dragged element page.dragging = null; elem.releaseCapture(); return false; }; + /** + * Handle a mouse move event. + */ elem.onmousemove = function() { if (page.dragging == null) return false; - var curX = ui.posn(page.dragging.style.left); - var curY = ui.posn(page.dragging.style.top); + + // Compute dragged element position + var curX = ui.csspos(page.dragging.style.left); + var curY = ui.csspos(page.dragging.style.top); var newX = curX + (window.event.clientX - page.dragX); var newY = curY + (window.event.clientY - page.dragY); if (newX >= 0) @@ -81,10 +91,11 @@ if (ui.isIE()) { else newY = 0; - if (page.dragging.id.substring(0, 8) == 'palette:') { - // Clone the dragged element + // Clone element dragged from palette + if (page.dragging.id.substring(0, 8) == 'palette:') page.dragging = page.clone(page.dragging); - } + + // Move dragged element page.dragging.style.left = newX; page.dragging.style.top = newY; page.dragging.cover.style.left = newX; @@ -92,7 +103,8 @@ if (ui.isIE()) { }; - // Cover child elements with span elements + // Cover child elements with span elements to prevent + // any input events to reach them map(page.cover, nodeList(elem.childNodes)); return elem; @@ -101,59 +113,69 @@ if (ui.isIE()) { } else { /** - * Init a page editor. + * Init a page editor. Generic implementation for all other browsers. */ page.initpage = function(elem) { page.dragging = null; - function draggable(n) { - if (n == elem) - return null; - if (n.id != '') - return n; - if (n.covered) - return n.covered; - return draggable(n.parentNode); - } - - function bringtotop(n) { - n.parentNode.appendChild(n); - n.cover.parentNode.appendChild(n.cover); - } - + /** + * Handle a mouse down event. + */ elem.onmousedown = function(e) { if (e.preventDefault) e.preventDefault(); else e.returnValue = false; - page.dragging = draggable(e.target); + + // Find a draggable element + page.dragging = page.draggable(e.target, elem); if (page.dragging == null) return false; - bringtotop(page.dragging); + + // Bring it to the top + page.bringtotop(page.dragging); + + // Remember mouse position var pos = typeof e.touches != "undefined" ? e.touches[0] : e; page.dragX = pos.screenX; page.dragY = pos.screenY; return false; }; + // Support touch devices elem.ontouchstart = elem.onmousedown; + /** + * Handle a mouse up event. + */ window.onmouseup = function(e) { if (page.dragging == null) return false; + + // Discard element if dragged out of page area + if (ui.csspos(page.dragging.style.left) < 350 && page.dragging.id.substring(0, 8) != 'palette:') + page.dragging.parentNode.removeChild(page.dragging); + + // Forget dragged element page.dragging = null; return false; }; + // Support touch devices window.top.onmouseup = window.onmouseup; window.ontouchend = window.onmouseup; window.top.ontouchend = window.onmouseup; + /** + * Handle a mouse move event. + */ window.onmousemove = function(e) { if (page.dragging == null) return false; - var curX = ui.posn(page.dragging.style.left); - var curY = ui.posn(page.dragging.style.top); + + // Compute position of dragged element + var curX = ui.csspos(page.dragging.style.left); + var curY = ui.csspos(page.dragging.style.top); var pos = typeof e.touches != "undefined" ? e.touches[0] : e; var newX = curX + (pos.screenX - page.dragX); var newY = curY + (pos.screenY - page.dragY); @@ -166,10 +188,12 @@ if (ui.isIE()) { else newY = 0; + // Clone element dragged from palette if (page.dragging.id.substring(0, 8) == 'palette:') { - // Clone the dragged element page.dragging = page.clone(page.dragging); } + + // Move the dragged element page.dragging.style.left = newX; page.dragging.style.top = newY; page.dragging.cover.style.left = newX; @@ -177,11 +201,13 @@ if (ui.isIE()) { return false; }; + // Support touch devices window.top.onmousemove = window.onmousemove; window.ontouchmove = window.onmousemove; window.top.ontouchmove = window.onmousemove; - // Cover child elements with span elements + // Cover child elements with span elements to prevent + // any input events to reach them map(page.cover, nodeList(elem.childNodes)); return elem; @@ -189,15 +215,37 @@ if (ui.isIE()) { } /** - * Cover a page element with a <span> element to prevent mouse events to reach it. + * Find a draggable element in a hierarchy of elements. + */ +page.draggable = function(n, e) { + if (n == e) + return null; + if (n.id != '') + return n; + if (n.covered) + return n.covered; + return page.draggable(n.parentNode, e); +} + +/** + * Bring an element and its parent to the top. + */ +page.bringtotop = function(n) { + n.parentNode.appendChild(n); + n.cover.parentNode.appendChild(n.cover); +} + +/** + * Cover a page element with a <span> element to prevent + * any input events to reach it. */ page.cover = function(e) { if (e.id == '' || isNil(e.style)) return e; var cover = document.createElement('span'); cover.style.position = 'absolute'; - cover.style.left = ui.posn(e.style.left) - 5; - cover.style.top = ui.posn(e.style.top) - 5; + cover.style.left = ui.csspos(e.style.left) - 5; + cover.style.top = ui.csspos(e.style.top) - 5; cover.style.width = e.clientWidth + 10; cover.style.height = e.clientHeight + 10; cover.style.visibility = 'visible'; @@ -208,20 +256,31 @@ page.cover = function(e) { } /** - * Clone a page element. + * Clone a palette element. */ page.clone = function(e) { + + /** + * Clone an element's HTML. + */ function mkclone(e) { var ne = document.createElement('span'); + + // Skip the palette: prefix ne.id = e.id.substr(8); + + // Copy the HTML content ne.innerHTML = e.innerHTML; return ne; } + /** + * Clone an element's position. + */ function posclone(ne, e) { ne.style.position = 'absolute'; - ne.style.left = ui.posn(e.style.left); - ne.style.top = ui.posn(e.style.top); + ne.style.left = ui.csspos(e.style.left); + ne.style.top = ui.csspos(e.style.top); e.parentNode.appendChild(ne); page.cover(ne); return ne; |