Add option to enable/disable scanning of source expressions in popups
This commit is contained in:
parent
3491affcf1
commit
71471d08e5
@ -221,6 +221,7 @@ function optionsSetDefaults(options) {
|
|||||||
modifier: 'shift',
|
modifier: 'shift',
|
||||||
deepDomScan: false,
|
deepDomScan: false,
|
||||||
popupNestingMaxDepth: 0,
|
popupNestingMaxDepth: 0,
|
||||||
|
enableOnPopupExpressions: false,
|
||||||
enableOnSearchPage: true
|
enableOnSearchPage: true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ async function formRead() {
|
|||||||
optionsNew.scanning.alphanumeric = $('#search-alphanumeric').prop('checked');
|
optionsNew.scanning.alphanumeric = $('#search-alphanumeric').prop('checked');
|
||||||
optionsNew.scanning.autoHideResults = $('#auto-hide-results').prop('checked');
|
optionsNew.scanning.autoHideResults = $('#auto-hide-results').prop('checked');
|
||||||
optionsNew.scanning.deepDomScan = $('#deep-dom-scan').prop('checked');
|
optionsNew.scanning.deepDomScan = $('#deep-dom-scan').prop('checked');
|
||||||
|
optionsNew.scanning.enableOnPopupExpressions = $('#enable-scanning-of-popup-expressions').prop('checked');
|
||||||
optionsNew.scanning.enableOnSearchPage = $('#enable-scanning-on-search-page').prop('checked');
|
optionsNew.scanning.enableOnSearchPage = $('#enable-scanning-on-search-page').prop('checked');
|
||||||
optionsNew.scanning.delay = parseInt($('#scan-delay').val(), 10);
|
optionsNew.scanning.delay = parseInt($('#scan-delay').val(), 10);
|
||||||
optionsNew.scanning.length = parseInt($('#scan-length').val(), 10);
|
optionsNew.scanning.length = parseInt($('#scan-length').val(), 10);
|
||||||
@ -191,6 +192,7 @@ async function onReady() {
|
|||||||
$('#search-alphanumeric').prop('checked', options.scanning.alphanumeric);
|
$('#search-alphanumeric').prop('checked', options.scanning.alphanumeric);
|
||||||
$('#auto-hide-results').prop('checked', options.scanning.autoHideResults);
|
$('#auto-hide-results').prop('checked', options.scanning.autoHideResults);
|
||||||
$('#deep-dom-scan').prop('checked', options.scanning.deepDomScan);
|
$('#deep-dom-scan').prop('checked', options.scanning.deepDomScan);
|
||||||
|
$('#enable-scanning-of-popup-expressions').prop('checked', options.scanning.enableOnPopupExpressions);
|
||||||
$('#enable-scanning-on-search-page').prop('checked', options.scanning.enableOnSearchPage);
|
$('#enable-scanning-on-search-page').prop('checked', options.scanning.enableOnSearchPage);
|
||||||
$('#scan-delay').val(options.scanning.delay);
|
$('#scan-delay').val(options.scanning.delay);
|
||||||
$('#scan-length').val(options.scanning.length);
|
$('#scan-length').val(options.scanning.length);
|
||||||
|
@ -192,6 +192,10 @@
|
|||||||
<label><input type="checkbox" id="auto-hide-results"> Automatically hide results</label>
|
<label><input type="checkbox" id="auto-hide-results"> Automatically hide results</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="checkbox options-advanced">
|
||||||
|
<label><input type="checkbox" id="enable-scanning-of-popup-expressions"> Enable scanning of popup expressions</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="checkbox">
|
<div class="checkbox">
|
||||||
<label><input type="checkbox" id="enable-scanning-on-search-page"> Enable scanning on search page</label>
|
<label><input type="checkbox" id="enable-scanning-on-search-page"> Enable scanning on search page</label>
|
||||||
</div>
|
</div>
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
|
|
||||||
class Frontend {
|
class Frontend {
|
||||||
constructor(popup) {
|
constructor(popup, ignoreNodes) {
|
||||||
this.popup = popup;
|
this.popup = popup;
|
||||||
this.popupTimer = null;
|
this.popupTimer = null;
|
||||||
this.mouseDownLeft = false;
|
this.mouseDownLeft = false;
|
||||||
@ -26,6 +26,7 @@ class Frontend {
|
|||||||
this.textSourceLast = null;
|
this.textSourceLast = null;
|
||||||
this.pendingLookup = false;
|
this.pendingLookup = false;
|
||||||
this.options = null;
|
this.options = null;
|
||||||
|
this.ignoreNodes = (Array.isArray(ignoreNodes) && ignoreNodes.length > 0 ? ignoreNodes.join(',') : null);
|
||||||
|
|
||||||
this.primaryTouchIdentifier = null;
|
this.primaryTouchIdentifier = null;
|
||||||
this.contextMenuChecking = false;
|
this.contextMenuChecking = false;
|
||||||
@ -39,10 +40,10 @@ class Frontend {
|
|||||||
static create() {
|
static create() {
|
||||||
const initializationData = window.frontendInitializationData;
|
const initializationData = window.frontendInitializationData;
|
||||||
const isNested = (initializationData !== null && typeof initializationData === 'object');
|
const isNested = (initializationData !== null && typeof initializationData === 'object');
|
||||||
const {id, parentFrameId} = initializationData || {};
|
const {id, parentFrameId, ignoreNodes} = isNested ? initializationData : {};
|
||||||
|
|
||||||
const popup = isNested ? new PopupProxy(id, parentFrameId) : PopupProxyHost.instance.createPopup(null);
|
const popup = isNested ? new PopupProxy(id, parentFrameId) : PopupProxyHost.instance.createPopup(null);
|
||||||
const frontend = new Frontend(popup);
|
const frontend = new Frontend(popup, ignoreNodes);
|
||||||
frontend.prepare();
|
frontend.prepare();
|
||||||
return frontend;
|
return frontend;
|
||||||
}
|
}
|
||||||
@ -337,9 +338,14 @@ class Frontend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async searchTerms(textSource, focus) {
|
async searchTerms(textSource, focus) {
|
||||||
textSource.setEndOffset(this.options.scanning.length);
|
this.setTextSourceScanLength(textSource, this.options.scanning.length);
|
||||||
|
|
||||||
const {definitions, length} = await apiTermsFind(textSource.text());
|
const searchText = textSource.text();
|
||||||
|
if (searchText.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const {definitions, length} = await apiTermsFind(searchText);
|
||||||
if (definitions.length === 0) {
|
if (definitions.length === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -365,9 +371,14 @@ class Frontend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async searchKanji(textSource, focus) {
|
async searchKanji(textSource, focus) {
|
||||||
textSource.setEndOffset(1);
|
this.setTextSourceScanLength(textSource, 1);
|
||||||
|
|
||||||
const definitions = await apiKanjiFind(textSource.text());
|
const searchText = textSource.text();
|
||||||
|
if (searchText.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const definitions = await apiKanjiFind(searchText);
|
||||||
if (definitions.length === 0) {
|
if (definitions.length === 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -493,6 +504,67 @@ class Frontend {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTextSourceScanLength(textSource, length) {
|
||||||
|
textSource.setEndOffset(length);
|
||||||
|
if (this.ignoreNodes === null || !textSource.range) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
length = textSource.text().length;
|
||||||
|
while (textSource.range && length > 0) {
|
||||||
|
const nodes = Frontend.getNodesInRange(textSource.range);
|
||||||
|
if (Frontend.isValidScanningNodeList(nodes, this.ignoreNodes)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
--length;
|
||||||
|
textSource.setEndOffset(length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getNodesInRange(range) {
|
||||||
|
const end = range.endContainer;
|
||||||
|
const nodes = [];
|
||||||
|
for (let node = range.startContainer; node !== null; node = Frontend.getNextNode(node)) {
|
||||||
|
nodes.push(node);
|
||||||
|
if (node === end) { break; }
|
||||||
|
}
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
static getNextNode(node) {
|
||||||
|
let next = node.firstChild;
|
||||||
|
if (next === null) {
|
||||||
|
while (true) {
|
||||||
|
next = node.nextSibling;
|
||||||
|
if (next !== null) { break; }
|
||||||
|
|
||||||
|
next = node.parentNode;
|
||||||
|
if (node === null) { break; }
|
||||||
|
|
||||||
|
node = next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
static isValidScanningNodeList(nodeList, selector) {
|
||||||
|
for (const node of nodeList) {
|
||||||
|
if (!Frontend.isValidScanningNode(node, selector)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static isValidScanningNode(node, selector) {
|
||||||
|
for (; node !== null; node = node.parentNode) {
|
||||||
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
||||||
|
return !node.matches(selector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.yomichan_frontend = Frontend.create();
|
window.yomichan_frontend = Frontend.create();
|
||||||
|
@ -32,7 +32,9 @@ async function popupNestedInitialize(id, depth, parentFrameId) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.frontendInitializationData = {id, depth, parentFrameId};
|
const ignoreNodes = options.scanning.enableOnPopupExpressions ? [] : [ '.expression', '.expression *' ];
|
||||||
|
|
||||||
|
window.frontendInitializationData = {id, depth, parentFrameId, ignoreNodes};
|
||||||
|
|
||||||
const scriptSrcs = [
|
const scriptSrcs = [
|
||||||
'/fg/js/frontend-api-sender.js',
|
'/fg/js/frontend-api-sender.js',
|
||||||
|
Loading…
Reference in New Issue
Block a user