@webspatial/core-sdk 1.6.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/iife/index.global.js +3 -3
- package/dist/iife/index.global.js.map +1 -1
- package/dist/index.js +14 -18
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/scene-polyfill.test.ts +60 -0
- package/src/scene-polyfill.ts +15 -17
package/package.json
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
initScene,
|
|
5
5
|
injectSceneHook,
|
|
6
6
|
__getSceneConfigSnapshotForTest,
|
|
7
|
+
hijackWindowATag,
|
|
7
8
|
} from './scene-polyfill'
|
|
8
9
|
import { SpatialSceneCreationOptions } from './types/types'
|
|
9
10
|
import { pointToPhysical } from './physicalMetrics'
|
|
@@ -464,3 +465,62 @@ describe('initScene callback chaining', () => {
|
|
|
464
465
|
expect(cb2).toHaveBeenCalledWith(firstReturn)
|
|
465
466
|
})
|
|
466
467
|
})
|
|
468
|
+
|
|
469
|
+
describe('hijackWindowATag', () => {
|
|
470
|
+
afterEach(() => {
|
|
471
|
+
document.body.innerHTML = ''
|
|
472
|
+
document.onclick = null
|
|
473
|
+
vi.restoreAllMocks()
|
|
474
|
+
})
|
|
475
|
+
|
|
476
|
+
it('handles clicks on nested elements inside anchor tags', () => {
|
|
477
|
+
const openSpy = vi.spyOn(window, 'open').mockImplementation(() => null)
|
|
478
|
+
hijackWindowATag(window)
|
|
479
|
+
|
|
480
|
+
const anchor = document.createElement('a')
|
|
481
|
+
anchor.href = 'https://example.com/detail'
|
|
482
|
+
anchor.target = '_blank'
|
|
483
|
+
|
|
484
|
+
const image = document.createElement('img')
|
|
485
|
+
anchor.appendChild(image)
|
|
486
|
+
document.body.appendChild(anchor)
|
|
487
|
+
|
|
488
|
+
image.dispatchEvent(
|
|
489
|
+
new MouseEvent('click', { bubbles: true, cancelable: true }),
|
|
490
|
+
)
|
|
491
|
+
|
|
492
|
+
expect(openSpy).toHaveBeenCalledWith('https://example.com/detail', '_blank')
|
|
493
|
+
})
|
|
494
|
+
})
|
|
495
|
+
|
|
496
|
+
describe('hijackWindowATag – defaultPrevented', () => {
|
|
497
|
+
afterEach(() => {
|
|
498
|
+
document.body.innerHTML = ''
|
|
499
|
+
document.onclick = null
|
|
500
|
+
vi.restoreAllMocks()
|
|
501
|
+
})
|
|
502
|
+
|
|
503
|
+
it('does not open a new window when the click was already preventDefault-ed', () => {
|
|
504
|
+
const openSpy = vi.spyOn(window, 'open').mockImplementation(() => null)
|
|
505
|
+
hijackWindowATag(window)
|
|
506
|
+
|
|
507
|
+
const anchor = document.createElement('a')
|
|
508
|
+
anchor.href = 'https://example.com/detail'
|
|
509
|
+
anchor.target = '_blank'
|
|
510
|
+
|
|
511
|
+
const span = document.createElement('span')
|
|
512
|
+
anchor.appendChild(span)
|
|
513
|
+
document.body.appendChild(anchor)
|
|
514
|
+
|
|
515
|
+
// Simulate an app-level handler that cancels the click before the polyfill sees it.
|
|
516
|
+
span.addEventListener('click', ev => {
|
|
517
|
+
ev.preventDefault()
|
|
518
|
+
})
|
|
519
|
+
|
|
520
|
+
span.dispatchEvent(
|
|
521
|
+
new MouseEvent('click', { bubbles: true, cancelable: true }),
|
|
522
|
+
)
|
|
523
|
+
|
|
524
|
+
expect(openSpy).not.toHaveBeenCalled()
|
|
525
|
+
})
|
|
526
|
+
})
|
package/src/scene-polyfill.ts
CHANGED
|
@@ -523,23 +523,22 @@ export function hijackWindowOpen(window: WindowProxy) {
|
|
|
523
523
|
export function hijackWindowATag(openedWindow: WindowProxy) {
|
|
524
524
|
openedWindow!.document.onclick = function (e) {
|
|
525
525
|
let element = e.target as HTMLElement | null
|
|
526
|
-
let found = false
|
|
527
526
|
|
|
528
527
|
// Look for <a> element in the clicked elements parents and if found override navigation behavior if needed
|
|
529
|
-
while (
|
|
530
|
-
if (element
|
|
528
|
+
while (element) {
|
|
529
|
+
if (element.tagName == 'A') {
|
|
531
530
|
// When using libraries like react route's <Link> it sets an onclick event, when this happens we should do nothing and let that occur
|
|
532
531
|
|
|
533
532
|
// if onClick is set for the element, the raw onclick will be noop() trapped so the onclick check is no longer trustable
|
|
534
533
|
// we handle all the scenarios
|
|
535
534
|
|
|
536
|
-
if (handleATag(e)) {
|
|
535
|
+
if (handleATag(e, element as HTMLAnchorElement)) {
|
|
537
536
|
return false // prevent default action and stop event propagation
|
|
538
537
|
}
|
|
539
538
|
|
|
540
539
|
return true
|
|
541
540
|
}
|
|
542
|
-
if (element
|
|
541
|
+
if (element.parentElement) {
|
|
543
542
|
element = element.parentElement
|
|
544
543
|
} else {
|
|
545
544
|
break
|
|
@@ -548,18 +547,17 @@ export function hijackWindowATag(openedWindow: WindowProxy) {
|
|
|
548
547
|
}
|
|
549
548
|
}
|
|
550
549
|
|
|
551
|
-
function handleATag(event: MouseEvent) {
|
|
552
|
-
|
|
553
|
-
if (
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
}
|
|
550
|
+
function handleATag(event: MouseEvent, link: HTMLAnchorElement) {
|
|
551
|
+
// Respect clicks that have already been cancelled (e.g. by app/router handlers).
|
|
552
|
+
if (event.defaultPrevented) return false
|
|
553
|
+
// Use the anchor found during bubbling so nested clicks like <a><img /></a> are handled correctly.
|
|
554
|
+
const target = link.target
|
|
555
|
+
const url = link.href
|
|
556
|
+
|
|
557
|
+
if (target && target !== '_self') {
|
|
558
|
+
event.preventDefault()
|
|
559
|
+
window.open(url, target)
|
|
560
|
+
return true
|
|
563
561
|
}
|
|
564
562
|
}
|
|
565
563
|
|