summaryrefslogtreecommitdiff
path: root/addons/website/static/src
diff options
context:
space:
mode:
authorAntony Lesuisse <al@openerp.com>2014-02-09 15:03:15 +0100
committerAntony Lesuisse <al@openerp.com>2014-02-09 15:03:15 +0100
commit87172d90d25c278a4b42db0b90a759d83b29f6cd (patch)
treef6c50386fb126d6faf7cad694dc3ec804eb97acc /addons/website/static/src
parente8aa9751b2154e72a7ed55c027543082c39bf728 (diff)
parenta3710efdb13d108887bdb9655f77fbab7742b48c (diff)
[MERGE] saas-3
bzr revid: al@openerp.com-20140209140315-ukqlf90ngy6ycu2k
Diffstat (limited to 'addons/website/static/src')
-rw-r--r--addons/website/static/src/css/common.sass44
-rw-r--r--addons/website/static/src/css/editor.css14
-rw-r--r--addons/website/static/src/css/editor.sass13
-rw-r--r--addons/website/static/src/css/website.css14
-rw-r--r--addons/website/static/src/css/website.sass14
-rw-r--r--addons/website/static/src/js/website.editor.js46
-rw-r--r--addons/website/static/src/js/website.editor.newpage.js4
-rw-r--r--addons/website/static/src/js/website.snippets.animation.js2
-rw-r--r--addons/website/static/src/js/website.snippets.editor.js21
-rw-r--r--addons/website/static/src/js/website.tests.js40
-rw-r--r--addons/website/static/src/js/website.tour.banner.js83
-rw-r--r--addons/website/static/src/js/website.tour.js184
-rw-r--r--addons/website/static/src/js/website.tour.test.admin.js106
-rw-r--r--addons/website/static/src/js/website.tour.test.js34
-rw-r--r--addons/website/static/src/xml/website.editor.xml5
-rw-r--r--addons/website/static/src/xml/website.xml2
16 files changed, 433 insertions, 193 deletions
diff --git a/addons/website/static/src/css/common.sass b/addons/website/static/src/css/common.sass
index 86e1f6655ef..4d5f0673e33 100644
--- a/addons/website/static/src/css/common.sass
+++ b/addons/website/static/src/css/common.sass
@@ -1,6 +1,7 @@
@import "compass/css3"
@import "compass/css3/user-interface"
@import "compass/css3/transition"
+@import "compass/support"
//smartphones, iPhone, portrait 480x320 phones
$smart_phone: 320px
@@ -23,3 +24,46 @@ $desktop: 1025px
@content
::selection
@content
+
+// Lifted from compass-animation
+// LICENSED UNDER THE MIT LICENSE (MIT)
+//
+// Copyright (c) 2012 Eric Meyer
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+@mixin set-experimental-support($moz: false, $webkit: false, $ms: false, $o: false, $khtml: false)
+ $experimental-support-for-mozilla: $moz
+ $experimental-support-for-webkit: $webkit
+ $experimental-support-for-microsoft: $ms
+ $experimental-support-for-opera: $o
+ $experimental-support-for-khtml: $khtml
+
+@mixin with-only-support-for($moz: false, $webkit: false, $ms: false, $o: false, $khtml: false)
+ // Capture the current state
+ $original-moz: $experimental-support-for-mozilla
+ $original-webkit: $experimental-support-for-webkit
+ $original-o: $experimental-support-for-opera
+ $original-ms: $experimental-support-for-microsoft
+ $original-khtml: $experimental-support-for-khtml
+
+ @include set-experimental-support($moz, $webkit, $ms, $o, $khtml)
+ @content
+ @include set-experimental-support($original-moz, $original-webkit, $original-ms, $original-o, $original-khtml)
+
+@mixin keyframes($name)
+ @-moz-keyframes #{$name}
+ +with-only-support-for($moz: true)
+ @content
+ @-webkit-keyframes #{$name}
+ +with-only-support-for($webkit: true)
+ @content
+ @-o-keyframes #{$name}
+ +with-only-support-for($o: true)
+ @content
+ @keyframes #{$name}
+ +with-only-support-for
+ @content
diff --git a/addons/website/static/src/css/editor.css b/addons/website/static/src/css/editor.css
index 1c54d6f47dd..4fb4496e692 100644
--- a/addons/website/static/src/css/editor.css
+++ b/addons/website/static/src/css/editor.css
@@ -195,13 +195,19 @@ ul.oe_menu_editor .disclose {
text-align: left;
}
-.modal.nosave .modal-footer button.save {
- display: none;
-}
-.modal.nosave .modal-footer button.wait {
+.modal.nosave .wait {
display: inline-block !important;
visibility: visible !important;
}
+.modal.nosave .modal-body .filepicker, .modal.nosave .modal-body .image-preview {
+ display: none;
+}
+.modal.nosave .modal-body .wait {
+ width: 100%;
+}
+.modal.nosave .modal-footer .save {
+ display: none;
+}
.modal .font-icons-icons {
font-size: 2em;
diff --git a/addons/website/static/src/css/editor.sass b/addons/website/static/src/css/editor.sass
index 3abfa4cff05..2e6513f7c1d 100644
--- a/addons/website/static/src/css/editor.sass
+++ b/addons/website/static/src/css/editor.sass
@@ -162,12 +162,17 @@ ul.oe_menu_editor
.modal-footer
text-align: left
-.modal.nosave .modal-footer
- button.save
- display: none
- button.wait
+.modal.nosave
+ .wait
display: inline-block !important
visibility: visible !important
+ .modal-body
+ .filepicker, .image-preview
+ display: none
+ .wait
+ width: 100%
+ .modal-footer .save
+ display: none
// fontawesome modal
.modal
diff --git a/addons/website/static/src/css/website.css b/addons/website/static/src/css/website.css
index 39a29be1aab..80e223eed00 100644
--- a/addons/website/static/src/css/website.css
+++ b/addons/website/static/src/css/website.css
@@ -276,12 +276,16 @@ ul.nav-stacked > li > a {
}
/* ---- SNIPPETS --- */
+.oe_img_bg {
+ background-size: 100%;
+}
+
[data-snippet-id], .colmd, .hr, .blockquote {
overflow: hidden;
}
@media (max-width: 400px) {
- [data-snippet-id] {
+ [data-snippet-id]:not([data-snippet-id="carousel"]) {
height: auto !important;
}
}
@@ -290,7 +294,7 @@ ul.nav-stacked > li > a {
}
.carousel-inner .item {
height: 100%;
- background-size: 100%;
+ background-size: cover;
}
.carousel .carousel-caption {
@@ -360,7 +364,7 @@ div.carousel[data-snippet-id="slider"] .carousel-indicators .active {
.parallax {
position: relative;
- background-size: 100%;
+ background-size: cover;
display: table;
width: 100%;
min-height: 100px;
@@ -440,10 +444,6 @@ div.carousel[data-snippet-id="slider"] .carousel-indicators .active {
}
/* Misc */
-.oe_img_bg {
- background-size: 100%;
-}
-
.texttop {
vertical-align: top;
}
diff --git a/addons/website/static/src/css/website.sass b/addons/website/static/src/css/website.sass
index 672976e31ae..cea00027315 100644
--- a/addons/website/static/src/css/website.sass
+++ b/addons/website/static/src/css/website.sass
@@ -224,19 +224,24 @@ ul.nav-stacked > li > a
a
color: white
+
/* ---- SNIPPETS --- */
+
+.oe_img_bg
+ background-size: 100%
+
[data-snippet-id],.colmd,.hr,.blockquote
overflow: hidden
@media (max-width: 400px)
- [data-snippet-id]
+ [data-snippet-id]:not([data-snippet-id="carousel"])
height: auto !important
.carousel-inner
height: 100%
.item
height: 100%
- background-size: 100%
+ background-size: cover
.carousel
.carousel-caption
left: auto
@@ -296,7 +301,7 @@ div.carousel[data-snippet-id="slider"]
.parallax
position: relative
- background-size: 100%
+ background-size: cover
display: table
width: 100%
min-height: 100px
@@ -358,9 +363,6 @@ div.carousel[data-snippet-id="slider"]
/* Misc */
-.oe_img_bg
- background-size: 100%
-
.texttop
vertical-align: top
diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js
index ab97ee2bcf9..1e8246366a9 100644
--- a/addons/website/static/src/js/website.editor.js
+++ b/addons/website/static/src/js/website.editor.js
@@ -10,6 +10,9 @@
if (!is_smartphone) {
website.ready().then(website.init_editor);
+ } else {
+ // remove padding of fake editor bar
+ document.body.style.padding = 0;
}
$(document).on('click', 'a.js_link2post', function (ev) {
@@ -411,6 +414,7 @@
openerp.jsonRpc('/website/customize_template_get', 'call', { 'xml_id': view_name }).then(
function(result) {
_.each(result, function (item) {
+ if (item.xml_id === "website.debugger" && !window.location.search.match(/[&?]debug(&|$)/)) return;
if (item.header) {
menu.append('<li class="dropdown-header">' + item.name + '</li>');
} else {
@@ -437,6 +441,12 @@
});
},
start: function() {
+ // remove placeholder editor bar
+ var fakebar = document.getElementById('website-top-navbar-placeholder');
+ if (fakebar) {
+ fakebar.parentNode.removeChild(fakebar);
+ }
+
var self = this;
this.saving_mutex = new openerp.Mutex();
@@ -1073,7 +1083,7 @@
} else {
// Create the page, get the URL back
done = $.get(_.str.sprintf(
- '/pagenew/%s?noredirect=1', encodeURI(data.id)))
+ '/website/add/%s?noredirect=1', encodeURI(data.id)))
.then(function (response) {
self.make_link(response, false, data.id);
});
@@ -1265,7 +1275,7 @@
}),
start: function () {
- this.$('.modal-footer [disabled]').text("Uploading…");
+ this.$('button.wait').text("Uploading…");
var $options = this.$('.image-style').children();
this.image_styles = $options.map(function () { return this.value; }).get();
@@ -1298,13 +1308,16 @@
* Sets the provided image url as the dialog's value-to-save and
* refreshes the preview element to use it.
*/
- set_image: function (url) {
+ set_image: function (url, error) {
+ this.$('input.url').val(
+ error ? '' : url);
this.$('input.url').val(url);
this.preview_image();
},
file_selection: function () {
this.$el.addClass('nosave');
+ this.$('form').removeClass('has-error').find('.help-block').empty();
this.$('button.filepicker').removeClass('btn-danger btn-success');
var self = this;
@@ -1319,25 +1332,38 @@
},
file_selected: function(url, error) {
var $button = this.$('button.filepicker');
- if (error) {
+ if (!error) {
+ $button.addClass('btn-success');
+ } else {
+ url = null;
+ this.$('form').addClass('has-error')
+ .find('.help-block').text(error);
$button.addClass('btn-danger');
- return;
}
- $button.addClass('btn-success');
- this.set_image(url);
+ this.set_image(url, error);
},
preview_image: function () {
- this.$el.removeClass('nosave');
+ var loaded = function () {
+ this.$el.removeClass('nosave');
+ }.bind(this);
var image = this.$('input.url').val();
- if (!image) { return; }
+ if (!image) { loaded(); return; }
- this.$('img.image-preview')
+ var $img = this.$('img.image-preview')
.attr('src', image)
.removeClass(this.image_styles.join(' '))
.addClass(this.$('select.image-style').val());
+
+ if ($img.prop('complete')) {
+ loaded();
+ } else {
+ $img.load(loaded)
+ }
},
browse_existing: function (e) {
e.preventDefault();
+ this.$('form').removeClass('has-error').find('.help-block').empty();
+ this.$('button.filepicker').removeClass('btn-danger btn-success');
new website.editor.ExistingImageDialog(this).appendTo(document.body);
},
});
diff --git a/addons/website/static/src/js/website.editor.newpage.js b/addons/website/static/src/js/website.editor.newpage.js
index 944a24b89d8..8d3b3e9b6b5 100644
--- a/addons/website/static/src/js/website.editor.newpage.js
+++ b/addons/website/static/src/js/website.editor.newpage.js
@@ -2,6 +2,7 @@
"use strict";
var website = openerp.website;
+ var _t = openerp._t;
website.is_editable = true;
website.is_editable_button = true;
@@ -16,7 +17,8 @@
'click a[data-action=new_page]': function (ev) {
ev.preventDefault();
website.prompt({
- window_title: "New Page",
+ id: "editor_new_page",
+ window_title: _t("New Page"),
input: "Page Title",
}).then(function (val) {
if (val) {
diff --git a/addons/website/static/src/js/website.snippets.animation.js b/addons/website/static/src/js/website.snippets.animation.js
index 60c5aea49e2..048cf20231f 100644
--- a/addons/website/static/src/js/website.snippets.animation.js
+++ b/addons/website/static/src/js/website.snippets.animation.js
@@ -105,7 +105,7 @@
var offset = 0;
var padding = parseInt($(document.body).css("padding-top"));
if (speed < 1) {
- var inner_offset = self.$target.outerHeight() - this.height / this.width * document.body.clientWidth;
+ var inner_offset = - self.$target.outerHeight() + this.height / this.width * document.body.clientWidth;
var outer_offset = self.$target.offset().top - (document.body.clientHeight - self.$target.outerHeight()) - padding;
offset = - outer_offset * speed + inner_offset;
} else {
diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js
index 8a3e7a4421d..e45bee9685b 100644
--- a/addons/website/static/src/js/website.snippets.editor.js
+++ b/addons/website/static/src/js/website.snippets.editor.js
@@ -9,7 +9,7 @@
var self = this;
$("[data-oe-model]").on('click', function (event) {
var $this = $(event.srcElement);
- var tag = $this[0].tagName.toLowerCase();
+ var tag = $this[0] && $this[0].tagName.toLowerCase();
if (!(tag === 'a' || tag === "button") && !$this.parents("a, button").length) {
self.$('[data-action="edit"]').parent().effect('bounce', {distance: 18, times: 5}, 250);
}
@@ -416,6 +416,25 @@
}
setTimeout(function () {
$("#oe_snippets").trigger('snippet-dropped', $target);
+
+ // reset snippet for rte
+ $target.removeData("snippet-editor");
+ if ($target.data("overlay")) {
+ $target.data("overlay").remove();
+ $target.removeData("overlay");
+ }
+ self.create_overlay($target);
+ $target.find("[data-snippet-id]").each(function () {
+ var $snippet = $(this);
+ $snippet.removeData("snippet-editor");
+ if ($snippet.data("overlay")) {
+ $snippet.data("overlay").remove();
+ $snippet.removeData("overlay");
+ }
+ self.create_overlay($snippet);
+ });
+ // end
+
self.make_active($target);
},0);
} else {
diff --git a/addons/website/static/src/js/website.tests.js b/addons/website/static/src/js/website.tests.js
deleted file mode 100644
index 977dc8e1848..00000000000
--- a/addons/website/static/src/js/website.tests.js
+++ /dev/null
@@ -1,40 +0,0 @@
-var tests = {};
-var droptest = function () {
- var errors = [];
- for (var snippet_id in tests) {
- if (!tests[snippet_id]['activated'] || !tests[snippet_id]['dropped']){
- console.log("Can't dropped or activated snippet: " + snippet_id);
- }
- }
- if (errors.length) {
- console.log(tests);
- throw new Error("Can't dropped or activated at least one snippet");
- }
- $("#oe_snippets").off('snippet-activated snippet-dropped');
-};
-var droptesttime = setTimeout(droptest,0);
-
-$("#oe_snippets").off('snippet-activated snippet-dropped')
- .on('snippet-activated', function (event, dom) {
- tests[$(dom).data('src-snippet-id')]['activated'] = true;
- clearTimeout(droptesttime);
- droptesttime = setTimeout(droptest,0);
- })
- .on('snippet-dropped', function (event, dom, src_snipped_id) {
- tests[$(dom).data('src-snippet-id')]['dropped'] = true;
- clearTimeout(droptesttime);
- droptesttime = setTimeout(droptest,0);
- });
-var $thumbnails = $('#oe_snippets div.oe_snippet[data-snippet-id] .oe_snippet_thumbnail');
-$thumbnails.each(function () {
- var $thumbnail = $(this);
- tests[$thumbnail.parent().data('snippet-id')] = {};
- var position = $thumbnail.position();
- $thumbnail.trigger( $.Event( "mousedown", { which: 1, pageX: position.left, pageY: position.top } ) );
- $thumbnail.trigger( $.Event( "mousemove", { which: 1, pageX: position.left+100, pageY: position.top+100 } ) );
- $first_drop = $(".oe_drop_zone").first();
- position = $first_drop.position();
- $first_drop.trigger( $.Event( "mouseup", { which: 1, pageX: position.left+20, pageY: position.top+20 } ) );
- clearTimeout(droptesttime);
- droptesttime = setTimeout(droptest,0);
-});
diff --git a/addons/website/static/src/js/website.tour.banner.js b/addons/website/static/src/js/website.tour.banner.js
index ee679f13cd5..017b47b641a 100644
--- a/addons/website/static/src/js/website.tour.banner.js
+++ b/addons/website/static/src/js/website.tour.banner.js
@@ -2,114 +2,113 @@
'use strict';
var website = openerp.website;
+ var _t = openerp._t;
website.EditorBar.include({
start: function () {
- this.registerTour(new website.BannerTour(this));
+ this.registerTour(new website.Tour.Banner(this));
return this._super();
},
});
- website.BannerTour = website.Tour.extend({
+ website.Tour.Banner = website.Tour.extend({
id: 'banner',
name: "Build a page",
path: '/page/website.homepage',
- init: function (editor) {
+ init: function () {
var self = this;
self.steps = [
{
- title: "Welcome to your website!",
- content: "This tutorial will guide you to build your home page. We will start by adding a banner.",
- template: self.popover({ next: "Start Tutorial", end: "Skip It" }),
- backdrop: true,
+ title: _t("Welcome to your website!"),
+ content: _t("This tutorial will guide you to build your home page. We will start by adding a banner."),
+ popover: { next: _t("Start Tutorial"), end: _t("Skip It") },
},
{
waitNot: '.popover.tour',
element: 'button[data-action=edit]',
placement: 'bottom',
- title: "Edit this page",
- content: "Every page of your website can be modified through the <i>Edit</i> button.",
- template: self.popover({ fixed: true }),
+ title: _t("Edit this page"),
+ content: _t("Every page of your website can be modified through the <i>Edit</i> button."),
+ popover: { fixed: true },
},
{
element: 'button[data-action=snippet]',
placement: 'bottom',
- title: "Insert building blocks",
- content: "To add content in a page, you can insert building blocks.",
- template: self.popover({ fixed: true }),
+ title: _t("Insert building blocks"),
+ content: _t("To add content in a page, you can insert building blocks."),
+ popover: { fixed: true },
},
{
snippet: 'carousel',
placement: 'bottom',
- title: "Drag & Drop a Banner",
- content: "Drag the Banner block and drop it in your page.",
- template: self.popover({ fixed: true }),
+ title: _t("Drag & Drop a Banner"),
+ content: _t("Drag the Banner block and drop it in your page."),
+ popover: { fixed: true },
},
{
waitFor: '.oe_overlay_options .oe_options:visible',
element: '#wrap [data-snippet-id=carousel]:first .carousel-caption',
- sampleText: 'My Title',
placement: 'top',
- title: "Customize banner's text",
- content: "Click in the text and start editing it.",
+ title: _("Customize banner's text"),
+ content: _("Click in the text and start editing it."),
+ popover: { next: _t("Continue") },
},
{
- waitNot: '#wrap [data-snippet-id=carousel]:first .carousel-caption:contains("Your Banner Title")',
element: '.oe_overlay_options .oe_options',
placement: 'left',
- title: "Customize the banner",
- content: "Customize any block through this menu. Try to change the background of the banner.",
- template: self.popover({ next: "Continue" }),
+ title: _t("Customize the banner"),
+ content: _t("Customize any block through this menu. Try to change the background of the banner."),
+ popover: { next: _t("Continue") },
},
{
waitNot: '.popover.tour',
element: 'button[data-action=snippet]',
placement: 'bottom',
- title: "Add Another Block",
- content: "Let's add another building block to your page.",
- template: self.popover({ fixed: true }),
+ title: _t("Add Another Block"),
+ content: _t("Let's add another building block to your page."),
+ popover: { fixed: true },
},
{
snippet: 'three-columns',
placement: 'bottom',
- title: "Drag & Drop a Block",
- content: "Drag the <em>'3 Columns'</em> block and drop it below the banner.",
- template: self.popover({ fixed: true }),
+ title: _t("Drag & Drop a Block"),
+ content: _t("Drag the <em>'3 Columns'</em> block and drop it below the banner."),
+ popover: { fixed: true },
},
{
waitFor: '.oe_overlay_options .oe_options:visible',
element: 'button[data-action=save]',
placement: 'right',
- title: "Save your modifications",
- content: "Publish your page by clicking on the <em>'Save'</em> button.",
- template: self.popover({ fixed: true }),
+ title: _t("Save your modifications"),
+ content: _t("Publish your page by clicking on the <em>'Save'</em> button."),
+ popover: { fixed: true },
},
{
waitFor: 'button[data-action=edit]:visible',
- title: "Good Job!",
- content: "Well done, you created your homepage.",
- template: self.popover({ next: "Continue" }),
+ title: _("Good Job!"),
+ content: _("Well done, you created your homepage."),
+ popover: { next: _t("Continue") },
},
{
waitNot: '.popover.tour',
element: 'a[data-action=show-mobile-preview]',
placement: 'bottom',
- title: "Test Your Mobile Version",
- content: "Let's check how your homepage looks like on mobile devices.",
- template: self.popover({ fixed: true }),
+ title: _t("Test Your Mobile Version"),
+ content: _t("Let's check how your homepage looks like on mobile devices."),
+ popover: { fixed: true },
},
{
element: 'button[data-dismiss=modal]',
placement: 'right',
- title: "Close Mobile Preview",
- content: "Scroll in the mobile preview to test the rendering. Once it's ok, close this dialog.",
+ title: _t("Close Mobile Preview"),
+ content: _t("Scroll in the mobile preview to test the rendering. Once it's ok, close this dialog."),
},
{
title: "Congratulation",
element: 'a[id=content-menu-button]',
placement: 'bottom',
- content: "This tour is finished. You can continue discovering features with the <em>'Content'</em> menu.",
- template: self.popover({ next: "Close Tutorial" }),
+ content: _t("This tour is finished. You can continue discovering features with the <em>'Content'</em> menu."),
+ popover: { fixed: true, next: _t("Close Tutorial") },
},
];
return this._super();
diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js
index 39eaa5b7279..408a4c01539 100644
--- a/addons/website/static/src/js/website.tour.js
+++ b/addons/website/static/src/js/website.tour.js
@@ -2,15 +2,14 @@
'use strict';
var website = openerp.website;
+
+if (typeof QWeb2 !== "undefined")
website.add_template_file('/website/static/src/xml/website.tour.xml');
+if (website.EditorBar)
website.EditorBar.include({
tours: [],
start: function () {
- // $('.tour-backdrop').click(function (e) {
- // e.stopImmediatePropagation();
- // e.preventDefault();
- // });
var self = this;
var menu = $('#help-menu');
_.each(this.tours, function (tour) {
@@ -21,31 +20,11 @@ website.EditorBar.include({
});
menu.append($menuItem);
});
-
- this.waitRTEReady = false;
- this.on('rte:called', this, function () {self.waitRTEReady = true; });
- this.on('rte:ready', this, function () {self.waitRTEReady = false;});
-
- var res = this._super();
- website.Tour.waitReady.call(this, this.testRunning);
- return res;
+ return this._super();
},
registerTour: function (tour) {
website.Tour.add(tour);
this.tours.push(tour);
- },
- testRunning: function () {
- if (this.waitRTEReady) {
- this.on('rte:ready', this, function () {
- website.Tour.each(function () {
- this.running();
- });
- });
- } else {
- website.Tour.each(function () {
- this.running();
- });
- }
}
});
@@ -82,23 +61,12 @@ $.ajaxSetup({
}
});
-
website.Tour = openerp.Class.extend({
steps: [],
defaultDelay: 50, //ms
+ defaultOverLaps: 5000, //ms
localStorage: window.localStorage,
- init: function (url) {
- this.tour = new Tour({
- name: this.id,
- storage: this.tourStorage,
- keyboard: false,
- template: this.popover(),
- onHide: function () {
- window.scrollTo(0, 0);
- }
- });
- this.registerSteps();
- },
+ init: function () {},
run: function (automatic) {
this.reset();
@@ -109,15 +77,16 @@ website.Tour = openerp.Class.extend({
website.Tour.busy = true;
- if (automatic) {
- this.localStorage.setItem("tour-"+this.id+"-test-automatic", true);
- }
+ this.localStorage.setItem("tour-"+this.id+"-test-automatic", automatic);
+ this.automatic = automatic;
- // redirect to begin of the tour
if (this.path) {
- var path = this.path.split('?');
- window.location.href = path[0] + "?tutorial."+this.id+"=true" + path.slice(1, path.length).join("?");
- return;
+ // redirect to begin of the tour in function of the language
+ if (!this.testUrl(this.path+"(#.*)?$")) {
+ var path = this.path.split('#');
+ window.location.href = "/"+this.getLang()+path[0] + "#tutorial."+this.id+"=true&" + path.slice(1, path.length).join("#");
+ return;
+ }
}
var self = this;
@@ -125,12 +94,13 @@ website.Tour = openerp.Class.extend({
website.Tour.waitReady.call(this, function () {self._running();});
},
running: function () {
- if (+this.localStorage.getItem("tour-"+this.id+"-test") >= this.steps.length) {
+ var self = this;
+ if (+this.localStorage.getItem("tour-"+this.id+"-test") >= this.steps.length-1) {
this.endTour();
return;
}
- if (website.Tour.is_busy() || !this.testUrl()) return;
+ if (website.Tour.is_busy()) return;
// launch tour with url
this.checkRunningUrl();
@@ -138,22 +108,32 @@ website.Tour = openerp.Class.extend({
// mark tour as busy (only one test running)
if (this.localStorage.getItem("tour-"+this.id+"-test") != null) {
website.Tour.busy = true;
+ this.automatic = !!this.localStorage.getItem("tour-"+this.id+"-test-automatic");
+ }
+
+ if (!this.testPathUrl()) {
+ if (this.automatic) {
+ this.timer = setTimeout(function () {
+ self.reset();
+ throw new Error("Wrong url for running " + self.id
+ + '\ntestPath: ' + self.testPath
+ + '\nhref: ' + window.location.href
+ + "\nreferrer: " + document.referrer
+ );
+ },this.defaultOverLaps);
+ }
+ return;
}
var self = this;
website.Tour.waitReady.call(this, function () {self._running();});
},
-
_running: function () {
var stepId = this.localStorage.getItem("tour-"+this.id+"-test");
- var automatic = !!this.localStorage.getItem("tour-"+this.id+"-test-automatic");
-
+
if (stepId != null) {
- if (!this.check(this.step(stepId))) {
- var step = this.next(stepId);
- stepId = step ? step.stepId : stepId;
- }
- this.nextStep(stepId, automatic ? this.autoNextStep : null, automatic ? 5000 : null);
+ this.registerTour();
+ this.nextStep(stepId, this.automatic ? this.autoNextStep : null, this.automatic ? this.defaultOverLaps : null);
}
},
@@ -174,30 +154,51 @@ website.Tour = openerp.Class.extend({
$('.popover.tour').remove();
},
- testUrl: function () {
- return !this.testPath || this.testPath.test(window.location.href);
+ getLang: function () {
+ return $("html").attr("lang").replace(/-/, '_');
+ },
+ testUrl: function (url) {
+ return new RegExp("(/"+this.getLang()+")?"+url, "i").test(window.location.href);
+ },
+ testPathUrl: function () {
+ if (!this.testPath || this.testUrl(this.testPath)) return true;
},
checkRunningUrl: function () {
- if (window.location.search.indexOf("tutorial."+this.id+"=true") > -1) {
+ if (window.location.hash.indexOf("tutorial."+this.id+"=true") > -1) {
this.localStorage.setItem("tour-"+this.id+"-test", 0);
- window.location.href = window.location.href.replace(/tutorial.+=true&?/, '');
+ window.location.hash = window.location.hash.replace(/tutorial.+=true&?/, '');
}
},
+ registerTour: function () {
+ this.tour = new Tour({
+ name: this.id,
+ storage: this.tourStorage,
+ keyboard: false,
+ template: this.popover(),
+ onHide: function () {
+ window.scrollTo(0, 0);
+ }
+ });
+ this.registerSteps();
+ },
registerSteps: function () {
for (var index=0, len=this.steps.length; index<len; index++) {
var step = this.steps[index];
step.stepId = step.stepId || ""+index;
- if (!step.waitNot && index > 0 && $(this.steps[index-1].template).has("button[data-role='next']").size()) {
- step.waitNot = '.popover.tour';
+ if (!step.waitNot && index > 0 && this.steps[index-1] &&
+ this.steps[index-1].popover && this.steps[index-1].popover.next) {
+ step.waitNot = '.popover.tour:visible';
}
if (!step.waitFor && index > 0 && this.steps[index-1].snippet) {
step.waitFor = '.oe_overlay_options .oe_options:visible';
}
- step._title = step.title;
- step.title = openerp.qweb.render('website.tour_popover_title', { title: step.title });
+ step._title = step._title || step.title;
+ step.title = this.popoverTitle({ title: step._title });
+ step.template = step.template || this.popover( step.popover );
+
if (!step.element) step.orphan = true;
if (step.snippet) {
step.element = '#oe_snippets div.oe_snippet[data-snippet-id="'+step.snippet+'"] .oe_snippet_thumbnail';
@@ -205,9 +206,10 @@ website.Tour = openerp.Class.extend({
}
- if ($(this.steps[index-1].template).has("button[data-role='next']").size()) {
+ if (this.steps[index-1] &&
+ this.steps[index-1].popover && this.steps[index-1].popover.next) {
var step = {
- stepId: index,
+ stepId: ""+index,
waitNot: '.popover.tour:visible'
};
this.steps.push(step);
@@ -216,8 +218,21 @@ website.Tour = openerp.Class.extend({
this.tour.addSteps(this.steps);
},
+ popoverTitle: function (options) {
+ try {
+ return openerp.qweb.render('website.tour_popover_title', options);
+ } catch (e) {
+ if (!this.automatic) throw e;
+ return options.title;
+ }
+ },
popover: function (options) {
- return openerp.qweb.render('website.tour_popover', options);
+ try {
+ return openerp.qweb.render('website.tour_popover', options);
+ } catch (e) {
+ if (!this.automatic) throw e;
+ return "";
+ }
},
timer: null,
@@ -265,7 +280,12 @@ website.Tour = openerp.Class.extend({
self.timer = setTimeout(checkNext, self.defaultDelay);
} else {
self.reset();
- throw new Error("Time overlaps to arrive to step " + step.stepId + ": '" + step._title + "'");
+ throw new Error("Time overlaps to arrive to step " + step.stepId + ": '" + step._title + "'"
+ + '\nelement: ' + Boolean(!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden")))
+ + '\nwaitNot: ' + Boolean(!step.waitNot || !$(step.waitNot).size())
+ + '\nwaitFor: ' + Boolean(!step.waitFor || $(step.waitFor).size())
+ + '\n\n' + $("body").html()
+ );
}
}
checkNext();
@@ -288,7 +308,7 @@ website.Tour = openerp.Class.extend({
$(".popover.tour").remove();
// go to step in bootstrap tour
this.tour.goto(index);
- if (step.callback) step.callback();
+ if (step.onload) step.onload();
next = steps.shift();
break;
}
@@ -315,7 +335,11 @@ website.Tour = openerp.Class.extend({
}
},
endTour: function () {
- console.log('{ "event": "success" }');
+ if (parseInt(this.localStorage.getItem("tour-"+this.id+"-test"),10) >= this.steps.length-1) {
+ console.log('{ "event": "success" }');
+ } else {
+ console.log('{ "event": "canceled" }');
+ }
this.reset();
},
autoNextStep: function () {
@@ -351,7 +375,10 @@ website.Tour = openerp.Class.extend({
} else if (step.sampleText) {
$element.trigger($.Event("keydown", { srcElement: $element }));
- if ($element.is("select") || $element.is("input") ) {
+ if ($element.is("input") ) {
+ $element.val(step.sampleText);
+ } if ($element.is("select")) {
+ $element.find("[value='"+step.sampleText+"'], option:contains('"+step.sampleText+"')").attr("selected", true);
$element.val(step.sampleText);
} else {
$element.html(step.sampleText);
@@ -397,7 +424,10 @@ website.Tour.busy = false;
website.Tour.add = function (tour) {
website.Tour.waitReady(function () {
tour = tour.id ? tour : new tour();
- website.Tour.tours[tour.id] = tour;
+ if (!website.Tour.tours[tour.id]) {
+ website.Tour.tours[tour.id] = tour;
+ tour.running();
+ }
});
};
website.Tour.get = function (id) {
@@ -413,7 +443,7 @@ website.Tour.each = function (callback) {
website.Tour.waitReady = function (callback) {
var self = this;
$(document).ready(function () {
- if ($.ajaxBusy == null || $.ajaxBusy) {
+ if ($.ajaxBusy) {
$(document).ajaxStop(function() {
setTimeout(function () {
callback.call(self);
@@ -428,18 +458,20 @@ website.Tour.waitReady = function (callback) {
});
};
website.Tour.run_test = function (id) {
- website.Tour.get(id).run(true);
+ website.Tour.waitReady(function () {
+ if (!website.Tour.is_busy()) {
+ website.Tour.tours[id].run(true);
+ }
+ });
};
website.Tour.is_busy = function () {
for (var k in this.localStorage) {
if (!k.indexOf("tour-")) {
- return true;
+ return k;
}
}
return website.Tour.busy;
};
-
-
}());
diff --git a/addons/website/static/src/js/website.tour.test.admin.js b/addons/website/static/src/js/website.tour.test.admin.js
new file mode 100644
index 00000000000..787f05beb23
--- /dev/null
+++ b/addons/website/static/src/js/website.tour.test.admin.js
@@ -0,0 +1,106 @@
+(function () {
+ 'use strict';
+
+ var website = openerp.website;
+
+ website.Tour.LoginEdit = website.Tour.extend({
+ id: 'login_edit',
+ name: "Try to log as admin and check editor",
+ path: '/',
+ init: function () {
+ var self = this;
+ self.steps = [
+ {
+ title: "click login",
+ element: '#top_menu a[href*="/web/login"]',
+ },
+ {
+ title: "insert login",
+ element: '.oe_login_form input[name="login"]',
+ sampleText: "admin",
+ },
+ {
+ title: "insert password",
+ waitFor: '.oe_login_form input[name="login"][value!=""]',
+ element: '.oe_login_form input[name="password"]',
+ sampleText: "admin",
+ },
+ {
+ title: "select 2 Standard tickets",
+ waitFor: '.oe_login_form input[name="password"][value!=""]',
+ element: '.oe_login_form button',
+ },
+ {
+ title: "go back to website from backend",
+ element: 'a[data-action-model="ir.actions.act_url"]:contains("Website")',
+ },
+ {
+ title: 'try to edit',
+ waitNot: '#wrap .carousel',
+ element: 'button[data-action=edit]:visible',
+ },
+ {
+ title: 'check edit mode',
+ waitFor: 'button[data-action=save]:visible',
+ },
+ {
+ title: 'check branding',
+ waitFor: '#wrap[data-oe-model="ir.ui.view"]',
+ },
+ {
+ title: 'check rte',
+ waitFor: '#oe_rte_toolbar',
+ },
+ {
+ title: 'check insert block button',
+ element: '[data-action="snippet"]:visible',
+ },
+ {
+ title: 'add snippets',
+ snippet: 'carousel',
+ },
+ {
+ title: 'try to save',
+ waitFor: '.oe_overlay_options .oe_options:visible',
+ element: 'button[data-action=save]:visible',
+ },
+ {
+ title: 'check saved',
+ waitFor: '#wrap div.carousel',
+ element: 'button[data-action=edit]:visible',
+ },
+ {
+ title: 'try to re-edit',
+ waitFor: 'button[data-action=save]:visible',
+ element: '#wrap .carousel',
+ },
+ {
+ title: 'remove snippet',
+ element: '.oe_snippet_remove',
+ },
+ {
+ title: 'try to re-save',
+ waitNot: '#wrap .carousel',
+ element: 'button[data-action=save]:visible',
+ },
+ {
+ title: "click admin",
+ waitFor: 'button[data-action=edit]:visible',
+ element: 'a:contains("Administrator")',
+ },
+ {
+ title: "click logout",
+ element: '#top_menu a[href*="/logout"]',
+ },
+ {
+ title: "check logout",
+ waitFor: '#top_menu a[href*="/web/login"]',
+ },
+ ];
+ return this._super();
+ },
+ });
+ // for test without editor bar
+ website.Tour.add(website.Tour.LoginEdit);
+
+}());
diff --git a/addons/website/static/src/js/website.tour.test.js b/addons/website/static/src/js/website.tour.test.js
new file mode 100644
index 00000000000..3e85ce20dae
--- /dev/null
+++ b/addons/website/static/src/js/website.tour.test.js
@@ -0,0 +1,34 @@
+(function () {
+
+function LoadScript(src) {
+ xmlHttp = new XMLHttpRequest();
+ xmlHttp.onreadystatechange = function() {
+ if(xmlHttp.readyState == 4) {
+ if (xmlHttp.status == 200 || xmlHttp.status == 304) {
+ new Function(xmlHttp.responseText)();
+ } else {
+ throw new Error("Can't load JavaScript.\nhref: " + window.location.href + "\nsrc: " + src);
+ }
+ }
+ };
+ xmlHttp.open("GET", src, false);
+ xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+ xmlHttp.send(null);
+}
+
+if (typeof jQuery === "undefined")
+ LoadScript("/web/static/lib/jquery/jquery.js");
+if (typeof _ === "undefined")
+ LoadScript("/web/static/lib/underscore/underscore.js");
+if (typeof openerp === "undefined") {
+ LoadScript("/web/static/lib/qweb/qweb2.js");
+ LoadScript("/web/static/src/js/openerpframework.js");
+}
+if (typeof openerp === "undefined" || !openerp.website || !openerp.website.add_template_file)
+ LoadScript("/website/static/src/js/website.js");
+if (typeof Tour === "undefined")
+ LoadScript("/website/static/lib/bootstrap-tour/bootstrap-tour.js");
+if (typeof openerp === "undefined" || !openerp.website.Tour)
+ LoadScript("/website/static/src/js/website.tour.js");
+
+})(); \ No newline at end of file
diff --git a/addons/website/static/src/xml/website.editor.xml b/addons/website/static/src/xml/website.editor.xml
index 448c615bb07..6c1e387c958 100644
--- a/addons/website/static/src/xml/website.editor.xml
+++ b/addons/website/static/src/xml/website.editor.xml
@@ -101,6 +101,7 @@
<button type="button" class="btn btn-primary btn-lg filepicker">
Upload an image from your computer
</button>
+ <button type="button" class="btn btn-lg hidden wait" disabled="disabled"/>
<p class="text-muted mt16">— or —</p>
</div>
<div class="well">
@@ -110,11 +111,15 @@
placeholder="http://openerp.com"/>
</div>
<input type="hidden" name="func"/>
+ <div class="help-block"/>
</form>
<div class="col-sm-4 image-preview-container">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAC0lEQVQIHWP4zwAAAgEBAMVfG14AAAAASUVORK5CYII%3D"
class="pull-right img-rounded image-preview"
width="100%"/>
+ <img src="/web/static/src/img/throbber-large.gif"
+ class="pull-right img-rounded wait hidden"
+ width="100%"/>
<select class="form-control image-style">
<option value="">No styling</option>
<option value="img-rounded">Rounded corners</option>
diff --git a/addons/website/static/src/xml/website.xml b/addons/website/static/src/xml/website.xml
index 5890350e2dc..f25a491a106 100644
--- a/addons/website/static/src/xml/website.xml
+++ b/addons/website/static/src/xml/website.xml
@@ -102,7 +102,7 @@
<h3 class="modal-title"><t t-esc="window_title"/></h3>
</div>
<div class="modal-body">
- <form class="form-horizontal" role="form">
+ <form class="form-horizontal" role="form" t-att-id="id">
<div class="form-group mb0">
<label for="page-name" class="col-sm-3 control-label">
<t t-esc="field_name"/>: