您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Universal syntax highlighting
// ==UserScript== // @name Syntaxify // @description Universal syntax highlighting // @namespace http://rob-bolton.co.uk // @version 1.4 // @include http* // @grant GM_addStyle // @grant GM_getResourceText // @require http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.6/highlight.min.js // @resource highlightJsCss https://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.6/styles/monokai.min.css // ==/UserScript== // var tagsToSearch = ["pre", "code"]; GM_addStyle(GM_getResourceText("highlightJsCss")); var codeBlocks = {}; var itemCounter = 0; var selectedItem; function isCodeBlock(node) { if(node) { var tagname = node.tagName.toLowerCase(); for(var i=0; i<tagsToSearch.length; i++) { if(tagname == tagsToSearch[i]) { return true; } } } return false; } function wrapSelection() { var selection = window.getSelection(); if(selection.rangeCount > 0) { var range = selection.getRangeAt(0); var parent = range.startContainer.parentNode; if(!isCodeBlock(parent)) { var container = document.createElement("code"); var containerData = addBlock(container); containerData.originalFragment = range.cloneContents(); container.setAttribute("contextmenu", "SyntaxifyPreUnwrapMenu"); range.surroundContents(container); } } } function unwrap() { if(selectedItem) { var node = selectedItem; var nodeData = codeBlocks[node.id]; var parent = node.parentNode; parent.insertBefore(nodeData.originalFragment, node); parent.removeChild(node); } } function addBlock(node) { if(!node.id) { node.id = "SyntaxifyBlock" + itemCounter++; } codeBlocks[node.id] = { "node": node, "highlighted": false, "originalNode": node.cloneNode(true) } return codeBlocks[node.id]; } function revert(nodeData) { var parent = nodeData.node.parentNode; parent.insertBefore(nodeData.originalNode, nodeData.node); parent.removeChild(nodeData.node); nodeData.node = nodeData.originalNode; nodeData.highlighted = false; if(nodeData.originalFragment) { nodeData.node.setAttribute("contextMenu", "SyntaxifyPreUnwrapMenu"); } else { nodeData.node.setAttribute("contextMenu", "SyntaxifyPreMenu"); } } function highlight() { var node = selectedItem; if(node) { if(!codeBlocks[node.id]) { addBlock(node); } var nodeData = codeBlocks[node.id]; if(nodeData.highlighted === false) { nodeData.originalNode = node.cloneNode(true); try { if(nodeData.lang) { node.className = (node.className || "") + " lang-" + nodeData.lang; } hljs.highlightBlock(node); } catch(e) { console.err(e); revert(nodeData); alert(e); return; } nodeData.highlighted = true; node.setAttribute("contextMenu", "SyntaxifyPostMenu"); } } } function highlightAs() { var node = selectedItem; if(node) { if(!codeBlocks[node.id]) { addBlock(node); } var lang = prompt("Language:"); if(lang) { codeBlocks[node.id].lang = lang; highlight(); } else { codeBlocks[node.id].lang = null; } } } function unHighlight() { var node = selectedItem; if(node) { if(!codeBlocks[node.id]) { addBlock(node); } var nodeData = codeBlocks[node.id]; if(nodeData.highlighted === true) { revert(nodeData); } } } var syntaxableElements = []; for(var i=0; i<tagsToSearch.length; i++) { var tagsFound = document.getElementsByTagName(tagsToSearch[i]); for(var j=0; j<tagsFound.length; j++) { syntaxableElements.push(tagsFound.item(j)); } } if(syntaxableElements) { for(var i=0; i<(syntaxableElements.length || 0); i++) { syntaxableElements[i].setAttribute("contextmenu", "SyntaxifyPreMenu"); } } var body = document.body; var bodyMenu; var bodyMenuId = body.getAttribute("contextmenu"); if(!bodyMenuId) { bodyMenu = document.createElement("menu"); bodyMenu.setAttribute("type", "context"); bodyMenu.setAttribute("id", "SyntaxifyMenuMain"); } else { bodyMenu = document.getElementById(bodyMenuId); } var wrapItem = document.createElement("menuitem"); wrapItem.setAttribute("label", "Syntaxify - Wrap with <code>"); wrapItem.addEventListener("click", wrapSelection, false); bodyMenu.appendChild(wrapItem); body.appendChild(bodyMenu); body.setAttribute("contextmenu", bodyMenu.getAttribute("id")); // Menu for un-highlighted code blocks var syntaxPreMenu = document.createElement("menu"); syntaxPreMenu.setAttribute("type", "context"); syntaxPreMenu.setAttribute("id", "SyntaxifyPreMenu"); var syntaxPreMenuHighlightItem = document.createElement("menuitem"); syntaxPreMenuHighlightItem.setAttribute("label", "Syntaxify - Highlight"); syntaxPreMenuHighlightItem.addEventListener("click", highlight, false); syntaxPreMenu.appendChild(syntaxPreMenuHighlightItem); var syntaxPreMenuHighlightAsItem = document.createElement("menuitem"); syntaxPreMenuHighlightAsItem.setAttribute("label", "Syntaxify - Highlight as..."); syntaxPreMenuHighlightAsItem.addEventListener("click", highlightAs, false); syntaxPreMenu.appendChild(syntaxPreMenuHighlightAsItem); body.appendChild(syntaxPreMenu); // Menu for un-highlighted ad-hoc code blocks created via the context-menu's wrap entry var syntaxPreUnwrapMenu = syntaxPreMenu.cloneNode(false); syntaxPreUnwrapMenu.setAttribute("id", "SyntaxifyPreUnwrapMenu"); var syntaxPreUnwrapMenuUnwrapItem = document.createElement("menuitem"); syntaxPreUnwrapMenuUnwrapItem.setAttribute("label", "Syntaxify - Unwrap"); syntaxPreUnwrapMenuUnwrapItem.addEventListener("click", unwrap, false); var syntaxPreUnwrapMenuHighlightItem = syntaxPreMenuHighlightItem.cloneNode(false); var syntaxPreUnwrapMenuHighlightAsItem = syntaxPreMenuHighlightAsItem.cloneNode(false); syntaxPreUnwrapMenuHighlightItem.addEventListener("click", highlight, false); syntaxPreUnwrapMenuHighlightAsItem.addEventListener("click", highlightAs, false); syntaxPreUnwrapMenu.appendChild(syntaxPreUnwrapMenuHighlightItem); syntaxPreUnwrapMenu.appendChild(syntaxPreUnwrapMenuHighlightAsItem); syntaxPreUnwrapMenu.appendChild(syntaxPreUnwrapMenuUnwrapItem); body.appendChild(syntaxPreUnwrapMenu); var syntaxPostMenu = document.createElement("menu"); syntaxPostMenu.setAttribute("type", "context"); syntaxPostMenu.setAttribute("id", "SyntaxifyPostMenu"); var syntaxPostMenuUnHighlightItem = document.createElement("menuitem"); syntaxPostMenuUnHighlightItem.setAttribute("label", "Syntaxify - UnHighlight"); syntaxPostMenuUnHighlightItem.addEventListener("click", unHighlight, false); syntaxPostMenu.appendChild(syntaxPostMenuUnHighlightItem); body.appendChild(syntaxPostMenu); document.addEventListener("mousedown", function(event) { if(event.button == 2) { var node = event.target; while(node.parentNode && !isCodeBlock(node)) { node = node.parentNode; } if(isCodeBlock(node)) { selectedItem = node; } else { selectedItem = null; } } });