diff --git a/addons/web/static/src/js/libs.js b/addons/web/static/src/js/libs.js deleted file mode 100644 index 1a058aee761..00000000000 --- a/addons/web/static/src/js/libs.js +++ /dev/null @@ -1,138 +0,0 @@ -odoo.define('web.libs', function () { -"use strict"; - -/** - * External Libraries Customization - * - * This is the place where we do some slightly crappy libraries customization. - * We are not proud of this, but at least, we try to avoid patching them in - * place. - * - * In an ideal world, this file would not be needed, because external libraries - * would not have bugs, their APIS would be done in a way that we could use them - * as is, and their distribution process would make sure that they are properly - * configured. However, we do not live in such a world, so this file is - * necessary. - */ - -// nvd3 customization -//------------------------------------------------------------------------- -if ('nv' in window) { - nv.dev = false; // sets nvd3 library in production mode - - // monkey patch nvd3 to allow removing eventhandler on windowresize events - // see https://github.com/novus/nvd3/pull/396 for more details - - // Adds a resize listener to the window. - nv.utils.onWindowResize = function(fun) { - if (fun === null) return; - window.addEventListener('resize', fun); - }; - - // Backwards compatibility with current API. - nv.utils.windowResize = nv.utils.onWindowResize; - - // Removes a resize listener from the window. - nv.utils.offWindowResize = function(fun) { - if (fun === null) return; - window.removeEventListener('resize', fun); - }; - - // monkey patch nvd3 to prevent crashes when user changes view and nvd3 - // tries to remove tooltips after 500 ms... seriously nvd3, what were you - // thinking? - nv.tooltip.cleanup = function () { - $('.nvtooltip').remove(); - }; - - // monkey patch nvd3 to prevent it to display a tooltip (position: absolute) - // with a negative `top`; with this patch the highest tooltip's position is - // still in the graph - var originalCalcTooltipPosition = nv.tooltip.calcTooltipPosition; - nv.tooltip.calcTooltipPosition = function () { - var container = originalCalcTooltipPosition.apply(this, arguments); - container.style.top = container.style.top.split('px')[0] < 0 ? 0 + 'px' : container.style.top; - return container; - }; -} - -// Bootstrap customization -//------------------------------------------------------------------------- -/* Bootstrap defaults overwrite */ -$.fn.tooltip.Constructor.DEFAULTS.placement = 'auto top'; -$.fn.tooltip.Constructor.DEFAULTS.html = true; -$.fn.tooltip.Constructor.DEFAULTS.trigger = 'hover focus click'; -$.fn.tooltip.Constructor.DEFAULTS.container = 'body'; -$.fn.tooltip.Constructor.DEFAULTS.delay = { show: 1000, hide: 0 }; -//overwrite bootstrap tooltip method to prevent showing 2 tooltip at the same time -var bootstrap_show_function = $.fn.tooltip.Constructor.prototype.show; -$.fn.modal.Constructor.prototype.enforceFocus = function () { }; -$.fn.tooltip.Constructor.prototype.show = function () { - $('.tooltip').remove(); - //the following fix the bug when using placement - //auto and the parent element does not exist anymore resulting in - //an error. This should be remove once we updade bootstrap to a version that fix the bug - //edit: bug has been fixed here : https://github.com/twbs/bootstrap/pull/13752 - var e = $.Event('show.bs.' + this.type); - var inDom = $.contains(document.documentElement, this.$element[0]); - if (e.isDefaultPrevented() || !inDom) return; - return bootstrap_show_function.call(this); -}; - -// jquery customization -//------------------------------------------------------------------------- -jQuery.expr[":"].Contains = jQuery.expr.createPseudo(function(arg) { - return function( elem ) { - return jQuery(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; - }; -}); - -/** Custom jQuery plugins */ -$.fn.getAttributes = function() { - var o = {}; - if (this.length) { - for (var attr, i = 0, attrs = this[0].attributes, l = attrs.length; i < l; i++) { - attr = attrs.item(i); - o[attr.nodeName] = attr.value; - } - } - return o; -}; -$.fn.openerpBounce = function() { - return this.each(function() { - $(this).css('box-sizing', 'content-box').effect('bounce', {distance: 18, times: 5}, 250); - }); -}; - -// jquery autocomplete tweak to allow html and classnames -var proto = $.ui.autocomplete.prototype; -var initSource = proto._initSource; - -function filter( array, term ) { - var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); - return $.grep( array, function(value_) { - return matcher.test( $( "
" ).html( value_.label || value_.value || value_ ).text() ); - }); -} - -$.extend( proto, { - _initSource: function() { - if ( this.options.html && $.isArray(this.options.source) ) { - this.source = function( request, response ) { - response( filter( this.options.source, request.term ) ); - }; - } else { - initSource.call( this ); - } - }, - - _renderItem: function( ul, item) { - return $( "
  • " ) - .data( "item.autocomplete", item ) - .append( $( "" )[ this.options.html ? "html" : "text" ]( item.label ) ) - .appendTo( ul ) - .addClass(item.classname); - } -}); - -}); diff --git a/addons/web/static/src/js/libs/autocomplete.js b/addons/web/static/src/js/libs/autocomplete.js new file mode 100644 index 00000000000..72f3ee8911b --- /dev/null +++ b/addons/web/static/src/js/libs/autocomplete.js @@ -0,0 +1,38 @@ +odoo.define('web.autocomplete.extensions', function () { +'use strict'; + +/** + * The jquery autocomplete library extensions and fixes should be done here to + * avoid patching in place. + */ + +// jquery autocomplete tweak to allow html and classnames +var proto = $.ui.autocomplete.prototype; +var initSource = proto._initSource; + +function filter( array, term ) { + var matcher = new RegExp( $.ui.autocomplete.escapeRegex(term), "i" ); + return $.grep( array, function (value_) { + return matcher.test( $( "
    " ).html( value_.label || value_.value || value_ ).text() ); + }); +} + +$.extend(proto, { + _initSource: function () { + if ( this.options.html && $.isArray(this.options.source) ) { + this.source = function (request, response) { + response( filter( this.options.source, request.term ) ); + }; + } else { + initSource.call( this ); + } + }, + _renderItem: function (ul, item) { + return $( "
  • " ) + .data( "item.autocomplete", item ) + .append( $( "" )[ this.options.html ? "html" : "text" ]( item.label ) ) + .appendTo( ul ) + .addClass(item.classname); + }, +}); +}); diff --git a/addons/web/static/src/js/libs/bootstrap.js b/addons/web/static/src/js/libs/bootstrap.js new file mode 100644 index 00000000000..04ca2381d7d --- /dev/null +++ b/addons/web/static/src/js/libs/bootstrap.js @@ -0,0 +1,29 @@ +odoo.define('web.bootstrap.extensions', function () { +'use strict'; + +/** + * The bootstrap library extensions and fixes should be done here to avoid + * patching in place. + */ + +/* Bootstrap defaults overwrite */ +$.fn.tooltip.Constructor.DEFAULTS.placement = 'auto top'; +$.fn.tooltip.Constructor.DEFAULTS.html = true; +$.fn.tooltip.Constructor.DEFAULTS.trigger = 'hover focus click'; +$.fn.tooltip.Constructor.DEFAULTS.container = 'body'; +$.fn.tooltip.Constructor.DEFAULTS.delay = { show: 1000, hide: 0 }; +//overwrite bootstrap tooltip method to prevent showing 2 tooltip at the same time +var bootstrap_show_function = $.fn.tooltip.Constructor.prototype.show; +$.fn.modal.Constructor.prototype.enforceFocus = function () { }; +$.fn.tooltip.Constructor.prototype.show = function () { + $('.tooltip').remove(); + //the following fix the bug when using placement + //auto and the parent element does not exist anymore resulting in + //an error. This should be remove once we updade bootstrap to a version that fix the bug + //edit: bug has been fixed here : https://github.com/twbs/bootstrap/pull/13752 + var e = $.Event('show.bs.' + this.type); + var inDom = $.contains(document.documentElement, this.$element[0]); + if (e.isDefaultPrevented() || !inDom) return; + return bootstrap_show_function.call(this); +}; +}); diff --git a/addons/web/static/src/js/libs/jquery.js b/addons/web/static/src/js/libs/jquery.js new file mode 100644 index 00000000000..ace99a0f8d3 --- /dev/null +++ b/addons/web/static/src/js/libs/jquery.js @@ -0,0 +1,98 @@ +odoo.define('web.jquery.extensions', function () { +'use strict'; + +/** + * The jquery library extensions and fixes should be done here to avoid patching + * in place. + */ + +// jQuery selectors extensions +$.extend($.expr[':'], { + containsLike: function (element, index, matches){ + return element.innerHTML.toUpperCase().indexOf(matches[3].toUpperCase()) >= 0; + }, + containsExact: function (element, index, matches){ + return $.trim(element.innerHTML) === matches[3]; + }, + /** + * Note all escaped characters need to be double escaped inside of the + * expression, so "\(" needs to be "\\(" + */ + containsRegex: function (element, index, matches){ + var regreg = /^\/((?:\\\/|[^\/])+)\/([mig]{0,3})$/, + reg = regreg.exec(matches[3]); + return reg ? new RegExp(reg[1], reg[2]).test($.trim(element.innerHTML)) : false; + }, + propChecked: function (element, index, matches) { + return $(element).prop("checked") === true; + }, + propSelected: function (element, index, matches) { + return $(element).prop("selected") === true; + }, + propValue: function (element, index, matches) { + return $(element).prop("value") === matches[3]; + }, + propValueContains: function (element, index, matches) { + return $(element).prop("value") && $(element).prop("value").indexOf(matches[3]) !== -1; + }, + hasData: function (element) { + return !!_.toArray(element.dataset).length; + }, + data: function (element, index, matches) { + return $(element).data(matches[3]); + }, +}); + +// jQuery functions extensions +$.fn.extend({ + /** + * Returns all the attributes of a DOM element (first one in the jQuery + * set). + * + * @returns {Object} attribute name -> attribute value + */ + getAttributes: function () { + var o = {}; + if (this.length) { + var attrs = this[0].attributes; + for (var i = 0, l = attrs.length ; i < l ; i++) { + var attr = attrs.item(i); + o[attr.name] = attr.value; + } + } + return o; + }, + /** + * Makes DOM elements bounce the way Odoo decided it. + */ + odooBounce: function () { + return this.each(function () { + var $elem = $(this); + $elem + .css('box-sizing', 'content-box') + .effect('bounce', {distance: 18, times: 5}, 250, function () { + $elem.css('box-sizing', ''); + }); + }); + }, + /** + * Allows to bind events to a handler just as the standard `$.on` function + * but binds the handler so that it is executed before any already-attached + * handler for the same events. + * + * @see jQuery.on + */ + prependEvent: function (events, selector, data, handler) { + this.on.apply(this, arguments); + + events = events.split(' '); + return this.each(function () { + var el = this; + _.each(events, function (evName) { + var handler = $._data(el, 'events')[evName].pop(); + $._data(el, 'events')[evName].unshift(handler); + }); + }); + }, +}); +}); diff --git a/addons/web/static/src/js/libs/nvd3.js b/addons/web/static/src/js/libs/nvd3.js new file mode 100644 index 00000000000..963a1454c3d --- /dev/null +++ b/addons/web/static/src/js/libs/nvd3.js @@ -0,0 +1,49 @@ +odoo.define('web.nvd3.extensions', function () { +'use strict'; + +/** + * The nvd3 library extensions and fixes should be done here to avoid patching + * in place. + */ + +if (!('nv' in window)) { + return; +} + +nv.dev = false; // sets nvd3 library in production mode + +// monkey patch nvd3 to allow removing eventhandler on windowresize events +// see https://github.com/novus/nvd3/pull/396 for more details + +// Adds a resize listener to the window. +nv.utils.onWindowResize = function (fun) { + if (fun === null) return; + window.addEventListener('resize', fun); +}; + +// Backwards compatibility with current API. +nv.utils.windowResize = nv.utils.onWindowResize; + +// Removes a resize listener from the window. +nv.utils.offWindowResize = function (fun) { + if (fun === null) return; + window.removeEventListener('resize', fun); +}; + +// monkey patch nvd3 to prevent crashes when user changes view and nvd3 +// tries to remove tooltips after 500 ms... seriously nvd3, what were you +// thinking? +nv.tooltip.cleanup = function () { + $('.nvtooltip').remove(); +}; + +// monkey patch nvd3 to prevent it to display a tooltip (position: absolute) +// with a negative `top`; with this patch the highest tooltip's position is +// still in the graph +var originalCalcTooltipPosition = nv.tooltip.calcTooltipPosition; +nv.tooltip.calcTooltipPosition = function () { + var container = originalCalcTooltipPosition.apply(this, arguments); + container.style.top = container.style.top.split('px')[0] < 0 ? 0 + 'px' : container.style.top; + return container; +}; +}); 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 0b85ee8cf42..e9bc8cf2a2a 100644 --- a/addons/web/static/src/js/views/form/form_controller.js +++ b/addons/web/static/src/js/views/form/form_controller.js @@ -339,7 +339,7 @@ var FormController = BasicController.extend({ */ _onBounceEdit: function () { if (this.$buttons) { - this.$buttons.find('.o_form_button_edit').openerpBounce(); + this.$buttons.find('.o_form_button_edit').odooBounce(); } }, /** diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml index 02ddcb28dde..fe23ff89679 100644 --- a/addons/web/views/webclient_templates.xml +++ b/addons/web/views/webclient_templates.xml @@ -59,6 +59,9 @@ + + + @@ -136,6 +139,7 @@ + @@ -171,7 +175,6 @@ - diff --git a/addons/web_editor/static/src/js/snippets.editor.js b/addons/web_editor/static/src/js/snippets.editor.js index f68bf8756bb..e11e3205815 100644 --- a/addons/web_editor/static/src/js/snippets.editor.js +++ b/addons/web_editor/static/src/js/snippets.editor.js @@ -18,15 +18,6 @@ var data = {}; /* ----- SNIPPET SELECTOR ---- */ -$.extend($.expr[':'], { - hasData: function (node) { - return !!_.toArray(node.dataset).length; - }, - data: function (node, i, m) { - return $(node).data(m[3]); - } -}); - data.globalSelector = { closest: function () { return $(); }, all: function () { return $(); }, diff --git a/addons/web_editor/static/src/js/translator.js b/addons/web_editor/static/src/js/translator.js index b2e7aa483fb..9d1ebe94082 100644 --- a/addons/web_editor/static/src/js/translator.js +++ b/addons/web_editor/static/src/js/translator.js @@ -13,21 +13,6 @@ var _t = core._t; var translatable = !!$('html').data('translatable'); var edit_translations = !!$('html').data('edit_translations'); -$.fn.extend({ - prependEvent: function (events, selector, data, handler) { - this.on(events, selector, data, handler); - events = events.split(' '); - this.each(function () { - var el = this; - _.each(events, function (event) { - var handler = $._data(el, 'events')[event].pop(); - $._data(el, 'events')[event].unshift(handler); - }); - }); - return this; - } -}); - var RTE_Translate = rte.Class.extend({ saveElement: function ($el, context) { // remove multi edition diff --git a/addons/web_tour/static/src/js/tour_manager.js b/addons/web_tour/static/src/js/tour_manager.js index 829c06e7dc5..26628e57384 100644 --- a/addons/web_tour/static/src/js/tour_manager.js +++ b/addons/web_tour/static/src/js/tour_manager.js @@ -12,34 +12,6 @@ var _t = core._t; var RUNNING_TOUR_TIMEOUT = 10000; -$.extend($.expr[':'],{ - containsExact: function(element, index, matches){ - return $.trim(element.innerHTML.toLowerCase()) === matches[3].toLowerCase(); - }, - containsExactCase: function(element, index, matches){ - return $.trim(element.innerHTML) === matches[3]; - }, - // Note all escaped characters need to be double escaped - // inside of the containsRegex, so "\(" needs to be "\\(" - containsRegex: function(element, index, matches){ - var regreg = /^\/((?:\\\/|[^\/])+)\/([mig]{0,3})$/, - reg = regreg.exec(matches[3]); - return reg ? new RegExp(reg[1], reg[2]).test($.trim(element.innerHTML)) : false; - }, - propChecked: function(element, index, matches) { - return $(element).prop("checked") === true; - }, - propSelected: function(element, index, matches) { - return $(element).prop("selected") === true; - }, - propValue: function(element, index, matches) { - return $(element).prop("value") === matches[3]; - }, - propValueContains: function(element, index, matches) { - return $(element).prop("value") && $(element).prop("value").indexOf(matches[3]) !== -1; - }, -}); - function get_step_key(name) { return 'tour_' + name + '_step'; } diff --git a/addons/website_event_track/static/src/js/website_event_track.js b/addons/website_event_track/static/src/js/website_event_track.js index ccb080270aa..4fb9baa8215 100644 --- a/addons/website_event_track/static/src/js/website_event_track.js +++ b/addons/website_event_track/static/src/js/website_event_track.js @@ -9,8 +9,8 @@ $(document).ready(function() { $("#search_summary").removeClass('invisible'); if (change_text) { - $("#search_number").text($(".event_track:Contains("+change_text+")").length); - $(".event_track:not(:Contains("+change_text+"))").addClass('invisible'); + $("#search_number").text($(".event_track:containsLike("+change_text+")").length); + $(".event_track:not(:containsLike("+change_text+"))").addClass('invisible'); } else { $("#search_number").text(30); }