Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Options Pseudo #158

Merged
merged 3 commits into from
Mar 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions src/vanilla/__tests__/optionsPseudo.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { OptionsPseudo } from '../components/optionsPseudo'

const invalidPseudoJson = `'Invalid JSON here'`
const validPseudoJson = `'{ "draggable": false }'`
const node = document.createElement('div')
let pseudoContentValue: string

const mockGetComputedStyle = (): void => {
Object.defineProperty(window, 'getComputedStyle', {
value: (elt: Element, pseudoElt?: string | null | undefined) => ({
content: pseudoElt === ':before' ? pseudoContentValue : 'none',
}),
})
}

beforeEach(() => {
mockGetComputedStyle()
})

describe('OptionsPseudo', () => {
describe('When the pseudo element property "content" contains', () => {
test('Invalid JSON, it does not throw', () => {
pseudoContentValue = invalidPseudoJson
expect(OptionsPseudo(node).get).not.toThrow()
})

test('Invalid JSON, it returns an empty object', () => {
pseudoContentValue = invalidPseudoJson
expect(OptionsPseudo(node).get()).toEqual({})
})

test('Has valid JSON, it parses the JSON and returns its contents', () => {
pseudoContentValue = validPseudoJson
expect(OptionsPseudo(node).get()).toEqual({ draggable: false })
})
})
})
2 changes: 0 additions & 2 deletions src/vanilla/components/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { ScrollContainOptionType } from './scrollContain'

export type OptionsType = {
align: AlignmentOptionType
autoResize: boolean
axis: AxisOptionType
containScroll: ScrollContainOptionType
direction: DirectionOptionType
Expand All @@ -23,7 +22,6 @@ export type OptionsType = {

export const defaultOptions: OptionsType = {
align: 'center',
autoResize: true,
axis: 'x',
containScroll: '',
direction: 'ltr',
Expand Down
21 changes: 21 additions & 0 deletions src/vanilla/components/optionsPseudo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { EmblaOptionsType } from './options'

export type OptionsPseudoType = {
get: () => EmblaOptionsType
}

export function OptionsPseudo(node: HTMLElement): OptionsPseudoType {
const psuedoString = window.getComputedStyle(node, ':before').content

function get(): EmblaOptionsType {
try {
return JSON.parse(psuedoString.slice(1, -1).replace(/\\/g, ''))
} catch (error) {} // eslint-disable-line no-empty
return {}
}

const self: OptionsPseudoType = {
get,
}
return self
}
27 changes: 13 additions & 14 deletions src/vanilla/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Engine } from './components/engine'
import { EventStore } from './components/eventStore'
import { defaultOptions, EmblaOptionsType } from './components/options'
import { OptionsPseudo, OptionsPseudoType } from './components/optionsPseudo'
import { addClass, debounce, removeClass } from './components/utils'
import {
EventEmitter,
Expand Down Expand Up @@ -44,32 +45,32 @@ function EmblaCarousel(
let engine: Engine
let activated = false
let options = Object.assign({}, defaultOptions)
let optionsPseudo: OptionsPseudoType
let rootNodeSize = 0
let container: HTMLElement
let slides: HTMLElement[]

activate(userOptions)

function storeElements(): void {
function setupElements(): void {
if (!sliderRoot) throw new Error('Missing root node 😢')

const sliderContainer = sliderRoot.querySelector('*')
if (!sliderContainer) throw new Error('Missing container node 😢')

container = sliderContainer as HTMLElement
slides = Array.prototype.slice.call(container.children)
optionsPseudo = OptionsPseudo(sliderRoot)
}

function activate(partialOptions?: EmblaOptionsType): void {
storeElements()
options = Object.assign(options, partialOptions)
setupElements()
options = Object.assign(options, partialOptions, optionsPseudo.get())
engine = Engine(sliderRoot, container, slides, options, events)
eventStore.add(window, 'resize', debouncedResize)
engine.translate.to(engine.location)
rootNodeSize = engine.axis.measureSize(sliderRoot.getBoundingClientRect())

if (options.autoResize) {
rootNodeSize = engine.axis.measureSize(sliderRoot.getBoundingClientRect())
}
if (options.loop) {
if (!engine.slideLooper.canLoop()) {
deActivate()
Expand Down Expand Up @@ -113,8 +114,8 @@ function EmblaCarousel(
const { selectedClass } = options
const inView = slidesInView(true)
const notInView = slidesNotInView(true)
notInView.forEach((i) => removeClass(slides[i], selectedClass))
inView.forEach((i) => addClass(slides[i], selectedClass))
notInView.forEach((index) => removeClass(slides[index], selectedClass))
inView.forEach((index) => addClass(slides[index], selectedClass))
}

function deActivate(): void {
Expand All @@ -125,7 +126,7 @@ function EmblaCarousel(
engine.translate.clear()
engine.slideLooper.clear(slides)
removeClass(sliderRoot, options.draggableClass)
slides.forEach((s) => removeClass(s, options.selectedClass))
slides.forEach((slide) => removeClass(slide, options.selectedClass))
events.off('select', toggleSelectedClass)
events.off('pointerUp', toggleSelectedClass)
events.off('pointerDown', toggleDraggingClass)
Expand All @@ -150,10 +151,8 @@ function EmblaCarousel(

function resize(): void {
if (!activated) return
if (options.autoResize) {
const size = engine.axis.measureSize(sliderRoot.getBoundingClientRect())
if (rootNodeSize !== size) reActivate()
}
const size = engine.axis.measureSize(sliderRoot.getBoundingClientRect())
if (rootNodeSize !== size) reActivate()
events.emit('resize')
}

Expand All @@ -165,7 +164,7 @@ function EmblaCarousel(

function slidesNotInView(target?: boolean): number[] {
const inView = slidesInView(target)
return engine.slideIndexes.filter((i) => inView.indexOf(i) === -1)
return engine.slideIndexes.filter((index) => inView.indexOf(index) === -1)
}

function scrollTo(index: number, direction?: number): void {
Expand Down