16
$\begingroup$

I come across a lot of posts which lack proper hotkey formatting: any key

And I change it to: AnyKey

It would save me 11 keystrokes per <kbd></kbd> if there was a button in the post editor toolbar.

Is there a way to add it? Or is it solely managed by SE?

UX has a unique wireframe-editor button, so there seem to be differences...

$\endgroup$
  • 10
    $\begingroup$ Any reason to not have this for users without moderator rights too? $\endgroup$ – gandalf3 May 4 '14 at 2:11
  • $\begingroup$ I worry it could be abused by new users to highlight anything but shortcuts. $\endgroup$ – CoDEmanX May 4 '14 at 13:25
  • 1
    $\begingroup$ We already have that issue to some extent with the existing formatting options (mainly with backtics). We'll just have to edit these when needed. Users that stay around will eventually catch on (if not, we can just leave a comment pointing the the style guide meta). $\endgroup$ – gandalf3 Jul 16 '14 at 9:00
12
$\begingroup$

I have made a variant of the script posted by CoDEmanX with:

  • Multi-char support

  • A keyboard shortcut (CtrlY, if you think of a better available key, please comment)

  • Optional key/mousebutton icons

  • Support for reviewing/improving edits, answering own questions, etc.

  • Undo support

  • An icon

  • Automatic extra space removal

Example of usage:

enter image description here

Tested on Firefox 59.0.2 and Chromium 65.0.3325.181.
Recommended to install with Tampermonkey for chrome users.

Greasyfork
Gist


Please forgive my less-than-polished js skills..

$\endgroup$
  • $\begingroup$ Nice additions gandalf! The problem with Chrome might be the sandboxing, since we inject the user script from another source (file:/// or localhost respectively)... The shortcut is not going to work for edits, 'cause it uses an ID: $("#wmd-input").keydown(...). You might want to bind it to the class .wmd-input instead. There's a } too much at the end it seems. $\endgroup$ – CoDEmanX May 5 '14 at 3:54
  • $\begingroup$ Hm ok, that } is needed, the Firefox code highlighter just can't find the matching one of main() {? Very strange. The button works like a charm, but the shortcut doesn't. Ctrl+E places the cursor in the quick search field in Firefox, Y does nothing and Z is for undo (Z and Y are swapped on German keyboards, so I checked that too...). There's a feature missing from my script: the cursor placing after button use. With no text selected, it should insert a kbd-tag and place cursor inbetween, otherwise add tags and place cursor behind the last. Also focus() the textarea in both cases. $\endgroup$ – CoDEmanX May 5 '14 at 4:07
  • $\begingroup$ Ok, I fixed some problems and optimized the embedded icon, works for me in Firefox. Hotkey is a bit problematic it seems, doesn't work in some cases. Back-ported my cursor placement. userscripts.org/scripts/review/486617 $\endgroup$ – CoDEmanX May 5 '14 at 5:13
  • $\begingroup$ Mystery solved: the deprecated .live() worked for the hotkey, but .on() didn't - 'cause it needs to be used on document and the elements we are interested in are given as second parameter as filter! Works like charm! $\endgroup$ – CoDEmanX May 5 '14 at 5:36
  • $\begingroup$ Brilliant :) I didn't do anything, but the hotkey didn't give me any trouble.. On my FF Ctrl E does nothing, however chrome puts it in the url bar, so I guess that's a no go either way. It would be nice to have a key a bit closer to left Ctrl, but it doesn't look like there is one free. Is it worth breaking the theme of using Ctrl to use Alt+nearby-sensible-letter or something instead? $\endgroup$ – gandalf3 May 5 '14 at 8:27
  • $\begingroup$ I added extra space removal, so now extra spaces are removed automatically. I also scaled down the icon to 20px so it fits better, but as a result un-optimized it again :/ (idk how to optimize it). I tried to get the button li to go after the image button (it seems like the right category to me) by replacing appendTo with insertAfter("#wmd-image-button"), but it still goes at the end?? $\endgroup$ – gandalf3 May 5 '14 at 8:30
  • $\begingroup$ Wow, this is really nice. Great job guys. Can we agree on one final version. @gandalf3 Would recommend uploading to userscripts.org so it can be 1 click installation. $\endgroup$ – iKlsR May 5 '14 at 8:34
  • $\begingroup$ @iKlsR Okay. Still not quite done yet, still some kinks imo (plus it's currently not working on chrome, looking at that now). Working again, jquery was used before it was loaded.. $\endgroup$ – gandalf3 May 5 '14 at 8:36
  • $\begingroup$ Really didn't see the need for a dependency tho. $\endgroup$ – iKlsR May 5 '14 at 9:08
  • $\begingroup$ For me, Ctrl+Y is fine, 'cause it's the closest key to Left Ctrl on my German keyboard ;) Ctrl+E is used by both browsers, so better not overwrite default behavior. You can optimize PNGs using tinypng.com, which uses pngquant.org. insertAfter doesn't work, 'cause every button has an offset (left: 25px * n, where n is the index). To insert another button, you would have to get the previous offset and add 25px to your and all subsequent buttons. @iKlsR: It did not work on Chrome apparantly, might be caused by its sandboxing / same-origin-policy. It does in Firefox however. $\endgroup$ – CoDEmanX May 5 '14 at 14:01
5
$\begingroup$

Such a feature is not available in the formatting toolbar, you have to do it manually. I've often wanted the same feature as it is encouraged that posts be formatted correctly, especially input.

My javascript is really, really rusty but I managed to throw something together that should save a bit of time (a few seconds at least ;) when doing this.

