After the Deadline

A More Secure AtD Experience for the Browser

Posted in News by rsmudge on May 25, 2010

We’ve been hard at work and now AtD for Google Chrome 1.1 and AtD for Firefox 1.3 are now available. These updates feature an important addition for your security and privacy.

AtD started as a plugin for WordPress and everything it checked was going to be posted on a public blog anyways. Now that AtD is in the browser this has changed. To protect your information, both AtD/Chrome and AtD/Firefox now use SSL to communicate with the AtD service. This means your data is now encrypted when it’s sent to our service for proofreading.

If you’d like to know what else is new, you can read the change logs:

How to Update:

To update to the latest After the Deadline for Google Chrome, visit chrome://extensions and click Update Extensions Now. This will automatically download and install the update for you. No restart required.

To update to the latest After the Deadline for Firefox, visit Tools -> Add-ons and click Find Updates. This will download and install the update for you. Firefox will ask you to restart your browser.

Comments Off on A More Secure AtD Experience for the Browser

How to Jump Through Hoops and Make a Chrome Extension

Posted in Talking to myself by rsmudge on May 14, 2010

Last week, we released After the Deadline for Google Chrome. I like Chrome. It’s low on UI clutter and it’s very fast.

Chrome for the extension developer is a rapidly changing world. I wanted After the Deadline for Google Chrome to match our Firefox add-on feature for feature. I hit and overcame a few road blocks meeting this goal.

This blog post is highly technical and deals with some of the innards of writing Chrome extensions. If you’re not interested in this kind of stuff, then take note that I like Chrome, it’s not done yet, and this makes things hard at times. I’m working to bring the best possible proofreading experience to Google Chrome. You may stop reading now.

If you’re still here, that means you’re a developer. I hope this information helps you in your Chrome extension development adventure.

How to refer to internal images in CSS

Google Chrome, like Firefox, makes extension resources available via a special URL. In Firefox, you set the identifier for your extension and can reference images and other resources using this URL. In Google Chrome this  URL depends on your extension’s ID. This extension ID changes depending on whether the extension is loaded as loose files or packaged. Because of this, you should not hard code the URL to an extension resource in your CSS file.

So how can one refer to internal images or other resources in a CSS file?

One option is to avoid referring to internal images or resources at all. You can set CSS properties using JavaScript and chrome.extension.getUrl(‘resource.ext’). This is kind of hacky and I didn’t want to set and unset hover listeners just to do something CSS already gives me for free.

Another option, discovered in this thread, is to convert your images to base64 and embed them as data URLs in your CSS file. It’s an extra step in the beginning but it solves the problem of referring to internal images.

div.afterthedeadline-button
{
background: url(data:image/png;base64,data goes here) transparent no-repeat top left !important;

Once this hack is in place, you won’t have to worry about extension IDs in your CSS files again.

Good luck with those IFRAMEs

Content scripts (Chrome JS extensions) run in a sandbox separate of the environment scripts attached to a page see. This is good as it reduces the possibility of extensions conflicting with web applications. Content scripts see the same DOM that user scripts see. It is possible to make changes to the DOM and inspect it. I recommend that you read the Chrome extension tutorial and watch Google’s video to understand content scripts.

Unfortunately, Google left a few toys out of the sandbox. It’s nearly impossible to work with an IFRAME. The contentWindow property of any IFRAME DOM element is null. Also window.frames is empty. This is a known bug.

Thankfully, the contentDocument.documentElement property does exist. Through this I can set and get the contents of an IFRAME. That’s close to what I want, but not exact. To proofread an editor, After the Deadline creates an editable DIV and copies style information from the editor to this new DIV. To make this convincing for IFRAMES, I have a need to access style information from the contentWindow property.

I tried to make a content script that figures out if it’s attached to an IFRAME. If it is, the script could communicate the needed information to the extension background script via Chrome’s message passing mechanism.

Unfortunately this didn’t work because Chrome only allows scripts to attach to URLs that have an http:// or https:// scheme. Dynamically generated IFRAMEs used by WYSIWYG editors usually have an empty source attribute which does not match an http:// or https:// scheme.

This thread suggests adding a SCRIPT tag to the DOM to execute a script outside the Chrome extension sandbox. However this isn’t necessarily a straight forward process either.

Execute a Script Outside the Chrome Sandbox

The Chrome extension sandbox exists to protect user scripts from extension scripts and vice versa. It would also be dangerous if a malicious user-land script could get into the Chrome sandbox and manipulate the Chrome extension APIs. For these reasons, it’s natural that Google Chrome would discourage extensions from running scripts outside the sandbox. I tried to insert a SCRIPT tag with a SRC attribute into the site’s DOM using jQuery. This didn’t work.

What did work was injecting inline JavaScript that constructs a SCRIPT tag with a SRC attribute from the site’s DOM. Here is the code:

jQuery('body').append('<script type="text/javascript">(function(l) { 
   var res = document.createElement('SCRIPT'); 
   res.type = 'text/javascript'; 
   res.src = l; 
   document.getElementsByTagName('head')[0].appendChild(res); 
})('"+chrome.extension.getURL("scripts/inherit-style.js");</script>');

