Skip to content

Commit

Permalink
fix(components): fix validation in Safari versions before 16.4 (VIV-1568
Browse files Browse the repository at this point in the history
) (#1608)
  • Loading branch information
RichardHelm authored Mar 7, 2024
1 parent 25829cb commit 65e342d
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'element-internals-polyfill';

import { fixture } from '@vivid-nx/shared';
import { customElement, FASTElement } from '@microsoft/fast-element';
import { FormAssociated } from '@microsoft/fast-foundation';
Expand All @@ -22,6 +24,12 @@ describe('Form Elements', function () {
describe('formElements() validate method', () => {
@formElements
class Test extends HTMLElement {
elementInternals: ElementInternals;
constructor() {
super();
this.elementInternals = this.attachInternals();
}

proxy = document.createElement('input');
control = document.createElement('input');

Expand Down Expand Up @@ -103,6 +111,14 @@ describe('Form Elements', function () {
undefined
);
});

it('should not call setValidity when element internals are not supported', () => {
delete (test as any).elementInternals;

test.validate();

expect(test.setValidity).not.toHaveBeenCalled();
});
});

describe('formElements mixin', function () {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ export function formElements<
* field. Our proxy is never interacted with, so the constraint never applies.
* Therefore, we need to use the validity from the actual control in this case.
*
* Additionally, we need to avoid calling setValidity when elementInternals is not available, otherwise the proxy gets
* stuck in an invalid state.
*
* This needs to be done in the original validate method from the FAST FormAssociated mixin.
* We walk up the prototype chain until we find the original method and replace it.
*/
Expand All @@ -59,7 +62,7 @@ export function formElements<
const parentPrototype = Object.getPrototypeOf(currentPrototype);
if (currentPrototype.validate && !parentPrototype.validate) {
currentPrototype.validate = function (anchor?: HTMLElement) {
if (this.proxy instanceof HTMLElement) {
if (this.proxy instanceof HTMLElement && this.elementInternals) {
const isValid = this.proxy.validity.valid;
const controlIsInvalidDueToMinOrMaxLength =
(this.control && this.control.validity)
Expand Down
13 changes: 13 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
"cem-plugin-jsdoc-function": "^0.0.5",
"cem-plugin-readonly": "^0.0.5",
"clean-css": "^5.3.0",
"element-internals-polyfill": "^1.3.10",
"eslint": "8.15.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-ban": "^1.6.0",
Expand Down

0 comments on commit 65e342d

Please sign in to comment.