Install

  1. Drag this line of code to your bookmarks bar, raw. (only tested on chrome and firefox).

    javascript:(function(){var txta = document.activeElement; if (txta.selectionStart == undefined) return; var chars = txta.value.split(""); chars.splice(txta.selectionStart, 0, '<kbd>'); chars.splice(txta.selectionEnd + 1, 0, '</kbd>'); txta.value = chars.join("");})()
    
  2. You can then rename the newly created bookmark to something useful.

Usage

Select the text to be wrapped in the textarea and click the bookmark.

$\endgroup$
  • $\begingroup$ Someone who has a few minutes to spare could convert this into a userscript and have it fit nicely in the formatting toolbar methinks. $\endgroup$ – iKlsR May 4 '14 at 7:12
  • $\begingroup$ Never made user scripts before, but I'll give it a go :) $\endgroup$ – gandalf3 May 4 '14 at 7:17
  • $\begingroup$ Super awesome! One question: on my OS X with Chrome, for some reason the formatting does not display in the formatting preview until I press some other key in the editing window. I'm not complaining, just wondering if this is a known issue? $\endgroup$ – Thom Blair III May 4 '14 at 12:33
  • $\begingroup$ Can we have a favicon for it too? $\endgroup$ – Thom Blair III May 4 '14 at 13:43
  • 1
    $\begingroup$ @ThomBlairIII Not really an issue per se, the input field needs some sort of trigger to update the kbd preview. CoDEmanX's script below has a little hack for getting around this and is much better. $\endgroup$ – iKlsR May 4 '14 at 15:48
5
$\begingroup$

Thanks iKlsR, I created a Greasemonkey script based on your code, which inserts a new button automatically:

// ==UserScript==
// @name        Add <kbd> Button to StackExchange Toolbar
// @namespace   http://blender.org
// @include     *.stackexchange.com/*
// @version     1
// @grant       none
// ==/UserScript==

var toolbar;
function toolbar_wait() {
    toolbar = document.getElementById('wmd-button-row');
    if (toolbar == null) {
        window.setTimeout(toolbar_wait, 500);
    } else {
        toolbar_add();
    }
}
toolbar_wait();

function insert_kbd()
{
    var txta = document.getElementById('wmd-input');
    if (txta.selectionStart == null) return;
    var chars = txta.value.split("");
    chars.splice(txta.selectionStart, 0, '<kbd>');
    chars.splice(txta.selectionEnd + 1, 0, '</kbd>');
    txta.value = chars.join("");
    toolbar_update();
}

function toolbar_add() {

    var style = document.createElement('style');
    style.setAttribute('type', 'text/css');
    style.innerHTML = '#wmd-kbd-button:hover {background-color: #deedff;}';
    document.body.appendChild(style);

    var li = document.createElement('li');
    li.onclick = insert_kbd;
    li.setAttribute('style', 'font-size: 9pt; left: 400px;');
    li.setAttribute('title', 'Keyboard Shortcut <kbd>')
    li.setAttribute('id', 'wmd-kbd-button')
    toolbar.appendChild(li);
    li.className = 'wmd-button';

    var span = document.createElement('span');
    span.innerHTML = 'kbd';
    span.setAttribute('style', 'background-image:none;');
    li.appendChild(span);
}

function toolbar_update() {

    var element = document.getElementById('wmd-input');

    var keyboardEvent = document.createEvent("KeyboardEvent");
    var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";


    keyboardEvent[initMethod](
                   "keydown", // event type : keydown, keyup, keypress
                    true, // bubbles
                    true, // cancelable
                    window, // viewArg: should be window
                    false, // ctrlKeyArg
                    false, // altKeyArg
                    false, // shiftKeyArg
                    false, // metaKeyArg
                    17, // keyCodeArg : unsigned long the virtual key code, else 0
                    0 // charCodeArgs : unsigned long the Unicode character associated with the depressed key, else 0
    );
    element.dispatchEvent(keyboardEvent);

}

Install: https://userscripts-mirror.org/scripts/show/486617

I added a hack to simulate a keydown event (ctrl) to make the live markdown preview update. Tested and working in Firefox 28.

$\endgroup$
  • $\begingroup$ Installed via Tampermonkey and working on latest version of chrome as well. Really nice. Thanks. I couldn't figure how to get the live update so I just opted to have it trigger with other user input after. ;) $\endgroup$ – iKlsR May 4 '14 at 15:40
  • $\begingroup$ I initially had it binded to wmd-input too but changed it as I thought since I was using a bookmarklet it could be useful elsewhere as well. $\endgroup$ – iKlsR May 4 '14 at 15:45
  • $\begingroup$ <kbd> isn't supported in comment anyway, I use backticks instead. Thanks for testing! Now, should I accept my own answer or yours? $\endgroup$ – CoDEmanX May 4 '14 at 16:31
  • $\begingroup$ Tested on Chrome OS X & it works GREAT if I'm creating an answer, but the kbd button is not there if I try to edit an existing answer. $\endgroup$ – Thom Blair III May 4 '14 at 16:57
  • $\begingroup$ @CoDEmanX Yours will do. I mean't elsewhere, not comments, we all use backticks ;). I need some sleep. $\endgroup$ – iKlsR May 4 '14 at 18:15
  • $\begingroup$ Alright! I updated the script to use jQuery and made it work that it also injects the button if you edit posts. Hope it still works for everyone. I couldn't find a jQuery-way of updating the markdown preview, so left that untouched for now and created a question on SO: stackoverflow.com/questions/23460904/… $\endgroup$ – CoDEmanX May 4 '14 at 20:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .