UNPKG

@phoenix-plugin-registry/brackets-markdown-preview

Version:

Markdown live preview incl. detached window, code syntax highlighting, output themes, adaptive preview width, graphical checkboxes, activation on start...

282 lines (253 loc) 13.5 kB
/** * @module ExtUtils * @file Functions and classes of common utility * @author Loïs Bégué * @license MIT license (MIT) * @copyright Copyright (c) 2017 Loïs Bégué */ /*global define, $, brackets, window, document, XMLSerializer */ define(function (require, exports, module) { "use strict"; var FileUtils = brackets.getModule("file/FileUtils"); var NativeApp = brackets.getModule("utils/NativeApp"); var FileSystem = brackets.getModule("filesystem/FileSystem"); const Ellipsis = "\u2026"; // the 1 char representation of "..." const DefaultPaddingString = " "; const DefaultPaddingWidth = 80; /** * This function just gives its input back... * @author Loïs Bégué * @param {any} voice the input to be returned by the function * @returns {any} the input is returned as output without any modification */ function echo(voice) { return voice; } /** * The string input containing html code is encoded as a displayable text (masking of "<", ">" ... to entities) * @author Loïs Bégué * @example <caption>How to display a html code on a web page </caption> * var html = "<h1>Content of the heading level 1</h1>"; * var htmlEncoded = encodeHTML2String(html); * var webPageFragment = "Coding a level 1 heading (sample):<br/><span style='white-space:pre'>" + htmlEncoded + "</span>"; * @param {string} htmlText the text containing html code * @returns {string} the masked html code */ function encodeHTML2String(htmlText){ return $("<div/>").text(htmlText).html(); } /** * Retrieves the doctype information of a html document or create one if none could be found * @author Loïs Bégué * @param {object} HTMLDoc The DOM document object representing the html document * @returns {string} the string containing the doctype information (a default 'html doctype' in case the document doctype was missing) */ function HTMLDocumentDoctype2String(HTMLDoc){ let dt = HTMLDoc.doctype; if (!dt){ dt = document.implementation.createDocumentType("html", "", ""); } return new XMLSerializer().serializeToString(dt); /* ALTERNATIVE let node = HTMLDoc.doctype; if (!node) { node = document.implementation.createDocumentType("html"); } var html = "<!DOCTYPE " + node.name + (node.publicId ? ' PUBLIC "' + node.publicId + '"' : '') + (!node.publicId && node.systemId ? ' SYSTEM' : '') + (node.systemId ? ' "' + node.systemId + '"' : '') + '>'; return html; */ } /** * The (java-)script described as path is inserted as "<script>" object into the head of the input DOM document. * @author Loïs Bégué * @param {object} HTMLDoc The DOM document to be modified. * @param {string} pathToScriptFile The path to the script file that is used as "src" for the link. */ function insertScriptLinkIntoHTMLDocument(HTMLDoc, pathToScriptFile){ let head = HTMLDoc.head;//HTMLDoc.getElementsByTagName("head")[0]; let script = document.createElement("script"); script.type = "text/javascript"; script.src = pathToScriptFile; head.appendChild(script); } /** * The style sheet described as path is inserted as "<link>" object into the head of the input DOM document. * @author Loïs Bégué * @param {object} HTMLDoc The DOM document to be modified. * @param {string} pathToStyleSheetFile The path to the style sheet file that is used as "href" for the link. */ function insertStyleSheetLinkIntoHTMLDocument(HTMLDoc, pathToStyleSheetFile){ let head = HTMLDoc.head;//getElementsByTagName("head")[0]; let link = document.createElement("link"); link.type = "text/css"; link.rel = "stylesheet"; link.href = pathToStyleSheetFile; link.media = "screen,print"; head.appendChild(link); } /** * This function opens the input URL in the system default browser - unless the URL describes a Hash location (bookmark link) * @author Loïs Bégué * @param {string} url An URL to be opened in a browser */ function openURL(url) { // Prevent the opening of html bookmark URLs if (url && !url.match(/^#/)) { NativeApp.openURLInDefaultBrowser(url); } } /** * The input DOM node element is analysed (scanned) to detect a link and its href. If found, the link URL is opened in the system default browser. The parameter callback function is fired once the link is opened. * @author Loïs Bégué * @param {object} node A DOM node element * @param {function} afterOpeningCallback A callback function to be executed once a link URL has been opened in the browser. */ function openAnchorURL(node, afterOpeningCallback) { while (node) { if (node.tagName === "A") { let href = node.getAttribute("href"); openURL(href); afterOpeningCallback(href); break; } node = node.parentElement; } } function openFile(filePath) { // ensure the path is in a standard format filePath = FileUtils.convertWindowsPathToUnixPath(filePath); // To be safe, the file path should start with "file:///", nevertheless the current platform is "win" or not if (!filePath.match(/^file:\/\/\//)) { filePath = "file:///" + filePath; } NativeApp.openURLInDefaultBrowser(filePath); } function saveTextToFile (text, filePath) { let file = null; // ensure the path is in a standard format filePath = FileUtils.convertWindowsPathToUnixPath(filePath); file = FileSystem.getFileForPath(filePath); return FileUtils.writeText(file, text, true); } /** * Truncate a string at a given length and replace the end with the given suffix... see also lodash and underscore functions 'String.truncate()' * @author Loïs Bégué * @throws {RangeError} The suffix must not be longer than the maximal output length. * @param {string} inputString the string to be shortened. * @param {number} maximalOutputLength the maximal length of the resulting string. * @param {string} [suffixReplacementString = Ellipsis] the replacement string that will suffix the original input text - up to the maximal output lenght. The suffix may be a string itself. * @returns {string} A (shortened) string based on the input string, its length, the max allowed output length and the replacing suffix. */ function shortenString(inputString, maximalOutputLength, suffixReplacementString = Ellipsis){ if (suffixReplacementString.length > maximalOutputLength) { throw new RangeError("String cannot be shortened: the suffix is too long."); } let result = inputString; if (result.length <= maximalOutputLength) { return result; } return result.substr(0, maximalOutputLength - suffixReplacementString.length) + suffixReplacementString; } /** * Gives the padding string to pad an input string up to the given padding width. the padding string can be a string itself. * @author Loïs Bégué * @throws {RangeError} The padding width and the length of the padding string must both be > 0 * @param {string} inputString The string that should be padded * @param {number} paddingWidth The length of the resulting string * @param {string} paddingString = DefaultPaddingString The string used to fill the result up to the (padding width-input length) * @returns {string} The pad (without the input string) for the given input string and padding length. */ function getPaddingString(inputString, paddingWidth, paddingString = DefaultPaddingString){ if (paddingWidth < 1) { throw new RangeError("Padding cannot operate with a paddingWidth parameter < 1."); } if (paddingString.length < 1) { throw new RangeError("Padding cannot operate with an empty paddingString parameter."); } let result = ""; let padLength = paddingWidth - inputString.length; if (padLength>0) { let paddingStringLength = paddingString.length; let paddingStringRepetition = Math.trunc(padLength/paddingStringLength); let paddingStringRemainder = padLength - (paddingStringRepetition * paddingStringLength); result = paddingString.repeat(paddingStringRepetition) + ((paddingStringRemainder > 0) ? paddingString.substr(0, paddingStringRemainder) : ""); } return result; } /** * The input text is left padded up to the given width using the given padding string. * @author Loïs Bégué * @param {string} inputString The string to be padded. * @param {number} paddingWidth The width of the resulting string. * @param {string} [paddingString = DefaultPaddingString] The string used to fill the padded string. * @returns {string} The padded string. */ function padLeft(inputString, paddingWidth, paddingString = DefaultPaddingString){ return getPaddingString(inputString, paddingWidth, paddingString) + inputString; } /** * The input text is right padded up to the given width using the given padding string. * @author Loïs Bégué * @param {string} inputString The string to be padded. * @param {number} paddingWidth The width of the resulting string. * @param {string} [paddingString = DefaultPaddingString] The string used to fill the padded string. * @returns {string} The padded string. */ function padRight(inputString, paddingWidth, paddingString = DefaultPaddingString){ return inputString + getPaddingString(inputString, paddingWidth, paddingString); } /** * The input string representation of a number is left padded up to the given width using "0" as a padding character. * @author Loïs Bégué * @param {string} inputString The string to be padded. * @param {number} [paddingWidth = 3] The width of the resulting string. * @returns {string} The padded number as a string. */ function padNumber(aNumber, paddingWidth = 3){ return padLeft(aNumber.toString(), paddingWidth, "0"); } /** * The input text is right padded up to a width of 80 chars using a space char " ". * @author Loïs Bégué * @param {string} inputString The string to be padded. * @param {number} [paddingWidth = 80] The width of the resulting string: by default = 80 chars * @param {string} [paddingString = DefaultPaddingString] The string used to fill the padded string: by default a space char. * @returns {string} The padded string. */ function padText(textString, paddingWidth = DefaultPaddingWidth, paddingString = DefaultPaddingString){ return padRight(textString, paddingWidth, paddingString); } exports.Echo = echo; exports.openURL = openURL; exports.openAnchorURL = openAnchorURL; exports.openFile = openFile; exports.saveTextToFile = saveTextToFile; exports.encodeHTML2String = encodeHTML2String; exports.HTMLDocumentDoctype2String = HTMLDocumentDoctype2String; exports.insertScriptLinkIntoHTMLDocument = insertScriptLinkIntoHTMLDocument; exports.insertStyleSheetLinkIntoHTMLDocument = insertStyleSheetLinkIntoHTMLDocument; exports.padLeft = padLeft; exports.padRight = padRight; exports.padNumber = padNumber; exports.padText = padText; exports.shortenString = shortenString; /**************************************************************** * JQUERY PLUGIN FOR VISIBILITY TEST * => $(...).isVisible() * as a much faster replacement for $(...).is(":visible") * source: https://jsperf.com/jquery-visibility-test/2 ****************************************************************/ /*$.fn.isVisible = function() { return $.expr.filters.visible(this[0]); };*/ }); /* === TEST === saveTextToFile var testFile = "w:/export-testfile.txt"; ExtUtils.saveTextToFile("some test text... " + Date.now(), testFile).done( function(){ ExtUtils.openFile(testFile); }).fail( function(error){ console.error("Couldn't save to the file [" + testFile + "] due to the following error:/n" + error ); }); === TEST === openFile //ExtUtils.openFile("file:///W:/test.txt"); //ExtUtils.openFile("W:/test.txt"); //ExtUtils.openFile("W:\test.txt"); */