summaryrefslogtreecommitdiff
path: root/addons/web_editor/static/src/xml
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web_editor/static/src/xml')
-rw-r--r--addons/web_editor/static/src/xml/backend.xml14
-rw-r--r--addons/web_editor/static/src/xml/editor.xml372
-rw-r--r--addons/web_editor/static/src/xml/snippets.xml6
-rw-r--r--addons/web_editor/static/src/xml/translator.xml15
-rw-r--r--addons/web_editor/static/src/xml/wysiwyg.xml375
-rw-r--r--addons/web_editor/static/src/xml/wysiwyg_colorpicker.xml91
6 files changed, 469 insertions, 404 deletions
diff --git a/addons/web_editor/static/src/xml/backend.xml b/addons/web_editor/static/src/xml/backend.xml
index 146d96fe1e5..904f21f440c 100644
--- a/addons/web_editor/static/src/xml/backend.xml
+++ b/addons/web_editor/static/src/xml/backend.xml
@@ -1,12 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
- <t t-name="web_editor.FieldTextHtml">
- <div class="oe_form_field oe_form_field_html oe_form_embedded_html" t-att-style="widget.attrs.style">
- <iframe/>
- </div>
- </t>
-
<t t-name="web_editor.FieldTextHtml.button.translate">
<div class="btn-group float-right">
<button t-if="widget.field.translate" class="o_field_translate btn btn-secondary" style="height: 24px; padding: 1px 17px 0px 5px" aria-label="Translate" title="Translate">
@@ -15,12 +9,4 @@
</div>
</t>
- <t t-name="web_editor.FieldTextHtml.fullscreen">
- <span style="margin: 5px; position: fixed; top: 0; right: 0; z-index: 2000;">
- <button class="o_fullscreen btn btn-primary" style="width: 24px; height: 24px; background-color: #337ab7; border: 1px solid #2e6da4; border-radius: 4px; padding: 0; position: relative;">
- <img src="/web_editor/font_to_img/61541/rgb(255,255,255)/16" style="position: absolute; top: 3px; left: 4px;" alt="Fullscreen"/>
- </button>
- </span>
- </t>
-
</templates>
diff --git a/addons/web_editor/static/src/xml/editor.xml b/addons/web_editor/static/src/xml/editor.xml
index 05e7d584337..51c3d5412ff 100644
--- a/addons/web_editor/static/src/xml/editor.xml
+++ b/addons/web_editor/static/src/xml/editor.xml
@@ -1,378 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<templates id="template" xml:space="preserve">
<!--=================-->
- <!-- Base components -->
- <!--=================-->
-
- <!-- Editor top bar which contains the summernote tools and save/discard buttons -->
- <t t-name="web_editor.editorbar">
- <div id="web_editor-top-edit">
- <div id="web_editor-toolbars"/>
- <form class="navbar-form text-muted">
- <button type="button" class="btn btn-secondary" data-action="cancel"><i class="fa fa-times"/> Discard</button>
- <button type="button" class="btn btn-primary" data-action="save"><i class="fa fa-floppy-o"/> Save</button>
- </form>
- </div>
- </t>
-
- <!-- Custom checkbox (material-design-like toggle) -->
- <t t-name="web_editor.components.switch">
- <label class="o_switch" t-att-for="id">
- <input type="checkbox" t-att-id="id"/>
- <span/>
- <t t-if="label"><t t-esc="label"/></t>
- </label>
- </t>
-
- <!--=================-->
- <!-- Edition Dialogs -->
- <!--=================-->
-
- <!-- Alt Dialog (allows to change alt and title of page images) -->
- <form t-name="web_editor.dialog.alt" action="#">
- <div class="form-group row">
- <label class="col-md-3 col-form-label" for="alt"
- title="'Alt tag' specifies an alternate text for an image, if the image cannot be displayed (slow connection, missing image, screen reader ...).">
- Description <small>(ALT Tag)</small>
- </label>
- <div class="col-md-8">
- <input class="form-control" id="alt" required="required" t-att-value="widget.alt" type="text"/>
- </div>
- </div>
- <div class="form-group row">
- <label class="col-md-3 col-form-label" for="title"
- title="'Title tag' is shown as a tooltip when you hover the picture.">
- Tooltip <small>(TITLE Tag)</small>
- </label>
- <div class="col-md-8">
- <input class="form-control" id="title" required="required" t-att-value="widget.tag_title" type="text"/>
- </div>
- </div>
- </form>
-
- <!-- Media Dialog (allows to choose an img/pictogram/video) -->
- <div t-name="web_editor.dialog.media">
- <ul class="nav nav-tabs" role="tablist">
- <li class="nav-item"><a role="tab" href="#editor-media-image" aria-controls="editor-media-image" data-toggle="tab" t-attf-class="nav-link#{widget.noImages ? ' d-none' : ''}">Image</a></li>
- <li class="nav-item"><a role="tab" href="#editor-media-document" aria-controls="editor-media-document" data-toggle="tab" t-attf-class="nav-link#{widget.noDocuments ? ' d-none' : ''}">Document</a></li>
- <li class="nav-item"><a role="tab" href="#editor-media-icon" aria-controls="editor-media-icon" data-toggle="tab" t-attf-class="nav-link#{widget.noIcons ? ' d-none' : ''}">Pictogram</a></li>
- <li class="nav-item"><a role="tab" href="#editor-media-video" aria-controls="editor-media-video" data-toggle="tab" t-attf-class="nav-link#{widget.noVideos ? ' d-none' : ''}">Video</a></li>
- </ul>
- <!-- Tab panes -->
- <div class="tab-content">
- <div role="tabpanel" class="tab-pane fade" id="editor-media-image"/>
- <div role="tabpanel" class="tab-pane fade" id="editor-media-document"/>
- <div role="tabpanel" class="tab-pane fade" id="editor-media-icon"/>
- <div role="tabpanel" class="tab-pane fade" id="editor-media-video"/>
- </div>
- </div>
- <t t-name="web_editor.dialog.media.search">
- <div class="input-group ml-auto">
- <input type="text" class="form-control o_we_search" t-att-placeholder="searchPlaceholder.trim()"/>
- <div class="input-group-append">
- <div class="input-group-text o_we_search_icon">
- <i class="fa fa-search" title="Search" role="img" aria-label="Search"/>
- </div>
- </div>
- </div>
- </t>
-
- <!-- Image choosing part of the Media Dialog -->
- <t t-name="web_editor.dialog.image">
- <t t-set="iframeName" t-value="_.uniqueId('fileframe-')"/>
- <form method="POST"
- action="/web_editor/attachment/add"
- enctype="multipart/form-data"
- t-att-target="iframeName">
- <input type="hidden" name="csrf_token" t-att-value="csrf_token"/>
- <input type="hidden" name="filters" t-att-value="widget.firstFilters.join('_')"/>
- <input t-if="widget.options.res_id" type="hidden" name="res_id" t-att-value="widget.options.res_id"/>
- <input t-if="widget.options.res_model" type="hidden" name="res_model" t-att-value="widget.options.res_model"/>
- <t t-call="web_editor.dialog.files.submenu">
- <t t-set="isDocument" t-value="widget.options.document"/>
- <t t-set="accept" t-value="widget.accept"/>
- </t>
- <div class="form-text"/>
- <div class="existing-attachments"/>
- <div class="mt-4 text-center mx-auto">
- <button class="btn btn-primary o_load_more" type="button">Load more...</button>
- <div class="mt-4 o_load_done_msg d-none">
- <span><i>All attachments have been loaded</i></span>
- </div>
- </div>
- <iframe class="o_file_upload_iframe d-none" t-att-name="iframeName"/>
- </form>
- </t>
- <t t-name="web_editor.dialog.files.submenu">
- <div class="form-inline align-items-center py-4">
- <input type="file" class="d-none o_file_input" name="upload" t-att-accept="accept" multiple="multiple"/>
- <input type="hidden" name="disable_optimization" value=""/>
-
- <div class="btn-group">
- <button type="button" class="btn btn-primary o_upload_media_button">
- <t t-if="isDocument">Upload a document</t>
- <t t-else="">Upload an image</t>
- </button>
- <t t-if="!isDocument">
- <button class="btn btn-primary dropdown-toggle dropdown-toggle-split o_media_optimization" data-toggle="dropdown" type="button">
- <span class="sr-only">Alternate Upload</span>
- </button>
- <div class="dropdown-menu" role="menu">
- <button type="button" role="menuitem" class="dropdown-item o_upload_media_button_no_optimization">Upload image without optimization</button>
- </div>
- </t>
- </div>
-
- <div class="input-group align-items-center ml-2">
- <input type="text" class="form-control o_we_url_input" name="url" t-attf-placeholder="https://www.odoo.com/#{isDocument ? 'mydocument' : 'logo.png'}"/>
- <div class="input-group-append align-items-center">
- <button type="button" class="btn btn-secondary o_upload_media_url_button" disabled="disabled">
- <t t-if="isDocument">Add document</t>
- <t t-else="">Add image</t>
- </button>
- <div class="ml-2">
- <span class="o_we_url_success text-success d-none fa fa-lg fa-check" title="The URL seems valid"/>
- <span class="o_we_url_warning text-warning d-none fa fa-lg fa-warning" title="The URL does not contain any image. The file will be added in the document section."/>
- <span class="o_we_url_error text-danger d-none fa fa-lg fa-times" title="The URL does not seem to work"/>
- </div>
- </div>
- </div>
-
- <t t-call="web_editor.dialog.media.search">
- <t t-set="searchPlaceholder">
- <t t-if="isDocument">Search a document</t>
- <t t-else="">Search an image</t>
- </t>
- </t>
- </div>
- </t>
- <t t-name="web_editor.dialog.files.existing.content">
- <div class="existing-attachments">
- <div t-foreach="rows" t-as="row" class="row mt-2">
- <div t-foreach="row" t-as="attachment" class="col-2 o_existing_attachment_cell">
- <i t-if="attachment.res_model === 'ir.ui.view'" class="fa fa-trash o_existing_attachment_remove" title="This file is a public view attachment" role="img" aria-label="This file is a public view attachment" t-att-data-id="attachment.id"/>
- <i t-else="" class="fa fa-trash o_existing_attachment_remove" title="This file is attached to the current record" role="img" aria-label="This file is attached to the current record" t-att-data-id="attachment.id"/>
- <div class="o_attachment_border" t-att-style="attachment.res_model === 'ir.ui.view' ? null : 'border: 1px solid #5cb85c;'"><div t-att-data-src="attachment.src" t-att-data-url="attachment.url" role="img" t-att-aria-label="attachment.name" t-att-title="attachment.name" t-att-data-id="attachment.id" t-att-data-mimetype="attachment.mimetype" t-attf-class="o_image #{withEffect ? 'o_image_loading' : ''}"/></div>
- <t t-if="isDocument">
- <small class="o_file_name"><t t-esc="attachment.name"/></small>
- </t>
- </div>
- </div>
- </div>
- </t>
- <t t-name="web_editor.dialog.image.existing.error">
- <div class="form-text">
- <p>The image could not be deleted because it is used in the
- following pages or views:</p>
- <ul t-as="view" t-foreach="views">
- <li>
- <a t-attf-href="/web#model=ir.ui.view&amp;id=#{view.id}">
- <t t-esc="view.name"/>
- </a>
- </li>
- </ul>
- </div>
- </t>
-
- <!-- Icon choosing part of the Media Dialog -->
- <t t-name="web_editor.dialog.font-icons">
- <form action="#">
- <div class="form-inline align-items-center py-4">
- <t t-call="web_editor.dialog.media.search">
- <t t-set="searchPlaceholder">Search a pictogram</t>
- </t>
- </div>
- <div class="font-icons-icons">
- <t t-call="web_editor.dialog.font-icons.icons">
- <t t-set="iconsParser" t-value="widget.iconsParser"/>
- </t>
- </div>
- </form>
- </t>
- <t t-name="web_editor.dialog.font-icons.icons">
- <t t-as="data" t-foreach="iconsParser">
- <span t-foreach="data.cssData" t-as="cssData"
- t-att-data-id="cssData.names[0]"
- t-att-title="cssData.names[0]"
- t-att-aria-label="cssData.names[0]" role="img"
- t-attf-class="font-icons-icon #{data.base} #{cssData.names[0]}"
- t-att-data-alias="cssData.names.join(',')"/>
- </t>
- </t>
-
- <!-- Video choosing part of the Media Dialog -->
- <t t-name="web_editor.dialog.video">
- <form action="#" class="row">
- <div class="col mt-4 o_video_dialog_form">
- <div class="form-group mb-2" id="o_video_form_group">
- <label class="col-form-label" for="o_video_text">
- Video code <small>(URL or Embed)</small>
- <div class="o_validate_feedback">
- <i class="fa fa-check text-success" role="img" aria-label="Checked" title="Checked"/>
- <i class="fa fa-exclamation-triangle text-danger" role="img" aria-label="Attention" title="Attention"/>
- </div>
- </label>
- <textarea class="form-control" id="o_video_text" placeholder="Copy-paste your URL or embed code here"/>
- </div>
- <div class="text-right">
- <small class="text-muted">Accepts <b><i>Youtube</i></b>, <b><i>Instagram</i></b>, <b><i>Vine.co</i></b>, <b><i>Vimeo</i></b>, <b><i>Dailymotion</i></b> and <b><i>Youku</i></b> videos</small>
- </div>
- <div class="o_video_dialog_options d-none mt-4">
- <div class="o_yt_option o_vim_option o_dm_option">
- <label class="o_switch mb0"><input id="o_video_autoplay" type="checkbox"/><span/>Autoplay</label>
- </div>
- <div class="o_yt_option o_vim_option">
- <label class="o_switch mb0"><input id="o_video_loop" type="checkbox"/><span/>Loop</label>
- </div>
- <div class="o_yt_option o_dm_option">
- <label class="o_switch mb0"><input id="o_video_hide_controls" type="checkbox"/><span/>Hide player controls</label>
- </div>
- <div class="o_yt_option">
- <label class="o_switch mb0"><input id="o_video_hide_fullscreen" type="checkbox"/><span/>Hide fullscreen button</label>
- </div>
- <div class="o_yt_option">
- <label class="o_switch mb0"><input id="o_video_hide_yt_logo" type="checkbox"/><span/>Hide Youtube logo</label>
- </div>
- <div class="o_dm_option">
- <label class="o_switch mb0"><input id="o_video_hide_dm_logo" type="checkbox"/><span/>Hide Dailymotion logo</label>
- </div>
- <div class="o_dm_option">
- <label class="o_switch mb0"><input id="o_video_hide_dm_share" type="checkbox"/><span/>Hide sharing button</label>
- </div>
- </div>
- </div>
- <div class="col-md-6">
- <div id="video-preview" class="p-3">
- <div class="o_video_dialog_preview_text small mb-2 d-none">Preview</div>
- <div class="media_iframe_video">
- <div class="media_iframe_video_size"/>
- <iframe class="o_video_dialog_iframe" allowfullscreen="allowfullscreen" frameborder="0" src=""/>
- </div>
- </div>
- </div>
- </form>
- </t>
-
- <!-- Link Dialog (allows to choose a style and content for a link on the page) -->
- <div t-name="web_editor.dialog.link" class="o_link_dialog">
- <div class="row">
- <form class="col-lg-8">
- <div t-attf-class="form-group row#{widget.needLabel ? '' : ' d-none'}">
- <label class="col-form-label col-md-3" for="o_link_dialog_label_input">Link Label</label>
- <div class="col-md-9">
- <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 row o_url_input">
- <label class="col-form-label col-md-3" for="o_link_dialog_url_input">URL or Email</label>
- <div class="col-md-9">
- <input type="text" name="url" class="form-control" id="o_link_dialog_url_input" required="required"/>
- </div>
- </div>
- <div class="form-group row">
- <label class="col-form-label col-md-3">Size</label>
- <div class="col-md-9">
- <select name="link_style_size" class="form-control link-style">
- <option value="sm">Small</option>
- <option value="" selected="selected">Medium</option>
- <option value="lg">Large</option>
- </select>
- </div>
- </div>
- <div class="form-group row">
- <label class="col-form-label col-md-3">Style</label>
- <div class="col-md-9">
- <select name="link_style_shape" class="form-control link-style">
- <option value="" selected="selected">Default</option>
- <option value="outline">Outline</option>
- <option value="rounded-circle">Rounded</option>
- <option value="outline,rounded-circle">Outline-Rounded</option>
- <option value="flat">Flat</option>
- </select>
- </div>
- </div>
- <div class="form-group row">
- <label class="col-form-label col-md-3">Color</label>
- <div class="col-md-9">
- <div class="o_link_dialog_color">
- <label role="button" t-attf-class="o_link_dialog_color_item o_btn_preview btn btn-link text-center" data-color="">
- <span>L</span>
- <input class="d-none link-style" name="link_style_color" type="radio" value=""/>
- <i class="fa"/>
- </label>
- <t t-foreach="['alpha', 'beta', 'gamma', 'delta', 'epsilon', 'primary', 'secondary', 'success', 'info', 'warning', 'danger']" t-as="color">
- <label role="button" t-attf-class="o_link_dialog_color_item o_btn_preview btn btn-#{color}" t-attf-aria-label="Color for #{color}" t-attf-title="Color for #{color}">
- <input type="radio" name="link_style_color" class="d-none link-style" t-att-value="color"/>
- <i class="fa"/>
- </label>
- </t>
- </div>
- </div>
- </div>
- <div class="form-group row">
- <div class="offset-md-3 col-md-9">
- <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>
- <div class="col-lg-4 o_link_dialog_preview">
- <div class="form-group text-center">
- <label>Preview</label>
- <div style="overflow: auto; max-width: 100%; max-height: 200px;">
- <a href="#" id="link-preview" aria-label="Preview" title="Preview"/>
- </div>
- </div>
- </div>
- </div>
- </div>
-
- <!-- Crop Image Dialog (allows to crop image on the page) -->
- <div t-name="web_editor.dialog.crop_image" class="o_crop_image_dialog">
- <div t-if="widget.imageData.isExternalImage" class="alert alert-warning text-center" role="alert">
- <i class="fa fa-exclamation-triangle fa-2x"/>
- <h4>This image is an external image</h4>
- <p>
- This type of image is not supported for cropping.<br/>
- If you want to crop it, please first download it from the original source and upload it in Odoo.
- </p>
- </div>
- <t t-else="">
- <div class="o_crop_area">
- <img class="img img-fluid o_cropper_image" t-att-src="widget.imageData.originalSrc"/>
- </div>
- <div class="o_crop_options text-center mt16">
- <div class="btn-group btn-group-toggle" title="Aspect Ratio" data-toggle="buttons">
- <t t-foreach="widget.aspectRatioList" t-as="ratio">
- <t t-set="is_active" t-value="ratio[1] === widget.imageData.aspectRatio"/>
- <label t-attf-class="btn btn-secondary#{is_active and ' active' or ''}" data-event="ratio" t-att-data-label="ratio[1]" t-att-data-value="ratio[2]">
- <input type="radio" /><t t-esc="ratio[0]"/>
- </label>
- </t>
- </div>
- <div class="btn-group" role="group">
- <button type="button" class="btn btn-secondary" title="Zoom In" data-event="zoom" data-value="0.1"><i class="fa fa-search-plus"/></button>
- <button type="button" class="btn btn-secondary" title="Zoom Out" data-event="zoom" data-value="-0.1"><i class="fa fa-search-minus"/></button>
- </div>
- <div class="btn-group" role="group">
- <button type="button" class="btn btn-secondary" title="Rotate Left" data-event="rotate" data-value="-45"><i class="fa fa-rotate-left"/></button>
- <button type="button" class="btn btn-secondary" title="Rotate Right" data-event="rotate" data-value="45"><i class="fa fa-rotate-right"/></button>
- </div>
- <div class="btn-group" role="group">
- <button type="button" class="btn btn-secondary" title="Flip Horizontal" data-event="flip" data-value="horizontal" data-x="1"><i class="fa fa-arrows-h"/></button>
- <button type="button" class="btn btn-secondary" title="Flip Vertical" data-event="flip" data-value="vertical" data-y="1"><i class="fa fa-arrows-v"/></button>
- </div>
- <div class="btn-group" role="group">
- <button type="button" class="btn btn-secondary" title="Reset Image" data-event="reset"><i class="fa fa-refresh"/> Reset Image</button>
- </div>
- </div>
- </t>
- </div>
-
- <!--=================-->
<!-- Snippet options -->
<!--=================-->
diff --git a/addons/web_editor/static/src/xml/snippets.xml b/addons/web_editor/static/src/xml/snippets.xml
index 7b85fb3998c..6e2ae656f2d 100644
--- a/addons/web_editor/static/src/xml/snippets.xml
+++ b/addons/web_editor/static/src/xml/snippets.xml
@@ -40,9 +40,9 @@
<t t-name="web_editor.many2one.button">
<div class="btn-group">
<a role="button" href="#" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" title="Search Contact" aria-label="Search Contact"><i class="fa fa-search"></i></a>
- <div class="dropdown-menu contact_menu" role="menu">
- <a role="menuitem" class="dropdown-item"><input href="#" type="email" placeholder="Search"/></a>
- </div>
+ <ul class="dropdown-menu contact_menu" role="menu">
+ <li><a role="menuitem" class="dropdown-item"><input href="#" type="email" placeholder="Search"/></a></li>
+ </ul>
</div>
</t>
diff --git a/addons/web_editor/static/src/xml/translator.xml b/addons/web_editor/static/src/xml/translator.xml
deleted file mode 100644
index dbd6c8287f6..00000000000
--- a/addons/web_editor/static/src/xml/translator.xml
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<templates id="template" xml:space="preserve">
-<div t-name="web_editor.TranslatorInfoDialog">
- <p>You are about to enter the translation mode.</p>
- <p>Here are the visuals used to help you translate efficiently:</p>
- <ul class="oe_translate_examples">
- <li data-oe-translation-state="to_translate">Content to translate</li>
- <li data-oe-translation-state="translated">Translated content</li>
- </ul>
- <p>
- In this mode, you can only translate texts. To change the structure of the page, you must edit the master page.
- Each modification on the master page is automatically applied to all translated versions.
- </p>
-</div>
-</templates>
diff --git a/addons/web_editor/static/src/xml/wysiwyg.xml b/addons/web_editor/static/src/xml/wysiwyg.xml
new file mode 100644
index 00000000000..2330629a93b
--- /dev/null
+++ b/addons/web_editor/static/src/xml/wysiwyg.xml
@@ -0,0 +1,375 @@
+<?xml version="1.0" encoding="utf-8"?>
+<templates id="template" xml:space="preserve">
+
+ <!--=================-->
+ <!-- Edition Dialogs -->
+ <!--=================-->
+
+ <!-- Alt Dialog (allows to change alt and title of page images) -->
+ <form t-name="wysiwyg.widgets.alt" action="#">
+ <div class="form-group row">
+ <label class="col-md-3 col-form-label" for="alt"
+ title="'Alt tag' specifies an alternate text for an image, if the image cannot be displayed (slow connection, missing image, screen reader ...).">
+ Description <small>(ALT Tag)</small>
+ </label>
+ <div class="col-md-8">
+ <input class="form-control" id="alt" required="required" t-att-value="widget.alt" type="text"/>
+ </div>
+ </div>
+ <div class="form-group row">
+ <label class="col-md-3 col-form-label" for="title"
+ title="'Title tag' is shown as a tooltip when you hover the picture.">
+ Tooltip <small>(TITLE Tag)</small>
+ </label>
+ <div class="col-md-8">
+ <input class="form-control" id="title" required="required" t-att-value="widget.tag_title" type="text"/>
+ </div>
+ </div>
+ </form>
+
+ <!-- Media Dialog (allows to choose an img/pictogram/video) -->
+ <div t-name="wysiwyg.widgets.media">
+ <ul class="nav nav-tabs" role="tablist">
+ <li class="nav-item"><a role="tab" href="#editor-media-image" aria-controls="editor-media-image" data-toggle="tab" t-attf-class="nav-link#{widget.noImages ? ' d-none' : ''}">Image</a></li>
+ <li class="nav-item"><a role="tab" href="#editor-media-document" aria-controls="editor-media-document" data-toggle="tab" t-attf-class="nav-link#{widget.noDocuments ? ' d-none' : ''}">Document</a></li>
+ <li class="nav-item"><a role="tab" href="#editor-media-icon" aria-controls="editor-media-icon" data-toggle="tab" t-attf-class="nav-link#{widget.noIcons ? ' d-none' : ''}">Pictogram</a></li>
+ <li class="nav-item"><a role="tab" href="#editor-media-video" aria-controls="editor-media-video" data-toggle="tab" t-attf-class="nav-link#{widget.noVideos ? ' d-none' : ''}">Video</a></li>
+ </ul>
+ <!-- Tab panes -->
+ <div class="tab-content">
+ <div role="tabpanel" class="tab-pane fade" id="editor-media-image"/>
+ <div role="tabpanel" class="tab-pane fade" id="editor-media-document"/>
+ <div role="tabpanel" class="tab-pane fade" id="editor-media-icon"/>
+ <div role="tabpanel" class="tab-pane fade" id="editor-media-video"/>
+ </div>
+ </div>
+
+ <t t-name="wysiwyg.widgets.media.search">
+ <div class="input-group ml-auto">
+ <input type="text" class="form-control o_we_search" t-att-placeholder="searchPlaceholder.trim()"/>
+ <div class="input-group-append">
+ <div class="input-group-text o_we_search_icon">
+ <i class="fa fa-search" title="Search" role="img" aria-label="Search"/>
+ </div>
+ </div>
+ </div>
+ </t>
+
+ <!-- Image choosing part of the Media Dialog -->
+ <t t-name="wysiwyg.widgets.image">
+ <t t-set="iframeName" t-value="_.uniqueId('fileframe-')"/>
+ <form method="POST"
+ action="/web_editor/attachment/add"
+ enctype="multipart/form-data"
+ t-att-target="iframeName">
+ <input type="hidden" name="csrf_token" t-att-value="csrf_token"/>
+ <input type="hidden" name="filters" t-att-value="widget.firstFilters.join('_')"/>
+ <input t-if="widget.options.res_id" type="hidden" name="res_id" t-att-value="widget.options.res_id"/>
+ <input t-if="widget.options.res_model" type="hidden" name="res_model" t-att-value="widget.options.res_model"/>
+ <t t-call="wysiwyg.widgets.files.submenu">
+ <t t-set="isDocument" t-value="widget.options.document"/>
+ <t t-set="accept" t-value="widget.accept"/>
+ </t>
+ <div class="form-text"/>
+ <div class="existing-attachments"/>
+ <div class="mt-4 text-center mx-auto">
+ <button class="btn btn-primary o_load_more" type="button">Load more...</button>
+ <div class="mt-4 o_load_done_msg d-none">
+ <span><i>All attachments have been loaded</i></span>
+ </div>
+ </div>
+ <iframe class="o_file_upload_iframe d-none" t-att-name="iframeName"/>
+ </form>
+ </t>
+
+ <t t-name="wysiwyg.widgets.files.submenu">
+ <div class="form-inline align-items-center py-4">
+ <input type="file" class="d-none o_file_input" name="upload" t-att-accept="accept" multiple="multiple"/>
+ <input type="hidden" name="disable_optimization" value=""/>
+
+ <div class="btn-group">
+ <button type="button" class="btn btn-primary o_upload_media_button">
+ <t t-if="isDocument">Upload a document</t>
+ <t t-else="">Upload an image</t>
+ </button>
+ <t t-if="!isDocument">
+ <button class="btn btn-primary dropdown-toggle dropdown-toggle-split o_media_optimization" data-toggle="dropdown" type="button">
+ <span class="sr-only">Alternate Upload</span>
+ </button>
+ <div class="dropdown-menu" role="menu">
+ <button type="button" role="menuitem" class="dropdown-item o_upload_media_button_no_optimization">Upload image without optimization</button>
+ </div>
+ </t>
+ </div>
+
+ <div class="input-group align-items-center ml-2">
+ <input type="text" class="form-control o_we_url_input" name="url" t-attf-placeholder="https://www.odoo.com/#{isDocument ? 'mydocument' : 'logo.png'}"/>
+ <div class="input-group-append align-items-center">
+ <button type="button" class="btn btn-secondary o_upload_media_url_button" disabled="disabled">
+ <t t-if="isDocument">Add document</t>
+ <t t-else="">Add image</t>
+ </button>
+ <div class="ml-2">
+ <span class="o_we_url_success text-success d-none fa fa-lg fa-check" title="The URL seems valid"/>
+ <span class="o_we_url_warning text-warning d-none fa fa-lg fa-warning" title="The URL does not contain any image. The file will be added in the document section."/>
+ <span class="o_we_url_error text-danger d-none fa fa-lg fa-times" title="The URL does not seem to work"/>
+ </div>
+ </div>
+ </div>
+
+ <t t-call="wysiwyg.widgets.media.search">
+ <t t-set="searchPlaceholder">
+ <t t-if="isDocument">Search a document</t>
+ <t t-else="">Search an image</t>
+ </t>
+ </t>
+ </div>
+ </t>
+
+ <t t-name="wysiwyg.widgets.image.existing">
+ <div role="dialog" class="modal" tabindex="-1">
+ <div class="modal-dialog select-image">
+ <div class="modal-content">
+ <header class="modal-header">
+ <h3 class="modal-title">Select a Picture</h3>
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
+ </header>
+ <main class="modal-body o_has_error">
+ <div class="existing-attachments"/>
+ <div class="form-text"/>
+ </main>
+ <footer class="modal-footer">
+ <button data-dismiss="modal" type="button" aria-label="Discard">Discard</button>
+ </footer>
+ </div>
+ </div>
+ </div>
+ </t>
+ <t t-name="wysiwyg.widgets.files.existing.content">
+ <div class="existing-attachments">
+ <div class="row mt16 ml-auto" t-as="row" t-foreach="rows">
+ <div class="col-2 o_existing_attachment_cell" t-as="attachment" t-foreach="row">
+ <i t-if="attachment.res_model === 'ir.ui.view'" class="fa fa-trash o_existing_attachment_remove" title="This file is a public view attachment" role="img" aria-label="This file is a public view attachment" t-att-data-id="attachment.id"/>
+ <i t-else="" class="fa fa-trash o_existing_attachment_remove" title="This file is attached to the current record" role="img" aria-label="This file is attached to the current record" t-att-data-id="attachment.id"/>
+ <div class="o_attachment_border" t-att-style="attachment.res_model === 'ir.ui.view' ? null : 'border: 1px solid #5cb85c;'"><div t-att-data-src="attachment.src" t-att-data-url="attachment.url" role="img" t-att-aria-label="attachment.name" t-att-title="attachment.name" t-att-data-id="attachment.id" t-att-data-mimetype="attachment.mimetype" t-attf-class="o_image {{withEffect ? 'o_image_loading' : ''}}"/></div>
+ <t t-if="isDocument">
+ <small class="o_file_name"><t t-esc="attachment.name"/></small>
+ </t>
+ </div>
+ </div>
+ </div>
+ </t>
+ <t t-name="wysiwyg.widgets.image.existing.error">
+ <div class="form-text">
+ <p>The image could not be deleted because it is used in the
+ following pages or views:</p>
+ <ul t-as="view" t-foreach="views">
+ <li>
+ <a t-attf-href="/web#model=ir.ui.view&amp;id=#{view.id}">
+ <t t-esc="view.name"/>
+ </a>
+ </li>
+ </ul>
+ </div>
+ </t>
+
+ <!-- Icon choosing part of the Media Dialog -->
+ <t t-name="wysiwyg.widgets.font-icons">
+ <form action="#">
+ <div class="form-inline align-items-center py-4">
+ <t t-call="wysiwyg.widgets.media.search">
+ <t t-set="searchPlaceholder">Search a pictogram</t>
+ </t>
+ </div>
+ <div class="font-icons-icons">
+ <t t-call="wysiwyg.widgets.font-icons.icons">
+ <t t-set="iconsParser" t-value="widget.iconsParser"/>
+ </t>
+ </div>
+ </form>
+ </t>
+ <t t-name="wysiwyg.widgets.font-icons.icons">
+ <t t-as="data" t-foreach="iconsParser">
+ <span t-foreach="data.cssData" t-as="cssData"
+ t-att-data-id="cssData.names[0]"
+ t-att-title="cssData.names[0]"
+ t-att-aria-label="cssData.names[0]" role="img"
+ t-attf-class="font-icons-icon #{data.base} #{cssData.names[0]}"
+ t-att-data-alias="cssData.names.join(',')"/>
+ </t>
+ </t>
+
+ <!-- Video choosing part of the Media Dialog -->
+ <t t-name="wysiwyg.widgets.video">
+ <form action="#" class="row">
+ <div class="col mt-4 o_video_dialog_form">
+ <div class="form-group mb-2" id="o_video_form_group">
+ <label class="col-form-label" for="o_video_text">
+ Video code <small>(URL or Embed)</small>
+ <div class="o_validate_feedback">
+ <i class="fa fa-check text-success" role="img" aria-label="Checked" title="Checked"/>
+ <i class="fa fa-exclamation-triangle text-danger" role="img" aria-label="Attention" title="Attention"/>
+ </div>
+ </label>
+ <textarea class="form-control" id="o_video_text" placeholder="Copy-paste your URL or embed code here"/>
+ </div>
+ <div class="text-right">
+ <small class="text-muted">Accepts <b><i>Youtube</i></b>, <b><i>Instagram</i></b>, <b><i>Vine.co</i></b>, <b><i>Vimeo</i></b>, <b><i>Dailymotion</i></b> and <b><i>Youku</i></b> videos</small>
+ </div>
+ <div class="o_video_dialog_options d-none mt-4">
+ <div class="o_yt_option o_vim_option o_dm_option">
+ <label class="o_switch mb0"><input id="o_video_autoplay" type="checkbox"/><span/>Autoplay</label>
+ </div>
+ <div class="o_yt_option o_vim_option">
+ <label class="o_switch mb0"><input id="o_video_loop" type="checkbox"/><span/>Loop</label>
+ </div>
+ <div class="o_yt_option o_dm_option">
+ <label class="o_switch mb0"><input id="o_video_hide_controls" type="checkbox"/><span/>Hide player controls</label>
+ </div>
+ <div class="o_yt_option">
+ <label class="o_switch mb0"><input id="o_video_hide_fullscreen" type="checkbox"/><span/>Hide fullscreen button</label>
+ </div>
+ <div class="o_yt_option">
+ <label class="o_switch mb0"><input id="o_video_hide_yt_logo" type="checkbox"/><span/>Hide Youtube logo</label>
+ </div>
+ <div class="o_dm_option">
+ <label class="o_switch mb0"><input id="o_video_hide_dm_logo" type="checkbox"/><span/>Hide Dailymotion logo</label>
+ </div>
+ <div class="o_dm_option">
+ <label class="o_switch mb0"><input id="o_video_hide_dm_share" type="checkbox"/><span/>Hide sharing button</label>
+ </div>
+ </div>
+ </div>
+ <div class="col-md-6">
+ <div id="video-preview" class="p-3">
+ <div class="o_video_dialog_preview_text small mb-2 d-none">Preview</div>
+ <div class="media_iframe_video">
+ <div class="media_iframe_video_size"/>
+ <iframe class="o_video_dialog_iframe" allowfullscreen="allowfullscreen" frameborder="0" src=""/>
+ </div>
+ </div>
+ </div>
+ </form>
+ </t>
+
+
+ <!-- Link Dialog (allows to choose a style and content for a link on the page) -->
+ <div t-name="wysiwyg.widgets.link" class="o_link_dialog">
+ <div class="row">
+ <form class="col-lg-8">
+ <div t-attf-class="form-group row#{widget.needLabel ? '' : ' d-none'}">
+ <label class="col-form-label col-md-3" for="o_link_dialog_label_input">Link Label</label>
+ <div class="col-md-9">
+ <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 row">
+ <label class="col-form-label col-md-3" for="o_link_dialog_url_input">URL or Email</label>
+ <div class="col-md-9">
+ <input type="text" name="url" class="form-control" id="o_link_dialog_url_input" required="required"/>
+ </div>
+ </div>
+ <div class="form-group row">
+ <label class="col-form-label col-md-3">Size</label>
+ <div class="col-md-9">
+ <select name="link_style_size" class="form-control link-style">
+ <option value="sm">Small</option>
+ <option value="" selected="selected">Medium</option>
+ <option value="lg">Large</option>
+ </select>
+ </div>
+ </div>
+ <div class="form-group row">
+ <label class="col-form-label col-md-3">Style</label>
+ <div class="col-md-9">
+ <select name="link_style_shape" class="form-control link-shape">
+ <option value="" selected="selected">Default</option>
+ <option value="outline">Outline</option>
+ <option value="rounded-circle">Rounded</option>
+ <option value="outline,rounded-circle">Outline-Rounded</option>
+ <option value="flat">Flat</option>
+ </select>
+ </div>
+ </div>
+ <div class="form-group row">
+ <label class="col-form-label col-md-3">Color</label>
+ <div class="col-md-9">
+ <div class="o_link_dialog_color">
+ <label role="button" t-attf-class="o_link_dialog_color_item o_btn_preview btn btn-link text-center" data-color="">
+ <span>L</span>
+ <input class="d-none link-style" name="link_style_color" type="radio" value=""/>
+ <i class="fa"/>
+ </label>
+ <t t-foreach="['alpha', 'beta', 'gamma', 'delta', 'epsilon', 'primary', 'secondary', 'success', 'info', 'warning', 'danger']" t-as="color">
+ <label role="button" t-attf-class="o_link_dialog_color_item o_btn_preview btn btn-#{color}" t-attf-aria-label="Color for #{color}" t-attf-title="Color for #{color}">
+ <input type="radio" name="link_style_color" class="d-none link-style" t-att-value="color"/>
+ <i class="fa"/>
+ </label>
+ </t>
+ </div>
+ </div>
+ </div>
+ <div class="form-group row">
+ <div class="offset-md-3 col-md-9">
+ <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>
+ <div class="col-lg-4 o_link_dialog_preview">
+ <div class="form-group text-center">
+ <label>Preview</label>
+ <div style="overflow-x: auto; max-width: 100%; max-height: 200px;">
+ <a href="#" id="link-preview" aria-label="Preview" title="Preview"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <!-- Crop Image Dialog (allows to crop image on the page) -->
+ <div t-name="wysiwyg.widgets.crop_image" class="o_crop_image_dialog">
+ <div t-if="widget.imageData.isExternalImage" class="alert alert-warning text-center" role="alert">
+ <i class="fa fa-exclamation-triangle fa-2x"/>
+ <h4>This image is an external image</h4>
+ <p>
+ This type of image is not supported for cropping.<br/>
+ If you want to crop it, please first download it from the original source and upload it in Odoo.
+ </p>
+ </div>
+ <t t-else="">
+ <div class="o_crop_area">
+ <img class="img img-fluid o_cropper_image" t-att-src="widget.imageData.originalSrc"/>
+ </div>
+ <div class="o_crop_options text-center mt16">
+ <div class="btn-group btn-group-toggle" title="Aspect Ratio" data-toggle="buttons">
+ <t t-foreach="widget.aspectRatioList" t-as="ratio">
+ <t t-set="is_active" t-value="ratio[1] === widget.imageData.aspectRatio"/>
+ <label t-attf-class="btn btn-secondary#{is_active and ' active' or ''}" data-event="ratio" t-att-data-label="ratio[1]" t-att-data-value="ratio[2]">
+ <input type="radio" /><t t-esc="ratio[0]"/>
+ </label>
+ </t>
+ </div>
+ <div class="btn-group" role="group">
+ <button type="button" class="btn btn-secondary" title="Zoom In" data-event="zoom" data-value="0.1"><i class="fa fa-search-plus"/></button>
+ <button type="button" class="btn btn-secondary" title="Zoom Out" data-event="zoom" data-value="-0.1"><i class="fa fa-search-minus"/></button>
+ </div>
+ <div class="btn-group" role="group">
+ <button type="button" class="btn btn-secondary" title="Rotate Left" data-event="rotate" data-value="-45"><i class="fa fa-rotate-left"/></button>
+ <button type="button" class="btn btn-secondary" title="Rotate Right" data-event="rotate" data-value="45"><i class="fa fa-rotate-right"/></button>
+ </div>
+ <div class="btn-group" role="group">
+ <button type="button" class="btn btn-secondary" title="Flip Horizontal" data-event="flip" data-value="horizontal" data-x="1"><i class="fa fa-arrows-h"/></button>
+ <button type="button" class="btn btn-secondary" title="Flip Vertical" data-event="flip" data-value="vertical" data-y="1"><i class="fa fa-arrows-v"/></button>
+ </div>
+ <div class="btn-group" role="group">
+ <button type="button" class="btn btn-secondary" title="Reset Image" data-event="reset"><i class="fa fa-refresh"/> Reset Image</button>
+ </div>
+ </div>
+ </t>
+ </div>
+
+</templates>
diff --git a/addons/web_editor/static/src/xml/wysiwyg_colorpicker.xml b/addons/web_editor/static/src/xml/wysiwyg_colorpicker.xml
new file mode 100644
index 00000000000..882a0edea11
--- /dev/null
+++ b/addons/web_editor/static/src/xml/wysiwyg_colorpicker.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<templates>
+ <div t-name="wysiwyg.plugin.font.paletteButton" t-attf-class="note-btn-group btn-group {{className}}">
+ <button type="button" class="note-btn btn btn-light btn-sm dropdown-toggle" tabindex="-1" data-toggle="dropdown"><i
+ t-att-class="icon"></i></button>
+ <div class="dropdown-menu" />
+ </div>
+
+ <div t-name="wysiwyg.plugin.font.colorPalette" class="note-palette">
+ <button type="button" class="note-color-reset btn btn-light note-color-btn bg-undefined">
+ <t t-esc="lang.color.resetToDefault" /></button>
+ <div class="note-holder">
+ <div class="note-color-palette">
+ <h6 class="mt-2">Theme colors</h6>
+ <div class="o_theme_color_placeholder" />
+ <h6 class="mt-2">Transparent colors</h6>
+ <div class="o_transparent_color_placeholder" />
+ <h6 class="mt-2">Common colors</h6>
+ <div class="o_common_color_placeholder">
+ <div class="note-color-row" t-foreach="colors" t-as="rowColors">
+ <button t-foreach="rowColors" t-as="color" type="button" class="note-color-btn" data-toggle="button"
+ tabindex="-1" t-attf-style="background-color:{{color}}" t-att-data-value="color"
+ t-att-title="color" />
+ </div>
+ </div>
+ </div>
+ <h6 class="note-custom-color mt8">
+ <t t-esc="lang.color.customColor" />
+ </h6>
+ <button class="note-custom-color-btn note-color-btn" style="display: none;"></button>
+ </div>
+ </div>
+
+ <div t-name="wysiwyg.widgets.ColorpickerDialog" class="o_colorpicker_widget">
+ <div class="row">
+ <div class="col-auto">
+ <div class="o_color_pick_area d-inline-block border">
+ <div class="o_picker_pointer rounded-circle" />
+ </div>
+ <div class="o_color_slider d-inline-block ml-2 border">
+ <div class="o_slider_pointer" />
+ </div>
+ <div class="o_opacity_slider d-inline-block ml-2 border">
+ <div class="o_opacity_pointer" />
+ </div>
+ </div>
+ <form class="col o_color_picker_inputs">
+ <div class="input-group">
+ <div class="input-group-prepend">
+ <span class="input-group-text rounded-0 o_color_preview" />
+ </div>
+ <input type="text" class="form-control o_hex_input" data-color-method="hex" />
+ </div>
+ <div class="form-row mt-2">
+ <div class="col">
+ <div class="form-group">
+ <label for="red">Red</label>
+ <input type="text" class="form-control o_red_input" data-color-method="rgb" id="red" />
+ </div>
+ <div class="form-group">
+ <label for="green">Green</label>
+ <input type="text" class="form-control o_green_input" data-color-method="rgb" id="green" />
+ </div>
+ <div class="form-group">
+ <label for="blue">Blue</label>
+ <input type="text" class="form-control o_blue_input" data-color-method="rgb" id="blue" />
+ </div>
+ </div>
+ <div class="col">
+ <div class="form-group">
+ <label for="hue">Hue</label>
+ <input type="text" class="form-control o_hue_input" data-color-method="hsl" id="hue" />
+ </div>
+ <div class="form-group">
+ <label for="saturation">Saturation %</label>
+ <input type="text" class="form-control o_saturation_input" data-color-method="hsl" id="saturation" />
+ </div>
+ <div class="form-group">
+ <label for="lightness">Lightness %</label>
+ <input type="text" class="form-control o_lightness_input" data-color-method="hsl" id="lightness" />
+ </div>
+ </div>
+ </div>
+ <div class="form-group">
+ <label for="opacity">Opacity %</label>
+ <input type="text" class="form-control o_opacity_input" data-color-method="opacity" id="opacity" />
+ </div>
+ </form>
+ </div>
+ </div>
+</templates>