Python的文档网站有一个搜索功能。结果是到python文档中不同地方的链接列表。所有这些结果链接都具有以下形式
https://docs.python.org/3/library/__future__.html?highlight=__future__#module-__future__
突出显示查询参数将导致“未来”在目的地突出显示。我不想要这种行为。因此,我正在编写一个用户脚本来更改搜索结果页面,从每个链接中删除?highlight=__future__
等。
这本来很容易,除非结果是动态生成的。所以,我不能只是在<a>
标签下找到所有的<li>
标签,然后编辑href
,如果我尝试了,就不会找到标记,因为它们在页面加载几秒钟后才会存在。如果我在页面加载后将替换脚本延迟几秒钟,那么在此延迟过期之前,修复程序将无法工作。在长时间搜索的情况下,结果可能需要很多秒才能全部进入。应用修复的唯一好方法是编辑javascript,生成结果标记。这就是我试过的。到目前为止,这是一个脚本:
// ==UserScript==
// @name python-search-no-highlight
// @version 0.3
// @description Disables highlighting in docs.python.org's search results.
// @match http://docs.python.org/*
// @match https://docs.python.org/*
// @match http://*.docs.python.org/*
// @match https://*.docs.python.org/*
// @namespace https://greasyfork.org/users/217495-eric-toombs
// ==/UserScript==
script_text = `
Search.query = function(query) {
var i;
// stem the searchterms and add them to the correct list
var stemmer = new Stemmer();
var searchterms = [];
var excluded = [];
var hlterms = [];
var tmp = splitQuery(query);
var objectterms = [];
for (i = 0; i < tmp.length; i++) {
if (tmp[i] !== "") {
objectterms.push(tmp[i].toLowerCase());
}
if ($u.indexOf(stopwords, tmp[i].toLowerCase()) != -1 || tmp[i].match(/^\d+$/) ||
tmp[i] === "") {
// skip this "word"
continue;
}
// stem the word
var word = stemmer.stemWord(tmp[i].toLowerCase());
// prevent stemmer from cutting word smaller than two chars
if(word.length < 3 && tmp[i].length >= 3) {
word = tmp[i];
}
var toAppend;
// select the correct list
if (word[0] == '-') {
toAppend = excluded;
word = word.substr(1);
}
else {
toAppend = searchterms;
hlterms.push(tmp[i].toLowerCase());
}
// only add if not already in the list
if (!$u.contains(toAppend, word))
toAppend.push(word);
}
// THIS IS THE LINE I MODIFIED!
var highlightstring = '';
// console.debug('SEARCH: searching for:');
// console.info('required: ', searchterms);
// console.info('excluded: ', excluded);
// prepare search
var terms = Search._index.terms;
var titleterms = Search._index.titleterms;
// array of [filename, title, anchor, descr, score]
var results = [];
$('#search-progress').empty();
// lookup as object
for (i = 0; i < objectterms.length; i++) {
var others = [].concat(objectterms.slice(0, i),
objectterms.slice(i+1, objectterms.length));
results = results.concat(Search.performObjectSearch(objectterms[i], others));
}
// lookup as search terms in fulltext
results = results.concat(Search.performTermsSearch(searchterms, excluded, terms, titleterms));
// let the scorer override scores with a custom scoring function
if (Scorer.score) {
for (i = 0; i < results.length; i++)
results[i][4] = Scorer.score(results[i]);
}
// now sort the results by score (in opposite order of appearance, since the
// display function below uses pop() to retrieve items) and then
// alphabetically
results.sort(function(a, b) {
var left = a[4];
var right = b[4];
if (left > right) {
return 1;
} else if (left < right) {
return -1;
} else {
// same score: sort alphabetically
left = a[1].toLowerCase();
right = b[1].toLowerCase();
return (left > right) ? -1 : ((left < right) ? 1 : 0);
}
});
// for debugging
//Search.lastresults = results.slice(); // a copy
//console.info('search results:', Search.lastresults);
// print the results
var resultCount = results.length;
function displayNextItem() {
// results left, load the summary and display it
if (results.length) {
var item = results.pop();
var listItem = $('<li style="display:none"></li>');
var requestUrl = "";
if (DOCUMENTATION_OPTIONS.BUILDER === 'dirhtml') {
// dirhtml builder
var dirname = item[0] + '/';
if (dirname.match(/\/index\/$/)) {
dirname = dirname.substring(0, dirname.length-6);
} else if (dirname == 'index/') {
dirname = '';
}
requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + dirname;
} else {
// normal html builders
requestUrl = DOCUMENTATION_OPTIONS.URL_ROOT + item[0] + DOCUMENTATION_OPTIONS.FILE_SUFFIX;
}
listItem.append($('<a/>').attr('href',
requestUrl +
highlightstring + item[2]).html(item[1]));
if (item[3]) {
listItem.append($('<span> (' + item[3] + ')</span>'));
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
} else if (DOCUMENTATION_OPTIONS.HAS_SOURCE) {
$.ajax({url: requestUrl,
dataType: "text",
complete: function(jqxhr, textstatus) {
var data = jqxhr.responseText;
if (data !== '' && data !== undefined) {
listItem.append(Search.makeSearchSummary(data, searchterms, hlterms));
}
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
}});
} else {
// no source available, just display title
Search.output.append(listItem);
listItem.slideDown(5, function() {
displayNextItem();
});
}
}
// search finished, update title and status message
else {
Search.stopPulse();
Search.title.text(_('Search Results'));
if (!resultCount)
Search.status.text(_('Your search did not match any documents. Please make sure that all words are spelled correctly and that you\'ve selected enough categories.'));
else
Search.status.text(_('Search finished, found %s page(s) matching the search query.').replace('%s', resultCount));
Search.status.fadeIn(500);
}
}
displayNextItem();
};
`;
script = document.createElement('script');
script.type = 'text/javascript';
script.text = script_text;
document.getElementsByTagName('head')[0].appendChild(script);
此脚本因错误而失败
Uncaught SyntaxError: missing ) after argument list search.html:106:60
当我点击search.html:106:60
时,它会引导我进入静态页面,所以我的更改当然不会出现。
当我复制javascript时,我试图将它直接注入并粘贴到控制台中,它可以正常工作。所以,我知道甚至没有语法错误。当我用一个简单得多的测试函数替换函数时,如
Search.query = function() {
// This is a comment.
console.log('</test>');
};
效果很好。到底是怎么回事?
发布于 2021-02-15 23:25:33
我终于想出来了。我认为javascript回勾文字并没有专门处理反斜杠,但事实证明,它们确实如此。我只需要避免反斜杠在反勾文字,这是有效的!因此,这是一个教训:每当将javascript存储在回勾文字中时,总是要避开反斜杠。哦,还有美元的标志和后排。
https://stackoverflow.com/questions/66216767
复制相似问题