[Challenge] DIC Chrome Extension: Editor Hotkeys

  • (2 Pages)
  • +
  • 1
  • 2

29 Replies - 5548 Views - Last Post: 11 September 2013 - 12:09 PM

#1 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4469
  • View blog
  • Posts: 7,780
  • Joined: 08-June 10

[Challenge] DIC Chrome Extension: Editor Hotkeys

Post icon  Posted 27 August 2013 - 08:47 AM

*
POPULAR

Hey guys,

I recently wrote a chrome extension that lets us use keyboard shortcuts in the DIC editor. I understand that the editor already has some shortcuts that work in Firefox. However, I've tested it in a clean Chrome and nothing happens. So, extension time!

https://github.com/c...ditor-Shortcuts

It still needs a lot of work. Work items so far:

  • works only on the main reply box. Not in edit boxes or topic creation boxes. Needs to be extended to all supported textareas. This might be hard, since some of these textareas are created dynamically. I'm confident we can make it work though.
  • Configuration. I'd like to have this use a config page that stores your shortcut preferences serialized to localStorage
  • Highlight and surround. There's already a function that checks if there is selected text (because ctrl-c shouldn't be blocked if it is) so we could modify the behavior to wrap selected text instead of inserting at cursor.
  • anything you can come up with that makes sense


But anyway, here it is, if you want to use it or help me work on it. I'm going to feature this topic and mark it a challenge.

Go ahead and fork it on github. If you're interested in doing a lot of work on the extension, I could add you as a contributor so you could merge pull requests too.

If you don't like using github, you could post your changes here, but that's a lot more for me than if you submit a pull request.

Discuss any changes or ideas in this thread. Let's make something really useful!



I also have the DIC-Chrome extension that auto checks your subscriptions every five minutes too, in case you're interested.

https://github.com/c...land/DIC-Chrome

If you want to use it or you'd like to assist with this project, feel free. Just let me know here (or on github). If this gains any traction, we may merge the two projects into one extension.



If you need to know how to load extensions that are under development, you can take a look here:

http://developer.chr...d.html#unpacked

Thanks! I'd also appreciate feedback.

Is This A Good Question/Topic? 8
  • +

Replies To: [Challenge] DIC Chrome Extension: Editor Hotkeys

#2 laytonsdad  Icon User is offline

  • Cheese and Sprinkles
  • member icon

Reputation: 436
  • View blog
  • Posts: 1,851
  • Joined: 30-April 10

Re: [Challenge] DIC Chrome Extension: Editor Hotkeys

Posted 27 August 2013 - 09:49 AM

I went ahead and pinned this topic for a while to keep it on the top.
Was This Post Helpful? 0
  • +
  • -

#3 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1391
  • View blog
  • Posts: 3,078
  • Joined: 05-April 11

Re: [Challenge] DIC Chrome Extension: Editor Hotkeys

Posted 27 August 2013 - 12:51 PM

I love the extension idea! There are so many interesting possibilities..!
I would love to see the extension add these couple of things:
Wrap code tags when it recognized code that doesn't use them
Select an url such as http://foo.com and let the extension create an url tag linking to the site
Allow the user to choose their own key combinations to use
Hover over a member's name with the mouse and do the member-tag combination

I tried fooling around with the extension for a bit
Chrome extensions are new to me, and I have already run into the first couple of Oopsies haha

How do you debug your extensions? I managed to debug using the "Sources" tab in the inspector, but is that the easiest way?
Somehow I managed to screw things up when trying to add my own files to the project haha
I kept on getting the following error: Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension (And something with the minified JQuery file)
Though the error went away when I kept it in one file....... So that will do :D

I'm willing to learn a bit more javascript, and I hope projects like these can help me on the way
I've never worked on a big javascript project, and I'm not familiar with the common patterns being used, but hopefully my code is not one big horror or you're more than welcome to give me advice
Namespaces are new to me, and I wanted to try it out, so this is my attempt ^^

