From 03865ba97823cf9516e0f9e17076454bbe3b33ec Mon Sep 17 00:00:00 2001 From: sebastiaan Date: Thu, 6 Sep 2012 08:10:48 -0200 Subject: [PATCH] Re-included ItemEditing*.js for canvas, was removed after a merge with 4.10 --- .../Modules/ItemEditing/ItemEditing.js | 341 ++++++++++++++++++ .../Modules/ItemEditing/ItemEditingInvoke.js | 3 + 2 files changed, 344 insertions(+) create mode 100644 src/Umbraco.Web.UI/umbraco/LiveEditing/Modules/ItemEditing/ItemEditing.js create mode 100644 src/Umbraco.Web.UI/umbraco/LiveEditing/Modules/ItemEditing/ItemEditingInvoke.js diff --git a/src/Umbraco.Web.UI/umbraco/LiveEditing/Modules/ItemEditing/ItemEditing.js b/src/Umbraco.Web.UI/umbraco/LiveEditing/Modules/ItemEditing/ItemEditing.js new file mode 100644 index 0000000000..b0644e5b3c --- /dev/null +++ b/src/Umbraco.Web.UI/umbraco/LiveEditing/Modules/ItemEditing/ItemEditing.js @@ -0,0 +1,341 @@ +// Umbraco Live Editing - ItemEditing: Item Editing +var ItemEditing = null; + +Type.registerNamespace("umbraco.presentation.LiveEditing"); + +/************************ ItemEditing class ************************/ + +// Creates a new instance of the ItemEditing class. +umbraco.presentation.LiveEditing.ItemEditing = function() { + umbraco.presentation.LiveEditing.ItemEditing.initializeBase(this); + this._inited = false; + this._items = new Array(); + this._activeItem = null; + this._editControl = null; + this._submitControl = null; + + var _this = this; + Sys.Debug.trace("Constructor, before init load"); + if (!this._inited) { + _this.init(); + } + Sys.Application.add_load(function() { + _this.init(); + }); + Sys.Debug.trace("Constructor, after init load"); + +} + +umbraco.presentation.LiveEditing.ItemEditing.prototype = { + // Initializes this instance. + init: function() { + Sys.Debug.trace("In init..."); + if (!this._inited) { + this._inited = true; + Sys.Debug.trace("Live Editing - ItemEditing: Initialization."); + Sys.Debug.assert(typeof (jQuery) == 'function', "jQuery is not loaded."); + + this.itemsEnable(); + + var _this = this; + LiveEditingToolbar.add_save(function(sender, args) { _this.delaySaveWhenEditing(args, "save"); }); + LiveEditingToolbar.add_saveAndPublish(function(sender, args) { _this.delaySaveWhenEditing(args, "saveAndPublish"); }); + + this._inited = true; + Sys.Debug.trace("Live Editing - ItemEditing: Ready."); + } + else { + this.updateItems(); + this.updateControls(); + } + }, + + // Starts Live Editing the specified item. + // This method is triggered by the server. + startEdit: function(itemId) { + Sys.Debug.trace("Live Editing - ItemEditing: Start editing of Item " + itemId + "."); + + this._activeItem = this._items[itemId]; + Sys.Debug.assert(this._activeItem != null, "Live Editing - ItemEditing: Could not find item with ID " + itemId + "."); + this._editControl = this.getElementsByTagName("umbraco:control"); + Sys.Debug.assert(this._editControl.length > 0, "Live Editing - ItemEditing: Could not find the editor control."); + //this._activeItem.jItem.fadeIn(); + this.moveChildControls(this._editControl, this._activeItem.jItem); + + // Only elements that are currently present, can cause item editing to stop. + // This enables transparent use of dynamically created elements (such as context/dropdown menus) + // as clicks on those elements will not trigger the stop edit signal. + jQuery("*").each(function () { jQuery(this).data("canStopEditing", true); }); + + // raise event + var handler = this.get_events().getHandler("startEdit"); + if (handler) + handler(this, Sys.EventArgs.Empty); + + this.ignoreChildClicks(this._activeItem.jItem); + + LiveEditingToolbar.setDirty(true); + }, + + // Stops the editing of a specified item, and raises the stopEdit event. + stopEdit: function() { + if (this._activeItem != null) { + Sys.Debug.trace("Live Editing - ItemEditing: Stop editing of " + this._activeItem.toString() + "."); + + // raise event + var handler = this.get_events().getHandler("stopEdit"); + if (handler) + handler(this, Sys.EventArgs.Empty); + + // submit changes + Sys.Debug.assert(this._submitControl != null, "Live Editing - ItemEditing: Submit button not set."); + this._submitControl.click(); + + // hide control + //this._activeItem.jItem.fadeOut(); + this._activeItem = null; + this._submitControl = null; + this._editControl = null; + } + }, + + // Adds an event handler to the startEdit event. + add_startEdit: function(handler) { + this.get_events().addHandler("startEdit", handler); + }, + + // Removes an event handler from the startEdit event. + remove_startEdit: function(handler) { + this.get_events().removeHandler("startEdit", handler); + }, + + // Adds an event handler to the stopEdit event. + add_stopEdit: function(handler) { + this.get_events().addHandler("stopEdit", handler); + }, + + // Removes an event handler from the stopEdit event. + remove_stopEdit: function(handler) { + this.get_events().removeHandler("stopEdit", handler); + }, + + // Cancels the save method when an item is active, and postpones it to the next postback. + delaySaveWhenEditing: function(args, type) { + if (this._activeItem != null) { + this.stopEdit(); + args.cancel = true; + (function() { + var f = function() { + Sys.Application.remove_load(f); + setTimeout(function() { + Sys.Debug.trace("Live Editing - Delayed Saving Changes to server"); + UmbracoCommunicator.SendClientMessage(type, ""); + }, 100); + } + Sys.Application.add_load(f); + })(); + } + else { + Sys.Debug.trace("Live Editing - Saving Changes to server"); + if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) { + UmbracoCommunicator.SendClientMessage(type, ""); + } + else { + Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function() { + UmbracoCommunicator.SendClientMessage(type, ""); + }); + } + } + }, + + // Enables Live Editing of items. + itemsEnable: function() { + var items = this.getElementsByTagName("umbraco:iteminfo"); + Sys.Debug.trace(" Found " + items.length + " editable Umbraco item(s)."); + + // enhance items with edit functionality + var _this = this; + var i = 0; + items.each(function() { + var item = new umbraco.presentation.LiveEditing.activeItem(jQuery(this)); + _this._items[item.itemId] = item; + Sys.Debug.trace(" " + (++i) + ". " + item.toString() + " is Live Editing enabled."); + }); + // disable hyperlinks to make them clickable for Live Editing + this.disableHyperlinks(); + + // add "stop editing" handler when clicking outside the item + var _this = this; + jQuery(document).mousedown(function(event) { + Sys.Debug.trace("DOCUMENT CLICKED"); + // the canStopEditing property is set in startEdit + if (_this._activeItem != null && jQuery(event.target).data("canStopEditing")) { + if (!_this._activeItem.clicked) + _this.stopEdit(); + else + _this._activeItem.clicked = false; + } + }); + jQuery("#LiveEditingToolbar").mousedown(function() { + Sys.Debug.trace("TOOLBAR CLICKED"); + if (_this._activeItem != null) + _this._activeItem.clicked = true; + }); + }, + + // Update items that have changed. + updateItems: function() { + var itemUpdates = this.getElementsByTagName("umbraco:itemupdate"); + Sys.Debug.trace("Live Editing - ItemEditing: " + itemUpdates.length + " item update(s)."); + + var _this = this; + itemUpdates.each(function() { + var itemUpdate = jQuery(this); + var itemId = itemUpdate.attr("itemId"); + var item = _this._items[itemId]; + + if (item != null) { + Sys.Debug.trace(" Updating " + item.toString() + "."); + + // remove old children and add updates ones + _this.moveChildControls(itemUpdate, item.jItem); + //item.jItem.fadeIn(); + + // disable hyperlinks to make them clickable for Live Editing + _this.disableHyperlinks(); + } + else { + itemUpdate.html(""); + } + }); + }, + + // Update controls that have changed. + updateControls: function() { + Sys.Debug.trace("Live Editing - ItemEditing: In updatecontrols"); + var controlUpdates = this.getElementsByTagName("umbraco:control"); + Sys.Debug.trace("Live Editing - ItemEditing: " + controlUpdates.length + " control update(s)."); + + if (controlUpdates.length == 1) { + if (this._activeItem != null && controlUpdates.children().length > 0) { + Sys.Debug.trace("Live Editing - ItemEditing: updating edit control."); + this.moveChildControls(controlUpdates, this._activeItem.jItem); + this.ignoreChildClicks(); + } + + this._submitControl = controlUpdates.next(); + Sys.Debug.assert(this._submitControl.length > 0, "Live Editing - ItemEditing: Submit button not found."); + } + }, + + // ignores clicks on child elements of the control + ignoreChildClicks: function() { + var _this = this; + this._activeItem.jItem.children().mousedown(function(e) { + _this._activeItem.clicked = true; + }); + }, + + // Moves the child controls from source into destination, overwriting existing elements. + moveChildControls: function(source, dest) { + Sys.Debug.trace("Live Editing - Moving Child Controls"); + + //remove contents in the destination + dest.html(""); + + //add the source to the destination + dest.append(source.html()); + + //remove teh contents from the source + source.html(""); + + }, + + // Gets a list of elements with the specified tagname including namespaced ones + getElementsByTagName: function(tagname) { + var found = jQuery("body").find("*").filter(function(index) { + if (this.nodeType != 3) { + var nn = this.nodeName.toLowerCase(); + var ftn = tagname.toLowerCase(); + var ln = (ftn.indexOf(":") > 0 ? ftn.substr(ftn.indexOf(":") + 1) : ftn); + return (nn == ftn + || (typeof this.scopeName != "undefined" && nn == ln && this.scopeName.toLowerCase() == ftn.substr(0, ftn.indexOf(":")))); + } + return false; + }); + Sys.Debug.trace("found " + found.length + " elements with selector: " + tagname); + return found; + }, + + // Disables hyperlinks inside the specified element. + disableHyperlinks: function() { + jQuery("a").click(function() { + return false; + }); + } +} + +umbraco.presentation.LiveEditing.ItemEditing.registerClass("umbraco.presentation.LiveEditing.ItemEditing", Sys.Component); + +//an object to store the information for the active item +umbraco.presentation.LiveEditing.activeItem = function(item) { + //error checking + if (item != null && item.length != 1) { + return null; + } + //create the object with values, wire up events and return it + var obj = { + jItem: item, + nodeId: item.attr("nodeId"), + fieldName: item.attr("name"), + itemId: item.attr("itemId"), + clicked: false, + toString: function() { + return "Item " + this.itemId + " (node " + this.nodeId + ": " + this.fieldName + ")"; + }, + // Activates an item for editing. + activate: function() { + ItemEditing._items[this.itemId] = this; + if (this != ItemEditing._activeItem) { + Sys.Debug.trace("Live Editing - ItemEditing: " + this.toString() + " was activated."); + if (!Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) { + UmbracoCommunicator.SendClientMessage("edititem", this.itemId); + } + else { + var itemId = this.itemId; + Sys.WebForms.PageRequestManager.getInstance().add_endRequest(function() { + if (itemId != 0) { + UmbracoCommunicator.SendClientMessage("edititem", itemId); + itemId = 0; + } + }); + } + //this.jItem.fadeOut(); + } + }, + // Item click handler. + onClick: function(e) { + if (ItemEditing._activeItem != null && ItemEditing._activeItem.itemId == this.itemId) { + Sys.Debug.trace("Live Editing - ItemEditing: " + this.toString() + " click ignored because it is already active."); + } + else { + Sys.Debug.trace("Live Editing - ItemEditing: " + this.toString() + " was clicked."); + e.stopPropagation(); // disable click event propagation to parent elements + this.activate(); + } + } + } + + //keep the scope on the click event method call + obj.jItem.click(function(e) { + obj.onClick.call(obj, e); + }); + + return obj; +} + + +// global instance of the ItemEditing class +function initializeGlobalItemEditing() { + ItemEditing = new umbraco.presentation.LiveEditing.ItemEditing(); +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/LiveEditing/Modules/ItemEditing/ItemEditingInvoke.js b/src/Umbraco.Web.UI/umbraco/LiveEditing/Modules/ItemEditing/ItemEditingInvoke.js new file mode 100644 index 0000000000..47c371631d --- /dev/null +++ b/src/Umbraco.Web.UI/umbraco/LiveEditing/Modules/ItemEditing/ItemEditingInvoke.js @@ -0,0 +1,3 @@ +//this is simply used for live editing in order to invoke a method from a previously lazy loaded script; +//alert("ItemEditingInvoke: " + initializeGlobalItemEditing); +initializeGlobalItemEditing(); \ No newline at end of file