diff options
author | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2011-05-02 05:58:26 +0000 |
---|---|---|
committer | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2011-05-02 05:58:26 +0000 |
commit | 8cfb387f9129dcff5ff74922a3be8f1662529037 (patch) | |
tree | 5a21e215aeddafb6669f9f12b89507217939f558 /sca-cpp/trunk/modules/edit/htdocs/page | |
parent | c5541eed95f492f5fd615e6159115b0840ef0c37 (diff) |
Simplify HTML and Javascript to improve UI and performance on iOS devices. Fix offline cache manifest. Add an app clone page.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1098489 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-cpp/trunk/modules/edit/htdocs/page')
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/page/index.html | 295 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/page/page.html | 243 | ||||
-rw-r--r-- | sca-cpp/trunk/modules/edit/htdocs/page/page.js | 509 |
3 files changed, 482 insertions, 565 deletions
diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/index.html b/sca-cpp/trunk/modules/edit/htdocs/page/index.html index bcda316504..b498e8d77c 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/page/index.html +++ b/sca-cpp/trunk/modules/edit/htdocs/page/index.html @@ -1,3 +1,4 @@ +<!DOCTYPE html> <!-- * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file @@ -23,21 +24,78 @@ <meta name="apple-mobile-web-app-capable" content="yes"/> <meta name="apple-mobile-web-app-status-bar-style" content="black"/> <link rel="apple-touch-icon" href="/public/touchicon.png"/> -<link rel="stylesheet" type="text/css" href="/ui.css"/> +<link rel="stylesheet" type="text/css" href="/ui-min.css"/> <script type="text/javascript" src="/config.js"></script> -<script type="text/javascript" src="/util.js"></script> -<script type="text/javascript" src="/ui.js"></script> +<script type="text/javascript" src="/all-min.js"></script> +<script type="text/javascript" src="/menu.js"></script> +<script type="text/javascript" src="page.js"></script> </head> -<body class="delayed"> +<body class="delayed" onorientationchange="ui.reload();"> +<div id="bodydiv" class="devicewidth"> + <div id="menu"></div> -<h1><span id="h1"></span><span id="appNameHeader"></span></h1> -<br/> +<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> +</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;"/> +<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> +--> +</th> +</tr> +</table> + +<div id="page" style="position: absolute; top: 95px; left: -2500px; right: 0px; height: 5000px;"> -<div id="page"></div> +<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> +<div class="guide" style="position: absolute; left: 2500px; top: 0px; width: 480px; height: 300px;"></div> +<div class="guide" style="position: absolute; left: 2500px; top: 0px; width: 768px; height: 911px;"></div> +<div class="guide" style="position: absolute; left: 2500px; top: 0px; width: 1024px; height: 655px;"></div> + +<span class="h1" id="palette:h1" style="position: absolute; left: 0px; top: 0px;"><h1>Header1</h1></span> +<span class="h2" id="palette:h2" style="position: absolute; left: 0px; top: 30px;"><h2>Header2</h2></span> +<span class="section" id="palette:section" style="position: absolute; left: 0px; top: 60px; width: 200px;"><span class="section">section</span></span> +<span class="button" id="palette:button" style="position: absolute; left: 0px; top: 90px;"><input type="button" value="button" class="graybutton"/></span> +<span class="entry" id="palette:entry" style="position: absolute; left: 0px; top: 120px;"><input type="text" value="field" size="20" autocapitalize="off"/></span> +<span class="password" id="palette:password" style="position: absolute; left: 0px; top: 150px;"><input type="password" value="password" size="20"/></span> +<span class="checkbox" id="palette:checkbox" style="position: absolute; left: 0px; top: 180px;"><input type="checkbox" value="checkbox"/><span>checkbox</span></span> +<span class="select" id="palette:select" style="position: absolute; left: 0px; top: 210px;"><select><option value="select">select</option></select></span> +<span class="list" id="palette:list" style="position: absolute; left: 0px; top: 240px; width: 200px;"> +<table class="datatable" style="width: 200px;"><tr><td class="datatd">list</td></tr><tr><td class="datatd">...</td></tr></table> +</span> +<span class="table" id="palette:table" style="position: absolute; left: 0px; top: 290px; width: 200px;"> +<table class="datatable" style="width: 200px;"><tr><td class="datatdl">table</td><td class="datatdr">...</td></tr><tr><td class="datatdl">...</td><td class="datatdr">...</td></tr></table> +</span> +<span class="link" id="palette:link" style="position: absolute; left: 0px; top: 340px;"><a href="/"><span>link</span></a></span> +<span class="text" id="palette:text" style="position: absolute; left: 0px; top: 370px;"><span>text</span></span> +<span class="iframe fakeframe" id="palette:iframe" style="position: absolute; left: 0px; top: 400px; width: 200px;"><a href="/public/iframe.html"><span class="fakeframe"><span>frame ...</span></span></a></span> +<span class="img" id="palette:img" style="position: absolute; left: 0px; top: 430px;"><img src="/public/img.png"/></span> + +</div> + +<div id="buffer" style="visibility: hidden; position: absolute; top: 0px; left: 0px; width: 0px; height: 0px"></div> + +</div> <script type="text/javascript"> +// Get the app name +var appname = ui.queryParams()['app']; +if (isNil(appname)) + window.open('/', '_self'); + /** * Return the link to an app. */ @@ -51,30 +109,229 @@ function applink(appname) { return link; } -// Get the app name -var appname = ui.queryParams()['app']; - -// Update the window title +// 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>'; // Load the menu bar -ui.loadwidget('menu', '/menu.html?app=' + appname, ui.showbody); +displaymenu(); + +// Show the page +ui.showbody(); + +// Init component references +var editWidget = sca.component("EditWidget"); +var pages = sca.reference(editWidget, "pages"); + +/** + * Return the page in an ATOM entry. + */ +function atompage(doc) { + var entry = atom.readATOMEntry(mklist(doc)); + if (isNil(entry)) + return mklist(); + var content = namedElementChild("'content", car(entry)); + if (content == null) + return mklist(); + return elementChildren(content); +} + +/** + * Track the current widget and page saved XHTML content. + */ +var widgetname = ''; +var savedpagexhtml = ''; /** - * Display the page editor for an app. + * Get and display an app page. */ -function editapp(name) { +function getpage(name, edit) { if (isNil(name)) + return false; + return pages.get(name, function(doc) { + + // Convert the page to XHTML and place it in a hidden buffer + var buffer = $('buffer'); + var el = atompage(doc); + + // Create a default empty page if necessary + if (isNil(el)) + buffer.innerHTML = '<DIV id="page">\n</DIV>\n'; + else + buffer.innerHTML = writeStrings(writeXML(atompage(doc), false)); + + // Append page nodes to editor + map(function(e) { + edit.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(); + return true; + }); +} + +/** + * Handle add widget button click event. + */ +$('addWidgetButton').onclick = function(e) { + // Show the widget palette + $('page').style.left = ui.pixpos(0); +}; + +/** + * Return the current page XHTML content. + */ +function pagexhtml() { + + // Copy page DOM to hidden buffer + var edit = $('page'); + var buffer = $('buffer'); + buffer.innerHTML = '<DIV id="page">\n</DIV>\n' + var div = buffer.childNodes[0]; + div.innerHTML = edit.innerHTML; + + // Filter out palette and editor artifacts, which are not + // part of the page, as well as nodes positioned out the + // editing area + var fnodes = filter(function(e) { + if (isNil(e.id) || e.id == '' || e.id.substr(0, 8) == 'palette:') + return false; + var x = ui.numpos(e.style.left) - 2500; + if (x < 0 || ui.numpos(e.style.top) < 0) + return false; + return true; + }, nodeList(div.childNodes)); + + // Reposition nodes + map(function(e) { + var x = ui.numpos(e.style.left) - 2500; + e.style.left = ui.pixpos(x); + return e; + }, fnodes); + + // Sort them by position + var snodes = fnodes.sort(function(a, b) { + var ay = ui.numpos(a.style.top); + var by = ui.numpos(b.style.top); + if (ay < by) return -1; + if (ay > by) return 1; + var ax = ui.numpos(a.style.left); + var bx = ui.numpos(b.style.left); + if (ax < bx) return -1; + if (ax > bx) return 1; + return 0; + }); + + // Append them back to the div in order + div.innerHTML = ''; + map(function(e) { + div.appendChild(e); + return e; + }, snodes); + + // Convert the page to XHTML + var lxhtml = readXHTMLElement(div); + var xhtml = writeStrings(writeXML(lxhtml, false)); + return xhtml; +} + +/** + * Save the current page. + */ +function save() { + $('saveStatus').innerHTML = 'Saving'; + + // Get the current page XHTML content + savedpagexhtml = pagexhtml(); + + // 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>'; + + pages.put(appname, entry); + if (savedpagexhtml == pagexhtml()) + $('saveStatus').innerHTML = 'Saved'; + return true; +}; + +/** + * Handle a page change event + */ +function onpagechange(prop) { + if (savedpagexhtml == pagexhtml()) + return false; + $('saveStatus').innerHTML = 'Modified'; + + // Save property changes right away + if (prop) + return save(); + + // Autosave other changes after 3 seconds + setTimeout(function() { + if (savedpagexhtml == pagexhtml()) + return false; + return save(); + }, 1000); + return true; +} + +/** + * Return the link to a component value. + */ +function compvaluelink(appname, cname) { + if (cname == '' || isNil(cname)) + return ''; + var protocol = window.location.protocol; + var host = window.location.hostname; + var port = ':' + window.location.port; + if (port == ':80' || port == ':443' || port == ':') + port = ''; + var link = protocol + '//' + appname + '.' + host + port + '/data/?component=' + cname; + return link; +} + +/** + * Handle a widget select event. + */ +function onwidgetselect(wname) { + if (wname == widgetname) + return true; + widgetname = wname; + var link = compvaluelink(appname, wname); + + function updateButton(b, v) { + b.style.color = v? '#000000' : '#808080'; + } + + updateButton($('deleteWidgetButton'), link != ''); + //updateButton($('playWidgetButton'), link != ''); + + return true; +} + +/** + * Play the component associated with the current widget. + */ +/* +$('playWidgetButton').onclick = function() { + var link = compvaluelink(appname, widgetname); + if (link == '') return; - $('page').innerHTML = - '<iframe id="pageFrame" style="height: 5000px; width: 100%; border: 0px;" scrolling="no" frameborder="0" src="page.html?' + - 'app=' + name + - '"></iframe>'; + return window.open(link, '_' + appname + '_' + widgetname); } +*/ + +// Initialize the page editor +var edit = $('page'); +page.edit(edit, $('widgetName'), $('widgetText'), $('addWidgetButton'), $('deleteWidgetButton'), onpagechange, onwidgetselect); -editapp(appname); +// Get and display the current app page +getpage(appname, edit); </script> </body> diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/page.html b/sca-cpp/trunk/modules/edit/htdocs/page/page.html deleted file mode 100644 index 87cdd7edb8..0000000000 --- a/sca-cpp/trunk/modules/edit/htdocs/page/page.html +++ /dev/null @@ -1,243 +0,0 @@ -<!-- - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. ---> -<html> -<head> -<link rel="stylesheet" type="text/css" href="/ui.css"> -<script type="text/javascript" src="/config.js"></script> -<script type="text/javascript" src="/util.js"></script> -<script type="text/javascript" src="/elemutil.js"></script> -<script type="text/javascript" src="/xmlutil.js"></script> -<script type="text/javascript" src="/atomutil.js"></script> -<script type="text/javascript" src="/scdl.js"></script> -<script type="text/javascript" src="/ui.js"></script> -<script type="text/javascript" src="/component.js"></script> -<script type="text/javascript" src="page.js"></script> -</head> -<body class="delayed"> - -<div id="bodydiv" style="position: absolute; top: 0px; left: 0px; right: 0px;"> - -<table style="width: 100%;"> -<tr> -<th class="thl" style="width: 225px; min-width: 225px; padding-top: 4px; padding-bottom: 4px;">Palette</th> - -<th class="thr" style="padding-left: 4px; padding-top: 0px; padding-bottom: 0px;"> -<input id="widgetName" type="text" value="widget name" title="Widget name" style="position: relative; width: 200px;"/> -<input id="widgetText" type="text" value="widget text" title="Widget text" style="position: relative; width: 300px;"/> -</th> - -<th class="thl thr" style="padding-top: 0px; padding-bottom: 0px; padding-right: 0px; text-align: right;"> -<input type="button" id="saveButton" title="Save the page" style="font-weight: bold;" Value="Saved"/> -</th> -</tr> - -<tr style="height: 5000px;"><td class="tdl"></td><td class="tdr" colspan="2"></td></tr> -</table> - -<div id="bigscreen" style="position: absolute; left: 250px; top: 40px; right: 0px; bottom: 0px; border:1px; border-style: solid; border-color: #a2bae7; background: url(/public/grid72.png);"></div> -<div id="iosportraitscreen" class="guide" style="position: absolute; left: 250px; top: 40px; width: 320px; height: 460px;"></div> -<div id="ioslandscapescreen" class="guide" style="position: absolute; left: 250px; top: 40px; width: 480px; height: 300px;"></div> -<div id="ipadportraitscreen" class="guide" style="position: absolute; left: 250px; top: 40px; width: 768px; height: 911px;"></div> -<div id="ipadlandscapescreen" class="guide" style="position: absolute; left: 250px; top: 40px; width: 1024px; height: 655px;"></div> - -<div id="page" style="position: absolute; top: 40px; left: 0px; width: 5000px; height: 5000px;"> - -<span class="h1" id="palette:h1" style="position: absolute; left: 0px; top: 0px;"><h1>Header1</h1></span> -<span class="h2" id="palette:h2" style="position: absolute; left: 0px; top: 35px;"><h2>Header2</h2></span> -<span class="section" id="palette:section" style="position: absolute; left: 0px; top: 70px; width: 200px;"><span class="section">section</span></span> -<span class="button" id="palette:button" style="position: absolute; left: 0px; top: 100px;"><input type="button" value="button"/></span> -<span class="entry" id="palette:entry" style="position: absolute; left: 0px; top: 130px;"><input type="text" value="field" size="20" autocapitalize="off"/></span> -<span class="password" id="palette:password" style="position: absolute; left: 0px; top: 160px;"><input type="password" value="password" size="20"/></span> -<span class="checkbox" id="palette:checkbox" style="position: absolute; left: 0px; top: 190px;"><input type="checkbox" value="checkbox"/><span>checkbox</span></span> -<span class="select" id="palette:select" style="position: absolute; left: 0px; top: 220px;"><select><option value="select">select</option></select></span> -<span class="list" id="palette:list" style="position: absolute; left: 0px; top: 250px; width: 200px;"> -<table class="datatable" style="width: 200px;"><tr><td class="datatd">list</td></tr><tr><td class="datatd">...</td></tr></table> -</span> -<span class="table" id="palette:table" style="position: absolute; left: 0px; top: 300px; width: 200px;"> -<table class="datatable" style="width: 200px;"><tr><td class="datatdl">table</td><td class="datatdr">...</td></tr><tr><td class="datatdl">...</td><td class="datatdr">...</td></tr></table> -</span> -<span class="link" id="palette:link" style="position: absolute; left: 0px; top: 350px;"><a href="/"><span>link</span></a></span> -<span class="text" id="palette:text" style="position: absolute; left: 0px; top: 380px;"><span>text</span></span> -<span class="iframe fakeframe" id="palette:iframe" style="position: absolute; left: 0px; top: 410px; width: 200px;"><a href="/public/iframe.html"><span class="fakeframe"><span>frame ...</span></span></a></span> -<span class="img" id="palette:img" style="position: absolute; left: 0px; top: 430px;"><img src="/public/img.png"/></span> - -</div> - -<div id="buffer" style="visibility: hidden; width: 0px; height: 0px"></div> - -</div> - -<script type="text/javascript"> -if (ui.isIE()) $('bodydiv').style.right = -20; - -var editWidget = sca.component("EditWidget"); -var pages = sca.reference(editWidget, "pages"); - -/** - * The current app name. - */ -var appname = ui.queryParams()['app']; - -/** - * Return the page in an ATOM entry. - */ -function atompage(doc) { - var entry = atom.readATOMEntry(mklist(doc)); - if (isNil(entry)) - return mklist(); - var content = namedElementChild("'content", car(entry)); - if (content == null) - return mklist(); - return elementChildren(content); -} - -/** - * Track the current page saved XHTML content. - */ -var savedpagexhtml = ''; - -/** - * Get and display an app page. - */ -function getpage(name, edit) { - if (isNil(name)) - return; - pages.get(name, function(doc) { - - // Convert the page to XHTML and place it in a hidden buffer - var buffer = $('buffer'); - var el = atompage(doc); - - // Create a default empty page if necessary - if (isNil(el)) - buffer.innerHTML = '<DIV id="page">\n</DIV>\n'; - else - buffer.innerHTML = writeStrings(writeXML(atompage(doc), false)); - - // Append page nodes to editor - map(function(e) { - if (!isNil(e.style)) - e.style.left = ui.csspos(e.style.left) + 250; - edit.appendChild(e); - return page.cover(e); - }, nodeList(buffer.childNodes[0].childNodes)); - - savedpagexhtml = pagexhtml(); - - // Show the page - ui.showbody(); - }); -} - -/** - * Handle save button click event. - */ -$('saveButton').onclick = function(e) { - return save(); -}; - -/** - * Return the current page XHTML content. - */ -function pagexhtml() { - - // Copy page DOM to hidden buffer - var edit = $('page'); - var buffer = $('buffer'); - buffer.innerHTML = '<DIV id="page">\n</DIV>\n' - var div = buffer.childNodes[0]; - div.innerHTML = edit.innerHTML; - - // Remove nodes from palette and editor artifacts, which are - // not part of the page, as well as nodes positioned out of - // the editing area - map(function(e) { - if (isNil(e.id) || e.id == '' || e.id.substr(0, 8) == 'palette:') { - div.removeChild(e); - return e; - } - var x = ui.csspos(e.style.left) - 250; - if (x < 0 || ui.csspos(e.style.top) < 0) { - div.removeChild(e); - return e; - } - e.style.left = x; - return e; - }, nodeList(div.childNodes)); - - // Convert the page to XHTML - var lxhtml = readXHTMLElement(div); - var xhtml = writeStrings(writeXML(lxhtml, false)); - - return xhtml; -} - -/** - * Save the current page. - */ -function save() { - $('saveButton').value = 'Saving'; - - // Get the current page XHTML content - savedpagexhtml = pagexhtml(); - - // 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>'; - - pages.put(appname, entry, function(e) { - if (savedpagexhtml == pagexhtml()) - $('saveButton').value = 'Saved'; - return true; - }); - return true; -}; - -/** - * Handle a page change event - */ -function onpagechange(prop) { - if (savedpagexhtml == pagexhtml()) - return false; - $('saveButton').value = 'Save now'; - - // Save property changes right away - if (prop) - return save(); - - // Autosave other changes after 3 seconds - setTimeout(function() { - if (savedpagexhtml == pagexhtml()) - return false; - return save(); - }, 3000); - return true; -} - -// Initialize the page editor -var edit = $('page'); -page.edit(edit, $('widgetName'), $('widgetText'), onpagechange); - -// Get and display the current app page -getpage(appname, edit); - -</script> -</body> -</html> diff --git a/sca-cpp/trunk/modules/edit/htdocs/page/page.js b/sca-cpp/trunk/modules/edit/htdocs/page/page.js index 7ecf5c148e..09617d9720 100644 --- a/sca-cpp/trunk/modules/edit/htdocs/page/page.js +++ b/sca-cpp/trunk/modules/edit/htdocs/page/page.js @@ -25,349 +25,252 @@ var page = {}; /** * Default positions and sizes. */ -var palcx = 250; -var trashcx = 230; +var palcx = 2500; +var trashcx = 2480; -if (ui.isIE()) { - - /** - * Init a page editor. IE-specific implementation. - */ - page.edit = function(elem, wname, wtext, onchange) { - - // Track element dragging and selection - page.dragging = null; - page.selected = null; - wname.disabled = true; - wtext.disabled = true; +/** + * Init a page editor. Works with all browsers except IE. + */ +page.edit = function(elem, wname, wtext, wadd, wdelete, onchange, onselect) { - // Trigger page change events - page.onpagechange = onchange; + // Track element dragging and selection + page.dragging = null; + page.selected = null; + wname.disabled = true; + wtext.disabled = true; + wdelete.disabled = true; - /** - * Handle a mouse down event. - */ - elem.onmousedown = function() { - window.event.returnValue = false; + // Trigger widget select and page change events + page.onpagechange = onchange; + page.onwidgetselect = onselect; - // Find a draggable element - page.dragging = page.draggable(window.event.srcElement, elem); + /** + * Handle a mouse down event. + */ + elem.onmousedown = function(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(''); + 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; - if (page.dragging == null) { - - // Reset current selection - wname.value = ''; - wname.disabled = true; - wtext.value = ''; - wtext.disabled = true; - return false; - } - - // 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); - // Save the mouse position - page.dragX = window.event.clientX; - page.dragY = window.event.clientY; - elem.setCapture(); - - // 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); - return false; - }; - - /** - * Handle a mouse up event. - */ - elem.onmouseup = function() { - if (page.dragging == null) - return false; - - // Snap to grid - var newX = page.gridsnap(ui.csspos(page.dragging.style.left)); - var newY = page.gridsnap(ui.csspos(page.dragging.style.top)); - page.dragging.style.left = newX; - page.dragging.style.top = newY; - page.dragging.cover.style.left = newX; - page.dragging.cover.style.top = newY; - - // Fixup widget style - page.fixupwidget(page.dragging); - - // Discard element dragged out of page area - if (ui.csspos(page.dragging.style.left) < palcx && page.dragging.id.substring(0, 8) != 'palette:') { - if (ui.csspos(page.dragging.style.left) >= trashcx) { - - // Unless it's close enough to page area, then move it there - page.dragging.style.left = palcx; - page.dragging.cover.style.left = palcx; - } else { - page.dragging.parentNode.removeChild(page.dragging); - - // Reset current selection - page.selected = null; - wname.value = ''; - wname.disabled = true; - wtext.value = ''; - wtext.disabled = true; - } - } - - // Forget current dragged element - page.dragging = null; - elem.releaseCapture(); - - // Trigger page change event - page.onpagechange(false); - return false; - }; - - /** - * Handle a mouse move event. - */ - elem.onmousemove = function() { - if (page.dragging == null) - return false; - - // 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) - page.dragX = window.event.clientX; - else - newX = 0; - if (newY >= 0) - page.dragY = window.event.clientY; - else - newY = 0; - - // Move dragged element - page.dragging.style.left = newX; - page.dragging.style.top = newY; - page.dragging.cover.style.left = newX; - page.dragging.cover.style.top = newY; - return false; - }; - - /** - * 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() { - if (page.selected == null) - return false; - page.settext(page.selected, wtext.value); - // Trigger page change event - page.onpagechange(true); - return false; - }; + } else { - // Cover child elements with span elements to prevent - // any input events to reach them - map(page.cover, nodeList(elem.childNodes)); - - return elem; + // 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; + + // 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 + e.returnValue = false; + return true; }; -} else { + // Support touch devices + elem.ontouchstart = elem.onmousedown; /** - * Init a page editor. Generic implementation for all other browsers. + * Handle a mouse up event. */ - page.edit = function(elem, wname, wtext, onchange) { - - // Track element dragging and selection - page.dragging = null; - page.selected = null; - wname.disabled = true; - wtext.disabled = true; - - // Trigger page change events - page.onpagechange = onchange; - - /** - * Handle a mouse down event. - */ - elem.onmousedown = function(e) { - if (e.preventDefault) - e.preventDefault(); - else - e.returnValue = false; - - // Find a draggable element - page.dragging = page.draggable(e.target, elem); - page.selected = page.dragging; - if (page.dragging == null) { + elem.onmouseup = function(e) { + if (page.dragging == null) + return true; + + // Snap to grid + var newX = page.gridsnap(ui.numpos(page.dragging.style.left)); + var newY = page.gridsnap(ui.numpos(page.dragging.style.top)); + page.dragging.style.left = ui.pixpos(newX); + page.dragging.style.top = ui.pixpos(newY); + page.dragging.cover.style.left = ui.pixpos(newX); + page.dragging.cover.style.top = ui.pixpos(newY); + + // 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; - return false; - } + wdelete.disabled = true; - // Clone element dragged from palette - if (page.dragging.id.substring(0, 8) == 'palette:') { - page.dragging = page.clone(page.dragging); - page.selected = page.dragging; + // Trigger widget select event + page.onwidgetselect(''); } + } - // Bring it to the top - page.bringtotop(page.dragging); + // Forget dragged element + page.dragging = null; - // Remember mouse position - var pos = typeof e.touches != "undefined" ? e.touches[0] : e; + // Trigger page change event + page.onpagechange(false); + return true; + }; + + // Support touch devices + elem.ontouchend = elem.onmouseup; + + /** + * Handle a mouse move event. + */ + window.onmousemove = function(e) { + if (page.dragging == null) + 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) page.dragX = pos.screenX; + else + newX = 0; + if (newY >= 0) page.dragY = pos.screenY; + else + newY = 0; + + // Move the dragged element + page.dragging.style.left = ui.pixpos(newX); + page.dragging.style.top = ui.pixpos(newY); + page.dragging.cover.style.left = ui.pixpos(newX); + page.dragging.cover.style.top = ui.pixpos(newY); + return true; + }; - // 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); - return false; - }; - - // Support touch devices - elem.ontouchstart = elem.onmousedown; - - /** - * Handle a mouse up event. - */ - window.onmouseup = function(e) { - if (page.dragging == null) - return false; - - // Snap to grid - var newX = page.gridsnap(ui.csspos(page.dragging.style.left)); - var newY = page.gridsnap(ui.csspos(page.dragging.style.top)); - page.dragging.style.left = newX; - page.dragging.style.top = newY; - page.dragging.cover.style.left = newX; - page.dragging.cover.style.top = newY; - - // Fixup widget style - page.fixupwidget(page.dragging); - - // Discard element dragged out of page area - if (ui.csspos(page.dragging.style.left) < palcx && page.dragging.id.substring(0, 8) != 'palette:') { - if (ui.csspos(page.dragging.style.left) >= trashcx) { - - // Unless it's close enough to page area, then move it there - page.dragging.style.left = palcx; - page.dragging.cover.style.left = palcx; - } else { - page.dragging.parentNode.removeChild(page.dragging); - - // Reset current selection - page.selected = null; - wname.value = ''; - wname.disabled = true; - wtext.value = ''; - wtext.disabled = true; - } - } + // Support touch devices + elem.ontouchmove = window.onmousemove; - // Forget dragged element - page.dragging = null; + /** + * Handle a mouse click event. + */ + elem.onclick = function(e) { + if (page.dragging == null) { - // Trigger page change event - page.onpagechange(false); + // Dismiss the palette + if (ui.numpos(elem.style.left) != (palcx * -1)) + elem.style.left = ui.pixpos(palcx * -1); + } + return true; + }; + + /** + * Handle field on change events. + */ + wname.onchange = wname.onblur = function() { + if (page.selected == 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; - - // 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); - if (newX >= 0) - page.dragX = pos.screenX; - else - newX = 0; - if (newY >= 0) - page.dragY = pos.screenY; - else - newY = 0; - - // Move the dragged element - page.dragging.style.left = newX; - page.dragging.style.top = newY; - page.dragging.cover.style.left = newX; - page.dragging.cover.style.top = newY; + page.selected.id = wname.value; + + // Trigger page change event + page.onpagechange(true); + return false; + }; + + wtext.onchange = wtext.onblur = function() { + if (page.selected == null) return false; - }; + page.settext(page.selected, wtext.value); + + // Trigger page change event + page.onpagechange(true); + return false; + }; - // Support touch devices - window.top.onmousemove = window.onmousemove; - window.ontouchmove = window.onmousemove; - window.top.ontouchmove = window.onmousemove; + // Handle add widget event. + wadd.onclick = function() { - /** - * Handle field on change events. - */ - wname.onchange = wname.onblue = function() { - if (page.selected == null) - return false; - page.selected.id = wname.value; + // Show the palette + elem.style.left = ui.pixpos(0); + return false; + }; - // Trigger page change event - page.onpagechange(true); + // Handle delete event. + wdelete.onclick = function() { + if (page.selected == null) return false; - }; - wtext.onchange = wtext.onblur = function() { - if (page.selected == null) - return false; - page.settext(page.selected, wtext.value); + // Remove selected widget + page.selected.parentNode.removeChild(page.selected); - // Trigger page change event - page.onpagechange(true); - return false; - }; + // Reset current selection + page.selected = null; + wname.value = ''; + wname.disabled = true; + wtext.value = ''; + wtext.disabled = true; + wdelete.disabled = true; - // Cover child elements with span elements to prevent - // any input events to reach them - map(page.cover, nodeList(elem.childNodes)); + // Trigger widget select event + page.onwidgetselect(''); - return elem; + // Trigger page change event + page.onpagechange(true); + return false; }; -} + + // Cover child elements with span elements to prevent + // any input events to reach them + map(page.cover, nodeList(elem.childNodes)); + + return elem; +}; /** * Return the text of a widget. @@ -532,8 +435,8 @@ page.cover = function(e) { return e; var cover = document.createElement('span'); cover.style.position = 'absolute'; - cover.style.left = ui.csspos(e.style.left) - 5; - cover.style.top = ui.csspos(e.style.top) - 5; + 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'; @@ -568,8 +471,8 @@ page.clone = function(e) { */ function posclone(ne, e) { ne.style.position = 'absolute'; - ne.style.left = ui.csspos(e.style.left); - ne.style.top = ui.csspos(e.style.top); + ne.style.left = ui.pixpos(ui.numpos(e.style.left)); + ne.style.top = ui.pixpos(ui.numpos(e.style.top)); e.parentNode.appendChild(ne); page.cover(ne); return ne; |