I just fool around a bit, add a couple of objects and see what happens
Managed to make it wrap the text in tags at least!
But I want the extension to be even more flexible than what I have currently come up with :)
var dic = (function() {
	
	function namespace(newNS, parentNS) {
		parentNS = parentNS || dic;
		
		var namespaces = newNS.split(".");
		
		for (var i=0; i<namespaces.length; i++) {
			var namespace = namespaces[i];
			parentNS[namespace] = parentNS[namespace] || {};
			parentNS = parentNS[namespace];
		}
		
		return parentNS;
	}
	
	return {
		namespace: namespace,
		editor: null
	}
})();

var editorsNS = dic.namespace("editors");

editorsNS.Editor = function(textareaElement) {
	var cursor = new editorsNS.Cursor(textareaElement);
	
	this.getCursor = function() {
		return cursor;
	}
	
	this.getTextArea = function() {
		return textareaElement;
	}
}

editorsNS.Cursor = function(textareaElement) {

	this.move = function(start, end) {
		textareaElement.selectionstart = start;
		textareaElement.selectionend = end;
	}

	this.hasSelection = function() {
		return textareaElement.selectionstart !== textareaElement.selectionend;
	}
	
	//Returns JSON { start, end }
	this.getSelectionRange = function() {
		return { start: textareaElement.selectionstart, end: textareaElement.selectionend };
	}
	
	//If there is a selection, the cursor position will be at the selection start
	this.getCursorPosition = function() {
		return textareaElement.selectionstart;
	}
}

var bindingsNS = dic.namespace("editors.bindings");

bindingsNS.EditorBinding = function(tag, endTag) {
	
	this.execute = function(e) {
		e.preventDefault();
		e.stopPropagation();
	
		var cursor = dic.editor.getCursor();
		var textarea = dic.editor.getTextArea();
		
		if (cursor.hasSelection())
			wrapInTag(cursor.getSelectionRange(), textarea);
		else
			addTags(cursor, textarea);
			
		return false;
	}
	
	function addTag(textarea, position) {
		textarea.value = insertIntoString(position, textarea.value, tag);
	}
	
	function addEndTag(textarea, position) {
		textarea.value = insertIntoString(position, textarea.value, endTag);
	}
	
	//Adds start and end tag plus moves cursor in between the tags
	function addTags(cursor, textarea) {
		var position = cursor.getCursorPosition();
		addTag(textarea, position);
		addEndTag(textarea, position + tag.length);
		cursor.move(position + tag.length, position + tag.length);
	}
	
	function wrapInTag(selectionRange, textarea) {
		addTag(textarea, selectionRange.start);
		addEndTag(textarea, selectionRange.end + tag.length);
	}
	
	function insertIntoString(index, string, value) {
		return string.substring(0, index) + value + string.substring(index, string.length);
	}
}

$(document).ready(function() {
	var textareaElement = $tb[0];
	dic.editor = new editorsNS.Editor(textareaElement);
	
	// Bindings
	var bindingsNS = dic.namespace("editors.bindings");
	$tb.bind('keydown', 'Ctrl+i', new bindingsNS.EditorBinding("[ai]", "[a/i]").execute);
	$tb.bind('keydown', 'Ctrl+u', new bindingsNS.EditorBinding("[au]", "[a/u]").execute);
	$tb.bind('keydown', 'Ctrl+k', new bindingsNS.EditorBinding("[ail]", "[a/il]").execute);
	$tb.bind('keydown', 'Ctrl+q', new bindingsNS.EditorBinding("[aquote]", "[a/quote]").execute);
	$tb.bind('keydown', 'Ctrl+l', new bindingsNS.EditorBinding("[aurl=]", "[a/url]").execute);
	$tb.bind('keydown', 'Ctrl+p', new bindingsNS.EditorBinding("[aimg]", "[a/img]").execute);
	$tb.bind('keydown', 'Ctrl+c', new bindingsNS.EditorBinding("[acode]", "[a/code]").execute);
});





Edit: had to add an 'a' to all the tags since the editor was being funny :D

This post has been edited by CasiOo: 27 August 2013 - 12:53 PM

Was This Post Helpful? 0
  • +
  • -

#4 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4469
  • View blog
  • Posts: 7,780
  • Joined: 08-June 10

Re: [Challenge] DIC Chrome Extension: Editor Hotkeys

Posted 27 August 2013 - 01:04 PM

Quote

Resources must be listed in the web_accessible_resources manifest key in order to be loaded by pages outside the extension (And something with the minified JQuery file)


I had that problem too. It's looking for a "map" file which apparently lets you debug minified JS. So I'm going to push a commit where I replace the minified JS with the full version. Other than that, you need to edit the manifest.json to include any files you want loaded, in the order in which they should load.

I'm going to look over your architecture that you posted here because I'm interested. I was also working on refactoring. I ran into an issue which I believe must be a closure issue. I tried to make each binding in a loop instead of manually (which would help if we made these shortcuts configurable) but when I tested they all outputted the same text. So at the moment I'm working on making an object that represents a key binding, then having all hotkeys trigger one function, then using that function to determine the text to insert.

Edit. I like your architecture. I'm going to start with that. I'm probably going to push a commit later today that should map to your style much more closely.

In case anyone can't tell, I'm not a JS programmer by trade. Getting there, but not there yet. But Chrome extensions are a really fun way to learn.
Was This Post Helpful? 0
  • +
  • -

#5 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4469
  • View blog
  • Posts: 7,780
  • Joined: 08-June 10

Re: [Challenge] DIC Chrome Extension: Editor Hotkeys

Posted 27 August 2013 - 03:24 PM

Alright, I've pushed an update to github. It looks and behaves much more like yours. And it's much more refactorable when we decide to add settings and such.

I really think I might merge the two projects so it's just one big DIC addon instead of two. But otherwise, I really do like having people who actually know JS working on this, because it gives me so many ideas that I never had.

Anyway, I realized I didn't answer one of your questions. Yes, debugging a chrome extension is a real pain in the butt. I do basically what you do: F12->Sources. But once you get in there, chrome has some of the better JS debugging tools.

And again, if anyone is interested in it, send me your github username and I can add you as a contributor. I'd ask that you send me one good pull request before I make you a contributor so I can know you're committed to the project.

Thanks!
Was This Post Helpful? 0
  • +
  • -

#6 andrewsw  Icon User is offline

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3369
  • View blog
  • Posts: 11,410
  • Joined: 12-December 12

Re: [Challenge] DIC Chrome Extension: Editor Hotkeys

Posted 28 August 2013 - 02:05 PM

I haven't had a chance to look into this in any detail as yet, but I notice localStorage is mentioned. Is it possible, do you think, to create an AutoCorrect feature similar to MS Office?

I don't mean like what used to be called AutoText - template-text; I wouldn't be in favour of this approach as it would lead to a lot of repetition, and laziness, by the poster. What I mean is to create ad-hoc shortcuts for short phrases that would be stored in localStorage, or perhaps a cookie.

I apologise, though, that I haven't investigated this myself (yet) it was just an idea that occurred to me. There's probably already an app for this :)
Was This Post Helpful? 0
  • +
  • -

#7 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1391
  • View blog
  • Posts: 3,078
  • Joined: 05-April 11

Re: [Challenge] DIC Chrome Extension: Editor Hotkeys

Posted 28 August 2013 - 02:39 PM

I'll setup Github one of the following days. I should have enough spare time to be working on the project if I'm allowed to haha
Good to see other coders interested in the project. I wouldn't mind if any of the javascript experts would join the project, I hope to learn a thing or ten :)

