inital commit

This commit is contained in:
2026-01-01 15:25:19 +05:30
commit f0ae49465a
36361 changed files with 4894111 additions and 0 deletions

View File

@@ -0,0 +1,26 @@
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Released under MIT see LICENSE.txt in the project root for license information.
* Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
*/
/**
* @module plugins/search
*/
import type { ICreate, IJodit, ISelectionRange } from "../../../types/index";
/**
* @private
*/
export declare function highlightTextRanges(jodit: IJodit, rng: ISelectionRange, restRanges: ISelectionRange[], ci: ICreate, root: HTMLElement): void;
/**
* @private
*/
export declare function getSelectionWrappers(root: HTMLElement): HTMLElement[];
/**
* @private
*/
export declare function clearSelectionWrappers(jodit: IJodit): void;
/**
* @private
*/
export declare function clearSelectionWrappersFromHTML(root: string): string;
export declare function clearNativeSelection(jodit: IJodit): void;

View File

@@ -0,0 +1,138 @@
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Released under MIT see LICENSE.txt in the project root for license information.
* Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
*/
import { globalWindow } from "../../../core/constants.js";
import { Dom } from "../../../core/dom/dom.js";
import { $$ } from "../../../core/helpers/utils/selector.js";
/**
* @private
*/
const TMP_ATTR = 'jd-tmp-selection';
/**
* @private
*/
export function highlightTextRanges(jodit, rng, restRanges, ci, root) {
if (rng.startContainer.nodeValue == null ||
rng.endContainer.nodeValue == null) {
return;
}
if (checkNativeSelectionMethod(jodit, rng, restRanges)) {
return;
}
const span = ci.element('span', {
[TMP_ATTR]: true
});
Dom.markTemporary(span);
normalizeRanges(rng, restRanges, ci);
let next = rng.startContainer;
do {
if (!next) {
break;
}
if (Dom.isText(next) && !isSelectionWrapper(next.parentNode)) {
Dom.wrap(next, span.cloneNode(), ci);
}
if (next === rng.endContainer) {
break;
}
let step = next.firstChild || next.nextSibling;
if (!step) {
while (next && !next.nextSibling && next !== root) {
next = next.parentNode;
}
step = next === null || next === void 0 ? void 0 : next.nextSibling;
}
next = step;
} while (next && next !== root);
}
/**
* @private
*/
export function getSelectionWrappers(root) {
return $$(`[${TMP_ATTR}]`, root);
}
/**
* @private
*/
export function clearSelectionWrappers(jodit) {
getSelectionWrappers(jodit.editor).forEach(span => Dom.unwrap(span));
clearNativeSelection(jodit);
}
/**
* @private
*/
export function clearSelectionWrappersFromHTML(root) {
return root.replace(RegExp(`<span[^>]+${TMP_ATTR}[^>]+>(.*?)</span>`, 'g'), '$1');
}
/**
* @private
*/
function isSelectionWrapper(node) {
return Dom.isElement(node) && node.hasAttribute(TMP_ATTR);
}
function checkNativeSelectionMethod(jodit, rng, restRanges) {
if (jodit.o.search.useCustomHighlightAPI &&
// @ts-ignore Because Highlight is not defined in the types TS 5.3.3
globalWindow &&
typeof globalWindow.Highlight !== 'undefined') {
const ranges = [rng, ...restRanges].map(rng => {
const range = jodit.selection.createRange();
range.setStart(rng.startContainer, rng.startOffset);
range.setEnd(rng.endContainer, rng.endOffset);
return range;
});
const searchHighlight = new Highlight(...ranges);
// @ts-ignore
CSS.highlights.clear();
// @ts-ignore
CSS.highlights.set('jodit-search-result', searchHighlight);
restRanges.length = 0;
return true;
}
return false;
}
export function clearNativeSelection(jodit) {
if (jodit.o.search.useCustomHighlightAPI &&
// @ts-ignore Because Highlight is not defined in the types TS 5.3.3
globalWindow &&
typeof globalWindow.Highlight !== 'undefined') {
// @ts-ignore
CSS.highlights.clear();
}
}
function normalizeRanges(rng, restRanges, ci) {
const startText = rng.startContainer.nodeValue;
let diff = 0;
if (rng.startOffset !== 0) {
const text = ci.text(startText.substring(0, rng.startOffset));
rng.startContainer.nodeValue = startText.substring(rng.startOffset);
Dom.before(rng.startContainer, text);
if (rng.startContainer === rng.endContainer) {
diff = rng.startOffset;
rng.endOffset -= diff;
}
rng.startOffset = 0;
}
const endText = rng.endContainer.nodeValue;
if (rng.endOffset !== endText.length) {
const text = ci.text(endText.substring(rng.endOffset));
rng.endContainer.nodeValue = endText.substring(0, rng.endOffset);
Dom.after(rng.endContainer, text);
for (const range of restRanges) {
if (range.startContainer === rng.endContainer) {
range.startContainer = text;
range.startOffset = range.startOffset - rng.endOffset - diff;
if (range.endContainer === rng.endContainer) {
range.endContainer = text;
range.endOffset = range.endOffset - rng.endOffset - diff;
}
}
else {
break;
}
}
rng.endOffset = rng.endContainer.nodeValue.length;
}
}

