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

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

XhmikosR's avatar
XhmikosR committed
21
22
23
24
25
26
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
27
28
29

const Default = {
  ...Tooltip.Default,
XhmikosR's avatar
XhmikosR committed
30
31
32
33
  placement: 'right',
  trigger: 'click',
  content: '',
  template: '<div class="popover" role="tooltip">' +
34
              '<div class="popover-arrow"></div>' +
Johann-S's avatar
Johann-S committed
35
36
37
38
39
40
              '<h3 class="popover-header"></h3>' +
              '<div class="popover-body"></div></div>'
}

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

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

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

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

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

class Popover extends Tooltip {
  // Getters

  static get VERSION() {
    return VERSION
78
79
  }

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

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

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

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

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

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

Johann-S's avatar
Johann-S committed
104
  // Overrides
fat's avatar
fat committed
105

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

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

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

117
118
    // 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
119
120
121
    let content = this._getContent()
    if (typeof content === 'function') {
      content = content.call(this.element)
fat's avatar
fat committed
122
    }
XhmikosR's avatar
XhmikosR committed
123

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

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

Johann-S's avatar
Johann-S committed
130
  // Private
fat's avatar
fat committed
131

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

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

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

Johann-S's avatar
Johann-S committed
147
  // Static
fat's avatar
fat committed
148

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

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

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

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

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

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

Johann-S's avatar
Johann-S committed
178
179
180
181
182
/**
 * ------------------------------------------------------------------------
 * jQuery
 * ------------------------------------------------------------------------
 */
fat's avatar
fat committed
183

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

export default Popover