An unfinished system to manage all your paper documentation in an easy way.
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. /**!
  2. * @fileOverview Kickass library to create and place poppers near their reference elements.
  3. * @version 1.3.2
  4. * @license
  5. * Copyright (c) 2016 Federico Zivolo and contributors
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in all
  15. * copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. * SOFTWARE.
  24. */
  25. (function (global, factory) {
  26. typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('popper.js')) :
  27. typeof define === 'function' && define.amd ? define(['popper.js'], factory) :
  28. (global.Tooltip = factory(global.Popper));
  29. }(this, (function (Popper) { 'use strict';
  30. Popper = Popper && Popper.hasOwnProperty('default') ? Popper['default'] : Popper;
  31. /**
  32. * Check if the given variable is a function
  33. * @method
  34. * @memberof Popper.Utils
  35. * @argument {Any} functionToCheck - variable to check
  36. * @returns {Boolean} answer to: is a function?
  37. */
  38. function isFunction(functionToCheck) {
  39. var getType = {};
  40. return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
  41. }
  42. var classCallCheck = function (instance, Constructor) {
  43. if (!(instance instanceof Constructor)) {
  44. throw new TypeError("Cannot call a class as a function");
  45. }
  46. };
  47. var createClass = function () {
  48. function defineProperties(target, props) {
  49. for (var i = 0; i < props.length; i++) {
  50. var descriptor = props[i];
  51. descriptor.enumerable = descriptor.enumerable || false;
  52. descriptor.configurable = true;
  53. if ("value" in descriptor) descriptor.writable = true;
  54. Object.defineProperty(target, descriptor.key, descriptor);
  55. }
  56. }
  57. return function (Constructor, protoProps, staticProps) {
  58. if (protoProps) defineProperties(Constructor.prototype, protoProps);
  59. if (staticProps) defineProperties(Constructor, staticProps);
  60. return Constructor;
  61. };
  62. }();
  63. var _extends = Object.assign || function (target) {
  64. for (var i = 1; i < arguments.length; i++) {
  65. var source = arguments[i];
  66. for (var key in source) {
  67. if (Object.prototype.hasOwnProperty.call(source, key)) {
  68. target[key] = source[key];
  69. }
  70. }
  71. }
  72. return target;
  73. };
  74. var DEFAULT_OPTIONS = {
  75. container: false,
  76. delay: 0,
  77. html: false,
  78. placement: 'top',
  79. title: '',
  80. template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
  81. trigger: 'hover focus',
  82. offset: 0,
  83. arrowSelector: '.tooltip-arrow, .tooltip__arrow',
  84. innerSelector: '.tooltip-inner, .tooltip__inner'
  85. };
  86. var Tooltip = function () {
  87. /**
  88. * Create a new Tooltip.js instance
  89. * @class Tooltip
  90. * @param {HTMLElement} reference - The DOM node used as reference of the tooltip (it can be a jQuery element).
  91. * @param {Object} options
  92. * @param {String} options.placement='top'
  93. * Placement of the popper accepted values: `top(-start, -end), right(-start, -end), bottom(-start, -end),
  94. * left(-start, -end)`
  95. * @param {String} options.arrowSelector='.tooltip-arrow, .tooltip__arrow' - className used to locate the DOM arrow element in the tooltip.
  96. * @param {String} options.innerSelector='.tooltip-inner, .tooltip__inner' - className used to locate the DOM inner element in the tooltip.
  97. * @param {HTMLElement|String|false} options.container=false - Append the tooltip to a specific element.
  98. * @param {Number|Object} options.delay=0
  99. * Delay showing and hiding the tooltip (ms) - does not apply to manual trigger type.
  100. * If a number is supplied, delay is applied to both hide/show.
  101. * Object structure is: `{ show: 500, hide: 100 }`
  102. * @param {Boolean} options.html=false - Insert HTML into the tooltip. If false, the content will inserted with `textContent`.
  103. * @param {String} [options.template='<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>']
  104. * Base HTML to used when creating the tooltip.
  105. * The tooltip's `title` will be injected into the `.tooltip-inner` or `.tooltip__inner`.
  106. * `.tooltip-arrow` or `.tooltip__arrow` will become the tooltip's arrow.
  107. * The outermost wrapper element should have the `.tooltip` class.
  108. * @param {String|HTMLElement|TitleFunction} options.title='' - Default title value if `title` attribute isn't present.
  109. * @param {String} [options.trigger='hover focus']
  110. * How tooltip is triggered - click, hover, focus, manual.
  111. * You may pass multiple triggers; separate them with a space. `manual` cannot be combined with any other trigger.
  112. * @param {Boolean} options.closeOnClickOutside=false - Close a popper on click outside of the popper and reference element. This has effect only when options.trigger is 'click'.
  113. * @param {String|HTMLElement} options.boundariesElement
  114. * The element used as boundaries for the tooltip. For more information refer to Popper.js'
  115. * [boundariesElement docs](https://popper.js.org/popper-documentation.html)
  116. * @param {Number|String} options.offset=0 - Offset of the tooltip relative to its reference. For more information refer to Popper.js'
  117. * [offset docs](https://popper.js.org/popper-documentation.html)
  118. * @param {Object} options.popperOptions={} - Popper options, will be passed directly to popper instance. For more information refer to Popper.js'
  119. * [options docs](https://popper.js.org/popper-documentation.html)
  120. * @return {Object} instance - The generated tooltip instance
  121. */
  122. function Tooltip(reference, options) {
  123. classCallCheck(this, Tooltip);
  124. _initialiseProps.call(this);
  125. // apply user options over default ones
  126. options = _extends({}, DEFAULT_OPTIONS, options);
  127. reference.jquery && (reference = reference[0]);
  128. // cache reference and options
  129. this.reference = reference;
  130. this.options = options;
  131. // get events list
  132. var events = typeof options.trigger === 'string' ? options.trigger.split(' ').filter(function (trigger) {
  133. return ['click', 'hover', 'focus'].indexOf(trigger) !== -1;
  134. }) : [];
  135. // set initial state
  136. this._isOpen = false;
  137. this._popperOptions = {};
  138. // set event listeners
  139. this._setEventListeners(reference, events, options);
  140. }
  141. //
  142. // Public methods
  143. //
  144. /**
  145. * Reveals an element's tooltip. This is considered a "manual" triggering of the tooltip.
  146. * Tooltips with zero-length titles are never displayed.
  147. * @method Tooltip#show
  148. * @memberof Tooltip
  149. */
  150. /**
  151. * Hides an element’s tooltip. This is considered a “manual” triggering of the tooltip.
  152. * @method Tooltip#hide
  153. * @memberof Tooltip
  154. */
  155. /**
  156. * Hides and destroys an element’s tooltip.
  157. * @method Tooltip#dispose
  158. * @memberof Tooltip
  159. */
  160. /**
  161. * Toggles an element’s tooltip. This is considered a “manual” triggering of the tooltip.
  162. * @method Tooltip#toggle
  163. * @memberof Tooltip
  164. */
  165. /**
  166. * Updates the tooltip's title content
  167. * @method Tooltip#updateTitleContent
  168. * @memberof Tooltip
  169. * @param {String|HTMLElement} title - The new content to use for the title
  170. */
  171. //
  172. // Private methods
  173. //
  174. createClass(Tooltip, [{
  175. key: '_create',
  176. /**
  177. * Creates a new tooltip node
  178. * @memberof Tooltip
  179. * @private
  180. * @param {HTMLElement} reference
  181. * @param {String} template
  182. * @param {String|HTMLElement|TitleFunction} title
  183. * @param {Boolean} allowHtml
  184. * @return {HTMLElement} tooltipNode
  185. */
  186. value: function _create(reference, template, title, allowHtml) {
  187. // create tooltip element
  188. var tooltipGenerator = window.document.createElement('div');
  189. tooltipGenerator.innerHTML = template.trim();
  190. var tooltipNode = tooltipGenerator.childNodes[0];
  191. // add unique ID to our tooltip (needed for accessibility reasons)
  192. tooltipNode.id = 'tooltip_' + Math.random().toString(36).substr(2, 10);
  193. // set initial `aria-hidden` state to `false` (it's visible!)
  194. tooltipNode.setAttribute('aria-hidden', 'false');
  195. // add title to tooltip
  196. var titleNode = tooltipGenerator.querySelector(this.options.innerSelector);
  197. this._addTitleContent(reference, title, allowHtml, titleNode);
  198. // return the generated tooltip node
  199. return tooltipNode;
  200. }
  201. }, {
  202. key: '_addTitleContent',
  203. value: function _addTitleContent(reference, title, allowHtml, titleNode) {
  204. if (title.nodeType === 1 || title.nodeType === 11) {
  205. // if title is a element node or document fragment, append it only if allowHtml is true
  206. allowHtml && titleNode.appendChild(title);
  207. } else if (isFunction(title)) {
  208. // if title is a function, call it and set textContent or innerHtml depending by `allowHtml` value
  209. var titleText = title.call(reference);
  210. allowHtml ? titleNode.innerHTML = titleText : titleNode.textContent = titleText;
  211. } else {
  212. // if it's just a simple text, set textContent or innerHtml depending by `allowHtml` value
  213. allowHtml ? titleNode.innerHTML = title : titleNode.textContent = title;
  214. }
  215. }
  216. }, {
  217. key: '_show',
  218. value: function _show(reference, options) {
  219. // don't show if it's already visible
  220. // or if it's not being showed
  221. if (this._isOpen && !this._isOpening) {
  222. return this;
  223. }
  224. this._isOpen = true;
  225. // if the tooltipNode already exists, just show it
  226. if (this._tooltipNode) {
  227. this._tooltipNode.style.visibility = 'visible';
  228. this._tooltipNode.setAttribute('aria-hidden', 'false');
  229. this.popperInstance.update();
  230. return this;
  231. }
  232. // get title
  233. var title = reference.getAttribute('title') || options.title;
  234. // don't show tooltip if no title is defined
  235. if (!title) {
  236. return this;
  237. }
  238. // create tooltip node
  239. var tooltipNode = this._create(reference, options.template, title, options.html);
  240. // Add `aria-describedby` to our reference element for accessibility reasons
  241. reference.setAttribute('aria-describedby', tooltipNode.id);
  242. // append tooltip to container
  243. var container = this._findContainer(options.container, reference);
  244. this._append(tooltipNode, container);
  245. this._popperOptions = _extends({}, options.popperOptions, {
  246. placement: options.placement
  247. });
  248. this._popperOptions.modifiers = _extends({}, this._popperOptions.modifiers, {
  249. arrow: _extends({}, this._popperOptions.modifiers && this._popperOptions.modifiers.arrow, {
  250. element: options.arrowSelector
  251. }),
  252. offset: _extends({}, this._popperOptions.modifiers && this._popperOptions.modifiers.offset, {
  253. offset: options.offset
  254. })
  255. });
  256. if (options.boundariesElement) {
  257. this._popperOptions.modifiers.preventOverflow = {
  258. boundariesElement: options.boundariesElement
  259. };
  260. }
  261. this.popperInstance = new Popper(reference, tooltipNode, this._popperOptions);
  262. this._tooltipNode = tooltipNode;
  263. return this;
  264. }
  265. }, {
  266. key: '_hide',
  267. value: function _hide() /*reference, options*/{
  268. // don't hide if it's already hidden
  269. if (!this._isOpen) {
  270. return this;
  271. }
  272. this._isOpen = false;
  273. // hide tooltipNode
  274. this._tooltipNode.style.visibility = 'hidden';
  275. this._tooltipNode.setAttribute('aria-hidden', 'true');
  276. return this;
  277. }
  278. }, {
  279. key: '_dispose',
  280. value: function _dispose() {
  281. var _this = this;
  282. // remove event listeners first to prevent any unexpected behaviour
  283. this._events.forEach(function (_ref) {
  284. var func = _ref.func,
  285. event = _ref.event;
  286. _this.reference.removeEventListener(event, func);
  287. });
  288. this._events = [];
  289. if (this._tooltipNode) {
  290. this._hide();
  291. // destroy instance
  292. this.popperInstance.destroy();
  293. // destroy tooltipNode if removeOnDestroy is not set, as popperInstance.destroy() already removes the element
  294. if (!this.popperInstance.options.removeOnDestroy) {
  295. this._tooltipNode.parentNode.removeChild(this._tooltipNode);
  296. this._tooltipNode = null;
  297. }
  298. }
  299. return this;
  300. }
  301. }, {
  302. key: '_findContainer',
  303. value: function _findContainer(container, reference) {
  304. // if container is a query, get the relative element
  305. if (typeof container === 'string') {
  306. container = window.document.querySelector(container);
  307. } else if (container === false) {
  308. // if container is `false`, set it to reference parent
  309. container = reference.parentNode;
  310. }
  311. return container;
  312. }
  313. /**
  314. * Append tooltip to container
  315. * @memberof Tooltip
  316. * @private
  317. * @param {HTMLElement} tooltipNode
  318. * @param {HTMLElement|String|false} container
  319. */
  320. }, {
  321. key: '_append',
  322. value: function _append(tooltipNode, container) {
  323. container.appendChild(tooltipNode);
  324. }
  325. }, {
  326. key: '_setEventListeners',
  327. value: function _setEventListeners(reference, events, options) {
  328. var _this2 = this;
  329. var directEvents = [];
  330. var oppositeEvents = [];
  331. events.forEach(function (event) {
  332. switch (event) {
  333. case 'hover':
  334. directEvents.push('mouseenter');
  335. oppositeEvents.push('mouseleave');
  336. break;
  337. case 'focus':
  338. directEvents.push('focus');
  339. oppositeEvents.push('blur');
  340. break;
  341. case 'click':
  342. directEvents.push('click');
  343. oppositeEvents.push('click');
  344. break;
  345. }
  346. });
  347. // schedule show tooltip
  348. directEvents.forEach(function (event) {
  349. var func = function func(evt) {
  350. if (_this2._isOpening === true) {
  351. return;
  352. }
  353. evt.usedByTooltip = true;
  354. _this2._scheduleShow(reference, options.delay, options, evt);
  355. };
  356. _this2._events.push({ event: event, func: func });
  357. reference.addEventListener(event, func);
  358. });
  359. // schedule hide tooltip
  360. oppositeEvents.forEach(function (event) {
  361. var func = function func(evt) {
  362. if (evt.usedByTooltip === true) {
  363. return;
  364. }
  365. _this2._scheduleHide(reference, options.delay, options, evt);
  366. };
  367. _this2._events.push({ event: event, func: func });
  368. reference.addEventListener(event, func);
  369. if (event === 'click' && options.closeOnClickOutside) {
  370. document.addEventListener('mousedown', function (e) {
  371. if (!_this2._isOpening) {
  372. return;
  373. }
  374. var popper = _this2.popperInstance.popper;
  375. if (reference.contains(e.target) || popper.contains(e.target)) {
  376. return;
  377. }
  378. func(e);
  379. }, true);
  380. }
  381. });
  382. }
  383. }, {
  384. key: '_scheduleShow',
  385. value: function _scheduleShow(reference, delay, options /*, evt */) {
  386. var _this3 = this;
  387. this._isOpening = true;
  388. // defaults to 0
  389. var computedDelay = delay && delay.show || delay || 0;
  390. this._showTimeout = window.setTimeout(function () {
  391. return _this3._show(reference, options);
  392. }, computedDelay);
  393. }
  394. }, {
  395. key: '_scheduleHide',
  396. value: function _scheduleHide(reference, delay, options, evt) {
  397. var _this4 = this;
  398. this._isOpening = false;
  399. // defaults to 0
  400. var computedDelay = delay && delay.hide || delay || 0;
  401. window.clearTimeout(this._showTimeout);
  402. window.setTimeout(function () {
  403. if (_this4._isOpen === false) {
  404. return;
  405. }
  406. if (!document.body.contains(_this4._tooltipNode)) {
  407. return;
  408. }
  409. // if we are hiding because of a mouseleave, we must check that the new
  410. // reference isn't the tooltip, because in this case we don't want to hide it
  411. if (evt.type === 'mouseleave') {
  412. var isSet = _this4._setTooltipNodeEvent(evt, reference, delay, options);
  413. // if we set the new event, don't hide the tooltip yet
  414. // the new event will take care to hide it if necessary
  415. if (isSet) {
  416. return;
  417. }
  418. }
  419. _this4._hide(reference, options);
  420. }, computedDelay);
  421. }
  422. }, {
  423. key: '_updateTitleContent',
  424. value: function _updateTitleContent(title) {
  425. if (typeof this._tooltipNode === 'undefined') {
  426. if (typeof this.options.title !== 'undefined') {
  427. this.options.title = title;
  428. }
  429. return;
  430. }
  431. var titleNode = this._tooltipNode.querySelector(this.options.innerSelector);
  432. this._clearTitleContent(titleNode, this.options.html, this.reference.getAttribute('title') || this.options.title);
  433. this._addTitleContent(this.reference, title, this.options.html, titleNode);
  434. this.options.title = title;
  435. this.popperInstance.update();
  436. }
  437. }, {
  438. key: '_clearTitleContent',
  439. value: function _clearTitleContent(titleNode, allowHtml, lastTitle) {
  440. if (lastTitle.nodeType === 1 || lastTitle.nodeType === 11) {
  441. allowHtml && titleNode.removeChild(lastTitle);
  442. } else {
  443. allowHtml ? titleNode.innerHTML = '' : titleNode.textContent = '';
  444. }
  445. }
  446. }]);
  447. return Tooltip;
  448. }();
  449. /**
  450. * Title function, its context is the Tooltip instance.
  451. * @memberof Tooltip
  452. * @callback TitleFunction
  453. * @return {String} placement - The desired title.
  454. */
  455. var _initialiseProps = function _initialiseProps() {
  456. var _this5 = this;
  457. this.show = function () {
  458. return _this5._show(_this5.reference, _this5.options);
  459. };
  460. this.hide = function () {
  461. return _this5._hide();
  462. };
  463. this.dispose = function () {
  464. return _this5._dispose();
  465. };
  466. this.toggle = function () {
  467. if (_this5._isOpen) {
  468. return _this5.hide();
  469. } else {
  470. return _this5.show();
  471. }
  472. };
  473. this.updateTitleContent = function (title) {
  474. return _this5._updateTitleContent(title);
  475. };
  476. this._events = [];
  477. this._setTooltipNodeEvent = function (evt, reference, delay, options) {
  478. var relatedreference = evt.relatedreference || evt.toElement || evt.relatedTarget;
  479. var callback = function callback(evt2) {
  480. var relatedreference2 = evt2.relatedreference || evt2.toElement || evt2.relatedTarget;
  481. // Remove event listener after call
  482. _this5._tooltipNode.removeEventListener(evt.type, callback);
  483. // If the new reference is not the reference element
  484. if (!reference.contains(relatedreference2)) {
  485. // Schedule to hide tooltip
  486. _this5._scheduleHide(reference, options.delay, options, evt2);
  487. }
  488. };
  489. if (_this5._tooltipNode.contains(relatedreference)) {
  490. // listen to mouseleave on the tooltip element to be able to hide the tooltip
  491. _this5._tooltipNode.addEventListener(evt.type, callback);
  492. return true;
  493. }
  494. return false;
  495. };
  496. };
  497. return Tooltip;
  498. })));
  499. //# sourceMappingURL=tooltip.js.map