View File

@@ -0,0 +1,10 @@
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Released under MIT see LICENSE.txt in the project root for license information.
* Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
*/
/**
* @module plugins/search
*/
export * from "./highlight-text-ranges";
export * from "./sentence-finder";

10
node_modules/jodit/esm/plugins/search/helpers/index.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Released under MIT see LICENSE.txt in the project root for license information.
* Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
*/
/**
* @module plugins/search
*/
export * from "./highlight-text-ranges.js";
export * from "./sentence-finder.js";

View File

@@ -0,0 +1,21 @@
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Released under MIT see LICENSE.txt in the project root for license information.
* Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
*/
/**
* @module plugins/search
*/
import type { FuzzySearch, ISelectionRange, Nullable } from "../../../types/index";
export interface State {
query: string;
sentence: SentenceFinder;
}
export declare class SentenceFinder {
private readonly searchIndex;
private queue;
private value;
constructor(searchIndex?: FuzzySearch);
add(node: Text): void;
ranges(needle: string, position?: number): Nullable<ISelectionRange[]>;
}

View File

@@ -0,0 +1,61 @@
/*!
* Jodit Editor (https://xdsoft.net/jodit/)
* Released under MIT see LICENSE.txt in the project root for license information.
* Copyright (c) 2013-2025 Valeriy Chupurnov. All rights reserved. https://xdsoft.net
*/
import { fuzzySearchIndex } from "../../../core/helpers/string/fuzzy-search-index.js";
export class SentenceFinder {
constructor(searchIndex = fuzzySearchIndex) {
this.searchIndex = searchIndex;
this.queue = [];
this.value = '';
}
add(node) {
var _a;
const value = ((_a = node.nodeValue) !== null && _a !== void 0 ? _a : '').toLowerCase();
if (!value.length) {
return;
}
const index = this.value.length;
this.queue.push({
startIndex: index,
endIndex: index + value.length,
node
});
this.value += value;
}
ranges(needle, position = 0) {
const results = [];
let index = position, len = 0, startQueueIndex = 0;
// Find all ranges in substring
do {
[index, len] = this.searchIndex(needle, this.value, index);
if (index !== -1) {
let startContainer, startOffset = 0, endContainer, endOffset = 0;
for (let i = startQueueIndex; i < this.queue.length; i += 1) {
if (!startContainer && this.queue[i].endIndex > index) {
startContainer = this.queue[i].node;
startOffset = index - this.queue[i].startIndex;
}
if (startContainer &&
this.queue[i].endIndex >= index + len) {
endContainer = this.queue[i].node;
endOffset = index + len - this.queue[i].startIndex;
startQueueIndex = i;
break;
}
}
if (startContainer && endContainer) {
results.push({
startContainer,
startOffset,
endContainer,
endOffset
});
}
index += len;
}
} while (index !== -1);
return results.length === 0 ? null : results;
}
}