Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
/**
2
 * --------------------------------------------------------------------------
3
 * Bootstrap util/template-factory.js
4
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5
 * --------------------------------------------------------------------------
6
 */
7
 
8
import SelectorEngine from '../dom/selector-engine'
9
import Config from './config'
10
import { DefaultAllowlist, sanitizeHtml } from './sanitizer'
11
import { execute, getElement, isElement } from './index'
12
 
13
/**
14
 * Constants
15
 */
16
 
17
const NAME = 'TemplateFactory'
18
 
19
const Default = {
20
  allowList: DefaultAllowlist,
21
  content: {}, // { selector : text ,  selector2 : text2 , }
22
  extraClass: '',
23
  html: false,
24
  sanitize: true,
25
  sanitizeFn: null,
26
  template: '<div></div>'
27
}
28
 
29
const DefaultType = {
30
  allowList: 'object',
31
  content: 'object',
32
  extraClass: '(string|function)',
33
  html: 'boolean',
34
  sanitize: 'boolean',
35
  sanitizeFn: '(null|function)',
36
  template: 'string'
37
}
38
 
39
const DefaultContentType = {
40
  entry: '(string|element|function|null)',
41
  selector: '(string|element)'
42
}
43
 
44
/**
45
 * Class definition
46
 */
47
 
48
class TemplateFactory extends Config {
49
  constructor(config) {
50
    super()
51
    this._config = this._getConfig(config)
52
  }
53
 
54
  // Getters
55
  static get Default() {
56
    return Default
57
  }
58
 
59
  static get DefaultType() {
60
    return DefaultType
61
  }
62
 
63
  static get NAME() {
64
    return NAME
65
  }
66
 
67
  // Public
68
  getContent() {
69
    return Object.values(this._config.content)
70
      .map(config => this._resolvePossibleFunction(config))
71
      .filter(Boolean)
72
  }
73
 
74
  hasContent() {
75
    return this.getContent().length > 0
76
  }
77
 
78
  changeContent(content) {
79
    this._checkContent(content)
80
    this._config.content = { ...this._config.content, ...content }
81
    return this
82
  }
83
 
84
  toHtml() {
85
    const templateWrapper = document.createElement('div')
86
    templateWrapper.innerHTML = this._maybeSanitize(this._config.template)
87
 
88
    for (const [selector, text] of Object.entries(this._config.content)) {
89
      this._setContent(templateWrapper, text, selector)
90
    }
91
 
92
    const template = templateWrapper.children[0]
93
    const extraClass = this._resolvePossibleFunction(this._config.extraClass)
94
 
95
    if (extraClass) {
96
      template.classList.add(...extraClass.split(' '))
97
    }
98
 
99
    return template
100
  }
101
 
102
  // Private
103
  _typeCheckConfig(config) {
104
    super._typeCheckConfig(config)
105
    this._checkContent(config.content)
106
  }
107
 
108
  _checkContent(arg) {
109
    for (const [selector, content] of Object.entries(arg)) {
110
      super._typeCheckConfig({ selector, entry: content }, DefaultContentType)
111
    }
112
  }
113
 
114
  _setContent(template, content, selector) {
115
    const templateElement = SelectorEngine.findOne(selector, template)
116
 
117
    if (!templateElement) {
118
      return
119
    }
120
 
121
    content = this._resolvePossibleFunction(content)
122
 
123
    if (!content) {
124
      templateElement.remove()
125
      return
126
    }
127
 
128
    if (isElement(content)) {
129
      this._putElementInTemplate(getElement(content), templateElement)
130
      return
131
    }
132
 
133
    if (this._config.html) {
134
      templateElement.innerHTML = this._maybeSanitize(content)
135
      return
136
    }
137
 
138
    templateElement.textContent = content
139
  }
140
 
141
  _maybeSanitize(arg) {
142
    return this._config.sanitize ? sanitizeHtml(arg, this._config.allowList, this._config.sanitizeFn) : arg
143
  }
144
 
145
  _resolvePossibleFunction(arg) {
146
    return execute(arg, [this])
147
  }
148
 
149
  _putElementInTemplate(element, templateElement) {
150
    if (this._config.html) {
151
      templateElement.innerHTML = ''
152
      templateElement.append(element)
153
      return
154
    }
155
 
156
    templateElement.textContent = element.textContent
157
  }
158
}
159
 
160
export default TemplateFactory