find.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. /**
  2. * @import {Schema} from 'property-information'
  3. */
  4. import {DefinedInfo} from './util/defined-info.js'
  5. import {Info} from './util/info.js'
  6. import {normalize} from './normalize.js'
  7. const cap = /[A-Z]/g
  8. const dash = /-[a-z]/g
  9. const valid = /^data[-\w.:]+$/i
  10. /**
  11. * Look up info on a property.
  12. *
  13. * In most cases the given `schema` contains info on the property.
  14. * All standard,
  15. * most legacy,
  16. * and some non-standard properties are supported.
  17. * For these cases,
  18. * the returned `Info` has hints about the value of the property.
  19. *
  20. * `name` can also be a valid data attribute or property,
  21. * in which case an `Info` object with the correctly cased `attribute` and
  22. * `property` is returned.
  23. *
  24. * `name` can be an unknown attribute,
  25. * in which case an `Info` object with `attribute` and `property` set to the
  26. * given name is returned.
  27. * It is not recommended to provide unsupported legacy or recently specced
  28. * properties.
  29. *
  30. *
  31. * @param {Schema} schema
  32. * Schema;
  33. * either the `html` or `svg` export.
  34. * @param {string} value
  35. * An attribute-like or property-like name;
  36. * it will be passed through `normalize` to hopefully find the correct info.
  37. * @returns {Info}
  38. * Info.
  39. */
  40. export function find(schema, value) {
  41. const normal = normalize(value)
  42. let property = value
  43. let Type = Info
  44. if (normal in schema.normal) {
  45. return schema.property[schema.normal[normal]]
  46. }
  47. if (normal.length > 4 && normal.slice(0, 4) === 'data' && valid.test(value)) {
  48. // Attribute or property.
  49. if (value.charAt(4) === '-') {
  50. // Turn it into a property.
  51. const rest = value.slice(5).replace(dash, camelcase)
  52. property = 'data' + rest.charAt(0).toUpperCase() + rest.slice(1)
  53. } else {
  54. // Turn it into an attribute.
  55. const rest = value.slice(4)
  56. if (!dash.test(rest)) {
  57. let dashes = rest.replace(cap, kebab)
  58. if (dashes.charAt(0) !== '-') {
  59. dashes = '-' + dashes
  60. }
  61. value = 'data' + dashes
  62. }
  63. }
  64. Type = DefinedInfo
  65. }
  66. return new Type(property, value)
  67. }
  68. /**
  69. * @param {string} $0
  70. * Value.
  71. * @returns {string}
  72. * Kebab.
  73. */
  74. function kebab($0) {
  75. return '-' + $0.toLowerCase()
  76. }
  77. /**
  78. * @param {string} $0
  79. * Value.
  80. * @returns {string}
  81. * Camel.
  82. */
  83. function camelcase($0) {
  84. return $0.charAt(1).toUpperCase()
  85. }