您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds a button to Summernote that inserts HTML snippets required by Marketplace themes.
当前为
// ==UserScript== // @name Kanka Marketplace Plugin HTML Inserter for Summernote // @namespace http://tampermonkey.net/ // @version 3 // @description Adds a button to Summernote that inserts HTML snippets required by Marketplace themes. // @author Salvatos // @match https://kanka.io/* // @icon https://www.google.com/s2/favicons?domain=kanka.io // @grant none // @run-at document-end // ==/UserScript== /* This one works for a single button async function fixCodeEditor() { // Wait for Summernote to finish initializing while(!document.querySelector(".note-codable")) { console.log("Waiting for Summernote."); await new Promise(r => setTimeout(r, 100)); } console.log("Ready."); const toolbar = document.getElementsByClassName('note-toolbar')[0]; var customButton = ` <div class="note-btn-group btn-group note-extensions custom-summernote-button"> <button type="button" class="note-btn btn btn-default btn-sm note-codeview-keep" tabindex="-1" title="Custom button"> <i class="fas fa-file-import" aria-hidden="true"></i> </button> </div>`; toolbar.insertAdjacentHTML("beforeend", customButton); const htmlSnippet = "<p>test input</p>"; // Add input event to code editor customButton = document.getElementsByClassName('custom-summernote-button')[0]; customButton.addEventListener('click', ()=>{ // Copy code editor’s value to Summernote’s hidden textarea in case of immediate saving document.getElementById('entry').value += htmlSnippet; // Insert HTML in editors document.getElementsByClassName('note-editable')[0].insertAdjacentHTML("beforeend", htmlSnippet); document.getElementsByClassName('note-codable')[0].value += htmlSnippet; }); }*/ // Let’s try a dropdown async function insertCustomTool() { // Wait for Summernote to finish initializing while(!document.querySelector(".note-codable")) { console.log("Waiting for Summernote."); await new Promise(r => setTimeout(r, 100)); } console.log("Ready."); // Prepare to check for supported themes in the campaign var rootFlags = getComputedStyle(document.documentElement); // Define our supported code snippets let snippets = []; // Build list items for our supported code snippets let themes = []; // Figure Box and Floats by Ornstein if (rootFlags.getPropertyValue('--summernote-insert-figure-box') || 1 === 1) { // Temporary bypass for initial release snippets.push('<div class="figure">Insert image and caption here</div>'); snippets.push('<div class="figure r clear">Insert image and caption here</div>'); themes.push('<li aria-label="Figure Box and Floats (no float)"><a href="#">Figure Box (no float)</a></li>'); themes.push('<li aria-label="Figure Box and Floats (float right + clear)"><a href="#">Figure Box (float right + clear)</a></li>'); } // Responsive Image Gallery by Salvatos if (rootFlags.getPropertyValue('--summernote-insert-autogallery') || 1 === 1) { // Temporary bypass for initial release snippets.push('<div class="autogallery">Insert gallery images here</div>'); themes.push('<li aria-label="Responsive Image Gallery"><a href="#">Responsive Image Gallery</a></li>'); } // Simple Tooltips by KeepOnScrollin if (rootFlags.getPropertyValue('--summernote-insert-simple-tooltip') || 1 === 1) { // Temporary bypass for initial release snippets.push('<span class="simple-tooltip">Tooltip trigger<span class="simple-tooltip-text top">Tooltip content</span></span>'); themes.push('<li aria-label="Simple Tooltip (top)"><a href="#">Simple Tooltip (top)</a></li>'); } // Tip Box by Critter if (rootFlags.getPropertyValue('--summernote-insert-tip-box') || 1 === 1) { // Temporary bypass for initial release snippets.push('<div class="tipbox-small">Small Tip Box text.</div>'); snippets.push('<div class="tipbox-big">Big Tip Box text.</div>'); themes.push('<li aria-label="Tip Box (small)"><a href="#">Tip Box (small)</a></li>'); themes.push('<li aria-label="Tip Box (big)"><a href="#">Tip Box (big)</a></li>'); } var themeList = themes.join(""); // Locate toolbar and insert our dropdown button const toolbar = document.getElementsByClassName('note-toolbar')[0]; var customButton = ` <div class="note-btn-group btn-group note-style"> <div class="note-btn-group btn-group"> <button type="button" class="note-btn btn btn-default btn-sm dropdown-toggle note-codeview-keep" tabindex="-1" data-toggle="dropdown" title="Marketplace theme HTML snippets" aria-expanded="false"> <i class="fas fa-puzzle-piece"></i> <span class="note-icon-caret"></span> </button> <ul class="note-dropdown-menu dropdown-menu dropdown-snippets" aria-label="Marketplace theme HTML snippets"> ` + themeList + ` </ul> </div> </div>`; toolbar.insertAdjacentHTML("beforeend", customButton); // Grab our completed dropdown const dropdown = document.getElementsByClassName('dropdown-snippets')[0]; // Make sure we have at least one supported theme enabled if (dropdown.children[0]) { // Add click events to editor for (let i = 0; i < dropdown.children.length; i++) { var currentButton = dropdown.children[i]; currentButton.addEventListener('click', ()=>{ // Add HTML to Summernote’s hidden textarea in case of immediate saving document.getElementById('entry').value += snippets[i]; // Insert HTML in editors document.getElementsByClassName('note-editable')[0].insertAdjacentHTML("beforeend", snippets[i]); document.getElementsByClassName('note-codable')[0].value += '\n' + snippets[i]; // TODO: Would be nice to scroll the editor to the end after inserting }); } } else { dropdown.insertAdjacentHTML("beforeend", "<li><a href='#'><em>No supported theme found</em></a></li>"); } } // Run it if (document.getElementById('entity-form')) { // TODO: this ID is currently missing from the campaign edit form and specific entry block editor; asking Jay for a fix insertCustomTool(); } /* * TODO: A different script (or button + function) should be used for themes that only need to add classes to any element, such as Redacted Text, Context-Aware Classes and .boxquote. * Those would only work in the visual editor since there I can target those elements as objects and manipulate their classes. * The question is how we would identify the element that corresponds to the cursor position. */ /* * TODO: We could try to insert at current position but that requires a decent chunk of additional code and jQuery * Plus we’d have to figure out which editor is open $('input[type=button]').on('click', function() { var cursorPos = $('#text').prop('selectionStart'); var v = $('#text').val(); var textBefore = v.substring(0, cursorPos); var textAfter = v.substring(cursorPos, v.length); $('#text').val(textBefore + $(this).val() + textAfter); }); */
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址