/* globals URLSearchParams */ /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ /* vim: set ft=javascript ts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; // Make this available to both AMD and CJS environments define(function (require, exports, module) { // Dependencies const React = require("devtools/client/shared/vendor/react"); /** * Create React factories for given arguments. * Example: * const { Rep } = createFactories(require("./rep")); */ function createFactories(args) { let result = {}; for (let p in args) { result[p] = React.createFactory(args[p]); } return result; } /** * Returns true if the given object is a grip (see RDP protocol) */ function isGrip(object) { return object && object.actor; } function escapeNewLines(value) { return value.replace(/\r/gm, "\\r").replace(/\n/gm, "\\n"); } function cropMultipleLines(text, limit) { return escapeNewLines(cropString(text, limit)); } function cropString(text, limit, alternativeText) { if (!alternativeText) { alternativeText = "\u2026"; } // Make sure it's a string and sanitize it. text = sanitizeString(text + ""); // Crop the string only if a limit is actually specified. if (!limit || limit <= 0) { return text; } // Set the limit at least to the length of the alternative text // plus one character of the original text. if (limit <= alternativeText.length) { limit = alternativeText.length + 1; } let halfLimit = (limit - alternativeText.length) / 2; if (text.length > limit) { return text.substr(0, Math.ceil(halfLimit)) + alternativeText + text.substr(text.length - Math.floor(halfLimit)); } return text; } function sanitizeString(text) { // Replace all non-printable characters, except of // (horizontal) tab (HT: \x09) and newline (LF: \x0A, CR: \x0D), // with unicode replacement character (u+fffd). // eslint-disable-next-line no-control-regex let re = new RegExp("[\x00-\x08\x0B\x0C\x0E-\x1F\x80-\x9F]", "g"); return text.replace(re, "\ufffd"); } function parseURLParams(url) { url = new URL(url); return parseURLEncodedText(url.searchParams); } function parseURLEncodedText(text) { let params = []; // In case the text is empty just return the empty parameters if (text == "") { return params; } let searchParams = new URLSearchParams(text); let entries = [...searchParams.entries()]; return entries.map(entry => { return { name: entry[0], value: entry[1] }; }); } function getFileName(url) { let split = splitURLBase(url); return split.name; } function splitURLBase(url) { if (!isDataURL(url)) { return splitURLTrue(url); } return {}; } function getURLDisplayString(url) { return cropString(url); } function isDataURL(url) { return (url && url.substr(0, 5) == "data:"); } function splitURLTrue(url) { const reSplitFile = /(.*?):\/{2,3}([^\/]*)(.*?)([^\/]*?)($|\?.*)/; let m = reSplitFile.exec(url); if (!m) { return { name: url, path: url }; } else if (m[4] == "" && m[5] == "") { return { protocol: m[1], domain: m[2], path: m[3], name: m[3] != "/" ? m[3] : m[2] }; } return { protocol: m[1], domain: m[2], path: m[2] + m[3], name: m[4] + m[5] }; } // Exports from this module exports.createFactories = createFactories; exports.isGrip = isGrip; exports.cropString = cropString; exports.cropMultipleLines = cropMultipleLines; exports.parseURLParams = parseURLParams; exports.parseURLEncodedText = parseURLEncodedText; exports.getFileName = getFileName; exports.getURLDisplayString = getURLDisplayString; exports.sanitizeString = sanitizeString; });