Chrome Extension Tutorial – Adding the productive features

This is the third post in the series – Building an automatic text expander. The first post in the series is about Placeholders and the second is about Data-Time Macros, Mathomania, and Auto-Inserts

So, now we are done with the most essential feature an automatic text expander should have. But, I don’t believe, and neither was ProKeys built, for solely being an automatic text expander. I mean, it was built to “save both your time and effort in online communication”. And, what better can help achieve this aim than date-time macros, auto-inserts, and mathomania? We will be covering how to build these three in this post.

Auto-Inserts

Auto-Inserts are those character pairs, in which, when the first character is pressed, its counterpart gets automatically inserted, and the caret gets placed in the middle of the two. Like pressing ( auto-inserts a ) and places the caret in between the two. Pretty sweet, aren’t they?

And they are easy to implement. Seriously! Before implementing them, we will look at their storage mechanism. We will store them in an array, call it insertsList , in this way:

We will listen for a keyPress  on the document:

Inside the handleKeyPress  function, we will do a four-step process:

  1. Get the keyCode of the key press.
  2. Generate a character from the keyCode.
  3. Search if this character exists in our stored array.
  4. If it does, get its counterpart from the pair, insert it, and place the caret between the two.

And we are done!

Learning point: String.fromCharCode()  method accepts a sequence of positive integers as parameter and returns a string constructed from them. So, String.fromCharCode(66, 67, 68)  returns “bcd”. Note that 66 is the ASCII value of b, 67 is the ASCII value of c, and so on.

See Auto-Inserts live in action (Works best in Chrome):

Mathomania

Mathomania is another interesting feature that lets you solve simple math expressions directly while typing without leaving your typing window. You simply type [[, which auto-inserts ]], type the math expression between those brackets, and press = key, which places the result of evaluating the expression in its place. We will handle Mathomania by this process:

  1. In the handleKeyPress  function, check to see if the typed character is a =.
  2. If it is, get the text preceding it (which would be our math expression) until we encounter a [
  3. Evaluate the math expression.
  4. Replace the entire [[expr=]] with the result. Set caret position after result.

Let’s examine the code for this:

Learning point: The eval() function takes a string, and evaluates it as JavaScript to produce a result. For example, eval(2+2)  returns 4. It is often considered safe as not to use eval  unless you are sure that the string which is fed to it would not be affected would not be affected by third party people, which could be used to inject malicious code and harm the safety of the extension/webpage. Here is a link to an in-depth guide to eval.

See Mathomania live in action (Works best in Chrome):

Date-Time macros

Date-Time macros are basically short symbols enclosed within the parentheses of [[%d()]] , and placed in a snippet body. When activating a snippet, these date-time macros will be replaced with their current value. After toiling hard, I successfully figured out a DRY – don’t repeat yourself – way to implement them. First, we will make an object called “macros”, which will store a key-value pair, the key being a string having the regex to test for the symbols, and value being the function, associated with it, which would give the current value of the symbol. The macros object is structured in this way:

As you can see, each key is a string containing a regex, and each associated value is a function which acts and produces a desired result. So, hh gets replaced with date.getHours()  (not the literal “date.getHours()”; but the result of calling the getHours method of the date object). Now, head to the formatSnippets function, and if you may remember the first blog post, I left this line to be covered later:

Well, the formatMacros  function is what converts the symbols to their desired value. Let’s have a look at it:

Ooh! That’s too much code in once! We will understand this step-by-step:

 

  1. We get the text inside the parentheses of [[%d()]]  using this regex –  /\[\[\%d\((.*?)\)\]\]/g . Here’s an easy-to-understand visualisation of the regex:Visualization of date-time-macro regexThe function, passed as the second argument to the .replace  method, is supposed to be executed when a match to the regex is found. The wholeMatch  argument will be the entire match, including the square brackets; while text  will be the text only inside the parentheses of %d() .
  1. We loop through the macros  object, receiving the regex  string we had earlier given as the key. We create a regex object from this string, which looks for a specific macro symbol. And, then, we find all occurrences of this symbol.
  2. We replace all the found macro symbols with the result of executing macros[regex](date) , which just gets the function in  macros object associated with regex  ( macros[regex] ), and then calls it with date  as an argument.

Learning point: Don’t Repeat Yourself principle. Notice that I create a single Date object and pass it as an argument to the macros functions. I do not create an individual Date object in each function of macros object. By doing so, I avoid the repetition of var date = new Date();  across all the methods present in macros. My code, instead of reading repetitive like this:

my code looks like this:

It can easily be seen that the latter code is more concise and clear than the former code. And, the work is done! You may read through it once again to understand the logic.

See Date-Time macros live in action (Works best in Firefox, Chrome):

Conclusion

We have come very far and accomplished the feat of creating an automatic text expander! Well done; you may give yourself a pat on your back 🙂 If you like my blog post series, you may also like ProKeys – an automatic text expander I created.

Do you have any ideas for improvement? Or wish to communicate something nice? Feel free to do so in the comments!

Next Post

Leave a Reply

Your email address will not be published. Required fields are marked *