From b06e49921bd947f86f3417d57b78c9edc3245ed3 Mon Sep 17 00:00:00 2001 From: wrwrwr Date: Sat, 4 Oct 2014 17:52:21 +0200 Subject: [PATCH 1/2] Fixed shadowing of jQuery referenced by a global ``jQuery`` variable by ``django.jQuery`` in the tabbed admin script. Javascript has a nasty semantic of moving initializers to the beginning of a block, thus rewritting ``var a = a || b`` as ``var a; a = a || b``. With such a code, if ``a`` starts as a global variable with some value, you could think that it would end up having the same value, but it is actually first set to ``undefined`` at the beginning of the block and then always set to ``b`` in the statement [1][2]. This is mostly of importance if you actually have more than one jQuery loaded. For instance, this happens with Mezzanine -- first Grappelli-safe loads a copy, and calls ``$.noConflict`` thus storing its version as ``jQuery``, second is Django, loading another copy and calling ``django.jQuery = jQuery.noConflict(true)``. So far so good, we have one copy on ``jQuery`` and another on ``django.jQuery``; jQuery UI chooses to load itself onto the ``jQuery`` (Grappelli) copy. But now runs the tabbed_translation_fields script, hiding the jQuery with UI loaded at the very beggining of the first block, and a moment later complaining that ``.tabs()`` or something else is not defined. [1]: http://www.ecma-international.org/ecma-262/5.1/#sec-12.2 (note the first paragraph after the grammar) [2]: http://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript (point 8) --- .../static/modeltranslation/js/tabbed_translation_fields.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modeltranslation/static/modeltranslation/js/tabbed_translation_fields.js b/modeltranslation/static/modeltranslation/js/tabbed_translation_fields.js index 8fe9928..6a6dc41 100644 --- a/modeltranslation/static/modeltranslation/js/tabbed_translation_fields.js +++ b/modeltranslation/static/modeltranslation/js/tabbed_translation_fields.js @@ -3,7 +3,9 @@ var google, django, gettext; (function () { - var jQuery = jQuery || $ || django.jQuery; + var t = jQuery || $ || django.jQuery; + jQuery = t; // Note: This is not equivalent to "var jQuery = jQuery || ...". + /* Add a new selector to jQuery that excludes parent items which match a given selector */ jQuery.expr[':'].parents = function(a, i, m) { return jQuery(a).parents(m[3]).length < 1; From 6026a9174157a3db4635d194f92b4fbed0b7f9cd Mon Sep 17 00:00:00 2001 From: wrwrwr Date: Sat, 4 Oct 2014 19:16:18 +0200 Subject: [PATCH 2/2] A more elegant solution suggested by zlorf. --- .../static/modeltranslation/js/tabbed_translation_fields.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modeltranslation/static/modeltranslation/js/tabbed_translation_fields.js b/modeltranslation/static/modeltranslation/js/tabbed_translation_fields.js index 6a6dc41..a0e4266 100644 --- a/modeltranslation/static/modeltranslation/js/tabbed_translation_fields.js +++ b/modeltranslation/static/modeltranslation/js/tabbed_translation_fields.js @@ -3,8 +3,7 @@ var google, django, gettext; (function () { - var t = jQuery || $ || django.jQuery; - jQuery = t; // Note: This is not equivalent to "var jQuery = jQuery || ...". + var jQuery = window.jQuery || $ || django.jQuery; /* Add a new selector to jQuery that excludes parent items which match a given selector */ jQuery.expr[':'].parents = function(a, i, m) {