UNPKG

14.3 kBJavaScriptView Raw
1(function (global, factory) {
2 if (typeof define === "function" && define.amd) {
3 define(["exports", "lodash.debounce", "../../globals/js/settings", "../../globals/js/misc/mixin", "../../globals/js/mixins/create-component", "../../globals/js/mixins/init-component-by-event", "../../globals/js/mixins/evented-show-hide-state", "../../globals/js/mixins/handles", "../floating-menu/floating-menu", "../../globals/js/misc/get-launching-details", "../../globals/js/misc/on"], factory);
4 } else if (typeof exports !== "undefined") {
5 factory(exports, require("lodash.debounce"), require("../../globals/js/settings"), require("../../globals/js/misc/mixin"), require("../../globals/js/mixins/create-component"), require("../../globals/js/mixins/init-component-by-event"), require("../../globals/js/mixins/evented-show-hide-state"), require("../../globals/js/mixins/handles"), require("../floating-menu/floating-menu"), require("../../globals/js/misc/get-launching-details"), require("../../globals/js/misc/on"));
6 } else {
7 var mod = {
8 exports: {}
9 };
10 factory(mod.exports, global.lodash, global.settings, global.mixin, global.createComponent, global.initComponentByEvent, global.eventedShowHideState, global.handles, global.floatingMenu, global.getLaunchingDetails, global.on);
11 global.tooltip = mod.exports;
12 }
13})(this, function (_exports, _lodash, _settings, _mixin2, _createComponent, _initComponentByEvent, _eventedShowHideState, _handles, _floatingMenu, _getLaunchingDetails, _on) {
14 "use strict";
15
16 Object.defineProperty(_exports, "__esModule", {
17 value: true
18 });
19 _exports.default = void 0;
20 _lodash = _interopRequireDefault(_lodash);
21 _settings = _interopRequireDefault(_settings);
22 _mixin2 = _interopRequireDefault(_mixin2);
23 _createComponent = _interopRequireDefault(_createComponent);
24 _initComponentByEvent = _interopRequireDefault(_initComponentByEvent);
25 _eventedShowHideState = _interopRequireDefault(_eventedShowHideState);
26 _handles = _interopRequireDefault(_handles);
27 _floatingMenu = _interopRequireWildcard(_floatingMenu);
28 _getLaunchingDetails = _interopRequireDefault(_getLaunchingDetails);
29 _on = _interopRequireDefault(_on);
30
31 function _interopRequireWildcard(obj) {
32 if (obj && obj.__esModule) {
33 return obj;
34 } else {
35 var newObj = {};
36
37 if (obj != null) {
38 for (var key in obj) {
39 if (Object.prototype.hasOwnProperty.call(obj, key)) {
40 var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {};
41
42 if (desc.get || desc.set) {
43 Object.defineProperty(newObj, key, desc);
44 } else {
45 newObj[key] = obj[key];
46 }
47 }
48 }
49 }
50
51 newObj.default = obj;
52 return newObj;
53 }
54 }
55
56 function _interopRequireDefault(obj) {
57 return obj && obj.__esModule ? obj : {
58 default: obj
59 };
60 }
61
62 function _typeof(obj) {
63 if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") {
64 _typeof = function _typeof(obj) {
65 return typeof obj;
66 };
67 } else {
68 _typeof = function _typeof(obj) {
69 return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
70 };
71 }
72
73 return _typeof(obj);
74 }
75
76 function _classCallCheck(instance, Constructor) {
77 if (!(instance instanceof Constructor)) {
78 throw new TypeError("Cannot call a class as a function");
79 }
80 }
81
82 function _defineProperties(target, props) {
83 for (var i = 0; i < props.length; i++) {
84 var descriptor = props[i];
85 descriptor.enumerable = descriptor.enumerable || false;
86 descriptor.configurable = true;
87 if ("value" in descriptor) descriptor.writable = true;
88 Object.defineProperty(target, descriptor.key, descriptor);
89 }
90 }
91
92 function _createClass(Constructor, protoProps, staticProps) {
93 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
94 if (staticProps) _defineProperties(Constructor, staticProps);
95 return Constructor;
96 }
97
98 function _possibleConstructorReturn(self, call) {
99 if (call && (_typeof(call) === "object" || typeof call === "function")) {
100 return call;
101 }
102
103 return _assertThisInitialized(self);
104 }
105
106 function _assertThisInitialized(self) {
107 if (self === void 0) {
108 throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
109 }
110
111 return self;
112 }
113
114 function _getPrototypeOf(o) {
115 _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
116 return o.__proto__ || Object.getPrototypeOf(o);
117 };
118 return _getPrototypeOf(o);
119 }
120
121 function _inherits(subClass, superClass) {
122 if (typeof superClass !== "function" && superClass !== null) {
123 throw new TypeError("Super expression must either be null or a function");
124 }
125
126 subClass.prototype = Object.create(superClass && superClass.prototype, {
127 constructor: {
128 value: subClass,
129 writable: true,
130 configurable: true
131 }
132 });
133 if (superClass) _setPrototypeOf(subClass, superClass);
134 }
135
136 function _setPrototypeOf(o, p) {
137 _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
138 o.__proto__ = p;
139 return o;
140 };
141
142 return _setPrototypeOf(o, p);
143 }
144
145 function _objectSpread(target) {
146 for (var i = 1; i < arguments.length; i++) {
147 var source = arguments[i] != null ? arguments[i] : {};
148 var ownKeys = Object.keys(source);
149
150 if (typeof Object.getOwnPropertySymbols === 'function') {
151 ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
152 return Object.getOwnPropertyDescriptor(source, sym).enumerable;
153 }));
154 }
155
156 ownKeys.forEach(function (key) {
157 _defineProperty(target, key, source[key]);
158 });
159 }
160
161 return target;
162 }
163
164 function _defineProperty(obj, key, value) {
165 if (key in obj) {
166 Object.defineProperty(obj, key, {
167 value: value,
168 enumerable: true,
169 configurable: true,
170 writable: true
171 });
172 } else {
173 obj[key] = value;
174 }
175
176 return obj;
177 }
178 /**
179 * @param {Element} menuBody The menu body with the menu arrow.
180 * @param {string} menuDirection Where the floating menu menu should be placed relative to the trigger button.
181 * @returns {FloatingMenu~offset} The adjustment of the floating menu position, upon the position of the menu arrow.
182 * @private
183 */
184
185
186 var getMenuOffset = function getMenuOffset(menuBody, menuDirection) {
187 var _DIRECTION_LEFT$DIREC, _DIRECTION_LEFT$DIREC2;
188
189 var arrowStyle = menuBody.ownerDocument.defaultView.getComputedStyle(menuBody, ':before');
190 var arrowPositionProp = (_DIRECTION_LEFT$DIREC = {}, _defineProperty(_DIRECTION_LEFT$DIREC, _floatingMenu.DIRECTION_LEFT, 'right'), _defineProperty(_DIRECTION_LEFT$DIREC, _floatingMenu.DIRECTION_TOP, 'bottom'), _defineProperty(_DIRECTION_LEFT$DIREC, _floatingMenu.DIRECTION_RIGHT, 'left'), _defineProperty(_DIRECTION_LEFT$DIREC, _floatingMenu.DIRECTION_BOTTOM, 'top'), _DIRECTION_LEFT$DIREC)[menuDirection];
191 var menuPositionAdjustmentProp = (_DIRECTION_LEFT$DIREC2 = {}, _defineProperty(_DIRECTION_LEFT$DIREC2, _floatingMenu.DIRECTION_LEFT, 'left'), _defineProperty(_DIRECTION_LEFT$DIREC2, _floatingMenu.DIRECTION_TOP, 'top'), _defineProperty(_DIRECTION_LEFT$DIREC2, _floatingMenu.DIRECTION_RIGHT, 'left'), _defineProperty(_DIRECTION_LEFT$DIREC2, _floatingMenu.DIRECTION_BOTTOM, 'top'), _DIRECTION_LEFT$DIREC2)[menuDirection];
192 var values = [arrowPositionProp, 'border-bottom-width'].reduce(function (o, name) {
193 return _objectSpread({}, o, _defineProperty({}, name, Number((/^([\d-.]+)px$/.exec(arrowStyle.getPropertyValue(name)) || [])[1])));
194 }, {});
195 var margin = 0;
196
197 if (menuDirection !== _floatingMenu.DIRECTION_BOTTOM) {
198 var style = menuBody.ownerDocument.defaultView.getComputedStyle(menuBody);
199 margin = Number((/^([\d-.]+)px$/.exec(style.getPropertyValue('margin-top')) || [])[1]);
200 }
201
202 values[arrowPositionProp] = values[arrowPositionProp] || -6; // IE, etc.
203
204 if (Object.keys(values).every(function (name) {
205 return !isNaN(values[name]);
206 })) {
207 var arrowPosition = values[arrowPositionProp],
208 borderBottomWidth = values['border-bottom-width'];
209 return _defineProperty({
210 left: 0,
211 top: 0
212 }, menuPositionAdjustmentProp, Math.sqrt(Math.pow(borderBottomWidth, 2) * 2) - arrowPosition + margin * (menuDirection === _floatingMenu.DIRECTION_TOP ? 2 : 1));
213 }
214
215 return undefined;
216 };
217
218 var Tooltip =
219 /*#__PURE__*/
220 function (_mixin) {
221 _inherits(Tooltip, _mixin);
222 /**
223 * Tooltip.
224 * @extends CreateComponent
225 * @extends InitComponentBySearch
226 * @extends Handles
227 */
228
229
230 function Tooltip(element, options) {
231 var _this;
232
233 _classCallCheck(this, Tooltip);
234
235 _this = _possibleConstructorReturn(this, _getPrototypeOf(Tooltip).call(this, element, options));
236 _this._hasContextMenu = false;
237 _this._debouncedHandleClick = (0, _lodash.default)(_this._handleClick, 200);
238
239 _this._hookOn(element);
240
241 return _this;
242 }
243 /**
244 * A flag to detect if `oncontextmenu` event is fired right before `focus`/`blur` events.
245 * @type {boolean}
246 */
247
248
249 _createClass(Tooltip, [{
250 key: "createdByEvent",
251
252 /**
253 * A method called when this widget is created upon events.
254 * @param {Event} event The event triggering the creation.
255 */
256 value: function createdByEvent(event) {
257 var relatedTarget = event.relatedTarget,
258 type = event.type;
259
260 this._debouncedHandleClick({
261 relatedTarget: relatedTarget,
262 type: type === 'focusin' ? 'focus' : type,
263 details: (0, _getLaunchingDetails.default)(event)
264 });
265 }
266 /**
267 * Changes the shown/hidden state.
268 * @param {string} state The new state.
269 * @param {Object} detail The detail of the event trigging this action.
270 * @param {Function} callback Callback called when change in state completes.
271 // */
272
273 }, {
274 key: "changeState",
275 value: function changeState(state, detail, callback) {
276 if (!this.tooltip) {
277 var tooltip = this.element.ownerDocument.querySelector(this.element.getAttribute(this.options.attribTooltipTarget));
278
279 if (!tooltip) {
280 throw new Error('Cannot find the target tooltip.');
281 } // Lazily create a component instance for tooltip
282
283
284 this.tooltip = _floatingMenu.default.create(tooltip, {
285 refNode: this.element,
286 classShown: this.options.classShown,
287 offset: this.options.objMenuOffset
288 });
289
290 this._hookOn(tooltip);
291
292 this.children.push(this.tooltip);
293 } // Delegates the action of changing state to the tooltip.
294 // (And thus the before/after shown/hidden events are fired from the tooltip)
295
296
297 this.tooltip.changeState(state, Object.assign(detail, {
298 delegatorNode: this.element
299 }), callback);
300 }
301 /**
302 * Attaches event handlers to show/hide the tooltip.
303 * @param {Element} element The element to attach the events to.
304 * @private
305 */
306
307 }, {
308 key: "_hookOn",
309 value: function _hookOn(element) {
310 var _this2 = this;
311
312 var hasFocusin = 'onfocusin' in window;
313 var focusinEventName = hasFocusin ? 'focusin' : 'focus';
314 [focusinEventName, 'blur', 'touchleave', 'touchcancel'].forEach(function (name) {
315 _this2.manage((0, _on.default)(element, name, function (event) {
316 var relatedTarget = event.relatedTarget,
317 type = event.type;
318 var hadContextMenu = _this2._hasContextMenu;
319 _this2._hasContextMenu = type === 'contextmenu';
320
321 _this2._debouncedHandleClick({
322 relatedTarget: relatedTarget,
323 type: type === 'focusin' ? 'focus' : type,
324 hadContextMenu: hadContextMenu,
325 details: (0, _getLaunchingDetails.default)(event)
326 });
327 }, name === focusinEventName && !hasFocusin));
328 });
329 }
330 /**
331 * Handles click/focus events.
332 * @param {Object} params The parameters.
333 * @param {Element} params.relatedTarget The element that focus went to. (For `blur` event)
334 * @param {string} params.type The event type triggering this method.
335 * @param {boolean} params.hadContextMenu
336 * @param {Object} params.details The event details.
337 * @private
338 */
339
340 }, {
341 key: "_handleClick",
342 value: function _handleClick(_ref2) {
343 var relatedTarget = _ref2.relatedTarget,
344 type = _ref2.type,
345 hadContextMenu = _ref2.hadContextMenu,
346 details = _ref2.details;
347 var state = {
348 focus: 'shown',
349 blur: 'hidden',
350 touchleave: 'hidden',
351 touchcancel: 'hidden'
352 }[type];
353 var shouldPreventClose;
354
355 if (type === 'blur') {
356 // Note: SVGElement in IE11 does not have `.contains()`
357 var wentToSelf = relatedTarget && this.element.contains && this.element.contains(relatedTarget) || this.tooltip && this.tooltip.element.contains(relatedTarget);
358 shouldPreventClose = hadContextMenu || wentToSelf;
359 }
360
361 if (!shouldPreventClose) {
362 this.changeState(state, details);
363 }
364 }
365 }], [{
366 key: "options",
367 get: function get() {
368 var prefix = _settings.default.prefix;
369 return {
370 selectorInit: '[data-tooltip-trigger]',
371 classShown: "".concat(prefix, "--tooltip--shown"),
372 attribTooltipTarget: 'data-tooltip-target',
373 objMenuOffset: getMenuOffset,
374 initEventNames: ['focus']
375 };
376 }
377 }]);
378
379 Tooltip.components = new WeakMap();
380 return Tooltip;
381 }((0, _mixin2.default)(_createComponent.default, _initComponentByEvent.default, _eventedShowHideState.default, _handles.default));
382
383 var _default = Tooltip;
384 _exports.default = _default;
385});
\No newline at end of file