Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[BREAKING] Align behavior with Primer guidance by default #81

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

Merged
merged 1 commit into from
Mar 24, 2025
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
8 changes: 0 additions & 8 deletions custom-elements.json
Original file line number Diff line number Diff line change
Expand Up @@ -214,14 +214,6 @@
"type": {
"text": "boolean"
}
},
{
"kind": "field",
"name": "onlyValidateOnBlur",
"type": {
"text": "boolean"
},
"readonly": true
}
],
"attributes": [
Expand Down
13 changes: 0 additions & 13 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,6 @@ <h2 tabindex="-1" id="success2" class="success" hidden>Your submission was succe
</auto-check>
<button value="2" name="form">submit</button>
</form>

<h2>only-validate-on-blur with custom validity messages</h2>
<h2 tabindex="-1" id="success3" class="success" hidden>Your submission was successful</h2>
<form id="custom2">
<p>All fields marked with * are required</p>

<label for="simple-field2">Desired username*:</label>
<auto-check csrf="foo" src="/demo" required only-validate-on-blur>
<input id="simple-field2" autofocus name="foo" required aria-describedby="state3" />
<p id="state3" aria-atomic="true" aria-live="polite" class="state"></p>
</auto-check>
<button value="3" name="form">submit</button>
</form>
</main>

<script>
Expand Down
21 changes: 4 additions & 17 deletions src/auto-check-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,6 @@ export class AutoCheckElement extends HTMLElement {
const value = this.getAttribute('validate-on-keystroke')
return value === 'true' || value === ''
}

get onlyValidateOnBlur(): boolean {
const value = this.getAttribute('only-validate-on-blur')
return value === 'true' || value === ''
}
}

