index.js 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. 'use strict';
  2. function cssBlankPseudo(document, opts) {
  3. // configuration
  4. const className = Object(opts).className;
  5. const attr = Object(opts).attr || 'blank';
  6. const force = Object(opts).force;
  7. try {
  8. document.querySelector(':blank');
  9. if (!force) {
  10. return;
  11. }
  12. } catch (ignoredError) {}
  13. /* do nothing and continue */
  14. // observe value changes on <input>, <select>, and <textarea>
  15. const window = (document.ownerDocument || document).defaultView;
  16. observeValueOfHTMLElement(window.HTMLInputElement);
  17. observeValueOfHTMLElement(window.HTMLSelectElement);
  18. observeValueOfHTMLElement(window.HTMLTextAreaElement); // form control elements selector
  19. const selector = 'input,select,textarea'; // conditionally update all form control elements
  20. Array.prototype.forEach.call(document.querySelectorAll(selector), node => {
  21. node.addEventListener('input', configureCssBlankAttribute);
  22. configureCssBlankAttribute.call(node);
  23. }); // conditionally observe added or unobserve removed form control elements
  24. new MutationObserver(mutationsList => {
  25. mutationsList.forEach(mutation => {
  26. if (mutation.addedNodes) {
  27. mutation.addedNodes.forEach(node => {
  28. if (node.nodeType === 1 && node.matches(selector)) {
  29. node.addEventListener('input', configureCssBlankAttribute);
  30. configureCssBlankAttribute.call(node);
  31. }
  32. });
  33. }
  34. if (mutation.removedNodes) {
  35. mutation.removedNodes.forEach(node => {
  36. if (node.nodeType === 1 && node.matches(selector)) {
  37. node.removeEventListener('input', configureCssBlankAttribute);
  38. }
  39. });
  40. }
  41. });
  42. }).observe(document, {
  43. childList: true,
  44. subtree: true
  45. }); // update a form control element’s css-blank attribute
  46. function configureCssBlankAttribute() {
  47. if (this.value) {
  48. if (attr) {
  49. this.removeAttribute(attr);
  50. }
  51. if (className) {
  52. this.classList.remove(className);
  53. }
  54. this.removeAttribute('blank');
  55. } else {
  56. if (attr) {
  57. this.setAttribute('blank', attr);
  58. }
  59. if (className) {
  60. this.classList.add(className);
  61. }
  62. }
  63. } // observe changes to the "value" property on an HTML Element
  64. function observeValueOfHTMLElement(HTMLElement) {
  65. const descriptor = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'value');
  66. const nativeSet = descriptor.set;
  67. descriptor.set = function set(value) {
  68. // eslint-disable-line no-unused-vars
  69. nativeSet.apply(this, arguments);
  70. configureCssBlankAttribute.apply(this);
  71. };
  72. Object.defineProperty(HTMLElement.prototype, 'value', descriptor);
  73. }
  74. }
  75. module.exports = cssBlankPseudo;
  76. //# sourceMappingURL=index.js.map