[MERGE] Sync with main website-al branch
bzr revid: tde@openerp.com-20130920135710-diowg05s6cmoxa05
This commit is contained in:
commit
835bad4386
|
@ -509,6 +509,22 @@ table.editorbar-panel td.selected {
|
|||
.oe_seo_configuration .oe_seo_suggestion {
|
||||
cursor: pointer;
|
||||
}
|
||||
.oe_seo_configuration .oe_seo_keyword {
|
||||
padding: 0.2em 0.4em 0.2em 0.5em;
|
||||
border-radius: 0.4em;
|
||||
}
|
||||
.oe_seo_configuration .keyword-in-title {
|
||||
background-color: #5cb85c;
|
||||
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 {
|
||||
|
|
|
@ -429,6 +429,10 @@ $icon_close: #E00101
|
|||
/* ---- SEO TOOLS ---- */
|
||||
|
||||
$remove_color: $icon_close
|
||||
$in_title_color: #5cb85c
|
||||
$in_description_color: #428bca
|
||||
$in_body_color: #5bc0de
|
||||
$highlighted_text_color: #ffffff
|
||||
.oe_seo_configuration
|
||||
.modal-dialog
|
||||
width: 80%
|
||||
|
@ -436,6 +440,18 @@ $remove_color: $icon_close
|
|||
color: $remove_color
|
||||
.oe_seo_suggestion
|
||||
cursor: pointer
|
||||
.oe_seo_keyword
|
||||
padding: .2em .4em .2em .5em
|
||||
border-radius: .4em
|
||||
.keyword-in-title
|
||||
background-color: $in_title_color
|
||||
color: $highlighted_text_color
|
||||
.keyword-in-description
|
||||
background-color: $in_description_color
|
||||
color: $highlighted_text_color
|
||||
.keyword-in-body
|
||||
background-color: $in_body_color
|
||||
color: $highlighted_text_color
|
||||
|
||||
/* ---- ACE EDITOR ---- */
|
||||
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
|
||||
website.EditorBar.include({
|
||||
events: _.extend({}, website.EditorBar.prototype.events, {
|
||||
'click a[data-action=ace]': 'launch',
|
||||
'click a[data-action=ace]': 'launchAce',
|
||||
}),
|
||||
launch: function (e) {
|
||||
launchAce: function (e) {
|
||||
e.preventDefault();
|
||||
launch();
|
||||
},
|
||||
|
|
|
@ -6,45 +6,51 @@
|
|||
|
||||
website.EditorBar.include({
|
||||
events: _.extend({}, website.EditorBar.prototype.events, {
|
||||
'click a[data-action=promote-current-page]': 'promotePage',
|
||||
'click a[data-action=promote-current-page]': 'launchSeo',
|
||||
}),
|
||||
promotePage: function () {
|
||||
launchSeo: function () {
|
||||
(new website.seo.Configurator()).appendTo($(document.body));
|
||||
},
|
||||
});
|
||||
|
||||
website.seo = {};
|
||||
|
||||
function analyzeKeyword(htmlPage, keyword) {
|
||||
return htmlPage.isInTitle(keyword) ? {
|
||||
title: 'keyword-in-title',
|
||||
description: "This keyword is used in the page title",
|
||||
} : htmlPage.isInDescription(keyword) ? {
|
||||
title: 'keyword-in-description',
|
||||
description: "This keyword is used in the page description",
|
||||
} : htmlPage.isInBody(keyword) ? {
|
||||
title: 'keyword-in-body',
|
||||
description: "This keyword is used in the page content."
|
||||
} : { title: "", description: "" };
|
||||
}
|
||||
|
||||
website.seo.Suggestion = openerp.Widget.extend({
|
||||
template: 'website.seo_suggestion',
|
||||
events: {
|
||||
'click .js_seo_suggestion': 'select',
|
||||
},
|
||||
init: function (parent, keyword, htmlPage) {
|
||||
this.keyword = keyword;
|
||||
this.htmlPage = htmlPage;
|
||||
this.type = this.computeType();
|
||||
init: function (parent, options) {
|
||||
this.root = options.root;
|
||||
this.keyword = options.keyword;
|
||||
this.htmlPage = options.page;
|
||||
this._super(parent);
|
||||
},
|
||||
start: function () {
|
||||
var self = this;
|
||||
function update () {
|
||||
self.updateType();
|
||||
}
|
||||
self.htmlPage.on('title-changed', self, update);
|
||||
self.htmlPage.on('description-changed', self, update);
|
||||
this.htmlPage.on('title-changed', this, this.renderElement);
|
||||
this.htmlPage.on('description-changed', this, this.renderElement);
|
||||
},
|
||||
computeType: function () {
|
||||
// cf. http://getbootstrap.com/components/#labels
|
||||
// default, primary, success, info, warning, danger
|
||||
return this.htmlPage.isInTitle(this.keyword) ? 'success'
|
||||
: this.htmlPage.isInDescription(this.keyword) ? 'primary'
|
||||
: this.htmlPage.isInBody(this.keyword) ? 'info'
|
||||
: 'default';
|
||||
analyze: function () {
|
||||
return analyzeKeyword(this.htmlPage, this.keyword);
|
||||
},
|
||||
updateType: function () {
|
||||
this.type = this.computeType();
|
||||
this.renderElement();
|
||||
highlight: function () {
|
||||
return this.analyze().title;
|
||||
},
|
||||
tooltip: function () {
|
||||
return this.analyze().description;
|
||||
},
|
||||
select: function () {
|
||||
this.trigger('selected', this.keyword);
|
||||
|
@ -53,9 +59,9 @@
|
|||
|
||||
website.seo.SuggestionList = openerp.Widget.extend({
|
||||
template: 'website.seo_list',
|
||||
init: function (parent, word, htmlPage) {
|
||||
this.word = word;
|
||||
this.htmlPage = htmlPage;
|
||||
init: function (parent, options) {
|
||||
this.root = options.root;
|
||||
this.htmlPage = options.page;
|
||||
this._super(parent);
|
||||
},
|
||||
start: function () {
|
||||
|
@ -67,14 +73,18 @@
|
|||
function addSuggestions (list) {
|
||||
self.$el.empty();
|
||||
// TODO Improve algorithm + Ajust based on custom user keywords
|
||||
var nameRegex = new RegExp(self.companyName, "gi");
|
||||
var cleanList = _.map(list, function removeCompanyName (word) {
|
||||
return word.replace(nameRegex, "").trim();
|
||||
var regex = new RegExp(self.root, "gi");
|
||||
var cleanList = _.map(list, function (word) {
|
||||
return word.replace(regex, "").trim();
|
||||
});
|
||||
// TODO Order properly ?
|
||||
_.each(_.uniq(cleanList), function (keyword) {
|
||||
if (keyword) {
|
||||
var suggestion = new website.seo.Suggestion(self, keyword, self.htmlPage);
|
||||
var suggestion = new website.seo.Suggestion(self, {
|
||||
root: self.root,
|
||||
keyword: keyword,
|
||||
page: self.htmlPage,
|
||||
});
|
||||
suggestion.on('selected', self, function (word) {
|
||||
self.trigger('selected', word);
|
||||
});
|
||||
|
@ -82,7 +92,7 @@
|
|||
}
|
||||
});
|
||||
}
|
||||
$.getJSON("http://seo.eu01.aws.af.cm/suggest/"+encodeURIComponent(this.word + " "), addSuggestions);
|
||||
$.getJSON("http://seo.eu01.aws.af.cm/suggest/"+encodeURIComponent(this.root + " "), addSuggestions);
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -92,36 +102,36 @@
|
|||
'click a[data-action=remove-keyword]': 'destroy',
|
||||
},
|
||||
maxWordsPerKeyword: 4, // TODO Check
|
||||
init: function (parent, keyword, htmlPage) {
|
||||
this.keyword = keyword;
|
||||
this.htmlPage = htmlPage;
|
||||
this.type = this.computeType();
|
||||
init: function (parent, options) {
|
||||
this.keyword = options.word;
|
||||
this.htmlPage = options.page;
|
||||
this._super(parent);
|
||||
},
|
||||
start: function () {
|
||||
var self = this;
|
||||
function update () {
|
||||
self.updateType();
|
||||
}
|
||||
self.htmlPage.on('title-changed', self, update);
|
||||
self.htmlPage.on('description-changed', self, update);
|
||||
self.suggestionList = new website.seo.SuggestionList(self, this.keyword, this.htmlPage);
|
||||
self.suggestionList.on('selected', self, function (word) {
|
||||
self.trigger('selected', word);
|
||||
this.htmlPage.on('title-changed', this, this.updateLabel);
|
||||
this.htmlPage.on('description-changed', this, this.updateLabel);
|
||||
this.suggestionList = new website.seo.SuggestionList(this, {
|
||||
root: this.keyword,
|
||||
page: this.htmlPage,
|
||||
});
|
||||
this.suggestionList.on('selected', this, function (word) {
|
||||
this.trigger('selected', word);
|
||||
});
|
||||
this.suggestionList.appendTo(this.$('.js_seo_keyword_suggestion'));
|
||||
},
|
||||
computeType: function () {
|
||||
// cf. http://getbootstrap.com/components/#labels
|
||||
// default, primary, success, info, warning, danger
|
||||
return this.htmlPage.isInTitle(this.keyword) ? 'success'
|
||||
: this.htmlPage.isInDescription(this.keyword) ? 'primary'
|
||||
: this.htmlPage.isInBody(this.keyword) ? 'warning'
|
||||
: 'default';
|
||||
analyze: function () {
|
||||
return analyzeKeyword(this.htmlPage, this.keyword);
|
||||
},
|
||||
updateType: function () {
|
||||
this.type = this.computeType();
|
||||
this.$('span.js_seo_keyword').attr('class', "label label-"+this.type+" js_seo_keyword");
|
||||
highlight: function () {
|
||||
return this.analyze().title;
|
||||
},
|
||||
tooltip: function () {
|
||||
return this.analyze().description;
|
||||
},
|
||||
updateLabel: function () {
|
||||
var cssClass = "oe_seo_keyword js_seo_keyword " + this.highlight();
|
||||
this.$(".js_seo_keyword").attr('class', cssClass);
|
||||
this.$(".js_seo_keyword").attr('title', this.tooltip());
|
||||
},
|
||||
destroy: function () {
|
||||
this.trigger('removed');
|
||||
|
@ -132,29 +142,44 @@
|
|||
website.seo.KeywordList = openerp.Widget.extend({
|
||||
template: 'website.seo_list',
|
||||
maxKeywords: 10,
|
||||
init: function (parent, htmlPage) {
|
||||
this.htmlPage = htmlPage;
|
||||
init: function (parent, options) {
|
||||
this.htmlPage = options.page;
|
||||
this._super(parent);
|
||||
},
|
||||
start: function () {
|
||||
var self = this;
|
||||
var existingKeywords = self.htmlPage.keywords();
|
||||
if (existingKeywords.length > 0) {
|
||||
_.each(existingKeywords, function (word) {
|
||||
self.add.call(self, word);
|
||||
});
|
||||
} else {
|
||||
var companyName = self.htmlPage.company().toLowerCase();
|
||||
self.add(companyName);
|
||||
}
|
||||
},
|
||||
keywords: function () {
|
||||
var result = [];
|
||||
this.$('span.js_seo_keyword').each(function () {
|
||||
this.$('.js_seo_keyword').each(function () {
|
||||
result.push($(this).data('keyword'));
|
||||
});
|
||||
return result;
|
||||
},
|
||||
isKeywordListFull: function () {
|
||||
isFull: function () {
|
||||
return this.keywords().length >= this.maxKeywords;
|
||||
},
|
||||
isExistingKeyword: function (word) {
|
||||
exists: function (word) {
|
||||
return _.contains(this.keywords(), word);
|
||||
},
|
||||
add: function (candidate) {
|
||||
var self = this;
|
||||
// TODO Refine
|
||||
var word = candidate ? candidate.replace(/[,;.:<>]+/g, " ").replace(/ +/g, " ").trim() : "";
|
||||
if (word && !self.isKeywordListFull() && !self.isExistingKeyword(word)) {
|
||||
var keyword = new website.seo.Keyword(self, word, this.htmlPage);
|
||||
var word = candidate ? candidate.replace(/[,;.:<>]+/g, " ").replace(/ +/g, " ").trim().toLowerCase() : "";
|
||||
if (word && !self.isFull() && !self.exists(word)) {
|
||||
var keyword = new website.seo.Keyword(self, {
|
||||
word: word,
|
||||
page: this.htmlPage,
|
||||
});
|
||||
keyword.on('removed', self, function () {
|
||||
self.trigger('list-not-full');
|
||||
self.trigger('removed', word);
|
||||
|
@ -164,7 +189,7 @@
|
|||
});
|
||||
keyword.appendTo(self.$el);
|
||||
}
|
||||
if (self.isKeywordListFull()) {
|
||||
if (self.isFull()) {
|
||||
self.trigger('list-full');
|
||||
}
|
||||
},
|
||||
|
@ -181,8 +206,8 @@
|
|||
|
||||
|
||||
website.seo.ImageList = openerp.Widget.extend({
|
||||
init: function (parent, htmlPage) {
|
||||
this.htmlPage = htmlPage;
|
||||
init: function (parent, options) {
|
||||
this.htmlPage = options.page;
|
||||
this._super(parent);
|
||||
},
|
||||
start: function () {
|
||||
|
@ -228,10 +253,11 @@
|
|||
this.trigger('description-changed', description);
|
||||
},
|
||||
keywords: function () {
|
||||
return $('meta[name=keywords]').attr('value').split(",");
|
||||
var parsed = $('meta[name=keywords]').attr('value').split(",");
|
||||
return parsed[0] ? parsed: [];
|
||||
},
|
||||
changeKeywords: function (keywords) {
|
||||
$('meta[name=keywords]').attr('value', keyword.join(","));
|
||||
$('meta[name=keywords]').attr('value', keywords.join(","));
|
||||
this.trigger('keywords-changed', keywords);
|
||||
},
|
||||
headers: function (tag) {
|
||||
|
@ -299,9 +325,13 @@
|
|||
$modal.find('input[name=seo_page_title]').val(htmlPage.title());
|
||||
$modal.find('textarea[name=seo_page_description]').val(htmlPage.description());
|
||||
self.suggestImprovements();
|
||||
self.imageList = new website.seo.ImageList(self, htmlPage);
|
||||
self.imageList.appendTo($modal.find('.js_seo_image_list'));
|
||||
self.keywordList = new website.seo.KeywordList(self, htmlPage);
|
||||
self.imageList = new website.seo.ImageList(self, { page: htmlPage });
|
||||
if (htmlPage.images().length === 0) {
|
||||
$modal.find('.js_image_section').remove()
|
||||
} else {
|
||||
self.imageList.appendTo($modal.find('.js_seo_image_list'));
|
||||
}
|
||||
self.keywordList = new website.seo.KeywordList(self, { page: htmlPage });
|
||||
self.keywordList.on('list-full', self, function () {
|
||||
$modal.find('input[name=seo_page_keywords]')
|
||||
.attr('readonly', "readonly")
|
||||
|
@ -319,9 +349,9 @@
|
|||
self.keywordList.add(word);
|
||||
});
|
||||
self.keywordList.appendTo($modal.find('.js_seo_keywords_list'));
|
||||
var companyName = htmlPage.company().toLowerCase();
|
||||
self.addKeyword(companyName);
|
||||
$modal.modal();
|
||||
// Avoid the 'Edit' button in the background boucing needlessly
|
||||
$modal.on('click', function (e) { e.stopPropagation(); });
|
||||
},
|
||||
suggestImprovements: function () {
|
||||
var tips = [];
|
||||
|
@ -336,13 +366,13 @@
|
|||
if (htmlPage.headers('h1').length === 0) {
|
||||
tips.push({
|
||||
type: 'warning',
|
||||
message: "You don't have an <h1> tag on your page.",
|
||||
message: "This page seems to be missing an <h1> tag.",
|
||||
});
|
||||
}
|
||||
if (htmlPage.headers('h1').length > 1) {
|
||||
tips.push({
|
||||
type: 'warning',
|
||||
message: "You have more than one <h1> tag on your page.",
|
||||
message: "The page contains more than one <h1> tag.",
|
||||
});
|
||||
}
|
||||
if (tips.length > 0) {
|
||||
|
@ -350,7 +380,7 @@
|
|||
displayTip(tip.message, tip.type);
|
||||
});
|
||||
} else {
|
||||
displayTip("Your page makup is appropriate for search engines.", 'success');
|
||||
displayTip("The markup on this page is appropriate for search engines.", 'success');
|
||||
}
|
||||
},
|
||||
confirmKeyword: function (e) {
|
||||
|
@ -389,5 +419,9 @@
|
|||
self.htmlPage.changeDescription(description);
|
||||
}, 1);
|
||||
},
|
||||
destroy: function () {
|
||||
this.htmlPage.changeKeywords(this.keywordList.keywords());
|
||||
this._super();
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
|
|
@ -426,13 +426,24 @@
|
|||
var $zone = $(this);
|
||||
var $template = $(zone_template).addClass("oe_vertical");
|
||||
var nb = 0;
|
||||
var $lastinsert = false;
|
||||
var left = 0;
|
||||
var temp_left = 0;
|
||||
$zone.find('> *:not(.oe_drop_zone):visible').each(function () {
|
||||
var $col = $(this);
|
||||
$template.css('height', ($col.outerHeight() + parseInt($col.css("margin-top")) + parseInt($col.css("margin-bottom")))+'px');
|
||||
$col.after($template.clone());
|
||||
if (!nb) {
|
||||
$(this).before($template.clone());
|
||||
$lastinsert = $template.clone();
|
||||
$(this).after($lastinsert);
|
||||
|
||||
temp_left = $col.position().left;
|
||||
if (left === temp_left) {
|
||||
$col.prev(".oe_drop_zone.oe_vertical").remove();
|
||||
$col.before($template.clone().css("clear", "left"));
|
||||
}
|
||||
else if (!nb) {
|
||||
$col.before($template.clone());
|
||||
}
|
||||
left = temp_left;
|
||||
nb ++;
|
||||
});
|
||||
if (!nb) {
|
||||
|
@ -456,11 +467,11 @@
|
|||
var count;
|
||||
do {
|
||||
count = 0;
|
||||
var $zones = $('.oe_drop_zone + .oe_drop_zone'); // no two consecutive zones
|
||||
count += $zones.length;
|
||||
$zones.remove();
|
||||
// var $zones = $('.oe_drop_zone + .oe_drop_zone'); // no two consecutive zones
|
||||
// count += $zones.length;
|
||||
// $zones.remove();
|
||||
|
||||
$zones = $('.oe_drop_zone > .oe_drop_zone').remove(); // no recusrive zones
|
||||
$zones = $('.oe_drop_zone > .oe_drop_zone:not(.oe_vertical)').remove(); // no recusrive zones
|
||||
count += $zones.length;
|
||||
$zones.remove();
|
||||
} while (count > 0);
|
||||
|
@ -846,7 +857,7 @@
|
|||
var xy = event['page'+XY];
|
||||
var begin = current;
|
||||
var beginClass = self.$target.attr("class");
|
||||
var regClass = new RegExp("\\s*" + resize[0][begin].replace(/[-]*[0-9]+/, '[0-9-]+'), 'g');
|
||||
var regClass = new RegExp("\\s*" + resize[0][begin].replace(/[-]*[0-9]+/, '[-]*[0-9]+'), 'g');
|
||||
|
||||
var cursor = $handle.css("cursor")+'-important';
|
||||
$("body").addClass(cursor);
|
||||
|
|
|
@ -26,14 +26,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<dl class="dl-horizontal">
|
||||
<dt><span class="label label-warning">Keywords</span></dt>
|
||||
<dd>
|
||||
<ul class="list-inline">
|
||||
<li><span class="label label-default">Most searched topics related to these keywords</span></li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
<span class="text-muted">Most searched topics related your keywords, ordered by importance:</span>
|
||||
<!-- filled in JS -->
|
||||
</section>
|
||||
<section>
|
||||
|
@ -53,10 +46,10 @@
|
|||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<section class="js_image_section">
|
||||
<h3 class="page-header">3. Describe your images</h3>
|
||||
<div class="row js_seo_image_list">
|
||||
<!-- filled in JS -->
|
||||
<!-- filled in JS -->
|
||||
</div>
|
||||
</section>
|
||||
<hr/>
|
||||
|
@ -76,19 +69,16 @@
|
|||
</t>
|
||||
|
||||
<t t-name="website.seo_tip">
|
||||
<div t-attf-class="alert alert-#{widget.type}">
|
||||
<button title="Dismiss" type="button" class="close" data-action="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
<t t-raw="widget.message"/>
|
||||
<div t-attf-class="alert alert-#{ widget.type }">
|
||||
<t t-raw="widget.message"/>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-name="website.seo_keyword">
|
||||
<dl class="dl-horizontal js_seo_keyword">
|
||||
<dl class="dl-horizontal">
|
||||
<dt>
|
||||
<span t-attf-class="label label-#{ widget.type } js_seo_keyword" t-att-data-keyword="widget.keyword">
|
||||
<a href="#" class="oe_remove" data-action="remove-keyword">x</a>
|
||||
&nbsp;
|
||||
<t t-raw="widget.keyword"/>
|
||||
<span t-attf-title="#{ widget.tooltip() }" t-attf-class="oe_seo_keyword #{ widget.highlight() } js_seo_keyword" t-att-data-keyword="widget.keyword">
|
||||
<a href="#" class="oe_remove" data-action="remove-keyword">x</a> <t t-raw="widget.keyword"/>
|
||||
</span>
|
||||
</dt>
|
||||
<dd class="js_seo_keyword_suggestion">
|
||||
|
@ -99,7 +89,7 @@
|
|||
|
||||
<t t-name="website.seo_suggestion">
|
||||
<li class="oe_seo_suggestion">
|
||||
<span t-attf-class="label label-#{ widget.type } js_seo_suggestion" t-att-data-keyword="widget.keyword">
|
||||
<span t-attf-title="#{ widget.tooltip() }" t-attf-class="oe_seo_keyword #{ widget.highlight() } js_seo_suggestion" t-att-data-keyword="widget.keyword">
|
||||
<t t-raw="widget.keyword"/>
|
||||
</span>
|
||||
</li>
|
||||
|
|
Loading…
Reference in New Issue