Opened 7 years ago
Last modified 4 years ago
#17588 new defect
dojo/on sometimes interferes with other sites' scripts when using embedded dojo
Reported by: | Matt Senter | Owned by: | |
---|---|---|---|
Priority: | undecided | Milestone: | 1.15 |
Component: | Events | Version: | 1.9.1 |
Keywords: | Cc: | ||
Blocked By: | Blocking: |
Description
Bear with me because this is a very specific use case with a very specific bug (and a fix!) Ok, so, I had a need to embed a custom-built dojo (for example for injecting via Chrome extension.) One of the most important things to consider when doing something like this is to make sure your script does not interfere with any existing scripts, right? Well, I had to customize the build system a bit to make this possible, but even after doing so, some sites still kept getting interference (i.e. "breaking") when my script was injected. I narrowed it down to the use of dojo/on
when adding events to the global window
object.
If you take a look at on.js at line 47 (v1.9.1,) there is a check to see if the target object has its own on()
function, and if so, call it (with a few exceptions for jQuery and Prototype, etc.) The problem was whenever you do something like this:
on(window, "resize", ...)
...the target
references the global window
, and some sites were creating their own on()
method on the global window
object! So, what was happening was that I was throwing resize events into some strange existing global on()
function, which would throw the site's existing script into chaos. Long story short, my attempt to add an event listener was getting short-circuited by the pre-existing script.
The fix: replace the block at line 47 of on.js with something like this:
if(typeof target.on == "function" && typeof type != "function" && !target.nodeType && target != window && target != top && target != parent && target != document){ // delegate to the target's on() method, so it can handle it's own listening if it wants (unless it // is DOM node and we may be dealing with jQuery or Prototype's incompatible addition to the // Element prototype return target.on(type, listener); }
Perhaps there is another method in dojo that helps us determine if an object is a default global javascript object, but I couldn't find it. Ultimately, the goal is to check target
to make sure it is not a default javascript object that normally does not come with its own on()
function. This will allow us to proceed to the on.parse()
call where ultimately something like addEventListener
will be called.
Change History (4)
comment:1 Changed 7 years ago by
comment:2 Changed 7 years ago by
See also #15888 and #17332 (and https://github.com/dojo/dojo/pull/16).
comment:3 Changed 5 years ago by
Milestone: | tbd → 1.12 |
---|
comment:4 Changed 4 years ago by
Milestone: | 1.13 → 1.15 |
---|
Ticket planning... move current 1.13 tickets out to 1.15 to make it easier to move tickets into the 1.13 milestone.
Oh, I forgot to mention a place you could test this: Google Calendar. They create a global
window.on()
function there.