var Normalizer, Quill, Tooltip, dom, _; Quill = require('../quill'); Normalizer = require('../lib/normalizer'); _ = Quill.require('lodash'); dom = Quill.require('dom'); Tooltip = (function() { Tooltip.DEFAULTS = { offset: 10, styles: { '.tooltip': { 'background-color': '#fff', 'border': '1px solid #000', 'top': '0px', 'white-space': 'nowrap', 'z-index': '2000' }, '.tooltip a': { 'cursor': 'pointer', 'text-decoration': 'none' } }, template: '' }; Tooltip.HIDE_MARGIN = '-10000px'; function Tooltip(quill, options) { this.quill = quill; this.options = options; this.quill.addStyles(this.options.styles); this.container = this.quill.addContainer('tooltip'); this.container.innerHTML = Normalizer.stripWhitespace(this.options.template); this.container.style.position = 'absolute'; dom(this.quill.root).on('focus', _.bind(this.hide, this)); this.hide(); this.quill.on(this.quill.constructor.events.TEXT_CHANGE, (function(_this) { return function(delta, source) { if (source === 'user' && _this.container.style.left !== Tooltip.HIDE_MARGIN) { _this.range = null; return _this.hide(); } }; })(this)); } Tooltip.prototype.initTextbox = function(textbox, enterCallback, escapeCallback) { return dom(textbox).on('keyup', (function(_this) { return function(event) { switch (event.which) { case dom.KEYS.ENTER: return enterCallback.call(_this); case dom.KEYS.ESCAPE: return escapeCallback.call(_this); default: return true; } }; })(this)); }; Tooltip.prototype.hide = function() { this.container.style.left = Tooltip.HIDE_MARGIN; if (this.range) { this.quill.setSelection(this.range); } return this.range = null; }; Tooltip.prototype.show = function(reference) { var left, top, win, _ref, _ref1; this.range = this.quill.getSelection(); _ref = this._position(reference), left = _ref[0], top = _ref[1]; _ref1 = this._limit(left, top), left = _ref1[0], top = _ref1[1]; win = dom(this.quill.root).window(); left += win.pageXOffset; top += win.pageYOffset; this.container.style.left = "" + left + "px"; this.container.style.top = "" + top + "px"; return this.container.focus(); }; Tooltip.prototype._getBounds = function() { var bounds, scrollX, scrollY, win; bounds = this.quill.root.getBoundingClientRect(); win = dom(this.quill.root).window(); scrollX = win.pageXOffset; scrollY = win.pageYOffset; return { left: bounds.left + scrollX, right: bounds.right + scrollX, top: bounds.top + scrollY, bottom: bounds.bottom + scrollY, width: bounds.width, height: bounds.height }; }; Tooltip.prototype._limit = function(left, top) { var editorRect, toolbarRect; editorRect = this._getBounds(); toolbarRect = this.container.getBoundingClientRect(); left = Math.min(editorRect.right - toolbarRect.width, left); left = Math.max(editorRect.left, left); top = Math.min(editorRect.bottom - toolbarRect.height, top); top = Math.max(editorRect.top, top); return [left, top]; }; Tooltip.prototype._position = function(reference) { var editorRect, left, referenceBounds, toolbarRect, top; toolbarRect = this.container.getBoundingClientRect(); editorRect = this._getBounds(); if (reference != null) { referenceBounds = reference.getBoundingClientRect(); left = referenceBounds.left + referenceBounds.width / 2 - toolbarRect.width / 2; top = referenceBounds.top + referenceBounds.height + this.options.offset; if (top + toolbarRect.height > editorRect.bottom) { top = referenceBounds.top - toolbarRect.height - this.options.offset; } } else { left = editorRect.left + editorRect.width / 2 - toolbarRect.width / 2; top = editorRect.top + editorRect.height / 2 - toolbarRect.height / 2; } return [left, top]; }; return Tooltip; })(); Quill.registerModule('tooltip', Tooltip); module.exports = Tooltip;