Selection Context

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

目前为 2025-03-05 提交的版本,查看 最新版本

此脚本不应直接安装,它是供其他脚本使用的外部库。如果你需要使用该库,请在脚本元属性加入:// @require https://update.cn-greasyfork.org/scripts/528822/1547803/Selection%20Context.js

  1. // ==UserScript==
  2. // @name Selection Context
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1.1
  5. // @description Get the selected text along with text before and after the selection
  6. // @author RoCry
  7. // @license MIT
  8. // ==/UserScript==
  9.  
  10. /**
  11. * Gets the selected text along with text before and after the selection
  12. * @param {number} tryContextLength - Desired length of context to try to collect (before + after selection)
  13. * @returns {Object} Object containing selectedText, textBefore, textAfter, and paragraphText
  14. */
  15. function GetSelectionContext(tryContextLength = 500) {
  16. const MAX_CONTEXT_LENGTH = 8192; // 8K characters max (reduced from 16K)
  17. const actualContextLength = Math.min(tryContextLength, MAX_CONTEXT_LENGTH);
  18. const halfContextLength = Math.floor(actualContextLength / 2);
  19.  
  20. const selection = window.getSelection();
  21. if (!selection || selection.rangeCount === 0 || selection.toString().trim() === '') {
  22. return { selectedText: null, textBefore: null, textAfter: null, paragraphText: null };
  23. }
  24.  
  25. const selectedText = selection.toString().trim();
  26. const range = selection.getRangeAt(0);
  27.  
  28. // Helper function to get text nodes in document order
  29. function getTextNodesIn(node) {
  30. const textNodes = [];
  31. const walk = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, null, false);
  32. let currentNode;
  33. while (currentNode = walk.nextNode()) {
  34. textNodes.push(currentNode);
  35. }
  36. return textNodes;
  37. }
  38.  
  39. // Get all text nodes in document
  40. const allTextNodes = getTextNodesIn(document.body);
  41.  
  42. // Find start and end text nodes of the selection
  43. const startNode = range.startContainer;
  44. const endNode = range.endContainer;
  45.  
  46. let textBefore = '';
  47. let textAfter = '';
  48.  
  49. // Collect text before the selection
  50. let beforeIndex = allTextNodes.findIndex(node => node === startNode) - 1;
  51. let currentLength = 0;
  52.  
  53. // First add partial text from the start node itself
  54. if (startNode.nodeType === Node.TEXT_NODE) {
  55. textBefore = startNode.textContent.substring(0, range.startOffset) + textBefore;
  56. currentLength = textBefore.length;
  57. }
  58.  
  59. // Then add text from previous nodes
  60. while (beforeIndex >= 0 && currentLength < halfContextLength) {
  61. const node = allTextNodes[beforeIndex];
  62. const nodeText = node.textContent;
  63.  
  64. // Add the entire node's text
  65. textBefore = nodeText + '\n' + textBefore;
  66. currentLength += nodeText.length;
  67.  
  68. beforeIndex--;
  69. }
  70.  
  71. // If we didn't get enough context, add ellipsis
  72. if (beforeIndex >= 0) {
  73. textBefore = '...\n' + textBefore;
  74. }
  75.  
  76. // Collect text after the selection
  77. let afterIndex = allTextNodes.findIndex(node => node === endNode) + 1;
  78. currentLength = 0;
  79.  
  80. // First add partial text from the end node itself
  81. if (endNode.nodeType === Node.TEXT_NODE) {
  82. textAfter += endNode.textContent.substring(range.endOffset);
  83. currentLength = textAfter.length;
  84. }
  85.  
  86. // Then add text from subsequent nodes
  87. while (afterIndex < allTextNodes.length && currentLength < halfContextLength) {
  88. const node = allTextNodes[afterIndex];
  89. const nodeText = node.textContent;
  90.  
  91. // Add the entire node's text
  92. textAfter += nodeText + '\n';
  93. currentLength += nodeText.length;
  94.  
  95. afterIndex++;
  96. }
  97.  
  98. // If we didn't get all the text, add ellipsis
  99. if (afterIndex < allTextNodes.length) {
  100. textAfter += '\n...';
  101. }
  102.  
  103. // Clean up and trim the text
  104. textBefore = textBefore.trim();
  105. textAfter = textAfter.trim();
  106.  
  107. // Combine everything for paragraph text
  108. const paragraphText = (textBefore + ' ' + selectedText + ' ' + textAfter).trim();
  109.  
  110. return { selectedText, textBefore, textAfter, paragraphText };
  111. }
  112.  
  113. // Export the function for use in other scripts
  114. if (typeof module !== 'undefined' && module.exports) {
  115. module.exports = { GetSelectionContext };
  116. } else {
  117. // For direct browser use
  118. window.SelectionUtils = window.SelectionUtils || {};
  119. window.SelectionUtils.GetSelectionContext = GetSelectionContext;
  120. }