diff options
| author | Christophe Simonis <chs@openerp.com> | 2014-02-20 17:38:15 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@openerp.com> | 2014-02-20 17:38:15 +0100 |
| commit | 4b72678bc74906e552ebc8cace7161901571d2c1 (patch) | |
| tree | d4965fd90f45af167c6a34eec3caad111a309f12 /addons/website/static/src/js | |
| parent | 65db3c635eea5324676c8f85d13e0058d66ce1b9 (diff) | |
| parent | d5106a4d34a9b7c52a1ecad7c65331f1fda2e231 (diff) | |
[MERGE] forward port of branch saas-2 up to revid 9195 chs@openerp.com-20140220154517-6y531n1mqtnfnsmr
bzr revid: chs@openerp.com-20140220163815-69sza1kclnh5mavs
Diffstat (limited to 'addons/website/static/src/js')
| -rw-r--r-- | addons/website/static/src/js/website.ace.js | 91 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.editor.js | 6 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.editor.newpage.js | 34 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.js | 13 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.snippets.animation.js | 2 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.snippets.editor.js | 96 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.tour.banner.js | 3 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.tour.js | 8 |
8 files changed, 188 insertions, 65 deletions
diff --git a/addons/website/static/src/js/website.ace.js b/addons/website/static/src/js/website.ace.js index 514969fc4c2..ed7037e903c 100644 --- a/addons/website/static/src/js/website.ace.js +++ b/addons/website/static/src/js/website.ace.js @@ -41,12 +41,14 @@ isWellFormed: function () { if (document.implementation.createDocument) { var dom = new DOMParser().parseFromString(this.xml, "text/xml"); - return dom.getElementsByTagName("parsererror").length === 0; + var error = dom.getElementsByTagName("parsererror"); + return error.length === 0 || error; } else if (window.ActiveXObject) { // TODO test in IE var msDom = new ActiveXObject("Microsoft.XMLDOM"); msDom.async = false; - return !msDom.loadXML(this.xml); + msDom.loadXML(this.xml); + return !msDom.parseError.errorCode || msDom.parseError.reason + "\nline " + msDom.parseError.line; } return true; }, @@ -256,28 +258,35 @@ }), function (session) { return session.isDirty; }); - var requests = _.map(toSave, self.saveView); + this.clearError(); + var requests = _.map(toSave, function (session) { + return self.saveView(session); + }); $.when.apply($, requests).then(function () { self.reloadPage.call(self); - }).fail(function (source, error) { - var message = _.isString(error) ? error - : (error && error.data && error.data.arguments && error.data.arguments[0] === "Access Denied") ? "Access denied: please sign in" - : (error && error.message) ? error.message - : "Unexpected error"; - self.displayError.call(self, message); + }).fail(function (source, session, error) { + self.displayError.call(self, source, session, error); }); }, saveView: function (session) { + var self = this; var xml = new website.ace.XmlDocument(session.text); - if (xml.isWellFormed()) { - return openerp.jsonRpc('/web/dataset/call', 'call', { + var isWellFormed = xml.isWellFormed(); + var def = $.Deferred(); + if (isWellFormed === true) { + openerp.jsonRpc('/web/dataset/call', 'call', { model: 'ir.ui.view', method: 'write', args: [[session.id], { 'arch': xml.xml }, website.get_context()], + }).then(function () { + def.resolve(); + }).fail(function (source, error) { + def.reject("server", session, error); }); } else { - return $.Deferred().reject(null, "Malformed XML document"); + def.reject(null, session, $(isWellFormed).text()); } + return def; }, updateHash: function () { window.location.hash = hash + "?view=" + this.selectedViewId(); @@ -286,9 +295,61 @@ this.updateHash(); window.location.reload(); }, - displayError: function (error) { - // TODO Improve feedback (e.g. update 'Save' button + tooltip) - alert(error); + clearError: function () { + this.$(".ace_layer.ace_text-layer .ace_line").css("background", ""); + }, + displayError: function (source, session, error) { + var self = this; + var line, test; + // format error message + var message = _.isString(error) ? error + : (error && error.data && error.data.arguments && error.data.arguments[0] === "Access Denied") ? "Access denied: please sign in" + : (error && error.data && error.data.message) ? error.data.message + : (error && error.message) ? error.message + : "Unexpected error"; + if (source == "server") { + message = eval(message.replace(/^\(/g, '([') + .replace(/\)$/g, '])') + .replace(/u'/g, "'") + .replace(/<([^>]+)>/g, '<b style="color:#661100;"><\$1></b>'))[1]; + line = -1; + } else { + line = message.match(/line ([0-9]+)/i); + line = line ? parseInt(line[1],10) : -1; + test = new RegExp("^\\s*"+line+"\\s*$"); + } + + function gotoline() { + self.aceEditor.gotoLine(line); + setTimeout(function () { + var $lines = self.$(".ace_editor .ace_gutter .ace_gutter-cell"); + var index = $lines.filter(function () { + return test.test($(this).text()); + }).index(); + if (index>0) { + self.$(".ace_layer.ace_text-layer .ace_line:eq(" + index + ")").css("background", "#661100"); + } + },100); + } + function onchangeSession (e) { + self.aceEditor.off('changeSession', onchangeSession); + gotoline(); + } + + var $list = this.$("#ace-view-list"); + if (+$list.val() == session.id) { + if (line>-1) gotoline(); + } else { + if (line) self.aceEditor.on('changeSession', onchangeSession); + this.$("#ace-view-list").val(session.id).change(); + } + + var $dialog = $(openerp.qweb.render('website.error_dialog', { + title: session.text.match(/\s+name=['"]([^'"]+)['"]/i)[1], + message:"<b>Malformed XML document</b>:<br/>" + message + })); + $dialog.appendTo("body"); + $dialog.modal('show'); }, open: function () { this.$el.removeClass('oe_ace_closed').addClass('oe_ace_open'); diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index 7e867dca685..dc82c0c17b9 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -994,6 +994,7 @@ start: function () { var sup = this._super(); this.$el.modal({backdrop: 'static'}); + this.$('input:first').focus(); return sup; }, save: function () { @@ -1033,10 +1034,13 @@ }, start: function () { var self = this; + var last; this.$('#link-page').select2({ minimumInputLength: 1, placeholder: _t("New or existing page"), query: function (q) { + if (q.term == last) return; + last = q.term; $.when( self.page_exists(q.term), self.fetch_pages(q.term) @@ -1667,6 +1671,8 @@ } switch(m.type) { case 'attributes': // ignore .cke_focus being added or removed + // ignore id modification + if (m.attributeName === 'id') { return false; } // if attribute is not a class, can't be .cke_focus change if (m.attributeName !== 'class') { return true; } diff --git a/addons/website/static/src/js/website.editor.newpage.js b/addons/website/static/src/js/website.editor.newpage.js index 8d3b3e9b6b5..b475223ecd9 100644 --- a/addons/website/static/src/js/website.editor.newpage.js +++ b/addons/website/static/src/js/website.editor.newpage.js @@ -13,16 +13,44 @@ this.$(".oe_content_menu li.divider").removeClass("hidden"); return res; }, + edit: function () { + this.on('rte:ready', this, function () { + $('a:has(span[data-oe-model="website.menu"])').tooltip({ + title: _t('Save this page and use the top "Content" menu to edit the menu.'), + placement: "bottom", + trigger: "hover", + show: 50, + hide: 100, + container: 'body' + }); + }); + return this._super(); + }, events: _.extend({}, website.EditorBar.prototype.events, { 'click a[data-action=new_page]': function (ev) { ev.preventDefault(); website.prompt({ id: "editor_new_page", window_title: _t("New Page"), - input: "Page Title", - }).then(function (val) { + input: _t("Page Title"), + init: function () { + var $group = this.$dialog.find("div.form-group"); + $group.removeClass("mb0"); + + var $add = $( + '<div class="form-group mb0">'+ + '<label class="col-sm-offset-3 col-sm-9 text-left">'+ + ' <input type="checkbox" checked="checked" required="required"/> '+ + '</label>'+ + '</div>'); + $add.find('label').append(_t("Add page in menu")); + $group.after($add); + } + }).then(function (val, field, $dialog) { if (val) { - document.location = '/website/add/' + encodeURI(val); + var url = '/website/add/' + encodeURI(val); + if ($dialog.find('input[type="checkbox"]').is(':checked')) url +="?add_menu=1"; + document.location = url; } }); } diff --git a/addons/website/static/src/js/website.js b/addons/website/static/src/js/website.js index 6fde9495d36..671dfc14ee9 100644 --- a/addons/website/static/src/js/website.js +++ b/addons/website/static/src/js/website.js @@ -206,6 +206,7 @@ var def = $.Deferred(); var dialog = $(openerp.qweb.render('website.prompt', options)).appendTo("body"); + options.$dialog = dialog; var field = dialog.find(options.field_type).first(); field.val(options.default); field.fillWith = function (data) { @@ -226,7 +227,7 @@ dialog.modal('show'); field.focus(); dialog.on('click', '.btn-primary', function () { - def.resolve(field.val(), field); + def.resolve(field.val(), field, dialog); dialog.remove(); }); }); @@ -247,13 +248,13 @@ website.form = function (url, method, params) { var form = document.createElement('form'); - form.action = url; - form.method = method; + form.setAttribute('action', url); + form.setAttribute('method', method); _.each(params, function (v, k) { var param = document.createElement('input'); - param.type = 'hidden'; - param.name = k; - param.value = v; + param.setAttribute('type', 'hidden'); + param.setAttribute('name', k); + param.setAttribute('value', v); form.appendChild(param); }); document.body.appendChild(form); diff --git a/addons/website/static/src/js/website.snippets.animation.js b/addons/website/static/src/js/website.snippets.animation.js index 048cf20231f..bc2ea064731 100644 --- a/addons/website/static/src/js/website.snippets.animation.js +++ b/addons/website/static/src/js/website.snippets.animation.js @@ -2,7 +2,7 @@ 'use strict'; var website = openerp.website; - website.snippet = {}; + if (!website.snippet) website.snippet = {}; website.snippet.readyAnimation = []; website.snippet.start_animation = function () { diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index e45bee9685b..23c5956ebf4 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -79,6 +79,7 @@ // 'snippet-dropped' is triggered on '#oe_snippets' whith $target as attribute when a snippet is dropped // 'snippet-activated' is triggered on '#oe_snippets' (and on snippet) when a snippet is activated + if (!website.snippet) website.snippet = {}; website.snippet.styles = {}; website.snippet.selector = []; website.snippet.BuildingBlock = openerp.Widget.extend({ @@ -139,9 +140,6 @@ this.$el.addClass("hidden"); - this.$modal = $(openerp.qweb.render('website.snippets_modal')); - this.$modal.appendTo("body"); - $(document).on('click', '.dropdown-submenu a[tabindex]', function (e) { e.preventDefault(); }); @@ -375,7 +373,7 @@ }); }, stop: function(ev, ui){ - if (action === 'insert' && ! dropped && $('.oe_drop_zone') && ui.position.top > 50) { + if (action === 'insert' && ! dropped && $('.oe_drop_zone') && ui.position.top > 3) { var el = $('.oe_drop_zone').nearest({x: ui.position.left, y: ui.position.top}).first(); if (el.length) { el.after($toInsert); @@ -392,7 +390,7 @@ website.snippet.start_animation(); self.create_overlay($target); - if ($snippet.data("snippet-editor")) { + if ($target.data("snippet-editor")) { $target.data("snippet-editor").drop_and_build_snippet($target); } @@ -439,9 +437,6 @@ },0); } else { $toInsert.remove(); - if (self.$modal.find('input:not(:checked)').length) { - self.$modal.modal('toggle'); - } } }, }); @@ -1126,6 +1121,38 @@ return this.grid; }, + onFocus : function () { + this._super(); + this.change_cursor(); + }, + + change_cursor : function () { + var _class = this.$target.attr("class") || ""; + + var col = _class.match(/col-md-([0-9-]+)/i); + col = col ? +col[1] : 0; + + var offset = _class.match(/col-md-offset-([0-9-]+)/i); + offset = offset ? +offset[1] : 0; + + var overlay_class = this.$overlay.attr("class").replace(/(^|\s+)block-[^\s]*/gi, ''); + if (col+offset >= 12) overlay_class+= " block-e-right"; + if (col === 1) overlay_class+= " block-w-right block-e-left"; + if (offset === 0) overlay_class+= " block-w-left"; + + var mb = _class.match(/mb([0-9-]+)/i); + mb = mb ? +mb[1] : 0; + if (mb >= 128) overlay_class+= " block-s-bottom"; + else if (!mb) overlay_class+= " block-s-top"; + + var mt = _class.match(/mt([0-9-]+)/i); + mt = mt ? +mt[1] : 0; + if (mt >= 128) overlay_class+= " block-n-top"; + else if (!mt) overlay_class+= " block-n-bottom"; + + this.$overlay.attr("class", overlay_class); + }, + /* on_resize * called when the box is resizing and the class change, before the cover_target * @compass: resize direction : 'n', 's', 'e', 'w' @@ -1133,7 +1160,7 @@ * @current: curent increment in this.grid */ on_resize: function (compass, beginClass, current) { - + this.change_cursor(); } }); @@ -1212,27 +1239,27 @@ return false; }, on_resize: function (compass, beginClass, current) { - if (compass !== 'w') - return; - - // don't change the right border position when we change the offset (replace col size) - var beginCol = Number(beginClass.match(/col-md-([0-9]+)|$/)[1] || 0); - var beginOffset = Number(beginClass.match(/col-md-offset-([0-9-]+)|$/)[1] || beginClass.match(/col-lg-offset-([0-9-]+)|$/)[1] || 0); - var offset = Number(this.grid.w[0][current].match(/col-md-offset-([0-9-]+)|$/)[1] || 0); - if (offset < 0) { - offset = 0; - } - var colSize = beginCol - (offset - beginOffset); - if (colSize <= 0) { - colSize = 1; - offset = beginOffset + beginCol - 1; - } - this.$target.attr("class",this.$target.attr("class").replace(/\s*(col-lg-offset-|col-md-offset-|col-md-)([0-9-]+)/g, '')); + if (compass === 'w') { + // don't change the right border position when we change the offset (replace col size) + var beginCol = Number(beginClass.match(/col-md-([0-9]+)|$/)[1] || 0); + var beginOffset = Number(beginClass.match(/col-md-offset-([0-9-]+)|$/)[1] || beginClass.match(/col-lg-offset-([0-9-]+)|$/)[1] || 0); + var offset = Number(this.grid.w[0][current].match(/col-md-offset-([0-9-]+)|$/)[1] || 0); + if (offset < 0) { + offset = 0; + } + var colSize = beginCol - (offset - beginOffset); + if (colSize <= 0) { + colSize = 1; + offset = beginOffset + beginCol - 1; + } + this.$target.attr("class",this.$target.attr("class").replace(/\s*(col-lg-offset-|col-md-offset-|col-md-)([0-9-]+)/g, '')); - this.$target.addClass('col-md-' + (colSize > 12 ? 12 : colSize)); - if (offset > 0) { - this.$target.addClass('col-md-offset-' + offset); + this.$target.addClass('col-md-' + (colSize > 12 ? 12 : colSize)); + if (offset > 0) { + this.$target.addClass('col-md-offset-' + offset); + } } + this._super(compass, beginClass, current); }, }); @@ -1254,8 +1281,6 @@ this.$target.attr('contentEditable', 'false'); this.$target.find('.oe_structure, .content>.row').attr('contentEditable', 'true'); - - this.$target.carousel('pause'); }, clean_for_save: function () { this._super(); @@ -1264,14 +1289,6 @@ this.$target.find(".item:first").addClass("active"); } }, - onFocus: function () { - this._super(); - this.$target.carousel('pause'); - }, - onBlur: function () { - this._super(); - this.$target.carousel('cycle'); - }, start : function () { var self = this; this._super(); @@ -1282,6 +1299,7 @@ this.$editor.find(".js_add").on('click', function () {self.on_add_slide(); return false;}); this.$editor.find(".js_remove").on('click', function () {self.on_remove_slide(); return false;}); + this.$target.carousel('pause'); this.rebind_event(); }, on_add_slide: function () { @@ -1401,7 +1419,7 @@ this.$target.find('.carousel-control').off('click').on('click', function () { self.$target.carousel( $(this).data('slide')); }); - this.$target.find('.carousel-image, .content').attr('contentEditable', 'true'); + this.$target.find('.carousel-inner .content > div').attr('contentEditable', 'true'); this.$target.find('.carousel-image').attr('attributeEditable', 'true'); this._super(); }, diff --git a/addons/website/static/src/js/website.tour.banner.js b/addons/website/static/src/js/website.tour.banner.js index 7d307bd26d7..53489b1737c 100644 --- a/addons/website/static/src/js/website.tour.banner.js +++ b/addons/website/static/src/js/website.tour.banner.js @@ -100,8 +100,9 @@ { element: '.modal:has(#mobile-viewport) button[data-dismiss=modal]', placement: 'right', - title: _t("Close Mobile Preview"), + title: _t("Check Mobile Preview"), content: _t("Scroll in the mobile preview to test the rendering. Once it's ok, close this dialog."), + popover: { next: _t("Continue") }, }, { waitNot: '.modal', diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index f1d5ab79228..2416cb511f1 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -281,6 +281,14 @@ website.Tour = openerp.Class.extend({ self.nextStep(step.stepId, callback, overlaps); }, self.defaultDelay); } else if (!overlaps || new Date().getTime() - time < overlaps) { + if (self.current.element) { + var $popover = $(".popover.tour"); + if(!$(self.current.element).is(":visible")) { + $popover.data("hide", true).fadeOut(300); + } else if($popover.data("hide")) { + $popover.data("hide", false).fadeIn(150); + } + } self.timer = setTimeout(checkNext, self.defaultDelay); } else { self.reset(); |
