[FIX] Ace: support multiple dirty buffers
bzr revid: ddm@openerp.com-20130916150209-h0j5qs3ozeoxz66c
This commit is contained in:
@@ -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');
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<link id="website_css" rel='stylesheet' href='/website/static/src/css/website.css' t-ignore="true"/>
|
||||
</template>
|
||||
|
||||
<template id="layout">
|
||||
<template id="layout" name="Main layout">
|
||||
<!DOCTYPE html>
|
||||
<html t-att-lang="lang.replace('_', '-')"
|
||||
t-att-data-editable="'1' if editable else '0'"
|
||||
@@ -159,7 +159,7 @@
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="homepage" page="True">
|
||||
<template id="homepage" name="Homepage" page="True">
|
||||
<t t-call="website.layout">
|
||||
<div id="wrap" class="oe_structure"></div>
|
||||
</t>
|
||||
|
||||
Reference in New Issue
Block a user