popover.js 4.42 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
import { jQuery as $ } from './util/index'
9
10
import Data from './dom/data'
import SelectorEngine from './dom/selectorEngine'
11
12
import Tooltip from './tooltip'

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

XhmikosR's avatar
XhmikosR committed
19
20
21
22
23
24
const NAME = 'popover'
const VERSION = '4.3.1'
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')
Johann-S's avatar
Johann-S committed
25
26
27

const Default = {
  ...Tooltip.Default,
XhmikosR's avatar
XhmikosR committed
28
29
30
31
  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
              '<h3 class="popover-header"></h3>' +
              '<div class="popover-body"></div></div>'
}

const DefaultType = {
  ...Tooltip.DefaultType,
XhmikosR's avatar
XhmikosR committed
39
  content: '(string|element|function)'
Johann-S's avatar
Johann-S committed
40
41
42
}

const ClassName = {
XhmikosR's avatar
XhmikosR committed
43
44
  FADE: 'fade',
  SHOW: 'show'
Johann-S's avatar
Johann-S committed
45
46
47
}

const Selector = {
XhmikosR's avatar
XhmikosR committed
48
49
  TITLE: '.popover-header',
  CONTENT: '.popover-body'
Johann-S's avatar
Johann-S committed
50
51
52
}

const Event = {
XhmikosR's avatar
XhmikosR committed
53
54
55
56
57
58
59
60
61
62
  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}`
Johann-S's avatar
Johann-S committed
63
64
65
66
67
68
69
70
71
72
73
74
75
}

/**
 * ------------------------------------------------------------------------
 * 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
    }
XhmikosR's avatar
XhmikosR committed
121

122
    this.setElementContent(SelectorEngine.findOne(Selector.CONTENT, tip), content)
fat's avatar
fat committed
123

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

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

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

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

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

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

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

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

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

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

Johann-S's avatar
Johann-S committed
166
167
168
        data[config]()
      }
    })
fat's avatar
fat committed
169
  }
170
171
172
173

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

Johann-S's avatar
Johann-S committed
176
177
178
179
180
/**
 * ------------------------------------------------------------------------
 * jQuery
 * ------------------------------------------------------------------------
 */
fat's avatar
fat committed
181

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

export default Popover