Firefox Add-on SDK code set that creates a context (right-click) menu item allowing the user to select any text and download it to a file on the desktop.  The filename is fixed (“OnlineNotes.html), but you as Super Developer can change that functionality!  Please note that this idea is mostly lifted from the FF tutorials; most changes I made were to fit it to my purposes, with little creative addition beyond that.

This is specialized code for a small project, so would need some work to be universally capable.  You will need to know or learn how to create and install a script to make this work.

Main code, stored in {your addon dir}/lib/main.js

exports.main = function (options, callbacks) {
   // load the context menu script. (Is part of the Firefox SDK.)
   var contextMenu = require("context-menu");
   // reference and store the local directory "data"
   // element-getter.js is stored in this directory
   var data = require("self").data;

   var fileMgr = require("fileMgr-test.js");

   contextMenu.Item({
      // name that appears in the right-click menu
      label: "Take a note.",
      // only show this menu item when something is selected
      context: contextMenu.SelectionContext(),
      // show this menu item after the entire page is loaded.  
      // This may take a while at times, and may make the user wonder where the menu item is.
      contentScriptWhen : "ready",
      // load this script onto the page (stored in the {local}/data directory).
      contentScriptFile : [data.url('element-getter.js')],
      // when a message is sent (from the page to the menu item), run this
      // elementContent = a JSON object with image name, URL, author, and copyright data
      onMessage: function (elementContent) {
         // record some info to the console -- run this script from the command line to see this data
         // console.log( elementContent );
         // save the image info
         fileMgr.saveText( elementContent, "OnlineNotes.html" );
      }
   });
}

.

Context menu functions, stored in {your addon dir}/lib/fileMgr-test.js

'use strict';

// super powerful Component script.  Allows access to everything a browser can access.
// As noted by Firefox, this is experimental, and may change or be removed in the future.
var {Cc, Ci, Cm, Cr, Cu} = require("chrome");

// joins an array with a single-quote and comma
var joinQuoted = function(arr){
   return arr.map(function(elem){
         // This will wrap each element of the array with quotes
         return "'" + elem + "'";
      }).join(","); // This puts a comma in between every element
};

// make joinQuoted a public function that other scripts can use
exports.joinQuoted = joinQuoted;

// save (create, else append) textJSON to the outFile
// This function is public to other scripts.
// NOTE:  The text in the file is an array of arrays, but it will not have a closing bracket.  This will have to be added manually.
exports.saveText = function(textJSON, outFile) {
   // netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');

   // load file stuff
   Cu.import("resource://gre/modules/FileUtils.jsm");

   // join textJSON array with quotes
   // var joinedText = ",[" + joinQuoted(textJSON) + "]";
   var joinedText = textJSON;
   // console.log("saveText.text = " + joinedText);

   // create a new file reference to the OS's current desktop directory
   var file = Cc["@mozilla.org/file/directory_service;1"].
           getService(Ci.nsIProperties).
           get("Desk", Ci.nsIFile);
   // reference a specific file for appending data
   file.append(outFile);

   console.log("intended file.path: " + file.path);

   // create the file if it doesn't exist
   if ( file.exists() == false ) {
      // console.log( "Creating file: " + file.path );
      file.create( Ci.nsIFile.NORMAL_FILE_TYPE, 420 );

      // fix joinedText for the first entry
      // replace initial comma with opening bracket
      // NOTE:  The file will not have a closing bracket.  This will have to be added manually.
      // joinedText = "[" + joinedText.substring(1,joinedText.length);
      joinedText = 
         "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\"><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" /><title>Notes</title></head><body >"  
         + joinedText;
   }

   // create an output stream
   var outputStream = Cc["@mozilla.org/network/file-output-stream;1"]
      .createInstance( Ci.nsIFileOutputStream );

   // flags found here:  https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/FileUtils.jsm?redirectlocale=en-US&redirectslug=JavaScript_code_modules%2FFileUtils.jsm

   // initalize/start the output stream.
   // write only, create if non-existent (redundant), append (instead of overwriting)
   outputStream.init( file, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_APPEND, 420, 0 );
   // write joinedText to file
   var result = outputStream.write( joinedText, joinedText.length );
   // close the stream
   outputStream.close();   
};

.
Code added to the page content, stored in {your addon dir}/data/element-getter.js

// Get the text selected on the webpage.

// This javascript file is _not_ connected to the context (right-click) menu.  They are in two separate code areas.
// The only way this file can communicate with the context menu is "self.postMessage(info)", 
// where "info" is a JSON object.
self.on('click', function (node, data) {
   var text = window.getSelection().toString();

   console.log("saving text = " + text);

   text = "<div style=\"width: 515px; margin: 8px;\">\n\"" + text + "\"\n<br />&nbsp;&nbsp;&nbsp;&nbsp;<a href=\"" + document.URL + "\" target=\"_blank\">" + document.URL + "</a></div><p />\n" ;

   self.postMessage(text);
});
Advertisements