Author: jmorliaguet Date: Mon Dec 19 17:52:36 2005 New Revision: 2053 Removed: cpsskins/branches/jmo-perspectives/ui/authoring/jsonrpc.py Modified: cpsskins/branches/jmo-perspectives/ui/authoring/authoring.js cpsskins/branches/jmo-perspectives/ui/authoring/authoring.py cpsskins/branches/jmo-perspectives/ui/authoring/configure.zcml Log:
- removed dependency on jsonserver - converted some parts on the javascript authoring.js to prototype.js' object oriented syntax. - converted json views to 'standard' views to do AJAX (with HTTP POST) TODO: convert the style editor Modified: cpsskins/branches/jmo-perspectives/ui/authoring/authoring.js ============================================================================== --- cpsskins/branches/jmo-perspectives/ui/authoring/authoring.js (original) +++ cpsskins/branches/jmo-perspectives/ui/authoring/authoring.js Mon Dec 19 17:52:36 2005 @@ -1,5 +1,5 @@ -var themeEditor = null; +var model = null; var moved = null; var copied = null; var factory = null; @@ -34,70 +34,135 @@ this.constraint = node.getAttribute("constraint"); } -function MenuActions() { - this.edit = Menu_edit; - this.duplicate = Menu_duplicate; - this.copy = Menu_copy; - this.paste = Menu_paste; - this.format = Menu_format; - this.remove = Menu_remove; +/* Actions */ +MenuActions = Class.create(); +MenuActions.prototype = { + initialize: function() { + this.handlers = { + 'edit': function(id) { + var new_url = '@@edit-panel.html?id=' + id; + newWindow(new_url); + }, + 'duplicate': function(id) { + current_elem = pd_selected_item; + model.duplicate({'id': id}); + }, + 'copy': function(id) { + model.copy({'id': id}); + }, + 'paste': function(id) { + model.paste({'id': id}); + }, + 'format': function(id, format) { + var new_url = '@@edit-panel.html?id=' + id + '&format=' + format; + newWindow(new_url); + }, + 'remove': function(id) { + model.remove({'id': id}); + var container = pd_selected_item.parentNode; + container.removeChild(pd_selected_item); + }, + } + }, + call: function(id, action, choice) { + handler = this.handlers[action]; + if (handler) handler(id, choice); + pd_hideContextSubMenu(); + pd_hideContextMenu(); + }, } /* MODELS */ -function model_edit(id, name, value) { - themeEditor.editElement( - id=id, name=name, value=value, - finish_edit); -} - -function model_duplicate(id) { - themeEditor.duplicateElement( - id=id, - finish_duplicate); -} - -function model_copy(id) { - themeEditor.copyElement( - id=id, - finish_copy); -} - -function model_paste(id) { - themeEditor.pasteElement( - id=id, - finish_paste); -} - -function model_delete(id) { - themeEditor.deleteElement( - id=id, - finish_delete); -} - -function model_reorder(id, order) { - themeEditor.reorderElement( - id=id, order=order, - finish_reorder); -} - -function model_move(src_id, dest_id, order) { - themeEditor.moveElement( - src_id=src_id, dest_id=dest_id, order=order, - finish_move); -} - -function model_add(container_id, type_name, order) { - themeEditor.addElement( - container_id=container_id, type_name=type_name, order=order, - finish_add); +Model = Class.create(); +Model.prototype = { + initialize: function() { + }, + call: function(url, args, options) { + var opts = {}; + Object.extend(opts, {parameters: $H(args).toQueryString()}); + Object.extend(opts, options || {}); + new Ajax.Request(url, opts); + }, + edit: function(args) { + this.call(url='editElement', args=args); + }, + duplicate: function(args) { + this.call(url='duplicateElement', args=args, options={ + onComplete: function(request) { + if (!current_elem) return; + var new_id = request.responseText; + var rendered = render_element(id=new_id); + var container = current_elem.parentNode; + container.insertBefore(rendered, getNextElement(current_elem)); + + highlight(rendered); + // set up the new nodes + pd_setupPage(); + } + }); + }, + copy: function(args) { + this.call(url='copyElement', args=args); + }, + paste: function(args) { + this.call(url='pasteElement', args=args); + }, + remove: function(args) { + this.call(url='deleteElement', args=args); + }, + reorder: function(args) { + this.call(url='reorderElement', args=args, options={ + parameters: $(parameters).toQueryString(), + onComplete: function(request) { + if (!current_elem) return; + highlight(current_elem); + current_elem = null; + } + }); + }, + move: function(args) { + this.call(url='moveElement', args=args, options={ + onComplete: function(request) { + if (!current_elem) return; + if (!current_container) return; + var new_id = resp; + if (current_container.getAttribute("render")) { + var rendered = render_element(id=new_id); + current_elem.parentNode.replaceChild(rendered, current_elem); + current_elem = rendered; + } + highlight(current_elem); + current_container = null; + current_elem = null; + pd_setupPage(); + }, + }); + }, + add: function(args) { + this.call(url='addElement', args=args, options={ + onComplete: function(request) { + var new_id = request.responseText; + var rendered = render_element(id=new_id); + if (current_elem) { + current_container.insertBefore(rendered, current_elem); + } else { + current_container.appendChild(rendered); + } + current_elem = null; + pd_setupPage(); + highlight(rendered); + }, + }); + }, } /* VIEWS */ function render_element(id) { - var rendered = themeEditor.renderElement(id=id, engine=getEngineName()); - var tag = getFirstTag(rendered); - var wrapper = document.createElement(tag); - replaceHTML(wrapper, rendered); + // XXX the wrapper is not mecessarily a div + var wrapper = document.createElement('div'); + new Ajax.Updater(wrapper, 'renderElement', options={ + parameters: $H({'id':id, 'engine':getEngineName()}).toQueryString(), + }); return wrapper; } @@ -188,72 +253,8 @@ } var action = target.getAttribute("action"); var choice = target.getAttribute("choice"); - if (action) { - handler = menu_actions[action]; - if (handler) handler(choice); - pd_hideContextSubMenu(); - pd_hideContextMenu(); - } -} - -// actions -function Menu_edit() { - var id = pd_selected_item.getAttribute("id"); - var new_url = '@@edit-panel.html?id=' + id; - newWindow(new_url); -} - -function Menu_duplicate() { - var id = pd_selected_item.getAttribute("id"); - current_elem = pd_selected_item; - model_duplicate(id); -} - -function finish_duplicate(resp, err) { - if (!current_elem) return; - if (!err) { - var new_id = resp; - var rendered = render_element(new_id); - var container = current_elem.parentNode; - container.insertBefore(rendered, getNextElement(current_elem)); - - highlight(rendered); - - // set up the new nodes - pd_setupPage(); - } -} - -function Menu_format(format) { - var id = pd_selected_item.getAttribute("id"); - var new_url = '@@edit-panel.html?id=' + id + '&format=' + format; - newWindow(new_url); -} - -function Menu_copy() { - var id = pd_selected_item.getAttribute("id"); - model_copy(id); -} - -function finish_copy(resp, err) { -} - -function Menu_paste() { var id = pd_selected_item.getAttribute("id"); - model_paste(id); -} - -function finish_paste(resp, err) { -} - -function Menu_remove() { - var id = pd_selected_item.getAttribute("id"); - model_delete(id); - var container = pd_selected_item.parentNode; - container.removeChild(pd_selected_item); -} - -function finish_delete(resp, err) { + menu_actions.call(id, action, choice); } /* Drag-and-drop, etc */ @@ -288,14 +289,6 @@ current_elem = moving; } -function finish_reorder(resp, err) { - if (!current_elem) return; - if (!err) { - highlight(current_elem); - } - current_elem = null; -} - function save_move(elem) { var parent = getParentElement(elem); var src_id = elem.getAttribute("id"); @@ -303,24 +296,7 @@ var order = getElementOrder(elem); current_elem = elem; current_container = parent; - model_move(src_id, dest_id, order); -} - -function finish_move(resp, err) { - if (!current_elem) return; - if (!current_container) return; - if (!err) { - var new_id = resp; - if (current_container.getAttribute("render")) { - var rendered = render_element(new_id); - current_elem.parentNode.replaceChild(rendered, current_elem); - current_elem = rendered; - } - highlight(current_elem); - current_container = null; - current_elem = null; - pd_setupPage(); - } + model.move({'src_id': src_id, 'dest_id': dest_id, 'order': order}); } function move_to_container(el, e) { @@ -345,22 +321,7 @@ } current_elem = el; current_container = container; - model_add(container_id, type_name, order); -} - -function finish_add(resp, err) { - if (!err) { - var new_id = resp; - var rendered = render_element(new_id); - if (current_elem) { - current_container.insertBefore(rendered, current_elem); - } else { - current_container.appendChild(rendered); - } - current_elem = null; - pd_setupPage(); - highlight(rendered); - } + model.add({'id': container_id, 'type_name': type_name, 'order': order}); } function edit_element(target, name, value) { @@ -372,10 +333,7 @@ } // update the model var model_id = target.getAttribute("model_id"); - model_edit(model_id, name, value); -} - -function finish_edit(resp, err) { + model.edit({'id': model_id, 'name': name, 'value': value}); } /* Event handlers */ @@ -485,7 +443,6 @@ tooltip_active = true; setTimeout("showTooltip()", 1000); }); - Event.observe(mo, 'mouseout', function(e) { Element.hide('tooltip-box'); tooltip_active = false; @@ -512,19 +469,6 @@ /* Setup editor, JSON-RPC */ function setupEditor() { - themeEditor = jsonrpcConnect(addr=".", - methods=["addElement", - "editElement", - "copyElement", - "pasteElement", - "moveElement", - "renderElement", - "deleteElement", - "reorderElement", - "duplicateElement", - "getCanvasMode" - ]); - drag_box = $("drag-feedback-box"); edit_space = $("editSpace"); context_menu = $("choice-context-menu"); @@ -532,6 +476,7 @@ tooltip_box = $("tooltip-box"); Element.hide('tooltip-box') + model = new Model(); menu_actions = new MenuActions(); pd_setupPage(); Modified: cpsskins/branches/jmo-perspectives/ui/authoring/authoring.py ============================================================================== --- cpsskins/branches/jmo-perspectives/ui/authoring/authoring.py (original) +++ cpsskins/branches/jmo-perspectives/ui/authoring/authoring.py Mon Dec 19 17:52:36 2005 @@ -17,16 +17,23 @@ """ __docformat__ = "reStructuredText" +from zope.app.event.objectevent import ObjectCreatedEvent from zope.app.publisher.browser import BrowserView from zope.app.session.interfaces import ISession -from zope.app.zapi import getMultiAdapter -from zope.component import adapts, getUtility +from zope.app.zapi import getParent, getMultiAdapter +from zope.component import adapts, getUtility, createObject +from zope.event import notify from zope.interface import implements, Interface +from cpsskins.browser.tree.interfaces import INodeAdding, INodeRemoving +from cpsskins.browser.tree.interfaces import INodeMoving, INodeOrdering +from cpsskins.browser.tree.interfaces import INodeDuplicating +from cpsskins.browser.rendering.interfaces import IViewer from cpsskins.elements.interfaces import IElement, IPresentable from cpsskins.elements.interfaces import IDisplayable from cpsskins.browser.rendering.interfaces import IViewer from cpsskins.setup.interfaces import IResourceManager +from cpsskins.utils import getThemeManager class IAuthoring(Interface): @@ -135,3 +142,105 @@ IPresentable(self.context).uncustomizeFormat(name, perspective) self._redirect() + ################################################################### + # Elements + ################################################################### + + def _getElementById(self, id): + """Return an element by id. + """ + return getThemeManager().getElementById(id) + + def renderElement(self, id, engine=u'default'): + """Render the element and return the markup + """ + element = self._getElementById(id) + request = self.request + + viewer = getMultiAdapter((element, request), IViewer) + return viewer(engine=engine) + + def editElement(self, id, name, value): + """Edit the element: assign a value to an attribute (name). + """ + element = self._getElementById(id) + element.name = value + + def copyElement(self, id): + """Copy an element to the clipboard. + """ + request = self.request + element = self._getElementById(id) + container = getParent(element) + request.form['ids'] = [zapi.name(element)] + view = Contents(container, request) + view.copyObjects() + + def pasteElement(self, id): + """Paste an element from the clipboard. + """ + request = self.request + element = self._getElementById(id) + container = getParent(element) + view = Contents(container, request) + view.pasteObjects() + + def addElement(self, id, type_name, order): + """Add an element in a container. + Return the id of added element. + """ + request = self.request + container = self._getElementById(id) + + content = createObject(type_name) + notify(ObjectCreatedEvent(content)) + + adding = getMultiAdapter((container, request), INodeAdding) + + added = adding.add(content) + added_id = added.identifier + self.reorderElement(added_id, int(order)) + return str(added_id) + + def moveElement(self, src_id, dest_id, order): + """Move an element to another destination element. + return the id of the moved element. + """ + request = self.request + element = self._getElementById(src_id) + dest_container = self._getElementById(dest_id) + # move the element to the destination container + moving = getMultiAdapter((dest_container, request), INodeMoving) + moved = moving.move(element) + + # move the element to the specified order + moved_id = moved.identifier + self.reorderElement(moved_id, int(order)) + return str(moved_id) + + def reorderElement(self, id, order): + """Move an element to a new position. + """ + element = self._getElementById(id) + container = getParent(element) + ordering = getMultiAdapter((container, self.request), INodeOrdering) + ordering.reorder(element, int(order)) + + def deleteElement(self, id): + """Delete the element specified by its path. + """ + request = self.request + element = self._getElementById(id) + container = getParent(element) + removing = getMultiAdapter((container, request), INodeRemoving) + removing.remove(element) + + def duplicateElement(self, id): + """Duplicate an element specified by its id. + Return the id of the duplicated element. + """ + request = self.request + element = self._getElementById(id) + container = getParent(element) + duplicating = getMultiAdapter((container, request), INodeDuplicating) + return str(duplicating.duplicate(element)) Modified: cpsskins/branches/jmo-perspectives/ui/authoring/configure.zcml ============================================================================== --- cpsskins/branches/jmo-perspectives/ui/authoring/configure.zcml (original) +++ cpsskins/branches/jmo-perspectives/ui/authoring/configure.zcml Mon Dec 19 17:52:36 2005 @@ -73,24 +73,46 @@ attribute="uncustomizeFormat" /> - </browser:pages> + <browser:page + name="renderElement" + attribute="renderElement" + /> + + <browser:page + name="moveElement" + attribute="moveElement" + /> + <browser:page + name="editElement" + attribute="editElement" + /> + + <browser:page + name="copyElement" + attribute="copyElement" + /> - <!-- JSON-RPC views --> + <browser:page + name="pasteElement" + attribute="pasteElement" + /> - <jsonrpc:view - class=".jsonrpc.Methods" - for="*" - permission="zope.ManageContent" - methods="addElement editElement moveElement - reorderElement deleteElement duplicateElement" - /> - - <jsonrpc:view - class=".jsonrpc.Methods" - for="*" - permission="zope.Public" - methods="renderElement" - /> + <browser:page + name="addElement" + attribute="addElement" + /> + + <browser:page + name="duplicateElement" + attribute="duplicateElement" + /> + + <browser:page + name="deleteElement" + attribute="deleteElement" + /> + + </browser:pages> </configure> -- http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins