Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@prosekit/extensions

Package Overview
Dependencies
Maintainers
0
Versions
117
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@prosekit/extensions - npm Package Compare versions

Comparing version 0.5.3 to 0.6.0

dist/shiki-import-UFUFVKJ2.js

124

dist/_tsup-dts-rollup.d.ts

@@ -12,3 +12,4 @@ import { Attrs } from '@prosekit/pm/model';

import { Extension } from '@prosekit/core';
import { getHighlighter } from 'shiki/bundle/full';
import { getSingletonHighlighter } from 'shiki/bundle/full';
import type { Highlighter } from 'shiki';
import { IndentListOptions } from 'prosemirror-flat-list';

@@ -26,3 +27,2 @@ import { InputRule } from '@prosekit/pm/inputrules';

import { ProseMirrorNode } from '@prosekit/pm/model';
import { Slice } from '@prosekit/pm/model';
import type { SpecialLanguage } from 'shiki';

@@ -94,3 +94,4 @@ import { ToggleCollapsedOptions } from 'prosemirror-flat-list';

/**
* Theme registation
* A list of shiki themes to pre-load. The first theme in the list will be
* used to render the code block.
*

@@ -101,3 +102,3 @@ * @default ['one-dark-pro']

/**
* Language registation
* A list of shiki languages to pre-load.
*

@@ -925,33 +926,7 @@ * @default ['text']

declare const findNext: Command;
export { findNext }
export { findNext as findNext_alias_1 }
declare const findNextNoWrap: Command;
export { findNextNoWrap }
export { findNextNoWrap as findNextNoWrap_alias_1 }
declare const findPrev: Command;
export { findPrev }
export { findPrev as findPrev_alias_1 }
declare const findPrevNoWrap: Command;
export { findPrevNoWrap }
export { findPrevNoWrap as findPrevNoWrap_alias_1 }
export declare function getCheckRanges(transactions: readonly Transaction[], oldState: EditorState, newState: EditorState): Array<[number, number]>;
export { getHighlighter }
export declare function getPluginState(state: EditorState): PredictionPluginState | undefined;
declare function getSearchState(state: EditorState): {
query: SearchQuery;
range: {
from: number;
to: number;
} | null;
} | undefined;
export { getSearchState }
export { getSearchState as getSearchState_alias_1 }
export { getSingletonHighlighter }

@@ -964,3 +939,3 @@ export declare function getTrMeta(tr: Transaction): PredictionPluginState;

declare type HighlighterOptions = {
export declare type HighlighterOptions = {
themes: BundledTheme[];

@@ -971,2 +946,10 @@ langs: (BundledLanguage | SpecialLanguage)[];

declare type HighlighterResult = {
highlighter: Highlighter;
promise?: undefined;
} | {
highlighter?: undefined;
promise: Promise<void>;
};
/**

@@ -1105,61 +1088,4 @@ * @public

declare interface QueryImpl {
findNext(state: EditorState, from: number, to: number): SearchResult | null;
findPrev(state: EditorState, from: number, to: number): SearchResult | null;
}
export declare function prepareHighlighter(options: HighlighterOptions): HighlighterResult;
declare const replaceAll: Command;
export { replaceAll }
export { replaceAll as replaceAll_alias_1 }
declare const replaceCurrent: Command;
export { replaceCurrent }
export { replaceCurrent as replaceCurrent_alias_1 }
declare const replaceNext: Command;
export { replaceNext }
export { replaceNext as replaceNext_alias_1 }
declare const replaceNextNoWrap: Command;
export { replaceNextNoWrap }
export { replaceNextNoWrap as replaceNextNoWrap_alias_1 }
declare function search(options?: {
initialQuery?: SearchQuery;
initialRange?: {
from: number;
to: number;
};
}): Plugin_2;
export { search }
export { search as search_alias_1 }
declare class SearchQuery {
readonly search: string;
readonly caseSensitive: boolean;
readonly literal: boolean;
readonly regexp: boolean;
readonly replace: string;
readonly valid: boolean;
readonly wholeWord: boolean;
impl: QueryImpl;
constructor(config: {
search: string;
caseSensitive?: boolean;
literal?: boolean;
regexp?: boolean;
replace?: string;
wholeWord?: boolean;
});
eq(other: SearchQuery): boolean;
findNext(state: EditorState, from?: number, to?: number): SearchResult | null;
findPrev(state: EditorState, from?: number, to?: number): SearchResult | null;
checkResult(state: EditorState, result: SearchResult): boolean;
unquote(string: string): string;
getReplacement(state: EditorState, result: SearchResult): Slice;
}
export { SearchQuery }
export { SearchQuery as SearchQuery_alias_1 }
export { SearchQuery as SearchQuery_alias_2 }
/**

@@ -1207,18 +1133,2 @@ * Options for {@link defineSearchQuery}

declare interface SearchResult {
from: number;
to: number;
match: RegExpMatchArray | null;
}
export { SearchResult }
export { SearchResult as SearchResult_alias_1 }
export { SearchResult as SearchResult_alias_2 }
declare function setSearchState(tr: Transaction, query: SearchQuery, range?: {
from: number;
to: number;
} | null): Transaction;
export { setSearchState }
export { setSearchState as setSearchState_alias_1 }
/**

@@ -1278,4 +1188,2 @@ * @internal

export declare function validRegExp(source: string): boolean;
export { }

@@ -126,22 +126,42 @@ import {

import { createParser } from "prosemirror-highlight/shiki";
function createHighlighterLoader() {
let highlighterPromise, highlighter, loadLangs = /* @__PURE__ */ new Set();
return function(lang, options) {
return highlighterPromise ? highlighter ? loadLangs.has(lang) ? { highlighter } : { promise: highlighter.loadLanguage(lang).then(() => {
loadLangs.add(lang);
}).catch((error) => {
console.warn(`Failed to load language '${lang}'`, error);
}) } : { promise: highlighterPromise } : (highlighterPromise = import("./shiki-import-25BJYIO2.js").then(({ getHighlighter }) => getHighlighter(options)).then((h) => {
highlighter = h;
}), { promise: highlighterPromise });
};
// src/code-block/shiki-highlighter.ts
var highlighter, loadedLangs = /* @__PURE__ */ new Set(), loadedThemes = /* @__PURE__ */ new Set();
async function createHighlighter(options) {
let { getSingletonHighlighter } = await import("./shiki-import-UFUFVKJ2.js");
highlighter || (highlighter = await getSingletonHighlighter(options));
}
async function loadLanguages(langs) {
for (let lang of langs) {
if (!highlighter) break;
await highlighter.loadLanguage(lang), loadedLangs.add(lang);
}
}
async function loadThemes(themes) {
for (let theme of themes) {
if (!highlighter) break;
await highlighter.loadTheme(theme), loadedThemes.add(theme);
}
}
function prepareHighlighter(options) {
if (!highlighter)
return { promise: createHighlighter(options) };
let langs = options.langs.filter((lang) => !loadedLangs.has(lang));
if (langs.length > 0)
return { promise: loadLanguages(langs) };
let themes = options.themes.filter((theme) => !loadedThemes.has(theme));
return themes.length > 0 ? { promise: loadThemes(themes) } : { highlighter };
}
// src/code-block/shiki-parser.ts
function createLazyParser(highlighterOptions) {
let parser, highlighterLoader = createHighlighterLoader();
return function(options) {
let language = options.language || "", { highlighter, promise } = highlighterLoader(
language,
highlighterOptions
);
return highlighter ? (parser || (parser = createParser(highlighter)), parser(options)) : promise || [];
let parser;
return prepareHighlighter(highlighterOptions), function(options) {
let language = options.language || "", { highlighter: highlighter2, promise } = prepareHighlighter({
langs: [language],
themes: highlighterOptions.themes
});
return highlighter2 ? (parser || (parser = createParser(highlighter2, {
theme: highlighterOptions.themes[0]
})), parser(options)) : promise;
};

@@ -148,0 +168,0 @@ }

// src/search/index.ts
import { defineCommands, definePlugin } from "@prosekit/core";
// src/search/prosemirror-search/search.ts
import {
Plugin,
PluginKey,
TextSelection
} from "@prosekit/pm/state";
import { DecorationSet, Decoration } from "@prosekit/pm/view";
// src/search/prosemirror-search/query.ts
import { Slice, Fragment } from "@prosekit/pm/model";
import "@prosekit/pm/state";
var SearchQuery = class {
/// Create a query object.
constructor(config) {
this.search = config.search, this.caseSensitive = !!config.caseSensitive, this.literal = !!config.literal, this.regexp = !!config.regexp, this.replace = config.replace || "", this.valid = !!this.search && !(this.regexp && !validRegExp(this.search)), this.wholeWord = !!config.wholeWord, this.impl = this.valid ? this.regexp ? new RegExpQuery(this) : new StringQuery(this) : nullQuery;
}
/// Compare this query to another query.
eq(other) {
return this.search == other.search && this.replace == other.replace && this.caseSensitive == other.caseSensitive && this.regexp == other.regexp && this.wholeWord == other.wholeWord;
}
/// Find the next occurrence of this query in the given range.
findNext(state, from = 0, to = state.doc.content.size) {
for (; ; ) {
if (from >= to) return null;
let result = this.impl.findNext(state, from, to);
if (!result || this.checkResult(state, result)) return result;
from = result.from + 1;
}
}
/// Find the previous occurrence of this query in the given range.
/// Note that, if `to` is given, it should be _less_ than `from`.
findPrev(state, from = state.doc.content.size, to = 0) {
for (; ; ) {
if (from <= to) return null;
let result = this.impl.findPrev(state, from, to);
if (!result || this.checkResult(state, result)) return result;
from = result.to - 1;
}
}
/// @internal
checkResult(state, result) {
return this.wholeWord ? checkWordBoundary(state, result.from) && checkWordBoundary(state, result.to) : !0;
}
/// @internal
unquote(string) {
return this.literal ? string : string.replace(
/\\([\\nrt])/g,
(_, ch) => ch == "n" ? `
` : ch == "r" ? "\r" : ch == "t" ? " " : "\\"
);
}
/// Get a replacement slice for a given search result.
getReplacement(state, result) {
let marks = state.doc.resolve(result.from).marksAcross(state.doc.resolve(result.to)), text = this.unquote(this.replace), nodes = [], i = 0, { match } = result;
if (match) {
text = text.replace(
/\$([\d$&+])/g,
(m, i2) => i2 == "$" ? "$" : i2 == "&" ? match[0] : i2 != "0" && +i2 < match.length ? match[+i2] : m
);
for (let pos = result.from; ; ) {
let obj = text.indexOf("\uFFFC", i);
if (obj < 0) break;
let found = findLeafBetween(state, pos, result.to);
if (!found) break;
obj > i && nodes.push(state.schema.text(text.slice(i, obj), marks)), nodes.push(found.node), i = obj + 1, pos = found.pos + 1;
}
}
return i < text.length && nodes.push(state.schema.text(text.slice(i), marks)), new Slice(Fragment.from(nodes), 0, 0);
}
}, nullQuery = new class {
findNext() {
return null;
}
findPrev() {
return null;
}
}(), StringQuery = class {
constructor(query) {
this.query = query;
let string = query.unquote(query.search);
query.caseSensitive || (string = string.toLowerCase()), this.string = string;
}
findNext(state, from, to) {
return scanTextblocks(state.doc, from, to, (node, start) => {
let off = Math.max(from, start), content = textContent(node).slice(
off - start,
Math.min(node.content.size, to - start)
), index = (this.query.caseSensitive ? content : content.toLowerCase()).indexOf(this.string);
return index < 0 ? null : {
from: off + index,
to: off + index + this.string.length,
match: null
};
});
}
findPrev(state, from, to) {
return scanTextblocks(state.doc, from, to, (node, start) => {
let off = Math.max(start, to), content = textContent(node).slice(
off - start,
Math.min(node.content.size, from - start)
);
this.query.caseSensitive || (content = content.toLowerCase());
let index = content.lastIndexOf(this.string);
return index < 0 ? null : {
from: off + index,
to: off + index + this.string.length,
match: null
};
});
}
}, baseFlags = "g" + (/x/.unicode == null ? "" : "u"), RegExpQuery = class {
constructor(query) {
this.query = query;
this.regexp = new RegExp(
query.search,
baseFlags + (query.caseSensitive ? "" : "i")
);
}
findNext(state, from, to) {
return scanTextblocks(state.doc, from, to, (node, start) => {
let content = textContent(node).slice(
0,
Math.min(node.content.size, to - start)
);
this.regexp.lastIndex = from - start;
let match = this.regexp.exec(content);
return match ? {
from: start + match.index,
to: start + match.index + match[0].length,
match
} : null;
});
}
findPrev(state, from, to) {
return scanTextblocks(state.doc, from, to, (node, start) => {
let content = textContent(node).slice(
0,
Math.min(node.content.size, from - start)
), match;
for (let off = 0; ; ) {
this.regexp.lastIndex = off;
let next = this.regexp.exec(content);
if (!next) break;
match = next, off = next.index + 1;
}
return match ? {
from: start + match.index,
to: start + match.index + match[0].length,
match
} : null;
});
}
};
function validRegExp(source) {
try {
return new RegExp(source, baseFlags), !0;
} catch (e) {
return !1;
}
}
var TextContentCache = /* @__PURE__ */ new WeakMap();
function textContent(node) {
let cached = TextContentCache.get(node);
if (cached) return cached;
let content = "";
for (let i = 0; i < node.childCount; i++) {
let child = node.child(i);
child.isText ? content += child.text : child.isLeaf ? content += "\uFFFC" : content += " " + textContent(child) + " ";
}
return TextContentCache.set(node, content), content;
}
function scanTextblocks(node, from, to, f, nodeStart = 0) {
if (node.inlineContent)
return f(node, nodeStart);
if (!node.isLeaf)
if (from > to)
for (let i = node.childCount - 1, pos = nodeStart + node.content.size; i >= 0 && pos > to; i--) {
let child = node.child(i);
if (pos -= child.nodeSize, pos < from) {
let result = scanTextblocks(child, from, to, f, pos + 1);
if (result != null) return result;
}
}
else
for (let i = 0, pos = nodeStart; i < node.childCount && pos < to; i++) {
let child = node.child(i), start = pos;
if (pos += child.nodeSize, pos > from) {
let result = scanTextblocks(child, from, to, f, start + 1);
if (result != null) return result;
}
}
return null;
}
function checkWordBoundary(state, pos) {
let $pos = state.doc.resolve(pos), before = $pos.nodeBefore, after = $pos.nodeAfter;
return !before || !after || !before.isText || !after.isText ? !0 : !/\p{L}$/u.test(before.text) || !/^\p{L}/u.test(after.text);
}
function findLeafBetween(state, from, to) {
let found = null;
return state.doc.nodesBetween(from, to, (node, pos) => {
if (found) return !1;
node.isLeaf && node.isInline && !node.isText && (found = { node, pos });
}), found;
}
// src/search/prosemirror-search/search.ts
var SearchState = class {
constructor(query, range, deco) {
this.query = query;
this.range = range;
this.deco = deco;
}
};
function buildMatchDeco(state, query, range) {
if (!query.valid) return DecorationSet.empty;
let deco = [], sel = state.selection;
for (let pos = range ? range.from : 0, end = range ? range.to : state.doc.content.size; ; ) {
let next = query.findNext(state, pos, end);
if (!next) break;
let cls = next.from == sel.from && next.to == sel.to ? "ProseMirror-active-search-match" : "ProseMirror-search-match";
deco.push(Decoration.inline(next.from, next.to, { class: cls })), pos = next.to;
}
return DecorationSet.create(state.doc, deco);
}
var searchKey = new PluginKey("search");
function search(options = {}) {
return new Plugin({
key: searchKey,
state: {
init(_config, state) {
let query = options.initialQuery || new SearchQuery({ search: "" }), range = options.initialRange || null;
return new SearchState(
query,
range,
buildMatchDeco(state, query, range)
);
},
apply(tr, search2, _oldState, state) {
let set = tr.getMeta(searchKey);
if (set)
return new SearchState(
set.query,
set.range,
buildMatchDeco(state, set.query, set.range)
);
if (tr.docChanged || tr.selectionSet) {
let range = search2.range;
if (range) {
let from = tr.mapping.map(range.from, 1), to = tr.mapping.map(range.to, -1);
range = from < to ? { from, to } : null;
}
search2 = new SearchState(
search2.query,
range,
buildMatchDeco(state, search2.query, range)
);
}
return search2;
}
},
props: {
decorations: (state) => searchKey.getState(state).deco
}
});
}
function nextMatch(search2, state, wrap, curFrom, curTo) {
let range = search2.range || { from: 0, to: state.doc.content.size }, next = search2.query.findNext(state, Math.max(curTo, range.from), range.to);
return !next && wrap && (next = search2.query.findNext(state, range.from, Math.min(curFrom, range.to))), next;
}
function prevMatch(search2, state, wrap, curFrom, curTo) {
let range = search2.range || { from: 0, to: state.doc.content.size }, prev = search2.query.findPrev(
state,
Math.min(curFrom, range.to),
range.from
);
return !prev && wrap && (prev = search2.query.findPrev(state, range.to, Math.max(curTo, range.from))), prev;
}
function findCommand(wrap, dir) {
return (state, dispatch) => {
let search2 = searchKey.getState(state);
if (!search2 || !search2.query.valid) return !1;
let { from, to } = state.selection, next = dir > 0 ? nextMatch(search2, state, wrap, from, to) : prevMatch(search2, state, wrap, from, to);
if (!next) return !1;
let selection = TextSelection.create(state.doc, next.from, next.to);
return dispatch && dispatch(state.tr.setSelection(selection).scrollIntoView()), !0;
};
}
var findNext = findCommand(!0, 1), findNextNoWrap = findCommand(!1, 1), findPrev = findCommand(!0, -1), findPrevNoWrap = findCommand(!1, -1);
function replaceCommand(wrap, moveForward) {
return (state, dispatch) => {
let search2 = searchKey.getState(state);
if (!search2 || !search2.query.valid) return !1;
let { from } = state.selection, next = nextMatch(search2, state, wrap, from, from);
if (!next) return !1;
if (!dispatch) return !0;
if (state.selection.from == next.from && state.selection.to == next.to) {
let tr = state.tr.replace(
next.from,
next.to,
search2.query.getReplacement(state, next)
), after = moveForward && nextMatch(search2, state, wrap, next.from, next.to);
after ? tr.setSelection(
TextSelection.create(
tr.doc,
tr.mapping.map(after.from, 1),
tr.mapping.map(after.to, -1)
)
) : tr.setSelection(
TextSelection.create(tr.doc, next.from, tr.mapping.map(next.to, 1))
), dispatch(tr.scrollIntoView());
} else if (moveForward)
dispatch(
state.tr.setSelection(TextSelection.create(state.doc, next.from, next.to)).scrollIntoView()
);
else
return !1;
return !0;
};
}
var replaceNext = replaceCommand(!0, !0), replaceNextNoWrap = replaceCommand(!1, !0), replaceCurrent = replaceCommand(!1, !1), replaceAll = (state, dispatch) => {
let search2 = searchKey.getState(state);
if (!search2) return !1;
let matches = [], range = search2.range || { from: 0, to: state.doc.content.size };
for (let pos = range.from; ; ) {
let next = search2.query.findNext(state, pos, range.to);
if (!next) break;
matches.push(next), pos = next.to;
}
if (dispatch) {
let tr = state.tr;
for (let i = matches.length - 1; i >= 0; i--) {
let match = matches[i];
tr.replace(
match.from,
match.to,
search2.query.getReplacement(state, match)
);
}
dispatch(tr);
}
return !0;
};
// src/search/index.ts
SearchQuery,
findNext,
findNextNoWrap,
findPrev,
findPrevNoWrap,
replaceAll,
replaceCurrent,
replaceNext,
replaceNextNoWrap,
search
} from "prosemirror-search";
function defineSearchQuery(options) {

@@ -349,0 +16,0 @@ let query = new SearchQuery(options);

{
"name": "@prosekit/extensions",
"type": "module",
"version": "0.5.3",
"version": "0.6.0",
"private": false,

@@ -175,6 +175,7 @@ "author": {

"prosemirror-flat-list": "^0.5.0",
"prosemirror-highlight": "^0.6.0",
"prosemirror-highlight": "^0.8.0",
"prosemirror-search": "^0.1.0",
"prosemirror-tables": "^1.3.7",
"shiki": "^1.6.2",
"@prosekit/core": "^0.5.5",
"shiki": "^1.9.0",
"@prosekit/core": "^0.6.0",
"@prosekit/pm": "^0.1.5"

@@ -184,3 +185,3 @@ },

"tsup": "^8.1.0",
"typescript": "^5.4.5",
"typescript": "^5.5.2",
"vitest": "^1.6.0",

@@ -187,0 +188,0 @@ "@prosekit/dev": "0.0.0"

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc