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

Remove dependencies #20

Merged
merged 6 commits into from
Apr 27, 2020
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
10 changes: 0 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,5 @@
"karma-mocha-reporter": "^2.2.5",
"mocha": "^6.2.2"
},
"dependencies": {
"form-data-entries": "^1.0.4",
"selector-set": "^1.1.5"
}
"dependencies": {}
}
40 changes: 25 additions & 15 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
/* @flow strict */

import SelectorSet from 'selector-set'
import formDataEntries from 'form-data-entries'

// Parse HTML text into document fragment.
function parseHTML(document: Document, html: string): DocumentFragment {
const template = document.createElement('template')
Expand All @@ -12,7 +9,7 @@ function parseHTML(document: Document, html: string): DocumentFragment {

function serialize(form: HTMLFormElement): string {
const params = new URLSearchParams()
const entries = 'entries' in FormData.prototype ? new FormData(form).entries() : formDataEntries(form)
const entries = new FormData(form).entries()
for (const [name, value] of [...entries]) {
params.append(name, value.toString())
}
Expand Down Expand Up @@ -65,9 +62,9 @@ type Kicker = {
html: () => Promise<SimpleResponse>
}

export type RemoteFormHandler = (form: HTMLFormElement, kicker: Kicker, req: SimpleRequest) => void | Promise<void>
export type RemoteFormHandler = (form: HTMLFormElement, kicker: Kicker, req: SimpleRequest) => void

let selectorSet: ?SelectorSet<RemoteFormHandler>
let formHandlers: Map<string, RemoteFormHandler[]>

const afterHandlers = []
const beforeHandlers = []
Expand All @@ -81,26 +78,39 @@ export function beforeRemote(fn: (form: HTMLFormElement) => mixed) {
}

export function remoteForm(selector: string, fn: RemoteFormHandler) {
if (!selectorSet) {
selectorSet = new SelectorSet()
if (!formHandlers) {
formHandlers = new Map<string, RemoteFormHandler[]>()
document.addEventListener('submit', handleSubmit)
}
selectorSet.add(selector, fn)
const handlers = formHandlers.get(selector) || []
formHandlers.set(selector, [...handlers, fn])
}

export function remoteUninstall(selector: string, fn: RemoteFormHandler) {
if (selectorSet) {
selectorSet.remove(selector, fn)
if (formHandlers) {
const handlers = formHandlers.get(selector) || []
formHandlers.set(selector, handlers.filter(x => x !== fn))
}
}

function getMatches(el: HTMLElement): RemoteFormHandler[] {
const results = []
for (const selector of formHandlers.keys()) {
if (el.matches(selector)) {
const handlers = formHandlers.get(selector) || []
results.push(...handlers)
}
}
return results
}

function handleSubmit(event: Event) {
if (!(event.target instanceof HTMLFormElement)) {
return
}
const form = event.target
const matches = selectorSet && selectorSet.matches(form)
if (!matches || matches.length === 0) {
const matches = getMatches(form)
if (matches.length === 0) {
return
}

Expand Down Expand Up @@ -143,7 +153,7 @@ function handleSubmit(event: Event) {
// Process each handler sequentially until it either completes or calls the
// kicker function.
async function processHandlers(
matches: Array<*>,
matches: RemoteFormHandler[],
form: HTMLFormElement,
req: SimpleRequest,
kickerPromise: Promise<SimpleResponse>
Expand All @@ -167,7 +177,7 @@ async function processHandlers(
return kick()
}
}
await Promise.race([kickerCalled, match.data.call(null, form, kicker, req)])
await Promise.race([kickerCalled, match(form, kicker, req)])
}
return kickerWasCalled
}
Expand Down
8 changes: 2 additions & 6 deletions test/karma.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,9 @@ function checker(request, response, next) {

module.exports = function(config) {
config.set({
basePath: '..',
frameworks: ['mocha', 'chai'],
files: [
'../node_modules/form-data-entries/index.umd.js',
'../node_modules/selector-set/selector-set.js',
'../dist/index.umd.js',
'test.js'
],
files: [{pattern: 'dist/index.esm.js', type: 'module'}, {pattern: 'test/test.js', type: 'module'}],
reporters: ['mocha'],
port: 9876,
colors: true,
Expand Down
18 changes: 11 additions & 7 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const {remoteForm: _remoteForm, remoteUninstall} = window.remoteForm
import {remoteForm as _remoteForm, remoteUninstall} from '../dist/index.esm.js'

describe('remoteForm', function() {
let htmlForm
Expand Down Expand Up @@ -63,17 +63,21 @@ describe('remoteForm', function() {
})

it('chained handlers', function(done) {
let previousCallbackCalled = false
let callbacksCalled = 0

remoteForm('.remote-widget', async function() {
await new Promise(resolve => setTimeout(resolve, 10))
previousCallbackCalled = true
callbacksCalled++

if (callbacksCalled === 2) {
done()
}
})

remoteForm('.my-remote-form', async function() {
if (previousCallbackCalled) {
callbacksCalled++

if (callbacksCalled === 2) {
done()
} else {
done(new Error('The previous remote form callback was not called'))
}
})

Expand Down