MediaWiki:Gadget-Textarea-Autoheight.js

From Cosmoteer Wiki
Jump to navigation Jump to search

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/*
 * gadget: Automatically expands specified textarea elements on entered content. 
 * authors: height autoexpand code by DreamTeK (https://stackoverflow.com/a/25621277), gadget code by aliser.
 * documentation and master version: https://github.com/murolem/cosmoteer-wiki-gadget-textarea-autoheight
 * license: MIT
*/

var __defProp = Object.defineProperty;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = function(obj, key, value) {
  return key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value: value }) : obj[key] = value;
};
var __spreadValues = function(a, b) {
  for (var prop in b || (b = {}))
    if (__hasOwnProp.call(b, prop))
      __defNormalProp(a, prop, b[prop]);
  if (__getOwnPropSymbols)
    for (var props = __getOwnPropSymbols(b), i = 0, n = props.length, prop; i < n; i++) {
      prop = props[i];
      if (__propIsEnum.call(b, prop))
        __defNormalProp(a, prop, b[prop]);
    }
  return a;
};
var gadgetName = "gadget-textarea-autoheight";
var loggerPrefix = gadgetName;
function getLoggers() {
  return {
    /**
     * Log messages using `console.log`.
     * @param message First message to log.
     * @param moreMessages Any additional messages to log.
     */
    logInfo: function(message, moreMessages) {
      console.log.apply(null, ["[".concat(loggerPrefix, "] ").concat(message)].concat(moreMessages != null ? moreMessages : []));
    },
    /**
    * Log warning messages using `mw.log.warn`.
    * @param message First message to log.
    * @param moreMessages Any additional messages to log.
    */
    logWarn: function(message, moreMessages) {
      mw.log.warn.apply(null, ["[".concat(loggerPrefix, "] ").concat(message)].concat(moreMessages != null ? moreMessages : []));
    },
    /**
     * Log error messages using `mw.log.error`.
     * @param message First message to log.
     * @param moreMessages Any additional messages to log.
     * @param opts Options.
     */
    logError: function(message, moreMessages, opts) {
      var defaulOpts = {
        throwErr: false
      };
      opts = Object.assign(defaulOpts, opts != null ? opts : {});
      mw.log.error.apply(null, ["[".concat(loggerPrefix, "] ").concat(message)].concat(moreMessages != null ? moreMessages : []));
      if (opts.throwErr) {
        throw new Error("[".concat(loggerPrefix, "] an error occured - see output above for details"));
      }
    }
  };
}
var loggers$1 = getLoggers();
var logError = loggers$1.logError;
function removePxFromStringEnd(str) {
  if (str.endsWith("px")) {
    return str.slice(0, -2);
  } else {
    return str;
  }
}
function removePxFromStringEndAndConvertToNumber(str) {
  var result = removePxFromStringEnd(str);
  if (result.length === str.length) {
    logError('expected "px" at the end of given string: '.concat(str), [], { throwErr: true });
  }
  return parseFloat(result);
}
var loggers = getLoggers();
var logInfo = loggers.logInfo;
var selectors = [
  /* templateData modal → param params → param input */
  {
    s: ".oo-ui-windowManager-modal .tdg-templateDataDialog-editParamPanel .oo-ui-inputWidget-input",
    factorInBorderWidth: true
  }
];
$(function() {
  var dataBySelectors = [];
  selectors.forEach(function(selectorEntry) {
    var selector = selectorEntry.s;
    var defaultOptions = {
      factorInBorderWidth: false
    };
    var providedOptions = selectorEntry;
    var opts = Object.assign(__spreadValues({}, defaultOptions), providedOptions);
    delete opts.s;
    var selectorData = {
      selector: selector,
      options: opts,
      results: {
        successful: [],
        failed__prohibitedTag: []
      }
    };
    dataBySelectors.push(selectorData);
    $(selector).each(function() {
      if (this.tagName !== "TEXTAREA") {
        selectorData.results.failed__prohibitedTag.push(this);
        return;
      }
      var el = this;
      var computedStyles = window.getComputedStyle(el);
      logInfo(computedStyles.height);
      var initialHeightPx = el.clientHeight + (opts.factorInBorderWidth ? removePxFromStringEndAndConvertToNumber(computedStyles.borderTopWidth) + removePxFromStringEndAndConvertToNumber(computedStyles.borderBottomWidth) : 0);
      var calculateAndSetHeight = function() {
        el.style.height = "0";
        var contentHeightPx = el.scrollHeight + (opts.factorInBorderWidth ? removePxFromStringEndAndConvertToNumber(computedStyles.borderTopWidth) + removePxFromStringEndAndConvertToNumber(computedStyles.borderBottomWidth) : 0);
        var resultingHeightPx = Math.max(initialHeightPx, contentHeightPx);
        el.style.height = "".concat(resultingHeightPx, "px");
      };
      el.addEventListener("input", calculateAndSetHeight);
      var lastObserverUpdateTimestamp = 0;
      var observer = new MutationObserver(function(mutations) {
        var timestamp = Date.now();
        if (el.style.height === "") {
          var lastUpdateDeltaMs = timestamp - lastObserverUpdateTimestamp;
          if (lastUpdateDeltaMs <= 10) {
            return;
          }
          calculateAndSetHeight();
          lastObserverUpdateTimestamp = timestamp;
        }
      });
      observer.observe(el, {
        attributes: true
        //configure it to listen to attribute changes
      });
      selectorData.results.successful.push(this);
    });
  });
  logInfo("affected elements:\n", [dataBySelectors]);
});