Don't get too excited. The Multiple HTML Reply Signatures Extension 1.0.2.3 update doesn't include too many new features. I got rid of the red update link that appears in the toolbar. I don't think it was working correctly. In addition, it took up valuable browser real estate. Bad idea.
I did try to see what would happen in Firefox 3. Sadly, the Firefox Extension doesn't work in Mozilla's newest and fastest browser. The problem isn't the editor or even the signature injection. It's the module that reads data from the XML file. This was a hack anyway. I could probably get by with using the Firefox RDF API or perhaps store the signatures using the preferences system.
The good news is, converting to Firefox 3 wouldn't be hard. The bad news is that I don't have time to do it. We just need to fix the mechanism that reads signatures from the XML data file! That's it! Everything else appeared to work when I tested it!
Anyone know any JavaScript who is bored? HTML Multiple Reply Signatures for Gmail is licensed under the GPL! You can crack open the XPI and try to fix this yourself! I'll even tell you what files to modify if you email me!
I did start working on a version for Gmail 2. Interestingly enough, there aren't many solutions out there for Gmail 2, yet there was tons of competition for Gmail 1. I have a prototype that Susan Hemmersmeier has happily tested for me. It's very buggy though. Too buggy to put up on the blog, and too buggy for her to use.
Susan asked me when this will be finished. I hate to keep promising that "I'll eventually get to it.". You see, thanks to this blog, I landed some contract work! It's a lot of fun, but it takes up a lot of time. As a result, it would appear that HTML Multiple Reply Signatures for Gmail may be a (sniff...) dying project...
Do you have the skills to resurrect it from it's ashes? Let me know! I can definitely provide the moral support and answer technical questions, I just can't devote programming time to it at the moment.
James
Showing posts with label Greasemonkey. Show all posts
Showing posts with label Greasemonkey. Show all posts
Friday, June 27, 2008
HTML Multiple Reply Signatures for Gmail 1.0.2.3
Labels:
Collaboration,
Firefox development,
Gmail,
Greasemonkey,
HTML Signatures,
JavaScript,
XUL
Thursday, March 13, 2008
Multiple HTML Reply Signatures for Google Apps
Gmail HTML Reply Signatures Greasemonkey Script
The company I work for uses Gmail for email communications. Specifically, the service the company uses is part of the Google Apps bundle of services, and it's the same service that I use for my blog email.
As many of you may know, custom signatures through Gmail can't contain HTML by default. However, HTML Multiple Reply Signatures for Gmail solves this by using the Greasemonkey engine to inject HTML into the page. The HTML Multiple Reply Signatures Script (and Firefox Extension) injects a drop down list to the left of the Gmail editor where a user can select from up to four customized HTML signatures, which will be injected into the Gmail editor.
History of Gmail HTML Multiple Reply Signatures
About a year ago, I integrated the HTML Reply Signatures script into our company's global Windows profile. Since the global profile was shared across most of the company workstations, I created a DOS batch script that took the user's Windows login details from a workstation PC and generated the Greasemonkey script using this information. The generated script on each workstation is exactly the same, except for the filename of the signature image to use. The constraint is that all of the images must use a standard naming convention and all be located on the same public server.
Reliable Gmail HTML Signatures Solution
This solution has worked out quite well. It has been very stable and reliable in the last year and has required absolutely zero maintenance. Now that we have a need for certain people to have more than one signature card, I suggested that one of our managers install the HTML Multiple Reply Signatures Greasemonkey script. So far, he's pretty satisfied with it.
Not being on the global profile made this much easier; otherwise, I would need to write a new batch script that generates the HTML Multiple Reply signatures script instead of the HTML Reply Signatures script, which can only handle injecting one signature. In addition, not being on the global profile means that he could essentially name the image files whatever he wants, as long as he modifies the signature HTML in the script to point to the correct filenames.
I recommended the script instead of the Firefox Extension for three reasons:
- The script is actually more reliable and bug-free than the Firefox Extension.
- This particular manager is technically adept and fully capable of modifying the script himself to configure new signatures.
- Google Apps Gmail is not using Gmail's New Interface, so it has not been susceptible to the same bugs that standard Gmail users have faced.
New version of Gmail
Once Gmail moves these customers to the new version, we're likely to see problems. I wonder why they haven't done this yet. The bigger question is, with my organization's growing use of this particular tool, should we prepare for the change by using a plug-in that supports the new interface?
At any rate, it was cool to see the script being used in my own organization! It may be a good idea to seriously consider moving the script to Gmail's Greasemonkey API to support the new interface.
Labels:
Business,
Firefox development,
Gmail,
Greasemonkey,
HTML Signatures
Saturday, November 10, 2007
Google Releases New Version of Gmail
Google has released a new version of Gmail. The ui parameter that appeared in the URL recently, the one that broke the HTML Reply Signatures for Gmail Signatures Firefox Extension and Greasemonkey, was part of the plan for allowing users to switch between the newer version and the older version.
How to Go Back to Gmail's Older Version explains more of the details regarding the new version features as well as how to switch back to the older version.
I just bought a 1968 Ford Thunderbird! I bought it yesterday actually. It hasn't even been 24 hours! It has a 429 cubic inch big block V8, suicide doors, a nice, well-preserved leather interior, and driving this well-engineered machine is like stepping back in time! It also has enough power to propel you into tomorrow!
And just how does this relate to the Gmail Reply Signatures Extension you ask? Well, it will be awhile before I will be able to fix this newly created Gmail bug, so for now, I'm going to recommend that you use the older version of Gmail so you can still use your HTML Signatures. Fortunately, Google is good at allowing us to enjoy backwards compatibility for awhile.
I'll post pictures of the car soon!
How to Go Back to Gmail's Older Version explains more of the details regarding the new version features as well as how to switch back to the older version.
I just bought a 1968 Ford Thunderbird! I bought it yesterday actually. It hasn't even been 24 hours! It has a 429 cubic inch big block V8, suicide doors, a nice, well-preserved leather interior, and driving this well-engineered machine is like stepping back in time! It also has enough power to propel you into tomorrow!
And just how does this relate to the Gmail Reply Signatures Extension you ask? Well, it will be awhile before I will be able to fix this newly created Gmail bug, so for now, I'm going to recommend that you use the older version of Gmail so you can still use your HTML Signatures. Fortunately, Google is good at allowing us to enjoy backwards compatibility for awhile.
I'll post pictures of the car soon!
Labels:
Firefox development,
Gmail,
Greasemonkey,
HTML Signatures
Tuesday, October 16, 2007
The Gmail Dependency
I knew it was going to happen one day, I just wasn't sure exactly when. I knew one day the script would suddenly stop working. Not because code rusts. Or because the code cracked like glass, but because the foundation that it depends on cracked.
Well, it didn't really crack. It's more like what happens when a house settles. It's just digging itself in. Gmail was digging itself in. The developers added a new parameter to the URL that opens the HTML Compose editor.
However, the script stopped working. The regular expression logic asks if the URL matches a specific "include" pattern. For most URLs, nothing happens, the script does nothing. There's no need to use processor power unnecessarily if there is no Gmail HTML content window to paste HTML into. Plus, users may get annoyed if the HTML popped up somewhere unwelcome.
If the URL were to match the pattern, then the code is executed. The HTML is read from an XML data file, as is the Greasemonkey Script. At a specified location in the script, JavaScript variables are generated, which contain the HTML retrieved from the XML file. This re factored JavaScript is then evaluated and dynamically inserted into the HTML content window of Gmail, using a compiled Greasemonkey engine.
An asterisk is all it takes. One small character, just 2 bytes of data, is enough to break functionality.
HTML Multiple Reply Signatures for Gmail is dependent on the functionality of Google's Gmail interface. The URL change was an easy fix, but should Google decide to perform a major overhaul of the Gmail interface, the HTML Multiple reply Signatures for Gmail scripts and Firefox Extension would reach the end of their useful lives. Better Gmail, and many other Firefox extensions built around Gmail's interface, such as Gspace, may also be rendered useless.
- Add the asterisk where indicated by the highlighting.
For all of the do-it-yourselfers, I highlighted the area where I had to make the change. If you're using one of the Greasemonkey scripts, the Firefox Extension, or another type of HTML Signature injector script that recently broke, you can fix it by making sure that highlighted asterisk is added to the included URL or regular expression. That's right! Even if you're using another Gmail HTML injector script other than one that I created, you can fix it yourself by editing the include URL list and correcting any errors!
Of course, if you find that you would rather get a new, updated copy, all of the links in the menu on this website reflect the updated URL changes. Since installing or reinstalling the scripts should fix the problem, you could just download a new copy and reinstall it.
Well, it didn't really crack. It's more like what happens when a house settles. It's just digging itself in. Gmail was digging itself in. The developers added a new parameter to the URL that opens the HTML Compose editor.
ui=1. If they added it to the end of the URL, it wouldn't have made a difference. But regular expressions care about where certain things are placed. Order doesn't matter in a URL parameter list, so Google developers could put this parameter wherever they wanted.However, the script stopped working. The regular expression logic asks if the URL matches a specific "include" pattern. For most URLs, nothing happens, the script does nothing. There's no need to use processor power unnecessarily if there is no Gmail HTML content window to paste HTML into. Plus, users may get annoyed if the HTML popped up somewhere unwelcome.
If the URL were to match the pattern, then the code is executed. The HTML is read from an XML data file, as is the Greasemonkey Script. At a specified location in the script, JavaScript variables are generated, which contain the HTML retrieved from the XML file. This re factored JavaScript is then evaluated and dynamically inserted into the HTML content window of Gmail, using a compiled Greasemonkey engine.
An asterisk is all it takes. One small character, just 2 bytes of data, is enough to break functionality.
HTML Multiple Reply Signatures for Gmail is dependent on the functionality of Google's Gmail interface. The URL change was an easy fix, but should Google decide to perform a major overhaul of the Gmail interface, the HTML Multiple reply Signatures for Gmail scripts and Firefox Extension would reach the end of their useful lives. Better Gmail, and many other Firefox extensions built around Gmail's interface, such as Gspace, may also be rendered useless.
- Add the asterisk where indicated by the highlighting.
For all of the do-it-yourselfers, I highlighted the area where I had to make the change. If you're using one of the Greasemonkey scripts, the Firefox Extension, or another type of HTML Signature injector script that recently broke, you can fix it by making sure that highlighted asterisk is added to the included URL or regular expression. That's right! Even if you're using another Gmail HTML injector script other than one that I created, you can fix it yourself by editing the include URL list and correcting any errors!
Of course, if you find that you would rather get a new, updated copy, all of the links in the menu on this website reflect the updated URL changes. Since installing or reinstalling the scripts should fix the problem, you could just download a new copy and reinstall it.
Labels:
Firefox development,
Gmail,
Greasemonkey,
HTML Signatures
Thursday, October 11, 2007
Nested-Nested Quotes
Larry Wakeman of Memory Pharmaceuticals recently sent me a reminder about a follow-up article that I forgot to write. Back in April, I addressed the concept of quotes within quotes within quotes and how to handle this phenomenon.
Any programmer who has ever had to write Greasemonkey scripts, as well as to perform any type of server-side or client-side programming has or will encounter this particular problem. For example, a JavaScript function that generates HTML that contains attributes that refer to JavaScript functions that take strings as parameters, will require some cleverness on the part of the developer, especially if the parameter passed into the JavaScript function is determined at the time the HTML is generated:
Here is a breakdown of the above process: The text "document.write" is what I refer to as top level. This is the actual command that outputs the string of text included within the outer quotes. The outer quotes are the quotes that wrap the text inside the parenthesis of the document.write method.
Note that there are two types of quotes: Single quotes and double quotes. We can use either to represent the outer quotes. For this example, I chose double quotes. The first set of inner quotes, like the outer quotes, can also be double or single quotes. However, if the inner quote is the same as the outer quote, then the inner quote must be escaped. Consider the following example:
The above example is the same as the following example:
Also, to demonstrate that we can use single-quotes as the outer quotes, check out this example:
Take a careful look at the above three JavaScript nested quote examples. Understanding this concept is a prerequisite to understanding deeper JavaScript nested quotes.
As I mentioned, the outer quote can be either a double or single quote, and the first inner quote can be either a double or a single quote independent of the choice made for the outer quote. In Example 1, I used double quotes for both the outer and inner quote, whereas in Examples 2 and 3 I alternated between single and double quotes. For convenience, here is Example 1 again:
It may seem confusing at first as to how this is possible, until you see the output in the browser source (of the generated HTML, that is. I'll go into more detail on this later):
The outer quotes don't appear in the generated HTML. Those were top level quotes. They served only to wrap what was being generated. As you can see, the escaped double-quotes render as actual quotes, and cause absolutely no conflict.
Example 4 produces the same output! Except in example 4 it is the single quotes that must be escaped, as this time single quotes represent the outer quotes.
By this point, it should be quite apparent that there are several combinations of outer and inner quotes that can be combined without causing a non-terminated string literal error. However, after choosing an outer and an inner quote, choices become much more limited.Instead, from this point forward, nested quotes must alternate between single and double quotes. Below is an example:
You may have noticed that the previous paragraph contains a sentence with strikethrough styling. After trying the example I was going to try, I realized that the rule that the quotes must alternate is not necessarily true. I'll explain, but first, here is the output when clicking the link:
Definition of literal quote: This is a quote that represents a quote as text in a string. A quote that marks the beginning or end of a string is a non-literal quote, and it is not part of the actual text. A non-literal quote can be represented as a literal quote by escaping it with a backslash (\) character.
Since the outer quote is a double quote, the inner quotes are literal quotes in the string. If the outer quotes were single quotes, then double quotes would be literal. As a result, I can place as may single quotes in a row as I want without affecting the String. However, this will affect not what occurs with the output, but what occurs with the output of the output:
Outer quote = " (This marks the beginning and end of the string)
Inner quote = \" (Escaped as to not flag "beginning/end of string")
Third-tier quote = ' (Literal quote)
Fourth-tier quote = \\' (Literal quote that will be generated as an escaped outer quote)
This is what really makes this JavaScript nesting quote process complicated. As I mentioned, the single quote is a literal quote. This means the string treats it as a normal character. However, in the HTML -- in the output that is -- the single quote becomes an outer quote. The single quotes around 'Hello World' are literal quotes in the JavaScript code, but in the HTML, these single quotes are inner quotes that must be escaped. However, using a single \' would simply result in a '. So the trick is to escape the slash. Thus, a document.write("\\'"); would produce a \' in the HTML, and this would be resolved to a ' if processed again.
Essentially, you must take two things into consideration when dealing with escaping a quote in JavaScript. If it needs to be escaped in the inner string, then you must think one level deep. It helps to move backwards. Write your desired output first, and then go through and "wrap it" with the tools that would generate it:
I want to dynamically generate this embedded JavaScript from the server with PHP. So I'll first verify that this works in between the body HTML tags of a PHP document. It does indeed work. Next, I'll wrap it with a PHP echo statement:
Escaping JavaScript quotes is recursive. After wrapping the PHP echo around the JavaScript with double quotes as outer quotes, I then had to escape the previous outer quotes. I then had to escape the inner-inner double quotes not once, but twice. Once to escape the backslash used to escape the quote, and once to escape the quote so that PHP wouldn't treat it as the end of the string. What I found most interesting is that the single quote used as the outer wrapper of the alert text was ignored during the PHP wrapping process because it is a literal quote. However, the innermost single quote had to have two backslashes added -- once to add another backslash and once to escape that backslash! Each time a wrapper is added, an escaped special character must be escaped again because during each iteration, a backslash escapes a backslash!
In summary, I'm not sure if this little exercise will be of any practical use. Perhaps it would be a good problem solving exercise during an employment interview to see how good a programmer is at dealing with complex layers of abstraction. Perhaps a situation will arise where one actually needs to generate different JavaScript functions based on different criteria. I can't think of any examples other than the Multiple HTML Reply Signatures Embedder for Gmail Greasemonkey script that I wrote, and sometimes I think that there may have been an easier way to generate a dynamic-drop down list in Gmail without having to nest quotes in JavaScript. Bottom line -- I'm not sure. However, if this has proved helpful, please share your story with me!
Any programmer who has ever had to write Greasemonkey scripts, as well as to perform any type of server-side or client-side programming has or will encounter this particular problem. For example, a JavaScript function that generates HTML that contains attributes that refer to JavaScript functions that take strings as parameters, will require some cleverness on the part of the developer, especially if the parameter passed into the JavaScript function is determined at the time the HTML is generated:
<html>
<head>
</head>
<body>
<script type="text/javascript">
function alertParameter(stringParameter) {
alert(stringParameter);
}
var topLevel = "test";
function generateHTML(topLevel) {
document.write("<a href=\"#\" onclick=\"alertParameter('"+topLevel+"')\">Click this link to see the result</a>");
}
generateHTML(topLevel);
</script>
</body>
</html>
Here is a breakdown of the above process: The text "document.write" is what I refer to as top level. This is the actual command that outputs the string of text included within the outer quotes. The outer quotes are the quotes that wrap the text inside the parenthesis of the document.write method.
document.write(" /* These quotes are the outer quotes */ ");
Note that there are two types of quotes: Single quotes and double quotes. We can use either to represent the outer quotes. For this example, I chose double quotes. The first set of inner quotes, like the outer quotes, can also be double or single quotes. However, if the inner quote is the same as the outer quote, then the inner quote must be escaped. Consider the following example:
Nested JavaScript Quotes Example 1
document.write("<div onclick=\"alert('ht')\">click me</div>");
The above example is the same as the following example:
Nested JavaScript Quotes Example 2
document.write("<div onclick='alert(\"ht\")'>click me</div>");
Also, to demonstrate that we can use single-quotes as the outer quotes, check out this example:
Nested JavaScript Quotes Example 3
document.write('<div onclick="alert(\'ht\')">click me<div>');
Take a careful look at the above three JavaScript nested quote examples. Understanding this concept is a prerequisite to understanding deeper JavaScript nested quotes.
As I mentioned, the outer quote can be either a double or single quote, and the first inner quote can be either a double or a single quote independent of the choice made for the outer quote. In Example 1, I used double quotes for both the outer and inner quote, whereas in Examples 2 and 3 I alternated between single and double quotes. For convenience, here is Example 1 again:
Nested JavaScript Quotes Example 1
document.write("<div onclick=\"alert('ht')\">click me</div>");
It may seem confusing at first as to how this is possible, until you see the output in the browser source (of the generated HTML, that is. I'll go into more detail on this later):
<div onclick="alert('hi')">click me</div>
The outer quotes don't appear in the generated HTML. Those were top level quotes. They served only to wrap what was being generated. As you can see, the escaped double-quotes render as actual quotes, and cause absolutely no conflict.
Nested JavaScript Quotes Example 4
document.write('<div onclick="alert(\'ht\')">click me</div>');
Example 4 produces the same output! Except in example 4 it is the single quotes that must be escaped, as this time single quotes represent the outer quotes.
JavaScript Inner, inner quotes
By this point, it should be quite apparent that there are several combinations of outer and inner quotes that can be combined without causing a non-terminated string literal error. However, after choosing an outer and an inner quote, choices become much more limited.
<html>
<head>
</head>
<body>
<script type="text/javascript">
function alertParameter(stringParameter) {
alert(stringParameter);
}
var topLevel = "test";
function generateHTML(topLevel) {
document.write("<a href=\"#\" onclick=\"alertParameter('Say \\'Hello World\\'')\">Click this link to see the result</a>");
}
generateHTML(topLevel);
</script>
</body>
</html>
You may have noticed that the previous paragraph contains a sentence with strikethrough styling. After trying the example I was going to try, I realized that the rule that the quotes must alternate is not necessarily true. I'll explain, but first, here is the output when clicking the link:
Say 'Hello World'Definition of literal quote: This is a quote that represents a quote as text in a string. A quote that marks the beginning or end of a string is a non-literal quote, and it is not part of the actual text. A non-literal quote can be represented as a literal quote by escaping it with a backslash (\) character.
Since the outer quote is a double quote, the inner quotes are literal quotes in the string. If the outer quotes were single quotes, then double quotes would be literal. As a result, I can place as may single quotes in a row as I want without affecting the String. However, this will affect not what occurs with the output, but what occurs with the output of the output:
(" ... onclick=\"alertParameter('Say \\'Hello World\\'')\"> ... ")Outer quote = " (This marks the beginning and end of the string)
Inner quote = \" (Escaped as to not flag "beginning/end of string")
Third-tier quote = ' (Literal quote)
Fourth-tier quote = \\' (Literal quote that will be generated as an escaped outer quote)
This is what really makes this JavaScript nesting quote process complicated. As I mentioned, the single quote is a literal quote. This means the string treats it as a normal character. However, in the HTML -- in the output that is -- the single quote becomes an outer quote. The single quotes around 'Hello World' are literal quotes in the JavaScript code, but in the HTML, these single quotes are inner quotes that must be escaped. However, using a single \' would simply result in a '. So the trick is to escape the slash. Thus, a document.write("\\'"); would produce a \' in the HTML, and this would be resolved to a ' if processed again.
Essentially, you must take two things into consideration when dealing with escaping a quote in JavaScript. If it needs to be escaped in the inner string, then you must think one level deep. It helps to move backwards. Write your desired output first, and then go through and "wrap it" with the tools that would generate it:
<script type="text/javascript">document.write("<a href=\"#\" onclick=\"alert('Say \\'Hello World\\'');\">click here</a>");</script>
I want to dynamically generate this embedded JavaScript from the server with PHP. So I'll first verify that this works in between the body HTML tags of a PHP document. It does indeed work. Next, I'll wrap it with a PHP echo statement:
<? echo "<script type=\"text/javascript\">document.write(\"<a href=\\\"#\\\" onclick=\\\"alert('Say \\\\'Hello World\\\\'');\\\">click here</a> \");</script>'"; ?>
Escaping JavaScript quotes is recursive. After wrapping the PHP echo around the JavaScript with double quotes as outer quotes, I then had to escape the previous outer quotes. I then had to escape the inner-inner double quotes not once, but twice. Once to escape the backslash used to escape the quote, and once to escape the quote so that PHP wouldn't treat it as the end of the string. What I found most interesting is that the single quote used as the outer wrapper of the alert text was ignored during the PHP wrapping process because it is a literal quote. However, the innermost single quote had to have two backslashes added -- once to add another backslash and once to escape that backslash! Each time a wrapper is added, an escaped special character must be escaped again because during each iteration, a backslash escapes a backslash!
In summary, I'm not sure if this little exercise will be of any practical use. Perhaps it would be a good problem solving exercise during an employment interview to see how good a programmer is at dealing with complex layers of abstraction. Perhaps a situation will arise where one actually needs to generate different JavaScript functions based on different criteria. I can't think of any examples other than the Multiple HTML Reply Signatures Embedder for Gmail Greasemonkey script that I wrote, and sometimes I think that there may have been an easier way to generate a dynamic-drop down list in Gmail without having to nest quotes in JavaScript. Bottom line -- I'm not sure. However, if this has proved helpful, please share your story with me!
Labels:
Greasemonkey,
JavaScript,
PHP,
String parsing
Sunday, October 7, 2007
Update for HTML Multiple Reply Signatures for Gmail
10/09/07 UPDATE: Due to a change made to the Gmail URL structure, the HTML Multiple Reply Signatures Extension suddenly stopped working. I've updated the URL to reflect the newest, working version.
There have been some problems with the Firefox Extension that can make inserting HTML signatures in Gmail somewhat of a hassle. However, in spite of these issues, people have been downloading and using it. To my surprise and pleasure, I've received quite a bit of positive feedback. For those of you who have given me feedback, thank you! In order to address some of the issues that you've had and to accommodate some requests I've received, I've updated the extension, which can be downloaded by clicking on the following link:
Multiple HTML Reply Signatures Extension 1.0.2
Multiple HTML Reply Signatures Extension 1.0.2.1
Multiple HTML Reply Signatures Extension 1.0.2.2
I've added multi-line functionality to the editor, so you won't have to type the HTML all on one line. In addition, this should make it much easier to paste HTML directly into the editor. This was causing the script to not function when HTML was pasted, since HTML is typically not written all on one line.
I also added an update notification to the new version. Firefox Extensions support update notifications through RDF, but since my hosting provider doesn't respond to RDF requests with "text/rdf" like an Apache server would, I was forced to create a hack that uses a regular expression to check the version number against my server. The cool thing about my custom version of update notifications is that the HTML Multiple Reply Signatures for Gmail extension will simply insert a "Click here to update" button in the tool bar.
It's not the most elegant way to notify users of an update, but I absolutely hate popup windows. This tool bar button is very unobtrusive. An image or a logo would be cool, but that's not my specialty so for now, it's plain text.
I started looking into the issue of why quotes won't work in the extension. This is turning out to be a lot more complicated and will take a lot more time to resolve. The problem is that the quotes have been escaped so many times that I think the strings aren't being parsed correctly. For now, you must enter your attributes without quotes like I've done below:
<a href=http://blog.opensourceopportunities.com style=color:orange>Blog</a>Oh, I recently discovered that ampersand codes weren't supported. That has also been fixed. You can now use in your HTML, if needed.
I'll continue to fix bugs in this extension. The quotes are a big one, but not easily fixed. As always, if you have any problems, questions, concerns, or suggestions, please email me and I'll respond as quickly as I can.
Labels:
Firefox development,
Gmail,
Greasemonkey,
HTML Signatures,
String parsing,
XUL
Thursday, June 7, 2007
HTML Multiple Reply Signatures for Gmail Firefox Extension
After spending the last three weekends working on the HTML Multiple Reply Signatures for Gmail Firefox Extension 1.0.1, I finally have a working prototype.
The Firefox Extension has all of the features and functionality of the HTML Multiple Reply Signatures for Gmail Greasemonkey script, except the extension doesn't require Greasemonkey. In addition, the extension provides a user interface for easy editing of signatures.
With Greasemonkey, users are required to edit the script manually in order to edit signatures. With the extension, this is no longer necessary.
For convenience, there is a real-time preview window so any HTML entered is immediately displayed for easy editing.
In fact, I'm thinking that the preview editor has some potential to be used in a number of applications, such as an HTML tutorial, HTML-area textbox for user comments, possibly a content-management system, and some other uses.
Since the user interface consists of XUL, these applications would all have a client-side feel to them, yet the potential exists to either serve them remotely or package them as Firefox Extensions.
You should be able to install the extension in Firefox simply by clicking on the HTML Multiple Reply Signatures for Gmail 1.0.1 Firefox Extension link. If you are prompted to install, wonderful! Simply choose the "Install" option and restart Firefox. However, I noticed that -- when I tried to install by clicking on the link -- I was instead prompted to save the XPI file to disk.
If you experience this, follow these steps to save the XPI to disk and install it locally.
Inserting the signature is automatic. When you click "compose" or "reply", the first signature in the list will automatically appear in the editor. To change signatures, use the dropdown list at the bottom of the Gmail left navigation section. The signature will be changed automatically as soon as your selection is made.
View the demo here.
There are some bugs that I have come across so far, and I am sure that there will be more. If you discover a bug that is not in this list, please email me or post a comment to this post.
Sometimes it is best to release software instead of trying to correct every single bug. None of these are showstoppers, but here they are:
This is the first project I've done on my own that is outside the context of work or school. Please don't hesitate to give me advice about how to better track bugs, write better documentation, or make improvements to the application.
Also, if you have any trouble or need help, please contact me. I hope you find this Firefox extension useful!
The Firefox Extension has all of the features and functionality of the HTML Multiple Reply Signatures for Gmail Greasemonkey script, except the extension doesn't require Greasemonkey. In addition, the extension provides a user interface for easy editing of signatures.
With Greasemonkey, users are required to edit the script manually in order to edit signatures. With the extension, this is no longer necessary.
For convenience, there is a real-time preview window so any HTML entered is immediately displayed for easy editing.
In fact, I'm thinking that the preview editor has some potential to be used in a number of applications, such as an HTML tutorial, HTML-area textbox for user comments, possibly a content-management system, and some other uses.
Since the user interface consists of XUL, these applications would all have a client-side feel to them, yet the potential exists to either serve them remotely or package them as Firefox Extensions.
The Firefox Extension
You should be able to install the extension in Firefox simply by clicking on the HTML Multiple Reply Signatures for Gmail 1.0.1 Firefox Extension link. If you are prompted to install, wonderful! Simply choose the "Install" option and restart Firefox. However, I noticed that -- when I tried to install by clicking on the link -- I was instead prompted to save the XPI file to disk.
If you experience this, follow these steps to save the XPI to disk and install it locally.
- To install the XPI locally, open the Extensions/Add ons window from the "Tools" menu.
- Next, drag and drop the XPI file from your desktop to the extensions window.
- When prompted to install, click "Install".
- Restart Firefox by closing all Firefox windows.
Using the HTML Multiple Reply Signatures for Gmail Firefox Extension
Creating a signature
- In Firefox, click "Tools" -> "Gmail Multiple Reply Signatures".
- Near the top of the window are two radio buttons. Use these to toggle between editing the signatures for initial compose emails or reply emails
- In the "Initial Composes" section, select from four signatures to configure.
- Enter HTML in the "Enter HTML Signature here" section. For attributes, do not use any quotes. Below is an example of a signature hyperlink where attributes are used, but without quotes:
- In the "Preview" section, you will see real-time HTML output based on your input in the "Enter HTML Signature here" section. You may fine-tune your signature until it appears the way you want.
- Once configured, click "Save".



<div>--</div><a href=http://blog.opensourceopportunities.com style=font-family:tahoma;color:blue;>James Mortensen</a><div></div>

Inserting the HTML Signature in Gmail
Inserting the signature is automatic. When you click "compose" or "reply", the first signature in the list will automatically appear in the editor. To change signatures, use the dropdown list at the bottom of the Gmail left navigation section. The signature will be changed automatically as soon as your selection is made.
View the demo here.
Known bugs
There are some bugs that I have come across so far, and I am sure that there will be more. If you discover a bug that is not in this list, please email me or post a comment to this post.
Sometimes it is best to release software instead of trying to correct every single bug. None of these are showstoppers, but here they are:
- Quotes cannot be used around attributes
- Large sections of HTML may be corrupted when saving.
- The signature names can't be renamed
- When pressing "Compose" in Gmail more than once, multiple drop-down lists appear
- After entering email content, selecting a different signature will cause part or all of my email to be deleted.
- Fixed in 1.0.1 on 6/9/07 - After entering a signature on multiple lines in the editor, the signatures would not appear in the Gmail compose or reply editors.
Simply leave out the quotes as they are not required.
When you enter large sections of HTML and save, the next time you open the sgnature content editor, you will be reverted back to defaults. You can find your signatures in an xml file called htmlmultiplereplysignaturesforgmail.xml in your Mozilla Firefox profile directory. Save this information somewhere else, or copy and paste the non-corrupted signatures back into the editor. I plan to create some means of recovery for these types of errors.
This functionality has not been completely implemented yet.
Just delete any unwanted signatures from the Gmail editor.
Be careful not to type below the "--" characters. There are invisible markers around he signature that mark the dynamic section. (Actually, the signature is placed inside a span element. If you type below the "--", you are typing inside the span element).
I enabled the multiline attribute of the textbox, which the script did not know how to handle. The temporary fix was to disable multiline support until I have time to fix the problem and test it thoroughly. Be aware that if you want line breaks in the signature, simply use a <br> or <div></div>
Comments
This is the first project I've done on my own that is outside the context of work or school. Please don't hesitate to give me advice about how to better track bugs, write better documentation, or make improvements to the application.
Also, if you have any trouble or need help, please contact me. I hope you find this Firefox extension useful!
Labels:
Firefox development,
Gmail,
Greasemonkey,
HTML Signatures,
XUL
Sunday, May 6, 2007
Multiple HTML Reply Signatures for Gmail
I've upgraded the HTML Reply Signatures for Gmail script. The Multiple HTML Reply Signatures for Gmail Greasemonkey script does the following:
1. When the user composes or replies to a message, an HTML signature is inserted in the Gmail editor by default.

2. At any time before pressing 'Send', the user can select another HTML signature from the drop down list in the left navigation menu of Gmail.

I've also addressed issues regarding the HTML signature placement. This script places the signature at the end of the reply, not at the end of the thread. I've noticed that the subject of HTML signature placement is a hotly debated topic. However, my reasons for placing the HTML signature at the end of the reply are as follows:
1. I find that I rarely, if ever, scroll through quotes from previous emails in a thread unless I need to refresh my memory; therefore, I find that I am less likely to see a signature that is at the bottom of the thread.
2. After several replies back and forth, signatures will begin to accumulate at the bottom of the thread. Because of reason #1, none of these signatures will be seen anyway, unless I need to reference an earlier part of the conversation. If I do scroll to the bottom, I'll see multiple instances of my signature and that of the person I've been collaborating with.
3. Keeping the entire message content at the top of a reply helps identify the boundary of where one message ends and another begins. Placing the signature at the end of the reply clearly identifies where the end of the reply is and where the previous email begins.
However, I realize that there are people who will disagree and insist that the HTML signature be placed at the bottom of the thread. If you want to move the HTML signature to the end, by all means, go for it. It is actually easier to code the script so that signatures are placed at the end. So, if you need help with this modification, let me know.
It is also worth noting that the dropdown list can be configured to plug in different signatures for replies than for initial composes; however, the drop down list values will be the same. What this means is this: I can configure a "Personal Signature" for replies and a "Personal Signature" for initial composes. Likewise, I can configure a "Work Signature" for initial composes and a "Work Signature" for replies. I can also set them to be the same. However, in any case, the dropdown list values will always be the same.
Finally, the script can be configured to insert no HTML signature by default. As long as the htmlsignature and/or htmlreplysig variable has a beginning span tag with an id="image_sig" and a closing span tag, anything, including whitespace, can be placed in the innerHTML. Once an HTML signature is selected from the dropdown list, only signatures from that list can be selected. Therefore, it is important to ensure that the default HTML signature is also in the dropdown list. It is for this reason that the fourth option in the dropdown list is configured as "No Signature", which sets the innerHTML to whitespace. Therefore, if a user decides not to use an HTML signature after selecting one, it can be removed by selecting this option.
In order to use this script, you must have Mozilla Firefox 1.5 or higher and the Greasemonkey firefox extension installed. If you've already installed Firefox and Greasemonkey, you can go ahead and install the Multiple HTML Reply Signatures for Gmail script.
UPDATE: The script is now available as a Firefox Extension!
1. When the user composes or replies to a message, an HTML signature is inserted in the Gmail editor by default.

2. At any time before pressing 'Send', the user can select another HTML signature from the drop down list in the left navigation menu of Gmail.

Multiple HTML Reply Signatures for Gmail Demo
Hello,
This is a demo Gmail content window that demonstrates the plug-in behavior of the Multiple HTML Reply Signatures for Gmail script. Use the drop-down list on the left to toggle between different signatures.
This is a demo Gmail content window that demonstrates the plug-in behavior of the Multiple HTML Reply Signatures for Gmail script. Use the drop-down list on the left to toggle between different signatures.
--
I've also addressed issues regarding the HTML signature placement. This script places the signature at the end of the reply, not at the end of the thread. I've noticed that the subject of HTML signature placement is a hotly debated topic. However, my reasons for placing the HTML signature at the end of the reply are as follows:
1. I find that I rarely, if ever, scroll through quotes from previous emails in a thread unless I need to refresh my memory; therefore, I find that I am less likely to see a signature that is at the bottom of the thread.
2. After several replies back and forth, signatures will begin to accumulate at the bottom of the thread. Because of reason #1, none of these signatures will be seen anyway, unless I need to reference an earlier part of the conversation. If I do scroll to the bottom, I'll see multiple instances of my signature and that of the person I've been collaborating with.
3. Keeping the entire message content at the top of a reply helps identify the boundary of where one message ends and another begins. Placing the signature at the end of the reply clearly identifies where the end of the reply is and where the previous email begins.
However, I realize that there are people who will disagree and insist that the HTML signature be placed at the bottom of the thread. If you want to move the HTML signature to the end, by all means, go for it. It is actually easier to code the script so that signatures are placed at the end. So, if you need help with this modification, let me know.
It is also worth noting that the dropdown list can be configured to plug in different signatures for replies than for initial composes; however, the drop down list values will be the same. What this means is this: I can configure a "Personal Signature" for replies and a "Personal Signature" for initial composes. Likewise, I can configure a "Work Signature" for initial composes and a "Work Signature" for replies. I can also set them to be the same. However, in any case, the dropdown list values will always be the same.
Finally, the script can be configured to insert no HTML signature by default. As long as the htmlsignature and/or htmlreplysig variable has a beginning span tag with an id="image_sig" and a closing span tag, anything, including whitespace, can be placed in the innerHTML. Once an HTML signature is selected from the dropdown list, only signatures from that list can be selected. Therefore, it is important to ensure that the default HTML signature is also in the dropdown list. It is for this reason that the fourth option in the dropdown list is configured as "No Signature", which sets the innerHTML to whitespace. Therefore, if a user decides not to use an HTML signature after selecting one, it can be removed by selecting this option.
In order to use this script, you must have Mozilla Firefox 1.5 or higher and the Greasemonkey firefox extension installed. If you've already installed Firefox and Greasemonkey, you can go ahead and install the Multiple HTML Reply Signatures for Gmail script.
UPDATE: The script is now available as a Firefox Extension!
Labels:
Gmail,
Greasemonkey,
HTML Signatures
Saturday, April 14, 2007
Gmail HTML Reply Signatures and JavaScript
Nested Quotes causing Bug in HTML Reply Signatures for Gmail
After doing a google search to see where my blog ranks, I've found that some people have been having trouble with the Gmail HTML Reply Signatures script that Greasemonkey uses to embed HTML signatures in Gmail. Consider this to be your user-guide for the script, as well as a little lesson in the intricacies of JavaScript.
Unless you've spent hours banging your head against your computer trying to get JavaScript code to do what you want it to do, you may be confused by the different syntax that you would see when reading code written by different programmers. Come to think of it, even after banging your head against your computer trying to get the code to do what you want it to do, you may still be confused.
In the Gmail HTML Reply Signatures script, the code you are instructed to modify looks like this:
var htmlsig = '<br><p><img src="http://mydomain.com/image.jpg"></p><br>';Notice that there are quotes and there are apostrophes. The apostrophes represent the beginning and the end of a string of text that is assigned to the variable called htmlsig. The string also happens to be HTML. However, in JavaScript, the HTML is simply a string that will be used to generate HTML in the Gmail compose window. When this string is written to the browser, it is then read as HTML and interpreted as such.
Now, consider this line of code, which will not work properly due to errors:
var htmlsig = "<br><p><img src="http://mydomain.com/image.jpg"></p><br>";Can you see why this won't work? Yes? Good! You've probably had quite a bit of JavaScript experience! You may have even made this mistake yourself in the past. But if you can't see the error, no worries, this is a great learning experience for you! Notice that there are four quotes ("). The JavaScript parser -- if that is what you call it -- is confused because the first quote represents the beginning of a string and the second quote represents the end of the string. But the second quotation mark is actually for the string within the string; it is supposed to mark the assignment of the url to the src attribute.
Nested Quotes JavaScript Analogy
Think about the last book you read where the main character quoted another character:
Mark said to Tammy, "What did John tell you?". Tammy replied, "Mark, John said: 'The only dumb question is the one that is never asked!', and I think he really means it.". Mark raised an eyebrow...
Notice how the storyline is told outside of quotes, quotes are used to indicate a character speaking, and apostrophes are nested within quotes to indicate a person speaking about a person speaking. Could this pattern be nested deeper, such as a person speaking about a person speaking about a person speaking? It could, but we only have two delimiting characters: Quotes and apostrophes. We'll come back to this problem later.
For now, lets apply this really horrible story about Tammy, John, and Mark to our Gmail HTML Reply Signatures nested quote problem. I'm a big fan of analogies, so lets use the following analogies to compare the story to our JavaScript problem:
- Narrator text outside of quotes - The story - JavaScript API (functions, variables, etc)
- Character text within quotes - A string assignment - What JavaScript will say to Gmail
- Character quoting character text within apostrophes - A quote within a string - What JavaScript will tell Gmail to tell the src attribute
Now, what would the reader think of this:
Mark said to Tammy, "Tammy, my writing career is in the toilet, what is this story about?". Tammy looked puzzled. Finally she said, "John said, "This quote is confusing because it is a quote within a quote.", and not to worry about our careers".
Notice the inner quotation uses the same type of quote. Instead of an inner quote, the text would actually represent the narration and not any type of quote.
Think of writing JavaScript as writing a book where the JavaScript parser is your reader, or audience. Unlike a human who could more than likely look past the incorrect usage of quotation marks, the JavaScript parser will become extremely confused by incorrect nesting of quotes.
Which nested JavaScript quote comes first?
Now here comes the really interesting part. You can use quotes in whatever order you want. Consider this:
var htmlsig = "<br><p><img src='http://mydomain.com/image.jpg'></p><br>";Notice that I reversed the (') and the ("). The quotation mark is now the outer string wrapper and the apostrophe now represents the inner string wrapper. Be prepared to see differences, as unlike publishing a novel, there is no rule determining whether an apostrophe is used first or a quote is used first. As long as one type is used for the outer string and the other type is used for the inner string, your result will be the same.
Quote within a Quote within a Quote within a ...
If you feel that you now have a good understanding of this concept, I've got a little exercise for you. Remember the story with John, Tammy, and Mark? I mentioned that it was possible to have a character quote a character quoting another character. Can you represent this third-level quote in JavaScript? How would you solve this problem? Remember that there are only two types of quotes, the (") and the ('). There is a solution to nest quotes deeper, good luck!
Feel free to drop me an email if you have any questions or would just like to chat about this topic. My email address is . If you are a beginner to JavaScript, please give me some feedback. Let me know if I have completely confused you. Have I cleared up any misconceptions you may have had and helped you see the light? Let me know.
Thank you,
James Mortensen
UPDATE: The article, Nested-Nested Quotes, describes the concept of nested quotes even deeper using real code and provides the solution to this problem!
Labels:
Gmail,
Greasemonkey,
HTML Signatures
Tuesday, February 27, 2007
Gmail HTML Reply Signatures
NOTE: See Multiple HTML Reply Signatures for Gmail for an update on this script.
Greasemonkey is a Firefox Extension that I recently discovered while I was searching for a way to automatically embed HTML image signatures inside of a Gmail thin client. There is a large pool of solutions to this problem on the Internet that range from dragging and dropping images into the Gmail compose window textbox to using a Greasemonkey script written by Garett Rogers.
However, none of the scripts that I found would insert the signature into a Gmail reply, only a blank email. After hours of searching, I went to Greasemonkey's Web site and found a free online book titled "Dive Into Greasemonkey". This is a great way to learn how to write your own Greasemonkey scripts!
From there, I installed Firebug, a Firefox Extension DOM Inspector, and used this tool to try and determine exactly what tag id corresponded to the reply email text editor. After some trial and error, I found id attributes labelled hc_0, hc_1, hc_2, which correspond to each conversation in a thread. For instance, the first reply in a series of emails is labelled hc_0. If I respond to it and then receive another reply, it is labelled hc_1. Thus, for the N'th reply, the id attribute is hc_N. However, my script only handles the first 5 replies.
If you would like to add your signatures to your replies, complete the following steps:
1. Install Firefox, if you haven't already done so.
2. Install Greasemonkey, if you haven't already done so.
3. Download the "Gmail HTML Reply Signatures" script. Greasemonkey will prompt you to install the script.
4. Go to http://www.signaturegenerator.net to create a free image signature.
My next experiment will be to attempt to use Greasemonkey to manipulate the Google Docs and Spreadsheet interface in order to add more shortcut keys to the interface. Another option is to use a Firefox Extension called iMacros to record a left-click of the Google Docs "File" button. I tried this, and it was successful; however, iMacros is missing what I consider to be an important feature: I need to be able to create a toolbar button for the macro which can also be activated by using a shortcut key. Perhaps this will be yet another experiment.
Until next time,

P.S. You can create a similar signature image for free at http://www.signaturegenerator.net, which I listed above in step 4.
Greasemonkey is a Firefox Extension that I recently discovered while I was searching for a way to automatically embed HTML image signatures inside of a Gmail thin client. There is a large pool of solutions to this problem on the Internet that range from dragging and dropping images into the Gmail compose window textbox to using a Greasemonkey script written by Garett Rogers.
However, none of the scripts that I found would insert the signature into a Gmail reply, only a blank email. After hours of searching, I went to Greasemonkey's Web site and found a free online book titled "Dive Into Greasemonkey". This is a great way to learn how to write your own Greasemonkey scripts!
From there, I installed Firebug, a Firefox Extension DOM Inspector, and used this tool to try and determine exactly what tag id corresponded to the reply email text editor. After some trial and error, I found id attributes labelled hc_0, hc_1, hc_2, which correspond to each conversation in a thread. For instance, the first reply in a series of emails is labelled hc_0. If I respond to it and then receive another reply, it is labelled hc_1. Thus, for the N'th reply, the id attribute is hc_N. However, my script only handles the first 5 replies.
If you would like to add your signatures to your replies, complete the following steps:
1. Install Firefox, if you haven't already done so.
2. Install Greasemonkey, if you haven't already done so.
3. Download the "Gmail HTML Reply Signatures" script. Greasemonkey will prompt you to install the script.
4. Go to http://www.signaturegenerator.net to create a free image signature.
My next experiment will be to attempt to use Greasemonkey to manipulate the Google Docs and Spreadsheet interface in order to add more shortcut keys to the interface. Another option is to use a Firefox Extension called iMacros to record a left-click of the Google Docs "File" button. I tried this, and it was successful; however, iMacros is missing what I consider to be an important feature: I need to be able to create a toolbar button for the macro which can also be activated by using a shortcut key. Perhaps this will be yet another experiment.
Until next time,

P.S. You can create a similar signature image for free at http://www.signaturegenerator.net, which I listed above in step 4.
Labels:
Gmail,
Greasemonkey,
HTML Signatures
Subscribe to:
Posts (Atom)
