diff --git a/addons/website/models/ir_qweb.py b/addons/website/models/ir_qweb.py
index d553acf363a..ea982bbe563 100644
--- a/addons/website/models/ir_qweb.py
+++ b/addons/website/models/ir_qweb.py
@@ -25,6 +25,7 @@ import openerp
from openerp.osv import orm, fields
from openerp.tools import ustr, DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
from openerp.addons.web.http import request
+from openerp.addons.base.ir import ir_qweb
REMOTE_CONNECTION_TIMEOUT = 2.5
@@ -198,7 +199,6 @@ class ManyToOne(orm.AbstractModel):
matches = self.pool[column._obj].name_search(
cr, uid, name=element.text_content().strip(), context=context)
# FIXME: no match? More than 1 match?
- print element.text_content().strip()
assert len(matches) == 1
return matches[0][0]
@@ -239,10 +239,10 @@ class Image(orm.AbstractModel):
if options is None: options = {}
classes = ['img', 'img-responsive'] + options.get('class', '').split()
- return '
' % (
+ return ir_qweb.HTMLSafe('
' % (
' '.join(itertools.imap(werkzeug.utils.escape, classes)),
record._model._name,
- field_name, record.id)
+ field_name, record.id))
local_url_re = re.compile(r'^/(?P[^]]+)/static/(?P.+)$')
def from_html(self, cr, uid, model, column, element, context=None):
@@ -390,4 +390,4 @@ class Contact(orm.AbstractModel):
'options': options
}, engine='website.qweb', context=context)
- return html
+ return ir_qweb.HTMLSafe(html)
diff --git a/addons/website/static/src/css/website.css b/addons/website/static/src/css/website.css
index 3c57d1bf69f..4d75ef6ef51 100644
--- a/addons/website/static/src/css/website.css
+++ b/addons/website/static/src/css/website.css
@@ -203,7 +203,7 @@ html, body, #wrapwrap {
width: 100%;
}
-header, #wrap, footer {
+header, main, footer {
display: table-row;
}
diff --git a/addons/website/static/src/css/website.sass b/addons/website/static/src/css/website.sass
index eeac3ce2eb5..babeee577a7 100644
--- a/addons/website/static/src/css/website.sass
+++ b/addons/website/static/src/css/website.sass
@@ -127,7 +127,7 @@ html,body, #wrapwrap
display: table
width: 100%
-header, #wrap, footer
+header, main, footer
display: table-row
footer
diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js
index 40b7820e89a..1e3ef0da66a 100644
--- a/addons/website/static/src/js/website.editor.js
+++ b/addons/website/static/src/js/website.editor.js
@@ -32,6 +32,27 @@
});
});
+ /**
+ * An editing host is an HTML element with @contenteditable=true, or the
+ * child of a document in designMode=on (but that one's not supported)
+ *
+ * https://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#editing-host
+ */
+ function is_editing_host(element) {
+ return element.getAttribute('contentEditable') === 'true';
+ }
+ /**
+ * Checks that both the element's content *and the element itself* are
+ * editable: an editing host is considered non-editable because its content
+ * is editable but its attributes should not be considered editable
+ */
+ function is_editable_node(element) {
+ return !(element.data('oe-model') === 'ir.ui.view'
+ || element.data('cke-realelement')
+ || is_editing_host(element)
+ || element.isReadOnly());
+ }
+
function link_dialog(editor) {
return new website.editor.RTELinkDialog(editor).appendTo(document.body);
}
@@ -54,18 +75,13 @@
init: function (editor) {
editor.on('doubleclick', function (evt) {
var element = evt.data.element;
- if (element.is('img')
- && !element.data('cke-realelement')
- && !element.isReadOnly()
- && (element.data('oe-model') !== 'ir.ui.view')) {
+ if (element.is('img') && is_editable_node(element)) {
image_dialog(editor, element);
return;
}
element = get_selected_link(editor) || evt.data.element;
- if (element.isReadOnly()
- || !element.is('a')
- || element.data('oe-model')) {
+ if (!(element.is('a') && is_editable_node(element))) {
return;
}
@@ -360,7 +376,8 @@
});
$body.css('padding-top', '50px'); // Not working properly: editor.$el.outerHeight());
};
- /* ----- TOP EDITOR BAR FOR ADMIN ---- */
+
+ /* ----- TOP EDITOR BAR FOR ADMIN ---- */
website.EditorBar = openerp.Widget.extend({
template: 'website.editorbar',
events: {
@@ -597,9 +614,7 @@
if (previous && previous === this) { return; }
var selected = new CKEDITOR.dom.element(this);
- if (selected.data('oe-model') === 'ir.ui.view'
- || selected.data('cke-realelement')
- || selected.isReadOnly()) {
+ if (!is_editable_node(selected)) {
return;
}
diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js
index c2f3b09911a..fb869119352 100644
--- a/addons/website/static/src/js/website.tour.js
+++ b/addons/website/static/src/js/website.tour.js
@@ -69,7 +69,7 @@
$doc.one('shown.bs.modal', function () {
$('.modal button.btn-primary').one('click', function () {
$doc.off('hide.bs.modal', onStop);
- self.moveToStep(step.trigger.modal.afterSubmit);
+ (callback || self.moveToNextStep).apply(self, [step.trigger.modal.afterSubmit]);
});
(callback || self.moveToNextStep).apply(self);
});
@@ -290,6 +290,7 @@
return this._super();
},
registerTour: function (tour) {
+ var self = this;
var testId = 'test_'+tour.id+'_tour';
this.tours.push(tour);
var test = {
@@ -343,9 +344,17 @@
currentStep = actionSteps.shift();
}
}
- setTimeout(function () {
- executeStep(currentStep);
- }, 0);
+ if (currentStep.snippet && $(currentStep.element).length === 0) {
+ self.on('rte:ready', this, function () {
+ executeStep(currentStep);
+ });
+ } else {
+ setTimeout(function () {
+ setTimeout(function () {
+ executeStep(currentStep);
+ }, 0);
+ }, 0);
+ }
}
},
reset: function () {
diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml
index 257e3bb4562..be7d4c65a85 100644
--- a/addons/website/views/website_templates.xml
+++ b/addons/website/views/website_templates.xml
@@ -114,7 +114,9 @@
-
+
+
+