8000 Event: Increase robustness of an inner native event in leverageNative · mgol/jquery@efb6e46 · GitHub
[go: up one dir, main page]

Skip to content
< 8000 script type="application/json" data-target="react-app.embeddedData">{"payload":{"commit":{"oid":"efb6e46cf16e5b9b67ad03e711de418a242853e2","url":"/mgol/jquery/commit/efb6e46cf16e5b9b67ad03e711de418a242853e2","authoredDate":"2024-04-02T17:47:59.000+02:00","committedDate":"2024-04-02T17:47:59.000+02:00","shortMessage":null,"shortMessageMarkdown":"\u003cdiv\u003eEvent: Increase robustness of an inner native event in leverageNative\u003c/div\u003e","shortMessageMarkdownLink":null,"bodyMessageHtml":"In Firefox, alert displayed just before blurring an element dispatches\nthe native blur event twice which tripped the jQuery logic if a jQuery blur\nhandler was not attached before the trigger call.\n\nThis was because the `leverageNative` logic part for triggering first checks if\nsetup was done before (which, for example, is done if a jQuery handler was\nregistered before for this element+event pair) and - if it was not - adds\na dummy handler that just returns `true`. The `leverageNative` logic makes that\n`true` then saved into private data, replacing the previous `saved` array. Since\n`true` passes the truthy check, the second native inner handler treated `true`\nas an array, crashing on the `slice` call.\n\nSince it's impossible to call `alert()` in unit tests, simulate the issue by\nreplacing the `addEventListener` method on a test button with a version that\ncalls attached blur handlers twice.\n\n\u003cspan class=\"issue-keyword tooltipped tooltipped-se\" aria-label=\"This commit closes issue #5459.\"\u003eFixes\u003c/span\u003e \u003ca class=\"issue-link js-issue-link\" data-error-text=\"Failed to load title\" data-id=\"2212814652\" data-permission-text=\"Title is private\" data-url=\"https://github.com/jquery/jquery/issues/5459\" data-hovercard-type=\"issue\" data-hovercard-url=\"/jquery/jquery/issues/5459/hovercard\" href=\"https://github.com/jquery/jquery/issues/5459\"\u003ejquerygh-5459\u003c/a\u003e\nRef \u003ca class=\"issue-link js-issue-link\" data-error-text=\"Failed to load title\" data-id=\"1648464937\" data-permission-text=\"Title is private\" data-url=\"https://github.com/jquery/jquery/issues/5236\" data-hovercard-type=\"pull_request\" data-hovercard-url=\"/jquery/jquery/pull/5236/hovercard\" href=\"https://github.com/jquery/jquery/pull/5236\"\u003ejquerygh-5236\u003c/a\u003e","authors":[{"login":"mgol","displayName":"Michał Gołębiowski-Owczarek","avatarUrl":"https://avatars.githubusercontent.com/u/1758366?v=4","path":"/mgol","isGitHub":false}],"committerAttribution":false,"committer":{"login":"mgol","displayName":"Michał Gołębiowski-Owczarek","avatarUrl":"https://avatars.githubusercontent.com/u/1758366?v=4","path":"/mgol","isGitHub":false},"parents":["284b082eb86602705519d6ca754c40f6d2f8fcc0"],"globalRelayId":"C_kwDOAIHiW9oAKGVmYjZlNDZjZjE2ZTViOWI2N2FkMDNlNzExZGU0MThhMjQyODUzZTI","sha1":"284b082eb86602705519d6ca754c40f6d2f8fcc0","sha2":"efb6e46cf16e5b9b67ad03e711de418a242853e2"},"currentUser":null,"repo":{"id":8512091,"defaultBranch":"main","name":"jquery","ownerLogin":"mgol","currentUserCanPush":false,"isFork":true,"isEmpty":false,"createdAt":"2013-03-01T23:04:07.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/1758366?v=4","public":true,"private":false,"isOrgOwned":false},"diffEntryData":[{"diffLines":[{"stylingDirective":null,"type":"HUNK","blobLineNumber":546,"text":"@@ -547,16 +547,13 @@ function leverageNative( el, type, isSetup ) {","html":"@@ -547,16 +547,13 @@ function leverageNative( el, type, isSetup ) {","displayNoNewLineWarning":false,"position":0,"left":546,"right":546},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":547,"text":" \t\t\t\t// If this is an inner synthetic event for an event with a bubbling surrogate","html":" \t\t\t\t\u003cspan class=pl-c\u003e// If this is an inner synthetic event for an event with a bubbling surrogate\u003c/span\u003e","displayNoNewLineWarning":false,"position":1,"left":547,"right":547},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":548,"text":" \t\t\t\t// (focus or blur), assume that the surrogate already propagated from triggering","html":" \t\t\t\t\u003cspan class=pl-c\u003e// (focus or blur), assume that the surrogate already propagated from triggering\u003c/span\u003e","displayNoNewLineWarning":false,"position":2,"left":548,"right":548},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":549,"text":" \t\t\t\t// the native event and prevent that from happening again here.","html":" \t\t\t\t\u003cspan class=pl-c\u003e// the native event and prevent that from happening again here.\u003c/span\u003e","displayNoNewLineWarning":false,"position":3,"left":549,"right":549},{"stylingDirective":null,"type":"DELETION","blobLineNumber":550,"text":"-\t\t\t\t// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the","html":"-\t\t\t\t\u003cspan class=pl-c\u003e// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the\u003c/span\u003e","displayNoNewLineWarning":false,"position":4,"left":550,"right":549},{"stylingDirective":null,"type":"DELETION","blobLineNumber":551,"text":"-\t\t\t\t// bubbling surrogate propagates *after* the non-bubbling base), but that seems","html":"-\t\t\t\t\u003cspan class=pl-c\u003e// bubbling surrogate propagates *after* the non-bubbling base), but that seems\u003c/span\u003e","displayNoNewLineWarning":false,"position":5,"left":551,"right":549},{"stylingDirective":null,"type":"DELETION","blobLineNumber":552,"text":"-\t\t\t\t// less bad than duplication.","html":"-\t\t\t\t\u003cspan class=pl-c\u003e// less bad than duplication.\u003c/span\u003e","displayNoNewLineWarning":false,"position":6,"left":552,"right":549},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":550,"text":" \t\t\t\t} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {","html":" \t\t\t\t\u003cspan class=pl-kos\u003e}\u003c/span\u003e \u003cspan class=pl-k\u003eelse\u003c/span\u003e \u003cspan class=pl-k\u003eif\u003c/span\u003e \u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-s1\u003ejQuery\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-c1\u003eevent\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-c1\u003especial\u003c/span\u003e\u003cspan class=pl-kos\u003e[\u003c/span\u003e \u003cspan class=pl-s1\u003etype\u003c/span\u003e \u003cspan class=pl-kos\u003e]\u003c/span\u003e \u003cspan class=pl-c1\u003e||\u003c/span\u003e \u003cspan class=pl-kos\u003e{\u003c/span\u003e\u003cspan class=pl-kos\u003e}\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-c1\u003edelegateType\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e \u003cspan class=pl-kos\u003e{\u003c/span\u003e","displayNoNewLineWarning":false,"position":7,"left":553,"right":550},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":551,"text":" \t\t\t\t\tevent.stopPropagation();","html":" \t\t\t\t\t\u003cspan class=pl-s1\u003eevent\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003estopPropagation\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e\u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":8,"left":554,"right":551},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":552,"text":" \t\t\t\t}","html":" \t\t\t\t\u003cspan class=pl-kos\u003e}\u003c/span\u003e","displayNoNewLineWarning":false,"position":9,"left":555,"right":552},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":553,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":10,"left":556,"right":553},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":554,"text":" \t\t\t// If this is a native event triggered above, everything is now in order","html":" \t\t\t\u003cspan class=pl-c\u003e// If this is a native event triggered above, everything is now in order\u003c/span\u003e","displayNoNewLineWarning":false,"position":11,"left":557,"right":554},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":555,"text":" \t\t\t// Fire an inner synthetic event with the original arguments","html":" \t\t\t\u003cspan class=pl-c\u003e// Fire an inner synthetic event with the original arguments\u003c/span\u003e","displayNoNewLineWarning":false,"position":12,"left":558,"right":555},{"stylingDirective":null,"type":"DELETION","blobLineNumber":559,"text":"-\t\t\t} else if ( saved ) {","html":"-\t\t\t\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003esaved\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e","displayNoNewLineWarning":false,"position":13,"left":559,"right":555},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":556,"text":"+\t\t\t} else if ( saved.length ) {","html":"+\t\t\t\u003cspan class=\"pl-kos\"\u003e}\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eelse\u003c/span\u003e \u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e(\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003esaved\u003c/span\u003e\u003cspan class=\"pl-kos x x-first\"\u003e.\u003c/span\u003e\u003cspan class=\"pl-c1 x x-last\"\u003elength\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e)\u003c/span\u003e \u003cspan class=\"pl-kos\"\u003e{\u003c/span\u003e","displayNoNewLineWarning":false,"position":14,"left":559,"right":556},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":557,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":15,"left":560,"right":557},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":558,"text":" \t\t\t\t// ...and capture the result","html":" \t\t\t\t\u003cspan class=pl-c\u003e// ...and capture the result\u003c/span\u003e","displayNoNewLineWarning":false,"position":16,"left":561,"right":558},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":559,"text":" \t\t\t\tdataPriv.set( this, type, jQuery.event.trigger(","html":" \t\t\t\t\u003cspan class=pl-s1\u003edataPriv\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003eset\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-smi\u003ethis\u003c/span\u003e\u003cspan class=pl-kos\u003e,\u003c/span\u003e \u003cspan class=pl-s1\u003etype\u003c/span\u003e\u003cspan class=pl-kos\u003e,\u003c/span\u003e \u003cspan class=pl-s1\u003ejQuery\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-c1\u003eevent\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003etrigger\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e","displayNoNewLineWarning":false,"position":17,"left":562,"right":559}],"diffNumber":0,"diffSize":"0 Bytes","isBinary":false,"isTooBig":false,"collapsed":false,"isSubmodule":false,"lineCount":851,"linesChanged":5,"newTreeEntry":{"lineCount":851,"path":"src/event.js","mode":100644,"isGenerated":false},"oldTreeEntry":{"lineCount":0,"path":"src/event.js","mode":100644},"linesAdded":1,"linesDeleted":4,"path":"src/event.js","pathDigest":"6ecf8b31e1ee3978e25c98049c40661dcd30ad4136093241dfa6462143b5e749","status":"MODIFIED","truncatedReason":null,"oldOid":"284b082eb86602705519d6ca754c40f6d2f8fcc0","newOid":"efb6e46cf16e5b9b67ad03e711de418a242853e2","copilotChatReference":null,"deletedSha":"284b082eb86602705519d6ca754c40f6d2f8fcc0","canToggleRichDiff":false,"defaultToRichDiff":false,"proseDifffHtml":null,"renderInfo":null,"dependencyDiffPath":null,"submodule":null},{"diffLines":[{"stylingDirective":null,"type":"HUNK","blobLineNumber":3492,"text":"@@ -3493,6 +3493,40 @@ QUnit.test( \"trigger(focus) fires native \u0026 jQuery handlers (gh-5015)\", function(","html":"@@ -3493,6 +3493,40 @@ QUnit.test( \u0026quot;trigger(focus) fires native \u0026amp; jQuery handlers (gh-5015)\u0026quot;, function(","displayNoNewLineWarning":false,"position":0,"left":3492,"right":3492},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":3493,"text":" \tinput.trigger( \"focus\" );","html":" \t\u003cspan class=pl-s1\u003einput\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003etrigger\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-s\u003e\u0026quot;focus\u0026quot;\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":1,"left":3493,"right":3493},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":3494,"text":" } );","html":" \u003cspan class=pl-kos\u003e}\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":2,"left":3494,"right":3494},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":3495,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":3,"left":3495,"right":3495},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3496,"text":"+QUnit.test( \"duplicate native blur doesn't crash (gh-5459)\", function( assert ) {","html":"+\u003cspan class=pl-v\u003eQUnit\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003etest\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-s\u003e\u0026quot;duplicate native blur doesn\u0026#39;t crash (gh-5459)\u0026quot;\u003c/span\u003e\u003cspan class=pl-kos\u003e,\u003c/span\u003e \u003cspan class=pl-k\u003efunction\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-s1\u003eassert\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e \u003cspan class=pl-kos\u003e{\u003c/span\u003e","displayNoNewLineWarning":false,"position":4,"left":3495,"right":3496},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3497,"text":"+\tassert.expect( 1 );","html":"+\t\u003cspan class=pl-s1\u003eassert\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003eexpect\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-c1\u003e1\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":5,"left":3495,"right":3497},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3498,"text":"+","html":"+","displayNoNewLineWarning":false,"position":6,"left":3495,"right":3498},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3499,"text":"+\tvar button = jQuery( \"\u003cbutton\u003e\u003c/button\u003e\" ),","html":"+\t\u003cspan class=pl-k\u003evar\u003c/span\u003e \u003cspan class=pl-s1\u003ebutton\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-en\u003ejQuery\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-s\u003e\u0026quot;\u0026lt;button\u0026gt;\u0026lt;/button\u0026gt;\u0026quot;\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e,\u003c/span\u003e","displayNoNewLineWarning":false,"position":7,"left":3495,"right":3499},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3500,"text":"+\t\tnativeAddEvent = button[ 0 ].addEventListener;","html":"+\t\t\u003cspan class=pl-s1\u003enativeAddEvent\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-s1\u003ebutton\u003c/span\u003e\u003cspan class=pl-kos\u003e[\u003c/span\u003e \u003cspan class=pl-c1\u003e0\u003c/span\u003e \u003cspan class=pl-kos\u003e]\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-c1\u003eaddEventListener\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":8,"left":3495,"right":3500},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3501,"text":"+\tbutton.appendTo( \"#qunit-fixture\" );","html":"+\t\u003cspan class=pl-s1\u003ebutton\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003eappendTo\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-s\u003e\u0026quot;#qunit-fixture\u0026quot;\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":9,"left":3495,"right":3501},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3502,"text":"+","html":"+","displayNoNewLineWarning":false,"position":10,"left":3495,"right":3502},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3503,"text":"+\tbutton.on( \"focus\", function() {","html":"+\t\u003cspan class=pl-s1\u003ebutton\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003eon\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-s\u003e\u0026quot;focus\u0026quot;\u003c/span\u003e\u003cspan class=pl-kos\u003e,\u003c/span\u003e \u003cspan class=pl-k\u003efunction\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e\u003cspan class=pl-kos\u003e)\u003c/span\u003e \u003cspan class=pl-kos\u003e{\u003c/span\u003e","displayNoNewLineWarning":false,"position":11,"left":3495,"right":3503},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3504,"text":"+\t\tbutton.trigger( \"blur\" );","html":"+\t\t\u003cspan class=pl-s1\u003ebutton\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003etrigger\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-s\u003e\u0026quot;blur\u0026quot;\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":12,"left":3495,"right":3504},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3505,"text":"+\t\tassert.ok( true, \"Did not crash\" );","html":"+\t\t\u003cspan class=pl-s1\u003eassert\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003eok\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-c1\u003etrue\u003c/span\u003e\u003cspan class=pl-kos\u003e,\u003c/span\u003e \u003cspan class=pl-s\u003e\u0026quot;Did not crash\u0026quot;\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":13,"left":3495,"right":3505},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3506,"text":"+\t} );","html":"+\t\u003cspan class=pl-kos\u003e}\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":14,"left":3495,"right":3506},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3507,"text":"+","html":"+","displayNoNewLineWarning":false,"position":15,"left":3495,"right":3507},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3508,"text":"+\t// Support: Firefox 124+","html":"+\t\u003cspan class=pl-c\u003e// Support: Firefox 124+\u003c/span\u003e","displayNoNewLineWarning":false,"position":16,"left":3495,"right":3508},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3509,"text":"+\t// In Firefox, alert displayed just before blurring an element","html":"+\t\u003cspan class=pl-c\u003e// In Firefox, alert displayed just before blurring an element\u003c/span\u003e","displayNoNewLineWarning":false,"position":17,"left":3495,"right":3509},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3510,"text":"+\t// dispatches the native blur event twice which tripped the jQuery","html":"+\t\u003cspan class=pl-c\u003e// dispatches the native blur event twice which tripped the jQuery\u003c/span\u003e","displayNoNewLineWarning":false,"position":18,"left":3495,"right":3510},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3511,"text":"+\t// logic. We cannot call `alert()` in unit tests; simulate the","html":"+\t\u003cspan class=pl-c\u003e// logic. We cannot call `alert()` in unit tests; simulate the\u003c/span\u003e","displayNoNewLineWarning":false,"position":19,"left":3495,"right":3511},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3512,"text":"+\t// behavior by overwriting the native `addEventListener` with","html":"+\t\u003cspan class=pl-c\u003e// behavior by overwriting the native `addEventListener` with\u003c/span\u003e","displayNoNewLineWarning":false,"position":20,"left":3495,"right":3512},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3513,"text":"+\t// a version that calls blur handlers twice.","html":"+\t\u003cspan class=pl-c\u003e// a version that calls blur handlers twice.\u003c/span\u003e","displayNoNewLineWarning":false,"position":21,"left":3495,"right":3513},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3514,"text":"+\tbutton[ 0 ].addEventListener = function( eventName, handler ) {","html":"+\t\u003cspan class=pl-s1\u003ebutton\u003c/span\u003e\u003cspan class=pl-kos\u003e[\u003c/span\u003e \u003cspan class=pl-c1\u003e0\u003c/span\u003e \u003cspan class=pl-kos\u003e]\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003eaddEventListener\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-k\u003efunction\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-s1\u003eeventName\u003c/span\u003e\u003cspan class=pl-kos\u003e,\u003c/span\u003e \u003cspan class=pl-s1\u003ehandler\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e \u003cspan class=pl-kos\u003e{\u003c/span\u003e","displayNoNewLineWarning":false,"position":22,"left":3495,"right":3514},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3515,"text":"+\t\tvar finalHandler;","html":"+\t\t\u003cspan class=pl-k\u003evar\u003c/span\u003e \u003cspan class=pl-s1\u003efinalHandler\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":23,"left":3495,"right":3515},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3516,"text":"+\t\tif ( eventName === \"blur\" ) {","html":"+\t\t\u003cspan class=pl-k\u003eif\u003c/span\u003e \u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-s1\u003eeventName\u003c/span\u003e \u003cspan class=pl-c1\u003e===\u003c/span\u003e \u003cspan class=pl-s\u003e\u0026quot;blur\u0026quot;\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e \u003cspan class=pl-kos\u003e{\u003c/span\u003e","displayNoNewLineWarning":false,"position":24,"left":3495,"right":3516},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3517,"text":"+\t\t\tfinalHandler = function wrappedHandler() {","html":"+\t\t\t\u003cspan class=pl-s1\u003efinalHandler\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-k\u003efunction\u003c/span\u003e \u003cspan class=pl-en\u003ewrappedHandler\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e\u003cspan class=pl-kos\u003e)\u003c/span\u003e \u003cspan class=pl-kos\u003e{\u003c/span\u003e","displayNoNewLineWarning":false,"position":25,"left":3495,"right":3517},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3518,"text":"+\t\t\t\thandler.apply( this, arguments );","html":"+\t\t\t\t\u003cspan class=pl-s1\u003ehandler\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003eapply\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-smi\u003ethis\u003c/span\u003e\u003cspan class=pl-kos\u003e,\u003c/span\u003e \u003cspan class=pl-smi\u003earguments\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":26,"left":3495,"right":3518},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3519,"text":"+\t\t\t\treturn handler.apply( this, arguments );","html":"+\t\t\t\t\u003cspan class=pl-k\u003ereturn\u003c/span\u003e \u003cspan class=pl-s1\u003ehandler\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003eapply\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-smi\u003ethis\u003c/span\u003e\u003cspan class=pl-kos\u003e,\u003c/span\u003e \u003cspan class=pl-smi\u003earguments\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":27,"left":3495,"right":3519},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3520,"text":"+\t\t\t};","html":"+\t\t\t\u003cspan class=pl-kos\u003e}\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":28,"left":3495,"right":3520},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3521,"text":"+\t\t} else {","html":"+\t\t\u003cspan class=pl-kos\u003e}\u003c/span\u003e \u003cspan class=pl-k\u003eelse\u003c/span\u003e \u003cspan class=pl-kos\u003e{\u003c/span\u003e","displayNoNewLineWarning":false,"position":29,"left":3495,"right":3521},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3522,"text":"+\t\t\tfinalHandler = handler;","html":"+\t\t\t\u003cspan class=pl-s1\u003efinalHandler\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-s1\u003ehandler\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":30,"left":3495,"right":3522},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3523,"text":"+\t\t}","html":"+\t\t\u003cspan class=pl-kos\u003e}\u003c/span\u003e","displayNoNewLineWarning":false,"position":31,"left":3495,"right":3523},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3524,"text":"+\t\treturn nativeAddEvent.call( this, eventName, finalHandler );","html":"+\t\t\u003cspan class=pl-k\u003ereturn\u003c/span\u003e \u003cspan class=pl-s1\u003enativeAddEvent\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003ecall\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-smi\u003ethis\u003c/span\u003e\u003cspan class=pl-kos\u003e,\u003c/span\u003e \u003cspan class=pl-s1\u003eeventName\u003c/span\u003e\u003cspan class=pl-kos\u003e,\u003c/span\u003e \u003cspan class=pl-s1\u003efinalHandler\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":32,"left":3495,"right":3524},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3525,"text":"+\t};","html":"+\t\u003cspan class=pl-kos\u003e}\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":33,"left":3495,"right":3525},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3526,"text":"+","html":"+","displayNoNewLineWarning":false,"position":34,"left":3495,"right":3526},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3527,"text":"+\tbutton.trigger( \"focus\" );","html":"+\t\u003cspan class=pl-s1\u003ebutton\u003c/span\u003e\u003cspan class=pl-kos\u003e.\u003c/span\u003e\u003cspan class=pl-en\u003etrigger\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-s\u003e\u0026quot;focus\u0026quot;\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":35,"left":3495,"right":3527},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3528,"text":"+} );","html":"+\u003cspan class=pl-kos\u003e}\u003c/span\u003e \u003cspan class=pl-kos\u003e)\u003c/span\u003e\u003cspan class=pl-kos\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":36,"left":3495,"right":3528},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":3529,"text":"+","html":"+","displayNoNewLineWarning":false,"position":37,"left":3495,"right":3529},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":3530,"text":" // TODO replace with an adaptation of","html":" \u003cspan class=pl-c\u003e// TODO replace with an adaptation of\u003c/span\u003e","displayNoNewLineWarning":false,"position":38,"left":3496,"right":3530},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":3531,"text":" // https://github.com/jquery/jquery/pull/1367/files#diff-a215316abbaabdf71857809e8673ea28R2464","html":" \u003cspan class=pl-c\u003e// https://github.com/jquery/jquery/pull/1367/files#diff-a215316abbaabdf71857809e8673ea28R2464\u003c/span\u003e","displayNoNewLineWarning":false,"position":39,"left":3497,"right":3531},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":3532,"text":" ( function() {","html":" \u003cspan class=pl-kos\u003e(\u003c/span\u003e \u003cspan class=pl-k\u003efunction\u003c/span\u003e\u003cspan class=pl-kos\u003e(\u003c/span\u003e\u003cspan class=pl-kos\u003e)\u003c/span\u003e \u003cspan class=pl-kos\u003e{\u003c/span\u003e","displayNoNewLineWarning":false,"position":40,"left":3498,"right":3532}],"diffNumber":1,"diffSize":"0 Bytes","isBinary":false,"isTooBig":false,"collapsed":false,"isSubmodule":false,"lineCount":3597,"linesChanged":34,"newTreeEntry":{"lineCount":3597,"path":"test/unit/event.js","mode":100644,"isGenerated":false},"oldTreeEntry":{"lineCount":0,"path":"test/unit/event.js","mode":100644},"linesAdded":34,"linesDeleted":0,"path":"test/unit/event.js","pathDigest":"33e49eecc6e72e95002a32fb85d2cc6b699803bacc62e6d944907d92f903bba1","status":"MODIFIED","truncatedReason":null,"oldOid":"284b082eb86602705519d6ca754c40f6d2f8fcc0","newOid":"efb6e46cf16e5b9b67ad03e711de418a242853e2","copilotChatReference":null,"deletedSha":"284b082eb86602705519d6ca754c40f6d2f8fcc0","canToggleRichDiff":false,"defaultToRichDiff":false,"proseDifffHtml":null,"renderInfo":null,"dependencyDiffPath":null,"submodule":null}],"splitViewPreference":"unified","ignoreWhitespace":false,"commentsPreference":"visible","diffLineSpacingPreference":"relaxed","useMonospaceFont":false,"pasteUrlLinkAsPlainText":false,"userNotices":[],"path":"/mgol/jquery/commit/efb6e46cf16e5b9b67ad03e711de418a242853e2","fileTreeExpanded":true,"headerInfo":{"additions":35,"deletions":4,"filesChanged":2,"filesChangedString":"2"},"moreDiffsToLoad":false,"asyncDiffLoadInfo":{"startIndex":2,"truncated":false,"byteCount":2310,"lineShownCount":59},"commentInfo":{"canComment":false,"locked":false,"canLock":false,"repoArchived":false},"csrf_tokens":{"/users/diffview?diff=split":{"post":"551XtFsadvgMHEo4SF1sZRrfaD1Jjr7uGL0eUWdQOWLqN0d_Ou7LhlzwVqZuEXAGsTjlcMMk4yLc0NQ9aigoLg"},"/users/diffview?diff=unified":{"post":"yLY8FjDoHw4jV3CLmz9u3_wqXIot3lzfw6iGnB5_3sHFHCzdURyicHO7bBW9c3K8V83Rx6d0ARMHxUzwEwfPjQ"},"/notifications/thread":{"post":"Q4JOvaaCLmpxXG4G7xtL6IqrKEJGknPDBssXKp_1qZg6uY2AS1aYnE6MZb-7WvjvMnZdCNL-lReA5ERVcDTqMQ"}}},"title":"Event: Increase robustness of an inner native event in leverageNative · mgol/jquery@efb6e46","appPayload":{"helpUrl":"https://docs.github.com","findInDiffWorkerPath":"/assets-cdn/worker/find-in-diff-worker-6dcb06aa9fad.js","enabled_features":{"diff_ux_refresh_beta":false,"diff_inline_comments":true,"diff_ux_refresh_ssr_five":false,"diff_ux_refresh_ssr_ten":false}}}

Commit efb6e46

Browse files
committed
Event: Increase robustness of an inner native event in leverageNative
In Firefox, alert displayed just before blurring an element dispatches the native blur event twice which tripped the jQuery logic if a jQuery blur handler was not attached before the trigger call. This was because the `leverageNative` logic part for triggering first checks if setup was done before (which, for example, is done if a jQuery handler was registered before for this element+event pair) and - if it was not - adds a dummy handler that just returns `true`. The `leverageNative` logic makes that `true` then saved into private data, replacing the previous `saved` array. Since `true` passes the truthy check, the second native inner handler treated `true` as an array, crashing on the `slice` call. Since it's impossible to call `alert()` in unit tests, simulate the issue by replacing the `addEventListener` method on a test button with a version that calls attached blur handlers twice. Fixes jquerygh-5459 Ref jquerygh-5236
1 parent 284b082 commit efb6e46

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

src/event.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -547,16 +547,13 @@ function leverageNative( el, type, isSetup ) {
547547
// If this is an inner synthetic event for an event with a bubbling surrogate
548548
// (focus or blur), assume that the surrogate already propagated from triggering
549549
// the native event and prevent that from happening again here.
550-
// This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the
551-
// bubbling surrogate propagates *after* the non-bubbling base), but that seems
552-
// less bad than duplication.
553550
} else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) {
554551
event.stopPropagation();
555552
}
556553

557554
// If this is a native event triggered above, everything is now in order
558555
// Fire an inner synthetic event with the original arguments
559-
} else if ( saved ) {
556+
} else if ( saved.length ) {
560557

561558
// ...and capture the result
562559
dataPriv.set( this, type, jQuery.event.trigger(

test/unit/event.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3493,6 +3493,40 @@ QUnit.test( "trigger(focus) fires native & jQuery handlers (gh-5015)", function(
34933493
input.trigger( "focus" );
34943494
} );
34953495

3496+
QUnit.test( "duplicate native blur doesn't crash (gh-5459)", function( assert ) {
3497+
assert.expect( 1 );
3498+
3499+
var button = jQuery( "<button></button>" ),
3500+
nativeAddEvent = button[ 0 ].addEventListener;
3501+
button.appendTo( "#qunit-fixture" );
3502+
3503+
button.on( "focus", function() {
3504+
button.trigger( "blur" );
3505+
assert.ok( true, "Did not crash" );
3506+
} );
3507+
3508+
// Support: Firefox 124+
3509+
// In Firefox, alert displayed just before blurring an element
3510+
// dispatches the native blur event twice which tripped the jQuery
3511+
// logic. We cannot call `alert()` in unit tests; simulate the
3512+
// behavior by overwriting the native `addEventListener` with
3513+
// a version that calls blur handlers twice.
3514+
button[ 0 ].addEventListener = function( eventName, handler ) {
3515+
var finalHandler;
3516+
if ( eventName === "blur" ) {
3517+
finalHandler = function wrappedHandler() {
3518+
handler.apply( this, arguments );
3519+
return handler.apply( this, arguments );
3520+
};
3521+
} else {
3522+
finalHandler = handler;
3523+
}
3524+
return nativeAddEvent.call( this, eventName, finalHandler );
3525+
};
3526+
3527+
button.trigger( "focus" );
3528+
} );
3529+
34963530
// TODO replace with an adaptation of
34973531
// https://github.com/jquery/jquery/pull/1367/files#diff-a215316abbaabdf71857809e8673ea28R2464
34983532
( function() {

0 commit comments

Comments
 (0)
0