[MERGE] from trunk

bzr revid: xmo@openerp.com-20130913125230-38lb4jv8ypt6y9dh
This commit is contained in:
Xavier Morel
2013-09-13 14:52:30 +02:00
15 changed files with 1150 additions and 677 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
ace.define("ace/theme/monokai",["require","exports","module","ace/lib/dom"],function(e,t,n){t.isDark=!0,t.cssClass="ace-monokai",t.cssText=".ace-monokai .ace_gutter {background: #2F3129;color: #8F908A}.ace-monokai .ace_print-margin {width: 1px;background: #555651}.ace-monokai {background-color: #272822;color: #F8F8F2}.ace-monokai .ace_cursor {border-left: 2px solid #F8F8F0}.ace-monokai .ace_overwrite-cursors .ace_cursor {border-left: 0px;border-bottom: 1px solid #F8F8F0}.ace-monokai .ace_marker-layer .ace_selection {background: #49483E}.ace-monokai.ace_multiselect .ace_selection.ace_start {box-shadow: 0 0 3px 0px #272822;border-radius: 2px}.ace-monokai .ace_marker-layer .ace_step {background: rgb(102, 82, 0)}.ace-monokai .ace_marker-layer .ace_bracket {margin: -1px 0 0 -1px;border: 1px solid #49483E}.ace-monokai .ace_marker-layer .ace_active-line {background: #202020}.ace-monokai .ace_gutter-active-line {background-color: #272727}.ace-monokai .ace_marker-layer .ace_selected-word {border: 1px solid #49483E}.ace-monokai .ace_invisible {color: #52524d}.ace-monokai .ace_entity.ace_name.ace_tag,.ace-monokai .ace_keyword,.ace-monokai .ace_meta.ace_tag,.ace-monokai .ace_storage {color: #F92672}.ace-monokai .ace_constant.ace_character,.ace-monokai .ace_constant.ace_language,.ace-monokai .ace_constant.ace_numeric,.ace-monokai .ace_constant.ace_other {color: #AE81FF}.ace-monokai .ace_invalid {color: #F8F8F0;background-color: #F92672}.ace-monokai .ace_invalid.ace_deprecated {color: #F8F8F0;background-color: #AE81FF}.ace-monokai .ace_support.ace_constant,.ace-monokai .ace_support.ace_function {color: #66D9EF}.ace-monokai .ace_fold {background-color: #A6E22E;border-color: #F8F8F2}.ace-monokai .ace_storage.ace_type,.ace-monokai .ace_support.ace_class,.ace-monokai .ace_support.ace_type {font-style: italic;color: #66D9EF}.ace-monokai .ace_entity.ace_name.ace_function,.ace-monokai .ace_entity.ace_other,.ace-monokai .ace_entity.ace_other.ace_attribute-name,.ace-monokai .ace_variable {color: #A6E22E}.ace-monokai .ace_variable.ace_parameter {font-style: italic;color: #FD971F}.ace-monokai .ace_string {color: #E6DB74}.ace-monokai .ace_comment {color: #75715E}.ace-monokai .ace_markup.ace_underline {text-decoration: underline}.ace-monokai .ace_indent-guide {background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWPQ0FD0ZXBzd/wPAAjVAoxeSgNeAAAAAElFTkSuQmCC) right repeat-y;}";var r=e("../lib/dom");r.importCssString(t.cssText,t.cssClass)})
@@ -0,0 +1,358 @@
/**
* vkBeautify - javascript plugin to pretty-print or minify text in XML, JSON, CSS and SQL formats.
*
* Version - 0.99.00.beta
* Copyright (c) 2012 Vadim Kiryukhin
* vkiryukhin @ gmail.com
* http://www.eslinstructor.net/vkbeautify/
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Pretty print
*
* vkbeautify.xml(text [,indent_pattern]);
* vkbeautify.json(text [,indent_pattern]);
* vkbeautify.css(text [,indent_pattern]);
* vkbeautify.sql(text [,indent_pattern]);
*
* @text - String; text to beatufy;
* @indent_pattern - Integer | String;
* Integer: number of white spaces;
* String: character string to visualize indentation ( can also be a set of white spaces )
* Minify
*
* vkbeautify.xmlmin(text [,preserve_comments]);
* vkbeautify.jsonmin(text);
* vkbeautify.cssmin(text [,preserve_comments]);
* vkbeautify.sqlmin(text);
*
* @text - String; text to minify;
* @preserve_comments - Bool; [optional];
* Set this flag to true to prevent removing comments from @text ( minxml and mincss functions only. )
*
* Examples:
* vkbeautify.xml(text); // pretty print XML
* vkbeautify.json(text, 4 ); // pretty print JSON
* vkbeautify.css(text, '. . . .'); // pretty print CSS
* vkbeautify.sql(text, '----'); // pretty print SQL
*
* vkbeautify.xmlmin(text, true);// minify XML, preserve comments
* vkbeautify.jsonmin(text);// minify JSON
* vkbeautify.cssmin(text);// minify CSS, remove comments ( default )
* vkbeautify.sqlmin(text);// minify SQL
*
*/
(function() {
function createShiftArr(step) {
var space = ' ';
if ( isNaN(parseInt(step)) ) { // argument is string
space = step;
} else { // argument is integer
switch(step) {
case 1: space = ' '; break;
case 2: space = ' '; break;
case 3: space = ' '; break;
case 4: space = ' '; break;
case 5: space = ' '; break;
case 6: space = ' '; break;
case 7: space = ' '; break;
case 8: space = ' '; break;
case 9: space = ' '; break;
case 10: space = ' '; break;
case 11: space = ' '; break;
case 12: space = ' '; break;
}
}
var shift = ['\n']; // array of shifts
for(ix=0;ix<100;ix++){
shift.push(shift[ix]+space);
}
return shift;
}
function vkbeautify(){
this.step = ' '; // 4 spaces
this.shift = createShiftArr(this.step);
};
vkbeautify.prototype.xml = function(text,step) {
var ar = text.replace(/>\s{0,}</g,"><")
.replace(/</g,"~::~<")
.replace(/\s*xmlns\:/g,"~::~xmlns:")
.replace(/\s*xmlns\=/g,"~::~xmlns=")
.split('~::~'),
len = ar.length,
inComment = false,
deep = 0,
str = '',
ix = 0,
shift = step ? createShiftArr(step) : this.shift;
for(ix=0;ix<len;ix++) {
// start comment or <![CDATA[...]]> or <!DOCTYPE //
if(ar[ix].search(/<!/) > -1) {
str += shift[deep]+ar[ix];
inComment = true;
// end comment or <![CDATA[...]]> //
if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1 || ar[ix].search(/!DOCTYPE/) > -1 ) {
inComment = false;
}
} else
// end comment or <![CDATA[...]]> //
if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1) {
str += ar[ix];
inComment = false;
} else
// <elm></elm> //
if( /^<\w/.exec(ar[ix-1]) && /^<\/\w/.exec(ar[ix]) &&
/^<[\w:\-\.\,]+/.exec(ar[ix-1]) == /^<\/[\w:\-\.\,]+/.exec(ar[ix])[0].replace('/','')) {
str += ar[ix];
if(!inComment) deep--;
} else
// <elm> //
if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) == -1 && ar[ix].search(/\/>/) == -1 ) {
str = !inComment ? str += shift[deep++]+ar[ix] : str += ar[ix];
} else
// <elm>...</elm> //
if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) > -1) {
str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
} else
// </elm> //
if(ar[ix].search(/<\//) > -1) {
str = !inComment ? str += shift[--deep]+ar[ix] : str += ar[ix];
} else
// <elm/> //
if(ar[ix].search(/\/>/) > -1 ) {
str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
} else
// <? xml ... ?> //
if(ar[ix].search(/<\?/) > -1) {
str += shift[deep]+ar[ix];
} else
// xmlns //
if( ar[ix].search(/xmlns\:/) > -1 || ar[ix].search(/xmlns\=/) > -1) {
str += shift[deep]+ar[ix];
}
else {
str += ar[ix];
}
}
return (str[0] == '\n') ? str.slice(1) : str;
}
vkbeautify.prototype.json = function(text,step) {
var step = step ? step : this.step;
if (typeof JSON === 'undefined' ) return text;
if ( typeof text === "string" ) return JSON.stringify(JSON.parse(text), null, step);
if ( typeof text === "object" ) return JSON.stringify(text, null, step);
return text; // text is not string nor object
}
vkbeautify.prototype.css = function(text, step) {
var ar = text.replace(/\s{1,}/g,' ')
.replace(/\{/g,"{~::~")
.replace(/\}/g,"~::~}~::~")
.replace(/\;/g,";~::~")
.replace(/\/\*/g,"~::~/*")
.replace(/\*\//g,"*/~::~")
.replace(/~::~\s{0,}~::~/g,"~::~")
.split('~::~'),
len = ar.length,
deep = 0,
str = '',
ix = 0,
shift = step ? createShiftArr(step) : this.shift;
for(ix=0;ix<len;ix++) {
if( /\{/.exec(ar[ix])) {
str += shift[deep++]+ar[ix];
} else
if( /\}/.exec(ar[ix])) {
str += shift[--deep]+ar[ix];
} else
if( /\*\\/.exec(ar[ix])) {
str += shift[deep]+ar[ix];
}
else {
str += shift[deep]+ar[ix];
}
}
return str.replace(/^\n{1,}/,'');
}
//----------------------------------------------------------------------------
function isSubquery(str, parenthesisLevel) {
return parenthesisLevel - (str.replace(/\(/g,'').length - str.replace(/\)/g,'').length )
}
function split_sql(str, tab) {
return str.replace(/\s{1,}/g," ")
.replace(/ AND /ig,"~::~"+tab+tab+"AND ")
.replace(/ BETWEEN /ig,"~::~"+tab+"BETWEEN ")
.replace(/ CASE /ig,"~::~"+tab+"CASE ")
.replace(/ ELSE /ig,"~::~"+tab+"ELSE ")
.replace(/ END /ig,"~::~"+tab+"END ")
.replace(/ FROM /ig,"~::~FROM ")
.replace(/ GROUP\s{1,}BY/ig,"~::~GROUP BY ")
.replace(/ HAVING /ig,"~::~HAVING ")
//.replace(/ SET /ig," SET~::~")
.replace(/ IN /ig," IN ")
.replace(/ JOIN /ig,"~::~JOIN ")
.replace(/ CROSS~::~{1,}JOIN /ig,"~::~CROSS JOIN ")
.replace(/ INNER~::~{1,}JOIN /ig,"~::~INNER JOIN ")
.replace(/ LEFT~::~{1,}JOIN /ig,"~::~LEFT JOIN ")
.replace(/ RIGHT~::~{1,}JOIN /ig,"~::~RIGHT JOIN ")
.replace(/ ON /ig,"~::~"+tab+"ON ")
.replace(/ OR /ig,"~::~"+tab+tab+"OR ")
.replace(/ ORDER\s{1,}BY/ig,"~::~ORDER BY ")
.replace(/ OVER /ig,"~::~"+tab+"OVER ")
.replace(/\(\s{0,}SELECT /ig,"~::~(SELECT ")
.replace(/\)\s{0,}SELECT /ig,")~::~SELECT ")
.replace(/ THEN /ig," THEN~::~"+tab+"")
.replace(/ UNION /ig,"~::~UNION~::~")
.replace(/ USING /ig,"~::~USING ")
.replace(/ WHEN /ig,"~::~"+tab+"WHEN ")
.replace(/ WHERE /ig,"~::~WHERE ")
.replace(/ WITH /ig,"~::~WITH ")
//.replace(/\,\s{0,}\(/ig,",~::~( ")
//.replace(/\,/ig,",~::~"+tab+tab+"")
.replace(/ ALL /ig," ALL ")
.replace(/ AS /ig," AS ")
.replace(/ ASC /ig," ASC ")
.replace(/ DESC /ig," DESC ")
.replace(/ DISTINCT /ig," DISTINCT ")
.replace(/ EXISTS /ig," EXISTS ")
.replace(/ NOT /ig," NOT ")
.replace(/ NULL /ig," NULL ")
.replace(/ LIKE /ig," LIKE ")
.replace(/\s{0,}SELECT /ig,"SELECT ")
.replace(/\s{0,}UPDATE /ig,"UPDATE ")
.replace(/ SET /ig," SET ")
.replace(/~::~{1,}/g,"~::~")
.split('~::~');
}
vkbeautify.prototype.sql = function(text,step) {
var ar_by_quote = text.replace(/\s{1,}/g," ")
.replace(/\'/ig,"~::~\'")
.split('~::~'),
len = ar_by_quote.length,
ar = [],
deep = 0,
tab = this.step,//+this.step,
inComment = true,
inQuote = false,
parenthesisLevel = 0,
str = '',
ix = 0,
shift = step ? createShiftArr(step) : this.shift;;
for(ix=0;ix<len;ix++) {
if(ix%2) {
ar = ar.concat(ar_by_quote[ix]);
} else {
ar = ar.concat(split_sql(ar_by_quote[ix], tab) );
}
}
len = ar.length;
for(ix=0;ix<len;ix++) {
parenthesisLevel = isSubquery(ar[ix], parenthesisLevel);
if( /\s{0,}\s{0,}SELECT\s{0,}/.exec(ar[ix])) {
ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"")
}
if( /\s{0,}\s{0,}SET\s{0,}/.exec(ar[ix])) {
ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"")
}
if( /\s{0,}\(\s{0,}SELECT\s{0,}/.exec(ar[ix])) {
deep++;
str += shift[deep]+ar[ix];
} else
if( /\'/.exec(ar[ix]) ) {
if(parenthesisLevel<1 && deep) {
deep--;
}
str += ar[ix];
}
else {
str += shift[deep]+ar[ix];
if(parenthesisLevel<1 && deep) {
deep--;
}
}
var junk = 0;
}
str = str.replace(/^\n{1,}/,'').replace(/\n{1,}/g,"\n");
return str;
}
vkbeautify.prototype.xmlmin = function(text, preserveComments) {
var str = preserveComments ? text
: text.replace(/\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>/g,"")
.replace(/[ \r\n\t]{1,}xmlns/g, ' xmlns');
return str.replace(/>\s{0,}</g,"><");
}
vkbeautify.prototype.jsonmin = function(text) {
if (typeof JSON === 'undefined' ) return text;
return JSON.stringify(JSON.parse(text), null, 0);
}
vkbeautify.prototype.cssmin = function(text, preserveComments) {
var str = preserveComments ? text
: text.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\//g,"") ;
return str.replace(/\s{1,}/g,' ')
.replace(/\{\s{1,}/g,"{")
.replace(/\}\s{1,}/g,"}")
.replace(/\;\s{1,}/g,";")
.replace(/\/\*\s{1,}/g,"/*")
.replace(/\*\/\s{1,}/g,"*/");
}
vkbeautify.prototype.sqlmin = function(text) {
return text.replace(/\s{1,}/g," ").replace(/\s{1,}\(/,"(").replace(/\s{1,}\)/,")");
}
window.vkbeautify = new vkbeautify();
})();
+46 -29
View File
@@ -1,3 +1,4 @@
@charset "utf-8";
/* ---- CKEditor Minimal Reset ---- */
.navbar.navbar-inverse .cke_chrome {
border: none;
@@ -24,7 +25,7 @@
width: 100%;
padding: 2px;
margin: 0;
z-index: 10000;
z-index: 20000;
background-color: #414141;
background: -webkit-linear-gradient(#646060, #262626);
box-sizing: border-box;
@@ -82,10 +83,6 @@
}
/* ---- EDITOR BAR ---- */
.modal .tab-content {
padding-top: 5px;
}
table.editorbar-panel {
cursor: pointer;
width: 100%;
@@ -94,10 +91,6 @@ table.editorbar-panel td.selected {
background-color: #b1c9d9;
}
.modal .image-preview-container, .modal .image-preview {
margin-bottom: 0.5em;
}
/* ---- RTE ---- */
.oe_editable .btn {
-webkit-user-select: auto;
@@ -118,7 +111,7 @@ table.editorbar-panel td.selected {
background: #282828;
box-shadow: 0px 10px 10px -10px black inset;
overflow-y: auto;
z-index: 100;
z-index: 20000;
}
#oe_snippets .nav-pills {
padding: 3px 8px;
@@ -179,6 +172,11 @@ table.editorbar-panel td.selected {
height: 32px;
margin: -16px 0px;
-webkit-transition: margin 250ms linear;
width: 100%;
z-index: 1000;
position: absolute;
background: rgba(153, 0, 255, 0.17);
border-radius: 3px;
}
.oe_drop_zone.oe_insert:first-child:not(:last-child) {
margin-top: -8px;
@@ -204,11 +202,11 @@ table.editorbar-panel td.selected {
.oe_drop_zone.oe_insert.oe_hover:before {
border-top: dashed 2px rgba(116, 255, 161, 0.72);
}
.oe_drop_zone.oe_overlay {
.oe_drop_zone.oe_insert.oe_vertical {
width: 16px;
display: inline-block;
position: absolute;
background: rgba(153, 0, 255, 0.17);
border-radius: 3px;
margin: 0px !important;
}
.oe_drop_zone {
@@ -217,7 +215,7 @@ table.editorbar-panel td.selected {
}
.oe_drop_zone.oe_hover {
background: rgba(0, 255, 133, 0.22);
z-index: 97;
z-index: 1001;
}
/* ---- SNIPPET MANIPULATOR ---- */
@@ -231,9 +229,6 @@ table.editorbar-panel td.selected {
box-sizing: border-box;
pointer-events: none;
}
.oe_overlay .oe_handle {
display: none !important;
}
.oe_overlay.oe_hover {
opacity: 1;
cursor: pointer;
@@ -248,6 +243,9 @@ table.editorbar-panel td.selected {
.oe_overlay.oe_selected {
border-color: rgba(0, 153, 255, 0.5);
}
.oe_overlay .oe_handle {
display: none !important;
}
.oe_overlay.oe_active {
border-color: rgba(153, 0, 255, 0.5);
}
@@ -255,25 +253,40 @@ table.editorbar-panel td.selected {
display: block !important;
pointer-events: auto;
}
.oe_overlay .icon.btn {
display: inline-block;
}
.oe_overlay .oe_overlay_options {
display: none;
z-index: 99;
z-index: 1002;
}
.oe_overlay .oe_overlay_options .oe_option {
pointer-events: auto;
.oe_overlay .oe_overlay_options .oe_options, .oe_overlay .oe_overlay_options .oe_label, .oe_overlay .oe_overlay_options .oe_move {
position: absolute;
display: block;
z-index: 1002;
top: -11px;
}
.oe_overlay .oe_overlay_options .oe_option.n {
top: 0px;
.oe_overlay .oe_overlay_options .oe_options {
pointer-events: auto;
left: -14px;
}
.oe_overlay .oe_overlay_options .oe_option.e {
right: 0px;
.oe_overlay .oe_overlay_options .oe_label {
top: -8px;
right: 6px;
background: white;
font-size: 75%;
color: rgba(153, 0, 255, 0.5);
padding: 0 5px;
}
.oe_overlay .oe_overlay_options .oe_option.s {
bottom: 0px;
.oe_overlay .oe_overlay_options .oe_move {
pointer-events: auto;
left: 50%;
}
.oe_overlay .oe_overlay_options .oe_option.w {
left: 0px;
.oe_overlay .oe_overlay_options .oe_move .js_box_move {
margin-left: -50%;
}
.oe_overlay .oe_overlay_options .dropdown-menu select, .oe_overlay .oe_overlay_options .dropdown-menu input {
display: block;
}
.oe_overlay.oe_active .oe_overlay_options {
display: block;
@@ -337,6 +350,10 @@ table.editorbar-panel td.selected {
cursor: w-resize !important;
}
.move-important, .move-important * {
cursor: move !important;
}
/* ---- MOBILE PREVIEW ---- */
.oe_mobile_preview.modal .modal-content {
height: 660px;
+39 -24
View File
@@ -25,7 +25,7 @@
width: 100%
padding: 2px
margin: 0
z-index: 10000
z-index: 20000
background-color: #414141
background: -webkit-linear-gradient(#646060, #262626)
box-sizing: border-box
@@ -74,18 +74,12 @@
/* ---- EDITOR BAR ---- */
.modal .tab-content
padding-top: 5px
table.editorbar-panel
cursor: pointer
width: 100%
td.selected
background-color: #b1c9d9
.modal .image-preview-container, .modal .image-preview
margin-bottom: 0.5em
/* ---- RTE ---- */
// bootstrap makes .btn elements unselectable -> RTE double-click can't know
@@ -109,7 +103,7 @@ table.editorbar-panel
background: rgb(40,40,40)
box-shadow: 0px 10px 10px -10px black inset
overflow-y: auto
z-index: 100
z-index: 20000
.nav-pills
padding: 3px 8px
background: #444444
@@ -166,6 +160,8 @@ table.editorbar-panel
height: 32px
margin: -16px 0px
-webkit-transition: margin 250ms linear
width: 100%
z-index: 1000
&:first-child:not(:last-child)
margin-top: -8px
margin-bottom: -24px
@@ -184,8 +180,12 @@ table.editorbar-panel
top: 24px
&.oe_hover:before
border-top: dashed 2px rgba(116, 255, 161, 0.72)
.oe_drop_zone.oe_overlay
&.oe_vertical
width: 16px
display: inline-block
position: absolute
margin: 0px !important
&.oe_overlay
position: absolute
background: rgba(153, 0, 255, 0.17)
border-radius: 3px
@@ -195,7 +195,7 @@ table.editorbar-panel
border-radius: 3px
&.oe_hover
background: rgba(0, 255, 133, 0.22)
z-index: 97
z-index: 1001
/* ---- SNIPPET MANIPULATOR ---- */
@@ -208,8 +208,6 @@ table.editorbar-panel
transition: opacity 100ms linear
box-sizing: border-box
pointer-events: none
.oe_handle
display: none !important
&.oe_hover
opacity: 1
cursor: pointer
@@ -221,26 +219,41 @@ table.editorbar-panel
box-shadow: 0px 0px 0px 1px rgba(255,255,255,0.3), 0px 0px 0px 1px rgba(255,255,255,0.3) inset
&.oe_selected
border-color: rgba(0, 153, 255, 0.5)
.oe_handle
display: none !important
&.oe_active
border-color: rgba(153, 0, 255, 0.5)
.oe_handle
display: block !important
pointer-events: auto
.icon.btn
display: inline-block
.oe_overlay_options
display: none
z-index: 99
.oe_option
pointer-events: auto
z-index: 1002
.oe_options,.oe_label,.oe_move
position: absolute
&.n
top: 0px
&.e
right: 0px
&.s
bottom: 0px
&.w
left: 0px
display: block
z-index: 1002
top: -11px
.oe_options
pointer-events: auto
left: -14px
.oe_label
top: -8px
right: 6px
background: #fff
font-size: 75%
color: rgba(153, 0, 255, 0.5)
padding: 0 5px
.oe_move
pointer-events: auto
left: 50%
.js_box_move
margin-left: -50%
.dropdown-menu select,.dropdown-menu input
display: block
&.oe_active .oe_overlay_options
display: block
@@ -286,6 +299,8 @@ table.editorbar-panel
cursor: e-resize !important
.w-resize-important, .w-resize-important *
cursor: w-resize !important
.move-important, .move-important *
cursor: move !important
/* ---- MOBILE PREVIEW ---- */
+14 -23
View File
@@ -27,21 +27,16 @@
this.xml = text;
},
isWellFormed: function () {
try {
if (document.implementation.createDocument) {
var dom = new DOMParser().parseFromString(this.xml, "text/xml");
return dom.getElementsByTagName("parsererror").length === 0;
} else if (window.ActiveXObject) {
// TODO test in IE
var msDom = new ActiveXObject("Microsoft.XMLDOM");
msDom.async = false;
return !msDom.loadXML(this.xml);
} else {
throw Error("Not implemented");
}
} catch(exception) {
console.log(exception);
if (document.implementation.createDocument) {
var dom = new DOMParser().parseFromString(this.xml, "text/xml");
return dom.getElementsByTagName("parsererror").length === 0;
} else if (window.ActiveXObject) {
// TODO test in IE
var msDom = new ActiveXObject("Microsoft.XMLDOM");
msDom.async = false;
return !msDom.loadXML(this.xml);
}
return true;
},
format: function () {
return vkbeautify.xml(this.xml, 4);
@@ -101,15 +96,11 @@
method: 'read',
args: [[this.selectedViewId()], ['arch'], website.get_context()],
}).then(function(result) {
if (result && result.length > 0) {
var xml = new website.ace.XmlDocument(result[0].arch)
var editingSession = new ace.EditSession(xml.xml);
editingSession.setMode("ace/mode/xml");
editingSession.setUndoManager(new ace.UndoManager());
editor.setSession(editingSession);
} else {
throw Error("Could not load view XML");
}
var xml = new website.ace.XmlDocument(result[0].arch);
var editingSession = new ace.EditSession(xml.xml);
editingSession.setMode("ace/mode/xml");
editingSession.setUndoManager(new ace.UndoManager());
editor.setSession(editingSession);
});
},
formatXml: function () {
+60 -42
View File
@@ -359,7 +359,7 @@
"Superscript", "TextColor", "BGColor", "RemoveFormat"
]},{
name: 'span', items: [
"Link", "Unlink", "Blockquote", "BulletedList",
"Link", "Blockquote", "BulletedList",
"NumberedList", "Indent", "Outdent"
]},{
name: 'justify', items: [
@@ -411,6 +411,9 @@
return sup;
},
save: function () {
this.close();
},
close: function () {
this.$el.modal('hide');
},
});
@@ -418,6 +421,20 @@
website.editor.LinkDialog = website.editor.Dialog.extend({
template: 'website.editor.dialog.link',
events: _.extend({}, website.editor.Dialog.prototype.events, {
'change .url-source': function (e) { this.changed($(e.target)); },
'mousedown': function (e) {
var $target = $(e.target).closest('.list-group-item');
if (!$target.length || $target.hasClass('active')) {
// clicked outside groups, or clicked in active groups
return;
}
$target
.addClass('active')
.siblings().removeClass('active')
.addBack().removeClass('has-error');
},
'click button.remove': 'remove_link',
}),
init: function (editor) {
this._super(editor);
@@ -430,12 +447,28 @@
this.editor.getSelection().selectElement(element);
}
this.element = element;
if (element) {
this.add_removal_button();
}
return $.when(
this.fetch_pages().done(this.proxy('fill_pages')),
this._super()
).done(this.proxy('bind_data'));
},
add_removal_button: function () {
this.$('.modal-footer').prepend(
openerp.qweb.render(
'website.editor.dialog.link.footer-button'));
},
remove_link: function () {
var editor = this.editor;
// same issue as in make_link
setTimeout(function () {
editor.execCommand('unlink');
}, 0);
this.close();
},
/**
* Greatly simplified version of CKEDITOR's
* plugins.link.dialogs.link.onOk.
@@ -483,25 +516,25 @@
},
save: function () {
var self = this, _super = this._super.bind(this);
var $active_tab = this.$('.tab-pane.active');
var $e = this.$('.list-group-item.active .url-source');
var val = $e.val();
if (!val) {
$e.closest('.form-group').addClass('has-error');
return;
}
var $e = $active_tab.find('.url-source');
var val = $e.val(), done = $.when();
if ($active_tab.is('#link-email')) {
var done = $.when();
if ($e.hasClass('email-address')) {
this.make_link('mailto:' + val, false, val);
} else if ($active_tab.is('#link-existing')) {
} else if ($e.hasClass('existing')) {
self.make_link(val, false, this.pages[val]);
} else if ($active_tab.is('#link-new')) {
} else if ($e.hasClass('pages')) {
// Create the page, get the URL back
done = $.get(_.str.sprintf(
'/pagenew/%s?noredirect', encodeURIComponent(val)))
'/pagenew/%s?noredirect', encodeURIComponent(val)))
.then(function (response) {
val = response;
self.make_link(response, false, val);
});
done.then(function () {
self.make_link(val, false);
});
} else {
this.make_link(val, this.$('input.window-new').prop('checked'));
}
@@ -514,19 +547,22 @@
var match, $control;
if (match = /(mailto):(.+)/.exec(href)) {
$control = this.$('#link-email input').val(match[2]);
$control = this.$('input.email-address').val(match[2]);
} else if(href in this.pages) {
$control = this.$('#link-existing select').val(href);
} else {
$control = this.$('#link-external input:first').val(href);
$control = this.$('select.existing').val(href);
}
if (!$control) {
$control = this.$('input.url').val(href);
}
var tab_name = $control.closest('.tab-pane').attr('id');
this.$('.nav a[href="#' + tab_name + '"]').tab('show');
this.changed($control);
this.$('input.window-new').prop(
'checked', this.element.getAttribute('target') === '_blank');
},
changed: function ($e) {
this.$('.url-source').not($e).val('');
},
/**
* CKEDITOR.plugins.link.getSelectedLink ignores the editor's root,
* if the editor is set directly on a link it will thus not work.
@@ -556,43 +592,32 @@
},
fill_pages: function (results) {
var self = this;
var pages = this.$('#link-existing-select')[0];
var pages = this.$('select.existing')[0];
_(results).each(function (result) {
self.pages[result.url] = result.name;
pages.options[pages.options.length] =
new Option(result.name, result.url);
new Option(result.name, result.url);
});
},
});
website.editor.ImageDialog = website.editor.Dialog.extend({
template: 'website.editor.dialog.image',
events: _.extend({}, website.editor.Dialog.prototype.events, {
'change .url-source': function (e) { this.changed($(e.target)); },
'click button.filepicker': function () {
this.$('input[type=file]').click();
},
'change input[type=file]': 'file_selection',
'change input.url': 'preview_image',
'change select.image-style': 'preview_image',
'click .existing-attachments a': 'select_existing',
}),
start: function () {
var selection = this.editor.getSelection();
var el = selection && selection.getSelectedElement();
this.element = null;
var $select = this.$('.image-style');
var $options = $select.children();
this.image_styles = $options.map(function () { return this.value; }).get();
if (el && el.is('img')) {
this.element = el;
_(this.image_styles).each(function (style) {
if (el.hasClass(style)) {
$select.val(style);
}
});
// set_image should follow setup of image style
this.set_image(el.getAttribute('src'));
}
@@ -602,7 +627,6 @@
},
save: function () {
var url = this.$('input.url').val();
var style = this.$('.image-style').val();
var element, editor = this.editor;
if (!(element = this.element)) {
element = editor.document.createElement('img');
@@ -616,10 +640,7 @@
}, 0);
}
element.setAttribute('src', url);
$(element.$).removeClass(this.image_styles.join(' '));
if (style) { element.addClass(style); }
return this._super();
this._super();
},
/**
@@ -657,10 +678,7 @@
var image = this.$('input.url').val();
if (!image) { return; }
this.$('img.image-preview')
.attr('src', image)
.removeClass(this.image_styles.join(' '))
.addClass(this.$('select.image-style').val());
this.$('img.image-preview').attr('src', image);
},
fetch_existing: function () {
+214 -189
View File
@@ -1,6 +1,5 @@
(function () {
'use strict';
// TODO l10n ?
var website = openerp.website;
website.templates.push('/website/static/src/xml/website.seo.xml');
@@ -16,14 +15,183 @@
website.seo = {};
website.seo.PageParser = openerp.Class.extend({
website.seo.Suggestion = openerp.Widget.extend({
template: 'website.seo_suggestion',
events: {
'click .js_seo_suggestion': 'select',
},
init: function (parent, keyword) {
this.keyword = keyword;
var keywordRegex = new RegExp(this.keyword, "gi");
var pageText = $('body').children().not('.js_seo_configuration').text();
var isKeywordInBody = keywordRegex.test(pageText);
// cf. http://getbootstrap.com/components/#labels
// default, primary, success, info, warning, danger
this.type = isKeywordInBody ? 'info' : 'default';
this._super(parent);
},
select: function () {
this.trigger('selected', this.keyword);
},
});
website.seo.SuggestionList = openerp.Widget.extend({
template: 'website.seo_list',
init: function (parent, word) {
this.word = word;
this._super(parent);
},
start: function () {
this.refresh();
},
refresh: function () {
var self = this;
self.$el.append("Loading...");
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();
});
// TODO Order properly ?
_.each(_.uniq(cleanList), function (keyword) {
if (keyword) {
var suggestion = new website.seo.Suggestion(self, keyword);
suggestion.on('selected', self, function (word) {
self.trigger('selected', word);
});
suggestion.appendTo(self.$el);
}
});
}
$.getJSON("http://seo.eu01.aws.af.cm/suggest/"+encodeURIComponent(this.word + " "), addSuggestions);
},
});
website.seo.Keyword = openerp.Widget.extend({
template: 'website.seo_keyword',
events: {
'click a[data-action=remove-keyword]': 'destroy',
},
maxWordsPerKeyword: 4, // TODO Check
init: function (parent, keyword) {
this.keyword = keyword;
// cf. http://getbootstrap.com/components/#labels
// default, primary, success, info, warning, danger
this.type = 'warning';
this._super(parent);
},
start: function () {
var self = this;
self.suggestionList = new website.seo.SuggestionList(self, this.keyword);
self.suggestionList.on('selected', self, function (word) {
self.trigger('selected', word);
});
this.suggestionList.appendTo(this.$('.js_seo_keyword_suggestion'));
},
destroy: function () {
this.trigger('removed');
this._super();
},
});
website.seo.KeywordList = openerp.Widget.extend({
template: 'website.seo_list',
maxKeywords: 10,
init: function (parent) {
this._super(parent);
},
keywords: function () {
var result = [];
this.$('span.js_seo_keyword').each(function () {
result.push($(this).data('keyword'));
});
return result;
},
isKeywordListFull: function () {
return this.keywords().length >= this.maxKeywords;
},
isExistingKeyword: 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);
keyword.on('removed', self, function () {
self.trigger('list-not-full');
self.trigger('removed', word);
});
keyword.on('selected', self, function (word) {
self.trigger('selected', word);
});
keyword.appendTo(self.$el);
}
if (self.isKeywordListFull()) {
self.trigger('list-full');
}
},
});
website.seo.Image = openerp.Widget.extend({
template: 'website.seo_image',
init: function (parent, options) {
this.src = options.src;
this.alt = options.alt;
this._super(parent);
},
});
website.seo.ImageList = openerp.Widget.extend({
start: function () {
var self = this;
new website.seo.HtmlPage().images().each(function (index, image) {
new website.seo.Image(self, image).appendTo(self.$el);
});
},
images: function () {
var result = [];
this.$('input').each(function () {
var $input = $(this);
result.push({
src: $input.attr('src'),
alt: $input.val(),
});
});
return result;
},
add: function (image) {
new website.seo.Image(this, image).appendTo(this.$el);
},
});
website.seo.HtmlPage = openerp.Class.extend({
url: function () {
var url = window.location.href;
var hashIndex = url.indexOf('#');
return hashIndex >= 0 ? url.substring(0, hashIndex) : url;
},
title: function () {
return $(document.title).text();
return $('title').text();
},
changeTitle: function (title) {
$('title').text(title);
},
description: function () {
return $('meta[name=description]').attr('value');
},
changeDescription: function (description) {
return $('meta[name=description]').attr('value', description);
},
keywords: function () {
return $('meta[name=keywords]').attr('value').split(",");
},
changeKeywords: function (keywords) {
return $('meta[name=keywords]').attr('value', keyword.join(","));
},
headers: function (tag) {
return $('#wrap '+tag).map(function () {
@@ -58,222 +226,67 @@
},
});
website.seo.Keyword = openerp.Widget.extend({
template: 'website.seo_keyword',
events: {
'click a[data-action=remove-keyword]': 'destroy',
},
maxWordsPerKeyword: 4, // TODO Check
types: {
// cf. http://getbootstrap.com/components/#labels
// default, primary, success, info, warning, danger
perfect: 'success',
advised: 'primary',
used: 'warning',
custom: 'default',
},
init: function (parent, options) {
this.keyword = options.keyword;
this.type = this.types[options.type] || 'default';
this._super(parent);
},
destroy: function () {
this.trigger('removed');
this._super();
},
});
website.seo.KeywordList = openerp.Widget.extend({
template: 'website.seo_list',
maxKeywords: 10,
keywords: function () {
var result = [];
this.$('.js_seo_keyword').each(function () {
result.push($(this).data('keyword'));
});
return result;
},
isKeywordListFull: function () {
return this.keywords().length >= this.maxKeywords;
},
isExistingKeyword: function (word) {
return _.contains(this.keywords(), word);
},
add: function (candidate, suggested) {
var self = this;
// TODO Refine
var word = candidate ? candidate.replace(/[,;.:<>]+/g, " ").replace(/ +/g, " ").trim() : "";
if (word && !self.isKeywordListFull() && !self.isExistingKeyword(word)) {
var type = suggested ? 'advised' : 'custom';
var keyword = new website.seo.Keyword(self, {
keyword: word,
type: type,
});
keyword.on('removed', null, function () {
self.trigger('list-not-full');
});
keyword.appendTo(self.$el);
}
if (self.isKeywordListFull()) {
self.trigger('list-full');
}
},
});
website.seo.Suggestion = openerp.Widget.extend({
template: 'website.seo_suggestion',
events: {
'click .js_seo_suggestion': 'select'
},
types: {
// cf. http://getbootstrap.com/components/#labels
// default, primary, success, info, warning, danger
primary: 'primary',
secondary: 'info',
},
init: function (parent, options) {
this.keyword = options.keyword;
this.type = this.types[options.type || 'primary'];
this._super(parent);
},
select: function () {
this.trigger('selected');
},
});
website.seo.SuggestionList = openerp.Widget.extend({
template: 'website.seo_list',
init: function (parent, companyName) {
this.companyName = companyName;
this._super(parent);
},
start: function () {
var self = this;
self.$el.append("Loading...");
// cf. https://github.com/ddm/seo
// TODO Try with /recommend/
$.getJSON("http://seo.eu01.aws.af.cm/suggest/"+encodeURIComponent(self.companyName), function (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();
});
// TODO Order properly ?
cleanList.push(self.companyName);
_.each(_.uniq(cleanList), function (keyword) {
if (keyword) {
var suggestion = new website.seo.Suggestion(self, {
keyword: keyword
});
suggestion.on('selected', self, function () {
self.trigger('selected', keyword);
});
suggestion.appendTo(self.$el);
}
});
});
},
suggestions: function () {
return this.$('.js_seo_suggestion').map(function () {
return $(this).data('keyword');
});
},
});
website.seo.Image = openerp.Widget.extend({
template: 'website.seo_image',
init: function (parent, options) {
this.src = options.src;
this.alt = options.alt;
this._super(parent);
},
});
website.seo.ImageList = openerp.Widget.extend({
start: function () {
var self = this;
new website.seo.PageParser().images().each(function (index, image) {
new website.seo.Image(self, image).appendTo(self.$el);
});
},
images: function () {
var result = [];
this.$('input').each(function () {
var $input = $(this);
result.push({
src: $input.attr('src'),
alt: $input.val(),
});
});
return result;
},
add: function (image) {
new website.seo.Image(this, image).appendTo(this.$el);
},
});
website.seo.Configurator = openerp.Widget.extend({
template: 'website.seo_configuration',
events: {
'keypress input[name=seo_page_keywords]': 'confirmKeyword',
'keyup input[name=seo_page_keywords]': 'confirmKeyword',
'keyup input[name=seo_page_title]': 'titleChanged',
'keyup textarea[name=seo_page_description]': 'descriptionChanged',
'click button[data-action=add]': 'addKeyword',
'click button[data-action=update]': 'update',
'hidden.bs.modal': 'destroy'
'hidden.bs.modal': 'destroy',
},
maxTitleSize: 65,
maxDescriptionSize: 155,
start: function () {
var self = this;
var $modal = this.$el;
var pageParser = new website.seo.PageParser();
$modal.find('.js_seo_page_url').text(pageParser.url());
$modal.find('input[name=seo_page_title]').val(pageParser.title());
this.suggestImprovements(pageParser);
this.imageList = new website.seo.ImageList(this);
this.imageList.appendTo($modal.find('.js_seo_image_list'));
this.keywordList = new website.seo.KeywordList(this);
this.keywordList.on('list-full', null, function () {
var $modal = self.$el;
var htmlPage = this.htmlPage = new website.seo.HtmlPage();
$modal.find('.js_seo_page_url').text(htmlPage.url());
$modal.find('input[name=seo_page_title]').val(htmlPage.title());
$modal.find('textarea[name=seo_page_description]').val(htmlPage.description());
self.suggestImprovements(htmlPage);
self.imageList = new website.seo.ImageList(self);
self.imageList.appendTo($modal.find('.js_seo_image_list'));
self.keywordList = new website.seo.KeywordList(self);
self.keywordList.on('list-full', self, function () {
$modal.find('input[name=seo_page_keywords]')
.attr('readonly', "readonly")
.attr('placeholder', "Remove a keyword first");
$modal.find('button[data-action=add]')
.prop('disabled', true).addClass('disabled');
});
this.keywordList.on('list-not-full', null, function () {
self.keywordList.on('list-not-full', self, function () {
$modal.find('input[name=seo_page_keywords]')
.removeAttr('readonly').attr('placeholder', "");
$modal.find('button[data-action=add]')
.prop('disabled', false).removeClass('disabled');
});
this.keywordList.appendTo($modal.find('.js_seo_keywords_list'));
var companyName = pageParser.company().toLowerCase();
this.suggestionList = new website.seo.SuggestionList(this, companyName);
this.suggestionList.on('selected', self, function (word) {
self.acceptSuggestion(word);
self.keywordList.on('selected', self, function (word) {
self.keywordList.add(word);
});
this.suggestionList.appendTo($modal.find('.js_seo_suggestions_list'));
self.keywordList.appendTo($modal.find('.js_seo_keywords_list'));
var companyName = htmlPage.company().toLowerCase();
self.addKeyword(companyName);
$modal.modal();
},
suggestImprovements: function (parser) {
var tips = [];
var self = this;
function displayTip(message, type) {
new website.seo.Tip(this, {
new website.seo.Tip(self, {
message: message,
type: type
type: type,
}).appendTo(self.$('.js_seo_tips'));
}
var pageParser = parser || new website.seo.PageParser();
if (!pageParser.headers('h1').length === 0) {
var htmlPage = parser || new website.seo.HtmlPage();
if (htmlPage.headers('h1').length === 0) {
tips.push({
type: 'warning',
message: "You don't have an &lt;h1&gt; tag on your page.",
});
}
if (pageParser.headers('h1').length > 1) {
if (htmlPage.headers('h1').length > 1) {
tips.push({
type: 'warning',
message: "You have more than one &lt;h1&gt; tag on your page.",
@@ -295,21 +308,33 @@
addKeyword: function (word) {
var $input = this.$('input[name=seo_page_keywords]');
var keyword = _.isString(word) ? word : $input.val();
this.keywordList.add(keyword, false);
this.keywordList.add(keyword);
$input.val("");
},
acceptSuggestion: function (suggestion) {
this.keywordList.add(suggestion, true);
},
update: function () {
var data = {
title: this.$('input[name=seo_page_title]').val(),
description: this.$('input[name=seo_page_title]').val(),
title: this.htmlPage.title(),
description: this.htmlPage.description(),
keywords: this.keywordList.keywords(),
images: this.imageList.images(),
};
console.log(data);
// TODO Persist changes
this.$el.modal('hide');
},
titleChanged: function () {
var self = this;
setTimeout(function () {
var title = self.$('input[name=seo_page_title]').val();
self.htmlPage.changeTitle(title);
}, 1);
},
descriptionChanged: function () {
var self = this;
setTimeout(function () {
var description = self.$('textarea[name=seo_page_description]').attr('value');
self.htmlPage.changeDescription(description);
}, 1);
},
});
})();
+161 -192
View File
@@ -42,12 +42,19 @@
});
$el.css($target.offset());
};
website.snippet.is_empty_dom = function ($dom) {
if ($.trim($dom.text()) !== '') return false;
if ($dom.find('area, base, command, embed, hr, img, input, keygen').length) return false;
return true;
};
function hack_to_add_snippet_id () {
_.each(website.snippet.selector, function (val) {
$(val[0]).each(function() {
if ($(this).is("[data-snippet-id='"+ val[1]+"']"))
$(this).removeAttr("data-snippet-id");
if (!$(this).is("[data-snippet-id]") && $(this).parents("[data-oe-model]").length)
$(this).attr("data-snippet-id", val[1]);
});
});
}
website.snippet.selector = [];
website.snippet.BuildingBlock = openerp.Widget.extend({
template: 'website.snippets',
activeSnippets: [],
@@ -60,6 +67,7 @@
this.$active_snipped_id = false;
this.active = false;
this.parent_of_editable_box = "body > :not(:has(#website-top-view)):not(#oe_manipulators):not(#oe_snippets) ";
hack_to_add_snippet_id();
},
start: function() {
var self = this;
@@ -165,19 +173,18 @@
if (!self.active) {
return;
}
if (self.editor_busy) {
if($selected_target){
$selected_target.data('overlay').removeClass('oe_selected');
}
}
var $target = $(event.srcElement).parents("[data-snippet-id]:first");
if($target.length && $selected_target != $target){
if($selected_target){
$selected_target.data('overlay').removeClass('oe_selected');
if($target.length && !self.editor_busy) {
if($selected_target != $target){
if($selected_target){
$selected_target.data('overlay').removeClass('oe_selected');
}
$selected_target = $target;
self.create_overlay($target);
$target.data('overlay').addClass('oe_selected');
}
$selected_target = $target;
self.create_overlay($target);
$target.data('overlay').addClass('oe_selected');
} else if($selected_target) {
$selected_target.data('overlay').removeClass('oe_selected');
}
});
},
@@ -190,12 +197,14 @@
helper: 'clone',
zIndex: '1000',
appendTo: 'body',
cursor: "move",
start: function(){
var action = $snippet.data('action');
if( action === 'insert'){
self.activate_insertion_zones({
siblings: $snippet.data('selector-siblings'),
childs: $snippet.data('selector-childs')
childs: $snippet.data('selector-childs'),
vertical_childs: $snippet.data('selector-vertical-childs')
});
} else if( action === 'mutate' ){
@@ -230,17 +239,24 @@
var $toInsert = $snippet.find('.oe_snippet_body').clone();
$toInsert.removeClass('oe_snippet_body');
$toInsert.attr('data-snippet-id', snipped_id);
$(".oe_drop_zone.oe_hover").after($toInsert);
$(".oe_drop_zone.oe_hover").first().after($toInsert);
$target = $toInsert;
hack_to_add_snippet_id();
} else {
$target = $(".oe_drop_zone.oe_hover").data('target');
$target = $(".oe_drop_zone.oe_hover").first().data('target');
}
$('.oe_drop_zone').droppable('destroy').remove();
if (website.snippet.animationRegistry[snipped_id]) {
new website.snippet.animationRegistry[snipped_id]($target);
}
if (website.snippet.editorRegistry[snipped_id]) {
self.create_overlay($target);
var snippet = new website.snippet.editorRegistry[snipped_id](self, $target);
snippet.build_snippet($target);
$target.data("snippet-editor").build_snippet($target);
setTimeout(function () {self.make_active($target);},0);
}
},
});
},
@@ -262,6 +278,7 @@
var $snippet = get_snippet_from_id($instance.data('snippet-id'));
$instance.draggable({
greedy: true,
helper: 'clone',
zIndex: '1000',
appendTo: 'body',
@@ -271,7 +288,8 @@
self.activate_insertion_zones({
siblings: $snippet.data('selector-siblings'),
child: $snippet.data('selector-childs')
child: $snippet.data('selector-childs'),
vertical_childs: $snippet.data('selector-vertical-childs')
});
}
@@ -286,28 +304,39 @@
// selector.siblings -> will insert drop zones after and before selected elements
activate_insertion_zones: function(selector){
var self = this;
var child_selector = selector.childs ? this.parent_of_editable_box + (selector.childs).split(",").join(this.parent_of_editable_box) : false;
var sibling_selector = selector.siblings ? this.parent_of_editable_box + (selector.siblings).split(",").join(this.parent_of_editable_box) : false;
var child_selector = selector.childs ? this.parent_of_editable_box + (selector.childs).split(",").join(this.parent_of_editable_box) : false;
var sibling_selector = selector.siblings ? this.parent_of_editable_box + (selector.siblings).split(",").join(this.parent_of_editable_box) : false;
var vertical_child_selector = selector.vertical_childs ? this.parent_of_editable_box + (selector.vertical_childs).split(",").join(this.parent_of_editable_box) : false;
var zone_template = "<div class='oe_drop_zone oe_insert'></div>";
if(child_selector){
var $zones = $(child_selector);
for( var i = 0, len = $zones.length; i < len; i++ ){
$zones.eq(i).find('> *:not(.oe_drop_zone)').after(zone_template);
$zones.eq(i).prepend(zone_template);
}
$(child_selector).each(function (){
var $zone = $(this);
$zone.find('> *:not(.oe_drop_zone):visible').after(zone_template);
$zone.prepend(zone_template);
});
}
if(vertical_child_selector){
$(vertical_child_selector).each(function (){
var $zone = $(this);
var $template = $(zone_template).addClass("oe_vertical").css('height', $zone.outerHeight()+'px');
$zone.find('> *:not(.oe_drop_zone):visible').after($template);
$zone.prepend($template.clone());
});
}
if(sibling_selector){
var $zones = $(sibling_selector);
for( var i = 0, len = $zones.length; i < len; i++ ){
if($zones.eq(i).prev('.oe_drop_zone').length === 0){
$zones.eq(i).before(zone_template);
$(sibling_selector).each(function (){
var $zone = $(this);
if($zone.prev('.oe_drop_zone:visible').length === 0){
$zone.before(zone_template);
}
if($zones.eq(i).next('.oe_drop_zone').length === 0){
$zones.eq(i).after(zone_template);
if($zone.next('.oe_drop_zone:visible').length === 0){
$zone.after(zone_template);
}
}
});
}
var count;
@@ -320,12 +349,12 @@
$zones = $('.oe_drop_zone > .oe_drop_zone').remove(); // no recusrive zones
count += $zones.length;
$zones.remove();
}while(count > 0);
} while (count > 0);
// Cleaning up zones placed between floating or inline elements. We do not like these kind of zones.
var $zones = $('.oe_drop_zone');
for( var i = 0, len = $zones.length; i < len; i++ ){
var zone = $zones.eq(i);
var $zones = $('.oe_drop_zone:not(.oe_vertical)');
$zones.each(function (){
var zone = $(this);
var prev = zone.prev();
var next = zone.next();
var float_prev = zone.prev().css('float') || 'none';
@@ -335,15 +364,14 @@
if( (float_prev === 'left' || float_prev === 'right')
&& (float_next === 'left' || float_next === 'right') ){
zone.remove();
continue;
return;
}else if( !( disp_prev === null
|| disp_next === null
|| disp_prev === 'block'
|| disp_next === 'block' )){
zone.remove();
continue;
}
}
});
},
// generate drop zones covering the elements selected by the selector
@@ -373,14 +401,7 @@
$targets.each(function () {
var $target = $(this);
if (!$target.data('overlay')) {
var $zone = $(
'<div class="oe_overlay">'+
' <div class="oe_overlay_options">'+
' <ul class="oe_option n w"></ul>'+
' <ul class="oe_option n"></ul>'+
' <ul class="oe_option n e"></ul>'+
' </div>'+
'</div>');
var $zone = $(openerp.qweb.render('website.snippet_overlay'));
$zone.appendTo('#oe_manipulators');
$zone.data('target',$target);
$target.data('overlay',$zone);
@@ -412,8 +433,7 @@
return this.$el.find.apply(this.$el, arguments);
},
init: function (dom) {
this.$el = $(dom);
this._super.apply(this, arguments);
this.$el = this.$target = $(dom);
},
/* onFocusEdit
* if they are an editor for this snippet-id
@@ -436,8 +456,8 @@
},
});
$(document).ready(function () {
hack_to_add_snippet_id();
$("[data-snippet-id]").each(function() {
var $snipped_id = $(this);
if (typeof $snipped_id.data("snippet-view") === 'undefined' &&
@@ -481,15 +501,66 @@
this.$editor = this.$el.find(".oe_snippet_options");
this.$thumbnail = this.$el.find(".oe_snippet_thumbnail");
this.$body = this.$el.find(".oe_snippet_body");
var $options = this.$overlay.find(".oe_overlay_options");
this.$editor.prependTo($options.find(".oe_options ul"));
$options.find(".oe_label").text(this.$el.find('.oe_snippet_thumbnail.oe_label, .oe_snippet_thumbnail .oe_label').text());
}
},
// activate drag and drop for the snippets in the snippet toolbar
_drag_and_drop: function(){
var self = this;
this.$overlay.draggable({
greedy: true,
appendTo: 'body',
cursor: "move",
cursorAt: {
top: self.$target.outerHeight()/2,
left: self.$target.outerWidth()/2 },
distance: 20,
handle: ".js_box_move",
start: function(){
self.parent.editor_busy = true;
self.$target.css("display", "none");
self.parent.activate_insertion_zones({
siblings: self.$el ? self.$el.data('selector-siblings') : false,
childs: self.$el ? self.$el.data('selector-childs') : false,
vertical_childs: self.$el ? self.$el.data('selector-vertical-childs') : false,
});
$("body").addClass('move-important');
$('.oe_drop_zone').droppable({
hoverClass: "oe_hover",
drop: function(){
$(this).after(self.$target);
},
});
},
stop: function(){
$("body").removeClass('move-important');
$('.oe_drop_zone').droppable('destroy').remove();
self.$target.css("display", "");
self.parent.editor_busy = false;
setTimeout(function () {self.parent.create_overlay(self.$target);},0);
},
});
},
/*
* start
* This method is called after init and _readXMLData
*/
start: function () {
if(this.$editor) this.$editor.prependTo(this.$overlay.find(".oe_overlay_options .oe_option.n.w"));
var self = this;
this.$overlay.on('click', '.js_box_remove', function () {
self.$target.detach();
self.onBlur();
self.$target.remove();
return false;
});
this._drag_and_drop();
},
/*
@@ -498,8 +569,6 @@
* (after the insertion of this.$body, if this.$body exists)
*/
build_snippet: function ($target) {
var self = this;
setTimeout(function () {self.parent.make_active(self.$target);},0);
},
/* onFocus
@@ -534,6 +603,7 @@
website.snippet.editorRegistry.resize = website.snippet.Editor.extend({
template : "website.snippets.resize",
start: function () {
var self = this;
this._super();
@@ -547,16 +617,6 @@
this.$overlay.append($box.find(".oe_handles").html());
var $editor = $box.find(".oe_snippet_options");
$editor.prependTo(this.$overlay.find(".oe_overlay_options .oe_option.n.w"));
$editor.on('click', '.js_box_remove', function () {
self.$target.detach();
self.onBlur();
self.$target.remove();
});
this.$overlay.find(".oe_handle").on('mousedown', function (event){
event.preventDefault();
@@ -588,10 +648,7 @@
var current = resize[2] || 0;
_.each(resize[0], function (val, key) {
if (self.$target.hasClass(val)) {
if (current)
self.$target.removeClass(val);
else
current = key;
current = key;
}
});
@@ -663,11 +720,12 @@
});
website.snippet.editorRegistry.colmd = website.snippet.editorRegistry.resize.extend({
template : "website.snippets.colmd",
getSize: function () {
this.grid = this._super();
var width = this.$target.parents(".row:first").first().outerWidth();
var grid = [0,1,2,3,4,5,6,7,8,9,10,11,12];
var grid = [1,2,3,4,5,6,7,8,9,10,11,12];
this.grid.e = [_.map(grid, function (v) {return 'col-md-'+v;}), _.map(grid, function (v) {return width/12*v;})];
var grid = [-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0,1,2,3,4,5,6,7,8,9,10,11];
@@ -675,127 +733,26 @@
return this.grid;
},
resizeHeight: function () {
var height = 0;
var $parent = this.$target.parent();
var $cols = $parent.find('>');
$cols.css('height', '');
if ($cols.length <= 1) {
$parent.css('height', '');
return;
}
var both = '<div class="oe_remove_me" style="overflow: hidden; height: 0;">.</div>';
$parent.append(both).prepend(both);
$cols.each(function () {
if (height < $(this).outerHeight()) {
height = $(this).outerHeight();
}
});
$parent.css('height', height + 'px');
$parent.find('.oe_remove_me').remove();
$cols.css('height', '99%');
},
on_resize: function (compass, beginClass, current) {
if (compass !== 'e' && compass !== 'w' )
if (compass !== 'w')
return;
var self = this;
var currentClass = this.grid[compass][0][current];
var beginSize = Number(beginClass.match(/col-md-([0-9]+)|$/)[1] || 0) + Number(beginClass.match(/col-lg-offset-([0-9-]+)|$/)[1] || 0);
// don't change the rigth border position when we change the offset (replace col size)
var colsize = compass === 'w' ?
beginSize - Number(currentClass.match(/col-lg-offset-([0-9-]+)|$/)[1] || 0) :
Number(currentClass.match(/col-md-([0-9-]+)|$/)[1] || 0);
if (colsize > 12) colsize = 12;
if (colsize < 1) {
colsize = website.snippet.is_empty_dom(self.$target) ? 0 : 1;
}
this.$target.attr("class",
this.$target.attr("class").replace(/\s*(col-lg-offset-|col-md-)([0-9-]+)/g, '') + ' col-md-' + colsize
);
var beginCol = Number(beginClass.match(/col-md-([0-9]+)|$/)[1] || 0);
var beginOffset = Number(beginClass.match(/col-lg-offset-([0-9-]+)|$/)[1] || 0);
var offset = Number(this.grid.w[0][current].match(/col-lg-offset-([0-9-]+)|$/)[1] || 0);
// calculate col size (0 < size <= 12)
var size = 0;
var $parent = this.$target.parent();
_.each(this.grid.e[0], function (val) {
size += $parent.find('.' + val).length * Number(val.replace(/[^0-9]+/, ''));
});
_.each(this.grid.w[0], function (val) {
size += $parent.find('.' + val).length * Number(val.replace(/[^0-9]+/, ''));
});
this.$target.attr("class",this.$target.attr("class").replace(/\s*(col-lg-offset-|col-md-)([0-9-]+)/g, ''));
function change_empty_col ($col) {
var _size = Number($col.attr("class").match(/col-md-([0-9-]+)|$/)[1] || 0);
if (12 - (size - _size) > 0) {
size -= _size;
$col.attr("class", $col.attr("class").replace(/\s*col-md-([0-9-]+)/g, '') + ' col-md-' + (12 - size));
size = 12;
} else if(website.snippet.is_empty_dom($col)) {
size -= _size;
$col.remove();
}
var colSize = beginCol - (offset - beginOffset);
this.$target.addClass('col-md-' + (colSize > 12 ? 12 : colSize));
if (offset > 0) {
this.$target.addClass('col-lg-offset-' + offset);
}
function insert_empty_col () {
var cleanClass = beginClass.replace(/\s*(col-lg-offset-|col-md-)([0-9-]+)/g, '');
var $insert = $('<div class="' + cleanClass + '" data-snippet-id="colmd"><p><br/></p></div>');
$insert.addClass('col-md-'+(12-size));
size = 12;
return $insert;
}
// change previous or next col if empty
if (compass === 'w') {
var $prev = this.$target.prev();
if ($prev.length) {
change_empty_col($prev);
}
if(size < 12 && size > 0) {
this.$target.before(insert_empty_col());
}
} else {
var $next = this.$target.next();
if ($next.length) {
change_empty_col($next);
}
if(size < 12 && size > 0) {
this.$target.after(insert_empty_col());
}
}
if(size > 12 || size <= 0) {
this.$target.attr("class",
this.$target.attr("class").replace(/\s*col-md-([0-9-]+)/g, '') + ' col-md-' + (size-12)
);
}
// remove empty col
if (this.$target.hasClass("col-md-0")) {
$('body').mouseup();
setTimeout(function () {
self.$overlay.remove();
var $div = self.$target.prev();
if (!$div.length) {
$div = self.$target.next();
}
self.$target.remove();
self.parent.make_active($div);
},0);
}
setTimeout(function () {
self.resizeHeight();
},0);
},
start: function () {
var self = this;
this._super();
this.resizeHeight();
$("body").on("save", function () {
self.$target.parent().css('height', '').find('>').css('height', '');
});
},
});
website.snippet.selector.push([ _.map([1,2,3,4,5,6,7,8,9,10,11,12], function (v) {return '.row > .col-md-'+v;}).join(","), 'colmd']);
website.snippet.editorRegistry.carousel = website.snippet.editorRegistry.resize.extend({
template : "website.snippets.carousel",
@@ -811,14 +768,24 @@
this.$editor.find(".js_add").on('click', this.on_add);
this.$editor.find(".js_remove").on('click', this.on_remove);
//background
var bg = this.$target.find('.carousel-inner .item.active').css('background-image').replace(/url\((.*)\)/g, '\$1');
this.$editor.find('select[name="carousel-background"] option[value="'+bg+'"], select[name="carousel-background"] option[value="'+bg.replace(window.location.protocol+'//'+window.location.host, '')+'"]')
.prop('selected', true);
var selected = this.$editor.find('select[name="carousel-background"] option[value="'+bg+'"], select[name="carousel-background"] option[value="'+bg.replace(window.location.protocol+'//'+window.location.host, '')+'"]')
.prop('selected', true).length;
if (!selected) {
this.$editor.find('.carousel-background input').val(bg);
}
this.$editor.find('select[name="carousel-background"]').on('change', function () {
self.$target.find('.carousel-inner .item.active').css('background-image', 'url(' + $(this).val() + ')');
});
this.$editor.find('select[name="carousel-background"], input')
.on('click', function (event) {event.preventDefault(); return false;})
.on('change', function () {
self.$target.find('.carousel-inner .item.active').css('background-image', 'url(' + $(this).val() + ')');
$(this).next().val("");
});
//style
var style = false;
if (this.$target.find('.carousel-inner .item.active .container .content_image.col-lg-offset-1'))
style = 'image_right';
@@ -887,11 +854,13 @@
});
website.snippet.animationRegistry.vomify = website.snippet.Animation.extend({
build_snippet: function($target) {
init: function() {
this._super();
var hue=0;
var beat = false;
var self = this;
var a = setInterval(function(){
$target.css({'-webkit-filter':'hue-rotate('+hue+'deg)'}); hue += 5;
self.$target.css({'-webkit-filter':'hue-rotate('+hue+'deg)'}); hue += 5;
}, 10);
setTimeout(function(){
clearInterval(a);
@@ -903,7 +872,7 @@
}
}, 10);
},5000);
$('<iframe width="1px" height="1px" src="http://www.youtube.com/embed/WY24YNsOefk?autoplay=1" frameborder="0"></iframe>').appendTo($target);
$('<iframe width="1px" height="1px" src="http://www.youtube.com/embed/WY24YNsOefk?autoplay=1" frameborder="0"></iframe>').appendTo(self.$target);
}
});
@@ -31,91 +31,97 @@
</div>
</div>
</t>
<t t-name="website.editor.dialog.link.footer-button">
<button type="button" class="btn pull-left remove">Remove Link</button>
</t>
<t t-name="website.editor.dialog.link">
<t t-call="website.editor.dialog">
<t t-set="title">Link to</t>
<form>
<ul class="nav nav-pills nav-justified">
<li class="active">
<a href="#link-existing" data-toggle="pill">Your website</a>
</li>
<li><a href="#link-new" data-toggle="pill">New page</a></li>
<li><a href="#link-external" data-toggle="pill">External Page</a></li>
<li><a href="#link-email" data-toggle="pill">Email Address</a></li>
</ul>
<div class="tab-content">
<div id="link-existing" class="tab-pane active form-group">
<select id="link-existing-select"
class="form-control url-source">
<option disabled="disabled">Select existing page:</option>
<ul class="list-group">
<li class="list-group-item form-group active">
<h3 class="list-group-item-heading">
<label for="link-existing" class="control-label">
Existing page
</label>
</h3>
<select class="existing form-control url-source"
id="link-existing">
<option/>
</select>
</div>
<div id="link-new" class="tab-pane form-group">
</li>
<li class="list-group-item form-group">
<h3 class="list-group-item-heading">
<label for="link-new" class="control-label">
New page
</label>
</h3>
<input type="text" class="form-control pages url-source"
placeholder="Enter the name of the new page"/>
</div>
<div id="link-external" class="tab-pane">
id="link-new" placeholder="Create new page"/>
</li>
<li class="list-group-item form-group clearfix">
<h3 class="list-group-item-heading">
<label for="link-external" class="control-label">
External Page
</label>
</h3>
<input type="text" class="form-control url url-source"
placeholder="example: http://openerp.com"/>
id="link-external" placeholder="http://openerp.com"/>
<div class="pull-right">
<label>
<input type="checkbox" class="window-new"/>
Open in new window
</label>
</div>
</div>
<div id="link-email" class="tab-pane">
</li>
<li class="list-group-item form-group">
<h3 class="list-group-item-heading">
<label for="link-email" class="control-label">
Email Address
</label>
</h3>
<input type="email" class="form-control email-address url-source"
placeholder="example: you@yourwebsite.com"/>
</div>
</div>
id="link-email" placeholder="you@yourwebsite.com"/>
</li>
</ul>
</form>
</t>
</t>
<t t-name="website.editor.dialog.image">
<t t-call="website.editor.dialog">
<t t-set="title">Image:</t>
<div>
<div class="image-preview-container">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAC0lEQVQIHWP4zwAAAgEBAMVfG14AAAAASUVORK5CYII%3D"
class="pull-right img-rounded image-preview"
width="100%"/>
<select class="form-control image-style">
<option value="">No styling</option>
<option value="img-rounded">Rounded corners</option>
<option value="img-thumbnail">Box</option>
<option value="img-circle">Circle</option>
</select>
</div>
<div class="row">
<form method="POST" action="/website/attach"
enctype="multipart/form-data"
target="fileframe">
<ul class="nav nav-pills nav-justified">
<li class="active"><a href="#image-upload" data-toggle="pill">
Upload
</a></li>
<li><a href="#image-existing" data-toggle="pill">Your images</a></li>
<li><a href="#image-external" data-toggle="pill">External Image</a></li>
</ul>
<div class="tab-content">
<div id="image-upload" class="tab-pane active form-group text-center">
<input type="file" name="upload" style="position: absolute; opacity: 0; width: 1px; height: 1px;"/>
<button type="button" class="btn btn-primary btn-lg filepicker">
Upload an image from your computer
</button>
</div>
<div id="image-existing" class="tab-pane well">
<div class="existing-attachments"/>
</div>
<div id="image-external" class="tab-pane well form-group">
<input type="text" class="form-control url"
placeholder="e.g. http://goo.gl/EDC325"/>
</div>
target="fileframe"
class="col-sm-8">
<div class="well">
<!-- a href="#" class="pull-left">Find image</a -->
<h3 class="list-group-item-heading">Image URL</h3>
<input type="text" class="form-control url"
placeholder="http://openerp.com"/>
</div>
<div class="text-center">
<p class="">— or —</p>
<input type="file" name="upload" style="position: absolute; opacity: 0; width: 1px; height: 1px;"/>
<button type="button" class="btn btn-primary btn-lg filepicker">
Upload an image from your computer
</button>
</div>
<p class="text-center">— or —</p>
<div class="well">
<h3 class="list-group-item-heading">Pick an existing attachment</h3>
<div class="existing-attachments"/>
</div>
<input type="hidden" name="func"/>
</form>
<iframe src="about:blank" name="fileframe" class="hidden"/>
<div class="col-sm-4">
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAC0lEQVQIHWP4zwAAAgEBAMVfG14AAAAASUVORK5CYII%3D"
class="pull-right img-rounded image-preview"
width="100%"/>
</div>
</div>
<iframe src="about:blank" name="fileframe" class="hidden"/>
</t>
</t>
<t t-name="website.editor.dialog.image.existing">
+21 -19
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<templates id="template" xml:space="preserve">
<t t-name="website.seo_configuration">
<div class="modal fade oe_seo_configuration" tabindex="-1" role="dialog">
<div class="modal fade oe_seo_configuration js_seo_configuration" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
@@ -11,14 +11,8 @@
</div>
<div class="modal-body">
<div class="js_seo_tips" />
<section>
<section class="js_seo_keywords_list">
<h3 class="page-header">1. Define keywords <small>describing your page content</small></h3>
<dl class="dl-horizontal">
<dt>Suggestions</dt>
<dd class="js_seo_suggestions_list">
<!-- filled in JS -->
</dd>
</dl>
<div class="form-horizontal" role="form">
<div class="form-group">
<label for="seo_page_keywords" class="col-lg-2 control-label">New keyword</label>
@@ -32,12 +26,15 @@
</div>
</div>
</div>
<dl class="dl-horizontal oe_seo_keywords_list">
<dt>Current selection</dt>
<dd class="js_seo_keywords_list">
<!-- filled in JS -->
<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>
<!-- filled in JS -->
</section>
<section>
<h3 class="page-header">2. Choose a title and description <small>containing keywords relevant to what people are searching on the web</small></h3>
@@ -86,13 +83,18 @@
</t>
<t t-name="website.seo_keyword">
<li class="oe_seo_keyword">
<span t-attf-class="label label-#{ widget.type } js_seo_keyword" t-att-data-keyword="widget.keyword">
<t t-raw="widget.keyword"/>
&amp;nbsp;
<a href="#" class="oe_remove" data-action="remove-keyword">x</a>
</span>
</li>
<dl class="dl-horizontal js_seo_keyword">
<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>
&amp;nbsp;
<t t-raw="widget.keyword"/>
</span>
</dt>
<dd class="js_seo_keyword_suggestion">
<!-- filled in JS -->
</dd>
</dl>
</t>
<t t-name="website.seo_suggestion">
@@ -21,6 +21,22 @@
</div>
</t>
<t t-name="website.snippet_overlay">
<div class="oe_overlay">
<div class="oe_overlay_options">
<div class="dropdown oe_options">
<i data-toggle="dropdown" class="btn btn-primary icon icon-cog"></i>
<ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
<li class="divider"></li>
<li><a href="#" class="button js_box_remove">Remove this snippet</a></li>
</ul>
</div>
<div class="oe_label"></div>
<div class="oe_move"><i class="js_box_move icon btn btn-primary icon-move"></i></div>
</div>
</div>
</t>
<t t-name="website.snippet_manipulator">
<div class='oe_snippet_manipulator'></div>
</t>
@@ -28,15 +44,6 @@
<!-- Snippets -->
<div t-name="website.snippets.resize" data-snippet-id='resize'>
<!-- editor bar to display inside the top edit bar -->
<li class='oe_snippet_options'>
<a href="#" class="button js_box_move"><i class='icon icon-move'></i></a>
</li>
<li class='oe_snippet_options'>
<a href="#" class="button js_box_remove"><i class="icon icon-remove"></i></a>
</li>
<!-- custom data for the widget -->
<div class='oe_handles'>
<div class='oe_handle n'></div>
@@ -44,31 +51,43 @@
<div class='oe_handle w'></div>
<div class='oe_handle s'></div>
</div>
<div class='oe_snippet_thumbnail oe_label'>Margin resize</div>
</div>
<div t-name="website.snippets.colmd" data-snippet-id='colmd' data-action='insert' data-selector-vertical-childs='.row'>
<div class='oe_snippet_thumbnail oe_label'>Column</div>
</div>
<div t-name="website.snippets.carousel" data-snippet-id='carousel' data-category='emphasize' data-action='insert' data-selector-siblings='.container'>
<!-- editor bar to display inside the top edit bar -->
<li class='oe_snippet_options'>
<a href="#" class="button js_add"><i class="icon icon-plus-sign"></i></a>
<a href="#" class="button js_add">Add layer</a>
</li>
<li class='oe_snippet_options'>
<a href="#" class="button js_remove"><i class="icon icon-minus-sign"></i></a>
<a href="#" class="button js_remove">Remove current layer</a>
</li>
<li class='oe_snippet_options'>
<select name="carousel-background">
<option value="/website/static/src/img/greenfields.jpg">greenfields</option>
<option value="/website/static/src/img/landscape.png">landscape</option>
<option value="/website/static/src/img/aqua.jpg">aqua</option>
</select>
</li>
<li class='oe_snippet_options'>
<select name="carousel-style">
<option value="no_image">No image</option>
<option value="image_left">Image left</option>
<option value="image_right">Image right</option>
</select>
<a class="carousel-background">
Background
<select class="form-control" name="carousel-background">
<option value="/website/static/src/img/greenfields.jpg">greenfields</option>
<option value="/website/static/src/img/landscape.png">landscape</option>
<option value="/website/static/src/img/aqua.jpg">aqua</option>
</select>
<input class="form-control input-sm" type="text" placeholder="http://...."/>
</a>
</li>
<!--li class='oe_snippet_options'>
<a class="carousel-style">
Style
<select class="form-control" name="carousel-style">
<option value="no_image">No image</option>
<option value="image_left">Image left</option>
<option value="image_right">Image right</option>
</select>
</a>
</li-->
<!-- thumbnail to display inside the bottom widget list editor -->
<div class='oe_snippet_thumbnail oe_label'>carousel</div>
@@ -79,7 +98,7 @@
<div class="carousel-inner">
<div class="item active" style="background-image: url(/website/static/src/img/greenfields.jpg); background-size: cover;">
<div class="container">
<div class="content" style="padding-top: 90px; padding-bottom:45px;">
<div class="content mt48 mb48" data-snippet-id='resize'>
<h1>Create Awesome Websites</h1>
<h3>Super easy, fully flexible</h3>
<a href="/page/website.contactus" class="btn btn-success btn-large mt16">Contact us</a>
@@ -109,10 +128,11 @@
</div>
<div t-name="website.snippets.surprise" data-snippet-id='vomify' data-category='content' data-action='mutate' data-selector='.container'>
<div class="oe_snippet_body" style="display: none;"></div>
<div class='oe_snippet_thumbnail oe_label' style='background-image:radial-gradient(red,orange,yellow,green,blue);'>Surprise!</div>
</div>
<div t-name="website.snippets.spacer" data-snippet-id='spacer' data-category='structure' data-action='insert' data-selector-siblings='.container'>
<div t-name="website.snippets.spacer" data-snippet-id='resize' data-category='structure' data-action='insert' data-selector-siblings='.container'>
<div class='oe_snippet_thumbnail oe_label'>Spacer</div>
<div class="oe_snippet_body container mt32"></div>
</div>
@@ -129,6 +149,47 @@
</section>
</div>
<div t-name="website.snippets.text-image" data-snippet-id='text-image' data-category='structure' data-action='insert' data-selector-childs='.container'>
<div class='oe_snippet_thumbnail oe_label'>Text-Image</div>
<section class="oe_snippet_body container">
<div class="row">
<div class="col-md-7">
<h4 class="mt16">Mollit Anim</h4>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.</p>
</div>
<div class="col-md-5">
<img class="img-rounded img-responsive" src="/website/static/src/img/island.jpg"/>
</div>
</div>
</section>
</div>
<div t-name="website.snippets.image-text" data-snippet-id='image-text' data-category='structure' data-action='insert' data-selector-childs='.container'>
<div class='oe_snippet_thumbnail oe_label'>Image-Text</div>
<section class="oe_snippet_body container">
<div class="row">
<div class="col-md-5">
<img class="img-rounded img-responsive" src="/website/static/src/img/island.jpg"/>
</div>
<div class="col-md-7">
<h4 class="mt16">Mollit Anim</h4>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.</p>
</div>
</div>
</section>
</div>
<div t-name="website.snippets.three-collumns" data-snippet-id='three-collumns' data-category='structure' data-action='insert' data-selector-siblings='.container'>
<div class='oe_snippet_thumbnail oe_label'>three-collumns</div>
<section class="oe_snippet_body container">
+71 -73
View File
@@ -19,6 +19,8 @@
<head>
<title><t t-esc="title or res_company.name"/></title>
<meta name="openerp.company" t-att-value="res_company.name" />
<meta name="description" value="" />
<meta name="keywords" value="" />
<script type="text/javascript" src="/web/static/lib/underscore/underscore.js"></script>
<script type="text/javascript" src="/web/static/lib/underscore.string/lib/underscore.string.js"></script>
<script type="text/javascript" src="/web/static/lib/jquery/jquery.js"></script>
@@ -35,8 +37,8 @@
<script type="text/javascript" src="/website/static/lib/ckeditor/ckeditor.js"></script>
<script type="text/javascript" src="/website/static/lib/ckeditor.sharedspace/plugin.js"></script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/ace/1.1.01/ace.js"></script>
<script type="text/javascript" src="//vkbeautify.googlecode.com/files/vkbeautify.0.99.00.beta.js"></script>
<script type="text/javascript" src="/website/static/lib/ace/ace.js"></script>
<script type="text/javascript" src="/website/static/lib/vkbeautify/vkbeautify.0.99.00.beta.js"></script>
<script type="text/javascript" src="/web/static/lib/jquery.ui/js/jquery-ui-1.9.1.custom.js"></script>
<!-- mutation observers shim backed by mutation events (8 < IE < 11, Safari < 6, FF < 14, Chrome < 17) -->
<script type="text/javascript" src="/website/static/lib/MutationObservers/test/sidetable.js"></script>
@@ -160,99 +162,95 @@
<template id="homepage" page="True">
<t t-call="website.layout">
<section>
<div id="myCarousel" data-snippet-id="carousel" class="carousel slide" data-interval="1000000">
<!-- Carousel items -->
<div class="carousel-inner">
<div class="item active" style="background-image: url(/website/static/src/img/greenfields.jpg); background-size: cover;">
<div class="container">
<div class="content" style="padding-top: 90px; padding-bottom:45px;">
<h1>Create Awesome Websites</h1>
<h3>Super easy, fully flexible</h3>
<a href="/page/website.contactus" class="btn btn-success btn-large mt16">Contact us</a>
</div>
<div id="myCarousel" data-snippet-id="carousel" class="carousel slide" data-interval="1000000">
<!-- Carousel items -->
<div class="carousel-inner">
<div class="item active" style="background-image: url(/website/static/src/img/greenfields.jpg); background-size: cover;">
<div class="container">
<div class="content mt48 mb48" data-snippet-id='resize'>
<h1>Create Awesome Websites</h1>
<h3>Super easy, fully flexible</h3>
<a href="/page/website.contactus" class="btn btn-success btn-large mt16">Contact us</a>
</div>
</div>
</div>
<!-- Carousel nav -->
<a class="carousel-control left" href="#myCarousel" data-slide="prev"></a>
<a class="carousel-control right" href="#myCarousel" data-slide="next"></a>
</div>
<!-- Carousel nav -->
<a class="carousel-control left" href="#myCarousel" data-slide="prev"></a>
<a class="carousel-control right" href="#myCarousel" data-slide="next"></a>
</div>
<section class="container" data-snippet-id="resize">
<div class="row">
<div class="col-md-12 text-center">
<h1>Welcome To Your New Homepage,</h1>
<h2>where <b>everything</b> can be <em>customized</em></h2>
</div>
</div>
</section>
<div>
<section class="container" data-snippet-id="resize">
<div class="dark mt64">
<section class="dark container" data-snippet-id="resize">
<div class="row">
<div class="col-md-12 text-center" data-snippet-id="colmd">
<h1>Welcome To Your New Homepage,</h1>
<h2>where <b>everything</b> can be <em>customized</em></h2>
<div class="col-md-5">
<img class="img-rounded img-responsive" src="/website/static/src/img/island.jpg" />
</div>
</div>
</section>
<div class="dark mt64">
<section class="container" data-snippet-id="resize">
<div class="row">
<div class="col-md-5" data-snippet-id="colmd">
<img class="img-rounded img-responsive" src="/website/static/src/img/island.jpg" />
</div>
<div class="col-md-6 col-lg-offset-1" data-snippet-id="colmd">
<p class="mt16">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
</p>
<p>
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum
</p>
<div class="text-center"> <a href="http://www.openerp.com/start" class="btn mt16 btn-lg btn-primary">Call To <em>Action</em></a></div>
</div>
</div>
</section>
</div>
<section class="container" data-snippet-id="resize">
<div class="row">
<div class="col-md-12 text-center" data-snippet-id="colmd">
<h2 class="mt48">Ut enim ad minim veniam</h2>
</div>
</div>
<div class="row mt32">
<div class="col-md-4" data-snippet-id="colmd">
<img class="img-rounded img-responsive" src="/website/static/src/img/china_thumb.jpg" />
<h4 class="mt16">Cillum Dolore</h4>
<p>
<div class="col-md-6 col-lg-offset-1">
<p class="mt16">
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
</p>
</div>
<div class="col-md-4" data-snippet-id="colmd">
<img class="img-rounded img-responsive" src="/website/static/src/img/desert_thumb.jpg"/>
<h4 class="mt16">Mollit Anim</h4>
<p>
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum
</p>
</div>
<div class="col-md-4" data-snippet-id="colmd">
<img class="img-rounded img-responsive" src="/website/static/src/img/deers_thumb.jpg"/>
<h4 class="mt16">Nemo Enim Ipsam</h4>
<p>
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium
doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore
veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim
ipsam voluptatem quia voluptas
</p>
<div class="text-center"> <a href="http://www.openerp.com/start" class="btn mt16 btn-lg btn-primary">Call To <em>Action</em></a></div>
</div>
</div>
</section>
</div>
<section class="container" data-snippet-id="resize">
<div class="row">
<div class="col-md-12 text-center">
<h2 class="mt48">Ut enim ad minim veniam</h2>
</div>
</div>
<div class="row mt32">
<div class="col-md-4">
<img class="img-rounded img-responsive" src="/website/static/src/img/china_thumb.jpg" />
<h4 class="mt16">Cillum Dolore</h4>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
</p>
</div>
<div class="col-md-4">
<img class="img-rounded img-responsive" src="/website/static/src/img/desert_thumb.jpg"/>
<h4 class="mt16">Mollit Anim</h4>
<p>
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum
</p>
</div>
<div class="col-md-4">
<img class="img-rounded img-responsive" src="/website/static/src/img/deers_thumb.jpg"/>
<h4 class="mt16">Nemo Enim Ipsam</h4>
<p>
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium
doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore
veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim
ipsam voluptatem quia voluptas
</p>
</div>
</div>
</section>
</t>
</template>
+2 -2
View File
@@ -181,10 +181,10 @@
<td t-field="ticket.price"/>
<td><span t-if="ticket.register_max"><t t-esc="ticket.register_current"/>/<t t-field="ticket.register_max"/></span></td>
<td>
<select t-if="ticket.register_avail" t-attf-name="ticket- #{ ticket.id }" class="form-control">
<select t-if="ticket.register_avail" t-attf-name="ticket-#{ ticket.id }" class="form-control">
<t t-foreach="range(0, ticket.register_avail > 9 and 10 or ticket.register_avail+1 )" t-as="nb"><option t-esc="nb"/></t>
</select>
<span t-if="not ticket.register_avail">Not ticket available</span>
<span t-if="not ticket.register_avail">No tickets available</span>
</td>
</tr>
</tbody>