I've been thinking about how you would design the program to let you have different implementations for the tags. For example the url tag might need to do something else than the code tag when the combination is pressed. Sure there must be a simple solution where you can still reuse the private functions of the EditorBinding object, but so far I haven't come up with a good one ^^
The localstorage part is very interesting. Seems very easy to work with
Loading and saving settings could be as simple as
dic.config = {
	defaults: {
		name: 'Default name',
		foo: 'Default foo'
	},
	settings: {
		name: 'Setting name'
	},
	save: function() {
		if (localStorage) localStorage.settings = JSON.stringify(this.settings);
	},
	reload: function() {
		if (localStorage && localStorage.settings) this.settings = JSON.parse(localStorage.settings);
		//Merge the values of settings into defaults and place the result in settings
		this.settings = $.extend({}, this.defaults, this.settings);
	}
};

dic.config.reload();

alert(dic.config.settings.name);


Merging the defaults with the saved settings would allow you to add new properties in future releases


With Chrome extensions it should be okay to split the JS code into different files without merging them, correct?
Since the files are loaded from the local system, there should be no problem having many JS files in the project, or am I missing something?
Was This Post Helpful? 0
  • +
  • -

#8 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4469
  • View blog
  • Posts: 7,780
  • Joined: 08-June 10

Re: [Challenge] DIC Chrome Extension: Editor Hotkeys

Posted 28 August 2013 - 02:51 PM

Quote

With Chrome extensions it should be okay to split the JS code into different files without merging them, correct?


Absolutely. Split them as much as you want. They'll be loaded in the order they're listed in the manifest.json which is in the project root.

My idea for different tag behaviors was to include a token in the string that could be replaced with clipboard text. For instance, usually when I'm ready to post a URL, I already have it copied. I'd like to be able to press CTRL-L and have this inserted:

[url=<clipboardText>]|[/url]


(The pipe character represents where the cursor would go).

So I was thinking about adding another parameter to the EditorBinding, or perhaps just choosing a default sequence of text, and allowing users to make their tags look like this:

[url={0}]


That could be implemented by adding a background script (which can have permission to the clipboard) and passing messages back and forth (though then you start getting into callback hell, but hey, it's Javascript).

And the {0} would be replaced with clipboard contents. Beyond that, I think that's all the behaviors. The member tag could be handled by setting startTag = ''.  That works for inserting and wrapping.
If you check my latest commit, you see I'm letting the EditorBinding object handle binding itself to the event, so each one is fairly self contained, and can be created from three strings. So we could easily serialize the strings into localStorage, basically like you've already done.

There's also the concept of a "settings page" in extensions. So we could use the settings page for a place for users to add/remove/customize their own shortcuts.

Quote

What I mean is to create ad-hoc shortcuts for short phrases that would be stored in localStorage, or perhaps a cookie.


Are you saying that it should be like how Apple's iphone keyboard works? Register a sequence of text that gets expanded into something larger? Like, I had mine set to expand 'addr' into my full address. If not, I guess I don't understand. But I'm sure its doable.
Was This Post Helpful? 0
  • +
  • -

#9 CasiOo  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1391
  • View blog
  • Posts: 3,078
  • Joined: 05-April 11

Re: [Challenge] DIC Chrome Extension: Editor Hotkeys

Posted 28 August 2013 - 03:28 PM

Oh setting up Github was really easy haha. Will take a look at how to do the different kind of requests :)
I like the changes you have made. The idea of letting the user choose how tags should be inserted is quite clever
The settings page would be the ideal way of customizing your own shortcuts indeed
What could be the pitfalls of using binding masks (if that's what you call them) ?

This post has been edited by CasiOo: 28 August 2013 - 03:29 PM

Was This Post Helpful? 0
  • +
  • -

#10 andrewsw  Icon User is offline

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3369
  • View blog
  • Posts: 11,410
  • Joined: 12-December 12

Re: [Challenge] DIC Chrome Extension: Editor Hotkeys

Posted 28 August 2013 - 03:28 PM

@Curtis I don't have an iPhone - recently bought a Samsung, but no idea how it works :dontgetit: :)

In Word we can create an abbreviation (an auto-correct entry) such as 'asap' and have it expand automatically to 'as soon as possible' - on pressing Space or Enter, etc.. I was guessing this kind of keyboard-event reading wasn't possible with GC extensions, or perhaps not desirable? I assumed it would have to be done by assigning a keyboard-shortcut to insert the phrase at the cursor position. But it would require some means of defining the shortcut, and the text to insert, and saving this information into our localStorage.

I dunno though, maybe it's not that useful. Ignore me :)
Was This Post Helpful? 0
  • +
  • -

#11 Curtis Rutland  Icon User is online

  • (╯□)╯︵ (~ .o.)~
  • member icon


Reputation: 4469
  • View blog
  • Posts: 7,780
  • Joined: 08-June 10

Re: [Challenge] DIC Chrome Extension: Editor Hotkeys

Posted 28 August 2013 - 03:33 PM

That would be completely possible. We'd just need to regex match the textbox contents for your shortcuts when you hit a certain key combo, then replace the match. I'm imagining something like this:

user types 'asap' then presses Ctrl-Space. That particular instance of 'asap' is expanded to "As Soon As Possible" or whatever the user has predefined.

Yes, we can try that. How about creating an issue for it on the github project page?

Edit: upon re-reading, you may want it more automatic than ctrl-space, perhaps space or enter. We could do that too. We'd just hook the textarea's keypress event to do it and filter for the keys you want to handle expanding macros. Speaking of, that's what we'd call the feature: macros.

Quote

Ignore me :)


