[MERGE] upstream
bzr revid: fme@openerp.com-20140122102232-77lvvwpzet58sa7p
This commit is contained in:
commit
df63fcba81
|
@ -23,7 +23,7 @@
|
|||
<button type="image" name="submit" width="100px"
|
||||
t-att-class="submit_class">
|
||||
<img t-if="not submit_txt" src="/payment_acquirer_adyen/static/src/img/adyen_icon.png"/>
|
||||
<span t-if="submit_txt"><t t-esc="submit_txt"/></span>
|
||||
<span t-if="submit_txt"><t t-esc="submit_txt"/> <span class="fa fa-long-arrow-right"/></span>
|
||||
</button>
|
||||
</form>
|
||||
</template>
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<button type="image" name="submit" width="100px"
|
||||
t-att-class="submit_class">
|
||||
<img t-if="not submit_txt" src="/payment_acquirer_ogone/static/src/img/ogone_icon.png"/>
|
||||
<span t-if="submit_txt"><t t-esc="submit_txt"/></span>
|
||||
<span t-if="submit_txt"><t t-esc="submit_txt"/> <span class="fa fa-long-arrow-right"/></span>
|
||||
</button>
|
||||
</form>
|
||||
</template>
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
<button type="image" name="submit" width="100px"
|
||||
t-att-class="submit_class">
|
||||
<img t-if="not submit_txt" src="/payment_acquirer_paypal/static/src/img/paypal_icon.png"/>
|
||||
<span t-if="submit_txt"><t t-esc="submit_txt"/></span>
|
||||
<span t-if="submit_txt"><t t-esc="submit_txt"/> <span class="fa fa-long-arrow-right"/></span>
|
||||
</button>
|
||||
</form>
|
||||
</template>
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<button type="image" name="submit" width="100px"
|
||||
t-att-class="submit_class">
|
||||
<img t-if="not submit_txt" src="/payment_acquirer_transfer/static/src/img/transfer_icon.png"/>
|
||||
<span t-if="submit_txt"><t t-esc="submit_txt"/></span>
|
||||
<span t-if="submit_txt"><t t-esc="submit_txt"/> <span class="fa fa-long-arrow-right"/></span>
|
||||
</button>
|
||||
</form>
|
||||
</template>
|
||||
|
|
|
@ -404,11 +404,7 @@ class Contact(orm.AbstractModel):
|
|||
field_browse = self.pool[column._obj].browse(cr, openerp.SUPERUSER_ID, id, context={"show_address": True})
|
||||
value = werkzeug.utils.escape( field_browse.name_get()[0][1] )
|
||||
|
||||
IMD = self.pool["ir.model.data"]
|
||||
model, id = IMD.get_object_reference(cr, uid, "website", "contact")
|
||||
view = self.pool["ir.ui.view"].browse(cr, uid, id, context=context)
|
||||
|
||||
html = view.render({
|
||||
val = {
|
||||
'name': value.split("\n")[0],
|
||||
'address': werkzeug.utils.escape("\n".join(value.split("\n")[1:])),
|
||||
'phone': field_browse.phone,
|
||||
|
@ -417,7 +413,9 @@ class Contact(orm.AbstractModel):
|
|||
'email': field_browse.email,
|
||||
'fields': opf,
|
||||
'options': options
|
||||
}, engine='website.qweb', context=context)
|
||||
}
|
||||
|
||||
html = self.pool["ir.ui.view"].render(cr, uid, "website.contact", val, engine='website.qweb', context=context)
|
||||
|
||||
return ir_qweb.HTMLSafe(html)
|
||||
|
||||
|
|
|
@ -117,6 +117,7 @@ class website(osv.osv):
|
|||
'social_linkedin': fields.char('LinkedIn Account'),
|
||||
'social_youtube': fields.char('Youtube Account'),
|
||||
'social_googleplus': fields.char('Google+ Account'),
|
||||
'google_analytics_key': fields.char('Google Analytics Key'),
|
||||
'public_user': fields.function(_get_public_user, relation='res.users', type='many2one', string='Public User'),
|
||||
'menu_id': fields.function(_get_menu, relation='website.menu', type='many2one', string='Main Menu',
|
||||
store= {
|
||||
|
@ -322,7 +323,7 @@ class website(osv.osv):
|
|||
:type rule: werkzeug.routing.Rule
|
||||
:rtype: bool
|
||||
"""
|
||||
spec = inspect.getargspec(rule.endpoint)
|
||||
spec = inspect.getargspec(rule.endpoint.method)
|
||||
|
||||
# if *args bail the fuck out, only dragons can live there
|
||||
if spec.varargs:
|
||||
|
|
|
@ -207,6 +207,44 @@ ul.oe_menu_editor .disclose {
|
|||
visibility: visible !important;
|
||||
}
|
||||
|
||||
.modal .font-icons-icons {
|
||||
font-size: 2em;
|
||||
max-height: 6em;
|
||||
overflow: auto;
|
||||
}
|
||||
.modal .font-icons-icons .font-icons-icon {
|
||||
display: inline-block;
|
||||
width: 2em;
|
||||
padding: 0.25em;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.modal .font-icons {
|
||||
position: relative;
|
||||
display: block;
|
||||
}
|
||||
.modal .font-icons:before {
|
||||
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);
|
||||
opacity: 0.7;
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
left: 3px;
|
||||
font-size: 2em;
|
||||
}
|
||||
.modal #icon-search {
|
||||
padding-left: 2.5em;
|
||||
}
|
||||
.modal #fa-preview {
|
||||
text-align: center;
|
||||
}
|
||||
.modal #fa-preview span {
|
||||
cursor: pointer;
|
||||
padding: 0 15px;
|
||||
}
|
||||
.modal #fa-preview .font-icons-selected {
|
||||
background-color: #dddddd;
|
||||
}
|
||||
|
||||
.existing-attachments .pager .disabled {
|
||||
display: none;
|
||||
}
|
||||
|
@ -320,6 +358,56 @@ ul.oe_menu_editor .disclose {
|
|||
-o-border-radius: 0.4em;
|
||||
border-radius: 0.4em;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g {
|
||||
line-height: 1.2;
|
||||
list-style: none;
|
||||
list-style-image: none;
|
||||
list-style-position: outside;
|
||||
list-style-type: none;
|
||||
font-size: small;
|
||||
font-family: arial, sans-serif;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g h3 {
|
||||
font-size: medium;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .r {
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
-webkit-text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .r a {
|
||||
color: #1e0fbe;
|
||||
text-decoration: underline;
|
||||
text-transform: none;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .r a em {
|
||||
font-style: normal !important;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .s {
|
||||
color: #444444;
|
||||
max-width: 42em;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .kv, .oe_seo_configuration li.oe_seo_preview_g .slp {
|
||||
display: block;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .f {
|
||||
color: #666666;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .f cite {
|
||||
color: #006621;
|
||||
font-style: normal;
|
||||
font-size: 14px;
|
||||
}
|
||||
.oe_seo_configuration li.oe_seo_preview_g .st {
|
||||
line-height: 1.24;
|
||||
}
|
||||
|
||||
/* ---- ACE EDITOR ---- {{{ */
|
||||
.oe_ace_view_editor {
|
||||
|
|
|
@ -172,6 +172,43 @@ ul.oe_menu_editor
|
|||
display: inline-block !important
|
||||
visibility: visible !important
|
||||
|
||||
// fontawesome modal
|
||||
.modal
|
||||
.font-icons-icons
|
||||
font-size: 2em
|
||||
max-height: 6em
|
||||
overflow: auto
|
||||
|
||||
.font-icons-icon
|
||||
display: inline-block
|
||||
width: 2em
|
||||
padding: 0.25em
|
||||
text-align: center
|
||||
cursor: pointer
|
||||
|
||||
.font-icons
|
||||
position: relative
|
||||
display: block
|
||||
|
||||
&:before
|
||||
+opacity(0.7)
|
||||
position: absolute
|
||||
top: 2px
|
||||
left: 3px
|
||||
font-size: 2em
|
||||
#icon-search
|
||||
padding-left: 2.5em
|
||||
|
||||
#fa-preview
|
||||
text-align: center
|
||||
|
||||
span
|
||||
cursor: pointer
|
||||
padding: 0 15px
|
||||
.font-icons-selected
|
||||
background-color: #ddd
|
||||
|
||||
|
||||
.existing-attachments .pager .disabled
|
||||
display: none
|
||||
|
||||
|
@ -276,6 +313,47 @@ $highlighted_text_color: #ffffff
|
|||
.oe_seo_keyword
|
||||
padding: .2em .4em .2em .5em
|
||||
+border-radius(.4em)
|
||||
li.oe_seo_preview_g
|
||||
line-height: 1.2
|
||||
list-style: none
|
||||
list-style-image: none
|
||||
list-style-position: outside
|
||||
list-style-type: none
|
||||
font-size: small
|
||||
font-family: arial,sans-serif
|
||||
h3
|
||||
font-size: medium
|
||||
.r
|
||||
margin: 0
|
||||
font-size: 16px
|
||||
font-style: normal
|
||||
font-weight: normal
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
-webkit-text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
a
|
||||
color: rgb(30, 15, 190)
|
||||
text-decoration: underline
|
||||
text-transform: none
|
||||
em
|
||||
font-style: normal !important
|
||||
.s
|
||||
color: #444
|
||||
max-width: 42em
|
||||
.kv,.slp
|
||||
display: block
|
||||
margin-bottom: 1px
|
||||
.f
|
||||
color: #666
|
||||
margin-bottom: 1px
|
||||
cite
|
||||
color: #006621
|
||||
font-style: normal
|
||||
font-size: 14px
|
||||
.st
|
||||
line-height: 1.24
|
||||
|
||||
|
||||
// }}}
|
||||
|
||||
|
|
|
@ -463,6 +463,10 @@
|
|||
$(window).on('resize', _.debounce(this.check_height.bind(this), 50));
|
||||
this.check_height();
|
||||
|
||||
if (website.is_editable_button) {
|
||||
this.$("button[data-action=edit]").removeClass("hidden");
|
||||
}
|
||||
|
||||
return $.when(
|
||||
this._super.apply(this, arguments),
|
||||
this.rte.appendTo(this.$('#website-top-edit .nav.pull-right'))
|
||||
|
@ -607,14 +611,19 @@
|
|||
*/
|
||||
setup_hover_buttons: function () {
|
||||
var editor = this.rte.editor;
|
||||
var $link_button = this.make_hover_button(_t("Edit Link"), function () {
|
||||
var $link_button = this.make_hover_button(_t("Change"), function () {
|
||||
var sel = new CKEDITOR.dom.element(previous);
|
||||
editor.getSelection().selectElement(sel);
|
||||
link_dialog(editor);
|
||||
if (previous.tagName.toUpperCase() === 'A') {
|
||||
link_dialog(editor);
|
||||
} else if(sel.hasClass('fa')) {
|
||||
new website.editor.FontIconsDialog(editor, previous)
|
||||
.appendTo(document.body);
|
||||
}
|
||||
$link_button.hide();
|
||||
previous = null;
|
||||
}, 'btn-xs');
|
||||
var $image_button = this.make_hover_button(_t("Edit Image"), function () {
|
||||
var $image_button = this.make_hover_button(_t("Change"), function () {
|
||||
image_dialog(editor, new CKEDITOR.dom.element(previous));
|
||||
$image_button.hide();
|
||||
previous = null;
|
||||
|
@ -625,12 +634,12 @@
|
|||
// -ish, because when moving to the button itself ``previous`` is
|
||||
// still set to the element having triggered showing the button.
|
||||
var previous;
|
||||
$(editor.element.$).on('mouseover', 'a, img', function (e) {
|
||||
$(editor.element.$).on('mouseover', 'a, img, .fa', function () {
|
||||
// Back from edit button -> ignore
|
||||
if (previous && previous === this) { return; }
|
||||
|
||||
var selected = new CKEDITOR.dom.element(this);
|
||||
if (!is_editable_node(selected)) {
|
||||
if (!is_editable_node(selected) && !selected.hasClass('fa')) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -659,7 +668,7 @@
|
|||
- $link_button.outerWidth() / 2
|
||||
})
|
||||
}
|
||||
}).on('mouseleave', 'a, img', function (e) {
|
||||
}).on('mouseleave', 'a, img, .fa', function (e) {
|
||||
var current = document.elementFromPoint(e.clientX, e.clientY);
|
||||
if (current === $link_button[0] || current === $image_button[0]) {
|
||||
return;
|
||||
|
@ -817,6 +826,28 @@
|
|||
document.execCommand("enableInlineTableEditing", false, "false");
|
||||
} catch (e) {}
|
||||
|
||||
|
||||
// detect & setup any CKEDITOR widget within a newly dropped
|
||||
// snippet. There does not seem to be a simple way to do it for
|
||||
// HTML not inserted via ckeditor APIs:
|
||||
// https://dev.ckeditor.com/ticket/11472
|
||||
$(document.body)
|
||||
.off('snippet-dropped')
|
||||
.on('snippet-dropped', function (e, el) {
|
||||
// CKEDITOR data processor extended by widgets plugin
|
||||
// to add wrappers around upcasting elements
|
||||
el.outerHTML = editor.dataProcessor.toHtml(el.outerHTML, {
|
||||
fixForBody: false,
|
||||
dontFilter: true,
|
||||
});
|
||||
// then repository.initOnAll() handles the conversion
|
||||
// from wrapper to actual widget instance (or something
|
||||
// like that).
|
||||
setTimeout(function () {
|
||||
editor.widgets.initOnAll();
|
||||
}, 0);
|
||||
});
|
||||
|
||||
self.trigger('rte:ready');
|
||||
def.resolve();
|
||||
});
|
||||
|
@ -1056,15 +1087,20 @@
|
|||
bind_data: function (text, href, new_window) {
|
||||
href = href || this.element && (this.element.data( 'cke-saved-href')
|
||||
|| this.element.getAttribute('href'));
|
||||
if (!href) { return; }
|
||||
|
||||
if (new_window === undefined) {
|
||||
new_window = this.element.getAttribute('target') === '_blank';
|
||||
new_window = this.element
|
||||
? this.element.getAttribute('target') === '_blank'
|
||||
: false;
|
||||
}
|
||||
if (text === undefined) {
|
||||
text = this.element.getText();
|
||||
text = this.element ? this.element.getText() : '';
|
||||
}
|
||||
|
||||
this.$('input#link-text').val(text);
|
||||
this.$('input.window-new').prop('checked', new_window);
|
||||
|
||||
if (!href) { return; }
|
||||
var match, $control;
|
||||
if ((match = /mailto:(.+)/.exec(href))) {
|
||||
$control = this.$('input.email-address').val(match[1]);
|
||||
|
@ -1074,9 +1110,6 @@
|
|||
}
|
||||
|
||||
this.changed($control);
|
||||
|
||||
this.$('input#link-text').val(text);
|
||||
this.$('input.window-new').prop('checked', new_window);
|
||||
},
|
||||
changed: function ($e) {
|
||||
this.$('.url-source').filter(':input').not($e).val('')
|
||||
|
@ -1456,6 +1489,34 @@
|
|||
template: 'website.editor.dialog.font-icons',
|
||||
events : _.extend({}, website.editor.Dialog.prototype.events, {
|
||||
change: 'update_preview',
|
||||
'click .font-icons-icon': function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
this.$('#fa-icon').val(e.target.getAttribute('data-id'));
|
||||
this.update_preview();
|
||||
},
|
||||
'click #fa-preview span': function (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
this.$('#fa-size').val(e.target.getAttribute('data-size'));
|
||||
this.update_preview();
|
||||
},
|
||||
'input input#icon-search': function () {
|
||||
var needle = this.$('#icon-search').val();
|
||||
var icons = this.icons;
|
||||
if (needle) {
|
||||
icons = _(icons).filter(function (icon) {
|
||||
return icon.id.substring(3).indexOf(needle) !== -1;
|
||||
});
|
||||
}
|
||||
|
||||
this.$('div.font-icons-icons').html(
|
||||
openerp.qweb.render(
|
||||
'website.editor.dialog.font-icons.icons',
|
||||
{icons: icons}));
|
||||
},
|
||||
}),
|
||||
|
||||
// List of FontAwesome icons in 4.0.3, extracted from the cheatsheet.
|
||||
|
@ -1474,26 +1535,7 @@
|
|||
* isn't customizable (?) and the fontawesome glyphs fail to appear.
|
||||
*/
|
||||
start: function () {
|
||||
var self = this;
|
||||
var started = this._super();
|
||||
this.$('#fa-icon').select2({
|
||||
data: this.icons,
|
||||
initSelection: function (element, callback) {
|
||||
var id = element.val(), match;
|
||||
if (id) {
|
||||
match = _.find(self.icons, function (item) {
|
||||
return item.id === id;
|
||||
}) || void 0;
|
||||
}
|
||||
|
||||
callback(match);
|
||||
},
|
||||
formatSelection: function (object) {
|
||||
return $('<span class="fa fa-fw">').text(object.text);
|
||||
},
|
||||
formatResultCssClass: function () { return 'fa'; },
|
||||
});
|
||||
return started.then(this.proxy('load_data'));
|
||||
return this._super().then(this.proxy('load_data'));
|
||||
},
|
||||
/**
|
||||
* Removes existing FontAwesome classes on the bound element, and sets
|
||||
|
@ -1520,7 +1562,7 @@
|
|||
for (var i = 0; i < classes.length; i++) {
|
||||
var cls = classes[i];
|
||||
switch(cls) {
|
||||
case 'fa-lg':case 'fa-2x':case 'fa-3x':case 'fa-4x':case 'fa-5x':
|
||||
case 'fa-2x':case 'fa-3x':case 'fa-4x':case 'fa-5x':
|
||||
// size classes
|
||||
this.$('#fa-size').val(cls);
|
||||
continue;
|
||||
|
@ -1529,15 +1571,14 @@
|
|||
case 'fa-flip-horizontal':case 'fa-rotate-vertical':
|
||||
this.$('#fa-rotation').val(cls);
|
||||
continue;
|
||||
case 'fa-fixed':
|
||||
this.$('#fa-fixed').prop('checked', true);
|
||||
case 'fa-fw':
|
||||
continue;
|
||||
case 'fa-border':
|
||||
this.$('#fa-border').prop('checked', true);
|
||||
continue;
|
||||
default:
|
||||
if (!/^fa-/.test(cls)) { continue; }
|
||||
this.$('#fa-icon').select2('val', cls);
|
||||
this.$('#fa-icon').val(cls);
|
||||
}
|
||||
}
|
||||
this.update_preview();
|
||||
|
@ -1549,19 +1590,34 @@
|
|||
get_fa_classes: function () {
|
||||
return [
|
||||
'fa',
|
||||
this.$('#fa-icon').select2('val'),
|
||||
this.$('#fa-icon').val(),
|
||||
this.$('#fa-size').val(),
|
||||
this.$('#fa-rotation').val(),
|
||||
this.$('#fa-fixed').prop('checked') ? 'fa-fixed' : '',
|
||||
this.$('#fa-border').prop('checked') ? 'fa-border' : ''
|
||||
];
|
||||
},
|
||||
update_preview: function () {
|
||||
this.$('#fa-preview')[0].className = this.get_fa_classes().join(' ');
|
||||
var $preview = this.$('#fa-preview').empty();
|
||||
var sizes = ['', 'fa-2x', 'fa-3x', 'fa-4x', 'fa-5x'];
|
||||
var classes = this.get_fa_classes();
|
||||
var no_sizes = _.difference(classes, sizes).join(' ');
|
||||
var selected = false;
|
||||
for (var i = sizes.length - 1; i >= 0; i--) {
|
||||
var size = sizes[i];
|
||||
|
||||
var $p = $('<span>')
|
||||
.attr('data-size', size)
|
||||
.addClass(size)
|
||||
.addClass(no_sizes);
|
||||
if ((size && _.contains(classes, size)) || (!size && !selected)) {
|
||||
$p.addClass('font-icons-selected');
|
||||
selected = true;
|
||||
}
|
||||
$preview.prepend($p);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
website.Observer = window.MutationObserver || window.WebkitMutationObserver || window.JsMutationObserver;
|
||||
var OBSERVER_CONFIG = {
|
||||
childList: true,
|
||||
|
|
|
@ -3,11 +3,12 @@
|
|||
|
||||
var website = openerp.website;
|
||||
website.is_editable = true;
|
||||
website.is_editable_button = true;
|
||||
|
||||
website.EditorBar.include({
|
||||
start: function() {
|
||||
var res = this._super();
|
||||
this.$("a[data-action=new_page]").parents("li").removeClass("hidden");
|
||||
this.$("button[data-action=edit]").removeClass("hidden");
|
||||
this.$(".oe_content_menu li.divider").removeClass("hidden");
|
||||
return res;
|
||||
},
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
var dom_ready = website.dom_ready = $.Deferred();
|
||||
$(document).ready(function () {
|
||||
website.is_editable = website.is_editable || $('html').data('editable');
|
||||
website.is_editable_button= website.is_editable_button || $('html').data('editable');
|
||||
dom_ready.resolve();
|
||||
});
|
||||
|
||||
|
|
|
@ -25,7 +25,10 @@
|
|||
} : htmlPage.isInBody(keyword) ? {
|
||||
title: 'label label-info',
|
||||
description: "This keyword is used in the page content."
|
||||
} : { title: "", description: "" };
|
||||
} : {
|
||||
title: 'label label-default',
|
||||
description: "This keyword is not used anywhere on the page."
|
||||
};
|
||||
}
|
||||
|
||||
website.seo.Suggestion = openerp.Widget.extend({
|
||||
|
@ -234,6 +237,16 @@
|
|||
},
|
||||
});
|
||||
|
||||
website.seo.Preview = openerp.Widget.extend({
|
||||
template: 'website.seo_preview',
|
||||
init: function (parent, options) {
|
||||
this.title = options.title;
|
||||
this.url = options.url;
|
||||
this.description = options.description || "[ The description will be generated by google unless you specify one ]";
|
||||
this._super(parent);
|
||||
},
|
||||
});
|
||||
|
||||
website.seo.HtmlPage = openerp.Class.extend(openerp.PropertiesMixin, {
|
||||
url: function () {
|
||||
var url = window.location.href;
|
||||
|
@ -327,7 +340,7 @@
|
|||
canEditDescription: false,
|
||||
canEditKeywords: false,
|
||||
maxTitleSize: 65,
|
||||
maxDescriptionSize: 155,
|
||||
maxDescriptionSize: 150,
|
||||
start: function () {
|
||||
var self = this;
|
||||
var $modal = self.$el;
|
||||
|
@ -361,6 +374,7 @@
|
|||
});
|
||||
self.keywordList.appendTo($modal.find('.js_seo_keywords_list'));
|
||||
self.disableUnsavableFields();
|
||||
self.renderPreview();
|
||||
$modal.modal();
|
||||
},
|
||||
disableUnsavableFields: function () {
|
||||
|
@ -376,7 +390,7 @@
|
|||
if (!self.canEditDescription) {
|
||||
$modal.find('textarea[name=seo_page_description]').attr('disabled', true);
|
||||
}
|
||||
if (!self.canEditTitle && !canEditDescription && !canEditKeywords) {
|
||||
if (!self.canEditTitle && !self.canEditDescription && !self.canEditKeywords) {
|
||||
$modal.find('button[data-action=update]').attr('disabled', true);
|
||||
}
|
||||
});
|
||||
|
@ -484,6 +498,7 @@
|
|||
setTimeout(function () {
|
||||
var title = self.$('input[name=seo_page_title]').val();
|
||||
self.htmlPage.changeTitle(title);
|
||||
self.renderPreview();
|
||||
}, 0);
|
||||
},
|
||||
descriptionChanged: function () {
|
||||
|
@ -491,7 +506,18 @@
|
|||
setTimeout(function () {
|
||||
var description = self.$('textarea[name=seo_page_description]').attr('value');
|
||||
self.htmlPage.changeDescription(description);
|
||||
}, 1);
|
||||
self.renderPreview();
|
||||
}, 0);
|
||||
},
|
||||
renderPreview: function () {
|
||||
var preview = new website.seo.Preview(this, {
|
||||
title: this.htmlPage.title(),
|
||||
description: this.htmlPage.description(),
|
||||
url: this.htmlPage.url(),
|
||||
});
|
||||
var $preview = this.$('.js_seo_preview');
|
||||
$preview.empty();
|
||||
preview.appendTo($preview);
|
||||
},
|
||||
destroy: function () {
|
||||
this.htmlPage.changeKeywords(this.keywordList.keywords());
|
||||
|
|
|
@ -76,6 +76,9 @@
|
|||
hack_to_add_snippet_id();
|
||||
});
|
||||
|
||||
// 'snippet-dropped' is triggered on '#oe_snippets' whith $target as attribute when a snippet is dropped
|
||||
// 'snippet-activated' is triggered on '#oe_snippets' (and on snippet) when a snippet is activated
|
||||
|
||||
website.snippet.styles = {};
|
||||
website.snippet.selector = [];
|
||||
website.snippet.BuildingBlock = openerp.Widget.extend({
|
||||
|
|
|
@ -19,104 +19,108 @@
|
|||
});
|
||||
this.registerSteps();
|
||||
},
|
||||
registerSteps: function () {
|
||||
registerStep: function (step) {
|
||||
var self = this;
|
||||
this.tour.addSteps(_.map(this.steps, function (step) {
|
||||
step.title = openerp.qweb.render('website.tour_popover_title', { title: step.title });
|
||||
if (!step.element) {
|
||||
step.orphan = true;
|
||||
}
|
||||
if (step.snippet) {
|
||||
step.element = '#oe_snippets div.oe_snippet[data-snippet-id="'+step.snippet+'"] .oe_snippet_thumbnail';
|
||||
}
|
||||
if (step.trigger) {
|
||||
if (step.trigger === 'click') {
|
||||
step.title = openerp.qweb.render('website.tour_popover_title', { title: step.title });
|
||||
if (!step.element) {
|
||||
step.orphan = true;
|
||||
}
|
||||
if (step.snippet) {
|
||||
step.element = '#oe_snippets div.oe_snippet[data-snippet-id="'+step.snippet+'"] .oe_snippet_thumbnail';
|
||||
}
|
||||
if (step.trigger) {
|
||||
if (step.trigger === 'click') {
|
||||
step.triggers = function (callback) {
|
||||
$(step.element).one('click', function () {
|
||||
(callback || self.moveToNextStep).apply(self);
|
||||
});
|
||||
};
|
||||
} else if (step.trigger === 'reload') {
|
||||
step.triggers = function (callback) {
|
||||
var stack = JSON.parse(localStorage.getItem("website-reloads")) || [];
|
||||
var index = stack.indexOf(step.stepId);
|
||||
if (index !== -1) {
|
||||
stack.splice(index,1);
|
||||
(callback || self.moveToNextStep).apply(self);
|
||||
} else {
|
||||
stack.push(step.stepId);
|
||||
}
|
||||
localStorage.setItem("website-reloads", JSON.stringify(stack));
|
||||
};
|
||||
} else if (step.trigger.url) {
|
||||
step.triggers = function (callback) {
|
||||
var stack = JSON.parse(localStorage.getItem("website-geturls")) || [];
|
||||
var id = step.trigger.url.toString();
|
||||
var index = stack.indexOf(id);
|
||||
if (index !== -1) {
|
||||
var url = new website.UrlParser(window.location.href);
|
||||
var test = typeof step.trigger.url === "string" ?
|
||||
step.trigger.url == url.pathname+url.search :
|
||||
step.trigger.url.test(url.pathname+url.search);
|
||||
if (!test) return;
|
||||
stack.splice(index,1);
|
||||
(callback || self.moveToNextStep).apply(self);
|
||||
} else {
|
||||
stack.push(id);
|
||||
}
|
||||
localStorage.setItem("website-geturls", JSON.stringify(stack));
|
||||
};
|
||||
} else if (step.trigger === 'drag') {
|
||||
step.triggers = function (callback) {
|
||||
self.onSnippetDragged(callback || self.moveToNextStep);
|
||||
};
|
||||
} else if (step.trigger.id) {
|
||||
if (step.trigger.emitter && step.trigger.type === 'openerp') {
|
||||
step.triggers = function (callback) {
|
||||
$(step.element).one('click', function () {
|
||||
(callback || self.moveToNextStep).apply(self);
|
||||
step.trigger.emitter.on(step.trigger.id, self, function customHandler () {
|
||||
step.trigger.emitter.off(step.trigger.id, customHandler);
|
||||
(callback || self.moveToNextStep).apply(self, arguments);
|
||||
});
|
||||
};
|
||||
} else if (step.trigger === 'reload') {
|
||||
} else {
|
||||
step.triggers = function (callback) {
|
||||
var stack = JSON.parse(localStorage.getItem("website-reloads")) || [];
|
||||
var index = stack.indexOf(step.stepId);
|
||||
if (index !== -1) {
|
||||
stack.splice(index,1);
|
||||
(callback || self.moveToNextStep).apply(self);
|
||||
} else {
|
||||
stack.push(step.stepId);
|
||||
}
|
||||
localStorage.setItem("website-reloads", JSON.stringify(stack));
|
||||
};
|
||||
} else if (step.trigger && step.trigger.url) {
|
||||
step.triggers = function (callback) {
|
||||
var stack = JSON.parse(localStorage.getItem("website-geturls")) || [];
|
||||
var id = step.trigger.url.toString();
|
||||
var index = stack.indexOf(id);
|
||||
if (index !== -1) {
|
||||
var url = new website.UrlParser(window.location.href);
|
||||
var test = typeof step.trigger.url === "string" ?
|
||||
step.trigger.url == url.pathname+url.search :
|
||||
step.trigger.url.test(url.pathname+url.search);
|
||||
if (!test) return;
|
||||
stack.splice(index,1);
|
||||
(callback || self.moveToNextStep).apply(self);
|
||||
} else {
|
||||
stack.push(id);
|
||||
}
|
||||
localStorage.setItem("website-geturls", JSON.stringify(stack));
|
||||
};
|
||||
} else if (step.trigger === 'drag') {
|
||||
step.triggers = function (callback) {
|
||||
self.onSnippetDragged(callback || self.moveToNextStep);
|
||||
};
|
||||
} else if (step.trigger && step.trigger.id) {
|
||||
if (step.trigger.emitter && step.trigger.type === 'openerp') {
|
||||
step.triggers = function (callback) {
|
||||
step.trigger.emitter.on(step.trigger.id, self, function customHandler () {
|
||||
step.trigger.emitter.off(step.trigger.id, customHandler);
|
||||
(callback || self.moveToNextStep).apply(self, arguments);
|
||||
});
|
||||
};
|
||||
} else {
|
||||
step.triggers = function (callback) {
|
||||
var emitter = _.isString(step.trigger.emitter) ? $(step.trigger.emitter) : (step.trigger.emitter || $(step.element));
|
||||
if (!emitter.size()) throw "Emitter is undefined";
|
||||
emitter.on(step.trigger.id, function () {
|
||||
(callback || self.moveToNextStep).apply(self, arguments);
|
||||
});
|
||||
};
|
||||
}
|
||||
} else if (step.trigger.modal) {
|
||||
step.triggers = function (callback) {
|
||||
var $doc = $(document);
|
||||
function onStop () {
|
||||
if (step.trigger.modal.stopOnClose) {
|
||||
self.stop();
|
||||
}
|
||||
}
|
||||
$doc.on('hide.bs.modal', onStop);
|
||||
$doc.one('shown.bs.modal', function () {
|
||||
$('.modal button.btn-primary').one('click', function () {
|
||||
$doc.off('hide.bs.modal', onStop);
|
||||
(callback || self.moveToNextStep).apply(self, [step.trigger.modal.afterSubmit]);
|
||||
});
|
||||
(callback || self.moveToNextStep).apply(self);
|
||||
var emitter = _.isString(step.trigger.emitter) ? $(step.trigger.emitter) : (step.trigger.emitter || $(step.element));
|
||||
if (!emitter.size()) throw "Emitter is undefined";
|
||||
emitter.on(step.trigger.id, function () {
|
||||
(callback || self.moveToNextStep).apply(self, arguments);
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
step.onShow = (function () {
|
||||
var executed = false;
|
||||
return function () {
|
||||
if (!executed) {
|
||||
_.isFunction(step.onStart) && step.onStart();
|
||||
_.isFunction(step.triggers) && step.triggers();
|
||||
executed = true;
|
||||
} else if (step.trigger.modal) {
|
||||
step.triggers = function (callback) {
|
||||
var $doc = $(document);
|
||||
function onStop () {
|
||||
if (step.trigger.modal.stopOnClose) {
|
||||
self.stop();
|
||||
}
|
||||
}
|
||||
$doc.on('hide.bs.modal', onStop);
|
||||
$doc.one('shown.bs.modal', function () {
|
||||
$('.modal button.btn-primary').one('click', function () {
|
||||
$doc.off('hide.bs.modal', onStop);
|
||||
(callback || self.moveToNextStep).apply(self, [step.trigger.modal.afterSubmit]);
|
||||
});
|
||||
(callback || self.moveToNextStep).apply(self);
|
||||
});
|
||||
};
|
||||
}());
|
||||
return step;
|
||||
}
|
||||
}
|
||||
step.onShow = (function () {
|
||||
var executed = false;
|
||||
return function () {
|
||||
if (!executed) {
|
||||
_.isFunction(step.onStart) && step.onStart();
|
||||
_.isFunction(step.triggers) && step.triggers();
|
||||
executed = true;
|
||||
}
|
||||
};
|
||||
}());
|
||||
return step;
|
||||
},
|
||||
registerSteps: function () {
|
||||
var self = this;
|
||||
this.tour.addSteps(_.map(this.steps, function (step) {
|
||||
return self.registerStep(step);
|
||||
}));
|
||||
},
|
||||
reset: function () {
|
||||
|
@ -152,8 +156,8 @@
|
|||
this.stop();
|
||||
} else if (index >= 0) {
|
||||
var self = this;
|
||||
$('.popover.tour').remove();
|
||||
setTimeout(function () {
|
||||
$('.popover.tour').remove();
|
||||
setTimeout(function () {
|
||||
self.tour.goto(index);
|
||||
}, 0);
|
||||
|
@ -323,6 +327,7 @@
|
|||
var testId = 'test_'+tour.id+'_tour';
|
||||
this.tours.push(tour);
|
||||
var defaultDelay = 500; //ms
|
||||
var overlapsCrash;
|
||||
var test = {
|
||||
id: tour.id,
|
||||
run: function (force) {
|
||||
|
@ -332,34 +337,63 @@
|
|||
var actionSteps = _.filter(tour.steps, function (step) {
|
||||
return step.trigger || step.sampleText;
|
||||
});
|
||||
window.onbeforeunload = function () {
|
||||
clearTimeout(overlapsCrash);
|
||||
};
|
||||
function executeStep (step) {
|
||||
var lastStep = window.localStorage.getItem(testId);
|
||||
var tryStep = lastStep != step.stepId ? 0 : parseInt(window.localStorage.getItem("last-"+testId) || 0, 10)+1;
|
||||
window.localStorage.setItem("last-"+testId, tryStep);
|
||||
if (tryStep > 2) {
|
||||
window.localStorage.removeItem(testId);
|
||||
throw "Test: '" + testId + "' cycling step: '" + step.stepId + "'";
|
||||
}
|
||||
|
||||
var _next = false;
|
||||
window.localStorage.setItem(testId, step.stepId);
|
||||
function next () {
|
||||
clearTimeout(overlapsCrash);
|
||||
_next = true;
|
||||
var nextStep = actionSteps.shift();
|
||||
if (nextStep) {
|
||||
executeStep(nextStep);
|
||||
setTimeout(function () {
|
||||
executeStep(nextStep);
|
||||
}, step.delay || defaultDelay);
|
||||
} else {
|
||||
window.localStorage.removeItem(testId);
|
||||
}
|
||||
}
|
||||
setTimeout(function () {
|
||||
if (step.triggers) step.triggers(next);
|
||||
var $element = $(step.element);
|
||||
if (step.snippet && step.trigger === 'drag') {
|
||||
website.TestConsole.dragAndDropSnippet(step.snippet);
|
||||
} else if (step.trigger && step.trigger.id === 'change') {
|
||||
$element.trigger($.Event("change", { srcElement: $element }));
|
||||
} else if (step.sampleText) {
|
||||
$element.val(step.sampleText);
|
||||
$element.trigger($.Event("change", { srcElement: $element }));
|
||||
} else if ($element.is(":visible")) { // Click by default
|
||||
$element.trigger($.Event("click", { srcElement: $element }));
|
||||
overlapsCrash = setTimeout(function () {
|
||||
window.localStorage.removeItem(testId);
|
||||
throw "Test: '" + testId + "' can't resolve step: '" + step.stepId + "'";
|
||||
}, (step.delay || defaultDelay) + 500);
|
||||
|
||||
var $element = $(step.element);
|
||||
if (step.triggers) step.triggers(next);
|
||||
if ((step.trigger === 'reload' || (step.trigger && step.trigger.url)) && _next) return;
|
||||
|
||||
if (step.snippet && step.trigger === 'drag') {
|
||||
website.TestConsole.dragAndDropSnippet(step.snippet);
|
||||
} else if (step.trigger && step.trigger.id === 'change') {
|
||||
$element.trigger($.Event("change", { srcElement: $element }));
|
||||
} else if (step.sampleText) {
|
||||
$element.val(step.sampleText);
|
||||
$element.trigger($.Event("change", { srcElement: $element }));
|
||||
} else if ($element.is(":visible")) { // Click by default
|
||||
if (step.trigger.id === 'mousedown') {
|
||||
$element.trigger($.Event("mousedown", { srcElement: $element }));
|
||||
}
|
||||
if (!step.triggers) next();
|
||||
}, step.delay || defaultDelay);
|
||||
var evt = document.createEvent("MouseEvents");
|
||||
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
|
||||
$element[0].dispatchEvent(evt);
|
||||
if (step.trigger.id === 'mouseup') {
|
||||
$element.trigger($.Event("mouseup", { srcElement: $element }));
|
||||
}
|
||||
}
|
||||
if (!step.triggers) next();
|
||||
}
|
||||
var url = new website.UrlParser(window.location.href);
|
||||
if (tour.path && url.pathname !== tour.path) {
|
||||
if (tour.path && url.pathname !== tour.path && !window.localStorage.getItem(testId)) {
|
||||
window.localStorage.setItem(testId, actionSteps[0].stepId);
|
||||
window.location.href = tour.path;
|
||||
} else {
|
||||
|
|
|
@ -13,9 +13,13 @@
|
|||
var self = this;
|
||||
this.initial_content = {};
|
||||
return this._super.apply(this, arguments).then(function () {
|
||||
self.$("button[data-action=edit]").removeClass("hidden");
|
||||
self.$('button[data-action=edit]')
|
||||
.text("Translate")
|
||||
.after(openerp.qweb.render('website.TranslatorAdditionalButtons'));
|
||||
.text("Translate");
|
||||
if (website.is_editable_button) {
|
||||
self.$('button[data-action=edit]')
|
||||
.after(openerp.qweb.render('website.TranslatorAdditionalButtons'));
|
||||
}
|
||||
self.$('.js_hide_on_translate').hide();
|
||||
});
|
||||
},
|
||||
|
|
|
@ -207,23 +207,18 @@
|
|||
<t t-call="website.editor.dialog">
|
||||
<t t-set="title">Icon:</t>
|
||||
<form>
|
||||
<div class="form-group">
|
||||
Preview: <span id="fa-preview"/>
|
||||
<div class="form-group" id="fa-preview">
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="fa-icon">icon</label>
|
||||
<div class="form-group font-icons fa fa-search">
|
||||
<input type="hidden" id="fa-icon" class="form-control"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="fa-size">size</label>
|
||||
<select id="fa-size" class="form-control">
|
||||
<option value="">Default</option>
|
||||
<option value="fa-lg">Large</option>
|
||||
<option value="fa-2x">x2</option>
|
||||
<option value="fa-3x">x3</option>
|
||||
<option value="fa-4x">x4</option>
|
||||
<option value="fa-5x">x5</option>
|
||||
</select>
|
||||
<input type="hidden" id="fa-size" class="form-control"/>
|
||||
<input type="search" class="form-control" id="icon-search"/>
|
||||
<div class="font-icons-icons">
|
||||
<t t-call="website.editor.dialog.font-icons.icons">
|
||||
<t t-set="icons" t-value="widget.icons"/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="fa-rotation">Rotation</label>
|
||||
|
@ -239,16 +234,18 @@
|
|||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<input type="checkbox" id="fa-fixed"/> fixed width
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>
|
||||
<input type="checkbox" id="fa-border"/> bordered
|
||||
<input type="checkbox" id="fa-border"/> border
|
||||
</label>
|
||||
</div>
|
||||
</form>
|
||||
</t>
|
||||
</t>
|
||||
<t t-name="website.editor.dialog.font-icons.icons">
|
||||
<span t-foreach="icons" t-as="icon"
|
||||
class="fa font-icons-icon"
|
||||
t-att-data-id="icon.id">
|
||||
<t t-esc="icon.text"/>
|
||||
</span>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
|
|
@ -43,19 +43,24 @@
|
|||
<div class="form-group">
|
||||
<label for="seo_page_description" class="col-lg-2 control-label">Description</label>
|
||||
<div class="col-lg-8">
|
||||
<textarea name="seo_page_description" class="form-control" rows="3" cols="70" size="160"/>
|
||||
<textarea name="seo_page_description" class="form-control" rows="3" cols="70" t-att-maxlength="widget.maxDescriptionSize"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<h3 class="page-header">3. Preview <small>how your page will be listed on Google</small></h3>
|
||||
<div class="js_seo_preview"></div>
|
||||
</section>
|
||||
<!--
|
||||
<section class="js_image_section">
|
||||
<h3 class="page-header">3. Describe your images</h3>
|
||||
<h3 class="page-header">4. Describe your images</h3>
|
||||
<div class="row js_seo_image_list">
|
||||
</div>
|
||||
</section>
|
||||
-->
|
||||
</div><div class="modal-footer">
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" data-action="update" class="btn btn-primary">Save</button>
|
||||
or
|
||||
<a data-action="discard" data-dismiss="modal" href="#" >Discard</a>
|
||||
|
@ -111,4 +116,26 @@
|
|||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="website.seo_preview">
|
||||
<li class="oe_seo_preview_g">
|
||||
<div class="rc">
|
||||
<span class="altcts"></span>
|
||||
<h3 class="r">
|
||||
<a t-att-href="url">
|
||||
<em><t t-esc="widget.title"/></em>
|
||||
</a>
|
||||
</h3>
|
||||
<div class="s">
|
||||
<div>
|
||||
<div class="f kv" style="white-space:nowrap">
|
||||
<cite><t t-esc="widget.url"/></cite>
|
||||
</div>
|
||||
<div class="f slp"></div>
|
||||
<span class="st"><t t-esc="widget.description"/></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
|
|
@ -141,11 +141,11 @@ class WebsiteUiSuite(unittest.TestSuite):
|
|||
except ValueError:
|
||||
result.addError(self._test, 'Unexpected message: "%s"' % "\n".join(lines))
|
||||
|
||||
def full_path(filename):
|
||||
return os.path.join(os.path.join(os.path.dirname(__file__), 'ui_suite'), filename)
|
||||
def full_path(pyfile, filename):
|
||||
return os.path.join(os.path.join(os.path.dirname(pyfile), 'ui_suite'), filename)
|
||||
|
||||
def load_tests(loader, base, _):
|
||||
base.addTest(WebsiteUiSuite(full_path('dummy_test.js'), {}, 5.0))
|
||||
base.addTest(WebsiteUiSuite(full_path('simple_dom_test.js'), {'redirect': '/page/website.homepage'}, 60.0))
|
||||
base.addTest(WebsiteUiSuite(full_path('homepage_test.js'), {'redirect': '/page/website.homepage'}, 60.0))
|
||||
base.addTest(WebsiteUiSuite(full_path(__file__, 'dummy_test.js'), {}, 5.0))
|
||||
base.addTest(WebsiteUiSuite(full_path(__file__, 'simple_dom_test.js'), {'redirect': '/page/website.homepage'}, 60.0))
|
||||
base.addTest(WebsiteUiSuite(full_path(__file__, 'homepage_test.js'), {'redirect': '/page/website.homepage'}, 60.0))
|
||||
return base
|
||||
|
|
|
@ -9,7 +9,8 @@ function waitFor (ready, callback, timeout, timeoutMessageCallback) {
|
|||
if(!condition) {
|
||||
var message = timeoutMessageCallback ? timeoutMessageCallback() : "Timeout after "+timeout+" ms";
|
||||
console.log('{ "event": "error", "message": "'+message+'" }');
|
||||
console.log("Waiting for...\n"+ready);
|
||||
var json = { "event": "error", "message": "Waiting for...\n"+ready };
|
||||
console.log(JSON.stringify(json));
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
clearInterval(interval);
|
||||
|
@ -17,7 +18,7 @@ function waitFor (ready, callback, timeout, timeoutMessageCallback) {
|
|||
}
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
}
|
||||
|
||||
function run (test) {
|
||||
var options = JSON.parse(phantom.args);
|
||||
|
|
|
@ -12,12 +12,18 @@
|
|||
</template>
|
||||
|
||||
<template id="website.submenu" name="Submenu">
|
||||
<li t-if="not submenu.child_id">
|
||||
<li t-if="not submenu.child_id" t-att-class="
|
||||
((submenu.url != '/' and request.httprequest.path.startswith(submenu.url)) or
|
||||
request.httprequest.path == submenu.url) and 'active'
|
||||
">
|
||||
<a t-att-href="url_for(submenu.url)" t-ignore="true" t-att-target="'blank' if submenu.new_window else None">
|
||||
<span t-field="submenu.name"/>
|
||||
</a>
|
||||
</li>
|
||||
<li t-if="submenu.child_id" class="dropdown">
|
||||
<li t-if="submenu.child_id" t-attf-class="dropdown #{
|
||||
((submenu.url != '/' and [1 for submenu in submenu.child_id if request.httprequest.path.startswith(submenu.url)]) or
|
||||
request.httprequest.path == submenu.url) and 'active'
|
||||
}">
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
<span t-field="submenu.name"/> <span class="caret" t-ignore="true"></span>
|
||||
</a>
|
||||
|
@ -96,8 +102,8 @@
|
|||
<t t-foreach="website.menu_id.child_id" t-as="submenu">
|
||||
<t t-call="website.submenu"/>
|
||||
</t>
|
||||
<li class="divider" t-if="user_id.id != website.public_user.id"/>
|
||||
<li class="dropdown" t-ignore="true" t-if="user_id.id != website.public_user.id">
|
||||
<li class="divider" groups="base.group_user,base.group_portal"/>
|
||||
<li class="dropdown" t-ignore="true" groups="base.group_user,base.group_portal">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
|
||||
<b>
|
||||
<span t-esc="user_id.name"/>
|
||||
|
@ -191,6 +197,16 @@
|
|||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
<t t-if="website.google_analytics_key">
|
||||
<script>
|
||||
(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
|
||||
function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
|
||||
e=o.createElement(i);r=o.getElementsByTagName(i)[0];
|
||||
e.src='//www.google-analytics.com/analytics.js';
|
||||
r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
|
||||
ga('create','<t t-esc="website.google_analytics_key"/>');ga('send','pageview');
|
||||
</script>
|
||||
</t>
|
||||
</body>
|
||||
</html>
|
||||
</template>
|
||||
|
@ -247,10 +263,10 @@
|
|||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="show_sign_in" inherit_option_id="website.layout" inherit_id="website.layout" name="Show Sign In">
|
||||
<template id="show_sign_in" inherit_option_id="website.layout" inherit_id="website.layout" name="Show Sign In" groups="base.group_public">
|
||||
<xpath expr="//ul[@id='top_menu']" position="inside">
|
||||
<li class="divider" t-if="user_id.id == website.public_user.id"/>
|
||||
<li t-if="user_id.id == website.public_user.id">
|
||||
<li class="divider"/>
|
||||
<li>
|
||||
<a t-attf-href="/web/login">
|
||||
<b>Sign in</b>
|
||||
</a>
|
||||
|
@ -643,6 +659,9 @@ Sitemap: <t t-esc="url_root"/>sitemap.xml
|
|||
</div>
|
||||
</div>
|
||||
<div class="col-md-4 mb32">
|
||||
<div groups="base.group_website_publisher" t-ignore="true" class="pull-right css_editable_mode_hidden" t-att-style="style or ''">
|
||||
<a class="btn btn-primary" t-att-href="'/web#return_label=Website&model=%s&id=%s' % (res_company._name, res_company.id)" title='Edit in backend'>Edit</a>
|
||||
</div>
|
||||
<t t-call="website.company_description"/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -732,8 +751,8 @@ Sitemap: <t t-esc="url_root"/>sitemap.xml
|
|||
</template>
|
||||
|
||||
<template id="contact">
|
||||
<address t-ignore="true">
|
||||
<div t-att-class='"" if "name" in fields else "css_non_editable_mode_hidden"'><span t-esc="name"/></div>
|
||||
<address t-ignore="true" class="mb0">
|
||||
<div t-attf-class="'name' not in fields and 'css_non_editable_mode_hidden'"><span t-esc="name"/></div>
|
||||
<div class='css_editable_mode_hidden'>
|
||||
<div t-if="address and 'address' in fields">
|
||||
<i class='fa fa-map-marker'/>
|
||||
|
|
|
@ -57,6 +57,9 @@
|
|||
<field name="language_ids" widget="many2many_checkboxes"/>
|
||||
<field name="default_lang_id" widget="selection"/>
|
||||
</group>
|
||||
<group string="Website Management">
|
||||
<field name="google_analytics_key" placeholder="UA-XXXXXXXX-X"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
|
|
|
@ -62,7 +62,9 @@
|
|||
placement: 'right',
|
||||
title: "Create Blog Post",
|
||||
content: "Click <em>Continue</em> to create the blog post.",
|
||||
trigger: 'click',
|
||||
trigger: {
|
||||
url: /blogpost\/[0-9]+\/.*/,
|
||||
},
|
||||
},
|
||||
{
|
||||
stepId: 'post-page',
|
||||
|
@ -139,7 +141,7 @@
|
|||
title: "Save Your Blog",
|
||||
content: "Click the <em>Save</em> button to record changes on the page.",
|
||||
template: self.popover({ fixed: true }),
|
||||
trigger: 'click',
|
||||
trigger: 'reload',
|
||||
},
|
||||
{
|
||||
stepId: 'publish-post',
|
||||
|
|
|
@ -7,10 +7,8 @@
|
|||
website.is_editable = true;
|
||||
website.EditorBar.include({
|
||||
start: function() {
|
||||
website.is_editable_button = website.is_editable_button || !!$("#wrap.js_blog").size();
|
||||
var res = this._super();
|
||||
if ($("#wrap.js_blog").size()) {
|
||||
this.$("button[data-action=edit]").removeClass("hidden");
|
||||
}
|
||||
this.$(".dropdown:has(.oe_content_menu)").removeClass("hidden");
|
||||
return res;
|
||||
},
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.website_blog.tests import test_controllers
|
||||
import test_controllers
|
||||
|
||||
import test_ui
|
||||
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
import os
|
||||
|
||||
import openerp.addons.website.tests.test_ui as test_ui
|
||||
|
||||
def full_path(filename):
|
||||
return os.path.join(os.path.join(os.path.dirname(__file__), 'ui_suite'), filename)
|
||||
|
||||
def load_tests(loader, base, _):
|
||||
base.addTest(test_ui.WebsiteUiSuite(full_path('post_test.js'), {'redirect': '/page/website.homepage'}, 60.0))
|
||||
base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'post_test.js'), {'redirect': '/page/website.homepage'}, 60.0))
|
||||
return base
|
||||
|
|
|
@ -60,7 +60,9 @@
|
|||
placement: 'right',
|
||||
title: "Create Event",
|
||||
content: "Click <em>Continue</em> to create the event.",
|
||||
trigger: 'click',
|
||||
trigger: {
|
||||
url: /event\/[0-9]+\/register/
|
||||
},
|
||||
},
|
||||
{
|
||||
stepId: 'event-page',
|
||||
|
@ -137,7 +139,7 @@
|
|||
title: "Save your modifications",
|
||||
content: "Once you click on save, your event is updated.",
|
||||
template: self.popover({ fixed: true }),
|
||||
trigger: 'click',
|
||||
trigger: 'reload',
|
||||
},
|
||||
{
|
||||
stepId: 'publish-event',
|
||||
|
|
|
@ -7,10 +7,8 @@
|
|||
website.is_editable = true;
|
||||
website.EditorBar.include({
|
||||
start: function() {
|
||||
website.is_editable_button = website.is_editable_button || !!$("#wrap.js_event").size();
|
||||
var res = this._super();
|
||||
if ($("#wrap.js_event").size()) {
|
||||
this.$("button[data-action=edit]").removeClass("hidden");
|
||||
}
|
||||
this.$(".dropdown:has(.oe_content_menu)").removeClass("hidden");
|
||||
return res;
|
||||
},
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.website_blog.tests import test_controllers
|
||||
import test_controllers
|
||||
|
||||
import test_ui
|
||||
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
import os
|
||||
|
||||
import openerp.addons.website.tests.test_ui as test_ui
|
||||
|
||||
def full_path(filename):
|
||||
return os.path.join(os.path.join(os.path.dirname(__file__), 'ui_suite'), filename)
|
||||
|
||||
def load_tests(loader, base, _):
|
||||
base.addTest(test_ui.WebsiteUiSuite(full_path('event_test.js'), {'redirect': '/page/website.homepage'}, 60.0))
|
||||
base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'event_test.js'), {'redirect': '/page/website.homepage'}, 60.0))
|
||||
return base
|
||||
|
|
|
@ -203,7 +203,7 @@
|
|||
</t>
|
||||
</ol>
|
||||
</div>
|
||||
<div class="col-sm-5">
|
||||
<div class="col-sm-5" groups="event.group_event_manager">
|
||||
<t t-call="website.publish_management">
|
||||
<t t-set="object" t-value="event"/>
|
||||
<t t-set="publish_edit" t-value="True"/>
|
||||
|
|
|
@ -6,10 +6,8 @@
|
|||
website.is_editable = true;
|
||||
website.EditorBar.include({
|
||||
start: function() {
|
||||
website.is_editable_button = website.is_editable_button || !!$("#wrap.js_hr_recruitment").size();
|
||||
var res = this._super();
|
||||
if ($("#wrap.js_hr_recruitment").size()) {
|
||||
this.$("button[data-action=edit]").removeClass("hidden");
|
||||
}
|
||||
this.$(".dropdown:has(.oe_content_menu)").removeClass("hidden");
|
||||
return res;
|
||||
},
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#
|
||||
##############################################################################
|
||||
|
||||
from openerp.addons.website_mail.tests import test_controllers
|
||||
import test_controllers
|
||||
|
||||
checks = [
|
||||
test_controllers,
|
||||
|
|
|
@ -246,7 +246,7 @@ class Ecommerce(http.Controller):
|
|||
'range': range,
|
||||
'search': {
|
||||
'search': search,
|
||||
'category': category,
|
||||
'category': category and category.id,
|
||||
'filters': filters,
|
||||
},
|
||||
'pager': pager,
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
website.EditorBar.include({
|
||||
start: function () {
|
||||
this.registerTour(new website.EditorShopTour(this));
|
||||
this.registerTour(new website.EditorShopTest(this));
|
||||
return this._super();
|
||||
},
|
||||
});
|
||||
|
@ -156,4 +157,151 @@
|
|||
},
|
||||
});
|
||||
|
||||
|
||||
website.Test = website.Tour.extend({
|
||||
registerStep: function (step) {
|
||||
var self = this;
|
||||
var step = this._super(step);
|
||||
if (step.beforeTrigger || step.afterTrigger) {
|
||||
var fn = step.triggers;
|
||||
step.triggers = function (callback) {
|
||||
if (step.beforeTrigger) step.beforeTrigger(self);
|
||||
if (!step.afterTrigger) {
|
||||
fn.call(step, callback);
|
||||
} else {
|
||||
fn.call(step, function () {
|
||||
(callback || self.moveToNextStep).apply(self);
|
||||
step.afterTrigger(self);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
return step;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
website.EditorShopTest = website.Test.extend({
|
||||
id: 'shoptest',
|
||||
name: "Try to by 3 products",
|
||||
path: '/shop',
|
||||
init: function (editor) {
|
||||
var self = this;
|
||||
self.steps = [
|
||||
{
|
||||
stepId: 'begin-test',
|
||||
title: 'begin-test',
|
||||
template: self.popover({ next: "Start Test"}),
|
||||
backdrop: true,
|
||||
},
|
||||
{
|
||||
stepId: 'display-ipod',
|
||||
element: '.oe_product_cart a:contains("iPod")',
|
||||
trigger: {
|
||||
url: /shop\/product\/.*/,
|
||||
},
|
||||
},
|
||||
{
|
||||
stepId: 'choose-ipod',
|
||||
element: 'input[name="product_id"]:not([checked])',
|
||||
trigger: {
|
||||
id: 'mouseup',
|
||||
},
|
||||
},
|
||||
{
|
||||
stepId: 'add-ipod',
|
||||
element: 'form[action="/shop/add_cart/"] button',
|
||||
trigger: {
|
||||
url: '/shop/mycart/',
|
||||
},
|
||||
},
|
||||
{
|
||||
stepId: 'add-suggested-product',
|
||||
element: 'form[action="/shop/add_cart/"] button:contains("Add to Cart")',
|
||||
trigger: 'reload',
|
||||
},
|
||||
{
|
||||
stepId: 'more-product',
|
||||
element: '.oe_mycart a.js_add_cart_json:eq(1)',
|
||||
trigger: 'click',
|
||||
},
|
||||
{
|
||||
stepId: 'less-product',
|
||||
element: '.oe_mycart a.js_add_cart_json:eq(2)',
|
||||
trigger: 'reload',
|
||||
},
|
||||
{
|
||||
stepId: 'number-product',
|
||||
element: '.oe_mycart input.js_quantity',
|
||||
trigger: 'reload',
|
||||
beforeTrigger: function (tour) {
|
||||
if (parseInt($(".oe_mycart input.js_quantity").val(),10) !== 1)
|
||||
$(".oe_mycart input.js_quantity").val("1").change();
|
||||
},
|
||||
afterTrigger: function (tour) {
|
||||
if ($(".oe_mycart input.js_quantity").size() !== 1)
|
||||
throw "Can't remove suggested item from my cart";
|
||||
if (parseInt($(".oe_mycart input.js_quantity").val(),10) !== 1)
|
||||
throw "Can't defined number of items in my cart";
|
||||
},
|
||||
},
|
||||
{
|
||||
stepId: 'go-checkout-product',
|
||||
element: 'a[href="/shop/checkout/"]',
|
||||
trigger: {
|
||||
url: '/shop/checkout/',
|
||||
},
|
||||
},
|
||||
{
|
||||
stepId: 'confirm-false-checkout-product',
|
||||
element: 'form[action="/shop/confirm_order/"] button',
|
||||
trigger: {
|
||||
url: '/shop/confirm_order/',
|
||||
},
|
||||
beforeTrigger: function (tour) {
|
||||
$("input[name='phone']").val("");
|
||||
},
|
||||
},
|
||||
{
|
||||
stepId: 'confirm-checkout-product',
|
||||
element: 'form[action="/shop/confirm_order/"] button',
|
||||
trigger: {
|
||||
url: '/shop/payment/',
|
||||
},
|
||||
beforeTrigger: function (tour) {
|
||||
if ($("input[name='name']").val() === "")
|
||||
$("input[name='name']").val("website_sale-test-shoptest");
|
||||
if ($("input[name='email']").val() === "")
|
||||
$("input[name='email']").val("website_sale-test-shoptest@website_sale-test-shoptest.optenerp.com");
|
||||
$("input[name='phone']").val("123");
|
||||
$("input[name='street']").val("123");
|
||||
$("input[name='city']").val("123");
|
||||
$("input[name='zip']").val("123");
|
||||
$("select[name='country_id']").val("21");
|
||||
},
|
||||
},
|
||||
{
|
||||
stepId: 'acquirer-checkout-product',
|
||||
element: 'input[name="acquirer"]',
|
||||
trigger: 'mouseup',
|
||||
},
|
||||
{
|
||||
stepId: 'pay-checkout-product',
|
||||
element: 'button:contains("Pay Now")',
|
||||
trigger: {
|
||||
url: /shop\/confirmation\//,
|
||||
},
|
||||
afterTrigger: function (tour) {
|
||||
window.localStorage.setItem("test-success", "{}");
|
||||
throw "afterTrigger test finish, remove this throw";
|
||||
},
|
||||
}
|
||||
];
|
||||
return this._super();
|
||||
},
|
||||
trigger: function () {
|
||||
return (this.resume() && this.testUrl(/^\/shop\//)) || this._super();
|
||||
},
|
||||
});
|
||||
|
||||
}());
|
||||
|
|
|
@ -7,10 +7,8 @@
|
|||
website.is_editable = true;
|
||||
website.EditorBar.include({
|
||||
start: function() {
|
||||
website.is_editable_button = website.is_editable_button || !!$("#wrap.js_sale").size();
|
||||
var res = this._super();
|
||||
if ($("#wrap.js_sale").size()) {
|
||||
this.$("button[data-action=edit]").removeClass("hidden");
|
||||
}
|
||||
this.$(".dropdown:has(.oe_content_menu)").removeClass("hidden");
|
||||
return res;
|
||||
},
|
||||
|
|
|
@ -7,5 +7,6 @@ $(document).ready(function () {
|
|||
$("div.oe_sale_acquirer_button[data-id]", $payment).addClass("hidden");
|
||||
$("div.oe_sale_acquirer_button[data-id='"+payment_id+"']", $payment).removeClass("hidden");
|
||||
});
|
||||
$payment.find("input[name='acquirer']:checked").click();
|
||||
|
||||
});
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
import test_ui
|
|
@ -0,0 +1,6 @@
|
|||
import openerp.addons.website.tests.test_ui as test_ui
|
||||
|
||||
def load_tests(loader, base, _):
|
||||
base.addTest(test_ui.WebsiteUiSuite(test_ui.full_path(__file__,'website_sale-sale_process-test.js'),
|
||||
{ 'action': 'website.action_website_homepage' }, 60.0))
|
||||
return base
|
|
@ -0,0 +1,28 @@
|
|||
var testRunner = require('../../../website/tests/ui_suite/ui_test_runner.js');
|
||||
|
||||
var waitFor = testRunner.waitFor;
|
||||
|
||||
testRunner.run(function websiteSaleTest (page, timeout) {
|
||||
page.evaluate(function () { localStorage.clear(); });
|
||||
waitFor(function clientReady () {
|
||||
return page.evaluate(function () {
|
||||
return window.$ && window.openerp && window.openerp.website
|
||||
&& window.openerp.website.TestConsole
|
||||
&& window.openerp.website.TestConsole.test('shoptest');
|
||||
});
|
||||
}, function executeTest () {
|
||||
page.evaluate(function () {
|
||||
window.openerp.website.TestConsole.test('shoptest').run(true);
|
||||
});
|
||||
waitFor(function testExecuted () {
|
||||
return page.evaluate(function () {
|
||||
var res = window.localStorage && window.localStorage.getItem
|
||||
&& window.localStorage.getItem("test-success");
|
||||
return res;
|
||||
});
|
||||
}, function finish () {
|
||||
console.log('{ "event": "success" }');
|
||||
phantom.exit();
|
||||
}, 4*timeout/5);
|
||||
}, timeout/5);
|
||||
});
|
|
@ -26,7 +26,7 @@
|
|||
<!-- List of categories -->
|
||||
|
||||
<template id="categories_recursive" name="Category list">
|
||||
<li t-att-class="str(category.id) == search.get('category') and 'active' or ''">
|
||||
<li t-att-class="category.id == search.get('category') and 'active' or ''">
|
||||
<a t-href="/shop/category/#{ slug(category) }/" t-field="category.name"></a>
|
||||
<ul t-if="category.child_id" class="nav nav-pills nav-stacked nav-hierarchy">
|
||||
<t t-foreach="category.child_id" t-as="category">
|
||||
|
@ -282,7 +282,7 @@
|
|||
<t t-call="website_sale.search" />
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<div class="col-sm-4" groups="base.group_sale_manager">
|
||||
<t t-call="website.publish_management">
|
||||
<t t-set="object" t-value="product"/>
|
||||
<t t-set="publish_edit" t-value="True"/>
|
||||
|
@ -713,7 +713,7 @@
|
|||
<div class="row">
|
||||
<div class="col-md-8 oe_mycart">
|
||||
<h3 class="page-header mt16">Billing Information
|
||||
<small t-if="user_id.id == website.public_user.id"> or
|
||||
<small groups="base.group_public"> or
|
||||
<a t-if="not partner" t-attf-href="/web#action=redirect&url=#{ request.httprequest.url }">sign in</a>
|
||||
</small>
|
||||
</h3>
|
||||
|
@ -946,6 +946,7 @@
|
|||
<img class="media-object" style="width: 60px; display: inline-block;"
|
||||
t-att-title="acquirer.name"
|
||||
t-att-src="'/payment_acquirer_%s/static/src/img/%s_icon.png' % (acquirer.name, acquirer.name)"/>
|
||||
<span t-field="acquirer.name"/>
|
||||
</label>
|
||||
</t>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue