Copy specific parts of HTML text and send them to Anki, converting relative URLs to absolute URLs. Trigger with Ctrl+Shift+Y or via Tampermonkey menu.
当前为
// ==UserScript==
// @name Copy HTML to Anki
// @namespace http://tampermonkey.net/
// @version 3.1
// @description Copy specific parts of HTML text and send them to Anki, converting relative URLs to absolute URLs. Trigger with Ctrl+Shift+Y or via Tampermonkey menu.
// @author nabe
// @match *://*/*
// @grant GM_xmlhttpRequest
// @grant GM_registerMenuCommand
// @connect localhost
// @run-at document-end
// @license MIT
// ==/UserScript==
(function() {
'use strict';
function copyHtmlToAnki() {
// Function to convert relative URLs to absolute URLs
function makeAbsolute(url) {
return new URL(url, document.baseURI).href;
}
// Clone the document to manipulate it
let docClone = document.documentElement.cloneNode(true);
// Convert all relative URLs to absolute URLs
let elements = docClone.querySelectorAll('[src], [href]');
elements.forEach(function(element) {
if (element.hasAttribute('src')) {
element.setAttribute('src', makeAbsolute(element.getAttribute('src')));
}
if (element.hasAttribute('href')) {
element.setAttribute('href', makeAbsolute(element.getAttribute('href')));
}
});
// Extract the text content of specific parts needed
let frontElement = docClone.querySelector('.container.card');
let frontField = frontElement ? frontElement.innerHTML : '';
console.log("Front Field:", frontField);
// If frontElement is empty, capture content from .photo-question
if (!frontField) {
let photoQuestionElement = docClone.querySelector('.solution.container .photo-question');
frontField = photoQuestionElement ? photoQuestionElement.outerHTML : '';
}
console.log("Front Field:", frontField);
let questionField = docClone.querySelector('form.question h3')?.innerText.trim() || '';
console.log("Question Field:", questionField);
let optionField = Array.from(docClone.querySelectorAll('.options .option'))
.map(option => option.innerText.trim())
.filter(text => text)
.map(text => `<li>${text}</lis>`)
.join('') || '';
console.log("Option Field:", optionField);
let backField = Array.from(docClone.querySelectorAll('.options .option.correct'))
.map(option => option.innerText.trim())
.filter(text => text)
.map(text => `<li>${text}</li>`)
.join('') || '';
console.log("Answer Field:", backField);
//let extraField = docClone.querySelector('.results.container.collected .feedback-container .text')?.innerText.trim() || '';
//console.log("Additional Info Field:", extraField);
let extraElement = docClone.querySelector('.results.container.collected .feedback-container .text');
let extraField = extraElement ? extraElement.innerHTML : '';
console.log("Additional Info Field:", extraField);
// Create the note fields
let noteFields = {
"Front": frontField,
"Question": questionField,
"Options": optionField,
"Back": backField,
"Extra": extraField
};
console.log("Note fields to be sent to Anki:", noteFields);
GM_xmlhttpRequest({
method: "POST",
url: "http://localhost:8765",
data: JSON.stringify({
"action": "addNote",
"version": 6,
"params": {
"note": {
"deckName": "Default",
"modelName": "Basic Build",
"fields": noteFields,
"tags": ["newimport"]
}
}
}),
headers: {
"Content-Type": "application/json"
},
onload: function(response) {
console.log("Response from AnkiConnect:", response);
if (response.status === 200) {
console.log("Note fields sent to Anki successfully!");
} else {
console.error("Failed to send note fields to Anki.");
}
}
});
}
// Add event listener for the keyboard shortcut (Ctrl+Shift+Y)
document.addEventListener('keydown', function(event) {
if (event.ctrlKey && event.shiftKey && event.code === 'KeyY') {
copyHtmlToAnki();
}
});
// Register the menu command to Tampermonkey menu
GM_registerMenuCommand("Copy HTML to Anki", copyHtmlToAnki);
})();