[REF] web_editor, website(_*): refactore media & link dialogs
* blog, gengo, sale
This commit is contained in:
@@ -140,7 +140,7 @@ class Web_Editor(http.Controller):
|
||||
# add attachment (images or link)
|
||||
#------------------------------------------------------
|
||||
@http.route('/web_editor/attachment/add', type='http', auth='user', methods=['POST'])
|
||||
def attach(self, func, upload=None, url=None, disable_optimization=None, **kwargs):
|
||||
def attach(self, upload=None, url=None, disable_optimization=None, **kwargs):
|
||||
# the upload argument doesn't allow us to access the files if more than
|
||||
# one file is uploaded, as upload references the first file
|
||||
# therefore we have to recover the files from the request object
|
||||
@@ -189,8 +189,9 @@ class Web_Editor(http.Controller):
|
||||
message = pycompat.text_type(e)
|
||||
|
||||
return """<script type='text/javascript'>
|
||||
window.parent['%s'](%s, %s);
|
||||
</script>""" % (func, json.dumps(uploads), json.dumps(message))
|
||||
window.attachments = %s;
|
||||
window.error = %s;
|
||||
</script>""" % (json.dumps(uploads), json.dumps(message))
|
||||
|
||||
#------------------------------------------------------
|
||||
# remove attachment (images or link)
|
||||
|
||||
@@ -8,6 +8,99 @@ var domReady = $.Deferred();
|
||||
$(domReady.resolve.bind(domReady));
|
||||
|
||||
return {
|
||||
/**
|
||||
* Retrieves all the CSS rules which match the given parser (Regex).
|
||||
*
|
||||
* @param {Regex} filter
|
||||
* @returns {Object[]} Array of CSS rules descriptions (objects). A rule is
|
||||
* defined by 3 values: 'selector', 'css' and 'names'. 'selector'
|
||||
* is a string which contains the whole selector, 'css' is a string
|
||||
* which contains the css properties and 'names' is an array of the
|
||||
* first captured groups for each selector part. E.g.: if the
|
||||
* filter is set to match .fa-* rules and capture the icon names,
|
||||
* the rule:
|
||||
* '.fa-alias1::before, .fa-alias2::before { hello: world; }'
|
||||
* will be retrieved as
|
||||
* {
|
||||
* selector: '.fa-alias1::before, .fa-alias2::before',
|
||||
* css: 'hello: world;',
|
||||
* names: ['.fa-alias1', '.fa-alias2'],
|
||||
* }
|
||||
*/
|
||||
cacheCssSelectors: {},
|
||||
getCssSelectors: function (filter) {
|
||||
if (this.cacheCssSelectors[filter]) {
|
||||
return this.cacheCssSelectors[filter];
|
||||
}
|
||||
this.cacheCssSelectors[filter] = [];
|
||||
var sheets = document.styleSheets;
|
||||
for (var i = 0; i < sheets.length; i++) {
|
||||
var rules;
|
||||
try {
|
||||
// try...catch because Firefox not able to enumerate
|
||||
// document.styleSheets[].cssRules[] for cross-domain
|
||||
// stylesheets.
|
||||
rules = sheets[i].rules || sheets[i].cssRules;
|
||||
} catch (e) {
|
||||
console.warn("Can't read the css rules of: " + sheets[i].href, e);
|
||||
continue;
|
||||
}
|
||||
if (!rules) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (var r = 0 ; r < rules.length ; r++) {
|
||||
var selectorText = rules[r].selectorText;
|
||||
if (!selectorText) {
|
||||
continue;
|
||||
}
|
||||
var selectors = selectorText.split(/\s*,\s*/);
|
||||
var data = null;
|
||||
for (var s = 0; s < selectors.length; s++) {
|
||||
var match = selectors[s].trim().match(filter);
|
||||
if (!match) {
|
||||
continue;
|
||||
}
|
||||
if (!data) {
|
||||
data = {
|
||||
selector: match[0],
|
||||
css: rules[r].cssText.replace(/(^.*\{\s*)|(\s*\}\s*$)/g, ''),
|
||||
names: [match[1]]
|
||||
};
|
||||
} else {
|
||||
data.selector += (', ' + match[0]);
|
||||
data.names.push(match[1]);
|
||||
}
|
||||
}
|
||||
if (data) {
|
||||
this.cacheCssSelectors[filter].push(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.cacheCssSelectors[filter];
|
||||
},
|
||||
/**
|
||||
* List of font icons to load by editor. The icons are displayed in the media
|
||||
* editor and identified like font and image (can be colored, spinned, resized
|
||||
* with fa classes).
|
||||
* To add font, push a new object {base, parser}
|
||||
*
|
||||
* - base: class who appear on all fonts
|
||||
* - parser: regular expression used to select all font in css stylesheets
|
||||
*
|
||||
* @type Array
|
||||
*/
|
||||
fontIcons: [{base: 'fa', parser: /\.(fa-(?:\w|-)+)::?before/i}],
|
||||
/**
|
||||
* Searches the fonts described by the @see fontIcons variable.
|
||||
*/
|
||||
computeFonts: _.once(function () {
|
||||
var self = this;
|
||||
_.each(this.fontIcons, function (data) {
|
||||
data.cssData = self.getCssSelectors(data.parser);
|
||||
data.alias = _.flatten(_.map(data.cssData, _.property('names')));
|
||||
});
|
||||
}),
|
||||
/**
|
||||
* If a widget needs to be instantiated on page loading, it needs to wait
|
||||
* for appropriate resources to be loaded. This function returns a Deferred
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
odoo.define('web_editor.rte', function (require) {
|
||||
'use strict';
|
||||
|
||||
var base = require('web_editor.base');
|
||||
var concurrency = require('web.concurrency');
|
||||
var core = require('web.core');
|
||||
var Widget = require('web.Widget');
|
||||
var weContext = require('web_editor.context');
|
||||
var summernote = require('web_editor.summernote');
|
||||
var weWidgets = require('web_editor.widget');
|
||||
|
||||
var _t = core._t;
|
||||
|
||||
@@ -257,7 +257,7 @@ var RTEWidget = Widget.extend({
|
||||
|
||||
this._getConfig = getConfig || this._getDefaultConfig;
|
||||
|
||||
weWidgets.computeFonts();
|
||||
base.computeFonts();
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
|
||||
@@ -5,6 +5,7 @@ var ajax = require('web.ajax');
|
||||
var Class = require('web.Class');
|
||||
var core = require('web.core');
|
||||
var mixins = require('web.mixins');
|
||||
var base = require('web_editor.base');
|
||||
var weContext = require('web_editor.context');
|
||||
var rte = require('web_editor.rte');
|
||||
var weWidgets = require('web_editor.widget');
|
||||
@@ -427,8 +428,8 @@ dom.isImgFont = function (node) {
|
||||
var className = (node && node.className || "");
|
||||
if (node && (nodeName === "SPAN" || nodeName === "I") && className.length) {
|
||||
var classNames = className.split(/\s+/);
|
||||
for (var k=0; k<weWidgets.fontIcons.length; k++) {
|
||||
if (_.intersection(weWidgets.fontIcons[k].alias, classNames).length) {
|
||||
for (var k=0; k<base.fontIcons.length; k++) {
|
||||
if (_.intersection(base.fontIcons[k].alias, classNames).length) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1029,7 +1030,7 @@ var SummernoteManager = Class.extend(mixins.EventDispatcherMixin, {
|
||||
return;
|
||||
}
|
||||
data.__alreadyDone = true;
|
||||
var altDialog = new weWidgets.alt(this,
|
||||
var altDialog = new weWidgets.AltDialog(this,
|
||||
data.options || {},
|
||||
data.$editable,
|
||||
data.media
|
||||
|
||||
@@ -5,7 +5,7 @@ var core = require('web.core');
|
||||
var Dialog = require('web.Dialog');
|
||||
var Widget = require('web.Widget');
|
||||
var weContext = require('web_editor.context');
|
||||
var widget = require('web_editor.widget');
|
||||
var weWidgets = require('web_editor.widget');
|
||||
|
||||
var qweb = core.qweb;
|
||||
var _t = core._t;
|
||||
@@ -813,7 +813,7 @@ registry.background = SnippetOption.extend({
|
||||
// Put fake image in the DOM, edit it and use it as background-image
|
||||
var $image = $('<img/>', {class: 'hidden', src: value}).appendTo(this.$target);
|
||||
|
||||
var _editor = new widget.MediaDialog(this, {}, null, $image[0]).open();
|
||||
var _editor = new weWidgets.MediaDialog(this, {}, null, $image[0]).open();
|
||||
_editor.opened(function () {
|
||||
_editor.$('[href="#editor-media-video"], [href="#editor-media-icon"]').addClass('hidden');
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
odoo.define('web_editor.transcoder', function (require) {
|
||||
'use strict';
|
||||
|
||||
var widget = require('web_editor.widget');
|
||||
var base = require('web_editor.base');
|
||||
|
||||
var rulesCache = [];
|
||||
|
||||
@@ -156,11 +156,11 @@ function fontToImg($editable) {
|
||||
$editable.find('.fa').each(function () {
|
||||
var $font = $(this);
|
||||
var icon, content;
|
||||
_.find(widget.fontIcons, function (font) {
|
||||
return _.find(widget.getCssSelectors(font.parser), function (css) {
|
||||
if ($font.is(css[0].replace(/::?before/g, ''))) {
|
||||
icon = css[2].split('-').shift();
|
||||
content = css[1].match(/content:\s*['"]?(.)['"]?/)[1];
|
||||
_.find(base.fontIcons, function (font) {
|
||||
return _.find(base.getCssSelectors(font.parser), function (data) {
|
||||
if ($font.is(data.selector.replace(/::?before/g, ''))) {
|
||||
icon = data.names[0].split('-').shift();
|
||||
content = data.css.match(/content:\s*['"]?(.)['"]?/)[1];
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -49,7 +49,7 @@ var AttributeTranslateDialog = weWidgets.Dialog.extend({
|
||||
this._super(parent, _.extend({
|
||||
title: _t("Translate Attribute"),
|
||||
buttons: [
|
||||
{text: _t("Close"), classes: 'btn-primary o_save_button', click: this.save}
|
||||
{text: _t("Close"), classes: 'btn-primary', click: this.save}
|
||||
],
|
||||
}, options || {}));
|
||||
this.$target = $(node);
|
||||
|
||||
@@ -4,11 +4,11 @@ odoo.define('web_editor.inline', function (require) {
|
||||
var core = require('web.core');
|
||||
var editor = require('web_editor.editor');
|
||||
var rte = require('web_editor.rte');
|
||||
var widget = require('web_editor.widget');
|
||||
var weWidgets = require('web_editor.widget');
|
||||
var transcoder = require('web_editor.transcoder');
|
||||
var snippet_editor = require('web_editor.snippet.editor');
|
||||
|
||||
widget.MediaDialog.include({
|
||||
weWidgets.MediaDialog.include({
|
||||
start: function () {
|
||||
this.$('[href="#editor-media-video"]').addClass('hidden');
|
||||
return this._super.apply(this, arguments);
|
||||
|
||||
@@ -157,7 +157,7 @@ tour.register('rte', {
|
||||
trigger: '#editor-media-icon.active span.fa:first',
|
||||
}, {
|
||||
content: "save pictogram",
|
||||
trigger: 'button.o_save_button',
|
||||
trigger: '.modal-footer > .btn-primary',
|
||||
extra_trigger: '#editor-media-icon.active span.o_selected',
|
||||
}, {
|
||||
content: "select a size for the pictogram",
|
||||
@@ -176,7 +176,7 @@ tour.register('rte', {
|
||||
extra_trigger: 'a#link-preview:containsRegex(/^<span [^>]+><\\/span>$/) > span.fa.fa-3x.pull-right',
|
||||
}, {
|
||||
content: "insert a link url",
|
||||
trigger: '#o_link_dialog_url_input',
|
||||
trigger: 'input[name="url"]',
|
||||
extra_trigger: 'a#link-preview.btn',
|
||||
run: "text http://www.odoo.com",
|
||||
}, {
|
||||
@@ -185,7 +185,7 @@ tour.register('rte', {
|
||||
run: "text ABC[IMG] DEF",
|
||||
}, {
|
||||
content: "save link",
|
||||
trigger: 'button.o_save_button',
|
||||
trigger: '.modal-footer > .btn-primary',
|
||||
extra_trigger: 'a#link-preview.btn:containsRegex(/^ABC<span [^>]+><\\/span> DEF$/)',
|
||||
}, {
|
||||
content: "click on other picture",
|
||||
@@ -201,12 +201,12 @@ tour.register('rte', {
|
||||
extra_trigger: 'a#link-preview:containsRegex(/^<img [^>]+>$/) img',
|
||||
}, {
|
||||
content: "insert an email",
|
||||
trigger: '#o_link_dialog_url_input',
|
||||
trigger: 'input[name="url"]',
|
||||
extra_trigger: 'a#link-preview.btn',
|
||||
run: "text test@test.test",
|
||||
}, {
|
||||
content: "save link",
|
||||
trigger: 'button.o_save_button',
|
||||
trigger: '.modal-footer > .btn-primary',
|
||||
extra_trigger: 'a#link-preview.btn[href="mailto:test@test.test"]',
|
||||
}, {
|
||||
content: "select for triple enter then double backspace",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1354,8 +1354,6 @@ body .modal {
|
||||
}
|
||||
|
||||
li.search {
|
||||
float: right;
|
||||
|
||||
ul.pager li:last-child{
|
||||
margin-left: 2px;
|
||||
}
|
||||
@@ -1378,7 +1376,8 @@ body .modal {
|
||||
}
|
||||
|
||||
.o_existing_attachment_cell {
|
||||
@odoo-border-image: 1px;
|
||||
@odoo-border-image: 2px;
|
||||
|
||||
.o_existing_attachment_remove {
|
||||
.o-position-absolute(@odoo-border-image, 15px + @odoo-border-image);
|
||||
padding: 3px 5px 5px 5px;
|
||||
@@ -1396,21 +1395,24 @@ body .modal {
|
||||
.o_image {
|
||||
border: @odoo-border-image solid transparent;
|
||||
cursor: pointer;
|
||||
.o-transition(opacity, 400ms);
|
||||
|
||||
&.o_webimage {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
background-image: none!important;
|
||||
}
|
||||
|
||||
&.o_image_loading {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
&.o_selected .o_image {
|
||||
border-color: @odoo-brand-primary;
|
||||
box-shadow: 0px 0px 2px 2px @odoo-brand-secondary;
|
||||
}
|
||||
&:hover {
|
||||
.o_existing_attachment_remove {
|
||||
opacity: 1;
|
||||
}
|
||||
&:hover .o_existing_attachment_remove {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.font-icons-icons {
|
||||
|
||||
@@ -48,10 +48,10 @@
|
||||
<div t-name="web_editor.dialog.media">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="#editor-media-image" data-toggle="tab">Image</a></li>
|
||||
<li><a href="#editor-media-document" data-toggle="tab">Document</a></li>
|
||||
<li><a href="#editor-media-icon" data-toggle="tab">Pictogram</a></li>
|
||||
<li><a href="#editor-media-video" data-toggle="tab">Video</a></li>
|
||||
<li class="search">
|
||||
<li><a href="#editor-media-document" data-toggle="tab" t-att-class="widget.onlyImages ? 'hidden' : ''">Document</a></li>
|
||||
<li><a href="#editor-media-icon" data-toggle="tab" t-att-class="widget.onlyImages ? 'hidden' : ''">Pictogram</a></li>
|
||||
<li><a href="#editor-media-video" data-toggle="tab" t-att-class="widget.onlyImages ? 'hidden' : ''">Video</a></li>
|
||||
<li class="search pull-right">
|
||||
<ul class="pager mb0 mt0">
|
||||
<li class="previous">
|
||||
<a class="btn btn-default disabled" href="#"><i class="fa fa-angle-left"/> Previous</a>
|
||||
@@ -61,7 +61,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="search">
|
||||
<li class="search pull-right">
|
||||
<div class="form-group">
|
||||
<input class="form-control" id="icon-search" type="search"/>
|
||||
<span class="fa fa-search"/>
|
||||
@@ -79,48 +79,44 @@
|
||||
|
||||
<!-- Image choosing part of the Media Dialog -->
|
||||
<t t-name="web_editor.dialog.image">
|
||||
<div>
|
||||
<form method="POST"
|
||||
action="/web_editor/attachment/add"
|
||||
enctype="multipart/form-data"
|
||||
target="fileframe"
|
||||
class="form-inline">
|
||||
<input type="hidden" name="csrf_token" t-att-value="csrf_token"/>
|
||||
<div class="well">
|
||||
<div class="form-group pull-left">
|
||||
<input type="file" name="upload" t-att-accept="widget.accept" multiple="multiple" style="position: absolute; opacity: 0; width: 1px; height: 1px;"/>
|
||||
<input type="hidden" name="disable_optimization" value=""/>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-primary filepicker" type="button">Upload an image</button>
|
||||
<button class="btn btn-primary dropdown-toggle" data-toggle="dropdown" type="button">
|
||||
<span class="caret"/>
|
||||
<span class="sr-only">Alternate Upload</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li>
|
||||
<a class="js_disable_optimization">Upload image without optimization</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<button class="btn hidden wait" disabled="disabled" type="button">Uploading...</button>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-muted">— or — </span>
|
||||
<label for="iamgeurl">Add an image URL</label>
|
||||
<div class="form-group btn-group">
|
||||
<input class="form-control url pull-left" id="iamgeurl" name="url" placeholder="https://www.odoo.com/logo.png" style="width: 320px;" type="text"/>
|
||||
<button class="btn btn-default" type="submit">Add</button>
|
||||
</div>
|
||||
<form class="form-inline"
|
||||
method="POST"
|
||||
action="/web_editor/attachment/add"
|
||||
enctype="multipart/form-data"
|
||||
target="fileframe">
|
||||
<input type="hidden" name="csrf_token" t-att-value="csrf_token"/>
|
||||
<div class="well">
|
||||
<div class="form-group pull-left">
|
||||
<input type="file" class="hidden" name="upload" t-att-accept="widget.accept" multiple="multiple"/>
|
||||
<input type="hidden" name="disable_optimization" value=""/>
|
||||
<div class="btn-group">
|
||||
<button class="btn btn-primary o_upload_image_button" type="button">Upload an image</button>
|
||||
<button class="btn btn-primary dropdown-toggle" data-toggle="dropdown" type="button">
|
||||
<span class="caret"/>
|
||||
<span class="sr-only">Alternate Upload</span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" role="menu">
|
||||
<li>
|
||||
<a class="o_upload_image_button_no_optimization">Upload image without optimization</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden" name="func"/>
|
||||
<div class="help-block"/>
|
||||
<div class="existing-attachments">
|
||||
<t t-call="web_editor.dialog.image.existing"/>
|
||||
<div>
|
||||
<span class="text-muted">— or —</span>
|
||||
<label for="imageurl">Add an image URL</label>
|
||||
<div class="form-group btn-group">
|
||||
<input type="text" class="form-control url pull-left" id="imageurl" name="url" placeholder="https://www.odoo.com/logo.png" style="width: 320px;"/>
|
||||
<button type="button" class="btn btn-default o_upload_image_url_button" disabled="disabled">Add</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<iframe class="hidden" name="fileframe" src="about:blank"/>
|
||||
</div>
|
||||
<div class="help-block"/>
|
||||
<div class="existing-attachments">
|
||||
<t t-call="web_editor.dialog.image.existing"/>
|
||||
</div>
|
||||
<iframe class="hidden" name="fileframe"/>
|
||||
</form>
|
||||
</t>
|
||||
<t t-name="web_editor.dialog.image.existing">
|
||||
<div class="modal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
@@ -146,7 +142,7 @@
|
||||
<div class="row mt16" t-as="row" t-foreach="rows">
|
||||
<div class="col-sm-2 o_existing_attachment_cell" t-as="attachment" t-foreach="row">
|
||||
<i class="fa fa-times o_existing_attachment_remove" t-att-data-id="attachment.id"/>
|
||||
<div class="o_attachment_border"><div t-att-data-src="attachment.src" t-att-data-url="attachment.url" t-att-alt="attachment.name" t-att-title="attachment.name" t-att-data-id="attachment.id" t-att-data-mimetype="attachment.mimetype" class="o_image"/></div>
|
||||
<div class="o_attachment_border"><div t-att-data-src="attachment.src" t-att-data-url="attachment.url" t-att-alt="attachment.name" t-att-title="attachment.name" t-att-data-id="attachment.id" t-att-data-mimetype="attachment.mimetype" class="o_image o_image_loading"/></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -168,8 +164,6 @@
|
||||
<!-- Icon choosing part of the Media Dialog -->
|
||||
<t t-name="web_editor.dialog.font-icons">
|
||||
<form action="#">
|
||||
<input type="hidden" id="fa-icon"/>
|
||||
<input type="hidden" id="fa-size" value="fa-1x"/>
|
||||
<div class="font-icons-icons">
|
||||
<t t-call="web_editor.dialog.font-icons.icons">
|
||||
<t t-set="iconsParser" t-value="widget.iconsParser"/>
|
||||
@@ -179,7 +173,11 @@
|
||||
</t>
|
||||
<t t-name="web_editor.dialog.font-icons.icons">
|
||||
<t t-as="data" t-foreach="iconsParser">
|
||||
<span t-as="cssData" t-att-data-id="cssData[2]" t-att-title="cssData[3].join(', ')" t-attf-class="#{data.base} font-icons-icon #{cssData[2]}" t-attf-data-alias=",#{cssData[3]}," t-foreach="data.cssData"/>
|
||||
<span t-foreach="data.cssData" t-as="cssData"
|
||||
t-att-data-id="cssData.names[0]"
|
||||
t-att-title="cssData.names[0]"
|
||||
t-attf-class="font-icons-icon #{data.base} #{cssData.names[0]}"
|
||||
t-att-data-alias="cssData.names.join(',')"/>
|
||||
</t>
|
||||
</t>
|
||||
|
||||
@@ -239,23 +237,23 @@
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-3" for="o_link_dialog_label_input">Link Label</label>
|
||||
<div class="col-sm-9">
|
||||
<input class="form-control" id="o_link_dialog_label_input" required="required"/>
|
||||
<input type="text" name="label" class="form-control" id="o_link_dialog_label_input" required="required" t-att-value="widget.data.text"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-3" for="o_link_dialog_url_input">URL or Email</label>
|
||||
<div class="col-sm-9">
|
||||
<input class="form-control url email-address url-source" id="o_link_dialog_url_input" required="required"/>
|
||||
<input type="text" name="url" class="form-control" id="o_link_dialog_url_input" required="required"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label col-sm-3">Size</label>
|
||||
<div class="col-sm-9">
|
||||
<select class="form-control col-sm-3 link-style">
|
||||
<option value="btn-xs">Extra Small</option>
|
||||
<option value="btn-sm">Small</option>
|
||||
<select name="link_style_size" class="form-control col-sm-3 link-style">
|
||||
<option value="xs">Extra Small</option>
|
||||
<option value="sm">Small</option>
|
||||
<option value="" selected="selected">Medium</option>
|
||||
<option value="btn-lg">Large</option>
|
||||
<option value="lg">Large</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -265,12 +263,12 @@
|
||||
<div class="o_link_dialog_color">
|
||||
<label t-attf-class="o_link_dialog_color_item o_btn_preview btn btn-link text-center" data-color="">
|
||||
<span>L</span>
|
||||
<input class="hidden link-style" name="link-style-type" type="radio" value=""/>
|
||||
<input class="hidden link-style" name="link_style_color" type="radio" value=""/>
|
||||
<i class="fa"/>
|
||||
</label>
|
||||
<t t-foreach="['btn-primary', 'btn-default', 'btn-success', 'btn-info', 'btn-warning', 'btn-danger', 'btn-alpha', 'btn-beta', 'btn-gamma', 'btn-delta', 'btn-epsilon']" t-as="color">
|
||||
<label t-attf-class="o_link_dialog_color_item o_btn_preview btn #{color}" t-att-data-color="color">
|
||||
<input class="hidden link-style" name="link-style-type" type="radio" t-att-value="color"/>
|
||||
<t t-foreach="['primary', 'default', 'success', 'info', 'warning', 'danger', 'alpha', 'beta', 'gamma', 'delta', 'epsilon']" t-as="color">
|
||||
<label t-attf-class="o_link_dialog_color_item o_btn_preview btn btn-#{color}">
|
||||
<input type="radio" name="link_style_color" class="hidden link-style" t-att-value="color"/>
|
||||
<i class="fa"/>
|
||||
</label>
|
||||
</t>
|
||||
@@ -279,11 +277,11 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-3 col-sm-9">
|
||||
<label class="o_switch">
|
||||
<input class="window-new" type="checkbox"/>
|
||||
<span/>
|
||||
Open in new window
|
||||
</label>
|
||||
<label class="o_switch">
|
||||
<input type="checkbox" name="is_new_window" t-att-checked="widget.data.isNewWindow ? 'checked' : undefined"/>
|
||||
<span/>
|
||||
Open in new window
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
@@ -1,22 +1,17 @@
|
||||
odoo.define('website.editor', function (require) {
|
||||
'use strict';
|
||||
|
||||
var widget = require('web_editor.widget');
|
||||
var weWidgets = require('web_editor.widget');
|
||||
var wUtils = require('website.utils');
|
||||
|
||||
widget.LinkDialog.include({
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
weWidgets.LinkDialog.include({
|
||||
/**
|
||||
* Allows the URL input to propose existing website pages.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
bind_data: function () {
|
||||
wUtils.autocompleteWithPages(this, this.$('#o_link_dialog_url_input'));
|
||||
start: function () {
|
||||
wUtils.autocompleteWithPages(this, this.$('input[name="url"]'));
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -3,7 +3,7 @@ odoo.define('website.snippets.options', function (require) {
|
||||
|
||||
var core = require('web.core');
|
||||
var Dialog = require('web.Dialog');
|
||||
var widgets = require('web_editor.widget');
|
||||
var weWidgets = require('web_editor.widget');
|
||||
var options = require('web_editor.snippets.options');
|
||||
|
||||
var _t = core._t;
|
||||
@@ -397,12 +397,12 @@ options.registry.parallax = options.Class.extend({
|
||||
},
|
||||
});
|
||||
|
||||
var FacebookPageDialog = widgets.Dialog.extend({
|
||||
xmlDependencies: widgets.Dialog.prototype.xmlDependencies.concat(
|
||||
var FacebookPageDialog = weWidgets.Dialog.extend({
|
||||
xmlDependencies: weWidgets.Dialog.prototype.xmlDependencies.concat(
|
||||
['/website/static/src/xml/website.facebook_page.xml']
|
||||
),
|
||||
template: 'website.facebook_page_dialog',
|
||||
events: _.extend({}, widgets.Dialog.prototype.events || {}, {
|
||||
events: _.extend({}, weWidgets.Dialog.prototype.events || {}, {
|
||||
'change': '_onOptionChange',
|
||||
}),
|
||||
|
||||
@@ -793,7 +793,7 @@ options.registry.gallery = options.Class.extend({
|
||||
addImages: function (previewMode) {
|
||||
var self = this;
|
||||
var $container = this.$('.container:first');
|
||||
var dialog = new widgets.MediaDialog(this, {select_images: true}, this.$target.closest('.o_editable'), null);
|
||||
var dialog = new weWidgets.MediaDialog(this, {multiImages: true}, this.$target.closest('.o_editable'), null);
|
||||
var lastImage = _.last(this._getImages());
|
||||
var index = lastImage ? this._getIndex(lastImage) : -1;
|
||||
dialog.on('save', this, function (attachments) {
|
||||
|
||||
@@ -5,7 +5,7 @@ var core = require('web.core');
|
||||
var Dialog = require('web.Dialog');
|
||||
var time = require('web.time');
|
||||
var weContext = require('web_editor.context');
|
||||
var widget = require('web_editor.widget');
|
||||
var weWidgets = require('web_editor.widget');
|
||||
var websiteNavbarData = require('website.navbar');
|
||||
var websiteRootData = require('website.WebsiteRoot');
|
||||
var Widget = require('web.Widget');
|
||||
@@ -13,12 +13,12 @@ var Widget = require('web.Widget');
|
||||
var _t = core._t;
|
||||
var qweb = core.qweb;
|
||||
|
||||
var PagePropertiesDialog = widget.Dialog.extend({
|
||||
var PagePropertiesDialog = weWidgets.Dialog.extend({
|
||||
template: 'website.pagesMenu.page_info',
|
||||
xmlDependencies: widget.Dialog.prototype.xmlDependencies.concat(
|
||||
xmlDependencies: weWidgets.Dialog.prototype.xmlDependencies.concat(
|
||||
['/website/static/src/xml/website.pageProperties.xml']
|
||||
),
|
||||
events: _.extend({}, widget.Dialog.prototype.events, {
|
||||
events: _.extend({}, weWidgets.Dialog.prototype.events, {
|
||||
'keyup input#page_name': '_onNameChanged',
|
||||
'keyup input#page_url': '_onUrlChanged',
|
||||
'change input#create_redirect': '_onCreateRedirectChanged',
|
||||
@@ -42,7 +42,7 @@ var PagePropertiesDialog = widget.Dialog.extend({
|
||||
this.page_id = page_id;
|
||||
|
||||
var buttons = [
|
||||
{text: _t("Save"), classes: 'btn-primary o_save_button', click: this.save},
|
||||
{text: _t("Save"), classes: 'btn-primary', click: this.save},
|
||||
{text: _t("Discard"), close: true},
|
||||
];
|
||||
if (options.fromPageManagement) {
|
||||
@@ -314,14 +314,16 @@ var PagePropertiesDialog = widget.Dialog.extend({
|
||||
},
|
||||
});
|
||||
|
||||
var MenuEntryDialog = widget.LinkDialog.extend({
|
||||
xmlDependencies: widget.LinkDialog.prototype.xmlDependencies.concat(
|
||||
var MenuEntryDialog = weWidgets.LinkDialog.extend({
|
||||
xmlDependencies: weWidgets.LinkDialog.prototype.xmlDependencies.concat(
|
||||
['/website/static/src/xml/website.contentMenu.xml']
|
||||
),
|
||||
events: _.extend({}, weWidgets.LinkDialog.prototype.events || {}, {
|
||||
'change input[name="link_menu_options"]': '_onNewMenuOptionChange',
|
||||
}),
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @override
|
||||
*/
|
||||
init: function (parent, options, editor, data) {
|
||||
data.text = data.name || '';
|
||||
@@ -336,23 +338,29 @@ var MenuEntryDialog = widget.LinkDialog.extend({
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
var self = this;
|
||||
// Remove style related elements
|
||||
this.$('.o_link_dialog_preview').remove();
|
||||
this.$('.window-new, .link-style').closest('.form-group').remove();
|
||||
this.$('label[for="o_link_dialog_label_input"]').text(_t("Menu Label"));
|
||||
if (this.menu_link_options) { // add menu link option only when adding new menu
|
||||
self.$('#o_link_dialog_url_input').closest('.form-group').hide();
|
||||
this.$('#o_link_dialog_label_input').closest('.form-group').after(qweb.render('website.contentMenu.dialog.edit.link_menu_options'));
|
||||
// remove the label that is automatically added before
|
||||
this.$('#o_link_dialog_url_input').parent().siblings().html('');
|
||||
this.$('input[name=link_menu_options]').on('change', function () {
|
||||
self.$('#o_link_dialog_url_input').closest('.form-group').toggle();
|
||||
});
|
||||
}
|
||||
this.$('input[name="is_new_window"], .link-style').closest('.form-group').remove();
|
||||
this.$modal.find('.modal-lg').removeClass('modal-lg')
|
||||
.find('.col-md-8').removeClass('col-md-8').addClass('col-xs-12');
|
||||
|
||||
// Adapt URL label
|
||||
this.$('label[for="o_link_dialog_label_input"]').text(_t("Menu Label"));
|
||||
|
||||
// If new menu, adapt URL field to new page / existing page
|
||||
if (this.menu_link_options) {
|
||||
this.$('input[name="label"]').closest('.form-group').after(qweb.render('website.contentMenu.dialog.edit.link_menu_options'));
|
||||
this.$('input[name="url"]').closest('.form-group').addClass('hidden');
|
||||
this.$('label[for="o_link_dialog_url_input"]').html('');
|
||||
}
|
||||
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
@@ -369,11 +377,22 @@ var MenuEntryDialog = widget.LinkDialog.extend({
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_onNewMenuOptionChange: function () {
|
||||
this.$('input[name="url"]').closest('.form-group').toggleClass('hidden');
|
||||
},
|
||||
});
|
||||
|
||||
var SelectEditMenuDialog = widget.Dialog.extend({
|
||||
var SelectEditMenuDialog = weWidgets.Dialog.extend({
|
||||
template: 'website.contentMenu.dialog.select',
|
||||
xmlDependencies: widget.Dialog.prototype.xmlDependencies.concat(
|
||||
xmlDependencies: weWidgets.Dialog.prototype.xmlDependencies.concat(
|
||||
['/website/static/src/xml/website.contentMenu.xml']
|
||||
),
|
||||
|
||||
@@ -401,12 +420,12 @@ var SelectEditMenuDialog = widget.Dialog.extend({
|
||||
},
|
||||
});
|
||||
|
||||
var EditMenuDialog = widget.Dialog.extend({
|
||||
var EditMenuDialog = weWidgets.Dialog.extend({
|
||||
template: 'website.contentMenu.dialog.edit',
|
||||
xmlDependencies: widget.Dialog.prototype.xmlDependencies.concat(
|
||||
xmlDependencies: weWidgets.Dialog.prototype.xmlDependencies.concat(
|
||||
['/website/static/src/xml/website.contentMenu.xml']
|
||||
),
|
||||
events: _.extend({}, widget.Dialog.prototype.events, {
|
||||
events: _.extend({}, weWidgets.Dialog.prototype.events, {
|
||||
'click a.js_add_menu': '_onAddMenuButtonClick',
|
||||
'click button.js_delete_menu': '_onDeleteMenuButtonClick',
|
||||
'click button.js_edit_menu': '_onEditMenuButtonClick',
|
||||
|
||||
@@ -94,7 +94,7 @@ tour.register('rte_translator', {
|
||||
run: 'text test french placeholder',
|
||||
}, {
|
||||
content: "close modal",
|
||||
trigger: 'button.o_save_button',
|
||||
trigger: '.modal-footer > .btn-primary',
|
||||
extra_trigger: '.modal input:propValue(test french placeholder)',
|
||||
}, {
|
||||
content: "save translation",
|
||||
|
||||
@@ -35,7 +35,7 @@ odoo.define("website_blog.tour", function (require) {
|
||||
content: _t("Choose an image from the library."),
|
||||
position: "top",
|
||||
}, {
|
||||
trigger: ".o_select_media_dialog .btn.o_save_button",
|
||||
trigger: ".o_select_media_dialog .modal-footer > .btn-primary",
|
||||
extra_trigger: ".o_existing_attachment_cell.o_selected",
|
||||
content: _t("Click on <b>Save</b> to set the picture as cover."),
|
||||
position: "top",
|
||||
|
||||
@@ -54,7 +54,7 @@ odoo.define('website_blog.editor', function (require) {
|
||||
'use strict';
|
||||
|
||||
require('web.dom_ready');
|
||||
var widget = require('web_editor.widget');
|
||||
var weWidgets = require('web_editor.widget');
|
||||
var options = require('web_editor.snippets.options');
|
||||
var rte = require('web_editor.rte');
|
||||
|
||||
@@ -134,7 +134,7 @@ options.registry.blog_cover = options.Class.extend({
|
||||
change: function (previewMode, value, $li) {
|
||||
var $image = $("<img/>", {src: this.$image.css("background-image")});
|
||||
|
||||
var editor = new widget.MediaDialog(this, {only_images: true}, $image, $image[0]).open();
|
||||
var editor = new weWidgets.MediaDialog(this, {onlyImages: true}, $image, $image[0]).open();
|
||||
editor.on("save", this, function (event, img) {
|
||||
var src = $image.attr("src");
|
||||
this.$image.css("background-image", src ? ("url(" + src + ")") : "");
|
||||
|
||||
@@ -134,13 +134,13 @@
|
||||
<li class="list-group-item form-group">
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" id="gengo_auto_approve" class="window-new" checked="1"/>
|
||||
<input type="checkbox" id="gengo_auto_approve" checked="1"/>
|
||||
Auto Approve Translation <small class="text-muted">- Jobs are Automatically Approved by Gengo.</small>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" id="gengo_sandbox" class="window-new"/>
|
||||
<input type="checkbox" id="gengo_sandbox"/>
|
||||
Sandbox <small class="text-muted">- Enable if you using testing account</small>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -38,7 +38,7 @@ odoo.define("website_sale.tour_shop", function (require) {
|
||||
content: _t("Click here to set an image describing your product."),
|
||||
position: "top",
|
||||
}, {
|
||||
trigger: ".o_select_media_dialog .btn.filepicker",
|
||||
trigger: ".o_select_media_dialog .o_upload_image_button",
|
||||
content: _t("Upload an image from your local library."),
|
||||
position: "bottom",
|
||||
run: function (actions) {
|
||||
|
||||
Reference in New Issue
Block a user