Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

element-internals-polyfill

Package Overview
Dependencies
Maintainers
1
Versions
110
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

element-internals-polyfill - npm Package Compare versions

Comparing version 0.0.5 to 0.0.6

7

CHANGELOG.md

@@ -5,2 +5,9 @@ # Changelog

### [0.0.6](https://github.com/calebdwilliams/element-internals-polyfill/compare/v0.0.5...v0.0.6) (2020-04-14)
### Bug Fixes
* **polyfill:** fix setValidity ([ee18f41](https://github.com/calebdwilliams/element-internals-polyfill/commit/ee18f4118b2d54ea482f6c7cdb4ae3ccb6ca6830))
### [0.0.5](https://github.com/calebdwilliams/element-internals-polyfill/compare/v0.0.4...v0.0.5) (2019-11-16)

@@ -7,0 +14,0 @@

357

dist/element-internals.js

@@ -1,199 +0,234 @@

const refMap = new WeakMap();
const validityMap = new WeakMap();
const hiddenInputMap = new WeakMap();
const internalsMap = new WeakMap();
const validationMessageMap = new WeakMap();
(function () {
'use strict';
const observerConfig = { attributes: true };
const refMap = new WeakMap();
const validityMap = new WeakMap();
const hiddenInputMap = new WeakMap();
const internalsMap = new WeakMap();
const validationMessageMap = new WeakMap();
const observer = new MutationObserver(mutationsList => {
for (const mutation of mutationsList) {
const { attributeName, target } = mutation;
const observerConfig = { attributes: true };
if (attributeName === 'disabled' && target.constructor.formAssociated) {
if (target.formDisabledCallback) {
target.formDisabledCallback.bind(target)();
const observer = new MutationObserver(mutationsList => {
for (const mutation of mutationsList) {
const { attributeName, target } = mutation;
if (attributeName === 'disabled' && target.constructor.formAssociated) {
if (target.formDisabledCallback) {
target.formDisabledCallback.apply(target);
}
}
}
}
});
});
const getHostRoot = node => {
if (node instanceof Document) {
return node;
}
let parent = node.parentNode;
if (parent && parent.toString() !== '[object ShadowRoot]') {
parent = getHostRoot(parent);
}
return parent;
};
const getHostRoot = node => {
if (node instanceof Document) {
return node;
}
let parent = node.parentNode;
if (parent && parent.toString() !== '[object ShadowRoot]') {
parent = getHostRoot(parent);
}
return parent;
};
const initRef = (ref, internals) => {
ref.toggleAttribute('form-associated-custom-element', true);
const input = document.createElement('input');
input.type = 'hidden';
input.name = ref.getAttribute('name');
ref.after(input);
hiddenInputMap.set(internals, input);
return observer.observe(ref, observerConfig);
};
const initRef = (ref, internals) => {
ref.toggleAttribute('form-associated-custom-element', true);
const input = document.createElement('input');
input.type = 'hidden';
input.name = ref.getAttribute('name');
ref.after(input);
hiddenInputMap.set(internals, input);
return observer.observe(ref, observerConfig);
};
const initLabels = (ref, labels) => {
Array.from(labels).forEach(label =>
label.addEventListener('click', ref.focus.bind(ref)));
const firstLabelId = `${labels[0].htmlFor}_Label`;
labels[0].id = firstLabelId;
ref.setAttribute('aria-describedby', firstLabelId);
};
const initLabels = (ref, labels) => {
if (labels.length) {
Array.from(labels).forEach(label =>
label.addEventListener('click', ref.focus.bind(ref)));
const firstLabelId = `${labels[0].htmlFor}_Label`;
labels[0].id = firstLabelId;
ref.setAttribute('aria-describedby', firstLabelId);
}
};
const initForm = (ref, form, internals) => {
form.addEventListener('submit', event => {
if (internals.checkValidity() === false) {
event.stopImmediatePropagation();
event.stopPropagation();
event.preventDefault();
const initForm = (ref, form, internals) => {
if (form) {
form.addEventListener('submit', event => {
if (internals.checkValidity() === false) {
event.stopImmediatePropagation();
event.stopPropagation();
event.preventDefault();
}
});
form.addEventListener('reset', () => {
if (ref.constructor.formAssociated && ref.formResetCallback) {
ref.formResetCallback();
}
});
}
});
};
form.addEventListener('reset', () => {
if (ref.constructor.formAssociated && ref.formResetCallback) {
ref.formResetCallback();
const findParentForm = elem => {
let parent = elem.parentNode;
if (parent && parent.tagName !== 'FORM') {
parent = findParentForm(parent);
} else if (!parent && elem.toString() === '[object ShadowRoot]') {
parent = findParentForm(parent.host);
}
});
};
return parent;
};
const findParentForm = elem => {
let parent = elem.parentNode;
if (parent && parent.tagName !== 'FORM') {
parent = findParentForm(parent);
} else if (!parent && elem.toString() === '[object ShadowRoot]') {
parent = findParentForm(parent.host);
class ValidityState {
constructor() {
this.badInput = false;
this.customError = false;
this.patternMismatch = false;
this.rangeOverflow = false;
this.rangeUnderflow = false;
this.stepMismatch = false;
this.tooLong = false;
this.tooShort = false;
this.typeMismatch = false;
this.valid = true;
this.valueMissing = false;
Object.seal(this);
}
}
return parent;
};
const setValid = validityObject => {
validityObject.badInput = false;
validityObject.customError = false;
validityObject.patternMismatch = false;
validityObject.rangeOverflow = false;
validityObject.rangeUnderflow = false;
validityObject.stepMismatch = false;
validityObject.tooLong = false;
validityObject.tooShort = false;
validityObject.typeMismatch = false;
validityObject.valid = true;
validityObject.valueMissing = false;
return validityObject;
};
class ValidityState {
constructor() {
this.badInput = false;
this.customError = false;
this.patternMismatch = false;
this.rangeOverflow = false;
this.rangeUnderflow = false;
this.stepMismatch = false;
this.tooLong = false;
this.tooShort = false;
this.typeMismatch = false;
this.valid = true;
this.valueMissing = false;
const reconcileValidty = (validityObject, newState) => {
validityObject.valid = isValid(newState);
Object.keys(newState).forEach(key => validityObject[key] = newState[key]);
return validityObject;
};
Object.seal(this);
}
}
const isValid = validityState => {
let valid = true;
for (let key in validityState) {
if (key !== 'valid' && validityState[key] !== false) {
valid = false;
}
}
return valid;
};
class ElementInternals {
constructor(ref) {
const validity = new ValidityState();
refMap.set(this, ref);
validityMap.set(this, validity);
internalsMap.set(ref, this);
const { labels, form } = this;
Object.seal(this);
class ElementInternals {
constructor(ref) {
if (!ref || !ref.tagName || ref.tagName.indexOf('-') === -1) {
throw new TypeError('Illegal constructor');
}
const validity = new ValidityState();
refMap.set(this, ref);
validityMap.set(this, validity);
internalsMap.set(ref, this);
const { labels, form } = this;
Object.seal(this);
initRef(ref, this);
initLabels(ref, labels);
initForm(ref, form, this);
}
initRef(ref, this);
initLabels(ref, labels);
initForm(ref, form, this);
}
checkValidity() {
const validity = validityMap.get(this);
return validity.valid;
}
checkValidity() {
const validity = validityMap.get(this);
return validity.valid;
}
get form() {
const ref = refMap.get(this);
let form;
if (ref && ref.constructor.formAssociated === true) {
form = findParentForm(ref);
get form() {
const ref = refMap.get(this);
let form;
if (ref && ref.constructor.formAssociated === true) {
form = findParentForm(ref);
}
return form;
}
return form;
}
get labels() {
const ref = refMap.get(this);
const id = ref.getAttribute('id');
const hostRoot = getHostRoot(ref);
return hostRoot.querySelectorAll(`[for=${id}]`);
}
get labels() {
const ref = refMap.get(this);
const id = ref.getAttribute('id');
const hostRoot = getHostRoot(ref);
return hostRoot.querySelectorAll(`[for=${id}]`);
}
reportValidity() {
// TODO: Figure out how to polyfill this
}
reportValidity() {
// TODO: Figure out how to polyfill this
}
setFormValue(value) {
if (!this.form) {
return;
setFormValue(value) {
if (!this.form) {
return undefined;
}
const hiddenInput = hiddenInputMap.get(this);
hiddenInput.value = value;
}
const hiddenInput = hiddenInputMap.get(this);
hiddenInput.value = value;
}
setValidity(validityChanges = {}, validationMessage = '') {
const validity = validityMap.get(this);
if (Object.keys(validityChanges).length === 0) {
console.log('yes');
validity.valid = true;
for (const key in validity) {
if (key !== 'valid') {
validity[key] = false;
}
setValidity(validityChanges, validationMessage) {
if (!validityChanges) {
throw new TypeError('Failed to execute \'setValidity\' on \'ElementInternals\': 1 argument required, but only 0 present.');
}
} else {
for (const key in validityChanges) {
if (validityChanges.hasOwnProperty(key)) {
const value = validityChanges[key];
validity[key] = validityChanges[key];
const validity = validityMap.get(this);
if (Object.keys(validityChanges).length === 0) {
setValid(validity);
}
const check = { ...validity, ...validityChanges };
delete check.valid;
const { valid } = reconcileValidty(validity, check);
if (value === true && key !== 'valid') {
validity.valid = false;
}
}
if (!valid && !validationMessage) {
throw new DOMException(`Failed to execute 'setValidity' on 'ElementInternals': The second argument should not be empty if one or more flags in the first argument are true.`);
}
validationMessageMap.set(this, valid ? '' : validationMessage);
this.reportValidity();
}
validationMessageMap.set(this, validationMessage);
get validationMessage() {
return validationMessageMap.get(this);
}
this.reportValidity();
}
get validity() {
const validity = validityMap.get(this);
return validity;
}
get validationMessage() {
return validationMessageMap.get(this);
get willValidate() {
const ref = refMap.get(this);
if (ref.disabled || ref.hasAttribute('disabled')) {
return false;
}
return true;
}
}
get validity() {
const validity = validityMap.get(this);
return validity;
}
if (!window.ElementInternals) {
window.ElementInternals = ElementInternals;
get willValidate() {
const ref = refMap.get(this);
if (ref.disabled || ref.hasAttribute('disabled')) {
return false;
}
return true;
Object.defineProperty(HTMLElement.prototype, 'attachInternals', {
get() {
return () => {
if (this.tagName.indexOf('-') === -1) {
throw new Error(`Failed to execute 'attachInternals' on 'HTMLElement': Unable to attach ElementInternals to non-custom elements.`);
}
return new ElementInternals(this);
};
}
});
}
}
if (!window.ElementInternals) {
window.ElementInternals = ElementInternals;
Object.defineProperty(HTMLElement.prototype, 'attachInternals', {
get() {
return () => {
return new ElementInternals(this);
};
}
});
}
export { ElementInternals };
}());
{
"name": "element-internals-polyfill",
"version": "0.0.5",
"version": "0.0.6",
"description": "A polyfill for the element internals specification",

@@ -12,2 +12,4 @@ "main": "/dist/element-internals.js",

"test": "karma start",
"test:watch": "npm run test -- --watch",
"test:coverage": "npm run test -- --coverage",
"start": "rollup -c --watch --environment BUILD:dev",

@@ -42,4 +44,23 @@ "build": "rollup -c --environment BUILD:production",

"devDependencies": {
"@babel/core": "^7.9.0",
"@babel/preset-env": "^7.9.5",
"@open-wc/testing-helpers": "^1.7.1",
"@rollup/plugin-node-resolve": "^7.1.3",
"babel-plugin-istanbul": "^6.0.0",
"babel-plugin-transform-async-to-promises": "^0.8.15",
"karma": "^5.0.1",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage-istanbul-reporter": "^2.1.1",
"karma-detect-browsers": "^2.3.3",
"karma-edge-launcher": "^0.4.2",
"karma-firefox-launcher": "^1.3.0",
"karma-ie-launcher": "^1.0.0",
"karma-jasmine": "^3.1.1",
"karma-rollup-preprocessor": "^7.0.5",
"karma-safari-launcher": "^1.0.0",
"karma-safarinative-launcher": "^1.1.0",
"rollup": "^1.27.0",
"rollup-plugin-livereload": "^1.0.4",
"rollup-plugin-babel": "^4.4.0",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-livereload": "^1.2.0",
"rollup-plugin-serve": "^1.0.1",

@@ -46,0 +67,0 @@ "standard-version": "^7.0.0"

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc