popover.js 4.56 KB
Newer Older
fat's avatar
fat committed
1
2
/**
 * --------------------------------------------------------------------------
XhmikosR's avatar
XhmikosR committed
3
 * Bootstrap (v4.3.1): popover.js
fat's avatar
fat committed
4
5
6
7
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * --------------------------------------------------------------------------
 */

8
9
import Data from './dom/data'
import SelectorEngine from './dom/selectorEngine'
10
import Tooltip from './tooltip'
11
import Util from './util'
12

Johann-S's avatar
Johann-S committed
13
14
15
16
17
18
19
/**
 * ------------------------------------------------------------------------
 * Constants
 * ------------------------------------------------------------------------
 */

const NAME                = 'popover'
XhmikosR's avatar
XhmikosR committed
20
const VERSION             = '4.3.1'
Johann-S's avatar
Johann-S committed
21
22
23
24
25
26
27
28
29
30
31
const DATA_KEY            = 'bs.popover'
const EVENT_KEY           = `.${DATA_KEY}`
const CLASS_PREFIX        = 'bs-popover'
const BSCLS_PREFIX_REGEX  = new RegExp(`(^|\\s)${CLASS_PREFIX}\\S+`, 'g')

const Default = {
  ...Tooltip.Default,
  placement : 'right',
  trigger   : 'click',
  content   : '',
  template  : '<div class="popover" role="tooltip">' +
32
              '<div class="popover-arrow"></div>' +
Johann-S's avatar
Johann-S committed
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
              '<h3 class="popover-header"></h3>' +
              '<div class="popover-body"></div></div>'
}

const DefaultType = {
  ...Tooltip.DefaultType,
  content : '(string|element|function)'
}

const ClassName = {
  FADE : 'fade',
  SHOW : 'show'
}

const Selector = {
  TITLE   : '.popover-header',
  CONTENT : '.popover-body'
}

const Event = {
  HIDE       : `hide${EVENT_KEY}`,
  HIDDEN     : `hidden${EVENT_KEY}`,
  SHOW       : `show${EVENT_KEY}`,
  SHOWN      : `shown${EVENT_KEY}`,
  INSERTED   : `inserted${EVENT_KEY}`,
  CLICK      : `click${EVENT_KEY}`,
  FOCUSIN    : `focusin${EVENT_KEY}`,
  FOCUSOUT   : `focusout${EVENT_KEY}`,
  MOUSEENTER : `mouseenter${EVENT_KEY}`,
  MOUSELEAVE : `mouseleave${EVENT_KEY}`
}

/**
 * ------------------------------------------------------------------------
 * Class Definition
 * ------------------------------------------------------------------------
 */

class Popover extends Tooltip {
  // Getters