function handleChange(checker: () => void, event: Event) {
Expand All @@ -229,12 +224,8 @@ function handleChange(checker: () => void, event: Event) {
if (input.value.length === 0) return

if (
(event.type !== 'blur' && !autoCheckElement.onlyValidateOnBlur) || // Existing default behavior
(event.type === 'blur' &&
autoCheckElement.onlyValidateOnBlur &&
!autoCheckElement.validateOnKeystroke &&
autoCheckElement.hasAttribute('dirty')) || // Only validate on blur if only-validate-on-blur is set, input is dirty, and input is not current validating on keystroke
(event.type === 'input' && autoCheckElement.onlyValidateOnBlur && autoCheckElement.validateOnKeystroke) || // Only validate on key inputs in only-validate-on-blur mode if validate-on-keystroke is set (when input is invalid)
(event.type === 'blur' && !autoCheckElement.validateOnKeystroke && autoCheckElement.hasAttribute('dirty')) || // Only validate on blur if input is dirty and input is not current validating on keystroke
(event.type === 'input' && autoCheckElement.validateOnKeystroke) || // Only validate on key inputs if validate-on-keystroke is set (when input is invalid)
event.type === 'triggervalidation' // Trigger validation manually
) {
setLoadingState(event)
Expand Down Expand Up @@ -359,14 +350,10 @@ async function check(autoCheckElement: AutoCheckElement) {
// To test, ensure that the input only validates on blur
// once it has been "healed" by a valid input after
// previously being in an invalid state.
if (autoCheckElement.onlyValidateOnBlur) {
autoCheckElement.validateOnKeystroke = false
}
autoCheckElement.validateOnKeystroke = false
input.dispatchEvent(new AutoCheckSuccessEvent(response.clone()))
} else {
if (autoCheckElement.onlyValidateOnBlur) {
autoCheckElement.validateOnKeystroke = true
}
autoCheckElement.validateOnKeystroke = true
const event = new AutoCheckErrorEvent(response.clone())
input.dispatchEvent(event)
if (autoCheckElement.required) {
Expand Down
37 changes: 22 additions & 15 deletions test/auto-check.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ describe('auto-check element', function () {
})
})

describe('when only-validate-on-blur is true', function () {
describe('blur event functionality', function () {
let checker
let input

beforeEach(function () {
const container = document.createElement('div')
container.innerHTML = `
<auto-check csrf="foo" src="/success" only-validate-on-blur>
<auto-check csrf="foo" src="/success">
<input>
</auto-check>`
document.body.append(container)
Expand Down Expand Up @@ -137,28 +137,32 @@ describe('auto-check element', function () {
assert.isFalse(input.checkValidity())
})

it('invalidates the input element on keypress', async function () {
it('invalidates the input element on blur', async function () {
const inputEvent = once(input, 'input')
triggerInput(input, 'hub')
triggerBlur(input)
await inputEvent
assert.isFalse(input.checkValidity())
})

it('invalidates input request is in-flight', async function () {
triggerInput(input, 'hub')
triggerBlur(input)
await once(checker, 'loadstart')
assert.isFalse(input.checkValidity())
})

it('invalidates input with failed server response', async function () {
checker.src = '/fail'
triggerInput(input, 'hub')
triggerBlur(input)
await once(input, 'auto-check-complete')
assert.isFalse(input.checkValidity())
})

it('validates input with successful server response', async function () {
triggerInput(input, 'hub')
triggerBlur(input)
await once(input, 'auto-check-complete')
assert.isTrue(input.checkValidity())
})
Expand All @@ -171,6 +175,7 @@ describe('auto-check element', function () {
resolve()
})
triggerInput(input, 'hub')
triggerBlur(input)
})
await send
assert(!input.validity.valid)
Expand All @@ -185,6 +190,7 @@ describe('auto-check element', function () {
resolve()
})
triggerInput(input, 'hub')
triggerBlur(input)
})
await error
assert(!input.validity.valid)
Expand All @@ -197,6 +203,7 @@ describe('auto-check element', function () {
input.value = 'hub'
assert.isTrue(input.checkValidity())
input.dispatchEvent(new InputEvent('input'))
triggerBlur(input)
await once(input, 'auto-check-complete')
assert.isTrue(input.checkValidity())
})
Expand Down Expand Up @@ -268,6 +275,7 @@ describe('auto-check element', function () {

it('validates input with successful server response with GET', async function () {
triggerInput(input, 'hub')
triggerBlur(input)
await once(input, 'auto-check-complete')
assert.isTrue(input.checkValidity())
})
Expand Down Expand Up @@ -306,6 +314,7 @@ describe('auto-check element', function () {

const completed = Promise.all([once(checker, 'loadstart'), once(checker, 'load'), once(checker, 'loadend')])
triggerInput(input, 'hub')
triggerBlur(input)
await completed

assert.deepEqual(['loadstart', 'load', 'loadend'], events)
Expand All @@ -322,6 +331,7 @@ describe('auto-check element', function () {

const completed = Promise.all([once(checker, 'loadstart'), once(checker, 'load'), once(checker, 'loadend')])
triggerInput(input, 'hub')
triggerBlur(input)
await completed

assert.deepEqual(['loadstart', 'load', 'loadend'], events)
Expand Down Expand Up @@ -350,36 +360,30 @@ describe('auto-check element', function () {
input = null
})

it('emits auto-check-send on input', function (done) {
it('emits auto-check-send on blur', function (done) {
input.addEventListener('auto-check-send', () => done())
input.value = 'hub'
input.dispatchEvent(new InputEvent('input'))
})

it('emits auto-check-send on change', function (done) {
input.addEventListener('auto-check-send', () => done())
triggerInput(input, 'hub')
triggerBlur(input)
})

it('emits auto-check-start on input', function (done) {
input.addEventListener('auto-check-start', () => done())
input.value = 'hub'
input.dispatchEvent(new InputEvent('input'))
triggerBlur(input)
})

it('emits auto-check-start on change', function (done) {
input.addEventListener('auto-check-start', () => done())
triggerInput(input, 'hub')
})

it('emits auto-check-send 300 milliseconds after keypress', function (done) {
it('emits auto-check-send 300 milliseconds after blur', function (done) {
input.addEventListener('auto-check-send', () => done())
input.value = 'hub'
input.dispatchEvent(new InputEvent('input'))
triggerBlur(input)
})

it('emits auto-check-success when server responds with 200 OK', async function () {
triggerInput(input, 'hub')
triggerBlur(input)
const event = await once(input, 'auto-check-success')
const result = await event.detail.response.text()
assert.equal('This is a warning', result)
Expand All @@ -388,6 +392,7 @@ describe('auto-check element', function () {
it('emits auto-check-error event when server returns an error response', async function () {
checker.src = '/fail'
triggerInput(input, 'hub')
triggerBlur(input)
const event = await once(input, 'auto-check-error')
const result = await event.detail.response.text()
assert.equal('This is an error', result)
Expand All @@ -396,6 +401,7 @@ describe('auto-check element', function () {
it('emits auto-check-complete event at the end of the lifecycle', function (done) {
input.addEventListener('auto-check-complete', () => done())
triggerInput(input, 'hub')
triggerBlur(input)
})

it('emits auto-check-send event before checking if there is a duplicate request', function (done) {
Expand All @@ -410,6 +416,7 @@ describe('auto-check element', function () {

input.value = 'hub'
input.dispatchEvent(new InputEvent('input'))
triggerBlur(input)
})

it('do not emit if essential attributes are missing', async function () {
Expand Down