diff options
Diffstat (limited to '')
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/page/index.html | 173 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/page/page.js | 237 |
2 files changed, 251 insertions, 159 deletions
diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/index.html b/sca-cpp/trunk/modules/edit/htdocs/page/index.html index b498e8d77c..678491f220 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/page/index.html +++ b/sca-cpp/trunk/modules/edit/htdocs/page/index.html @@ -37,26 +37,28 @@ <table style="width: 100%;"> <tr> -<td><h1><span id="h1"></span><span id="appNameHeader"></span></h1></td> -<td style="vertical-align: middle; text-align: right;"><span id="saveStatus" style="font-weight: bold; color: #808080;">Saved</span></td> +<td><h2><span id="h1"></span><span id="appNameHeader"></span></h2></td> +<td style="vertical-align: middle; text-align: right; padding-right: 2px;"><span id="saveStatus" style="font-weight: bold; color: #808080;">Saved</span></td> </tr> </table> <table style="width: 100%;"> <tr> -<th class="thr thl" style="padding-left: 2px; padding-right: 2px;"> -<input id="widgetName" type="text" value="" title="Widget name" placeholder="Name" style="position: relative; width: 65px;"/> -<input id="widgetText" type="text" value="" title="Widget text" placeholder="Text" style="position: relative; width: 120px;"/> +<th class="thr thl" style="padding-left: 2px; padding-right: 2px; width: 100%;"> +<input id="widgetValue" type="text" value="" title="Widget value" autocapitalize="off" placeholder="Value" style="position: relative; width: 100%;"/> +</th> + +<th class="thl thr" style="text-align: right; padding-right: 2px;"> <span id="deleteWidgetButton" title="Delete a Widget" class="redbutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">-</span> + <span id="addWidgetButton" title="Add a Widget" class="greenbutton" style="font-weight: bold; font-size: 16px; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">+</span> -<!-- -<span id="playWidgetButton" title="View" class="bluebutton" style="font-weight: bold; font-size: 16px; color: #808080; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">></span> ---> + +<span id="playPageButton" title="View page" class="bluebutton" style="font-weight: bold; font-size: 16px; display: inline-block; width: 24px; height: 20px; padding-top: 0px; padding-bottom: 0px; vertical-align: middle; text-align: center; margin-left: 0px; margin-right: 0px;">></span> </th> </tr> </table> -<div id="page" style="position: absolute; top: 95px; left: -2500px; right: 0px; height: 5000px;"> +<div id="editdiv" style="position: absolute; top: 95px; left: -2500px; right: 0px; height: 5000px;"> <div style="position: absolute; left: 2500px; top: 0px; right: 0px; height: 5000px; border:1px; border-style: solid; border-color: #a2bae7; background: url(/public/grid72.png);"></div> <div class="guide" style="position: absolute; left: 2500px; top: 0px; width: 320px; height: 460px;"></div> @@ -85,6 +87,8 @@ </div> +<div id="playdiv" style="visibility: hidden; position: absolute; top: 95px; left: 0px; right: 0px; height: 5000px;"></div> + <div id="buffer" style="visibility: hidden; position: absolute; top: 0px; left: 0px; width: 0px; height: 0px"></div> </div> @@ -111,12 +115,35 @@ function applink(appname) { // Set page titles document.title = windowtitle(window.location.hostname) + ' - Page - ' + appname; -$('h1').innerHTML = hometitle(window.location.hostname); -$('appNameHeader').innerHTML = ' - <a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '</a>'; +//$('h1').innerHTML = hometitle(window.location.hostname); +$('appNameHeader').innerHTML = '<a href=\"' + applink(appname) + '\" target=\"' + '_blank' + '\">' + appname + '.' + window.location.hostname + '</a>'; // Load the menu bar displaymenu(); +/** + * Page editor area, widget value field, add, delete and play page buttons. + */ +var ediv = $('editdiv'); +var evisible = true; +var pdiv = $('playdiv'); +var wvalue = $('widgetValue'); +var wadd = $('addWidgetButton'); +var wdelete = $('deleteWidgetButton'); +var pplay = $('playPageButton'); + +/** + * Adjust fields sizes. + */ +function resizeFields() { + wvalue.style.width = '0px'; + wvalue.style.width = ui.pixpos(wvalue.parentNode.clientWidth - 18); + return true; +} + +resizeFields(); +window.onresize = resizeFields; + // Show the page ui.showbody(); @@ -138,15 +165,19 @@ function atompage(doc) { } /** - * Track the current widget and page saved XHTML content. + * Track the current page saved XHTML content. */ -var widgetname = ''; var savedpagexhtml = ''; /** + * Track the current widget. + */ +var widget = null; + +/** * Get and display an app page. */ -function getpage(name, edit) { +function getpage(name, ediv) { if (isNil(name)) return false; return pages.get(name, function(doc) { @@ -157,19 +188,19 @@ function getpage(name, edit) { // Create a default empty page if necessary if (isNil(el)) - buffer.innerHTML = '<DIV id="page">\n</DIV>\n'; + buffer.innerHTML = '<div id="page"></div>'; else buffer.innerHTML = writeStrings(writeXML(atompage(doc), false)); // Append page nodes to editor map(function(e) { - edit.appendChild(e); + ediv.appendChild(e); if (!isNil(e.style)) e.style.left = ui.pixpos(ui.numpos(e.style.left) + 2500); return page.cover(e); }, nodeList(buffer.childNodes[0].childNodes)); - savedpagexhtml = pagexhtml(); + savedpagexhtml = pagexhtml(ediv); return true; }); } @@ -177,22 +208,28 @@ function getpage(name, edit) { /** * Handle add widget button click event. */ -$('addWidgetButton').onclick = function(e) { +wadd.onclick = function(e) { // Show the widget palette - $('page').style.left = ui.pixpos(0); + ediv.style.left = ui.pixpos(0); }; /** * Return the current page XHTML content. */ -function pagexhtml() { +function pagexhtml(ediv) { // Copy page DOM to hidden buffer - var edit = $('page'); var buffer = $('buffer'); - buffer.innerHTML = '<DIV id="page">\n</DIV>\n' + buffer.innerHTML = '<div id="page"></div>' var div = buffer.childNodes[0]; - div.innerHTML = edit.innerHTML; + + // Capture the nodes inside the page div + div.innerHTML = ediv.innerHTML; + var nodes = nodeList(div.childNodes); + map(function(e) { + div.removeChild(e); + return e; + }, nodes); // Filter out palette and editor artifacts, which are not // part of the page, as well as nodes positioned out the @@ -204,7 +241,7 @@ function pagexhtml() { if (x < 0 || ui.numpos(e.style.top) < 0) return false; return true; - }, nodeList(div.childNodes)); + }, nodes); // Reposition nodes map(function(e) { @@ -226,8 +263,7 @@ function pagexhtml() { return 0; }); - // Append them back to the div in order - div.innerHTML = ''; + // Append the sorted nodes back to the div in order map(function(e) { div.appendChild(e); return e; @@ -242,20 +278,20 @@ function pagexhtml() { /** * Save the current page. */ -function save() { +function save(newxml) { $('saveStatus').innerHTML = 'Saving'; // Get the current page XHTML content - savedpagexhtml = pagexhtml(); + savedpagexhtml = newxml; // Update the page ATOM entry var entry = '<entry xmlns="http://www.w3.org/2005/Atom">' + '<title type="text">' + appname + '</title><id>' + appname + '</id><content type="application/xml">' + - savedpagexhtml + '</content></entry>'; + newxml + '</content></entry>'; - pages.put(appname, entry); - if (savedpagexhtml == pagexhtml()) + pages.put(appname, entry, function(r) { $('saveStatus').innerHTML = 'Saved'; + }); return true; }; @@ -263,19 +299,22 @@ function save() { * Handle a page change event */ function onpagechange(prop) { - if (savedpagexhtml == pagexhtml()) + var newxml = pagexhtml(ediv); + if (savedpagexhtml == newxml) return false; $('saveStatus').innerHTML = 'Modified'; // Save property changes right away if (prop) - return save(); + return save(newxml); - // Autosave other changes after 3 seconds + // Autosave other changes after 1 second setTimeout(function() { - if (savedpagexhtml == pagexhtml()) + if (savedpagexhtml == newxml) { + $('saveStatus').innerHTML = 'Saved'; return false; - return save(); + } + return save(newxml); }, 1000); return true; } @@ -298,40 +337,68 @@ function compvaluelink(appname, cname) { /** * Handle a widget select event. */ -function onwidgetselect(wname) { - if (wname == widgetname) +function onwidgetselect(w) { + if (w == widget) return true; - widgetname = wname; - var link = compvaluelink(appname, wname); + widget = w; + var link = compvaluelink(appname, isNil(w)? '' : w.id); function updateButton(b, v) { b.style.color = v? '#000000' : '#808080'; } - updateButton($('deleteWidgetButton'), link != ''); - //updateButton($('playWidgetButton'), link != ''); + updateButton(wdelete, link != ''); + return true; +} +/** + * Play page in a frame. + */ +function playpage() { + if (!evisible) + return true; + page.widgetselect(widget, false, wvalue, wdelete); + page.selected = null; + wvalue.value = applink(appname); + pplay.innerHTML = '<'; + ediv.style.visibility = 'hidden' + evisible = false; + pdiv.style.visibility = 'visible'; + pdiv.innerHTML = '<iframe id="appFrame" style="position: relative; height: 5000px; width: 100%; border: 0px;" scrolling="no" frameborder="0" src="' + + applink(appname) + '"></iframe>'; + return true; +} + +/** + * Show the page editor. + */ +function showedit() { + if (evisible) + return true; + pplay.innerHTML = '>'; + pdiv.style.visibility = 'hidden'; + pdiv.innerHTML = ''; + ediv.style.visibility = 'visible' + evisible = true; + page.widgetselect(widget, true, wvalue, wdelete); + page.selected = widget; return true; } /** - * Play the component associated with the current widget. + * Handle play page button event. */ -/* -$('playWidgetButton').onclick = function() { - var link = compvaluelink(appname, widgetname); - if (link == '') - return; - return window.open(link, '_' + appname + '_' + widgetname); +pplay.onclick = function() { + if (!evisible) + return showedit(); + return playpage(); } -*/ // Initialize the page editor -var edit = $('page'); -page.edit(edit, $('widgetName'), $('widgetText'), $('addWidgetButton'), $('deleteWidgetButton'), onpagechange, onwidgetselect); +page.edit(ediv, wvalue, wadd, wdelete, onpagechange, onwidgetselect); // Get and display the current app page -getpage(appname, edit); +getpage(appname, ediv); </script> </body> diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/page.js b/sca-cpp/trunk/modules/edit/htdocs/page/page.js index 09617d9720..707788cc64 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/page/page.js +++ b/sca-cpp/trunk/modules/edit/htdocs/page/page.js @@ -26,18 +26,16 @@ var page = {}; * Default positions and sizes. */ var palcx = 2500; -var trashcx = 2480; /** * Init a page editor. Works with all browsers except IE. */ -page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) { +page.edit = function(elem, wvalue, wadd, wdelete, onchange, onselect) { // Track element dragging and selection page.dragging = null; page.selected = null; - wname.disabled = true; - wtext.disabled = true; + wvalue.disabled = true; wdelete.disabled = true; // Trigger widget select and page change events @@ -49,59 +47,22 @@ page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) { */ elem.onmousedown = function(e) { + // On mouse controlled devices, engage the click component selection + // logic right away + if (typeof e.touches == 'undefined') + elem.onclick(e); + // Find a draggable element - page.dragging = page.draggable(e.target, elem); - page.selected = page.dragging; - if (page.dragging == null) { - - // Reset current selection - wname.value = ''; - wname.disabled = true; - wtext.value = ''; - wtext.disabled = true; - wdelete.disabled = true; - - // Trigger widget select event - page.onwidgetselect(''); + var dragging = page.draggable(e.target, elem); + if (dragging == null || dragging != page.selected) return true; - } - - // Clone element dragged from palette - if (page.dragging.id.substring(0, 8) == 'palette:') { - page.dragging = page.clone(page.dragging); - page.selected = page.dragging; - - // Move into the editing area and hide the palette - page.selected.style.left = ui.pixpos(ui.numpos(page.selected.style.left) + palcx); - elem.style.left = ui.pixpos(palcx * -1); - - // Bring it to the top - page.bringtotop(page.dragging); - - // Trigger page change event - page.onpagechange(true); - - } else { - - // Bring it to the top - page.bringtotop(page.dragging); - } + page.dragging = dragging; // Remember mouse position var pos = typeof e.touches != "undefined" ? e.touches[0] : e; page.dragX = pos.screenX; page.dragY = pos.screenY; - // Update the widget name and text fields - wname.value = page.selected.id; - wname.disabled = false; - wtext.value = page.text(page.selected); - wtext.disabled = !page.hastext(page.selected); - wdelete.disabled = false; - - // Trigger widget select event - page.onwidgetselect(page.selected.id); - if (e.preventDefault) e.preventDefault(); else @@ -130,29 +91,6 @@ page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) { // Fixup widget style page.fixupwidget(page.dragging); - // Discard element dragged out of page area - if (ui.numpos(page.dragging.style.left) < palcx && page.dragging.id.substring(0, 8) != 'palette:') { - if (ui.numpos(page.dragging.style.left) >= trashcx) { - - // Unless it's close enough to page area, then move it there - page.dragging.style.left = ui.pixpos(palcx); - page.dragging.cover.style.left = ui.pixpos(palcx); - } else { - page.dragging.parentNode.removeChild(page.dragging); - - // Reset current selection - page.selected = null; - wname.value = ''; - wname.disabled = true; - wtext.value = ''; - wtext.disabled = true; - wdelete.disabled = true; - - // Trigger widget select event - page.onwidgetselect(''); - } - } - // Forget dragged element page.dragging = null; @@ -171,16 +109,20 @@ page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) { if (page.dragging == null) return true; + // Get the mouse position + var pos = typeof e.touches != "undefined" ? e.touches[0] : e; + if (pos.screenX == page.dragX && pos.screenY == page.dragY) + return true; + // Compute position of dragged element var curX = ui.numpos(page.dragging.style.left); var curY = ui.numpos(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); - if (newX >= 0) + if (newX >= palcx) page.dragX = pos.screenX; else - newX = 0; + newX = palcx; if (newY >= 0) page.dragY = pos.screenY; else @@ -201,32 +143,70 @@ page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) { * Handle a mouse click event. */ elem.onclick = function(e) { - if (page.dragging == null) { + + // Find selected element + var selected = page.draggable(e.target, elem); + if (selected == null) { + if (page.selected != null) { + + // Reset current selection + page.widgetselect(page.selected, false, wvalue, wdelete); + page.selected = null; + + // Trigger widget select event + page.onwidgetselect(null); + } // Dismiss the palette if (ui.numpos(elem.style.left) != (palcx * -1)) elem.style.left = ui.pixpos(palcx * -1); + + return true; } + + // Deselect the previously selected element + page.widgetselect(page.selected, false, wvalue, wdelete); + + // Clone element dragged from palette + if (selected.id.substring(0, 8) == 'palette:') { + page.selected = page.clone(selected); + + // Move into the editing area and hide the palette + page.selected.style.left = ui.pixpos(ui.numpos(page.selected.style.left) + palcx); + page.selected.cover.style.left = ui.pixpos(ui.numpos(page.selected.cover.style.left) + palcx); + elem.style.left = ui.pixpos(palcx * -1); + + // Bring it to the top + page.bringtotop(page.selected); + + // Trigger page change event + page.onpagechange(true); + + } else { + + // Bring selected element to the top + page.selected = selected; + page.bringtotop(page.selected); + } + + // Select the element + page.widgetselect(page.selected, true, wvalue, wdelete); + + // Trigger widget select event + page.onwidgetselect(page.selected); + return true; }; /** * Handle field on change events. */ - wname.onchange = wname.onblur = function() { - if (page.selected == null) - return false; - page.selected.id = wname.value; - - // Trigger page change event - page.onpagechange(true); - return false; - }; - - wtext.onchange = wtext.onblur = function() { + wvalue.onchange = wvalue.onblur = function() { if (page.selected == null) return false; - page.settext(page.selected, wtext.value); + page.settext(page.selected, wvalue.value); + page.selected.cover.style.width = ui.pixpos(page.selected.clientWidth + 4); + page.selected.cover.style.height = ui.pixpos(page.selected.clientHeight + 4); // Trigger page change event page.onpagechange(true); @@ -246,19 +226,16 @@ page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) { if (page.selected == null) return false; + // Reset current selection + page.widgetselect(page.selected, false, wvalue, wdelete); + // Remove selected widget page.selected.parentNode.removeChild(page.selected); - - // Reset current selection + page.selected.cover.parentNode.removeChild(page.selected.cover); page.selected = null; - wname.value = ''; - wname.disabled = true; - wtext.value = ''; - wtext.disabled = true; - wdelete.disabled = true; // Trigger widget select event - page.onwidgetselect(''); + page.onwidgetselect(null); // Trigger page change event page.onpagechange(true); @@ -276,6 +253,11 @@ page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) { * Return the text of a widget. */ page.text = function(e) { + var formula = e.id; + if (formula.substring(0, 5) != 'page:') { + return '=' + formula; + } + if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section') return car(childElements(e)).innerHTML; if (e.className == 'button' || e.className == 'checkbox') @@ -331,6 +313,9 @@ page.hastext = function(e) { * Set the text of a widget. */ page.settext = function(e, t) { + var formula = t.length > 1 && t.substring(0, 1) == '='; + e.id = formula? t.substring(1) : 'page:' + e.className; + if (e.className == 'h1' || e.className == 'h2' || e.className == 'text' || e.className == 'section') { car(childElements(e)).innerHTML = t; return t; @@ -351,10 +336,12 @@ page.settext = function(e, t) { return t; } if (e.className == 'list') { + e.innerHTML = '<table class="datatable" style="width: 100%;;"><tr><td class="datatd">' + t + '</td></tr><tr><td class="datatd">...</td></tr></table>'; return ''; } if (e.className == 'table') { - return ''; + e.innerHTML = '<table class="datatable" style="width: 100%;"><tr><td class="datatdl">' + t + '</td><td class="datatdr">...</td></tr><tr><td class="datatdl">...</td><td class="datatdr">...</td></tr></table>'; + return t; } if (e.className == 'link') { var l = t.split(','); @@ -364,11 +351,11 @@ page.settext = function(e, t) { return t; } if (e.className == 'img') { - car(childElements(e)).src = t; + car(childElements(e)).src = formula? '/public/img.png' : t; return t; } if (e.className == 'iframe') { - car(childElements(e)).href = t; + car(childElements(e)).href = formula? '/public/iframe.html' : t; return t; } return ''; @@ -388,10 +375,12 @@ page.fixupwidget = function(e) { return e; } if (e.className == 'list') { + e.style.width = '100%'; car(childElements(e)).style.width = '100%'; return e; } if (e.className == 'table') { + e.style.width = '100%'; car(childElements(e)).style.width = '100%'; return e; } @@ -427,19 +416,51 @@ page.bringtotop = function(n) { } /** + * Draw widget selection. + */ +page.widgetselect = function(n, s, wvalue, wdelete) { + if (isNil(n) || !s) { + // Clear the widget value field + wvalue.value = ''; + wvalue.disabled = true; + wdelete.disabled = true; + + // Clear the widget outline + if (!isNil(n)) + n.cover.style.borderWidth = '0px'; + } + if (isNil(n)) + return true; + + // Update the widget value field + wvalue.value = page.text(n); + wvalue.disabled = false; + wdelete.disabled = false; + + // Outline the widget + n.cover.style.borderWidth = s? '2px' : '0px'; + return true; +}; + +/** * 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'); + var cover = document.createElement('div'); cover.style.position = 'absolute'; - cover.style.left = ui.pixpos(ui.numpos(e.style.left) - 5); - cover.style.top = ui.pixpos(ui.numpos(e.style.top) - 5); - cover.style.width = e.clientWidth + 10; - cover.style.height = e.clientHeight + 10; - cover.style.visibility = 'visible'; + cover.style.left = ui.pixpos(ui.numpos(e.style.left) - 2); + cover.style.top = ui.pixpos(ui.numpos(e.style.top) - 2); + cover.style.width = ui.pixpos(e.clientWidth + 4); + cover.style.height = ui.pixpos(e.clientHeight + 4); + cover.style.visibility = 'inherit'; + cover.style.borderStyle = 'solid'; + cover.style.borderWidth = '0px'; + cover.style.borderColor = '#598edd'; + cover.style.padding = '0px'; + cover.style.margin = '0px'; cover.covered = e; e.cover = cover; e.parentNode.appendChild(cover); @@ -458,11 +479,15 @@ page.clone = function(e) { var ne = document.createElement('span'); // Skip the palette: prefix - ne.id = e.id.substr(8); + ne.id = 'page:' + e.id.substr(8); // Copy the class and HTML content ne.className = e.className; ne.innerHTML = e.innerHTML; + + // Fixup the widget style + page.fixupwidget(ne); + return ne; } |