  static get VERSION() {
    return VERSION
76
77
  }

Johann-S's avatar
Johann-S committed
78
79
  static get Default() {
    return Default
80
  }
fat's avatar
fat committed
81

Johann-S's avatar
Johann-S committed
82
83
  static get NAME() {
    return NAME
fat's avatar
fat committed
84
85
  }

Johann-S's avatar
Johann-S committed
86
87
  static get DATA_KEY() {
    return DATA_KEY
fat's avatar
fat committed
88
89
  }

Johann-S's avatar
Johann-S committed
90
91
  static get Event() {
    return Event
fat's avatar
fat committed
92
93
  }

Johann-S's avatar
Johann-S committed
94
95
96
  static get EVENT_KEY() {
    return EVENT_KEY
  }
fat's avatar
fat committed
97

Johann-S's avatar
Johann-S committed
98
99
100
  static get DefaultType() {
    return DefaultType
  }
fat's avatar
fat committed
101

Johann-S's avatar
Johann-S committed
102
  // Overrides
fat's avatar
fat committed
103

Johann-S's avatar
Johann-S committed
104
105
106
  isWithContent() {
    return this.getTitle() || this._getContent()
  }
fat's avatar
fat committed
107

Johann-S's avatar
Johann-S committed
108
  addAttachmentClass(attachment) {
109
    this.getTipElement().classList.add(`${CLASS_PREFIX}-${attachment}`)
Johann-S's avatar
Johann-S committed
110
  }
fat's avatar
fat committed
111

Johann-S's avatar
Johann-S committed
112
  setContent() {
113
    const tip = this.getTipElement()
fat's avatar
fat committed
114

115
116
    // we use append for html objects to maintain js events
    this.setElementContent(SelectorEngine.findOne(Selector.TITLE, tip), this.getTitle())
Johann-S's avatar
Johann-S committed
117
118
119
    let content = this._getContent()
    if (typeof content === 'function') {
      content = content.call(this.element)
fat's avatar
fat committed
120
    }
121
    this.setElementContent(SelectorEngine.findOne(Selector.CONTENT, tip), content)
fat's avatar
fat committed
122

123
124
    tip.classList.remove(ClassName.FADE)
    tip.classList.remove(ClassName.SHOW)
Johann-S's avatar
Johann-S committed
125
  }
fat's avatar
fat committed
126

Johann-S's avatar
Johann-S committed
127
  // Private
fat's avatar
fat committed
128

Johann-S's avatar
Johann-S committed
129
130
131
132
  _getContent() {
    return this.element.getAttribute('data-content') ||
      this.config.content
  }
fat's avatar
fat committed
133

Johann-S's avatar
Johann-S committed
134
  _cleanTipClass() {
135
136
    const tip = this.getTipElement()
    const tabClass = tip.getAttribute('class').match(BSCLS_PREFIX_REGEX)
137

Johann-S's avatar
Johann-S committed
138
    if (tabClass !== null && tabClass.length > 0) {
139
140
      tabClass.map((token) => token.trim())
        .forEach((tClass) => tip.classList.remove(tClass))
Johann-S's avatar
Johann-S committed
141
    }
Johann-S's avatar
Johann-S committed
142
  }
Johann-S's avatar
Johann-S committed
143

Johann-S's avatar
Johann-S committed
144
  // Static
fat's avatar
fat committed
145

Johann-S's avatar
Johann-S committed
146
147
  static _jQueryInterface(config) {
    return this.each(function () {
148
      let data      = Data.getData(this, DATA_KEY)
Johann-S's avatar
Johann-S committed
149
      const _config = typeof config === 'object' ? config : null
fat's avatar
fat committed
150

Johann-S's avatar
Johann-S committed
151
152
      if (!data && /dispose|hide/.test(config)) {
        return
153
      }
fat's avatar
fat committed
154

Johann-S's avatar
Johann-S committed
155
156
      if (!data) {
        data = new Popover(this, _config)
157
        Data.setData(this, DATA_KEY, data)
Johann-S's avatar
Johann-S committed
158
      }
fat's avatar
fat committed
159

Johann-S's avatar
Johann-S committed
160
161
162
      if (typeof config === 'string') {
        if (typeof data[config] === 'undefined') {
          throw new TypeError(`No method named "${config}"`)
fat's avatar
fat committed
163
        }
Johann-S's avatar
Johann-S committed
164
165
166
        data[config]()
      }
    })
fat's avatar
fat committed
167
  }
168
169
170
171

  static _getInstance(element) {
    return Data.getData(element, DATA_KEY)
  }
Johann-S's avatar
Johann-S committed
172
}
fat's avatar
fat committed
173

Johann-S's avatar
Johann-S committed
174
175
176
177
178
/**
 * ------------------------------------------------------------------------
 * jQuery
 * ------------------------------------------------------------------------
 */
fat's avatar
fat committed
179

180
181
182
183
184
185
186
187
188
const $ = Util.jQuery
if (typeof $ !== 'undefined') {
  const JQUERY_NO_CONFLICT = $.fn[NAME]
  $.fn[NAME]               = Popover._jQueryInterface
  $.fn[NAME].Constructor   = Popover
  $.fn[NAME].noConflict    = () => {
    $.fn[NAME] = JQUERY_NO_CONFLICT
    return Popover._jQueryInterface
  }
Johann-S's avatar
Johann-S committed
189
}
fat's avatar
fat committed
190
191

export default Popover