diff --git a/web_editor_background_color/README.rst b/web_editor_background_color/README.rst new file mode 100644 index 00000000..24a2f466 --- /dev/null +++ b/web_editor_background_color/README.rst @@ -0,0 +1,69 @@ +.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 + +================================== +Web Editor Background Color Picker +================================== + +This module extends the functionality of the web editor to support +setting a custom background color to any snippet allowing you to customize it. + +.. figure:: /web_editor_background_color/static/description/mass_mailing_editor.png + :alt: Screenshot of color picker in mass mailing editor + +Usage +===== + +To use this module, you need to: + +#. Install any module that makes use of the web editor, such as + ``mass_mailing`` or ``website``. +#. Use that module's facilities to edit some web content. +#. Drag & drop any snippet into the web editor body. +#. Click on *Customize > Text-Image > Background Color > icon*. +#. Choose a custom color by either: + * Writing any valid HTML color code in the text input. + * Selecting a color from the color picker. + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/162/10.0 + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smash it by providing detailed and welcomed feedback. + +Credits +======= + +External libraries +------------------ + +* This addon includes code copied from bootstrap-colorpicker_ + +.. _bootstrap-colorpicker: https://github.com/itsjavi/bootstrap-colorpicker/tree/2.5.1 + +Contributors +------------ + +* Jairo Llopis + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/web_editor_background_color/__init__.py b/web_editor_background_color/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/web_editor_background_color/__manifest__.py b/web_editor_background_color/__manifest__.py new file mode 100644 index 00000000..29fda211 --- /dev/null +++ b/web_editor_background_color/__manifest__.py @@ -0,0 +1,22 @@ +# Copyright 2017 Jairo Llopis +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). +{ + "name": "Web Editor Background Color Picker", + "summary": "Set any background color for web editor snippets", + "version": "11.0.1.0.0", + "category": "Website", + "website": "https://www.tecnativa.com", + "author": "Tecnativa, Odoo Community Association (OCA)", + "license": "LGPL-3", + "application": False, + "installable": True, + "images": [ + "static/description/mass_mailing_editor.png", + ], + "depends": [ + "web_editor", + ], + "data": [ + "templates/assets.xml", + ], +} diff --git a/web_editor_background_color/i18n/ca.po b/web_editor_background_color/i18n/ca.po new file mode 100644 index 00000000..5e97c583 --- /dev/null +++ b/web_editor_background_color/i18n/ca.po @@ -0,0 +1,22 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_editor_background_color +# +# Translators: +# Marc Tormo i Bochaca , 2017 +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2017-03-30 08:28+0000\n" +"PO-Revision-Date: 2017-03-30 08:28+0000\n" +"Last-Translator: Marc Tormo i Bochaca , 2017\n" +"Language-Team: Catalan (https://www.transifex.com/oca/teams/23907/ca/)\n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#~ msgid "Color" +#~ msgstr "Color" diff --git a/web_editor_background_color/i18n/es.po b/web_editor_background_color/i18n/es.po new file mode 100644 index 00000000..bab232fc --- /dev/null +++ b/web_editor_background_color/i18n/es.po @@ -0,0 +1,21 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * website_mail_snippet_bg_color +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 8.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-02-09 16:32+0000\n" +"PO-Revision-Date: 2016-02-09 17:33+0100\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: \n" +"X-Generator: Poedit 1.8.6\n" + +#~ msgid "Pick Background Color" +#~ msgstr "Escoger el color de fondo" diff --git a/web_editor_background_color/i18n/fr.po b/web_editor_background_color/i18n/fr.po new file mode 100644 index 00000000..0a3d95a3 --- /dev/null +++ b/web_editor_background_color/i18n/fr.po @@ -0,0 +1,23 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * website_mail_snippet_bg_color +# +# Translators: +# Christophe CHAUVET , 2016 +msgid "" +msgstr "" +"Project-Id-Version: social (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-06-30 01:07+0000\n" +"PO-Revision-Date: 2016-06-17 14:52+0000\n" +"Last-Translator: Christophe CHAUVET \n" +"Language-Team: French (http://www.transifex.com/oca/OCA-social-8-0/language/" +"fr/)\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=(n > 1);\n" + +#~ msgid "Pick Background Color" +#~ msgstr "Mettre la couleur de fond" diff --git a/web_editor_background_color/i18n/sl.po b/web_editor_background_color/i18n/sl.po new file mode 100644 index 00000000..a06a2d19 --- /dev/null +++ b/web_editor_background_color/i18n/sl.po @@ -0,0 +1,24 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * website_mail_snippet_bg_color +# +# Translators: +# Matjaž Mozetič , 2016 +msgid "" +msgstr "" +"Project-Id-Version: social (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-02-27 01:40+0000\n" +"PO-Revision-Date: 2016-02-27 16:56+0000\n" +"Last-Translator: Matjaž Mozetič \n" +"Language-Team: Slovenian (http://www.transifex.com/oca/OCA-social-8-0/" +"language/sl/)\n" +"Language: sl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n" +"%100==4 ? 2 : 3);\n" + +#~ msgid "Pick Background Color" +#~ msgstr "Izbira barve ozadja" diff --git a/web_editor_background_color/i18n/web_editor_background_color.pot b/web_editor_background_color/i18n/web_editor_background_color.pot new file mode 100644 index 00000000..b662aad9 --- /dev/null +++ b/web_editor_background_color/i18n/web_editor_background_color.pot @@ -0,0 +1,14 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + diff --git a/web_editor_background_color/readme/CONTRIBUTORS.rst b/web_editor_background_color/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..bf93c78d --- /dev/null +++ b/web_editor_background_color/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Jairo Llopis - https://www.tecnativa.com diff --git a/web_editor_background_color/readme/CREDITS.rst b/web_editor_background_color/readme/CREDITS.rst new file mode 100644 index 00000000..7c81b130 --- /dev/null +++ b/web_editor_background_color/readme/CREDITS.rst @@ -0,0 +1,3 @@ +* This addon includes code copied from bootstrap-colorpicker_ + +.. _bootstrap-colorpicker: https://github.com/itsjavi/bootstrap-colorpicker/tree/2.5.3 diff --git a/web_editor_background_color/readme/DESCRIPTION.rst b/web_editor_background_color/readme/DESCRIPTION.rst new file mode 100644 index 00000000..76576d15 --- /dev/null +++ b/web_editor_background_color/readme/DESCRIPTION.rst @@ -0,0 +1,5 @@ +This module extends the functionality of the web editor to support +setting a custom background color to any snippet allowing you to customize it. + +.. figure:: https://user-images.githubusercontent.com/973709/46802401-1c915180-cd55-11e8-9397-f198548a690c.gif + :alt: Screenshot of color picker in mass mailing editor diff --git a/web_editor_background_color/readme/USAGE.rst b/web_editor_background_color/readme/USAGE.rst new file mode 100644 index 00000000..6046c99f --- /dev/null +++ b/web_editor_background_color/readme/USAGE.rst @@ -0,0 +1,10 @@ +To use this module, you need to: + +#. Install any module that makes use of the web editor, such as + ``mass_mailing`` or ``website``. +#. Use that module's facilities to edit some web content. +#. Drag & drop any snippet into the web editor body. +#. Click on *Customize > Text-Image > Background Color > icon*. +#. Choose a custom color by either: + * Writing any valid HTML color code in the text input. + * Selecting a color from the color picker. diff --git a/web_editor_background_color/static/description/icon.png b/web_editor_background_color/static/description/icon.png new file mode 100644 index 00000000..794e8ef5 Binary files /dev/null and b/web_editor_background_color/static/description/icon.png differ diff --git a/web_editor_background_color/static/src/css/background_color.less b/web_editor_background_color/static/src/css/background_color.less new file mode 100644 index 00000000..52680a2d --- /dev/null +++ b/web_editor_background_color/static/src/css/background_color.less @@ -0,0 +1,21 @@ +/* Copyright 2017 Jairo Llopis + * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ + +.colorpicker-element { + @colorpicker-width: 170px; + @colorpicker-height: 118px; + + .colorpicker-inline { + min-width: initial; + display: block; + margin-top: 3px !important; + } + .colorpicker-saturation { + width: @colorpicker-height; + height: @colorpicker-height; + } + .colorpicker-hue, .colorpicker-alpha { + width: (@colorpicker-width - @colorpicker-height) / 2; + height: @colorpicker-height; + } +} diff --git a/web_editor_background_color/static/src/js/background_color.js b/web_editor_background_color/static/src/js/background_color.js new file mode 100644 index 00000000..8b33cc64 --- /dev/null +++ b/web_editor_background_color/static/src/js/background_color.js @@ -0,0 +1,103 @@ +/* Copyright 2016-2017 Jairo Llopis + * License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */ + +odoo.define("web_editor_background_color.colorpicker", function (require) { + "use strict"; + var options = require("web_editor.snippets.options"); + var colorpicker = options.registry.colorpicker; + + colorpicker.include({ + events: _.extend({}, colorpicker.prototype.events, { + "changeColor [data-name=custom_color]": + "set_inline_background_color", + // Remove inline background-color for normal class-based buttons + "click .o_colorpicker_section button[data-color]": + "remove_inline_background_color", + "click [data-name=custom_color] input": "input_select", + "click [data-name=custom_color]": "custom_abort_event", + "keydown [data-name=custom_color]": "custom_abort_event", + "keypress [data-name=custom_color]": "custom_abort_event", + "keyup [data-name=custom_color]": "custom_abort_event", + }), + xmlDependencies: colorpicker.prototype.xmlDependencies.concat([ + "/web_editor_background_color/static/src/xml/colorpicker.xml", + ]), + + /** + * @override + */ + start: function () { + this._super(); + // Enable custom color picker + this.$custom = this.$el.find('[data-name="custom_color"]'); + this.$custom.colorpicker({ + color: this.$target.css("background-color"), + container: true, + inline: true, + sliders: { + saturation: { + maxLeft: 118, + maxTop: 118, + }, + hue: { + maxTop: 118, + }, + alpha: { + maxTop: 118, + }, + }, + }); + // Activate border color changes if it matches background's + var style = this.$target.prop("style"); + this.change_border = + style["border-color"] && + style["background-color"] === style["border-color"]; + }, + + /** + * A HACK to avoid dropdown disappearing when picking colors + * + * @param {Event} event + */ + custom_abort_event: function (event) { + event.stopPropagation(); + }, + + /** + * Select the color picker input + * + * @param {Event} event + */ + input_select: function (event) { + $(event.target).focus().select(); + }, + + /** + * Undo the inline background color, besides upstream color classes + * + * @override + */ + _onColorResetButtonClick: function (event) { + this._super.apply(this, arguments); + this.$target.css("background-color", ""); + if (this.change_border) { + this.$target.css("border-color", ""); + } + this.$target.trigger("background-color-event", event.type); + }, + + /** + * Apply the chosen color as an inline style + * + * @param {Event} event + */ + set_inline_background_color: function (event) { + var color = String(event.color); + this.$target.css("background-color", color); + if (this.change_border) { + this.$target.css("border-color", color); + } + this.$target.trigger("background-color-event", event.type); + }, + }); +}); diff --git a/web_editor_background_color/static/src/lib/bootstrap-colorpicker/bootstrap-colorpicker.css b/web_editor_background_color/static/src/lib/bootstrap-colorpicker/bootstrap-colorpicker.css new file mode 100644 index 00000000..359676d5 --- /dev/null +++ b/web_editor_background_color/static/src/lib/bootstrap-colorpicker/bootstrap-colorpicker.css @@ -0,0 +1,230 @@ +/*! + * Bootstrap Colorpicker v2.5.2 + * https://itsjavi.com/bootstrap-colorpicker/ + * + * Originally written by (c) 2012 Stefan Petre + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + */ +.colorpicker-saturation { + width: 100px; + height: 100px; + background-image: url("data:image/png;base64,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"); + cursor: crosshair; + float: left; +} +.colorpicker-saturation i { + display: block; + height: 5px; + width: 5px; + border: 1px solid #000; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + position: absolute; + top: 0; + left: 0; + margin: -4px 0 0 -4px; +} +.colorpicker-saturation i b { + display: block; + height: 5px; + width: 5px; + border: 1px solid #fff; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} +.colorpicker-hue, +.colorpicker-alpha { + width: 15px; + height: 100px; + float: left; + cursor: row-resize; + margin-left: 4px; + margin-bottom: 4px; +} +.colorpicker-hue i, +.colorpicker-alpha i { + display: block; + height: 1px; + background: #000; + border-top: 1px solid #fff; + position: absolute; + top: 0; + left: 0; + width: 100%; + margin-top: -1px; +} +.colorpicker-hue { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAABkCAMAAABw8qpSAAABLFBMVEXqFBb/ABH/ACL/ADH/AEH/AFD/AGD/AG7/AH7/AI3/AJ3/AKz/ALz/AMr/ANv/AOr/APr2AP/mAP/XAP/HAP+4AP+oAP+aAP+JAP97AP9rAP9cAP9MAP8+AP8tAP8fAP8PAP8BAv8AEP8AH/8AL/8APv8ATv8AXP8Abf8Ae/8Ai/8Amv8Aqv8AuP8Ayf8A1/8A5/8A9/8A//gA/+kA/9kA/8oA/7oA/6wA/5sA/40A/30A/24A/14A/1AA/z8A/zEA/yEA/xEB/wMN/wAd/wAs/wA8/wBK/wBb/wBp/wB5/wCI/wCY/wCm/wC3/wDF/wDV/wDk/wD1/wD/+gD/7AD/3AD/zAD/vgD/rQD/nwD/jgD/gAD/cAD/YgD/UQD/QwD/MgD/JAD/FAD4Eg42qAedAAAAh0lEQVR4XgXAg3EDAAAAwI9to7Zt27a1/w49BASFhEVExcQlJKWkZWTl5BUUlZRVVNXUNTS1tHXo1KVbj159+g0YNGTYiFFjxk2YNGXajFlz5i1YtGTZilVr1m3YtGXbjl179h04dOTYiVNnzl24dOXajVt37j149OTZi1dv3n349OXbj19//wOxE1dQ8reGAAAAAElFTkSuQmCC"); +} +.colorpicker-alpha { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAABkCAQAAAAVxWkcAAABr0lEQVR4Xo2VwU0DQQxF7dmRuNIFlzlSAR3QAaXQQdIBJVABFXDcOVAAd67cjJLR07dkhcSrkZKfb/t7bG88rFo3B5gZPMNycItu2xloGV7MWHzM9zuzFWCkmA0nK6AszCUJDW6+mG6R03ncw5v8EMTEvZ2O3AliYjpslblc0RF9LmZYWxURU6aKytWZYsoWCAe+xwOZp1GsEukGiIkYxcQCHck99+gRgB7JncyIB5SGEhP3Yh5P6JwX+u6AnYot104d8DJT7uH7M9JH6OZbimj0vfMVaYnJIZFJDBW9kHlerL2C6JV4mSt7uuo2N57RxnZ+usQjn0R1jwBJBrNO3evJpVYUWsJ/E3UiXRlv24/7YZ04xmEdWlzcKS+B/eapeyMvFd2k0+hRk/T0AmTW8h69s2sjYMsdPntECiILhAeIMZAeH4QvUwfn6ijC0tTV+fT9ky8jM9nK2g7Ly1VjSpKYq6IvsAm7MtNu1orEqa/K3KNvgMFdhfquPfJmp2dbh0/8Gzb6Y22ViaNr6n5410zXdngVhbu6XqdOtWOuin5hjABGp4a2uotZ71MVCfwDBt2/v37yo6AAAAAASUVORK5CYII="); + display: none; +} +.colorpicker-saturation, +.colorpicker-hue, +.colorpicker-alpha { + background-size: contain; +} +.colorpicker { + padding: 4px; + min-width: 130px; + margin-top: 1px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + z-index: 2500; +} +.colorpicker:before, +.colorpicker:after { + display: table; + content: ""; + line-height: 0; +} +.colorpicker:after { + clear: both; +} +.colorpicker:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + top: -7px; + left: 6px; +} +.colorpicker:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + position: absolute; + top: -6px; + left: 7px; +} +.colorpicker div { + position: relative; +} +.colorpicker.colorpicker-with-alpha { + min-width: 140px; +} +.colorpicker.colorpicker-with-alpha .colorpicker-alpha { + display: block; +} +.colorpicker-color { + height: 10px; + margin-top: 5px; + clear: both; + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAABkCAQAAAAVxWkcAAABr0lEQVR4Xo2VwU0DQQxF7dmRuNIFlzlSAR3QAaXQQdIBJVABFXDcOVAAd67cjJLR07dkhcSrkZKfb/t7bG88rFo3B5gZPMNycItu2xloGV7MWHzM9zuzFWCkmA0nK6AszCUJDW6+mG6R03ncw5v8EMTEvZ2O3AliYjpslblc0RF9LmZYWxURU6aKytWZYsoWCAe+xwOZp1GsEukGiIkYxcQCHck99+gRgB7JncyIB5SGEhP3Yh5P6JwX+u6AnYot104d8DJT7uH7M9JH6OZbimj0vfMVaYnJIZFJDBW9kHlerL2C6JV4mSt7uuo2N57RxnZ+usQjn0R1jwBJBrNO3evJpVYUWsJ/E3UiXRlv24/7YZ04xmEdWlzcKS+B/eapeyMvFd2k0+hRk/T0AmTW8h69s2sjYMsdPntECiILhAeIMZAeH4QvUwfn6ijC0tTV+fT9ky8jM9nK2g7Ly1VjSpKYq6IvsAm7MtNu1orEqa/K3KNvgMFdhfquPfJmp2dbh0/8Gzb6Y22ViaNr6n5410zXdngVhbu6XqdOtWOuin5hjABGp4a2uotZ71MVCfwDBt2/v37yo6AAAAAASUVORK5CYII="); + background-position: 0 100%; +} +.colorpicker-color div { + height: 10px; +} +.colorpicker-selectors { + display: none; + height: 10px; + margin-top: 5px; + clear: both; +} +.colorpicker-selectors i { + cursor: pointer; + float: left; + height: 10px; + width: 10px; +} +.colorpicker-selectors i + i { + margin-left: 3px; +} +.colorpicker-element .input-group-addon i, +.colorpicker-element .add-on i { + display: inline-block; + cursor: pointer; + height: 16px; + vertical-align: text-top; + width: 16px; +} +.colorpicker.colorpicker-inline { + position: relative; + display: inline-block; + float: none; + z-index: auto; +} +.colorpicker.colorpicker-horizontal { + width: 110px; + min-width: 110px; + height: auto; +} +.colorpicker.colorpicker-horizontal .colorpicker-saturation { + margin-bottom: 4px; +} +.colorpicker.colorpicker-horizontal .colorpicker-color { + width: 100px; +} +.colorpicker.colorpicker-horizontal .colorpicker-hue, +.colorpicker.colorpicker-horizontal .colorpicker-alpha { + width: 100px; + height: 15px; + float: left; + cursor: col-resize; + margin-left: 0px; + margin-bottom: 4px; +} +.colorpicker.colorpicker-horizontal .colorpicker-hue i, +.colorpicker.colorpicker-horizontal .colorpicker-alpha i { + display: block; + height: 15px; + background: #ffffff; + position: absolute; + top: 0; + left: 0; + width: 1px; + border: none; + margin-top: 0px; +} +.colorpicker.colorpicker-horizontal .colorpicker-hue { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAABCAMAAAAfBfuPAAABLFBMVEXqFBb/ABH/ACL/ADH/AEH/AFD/AGD/AG7/AH7/AI3/AJ3/AKz/ALz/AMr/ANv/AOr/APr2AP/mAP/XAP/HAP+4AP+oAP+aAP+JAP97AP9rAP9cAP9MAP8+AP8tAP8fAP8PAP8BAv8AEP8AH/8AL/8APv8ATv8AXP8Abf8Ae/8Ai/8Amv8Aqv8AuP8Ayf8A1/8A5/8A9/8A//gA/+kA/9kA/8oA/7oA/6wA/5sA/40A/30A/24A/14A/1AA/z8A/zEA/yEA/xEB/wMN/wAd/wAs/wA8/wBK/wBb/wBp/wB5/wCI/wCY/wCm/wC3/wDF/wDV/wDk/wD1/wD/+gD/7AD/3AD/zAD/vgD/rQD/nwD/jgD/gAD/cAD/YgD/UQD/QwD/MgD/JAD/FAD4Eg42qAedAAAAbUlEQVR4XgXAghEDsbxtlrZt27ax/w49ACAYQTGcICmaYTleECVZUTXdMC1Wm93hdLk9Xp8/EAyFI9FYPJFMpTPZXL5QLJUr1Vq90Wy1O91efzAcjSfT2XyxXK03293+cDydL9fb/fF8vT/f3x+LfRNXARMbCAAAAABJRU5ErkJggg=="); +} +.colorpicker.colorpicker-horizontal .colorpicker-alpha { + background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAKCAQAAADoFTP1AAAB9ElEQVR4XoWTQW4VMRBEu9qWEimL7DhEMp8NF+ASnJJLcAQgE1bcgBUSkYKUuHCrZ9pjeqSU5Yn9LPu7umJQBIIv+k7vIOrtK66L4lmr3pVOrOv3otp619KZ0/KjdNI79L52Uo09FBQWrU0vfe5trezU+hLsoUKd3Repovte+0vbq/7Lj5XbaHECKasR9G4MPlbp+gzZxd6koPEJCkAYC5SjcOTAIIOK90Dja1IfIZ8Z+zAY9jm3b5Ia+MT5sFcqRJrR2AYYA8Kua5BzYRrFPNmD4PQMegGJMOffJJUsWiI3nCHZZjInNdffLWOufzbc3JaboCAVxwmnRHbhLSPwRJ4wU0BRSc6HkECYYVw95nMKgJOcylxrJttE5Ibzf9Xq9GPvP+WX3MiV/MGHfRu/SentRQrfG1GzsIrytdNXucSRKxQNIGHM9YhGFQJcdjNcBZvfJayuYe4Sia1CzwW+19mWOhe37HsxJWKwbu/jluEU15QzAQjAqCEbhMJc78GYV2E0kooHDubUImWkTOhGpgv8PoT8DJG/bzxna4BZ0eOFSOaLADGeSpFsg5AzeaDZIDQQXjZ4y/8ryfzUXBwdELRjTjCNvOeT0rNlrJz90vwy6N9pXXQEluX0inElpPWokSdiLCfiNJJjMKQ8Qsh8GEKQKMo/eiHrNbI9UksAAAAASUVORK5CYII="); +} +.colorpicker-right:before { + left: auto; + right: 6px; +} +.colorpicker-right:after { + left: auto; + right: 7px; +} +.colorpicker-no-arrow:before { + border-right: 0; + border-left: 0; +} +.colorpicker-no-arrow:after { + border-right: 0; + border-left: 0; +} +.colorpicker.colorpicker-visible, +.colorpicker-alpha.colorpicker-visible, +.colorpicker-saturation.colorpicker-visible, +.colorpicker-hue.colorpicker-visible, +.colorpicker-selectors.colorpicker-visible { + display: block; +} +.colorpicker.colorpicker-hidden, +.colorpicker-alpha.colorpicker-hidden, +.colorpicker-saturation.colorpicker-hidden, +.colorpicker-hue.colorpicker-hidden, +.colorpicker-selectors.colorpicker-hidden { + display: none; +} +.colorpicker-inline.colorpicker-visible { + display: inline-block; +} +/*# sourceMappingURL=bootstrap-colorpicker.css.map */ \ No newline at end of file diff --git a/web_editor_background_color/static/src/lib/bootstrap-colorpicker/bootstrap-colorpicker.js b/web_editor_background_color/static/src/lib/bootstrap-colorpicker/bootstrap-colorpicker.js new file mode 100644 index 00000000..ac22ed52 --- /dev/null +++ b/web_editor_background_color/static/src/lib/bootstrap-colorpicker/bootstrap-colorpicker.js @@ -0,0 +1,1327 @@ +/*! + * Bootstrap Colorpicker v2.5.2 + * https://itsjavi.com/bootstrap-colorpicker/ + * + * Originally written by (c) 2012 Stefan Petre + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0.txt + * + */ + +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module unless amdModuleId is set + define(["jquery"], function(jq) { + return (factory(jq)); + }); + } else if (typeof exports === 'object') { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(require("jquery")); + } else if (jQuery && !jQuery.fn.colorpicker) { + factory(jQuery); + } +}(this, function($) { + 'use strict'; + /** + * Color manipulation helper class + * + * @param {Object|String} [val] + * @param {Object} [predefinedColors] + * @param {String|null} [fallbackColor] + * @param {String|null} [fallbackFormat] + * @param {Boolean} [hexNumberSignPrefix] + * @constructor + */ + var Color = function( + val, predefinedColors, fallbackColor, fallbackFormat, hexNumberSignPrefix) { + this.fallbackValue = fallbackColor ? + ( + (typeof fallbackColor === 'string') ? + this.parse(fallbackColor) : + fallbackColor + ) : + null; + + this.fallbackFormat = fallbackFormat ? fallbackFormat : 'rgba'; + + this.hexNumberSignPrefix = hexNumberSignPrefix === true; + + this.value = this.fallbackValue; + + this.origFormat = null; // original string format + + this.predefinedColors = predefinedColors ? predefinedColors : {}; + + // We don't want to share aliases across instances so we extend new object + this.colors = $.extend({}, Color.webColors, this.predefinedColors); + + if (val) { + if (typeof val.h !== 'undefined') { + this.value = val; + } else { + this.setColor(String(val)); + } + } + + if (!this.value) { + // Initial value is always black if no arguments are passed or val is empty + this.value = { + h: 0, + s: 0, + b: 0, + a: 1 + }; + } + }; + + Color.webColors = { // 140 predefined colors from the HTML Colors spec + "aliceblue": "f0f8ff", + "antiquewhite": "faebd7", + "aqua": "00ffff", + "aquamarine": "7fffd4", + "azure": "f0ffff", + "beige": "f5f5dc", + "bisque": "ffe4c4", + "black": "000000", + "blanchedalmond": "ffebcd", + "blue": "0000ff", + "blueviolet": "8a2be2", + "brown": "a52a2a", + "burlywood": "deb887", + "cadetblue": "5f9ea0", + "chartreuse": "7fff00", + "chocolate": "d2691e", + "coral": "ff7f50", + "cornflowerblue": "6495ed", + "cornsilk": "fff8dc", + "crimson": "dc143c", + "cyan": "00ffff", + "darkblue": "00008b", + "darkcyan": "008b8b", + "darkgoldenrod": "b8860b", + "darkgray": "a9a9a9", + "darkgreen": "006400", + "darkkhaki": "bdb76b", + "darkmagenta": "8b008b", + "darkolivegreen": "556b2f", + "darkorange": "ff8c00", + "darkorchid": "9932cc", + "darkred": "8b0000", + "darksalmon": "e9967a", + "darkseagreen": "8fbc8f", + "darkslateblue": "483d8b", + "darkslategray": "2f4f4f", + "darkturquoise": "00ced1", + "darkviolet": "9400d3", + "deeppink": "ff1493", + "deepskyblue": "00bfff", + "dimgray": "696969", + "dodgerblue": "1e90ff", + "firebrick": "b22222", + "floralwhite": "fffaf0", + "forestgreen": "228b22", + "fuchsia": "ff00ff", + "gainsboro": "dcdcdc", + "ghostwhite": "f8f8ff", + "gold": "ffd700", + "goldenrod": "daa520", + "gray": "808080", + "green": "008000", + "greenyellow": "adff2f", + "honeydew": "f0fff0", + "hotpink": "ff69b4", + "indianred": "cd5c5c", + "indigo": "4b0082", + "ivory": "fffff0", + "khaki": "f0e68c", + "lavender": "e6e6fa", + "lavenderblush": "fff0f5", + "lawngreen": "7cfc00", + "lemonchiffon": "fffacd", + "lightblue": "add8e6", + "lightcoral": "f08080", + "lightcyan": "e0ffff", + "lightgoldenrodyellow": "fafad2", + "lightgrey": "d3d3d3", + "lightgreen": "90ee90", + "lightpink": "ffb6c1", + "lightsalmon": "ffa07a", + "lightseagreen": "20b2aa", + "lightskyblue": "87cefa", + "lightslategray": "778899", + "lightsteelblue": "b0c4de", + "lightyellow": "ffffe0", + "lime": "00ff00", + "limegreen": "32cd32", + "linen": "faf0e6", + "magenta": "ff00ff", + "maroon": "800000", + "mediumaquamarine": "66cdaa", + "mediumblue": "0000cd", + "mediumorchid": "ba55d3", + "mediumpurple": "9370d8", + "mediumseagreen": "3cb371", + "mediumslateblue": "7b68ee", + "mediumspringgreen": "00fa9a", + "mediumturquoise": "48d1cc", + "mediumvioletred": "c71585", + "midnightblue": "191970", + "mintcream": "f5fffa", + "mistyrose": "ffe4e1", + "moccasin": "ffe4b5", + "navajowhite": "ffdead", + "navy": "000080", + "oldlace": "fdf5e6", + "olive": "808000", + "olivedrab": "6b8e23", + "orange": "ffa500", + "orangered": "ff4500", + "orchid": "da70d6", + "palegoldenrod": "eee8aa", + "palegreen": "98fb98", + "paleturquoise": "afeeee", + "palevioletred": "d87093", + "papayawhip": "ffefd5", + "peachpuff": "ffdab9", + "peru": "cd853f", + "pink": "ffc0cb", + "plum": "dda0dd", + "powderblue": "b0e0e6", + "purple": "800080", + "red": "ff0000", + "rosybrown": "bc8f8f", + "royalblue": "4169e1", + "saddlebrown": "8b4513", + "salmon": "fa8072", + "sandybrown": "f4a460", + "seagreen": "2e8b57", + "seashell": "fff5ee", + "sienna": "a0522d", + "silver": "c0c0c0", + "skyblue": "87ceeb", + "slateblue": "6a5acd", + "slategray": "708090", + "snow": "fffafa", + "springgreen": "00ff7f", + "steelblue": "4682b4", + "tan": "d2b48c", + "teal": "008080", + "thistle": "d8bfd8", + "tomato": "ff6347", + "turquoise": "40e0d0", + "violet": "ee82ee", + "wheat": "f5deb3", + "white": "ffffff", + "whitesmoke": "f5f5f5", + "yellow": "ffff00", + "yellowgreen": "9acd32", + "transparent": "transparent" + }; + + Color.prototype = { + constructor: Color, + colors: {}, // merged web and predefined colors + predefinedColors: {}, + /** + * @return {Object} + */ + getValue: function() { + return this.value; + }, + /** + * @param {Object} val + */ + setValue: function(val) { + this.value = val; + }, + _sanitizeNumber: function(val) { + if (typeof val === 'number') { + return val; + } + if (isNaN(val) || (val === null) || (val === '') || (val === undefined)) { + return 1; + } + if (val === '') { + return 0; + } + if (typeof val.toLowerCase !== 'undefined') { + if (val.match(/^\./)) { + val = "0" + val; + } + return Math.ceil(parseFloat(val) * 100) / 100; + } + return 1; + }, + isTransparent: function(strVal) { + if (!strVal || !(typeof strVal === 'string' || strVal instanceof String)) { + return false; + } + strVal = strVal.toLowerCase().trim(); + return (strVal === 'transparent') || (strVal.match(/#?00000000/)) || (strVal.match(/(rgba|hsla)\(0,0,0,0?\.?0\)/)); + }, + rgbaIsTransparent: function(rgba) { + return ((rgba.r === 0) && (rgba.g === 0) && (rgba.b === 0) && (rgba.a === 0)); + }, + // parse a string to HSB + /** + * @protected + * @param {String} strVal + * @returns {boolean} Returns true if it could be parsed, false otherwise + */ + setColor: function(strVal) { + strVal = strVal.toLowerCase().trim(); + if (strVal) { + if (this.isTransparent(strVal)) { + this.value = { + h: 0, + s: 0, + b: 0, + a: 0 + }; + return true; + } else { + var parsedColor = this.parse(strVal); + if (parsedColor) { + this.value = this.value = { + h: parsedColor.h, + s: parsedColor.s, + b: parsedColor.b, + a: parsedColor.a + }; + if (!this.origFormat) { + this.origFormat = parsedColor.format; + } + } else if (this.fallbackValue) { + // if parser fails, defaults to fallbackValue if defined, otherwise the value won't be changed + this.value = this.fallbackValue; + } + } + } + return false; + }, + setHue: function(h) { + this.value.h = 1 - h; + }, + setSaturation: function(s) { + this.value.s = s; + }, + setBrightness: function(b) { + this.value.b = 1 - b; + }, + setAlpha: function(a) { + this.value.a = Math.round((parseInt((1 - a) * 100, 10) / 100) * 100) / 100; + }, + toRGB: function(h, s, b, a) { + if (arguments.length === 0) { + h = this.value.h; + s = this.value.s; + b = this.value.b; + a = this.value.a; + } + + h *= 360; + var R, G, B, X, C; + h = (h % 360) / 60; + C = b * s; + X = C * (1 - Math.abs(h % 2 - 1)); + R = G = B = b - C; + + h = ~~h; + R += [C, X, 0, 0, X, C][h]; + G += [X, C, C, X, 0, 0][h]; + B += [0, 0, X, C, C, X][h]; + + return { + r: Math.round(R * 255), + g: Math.round(G * 255), + b: Math.round(B * 255), + a: a + }; + }, + toHex: function(ignoreFormat, h, s, b, a) { + if (arguments.length <= 1) { + h = this.value.h; + s = this.value.s; + b = this.value.b; + a = this.value.a; + } + + var prefix = '#'; + var rgb = this.toRGB(h, s, b, a); + + if (this.rgbaIsTransparent(rgb)) { + return 'transparent'; + } + + if (!ignoreFormat) { + prefix = (this.hexNumberSignPrefix ? '#' : ''); + } + + var hexStr = prefix + ( + (1 << 24) + + (parseInt(rgb.r) << 16) + + (parseInt(rgb.g) << 8) + + parseInt(rgb.b)) + .toString(16) + .slice(1); + + return hexStr; + }, + toHSL: function(h, s, b, a) { + if (arguments.length === 0) { + h = this.value.h; + s = this.value.s; + b = this.value.b; + a = this.value.a; + } + + var H = h, + L = (2 - s) * b, + S = s * b; + if (L > 0 && L <= 1) { + S /= L; + } else { + S /= 2 - L; + } + L /= 2; + if (S > 1) { + S = 1; + } + return { + h: isNaN(H) ? 0 : H, + s: isNaN(S) ? 0 : S, + l: isNaN(L) ? 0 : L, + a: isNaN(a) ? 0 : a + }; + }, + toAlias: function(r, g, b, a) { + var c, rgb = (arguments.length === 0) ? this.toHex(true) : this.toHex(true, r, g, b, a); + + // support predef. colors in non-hex format too, as defined in the alias itself + var original = this.origFormat === 'alias' ? rgb : this.toString(false, this.origFormat); + + for (var alias in this.colors) { + c = this.colors[alias].toLowerCase().trim(); + if ((c === rgb) || (c === original)) { + return alias; + } + } + return false; + }, + RGBtoHSB: function(r, g, b, a) { + r /= 255; + g /= 255; + b /= 255; + + var H, S, V, C; + V = Math.max(r, g, b); + C = V - Math.min(r, g, b); + H = (C === 0 ? null : + V === r ? (g - b) / C : + V === g ? (b - r) / C + 2 : + (r - g) / C + 4 + ); + H = ((H + 360) % 6) * 60 / 360; + S = C === 0 ? 0 : C / V; + return { + h: this._sanitizeNumber(H), + s: S, + b: V, + a: this._sanitizeNumber(a) + }; + }, + HueToRGB: function(p, q, h) { + if (h < 0) { + h += 1; + } else if (h > 1) { + h -= 1; + } + if ((h * 6) < 1) { + return p + (q - p) * h * 6; + } else if ((h * 2) < 1) { + return q; + } else if ((h * 3) < 2) { + return p + (q - p) * ((2 / 3) - h) * 6; + } else { + return p; + } + }, + HSLtoRGB: function(h, s, l, a) { + if (s < 0) { + s = 0; + } + var q; + if (l <= 0.5) { + q = l * (1 + s); + } else { + q = l + s - (l * s); + } + + var p = 2 * l - q; + + var tr = h + (1 / 3); + var tg = h; + var tb = h - (1 / 3); + + var r = Math.round(this.HueToRGB(p, q, tr) * 255); + var g = Math.round(this.HueToRGB(p, q, tg) * 255); + var b = Math.round(this.HueToRGB(p, q, tb) * 255); + return [r, g, b, this._sanitizeNumber(a)]; + }, + /** + * @param {String} strVal + * @returns {Object} Object containing h,s,b,a,format properties or FALSE if failed to parse + */ + parse: function(strVal) { + if (typeof strVal !== 'string') { + return this.fallbackValue; + } + if (arguments.length === 0) { + return false; + } + + var that = this, + result = false, + isAlias = (typeof this.colors[strVal] !== 'undefined'), + values, format; + + if (isAlias) { + strVal = this.colors[strVal].toLowerCase().trim(); + } + + $.each(this.stringParsers, function(i, parser) { + var match = parser.re.exec(strVal); + values = match && parser.parse.apply(that, [match]); + if (values) { + result = {}; + format = (isAlias ? 'alias' : (parser.format ? parser.format : that.getValidFallbackFormat())); + if (format.match(/hsla?/)) { + result = that.RGBtoHSB.apply(that, that.HSLtoRGB.apply(that, values)); + } else { + result = that.RGBtoHSB.apply(that, values); + } + if (result instanceof Object) { + result.format = format; + } + return false; // stop iterating + } + return true; + }); + return result; + }, + getValidFallbackFormat: function() { + var formats = [ + 'rgba', 'rgb', 'hex', 'hsla', 'hsl' + ]; + if (this.origFormat && (formats.indexOf(this.origFormat) !== -1)) { + return this.origFormat; + } + if (this.fallbackFormat && (formats.indexOf(this.fallbackFormat) !== -1)) { + return this.fallbackFormat; + } + + return 'rgba'; // By default, return a format that will not lose the alpha info + }, + /** + * + * @param {string} [format] (default: rgba) + * @param {boolean} [translateAlias] Return real color for pre-defined (non-standard) aliases (default: false) + * @param {boolean} [forceRawValue] Forces hashtag prefix when getting hex color (default: false) + * @returns {String} + */ + toString: function(forceRawValue, format, translateAlias) { + format = format || this.origFormat || this.fallbackFormat; + translateAlias = translateAlias || false; + + var c = false; + + switch (format) { + case 'rgb': + { + c = this.toRGB(); + if (this.rgbaIsTransparent(c)) { + return 'transparent'; + } + return 'rgb(' + c.r + ',' + c.g + ',' + c.b + ')'; + } + break; + case 'rgba': + { + c = this.toRGB(); + return 'rgba(' + c.r + ',' + c.g + ',' + c.b + ',' + c.a + ')'; + } + break; + case 'hsl': + { + c = this.toHSL(); + return 'hsl(' + Math.round(c.h * 360) + ',' + Math.round(c.s * 100) + '%,' + Math.round(c.l * 100) + '%)'; + } + break; + case 'hsla': + { + c = this.toHSL(); + return 'hsla(' + Math.round(c.h * 360) + ',' + Math.round(c.s * 100) + '%,' + Math.round(c.l * 100) + '%,' + c.a + ')'; + } + break; + case 'hex': + { + return this.toHex(forceRawValue); + } + break; + case 'alias': + { + c = this.toAlias(); + + if (c === false) { + return this.toString(forceRawValue, this.getValidFallbackFormat()); + } + + if (translateAlias && !(c in Color.webColors) && (c in this.predefinedColors)) { + return this.predefinedColors[c]; + } + + return c; + } + default: + { + return c; + } + break; + } + }, + // a set of RE's that can match strings and generate color tuples. + // from John Resig color plugin + // https://github.com/jquery/jquery-color/ + stringParsers: [{ + re: /rgb\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*?\)/, + format: 'rgb', + parse: function(execResult) { + return [ + execResult[1], + execResult[2], + execResult[3], + 1 + ]; + } + }, { + re: /rgb\(\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*?\)/, + format: 'rgb', + parse: function(execResult) { + return [ + 2.55 * execResult[1], + 2.55 * execResult[2], + 2.55 * execResult[3], + 1 + ]; + } + }, { + re: /rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d*(?:\.\d+)?)\s*)?\)/, + format: 'rgba', + parse: function(execResult) { + return [ + execResult[1], + execResult[2], + execResult[3], + execResult[4] + ]; + } + }, { + re: /rgba\(\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*(?:,\s*(\d*(?:\.\d+)?)\s*)?\)/, + format: 'rgba', + parse: function(execResult) { + return [ + 2.55 * execResult[1], + 2.55 * execResult[2], + 2.55 * execResult[3], + execResult[4] + ]; + } + }, { + re: /hsl\(\s*(\d*(?:\.\d+)?)\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*?\)/, + format: 'hsl', + parse: function(execResult) { + return [ + execResult[1] / 360, + execResult[2] / 100, + execResult[3] / 100, + execResult[4] + ]; + } + }, { + re: /hsla\(\s*(\d*(?:\.\d+)?)\s*,\s*(\d*(?:\.\d+)?)\%\s*,\s*(\d*(?:\.\d+)?)\%\s*(?:,\s*(\d*(?:\.\d+)?)\s*)?\)/, + format: 'hsla', + parse: function(execResult) { + return [ + execResult[1] / 360, + execResult[2] / 100, + execResult[3] / 100, + execResult[4] + ]; + } + }, { + re: /#?([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/, + format: 'hex', + parse: function(execResult) { + return [ + parseInt(execResult[1], 16), + parseInt(execResult[2], 16), + parseInt(execResult[3], 16), + 1 + ]; + } + }, { + re: /#?([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/, + format: 'hex', + parse: function(execResult) { + return [ + parseInt(execResult[1] + execResult[1], 16), + parseInt(execResult[2] + execResult[2], 16), + parseInt(execResult[3] + execResult[3], 16), + 1 + ]; + } + }], + colorNameToHex: function(name) { + if (typeof this.colors[name.toLowerCase()] !== 'undefined') { + return this.colors[name.toLowerCase()]; + } + return false; + } + }; + + /* + * Default plugin options + */ + var defaults = { + horizontal: false, // horizontal mode layout ? + inline: false, //forces to show the colorpicker as an inline element + color: false, //forces a color + format: false, //forces a format + input: 'input', // children input selector + container: false, // container selector + component: '.add-on, .input-group-addon', // children component selector + fallbackColor: false, // fallback color value. null = keeps current color. + fallbackFormat: 'hex', // fallback color format + hexNumberSignPrefix: true, // put a '#' (number sign) before hex strings + sliders: { + saturation: { + maxLeft: 100, + maxTop: 100, + callLeft: 'setSaturation', + callTop: 'setBrightness' + }, + hue: { + maxLeft: 0, + maxTop: 100, + callLeft: false, + callTop: 'setHue' + }, + alpha: { + maxLeft: 0, + maxTop: 100, + callLeft: false, + callTop: 'setAlpha' + } + }, + slidersHorz: { + saturation: { + maxLeft: 100, + maxTop: 100, + callLeft: 'setSaturation', + callTop: 'setBrightness' + }, + hue: { + maxLeft: 100, + maxTop: 0, + callLeft: 'setHue', + callTop: false + }, + alpha: { + maxLeft: 100, + maxTop: 0, + callLeft: 'setAlpha', + callTop: false + } + }, + template: '