596 lines
25 KiB
JavaScript
596 lines
25 KiB
JavaScript
'use strict';
|
||
|
||
Object.defineProperty(exports, "__esModule", {
|
||
value: true
|
||
});
|
||
|
||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||
|
||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||
|
||
// Thanks to https://github.com/jeff-collins/ment.io
|
||
var TributeRange = function () {
|
||
function TributeRange(tribute) {
|
||
_classCallCheck(this, TributeRange);
|
||
|
||
this.tribute = tribute;
|
||
this.tribute.range = this;
|
||
}
|
||
|
||
_createClass(TributeRange, [{
|
||
key: 'getDocument',
|
||
value: function getDocument() {
|
||
var iframe = void 0;
|
||
if (this.tribute.current.collection) {
|
||
iframe = this.tribute.current.collection.iframe;
|
||
}
|
||
|
||
if (!iframe) {
|
||
return document;
|
||
}
|
||
|
||
return iframe.contentWindow.document;
|
||
}
|
||
}, {
|
||
key: 'positionMenuAtCaret',
|
||
value: function positionMenuAtCaret(scrollTo) {
|
||
var _this = this;
|
||
|
||
var context = this.tribute.current,
|
||
coordinates = void 0;
|
||
|
||
var info = this.getTriggerInfo(false, false, true, this.tribute.allowSpaces);
|
||
|
||
if (typeof info !== 'undefined') {
|
||
|
||
if (!this.tribute.positionMenu) {
|
||
this.tribute.menu.style.cssText = 'display: block;';
|
||
return;
|
||
}
|
||
|
||
if (!this.isContentEditable(context.element)) {
|
||
coordinates = this.getTextAreaOrInputUnderlinePosition(this.getDocument().activeElement, info.mentionPosition);
|
||
} else {
|
||
coordinates = this.getContentEditableCaretPosition(info.mentionPosition);
|
||
}
|
||
|
||
this.tribute.menu.style.cssText = 'top: ' + coordinates.top + 'px;\n left: ' + coordinates.left + 'px;\n right: ' + coordinates.right + 'px;\n bottom: ' + coordinates.bottom + 'px;\n position: absolute;\n zIndex: 10000;\n display: block;';
|
||
|
||
if (coordinates.left === 'auto') {
|
||
this.tribute.menu.style.left = 'auto';
|
||
}
|
||
|
||
if (coordinates.top === 'auto') {
|
||
this.tribute.menu.style.top = 'auto';
|
||
}
|
||
|
||
if (scrollTo) this.scrollIntoView();
|
||
|
||
window.setTimeout(function () {
|
||
var menuDimensions = {
|
||
width: _this.tribute.menu.offsetWidth,
|
||
height: _this.tribute.menu.offsetHeight
|
||
};
|
||
var menuIsOffScreen = _this.isMenuOffScreen(coordinates, menuDimensions);
|
||
|
||
if (menuIsOffScreen.horizontally || menuIsOffScreen.vertically) {
|
||
_this.tribute.menu.style.cssText = 'display: none';
|
||
_this.positionMenuAtCaret(scrollTo);
|
||
}
|
||
}, 0);
|
||
} else {
|
||
this.tribute.menu.style.cssText = 'display: none';
|
||
}
|
||
}
|
||
}, {
|
||
key: 'selectElement',
|
||
value: function selectElement(targetElement, path, offset) {
|
||
var range = void 0;
|
||
var elem = targetElement;
|
||
|
||
if (path) {
|
||
for (var i = 0; i < path.length; i++) {
|
||
elem = elem.childNodes[path[i]];
|
||
if (elem === undefined) {
|
||
return;
|
||
}
|
||
while (elem.length < offset) {
|
||
offset -= elem.length;
|
||
elem = elem.nextSibling;
|
||
}
|
||
if (elem.childNodes.length === 0 && !elem.length) {
|
||
elem = elem.previousSibling;
|
||
}
|
||
}
|
||
}
|
||
var sel = this.getWindowSelection();
|
||
|
||
range = this.getDocument().createRange();
|
||
range.setStart(elem, offset);
|
||
range.setEnd(elem, offset);
|
||
range.collapse(true);
|
||
|
||
try {
|
||
sel.removeAllRanges();
|
||
} catch (error) {}
|
||
|
||
sel.addRange(range);
|
||
targetElement.focus();
|
||
}
|
||
|
||
// TODO: this may not be necessary anymore as we are using mouseup instead of click
|
||
|
||
}, {
|
||
key: 'resetSelection',
|
||
value: function resetSelection(targetElement, path, offset) {
|
||
if (!this.isContentEditable(targetElement)) {
|
||
if (targetElement !== this.getDocument().activeElement) {
|
||
targetElement.focus();
|
||
}
|
||
} else {
|
||
this.selectElement(targetElement, path, offset);
|
||
}
|
||
}
|
||
}, {
|
||
key: 'replaceTriggerText',
|
||
value: function replaceTriggerText(text, requireLeadingSpace, hasTrailingSpace, originalEvent, item) {
|
||
var context = this.tribute.current;
|
||
// TODO: this may not be necessary anymore as we are using mouseup instead of click
|
||
// this.resetSelection(context.element, context.selectedPath, context.selectedOffset)
|
||
|
||
var info = this.getTriggerInfo(true, hasTrailingSpace, requireLeadingSpace, this.tribute.allowSpaces);
|
||
|
||
// Create the event
|
||
var replaceEvent = new CustomEvent('tribute-replaced', {
|
||
detail: {
|
||
item: item,
|
||
event: originalEvent
|
||
}
|
||
});
|
||
|
||
if (info !== undefined) {
|
||
if (!this.isContentEditable(context.element)) {
|
||
var myField = this.getDocument().activeElement;
|
||
var textSuffix = typeof this.tribute.replaceTextSuffix == 'string' ? this.tribute.replaceTextSuffix : ' ';
|
||
text += textSuffix;
|
||
var startPos = info.mentionPosition;
|
||
var endPos = info.mentionPosition + info.mentionText.length + textSuffix.length;
|
||
myField.value = myField.value.substring(0, startPos) + text + myField.value.substring(endPos, myField.value.length);
|
||
myField.selectionStart = startPos + text.length;
|
||
myField.selectionEnd = startPos + text.length;
|
||
} else {
|
||
// add a space to the end of the pasted text
|
||
var _textSuffix = typeof this.tribute.replaceTextSuffix == 'string' ? this.tribute.replaceTextSuffix : '\xA0';
|
||
text += _textSuffix;
|
||
this.pasteHtml(text, info.mentionPosition, info.mentionPosition + info.mentionText.length + 1);
|
||
}
|
||
|
||
context.element.dispatchEvent(replaceEvent);
|
||
}
|
||
}
|
||
}, {
|
||
key: 'pasteHtml',
|
||
value: function pasteHtml(html, startPos, endPos) {
|
||
var range = void 0,
|
||
sel = void 0;
|
||
sel = this.getWindowSelection();
|
||
range = this.getDocument().createRange();
|
||
range.setStart(sel.anchorNode, startPos);
|
||
range.setEnd(sel.anchorNode, endPos);
|
||
range.deleteContents();
|
||
|
||
var el = this.getDocument().createElement('div');
|
||
el.innerHTML = html;
|
||
var frag = this.getDocument().createDocumentFragment(),
|
||
node = void 0,
|
||
lastNode = void 0;
|
||
while (node = el.firstChild) {
|
||
lastNode = frag.appendChild(node);
|
||
}
|
||
range.insertNode(frag);
|
||
|
||
// Preserve the selection
|
||
if (lastNode) {
|
||
range = range.cloneRange();
|
||
range.setStartAfter(lastNode);
|
||
range.collapse(true);
|
||
sel.removeAllRanges();
|
||
sel.addRange(range);
|
||
}
|
||
}
|
||
}, {
|
||
key: 'getWindowSelection',
|
||
value: function getWindowSelection() {
|
||
if (this.tribute.collection.iframe) {
|
||
return this.tribute.collection.iframe.contentWindow.getSelection();
|
||
}
|
||
|
||
return window.getSelection();
|
||
}
|
||
}, {
|
||
key: 'getNodePositionInParent',
|
||
value: function getNodePositionInParent(element) {
|
||
if (element.parentNode === null) {
|
||
return 0;
|
||
}
|
||
|
||
for (var i = 0; i < element.parentNode.childNodes.length; i++) {
|
||
var node = element.parentNode.childNodes[i];
|
||
|
||
if (node === element) {
|
||
return i;
|
||
}
|
||
}
|
||
}
|
||
}, {
|
||
key: 'getContentEditableSelectedPath',
|
||
value: function getContentEditableSelectedPath(ctx) {
|
||
var sel = this.getWindowSelection();
|
||
var selected = sel.anchorNode;
|
||
var path = [];
|
||
var offset = void 0;
|
||
|
||
if (selected != null) {
|
||
var i = void 0;
|
||
var ce = selected.contentEditable;
|
||
while (selected !== null && ce !== 'true') {
|
||
i = this.getNodePositionInParent(selected);
|
||
path.push(i);
|
||
selected = selected.parentNode;
|
||
if (selected !== null) {
|
||
ce = selected.contentEditable;
|
||
}
|
||
}
|
||
path.reverse();
|
||
|
||
// getRangeAt may not exist, need alternative
|
||
offset = sel.getRangeAt(0).startOffset;
|
||
|
||
return {
|
||
selected: selected,
|
||
path: path,
|
||
offset: offset
|
||
};
|
||
}
|
||
}
|
||
}, {
|
||
key: 'getTextPrecedingCurrentSelection',
|
||
value: function getTextPrecedingCurrentSelection() {
|
||
var context = this.tribute.current,
|
||
text = '';
|
||
|
||
if (!this.isContentEditable(context.element)) {
|
||
var textComponent = this.tribute.current.element;
|
||
if (textComponent) {
|
||
var startPos = textComponent.selectionStart;
|
||
if (textComponent.value && startPos >= 0) {
|
||
text = textComponent.value.substring(0, startPos);
|
||
}
|
||
}
|
||
} else {
|
||
var selectedElem = this.getWindowSelection().anchorNode;
|
||
|
||
if (selectedElem != null) {
|
||
var workingNodeContent = selectedElem.textContent;
|
||
var selectStartOffset = this.getWindowSelection().getRangeAt(0).startOffset;
|
||
|
||
if (workingNodeContent && selectStartOffset >= 0) {
|
||
text = workingNodeContent.substring(0, selectStartOffset);
|
||
}
|
||
}
|
||
}
|
||
|
||
return text;
|
||
}
|
||
}, {
|
||
key: 'getTriggerInfo',
|
||
value: function getTriggerInfo(menuAlreadyActive, hasTrailingSpace, requireLeadingSpace, allowSpaces) {
|
||
var _this2 = this;
|
||
|
||
var ctx = this.tribute.current;
|
||
var selected = void 0,
|
||
path = void 0,
|
||
offset = void 0;
|
||
|
||
if (!this.isContentEditable(ctx.element)) {
|
||
selected = this.getDocument().activeElement;
|
||
} else {
|
||
var selectionInfo = this.getContentEditableSelectedPath(ctx);
|
||
|
||
if (selectionInfo) {
|
||
selected = selectionInfo.selected;
|
||
path = selectionInfo.path;
|
||
offset = selectionInfo.offset;
|
||
}
|
||
}
|
||
|
||
var effectiveRange = this.getTextPrecedingCurrentSelection();
|
||
|
||
if (effectiveRange !== undefined && effectiveRange !== null) {
|
||
var mostRecentTriggerCharPos = -1;
|
||
var triggerChar = void 0;
|
||
|
||
this.tribute.collection.forEach(function (config) {
|
||
var c = config.trigger;
|
||
var idx = config.requireLeadingSpace ? _this2.lastIndexWithLeadingSpace(effectiveRange, c) : effectiveRange.lastIndexOf(c);
|
||
|
||
if (idx > mostRecentTriggerCharPos) {
|
||
mostRecentTriggerCharPos = idx;
|
||
triggerChar = c;
|
||
requireLeadingSpace = config.requireLeadingSpace;
|
||
}
|
||
});
|
||
|
||
if (mostRecentTriggerCharPos >= 0 && (mostRecentTriggerCharPos === 0 || !requireLeadingSpace || /[\xA0\s]/g.test(effectiveRange.substring(mostRecentTriggerCharPos - 1, mostRecentTriggerCharPos)))) {
|
||
var currentTriggerSnippet = effectiveRange.substring(mostRecentTriggerCharPos + 1, effectiveRange.length);
|
||
|
||
triggerChar = effectiveRange.substring(mostRecentTriggerCharPos, mostRecentTriggerCharPos + 1);
|
||
var firstSnippetChar = currentTriggerSnippet.substring(0, 1);
|
||
var leadingSpace = currentTriggerSnippet.length > 0 && (firstSnippetChar === ' ' || firstSnippetChar === '\xA0');
|
||
if (hasTrailingSpace) {
|
||
currentTriggerSnippet = currentTriggerSnippet.trim();
|
||
}
|
||
|
||
var regex = allowSpaces ? /[^\S ]/g : /[\xA0\s]/g;
|
||
|
||
if (!leadingSpace && (menuAlreadyActive || !regex.test(currentTriggerSnippet))) {
|
||
return {
|
||
mentionPosition: mostRecentTriggerCharPos,
|
||
mentionText: currentTriggerSnippet,
|
||
mentionSelectedElement: selected,
|
||
mentionSelectedPath: path,
|
||
mentionSelectedOffset: offset,
|
||
mentionTriggerChar: triggerChar
|
||
};
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}, {
|
||
key: 'lastIndexWithLeadingSpace',
|
||
value: function lastIndexWithLeadingSpace(str, char) {
|
||
var reversedStr = str.split('').reverse().join('');
|
||
var index = -1;
|
||
|
||
for (var cidx = 0, len = str.length; cidx < len; cidx++) {
|
||
var firstChar = cidx === str.length - 1;
|
||
var leadingSpace = /\s/.test(reversedStr[cidx + 1]);
|
||
var match = char === reversedStr[cidx];
|
||
|
||
if (match && (firstChar || leadingSpace)) {
|
||
index = str.length - 1 - cidx;
|
||
break;
|
||
}
|
||
}
|
||
|
||
return index;
|
||
}
|
||
}, {
|
||
key: 'isContentEditable',
|
||
value: function isContentEditable(element) {
|
||
return element.nodeName !== 'INPUT' && element.nodeName !== 'TEXTAREA';
|
||
}
|
||
}, {
|
||
key: 'isMenuOffScreen',
|
||
value: function isMenuOffScreen(coordinates, menuDimensions) {
|
||
var contentWidth = menuDimensions.width + coordinates.left;
|
||
var contentHeight = menuDimensions.height + coordinates.top;
|
||
|
||
var windowWidth = window.innerWidth;
|
||
var windowHeight = window.innerHeight;
|
||
var doc = document.documentElement;
|
||
var windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
|
||
var windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
|
||
|
||
return {
|
||
horizontally: Math.ceil(contentWidth - windowLeft) >= windowWidth,
|
||
vertically: Math.ceil(contentHeight - windowTop) >= windowHeight
|
||
};
|
||
}
|
||
}, {
|
||
key: 'getMenuDimensions',
|
||
value: function getMenuDimensions() {
|
||
// Width of the menu depends of its contents and position
|
||
// We must check what its width would be without any obstruction
|
||
// This way, we can achieve good positioning for flipping the menu
|
||
var dimensions = {
|
||
width: null,
|
||
height: null
|
||
};
|
||
|
||
this.tribute.menu.style.cssText = 'top: 0px;\n left: 0px;\n position: fixed;\n zIndex: 10000;\n display: block;\n visibility; hidden;';
|
||
dimensions.width = this.tribute.menu.offsetWidth;
|
||
dimensions.height = this.tribute.menu.offsetHeight;
|
||
|
||
this.tribute.menu.style.cssText = 'display: none;';
|
||
|
||
return dimensions;
|
||
}
|
||
}, {
|
||
key: 'getTextAreaOrInputUnderlinePosition',
|
||
value: function getTextAreaOrInputUnderlinePosition(element, position, flipped) {
|
||
var properties = ['direction', 'boxSizing', 'width', 'height', 'overflowX', 'overflowY', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'paddingTop', 'paddingRight', 'paddingBottom', 'paddingLeft', 'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch', 'fontSize', 'fontSizeAdjust', 'lineHeight', 'fontFamily', 'textAlign', 'textTransform', 'textIndent', 'textDecoration', 'letterSpacing', 'wordSpacing'];
|
||
|
||
var isFirefox = window.mozInnerScreenX !== null;
|
||
|
||
var div = this.getDocument().createElement('div');
|
||
div.id = 'input-textarea-caret-position-mirror-div';
|
||
this.getDocument().body.appendChild(div);
|
||
|
||
var style = div.style;
|
||
var computed = window.getComputedStyle ? getComputedStyle(element) : element.currentStyle;
|
||
|
||
style.whiteSpace = 'pre-wrap';
|
||
if (element.nodeName !== 'INPUT') {
|
||
style.wordWrap = 'break-word';
|
||
}
|
||
|
||
// position off-screen
|
||
style.position = 'absolute';
|
||
style.visibility = 'hidden';
|
||
|
||
// transfer the element's properties to the div
|
||
properties.forEach(function (prop) {
|
||
style[prop] = computed[prop];
|
||
});
|
||
|
||
if (isFirefox) {
|
||
style.width = parseInt(computed.width) - 2 + 'px';
|
||
if (element.scrollHeight > parseInt(computed.height)) style.overflowY = 'scroll';
|
||
} else {
|
||
style.overflow = 'hidden';
|
||
}
|
||
|
||
div.textContent = element.value.substring(0, position);
|
||
|
||
if (element.nodeName === 'INPUT') {
|
||
div.textContent = div.textContent.replace(/\s/g, ' ');
|
||
}
|
||
|
||
var span = this.getDocument().createElement('span');
|
||
span.textContent = element.value.substring(position) || '.';
|
||
div.appendChild(span);
|
||
|
||
var rect = element.getBoundingClientRect();
|
||
var doc = document.documentElement;
|
||
var windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
|
||
var windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
|
||
|
||
var coordinates = {
|
||
top: rect.top + windowTop + span.offsetTop + parseInt(computed.borderTopWidth) + parseInt(computed.fontSize) - element.scrollTop,
|
||
left: rect.left + windowLeft + span.offsetLeft + parseInt(computed.borderLeftWidth)
|
||
};
|
||
|
||
var windowWidth = window.innerWidth;
|
||
var windowHeight = window.innerHeight;
|
||
|
||
var menuDimensions = this.getMenuDimensions();
|
||
var menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions);
|
||
|
||
if (menuIsOffScreen.horizontally) {
|
||
coordinates.right = windowWidth - coordinates.left;
|
||
coordinates.left = 'auto';
|
||
}
|
||
|
||
var parentHeight = this.tribute.menuContainer ? this.tribute.menuContainer.offsetHeight : this.getDocument().body.offsetHeight;
|
||
|
||
if (menuIsOffScreen.vertically) {
|
||
var parentRect = this.tribute.menuContainer ? this.tribute.menuContainer.getBoundingClientRect() : this.getDocument().body.getBoundingClientRect();
|
||
var scrollStillAvailable = parentHeight - (windowHeight - parentRect.top);
|
||
|
||
coordinates.bottom = scrollStillAvailable + (windowHeight - rect.top - span.offsetTop);
|
||
coordinates.top = 'auto';
|
||
}
|
||
|
||
this.getDocument().body.removeChild(div);
|
||
|
||
return coordinates;
|
||
}
|
||
}, {
|
||
key: 'getContentEditableCaretPosition',
|
||
value: function getContentEditableCaretPosition(selectedNodePosition) {
|
||
var markerTextChar = '';
|
||
var markerEl = void 0,
|
||
markerId = 'sel_' + new Date().getTime() + '_' + Math.random().toString().substr(2);
|
||
var range = void 0;
|
||
var sel = this.getWindowSelection();
|
||
var prevRange = sel.getRangeAt(0);
|
||
|
||
range = this.getDocument().createRange();
|
||
range.setStart(sel.anchorNode, selectedNodePosition);
|
||
range.setEnd(sel.anchorNode, selectedNodePosition);
|
||
|
||
range.collapse(false);
|
||
|
||
// Create the marker element containing a single invisible character using DOM methods and insert it
|
||
markerEl = this.getDocument().createElement('span');
|
||
markerEl.id = markerId;
|
||
|
||
markerEl.appendChild(this.getDocument().createTextNode(markerTextChar));
|
||
range.insertNode(markerEl);
|
||
sel.removeAllRanges();
|
||
sel.addRange(prevRange);
|
||
|
||
var rect = markerEl.getBoundingClientRect();
|
||
var doc = document.documentElement;
|
||
var windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
|
||
var windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
|
||
var coordinates = {
|
||
left: rect.left + windowLeft,
|
||
top: rect.top + markerEl.offsetHeight + windowTop
|
||
};
|
||
var windowWidth = window.innerWidth;
|
||
var windowHeight = window.innerHeight;
|
||
|
||
var menuDimensions = this.getMenuDimensions();
|
||
var menuIsOffScreen = this.isMenuOffScreen(coordinates, menuDimensions);
|
||
|
||
if (menuIsOffScreen.horizontally) {
|
||
coordinates.left = 'auto';
|
||
coordinates.right = windowWidth - rect.left - windowLeft;
|
||
}
|
||
|
||
var parentHeight = this.tribute.menuContainer ? this.tribute.menuContainer.offsetHeight : this.getDocument().body.offsetHeight;
|
||
|
||
if (menuIsOffScreen.vertically) {
|
||
var parentRect = this.tribute.menuContainer ? this.tribute.menuContainer.getBoundingClientRect() : this.getDocument().body.getBoundingClientRect();
|
||
var scrollStillAvailable = parentHeight - (windowHeight - parentRect.top);
|
||
|
||
windowLeft = (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
|
||
windowTop = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
|
||
coordinates.top = 'auto';
|
||
coordinates.bottom = scrollStillAvailable + (windowHeight - rect.top);
|
||
}
|
||
|
||
markerEl.parentNode.removeChild(markerEl);
|
||
return coordinates;
|
||
}
|
||
}, {
|
||
key: 'scrollIntoView',
|
||
value: function scrollIntoView(elem) {
|
||
var reasonableBuffer = 20,
|
||
clientRect = void 0;
|
||
var maxScrollDisplacement = 100;
|
||
var e = this.menu;
|
||
|
||
if (typeof e === 'undefined') return;
|
||
|
||
while (clientRect === undefined || clientRect.height === 0) {
|
||
clientRect = e.getBoundingClientRect();
|
||
|
||
if (clientRect.height === 0) {
|
||
e = e.childNodes[0];
|
||
if (e === undefined || !e.getBoundingClientRect) {
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
var elemTop = clientRect.top;
|
||
var elemBottom = elemTop + clientRect.height;
|
||
|
||
if (elemTop < 0) {
|
||
window.scrollTo(0, window.pageYOffset + clientRect.top - reasonableBuffer);
|
||
} else if (elemBottom > window.innerHeight) {
|
||
var maxY = window.pageYOffset + clientRect.top - reasonableBuffer;
|
||
|
||
if (maxY - window.pageYOffset > maxScrollDisplacement) {
|
||
maxY = window.pageYOffset + maxScrollDisplacement;
|
||
}
|
||
|
||
var targetY = window.pageYOffset - (window.innerHeight - elemBottom);
|
||
|
||
if (targetY > maxY) {
|
||
targetY = maxY;
|
||
}
|
||
|
||
window.scrollTo(0, targetY);
|
||
}
|
||
}
|
||
}]);
|
||
|
||
return TributeRange;
|
||
}();
|
||
|
||
exports.default = TributeRange;
|
||
module.exports = exports['default']; |