get-element-spec.js 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import standards from '../../standards';
  2. import matchesFn from '../../commons/matches';
  3. /**
  4. * Return the spec for an HTML element from the standards object. Since the spec is determined by the node and what attributes it has, a node is required.
  5. * @param {VirtualNode} vNode The VirtualNode to get the spec for.
  6. * @return {Object} The standard spec object
  7. */
  8. function getElementSpec(vNode) {
  9. const standard = standards.htmlElms[vNode.props.nodeName];
  10. // invalid element name (could be an svg or custom element name)
  11. if (!standard) {
  12. return {};
  13. }
  14. if (!standard.variant) {
  15. return standard;
  16. }
  17. // start with the information at the top level
  18. const { variant, ...spec } = standard;
  19. // loop through all variants (excluding default) finding anything
  20. // that matches
  21. for (const variantName in variant) {
  22. if (!variant.hasOwnProperty(variantName) || variantName === 'default') {
  23. continue;
  24. }
  25. const { matches, ...props } = variant[variantName];
  26. if (matchesFn(vNode, matches)) {
  27. for (const propName in props) {
  28. if (props.hasOwnProperty(propName)) {
  29. spec[propName] = props[propName];
  30. }
  31. }
  32. }
  33. }
  34. // apply defaults if properties were not found
  35. for (const propName in variant.default) {
  36. if (
  37. variant.default.hasOwnProperty(propName) &&
  38. typeof spec[propName] === 'undefined'
  39. ) {
  40. spec[propName] = variant.default[propName];
  41. }
  42. }
  43. return spec;
  44. }
  45. export default getElementSpec;