Skip to content

Commit

Permalink
Merge pull request #185 from marp-team/update-browser-script
Browse files Browse the repository at this point in the history
Update browser script to make changeable the target root
  • Loading branch information
yhatt authored Aug 18, 2020
2 parents 0d113df + 165319c commit d232e37
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 29 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

## [Unreleased]

### Changed

- Upgrade Marpit SVG polyfill to [v1.7.0](https://github.com/marp-team/marpit-svg-polyfill/releases/v1.7.0) ([#184](https://github.com/marp-team/marp-core/pull/184), [#185](https://github.com/marp-team/marp-core/pull/185))
- Update browser script to make changeable the target root ([#185](https://github.com/marp-team/marp-core/pull/185))

### Deprecated

- `observe()` with boolean argument from `@marp-team/marp-core/browser` has been deprecated in favor of the usage of the option object ([#185](https://github.com/marp-team/marp-core/pull/185))

## v1.2.2 - 2020-07-18

### Added
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
},
"dependencies": {
"@marp-team/marpit": "^1.6.2",
"@marp-team/marpit-svg-polyfill": "^1.5.0",
"@marp-team/marpit-svg-polyfill": "^1.7.0",
"emoji-regex": "^9.0.0",
"highlight.js": "^10.1.1",
"katex": "^0.11.1",
Expand Down
6 changes: 4 additions & 2 deletions scripts/browser.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import browser from '../src/browser'
import { browser } from '../src/browser'

browser()
const script = document.currentScript

browser(script ? script.getRootNode() : document)
26 changes: 18 additions & 8 deletions src/browser.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
import observer from './observer'

import { observer } from './observer'
export { observer }

export default function browser(): void {
const marpCoreBrowserScript = Symbol()

export const browser = (target: ParentNode = document): (() => void) => {
if (typeof window === 'undefined') {
throw new Error(
"Marp Core's browser script is valid only in browser context."
)
}

if (window['marpCoreBrowserScript']) {
console.warn("Marp Core's browser script has already executed.")
return
if (target[marpCoreBrowserScript]) return target[marpCoreBrowserScript]

const cleanupObserver = observer({ target })
const cleanup = () => {
cleanupObserver()
delete target[marpCoreBrowserScript]
}

Object.defineProperty(window, 'marpCoreBrowserScript', { value: true })
observer()
Object.defineProperty(target, marpCoreBrowserScript, {
configurable: true,
value: cleanup,
})

return cleanup
}

export default browser
4 changes: 2 additions & 2 deletions src/fitting/observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ const updateAttr = (elm: Element, attr: string, value: string): true | void => {
}
}

export default function fittingObserver(): void {
export default function fittingObserver(target: ParentNode = document): void {
Array.from(
document.querySelectorAll<HTMLElement>(`svg[${attr}="svg"]`),
target.querySelectorAll<HTMLElement>(`svg[${attr}="svg"]`),
(svg) => {
const foreignObject = svg.firstChild as SVGForeignObjectElement
const container = foreignObject.firstChild as HTMLSpanElement
Expand Down
45 changes: 40 additions & 5 deletions src/observer.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,45 @@
import { polyfills } from '@marp-team/marpit-svg-polyfill'
import fittingObserver from './fitting/observer'

// Observer is divided for usage in Marp Web.
export default function observer(keep = true): void {
for (const polyfill of polyfills()) polyfill()
fittingObserver()
type ObserverOptions = {
once?: boolean
target?: ParentNode
}

export function observer(opts?: ObserverOptions): () => void
/** @deprecated Usage of observer() with boolean option has been deprecated. Please replace with the usage of option object. */
export function observer(keep?: boolean): () => void
export function observer(opts: ObserverOptions | boolean = {}): () => void {
const _opts =
typeof opts === 'boolean'
? ((keep): ObserverOptions => {
const once = !keep
console.warn(
`[DEPRECATION WARNING] Usage of observer() with boolean option has been deprecated. Please replace with the usage of option object: observer({ once: ${
once ? 'true' : 'false'
} }).`
)

return { once }
})(opts)
: opts

const { once = false, target = document } = _opts
const polyfillFuncs = polyfills()

if (keep) window.requestAnimationFrame(() => observer(keep))
let enabled = !once

const observer = () => {
for (const polyfill of polyfillFuncs) polyfill({ target })
fittingObserver(target)

if (enabled) window.requestAnimationFrame(observer)
}
observer()

return () => {
enabled = false
}
}

export default observer
5 changes: 3 additions & 2 deletions src/script/browser-script.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
const dummy = 'This is a placeholder for the content of built browser script.'
const placeholder =
'This is a placeholder for the content of built browser script.'

export default dummy
export default placeholder
39 changes: 34 additions & 5 deletions test/browser.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @jest-environment jsdom-fifteen */
// TODO: Use Jest built-in jsdom environment if https://github.com/jsdom/jsdom/issues/2961 was fixed
import browser, { observer } from '../src/browser'
import { browser, observer } from '../src/browser'
import fittingObserver from '../src/fitting/observer'

const polyfill = jest.fn()
Expand All @@ -18,25 +18,54 @@ describe('Browser script', () => {
it('executes observers for polyfill and fitting', () => {
const spy = jest.spyOn(window, 'requestAnimationFrame')

browser()
const cleanup = browser()
expect(spy).toHaveBeenCalledTimes(1)
expect(polyfill).toHaveBeenCalledTimes(1)
expect(fittingObserver).toHaveBeenCalledTimes(1)
expect(browser()).toStrictEqual(cleanup)

const rafFunc = spy.mock.calls[0][0]
rafFunc(performance.now())

spy.mock.calls[0][0](performance.now())
expect(spy).toHaveBeenCalledTimes(2)
expect(polyfill).toHaveBeenCalledTimes(2)
expect(fittingObserver).toHaveBeenCalledTimes(2)

cleanup()
rafFunc(performance.now())
expect(spy).toHaveBeenCalledTimes(2) // No more calling function after cleanup
})

describe('with passed shadow root', () => {
it('calls polyfills and fitting observer with specific target', () => {
const root = document.createElement('div').attachShadow({ mode: 'open' })
const cleanup = browser(root)

expect(polyfill).toHaveBeenCalledWith({ target: root })
expect(fittingObserver).toHaveBeenCalledWith(root)
cleanup()
})
})
})

describe('Observer', () => {
describe('with passed false', () => {
describe('with once option', () => {
it('does not call window.requestAnimationFrame', () => {
const spy = jest.spyOn(window, 'requestAnimationFrame')
const cleanup = observer({ once: true })

expect(spy).not.toHaveBeenCalled()
cleanup()
})
})

describe('[DEPRECATED] with passed false', () => {
it('does not call window.requestAnimationFrame', () => {
const spy = jest.spyOn(window, 'requestAnimationFrame')
const cleanup = observer(false)

observer(false)
expect(spy).not.toHaveBeenCalled()
cleanup()
})
})
})
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -581,10 +581,10 @@
twemoji "^13.0.0"
xss "^1.0.7"

"@marp-team/marpit-svg-polyfill@^1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@marp-team/marpit-svg-polyfill/-/marpit-svg-polyfill-1.5.0.tgz#420db83762914e2dd0f0019300e2ba703deed0a0"
integrity sha512-1JksTIO/Kq3D2FxfoJaBs0Qcq/gvzQqGyEiVNJY+4NfOtUhkGzYyMfGa0ESAkfRCyFZqjrF3WinK+ZILppbJEA==
"@marp-team/marpit-svg-polyfill@^1.5.0", "@marp-team/marpit-svg-polyfill@^1.7.0":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@marp-team/marpit-svg-polyfill/-/marpit-svg-polyfill-1.7.0.tgz#cd4e26f2a66d487bb79db7ea5c651d21e7561d07"
integrity sha512-zgxLmO6ndj7DjYQqJ7i5Re62hkHFdx2j5xMa1plKeU3nmmpldXC4iBPTEuw2K/T3RBbgq9Dm2JViThKZSFbAMQ==

"@marp-team/marpit@^1.6.2":
version "1.6.2"
Expand Down

0 comments on commit d232e37

Please sign in to comment.