You’ll want to replace chrome.extension.getURL('scripts/inherit-style.js') with your resource. This is a convenient way to execute code outside of the extension sandbox.

Beware of WebKit Specific Styles

To make my proofreader look pretty, I inherit as many style properties as I can from the original editor. Mitcho showed me this great trick to copy the styles of one element to another:

var css = node.defaultView.getComputedStyle(node, null);
for (var i = 0; i < css.length; i++) {
    var property = css.item(i);
    /* note that I'm assuming jQuery here, proofreader is the note inheriting the property */
    proofreader.css(property, css.getPropertyValue(property));
}

This trick works fine in Chrome, except I found myself scratching my head when some DIVs were editable even though their contentEditable attribute was undefined. The opposite also held true, sometimes my DIV was not editable even though I defined the contentEditable attribute as true. I learned that WebKit has a CSS property -webkit-user-modify that trumps this attribute.

It’s unlikely you’ll ever encounter this, but one day, someone will do a google search, find this post, and I’ll have given them three hours of life they would have lost otherwise.

Final Thoughts

I like Chrome. It’s a good browser. The world of Chrome extensions is changing and expanding rapidly. On one hand, extensions can’t do simple stuff yet, like add items to the context menu. On the other hand, this is being worked on.

Now for the final hoop. There are three distributions of Google Chrome. These are the stable channel, beta channel, and the developer channel. I started out developing in the developer channel and later downgraded to the beta channel as I continued my development. This was a mistake. There are big differences between the stable channel and beta channels. For example, browser actions (toolbar buttons) are allowed to have popup menus. These popups work in the beta channel (5.x) but not in the stable channel (4.x).

Before you release, be aware of these differences. I recommend developing against the stable channel. If you rely on features from a new version, implement them and then verify that your extension degrades nicely on the old version of Chrome. That’s it.

If you’re willing to jump through some hoops you can make a great Chrome extension. I found the Chrome extension mailing list very helpful.

Thanks to Google and the Chromium community for developing a great browser. I’m ok with jumping through a few hoops.

After the Deadline for Firefox – Released

Posted in Firefox addon, News by rsmudge on February 1, 2010

We received addons.mozilla.org approval of After the Deadline recently and we’re pleased to announce the release of the After the Deadline add-on for Firefox.

After the Deadline works in text areas on most webpages. Simply push a button (F7) or click to check your spelling, style, and grammar no matter where you are.

This add-on has all the After the Deadline features. You can enable the style checker options you use in the preferences and you can ignore errors to prevent them from coming up.

Links of interest:

After the Deadline is an open source proofreading technology. You can also embed it into web applications using TinyMCE, jQuery, and CKEditor.

Coming Soon: Firefox Add-on

Posted in Firefox addon, News by mitcho (Michael 芳貴 Erlewine) on January 14, 2010

After the Deadline already can be easily embedded and can travel with you as a bookmarklet, but what if you could have After the Deadline’s superior grammar and spell check incorporated into the browser? We’re going to make this happen with the After the Deadline Firefox add-on. The Firefox add-on will let you use After the Deadline on web forms across the web, while providing the clean integration only possible through an add-on.

While there is still much work to be done on the add-on, a very early-stage beta of the add-on is now available for download. Please install the add-on and give it a try! If you find a bug or have a feature request, please post it to our trac bug tracker or email us. We’ll look forward to hearing your feedback!

Tagged with: