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/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_blog/controllers/main.py b/addons/website_blog/controllers/main.py index d38d110aac1..00835d133ab 100644 --- a/addons/website_blog/controllers/main.py +++ b/addons/website_blog/controllers/main.py @@ -209,6 +209,7 @@ class WebsiteBlog(http.Controller): 'tags': tags, 'tag': tag and request.registry['blog.tag'].browse(cr, uid, int(tag), context=context) or None, 'blog_post': blog_post, + 'main_object': blog_post, 'pager': pager, 'nav_list': self.nav_list(), 'enable_editor': enable_editor, diff --git a/addons/website_crm_partner_assign/controllers/main.py b/addons/website_crm_partner_assign/controllers/main.py index 6ac2f54b6d2..50ad1e26519 100644 --- a/addons/website_crm_partner_assign/controllers/main.py +++ b/addons/website_crm_partner_assign/controllers/main.py @@ -96,4 +96,5 @@ class WebsiteCrmPartnerAssign(http.Controller): values = website_partner.get_partner_template_value(partner) if not values: return self.partners(**post) + values['main_object'] = values['partner'] return request.website.render("website_crm_partner_assign.partner", values) diff --git a/addons/website_crm_partner_assign/models/res_partner.py b/addons/website_crm_partner_assign/models/res_partner.py index bd3c1e64ff3..e295c7ab0b1 100644 --- a/addons/website_crm_partner_assign/models/res_partner.py +++ b/addons/website_crm_partner_assign/models/res_partner.py @@ -6,4 +6,4 @@ class res_partner_grade(osv.osv): _inherit = 'res.partner.grade' _columns = { 'website_description': fields.html('Description for the website'), - } \ No newline at end of file + } diff --git a/addons/website_customer/controllers/main.py b/addons/website_customer/controllers/main.py index 21aca3b6235..d0663dfdfdc 100644 --- a/addons/website_customer/controllers/main.py +++ b/addons/website_customer/controllers/main.py @@ -81,11 +81,11 @@ class WebsiteCustomer(http.Controller): return self.customers(**post) partner_obj = request.registry['res.partner'] - if values['partner_data']['assigned_partner_id']: + if values['partner_data'].get('assigned_partner_id', None): values['assigned_partner_data'] = partner_obj.read( request.cr, openerp.SUPERUSER_ID, [values['partner_data']['assigned_partner_id'][0]], request.website.get_partner_white_list_fields(), context=request.context)[0] - if values['partner_data']['implemented_partner_ids']: + if values['partner_data'].get('implemented_partner_ids', None): implemented_partners_data = partner_obj.read( request.cr, openerp.SUPERUSER_ID, values['partner_data']['implemented_partner_ids'], request.website.get_partner_white_list_fields(), context=request.context) @@ -94,4 +94,5 @@ class WebsiteCustomer(http.Controller): if data.get('website_published'): values['implemented_partners_data'].append(data) + values['main_object'] = values['partner'] return request.website.render("website_customer.details", values) diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py index a9cc84b1d6d..638c5ded6e5 100644 --- a/addons/website_event/controllers/main.py +++ b/addons/website_event/controllers/main.py @@ -166,6 +166,7 @@ class website_event(http.Controller): website.preload_records(event, on_error="website_event.404") values = { 'event': event, + 'main_object': event } return request.website.render(page, values) @@ -185,7 +186,9 @@ class website_event(http.Controller): website.preload_records(event, on_error="website_event.404") values = { 'event': event, + 'main_object': event, 'range': range, + 'main_object': event, } return request.website.render("website_event.event_description_full", values) diff --git a/addons/website_event_track/controllers/event.py b/addons/website_event_track/controllers/event.py index ba683b956b5..22e4c1501a9 100644 --- a/addons/website_event_track/controllers/event.py +++ b/addons/website_event_track/controllers/event.py @@ -31,7 +31,7 @@ class website_event(http.Controller): @website.route(['/event//track/'], type='http', auth="public", multilang=True) def event_track_view(self, event, track, **post): # TODO: not implemented - values = { 'track': track, 'event': track.event_id} + values = { 'track': track, 'event': track.event_id, 'main_object': track } return request.website.render("website_event_track.track_view", values) @website.route([ @@ -55,6 +55,7 @@ class website_event(http.Controller): values = { 'event': event, + 'main_object': event, 'tracks': tracks, 'tags': event.tracks_tag_ids, 'searches': searches, @@ -64,7 +65,7 @@ class website_event(http.Controller): @website.route(['/event/detail/'], type='http', auth="public", multilang=True) def event_detail(self, event, **post): - values = { 'event': event } + values = { 'event': event, 'main_object': event } return request.website.render("website_event_track.event_home", values) @website.route(['/event//track_proposal/'], type='http', auth="public", multilang=True) diff --git a/addons/website_event_track/models/event.py b/addons/website_event_track/models/event.py index 009e12308da..99376fe913e 100644 --- a/addons/website_event_track/models/event.py +++ b/addons/website_event_track/models/event.py @@ -59,7 +59,7 @@ class event_track_location(osv.osv): class event_track(osv.osv): _name = "event.track" _order = 'date' - _inherit = ['mail.thread', 'ir.needaction_mixin'] + _inherit = ['mail.thread', 'ir.needaction_mixin', 'website.seo.metadata'] _columns = { 'name': fields.char('Track Title', required=True), 'user_id': fields.many2one('res.users', 'Responsible'), diff --git a/addons/website_hr_recruitment/controllers/main.py b/addons/website_hr_recruitment/controllers/main.py index f1d5fc81916..42d9fbbc2d0 100644 --- a/addons/website_hr_recruitment/controllers/main.py +++ b/addons/website_hr_recruitment/controllers/main.py @@ -49,7 +49,7 @@ class website_hr_recruitment(http.Controller): @website.route(['/job/detail/'], type='http', auth="public", multilang=True) def detail(self, job, **kwargs): - return request.website.render("website_hr_recruitment.detail", {'job': job}) + return request.website.render("website_hr_recruitment.detail", { 'job': job, 'main_object': job }) @website.route(['/job/success'], methods=['POST'], type='http', auth="admin", multilang=True) def success(self, **post): diff --git a/addons/website_hr_recruitment/models/hr_job.py b/addons/website_hr_recruitment/models/hr_job.py index d2624231fc7..0984c9d40eb 100644 --- a/addons/website_hr_recruitment/models/hr_job.py +++ b/addons/website_hr_recruitment/models/hr_job.py @@ -5,7 +5,8 @@ from openerp.osv import osv, fields class hr_job(osv.osv): """ Override to add website-related columns: published, description. """ - _inherit = "hr.job" + _name = 'hr.job' + _inherit = ['hr.job','website.seo.metadata'] def _website_url(self, cr, uid, ids, field_name, arg, context=None): res = dict.fromkeys(ids, '') diff --git a/addons/website_membership/controllers/main.py b/addons/website_membership/controllers/main.py index feab461f6c3..6985d4449f2 100644 --- a/addons/website_membership/controllers/main.py +++ b/addons/website_membership/controllers/main.py @@ -87,4 +87,5 @@ class WebsiteMembership(http.Controller): values = website_partner.get_partner_template_value(partner) if not values: return self.members(**post) + values['main_object'] = values['partner'] return request.website.render("website_membership.partner", values) diff --git a/addons/website_partner/models/res_partner.py b/addons/website_partner/models/res_partner.py index c5d7539edca..aa9a7cc02a3 100644 --- a/addons/website_partner/models/res_partner.py +++ b/addons/website_partner/models/res_partner.py @@ -4,7 +4,8 @@ from openerp.osv import osv, fields class WebsiteResPartner(osv.Model): - _inherit = 'res.partner' + _name = 'res.partner' + _inherit = ['res.partner','website.seo.metadata'] _columns = { 'website_published': fields.boolean(