From e88913bd28379206f1a21cfc3934360a3008a066 Mon Sep 17 00:00:00 2001
From: qsm-odoo <qsm@odoo.com>
Date: Fri, 16 Feb 2018 14:54:40 +0100
Subject: [PATCH] [IMP] web, *: do not use 'oe_highlight' and 'oe_link' class
 in the DOM

* test_main_flows

The style of a primary/link button is given by the
'btn-primary'/'btn-link' class. The old 'oe_highlight'/'oe_link'
class should still be supported in views but not rendered in the DOM.
---
 addons/web/static/src/js/core/dialog.js       | 18 +++++-----
 addons/web/static/src/js/core/dom.js          |  7 +++-
 .../src/js/views/form/form_controller.js      | 19 +++++------
 .../static/src/js/views/form/form_renderer.js |  2 +-
 .../src/js/views/list/list_controller.js      |  4 +--
 addons/web/static/src/less/base_settings.less |  4 +--
 addons/web/static/src/less/form_view.less     |  3 --
 addons/web/static/src/less/webclient.less     |  4 ---
 addons/web/static/tests/views/form_tests.js   | 34 +++++++++----------
 .../test_main_flows/static/src/js/tour.js     |  2 +-
 10 files changed, 47 insertions(+), 50 deletions(-)

diff --git a/addons/web/static/src/js/core/dialog.js b/addons/web/static/src/js/core/dialog.js
index 5ba24f57cad8..7d4796886b70 100644
--- a/addons/web/static/src/js/core/dialog.js
+++ b/addons/web/static/src/js/core/dialog.js
@@ -158,9 +158,9 @@ var Dialog = Widget.extend({
 
     /**
      * Show a dialog
-     * 
+     *
      * @param {Object} options
-     * @param {boolean} options.shouldFocusButtons  if true, put the focus on 
+     * @param {boolean} options.shouldFocusButtons  if true, put the focus on
      * the first button primary when the dialog opens
      */
     open: function (options) {
@@ -194,7 +194,7 @@ var Dialog = Widget.extend({
         if (this.isDestroyed()) {
             return;
         }
-        var isFocusSet = this._focusOnClose(); 
+        var isFocusSet = this._focusOnClose();
 
         this._super();
 
@@ -214,7 +214,7 @@ var Dialog = Widget.extend({
         }
     },
     /**
-     * adds the keydown behavior to the dialogs after external files modifies 
+     * adds the keydown behavior to the dialogs after external files modifies
      * its DOM.
      */
     rebindButtonBehavior: function () {
@@ -226,7 +226,7 @@ var Dialog = Widget.extend({
     /**
      * Manages the focus when the dialog closes. The default behavior is to set the focus on the top-most opened popup.
      * The goal of this function is to be overridden by all children of the dialog class.
-     * 
+     *
      * @returns: boolean  should return true if the focus has already been set else false.
      */
     _focusOnClose: function() {
@@ -237,7 +237,7 @@ var Dialog = Widget.extend({
     //--------------------------------------------------------------------------
     /**
      * Moves the focus to the first button primary in the footer of the dialog
-     * 
+     *
      * @private
      * @param {odooEvent} e
      */
@@ -250,17 +250,17 @@ var Dialog = Widget.extend({
         }
     },
     /**
-     * Manages the TAB key on the buttons. If you the focus is on a primary 
+     * Manages the TAB key on the buttons. If you the focus is on a primary
      * button and the users tries to tab to go to the next button, display
      * a tooltip
-     * 
+     *
      * @param {jQueryEvent} e
      * @private
      */
     _onFooterButtonKeyDown: function (e) {
         switch(e.which) {
             case $.ui.keyCode.TAB:
-                if (!e.shiftKey && (e.target.classList.contains("btn-primary") || e.target.classList.contains("oe_highlight"))) {
+                if (!e.shiftKey && e.target.classList.contains("btn-primary")) {
                     e.preventDefault();
                     var $primaryButton = $(e.target);
                     $primaryButton.tooltip({
diff --git a/addons/web/static/src/js/core/dom.js b/addons/web/static/src/js/core/dom.js
index 274f82bcc538..5335ef8e9548 100644
--- a/addons/web/static/src/js/core/dom.js
+++ b/addons/web/static/src/js/core/dom.js
@@ -221,7 +221,12 @@ return {
     renderButton: function (options) {
         var params = options.attrs || {};
         params.type = params.type || 'button';
-        params.class = 'btn btn-' + (options.size || 'sm') + ' ' + (params.class || 'btn-default');
+        var classes = 'btn-default';
+        if (params.class) {
+            classes = params.class.replace(/\boe_highlight\b/g, 'btn-primary')
+                                  .replace(/\boe_link\b/g, 'btn-link');
+        }
+        params.class = 'btn btn-' + (options.size || 'sm') + ' ' + classes;
         var $button = $('<button/>', params);
         if (options.icon) {
             if (options.icon.substr(0, 3) === 'fa-') {
diff --git a/addons/web/static/src/js/views/form/form_controller.js b/addons/web/static/src/js/views/form/form_controller.js
index e66194dcf994..dbb64dc36820 100644
--- a/addons/web/static/src/js/views/form/form_controller.js
+++ b/addons/web/static/src/js/views/form/form_controller.js
@@ -50,8 +50,9 @@ var FormController = BasicController.extend({
     autofocus: function () {
         if (!this.disableAutofocus) {
             var isControlActivted = this.renderer.autofocus();
-            if (!isControlActivted) { 
-                // this can happen in read mode if there are no button with class oe_highlight
+            if (!isControlActivted) {
+                // this can happen in read mode if there are no buttons with
+                // btn-primary class
                 if (this.$buttons && this.mode === 'readonly') {
                     return this.$buttons.find('.o_form_button_edit').focus();
                 }
@@ -239,7 +240,7 @@ var FormController = BasicController.extend({
     /**
      * Assign on the buttons save and discard additionnal behavior to facilitate
      * the work of the users doing input only using the keyboard
-     * 
+     *
      * @param {jQueryElement} $saveCancelButtonContainer  The div containing the
      * save and cancel buttons
      * @private
@@ -257,9 +258,7 @@ var FormController = BasicController.extend({
                     self._discardChanges.apply(self);
                     break;
                 case $.ui.keyCode.TAB:
-                    if (!e.shiftKey && 
-                        (e.target.classList.contains("btn-primary") || 
-                         e.target.classList.contains("oe_highlight"))) {
+                    if (!e.shiftKey && e.target.classList.contains("btn-primary")) {
                         $saveCancelButtonContainer.tooltip('show');
                         e.preventDefault();
                     }
@@ -491,11 +490,11 @@ var FormController = BasicController.extend({
      */
     _onDoAction: function (event) {
         var self=this;
-        // A priori, different widgets could write on the "on_success" key. 
+        // A priori, different widgets could write on the "on_success" key.
         // Below we ensure that all the actions required by those widgets
         // are executed in a suitable order before every cycle of destruction.
         var callback = event.data.on_success || function () {};
-        event.data.on_success = function () { 
+        event.data.on_success = function () {
             callback();
             function isDialog (widget) {
                 return (widget instanceof Dialog);
@@ -542,7 +541,7 @@ var FormController = BasicController.extend({
     },
     /**
      * Set the focus on the first primary button of the controller (likely Edit)
-     * 
+     *
      * @private
      * @param {OdooEvent} event
      */
@@ -554,7 +553,7 @@ var FormController = BasicController.extend({
     },
     /**
      * Reset the focus on the control that openned a Dialog after it was closed
-     * 
+     *
      * @private
      * @param {OdooEvent} event
      */
diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js
index 3f8c343d599d..ddae62ca3583 100644
--- a/addons/web/static/src/js/views/form/form_renderer.js
+++ b/addons/web/static/src/js/views/form/form_renderer.js
@@ -55,7 +55,7 @@ var FormRenderer = BasicRenderer.extend({
      */
     autofocus: function () {
         if (this.mode === 'readonly') {
-            var firstPrimaryFormButton =  this.$el.find('button.oe_highlight:enabled:visible:first()');
+            var firstPrimaryFormButton =  this.$el.find('button.btn-primary:enabled:visible:first()');
             if (firstPrimaryFormButton.length > 0) {
                 return firstPrimaryFormButton.focus();
             } else {
diff --git a/addons/web/static/src/js/views/list/list_controller.js b/addons/web/static/src/js/views/list/list_controller.js
index 3262196fa511..b42da9665ade 100644
--- a/addons/web/static/src/js/views/list/list_controller.js
+++ b/addons/web/static/src/js/views/list/list_controller.js
@@ -232,7 +232,7 @@ var ListController = BasicController.extend({
     },
     /**
      * Assign on the buttons create additionnal behavior to facilitate the work of the users doing input only using the keyboard
-     * 
+     *
      * @param {jQueryElement} $createButton  The create button itself
      */
     _assignCreateKeyboardBehavior: function($createButton) {
@@ -249,7 +249,7 @@ var ListController = BasicController.extend({
                     self.renderer.giveFocus();
                     break;
                 case $.ui.keyCode.TAB:
-                    if (!e.shiftKey && (e.target.classList.contains("btn-primary") || e.target.classList.contains("oe_highlight"))) {
+                    if (!e.shiftKey && e.target.classList.contains("btn-primary")) {
                         e.preventDefault();
                         $createButton.tooltip('show');
                     }
diff --git a/addons/web/static/src/less/base_settings.less b/addons/web/static/src/less/base_settings.less
index 74ef6472aeff..426d8cb557ca 100644
--- a/addons/web/static/src/less/base_settings.less
+++ b/addons/web/static/src/less/base_settings.less
@@ -63,11 +63,11 @@
             margin: 0;
             border: 0;
 
-            .oe_highlight, .oe_link  {
+            .btn-primary, .btn-link  {
                 padding: @padding-small-vertical @padding-small-horizontal;
             }
 
-            .oe_link {
+            .btn-link {
                 .o-hover-text-color(@link-color, @link-hover-color);
             }
         }
diff --git a/addons/web/static/src/less/form_view.less b/addons/web/static/src/less/form_view.less
index c36fe2d0d9a8..1e477aac02d2 100644
--- a/addons/web/static/src/less/form_view.less
+++ b/addons/web/static/src/less/form_view.less
@@ -12,9 +12,6 @@
     .oe_text_center {
         text-align: center;
     }
-    .oe_link {
-        .btn-link;
-    }
     .oe_grey {
         opacity: 0.5;
     }
diff --git a/addons/web/static/src/less/webclient.less b/addons/web/static/src/less/webclient.less
index e1344ee49e6f..1de198d282b3 100644
--- a/addons/web/static/src/less/webclient.less
+++ b/addons/web/static/src/less/webclient.less
@@ -69,10 +69,6 @@
     outline: none;
 }
 
-.oe_highlight {
-    .btn-primary;
-}
-
 // Boolean Toggle widget
 div.o_boolean_toggle {
     position: relative;
diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js
index ce206777ac50..534fa4fbea99 100644
--- a/addons/web/static/tests/views/form_tests.js
+++ b/addons/web/static/tests/views/form_tests.js
@@ -6703,9 +6703,9 @@ QUnit.module('Views', {
             model: 'partner',
             data: this.data,
             arch:'<form>' +
-                    '<field name="product_ids">' + 
-                        '<tree><field name="partner_type_id"/></tree>' + 
-                        '<form><field name="partner_type_id"/></form>' + 
+                    '<field name="product_ids">' +
+                        '<tree><field name="partner_type_id"/></tree>' +
+                        '<form><field name="partner_type_id"/></form>' +
                     '</field>' +
                 '</form>',
             res_id: 1,
@@ -6723,7 +6723,7 @@ QUnit.module('Views', {
         });
         // Open one2many
         form.$('.o_data_row').click();
-        assert.strictEqual($('.modal-content').length, 1, "a popup window should have opened");       
+        assert.strictEqual($('.modal-content').length, 1, "a popup window should have opened");
         // Click on many2one and trigger do_action
         $('.modal-content a[name="partner_type_id"]').click();
         assert.strictEqual($('.modal-content').length, 0, "the popup window should have closed");
@@ -6749,14 +6749,14 @@ QUnit.module('Views', {
             data: this.data,
             arch:'<form>' +
                         '<field name="p">' +
-                            '<tree><field name="display_name"/></tree>' + 
+                            '<tree><field name="display_name"/></tree>' +
                         '</field>' +
                 '</form>',
             archs: {
                 'partner,false,form': '<form><field name="product_ids">' +
                                             '<tree><field name="partner_type_id"/></tree>' +
                                             '<form><field name="partner_type_id"/></form>' +
-                                        '</field></form>', 
+                                        '</field></form>',
             },
             res_id: 1,
             mockRPC: function (route, args) {
@@ -6874,8 +6874,8 @@ QUnit.module('Views', {
             arch: '<form string="Partners">' +
                     '<field name="state" invisible="1"/>' +
                     '<header>' +
-                        '<button name="post" class="oe_highlight firstButton" string="Confirm" type="object"/>' +
-                        '<button name="post" class="oe_highlight secondButton" string="Confirm2" type="object"/>' +
+                        '<button name="post" class="btn-primary firstButton" string="Confirm" type="object"/>' +
+                        '<button name="post" class="btn-primary secondButton" string="Confirm2" type="object"/>' +
                     '</header>' +
                     '<sheet>' +
                         '<group>' +
@@ -6907,8 +6907,8 @@ QUnit.module('Views', {
             arch: '<form string="Partners">' +
                     '<field name="state" invisible="1"/>' +
                     '<header>' +
-                        '<button name="post" class="oe_highlight firstButton" string="Confirm" type="object"/>' +
-                        '<button name="post" class="oe_highlight secondButton" string="Confirm2" type="object"/>' +
+                        '<button name="post" class="btn-primary firstButton" string="Confirm" type="object"/>' +
+                        '<button name="post" class="btn-primary secondButton" string="Confirm2" type="object"/>' +
                     '</header>' +
                     '<sheet>' +
                         '<group>' +
@@ -6946,14 +6946,14 @@ QUnit.module('Views', {
                         '</group>' +
                     '</sheet>' +
                 '</form>',
-            res_id: 2,           
+            res_id: 2,
             //debug:1,
         });
         assert.strictEqual(form.$buttons.find('.o_form_button_edit')[0],document.activeElement,
-                        "in read mode, when there are no primary buttons on the form, the default button with the focus should be edit");        
+                        "in read mode, when there are no primary buttons on the form, the default button with the focus should be edit");
         form.destroy();
     });
-    
+
     QUnit.test('In Edition mode, when an attribute is dynamically required (and not required), TAB should navigate to the next field', function (assert) {
         assert.expect(1);
 
@@ -7040,7 +7040,7 @@ QUnit.module('Views', {
                 '</form>',
             viewOptions: {
                 mode: 'edit',
-            },            
+            },
             mockRPC: function (route, args) {
                 if (args.method === 'create') {
                     assert.ok(true, "should call the /create route");
@@ -7066,7 +7066,7 @@ QUnit.module('Views', {
                 '</form>',
             viewOptions: {
                 mode: 'edit',
-            },            
+            },
             mockRPC: function (route, args) {
                 if (args.method === 'create') {
                     assert.ok(true, "should call the /create route");
@@ -7092,7 +7092,7 @@ QUnit.module('Views', {
                 '</form>',
             viewOptions: {
                 mode: 'edit',
-            },            
+            },
             mockRPC: function (route, args) {
                 if (args.method === 'default_get') {
                     assert.ok(true, "should call the /create route");
@@ -7118,7 +7118,7 @@ QUnit.module('Views', {
                 '</form>',
             viewOptions: {
                 mode: 'edit',
-            },            
+            },
             mockRPC: function (route, args) {
                 if (args.method === 'default_get') {
                     assert.ok(true, "should call the /create route");
diff --git a/odoo/addons/test_main_flows/static/src/js/tour.js b/odoo/addons/test_main_flows/static/src/js/tour.js
index 20037b201717..db50cc362600 100644
--- a/odoo/addons/test_main_flows/static/src/js/tour.js
+++ b/odoo/addons/test_main_flows/static/src/js/tour.js
@@ -524,7 +524,7 @@ tour.register('main_flow_tour', {
     content: _t("Check availability"),
     position: "bottom",
 }, {
-    trigger: ".o_statusbar_buttons > button.oe_highlight:enabled:contains('Produce')",
+    trigger: ".o_statusbar_buttons > button.btn-primary:enabled:contains('Produce')",
     content: _t("Produce"),
     position: "bottom",
 }, {
-- 
GitLab