util.js

/* eslint-disable prettier/prettier */
function tw2018func_cloneObj(obj) {
  const result = Object.create(null);
  for (const i in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, i)) {
      result[i] = obj[i];
    }
  }
  return result;
}

function tw_focus(elem, val) {
  if (val) {
    elem.classList.add("tw2018css_focused");
  } else {
    elem.classList.remove("tw2018css_focused");
  }
}

function tw_hide(elem) {
  elem.style.display = "none";
}

function tw_toggleCssClass(elem, cssClass) {
  if (elem.classList.contains(cssClass)) {
    elem.classList.remove(cssClass);
  } else {
    elem.classList.add(cssClass);
  }
}

/**
 * Gets the size of the specified page, converted from PDF units to inches.
 * @param {Object} An Object containing the properties: {Array} `view`,
 *   {number} `userUnit`, and {number} `rotate`.
 * @return {Object} An Object containing the properties: {number} `width`
 *   and {number} `height`, given in inches.
 */
function tw2018func_getPageSizeInches({ view, userUnit, rotate }) {
  const [x1, y1, x2, y2] = view;
  // We need to take the page rotation into account as well.
  const changeOrientation = rotate % 180 !== 0;

  const width = ((x2 - x1) / 72) * userUnit;
  const height = ((y2 - y1) / 72) * userUnit;

  return {
    width: changeOrientation ? height : width,
    height: changeOrientation ? width : height,
  };
}

/**
 * Helper function to parse query string (e.g. ?param1=value&parm2=...).
 */
function parseQueryString(query) {
  const parts = query.split("&");
  const params = Object.create(null);
  for (let i = 0, ii = parts.length; i < ii; ++i) {
    const param = parts[i].split("=");
    const key = param[0].toLowerCase();
    const value = param.length > 1 ? param[1] : null;
    params[decodeURIComponent(key)] = decodeURIComponent(value);
  }
  return params;
}

function tw2018func_isPortraitOrientation(size) {
  return size.width <= size.height;
}
/**
 * Returns the filename or guessed filename from the url (see issue 3455).
 * url {String} The original PDF location.
 * @return {String} Guessed PDF file name.
 */
function tw2018func_getPDFFileNameFromURL(url) {
  const reURI = /^(?:([^:]+:)?\/\/[^/]+)?([^?#]*)(\?[^#]*)?(#.*)?$/;
  //            SCHEME      HOST         1.PATH  2.QUERY   3.REF
  // Pattern to get last matching NAME.pdf
  const reFilename = /[^/?#=]+\.pdf\b(?!.*\.pdf\b)/i;
  const splitURI = reURI.exec(url);
  let suggestedFilename =
    reFilename.exec(splitURI[1]) ||
    reFilename.exec(splitURI[2]) ||
    reFilename.exec(splitURI[3]);
  if (suggestedFilename) {
    suggestedFilename = suggestedFilename[0];
    if (suggestedFilename.includes("%")) {
      // URL-encoded %2Fpath%2Fto%2Ffile.pdf should be file.pdf
      try {
        suggestedFilename = reFilename.exec(
          decodeURIComponent(suggestedFilename)
        )[0];
      } catch (e) {
        // Possible (extremely rare) errors:
        // URIError "Malformed URI", e.g. for "%AA.pdf"
        // TypeError "null has no properties", e.g. for "%2F.pdf"
      }
    }
  }
  return suggestedFilename || "document.pdf";
}

const MIN_Y_OFFSET = 10;
const MIN_X_OFFSET = 10;
const TW_DATA_TAG = "data-tw2018-pdf-viewer";

export {
  MIN_X_OFFSET,
  MIN_Y_OFFSET,
  TW_DATA_TAG,
  parseQueryString,
  tw2018func_cloneObj,
  tw2018func_getPageSizeInches,
  tw2018func_getPDFFileNameFromURL,
  tw2018func_isPortraitOrientation,
  tw_focus,
  tw_hide,
  tw_toggleCssClass,
};