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

Support Dirty Flag for HTMLInputElement.value #913

Merged
merged 11 commits into from
Sep 1, 2020
Prev Previous commit
Next Next commit
Support dirty flag for HTMLInputElement.value
  • Loading branch information
kristoferbaxter authored and samouri committed Aug 26, 2020
commit ad18039c29471b7356f9d160b465b482e797f549
19 changes: 19 additions & 0 deletions demo/populated/author.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* Copyright 2019 The AMP HTML Authors. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS-IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

document.getElementById('get-value').addEventListener('click', (_) => {
console.log('Prefilled value', document.getElementById('input').value);
});
53 changes: 53 additions & 0 deletions demo/populated/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Empty Initial Element</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="/demo.css" rel="stylesheet">
<style>
body {
font-size: 4em;
}
button {
display: block;
margin: 0.2em 0;
}
input {
font-size: 1em;
margin-top: 0.2em;
border: 1px solid #ccc;
display: block;
}
</style>
<script src="/dist/debug/main.mjs" type="module"></script>
<script src="/dist/debug/main.js" nomodule defer></script>
<!-- This comment block is intended to make it easier to test both the script module and nomodule path -->
<!-- Comment either block to enable module/nomodule or disable it. -->
<!-- <script src="./dist/main.js" defer></script> -->
</head>
<body>
<div src="/populated/author.js" id="upgrade-me">
<input id="input" value="prefilled-value">
<button id="get-value">
Get prefilled value
</button>
</div>
<script type="module">
import {upgradeElement} from '/dist/debug/main.mjs';
upgradeElement(document.getElementById('upgrade-me'), '/dist/debug/worker/worker.mjs');
</script>
<script nomodule async=false defer>
document.addEventListener('DOMContentLoaded', function() {
MainThread.upgradeElement(document.getElementById('upgrade-me'), '/dist/debug/worker/worker.js');
}, false);
</script>
<!-- This comment block is intended to make it easier to test both the script module and nomodule path -->
<!-- Comment either block to enable module/nomodule or disable it. -->
<!-- <script async=false defer>
document.addEventListener('DOMContentLoaded', function() {
MainThread.upgradeElement(document.getElementById('upgrade-me'), '/dist/worker/worker.js');
}, false);
</script> -->
</body>
</html>
10 changes: 6 additions & 4 deletions src/worker-thread/dom/HTMLInputElement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class HTMLInputElement extends HTMLElement {
// and forwarding interaction events to flag "dirtiness".
// https://html.spec.whatwg.org/multipage/input.html#common-input-element-apis
private [TransferrableKeys.value]: string = '';
private dirtyValue: boolean = false;
private [TransferrableKeys.checked]: boolean = false;

// TODO(willchou): There are a few interrelated issues with `value` property.
Expand All @@ -41,13 +42,14 @@ export class HTMLInputElement extends HTMLElement {
// 3. Duplicate MUTATE events. Caused by stale `value` in worker due to no default 'input' listener (see below).

get value(): string {
return this[TransferrableKeys.value];
return !this.dirtyValue ? this.getAttribute('value') || '' : this[TransferrableKeys.value];
}

set value(value: string) {
// Don't early-out if value doesn't appear to have changed.
// The worker may have a stale value since 'input' events aren't being forwarded.
this[TransferrableKeys.value] = String(value);
this.dirtyValue = true;
transfer(this.ownerDocument as Document, [
TransferrableMutationType.PROPERTIES,
this[TransferrableKeys.index],
Expand All @@ -59,7 +61,7 @@ export class HTMLInputElement extends HTMLElement {

get valueAsDate(): Date | null {
// Don't use Date constructor or Date.parse() since ISO 8601 (yyyy-mm-dd) parsing is inconsistent.
const date = this.stringToDate(this[TransferrableKeys.value]);
const date = this.stringToDate(this.value);
const invalid = !date || isNaN(date.getTime());
return invalid ? null : date;
}
Expand All @@ -73,10 +75,10 @@ export class HTMLInputElement extends HTMLElement {
}

get valueAsNumber(): number {
if (this[TransferrableKeys.value].length === 0) {
if (this.value.length === 0) {
return NaN;
}
return Number(this[TransferrableKeys.value]);
return Number(this.value);
}

/** Unlike browsers, does not throw if this input[type] doesn't support numbers. */
Expand Down