diff --git a/setup/web_widget_text_markdown/odoo/addons/web_widget_text_markdown b/setup/web_widget_text_markdown/odoo/addons/web_widget_text_markdown new file mode 120000 index 000000000..872e5f4ad --- /dev/null +++ b/setup/web_widget_text_markdown/odoo/addons/web_widget_text_markdown @@ -0,0 +1 @@ +../../../../web_widget_text_markdown \ No newline at end of file diff --git a/setup/web_widget_text_markdown/setup.py b/setup/web_widget_text_markdown/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/web_widget_text_markdown/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/web_widget_text_markdown/README.rst b/web_widget_text_markdown/README.rst new file mode 100644 index 000000000..5b71ca24f --- /dev/null +++ b/web_widget_text_markdown/README.rst @@ -0,0 +1,104 @@ +======================== +Web Widget Text Markdown +======================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github + :target: https://github.com/OCA/web/tree/11.0/web_widget_text_markdown + :alt: OCA/web +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/web-11-0/web-11-0-web_widget_text_markdown + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/162/11.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module adds a new widget for text field in form view on Odoo: + +- In readonly mode, it uses text contents to parse and render them to html markdown syntax. +- In write mode, use [bootstrap-markdown][1] + +[1]: `bootstrap-markdown `_ + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Your XML form view definition should contain:: + + ... + + ... + +Known issues / Roadmap +====================== + +* Can't create attachments on virtual records + +* Improve user experience with Odoo specific syntax +* Improve user experience with Github specific syntax + +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 smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Alexandre Díaz +* Komit +* Sudokeys + +Contributors +~~~~~~~~~~~~ + +* Nicolas Jeudy +* Nguyen Tan Phuc +* Alexandre Díaz + +Other credits +~~~~~~~~~~~~~ + +* Komit https://komit-consulting.com + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +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. + +This module is part of the `OCA/web `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/web_widget_text_markdown/__init__.py b/web_widget_text_markdown/__init__.py new file mode 100644 index 000000000..ef5ae3587 --- /dev/null +++ b/web_widget_text_markdown/__init__.py @@ -0,0 +1 @@ +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). diff --git a/web_widget_text_markdown/__manifest__.py b/web_widget_text_markdown/__manifest__.py new file mode 100644 index 000000000..11e02b22c --- /dev/null +++ b/web_widget_text_markdown/__manifest__.py @@ -0,0 +1,23 @@ +# Copyright (C) 2014 Sudokeys () +# Copyright (C) 2017 Komit () +# +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +{ + "name": "Web Widget Text Markdown", + "version": "13.0.1.0.0", + "author": "Alexandre Díaz, " + "Komit, " + "Sudokeys, " + "Odoo Community Association (OCA)", + "category": "Web", + "license": "AGPL-3", + "website": "https://github.com/OCA/web", + "summary": "Widget to text fields that adds markdown support", + "depends": ["web"], + "demo": ["demo/bootstrap_markdown.xml"], + "data": ["views/assets.xml"], + "qweb": ["static/src/xml/bootstrap_markdown.xml"], + "installable": True, + "auto_install": False, + "application": False, +} diff --git a/web_widget_text_markdown/demo/bootstrap_markdown.xml b/web_widget_text_markdown/demo/bootstrap_markdown.xml new file mode 100644 index 000000000..be6bc22c2 --- /dev/null +++ b/web_widget_text_markdown/demo/bootstrap_markdown.xml @@ -0,0 +1,12 @@ + + + + res.groups + + + + bootstrap_markdown + + + + diff --git a/web_widget_text_markdown/i18n/ar.po b/web_widget_text_markdown/i18n/ar.po new file mode 100644 index 000000000..e70ecf7a0 --- /dev/null +++ b/web_widget_text_markdown/i18n/ar.po @@ -0,0 +1,52 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_text_markdown +# +# Translators: +# SaFi J. , 2015 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-12-16 07:41+0000\n" +"PO-Revision-Date: 2015-12-16 17:24+0000\n" +"Last-Translator: SaFi J. \n" +"Language-Team: Arabic (http://www.transifex.com/oca/OCA-web-8-0/language/" +"ar/)\n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " +"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:132 +#, python-format +msgid "Can't create the attachment." +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:131 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:92 +#, python-format +msgid "Translate" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:125 +#, python-format +msgid "description" +msgstr "" + +#~ msgid "MarkDown" +#~ msgstr "مارك داون" diff --git a/web_widget_text_markdown/i18n/de.po b/web_widget_text_markdown/i18n/de.po new file mode 100644 index 000000000..e64f4c579 --- /dev/null +++ b/web_widget_text_markdown/i18n/de.po @@ -0,0 +1,51 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_text_markdown +# +# Translators: +# Rudolf Schnapka , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-10 07:31+0000\n" +"PO-Revision-Date: 2016-01-18 20:15+0000\n" +"Last-Translator: Rudolf Schnapka \n" +"Language-Team: German (http://www.transifex.com/oca/OCA-web-8-0/language/" +"de/)\n" +"Language: de\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" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:132 +#, python-format +msgid "Can't create the attachment." +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:131 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:92 +#, python-format +msgid "Translate" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:125 +#, python-format +msgid "description" +msgstr "" + +#~ msgid "MarkDown" +#~ msgstr "Abschlag" diff --git a/web_widget_text_markdown/i18n/es.po b/web_widget_text_markdown/i18n/es.po new file mode 100644 index 000000000..bf688f4ff --- /dev/null +++ b/web_widget_text_markdown/i18n/es.po @@ -0,0 +1,51 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_text_markdown +# +# Translators: +# Pedro M. Baeza , 2015 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-11-23 13:46+0000\n" +"PO-Revision-Date: 2015-11-07 11:29+0000\n" +"Last-Translator: Pedro M. Baeza \n" +"Language-Team: Spanish (http://www.transifex.com/oca/OCA-web-8-0/language/" +"es/)\n" +"Language: es\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" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:132 +#, python-format +msgid "Can't create the attachment." +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:131 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:92 +#, python-format +msgid "Translate" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:125 +#, python-format +msgid "description" +msgstr "" + +#~ msgid "MarkDown" +#~ msgstr "MarkDown" diff --git a/web_widget_text_markdown/i18n/fi.po b/web_widget_text_markdown/i18n/fi.po new file mode 100644 index 000000000..5281f6b24 --- /dev/null +++ b/web_widget_text_markdown/i18n/fi.po @@ -0,0 +1,51 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_text_markdown +# +# Translators: +# Jarmo Kortetjärvi , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-10 07:31+0000\n" +"PO-Revision-Date: 2016-02-01 09:42+0000\n" +"Last-Translator: Jarmo Kortetjärvi \n" +"Language-Team: Finnish (http://www.transifex.com/oca/OCA-web-8-0/language/" +"fi/)\n" +"Language: fi\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" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:132 +#, python-format +msgid "Can't create the attachment." +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:131 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:92 +#, python-format +msgid "Translate" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:125 +#, python-format +msgid "description" +msgstr "" + +#~ msgid "MarkDown" +#~ msgstr "Markdown" diff --git a/web_widget_text_markdown/i18n/fr.po b/web_widget_text_markdown/i18n/fr.po new file mode 100644 index 000000000..164ee5a88 --- /dev/null +++ b/web_widget_text_markdown/i18n/fr.po @@ -0,0 +1,51 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_text_markdown +# +# Translators: +# Christophe CHAUVET , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-05-06 15:50+0000\n" +"PO-Revision-Date: 2016-05-06 08:22+0000\n" +"Last-Translator: Christophe CHAUVET \n" +"Language-Team: French (http://www.transifex.com/oca/OCA-web-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" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:132 +#, python-format +msgid "Can't create the attachment." +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:131 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:92 +#, python-format +msgid "Translate" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:125 +#, python-format +msgid "description" +msgstr "" + +#~ msgid "MarkDown" +#~ msgstr "MarkDown" diff --git a/web_widget_text_markdown/i18n/pt_BR.po b/web_widget_text_markdown/i18n/pt_BR.po new file mode 100644 index 000000000..6529541d8 --- /dev/null +++ b/web_widget_text_markdown/i18n/pt_BR.po @@ -0,0 +1,51 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_text_markdown +# +# Translators: +# danimaribeiro , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-03-11 02:18+0000\n" +"PO-Revision-Date: 2016-03-05 16:20+0000\n" +"Last-Translator: danimaribeiro \n" +"Language-Team: Portuguese (Brazil) (http://www.transifex.com/oca/OCA-web-8-0/" +"language/pt_BR/)\n" +"Language: pt_BR\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" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:132 +#, python-format +msgid "Can't create the attachment." +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:131 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:92 +#, python-format +msgid "Translate" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:125 +#, python-format +msgid "description" +msgstr "" + +#~ msgid "MarkDown" +#~ msgstr "MarkDown" diff --git a/web_widget_text_markdown/i18n/sl.po b/web_widget_text_markdown/i18n/sl.po new file mode 100644 index 000000000..b41fb9821 --- /dev/null +++ b/web_widget_text_markdown/i18n/sl.po @@ -0,0 +1,52 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_text_markdown +# +# Translators: +# Matjaž Mozetič , 2015 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2015-11-23 13:46+0000\n" +"PO-Revision-Date: 2015-11-08 05:48+0000\n" +"Last-Translator: Matjaž Mozetič \n" +"Language-Team: Slovenian (http://www.transifex.com/oca/OCA-web-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" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:132 +#, python-format +msgid "Can't create the attachment." +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:131 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:92 +#, python-format +msgid "Translate" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:125 +#, python-format +msgid "description" +msgstr "" + +#~ msgid "MarkDown" +#~ msgstr "MarkDown" diff --git a/web_widget_text_markdown/i18n/tr.po b/web_widget_text_markdown/i18n/tr.po new file mode 100644 index 000000000..e995f526d --- /dev/null +++ b/web_widget_text_markdown/i18n/tr.po @@ -0,0 +1,51 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_text_markdown +# +# Translators: +# Ahmet Altınışık , 2016 +msgid "" +msgstr "" +"Project-Id-Version: web (8.0)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-01-10 07:31+0000\n" +"PO-Revision-Date: 2016-01-31 11:44+0000\n" +"Last-Translator: Ahmet Altınışık \n" +"Language-Team: Turkish (http://www.transifex.com/oca/OCA-web-8-0/language/" +"tr/)\n" +"Language: tr\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" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:132 +#, python-format +msgid "Can't create the attachment." +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:131 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:92 +#, python-format +msgid "Translate" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:125 +#, python-format +msgid "description" +msgstr "" + +#~ msgid "MarkDown" +#~ msgstr "MarkDown" diff --git a/web_widget_text_markdown/i18n/web_widget_text_markdown.pot b/web_widget_text_markdown/i18n/web_widget_text_markdown.pot new file mode 100644 index 000000000..a40fd667b --- /dev/null +++ b/web_widget_text_markdown/i18n/web_widget_text_markdown.pot @@ -0,0 +1,43 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_widget_text_markdown +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 11.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" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:132 +#, python-format +msgid "Can't create the attachment." +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:131 +#, python-format +msgid "Error" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:92 +#, python-format +msgid "Translate" +msgstr "" + +#. module: web_widget_text_markdown +#. openerp-web +#: code:addons/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js:125 +#, python-format +msgid "description" +msgstr "" + diff --git a/web_widget_text_markdown/readme/CONTRIBUTORS.rst b/web_widget_text_markdown/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..e8a55ac15 --- /dev/null +++ b/web_widget_text_markdown/readme/CONTRIBUTORS.rst @@ -0,0 +1,4 @@ +* Nicolas Jeudy +* Nguyen Tan Phuc +* Alexandre Díaz +* Olga Marco Puértolas diff --git a/web_widget_text_markdown/readme/CREDITS.rst b/web_widget_text_markdown/readme/CREDITS.rst new file mode 100644 index 000000000..ca0b19940 --- /dev/null +++ b/web_widget_text_markdown/readme/CREDITS.rst @@ -0,0 +1 @@ +* Komit https://komit-consulting.com diff --git a/web_widget_text_markdown/readme/DESCRIPTION.rst b/web_widget_text_markdown/readme/DESCRIPTION.rst new file mode 100644 index 000000000..45bf1ff0e --- /dev/null +++ b/web_widget_text_markdown/readme/DESCRIPTION.rst @@ -0,0 +1,6 @@ +This module adds a new widget for text field in form view on Odoo: + +- In readonly mode, it uses text contents to parse and render them to html markdown syntax. +- In write mode, use [bootstrap-markdown][1] + +[1]: `bootstrap-markdown `_ diff --git a/web_widget_text_markdown/readme/ROADMAP.rst b/web_widget_text_markdown/readme/ROADMAP.rst new file mode 100644 index 000000000..8d1b2e80a --- /dev/null +++ b/web_widget_text_markdown/readme/ROADMAP.rst @@ -0,0 +1,4 @@ +* Can't create attachments on virtual records + +* Improve user experience with Odoo specific syntax +* Improve user experience with Github specific syntax diff --git a/web_widget_text_markdown/readme/USAGE.rst b/web_widget_text_markdown/readme/USAGE.rst new file mode 100644 index 000000000..c4551498a --- /dev/null +++ b/web_widget_text_markdown/readme/USAGE.rst @@ -0,0 +1,5 @@ +Your XML form view definition should contain:: + + ... + + ... diff --git a/web_widget_text_markdown/static/description/icon.png b/web_widget_text_markdown/static/description/icon.png new file mode 100644 index 000000000..3a0328b51 Binary files /dev/null and b/web_widget_text_markdown/static/description/icon.png differ diff --git a/web_widget_text_markdown/static/description/index.html b/web_widget_text_markdown/static/description/index.html new file mode 100644 index 000000000..53da2b6d6 --- /dev/null +++ b/web_widget_text_markdown/static/description/index.html @@ -0,0 +1,454 @@ + + + + + + +Web Widget Text Markdown + + + +
+

