🏠 Home 

Selection Context

Get the selected text along with text before and after the selection

Этот скрипт недоступен для установки пользователем. Он является библиотекой, которая подключается к другим скриптам мета-ключом // @require https://update.greasyfork.org/scripts/528822/1550450/Selection%20Context.js

// ==UserScript==
// @name         Selection Context
// @namespace    http://tampermonkey.net/
// @version      0.1.2
// @description  Get the selected text along with text before and after the selection
// @author       RoCry
// @license MIT
// ==/UserScript==
/**
* Gets the selected text along with text before and after the selection
* @param {number} tryContextLength - Desired length of context to try to collect (before + after selection)
* @returns {Object} Object containing selectedHTML, selectedText, textBefore, textAfter, paragraphText
*/
function GetSelectionContext(tryContextLength = 500) {
const MAX_CONTEXT_LENGTH = 8192; // 8K characters max (reduced from 16K)
const actualContextLength = Math.min(tryContextLength, MAX_CONTEXT_LENGTH);
const halfContextLength = Math.floor(actualContextLength / 2);
const selection = window.getSelection();
if (!selection || selection.rangeCount === 0 || selection.toString().trim() === '') {
return { selectedHTML: null, selectedText: null, textBefore: null, textAfter: null, paragraphText: null };
}
const range = selection.getRangeAt(0);
const selectedText = selection.toString().trim();
// Improved HTML extraction
let selectedHTML;
try {
// Method 1: Try to get HTML with surrounding elements
const clonedRange = range.cloneRange();
const container = document.createElement('div');
container.appendChild(clonedRange.cloneContents());
// If selection starts/ends in the middle of an element, we need to recreate parent structure
const parentElement = range.commonAncestorContainer.nodeType === Node.TEXT_NODE
? range.commonAncestorContainer.parentElement
: range.commonAncestorContainer;
if (parentElement && parentElement.nodeName !== 'BODY') {
// Get the parent element's tag name and recreate it
const tagName = parentElement.nodeName.toLowerCase();
selectedHTML = `<${tagName}>${container.innerHTML}</${tagName}>`;
} else {
selectedHTML = container.innerHTML;
}
} catch (e) {
// Fallback method
console.error('Error extracting HTML from selection:', e);
selectedHTML = selectedText;
}
// Helper function to get text nodes in document order
function getTextNodesIn(node) {
const textNodes = [];
const walk = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, null, false);
let currentNode;
while (currentNode = walk.nextNode()) {
textNodes.push(currentNode);
}
return textNodes;
}
// Get all text nodes in document
const allTextNodes = getTextNodesIn(document.body);
// Find start and end text nodes of the selection
const startNode = range.startContainer;
const endNode = range.endContainer;
let textBefore = '';
let textAfter = '';
// Collect text before the selection
let beforeIndex = allTextNodes.findIndex(node => node === startNode) - 1;
let currentLength = 0;
// First add partial text from the start node itself
if (startNode.nodeType === Node.TEXT_NODE) {
textBefore = startNode.textContent.substring(0, range.startOffset) + textBefore;
currentLength = textBefore.length;
}
// Then add text from previous nodes
while (beforeIndex >= 0 && currentLength < halfContextLength) {
const node = allTextNodes[beforeIndex];
const nodeText = node.textContent;
// Add the entire node's text
textBefore = nodeText + '\n' + textBefore;
currentLength += nodeText.length;
beforeIndex--;
}
// If we didn't get enough context, add ellipsis
if (beforeIndex >= 0) {
textBefore = '...\n' + textBefore;
}
// Collect text after the selection
let afterIndex = allTextNodes.findIndex(node => node === endNode) + 1;
currentLength = 0;
// First add partial text from the end node itself
if (endNode.nodeType === Node.TEXT_NODE) {
textAfter += endNode.textContent.substring(range.endOffset);
currentLength = textAfter.length;
}
// Then add text from subsequent nodes
while (afterIndex < allTextNodes.length && currentLength < halfContextLength) {
const node = allTextNodes[afterIndex];
const nodeText = node.textContent;
// Add the entire node's text
textAfter += nodeText + '\n';
currentLength += nodeText.length;
afterIndex++;
}
// If we didn't get all the text, add ellipsis
if (afterIndex < allTextNodes.length) {
textAfter += '\n...';
}
// Clean up and trim the text
textBefore = textBefore.trim();
textAfter = textAfter.trim();
// Combine everything for paragraph text
const paragraphText = (textBefore + ' ' + selectedText + ' ' + textAfter).trim();
return { selectedHTML, selectedText, textBefore, textAfter, paragraphText };
}
// Export the function for use in other scripts
if (typeof module !== 'undefined' && module.exports) {
module.exports = { GetSelectionContext };
} else {
// For direct browser use
window.SelectionUtils = window.SelectionUtils || {};
window.SelectionUtils.GetSelectionContext = GetSelectionContext;
}