@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
JavaScript
/**
* @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");
*/