Posted Image
Was This Post Helpful? 0
  • +
  • -

#12 andrewsw  Icon User is offline

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3369
  • View blog
  • Posts: 11,410
  • Joined: 12-December 12

Re: [Challenge] DIC Chrome Extension: Editor Hotkeys

Posted 28 August 2013 - 04:09 PM

Nice picture :)

It could use numeric keyboard-shortcuts such as Ctrl-Alt-0 through 9 (if these are available?) so that the feature is not over-used. Having selected some text such as:

Quote

Please use CODE tags you plum..

pressing the key-combination would assign the text as the macro (the speed-dial! or speed-insert might be a better name, macro might suggest that is more powerful than it is); if there is no selected text then it inserts the text.

And so to bed..
Was This Post Helpful? 0
  • +
  • -

#13 AdamSpeight2008  Icon User is offline

  • MrCupOfT
  • member icon


Reputation: 2257
  • View blog
  • Posts: 9,445
  • Joined: 29-May 08

Re: [Challenge] DIC Chrome Extension: Editor Hotkeys

Posted 28 August 2013 - 05:38 PM

View PostCasiOo, on 27 August 2013 - 08:51 PM, said:

I love the extension idea! There are so many interesting possibilities..!
I would love to see the extension add these couple of things:
Wrap code tags when it recognized code that doesn't use them


How would you recognise what is code and what isn't? Which programming language?
Was This Post Helpful? 0
  • +
  • -

#14 blackcompe  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1152
  • View blog
  • Posts: 2,530
  • Joined: 05-May 05

Re: [Challenge] DIC Chrome Extension: Editor Hotkeys

Posted 30 August 2013 - 03:59 PM

Quote

How would you recognise what is code and what isn't? Which programming language?


There are plenty of syntax highlighting libraries that can differentiate languages. You could use a Bayesian classifier system to easily and reliable do it. The real challenge is how to extract source code accurately from a bunch of text. At best, you may be able to recognize whether code exists in the text and whether there exists at least one pair of code tags. I think it could be done, just not easily. It's overkill for this project.
Was This Post Helpful? 0
  • +
  • -

#15 andrewsw  Icon User is offline

  • Fire giant boob nipple gun!
  • member icon

Reputation: 3369
  • View blog
  • Posts: 11,410
  • Joined: 12-December 12

Re: [Challenge] DIC Chrome Extension: Editor Hotkeys

Posted 30 August 2013 - 04:10 PM

Perhaps if we can recognise code that isn't within code-tags we can delete the post :bigsmile: forcing them to try again ;)
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2