'use strict'; /** * Licensed Materials - Property of IBM * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2015, 2017 * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ define(['../../../../lib/@waca/core-client/js/core-client/ui/core/Class', 'jquery'], function (Class, $) { // eslint-disable-next-line no-undef var MODIFIER_KEY = /^Mac/.test(navigator.platform) ? 'metaKey' : 'ctrlKey'; var RANGE_PROPERTIES = ['startContainer', 'endContainer', 'startOffset', 'endOffset']; /** * This helper class tries to mimic the behaviour of the new |selectionchange| event in browsers * that currently do not support it (Firefox). Once all browsers support this event, we can toss * this class. */ var TextSelectionNormalizer = Class.extend({ lastRange: null, init: function init() { TextSelectionNormalizer.inherited('init', this, arguments); // Immediately bind the events. this.bindEvents(); }, destroy: function destroy() { this.unbindEvents(); }, /** * Bind to mouse and keyboard events if needed. If the browser already supports the |selectionchange| event * then do nothing. */ bindEvents: function bindEvents() { if (!this.hasNativeEvent()) { this.lastRange = this.getSelectionRange(); this.fnOnMouseDown = this.onMouseDown.bind(this); this.fnOnMouseMove = this.onMouseMove.bind(this); this.fnOnMouseUp = this.onMouseUp.bind(this); this.fnOnKeyPress = this.onKeyPress.bind(this); this.fnOnFocus = this.onFocus.bind(this); $(document).on('mousedown', this.fnOnMouseDown).on('mousemove', this.fnOnMouseMove).on('mouseup', this.fnOnMouseUp).on('keypress', this.fnOnKeyPress); $(document.defaultView).on('focus', this.fnOnFocus); } }, /** * Unbinds all the events that were binded in bindEvents(). */ unbindEvents: function unbindEvents() { if (this.fnOnKeyPress) { $(document).off('mousedown', this.fnOnMouseDown).off('mousemove', this.fnOnMouseMove).off('mouseup', this.fnOnMouseUp).off('keypress', this.fnOnKeyPress); $(document.defaultView).off('focus', this.fnOnFocus); this.fnOnMouseDown = null; this.fnOnMouseMove = null; this.fnOnMouseUp = null; this.fnOnKeyPress = null; this.fnOnFocus = null; this.lastRange = null; } }, /** * Determine if the browser supports the selectionchange event. */ hasNativeEvent: function hasNativeEvent() { var handler = document.onselectionchange; if (handler !== undefined) { try { document.onselectionchange = 0; return document.onselectionchange === null; } catch (e) { console.error('ERROR: onSelectionChange event error.'); } finally { document.onselectionchange = handler; } } return false; }, getSelectionRange: function getSelectionRange() { var sel = document.getSelection(); return sel.rangeCount ? sel.getRangeAt(0) : null; }, onMouseDown: function onMouseDown(event) { var _this = this; var result = void 0; if (event.button === 0) { $(document).on('mousemove', this.fnOnMouseMove); result = new Promise(function (resolve, reject) { try { setTimeout(function () { _this.notifyIfNecessary(); resolve(); }, 0); } catch (error) { reject(error); } }); } else { result = Promise.resolve(); } return result; }, onMouseMove: function onMouseMove(event) { if (event.buttons === 1) { this.notifyIfNecessary(); } else { $(document).off('mousemove', this.fnOnMouseMove); } }, onMouseUp: function onMouseUp(event) { var _this2 = this; var result = void 0; if (event.button === 0) { result = new Promise(function (resolve, reject) { try { setTimeout(function () { _this2.notifyIfNecessary(); resolve(); }, 0); } catch (error) { reject(error); } }); } else { $(document).off('mousemove', this.fnOnMouseMove); result = Promise.resolve(); } return result; }, onKeyPress: function onKeyPress(event) { var _this3 = this; var code = event.keyCode; // Check for arrow keys, or [ctrl|cmd]-a var notify = code >= 37 && code <= 40 || event[MODIFIER_KEY] && !event.shiftKey && !event.altKey && event.key === 'a'; var result = void 0; if (notify) { result = new Promise(function (resolve, reject) { try { setTimeout(function () { _this3.notifyIfNecessary(); resolve(); }, 0); } catch (error) { reject(error); } }); } else { result = Promise.resolve(); } return result; }, onFocus: function onFocus() { var _this4 = this; return new Promise(function (resolve, reject) { try { setTimeout(function () { _this4.notifyIfNecessary(); resolve(); }, 0); } catch (error) { reject(error); } }); }, notifyIfNecessary: function notifyIfNecessary() { var rOld = this.lastRange; var rNew = this.getSelectionRange(); if (!this.sameRange(rNew, rOld)) { this.lastRange = rNew; // eslint-disable-next-line no-undef setTimeout(document.dispatchEvent.bind(document, new Event('selectionchange')), 0); } }, sameRange: function sameRange(r1, r2) { return r1 === r2 || r1 && r2 && RANGE_PROPERTIES.every(function (item) { return r1[item] === r2[item]; }); } }); return TextSelectionNormalizer; }); //# sourceMappingURL=TextSelectionNormalizer.js.map