css.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import { domEach } from '../utils.js';
  2. import { isTag } from 'domhandler';
  3. /**
  4. * Set multiple CSS properties for every matched element.
  5. *
  6. * @category CSS
  7. * @param prop - The names of the properties.
  8. * @param val - The new values.
  9. * @returns The instance itself.
  10. * @see {@link https://api.jquery.com/css/}
  11. */
  12. export function css(prop, val) {
  13. if ((prop != null && val != null) ||
  14. // When `prop` is a "plain" object
  15. (typeof prop === 'object' && !Array.isArray(prop))) {
  16. return domEach(this, (el, i) => {
  17. if (isTag(el)) {
  18. // `prop` can't be an array here anymore.
  19. setCss(el, prop, val, i);
  20. }
  21. });
  22. }
  23. if (this.length === 0) {
  24. return undefined;
  25. }
  26. return getCss(this[0], prop);
  27. }
  28. /**
  29. * Set styles of all elements.
  30. *
  31. * @private
  32. * @param el - Element to set style of.
  33. * @param prop - Name of property.
  34. * @param value - Value to set property to.
  35. * @param idx - Optional index within the selection.
  36. */
  37. function setCss(el, prop, value, idx) {
  38. if (typeof prop === 'string') {
  39. const styles = getCss(el);
  40. const val = typeof value === 'function' ? value.call(el, idx, styles[prop]) : value;
  41. if (val === '') {
  42. delete styles[prop];
  43. }
  44. else if (val != null) {
  45. styles[prop] = val;
  46. }
  47. el.attribs['style'] = stringify(styles);
  48. }
  49. else if (typeof prop === 'object') {
  50. const keys = Object.keys(prop);
  51. for (let i = 0; i < keys.length; i++) {
  52. const k = keys[i];
  53. setCss(el, k, prop[k], i);
  54. }
  55. }
  56. }
  57. function getCss(el, prop) {
  58. if (!el || !isTag(el))
  59. return;
  60. const styles = parse(el.attribs['style']);
  61. if (typeof prop === 'string') {
  62. return styles[prop];
  63. }
  64. if (Array.isArray(prop)) {
  65. const newStyles = {};
  66. for (const item of prop) {
  67. if (styles[item] != null) {
  68. newStyles[item] = styles[item];
  69. }
  70. }
  71. return newStyles;
  72. }
  73. return styles;
  74. }
  75. /**
  76. * Stringify `obj` to styles.
  77. *
  78. * @private
  79. * @category CSS
  80. * @param obj - Object to stringify.
  81. * @returns The serialized styles.
  82. */
  83. function stringify(obj) {
  84. return Object.keys(obj).reduce((str, prop) => `${str}${str ? ' ' : ''}${prop}: ${obj[prop]};`, '');
  85. }
  86. /**
  87. * Parse `styles`.
  88. *
  89. * @private
  90. * @category CSS
  91. * @param styles - Styles to be parsed.
  92. * @returns The parsed styles.
  93. */
  94. function parse(styles) {
  95. styles = (styles || '').trim();
  96. if (!styles)
  97. return {};
  98. const obj = {};
  99. let key;
  100. for (const str of styles.split(';')) {
  101. const n = str.indexOf(':');
  102. // If there is no :, or if it is the first/last character, add to the previous item's value
  103. if (n < 1 || n === str.length - 1) {
  104. const trimmed = str.trimEnd();
  105. if (trimmed.length > 0 && key !== undefined) {
  106. obj[key] += `;${trimmed}`;
  107. }
  108. }
  109. else {
  110. key = str.slice(0, n).trim();
  111. obj[key] = str.slice(n + 1).trim();
  112. }
  113. }
  114. return obj;
  115. }
  116. //# sourceMappingURL=css.js.map