odoo.define('web.dom_ready', function (require) { 'use strict'; return new Promise(function (resolve, reject) { $(resolve); }); }); //============================================================================== odoo.define('web.dom', function (require) { "use strict"; /** * DOM Utility helpers * * We collect in this file some helpers to help integrate various DOM * functionalities with the odoo framework. A common theme in these functions * is the use of the main core.bus, which helps the framework react when * something happens in the DOM. */ var concurrency = require('web.concurrency'); var config = require('web.config'); var core = require('web.core'); var _t = core._t; /** * Private function to notify that something has been attached in the DOM * @param {htmlString or Element or Array or jQuery} [content] the content that * has been attached in the DOM * @params {Array} [callbacks] array of {widget: w, callback_args: args} such * that on_attach_callback() will be called on each w with arguments args */ function _notify(content, callbacks) { callbacks.forEach(function (c) { if (c.widget && c.widget.on_attach_callback) { c.widget.on_attach_callback(c.callback_args); } }); core.bus.trigger('DOM_updated', content); } var dom = { DEBOUNCE: 400, /** * Appends content in a jQuery object and optionnally triggers an event * * @param {jQuery} [$target] the node where content will be appended * @param {htmlString or Element or Array or jQuery} [content] DOM element, * array of elements, HTML string or jQuery object to append to $target * @param {Boolean} [options.in_DOM] true if $target is in the DOM * @param {Array} [options.callbacks] array of objects describing the * callbacks to perform (see _notify for a complete description) */ append: function ($target, content, options) { $target.append(content); if (options && options.in_DOM) { _notify(content, options.callbacks); } }, /** * Detects if 2 elements are colliding. * * @param {Element} el1 * @param {Element} el2 * @returns {boolean} */ areColliding(el1, el2) { const el1Rect = el1.getBoundingClientRect(); const el2Rect = el2.getBoundingClientRect(); return el1Rect.bottom > el2Rect.top && el1Rect.top < el2Rect.bottom && el1Rect.right > el2Rect.left && el1Rect.left < el2Rect.right; }, /** * Autoresize a $textarea node, by recomputing its height when necessary * @param {number} [options.min_height] by default, 50. * @param {Widget} [options.parent] if set, autoresize will listen to some * extra events to decide when to resize itself. This is useful for * widgets that are not in the dom when the autoresize is declared. */ autoresize: function ($textarea, options) { if ($textarea.data("auto_resize")) { return; } var $fixedTextarea; var minHeight; function resize() { $fixedTextarea.insertAfter($textarea); var heightOffset = 0; var style = window.getComputedStyle($textarea[0], null); if (style.boxSizing === 'border-box') { var paddingHeight = parseFloat(style.paddingTop) + parseFloat(style.paddingBottom); var borderHeight = parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth); heightOffset = borderHeight + paddingHeight; } $fixedTextarea.width($textarea.width()); $fixedTextarea.val($textarea.val()); var height = $fixedTextarea[0].scrollHeight; $textarea.css({height: Math.max(height + heightOffset, minHeight)}); } function removeVerticalResize() { // We already compute the correct height: // we don't want the user to resize it vertically. // On Chrome this needs to be called after the DOM is ready. var style = window.getComputedStyle($textarea[0], null); if (style.resize === 'vertical') { $textarea[0].style.resize = 'none'; } else if (style.resize === 'both') { $textarea[0].style.resize = 'horizontal'; } } options = options || {}; minHeight = 'min_height' in options ? options.min_height : 50; $fixedTextarea = $('