@samuelmeuli/font-manager
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -0,0 +0,0 @@ import { Font } from "../types"; |
@@ -0,0 +0,0 @@ export declare function stylesheetExists(fontId: string, isPreview?: boolean): boolean; |
@@ -10,3 +10,3 @@ import "./picker-styles/styles.scss"; | ||
selectorSuffix: string; | ||
constructor(apiKey: string, defaultFamily: string, { pickerId, families, categories, scripts, variants, limit, }: Options, onChange?: (font: Font) => void); | ||
constructor(apiKey: string, defaultFamily: string | undefined, { pickerId, families, categories, scripts, variants, limit, sort, }: Options, onChange?: (font: Font) => void); | ||
init(): Promise<FontList>; | ||
@@ -13,0 +13,0 @@ getFonts(): FontList; |
export default function extractFontStyles(allFontStyles: string): Record<string, string>; | ||
//# sourceMappingURL=extractFontStyles.d.ts.map |
import { Font } from "../types"; | ||
export default function getFontList(apiKey: string): Promise<Font[]>; | ||
//# sourceMappingURL=fontList.d.ts.map |
import { Font, Script, Variant } from "../types"; | ||
export default function getStylesheet(fonts: Font[], scripts: Script[], variants: Variant[], previewsOnly: boolean): Promise<string>; | ||
//# sourceMappingURL=fontStylesheet.d.ts.map |
@@ -0,0 +0,0 @@ export { default as FontManager } from "./FontManager"; |
1100
dist/index.es.js
@@ -1,197 +0,359 @@ | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use | ||
this file except in compliance with the License. You may obtain a copy of the | ||
License at http://www.apache.org/licenses/LICENSE-2.0 | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { | ||
try { | ||
var info = gen[key](arg); | ||
var value = info.value; | ||
} catch (error) { | ||
reject(error); | ||
return; | ||
} | ||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED | ||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | ||
MERCHANTABLITY OR NON-INFRINGEMENT. | ||
if (info.done) { | ||
resolve(value); | ||
} else { | ||
Promise.resolve(value).then(_next, _throw); | ||
} | ||
} | ||
See the Apache Version 2.0 License for specific language governing permissions | ||
and limitations under the License. | ||
***************************************************************************** */ | ||
function _asyncToGenerator(fn) { | ||
return function () { | ||
var self = this, | ||
args = arguments; | ||
return new Promise(function (resolve, reject) { | ||
var gen = fn.apply(self, args); | ||
var __assign = function() { | ||
__assign = Object.assign || function __assign(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
function _next(value) { | ||
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); | ||
} | ||
function __rest(s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) | ||
t[p[i]] = s[p[i]]; | ||
return t; | ||
function _throw(err) { | ||
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); | ||
} | ||
_next(undefined); | ||
}); | ||
}; | ||
} | ||
function __awaiter(thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
function _classCallCheck(instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
} | ||
function _defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || false; | ||
descriptor.configurable = true; | ||
if ("value" in descriptor) descriptor.writable = true; | ||
Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
} | ||
function _createClass(Constructor, protoProps, staticProps) { | ||
if (protoProps) _defineProperties(Constructor.prototype, protoProps); | ||
if (staticProps) _defineProperties(Constructor, staticProps); | ||
return Constructor; | ||
} | ||
function _defineProperty(obj, key, value) { | ||
if (key in obj) { | ||
Object.defineProperty(obj, key, { | ||
value: value, | ||
enumerable: true, | ||
configurable: true, | ||
writable: true | ||
}); | ||
} else { | ||
obj[key] = value; | ||
} | ||
return obj; | ||
} | ||
function __generator(thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
function ownKeys(object, enumerableOnly) { | ||
var keys = Object.keys(object); | ||
if (Object.getOwnPropertySymbols) { | ||
var symbols = Object.getOwnPropertySymbols(object); | ||
if (enumerableOnly) symbols = symbols.filter(function (sym) { | ||
return Object.getOwnPropertyDescriptor(object, sym).enumerable; | ||
}); | ||
keys.push.apply(keys, symbols); | ||
} | ||
return keys; | ||
} | ||
function _objectSpread2(target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i] != null ? arguments[i] : {}; | ||
if (i % 2) { | ||
ownKeys(source, true).forEach(function (key) { | ||
_defineProperty(target, key, source[key]); | ||
}); | ||
} else if (Object.getOwnPropertyDescriptors) { | ||
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); | ||
} else { | ||
ownKeys(source).forEach(function (key) { | ||
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); | ||
}); | ||
} | ||
} | ||
return target; | ||
} | ||
function _objectWithoutPropertiesLoose(source, excluded) { | ||
if (source == null) return {}; | ||
var target = {}; | ||
var sourceKeys = Object.keys(source); | ||
var key, i; | ||
for (i = 0; i < sourceKeys.length; i++) { | ||
key = sourceKeys[i]; | ||
if (excluded.indexOf(key) >= 0) continue; | ||
target[key] = source[key]; | ||
} | ||
return target; | ||
} | ||
function _objectWithoutProperties(source, excluded) { | ||
if (source == null) return {}; | ||
var target = _objectWithoutPropertiesLoose(source, excluded); | ||
var key, i; | ||
if (Object.getOwnPropertySymbols) { | ||
var sourceSymbolKeys = Object.getOwnPropertySymbols(source); | ||
for (i = 0; i < sourceSymbolKeys.length; i++) { | ||
key = sourceSymbolKeys[i]; | ||
if (excluded.indexOf(key) >= 0) continue; | ||
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; | ||
target[key] = source[key]; | ||
} | ||
} | ||
return target; | ||
} | ||
/** | ||
* Return the fontId based on the provided font family | ||
*/ | ||
function getFontId(fontFamily) { | ||
return fontFamily.replace(/\s+/g, "-").toLowerCase(); | ||
return fontFamily.replace(/\s+/g, "-").toLowerCase(); | ||
} | ||
/** | ||
* Throw an error if the provided pickerId doesn't consist only of letters and digits | ||
*/ | ||
function validatePickerId(pickerId) { | ||
if (pickerId.match(/[^0-9a-z]/i)) { | ||
throw Error("The `pickerId` parameter may only contain letters and digits"); | ||
} | ||
if (pickerId.match(/[^0-9a-z]/i)) { | ||
throw Error("The `pickerId` parameter may only contain letters and digits"); | ||
} | ||
} | ||
/** | ||
* Execute a GET XMLHttpRequest and return the result | ||
*/ | ||
function get(url) { | ||
return new Promise(function (resolve, reject) { | ||
var request = new XMLHttpRequest(); | ||
request.overrideMimeType("application/json"); | ||
request.open("GET", url, true); | ||
request.onreadystatechange = function () { | ||
if (request.readyState === 4) { | ||
if (request.status !== 200) { | ||
reject(new Error("Response has status code " + request.status)); | ||
} | ||
else { | ||
resolve(request.responseText); | ||
} | ||
} | ||
}; | ||
request.send(); | ||
}); | ||
return new Promise(function (resolve, reject) { | ||
var request = new XMLHttpRequest(); | ||
request.overrideMimeType("application/json"); | ||
request.open("GET", url, true); | ||
request.onreadystatechange = function () { | ||
// Request has completed | ||
if (request.readyState === 4) { | ||
if (request.status !== 200) { | ||
// On error | ||
reject(new Error("Response has status code ".concat(request.status))); | ||
} else { | ||
// On success | ||
resolve(request.responseText); | ||
} | ||
} | ||
}; | ||
request.send(); | ||
}); | ||
} | ||
var LIST_BASE_URL = "https://www.googleapis.com/webfonts/v1"; | ||
function getFontList(apiKey) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var url, response, json, fontsOriginal; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
url = LIST_BASE_URL + "/webfonts?sort=popularity&key=" + apiKey; | ||
return [4, get(url)]; | ||
case 1: | ||
response = _a.sent(); | ||
json = JSON.parse(response); | ||
fontsOriginal = json.items; | ||
return [2, fontsOriginal.map(function (fontOriginal) { | ||
var family = fontOriginal.family, subsets = fontOriginal.subsets, others = __rest(fontOriginal, ["family", "subsets"]); | ||
return __assign({}, others, { family: family, id: getFontId(family), scripts: subsets }); | ||
})]; | ||
} | ||
}); | ||
}); | ||
/** | ||
* Font object returned by the Google API. Contains a field "subsets" which will be renamed to | ||
* "scripts" | ||
*/ | ||
/** | ||
* Fetch the list of all available fonts from the Google Fonts API | ||
*/ | ||
function getFontList(_x) { | ||
return _getFontList.apply(this, arguments); | ||
} | ||
function _getFontList() { | ||
_getFontList = _asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee(apiKey) { | ||
var url, response, json, fontsOriginal; | ||
return regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
// Request list of all Google Fonts, sorted by popularity | ||
url = "".concat(LIST_BASE_URL, "/webfonts?sort=popularity&key=").concat(apiKey); | ||
_context.next = 3; | ||
return get(url); | ||
case 3: | ||
response = _context.sent; | ||
// Parse font list | ||
json = JSON.parse(response); // For each font: | ||
// - Rename "subset" key to "script" | ||
// - Generate fontId | ||
// Return the updated list | ||
fontsOriginal = json.items; | ||
return _context.abrupt("return", fontsOriginal.map(function (fontOriginal) { | ||
var family = fontOriginal.family, | ||
subsets = fontOriginal.subsets, | ||
others = _objectWithoutProperties(fontOriginal, ["family", "subsets"]); | ||
return _objectSpread2({}, others, { | ||
family: family, | ||
id: getFontId(family), | ||
scripts: subsets | ||
}); | ||
})); | ||
case 7: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee); | ||
})); | ||
return _getFontList.apply(this, arguments); | ||
} | ||
var previewFontsStylesheet = document.createElement("style"); | ||
document.head.appendChild(previewFontsStylesheet); | ||
/** | ||
* Add declaration for applying the specified preview font | ||
*/ | ||
function applyFontPreview(previewFont, selectorSuffix) { | ||
var fontId = getFontId(previewFont.family); | ||
var style = "\n\t\t\t#font-button-" + fontId + selectorSuffix + " {\n\t\t\t\tfont-family: \"" + previewFont.family + "\";\n\t\t\t}\n\t\t"; | ||
previewFontsStylesheet.appendChild(document.createTextNode(style)); | ||
var fontId = getFontId(previewFont.family); | ||
var style = "\n\t\t\t#font-button-".concat(fontId).concat(selectorSuffix, " {\n\t\t\t\tfont-family: \"").concat(previewFont.family, "\";\n\t\t\t}\n\t\t"); | ||
previewFontsStylesheet.appendChild(document.createTextNode(style)); | ||
} | ||
/** | ||
* Create/find and return the apply-font stylesheet for the provided selectorSuffix | ||
*/ | ||
function getActiveFontStylesheet(selectorSuffix) { | ||
var stylesheetId = "active-font-" + selectorSuffix; | ||
var activeFontStylesheet = document.getElementById(stylesheetId); | ||
if (!activeFontStylesheet) { | ||
activeFontStylesheet = document.createElement("style"); | ||
activeFontStylesheet.id = stylesheetId; | ||
document.head.appendChild(activeFontStylesheet); | ||
} | ||
return activeFontStylesheet; | ||
var stylesheetId = "active-font-".concat(selectorSuffix); | ||
var activeFontStylesheet = document.getElementById(stylesheetId); | ||
if (!activeFontStylesheet) { | ||
activeFontStylesheet = document.createElement("style"); | ||
activeFontStylesheet.id = stylesheetId; | ||
document.head.appendChild(activeFontStylesheet); | ||
} | ||
return activeFontStylesheet; | ||
} | ||
/** | ||
* Add/update declaration for applying the current active font | ||
*/ | ||
function applyActiveFont(activeFont, previousFontFamily, selectorSuffix) { | ||
var style = "\n\t\t.apply-font" + selectorSuffix + " {\n\t\t\tfont-family: \"" + activeFont.family + "\"" + (previousFontFamily ? ", \"" + previousFontFamily + "\"" : "") + ";\n\t\t}\n\t"; | ||
var activeFontStylesheet = getActiveFontStylesheet(selectorSuffix); | ||
activeFontStylesheet.innerHTML = style; | ||
var style = "\n\t\t.apply-font".concat(selectorSuffix, " {\n\t\t\tfont-family: \"").concat(activeFont.family, "\"").concat(previousFontFamily ? ", \"".concat(previousFontFamily, "\"") : "", ";\n\t\t}\n\t"); | ||
var activeFontStylesheet = getActiveFontStylesheet(selectorSuffix); | ||
activeFontStylesheet.innerHTML = style; | ||
} | ||
var PREVIEW_ATTRIBUTE_NAME = "data-is-preview"; | ||
/** | ||
* Generate font stylesheet ID from fontId | ||
*/ | ||
function getStylesheetId(fontId) { | ||
return "font-" + fontId; | ||
return "font-".concat(fontId); | ||
} | ||
/** | ||
* Check whether a font stylesheet already exists in the document head | ||
*/ | ||
function stylesheetExists(fontId, isPreview) { | ||
var stylesheetNode = document.getElementById(getStylesheetId(fontId)); | ||
var stylesheetNodeExists = stylesheetNode !== null; | ||
if (isPreview === null || isPreview === undefined) { | ||
return stylesheetNodeExists; | ||
} | ||
return (stylesheetNodeExists && | ||
stylesheetNode.getAttribute(PREVIEW_ATTRIBUTE_NAME) === isPreview.toString()); | ||
var stylesheetNode = document.getElementById(getStylesheetId(fontId)); | ||
if (isPreview === null || isPreview === undefined) { | ||
return stylesheetNode !== null; | ||
} | ||
return stylesheetNode !== null && stylesheetNode.getAttribute(PREVIEW_ATTRIBUTE_NAME) === isPreview.toString(); | ||
} | ||
/** | ||
* Attach a new font stylesheet to the document head using the provided content | ||
*/ | ||
function createStylesheet(fontId, isPreview) { | ||
var stylesheetNode = document.createElement("style"); | ||
stylesheetNode.id = getStylesheetId(fontId); | ||
stylesheetNode.setAttribute(PREVIEW_ATTRIBUTE_NAME, isPreview.toString()); | ||
document.head.appendChild(stylesheetNode); | ||
var stylesheetNode = document.createElement("style"); | ||
stylesheetNode.id = getStylesheetId(fontId); | ||
stylesheetNode.setAttribute(PREVIEW_ATTRIBUTE_NAME, isPreview.toString()); | ||
document.head.appendChild(stylesheetNode); | ||
} | ||
/** | ||
* Insert the provided styles in the font's <style> element (existing styles are replaced) | ||
*/ | ||
function fillStylesheet(fontId, styles) { | ||
var stylesheetId = getStylesheetId(fontId); | ||
var stylesheetNode = document.getElementById(stylesheetId); | ||
if (stylesheetNode) { | ||
stylesheetNode.textContent = styles; | ||
} | ||
else { | ||
console.error("Could not fill stylesheet: Stylesheet with ID \"" + stylesheetId + "\" not found"); | ||
} | ||
var stylesheetId = getStylesheetId(fontId); | ||
var stylesheetNode = document.getElementById(stylesheetId); | ||
if (stylesheetNode) { | ||
stylesheetNode.textContent = styles; | ||
} else { | ||
console.error("Could not fill stylesheet: Stylesheet with ID \"".concat(stylesheetId, "\" not found")); | ||
} | ||
} | ||
/** | ||
* Update the value of a stylesheet's "data-is-preview" attribute | ||
*/ | ||
function setStylesheetType(fontId, isPreview) { | ||
var stylesheetId = getStylesheetId(fontId); | ||
var stylesheetNode = document.getElementById(stylesheetId); | ||
if (stylesheetNode) { | ||
stylesheetNode.setAttribute(PREVIEW_ATTRIBUTE_NAME, isPreview.toString()); | ||
} | ||
else { | ||
console.error("Could not change stylesheet type: Stylesheet with ID \"" + stylesheetId + "\" not found"); | ||
} | ||
var stylesheetId = getStylesheetId(fontId); | ||
var stylesheetNode = document.getElementById(stylesheetId); | ||
if (stylesheetNode) { | ||
stylesheetNode.setAttribute(PREVIEW_ATTRIBUTE_NAME, isPreview.toString()); | ||
} else { | ||
console.error("Could not change stylesheet type: Stylesheet with ID \"".concat(stylesheetId, "\" not found")); | ||
} | ||
} | ||
/** | ||
* Execute the provided regex on the string and return all matched groups | ||
*/ | ||
function getMatches(regex, str) { | ||
var matches = []; | ||
var match; | ||
do { | ||
match = regex.exec(str); | ||
if (match) { | ||
matches.push(match[1]); | ||
} | ||
} while (match); | ||
return matches; | ||
var matches = []; | ||
var match; | ||
do { | ||
match = regex.exec(str); | ||
if (match) { | ||
matches.push(match[1]); | ||
} | ||
} while (match); | ||
return matches; | ||
} | ||
@@ -201,95 +363,202 @@ | ||
var FONT_FAMILY_REGEX = /font-family: ['"](.*?)['"]/gm; | ||
/** | ||
* Parse the list of @font-face rules provided by the Google Fonts API. Split up the rules | ||
* according to the font family and return them in an object | ||
*/ | ||
function extractFontStyles(allFontStyles) { | ||
var rules = getMatches(FONT_FACE_REGEX, allFontStyles); | ||
var fontStyles = {}; | ||
rules.forEach(function (rule) { | ||
var fontFamily = getMatches(FONT_FAMILY_REGEX, rule)[0]; | ||
var fontId = getFontId(fontFamily); | ||
if (!(fontId in fontStyles)) { | ||
fontStyles[fontId] = ""; | ||
} | ||
fontStyles[fontId] += "@font-face {\n" + rule + "\n}\n\n"; | ||
}); | ||
return fontStyles; | ||
// Run Regex to separate font-face rules | ||
var rules = getMatches(FONT_FACE_REGEX, allFontStyles); // Assign font-face rules to fontIds | ||
var fontStyles = {}; | ||
rules.forEach(function (rule) { | ||
// Run regex to get font family | ||
var fontFamily = getMatches(FONT_FAMILY_REGEX, rule)[0]; | ||
var fontId = getFontId(fontFamily); // Append rule to font font family's other rules | ||
if (!(fontId in fontStyles)) { | ||
fontStyles[fontId] = ""; | ||
} | ||
fontStyles[fontId] += "@font-face {\n".concat(rule, "\n}\n\n"); | ||
}); | ||
return fontStyles; | ||
} | ||
var FONT_BASE_URL = "https://fonts.googleapis.com/css"; | ||
function getStylesheet(fonts, scripts, variants, previewsOnly) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var variantsEnc, familiesEnc, query, familyNamesConcat, downloadChars, url; | ||
return __generator(this, function (_a) { | ||
/** | ||
* Return URL to the Google Fonts stylesheet for the specified font families and variants. | ||
* If previewsOnly is set to true, only the characters contained in the font family names are | ||
* included | ||
*/ | ||
function getStylesheet(_x, _x2, _x3, _x4) { | ||
return _getStylesheet.apply(this, arguments); | ||
} | ||
function _getStylesheet() { | ||
_getStylesheet = _asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee(fonts, scripts, variants, previewsOnly) { | ||
var variantsEnc, familiesEnc, query, familyNamesConcat, downloadChars, url; | ||
return regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
// Build query URL for specified font families and variants | ||
variantsEnc = variants.join(","); | ||
familiesEnc = fonts.map(function (font) { return encodeURIComponent(font.family) + ":" + variantsEnc; }); | ||
query = "?family=" + familiesEnc.join("|"); | ||
query += "&subset=" + scripts.join(","); | ||
familiesEnc = fonts.map(function (font) { | ||
return "".concat(encodeURIComponent(font.family), ":").concat(variantsEnc); | ||
}); | ||
query = "?family=".concat(familiesEnc.join("|")); // Query the fonts in the specified scripts | ||
query += "&subset=".concat(scripts.join(",")); // If previewsOnly: Only query the characters contained in the font names | ||
if (previewsOnly) { | ||
familyNamesConcat = fonts.map(function (font) { return font.family; }).join(""); | ||
downloadChars = familyNamesConcat | ||
.split("") | ||
.filter(function (char, pos, self) { return self.indexOf(char) === pos; }) | ||
.join(""); | ||
query += "&text=" + downloadChars; | ||
} | ||
url = "" + FONT_BASE_URL + query; | ||
return [2, get(url)]; | ||
}); | ||
}); | ||
// Concatenate the family names of all fonts | ||
familyNamesConcat = fonts.map(function (font) { | ||
return font.family; | ||
}).join(""); // Create a string with all characters (listed once) contained in the font family names | ||
downloadChars = familyNamesConcat.split("").filter(function (_char, pos, self) { | ||
return self.indexOf(_char) === pos; | ||
}).join(""); // Query only the identified characters | ||
query += "&text=".concat(downloadChars); | ||
} // Fetch and return stylesheet | ||
url = "".concat(FONT_BASE_URL).concat(query); | ||
return _context.abrupt("return", get(url)); | ||
case 7: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee); | ||
})); | ||
return _getStylesheet.apply(this, arguments); | ||
} | ||
function loadFontPreviews(fonts, scripts, variants, selectorSuffix) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var fontsArray, fontsToFetch, response, fontStyles; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
fontsArray = Array.from(fonts.values()); | ||
fontsToFetch = fontsArray | ||
.map(function (font) { return font.id; }) | ||
.filter(function (fontId) { return !stylesheetExists(fontId); }); | ||
fontsToFetch.forEach(function (fontId) { return createStylesheet(fontId, true); }); | ||
return [4, getStylesheet(fontsArray, scripts, variants, true)]; | ||
case 1: | ||
response = _a.sent(); | ||
fontStyles = extractFontStyles(response); | ||
fontsArray.forEach(function (font) { | ||
applyFontPreview(font, selectorSuffix); | ||
if (fontsToFetch.includes(font.id)) { | ||
if (!(font.id in fontStyles)) { | ||
console.error("Missing styles for font \"" + font.family + "\" (fontId \"" + font.id + "\") in Google Fonts response"); | ||
return; | ||
} | ||
fillStylesheet(font.id, fontStyles[font.id]); | ||
} | ||
}); | ||
return [2]; | ||
} | ||
}); | ||
}); | ||
/** | ||
* Get the Google Fonts stylesheet for the specified font (in the specified scripts and variants, | ||
* only the characters needed for creating the font previews), add the necessary CSS declarations to | ||
* apply them and add the fonts' stylesheets to the document head | ||
*/ | ||
function loadFontPreviews(_x, _x2, _x3, _x4) { | ||
return _loadFontPreviews.apply(this, arguments); | ||
} | ||
function loadActiveFont(font, previousFontFamily, scripts, variants, selectorSuffix) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var fontStyle; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!stylesheetExists(font.id, false)) return [3, 1]; | ||
applyActiveFont(font, previousFontFamily, selectorSuffix); | ||
return [3, 3]; | ||
case 1: | ||
if (stylesheetExists(font.id, true)) { | ||
setStylesheetType(font.id, false); | ||
} | ||
else { | ||
createStylesheet(font.id, false); | ||
} | ||
return [4, getStylesheet([font], scripts, variants, false)]; | ||
case 2: | ||
fontStyle = _a.sent(); | ||
applyActiveFont(font, previousFontFamily, selectorSuffix); | ||
fillStylesheet(font.id, fontStyle); | ||
_a.label = 3; | ||
case 3: return [2]; | ||
/** | ||
* Get the Google Fonts stylesheet for the specified font (in the specified scripts and variants), | ||
* add the necessary CSS declarations to apply it and add the font's stylesheet to the document head | ||
*/ | ||
function _loadFontPreviews() { | ||
_loadFontPreviews = _asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee(fonts, scripts, variants, selectorSuffix) { | ||
var fontsArray, fontsToFetch, response, fontStyles; | ||
return regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
// Only load previews of fonts which don't have a stylesheet (for preview or full font) yet | ||
fontsArray = Array.from(fonts.values()); | ||
fontsToFetch = fontsArray.map(function (font) { | ||
return font.id; | ||
}).filter(function (fontId) { | ||
return !stylesheetExists(fontId); | ||
}); // Create stylesheet elements for all fonts which will be fetched (this prevents other font | ||
// pickers from loading the fonts as well) | ||
fontsToFetch.forEach(function (fontId) { | ||
return createStylesheet(fontId, true); | ||
}); // Get Google Fonts stylesheet containing all requested styles | ||
_context.next = 5; | ||
return getStylesheet(fontsArray, scripts, variants, true); | ||
case 5: | ||
response = _context.sent; | ||
// Parse response and assign styles to the corresponding font | ||
fontStyles = extractFontStyles(response); // Create separate stylesheets for the fonts | ||
fontsArray.forEach(function (font) { | ||
applyFontPreview(font, selectorSuffix); // Add stylesheets for fonts which need to be downloaded | ||
if (fontsToFetch.includes(font.id)) { | ||
// Make sure response contains styles for the font | ||
if (!(font.id in fontStyles)) { | ||
console.error("Missing styles for font \"".concat(font.family, "\" (fontId \"").concat(font.id, "\") in Google Fonts response")); | ||
return; | ||
} // Insert styles into the stylesheet element which was created earlier | ||
fillStylesheet(font.id, fontStyles[font.id]); | ||
} | ||
}); | ||
case 8: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee); | ||
})); | ||
return _loadFontPreviews.apply(this, arguments); | ||
} | ||
function loadActiveFont(_x5, _x6, _x7, _x8, _x9) { | ||
return _loadActiveFont.apply(this, arguments); | ||
} | ||
function _loadActiveFont() { | ||
_loadActiveFont = _asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee2(font, previousFontFamily, scripts, variants, selectorSuffix) { | ||
var fontStyle; | ||
return regeneratorRuntime.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
if (!stylesheetExists(font.id, false)) { | ||
_context2.next = 4; | ||
break; | ||
} | ||
}); | ||
}); | ||
// Add CSS declaration to apply the new active font | ||
applyActiveFont(font, previousFontFamily, selectorSuffix); | ||
_context2.next = 10; | ||
break; | ||
case 4: | ||
if (stylesheetExists(font.id, true)) { | ||
// Update the stylesheet's "data-is-preview" attribute to "false" | ||
setStylesheetType(font.id, false); | ||
} else { | ||
// Create stylesheet for the font to be fetched (this prevents other font pickers from loading | ||
// the font as well) | ||
createStylesheet(font.id, false); | ||
} // Get Google Fonts stylesheet containing all requested styles | ||
_context2.next = 7; | ||
return getStylesheet([font], scripts, variants, false); | ||
case 7: | ||
fontStyle = _context2.sent; | ||
// Add CSS declaration to apply the new active font | ||
applyActiveFont(font, previousFontFamily, selectorSuffix); // Insert styles into the stylesheet element which was created earlier | ||
fillStylesheet(font.id, fontStyle); | ||
case 10: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2); | ||
})); | ||
return _loadActiveFont.apply(this, arguments); | ||
} | ||
@@ -327,102 +596,271 @@ | ||
var FontManager = (function () { | ||
function FontManager(apiKey, defaultFamily, _a, onChange) { | ||
if (defaultFamily === void 0) { defaultFamily = "Open Sans"; } | ||
var _b = _a.pickerId, pickerId = _b === void 0 ? "" : _b, _c = _a.families, families = _c === void 0 ? [] : _c, _d = _a.categories, categories = _d === void 0 ? [] : _d, _e = _a.scripts, scripts = _e === void 0 ? ["latin"] : _e, _f = _a.variants, variants = _f === void 0 ? ["regular"] : _f, _g = _a.limit, limit = _g === void 0 ? 50 : _g; | ||
if (onChange === void 0) { onChange = function () { }; } | ||
this.fonts = new Map(); | ||
validatePickerId(pickerId); | ||
this.selectorSuffix = pickerId ? "-" + pickerId : ""; | ||
this.apiKey = apiKey; | ||
this.options = { | ||
pickerId: pickerId, | ||
families: families, | ||
categories: categories, | ||
scripts: scripts, | ||
variants: variants, | ||
limit: limit, | ||
}; | ||
this.onChange = onChange; | ||
this.addFont(defaultFamily, false); | ||
this.setActiveFont(defaultFamily, false); | ||
} | ||
FontManager.prototype.init = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var fonts, _loop_1, this_1, i, state_1, fontsToLoad; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4, getFontList(this.apiKey)]; | ||
case 1: | ||
fonts = _a.sent(); | ||
_loop_1 = function (i) { | ||
var font = fonts[i]; | ||
if (this_1.fonts.size >= this_1.options.limit) { | ||
return "break"; | ||
} | ||
if (!this_1.fonts.has(font.family) && | ||
(this_1.options.families.length === 0 || this_1.options.families.includes(font.family)) && | ||
(this_1.options.categories.length === 0 || this_1.options.categories.includes(font.category)) && | ||
this_1.options.scripts.every(function (script) { return font.scripts.includes(script); }) && | ||
this_1.options.variants.every(function (variant) { return font.variants.includes(variant); })) { | ||
this_1.fonts.set(font.family, font); | ||
} | ||
}; | ||
this_1 = this; | ||
for (i = 0; i < fonts.length; i += 1) { | ||
state_1 = _loop_1(i); | ||
if (state_1 === "break") | ||
break; | ||
} | ||
fontsToLoad = new Map(this.fonts); | ||
fontsToLoad["delete"](this.activeFontFamily); | ||
loadFontPreviews(fontsToLoad, this.options.scripts, this.options.variants, this.selectorSuffix); | ||
return [2, this.fonts]; | ||
} | ||
}); | ||
}); | ||
var FONT_FAMILY_DEFAULT = "Open Sans"; | ||
var OPTIONS_DEFAULTS = { | ||
pickerId: "", | ||
families: [], | ||
categories: [], | ||
scripts: ["latin"], | ||
variants: ["regular"], | ||
limit: 50, | ||
sort: "alphabet" | ||
}; | ||
/** | ||
* Class for managing the list of fonts for the font picker, keeping track of the active font and | ||
* downloading/activating Google Fonts | ||
*/ | ||
var FontManager = | ||
/*#__PURE__*/ | ||
function () { | ||
// Parameters | ||
// Other class variables | ||
// Name of currently applied font | ||
// Map from font families to font objects | ||
// Suffix appended to CSS selectors which would have name clashes if multiple font pickers are | ||
// used on the same site (e.g. "-test" if the picker has pickerId "test" or "" if the picker | ||
// doesn't have an ID) | ||
/** | ||
* Save relevant options, download the default font, add it to the font list and apply it | ||
*/ | ||
function FontManager(apiKey) { | ||
var defaultFamily = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : FONT_FAMILY_DEFAULT; | ||
var _ref = arguments.length > 2 ? arguments[2] : undefined, | ||
_ref$pickerId = _ref.pickerId, | ||
pickerId = _ref$pickerId === void 0 ? OPTIONS_DEFAULTS.pickerId : _ref$pickerId, | ||
_ref$families = _ref.families, | ||
families = _ref$families === void 0 ? OPTIONS_DEFAULTS.families : _ref$families, | ||
_ref$categories = _ref.categories, | ||
categories = _ref$categories === void 0 ? OPTIONS_DEFAULTS.categories : _ref$categories, | ||
_ref$scripts = _ref.scripts, | ||
scripts = _ref$scripts === void 0 ? OPTIONS_DEFAULTS.scripts : _ref$scripts, | ||
_ref$variants = _ref.variants, | ||
variants = _ref$variants === void 0 ? OPTIONS_DEFAULTS.variants : _ref$variants, | ||
_ref$limit = _ref.limit, | ||
limit = _ref$limit === void 0 ? OPTIONS_DEFAULTS.limit : _ref$limit, | ||
_ref$sort = _ref.sort, | ||
sort = _ref$sort === void 0 ? OPTIONS_DEFAULTS.sort : _ref$sort; | ||
var onChange = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {}; | ||
_classCallCheck(this, FontManager); | ||
_defineProperty(this, "apiKey", void 0); | ||
_defineProperty(this, "options", void 0); | ||
_defineProperty(this, "onChange", void 0); | ||
_defineProperty(this, "activeFontFamily", void 0); | ||
_defineProperty(this, "fonts", new Map()); | ||
_defineProperty(this, "selectorSuffix", void 0); | ||
// Validate pickerId parameter | ||
validatePickerId(pickerId); | ||
this.selectorSuffix = pickerId ? "-".concat(pickerId) : ""; // Save parameters as class variables | ||
this.apiKey = apiKey; | ||
this.options = { | ||
pickerId: pickerId, | ||
families: families, | ||
categories: categories, | ||
scripts: scripts, | ||
variants: variants, | ||
limit: limit, | ||
sort: sort | ||
}; | ||
FontManager.prototype.getFonts = function () { | ||
return this.fonts; | ||
}; | ||
FontManager.prototype.addFont = function (fontFamily, downloadPreview) { | ||
if (downloadPreview === void 0) { downloadPreview = true; } | ||
var font = { | ||
family: fontFamily, | ||
id: getFontId(fontFamily), | ||
}; | ||
this.fonts.set(fontFamily, font); | ||
if (downloadPreview) { | ||
var fontMap = new Map(); | ||
fontMap.set(fontFamily, font); | ||
loadFontPreviews(fontMap, this.options.scripts, this.options.variants, this.selectorSuffix); | ||
} | ||
}; | ||
FontManager.prototype.removeFont = function (fontFamily) { | ||
this.fonts["delete"](fontFamily); | ||
}; | ||
FontManager.prototype.getActiveFont = function () { | ||
return this.fonts.get(this.activeFontFamily); | ||
}; | ||
FontManager.prototype.setActiveFont = function (fontFamily, runOnChange) { | ||
this.onChange = onChange; // Download default font and add it to the empty font list | ||
this.addFont(defaultFamily, false); | ||
this.setActiveFont(defaultFamily, false); | ||
} | ||
/** | ||
* Fetch list of all fonts from Google Fonts API, filter it according to the class parameters and | ||
* save them to the font map | ||
*/ | ||
_createClass(FontManager, [{ | ||
key: "init", | ||
value: function () { | ||
var _init = _asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee() { | ||
var _this = this; | ||
if (runOnChange === void 0) { runOnChange = true; } | ||
if (!this.fonts.has(fontFamily)) { | ||
console.error("Cannot update active font: \"" + fontFamily + "\" is not in the font list"); | ||
return; | ||
} | ||
var previousFontFamily = this.activeFontFamily; | ||
var activeFont = this.fonts.get(fontFamily); | ||
this.activeFontFamily = fontFamily; | ||
loadActiveFont(activeFont, previousFontFamily, this.options.scripts, this.options.variants, this.selectorSuffix).then(function () { | ||
if (runOnChange) { | ||
_this.onChange(activeFont); | ||
var fonts, _loop, i, _ret, fontsToLoad; | ||
return regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.next = 2; | ||
return getFontList(this.apiKey); | ||
case 2: | ||
fonts = _context.sent; | ||
_loop = function _loop(i) { | ||
var font = fonts[i]; // Exit once specified limit of number of fonts is reached | ||
if (_this.fonts.size >= _this.options.limit) { | ||
return "break"; | ||
} | ||
if ( // Skip default font if it is also contained in the list | ||
!_this.fonts.has(font.family) && ( // `families` parameter: Only keep fonts whose names are included in the provided array | ||
_this.options.families.length === 0 || _this.options.families.includes(font.family)) && ( // `categories` parameter: only keep fonts in categories from the provided array | ||
_this.options.categories.length === 0 || _this.options.categories.includes(font.category)) && // `scripts` parameter: Only keep fonts which are available in all specified scripts | ||
_this.options.scripts.every(function (script) { | ||
return font.scripts.includes(script); | ||
}) && // `variants` parameter: Only keep fonts which contain all specified variants | ||
_this.options.variants.every(function (variant) { | ||
return font.variants.includes(variant); | ||
})) { | ||
// Font fulfils all requirements: Add it to font map | ||
_this.fonts.set(font.family, font); | ||
} | ||
}; | ||
i = 0; | ||
case 5: | ||
if (!(i < fonts.length)) { | ||
_context.next = 12; | ||
break; | ||
} | ||
_ret = _loop(i); | ||
if (!(_ret === "break")) { | ||
_context.next = 9; | ||
break; | ||
} | ||
return _context.abrupt("break", 12); | ||
case 9: | ||
i += 1; | ||
_context.next = 5; | ||
break; | ||
case 12: | ||
// Download previews for all fonts in list except for default font (its full font has already | ||
// been downloaded) | ||
fontsToLoad = new Map(this.fonts); | ||
fontsToLoad["delete"](this.activeFontFamily); | ||
loadFontPreviews(fontsToLoad, this.options.scripts, this.options.variants, this.selectorSuffix); | ||
return _context.abrupt("return", this.fonts); | ||
case 16: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
}); | ||
}; | ||
FontManager.prototype.setOnChange = function (onChange) { | ||
this.onChange = onChange; | ||
}; | ||
return FontManager; | ||
}()); | ||
} | ||
}, _callee, this); | ||
})); | ||
export { FontManager, getFontId }; | ||
function init() { | ||
return _init.apply(this, arguments); | ||
} | ||
return init; | ||
}() | ||
/** | ||
* Return font map | ||
*/ | ||
}, { | ||
key: "getFonts", | ||
value: function getFonts() { | ||
return this.fonts; | ||
} | ||
/** | ||
* Add a new font to the font map and download its preview characters | ||
*/ | ||
}, { | ||
key: "addFont", | ||
value: function addFont(fontFamily) { | ||
var downloadPreview = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; | ||
// @ts-ignore: Custom font does not need `categories`, `scripts` and `variants` attributes | ||
var font = { | ||
family: fontFamily, | ||
id: getFontId(fontFamily) | ||
}; | ||
this.fonts.set(fontFamily, font); // Download font preview unless specified not to | ||
if (downloadPreview) { | ||
var fontMap = new Map(); | ||
fontMap.set(fontFamily, font); | ||
loadFontPreviews(fontMap, this.options.scripts, this.options.variants, this.selectorSuffix); | ||
} | ||
} | ||
/** | ||
* Remove the specified font from the font map | ||
*/ | ||
}, { | ||
key: "removeFont", | ||
value: function removeFont(fontFamily) { | ||
this.fonts["delete"](fontFamily); | ||
} | ||
/** | ||
* Return the font object of the currently active font | ||
*/ | ||
}, { | ||
key: "getActiveFont", | ||
value: function getActiveFont() { | ||
var activeFont = this.fonts.get(this.activeFontFamily); | ||
if (!activeFont) { | ||
throw Error("Cannot get active font: \"".concat(this.activeFontFamily, "\" is not in the font list")); | ||
} else { | ||
return activeFont; | ||
} | ||
} | ||
/** | ||
* Set the specified font as the active font and download it | ||
*/ | ||
}, { | ||
key: "setActiveFont", | ||
value: function setActiveFont(fontFamily) { | ||
var _this2 = this; | ||
var runOnChange = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; | ||
var previousFontFamily = this.activeFontFamily; | ||
var activeFont = this.fonts.get(fontFamily); | ||
if (!activeFont) { | ||
// Font is not in fontList: Keep current activeFont and log error | ||
throw Error("Cannot update active font: \"".concat(fontFamily, "\" is not in the font list")); | ||
} | ||
this.activeFontFamily = fontFamily; | ||
loadActiveFont(activeFont, previousFontFamily, this.options.scripts, this.options.variants, this.selectorSuffix).then(function () { | ||
if (runOnChange) { | ||
_this2.onChange(activeFont); | ||
} | ||
}); | ||
} | ||
/** | ||
* Update the onChange function (executed when changing the active font) | ||
*/ | ||
}, { | ||
key: "setOnChange", | ||
value: function setOnChange(onChange) { | ||
this.onChange = onChange; | ||
} | ||
}]); | ||
return FontManager; | ||
}(); | ||
export { FONT_FAMILY_DEFAULT, FontManager, OPTIONS_DEFAULTS, getFontId }; |
1206
dist/index.js
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | ||
typeof define === 'function' && define.amd ? define(['exports'], factory) : | ||
(global = global || self, factory(global.FontManager = {})); | ||
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | ||
typeof define === 'function' && define.amd ? define(['exports'], factory) : | ||
(global = global || self, factory(global.FontManager = {})); | ||
}(this, function (exports) { 'use strict'; | ||
/*! ***************************************************************************** | ||
Copyright (c) Microsoft Corporation. All rights reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use | ||
this file except in compliance with the License. You may obtain a copy of the | ||
License at http://www.apache.org/licenses/LICENSE-2.0 | ||
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { | ||
try { | ||
var info = gen[key](arg); | ||
var value = info.value; | ||
} catch (error) { | ||
reject(error); | ||
return; | ||
} | ||
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED | ||
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, | ||
MERCHANTABLITY OR NON-INFRINGEMENT. | ||
if (info.done) { | ||
resolve(value); | ||
} else { | ||
Promise.resolve(value).then(_next, _throw); | ||
} | ||
} | ||
See the Apache Version 2.0 License for specific language governing permissions | ||
and limitations under the License. | ||
***************************************************************************** */ | ||
function _asyncToGenerator(fn) { | ||
return function () { | ||
var self = this, | ||
args = arguments; | ||
return new Promise(function (resolve, reject) { | ||
var gen = fn.apply(self, args); | ||
var __assign = function() { | ||
__assign = Object.assign || function __assign(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
function _next(value) { | ||
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); | ||
} | ||
function _throw(err) { | ||
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); | ||
} | ||
_next(undefined); | ||
}); | ||
}; | ||
} | ||
function __rest(s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) | ||
t[p[i]] = s[p[i]]; | ||
return t; | ||
function _classCallCheck(instance, Constructor) { | ||
if (!(instance instanceof Constructor)) { | ||
throw new TypeError("Cannot call a class as a function"); | ||
} | ||
} | ||
function __awaiter(thisArg, _arguments, P, generator) { | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
function _defineProperties(target, props) { | ||
for (var i = 0; i < props.length; i++) { | ||
var descriptor = props[i]; | ||
descriptor.enumerable = descriptor.enumerable || false; | ||
descriptor.configurable = true; | ||
if ("value" in descriptor) descriptor.writable = true; | ||
Object.defineProperty(target, descriptor.key, descriptor); | ||
} | ||
} | ||
function __generator(thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
function _createClass(Constructor, protoProps, staticProps) { | ||
if (protoProps) _defineProperties(Constructor.prototype, protoProps); | ||
if (staticProps) _defineProperties(Constructor, staticProps); | ||
return Constructor; | ||
} | ||
function _defineProperty(obj, key, value) { | ||
if (key in obj) { | ||
Object.defineProperty(obj, key, { | ||
value: value, | ||
enumerable: true, | ||
configurable: true, | ||
writable: true | ||
}); | ||
} else { | ||
obj[key] = value; | ||
} | ||
function getFontId(fontFamily) { | ||
return fontFamily.replace(/\s+/g, "-").toLowerCase(); | ||
return obj; | ||
} | ||
function ownKeys(object, enumerableOnly) { | ||
var keys = Object.keys(object); | ||
if (Object.getOwnPropertySymbols) { | ||
var symbols = Object.getOwnPropertySymbols(object); | ||
if (enumerableOnly) symbols = symbols.filter(function (sym) { | ||
return Object.getOwnPropertyDescriptor(object, sym).enumerable; | ||
}); | ||
keys.push.apply(keys, symbols); | ||
} | ||
function validatePickerId(pickerId) { | ||
if (pickerId.match(/[^0-9a-z]/i)) { | ||
throw Error("The `pickerId` parameter may only contain letters and digits"); | ||
} | ||
} | ||
function get(url) { | ||
return new Promise(function (resolve, reject) { | ||
var request = new XMLHttpRequest(); | ||
request.overrideMimeType("application/json"); | ||
request.open("GET", url, true); | ||
request.onreadystatechange = function () { | ||
if (request.readyState === 4) { | ||
if (request.status !== 200) { | ||
reject(new Error("Response has status code " + request.status)); | ||
} | ||
else { | ||
resolve(request.responseText); | ||
} | ||
} | ||
}; | ||
request.send(); | ||
return keys; | ||
} | ||
function _objectSpread2(target) { | ||
for (var i = 1; i < arguments.length; i++) { | ||
var source = arguments[i] != null ? arguments[i] : {}; | ||
if (i % 2) { | ||
ownKeys(source, true).forEach(function (key) { | ||
_defineProperty(target, key, source[key]); | ||
}); | ||
} else if (Object.getOwnPropertyDescriptors) { | ||
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); | ||
} else { | ||
ownKeys(source).forEach(function (key) { | ||
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); | ||
}); | ||
} | ||
} | ||
var LIST_BASE_URL = "https://www.googleapis.com/webfonts/v1"; | ||
function getFontList(apiKey) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var url, response, json, fontsOriginal; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
url = LIST_BASE_URL + "/webfonts?sort=popularity&key=" + apiKey; | ||
return [4, get(url)]; | ||
case 1: | ||
response = _a.sent(); | ||
json = JSON.parse(response); | ||
fontsOriginal = json.items; | ||
return [2, fontsOriginal.map(function (fontOriginal) { | ||
var family = fontOriginal.family, subsets = fontOriginal.subsets, others = __rest(fontOriginal, ["family", "subsets"]); | ||
return __assign({}, others, { family: family, id: getFontId(family), scripts: subsets }); | ||
})]; | ||
} | ||
}); | ||
}); | ||
return target; | ||
} | ||
function _objectWithoutPropertiesLoose(source, excluded) { | ||
if (source == null) return {}; | ||
var target = {}; | ||
var sourceKeys = Object.keys(source); | ||
var key, i; | ||
for (i = 0; i < sourceKeys.length; i++) { | ||
key = sourceKeys[i]; | ||
if (excluded.indexOf(key) >= 0) continue; | ||
target[key] = source[key]; | ||
} | ||
var previewFontsStylesheet = document.createElement("style"); | ||
document.head.appendChild(previewFontsStylesheet); | ||
function applyFontPreview(previewFont, selectorSuffix) { | ||
var fontId = getFontId(previewFont.family); | ||
var style = "\n\t\t\t#font-button-" + fontId + selectorSuffix + " {\n\t\t\t\tfont-family: \"" + previewFont.family + "\";\n\t\t\t}\n\t\t"; | ||
previewFontsStylesheet.appendChild(document.createTextNode(style)); | ||
return target; | ||
} | ||
function _objectWithoutProperties(source, excluded) { | ||
if (source == null) return {}; | ||
var target = _objectWithoutPropertiesLoose(source, excluded); | ||
var key, i; | ||
if (Object.getOwnPropertySymbols) { | ||
var sourceSymbolKeys = Object.getOwnPropertySymbols(source); | ||
for (i = 0; i < sourceSymbolKeys.length; i++) { | ||
key = sourceSymbolKeys[i]; | ||
if (excluded.indexOf(key) >= 0) continue; | ||
if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; | ||
target[key] = source[key]; | ||
} | ||
} | ||
function getActiveFontStylesheet(selectorSuffix) { | ||
var stylesheetId = "active-font-" + selectorSuffix; | ||
var activeFontStylesheet = document.getElementById(stylesheetId); | ||
if (!activeFontStylesheet) { | ||
activeFontStylesheet = document.createElement("style"); | ||
activeFontStylesheet.id = stylesheetId; | ||
document.head.appendChild(activeFontStylesheet); | ||
} | ||
return activeFontStylesheet; | ||
return target; | ||
} | ||
/** | ||
* Return the fontId based on the provided font family | ||
*/ | ||
function getFontId(fontFamily) { | ||
return fontFamily.replace(/\s+/g, "-").toLowerCase(); | ||
} | ||
/** | ||
* Throw an error if the provided pickerId doesn't consist only of letters and digits | ||
*/ | ||
function validatePickerId(pickerId) { | ||
if (pickerId.match(/[^0-9a-z]/i)) { | ||
throw Error("The `pickerId` parameter may only contain letters and digits"); | ||
} | ||
function applyActiveFont(activeFont, previousFontFamily, selectorSuffix) { | ||
var style = "\n\t\t.apply-font" + selectorSuffix + " {\n\t\t\tfont-family: \"" + activeFont.family + "\"" + (previousFontFamily ? ", \"" + previousFontFamily + "\"" : "") + ";\n\t\t}\n\t"; | ||
var activeFontStylesheet = getActiveFontStylesheet(selectorSuffix); | ||
activeFontStylesheet.innerHTML = style; | ||
} | ||
} | ||
var PREVIEW_ATTRIBUTE_NAME = "data-is-preview"; | ||
function getStylesheetId(fontId) { | ||
return "font-" + fontId; | ||
} | ||
function stylesheetExists(fontId, isPreview) { | ||
var stylesheetNode = document.getElementById(getStylesheetId(fontId)); | ||
var stylesheetNodeExists = stylesheetNode !== null; | ||
if (isPreview === null || isPreview === undefined) { | ||
return stylesheetNodeExists; | ||
/** | ||
* Execute a GET XMLHttpRequest and return the result | ||
*/ | ||
function get(url) { | ||
return new Promise(function (resolve, reject) { | ||
var request = new XMLHttpRequest(); | ||
request.overrideMimeType("application/json"); | ||
request.open("GET", url, true); | ||
request.onreadystatechange = function () { | ||
// Request has completed | ||
if (request.readyState === 4) { | ||
if (request.status !== 200) { | ||
// On error | ||
reject(new Error("Response has status code ".concat(request.status))); | ||
} else { | ||
// On success | ||
resolve(request.responseText); | ||
} | ||
} | ||
return (stylesheetNodeExists && | ||
stylesheetNode.getAttribute(PREVIEW_ATTRIBUTE_NAME) === isPreview.toString()); | ||
} | ||
function createStylesheet(fontId, isPreview) { | ||
var stylesheetNode = document.createElement("style"); | ||
stylesheetNode.id = getStylesheetId(fontId); | ||
stylesheetNode.setAttribute(PREVIEW_ATTRIBUTE_NAME, isPreview.toString()); | ||
document.head.appendChild(stylesheetNode); | ||
} | ||
function fillStylesheet(fontId, styles) { | ||
var stylesheetId = getStylesheetId(fontId); | ||
var stylesheetNode = document.getElementById(stylesheetId); | ||
if (stylesheetNode) { | ||
stylesheetNode.textContent = styles; | ||
}; | ||
request.send(); | ||
}); | ||
} | ||
var LIST_BASE_URL = "https://www.googleapis.com/webfonts/v1"; | ||
/** | ||
* Font object returned by the Google API. Contains a field "subsets" which will be renamed to | ||
* "scripts" | ||
*/ | ||
/** | ||
* Fetch the list of all available fonts from the Google Fonts API | ||
*/ | ||
function getFontList(_x) { | ||
return _getFontList.apply(this, arguments); | ||
} | ||
function _getFontList() { | ||
_getFontList = _asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee(apiKey) { | ||
var url, response, json, fontsOriginal; | ||
return regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
// Request list of all Google Fonts, sorted by popularity | ||
url = "".concat(LIST_BASE_URL, "/webfonts?sort=popularity&key=").concat(apiKey); | ||
_context.next = 3; | ||
return get(url); | ||
case 3: | ||
response = _context.sent; | ||
// Parse font list | ||
json = JSON.parse(response); // For each font: | ||
// - Rename "subset" key to "script" | ||
// - Generate fontId | ||
// Return the updated list | ||
fontsOriginal = json.items; | ||
return _context.abrupt("return", fontsOriginal.map(function (fontOriginal) { | ||
var family = fontOriginal.family, | ||
subsets = fontOriginal.subsets, | ||
others = _objectWithoutProperties(fontOriginal, ["family", "subsets"]); | ||
return _objectSpread2({}, others, { | ||
family: family, | ||
id: getFontId(family), | ||
scripts: subsets | ||
}); | ||
})); | ||
case 7: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
else { | ||
console.error("Could not fill stylesheet: Stylesheet with ID \"" + stylesheetId + "\" not found"); | ||
} | ||
}, _callee); | ||
})); | ||
return _getFontList.apply(this, arguments); | ||
} | ||
var previewFontsStylesheet = document.createElement("style"); | ||
document.head.appendChild(previewFontsStylesheet); | ||
/** | ||
* Add declaration for applying the specified preview font | ||
*/ | ||
function applyFontPreview(previewFont, selectorSuffix) { | ||
var fontId = getFontId(previewFont.family); | ||
var style = "\n\t\t\t#font-button-".concat(fontId).concat(selectorSuffix, " {\n\t\t\t\tfont-family: \"").concat(previewFont.family, "\";\n\t\t\t}\n\t\t"); | ||
previewFontsStylesheet.appendChild(document.createTextNode(style)); | ||
} | ||
/** | ||
* Create/find and return the apply-font stylesheet for the provided selectorSuffix | ||
*/ | ||
function getActiveFontStylesheet(selectorSuffix) { | ||
var stylesheetId = "active-font-".concat(selectorSuffix); | ||
var activeFontStylesheet = document.getElementById(stylesheetId); | ||
if (!activeFontStylesheet) { | ||
activeFontStylesheet = document.createElement("style"); | ||
activeFontStylesheet.id = stylesheetId; | ||
document.head.appendChild(activeFontStylesheet); | ||
} | ||
function setStylesheetType(fontId, isPreview) { | ||
var stylesheetId = getStylesheetId(fontId); | ||
var stylesheetNode = document.getElementById(stylesheetId); | ||
if (stylesheetNode) { | ||
stylesheetNode.setAttribute(PREVIEW_ATTRIBUTE_NAME, isPreview.toString()); | ||
} | ||
else { | ||
console.error("Could not change stylesheet type: Stylesheet with ID \"" + stylesheetId + "\" not found"); | ||
} | ||
} | ||
function getMatches(regex, str) { | ||
var matches = []; | ||
var match; | ||
do { | ||
match = regex.exec(str); | ||
if (match) { | ||
matches.push(match[1]); | ||
} | ||
} while (match); | ||
return matches; | ||
return activeFontStylesheet; | ||
} | ||
/** | ||
* Add/update declaration for applying the current active font | ||
*/ | ||
function applyActiveFont(activeFont, previousFontFamily, selectorSuffix) { | ||
var style = "\n\t\t.apply-font".concat(selectorSuffix, " {\n\t\t\tfont-family: \"").concat(activeFont.family, "\"").concat(previousFontFamily ? ", \"".concat(previousFontFamily, "\"") : "", ";\n\t\t}\n\t"); | ||
var activeFontStylesheet = getActiveFontStylesheet(selectorSuffix); | ||
activeFontStylesheet.innerHTML = style; | ||
} | ||
var PREVIEW_ATTRIBUTE_NAME = "data-is-preview"; | ||
/** | ||
* Generate font stylesheet ID from fontId | ||
*/ | ||
function getStylesheetId(fontId) { | ||
return "font-".concat(fontId); | ||
} | ||
/** | ||
* Check whether a font stylesheet already exists in the document head | ||
*/ | ||
function stylesheetExists(fontId, isPreview) { | ||
var stylesheetNode = document.getElementById(getStylesheetId(fontId)); | ||
if (isPreview === null || isPreview === undefined) { | ||
return stylesheetNode !== null; | ||
} | ||
var FONT_FACE_REGEX = /@font-face {([\s\S]*?)}/gm; | ||
var FONT_FAMILY_REGEX = /font-family: ['"](.*?)['"]/gm; | ||
function extractFontStyles(allFontStyles) { | ||
var rules = getMatches(FONT_FACE_REGEX, allFontStyles); | ||
var fontStyles = {}; | ||
rules.forEach(function (rule) { | ||
var fontFamily = getMatches(FONT_FAMILY_REGEX, rule)[0]; | ||
var fontId = getFontId(fontFamily); | ||
if (!(fontId in fontStyles)) { | ||
fontStyles[fontId] = ""; | ||
} | ||
fontStyles[fontId] += "@font-face {\n" + rule + "\n}\n\n"; | ||
}); | ||
return fontStyles; | ||
return stylesheetNode !== null && stylesheetNode.getAttribute(PREVIEW_ATTRIBUTE_NAME) === isPreview.toString(); | ||
} | ||
/** | ||
* Attach a new font stylesheet to the document head using the provided content | ||
*/ | ||
function createStylesheet(fontId, isPreview) { | ||
var stylesheetNode = document.createElement("style"); | ||
stylesheetNode.id = getStylesheetId(fontId); | ||
stylesheetNode.setAttribute(PREVIEW_ATTRIBUTE_NAME, isPreview.toString()); | ||
document.head.appendChild(stylesheetNode); | ||
} | ||
/** | ||
* Insert the provided styles in the font's <style> element (existing styles are replaced) | ||
*/ | ||
function fillStylesheet(fontId, styles) { | ||
var stylesheetId = getStylesheetId(fontId); | ||
var stylesheetNode = document.getElementById(stylesheetId); | ||
if (stylesheetNode) { | ||
stylesheetNode.textContent = styles; | ||
} else { | ||
console.error("Could not fill stylesheet: Stylesheet with ID \"".concat(stylesheetId, "\" not found")); | ||
} | ||
} | ||
/** | ||
* Update the value of a stylesheet's "data-is-preview" attribute | ||
*/ | ||
var FONT_BASE_URL = "https://fonts.googleapis.com/css"; | ||
function getStylesheet(fonts, scripts, variants, previewsOnly) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var variantsEnc, familiesEnc, query, familyNamesConcat, downloadChars, url; | ||
return __generator(this, function (_a) { | ||
variantsEnc = variants.join(","); | ||
familiesEnc = fonts.map(function (font) { return encodeURIComponent(font.family) + ":" + variantsEnc; }); | ||
query = "?family=" + familiesEnc.join("|"); | ||
query += "&subset=" + scripts.join(","); | ||
if (previewsOnly) { | ||
familyNamesConcat = fonts.map(function (font) { return font.family; }).join(""); | ||
downloadChars = familyNamesConcat | ||
.split("") | ||
.filter(function (char, pos, self) { return self.indexOf(char) === pos; }) | ||
.join(""); | ||
query += "&text=" + downloadChars; | ||
} | ||
url = "" + FONT_BASE_URL + query; | ||
return [2, get(url)]; | ||
}); | ||
}); | ||
function setStylesheetType(fontId, isPreview) { | ||
var stylesheetId = getStylesheetId(fontId); | ||
var stylesheetNode = document.getElementById(stylesheetId); | ||
if (stylesheetNode) { | ||
stylesheetNode.setAttribute(PREVIEW_ATTRIBUTE_NAME, isPreview.toString()); | ||
} else { | ||
console.error("Could not change stylesheet type: Stylesheet with ID \"".concat(stylesheetId, "\" not found")); | ||
} | ||
} | ||
function loadFontPreviews(fonts, scripts, variants, selectorSuffix) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var fontsArray, fontsToFetch, response, fontStyles; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
fontsArray = Array.from(fonts.values()); | ||
fontsToFetch = fontsArray | ||
.map(function (font) { return font.id; }) | ||
.filter(function (fontId) { return !stylesheetExists(fontId); }); | ||
fontsToFetch.forEach(function (fontId) { return createStylesheet(fontId, true); }); | ||
return [4, getStylesheet(fontsArray, scripts, variants, true)]; | ||
case 1: | ||
response = _a.sent(); | ||
fontStyles = extractFontStyles(response); | ||
fontsArray.forEach(function (font) { | ||
applyFontPreview(font, selectorSuffix); | ||
if (fontsToFetch.includes(font.id)) { | ||
if (!(font.id in fontStyles)) { | ||
console.error("Missing styles for font \"" + font.family + "\" (fontId \"" + font.id + "\") in Google Fonts response"); | ||
return; | ||
} | ||
fillStylesheet(font.id, fontStyles[font.id]); | ||
} | ||
}); | ||
return [2]; | ||
/** | ||
* Execute the provided regex on the string and return all matched groups | ||
*/ | ||
function getMatches(regex, str) { | ||
var matches = []; | ||
var match; | ||
do { | ||
match = regex.exec(str); | ||
if (match) { | ||
matches.push(match[1]); | ||
} | ||
} while (match); | ||
return matches; | ||
} | ||
var FONT_FACE_REGEX = /@font-face {([\s\S]*?)}/gm; | ||
var FONT_FAMILY_REGEX = /font-family: ['"](.*?)['"]/gm; | ||
/** | ||
* Parse the list of @font-face rules provided by the Google Fonts API. Split up the rules | ||
* according to the font family and return them in an object | ||
*/ | ||
function extractFontStyles(allFontStyles) { | ||
// Run Regex to separate font-face rules | ||
var rules = getMatches(FONT_FACE_REGEX, allFontStyles); // Assign font-face rules to fontIds | ||
var fontStyles = {}; | ||
rules.forEach(function (rule) { | ||
// Run regex to get font family | ||
var fontFamily = getMatches(FONT_FAMILY_REGEX, rule)[0]; | ||
var fontId = getFontId(fontFamily); // Append rule to font font family's other rules | ||
if (!(fontId in fontStyles)) { | ||
fontStyles[fontId] = ""; | ||
} | ||
fontStyles[fontId] += "@font-face {\n".concat(rule, "\n}\n\n"); | ||
}); | ||
return fontStyles; | ||
} | ||
var FONT_BASE_URL = "https://fonts.googleapis.com/css"; | ||
/** | ||
* Return URL to the Google Fonts stylesheet for the specified font families and variants. | ||
* If previewsOnly is set to true, only the characters contained in the font family names are | ||
* included | ||
*/ | ||
function getStylesheet(_x, _x2, _x3, _x4) { | ||
return _getStylesheet.apply(this, arguments); | ||
} | ||
function _getStylesheet() { | ||
_getStylesheet = _asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee(fonts, scripts, variants, previewsOnly) { | ||
var variantsEnc, familiesEnc, query, familyNamesConcat, downloadChars, url; | ||
return regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
// Build query URL for specified font families and variants | ||
variantsEnc = variants.join(","); | ||
familiesEnc = fonts.map(function (font) { | ||
return "".concat(encodeURIComponent(font.family), ":").concat(variantsEnc); | ||
}); | ||
query = "?family=".concat(familiesEnc.join("|")); // Query the fonts in the specified scripts | ||
query += "&subset=".concat(scripts.join(",")); // If previewsOnly: Only query the characters contained in the font names | ||
if (previewsOnly) { | ||
// Concatenate the family names of all fonts | ||
familyNamesConcat = fonts.map(function (font) { | ||
return font.family; | ||
}).join(""); // Create a string with all characters (listed once) contained in the font family names | ||
downloadChars = familyNamesConcat.split("").filter(function (_char, pos, self) { | ||
return self.indexOf(_char) === pos; | ||
}).join(""); // Query only the identified characters | ||
query += "&text=".concat(downloadChars); | ||
} // Fetch and return stylesheet | ||
url = "".concat(FONT_BASE_URL).concat(query); | ||
return _context.abrupt("return", get(url)); | ||
case 7: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee); | ||
})); | ||
return _getStylesheet.apply(this, arguments); | ||
} | ||
/** | ||
* Get the Google Fonts stylesheet for the specified font (in the specified scripts and variants, | ||
* only the characters needed for creating the font previews), add the necessary CSS declarations to | ||
* apply them and add the fonts' stylesheets to the document head | ||
*/ | ||
function loadFontPreviews(_x, _x2, _x3, _x4) { | ||
return _loadFontPreviews.apply(this, arguments); | ||
} | ||
/** | ||
* Get the Google Fonts stylesheet for the specified font (in the specified scripts and variants), | ||
* add the necessary CSS declarations to apply it and add the font's stylesheet to the document head | ||
*/ | ||
function _loadFontPreviews() { | ||
_loadFontPreviews = _asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee(fonts, scripts, variants, selectorSuffix) { | ||
var fontsArray, fontsToFetch, response, fontStyles; | ||
return regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
// Only load previews of fonts which don't have a stylesheet (for preview or full font) yet | ||
fontsArray = Array.from(fonts.values()); | ||
fontsToFetch = fontsArray.map(function (font) { | ||
return font.id; | ||
}).filter(function (fontId) { | ||
return !stylesheetExists(fontId); | ||
}); // Create stylesheet elements for all fonts which will be fetched (this prevents other font | ||
// pickers from loading the fonts as well) | ||
fontsToFetch.forEach(function (fontId) { | ||
return createStylesheet(fontId, true); | ||
}); // Get Google Fonts stylesheet containing all requested styles | ||
_context.next = 5; | ||
return getStylesheet(fontsArray, scripts, variants, true); | ||
case 5: | ||
response = _context.sent; | ||
// Parse response and assign styles to the corresponding font | ||
fontStyles = extractFontStyles(response); // Create separate stylesheets for the fonts | ||
fontsArray.forEach(function (font) { | ||
applyFontPreview(font, selectorSuffix); // Add stylesheets for fonts which need to be downloaded | ||
if (fontsToFetch.includes(font.id)) { | ||
// Make sure response contains styles for the font | ||
if (!(font.id in fontStyles)) { | ||
console.error("Missing styles for font \"".concat(font.family, "\" (fontId \"").concat(font.id, "\") in Google Fonts response")); | ||
return; | ||
} // Insert styles into the stylesheet element which was created earlier | ||
fillStylesheet(font.id, fontStyles[font.id]); | ||
} | ||
}); | ||
}); | ||
} | ||
function loadActiveFont(font, previousFontFamily, scripts, variants, selectorSuffix) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var fontStyle; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
if (!stylesheetExists(font.id, false)) return [3, 1]; | ||
applyActiveFont(font, previousFontFamily, selectorSuffix); | ||
return [3, 3]; | ||
case 1: | ||
if (stylesheetExists(font.id, true)) { | ||
setStylesheetType(font.id, false); | ||
} | ||
else { | ||
createStylesheet(font.id, false); | ||
} | ||
return [4, getStylesheet([font], scripts, variants, false)]; | ||
case 2: | ||
fontStyle = _a.sent(); | ||
applyActiveFont(font, previousFontFamily, selectorSuffix); | ||
fillStylesheet(font.id, fontStyle); | ||
_a.label = 3; | ||
case 3: return [2]; | ||
} | ||
}); | ||
}); | ||
} | ||
}); | ||
function styleInject(css, ref) { | ||
if ( ref === void 0 ) ref = {}; | ||
var insertAt = ref.insertAt; | ||
case 8: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee); | ||
})); | ||
return _loadFontPreviews.apply(this, arguments); | ||
} | ||
if (!css || typeof document === 'undefined') { return; } | ||
function loadActiveFont(_x5, _x6, _x7, _x8, _x9) { | ||
return _loadActiveFont.apply(this, arguments); | ||
} | ||
var head = document.head || document.getElementsByTagName('head')[0]; | ||
var style = document.createElement('style'); | ||
style.type = 'text/css'; | ||
function _loadActiveFont() { | ||
_loadActiveFont = _asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee2(font, previousFontFamily, scripts, variants, selectorSuffix) { | ||
var fontStyle; | ||
return regeneratorRuntime.wrap(function _callee2$(_context2) { | ||
while (1) { | ||
switch (_context2.prev = _context2.next) { | ||
case 0: | ||
if (!stylesheetExists(font.id, false)) { | ||
_context2.next = 4; | ||
break; | ||
} | ||
if (insertAt === 'top') { | ||
if (head.firstChild) { | ||
head.insertBefore(style, head.firstChild); | ||
} else { | ||
head.appendChild(style); | ||
// Add CSS declaration to apply the new active font | ||
applyActiveFont(font, previousFontFamily, selectorSuffix); | ||
_context2.next = 10; | ||
break; | ||
case 4: | ||
if (stylesheetExists(font.id, true)) { | ||
// Update the stylesheet's "data-is-preview" attribute to "false" | ||
setStylesheetType(font.id, false); | ||
} else { | ||
// Create stylesheet for the font to be fetched (this prevents other font pickers from loading | ||
// the font as well) | ||
createStylesheet(font.id, false); | ||
} // Get Google Fonts stylesheet containing all requested styles | ||
_context2.next = 7; | ||
return getStylesheet([font], scripts, variants, false); | ||
case 7: | ||
fontStyle = _context2.sent; | ||
// Add CSS declaration to apply the new active font | ||
applyActiveFont(font, previousFontFamily, selectorSuffix); // Insert styles into the stylesheet element which was created earlier | ||
fillStylesheet(font.id, fontStyle); | ||
case 10: | ||
case "end": | ||
return _context2.stop(); | ||
} | ||
} | ||
}, _callee2); | ||
})); | ||
return _loadActiveFont.apply(this, arguments); | ||
} | ||
function styleInject(css, ref) { | ||
if ( ref === void 0 ) ref = {}; | ||
var insertAt = ref.insertAt; | ||
if (!css || typeof document === 'undefined') { return; } | ||
var head = document.head || document.getElementsByTagName('head')[0]; | ||
var style = document.createElement('style'); | ||
style.type = 'text/css'; | ||
if (insertAt === 'top') { | ||
if (head.firstChild) { | ||
head.insertBefore(style, head.firstChild); | ||
} else { | ||
head.appendChild(style); | ||
} | ||
} else { | ||
head.appendChild(style); | ||
} | ||
if (style.styleSheet) { | ||
style.styleSheet.cssText = css; | ||
} else { | ||
style.appendChild(document.createTextNode(css)); | ||
} | ||
if (style.styleSheet) { | ||
style.styleSheet.cssText = css; | ||
} else { | ||
style.appendChild(document.createTextNode(css)); | ||
} | ||
} | ||
var css = "@charset \"UTF-8\";\ndiv[id^=\"font-picker\"] {\n position: relative;\n display: inline-block;\n width: 200px;\n box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2); }\n div[id^=\"font-picker\"] * {\n box-sizing: border-box; }\n div[id^=\"font-picker\"] p {\n margin: 0;\n padding: 0; }\n div[id^=\"font-picker\"] button {\n color: inherit;\n font-size: inherit;\n background: none;\n border: 0;\n outline: none;\n cursor: pointer; }\n div[id^=\"font-picker\"] .dropdown-button {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: 35px;\n padding: 0 10px;\n background: #cbcbcb; }\n div[id^=\"font-picker\"] .dropdown-button:hover, div[id^=\"font-picker\"] .dropdown-button:focus {\n background: #bebebe; }\n div[id^=\"font-picker\"] .dropdown-button .dropdown-font-name {\n overflow: hidden;\n white-space: nowrap; }\n div[id^=\"font-picker\"] .dropdown-icon {\n margin-left: 10px; }\n\n@-webkit-keyframes spinner {\n to {\n transform: rotate(360deg); } }\n\n@keyframes spinner {\n to {\n transform: rotate(360deg); } }\n div[id^=\"font-picker\"] .dropdown-icon.loading::before {\n display: block;\n width: 10px;\n height: 10px;\n border: 2px solid #b2b2b2;\n border-top-color: #000000;\n border-radius: 50%;\n -webkit-animation: spinner 0.6s linear infinite;\n animation: spinner 0.6s linear infinite;\n content: \"\"; }\n div[id^=\"font-picker\"] .dropdown-icon.finished::before {\n display: block;\n width: 0;\n height: 0;\n margin: 0 2px;\n border-top: 6px solid #000000;\n border-right: 5px solid transparent;\n border-left: 5px solid transparent;\n transition: transform 0.3s;\n content: \"\"; }\n div[id^=\"font-picker\"] .dropdown-icon.error::before {\n content: \"⚠\"; }\n div[id^=\"font-picker\"].expanded .dropdown-icon.finished::before {\n transform: rotate(-180deg); }\n div[id^=\"font-picker\"].expanded ul {\n max-height: 200px; }\n div[id^=\"font-picker\"] ul {\n position: absolute;\n z-index: 1;\n width: 100%;\n max-height: 0;\n margin: 0;\n padding: 0;\n overflow-x: hidden;\n overflow-y: auto;\n background: #eaeaea;\n box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);\n transition: 0.3s;\n -webkit-overflow-scrolling: touch; }\n div[id^=\"font-picker\"] ul li {\n height: 35px;\n list-style: none; }\n div[id^=\"font-picker\"] ul li button {\n display: flex;\n align-items: center;\n width: 100%;\n height: 100%;\n padding: 0 10px;\n white-space: nowrap; }\n div[id^=\"font-picker\"] ul li button:hover, div[id^=\"font-picker\"] ul li button:focus {\n background: #dddddd; }\n div[id^=\"font-picker\"] ul li button.active-font {\n background: #d1d1d1; }\n"; | ||
styleInject(css); | ||
var css = "@charset \"UTF-8\";\ndiv[id^=\"font-picker\"] {\n position: relative;\n display: inline-block;\n width: 200px;\n box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2); }\n div[id^=\"font-picker\"] * {\n box-sizing: border-box; }\n div[id^=\"font-picker\"] p {\n margin: 0;\n padding: 0; }\n div[id^=\"font-picker\"] button {\n color: inherit;\n font-size: inherit;\n background: none;\n border: 0;\n outline: none;\n cursor: pointer; }\n div[id^=\"font-picker\"] .dropdown-button {\n display: flex;\n align-items: center;\n justify-content: space-between;\n width: 100%;\n height: 35px;\n padding: 0 10px;\n background: #cbcbcb; }\n div[id^=\"font-picker\"] .dropdown-button:hover, div[id^=\"font-picker\"] .dropdown-button:focus {\n background: #bebebe; }\n div[id^=\"font-picker\"] .dropdown-button .dropdown-font-name {\n overflow: hidden;\n white-space: nowrap; }\n div[id^=\"font-picker\"] .dropdown-icon {\n margin-left: 10px; }\n\n@-webkit-keyframes spinner {\n to {\n transform: rotate(360deg); } }\n\n@keyframes spinner {\n to {\n transform: rotate(360deg); } }\n div[id^=\"font-picker\"] .dropdown-icon.loading::before {\n display: block;\n width: 10px;\n height: 10px;\n border: 2px solid #b2b2b2;\n border-top-color: #000000;\n border-radius: 50%;\n -webkit-animation: spinner 0.6s linear infinite;\n animation: spinner 0.6s linear infinite;\n content: \"\"; }\n div[id^=\"font-picker\"] .dropdown-icon.finished::before {\n display: block;\n width: 0;\n height: 0;\n margin: 0 2px;\n border-top: 6px solid #000000;\n border-right: 5px solid transparent;\n border-left: 5px solid transparent;\n transition: transform 0.3s;\n content: \"\"; }\n div[id^=\"font-picker\"] .dropdown-icon.error::before {\n content: \"⚠\"; }\n div[id^=\"font-picker\"].expanded .dropdown-icon.finished::before {\n transform: rotate(-180deg); }\n div[id^=\"font-picker\"].expanded ul {\n max-height: 200px; }\n div[id^=\"font-picker\"] ul {\n position: absolute;\n z-index: 1;\n width: 100%;\n max-height: 0;\n margin: 0;\n padding: 0;\n overflow-x: hidden;\n overflow-y: auto;\n background: #eaeaea;\n box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.2);\n transition: 0.3s;\n -webkit-overflow-scrolling: touch; }\n div[id^=\"font-picker\"] ul li {\n height: 35px;\n list-style: none; }\n div[id^=\"font-picker\"] ul li button {\n display: flex;\n align-items: center;\n width: 100%;\n height: 100%;\n padding: 0 10px;\n white-space: nowrap; }\n div[id^=\"font-picker\"] ul li button:hover, div[id^=\"font-picker\"] ul li button:focus {\n background: #dddddd; }\n div[id^=\"font-picker\"] ul li button.active-font {\n background: #d1d1d1; }\n"; | ||
styleInject(css); | ||
var FontManager = (function () { | ||
function FontManager(apiKey, defaultFamily, _a, onChange) { | ||
if (defaultFamily === void 0) { defaultFamily = "Open Sans"; } | ||
var _b = _a.pickerId, pickerId = _b === void 0 ? "" : _b, _c = _a.families, families = _c === void 0 ? [] : _c, _d = _a.categories, categories = _d === void 0 ? [] : _d, _e = _a.scripts, scripts = _e === void 0 ? ["latin"] : _e, _f = _a.variants, variants = _f === void 0 ? ["regular"] : _f, _g = _a.limit, limit = _g === void 0 ? 50 : _g; | ||
if (onChange === void 0) { onChange = function () { }; } | ||
this.fonts = new Map(); | ||
validatePickerId(pickerId); | ||
this.selectorSuffix = pickerId ? "-" + pickerId : ""; | ||
this.apiKey = apiKey; | ||
this.options = { | ||
pickerId: pickerId, | ||
families: families, | ||
categories: categories, | ||
scripts: scripts, | ||
variants: variants, | ||
limit: limit, | ||
}; | ||
this.onChange = onChange; | ||
this.addFont(defaultFamily, false); | ||
this.setActiveFont(defaultFamily, false); | ||
} | ||
FontManager.prototype.init = function () { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var fonts, _loop_1, this_1, i, state_1, fontsToLoad; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4, getFontList(this.apiKey)]; | ||
case 1: | ||
fonts = _a.sent(); | ||
_loop_1 = function (i) { | ||
var font = fonts[i]; | ||
if (this_1.fonts.size >= this_1.options.limit) { | ||
return "break"; | ||
} | ||
if (!this_1.fonts.has(font.family) && | ||
(this_1.options.families.length === 0 || this_1.options.families.includes(font.family)) && | ||
(this_1.options.categories.length === 0 || this_1.options.categories.includes(font.category)) && | ||
this_1.options.scripts.every(function (script) { return font.scripts.includes(script); }) && | ||
this_1.options.variants.every(function (variant) { return font.variants.includes(variant); })) { | ||
this_1.fonts.set(font.family, font); | ||
} | ||
}; | ||
this_1 = this; | ||
for (i = 0; i < fonts.length; i += 1) { | ||
state_1 = _loop_1(i); | ||
if (state_1 === "break") | ||
break; | ||
} | ||
fontsToLoad = new Map(this.fonts); | ||
fontsToLoad["delete"](this.activeFontFamily); | ||
loadFontPreviews(fontsToLoad, this.options.scripts, this.options.variants, this.selectorSuffix); | ||
return [2, this.fonts]; | ||
var FONT_FAMILY_DEFAULT = "Open Sans"; | ||
var OPTIONS_DEFAULTS = { | ||
pickerId: "", | ||
families: [], | ||
categories: [], | ||
scripts: ["latin"], | ||
variants: ["regular"], | ||
limit: 50, | ||
sort: "alphabet" | ||
}; | ||
/** | ||
* Class for managing the list of fonts for the font picker, keeping track of the active font and | ||
* downloading/activating Google Fonts | ||
*/ | ||
var FontManager = | ||
/*#__PURE__*/ | ||
function () { | ||
// Parameters | ||
// Other class variables | ||
// Name of currently applied font | ||
// Map from font families to font objects | ||
// Suffix appended to CSS selectors which would have name clashes if multiple font pickers are | ||
// used on the same site (e.g. "-test" if the picker has pickerId "test" or "" if the picker | ||
// doesn't have an ID) | ||
/** | ||
* Save relevant options, download the default font, add it to the font list and apply it | ||
*/ | ||
function FontManager(apiKey) { | ||
var defaultFamily = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : FONT_FAMILY_DEFAULT; | ||
var _ref = arguments.length > 2 ? arguments[2] : undefined, | ||
_ref$pickerId = _ref.pickerId, | ||
pickerId = _ref$pickerId === void 0 ? OPTIONS_DEFAULTS.pickerId : _ref$pickerId, | ||
_ref$families = _ref.families, | ||
families = _ref$families === void 0 ? OPTIONS_DEFAULTS.families : _ref$families, | ||
_ref$categories = _ref.categories, | ||
categories = _ref$categories === void 0 ? OPTIONS_DEFAULTS.categories : _ref$categories, | ||
_ref$scripts = _ref.scripts, | ||
scripts = _ref$scripts === void 0 ? OPTIONS_DEFAULTS.scripts : _ref$scripts, | ||
_ref$variants = _ref.variants, | ||
variants = _ref$variants === void 0 ? OPTIONS_DEFAULTS.variants : _ref$variants, | ||
_ref$limit = _ref.limit, | ||
limit = _ref$limit === void 0 ? OPTIONS_DEFAULTS.limit : _ref$limit, | ||
_ref$sort = _ref.sort, | ||
sort = _ref$sort === void 0 ? OPTIONS_DEFAULTS.sort : _ref$sort; | ||
var onChange = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {}; | ||
_classCallCheck(this, FontManager); | ||
_defineProperty(this, "apiKey", void 0); | ||
_defineProperty(this, "options", void 0); | ||
_defineProperty(this, "onChange", void 0); | ||
_defineProperty(this, "activeFontFamily", void 0); | ||
_defineProperty(this, "fonts", new Map()); | ||
_defineProperty(this, "selectorSuffix", void 0); | ||
// Validate pickerId parameter | ||
validatePickerId(pickerId); | ||
this.selectorSuffix = pickerId ? "-".concat(pickerId) : ""; // Save parameters as class variables | ||
this.apiKey = apiKey; | ||
this.options = { | ||
pickerId: pickerId, | ||
families: families, | ||
categories: categories, | ||
scripts: scripts, | ||
variants: variants, | ||
limit: limit, | ||
sort: sort | ||
}; | ||
this.onChange = onChange; // Download default font and add it to the empty font list | ||
this.addFont(defaultFamily, false); | ||
this.setActiveFont(defaultFamily, false); | ||
} | ||
/** | ||
* Fetch list of all fonts from Google Fonts API, filter it according to the class parameters and | ||
* save them to the font map | ||
*/ | ||
_createClass(FontManager, [{ | ||
key: "init", | ||
value: function () { | ||
var _init = _asyncToGenerator( | ||
/*#__PURE__*/ | ||
regeneratorRuntime.mark(function _callee() { | ||
var _this = this; | ||
var fonts, _loop, i, _ret, fontsToLoad; | ||
return regeneratorRuntime.wrap(function _callee$(_context) { | ||
while (1) { | ||
switch (_context.prev = _context.next) { | ||
case 0: | ||
_context.next = 2; | ||
return getFontList(this.apiKey); | ||
case 2: | ||
fonts = _context.sent; | ||
_loop = function _loop(i) { | ||
var font = fonts[i]; // Exit once specified limit of number of fonts is reached | ||
if (_this.fonts.size >= _this.options.limit) { | ||
return "break"; | ||
} | ||
}); | ||
}); | ||
}; | ||
FontManager.prototype.getFonts = function () { | ||
return this.fonts; | ||
}; | ||
FontManager.prototype.addFont = function (fontFamily, downloadPreview) { | ||
if (downloadPreview === void 0) { downloadPreview = true; } | ||
var font = { | ||
family: fontFamily, | ||
id: getFontId(fontFamily), | ||
}; | ||
this.fonts.set(fontFamily, font); | ||
if (downloadPreview) { | ||
var fontMap = new Map(); | ||
fontMap.set(fontFamily, font); | ||
loadFontPreviews(fontMap, this.options.scripts, this.options.variants, this.selectorSuffix); | ||
if ( // Skip default font if it is also contained in the list | ||
!_this.fonts.has(font.family) && ( // `families` parameter: Only keep fonts whose names are included in the provided array | ||
_this.options.families.length === 0 || _this.options.families.includes(font.family)) && ( // `categories` parameter: only keep fonts in categories from the provided array | ||
_this.options.categories.length === 0 || _this.options.categories.includes(font.category)) && // `scripts` parameter: Only keep fonts which are available in all specified scripts | ||
_this.options.scripts.every(function (script) { | ||
return font.scripts.includes(script); | ||
}) && // `variants` parameter: Only keep fonts which contain all specified variants | ||
_this.options.variants.every(function (variant) { | ||
return font.variants.includes(variant); | ||
})) { | ||
// Font fulfils all requirements: Add it to font map | ||
_this.fonts.set(font.family, font); | ||
} | ||
}; | ||
i = 0; | ||
case 5: | ||
if (!(i < fonts.length)) { | ||
_context.next = 12; | ||
break; | ||
} | ||
_ret = _loop(i); | ||
if (!(_ret === "break")) { | ||
_context.next = 9; | ||
break; | ||
} | ||
return _context.abrupt("break", 12); | ||
case 9: | ||
i += 1; | ||
_context.next = 5; | ||
break; | ||
case 12: | ||
// Download previews for all fonts in list except for default font (its full font has already | ||
// been downloaded) | ||
fontsToLoad = new Map(this.fonts); | ||
fontsToLoad["delete"](this.activeFontFamily); | ||
loadFontPreviews(fontsToLoad, this.options.scripts, this.options.variants, this.selectorSuffix); | ||
return _context.abrupt("return", this.fonts); | ||
case 16: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
} | ||
}, _callee, this); | ||
})); | ||
function init() { | ||
return _init.apply(this, arguments); | ||
} | ||
return init; | ||
}() | ||
/** | ||
* Return font map | ||
*/ | ||
}, { | ||
key: "getFonts", | ||
value: function getFonts() { | ||
return this.fonts; | ||
} | ||
/** | ||
* Add a new font to the font map and download its preview characters | ||
*/ | ||
}, { | ||
key: "addFont", | ||
value: function addFont(fontFamily) { | ||
var downloadPreview = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; | ||
// @ts-ignore: Custom font does not need `categories`, `scripts` and `variants` attributes | ||
var font = { | ||
family: fontFamily, | ||
id: getFontId(fontFamily) | ||
}; | ||
FontManager.prototype.removeFont = function (fontFamily) { | ||
this.fonts["delete"](fontFamily); | ||
}; | ||
FontManager.prototype.getActiveFont = function () { | ||
return this.fonts.get(this.activeFontFamily); | ||
}; | ||
FontManager.prototype.setActiveFont = function (fontFamily, runOnChange) { | ||
var _this = this; | ||
if (runOnChange === void 0) { runOnChange = true; } | ||
if (!this.fonts.has(fontFamily)) { | ||
console.error("Cannot update active font: \"" + fontFamily + "\" is not in the font list"); | ||
return; | ||
} | ||
var previousFontFamily = this.activeFontFamily; | ||
var activeFont = this.fonts.get(fontFamily); | ||
this.activeFontFamily = fontFamily; | ||
loadActiveFont(activeFont, previousFontFamily, this.options.scripts, this.options.variants, this.selectorSuffix).then(function () { | ||
if (runOnChange) { | ||
_this.onChange(activeFont); | ||
} | ||
}); | ||
}; | ||
FontManager.prototype.setOnChange = function (onChange) { | ||
this.onChange = onChange; | ||
}; | ||
return FontManager; | ||
}()); | ||
this.fonts.set(fontFamily, font); // Download font preview unless specified not to | ||
exports.FontManager = FontManager; | ||
exports.getFontId = getFontId; | ||
if (downloadPreview) { | ||
var fontMap = new Map(); | ||
fontMap.set(fontFamily, font); | ||
loadFontPreviews(fontMap, this.options.scripts, this.options.variants, this.selectorSuffix); | ||
} | ||
} | ||
/** | ||
* Remove the specified font from the font map | ||
*/ | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
}, { | ||
key: "removeFont", | ||
value: function removeFont(fontFamily) { | ||
this.fonts["delete"](fontFamily); | ||
} | ||
/** | ||
* Return the font object of the currently active font | ||
*/ | ||
}, { | ||
key: "getActiveFont", | ||
value: function getActiveFont() { | ||
var activeFont = this.fonts.get(this.activeFontFamily); | ||
if (!activeFont) { | ||
throw Error("Cannot get active font: \"".concat(this.activeFontFamily, "\" is not in the font list")); | ||
} else { | ||
return activeFont; | ||
} | ||
} | ||
/** | ||
* Set the specified font as the active font and download it | ||
*/ | ||
}, { | ||
key: "setActiveFont", | ||
value: function setActiveFont(fontFamily) { | ||
var _this2 = this; | ||
var runOnChange = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; | ||
var previousFontFamily = this.activeFontFamily; | ||
var activeFont = this.fonts.get(fontFamily); | ||
if (!activeFont) { | ||
// Font is not in fontList: Keep current activeFont and log error | ||
throw Error("Cannot update active font: \"".concat(fontFamily, "\" is not in the font list")); | ||
} | ||
this.activeFontFamily = fontFamily; | ||
loadActiveFont(activeFont, previousFontFamily, this.options.scripts, this.options.variants, this.selectorSuffix).then(function () { | ||
if (runOnChange) { | ||
_this2.onChange(activeFont); | ||
} | ||
}); | ||
} | ||
/** | ||
* Update the onChange function (executed when changing the active font) | ||
*/ | ||
}, { | ||
key: "setOnChange", | ||
value: function setOnChange(onChange) { | ||
this.onChange = onChange; | ||
} | ||
}]); | ||
return FontManager; | ||
}(); | ||
exports.FONT_FAMILY_DEFAULT = FONT_FAMILY_DEFAULT; | ||
exports.FontManager = FontManager; | ||
exports.OPTIONS_DEFAULTS = OPTIONS_DEFAULTS; | ||
exports.getFontId = getFontId; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
})); |
@@ -0,0 +0,0 @@ import { Font, FontList, Script, Variant } from "./types"; |
@@ -8,5 +8,5 @@ export declare type Category = "sans-serif" | "serif" | "display" | "handwriting" | "monospace"; | ||
id: string; | ||
category?: Category; | ||
scripts?: Script[]; | ||
variants?: Variant[]; | ||
category: Category; | ||
scripts: Script[]; | ||
variants: Variant[]; | ||
kind?: string; | ||
@@ -17,12 +17,14 @@ version?: string; | ||
} | ||
export declare const FONT_FAMILY_DEFAULT = "Open Sans"; | ||
export declare type FontList = Map<string, Font>; | ||
export interface Options { | ||
pickerId?: string; | ||
families?: string[]; | ||
categories?: Category[]; | ||
scripts?: Script[]; | ||
variants?: Variant[]; | ||
limit?: number; | ||
sort?: SortOption; | ||
pickerId: string; | ||
families: string[]; | ||
categories: Category[]; | ||
scripts: Script[]; | ||
variants: Variant[]; | ||
limit: number; | ||
sort: SortOption; | ||
} | ||
export declare const OPTIONS_DEFAULTS: Options; | ||
//# sourceMappingURL=types.d.ts.map |
export declare function getFontId(fontFamily: string): string; | ||
export declare function validatePickerId(pickerId: string): void; | ||
//# sourceMappingURL=ids.d.ts.map |
export default function getMatches(regex: RegExp, str: string): string[]; | ||
//# sourceMappingURL=regex.d.ts.map |
export default function get(url: string): Promise<string>; | ||
//# sourceMappingURL=request.d.ts.map |
{ | ||
"name": "@samuelmeuli/font-manager", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Manages, downloads and applies Google Fonts for picker components", | ||
"author": "Samuel Meuli <me@samuelmeuli.com>", | ||
"author": { | ||
"name": "Samuel Meuli", | ||
"email": "me@samuelmeuli.com", | ||
"url": "https://samuelmeuli.com" | ||
}, | ||
"repository": "github:samuelmeuli/font-manager", | ||
@@ -25,2 +29,3 @@ "license": "MIT", | ||
"build:rollup": "rollup --config", | ||
"build:types": "tsc --emitDeclarationOnly", | ||
"format": "prettier --write", | ||
@@ -31,2 +36,3 @@ "lint:css": "stylelint --fix --max-warnings 0", | ||
"lint:ts": "eslint --ext .ts,.tsx --fix --max-warnings 0", | ||
"typecheck": "tsc --noEmit", | ||
"version": "yarn build", | ||
@@ -37,13 +43,18 @@ "release": "np" | ||
"devDependencies": { | ||
"@babel/core": "^7.5.5", | ||
"@babel/plugin-proposal-class-properties": "^7.5.5", | ||
"@babel/preset-env": "^7.5.5", | ||
"@babel/preset-typescript": "^7.3.3", | ||
"@samuelmeuli/eslint-config": "^2.1.0", | ||
"@samuelmeuli/stylelint-config": "^1.0.2", | ||
"@samuelmeuli/tsconfig": "^0.1.1", | ||
"@typescript-eslint/eslint-plugin": "^1.4.2", | ||
"@typescript-eslint/parser": "^1.4.2", | ||
"autoprefixer": "^9.6.0", | ||
"eslint": "5.16.0", | ||
"eslint-config-airbnb-base": "13.1.0", | ||
"eslint-config-prettier": "^4.0.0", | ||
"eslint-plugin-import": "^2.16.0", | ||
"husky": "^2.2.0", | ||
"lint-staged": "^8.1.3", | ||
"eslint": "5.3.0", | ||
"eslint-config-airbnb-base": "13.2.0", | ||
"eslint-config-prettier": "^6.0.0", | ||
"eslint-plugin-import": "^2.17.2", | ||
"husky": "^3.0.2", | ||
"lint-staged": "^9.2.1", | ||
"node-sass": "^4.12.0", | ||
@@ -55,6 +66,8 @@ "np": "^5.0.2", | ||
"rollup": "^1.15.3", | ||
"rollup-plugin-auto-external": "^2.0.0", | ||
"rollup-plugin-babel": "^4.3.3", | ||
"rollup-plugin-node-resolve": "^5.2.0", | ||
"rollup-plugin-postcss": "^2.0.3", | ||
"rollup-plugin-typescript2": "^0.21.0", | ||
"stylelint": "^10.1.0", | ||
"typescript": "^3.3.3333" | ||
"typescript": "^3.5.3" | ||
}, | ||
@@ -107,5 +120,5 @@ "eslintConfig": { | ||
"hooks": { | ||
"pre-commit": "lint-staged" | ||
"pre-commit": "yarn typecheck && lint-staged" | ||
} | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
76443
0
1532
28
1