From 48c80bac226f044ebc6d9577343d99b6c80c3c31 Mon Sep 17 00:00:00 2001 From: ddm Date: Mon, 16 Sep 2013 17:02:09 +0200 Subject: [PATCH] [FIX] Ace: support multiple dirty buffers bzr revid: ddm@openerp.com-20130916150209-h0j5qs3ozeoxz66c --- addons/website/static/src/js/website.ace.js | 121 +++++++++++++------- addons/website/static/src/js/website.seo.js | 4 +- addons/website/views/views.xml | 4 +- 3 files changed, 83 insertions(+), 46 deletions(-) diff --git a/addons/website/static/src/js/website.ace.js b/addons/website/static/src/js/website.ace.js index fd26c50aefd..840e3317d56 100644 --- a/addons/website/static/src/js/website.ace.js +++ b/addons/website/static/src/js/website.ace.js @@ -55,82 +55,119 @@ website.ace.ViewEditor = openerp.Widget.extend({ template: 'website.ace_view_editor', events: { - 'change #ace-view-list': 'displayView', - 'click button[data-action=save]': 'saveView', + 'change #ace-view-list': 'displaySelectedView', + 'click button[data-action=save]': 'saveViews', 'click button[data-action=format]': 'formatXml', 'click button[data-action=close]': 'close', }, + init: function (parent) { + this.buffers = {}; + this._super(parent); + }, start: function () { var self = this; + self.aceEditor = ace.edit(self.$('#ace-view-editor')[0]); + self.aceEditor.setTheme("ace/theme/monokai"); var viewId = $(document.documentElement).data('view-xmlid'); openerp.jsonRpc('/website/customize_template_get', 'call', { 'xml_id': viewId, 'optional': false, }).then(function (views) { - self.loadViewList.call(self, views); + self.loadViews.call(self, views); + self.open.call(self); + }); + }, + loadViews: function (views) { + var self = this; + var activeViews = _.filter(views, function (view) { + return view.active; + }); + var $viewList = self.$('#ace-view-list'); + _.each(activeViews, function (view) { + if (view.id) { + new website.ace.ViewOption(self, view).appendTo($viewList); + self.loadView(view.id); + } + }); + }, + loadView: function (id) { + var viewId = parseInt(id, 10); + var self = this; + openerp.jsonRpc('/web/dataset/call', 'call', { + model: 'ir.ui.view', + method: 'read', + args: [[viewId], ['arch'], website.get_context()], + }).then(function(result) { + var editingSession = self.buffers[viewId] = new ace.EditSession(result[0].arch);; + editingSession.setMode("ace/mode/xml"); + editingSession.setUndoManager(new ace.UndoManager()); + editingSession.on("change", function () { + setTimeout(function () { + var $option = self.$('#ace-view-list').find('[value='+viewId+']'); + var bufferName = $option.text(); + var dirtyMarker = " (unsaved changes)"; + var isDirty = editingSession.getUndoManager().hasUndo(); + if (isDirty && bufferName.indexOf(dirtyMarker) < 0) { + $option.text(bufferName + dirtyMarker); + } else if (!isDirty && bufferName.indexOf(dirtyMarker) > 0) { + $option.text(bufferName.substring(0, bufferName.indexOf(dirtyMarker))); + } + }, 1); + }); + if (viewId === self.selectedViewId()) { + self.displayView.call(self, viewId); + } }); - this.$el.hover(); }, selectedViewId: function () { return parseInt(this.$('#ace-view-list').val(), 10); }, - loadViewList: function (views) { - var activeViews = _.filter(views, function (view) { - return view.active; - }); - var $viewList = this.$('#ace-view-list'); - _.each(activeViews, function (view) { - if (view.id) { - new website.ace.ViewOption(this, view).appendTo($viewList); - } - }); - var editor = ace.edit(this.$('#ace-view-editor')[0]); - editor.setTheme("ace/theme/monokai"); - this.aceEditor = editor; - this.open(); + displayView: function (id) { + var viewId = parseInt(id, 10); + var editingSession = this.buffers[viewId]; + if (editingSession) { + this.aceEditor.setSession(editingSession); + } }, - displayView: function () { - var editor = this.aceEditor; - openerp.jsonRpc('/web/dataset/call', 'call', { - model: 'ir.ui.view', - method: 'read', - args: [[this.selectedViewId()], ['arch'], website.get_context()], - }).then(function(result) { - var xml = new website.ace.XmlDocument(result[0].arch); - var editingSession = new ace.EditSession(xml.xml); - editingSession.setMode("ace/mode/xml"); - editingSession.setUndoManager(new ace.UndoManager()); - editor.setSession(editingSession); - }); + displaySelectedView: function () { + this.displayView(this.selectedViewId()); }, formatXml: function () { var xml = new website.ace.XmlDocument(this.aceEditor.getValue()); this.aceEditor.setValue(xml.format()); }, - saveView: function () { + saveViews: function () { var self = this; - var xml = new website.ace.XmlDocument(this.aceEditor.getValue()); + var toSave = _.filter(_.map(self.buffers, function (editingSession, viewId) { + return { + id: parseInt(viewId, 10), + isDirty: editingSession.getUndoManager().hasUndo(), + text: editingSession.getValue(), + }; + }), function (session) { + return session.isDirty; + }); + var requests = _.map(toSave, self.saveView); + $.when.apply($, requests).then(self.reloadPage).fail(self.displayError); + }, + saveView: function (session) { + var xml = new website.ace.XmlDocument(session.text); if (xml.isWellFormed()) { - openerp.jsonRpc('/web/dataset/call', 'call', { + return openerp.jsonRpc('/web/dataset/call', 'call', { model: 'ir.ui.view', method: 'write', - args: [[this.selectedViewId()], { 'arch': xml.xml }, website.get_context()], - }).then(function(result) { - self.reloadPage(); - }).fail(function (error) { - self.displayError(error); + args: [[session.id], { 'arch': xml.xml }, website.get_context()], }); } else { - self.displayError(); + return $.Deferred().fail("Malformed XML document"); } }, reloadPage: function () { - // TODO Reload { header + div#wrap + footer } only window.location.reload(); }, displayError: function (error) { // TODO Improve feedback (e.g. update 'Save' button + tooltip) - alert("Malformed XML document"); + alert(error); }, open: function () { this.$el.removeClass('oe_ace_closed').addClass('oe_ace_open'); diff --git a/addons/website/static/src/js/website.seo.js b/addons/website/static/src/js/website.seo.js index e5741123ccb..49cc65e1b09 100644 --- a/addons/website/static/src/js/website.seo.js +++ b/addons/website/static/src/js/website.seo.js @@ -214,14 +214,14 @@ return hashIndex >= 0 ? url.substring(0, hashIndex) : url; }, title: function () { - return $('title').text(); + return $('title').text().trim(); }, changeTitle: function (title) { $('title').text(title); this.trigger('title-changed', title); }, description: function () { - return $('meta[name=description]').attr('value'); + return $('meta[name=description]').attr('value').trim(); }, changeDescription: function (description) { $('meta[name=description]').attr('value', description); diff --git a/addons/website/views/views.xml b/addons/website/views/views.xml index 485c1b9f9f2..5a9f427641c 100644 --- a/addons/website/views/views.xml +++ b/addons/website/views/views.xml @@ -11,7 +11,7 @@ -