diff --git a/javascript/_caretPosition.js b/javascript/_caretPosition.js
index c7d347f..3182514 100644
--- a/javascript/_caretPosition.js
+++ b/javascript/_caretPosition.js
@@ -1,147 +1,146 @@
// From https://github.com/component/textarea-caret-position
-class CaretUtils {
- // We'll copy the properties below into the mirror div.
- // Note that some browsers, such as Firefox, do not concatenate properties
- // into their shorthand (e.g. padding-top, padding-bottom etc. -> padding),
- // so we have to list every single property explicitly.
- static #properties = [
- 'direction', // RTL support
- 'boxSizing',
- 'width', // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does
- 'height',
- 'overflowX',
- 'overflowY', // copy the scrollbar for IE
-
- 'borderTopWidth',
- 'borderRightWidth',
- 'borderBottomWidth',
- 'borderLeftWidth',
- 'borderStyle',
-
- 'paddingTop',
- 'paddingRight',
- 'paddingBottom',
- 'paddingLeft',
-
- // https://developer.mozilla.org/en-US/docs/Web/CSS/font
- 'fontStyle',
- 'fontVariant',
- 'fontWeight',
- 'fontStretch',
- 'fontSize',
- 'fontSizeAdjust',
- 'lineHeight',
- 'fontFamily',
-
- 'textAlign',
- 'textTransform',
- 'textIndent',
- 'textDecoration', // might not make a difference, but better be safe
-
- 'letterSpacing',
- 'wordSpacing',
-
- 'tabSize',
- 'MozTabSize'
-
- ];
-
- static #isBrowser = (typeof window !== 'undefined');
- static #isFirefox = (this.#isBrowser && window.mozInnerScreenX != null);
-
- static getCaretCoordinates(element, position, options) {
- if (!this.#isBrowser) {
- throw new Error('textarea-caret-position#getCaretCoordinates should only be called in a browser');
- }
-
- var debug = options && options.debug || false;
- if (debug) {
- var el = document.querySelector('#input-textarea-caret-position-mirror-div');
- if (el) el.parentNode.removeChild(el);
- }
-
- // The mirror div will replicate the textarea's style
- var div = document.createElement('div');
- div.id = 'input-textarea-caret-position-mirror-div';
- document.body.appendChild(div);
-
- var style = div.style;
- var computed = window.getComputedStyle ? window.getComputedStyle(element) : element.currentStyle; // currentStyle for IE < 9
- var isInput = element.nodeName === 'INPUT';
-
- // Default textarea styles
- style.whiteSpace = 'pre-wrap';
- if (!isInput)
- style.wordWrap = 'break-word'; // only for textarea-s
-
- // Position off-screen
- style.position = 'absolute'; // required to return coordinates properly
- if (!debug)
- style.visibility = 'hidden'; // not 'display: none' because we want rendering
-
- // Transfer the element's properties to the div
- this.#properties.forEach(function (prop) {
- if (isInput && prop === 'lineHeight') {
- // Special case for s because text is rendered centered and line height may be != height
- if (computed.boxSizing === "border-box") {
- var height = parseInt(computed.height);
- var outerHeight =
- parseInt(computed.paddingTop) +
- parseInt(computed.paddingBottom) +
- parseInt(computed.borderTopWidth) +
- parseInt(computed.borderBottomWidth);
- var targetHeight = outerHeight + parseInt(computed.lineHeight);
- if (height > targetHeight) {
- style.lineHeight = height - outerHeight + "px";
- } else if (height === targetHeight) {
- style.lineHeight = computed.lineHeight;
- } else {
- style.lineHeight = 0;
- }
- } else {
- style.lineHeight = computed.height;
+TAC.getCaretCoordinates = class CaretUtils {
+ // We'll copy the properties below into the mirror div.
+ // Note that some browsers, such as Firefox, do not concatenate properties
+ // into their shorthand (e.g. padding-top, padding-bottom etc. -> padding),
+ // so we have to list every single property explicitly.
+ static #properties = [
+ "direction", // RTL support
+ "boxSizing",
+ "width", // on Chrome and IE, exclude the scrollbar, so the mirror div wraps exactly as the textarea does
+ "height",
+ "overflowX",
+ "overflowY", // copy the scrollbar for IE
+
+ "borderTopWidth",
+ "borderRightWidth",
+ "borderBottomWidth",
+ "borderLeftWidth",
+ "borderStyle",
+
+ "paddingTop",
+ "paddingRight",
+ "paddingBottom",
+ "paddingLeft",
+
+ // https://developer.mozilla.org/en-US/docs/Web/CSS/font
+ "fontStyle",
+ "fontVariant",
+ "fontWeight",
+ "fontStretch",
+ "fontSize",
+ "fontSizeAdjust",
+ "lineHeight",
+ "fontFamily",
+
+ "textAlign",
+ "textTransform",
+ "textIndent",
+ "textDecoration", // might not make a difference, but better be safe
+
+ "letterSpacing",
+ "wordSpacing",
+
+ "tabSize",
+ "MozTabSize",
+ ];
+
+ static #isBrowser = typeof window !== "undefined";
+ static #isFirefox = this.#isBrowser && window.mozInnerScreenX != null;
+
+ static getCaretCoordinates(element, position, options) {
+ if (!CaretUtils.#isBrowser) {
+ throw new Error(
+ "textarea-caret-position#getCaretCoordinates should only be called in a browser"
+ );
}
- } else {
- style[prop] = computed[prop];
- }
- });
-
- if (this.#isFirefox) {
- // Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275
- if (element.scrollHeight > parseInt(computed.height))
- style.overflowY = 'scroll';
- } else {
- style.overflow = 'hidden'; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'
+
+ var debug = (options && options.debug) || false;
+ if (debug) {
+ var el = document.querySelector("#input-textarea-caret-position-mirror-div");
+ if (el) el.parentNode.removeChild(el);
+ }
+
+ // The mirror div will replicate the textarea's style
+ var div = document.createElement("div");
+ div.id = "input-textarea-caret-position-mirror-div";
+ document.body.appendChild(div);
+
+ var style = div.style;
+ var computed = window.getComputedStyle
+ ? window.getComputedStyle(element)
+ : element.currentStyle; // currentStyle for IE < 9
+ var isInput = element.nodeName === "INPUT";
+
+ // Default textarea styles
+ style.whiteSpace = "pre-wrap";
+ if (!isInput) style.wordWrap = "break-word"; // only for textarea-s
+
+ // Position off-screen
+ style.position = "absolute"; // required to return coordinates properly
+ if (!debug) style.visibility = "hidden"; // not 'display: none' because we want rendering
+
+ // Transfer the element's properties to the div
+ CaretUtils.#properties.forEach(function (prop) {
+ if (isInput && prop === "lineHeight") {
+ // Special case for s because text is rendered centered and line height may be != height
+ if (computed.boxSizing === "border-box") {
+ var height = parseInt(computed.height);
+ var outerHeight =
+ parseInt(computed.paddingTop) +
+ parseInt(computed.paddingBottom) +
+ parseInt(computed.borderTopWidth) +
+ parseInt(computed.borderBottomWidth);
+ var targetHeight = outerHeight + parseInt(computed.lineHeight);
+ if (height > targetHeight) {
+ style.lineHeight = height - outerHeight + "px";
+ } else if (height === targetHeight) {
+ style.lineHeight = computed.lineHeight;
+ } else {
+ style.lineHeight = 0;
+ }
+ } else {
+ style.lineHeight = computed.height;
+ }
+ } else {
+ style[prop] = computed[prop];
+ }
+ });
+
+ if (CaretUtils.#isFirefox) {
+ // Firefox lies about the overflow property for textareas: https://bugzilla.mozilla.org/show_bug.cgi?id=984275
+ if (element.scrollHeight > parseInt(computed.height)) style.overflowY = "scroll";
+ } else {
+ style.overflow = "hidden"; // for Chrome to not render a scrollbar; IE keeps overflowY = 'scroll'
+ }
+
+ div.textContent = element.value.substring(0, position);
+ // The second special handling for input type="text" vs textarea:
+ // spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037
+ if (isInput) div.textContent = div.textContent.replace(/\s/g, "\u00a0");
+
+ var span = document.createElement("span");
+ // Wrapping must be replicated *exactly*, including when a long word gets
+ // onto the next line, with whitespace at the end of the line before (#7).
+ // The *only* reliable way to do that is to copy the *entire* rest of the
+ // textarea's content into the created at the caret position.
+ // For inputs, just '.' would be enough, but no need to bother.
+ span.textContent = element.value.substring(position) || "."; // || because a completely empty faux span doesn't render at all
+ div.appendChild(span);
+
+ var coordinates = {
+ top: span.offsetTop + parseInt(computed["borderTopWidth"]),
+ left: span.offsetLeft + parseInt(computed["borderLeftWidth"]),
+ height: parseInt(computed["lineHeight"]),
+ };
+
+ if (debug) {
+ span.style.backgroundColor = "#aaa";
+ } else {
+ document.body.removeChild(div);
+ }
+
+ return coordinates;
}
-
- div.textContent = element.value.substring(0, position);
- // The second special handling for input type="text" vs textarea:
- // spaces need to be replaced with non-breaking spaces - http://stackoverflow.com/a/13402035/1269037
- if (isInput)
- div.textContent = div.textContent.replace(/\s/g, '\u00a0');
-
- var span = document.createElement('span');
- // Wrapping must be replicated *exactly*, including when a long word gets
- // onto the next line, with whitespace at the end of the line before (#7).
- // The *only* reliable way to do that is to copy the *entire* rest of the
- // textarea's content into the created at the caret position.
- // For inputs, just '.' would be enough, but no need to bother.
- span.textContent = element.value.substring(position) || '.'; // || because a completely empty faux span doesn't render at all
- div.appendChild(span);
-
- var coordinates = {
- top: span.offsetTop + parseInt(computed['borderTopWidth']),
- left: span.offsetLeft + parseInt(computed['borderLeftWidth']),
- height: parseInt(computed['lineHeight'])
- };
-
- if (debug) {
- span.style.backgroundColor = '#aaa';
- } else {
- document.body.removeChild(div);
- }
-
- return coordinates;
- }
-}
\ No newline at end of file
+}.getCaretCoordinates;
diff --git a/javascript/tagAutocomplete.js b/javascript/tagAutocomplete.js
index 0f5bfa8..be3bb58 100644
--- a/javascript/tagAutocomplete.js
+++ b/javascript/tagAutocomplete.js
@@ -364,7 +364,7 @@ function showResults(textArea) {
parentDiv.style.display = "flex";
if (TAC.CFG.slidingPopup) {
- let caretPosition = CaretUtils.getCaretCoordinates(textArea, textArea.selectionEnd);
+ let caretPosition = TAC.getCaretCoordinates(textArea, textArea.selectionEnd);
// Top cursor offset fix for SDNext modern UI, based on code by https://github.com/Nyx01
let offsetTop = textArea.offsetTop + caretPosition.top - textArea.scrollTop + 10; // Adjust this value for desired distance below cursor
let offsetLeft = Math.min(textArea.offsetLeft - textArea.scrollLeft + caretPosition.left, textArea.offsetWidth - parentDiv.offsetWidth);