From 876b61f42c3cd1bd446af3ef5e9d266036a58c15 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 29 Jan 2014 17:08:39 +0100 Subject: [PATCH] [FIX] website: test tour and website_sale tour. Add ajax trigger to display popover when the ajax is complete and hmlt is loaded bzr revid: chm@openerp.com-20140129160839-ijdcnuiny6ys8z6p --- addons/website/controllers/main.py | 2 +- addons/website/static/src/js/website.tour.js | 164 +++++++++++------- .../static/src/js/website.tour.event.js | 8 +- addons/website_project/controllers/main.py | 6 +- .../website_project/views/website_project.xml | 4 +- .../static/src/js/website.tour.shop.js | 76 ++++---- 6 files changed, 162 insertions(+), 98 deletions(-) diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index 9befae01931..8f26dfaf663 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -55,7 +55,7 @@ class Website(openerp.addons.web.controllers.main.Home): return werkzeug.wrappers.Response(url, mimetype='text/plain') return werkzeug.utils.redirect(url) - @http.route('/website/theme_change', type='http', auth="public", website=True) + @http.route('/website/theme_change', type='http', auth="user", website=True) def theme_change(self, theme_id=False, **kwargs): imd = request.registry['ir.model.data'] view = request.registry['ir.ui.view'] diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index 5453c68c866..322bcc1545c 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -21,6 +21,7 @@ }, registerStep: function (step) { var self = this; + step.tour = self; step.title = openerp.qweb.render('website.tour_popover_title', { title: step.title }); if (!step.element) { step.orphan = true; @@ -37,15 +38,21 @@ }; } else if (step.trigger === 'reload') { step.triggers = function (callback) { - var stack = JSON.parse(localStorage.getItem("website-reloads")) || []; + var stack = JSON.parse(step.tour.tourStorage.getItem("website-reloads")) || []; var index = stack.indexOf(step.stepId); if (index !== -1) { - stack.splice(index,1); - (callback || self.moveToNextStep).apply(self); + setTimeout(function () { + $(step.element).popover("destroy"); + setTimeout(function () { + stack.splice(index,1); + (callback || self.moveToNextStep).apply(self); + step.tour.tourStorage.setItem("website-reloads", JSON.stringify(stack)); + },10); + },0); } else { stack.push(step.stepId); + step.tour.tourStorage.setItem("website-reloads", JSON.stringify(stack)); } - localStorage.setItem("website-reloads", JSON.stringify(stack)); }; } else if (step.trigger === 'drag') { step.triggers = function (callback) { @@ -70,7 +77,7 @@ } } else if (step.trigger.url) { step.triggers = function (callback) { - var stack = JSON.parse(localStorage.getItem("website-geturls")) || []; + var stack = JSON.parse(step.tour.tourStorage.getItem("website-geturls")) || []; var id = step.trigger.url.toString(); var index = stack.indexOf(id); if (index !== -1) { @@ -79,12 +86,18 @@ step.trigger.url == url.pathname+url.search : step.trigger.url.test(url.pathname+url.search); if (!test) return; - stack.splice(index,1); - (callback || self.moveToNextStep).apply(self); + setTimeout(function () { + $(step.element).popover("destroy"); + setTimeout(function () { + stack.splice(index,1); + (callback || self.moveToNextStep).apply(self); + step.tour.tourStorage.setItem("website-geturls", JSON.stringify(stack)); + },10); + },0); } else { stack.push(id); + step.tour.tourStorage.setItem("website-geturls", JSON.stringify(stack)); } - localStorage.setItem("website-geturls", JSON.stringify(stack)); return index !== -1; }; } else if (step.trigger.modal) { @@ -99,7 +112,6 @@ $doc.one('shown.bs.modal', function () { $('.modal button.btn-primary').one('click', function () { $doc.off('hide.bs.modal', onStop); - console.log(callback); if (!callback) { self.moveToStep(step.trigger.modal.afterSubmit); } @@ -107,6 +119,30 @@ (callback || self.moveToNextStep).apply(self); }); }; + } else if (step.trigger === 'ajax') { + step.triggers = function (callback) { + $( document ).ajaxSuccess(function(event, xhr, settings) { + $( document ).unbind('ajaxSuccess'); + xhr.then(function () { + setTimeout(function () { + $(step.element).popover("destroy"); + setTimeout(function () { + (callback || self.moveToNextStep).apply(self); + },10); + },0); + }); + }); + }; + } else { + step.triggers = function (callback) { + var emitter = $(step.element); + if (!emitter.size()) throw "Emitter is undefined"; + var trigger = function () { + emitter.off(step.trigger, trigger); + (callback || self.moveToNextStep).apply(self, arguments); + }; + emitter.on(step.trigger, trigger); + }; } } step.onShow = (function () { @@ -130,10 +166,15 @@ reset: function () { this.tourStorage.removeItem(this.id+'_current_step'); this.tourStorage.removeItem(this.id+'_end'); + this.tourStorage.removeItem("website-reloads"); + this.tourStorage.removeItem("website-geturls"); this.tour._current = 0; $('.popover.tour').remove(); }, start: function () { + window.Tour.prototype._isOrphan = function(step) { + return (step.element == null) || !$(step.element).length; + }; if (this.resume() || ((this.currentStepIndex() === 0) && !this.tour.ended())) { this.tour.start(); } @@ -160,12 +201,8 @@ this.stop(); } else if (index >= 0) { var self = this; - setTimeout(function () { - $('.popover.tour').remove(); - setTimeout(function () { - self.tour.goto(index); - }, 0); - }, 0); + $('.popover.tour').remove(); + self.tour.goto(index); } }, moveToNextStep: function () { @@ -319,13 +356,16 @@ _.each(this.tours, function (tour) { var $menuItem = $($.parseHTML('
  • '+tour.name+'
  • ')); $menuItem.click(function () { - tour.redirect(new website.UrlParser(window.location.href)); tour.reset(); - tour.start(); + tour.redirect(new website.UrlParser(window.location.href)); }); menu.append($menuItem); if (tour.trigger()) { - tour.start(); + setTimeout(function () { + setTimeout(function () { + tour.start(); + },100); + },0); } }); return this._super(); @@ -335,63 +375,63 @@ var testId = 'test_'+tour.id+'_tour'; this.tours.push(tour); var defaultDelay = 250; //ms - var defaultDelayReload = 1500; //ms var overlapsCrash; var test = { id: tour.id, run: function (force) { if (force === true) { this.reset(); + tour.reset(); } var actionSteps = _.filter(tour.steps, function (step) { - return step.trigger || step.sampleText; + return step.trigger || step.triggers || step.sampleText; }); window.onbeforeunload = function () { clearTimeout(overlapsCrash); }; function throwError (message) { - console.log(window.localStorage.getItem("test-report")); + console.log(tour.tourStorage.getItem("test-report")); test.reset(); + tour.reset(); throw message; } function initReport () { // set last time for report - if (!window.localStorage.getItem("test-last-time")) { - window.localStorage.setItem("test-last-time", new Date().getTime()); + if (!tour.tourStorage.getItem("test-last-time")) { + tour.tourStorage.setItem("test-last-time", new Date().getTime()); } } function setReport (step) { - var report = JSON.parse(window.localStorage.getItem("test-report")) || {}; - report[step.stepId] = (new Date().getTime() - window.localStorage.getItem("test-last-time")) + " ms"; - window.localStorage.setItem("test-report", JSON.stringify(report)); + var report = JSON.parse(tour.tourStorage.getItem("test-report")) || {}; + report[step.stepId] = (new Date().getTime() - tour.tourStorage.getItem("test-last-time")) + " ms"; + tour.tourStorage.setItem("test-report", JSON.stringify(report)); } function testCycling (step) { - var lastStep = window.localStorage.getItem(testId); - var tryStep = lastStep != step.stepId ? 0 : (+(window.localStorage.getItem("test-last-"+testId) || 0) + 1); - window.localStorage.setItem("test-last-"+testId, tryStep); + var lastStep = tour.tourStorage.getItem(testId); + var tryStep = lastStep != step.stepId ? 0 : (+(tour.tourStorage.getItem("test-last-"+testId) || 0) + 1); + tour.tourStorage.setItem("test-last-"+testId, tryStep); if (tryStep > 2) { throwError("Test: '" + testId + "' cycling step: '" + step.stepId + "'"); } return tryStep; } function getDelay (step) { - return step.delay || - ((step.trigger === 'reload' || (step.trigger && step.trigger.url)) - ? defaultDelayReload - : defaultDelay); + return step.delay || defaultDelay; } function executeStep (step) { if (testCycling(step) === 0) initReport(); + tour.tourStorage.setItem(testId, step.stepId); + var delay = getDelay (step); overlapsCrash = setTimeout(function () { throwError("Test: '" + testId + "' can't resolve step: '" + step.stepId + "'"); - }, delay + 1000); + }, delay + 3000); var _next = false; - window.localStorage.setItem(testId, step.stepId); + tour.tourStorage.setItem(testId, step.stepId); function next () { _next = true; clearTimeout(overlapsCrash); @@ -401,16 +441,15 @@ var nextStep = actionSteps.shift(); if (nextStep) { - setTimeout(function () { - executeStep(nextStep); - }, delay); + executeStep(nextStep); } else { - window.localStorage.removeItem(testId); + tour.tourStorage.removeItem(testId); } } setTimeout(function () { var $element = $(step.element); + var flag = step.triggers && (!step.trigger || !step.trigger.modal); if (flag) { try { @@ -420,34 +459,41 @@ } } if ((step.trigger === 'reload' || (step.trigger && step.trigger.url)) && _next) return; - + if (step.snippet && step.trigger === 'drag') { website.TestConsole.dragAndDropSnippet(step.snippet); } else if (step.trigger && step.trigger.id === 'change') { $element.trigger($.Event("change", { srcElement: $element })); } else if (step.sampleText) { - $element.val(step.sampleText); - $element.trigger($.Event("change", { srcElement: $element })); - } else if ($element.is(":visible")) { // Click by default - if (step.trigger.id === 'mousedown') { - $element.trigger($.Event("mousedown", { srcElement: $element })); + $element.trigger($.Event("keydown", { srcElement: $element })); + if ($element.is("select") || $element.is("input") ) { + $element.val(step.sampleText); + } else { + $element.html(step.sampleText); } + $element.trigger($.Event("change", { srcElement: $element })); + $element.trigger($.Event("keyup", { srcElement: $element })); + } else if ($element.is(":visible")) { // Click by default + $element.trigger($.Event("mouseenter", { srcElement: $element })); + $element.trigger($.Event("mousedown", { srcElement: $element })); var evt = document.createEvent("MouseEvents"); evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); $element[0].dispatchEvent(evt); - if (step.trigger.id === 'mouseup') { - $element.trigger($.Event("mouseup", { srcElement: $element })); - } + $element.trigger($.Event("mouseup", { srcElement: $element })); + $element.trigger($.Event("mouseleave", { srcElement: $element })); + + // trigger after for step like: mouseenter, next step click on button display with mouseenter + $element.trigger($.Event("mouseenter", { srcElement: $element })); } if (!flag) next(); - },0); + },delay); } var url = new website.UrlParser(window.location.href); - if (tour.path && url.pathname !== tour.path && !window.localStorage.getItem(testId)) { - window.localStorage.setItem(testId, actionSteps[0].stepId); + if (tour.path && url.pathname !== tour.path && !tour.tourStorage.getItem(testId)) { + tour.tourStorage.setItem(testId, actionSteps[0].stepId); window.location.href = tour.path; } else { - var lastStepId = window.localStorage.getItem(testId); + var lastStepId = tour.tourStorage.getItem(testId); var currentStep = actionSteps.shift(); if (lastStepId) { while (currentStep && lastStepId !== currentStep.stepId) { @@ -459,16 +505,18 @@ executeStep(currentStep); }); } else { - executeStep(currentStep); + setTimeout(function () { + executeStep(currentStep); + }, 500); } } }, reset: function () { - window.localStorage.removeItem(testId); - window.localStorage.removeItem("test-report"); - for (var k in window.localStorage) { - if (window.localStorage[k].indexOf("test-last")) { - window.localStorage.removeItem(k); + tour.tourStorage.removeItem(testId); + tour.tourStorage.removeItem("test-report"); + for (var k in tour.tourStorage) { + if (tour.tourStorage[k].indexOf("test-last")) { + tour.tourStorage.removeItem(k); } } }, diff --git a/addons/website_event/static/src/js/website.tour.event.js b/addons/website_event/static/src/js/website.tour.event.js index 8bae9f8b560..29f14cc2d7a 100644 --- a/addons/website_event/static/src/js/website.tour.event.js +++ b/addons/website_event/static/src/js/website.tour.event.js @@ -42,7 +42,6 @@ trigger: { modal: { stopOnClose: true, - afterSubmit: 'event-page', }, }, }, @@ -53,6 +52,7 @@ placement: 'right', title: "Create an Event Name", content: "Create a name for your new event and click 'Continue'. e.g: Technical Training", + trigger: 'keyup', }, { stepId: 'continue-name', @@ -60,9 +60,7 @@ placement: 'right', title: "Create Event", content: "Click Continue to create the event.", - trigger: { - url: /event\/[0-9]+\/register/ - }, + trigger: 'reload', }, { stepId: 'event-page', @@ -139,7 +137,7 @@ placement: 'top', title: "Publish your event", content: "Click to publish your event.", - trigger: 'click', + trigger: 'ajax' }, { stepId: 'customize-event', diff --git a/addons/website_project/controllers/main.py b/addons/website_project/controllers/main.py index 17a91bed21b..4940a521072 100644 --- a/addons/website_project/controllers/main.py +++ b/addons/website_project/controllers/main.py @@ -31,9 +31,11 @@ class Website(osv.Model): project_obj = request.registry['project.project'] project_ids = project_obj.search(cr, uid, [('privacy_visibility', "=", "public")], context=request.context) - request.context['website_project_ids'] = project_obj.browse(cr, uid, project_ids, request.context) + request.context.update({ + 'website_project_ids': project_obj.browse(cr, uid, project_ids, context=request.context) + }) - return super(Website, self).preprocess_request(cr, uid, ids, request, context) + return super(Website, self).preprocess_request(cr, uid, ids, request, context=None) class website_project(http.Controller): diff --git a/addons/website_project/views/website_project.xml b/addons/website_project/views/website_project.xml index bd3ee9375c6..514194083f2 100644 --- a/addons/website_project/views/website_project.xml +++ b/addons/website_project/views/website_project.xml @@ -5,7 +5,9 @@ diff --git a/addons/website_sale/static/src/js/website.tour.shop.js b/addons/website_sale/static/src/js/website.tour.shop.js index 7a8012738a8..0f03ff4e22a 100644 --- a/addons/website_sale/static/src/js/website.tour.shop.js +++ b/addons/website_sale/static/src/js/website.tour.shop.js @@ -44,27 +44,36 @@ trigger: { modal: { stopOnClose: true, - afterSubmit: 'product-page', }, }, }, { stepId: 'enter-name', element: '.modal input[type=text]', + sampleText: 'New Product', placement: 'right', title: "Choose name", content: "Enter a name for your new product then click 'Continue'.", + trigger: 'keyup', + }, + { + stepId: 'continue-name', + element: '.modal button.btn-primary', + placement: 'right', + title: "Create Product", + content: "Click Continue to create the product.", + trigger: 'reload', }, { stepId: 'product-page', title: "New product created", content: "This page contains all the information related to the new product.", template: self.popover({ next: "OK" }), - backdrop: true, }, { - stepId: 'edit-price', - element: '.product_price', + stepId: 'edit-price-cke', + element: '.product_price .oe_currency_value', + sampleText: '20.50', placement: 'left', title: "Change the price", content: "Edit the price of this product by clicking on the amount.", @@ -76,17 +85,24 @@ placement: 'top', title: "Update image", content: "Click here to set an image describing your product.", - triggers: function () { - function registerClick () { - $('button.hover-edition-button').one('click', function () { - $('#wrap img.img:first').off('hover', registerClick); - self.moveToNextStep(); - }); - } - $('#wrap img.img:first').on('hover', registerClick); - + triggers: function (callback) { + var self = this; + $(self.element).on('mouseenter', function () { + $(this).off('mouseenter'); + setTimeout(function () { + (callback || self.tour.moveToNextStep).apply(self.tour); + },0); + }); }, }, + { + stepId: 'update-image-button', + element: 'button.hover-edition-button:visible', + placement: 'top', + title: "Update image", + content: "Click here to set an image describing your product.", + trigger: 'click', + }, { stepId: 'upload-image', element: '.well a.pull-right', @@ -94,7 +110,7 @@ title: "Select an Image", content: "Let's select an existing image.", template: self.popover({ fixed: true }), - trigger: 'click', + trigger: 'ajax' }, { stepId: 'select-image', @@ -103,7 +119,16 @@ title: "Select an Image", content: "Let's select an imac image.", template: self.popover({ fixed: true }), - trigger: 'click', + triggers: function (callback) { + var self = this; + var click = function () { + $('.modal-dialog.select-image img').off('click', click); + setTimeout(function () { + (callback || self.tour.moveToNextStep).apply(self.tour); + },0); + }; + $('.modal-dialog.select-image img').on('click', click); + }, }, { stepId: 'save-image', @@ -139,7 +164,7 @@ title: "Save your modifications", content: "Once you click on save, your product is updated.", template: self.popover({ fixed: true }), - trigger: 'click', + trigger: 'reload', }, { @@ -148,7 +173,7 @@ placement: 'top', title: "Publish your product", content: "Click to publish your product so your customers can see it.", - trigger: 'click', + trigger: 'ajax' }, { stepId: 'congratulations', @@ -212,9 +237,7 @@ { stepId: 'choose-ipod', element: 'input[name="product_id"]:not([checked])', - trigger: { - id: 'mouseup', - }, + trigger: 'mouseup', }, { stepId: 'add-ipod', @@ -231,7 +254,7 @@ { stepId: 'more-product', element: '.oe_mycart a.js_add_cart_json:eq(1)', - trigger: 'click', + trigger: 'ajax', }, { stepId: 'less-product', @@ -241,17 +264,8 @@ { stepId: 'number-product', element: '.oe_mycart input.js_quantity', + sampleText: '1', trigger: 'reload', - beforeTrigger: function (tour) { - if (parseInt($(".oe_mycart input.js_quantity").val(),10) !== 1) - $(".oe_mycart input.js_quantity").val("1").change(); - }, - afterTrigger: function (tour) { - if ($(".oe_mycart input.js_quantity").size() !== 1) - throw "Can't remove suggested item from my cart"; - if (parseInt($(".oe_mycart input.js_quantity").val(),10) !== 1) - throw "Can't defined number of items in my cart"; - }, }, { stepId: 'go-checkout-product',