我有一个用户脚本,其中包含
GM_registerMenuCommand('Render LaTeX', () => {
(等等),该用户脚本的一部分仅在通过从浏览器栏中选择 ViolentMonkey 插件手动触发时运行,然后单击标有“Render LaTeX”的按钮。
我想向该用户脚本设置为匹配的网页添加一个按钮,单击该按钮即可执行上述操作。我只是不知道该怎么做。我能找到的关于按钮的唯一信息是here。
我尝试修改链接问题的第二个答案中提供的代码。我能够调整文本和位置,但我不知道如何使按钮执行我想要的操作或更改其外观以更好地适应它正在运行的网站。
// ==UserScript==
// @name TeX Button
// @namespace all
// @match https://mail.google.com/mail/*
// @version 1
// @grant none
// ==/UserScript==
(function(){
'use strict'
window.addEventListener('load', () => {
addButton('TeX', selectReadFn)
})
function addButton(text, onclick, cssObj) {
cssObj = cssObj || {position: 'absolute', bottom: '92.375%', left:'19.35%', 'z-index': 3}
let button = document.createElement('button'), btnStyle = button.style
document.body.appendChild(button)
button.innerHTML = text
button.onclick = onclick
Object.keys(cssObj).forEach(key => btnStyle[key] = cssObj[key])
return button
}
function selectReadFn() {
[...document.getElementsByClassName('MN')].filter(isRead).forEach(element => element.click())
}
function isRead(element) {
childs = element.parentElement.parentElement.parentElement.getElementsByClassName('G3')
return ![...childs].some(e => e.innerText.search(/unread/i)!==-1)
}
}())
下面是我提到的 GM_registerMenuCommand 的代码。我不知道这是否真的需要参考,但我想分享一下也没什么坏处。
// ==UserScript==
// @name LaTeX for Gmail v2.1
// @namespace Violentmonkey Scripts
// @match https://mail.google.com/mail/*
// @grant GM_registerMenuCommand
// @grant GM_addElement
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js
// @version 2.1
// @author /u/MistralMireille & /u/LoganJFisher
// @description Adds support for TeXTheWorld delimiters to Gmail, and an register menu to activate rendering using traditional LaTeX delimiters
// ==/UserScript==
GM_addElement('link', {
rel: "stylesheet",
src: "https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.css"
});
function renderLatex() {
document.querySelectorAll("#\\:1 > .nH .aHU.hx > [role='list'] > [role='listitem'][aria-expanded='true']").forEach(message => {
let subportion = message.querySelector("[data-message-id]"); // need to select a subportion of [role='listitem'] to stop rendering latex in the textinput
if(subportion) {
message = subportion;
}
message.innerHTML = message.innerHTML.replace(/\[;(.+?);\]/g, (match, p1) => {
return katex.renderToString(p1, { throwOnError: false, output: "mathml", displayMode: false });
});
message.innerHTML = message.innerHTML.replace(/\[\(;(.+?);\)\]/g, (match, p1) => {
return katex.renderToString(p1, { throwOnError: false, output: "mathml", displayMode: true });
});
});
}
GM_registerMenuCommand('Render LaTeX', () => {
document.querySelectorAll("#\\:1 > .nH .aHU.hx > [role='list'] > [role='listitem'][aria-expanded='true']").forEach(message => {
let subportion = message.querySelector("[data-message-id]"); // need to select a subportion of [role='listitem'] to stop rendering latex in the textinput
if(subportion) {
message = subportion;
}
message.innerHTML = message.innerHTML.replace(/\\\[(.+?)\\\]/g, (match, p1) => {
return katex.renderToString(p1, { throwOnError: false, output: "mathml", displayMode: true });
});
message.innerHTML = message.innerHTML.replace(/\$\$(.+?)\$\$/g, (match, p1) => {
return katex.renderToString(p1, { throwOnError: false, output: "mathml", displayMode: true });
});
//message.innerHTML = message.innerHTML.replace(/\\begin\{displaymath}(.+?)\\end\{displaymath}/g, (match, p1) => {
//return katex.renderToString(p1, { throwOnError: false, output: "mathml", displayMode: true });
//});
//message.innerHTML = message.innerHTML.replace(/\\begin\{equation}(.+?)\\end\{equation}/g, (match, p1) => {
//return katex.renderToString(p1, { throwOnError: false, output: "mathml", displayMode: true });
//});
message.innerHTML = message.innerHTML.replace(/\\\((.+?)\\\)/g, (match, p1) => {
return katex.renderToString(p1, { throwOnError: false, output: "mathml", displayMode: false });
});
message.innerHTML = message.innerHTML.replace(/\$(.+?)\$/g, (match, p1) => {
return katex.renderToString(p1, { throwOnError: false, output: "mathml", displayMode: false });
});
message.innerHTML = message.innerHTML.replace(/\\begin\{math}(.+?)\\end\{math}/g, (match, p1) => {
return katex.renderToString(p1, { throwOnError: false, output: "mathml", displayMode: false });
});
});
});
function waitForElement(queryString) {
let count = 0;
return new Promise((resolve, reject) => {
let findInterval = setInterval(() => {
let waitElement = document.querySelector(queryString);
if(waitElement) {
clearInterval(findInterval);
resolve(waitElement);
} else if(count > 20) {
clearInterval(findInterval);
reject(`Couldn't find waitElement: ${queryString}.`);
} else {
count += 1;
}
}, 100);
});
}
window.addEventListener('load', () => {
waitForElement("#\\:1 > .nH").then(messagesDiv => {
(new MutationObserver((mutationRecords, observerElement) => {
mutationRecords.forEach(mutationRecord => {
switch(mutationRecord.type) {
case "childList":
mutationRecord.addedNodes.forEach(addedNode => {
console.log(addedNode);
if(addedNode.tagName === "DIV" && addedNode.getAttribute("role") === "listitem") {
renderLatex();
}
});
break;
case "attributes":
if(mutationRecord.target.tagName === "DIV" && mutationRecord.target.getAttribute("role") === "listitem" && mutationRecord.attributeName === "aria-expanded") {
renderLatex();
}
}
});
})).observe(messagesDiv, { childList: true, subtree: true, attributes: true, attributeOldValue: true});
});
});
这是修改后的脚本,添加一个按钮和一个 menuCommand,它们都会调用
renderLatex
:
// ==UserScript==
// @name LaTeX for Gmail v2.1
// @namespace Violentmonkey Scripts
// @match https://mail.google.com/mail/*
// @grant GM_registerMenuCommand
// @grant GM_addElement
// @require https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js
// @version 2.1
// @author /u/MistralMireille & /u/LoganJFisher
// @description Adds support for TeXTheWorld delimiters to Gmail, and an register menu to activate rendering using traditional LaTeX delimiters
// @noframes
// ==/UserScript==
/* globals katex */
GM_addElement('link', {
rel: "stylesheet",
src: "https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.css"
});
function renderLatex() {
console.log('rendering latex...');
const messages = document.querySelectorAll("#\\:1 > .nH .aHU.hx > [role='list'] > [role='listitem'][aria-expanded='true']");
messages.forEach(message => {
let subportion = message.querySelector("[data-message-id]"); // need to select a subportion of [role='listitem'] to stop rendering latex in the textinput
if(subportion) {
message = subportion;
}
message.innerHTML = message.innerHTML.replace(/\[;(.+?);\]/g, (match, p1) => {
return katex.renderToString(p1, { throwOnError: false, output: "mathml", displayMode: false });
});
message.innerHTML = message.innerHTML.replace(/\[\(;(.+?);\)\]/g, (match, p1) => {
return katex.renderToString(p1, { throwOnError: false, output: "mathml", displayMode: true });
});
});
}
function waitForElement(queryString) {
let count = 0;
return new Promise((resolve, reject) => {
let findInterval = setInterval(() => {
let waitElement = document.querySelector(queryString);
if(waitElement) {
clearInterval(findInterval);
resolve(waitElement);
} else if(count > 20) {
clearInterval(findInterval);
reject(`Couldn't find waitElement: ${queryString}.`);
} else {
count += 1;
}
}, 100);
});
}
window.addEventListener('load', () => {
waitForElement("#\\:1 > .nH").then(messagesDiv => {
addButton(messagesDiv);
(new MutationObserver((mutationRecords, observerElement) => {
mutationRecords.forEach(mutationRecord => {
switch(mutationRecord.type) {
case "childList":
mutationRecord.addedNodes.forEach(addedNode => {
console.log(addedNode);
if(addedNode.tagName === "DIV" && addedNode.getAttribute("role") === "listitem") {
renderLatex();
}
});
break;
case "attributes":
if(mutationRecord.target.tagName === "DIV" && mutationRecord.target.getAttribute("role") === "listitem" && mutationRecord.attributeName === "aria-expanded") {
renderLatex();
}
}
});
})).observe(messagesDiv, { childList: true, subtree: true, attributes: true, attributeOldValue: true});
});
});
function addButton(parent) {
GM_registerMenuCommand('Render LaTeX', renderLatex);
GM_addElement(parent, 'button', {
id: 'LatexButton',
textContent: 'RENDER LATEX'
});
parent.querySelector('#LatexButton').addEventListener('click', renderLatex);
}
*您可以使用
GM_addStyle(css)
轻松为此按钮添加样式。