From 6a9c3e46b114269addd49ce8d4eb5e3c1ee3d55f Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Sun, 5 Jul 2020 22:50:55 +0900 Subject: [PATCH 1/3] Follow zoom factor in parent window if accessible --- src/polyfill.ts | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/polyfill.ts b/src/polyfill.ts index 617a2d8..224b0e8 100644 --- a/src/polyfill.ts +++ b/src/polyfill.ts @@ -22,7 +22,11 @@ export function observe() { export const polyfills = () => navigator.vendor === 'Apple Computer, Inc.' ? [webkit] : [] +let previousZoomFactor: number | undefined = undefined + export function webkit(zoom?: number) { + let changedZoomFactor: false | number = false + Array.from( document.querySelectorAll('svg[data-marpit-svg]'), (svg) => { @@ -31,8 +35,18 @@ export function webkit(zoom?: number) { // NOTE: Safari reflects a zoom level to SVG's currentScale property, but // the other browsers will always return 1. You have to specify the zoom - // factor manually if it is used in outdated Blink engine. (e.g. Electron) - const zoomFactor = zoom || svg.currentScale || 1 + // factor manually if used in outdated Blink engine. (e.g. Electron) + const zoomFactor = + zoom || + (window !== window.parent && + window.parent['marpitSVGPolyfillZoomFactor']) || + svg.currentScale || + 1 + + if (previousZoomFactor !== zoomFactor) { + previousZoomFactor = zoomFactor + changedZoomFactor = zoomFactor + } const width = viewBox.baseVal.width / zoomFactor const height = viewBox.baseVal.height / zoomFactor @@ -48,4 +62,11 @@ export function webkit(zoom?: number) { } } ) + + if (changedZoomFactor !== false) { + Object.defineProperty(window, 'marpitSVGPolyfillZoomFactor', { + configurable: true, + value: changedZoomFactor, + }) + } } From f1cd050b8ce2b0d5ee4b170a679bfa3734ad4c37 Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Thu, 9 Jul 2020 22:11:12 +0900 Subject: [PATCH 2/3] Add tests about zoom factor --- test/polyfill.ts | 66 +++++++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/test/polyfill.ts b/test/polyfill.ts index 0525241..addd2ba 100644 --- a/test/polyfill.ts +++ b/test/polyfill.ts @@ -39,27 +39,9 @@ describe('Marpit SVG polyfill', () => { document.body.innerHTML = marpit.render('').html Array.from(document.querySelectorAll('svg'), (svg: any) => { + jest.spyOn(svg, 'clientWidth', 'get').mockImplementation(() => 640) + jest.spyOn(svg, 'clientHeight', 'get').mockImplementation(() => 360) svg.viewBox = { baseVal: { width: 1280, height: 720 } } - - const foreignObjects = Array.from( - svg.querySelectorAll('foreignObject'), - (foreignObject: any) => { - foreignObject.x = { baseVal: { value: 0 } } - foreignObject.y = { baseVal: { value: 0 } } - - // mock for unsupported `:scope` selector - jest - .spyOn(foreignObject, 'querySelectorAll') - .mockImplementation(() => document.querySelectorAll('section')) - - return foreignObject - } - ) - - // mock for unsupported `:scope` selector - jest - .spyOn(svg, 'querySelectorAll') - .mockImplementation(() => foreignObjects) }) }) @@ -72,23 +54,49 @@ describe('Marpit SVG polyfill', () => { }) it('applies calculated transform style to section elements for scaling', () => { - const sections = document.getElementsByTagName('section') + expect.hasAssertions() - Array.from(sections, (section) => { - const { transform, transformOrigin } = section.style + const sections = document.getElementsByTagName('section') - expect(transformOrigin).toBeFalsy() - expect(transform).not.toContain('scale') + Array.from(sections, ({ style }) => { + expect(style.transformOrigin).toBeFalsy() + expect(style.transform).not.toContain('scale') }) webkit() - Array.from(sections, (section) => { - const { transform, transformOrigin } = section.style + Array.from(sections, ({ style }) => { + expect(style.transformOrigin).toBe('0 0') + expect(style.transform).toContain('scale(0.5)') + }) + }) + + it("takes account of SVG's currentScale property", () => { + expect.hasAssertions() - expect(transformOrigin).toBe('0 0') - expect(transform).toContain('scale') + Array.from(document.querySelectorAll('svg'), (svg) => { + svg.currentScale = 1.25 }) + + webkit() + + Array.from(document.getElementsByTagName('section'), ({ style }) => + expect(style.transform).toContain('scale(0.625)') + ) + }) + + it('prefers the zoom factor defined in parent.marpitSVGPolyfillZoomFactor', () => { + expect.hasAssertions() + + jest.spyOn(window, 'parent', 'get').mockImplementation((): any => ({ + marpitSVGPolyfillZoomFactor: 2, + })) + + webkit() + + Array.from(document.getElementsByTagName('section'), ({ style }) => + expect(style.transform).toContain('scale(1)') + ) }) }) }) From cf60e37461eb71b1cc71af00373889b2bce9954f Mon Sep 17 00:00:00 2001 From: Yuki Hattori Date: Thu, 9 Jul 2020 22:15:44 +0900 Subject: [PATCH 3/3] [ci skip] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea42247..1b95f71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Follow zoom factor of the parent window in `