Web Widget Text Markdown

+ + +

Beta License: AGPL-3 OCA/web Translate me on Weblate Try me on Runbot

+

This module adds a new widget for text field in form view on Odoo:

+
    +
  • In readonly mode, it uses text contents to parse and render them to html markdown syntax.
  • +
  • In write mode, use [bootstrap-markdown][1]
  • +
+

[1]: bootstrap-markdown

+

Table of contents

+ +
+

Usage

+

Your XML form view definition should contain:

+
+...
+<field name="field_name" widget="bootstrap_markdown"/>
+...
+
+
+
+

Known issues / Roadmap

+
    +
  • Can’t create attachments on virtual records
  • +
  • Improve user experience with Odoo specific syntax
  • +
  • Improve user experience with Github specific syntax
  • +
+
+
+

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 smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Alexandre Díaz
  • +
  • Komit
  • +
  • Sudokeys
  • +
+
+
+

Contributors

+ +
+ +
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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.

+

This module is part of the OCA/web project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js b/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js new file mode 100644 index 000000000..673ed35d7 --- /dev/null +++ b/web_widget_text_markdown/static/src/js/web_widget_text_markdown.js @@ -0,0 +1,163 @@ +/* global marked */ +/* Copyright 2014 Sudokeys + * Copyright 2017 Komit - + * Copyright 2019 Alexandre Díaz - + * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */ +odoo.define("web_widget_text_markdown.FieldTextMarkDown", function(require) { + "use strict"; + + var basic_fields = require("web.basic_fields"); + var field_registry = require("web.field_registry"); + var core = require("web.core"); + + var _t = core._t; + var LIBS_PATH = "/web_widget_text_markdown/static/src/lib/"; + + var FieldTextMarkDown = basic_fields.FieldText.extend({ + className: [ + basic_fields.FieldText.prototype.className, + "o_field_text_markdown", + ].join(" "), + jsLibs: [ + LIBS_PATH + "marked.js", + LIBS_PATH + "dropzone.js", + LIBS_PATH + "bootstrap-markdown.js", + ], + cssLibs: [LIBS_PATH + "bootstrap-markdown.min.css"], + + _getValue: function() { + return this.$markdown.getContent(); + }, + + _prepareInput: function() { + var $input = this._super.apply(this, arguments); + _.defer( + function($elm) { + $input.removeClass(this.className); + $input.wrap( + _.str.sprintf("
", this.className) + ); + $elm.markdown(this._getMarkdownOptions()); + this.$markdown = $elm.data("markdown"); + this.$markdown.setContent(this.value || ""); + }.bind(this), + $input + ); + return $input; + }, + + _renderReadonly: function() { + this.$el.html(marked(this._formatValue(this.value))); + }, + + _getMarkdownOptions: function() { + var markdownOpts = { + autofocus: false, + savable: false, + language: this.getSession().user_context.lang, + }; + + // Only can create attachments on non-virtual records + if (this.res_id) { + var self = this; + markdownOpts.dropZoneOptions = { + paramName: "ufile", + url: "/web/binary/upload_attachment", + acceptedFiles: "image/*", + width: "o_field_text_markdown", + params: { + csrf_token: core.csrf_token, + session_id: this.getSession().override_session, + callback: "", + model: this.model, + id: this.res_id, + }, + success: function() { + self._markdownDropZoneUploadSuccess(this); + }, + error: function() { + self._markdownDropZoneUploadError(this); + }, + init: function() { + self._markdownDropZoneInit(this); + }, + }; + + if (_t.database.multi_lang && this.field.translate) { + markdownOpts.additionalButtons = [ + [ + { + name: "oTranslate", + data: [ + { + name: "cmdTranslate", + title: _t("Translate"), + icon: {glyph: "glyphicon glyphicon-flag"}, + callback: this._markdownTranslate, + }, + ], + }, + ], + ]; + } + } + + return markdownOpts; + }, + + _getAttachmentId: function(response) { + var matchElms = response.match(/"id":\s?(\d+)/); + if (matchElms && matchElms.length) { + return matchElms[1]; + } + return null; + }, + + _markdownDropZoneInit: function(markdown) { + var self = this; + var caretPos = 0; + var $textarea = null; + markdown.on("drop", function(e) { + $textarea = $(e.target); + caretPos = $textarea.prop("selectionStart"); + }); + markdown.on("success", function(file, response) { + var text = $textarea.val(); + var attachment_id = self._getAttachmentId(response); + if (attachment_id) { + var ftext = + text.substring(0, caretPos) + + "\n![" + + _t("description") + + "](/web/image/" + + attachment_id + + ")\n" + + text.substring(caretPos); + $textarea.val(ftext); + } else { + self.do_warn(_t("Error"), _t("Can't create the attachment.")); + } + }); + markdown.on("error", function(file, error) { + console.warn(error); + }); + }, + + _markdownDropZoneUploadSuccess: function() { + this.isDirty = true; + this._doDebouncedAction(); + this.$markdown.$editor.find(".dz-error-mark:last").css("display", "none"); + }, + + _markdownDropZoneUploadError: function() { + this.$markdown.$editor.find(".dz-success-mark:last").css("display", "none"); + }, + + _markdownTranslate: function() { + this._onTranslate(); + }, + }); + + field_registry.add("bootstrap_markdown", FieldTextMarkDown); + return FieldTextMarkDown; +}); diff --git a/web_widget_text_markdown/static/src/lib/bootstrap-markdown.js b/web_widget_text_markdown/static/src/lib/bootstrap-markdown.js new file mode 100644 index 000000000..e3f1ca9d3 --- /dev/null +++ b/web_widget_text_markdown/static/src/lib/bootstrap-markdown.js @@ -0,0 +1,1575 @@ +/* =================================================== + * bootstrap-markdown.js v2.10.0 + * http://github.com/toopay/bootstrap-markdown + * =================================================== + * Copyright 2013-2016 Taufan Aditya + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ========================================================== */ +(function(factory) { + if (typeof define === "function" && define.amd) { + // RequireJS + define(["jquery"], factory); + } else if (typeof exports === 'object') { + // Backbone.js + factory(require('jquery')); + } else { + // jQuery plugin + factory(jQuery); + } +}(function($) { + "use strict"; + + /* MARKDOWN CLASS DEFINITION + * ========================== */ + + var Markdown = function(element, options) { + // @TODO : remove this BC on next major release + // @see : https://github.com/toopay/bootstrap-markdown/issues/109 + var opts = ['autofocus', 'savable', 'hideable', 'width', + 'height', 'resize', 'iconlibrary', 'language', + 'footer', 'fullscreen', 'hiddenButtons', 'disabledButtons' + ]; + $.each(opts, function(_, opt) { + if (typeof $(element).data(opt) !== 'undefined') { + options = typeof options == 'object' ? options : {}; + options[opt] = $(element).data(opt); + } + }); + // End BC + + // Class Properties + this.$ns = 'bootstrap-markdown'; + this.$element = $(element); + this.$editable = { + el: null, + type: null, + attrKeys: [], + attrValues: [], + content: null + }; + this.$options = $.extend(true, {}, $.fn.markdown.defaults, options, this.$element.data('options')); + this.$oldContent = null; + this.$isPreview = false; + this.$isFullscreen = false; + this.$editor = null; + this.$textarea = null; + this.$handler = []; + this.$callback = []; + this.$nextTab = []; + + this.showEditor(); + }; + + Markdown.prototype = { + + constructor: Markdown, + __alterButtons: function(name, alter) { + var handler = this.$handler, + isAll = (name == 'all'), + that = this; + + $.each(handler, function(k, v) { + var halt = true; + if (isAll) { + halt = false; + } else { + halt = v.indexOf(name) < 0; + } + + if (halt === false) { + alter(that.$editor.find('button[data-handler="' + v + '"]')); + } + }); + }, + __buildButtons: function(buttonsArray, container) { + var i, + ns = this.$ns, + handler = this.$handler, + callback = this.$callback; + + for (i = 0; i < buttonsArray.length; i++) { + // Build each group container + var y, btnGroups = buttonsArray[i]; + for (y = 0; y < btnGroups.length; y++) { + // Build each button group + var z, + buttons = btnGroups[y].data, + btnGroupContainer = $('
', { + 'class': 'btn-group' + }); + + for (z = 0; z < buttons.length; z++) { + var button = buttons[z], + buttonContainer, buttonIconContainer, + buttonHandler = ns + '-' + button.name, + buttonIcon = this.__getIcon(button), + btnText = button.btnText ? button.btnText : '', + btnClass = button.btnClass ? button.btnClass : 'btn', + tabIndex = button.tabIndex ? button.tabIndex : '-1', + hotkey = typeof button.hotkey !== 'undefined' ? button.hotkey : '', + hotkeyCaption = typeof jQuery.hotkeys !== 'undefined' && hotkey !== '' ? ' (' + hotkey + ')' : ''; + + // Construct the button object + buttonContainer = $(''); + buttonContainer.text(' ' + this.__localize(btnText)).addClass('btn-default btn-sm').addClass(btnClass); + if (btnClass.match(/btn\-(primary|success|info|warning|danger|link)/)) { + buttonContainer.removeClass('btn-default'); + } + buttonContainer.attr({ + 'type': 'button', + 'title': this.__localize(button.title) + hotkeyCaption, + 'tabindex': tabIndex, + 'data-provider': ns, + 'data-handler': buttonHandler, + 'data-hotkey': hotkey + }); + if (button.toggle === true) { + buttonContainer.attr('data-toggle', 'button'); + } + buttonIconContainer = $(''); + buttonIconContainer.addClass(buttonIcon); + buttonIconContainer.prependTo(buttonContainer); + + // Attach the button object + btnGroupContainer.append(buttonContainer); + + // Register handler and callback + handler.push(buttonHandler); + callback.push(button.callback); + } + + // Attach the button group into container DOM + container.append(btnGroupContainer); + } + } + + return container; + }, + __setListener: function() { + // Set size and resizable Properties + var hasRows = typeof this.$textarea.attr('rows') !== 'undefined', + maxRows = this.$textarea.val().split("\n").length > 5 ? this.$textarea.val().split("\n").length : '5', + rowsVal = hasRows ? this.$textarea.attr('rows') : maxRows; + + this.$textarea.attr('rows', rowsVal); + if (this.$options.resize) { + this.$textarea.css('resize', this.$options.resize); + } + + // Re-attach markdown data + this.$textarea.data('markdown', this); + }, + __setEventListeners: function() { + this.$textarea.on({ + 'focus': $.proxy(this.focus, this), + 'keyup': $.proxy(this.keyup, this), + 'change': $.proxy(this.change, this), + 'select': $.proxy(this.select, this) + }); + + if (this.eventSupported('keydown')) { + this.$textarea.on('keydown', $.proxy(this.keydown, this)); + } + + if (this.eventSupported('keypress')) { + this.$textarea.on('keypress', $.proxy(this.keypress, this)); + } + }, + __handle: function(e) { + var target = $(e.currentTarget), + handler = this.$handler, + callback = this.$callback, + handlerName = target.attr('data-handler'), + callbackIndex = handler.indexOf(handlerName), + callbackHandler = callback[callbackIndex]; + + // Trigger the focusin + $(e.currentTarget).focus(); + + callbackHandler(this); + + // Trigger onChange for each button handle + this.change(this); + + // Unless it was the save handler, + // focusin the textarea + if (handlerName.indexOf('cmdSave') < 0) { + this.$textarea.focus(); + } + + e.preventDefault(); + }, + __localize: function(string) { + var messages = $.fn.markdown.messages, + language = this.$options.language; + if ( + typeof messages !== 'undefined' && + typeof messages[language] !== 'undefined' && + typeof messages[language][string] !== 'undefined' + ) { + return messages[language][string]; + } + return string; + }, + __getIcon: function(src) { + if(typeof src == 'object'){ + var customIcon = this.$options.customIcons[src.name]; + return typeof customIcon == 'undefined' ? src.icon[this.$options.iconlibrary] : customIcon; + } else { + return src; + } + }, + setFullscreen: function(mode) { + var $editor = this.$editor, + $textarea = this.$textarea; + + if (mode === true) { + $editor.addClass('md-fullscreen-mode'); + $('body').addClass('md-nooverflow'); + this.$options.onFullscreen(this); + } else { + $editor.removeClass('md-fullscreen-mode'); + $('body').removeClass('md-nooverflow'); + this.$options.onFullscreenExit(this); + + if (this.$isPreview === true) + this.hidePreview().showPreview(); + } + + this.$isFullscreen = mode; + $textarea.focus(); + }, + showEditor: function() { + var instance = this, + textarea, + ns = this.$ns, + container = this.$element, + originalHeigth = container.css('height'), + originalWidth = container.css('width'), + editable = this.$editable, + handler = this.$handler, + callback = this.$callback, + options = this.$options, + editor = $('
', { + 'class': 'md-editor', + click: function() { + instance.focus(); + } + }); + + // Prepare the editor + if (this.$editor === null) { + // Create the panel + var editorHeader = $('
', { + 'class': 'md-header btn-toolbar' + }); + + // Merge the main & additional button groups together + var allBtnGroups = []; + if (options.buttons.length > 0) allBtnGroups = allBtnGroups.concat(options.buttons[0]); + if (options.additionalButtons.length > 0) { + // iterate the additional button groups + $.each(options.additionalButtons[0], function(idx, buttonGroup) { + + // see if the group name of the additional group matches an existing group + var matchingGroups = $.grep(allBtnGroups, function(allButtonGroup, allIdx) { + return allButtonGroup.name === buttonGroup.name; + }); + + // if it matches add the additional buttons to that group, if not just add it to the all buttons group + if (matchingGroups.length > 0) { + matchingGroups[0].data = matchingGroups[0].data.concat(buttonGroup.data); + } else { + allBtnGroups.push(options.additionalButtons[0][idx]); + } + + }); + } + + // Reduce and/or reorder the button groups + if (options.reorderButtonGroups.length > 0) { + allBtnGroups = allBtnGroups + .filter(function(btnGroup) { + return options.reorderButtonGroups.indexOf(btnGroup.name) > -1; + }) + .sort(function(a, b) { + if (options.reorderButtonGroups.indexOf(a.name) < options.reorderButtonGroups.indexOf(b.name)) return -1; + if (options.reorderButtonGroups.indexOf(a.name) > options.reorderButtonGroups.indexOf(b.name)) return 1; + return 0; + }); + } + + // Build the buttons + if (allBtnGroups.length > 0) { + editorHeader = this.__buildButtons([allBtnGroups], editorHeader); + } + + if (options.fullscreen.enable) { + editorHeader.append('
').on('click', '.md-control-fullscreen', function(e) { + e.preventDefault(); + instance.setFullscreen(true); + }); + } + + editor.append(editorHeader); + + // Wrap the textarea + if (container.is('textarea')) { + container.before(editor); + textarea = container; + textarea.addClass('md-input'); + editor.append(textarea); + } else { + var rawContent = (typeof toMarkdown == 'function') ? toMarkdown(container.html()) : container.html(), + currentContent = $.trim(rawContent); + + // This is some arbitrary content that could be edited + textarea = $('