UNPKG

react-notion-blocks

Version:

A library for mapping Notion blocks to React components

1,207 lines (1,205 loc) 102 kB
import $e, { useState as lt, useRef as ee, useEffect as Ue, useContext as De, createContext as ut, useLayoutEffect as ct } from "react"; var Re = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {}, be = { exports: {} }, pe = {}; /** * @license React * react-jsx-runtime.production.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var Oe; function dt() { if (Oe) return pe; Oe = 1; var e = Symbol.for("react.transitional.element"), o = Symbol.for("react.fragment"); function r(d, g, F) { var j = null; if (F !== void 0 && (j = "" + F), g.key !== void 0 && (j = "" + g.key), "key" in g) { F = {}; for (var c in g) c !== "key" && (F[c] = g[c]); } else F = g; return g = F.ref, { $$typeof: e, type: d, key: j, ref: g !== void 0 ? g : null, props: F }; } return pe.Fragment = o, pe.jsx = r, pe.jsxs = r, pe; } var fe = {}; /** * @license React * react-jsx-runtime.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var Pe; function gt() { return Pe || (Pe = 1, process.env.NODE_ENV !== "production" && function() { function e(t) { if (t == null) return null; if (typeof t == "function") return t.$$typeof === R ? null : t.displayName || t.name || null; if (typeof t == "string") return t; switch (t) { case i: return "Fragment"; case u: return "Portal"; case x: return "Profiler"; case h: return "StrictMode"; case q: return "Suspense"; case te: return "SuspenseList"; } if (typeof t == "object") switch (typeof t.tag == "number" && console.error( "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." ), t.$$typeof) { case $: return (t.displayName || "Context") + ".Provider"; case m: return (t._context.displayName || "Context") + ".Consumer"; case C: var p = t.render; return t = t.displayName, t || (t = p.displayName || p.name || "", t = t !== "" ? "ForwardRef(" + t + ")" : "ForwardRef"), t; case re: return p = t.displayName || null, p !== null ? p : e(t.type) || "Memo"; case oe: p = t._payload, t = t._init; try { return e(t(p)); } catch { } } return null; } function o(t) { return "" + t; } function r(t) { try { o(t); var p = !1; } catch { p = !0; } if (p) { p = console; var f = p.error, _ = typeof Symbol == "function" && Symbol.toStringTag && t[Symbol.toStringTag] || t.constructor.name || "Object"; return f.call( p, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", _ ), o(t); } } function d() { } function g() { if (I === 0) { Z = console.log, V = console.info, X = console.warn, ne = console.error, ce = console.group, ae = console.groupCollapsed, Q = console.groupEnd; var t = { configurable: !0, enumerable: !0, value: d, writable: !0 }; Object.defineProperties(console, { info: t, log: t, warn: t, error: t, group: t, groupCollapsed: t, groupEnd: t }); } I++; } function F() { if (I--, I === 0) { var t = { configurable: !0, enumerable: !0, writable: !0 }; Object.defineProperties(console, { log: U({}, t, { value: Z }), info: U({}, t, { value: V }), warn: U({}, t, { value: X }), error: U({}, t, { value: ne }), group: U({}, t, { value: ce }), groupCollapsed: U({}, t, { value: ae }), groupEnd: U({}, t, { value: Q }) }); } 0 > I && console.error( "disabledDepth fell below zero. This is a bug in React. Please file an issue." ); } function j(t) { if (de === void 0) try { throw Error(); } catch (f) { var p = f.stack.trim().match(/\n( *(at )?)/); de = p && p[1] || "", se = -1 < f.stack.indexOf(` at`) ? " (<anonymous>)" : -1 < f.stack.indexOf("@") ? "@unknown:0:0" : ""; } return ` ` + de + t + se; } function c(t, p) { if (!t || _e) return ""; var f = Fe.get(t); if (f !== void 0) return f; _e = !0, f = Error.prepareStackTrace, Error.prepareStackTrace = void 0; var _ = null; _ = O.H, O.H = null, g(); try { var P = { DetermineComponentFrameRoot: function() { try { if (p) { var W = function() { throw Error(); }; if (Object.defineProperty(W.prototype, "props", { set: function() { throw Error(); } }), typeof Reflect == "object" && Reflect.construct) { try { Reflect.construct(W, []); } catch (H) { var ye = H; } Reflect.construct(t, [], W); } else { try { W.call(); } catch (H) { ye = H; } t.call(W.prototype); } } else { try { throw Error(); } catch (H) { ye = H; } (W = t()) && typeof W.catch == "function" && W.catch(function() { }); } } catch (H) { if (H && ye && typeof H.stack == "string") return [H.stack, ye.stack]; } return [null, null]; } }; P.DetermineComponentFrameRoot.displayName = "DetermineComponentFrameRoot"; var S = Object.getOwnPropertyDescriptor( P.DetermineComponentFrameRoot, "name" ); S && S.configurable && Object.defineProperty( P.DetermineComponentFrameRoot, "name", { value: "DetermineComponentFrameRoot" } ); var y = P.DetermineComponentFrameRoot(), Y = y[0], ie = y[1]; if (Y && ie) { var L = Y.split(` `), K = ie.split(` `); for (y = S = 0; S < L.length && !L[S].includes( "DetermineComponentFrameRoot" ); ) S++; for (; y < K.length && !K[y].includes( "DetermineComponentFrameRoot" ); ) y++; if (S === L.length || y === K.length) for (S = L.length - 1, y = K.length - 1; 1 <= S && 0 <= y && L[S] !== K[y]; ) y--; for (; 1 <= S && 0 <= y; S--, y--) if (L[S] !== K[y]) { if (S !== 1 || y !== 1) do if (S--, y--, 0 > y || L[S] !== K[y]) { var ge = ` ` + L[S].replace( " at new ", " at " ); return t.displayName && ge.includes("<anonymous>") && (ge = ge.replace("<anonymous>", t.displayName)), typeof t == "function" && Fe.set(t, ge), ge; } while (1 <= S && 0 <= y); break; } } } finally { _e = !1, O.H = _, F(), Error.prepareStackTrace = f; } return L = (L = t ? t.displayName || t.name : "") ? j(L) : "", typeof t == "function" && Fe.set(t, L), L; } function w(t) { if (t == null) return ""; if (typeof t == "function") { var p = t.prototype; return c( t, !(!p || !p.isReactComponent) ); } if (typeof t == "string") return j(t); switch (t) { case q: return j("Suspense"); case te: return j("SuspenseList"); } if (typeof t == "object") switch (t.$$typeof) { case C: return t = c(t.render, !1), t; case re: return w(t.type); case oe: p = t._payload, t = t._init; try { return w(t(p)); } catch { } } return ""; } function N() { var t = O.A; return t === null ? null : t.getOwner(); } function J(t) { if (D.call(t, "key")) { var p = Object.getOwnPropertyDescriptor(t, "key").get; if (p && p.isReactWarning) return !1; } return t.key !== void 0; } function k(t, p) { function f() { Te || (Te = !0, console.error( "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", p )); } f.isReactWarning = !0, Object.defineProperty(t, "key", { get: f, configurable: !0 }); } function z() { var t = e(this.type); return Se[t] || (Se[t] = !0, console.error( "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release." )), t = this.props.ref, t !== void 0 ? t : null; } function b(t, p, f, _, P, S) { return f = S.ref, t = { $$typeof: l, type: t, key: p, props: S, _owner: P }, (f !== void 0 ? f : null) !== null ? Object.defineProperty(t, "ref", { enumerable: !1, get: z }) : Object.defineProperty(t, "ref", { enumerable: !1, value: null }), t._store = {}, Object.defineProperty(t._store, "validated", { configurable: !1, enumerable: !1, writable: !0, value: 0 }), Object.defineProperty(t, "_debugInfo", { configurable: !1, enumerable: !1, writable: !0, value: null }), Object.freeze && (Object.freeze(t.props), Object.freeze(t)), t; } function T(t, p, f, _, P, S) { if (typeof t == "string" || typeof t == "function" || t === i || t === x || t === h || t === q || t === te || t === we || typeof t == "object" && t !== null && (t.$$typeof === oe || t.$$typeof === re || t.$$typeof === $ || t.$$typeof === m || t.$$typeof === C || t.$$typeof === B || t.getModuleId !== void 0)) { var y = p.children; if (y !== void 0) if (_) if (ue(y)) { for (_ = 0; _ < y.length; _++) E(y[_], t); Object.freeze && Object.freeze(y); } else console.error( "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead." ); else E(y, t); } else y = "", (t === void 0 || typeof t == "object" && t !== null && Object.keys(t).length === 0) && (y += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports."), t === null ? _ = "null" : ue(t) ? _ = "array" : t !== void 0 && t.$$typeof === l ? (_ = "<" + (e(t.type) || "Unknown") + " />", y = " Did you accidentally export a JSX literal instead of a component?") : _ = typeof t, console.error( "React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s", _, y ); if (D.call(p, "key")) { y = e(t); var Y = Object.keys(p).filter(function(L) { return L !== "key"; }); _ = 0 < Y.length ? "{key: someKey, " + Y.join(": ..., ") + ": ...}" : "{key: someKey}", Ne[y + _] || (Y = 0 < Y.length ? "{" + Y.join(": ..., ") + ": ...}" : "{}", console.error( `A props object containing a "key" prop is being spread into JSX: let props = %s; <%s {...props} /> React keys must be passed directly to JSX without using spread: let props = %s; <%s key={someKey} {...props} />`, _, y, Y, y ), Ne[y + _] = !0); } if (y = null, f !== void 0 && (r(f), y = "" + f), J(p) && (r(p.key), y = "" + p.key), "key" in p) { f = {}; for (var ie in p) ie !== "key" && (f[ie] = p[ie]); } else f = p; return y && k( f, typeof t == "function" ? t.displayName || t.name || "Unknown" : t ), b(t, y, S, P, N(), f); } function E(t, p) { if (typeof t == "object" && t && t.$$typeof !== ot) { if (ue(t)) for (var f = 0; f < t.length; f++) { var _ = t[f]; v(_) && A(_, p); } else if (v(t)) t._store && (t._store.validated = 1); else if (t === null || typeof t != "object" ? f = null : (f = le && t[le] || t["@@iterator"], f = typeof f == "function" ? f : null), typeof f == "function" && f !== t.entries && (f = f.call(t), f !== t)) for (; !(t = f.next()).done; ) v(t.value) && A(t.value, p); } } function v(t) { return typeof t == "object" && t !== null && t.$$typeof === l; } function A(t, p) { if (t._store && !t._store.validated && t.key == null && (t._store.validated = 1, p = a(p), !Ce[p])) { Ce[p] = !0; var f = ""; t && t._owner != null && t._owner !== N() && (f = null, typeof t._owner.tag == "number" ? f = e(t._owner.type) : typeof t._owner.name == "string" && (f = t._owner.name), f = " It was passed a child from " + f + "."); var _ = O.getCurrentStack; O.getCurrentStack = function() { var P = w(t.type); return _ && (P += _() || ""), P; }, console.error( 'Each child in a list should have a unique "key" prop.%s%s See https://react.dev/link/warning-keys for more information.', p, f ), O.getCurrentStack = _; } } function a(t) { var p = "", f = N(); return f && (f = e(f.type)) && (p = ` Check the render method of \`` + f + "`."), p || (t = e(t)) && (p = ` Check the top-level render call using <` + t + ">."), p; } var n = $e, l = Symbol.for("react.transitional.element"), u = Symbol.for("react.portal"), i = Symbol.for("react.fragment"), h = Symbol.for("react.strict_mode"), x = Symbol.for("react.profiler"), m = Symbol.for("react.consumer"), $ = Symbol.for("react.context"), C = Symbol.for("react.forward_ref"), q = Symbol.for("react.suspense"), te = Symbol.for("react.suspense_list"), re = Symbol.for("react.memo"), oe = Symbol.for("react.lazy"), we = Symbol.for("react.offscreen"), le = Symbol.iterator, R = Symbol.for("react.client.reference"), O = n.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, D = Object.prototype.hasOwnProperty, U = Object.assign, B = Symbol.for("react.client.reference"), ue = Array.isArray, I = 0, Z, V, X, ne, ce, ae, Q; d.__reactDisabledLog = !0; var de, se, _e = !1, Fe = new (typeof WeakMap == "function" ? WeakMap : Map)(), ot = Symbol.for("react.client.reference"), Te, Se = {}, Ne = {}, Ce = {}; fe.Fragment = i, fe.jsx = function(t, p, f, _, P) { return T(t, p, f, !1, _, P); }, fe.jsxs = function(t, p, f, _, P) { return T(t, p, f, !0, _, P); }; }()), fe; } var Me; function pt() { return Me || (Me = 1, process.env.NODE_ENV === "production" ? be.exports = dt() : be.exports = gt()), be.exports; } var s = pt(); const ze = { default: "", gray: "text-gray-500 dark:text-gray-400", brown: "text-[#9F6B53] dark:text-[#B38B74]", orange: "text-[#D9730D] dark:text-[#E69A3C]", yellow: "text-[#CB912F] dark:text-[#EAB308]", green: "text-[#448361] dark:text-[#65A30D]", blue: "text-[#337EA9] dark:text-[#3B82F6]", purple: "text-[#9065B0] dark:text-[#A855F7]", pink: "text-[#C14C8A] dark:text-[#EC4899]", red: "text-[#D44C47] dark:text-[#EF4444]" }, M = ({ richText: e }) => !Array.isArray(e) || e.length === 0 ? null : /* @__PURE__ */ s.jsx(s.Fragment, { children: e.length > 0 && e.map((o, r) => { var N, J; if (!o || !o.annotations || !o.text) return console.error("Invalid rich text item:", o), null; const { bold: d, italic: g, strikethrough: F, underline: j, code: c, color: w } = o.annotations; return /* @__PURE__ */ s.jsx( "span", { className: [ "notion-rich-text", ze[w] || ze.default, d ? "font-bold" : "", g ? "italic" : "", F ? "line-through" : "", j ? "underline" : "", c ? "notion-rich-text--code font-mono bg-gray-200/80 text-red-500 px-1.5 rounded" : "" ].filter(Boolean).join(" "), children: (J = (N = o == null ? void 0 : o.text) == null ? void 0 : N.link) != null && J.url ? /* @__PURE__ */ s.jsx( "a", { href: o.text.link.url, className: "notion-rich-text--link text-primary dark:text-primary-300 hover:underline", target: "_blank", rel: "noopener noreferrer", children: o.text.content || "" } ) : o.text.content || "" }, r ); }) }), Ye = ({ block: e }) => { var d; const o = e.type === "heading_1" ? 1 : e.type === "heading_2" ? 2 : 3, r = `h${o}`; return /* @__PURE__ */ s.jsx(r, { className: `notion-heading notion-heading--h${o}`, children: /* @__PURE__ */ s.jsx(M, { richText: ((d = e[e.type]) == null ? void 0 : d.rich_text) || [] }) }); }, He = () => /* @__PURE__ */ s.jsx("hr", { className: "notion-divider border-t border-gray-300 dark:border-gray-600 my-5" }), Ze = ({ block: e }) => { const [o, r] = lt(!0), d = e.image.type === "external" ? e.image.external.url : e.image.file.url; return /* @__PURE__ */ s.jsxs("figure", { className: "notion-image my-5", children: [ /* @__PURE__ */ s.jsxs("div", { className: "notion-image__wrapper relative w-full mx-auto", children: [ o && /* @__PURE__ */ s.jsx("div", { className: "notion-image__skeleton absolute inset-0 bg-zinc-100 dark:bg-zinc-600 animate-pulse rounded-lg" }), /* @__PURE__ */ s.jsx( "img", { src: d, alt: e.image.caption.map((g) => g.plain_text).join("") || "Image", className: `notion-image__img w-full mx-auto h-auto object-cover rounded-md transition-opacity duration-300 ${o ? "opacity-0" : "opacity-100"}`, loading: "lazy", onLoad: () => r(!1) } ) ] }), e.image.caption.length > 0 && /* @__PURE__ */ s.jsx("figcaption", { className: "notion-image__caption text-sm text-gray-600 dark:text-gray-400 mt-2", children: /* @__PURE__ */ s.jsx(M, { richText: e.image.caption }) }) ] }); }; var je = { exports: {} }, Le; function ft() { return Le || (Le = 1, function(e) { var o = typeof window < "u" ? window : typeof WorkerGlobalScope < "u" && self instanceof WorkerGlobalScope ? self : {}; /** * Prism: Lightweight, robust, elegant syntax highlighting * * @license MIT <https://opensource.org/licenses/MIT> * @author Lea Verou <https://lea.verou.me> * @namespace * @public */ var r = function(d) { var g = /(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i, F = 0, j = {}, c = { /** * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load * additional languages or plugins yourself. * * By setting this value to `true`, Prism will not automatically highlight all code elements on the page. * * You obviously have to change this value before the automatic highlighting started. To do this, you can add an * empty Prism object into the global scope before loading the Prism script like this: * * ```js * window.Prism = window.Prism || {}; * Prism.manual = true; * // add a new <script> to load Prism's script * ``` * * @default false * @type {boolean} * @memberof Prism * @public */ manual: d.Prism && d.Prism.manual, /** * By default, if Prism is in a web worker, it assumes that it is in a worker it created itself, so it uses * `addEventListener` to communicate with its parent instance. However, if you're using Prism manually in your * own worker, you don't want it to do this. * * By setting this value to `true`, Prism will not add its own listeners to the worker. * * You obviously have to change this value before Prism executes. To do this, you can add an * empty Prism object into the global scope before loading the Prism script like this: * * ```js * window.Prism = window.Prism || {}; * Prism.disableWorkerMessageHandler = true; * // Load Prism's script * ``` * * @default false * @type {boolean} * @memberof Prism * @public */ disableWorkerMessageHandler: d.Prism && d.Prism.disableWorkerMessageHandler, /** * A namespace for utility methods. * * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may * change or disappear at any time. * * @namespace * @memberof Prism */ util: { encode: function a(n) { return n instanceof w ? new w(n.type, a(n.content), n.alias) : Array.isArray(n) ? n.map(a) : n.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/\u00a0/g, " "); }, /** * Returns the name of the type of the given value. * * @param {any} o * @returns {string} * @example * type(null) === 'Null' * type(undefined) === 'Undefined' * type(123) === 'Number' * type('foo') === 'String' * type(true) === 'Boolean' * type([1, 2]) === 'Array' * type({}) === 'Object' * type(String) === 'Function' * type(/abc+/) === 'RegExp' */ type: function(a) { return Object.prototype.toString.call(a).slice(8, -1); }, /** * Returns a unique number for the given object. Later calls will still return the same number. * * @param {Object} obj * @returns {number} */ objId: function(a) { return a.__id || Object.defineProperty(a, "__id", { value: ++F }), a.__id; }, /** * Creates a deep clone of the given object. * * The main intended use of this function is to clone language definitions. * * @param {T} o * @param {Record<number, any>} [visited] * @returns {T} * @template T */ clone: function a(n, l) { l = l || {}; var u, i; switch (c.util.type(n)) { case "Object": if (i = c.util.objId(n), l[i]) return l[i]; u = /** @type {Record<string, any>} */ {}, l[i] = u; for (var h in n) n.hasOwnProperty(h) && (u[h] = a(n[h], l)); return ( /** @type {any} */ u ); case "Array": return i = c.util.objId(n), l[i] ? l[i] : (u = [], l[i] = u, /** @type {Array} */ /** @type {any} */ n.forEach(function(x, m) { u[m] = a(x, l); }), /** @type {any} */ u); default: return n; } }, /** * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class. * * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned. * * @param {Element} element * @returns {string} */ getLanguage: function(a) { for (; a; ) { var n = g.exec(a.className); if (n) return n[1].toLowerCase(); a = a.parentElement; } return "none"; }, /** * Sets the Prism `language-xxxx` class of the given element. * * @param {Element} element * @param {string} language * @returns {void} */ setLanguage: function(a, n) { a.className = a.className.replace(RegExp(g, "gi"), ""), a.classList.add("language-" + n); }, /** * Returns the script element that is currently executing. * * This does __not__ work for line script element. * * @returns {HTMLScriptElement | null} */ currentScript: function() { if (typeof document > "u") return null; if ("currentScript" in document) return ( /** @type {any} */ document.currentScript ); try { throw new Error(); } catch (u) { var a = (/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(u.stack) || [])[1]; if (a) { var n = document.getElementsByTagName("script"); for (var l in n) if (n[l].src == a) return n[l]; } return null; } }, /** * Returns whether a given class is active for `element`. * * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the * given class is just the given class with a `no-` prefix. * * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its * ancestors have the given class or the negated version of it, then the default activation will be returned. * * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated * version of it, the class is considered active. * * @param {Element} element * @param {string} className * @param {boolean} [defaultActivation=false] * @returns {boolean} */ isActive: function(a, n, l) { for (var u = "no-" + n; a; ) { var i = a.classList; if (i.contains(n)) return !0; if (i.contains(u)) return !1; a = a.parentElement; } return !!l; } }, /** * This namespace contains all currently loaded languages and the some helper functions to create and modify languages. * * @namespace * @memberof Prism * @public */ languages: { /** * The grammar for plain, unformatted text. */ plain: j, plaintext: j, text: j, txt: j, /** * Creates a deep copy of the language with the given id and appends the given tokens. * * If a token in `redef` also appears in the copied language, then the existing token in the copied language * will be overwritten at its original position. * * ## Best practices * * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language) * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to * understand the language definition because, normally, the order of tokens matters in Prism grammars. * * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens. * Furthermore, all non-overwriting tokens should be placed after the overwriting ones. * * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`. * @param {Grammar} redef The new tokens to append. * @returns {Grammar} The new language created. * @public * @example * Prism.languages['css-with-colors'] = Prism.languages.extend('css', { * // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token * // at its original position * 'comment': { ... }, * // CSS doesn't have a 'color' token, so this token will be appended * 'color': /\b(?:red|green|blue)\b/ * }); */ extend: function(a, n) { var l = c.util.clone(c.languages[a]); for (var u in n) l[u] = n[u]; return l; }, /** * Inserts tokens _before_ another token in a language definition or any other grammar. * * ## Usage * * This helper method makes it easy to modify existing languages. For example, the CSS language definition * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do * this: * * ```js * Prism.languages.markup.style = { * // token * }; * ``` * * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens * before existing tokens. For the CSS example above, you would use it like this: * * ```js * Prism.languages.insertBefore('markup', 'cdata', { * 'style': { * // token * } * }); * ``` * * ## Special cases * * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar * will be ignored. * * This behavior can be used to insert tokens after `before`: * * ```js * Prism.languages.insertBefore('markup', 'comment', { * 'comment': Prism.languages.markup.comment, * // tokens after 'comment' * }); * ``` * * ## Limitations * * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily * deleting properties which is necessary to insert at arbitrary positions. * * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object. * Instead, it will create a new object and replace all references to the target object with the new one. This * can be done without temporarily deleting properties, so the iteration order is well-defined. * * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if * you hold the target object in a variable, then the value of the variable will not change. * * ```js * var oldMarkup = Prism.languages.markup; * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... }); * * assert(oldMarkup !== Prism.languages.markup); * assert(newMarkup === Prism.languages.markup); * ``` * * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the * object to be modified. * @param {string} before The key to insert before. * @param {Grammar} insert An object containing the key-value pairs to be inserted. * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the * object to be modified. * * Defaults to `Prism.languages`. * @returns {Grammar} The new grammar object. * @public */ insertBefore: function(a, n, l, u) { u = u || /** @type {any} */ c.languages; var i = u[a], h = {}; for (var x in i) if (i.hasOwnProperty(x)) { if (x == n) for (var m in l) l.hasOwnProperty(m) && (h[m] = l[m]); l.hasOwnProperty(x) || (h[x] = i[x]); } var $ = u[a]; return u[a] = h, c.languages.DFS(c.languages, function(C, q) { q === $ && C != a && (this[C] = h); }), h; }, // Traverse a language definition with Depth First Search DFS: function a(n, l, u, i) { i = i || {}; var h = c.util.objId; for (var x in n) if (n.hasOwnProperty(x)) { l.call(n, x, n[x], u || x); var m = n[x], $ = c.util.type(m); $ === "Object" && !i[h(m)] ? (i[h(m)] = !0, a(m, l, null, i)) : $ === "Array" && !i[h(m)] && (i[h(m)] = !0, a(m, l, x, i)); } } }, plugins: {}, /** * This is the most high-level function in Prism’s API. * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on * each one of them. * * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`. * * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}. * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}. * @memberof Prism * @public */ highlightAll: function(a, n) { c.highlightAllUnder(document, a, n); }, /** * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls * {@link Prism.highlightElement} on each one of them. * * The following hooks will be run: * 1. `before-highlightall` * 2. `before-all-elements-highlight` * 3. All hooks of {@link Prism.highlightElement} for each element. * * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted. * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers. * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done. * @memberof Prism * @public */ highlightAllUnder: function(a, n, l) { var u = { callback: l, container: a, selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code' }; c.hooks.run("before-highlightall", u), u.elements = Array.prototype.slice.apply(u.container.querySelectorAll(u.selector)), c.hooks.run("before-all-elements-highlight", u); for (var i = 0, h; h = u.elements[i++]; ) c.highlightElement(h, n === !0, u.callback); }, /** * Highlights the code inside a single element. * * The following hooks will be run: * 1. `before-sanity-check` * 2. `before-highlight` * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`. * 4. `before-insert` * 5. `after-highlight` * 6. `complete` * * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for * the element's language. * * @param {Element} element The element containing the code. * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier. * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default). * * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for * asynchronous highlighting to work. You can build your own bundle on the * [Download page](https://prismjs.com/download.html). * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done. * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously. * @memberof Prism * @public */ highlightElement: function(a, n, l) { var u = c.util.getLanguage(a), i = c.languages[u]; c.util.setLanguage(a, u); var h = a.parentElement; h && h.nodeName.toLowerCase() === "pre" && c.util.setLanguage(h, u); var x = a.textContent, m = { element: a, language: u, grammar: i, code: x }; function $(q) { m.highlightedCode = q, c.hooks.run("before-insert", m), m.element.innerHTML = m.highlightedCode, c.hooks.run("after-highlight", m), c.hooks.run("complete", m), l && l.call(m.element); } if (c.hooks.run("before-sanity-check", m), h = m.element.parentElement, h && h.nodeName.toLowerCase() === "pre" && !h.hasAttribute("tabindex") && h.setAttribute("tabindex", "0"), !m.code) { c.hooks.run("complete", m), l && l.call(m.element); return; } if (c.hooks.run("before-highlight", m), !m.grammar) { $(c.util.encode(m.code)); return; } if (n && d.Worker) { var C = new Worker(c.filename); C.onmessage = function(q) { $(q.data); }, C.postMessage(JSON.stringify({ language: m.language, code: m.code, immediateClose: !0 })); } else $(c.highlight(m.code, m.grammar, m.language)); }, /** * Low-level function, only use if you know what you’re doing. It accepts a string of text as input * and the language definitions to use, and returns a string with the HTML produced. * * The following hooks will be run: * 1. `before-tokenize` * 2. `after-tokenize` * 3. `wrap`: On each {@link Token}. * * @param {string} text A string with the code to be highlighted. * @param {Grammar} grammar An object containing the tokens to use. * * Usually a language definition like `Prism.languages.markup`. * @param {string} language The name of the language definition passed to `grammar`. * @returns {string} The highlighted HTML. * @memberof Prism * @public * @example * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript'); */ highlight: function(a, n, l) { var u = { code: a, grammar: n, language: l }; if (c.hooks.run("before-tokenize", u), !u.grammar) throw new Error('The language "' + u.language + '" has no grammar.'); return u.tokens = c.tokenize(u.code, u.grammar), c.hooks.run("after-tokenize", u), w.stringify(c.util.encode(u.tokens), u.language); }, /** * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input * and the language definitions to use, and returns an array with the tokenized code. * * When the language definition includes nested tokens, the function is called recursively on each of these tokens. * * This method could be useful in other contexts as well, as a very crude parser. * * @param {string} text A string with the code to be highlighted. * @param {Grammar} grammar An object containing the tokens to use. * * Usually a language definition like `Prism.languages.markup`. * @returns {TokenStream} An array of strings and tokens, a token stream. * @memberof Prism * @public * @example * let code = `var foo = 0;`; * let tokens = Prism.tokenize(code, Prism.languages.javascript); * tokens.forEach(token => { * if (token instanceof Prism.Token && token.type === 'number') { * console.log(`Found numeric literal: ${token.content}`); * } * }); */ tokenize: function(a, n) { var l = n.rest; if (l) { for (var u in l) n[u] = l[u]; delete n.rest; } var i = new k(); return z(i, i.head, a), J(a, i, n, i.head, 0), T(i); }, /** * @namespace * @memberof Prism * @public */ hooks: { all: {}, /** * Adds the given callback to the list of callbacks for the given hook. * * The callback will be invoked when the hook it is registered for is run. * Hooks are usually directly run by a highlight function but you can also run hooks yourself. * * One callback function can be registered to multiple hooks and the same hook multiple times. * * @param {string} name The name of the hook. * @param {HookCallback} callback The callback function which is given environment variables. * @public */ add: function(a, n) { var l = c.hooks.all; l[a] = l[a] || [], l[a].push(n); }, /** * Runs a hook invoking all registered callbacks with the given environment variables. * * Callbacks will be invoked synchronously and in the order in which they were registered. * * @param {string} name The name of the hook. * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered. * @public */ run: function(a, n) { var l = c.hooks.all[a]; if (!(!l || !l.length)) for (var u = 0, i; i = l[u++]; ) i(n); } }, Token: w }; d.Prism = c; function w(a, n, l, u) { this.type = a, this.content = n, this.alias = l, this.length = (u || "").length | 0; } w.stringify = function a(n, l) { if (typeof n == "string") return n; if (Array.isArray(n)) { var u = ""; return n.forEach(function($) { u += a($, l); }), u; } var i = { type: n.type, content: a(n.content, l), tag: "span", classes: ["token", n.type], attributes: {}, language: l }, h = n.alias; h && (Array.isArray(h) ? Array.prototype.push.apply(i.classes, h) : i.classes.push(h)), c.hooks.run("wrap", i); var x = ""; for (var m in i.attributes) x += " " + m + '="' + (i.attributes[m] || "").replace(/"/g, "&quot;") + '"'; return "<" + i.tag + ' class="' + i.classes.join(" ") + '"' + x + ">" + i.content + "</" + i.tag + ">"; }; function N(a, n, l, u) { a.lastIndex = n; var i = a.exec(l); if (i && u && i[1]) { var h = i[1].length; i.index += h, i[0] = i[0].slice(h); } return i; } function J(a, n, l, u, i, h) { for (var x in l) if (!(!l.hasOwnProperty(x) || !l[x])) { var m = l[x]; m = Array.isArray(m) ? m : [m]; for (var $ = 0; $ < m.length; ++$) { if (h && h.cause == x + "," + $) return; var C = m[$], q = C.inside, te = !!C.lookbehind, re = !!C.greedy, oe = C.alias; if (re && !C.pattern.global) { var we = C.pattern.toString().match(/[imsuy]*$/)[0]; C.pattern = RegExp(C.pattern.source, we + "g"); } for (var le = C.pattern || C, R = u.next, O = i; R !== n.tail && !(h && O >= h.reach); O += R.value.length, R = R.next) { var D = R.value; if (n.length > a.length) return; if (!(D instanceof w)) { var U = 1, B; if (re) { if (B = N(le, O, a, te), !B || B.index >= a.length) break; var V = B.index, ue = B.index + B[0].length, I = O; for (I += R.value.length; V >= I; ) R = R.next, I += R.value.length; if (I -= R.value.length, O = I, R.value instanceof w) continue; for (var Z = R; Z !== n.tail && (I < ue || typeof Z.value == "string"); Z = Z.next) U++, I += Z.value.length; U--, D = a.slice(O, I), B.index -= O; } else if (B = N(le, 0, D, te), !B) continue; var V = B.index, X = B[0], ne = D.slice(0, V), ce = D.slice(V + X.length), ae = O + D.length; h && ae > h.reach && (h.reach = ae); var Q = R.prev; ne && (Q = z(n, Q, ne), O += ne.length), b(n, Q, U); var de = new w(x, q ? c.tokenize(X, q) : X, oe, X); if (R = z(n, Q, de), ce && z(n, R, ce), U > 1) { var se = { cause: x + "," + $, reach: ae }; J(a, n, l, R.prev, O, se), h && se.reach > h.reach && (h.reach = se.reach); } } } } } } function k() { var a = { value: null, prev: null, next: null }, n = { value: null, prev: a, next: null }; a.next = n, this.head = a, this.tail = n, this.length = 0; } function z(a, n, l) { var u = n.next, i = { value: l, prev: n, next: u }; return n.next = i, u.prev = i, a.length++, i; } function b(a, n, l) { for (var u = n.next, i = 0; i < l && u !== a.tail; i++) u = u.next; n.next = u, u.prev = n, a.length -= i; } function T(a) { for (var n = [], l = a.head.next; l !== a.tail; ) n.push(l.value), l = l.next; return n; } if (!d.document) return d.addEventListener && (c.disableWorkerMessageHandler || d.addEventListener("message", function(a) { var n = JSON.parse(a.data), l = n.language, u = n.code, i = n.immediateClose; d.postMessage(c.highlight(u, c.languages[l], l)), i && d.close(); }, !1)), c; var E = c.util.currentScript(); E && (c.filename = E.src, E.hasAttribute("data-manual") && (c.manual = !0)); function v() { c.manual || c.highlightAll(); } if (!c.manual) { var A = document.readyState; A === "loading" || A === "interactive" && E && E.defer ? document.addEventListener("DOMContentLoaded", v) : window.requestAnimationFrame ? window.requestAnimationFrame(v) : window.setTimeout(v, 16); } return c; }(o); e.exports && (e.exports = r), typeof Re < "u" && (Re.Prism = r), r.languages.mark