PageSourceSearch

https://odoo.coffeefactory.nl/web/static/src/legacy/js/libs/jquery.js

js coffeefactory.nl collected 2026-09-28 05:39:13 UTC 6,182 bytes, 154 lines download raw bytes

1/**
2 * The jquery library extensions and fixes should be done here to avoid patching
3 * in place.
4 */
5
6// jQuery selectors extensions
7$.extend($.expr[':'], {
8    data: function (element, index, matches) {
9        return $(element).data(matches[3]);
10    },
11});
12
13// jQuery functions extensions
14$.fn.extend({
15    /**
16     * Makes DOM elements bounce the way Odoo decided it.
17     *
18     * @param {string} [extraClass]
19     */
20    odooBounce: function (extraClass) {
21        for (const el of this) {
22            el.classList.add('o_catch_attention', extraClass);
23            setTimeout(() => el.classList.remove('o_catch_attention', extraClass), 400);
24        }
25        return this;
26    },
27    /**
28     * Allows to bind events to a handler just as the standard `$.on` function
29     * but binds the handler so that it is executed before any already-attached
30     * handler for the same events.
31     *
32     * @see jQuery.on
33     */
34    prependEvent: function (events, selector, data, handler) {
35        this.on.apply(this, arguments);
36
37        events = events.split(' ');
38        return this.each(function () {
39            var el = this;
40            events.forEach((evNameNamespaced) => {
41                var evName = evNameNamespaced.split('.')[0];
42                var handler = $._data(el, 'events')[evName].pop();
43                $._data(el, 'events')[evName].unshift(handler);
44            });
45        });
46    },
47    /**
48     * @deprecated this will soon be removed: just rely on the fact that the
49     * scrollbar is at its natural position.
50     * @returns {jQuery}
51     */
52    getScrollingElement(document = window.document) {
53        const $baseScrollingElement = $(document.scrollingElement);
54        if ($baseScrollingElement.isScrollable()
55                && $baseScrollingElement.hasScrollableContent()) {
56            return $baseScrollingElement;
57        }
58        const bodyHeight = $(document.body).height();
59        for (const el of document.body.children) {
60            // Search for a body child which is at least as tall as the body
61            // and which has the ability to scroll if enough content in it. If
62            // found, suppose this is the top scrolling element.
63            if (bodyHeight - el.scrollHeight > 1.5) {
64                continue;
65            }
66            const $el = $(el);
67            if ($el.isScrollable()) {
68                return $el;
69            }
70        }
71        return $baseScrollingElement;
72    },
73    /**
74     * @deprecated this will soon be removed: just rely on the fact that the
75     * scrollbar is at its natural position.
76     * @returns {jQuery}
77     */
78    getScrollingTarget(contextItem = window.document) {
79        // Cannot use `instanceof` because of cross-frame issues.
80        const isElement = obj => obj && obj.nodeType === Node.ELEMENT_NODE;
81        const isJQuery = obj => obj && ('jquery' in obj);
82
83        const $scrollingElement = isElement(contextItem)
84            ? $(contextItem)
85            : isJQuery(contextItem)
86            ? contextItem
87            : $().getScrollingElement(contextItem);
88        const document = $scrollingElement[0].ownerDocument;
89        return $scrollingElement.is(document.scrollingElement)
90            ? $(document.defaultView)
91            : $scrollingElement;
92    },
93    /**
94     * @return {boolean}
95     */
96    hasScrollableContent() {
97        return this[0].scrollHeight > this[0].clientHeight;
98    },
99    /**
100     * @returns {boolean}
101     */
102    isScrollable() {
103        if (!this.length) {
104            return false;
105        }
106        const overflow = this.css('overflow-y');
107        const el = this[0];
108        return overflow === 'auto' || overflow === 'scroll'
109            || (overflow === 'visible' && el === el.ownerDocument.scrollingElement);
110    },
111});
112
113// jQuery functions monkey-patching
114
115// Some magic to ensure scrollTop and animate on html/body animate the top level
116// scrollable element even if not html or body. Note: we should consider
117// removing this as it was only really needed when the #wrapwrap was the one
118// with the scrollbar. Although the rest of the code still use
119// getScrollingElement to be generic so this is consistent. Maybe all of this
120// can live on as long as we continue using jQuery a lot. We can decide of the
121// fate of getScrollingElement and related code the moment we get rid of jQuery.
122const originalScrollTop = $.fn.scrollTop;
123$.fn.scrollTop = function (value) {
124    if (value !== undefined && this.filter('html, body').length) {
125        // The caller wants to scroll a set of elements including html and/or
126        // body to a specific point -> do that but make sure to add the real
127        // top level element to that set of elements if any different is found.
128        const $withRealScrollable = this.not('html, body').add($().getScrollingElement(this[0].ownerDocument));
129        originalScrollTop.apply($withRealScrollable, arguments);
130        return this;
131    } else if (value === undefined && this.eq(0).is('html, body')) {
132        // The caller wants to get the scroll point of a set of elements, jQuery
133        // will return the scroll point of the first one, if it is html or body
134        // return the scroll point of the real top level element.
135        return originalScrollTop.apply($().getScrollingElement(this[0].ownerDocument), arguments);
136    }
137    return originalScrollTop.apply(this, arguments);
138};
139const originalAnimate = $.fn.animate;
140$.fn.animate = function (properties, ...rest) {
141    const props = Object.assign({}, properties);
142    if ('scrollTop' in props && this.filter('html, body').length) {
143        // The caller wants to scroll a set of elements including html and/or
144        // body to a specific point -> do that but make sure to add the real
145        // top level element to that set of elements if any different is found.
146        const $withRealScrollable = this.not('html, body').add($().getScrollingElement(this[0].ownerDocument));
147        originalAnimate.call($withRealScrollable, {'scrollTop': props['scrollTop']}, ...rest);
148        delete props['scrollTop'];
149    }
150    if (!Object.keys(props).length) {
151        return this;
152    }
153    return originalAnimate.call(this, props, ...rest);
154};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.