widget.js 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. const Block = require('widget-ui')
  2. const {splitLineToCamelCase} = require('./utils')
  3. class Element extends Block {
  4. constructor(prop) {
  5. super(prop.style)
  6. this.name = prop.name
  7. this.attributes = prop.attributes
  8. }
  9. }
  10. class Widget {
  11. constructor(xom, style) {
  12. this.xom = xom
  13. this.style = style
  14. this.inheritProps = ['fontSize', 'lineHeight', 'textAlign', 'verticalAlign', 'color']
  15. }
  16. init() {
  17. this.container = this.create(this.xom)
  18. this.container.layout()
  19. this.inheritStyle(this.container)
  20. return this.container
  21. }
  22. // 继承父节点的样式
  23. inheritStyle(node) {
  24. const parent = node.parent || null
  25. const children = node.children || {}
  26. const computedStyle = node.computedStyle
  27. if (parent) {
  28. this.inheritProps.forEach(prop => {
  29. computedStyle[prop] = computedStyle[prop] || parent.computedStyle[prop]
  30. })
  31. }
  32. Object.values(children).forEach(child => {
  33. this.inheritStyle(child)
  34. })
  35. }
  36. create(node) {
  37. let classNames = (node.attributes.class || '').split(' ')
  38. classNames = classNames.map(item => splitLineToCamelCase(item.trim()))
  39. const style = {}
  40. classNames.forEach(item => {
  41. Object.assign(style, this.style[item] || {})
  42. })
  43. const args = {name: node.name, style}
  44. const attrs = Object.keys(node.attributes)
  45. const attributes = {}
  46. for (const attr of attrs) {
  47. const value = node.attributes[attr]
  48. const CamelAttr = splitLineToCamelCase(attr)
  49. if (value === '' || value === 'true') {
  50. attributes[CamelAttr] = true
  51. } else if (value === 'false') {
  52. attributes[CamelAttr] = false
  53. } else {
  54. attributes[CamelAttr] = value
  55. }
  56. }
  57. attributes.text = node.content
  58. args.attributes = attributes
  59. const element = new Element(args)
  60. node.children.forEach(childNode => {
  61. const childElement = this.create(childNode)
  62. element.add(childElement)
  63. })
  64. return element
  65. }
  66. }
  67. module.exports = {Widget}