emacs-moz-controller: View Page Source

I’ve added a new functionality to emacs-moz-controller: with some simple configurations, you can press C-c m u in Emacs to view the source of the current Firefox page.

1 Instructions

  • The changes have been pushed to Github (b94d496), you need to install this version or later.
  • If you want to view the source in Emacs, please follow 2.2.
  • If you are a KeySnail user, the default keyboard shortcut for View Page Source ( C-u ) is overwritten. You can bind it to C-c C-u, please follow the instructions in issue#146 or 2.3.

2 Hack Log

2.1 Emacs Controls Firefox to “View Page Source”

I opened an issue on KeySnail’s Github repo but didn’t receive any reply. So I have to hack it myself.

Googling, Baiduing and Ducking don’t give me much useful information.

“A voice echoed: READ THE SOURCE, LUKE” (see DMC4 Wikiquotes and Learn to Read the Source, Luke)

hg clone firefox source code, almost 2.5G, huge.

ag (a searching tool) “view page source” in the code repo, got two results:

browser/metro/locales/en-US/chrome/browser.dtd:22:41:<!ENTITY appbarViewPageSource.label    "View page source">
browser/locales/en-US/chrome/browser/browser.dtd:419:40:<!ENTITY viewPageSourceCmd.label      "View Page Source">

Then ag “viewPageSourceCmd.label” and got:

browser/base/content/browser-context.inc:366:25:                label="&viewPageSourceCmd.label;"

Read browser/base/content/browser-context.inc :

<menuitem id="context-viewsource"
          label="&viewPageSourceCmd.label;"
          accesskey="&viewPageSourceCmd.accesskey;"
          oncommand="BrowserViewSourceOfDocument(gContextMenu.browser.contentDocument);"
          observes="isImage"/>

It seems to me that the command is BrowserViewSourceOfDocument(gContextMenu.browser.contentDocument)

But evaluating BrowserViewSourceOfDocument(gContextMenu.browser.contentDocument) in MozRepl gives me:#

!!! TypeError: gContextMenu is null

Trial and error, trail and error… (MozRepl doesn’t have auto-completion, annoying) and find the following command:

BrowserViewSourceOfDocument(gBrowser.contentDocument);

2.2 View Page Source with emacsclient

I’d like to view page source in Emacs and I guess this is a “common” need for Emacs users. Googling gives me this article http://grok.lsu.edu/Article.aspx?articleId=12278, which solved the problem.

Get into about:config and make two changes:

  • view_source.editor.external => true
  • view_source.editor.path => /usr/local/bin/emacsclient (path of emacsclient)

2.3 Firefox Keyboard Shortcut

I have KeySnail installed in my Firefox, so C-u is overwritten. Now I know what command is associated with View Page Source, so I should be able to bind a new keyboard shortcut for it in KeySnail.

Open .keysnail and add the following code snippet:

key.setGlobalKey(['C-c', 'C-u'], function (ev) {
    BrowserViewSourceOfDocument(gContextMenu.browser.contentDocument);
}, 'View page source', false);

Reload Keysnail’s configuration file, press C-c C-u , but there is no effect.

Change gContextMenu.browser to gBrowser and give it go:

key.setGlobalKey(['C-c', 'C-u'], function (ev) {
    BrowserViewSourceOfDocument(gBrowser.contentDocument);
}, 'View page source', false);

Reload, try, still no effect.

Browse .keysnail and find that getBrowser() is used in many places. Hmm, have a try:

key.setGlobalKey(['C-c', 'C-u'], function (ev) {
    BrowserViewSourceOfDocument(getBrowser().contentDocument);
}, 'View page source', false);

Reload, C-c C-u, the source code is opened in Emacs, it works!

2.4 Add the Changes to moz-controller

Use macro defun-moz-controller-command to define a new command:

(defun-moz-controller-command moz-controller-view-page-source ()
  "View current page source code."
  "BrowserViewSourceOfDocument(gBrowser.contentDocument);"
  )

Add a new keyboard shortcut in keymap:

(define-key moz-controller-map (kbd "C-c m u") 'moz-controller-view-page-source)

The whole diff:

diff --git a/moz-controller.el b/moz-controller.el
index 72d8121..09876f6 100644
--- a/moz-controller.el
+++ b/moz-controller.el
@@ -111,6 +111,11 @@ BODY: the desired JavaScript expression, as a string."
   "getBrowser().mTabContainer.advanceSelectedTab(1, true);"
   )

+(defun-moz-controller-command moz-controller-view-page-source ()
+  "View current page source code."
+  "BrowserViewSourceOfDocument(gBrowser.contentDocument);"
+  )
+
 (unless moz-controller-mode-map
   (setq moz-controller-mode-map
         (let ((moz-controller-map (make-sparse-keymap)))
@@ -123,6 +128,7 @@ BODY: the desired JavaScript expression, as a string."
           (define-key moz-controller-map (kbd "C-c m +") 'moz-controller-zoom-in)
           (define-key moz-controller-map (kbd "C-c m -") 'moz-controller-zoom-out)
           (define-key moz-controller-map (kbd "C-c m 0") 'moz-controller-zoom-reset)
+          (define-key moz-controller-map (kbd "C-c m u") 'moz-controller-view-page-source)
           moz-controller-map)))

 ;;;###autoload

Add instructions in the README and push the changes to Github.

Done, happy hacking!