refactor: refactor ResizeObserver code, fix code coverage for RO (#101)
* fix: detect ResizeObserver on-demand, fix code coverage for RO * fix: fix test * test: test ro * fix: avoid recalc
This commit is contained in:
parent
e0c7245d5c
commit
b86b8c6b2c
|
@ -2,6 +2,7 @@ import '@testing-library/jest-dom/extend-expect'
|
|||
import FDBFactory from 'fake-indexeddb/build/FDBFactory'
|
||||
import FDBKeyRange from 'fake-indexeddb/build/FDBKeyRange'
|
||||
import { Crypto } from '@peculiar/webcrypto'
|
||||
import { ResizeObserver } from 'd2l-resize-aware/resize-observer-module.js'
|
||||
|
||||
jest.mock('node-fetch', () => require('fetch-mock-jest').sandbox())
|
||||
jest.setTimeout(60000)
|
||||
|
@ -9,6 +10,7 @@ jest.setTimeout(60000)
|
|||
global.fetch = require('node-fetch')
|
||||
global.Response = fetch.Response
|
||||
global.crypto = new Crypto()
|
||||
global.ResizeObserver = ResizeObserver
|
||||
|
||||
process.env.NODE_ENV = 'test'
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ module.exports = {
|
|||
},
|
||||
moduleFileExtensions: ['js', 'svelte'],
|
||||
testPathIgnorePatterns: ['node_modules'],
|
||||
transformIgnorePatterns: ['<rootDir>/node_modules/(?!lodash-es|if-emoji)'],
|
||||
transformIgnorePatterns: ['<rootDir>/node_modules/(?!lodash-es|if-emoji|d2l-resize-aware)'],
|
||||
bail: true,
|
||||
verbose: true,
|
||||
silent: false,
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
"compression": "^1.7.4",
|
||||
"conventional-changelog-cli": "^2.1.1",
|
||||
"cssnano": "^4.1.10",
|
||||
"d2l-resize-aware": "BrightspaceUI/resize-aware#semver:^1.2.2",
|
||||
"emoji-picker-element-data": "^1.0.0",
|
||||
"emojibase-data": "^5.1.1",
|
||||
"express": "^4.17.1",
|
||||
|
|
|
@ -20,7 +20,7 @@ import {
|
|||
} from '../../constants'
|
||||
import { uniqBy } from '../../../shared/uniqBy'
|
||||
import { summarizeEmojisForUI } from '../../utils/summarizeEmojisForUI'
|
||||
import { calculateWidth, resizeObserverSupported } from '../../utils/calculateWidth'
|
||||
import * as widthCalculator from '../../utils/widthCalculator'
|
||||
import { checkZwjSupport } from '../../utils/checkZwjSupport'
|
||||
import { requestPostAnimationFrame } from '../../utils/requestPostAnimationFrame'
|
||||
import { stop } from '../../../shared/marks'
|
||||
|
@ -253,7 +253,7 @@ $: {
|
|||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function calculateEmojiGridWidth (node) {
|
||||
return calculateWidth(node, width => {
|
||||
return widthCalculator.calculateWidth(node, width => {
|
||||
/* istanbul ignore next */
|
||||
const newNumColumns = process.env.NODE_ENV === 'test'
|
||||
? DEFAULT_NUM_COLUMNS
|
||||
|
@ -280,7 +280,7 @@ $: currentGroup = groups[currentGroupIndex]
|
|||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
function calculateIndicatorWidth (node) {
|
||||
return calculateWidth(node, width => {
|
||||
return widthCalculator.calculateWidth(node, width => {
|
||||
computedIndicatorWidth = width
|
||||
})
|
||||
}
|
||||
|
@ -290,14 +290,12 @@ function calculateIndicatorWidth (node) {
|
|||
// So we calculate of the indicator and use exact pixel values in the animation instead
|
||||
// (where ResizeObserver is supported).
|
||||
$: {
|
||||
/* istanbul ignore if */
|
||||
if (resizeObserverSupported) {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
indicatorStyle = `transform: translateX(${currentGroupIndex * computedIndicatorWidth}px);` // exact pixels
|
||||
} else {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
indicatorStyle = `transform: translateX(${currentGroupIndex * 100}%);`// fallback to percent-based
|
||||
}
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
indicatorStyle = `transform: translateX(${
|
||||
widthCalculator.resizeObserverSupported
|
||||
? `${currentGroupIndex * computedIndicatorWidth}px` // exact pixels
|
||||
: `${currentGroupIndex * 100}%` // fallback to percent-based
|
||||
})`
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -4,11 +4,15 @@
|
|||
|
||||
import { requestAnimationFrame } from './requestAnimationFrame'
|
||||
|
||||
export const resizeObserverSupported = typeof ResizeObserver === 'function'
|
||||
export let resizeObserverSupported = typeof ResizeObserver === 'function'
|
||||
|
||||
// only used in jest tests
|
||||
export const resetResizeObserverSupported = () => {
|
||||
resizeObserverSupported = typeof ResizeObserver === 'function'
|
||||
}
|
||||
|
||||
export function calculateWidth (node, onUpdate) {
|
||||
let resizeObserver
|
||||
/* istanbul ignore if */
|
||||
if (resizeObserverSupported) {
|
||||
resizeObserver = new ResizeObserver(entries => (
|
||||
onUpdate(entries[0].contentRect.width)
|
||||
|
@ -22,7 +26,6 @@ export function calculateWidth (node, onUpdate) {
|
|||
|
||||
return {
|
||||
destroy () {
|
||||
/* istanbul ignore if */
|
||||
if (resizeObserver) {
|
||||
resizeObserver.disconnect()
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
import { groups } from '../../../src/picker/groups'
|
||||
import * as testingLibrary from '@testing-library/dom'
|
||||
import {
|
||||
waitFor, getAllByRole,
|
||||
getByRole, fireEvent
|
||||
} from '@testing-library/dom'
|
||||
import { ALL_EMOJI, basicAfterEach, basicBeforeEach, tick, truncatedEmoji } from '../shared'
|
||||
import Picker from '../../../src/picker/PickerElement'
|
||||
import Database from '../../../src/database/Database'
|
||||
import { resetResizeObserverSupported } from '../../../src/picker/utils/widthCalculator'
|
||||
|
||||
// TODO: we can remove these tests when/if we stop supporting browsers without ResizeObserver
|
||||
// https://caniuse.com/resizeobserver
|
||||
|
||||
describe('ResizeObserver unsupported', () => {
|
||||
let picker
|
||||
let container
|
||||
let oldResizeObserver
|
||||
|
||||
beforeEach(async () => {
|
||||
basicBeforeEach()
|
||||
|
||||
oldResizeObserver = global.ResizeObserver
|
||||
delete global.ResizeObserver
|
||||
resetResizeObserverSupported()
|
||||
|
||||
picker = new Picker({ dataSource: ALL_EMOJI })
|
||||
document.body.appendChild(picker)
|
||||
container = picker.shadowRoot.querySelector('.picker')
|
||||
await tick(40)
|
||||
})
|
||||
|
||||
afterEach(async () => {
|
||||
await tick(40)
|
||||
document.body.removeChild(picker)
|
||||
await tick(40)
|
||||
await new Database({ dataSource: ALL_EMOJI }).delete()
|
||||
await tick(40)
|
||||
basicAfterEach()
|
||||
|
||||
global.ResizeObserver = oldResizeObserver
|
||||
resetResizeObserverSupported()
|
||||
})
|
||||
|
||||
test('basic picker test', async () => {
|
||||
const numInGroup1 = truncatedEmoji.filter(_ => _.group === 0).length
|
||||
const numInGroup2 = truncatedEmoji.filter(_ => _.group === 1).length
|
||||
|
||||
await waitFor(() => expect(getByRole(container, 'button', { name: 'Choose a skin tone (currently Default)' })).toBeVisible())
|
||||
expect(getAllByRole(container, 'tab')).toHaveLength(groups.length)
|
||||
|
||||
expect(getByRole(container, 'tab', { name: 'Smileys and emoticons', selected: true })).toBeVisible()
|
||||
await waitFor(() => expect(
|
||||
testingLibrary.getAllByRole(getByRole(container, 'tabpanel'), 'menuitem')).toHaveLength(numInGroup1)
|
||||
)
|
||||
|
||||
expect(getByRole(container, 'tab', { name: 'People and body' })).toBeVisible()
|
||||
fireEvent.click(getByRole(container, 'tab', { name: 'People and body' }))
|
||||
|
||||
await waitFor(() => expect(
|
||||
testingLibrary.getAllByRole(getByRole(container, 'tabpanel'), 'menuitem')).toHaveLength(numInGroup2))
|
||||
|
||||
expect(getByRole(container, 'tab', { name: 'People and body', selected: true })).toBeVisible()
|
||||
})
|
||||
})
|
18
yarn.lock
18
yarn.lock
|
@ -1500,6 +1500,13 @@
|
|||
tslib "^2.0.3"
|
||||
webcrypto-core "^1.1.8"
|
||||
|
||||
"@polymer/polymer@^3.0.0":
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@polymer/polymer/-/polymer-3.4.1.tgz#333bef25711f8411bb5624fb3eba8212ef8bee96"
|
||||
integrity sha512-KPWnhDZibtqKrUz7enIPOiO4ZQoJNOuLwqrhV2MXzIt3VVnUVJVG5ORz4Z2sgO+UZ+/UZnPD0jqY+jmw/+a9mQ==
|
||||
dependencies:
|
||||
"@webcomponents/shadycss" "^1.9.1"
|
||||
|
||||
"@rollup/plugin-commonjs@^16.0.0":
|
||||
version "16.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-16.0.0.tgz#169004d56cd0f0a1d0f35915d31a036b0efe281f"
|
||||
|
@ -1842,6 +1849,11 @@
|
|||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@webcomponents/shadycss@^1.9.1":
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/@webcomponents/shadycss/-/shadycss-1.10.2.tgz#40e03cab6dc5e12f199949ba2b79e02f183d1e7b"
|
||||
integrity sha512-9Iseu8bRtecb0klvv+WXZOVZatsRkbaH7M97Z+f+Pt909R4lDfgUODAnra23DOZTpeMTAkVpf4m/FZztN7Ox1A==
|
||||
|
||||
JSONStream@^1.0.4:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
|
||||
|
@ -3419,6 +3431,12 @@ currently-unhandled@^0.4.1:
|
|||
dependencies:
|
||||
array-find-index "^1.0.1"
|
||||
|
||||
"d2l-resize-aware@BrightspaceUI/resize-aware#semver:^1.2.2":
|
||||
version "1.2.2"
|
||||
resolved "https://codeload.github.com/BrightspaceUI/resize-aware/tar.gz/96ba3ac560380abfb753f128ac9a5c0992d7d723"
|
||||
dependencies:
|
||||
"@polymer/polymer" "^3.0.0"
|
||||
|
||||
dargs@^4.0.1:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17"
|
||||
|
|
Loading…
Reference in New Issue