From 1ab0cea62c914d629ec56fec0634d1e0f376b258 Mon Sep 17 00:00:00 2001 From: Vidhin Mehta Date: Fri, 20 Sep 2013 18:49:10 +0530 Subject: [PATCH 1/8] [TEST] bzr revid: vme@tinyerp.com-20130920131910-gckti41bb7tg9i13 --- addons/website/__openerp__.py | 3 + .../lib/bootstrap-tour/css/bootstrap-tour.css | 42 ++ .../static/lib/bootstrap-tour/css/prism.css | 107 ++++ .../bootstrap-tour/js/bootstrap-popover.js | 114 ++++ .../bootstrap-tour/js/bootstrap-tooltip.js | 361 ++++++++++++ .../lib/bootstrap-tour/js/bootstrap-tour.js | 540 ++++++++++++++++++ .../bootstrap-tour/js/jquery.smoothscroll.js | 47 ++ .../static/lib/bootstrap-tour/js/prism.js | 8 + addons/website/static/src/js/website.seo.js | 2 +- addons/website/static/src/js/website.tour.js | 72 +++ .../website/static/src/xml/website.tour.xml | 16 + addons/website/views/views.xml | 10 + 12 files changed, 1321 insertions(+), 1 deletion(-) create mode 100644 addons/website/static/lib/bootstrap-tour/css/bootstrap-tour.css create mode 100644 addons/website/static/lib/bootstrap-tour/css/prism.css create mode 100644 addons/website/static/lib/bootstrap-tour/js/bootstrap-popover.js create mode 100644 addons/website/static/lib/bootstrap-tour/js/bootstrap-tooltip.js create mode 100644 addons/website/static/lib/bootstrap-tour/js/bootstrap-tour.js create mode 100644 addons/website/static/lib/bootstrap-tour/js/jquery.smoothscroll.js create mode 100644 addons/website/static/lib/bootstrap-tour/js/prism.js create mode 100644 addons/website/static/src/js/website.tour.js create mode 100644 addons/website/static/src/xml/website.tour.xml diff --git a/addons/website/__openerp__.py b/addons/website/__openerp__.py index b17d79407ca..36b43209053 100644 --- a/addons/website/__openerp__.py +++ b/addons/website/__openerp__.py @@ -11,6 +11,7 @@ OpenERP Website CMS 'author': 'OpenERP SA', 'depends': ['web', 'share'], 'installable': True, + 'css': ['static/lib/bootstrap-tour/css/website-tour.css'], 'data': [ 'views/views.xml', 'views/themes.xml', @@ -19,4 +20,6 @@ OpenERP Website CMS 'website_view.xml', 'security/ir.model.access.csv', ], + 'css': ['static/lib/bootstrap-tour/css/website-tour.css'], + } diff --git a/addons/website/static/lib/bootstrap-tour/css/bootstrap-tour.css b/addons/website/static/lib/bootstrap-tour/css/bootstrap-tour.css new file mode 100644 index 00000000000..4e0936e532d --- /dev/null +++ b/addons/website/static/lib/bootstrap-tour/css/bootstrap-tour.css @@ -0,0 +1,42 @@ +.tour-backdrop { + position: absolute; + z-index: 1009; + background: #000; + opacity: 0.8; + top: 0; + left: 0; + width: 100%; +} +.tour-step-backdrop { + position: relative; + z-index: 1011; +} +.tour-step-background { + position: absolute; + z-index: 1010; + background: #fff; + border-radius: 6px; +} +.popover[class*="tour-"] .popover-navigation { + padding: 9px 14px; +} +.popover[class*="tour-"] .popover-navigation *[data-role=end] { + float: right; +} +.popover[class*="tour-"] .popover-navigation *[data-role=prev], +.popover[class*="tour-"] .popover-navigation *[data-role=next], +.popover[class*="tour-"] .popover-navigation *[data-role=end] { + cursor: pointer; +} +.popover[class*="tour-"] .popover-navigation *[data-role=prev].disabled, +.popover[class*="tour-"] .popover-navigation *[data-role=next].disabled, +.popover[class*="tour-"] .popover-navigation *[data-role=end].disabled { + cursor: default; +} +.popover[class*="tour-"].orphan { + position: fixed; + margin-top: 0; +} +.popover[class*="tour-"].orphan .arrow { + display: none; +} diff --git a/addons/website/static/lib/bootstrap-tour/css/prism.css b/addons/website/static/lib/bootstrap-tour/css/prism.css new file mode 100644 index 00000000000..7e97fbb459a --- /dev/null +++ b/addons/website/static/lib/bootstrap-tour/css/prism.css @@ -0,0 +1,107 @@ +/** + * prism.js default theme for JavaScript, CSS and HTML + * Based on dabblet (http://dabblet.com) + * @author Lea Verou + */ + +code[class*="language-"], +pre[class*="language-"] { + color: black; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', monospace; + direction: ltr; + text-align: left; + white-space: pre; + word-spacing: normal; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; +} + +@media print { + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } +} + +/* Code blocks */ +pre[class*="language-"] { + padding: 1em; + margin: .5em 0; + overflow: auto; +} + +:not(pre) > code[class*="language-"], +pre[class*="language-"] { + background: #f5f2f0; +} + +/* Inline code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string { + color: #690; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #a67f59; + background: hsla(0,0%,100%,.5); +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + + +.token.regex, +.token.important { + color: #e90; +} + +.token.important { + font-weight: bold; +} + +.token.entity { + cursor: help; +} diff --git a/addons/website/static/lib/bootstrap-tour/js/bootstrap-popover.js b/addons/website/static/lib/bootstrap-tour/js/bootstrap-popover.js new file mode 100644 index 00000000000..e6a23d21045 --- /dev/null +++ b/addons/website/static/lib/bootstrap-tour/js/bootstrap-popover.js @@ -0,0 +1,114 @@ +/* =========================================================== + * bootstrap-popover.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#popovers + * =========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * =========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* POPOVER PUBLIC CLASS DEFINITION + * =============================== */ + + var Popover = function (element, options) { + this.init('popover', element, options) + } + + + /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js + ========================================== */ + + Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, { + + constructor: Popover + + , setContent: function () { + var $tip = this.tip() + , title = this.getTitle() + , content = this.getContent() + + $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title) + $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content) + + $tip.removeClass('fade top bottom left right in') + } + + , hasContent: function () { + return this.getTitle() || this.getContent() + } + + , getContent: function () { + var content + , $e = this.$element + , o = this.options + + content = (typeof o.content == 'function' ? o.content.call($e[0]) : o.content) + || $e.attr('data-content') + + return content + } + + , tip: function () { + if (!this.$tip) { + this.$tip = $(this.options.template) + } + return this.$tip + } + + , destroy: function () { + this.hide().$element.off('.' + this.type).removeData(this.type) + } + + }) + + + /* POPOVER PLUGIN DEFINITION + * ======================= */ + + var old = $.fn.popover + + $.fn.popover = function (option) { + return this.each(function () { + var $this = $(this) + , data = $this.data('popover') + , options = typeof option == 'object' && option + if (!data) $this.data('popover', (data = new Popover(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.popover.Constructor = Popover + + $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, { + placement: 'right' + , trigger: 'click' + , content: '' + , template: '

' + }) + + + /* POPOVER NO CONFLICT + * =================== */ + + $.fn.popover.noConflict = function () { + $.fn.popover = old + return this + } + +}(window.jQuery); diff --git a/addons/website/static/lib/bootstrap-tour/js/bootstrap-tooltip.js b/addons/website/static/lib/bootstrap-tour/js/bootstrap-tooltip.js new file mode 100644 index 00000000000..a3bbd580bba --- /dev/null +++ b/addons/website/static/lib/bootstrap-tour/js/bootstrap-tooltip.js @@ -0,0 +1,361 @@ +/* =========================================================== + * bootstrap-tooltip.js v2.3.2 + * http://twitter.github.com/bootstrap/javascript.html#tooltips + * Inspired by the original jQuery.tipsy by Jason Frame + * =========================================================== + * Copyright 2012 Twitter, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ + + +!function ($) { + + "use strict"; // jshint ;_; + + + /* TOOLTIP PUBLIC CLASS DEFINITION + * =============================== */ + + var Tooltip = function (element, options) { + this.init('tooltip', element, options) + } + + Tooltip.prototype = { + + constructor: Tooltip + + , init: function (type, element, options) { + var eventIn + , eventOut + , triggers + , trigger + , i + + this.type = type + this.$element = $(element) + this.options = this.getOptions(options) + this.enabled = true + + triggers = this.options.trigger.split(' ') + + for (i = triggers.length; i--;) { + trigger = triggers[i] + if (trigger == 'click') { + this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this)) + } else if (trigger != 'manual') { + eventIn = trigger == 'hover' ? 'mouseenter' : 'focus' + eventOut = trigger == 'hover' ? 'mouseleave' : 'blur' + this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this)) + this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this)) + } + } + + this.options.selector ? + (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) : + this.fixTitle() + } + + , getOptions: function (options) { + options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options) + + if (options.delay && typeof options.delay == 'number') { + options.delay = { + show: options.delay + , hide: options.delay + } + } + + return options + } + + , enter: function (e) { + var defaults = $.fn[this.type].defaults + , options = {} + , self + + this._options && $.each(this._options, function (key, value) { + if (defaults[key] != value) options[key] = value + }, this) + + self = $(e.currentTarget)[this.type](options).data(this.type) + + if (!self.options.delay || !self.options.delay.show) return self.show() + + clearTimeout(this.timeout) + self.hoverState = 'in' + this.timeout = setTimeout(function() { + if (self.hoverState == 'in') self.show() + }, self.options.delay.show) + } + + , leave: function (e) { + var self = $(e.currentTarget)[this.type](this._options).data(this.type) + + if (this.timeout) clearTimeout(this.timeout) + if (!self.options.delay || !self.options.delay.hide) return self.hide() + + self.hoverState = 'out' + this.timeout = setTimeout(function() { + if (self.hoverState == 'out') self.hide() + }, self.options.delay.hide) + } + + , show: function () { + var $tip + , pos + , actualWidth + , actualHeight + , placement + , tp + , e = $.Event('show') + + if (this.hasContent() && this.enabled) { + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + $tip = this.tip() + this.setContent() + + if (this.options.animation) { + $tip.addClass('fade') + } + + placement = typeof this.options.placement == 'function' ? + this.options.placement.call(this, $tip[0], this.$element[0]) : + this.options.placement + + $tip + .detach() + .css({ top: 0, left: 0, display: 'block' }) + + this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element) + + pos = this.getPosition() + + actualWidth = $tip[0].offsetWidth + actualHeight = $tip[0].offsetHeight + + switch (placement) { + case 'bottom': + tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2} + break + case 'top': + tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2} + break + case 'left': + tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth} + break + case 'right': + tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width} + break + } + + this.applyPlacement(tp, placement) + this.$element.trigger('shown') + } + } + + , applyPlacement: function(offset, placement){ + var $tip = this.tip() + , width = $tip[0].offsetWidth + , height = $tip[0].offsetHeight + , actualWidth + , actualHeight + , delta + , replace + + $tip + .offset(offset) + .addClass(placement) + .addClass('in') + + actualWidth = $tip[0].offsetWidth + actualHeight = $tip[0].offsetHeight + + if (placement == 'top' && actualHeight != height) { + offset.top = offset.top + height - actualHeight + replace = true + } + + if (placement == 'bottom' || placement == 'top') { + delta = 0 + + if (offset.left < 0){ + delta = offset.left * -2 + offset.left = 0 + $tip.offset(offset) + actualWidth = $tip[0].offsetWidth + actualHeight = $tip[0].offsetHeight + } + + this.replaceArrow(delta - width + actualWidth, actualWidth, 'left') + } else { + this.replaceArrow(actualHeight - height, actualHeight, 'top') + } + + if (replace) $tip.offset(offset) + } + + , replaceArrow: function(delta, dimension, position){ + this + .arrow() + .css(position, delta ? (50 * (1 - delta / dimension) + "%") : '') + } + + , setContent: function () { + var $tip = this.tip() + , title = this.getTitle() + + $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title) + $tip.removeClass('fade in top bottom left right') + } + + , hide: function () { + var that = this + , $tip = this.tip() + , e = $.Event('hide') + + this.$element.trigger(e) + if (e.isDefaultPrevented()) return + + $tip.removeClass('in') + + function removeWithAnimation() { + var timeout = setTimeout(function () { + $tip.off($.support.transition.end).detach() + }, 500) + + $tip.one($.support.transition.end, function () { + clearTimeout(timeout) + $tip.detach() + }) + } + + $.support.transition && this.$tip.hasClass('fade') ? + removeWithAnimation() : + $tip.detach() + + this.$element.trigger('hidden') + + return this + } + + , fixTitle: function () { + var $e = this.$element + if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') { + $e.attr('data-original-title', $e.attr('title') || '').attr('title', '') + } + } + + , hasContent: function () { + return this.getTitle() + } + + , getPosition: function () { + var el = this.$element[0] + return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : { + width: el.offsetWidth + , height: el.offsetHeight + }, this.$element.offset()) + } + + , getTitle: function () { + var title + , $e = this.$element + , o = this.options + + title = $e.attr('data-original-title') + || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title) + + return title + } + + , tip: function () { + return this.$tip = this.$tip || $(this.options.template) + } + + , arrow: function(){ + return this.$arrow = this.$arrow || this.tip().find(".tooltip-arrow") + } + + , validate: function () { + if (!this.$element[0].parentNode) { + this.hide() + this.$element = null + this.options = null + } + } + + , enable: function () { + this.enabled = true + } + + , disable: function () { + this.enabled = false + } + + , toggleEnabled: function () { + this.enabled = !this.enabled + } + + , toggle: function (e) { + var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this + self.tip().hasClass('in') ? self.hide() : self.show() + } + + , destroy: function () { + this.hide().$element.off('.' + this.type).removeData(this.type) + } + + } + + + /* TOOLTIP PLUGIN DEFINITION + * ========================= */ + + var old = $.fn.tooltip + + $.fn.tooltip = function ( option ) { + return this.each(function () { + var $this = $(this) + , data = $this.data('tooltip') + , options = typeof option == 'object' && option + if (!data) $this.data('tooltip', (data = new Tooltip(this, options))) + if (typeof option == 'string') data[option]() + }) + } + + $.fn.tooltip.Constructor = Tooltip + + $.fn.tooltip.defaults = { + animation: true + , placement: 'top' + , selector: false + , template: '
' + , trigger: 'hover focus' + , title: '' + , delay: 0 + , html: false + , container: false + } + + + /* TOOLTIP NO CONFLICT + * =================== */ + + $.fn.tooltip.noConflict = function () { + $.fn.tooltip = old + return this + } + +}(window.jQuery); diff --git a/addons/website/static/lib/bootstrap-tour/js/bootstrap-tour.js b/addons/website/static/lib/bootstrap-tour/js/bootstrap-tour.js new file mode 100644 index 00000000000..9424b3f6c12 --- /dev/null +++ b/addons/website/static/lib/bootstrap-tour/js/bootstrap-tour.js @@ -0,0 +1,540 @@ +/* =========================================================== +# bootstrap-tour - v0.6.0 +# http://bootstraptour.com +# ============================================================== +# Copyright 2012-2013 Ulrich Sossou +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +*/ +(function() { + (function($, window) { + var Tour, document; + document = window.document; + Tour = (function() { + function Tour(options) { + this._options = $.extend({ + name: "tour", + container: "body", + keyboard: true, + storage: window.localStorage, + debug: false, + backdrop: false, + redirect: true, + orphan: false, + basePath: "", + template: "

", + afterSetState: function(key, value) {}, + afterGetState: function(key, value) {}, + afterRemoveState: function(key) {}, + onStart: function(tour) {}, + onEnd: function(tour) {}, + onShow: function(tour) {}, + onShown: function(tour) {}, + onHide: function(tour) {}, + onHidden: function(tour) {}, + onNext: function(tour) {}, + onPrev: function(tour) {} + }, options); + this._steps = []; + this.setCurrentStep(); + this.backdrop = { + overlay: null, + $element: null, + $background: null + }; + } + + Tour.prototype.setState = function(key, value) { + var keyName; + keyName = "" + this._options.name + "_" + key; + this._options.storage.setItem(keyName, value); + return this._options.afterSetState(keyName, value); + }; + + Tour.prototype.removeState = function(key) { + var keyName; + keyName = "" + this._options.name + "_" + key; + this._options.storage.removeItem(keyName); + return this._options.afterRemoveState(keyName); + }; + + Tour.prototype.getState = function(key) { + var keyName, value; + keyName = "" + this._options.name + "_" + key; + value = this._options.storage.getItem(keyName); + if (value === void 0 || value === "null") { + value = null; + } + this._options.afterGetState(key, value); + return value; + }; + + Tour.prototype.addSteps = function(steps) { + var step, _i, _len, _results; + _results = []; + for (_i = 0, _len = steps.length; _i < _len; _i++) { + step = steps[_i]; + _results.push(this.addStep(step)); + } + return _results; + }; + + Tour.prototype.addStep = function(step) { + return this._steps.push(step); + }; + + Tour.prototype.getStep = function(i) { + if (this._steps[i] != null) { + return $.extend({ + id: "step-" + i, + path: "", + placement: "right", + title: "", + content: "

", + next: i === this._steps.length - 1 ? -1 : i + 1, + prev: i - 1, + animation: true, + container: this._options.container, + backdrop: this._options.backdrop, + redirect: this._options.redirect, + orphan: this._options.orphan, + template: this._options.template, + onShow: this._options.onShow, + onShown: this._options.onShown, + onHide: this._options.onHide, + onHidden: this._options.onHidden, + onNext: this._options.onNext, + onPrev: this._options.onPrev + }, this._steps[i]); + } + }; + + Tour.prototype.start = function(force) { + var promise, + _this = this; + if (force == null) { + force = false; + } + if (this.ended() && !force) { + return this._debug("Tour ended, start prevented."); + } + $(document).off("click.tour." + this._options.name, ".popover *[data-role=next]").on("click.tour." + this._options.name, ".popover *[data-role=next]:not(.disabled)", function(e) { + e.preventDefault(); + return _this.next(); + }); + $(document).off("click.tour." + this._options.name, ".popover *[data-role=prev]").on("click.tour." + this._options.name, ".popover *[data-role=prev]:not(.disabled)", function(e) { + e.preventDefault(); + return _this.prev(); + }); + $(document).off("click.tour." + this._options.name, ".popover *[data-role=end]").on("click.tour." + this._options.name, ".popover *[data-role=end]", function(e) { + e.preventDefault(); + return _this.end(); + }); + this._onResize(function() { + return _this.showStep(_this._current); + }); + this._setupKeyboardNavigation(); + promise = this._makePromise(this._options.onStart != null ? this._options.onStart(this) : void 0); + return this._callOnPromiseDone(promise, this.showStep, this._current); + }; + + Tour.prototype.next = function() { + var promise; + if (this.ended()) { + return this._debug("Tour ended, next prevented."); + } + promise = this.hideStep(this._current); + return this._callOnPromiseDone(promise, this._showNextStep); + }; + + Tour.prototype.prev = function() { + var promise; + if (this.ended()) { + return this._debug("Tour ended, prev prevented."); + } + promise = this.hideStep(this._current); + return this._callOnPromiseDone(promise, this._showPrevStep); + }; + + Tour.prototype.goto = function(i) { + var promise; + if (this.ended()) { + return this._debug("Tour ended, goto prevented."); + } + promise = this.hideStep(this._current); + return this._callOnPromiseDone(promise, this.showStep, i); + }; + + Tour.prototype.end = function() { + var endHelper, hidePromise, + _this = this; + endHelper = function(e) { + $(document).off("click.tour." + _this._options.name); + $(document).off("keyup.tour." + _this._options.name); + $(window).off("resize.tour." + _this._options.name); + _this.setState("end", "yes"); + if (_this._options.onEnd != null) { + return _this._options.onEnd(_this); + } + }; + hidePromise = this.hideStep(this._current); + return this._callOnPromiseDone(hidePromise, endHelper); + }; + + Tour.prototype.ended = function() { + return !!this.getState("end"); + }; + + Tour.prototype.restart = function() { + this.removeState("current_step"); + this.removeState("end"); + this.setCurrentStep(0); + return this.start(); + }; + + Tour.prototype.hideStep = function(i) { + var hideStepHelper, promise, step, + _this = this; + step = this.getStep(i); + promise = this._makePromise(step.onHide != null ? step.onHide(this, i) : void 0); + hideStepHelper = function(e) { + var $element; + $element = _this._isOrphan(step) ? $("body") : $(step.element); + $element.popover("destroy"); + if (step.reflex) { + $element.css("cursor", "").off("click.tour." + _this._options.name); + } + if (step.backdrop) { + _this._hideBackdrop(); + } + if (step.onHidden != null) { + return step.onHidden(_this); + } + }; + this._callOnPromiseDone(promise, hideStepHelper); + return promise; + }; + + Tour.prototype.showStep = function(i) { + var promise, showStepHelper, skipToPrevious, step, + _this = this; + step = this.getStep(i); + if (!step) { + return; + } + skipToPrevious = i < this._current; + promise = this._makePromise(step.onShow != null ? step.onShow(this, i) : void 0); + showStepHelper = function(e) { + var current_path, path; + _this.setCurrentStep(i); + path = $.isFunction(step.path) ? step.path.call() : _this._options.basePath + step.path; + current_path = [document.location.pathname, document.location.hash].join(""); + if (_this._isRedirect(path, current_path)) { + _this._redirect(step, path); + return; + } + if (_this._isOrphan(step)) { + if (!step.orphan) { + _this._debug("Skip the orphan step " + (_this._current + 1) + ". Orphan option is false and the element doesn't exist or is hidden."); + if (skipToPrevious) { + _this._showPrevStep(); + } else { + _this._showNextStep(); + } + return; + } + _this._debug("Show the orphan step " + (_this._current + 1) + ". Orphans option is true."); + } + if (step.backdrop) { + _this._showBackdrop(!_this._isOrphan(step) ? step.element : void 0); + } + _this._showPopover(step, i); + if (step.onShown != null) { + step.onShown(_this); + } + return _this._debug("Step " + (_this._current + 1) + " of " + _this._steps.length); + }; + return this._callOnPromiseDone(promise, showStepHelper); + }; + + Tour.prototype.setCurrentStep = function(value) { + if (value != null) { + this._current = value; + return this.setState("current_step", value); + } else { + this._current = this.getState("current_step"); + return this._current = this._current === null ? 0 : parseInt(this._current, 10); + } + }; + + Tour.prototype._showNextStep = function() { + var promise, showNextStepHelper, step, + _this = this; + step = this.getStep(this._current); + showNextStepHelper = function(e) { + return _this.showStep(step.next); + }; + promise = this._makePromise((step.onNext != null ? step.onNext(this) : void 0)); + return this._callOnPromiseDone(promise, showNextStepHelper); + }; + + Tour.prototype._showPrevStep = function() { + var promise, showPrevStepHelper, step, + _this = this; + step = this.getStep(this._current); + showPrevStepHelper = function(e) { + return _this.showStep(step.prev); + }; + promise = this._makePromise((step.onPrev != null ? step.onPrev(this) : void 0)); + return this._callOnPromiseDone(promise, showPrevStepHelper); + }; + + Tour.prototype._debug = function(text) { + if (this._options.debug) { + return window.console.log("Bootstrap Tour '" + this._options.name + "' | " + text); + } + }; + + Tour.prototype._isRedirect = function(path, currentPath) { + return (path != null) && path !== "" && path.replace(/\?.*$/, "").replace(/\/?$/, "") !== currentPath.replace(/\/?$/, ""); + }; + + Tour.prototype._redirect = function(step, path) { + if ($.isFunction(step.redirect)) { + return step.redirect.call(this, path); + } else if (step.redirect === true) { + this._debug("Redirect to " + path); + return document.location.href = path; + } + }; + + Tour.prototype._isOrphan = function(step) { + return (step.element == null) || !$(step.element).length || $(step.element).is(":hidden"); + }; + + Tour.prototype._showPopover = function(step, i) { + var $element, $navigation, $template, $tip, isOrphan, options, + _this = this; + options = $.extend({}, this._options); + $template = $.isFunction(step.template) ? $(step.template(i, step)) : $(step.template); + $navigation = $template.find(".popover-navigation"); + isOrphan = this._isOrphan(step); + if (isOrphan) { + step.element = "body"; + step.placement = "top"; + $template = $template.addClass("orphan"); + } + $element = $(step.element); + $template.addClass("tour-" + this._options.name); + if (step.options) { + $.extend(options, step.options); + } + if (step.reflex) { + $element.css("cursor", "pointer").on("click.tour." + this._options.name, function(e) { + if (_this._current < _this._steps.length - 1) { + return _this.next(); + } else { + return _this.end(); + } + }); + } + if (step.prev < 0) { + $navigation.find("*[data-role=prev]").addClass("disabled"); + } + if (step.next < 0) { + $navigation.find("*[data-role=next]").addClass("disabled"); + } + step.template = $template.clone().wrap("
").parent().html(); + $element.popover({ + placement: step.placement, + trigger: "manual", + title: step.title, + content: step.content, + html: true, + animation: step.animation, + container: step.container, + template: step.template, + selector: step.element + }).popover("show"); + $tip = $element.data("bs.popover") ? $element.data("bs.popover").tip() : $element.data("popover").tip(); + $tip.attr("id", step.id); + this._scrollIntoView($tip); + this._reposition($tip, step); + if (isOrphan) { + return this._center($tip); + } + }; + + Tour.prototype._reposition = function($tip, step) { + var offsetBottom, offsetHeight, offsetRight, offsetWidth, originalLeft, originalTop, tipOffset; + offsetWidth = $tip[0].offsetWidth; + offsetHeight = $tip[0].offsetHeight; + tipOffset = $tip.offset(); + originalLeft = tipOffset.left; + originalTop = tipOffset.top; + offsetBottom = $(document).outerHeight() - tipOffset.top - $tip.outerHeight(); + if (offsetBottom < 0) { + tipOffset.top = tipOffset.top + offsetBottom; + } + offsetRight = $("html").outerWidth() - tipOffset.left - $tip.outerWidth(); + if (offsetRight < 0) { + tipOffset.left = tipOffset.left + offsetRight; + } + if (tipOffset.top < 0) { + tipOffset.top = 0; + } + if (tipOffset.left < 0) { + tipOffset.left = 0; + } + $tip.offset(tipOffset); + if (step.placement === "bottom" || step.placement === "top") { + if (originalLeft !== tipOffset.left) { + return this._replaceArrow($tip, (tipOffset.left - originalLeft) * 2, offsetWidth, "left"); + } + } else { + if (originalTop !== tipOffset.top) { + return this._replaceArrow($tip, (tipOffset.top - originalTop) * 2, offsetHeight, "top"); + } + } + }; + + Tour.prototype._center = function($tip) { + return $tip.css("top", $(window).outerHeight() / 2 - $tip.outerHeight() / 2); + }; + + Tour.prototype._replaceArrow = function($tip, delta, dimension, position) { + return $tip.find(".arrow").css(position, delta ? 50 * (1 - delta / dimension) + "%" : ""); + }; + + Tour.prototype._scrollIntoView = function(tip) { + return $("html, body").stop().animate({ + scrollTop: Math.ceil(tip.offset().top - ($(window).height() / 2)) + }); + }; + + Tour.prototype._onResize = function(callback, timeout) { + return $(window).on("resize.tour." + this._options.name, function() { + clearTimeout(timeout); + return timeout = setTimeout(callback, 100); + }); + }; + + Tour.prototype._setupKeyboardNavigation = function() { + var _this = this; + if (this._options.keyboard) { + return $(document).on("keyup.tour." + this._options.name, function(e) { + if (!e.which) { + return; + } + switch (e.which) { + case 39: + e.preventDefault(); + if (_this._current < _this._steps.length - 1) { + return _this.next(); + } else { + return _this.end(); + } + break; + case 37: + e.preventDefault(); + if (_this._current > 0) { + return _this.prev(); + } + break; + case 27: + e.preventDefault(); + return _this.end(); + } + }); + } + }; + + Tour.prototype._makePromise = function(result) { + if (result && $.isFunction(result.then)) { + return result; + } else { + return null; + } + }; + + Tour.prototype._callOnPromiseDone = function(promise, cb, arg) { + var _this = this; + if (promise) { + return promise.then(function(e) { + return cb.call(_this, arg); + }); + } else { + return cb.call(this, arg); + } + }; + + Tour.prototype._showBackdrop = function(element) { + if (this.backdrop.overlay !== null) { + return; + } + this._showOverlay(); + if (element != null) { + return this._showOverlayElement(element); + } + }; + + Tour.prototype._hideBackdrop = function() { + if (this.backdrop.overlay === null) { + return; + } + if (this.backdrop.$element) { + this._hideOverlayElement(); + } + return this._hideOverlay(); + }; + + Tour.prototype._showOverlay = function() { + this.backdrop = $("
"); + this.backdrop.addClass("tour-backdrop"); + this.backdrop.height($(document).innerHeight()); + return $("body").append(this.backdrop); + }; + + Tour.prototype._hideOverlay = function() { + this.backdrop.remove(); + return this.backdrop.overlay = null; + }; + + Tour.prototype._showOverlayElement = function(element) { + var $background, $element, offset; + $element = $(element); + $background = $("
"); + offset = $element.offset(); + offset.top = offset.top; + offset.left = offset.left; + $background.width($element.innerWidth()).height($element.innerHeight()).addClass("tour-step-background").offset(offset); + $element.addClass("tour-step-backdrop"); + $("body").append($background); + this.backdrop.$element = $element; + return this.backdrop.$background = $background; + }; + + Tour.prototype._hideOverlayElement = function() { + this.backdrop.$element.removeClass("tour-step-backdrop"); + this.backdrop.$background.remove(); + this.backdrop.$element = null; + return this.backdrop.$background = null; + }; + + return Tour; + + })(); + return window.Tour = Tour; + })(jQuery, window); + +}).call(this); diff --git a/addons/website/static/lib/bootstrap-tour/js/jquery.smoothscroll.js b/addons/website/static/lib/bootstrap-tour/js/jquery.smoothscroll.js new file mode 100644 index 00000000000..9c71e5032e9 --- /dev/null +++ b/addons/website/static/lib/bootstrap-tour/js/jquery.smoothscroll.js @@ -0,0 +1,47 @@ +/*! http://mths.be/smoothscroll v1.5.2 by @mathias */ +; +(function(document, $) { + + var $scrollElement = (function() { + // Find out what to scroll (html or body) + var $html = $(document.documentElement), + $body = $(document.body), + bodyScrollTop; + if ($html.scrollTop()) { + return $html; + } else { + bodyScrollTop = $body.scrollTop(); + // If scrolling the body doesn’t do anything + if ($body.scrollTop(bodyScrollTop + 1).scrollTop() == bodyScrollTop) { + return $html; + } else { + // We actually scrolled, so undo it + return $body.scrollTop(bodyScrollTop); + } + } + }()); + + $.fn.smoothScroll = function(speed) { + speed = ~~speed || 400; + // Look for links to anchors (on any page) + return this.find('a[href*="#"]').click(function(event) { + var hash = this.hash, + $hash = $(hash); // The in-document element the link points to + // If it’s a link to an anchor in the same document + if (location.pathname.replace(/^\//, '') === this.pathname.replace(/^\//, '') && location.hostname === this.hostname) { + // If the anchor actually exists… + if ($hash.length) { + // …don’t jump to the link right away… + event.preventDefault(); + // …and smoothly scroll to it + $scrollElement.stop().animate({ + 'scrollTop': $hash.offset().top + }, speed, function() { + location.hash = hash; + }); + } + } + }).end(); + }; + +}(document, jQuery)); \ No newline at end of file diff --git a/addons/website/static/lib/bootstrap-tour/js/prism.js b/addons/website/static/lib/bootstrap-tour/js/prism.js new file mode 100644 index 00000000000..26c9e8beba8 --- /dev/null +++ b/addons/website/static/lib/bootstrap-tour/js/prism.js @@ -0,0 +1,8 @@ +/** + * Prism: Lightweight, robust, elegant syntax highlighting + * MIT license http://www.opensource.org/licenses/mit-license.php/ + * @author Lea Verou http://lea.verou.me + */(function(){var e=/\blang(?:uage)?-(?!\*)(\w+)\b/i,t=self.Prism={util:{type:function(e){return Object.prototype.toString.call(e).match(/\[object (\w+)\]/)[1]},clone:function(e){var n=t.util.type(e);switch(n){case"Object":var r={};for(var i in e)e.hasOwnProperty(i)&&(r[i]=t.util.clone(e[i]));return r;case"Array":return e.slice()}return e}},languages:{extend:function(e,n){var r=t.util.clone(t.languages[e]);for(var i in n)r[i]=n[i];return r},insertBefore:function(e,n,r,i){i=i||t.languages;var s=i[e],o={};for(var u in s)if(s.hasOwnProperty(u)){if(u==n)for(var a in r)r.hasOwnProperty(a)&&(o[a]=r[a]);o[u]=s[u]}return i[e]=o},DFS:function(e,n){for(var r in e){n.call(e,r,e[r]);t.util.type(e)==="Object"&&t.languages.DFS(e[r],n)}}},highlightAll:function(e,n){var r=document.querySelectorAll('code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code');for(var i=0,s;s=r[i++];)t.highlightElement(s,e===!0,n)},highlightElement:function(r,i,s){var o,u,a=r;while(a&&!e.test(a.className))a=a.parentNode;if(a){o=(a.className.match(e)||[,""])[1];u=t.languages[o]}if(!u)return;r.className=r.className.replace(e,"").replace(/\s+/g," ")+" language-"+o;a=r.parentNode;/pre/i.test(a.nodeName)&&(a.className=a.className.replace(e,"").replace(/\s+/g," ")+" language-"+o);var f=r.textContent;if(!f)return;f=f.replace(/&/g,"&").replace(/e.length)break e;if(p instanceof i)continue;a.lastIndex=0;var d=a.exec(p);if(d){l&&(c=d[1].length);var v=d.index-1+c,d=d[0].slice(c),m=d.length,g=v+m,y=p.slice(0,v+1),b=p.slice(g+1),w=[h,1];y&&w.push(y);var E=new i(u,f?t.tokenize(d,f):d);w.push(E);b&&w.push(b);Array.prototype.splice.apply(s,w)}}}return s},hooks:{all:{},add:function(e,n){var r=t.hooks.all;r[e]=r[e]||[];r[e].push(n)},run:function(e,n){var r=t.hooks.all[e];if(!r||!r.length)return;for(var i=0,s;s=r[i++];)s(n)}}},n=t.Token=function(e,t){this.type=e;this.content=t};n.stringify=function(e,r,i){if(typeof e=="string")return e;if(Object.prototype.toString.call(e)=="[object Array]")return e.map(function(t){return n.stringify(t,r,e)}).join("");var s={type:e.type,content:n.stringify(e.content,r,i),tag:"span",classes:["token",e.type],attributes:{},language:r,parent:i};s.type=="comment"&&(s.attributes.spellcheck="true");t.hooks.run("wrap",s);var o="";for(var u in s.attributes)o+=u+'="'+(s.attributes[u]||"")+'"';return"<"+s.tag+' class="'+s.classes.join(" ")+'" '+o+">"+s.content+""};if(!self.document){self.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,i=n.code;self.postMessage(JSON.stringify(t.tokenize(i,t.languages[r])));self.close()},!1);return}var r=document.getElementsByTagName("script");r=r[r.length-1];if(r){t.filename=r.src;document.addEventListener&&!r.hasAttribute("data-manual")&&document.addEventListener("DOMContentLoaded",t.highlightAll)}})();; +Prism.languages.markup={comment:/<!--[\w\W]*?-->/g,prolog:/<\?.+?\?>/,doctype:/<!DOCTYPE.+?>/,cdata:/<!\[CDATA\[[\w\W]*?]]>/i,tag:{pattern:/<\/?[\w:-]+\s*(?:\s+[\w:-]+(?:=(?:("|')(\\?[\w\W])*?\1|\w+))?\s*)*\/?>/gi,inside:{tag:{pattern:/^<\/?[\w:-]+/i,inside:{punctuation:/^<\/?/,namespace:/^[\w-]+?:/}},"attr-value":{pattern:/=(?:('|")[\w\W]*?(\1)|[^\s>]+)/gi,inside:{punctuation:/=|>|"/g}},punctuation:/\/?>/g,"attr-name":{pattern:/[\w:-]+/g,inside:{namespace:/^[\w-]+?:/}}}},entity:/&#?[\da-z]{1,8};/gi};Prism.hooks.add("wrap",function(e){e.type==="entity"&&(e.attributes.title=e.content.replace(/&/,"&"))});; +Prism.languages.clike={comment:{pattern:/(^|[^\\])(\/\*[\w\W]*?\*\/|(^|[^:])\/\/.*?(\r?\n|$))/g,lookbehind:!0},string:/("|')(\\?.)*?\1/g,"class-name":{pattern:/((?:(?:class|interface|extends|implements|trait|instanceof|new)\s+)|(?:catch\s+\())[a-z0-9_\.\\]+/ig,lookbehind:!0,inside:{punctuation:/(\.|\\)/}},keyword:/\b(if|else|while|do|for|return|in|instanceof|function|new|try|catch|finally|null|break|continue)\b/g,"boolean":/\b(true|false)\b/g,"function":{pattern:/[a-z0-9_]+\(/ig,inside:{punctuation:/\(/}}, number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?)\b/g,operator:/[-+]{1,2}|!|<=?|>=?|={1,3}|(&){1,2}|\|?\||\?|\*|\/|\~|\^|\%/g,ignore:/&(lt|gt|amp);/gi,punctuation:/[{}[\];(),.:]/g};; +Prism.languages.javascript=Prism.languages.extend("clike",{keyword:/\b(var|let|if|else|while|do|for|return|in|instanceof|function|new|with|typeof|try|catch|finally|null|break|continue)\b/g,number:/\b-?(0x[\dA-Fa-f]+|\d*\.?\d+([Ee]-?\d+)?|NaN|-?Infinity)\b/g});Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/(^|[^/])\/(?!\/)(\[.+?]|\\.|[^/\r\n])+\/[gim]{0,3}(?=\s*($|[\r\n,.;})]))/g,lookbehind:!0}});Prism.languages.markup&&Prism.languages.insertBefore("markup","tag",{script:{pattern:/(<|<)script[\w\W]*?(>|>)[\w\W]*?(<|<)\/script(>|>)/ig,inside:{tag:{pattern:/(<|<)script[\w\W]*?(>|>)|(<|<)\/script(>|>)/ig,inside:Prism.languages.markup.tag.inside},rest:Prism.languages.javascript}}});; diff --git a/addons/website/static/src/js/website.seo.js b/addons/website/static/src/js/website.seo.js index 49cc65e1b09..c2c2ce16d9a 100644 --- a/addons/website/static/src/js/website.seo.js +++ b/addons/website/static/src/js/website.seo.js @@ -1,6 +1,6 @@ (function () { 'use strict'; - + var website = openerp.website; website.templates.push('/website/static/src/xml/website.seo.xml'); diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js new file mode 100644 index 00000000000..022ec4b6ffb --- /dev/null +++ b/addons/website/static/src/js/website.tour.js @@ -0,0 +1,72 @@ + +(function() { + var website = openerp.website; + website.Tour = openerp.Class.extend({ + template: 'website.tour', + init: function () { + this.template = "
\ +
\ +

\ +
\ + \ +
" + + }, + start: function(){ + this.tour = new this.init_plugin(); + this.add_step(); + this.tour.restart(true); + }, + add_step: function(){ + this.tour.addSteps([ + { + element: "header", + placement: "bottom", + title: "Welcome to your website!", + content: "This tutorial will guide you through the firsts steps to build your enterprise class website.", + },{ + element: '.navbar-header:first', + placement: "bottom", + title: "Edit this page", + content: "Every page of your website can be edited. Click the button to modify your homepage.", + } + ]); + }, + init_plugin: function(){ + return new Tour({ + name: "tour", + container: "body", + keyboard: true, + storage: window.localStorage, + debug: true, + backdrop: false, + redirect: true, + orphan: true, + basePath: "", + template: this.template, + afterGetState: function(key, value) {}, + afterSetState: function(key, value) {}, + afterRemoveState: function(key, value) {}, + onStart: function(tour) {}, + onEnd: function(tour) {}, + onShow: function(tour) {}, + onShown: function(tour) {}, + onHide: function(tour) {}, + onHidden: function(tour) {}, + onNext: function(tour){}, + onPrev: function(tour) {} + }); + } + + }); + $(document).ready(function () { + if (window.location.href.indexOf("?tutorial=true") != -1) { + var Tour = new website.Tour().start() + } + }); +}).call(this); \ No newline at end of file diff --git a/addons/website/static/src/xml/website.tour.xml b/addons/website/static/src/xml/website.tour.xml new file mode 100644 index 00000000000..91a4b3f682d --- /dev/null +++ b/addons/website/static/src/xml/website.tour.xml @@ -0,0 +1,16 @@ + + + +
+
+

+
+ +
+
+
\ No newline at end of file diff --git a/addons/website/views/views.xml b/addons/website/views/views.xml index 08415623421..c2ea608a097 100644 --- a/addons/website/views/views.xml +++ b/addons/website/views/views.xml @@ -25,6 +25,15 @@ + + + + + + + + + @@ -54,6 +63,7 @@ + From 1072bbce1d21125833cd5392e212d10f1823f2b4 Mon Sep 17 00:00:00 2001 From: Vidhin Mehta Date: Mon, 23 Sep 2013 11:58:07 +0530 Subject: [PATCH 2/8] [FIX]some library path. bzr revid: vme@tinyerp.com-20130923062807-m7z6o6ay7odcw612 --- addons/website/static/src/js/website.tour.js | 3 +-- addons/website/views/views.xml | 9 ++------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index 022ec4b6ffb..2dd38ac841d 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -62,11 +62,10 @@ onPrev: function(tour) {} }); } - }); $(document).ready(function () { if (window.location.href.indexOf("?tutorial=true") != -1) { - var Tour = new website.Tour().start() + var Tour = new website.Tour().start(); } }); }).call(this); \ No newline at end of file diff --git a/addons/website/views/views.xml b/addons/website/views/views.xml index c2ea608a097..0a08bc2b940 100644 --- a/addons/website/views/views.xml +++ b/addons/website/views/views.xml @@ -26,13 +26,8 @@ - - - - - - - + + From 74b67c684e742472a6ebcd5a9c6f7bebe4d71112 Mon Sep 17 00:00:00 2001 From: Vidhin Mehta Date: Thu, 26 Sep 2013 15:59:53 +0530 Subject: [PATCH 3/8] [FIX] bzr revid: vme@tinyerp.com-20130926102953-27564q9jy4ydhh66 --- addons/website/views/views.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/website/views/views.xml b/addons/website/views/views.xml index 83354c20945..effebc221f3 100644 --- a/addons/website/views/views.xml +++ b/addons/website/views/views.xml @@ -53,6 +53,7 @@ + From 333ba6959986989041f3251a409c973a28fb73ba Mon Sep 17 00:00:00 2001 From: Vidhin Mehta Date: Thu, 26 Sep 2013 16:22:42 +0530 Subject: [PATCH 4/8] [TEST] for second task bzr revid: vme@tinyerp.com-20130926105242-gza93fwh0vcoucid --- addons/website/static/src/css/website.css | 23 +++++++++++++++++++++++ addons/website/views/views.xml | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/addons/website/static/src/css/website.css b/addons/website/static/src/css/website.css index 20a0968347a..0b74e330026 100644 --- a/addons/website/static/src/css/website.css +++ b/addons/website/static/src/css/website.css @@ -215,6 +215,29 @@ footer { padding-bottom: 12px; } +.oe_structure.oe_empty_edit:empty, [data-oe-type=html]:empty, .oe_structure.oe_empty_edit > .oe_drop_zone.oe_insert:only-child, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child { + background-image: url("/web/static/src/img/view_empty_arrow.png"); + background-repeat: no-repeat; + background-position: left top; + height: 200px !important; +} + +.oe_structure.oe_empty_edit > .oe_drop_zone.oe_insert:only-child, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child { + position: static; +} + +.oe_structure.oe_empty_edit:empty:before, [data-oe-type=html]:empty:before, .oe_structure.oe_empty_edit > .oe_drop_zone.oe_insert:only-child:before, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child:before { + content: "Click here to build you website and edit the content"; + text-align: left; + display: block; + padding-top: 60px; + padding-bottom: 50px; + padding-left: 90px; + color: grey; + font-size: 24px; +} + + /* ---- HACK FOR COVERING UP CK EDITOR BOGUS P INSERTION --- */ .oe_structure.oe_empty:empty, [data-oe-type=html]:empty, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child { background-image: url("/website/static/src/img/drag_here.png"); diff --git a/addons/website/views/views.xml b/addons/website/views/views.xml index effebc221f3..9f24e9469a2 100644 --- a/addons/website/views/views.xml +++ b/addons/website/views/views.xml @@ -192,7 +192,7 @@ From a0894db0530a4419f8f1478bfd4b5c514efb66a7 Mon Sep 17 00:00:00 2001 From: ddm Date: Wed, 9 Oct 2013 14:39:27 +0200 Subject: [PATCH 5/8] [IMP] Tour copyediting bzr revid: ddm@openerp.com-20131009123927-ls48qe49mmc4b0x9 --- addons/website/static/src/js/website.tour.js | 35 ++++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index 34f3948ef60..b2ca10141fc 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -77,7 +77,7 @@ backdrop: true, title: "Welcome to your website!", content: "This tutorial will guide you through the firsts steps to build your enterprise class website.", - template: render('website.tour_full', { next: "OK", end: "Close" }), + template: render('website.tour_full', { next: "Continue", end: "Close Tutorial" }), }, { stepId: 'edit-page', @@ -85,32 +85,31 @@ placement: 'right', reflex: true, title: "Edit this page", - content: "Every page of your website can be edited. Click the Edit button to modify your homepage.", + content: "Every page of your website can be edited. Click the Edit button to modify your homepage.", template: render('website.tour_simple'), }, { - stepId: 'show-bar', - element: '#website-top-navbar', - placement: 'bottom', - title: "Editor bar", - content: "This is the Editor Bar, use it to modify your website's pages.", - template: render('website.tour_confirm', { next: "OK" }), + stepId: 'add-banner', + orphan: true, + title: "Now, let's add a banner", + content: "Let's add a banner on the top of the page to make your homepage look more attractive.", + template: render('website.tour_confirm', { next: "Continue" }), }, { stepId: 'add-block', element: 'button[data-action=snippet]', placement: 'right', reflex: true, - title: "Add a block to your page", - content: "Click on the Insert Blocks button to open the block collection.", + title: "Shows Building Blocks", + content: "Click on the Insert Blocks button to show the available building blocks.", template: render('website.tour_simple'), }, { stepId: 'drag-banner', element: '#website-top-navbar [data-snippet-id=carousel]', placement: 'bottom', - title: "Add a banner to your page", - content: "Drag the Banner block to the body of the page and drop it on a purple zone.", + title: "Drag & Drop a Banner", + content: "Drag the Banner block and drop it to the top of your page (purple zone).", template: render('website.tour_simple'), onShown: function () { function beginDrag () { @@ -130,8 +129,8 @@ stepId: 'edit-title', element: '#wrap [data-snippet-id=carousel]:first .carousel-caption', placement: 'top', - title: "Change the title", - content: "Click on the title and modify it to fit your needs then click Done.", + title: "Set your Banner text", + content: "Click on the text to start modifying it then click Done to continue the tutorial.
You can also use the options of the top menubar to change the look of the banner. ", template: render('website.tour_confirm', { next: "Done" }), onHide: function () { var $banner = $("#wrap [data-snippet-id=carousel]:first"); @@ -144,8 +143,8 @@ stepId: 'customize-banner', element: '.oe_overlay_options .oe_options', placement: 'left', - title: "Customize the banner", - content: "Click on Customize and change the background of your banner.", + title: "Customize your new Banner style", + content: "Click on Customize and change the background of your banner.", template: render('website.tour_confirm', { next: "Not now" }), onShow: function () { $('.dropdown-menu [name=carousel-background]').click(function () { @@ -159,7 +158,7 @@ placement: 'right', reflex: true, title: "Save your modifications", - content: "Click the Save button to apply modifications on your website.", + content: "Click the Save button to apply modifications on your website.", template: render('website.tour_simple'), onHide: function () { self.saveStep('part-2'); @@ -178,7 +177,7 @@ element: '#help-menu-button', placement: 'left', title: "Help is always available", - content: "You can find more tutorials in the Help menu.", + content: "You can find more tutorials in the Help menu.", template: render('website.tour_end', { end: "Close" }), }, ]; From 75bf46996c0e7b782f43c782a25adf6edef293b8 Mon Sep 17 00:00:00 2001 From: ddm Date: Wed, 9 Oct 2013 17:20:15 +0200 Subject: [PATCH 6/8] [FIX] Tour reset bug bzr revid: ddm@openerp.com-20131009152015-s2p3hjkivls16yk2 --- addons/website/static/src/css/editor.css | 16 ++++------------ addons/website/static/src/css/editor.sass | 3 ++- addons/website/static/src/js/website.tour.js | 19 +++++++++++++------ .../website/static/src/xml/website.tour.xml | 8 ++++---- 4 files changed, 23 insertions(+), 23 deletions(-) diff --git a/addons/website/static/src/css/editor.css b/addons/website/static/src/css/editor.css index 9e363448103..0368995185d 100644 --- a/addons/website/static/src/css/editor.css +++ b/addons/website/static/src/css/editor.css @@ -564,18 +564,6 @@ table.editorbar-panel td.selected { -o-border-radius: 0.4em; border-radius: 0.4em; } -.oe_seo_configuration .keyword-in-title { - background-color: #5cb85cpointer; - color: white; -} -.oe_seo_configuration .keyword-in-description { - background-color: #428bca; - color: white; -} -.oe_seo_configuration .keyword-in-body { - background-color: #5bc0de; - color: white; -} /* ---- ACE EDITOR ---- */ .oe_ace_view_editor { @@ -634,6 +622,10 @@ table.editorbar-panel td.selected { } /* ---- EDITOR TOUR ---- */ +div.tour-backdrop { + z-index: 2009; +} + .popover.tour { z-index: 2010; } diff --git a/addons/website/static/src/css/editor.sass b/addons/website/static/src/css/editor.sass index 6eab4f6fb32..26838496cc8 100644 --- a/addons/website/static/src/css/editor.sass +++ b/addons/website/static/src/css/editor.sass @@ -479,7 +479,8 @@ $navbar_height: 51px +opacity(0) /* ---- EDITOR TOUR ---- */ - +div.tour-backdrop + z-index: 2009 .popover.tour z-index: 2010 // vim:tabstop=4:shiftwidth=4:softtabstop=4:fdm=marker: diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index b2ca10141fc..cfb2dd72007 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -26,6 +26,7 @@ reset: function () { this.tourStorage.removeItem(this.id+'_current_step'); this.tourStorage.removeItem(this.id+'_end'); + this.tour._current = 0; $('.popover.tour').remove(); }, start: function () { @@ -34,7 +35,7 @@ } }, canResume: function () { - return this.currentStepIndex() === 0 && !this.tour.ended(); + return (this.currentStepIndex() === 0) && !this.tour.ended(); }, currentStepIndex: function () { var index = this.tourStorage.getItem(this.id+'_current_step') || 0; @@ -91,8 +92,9 @@ { stepId: 'add-banner', orphan: true, + backdrop: true, title: "Now, let's add a banner", - content: "Let's add a banner on the top of the page to make your homepage look more attractive.", + content: "Let's add a banner on the top of the page to make your homepage more attractive.", template: render('website.tour_confirm', { next: "Continue" }), }, { @@ -130,8 +132,8 @@ element: '#wrap [data-snippet-id=carousel]:first .carousel-caption', placement: 'top', title: "Set your Banner text", - content: "Click on the text to start modifying it then click Done to continue the tutorial.
You can also use the options of the top menubar to change the look of the banner. ", - template: render('website.tour_confirm', { next: "Done" }), + content: "Click on the text to start modifying it then click Continue to continue the tutorial.
You can also use the options of the top menubar to change the look of the banner. ", + template: render('website.tour_confirm', { next: "Continue" }), onHide: function () { var $banner = $("#wrap [data-snippet-id=carousel]:first"); if ($banner.length) { @@ -144,8 +146,8 @@ element: '.oe_overlay_options .oe_options', placement: 'left', title: "Customize your new Banner style", - content: "Click on Customize and change the background of your banner.", - template: render('website.tour_confirm', { next: "Not now" }), + content: "Click on Customize and change the background of your banner.
If your are satisfied with the current background, just click Continue.", + template: render('website.tour_confirm', { next: "Continue" }), onShow: function () { $('.dropdown-menu [name=carousel-background]').click(function () { self.movetoStep('save-changes'); @@ -168,6 +170,7 @@ { stepId: 'part-2', orphan: true, + backdrop: true, title: "Congratutaltions!", content: "Congratulations on your first modifications.", template: render('website.tour_confirm', { next: "OK" }), @@ -226,6 +229,10 @@ if (url.search === '?tutorial=true' || website.tutorials.basic.startOfPart2()) { website.tutorials.basic.start(); } + $('.tour-backdrop').click(function (e) { + e.stopImmediatePropagation(); + e.preventDefault(); + }); return this._super(); }, }); diff --git a/addons/website/static/src/xml/website.tour.xml b/addons/website/static/src/xml/website.tour.xml index 6d2ef140610..b9398340983 100644 --- a/addons/website/static/src/xml/website.tour.xml +++ b/addons/website/static/src/xml/website.tour.xml @@ -13,7 +13,7 @@

@@ -23,7 +23,7 @@

@@ -33,8 +33,8 @@

From 9ba56d0d71a931f30040f63d3094daaa28606dbf Mon Sep 17 00:00:00 2001 From: ddm Date: Wed, 9 Oct 2013 18:09:49 +0200 Subject: [PATCH 7/8] [IMP] Finish tour according to kanban task bzr revid: ddm@openerp.com-20131009160949-ma5e3a13qchzq4vy --- .../website/static/src/js/website.editor.js | 3 +- addons/website/static/src/js/website.tour.js | 29 +++++++++++++++++-- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index f40ccea715b..7d3ebc74321 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -203,8 +203,9 @@ } }); // Adding Static Menus - menu.append('
  • Change Theme
  • '); + menu.append('
  • Change Theme
  • '); menu.append('
  • Advanced view editor
  • '); + self.trigger('rte:customize_menu_ready'); } ); }); diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index cfb2dd72007..147ed80c50c 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -69,7 +69,7 @@ website.EditorBasicTour = website.EditorTour.extend({ id: 'add_banner_tour', name: "How to add a banner", - init: function () { + init: function (editor) { var self = this; self.steps = [ { @@ -175,6 +175,28 @@ content: "Congratulations on your first modifications.", template: render('website.tour_confirm', { next: "OK" }), }, + { + stepId: 'show-customize', + element: '#customize-menu-button', + placement: 'left', + title: "Customize your Website", + content: "Go on the Customize menu to get access customization options for the current page.", + template: render('website.tour_simple'), + onShow: function () { + editor.on('rte:customize_menu_ready', self, function () { + self.movetoStep('change-themes'); + }); + }, + }, + { + stepId: 'change-themes', + element: '.js_change_theme', + placement: 'left', + reflex: true, + title: "Click to View Themes", + content: "You can change the theme at any time to customize the look and feel of your website.", + template: render('website.tour_simple'), + }, { stepId: 'show-tutorials', element: '#help-menu-button', @@ -189,7 +211,8 @@ startOfPart2: function () { var currentStepIndex = this.currentStepIndex(); var secondPartIndex = this.indexOfStep('part-2'); - return currentStepIndex === secondPartIndex && !this.tour.ended(); + var showTutorialsIndex = this.indexOfStep('show-tutorials'); + return (currentStepIndex === secondPartIndex || currentStepIndex === showTutorialsIndex) && !this.tour.ended(); }, canResume: function () { return this.startOfPart2() || this._super(); @@ -214,7 +237,7 @@ website.EditorBar.include({ start: function () { website.tutorials = { - basic: new website.EditorBasicTour(), + basic: new website.EditorBasicTour(this), }; var menu = $('#help-menu'); _.each(website.tutorials, function (tutorial) { From 0ca2b26ead126c240311e6f028a515ae726ec1d0 Mon Sep 17 00:00:00 2001 From: ddm Date: Wed, 9 Oct 2013 18:31:14 +0200 Subject: [PATCH 8/8] [IMP] Better 'close' caption bzr revid: ddm@openerp.com-20131009163114-jl3v5757fcwmh010 --- addons/website/static/src/xml/website.tour.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/website/static/src/xml/website.tour.xml b/addons/website/static/src/xml/website.tour.xml index b9398340983..75ffe0fe505 100644 --- a/addons/website/static/src/xml/website.tour.xml +++ b/addons/website/static/src/xml/website.tour.xml @@ -13,7 +13,7 @@

    @@ -23,7 +23,7 @@

    @@ -33,12 +33,12 @@

    - + \ No newline at end of file