extension.js

Summary

JavaScript code for controlling the Mozile Extension. This is one of the few files which does not appeaar in Mozile Server-Side.

Version: 0.7

Author: James A. Overton


Class Summary
MozileExtension

/* ***** BEGIN LICENSE BLOCK *****
 * Licensed under Version: MPL 1.1/GPL 2.0/LGPL 2.1
 * Full Terms at http://mozile.mozdev.org/license2.html
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is James A. Overton's code (james@overton.ca).
 *
 * The Initial Developer of the Original Code is James A. Overton.
 * Portions created by the Initial Developer are Copyright (C) 2005-2006
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *	James A. Overton <james@overton.ca>
 *
 * ***** END LICENSE BLOCK ***** */

/** 
 * @fileoverview JavaScript code for controlling the Mozile Extension. This is one of the few files which does not appeaar in Mozile Server-Side.
 * @link http://mozile.mozdev.org 
 * @author James A. Overton <james@overton.ca>
 * @version 0.7
 */
var mozileVersion = "0.7.3";
var mozileScriptSource = "chrome://mozile/content/";

// Define the default XHTML namespace to use in XML documents
var XHTMLNS = "http://www.w3.org/1999/xhtml";

var mozileEnhancementList = "getClipboard;setClipboard";
var mozileEnhancementCode = [
	"this.setSharedData('clipboard', mozile.getModule('CopyCutPaste').getClipboard())",
	"mozile.getModule('CopyCutPaste').setClipboard(this.getSharedData('clipboard')); this.setSharedData('clipboard', '')"
];

for(var i=0; i < mozileEnhancementCode.length; i++) {
	mozileEnhancementCode[i] = escape(mozileEnhancementCode[i]);
}



// Set initial preferences
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var mozilePrefs = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefService).getBranch(null);	

try { mozilePrefs.getCharPref("mozile.version") }
catch(e) { mozilePrefs.setCharPref("mozile.version", mozileVersion); }
if(mozilePrefs.getCharPref("mozile.version") != mozileVersion) {
	mozilePrefs.setCharPref("mozile.version", mozileVersion);
	mozilePrefs.setCharPref("mozile.enhancementList", mozileEnhancementList);
	mozilePrefs.setCharPref("mozile.enhancementCode", mozileEnhancementCode.join(";") ); 
}

try { mozilePrefs.getBoolPref("mozile.caretAlwaysOn"); }
catch(e) { mozilePrefs.setBoolPref("mozile.caretAlwaysOn",false); }

try { mozilePrefs.getCharPref("mozile.debugLevel"); }
catch(e) { mozilePrefs.setCharPref("mozile.debugLevel","0"); }

try { mozilePrefs.getBoolPref("mozile.neverWarn"); }
catch(e) { mozilePrefs.setBoolPref("mozile.neverWarn",false); }

try { mozilePrefs.getIntPref("mozile.updateInterval"); }
catch(e) { mozilePrefs.setIntPref("mozile.updateInterval", 100); }
var mozileTimeout = mozilePrefs.getIntPref("mozile.updateInterval");

try { mozilePrefs.getCharPref("mozile.enhancementList"); }
catch(e) { 
	mozilePrefs.setCharPref("mozile.enhancementList", mozileEnhancementList);
	mozilePrefs.setCharPref("mozile.enhancementCode", mozileEnhancementCode.join(";") ); 
}

try { mozilePrefs.getCharPref("mozile.trustedSites"); }
catch(e) { mozilePrefs.setCharPref("mozile.trustedSites",""); }

try { mozilePrefs.getCharPref("mozile.autoEnhanceSites"); }
catch(e) { mozilePrefs.setCharPref("mozile.autoEnhanceSites",""); }



/**
 * The object which controls the Mozile Extension.
 * @constuctor
 */
function MozileExtension() { }

/** 
 * Get an attribute from the core.js script tag.
 * @param {String} attribute The attribute name.
 * @type String
 */
MozileExtension.prototype.getSharedData = function(attribute) {
	var target = document.commandDispatcher.focusedWindow;
	if(!target || !target.document.getElementById("Mozile-Core-core.js")) return undefined;
	if(target.document.getElementById("Mozile-Core-core.js").hasAttribute(attribute)) {
		var value = target.document.getElementById("Mozile-Core-core.js").getAttribute(attribute);
		return unescape(value);
	}
	else return undefined;
}

/** 
 * Set an attribute from the core.js script tag. 
 * @param {String} attribute
 * @param {String} value
 * @type String
 */
MozileExtension.prototype.setSharedData = function(attribute, value) {
	var target = document.commandDispatcher.focusedWindow;
	if(value=="") target.document.getElementById("Mozile-Core-core.js").removeAttribute(attribute);
	else target.document.getElementById("Mozile-Core-core.js").setAttribute(attribute, escape(value));
 	return value;
}

/** 
 * Checks for changes to the attributes. 
 * @type Void
 */
MozileExtension.prototype.watchSharedData = function() {
	var target = document.commandDispatcher.focusedWindow;
	if(target && target.mozileEnhancement && target.mozileEnhancement == "injected" && this.getSharedData("status") == "loaded") {
		this.preloadInterfaces();
	}
	
	if(!this.mozileEnhanced()) return;
	
	if(this.getSharedData("clientRequest")) {
		this.safeEval(this.getSharedData("clientRequest"));
		this.setSharedData("clientRequest", "");
	}
}


/** 
 * Checks for changes to the attributes.
 * @type Boolean
 */
MozileExtension.prototype.safeEval = function(requestCode) {
	var handlerNames = mozilePrefs.getCharPref("mozile.enhancementList").split(";");
	for(var i=0; i < handlerNames.length; i++) {
		if(handlerNames[i] == requestCode) break;
	}
	if(i >= handlerNames) return false;
	
	var handlerCode = mozilePrefs.getCharPref("mozile.enhancementCode").split(";");
	eval(unescape(handlerCode[i]));
	
	this.setSharedData("serverReply", requestCode);
	return true;
}


/**
 * True if the "mozile" object is defined in the target document, and false otherwise.
 * @type Boolean
 */
MozileExtension.prototype.mozileDefined = function() {
	var target = document.commandDispatcher.focusedWindow;
	if(target.document.getElementById("Mozile-Core-core.js")) return true;
	else return false;
}

/**
 * True if the "mozile" object has been enhanced, and false otherwise.
 * @type Boolean
 */
MozileExtension.prototype.mozileEnhanced = function() {
	var target = document.commandDispatcher.focusedWindow;
	if(target && target.mozileEnhancement && target.mozileEnhancement == "enhanced") return true;
	//if(this.getSharedData("enhanced")=="true") return true;
	else return false;
}

/**
 * True if the "mozile" object in the target document isEditable(), and false otherwise.
 * @type Boolean
 */
MozileExtension.prototype.mozileIsEditable = function() {
	if(this.getSharedData("editable")=="true") return true;
	else return false;
}

/**
 * True if the "mozile" object in the target document has option "activateOnFocus" set to true, and false otherwise.
 * @type Boolean
 */
MozileExtension.prototype.mozileActivateOnFocus = function() {
	if(this.getSharedData("activateOnFocus")=="true") return true;
	else return false;
}



var mozileLastDocument;
/**
 * A listener for focus, click, and keydown events. Checks the focussed document for Mozile, shows or hides the caret, and updates the status of the toolbar button (if present).
 * @type Void
 */
MozileExtension.prototype.update = function(event) {
	var target = document.commandDispatcher.focusedWindow;

	if(mozileExtension.getSharedData("editing")=="true") mozile.showCaret();
	else mozile.hideCaret();

	var editButton = document.getElementById("mozileEditButton");
	if(!editButton) return;
	
	var startEditingButton = document.getElementById("mozileStartEditingButton");
	var stopEditingButton = document.getElementById("mozileStopEditingButton");
	var enhanceEditingButton = document.getElementById("mozileEnhanceEditingButton");

	if(target!=window && mozileExtension.mozileDefined()) {
		if(mozileExtension.mozileIsEditable() || mozileExtension.mozileActivateOnFocus()) {
			editButton.setAttribute("status", "editing");
			editButton.setAttribute("next", "enhanced");
			startEditingButton.collapsed = true;
			stopEditingButton.collapsed = false;
		}
		else {
			editButton.setAttribute("status", "stopped");
			editButton.setAttribute("next", "editing");
			startEditingButton.collapsed = false;
			stopEditingButton.collapsed = true;
		}
		
		if(mozileExtension.mozileEnhanced()) {
			enhanceEditingButton.collapsed = true;
			if(mozileExtension.mozileIsEditable()) editButton.setAttribute("status", "enhanced");
			else editButton.setAttribute("next", "enhanced");
		}
		else {
			enhanceEditingButton.collapsed = false;
		}
	}
	else {
		editButton.setAttribute("status", "read");
		editButton.setAttribute("next", "editing");
		startEditingButton.collapsed = false;
		stopEditingButton.collapsed = true;
		enhanceEditingButton.collapsed = false;
	}
	
	if(editButton.getAttribute("next")=="editing")
		editButton.setAttribute("tooltiptext", "Edit this page with Mozile");
	else if(editButton.getAttribute("next")=="enhanced")
		editButton.setAttribute("tooltiptext", "Enhance the Mozile editor on this page");
	if(editButton.getAttribute("status")=="stopped")
		editButton.setAttribute("tooltiptext", "Start editing this page with Mozile");
	
	return;
}


	
/**
 * Checks the state of mozile editing, and upgrades it.
 * @type Void
 */
MozileExtension.prototype.activate = function(event, enhance) {
	if(!this._editButton) this._editButton = document.getElementById("mozileEditButton");
	if(event && enhance==undefined && event.target != this._editButton) return;
	
	var target = document.commandDispatcher.focusedWindow;
	if(!this.mozileDefined()) this.editPage();
	else if(!this.mozileIsEditable() && !this.mozileActivateOnFocus()) this.startEditing();
	else if(!this.mozileEnhanced()) this.checkForEnhance();
	if (enhance) this.checkForEnhance();
	
	//window.setTimeout("document.commandDispatcher.focusedWindow.wrappedJSObject.mozile.startEditing(); mozileExtension.update()", mozileTimeout);
}


/**
 * Inserts the "mozile.js" configuration file into the page, much like the code in "mozile.js" does itself.
 * @type Void
 */
MozileExtension.prototype.editPage = function() {
	var target = document.commandDispatcher.focusedWindow;
	var host = target.document.location.host;
	if(target.document.location.protocol == "file:") host = "local files";

		// Build the script tag
	var scriptTag = target.document.createElementNS(XHTMLNS,"script");
	scriptTag.setAttribute("id","Mozile-Core-mozile.js");
	scriptTag.setAttribute("type","application/x-javascript");
	scriptTag.setAttribute("src", mozileScriptSource +"extension/mozile.js");
		
		// For HTML insert the tag in the head, otherwise at the beginning of the documentElement
	if(target.document.documentElement.tagName.toLowerCase() == "html") target.document.getElementsByTagName("head")[0].appendChild(scriptTag);
	else target.document.documentElement.insertBefore(scriptTag, target.document.documentElement.firstChild);
	
		// Check to see if the site should be automatically enhanced
	var autoEnhanceSites = mozilePrefs.getCharPref("mozile.autoEnhanceSites").split(";");
	for(i in autoEnhanceSites) {
		if(host == autoEnhanceSites[i]) {
			window.setTimeout("mozileExtension.checkForEnhance(true)", mozileTimeout);
			break;
		}
	}
	
	target.mozileEnhancement = "injected";
	this.update();
}

/**
 * Loads the mozileInterfaces on the "mozileInterfaces" list into the document, then tries to hide them or delete them.
 * @type Void
 */
MozileExtension.prototype.preloadInterfaces = function() {
	//var target = document.commandDispatcher.focusedWindow.wrappedJSObject;
	var target = document.commandDispatcher.focusedWindow;
	var body = target.document.documentElement;
	if(target.document.documentElement.tagName.toLowerCase()=="html") 
		body = target.document.getElementsByTagName("body")[0];
	
	var xmlDoc, loaded, element;
	for (var i=0; i < mozile._interfaces.length; i++) {
		xmlDoc = mozile.document.implementation.createDocument("", "", null);
		xmlDoc.async = false;
		loaded = xmlDoc.load(mozileScriptSource+mozile._interfaces[i]["source"]);
		element = body.appendChild(xmlDoc.documentElement);
		element.collapsed = true;
		//try {	eval("target."+ mozile._interfaces[i]["access"] +".hide()"); }
		//catch(e) { body.removeChild(element); }
	}
	
	this.setSharedData("serverRequest", "mozile._cleanUpInterfaces()");
	target.mozileEnhancement = "loaded";
}



/**
 * Overrides functions in the document with functions from the extension. Does so for each function in the mozile.enhancedFunctionsList preference.
 * @type Void
 */
MozileExtension.prototype.enhancePage = function() {
	var target = document.commandDispatcher.focusedWindow;
	target.mozileEnhancement = "enhanced"; // should not be visibile within the content
	this.setSharedData("enhancement", mozilePrefs.getCharPref("mozile.enhancementList"));
	this.setSharedData("serverRequest", "mozile.showToolbar()");
	this.update();
}



/**
 * Tells the Mozile editor in the page to start editing.
 * @type Void
 */
MozileExtension.prototype.startEditing = function() {
	if(this.mozileDefined()) {
		this.setSharedData("editable", "true");
	}
	else this.activate();
	this.update();
}

/**
 * Tells the Mozile editor in the page to stop editing.
 * @type Void
 */
MozileExtension.prototype.stopEditing = function() {
	if(this.mozileDefined()) {
		this.setSharedData("editable", "false");
		this.setSharedData("activateOnFocus", "false");
	}
	this.update();
}




/**
 * Check to see if Mozile should enhance the page.
 * @type Void
 */
MozileExtension.prototype.checkForEnhance = function(auto) {
	if(mozilePrefs.getBoolPref("mozile.neverWarn")) {
		this.enhancePage();
		return;
	}

	var target = document.commandDispatcher.focusedWindow;
	var host = target.document.location.host;
	if(target.document.location.protocol == "file:") host = "local files";
	
		// Check to see if the site is on the white list. If it is, then enhance.
	var trustedArray = mozilePrefs.getCharPref("mozile.trustedSites").split(";");
	for(i in trustedArray) {
		if(host == trustedArray[i]) {
			this.enhancePage();
			return;
		}
	}
	
	if(!auto) auto = false;

		// Ask the user about enhancing the page.
	window.openDialog("chrome://mozile/content/extension/warning.xul", "Mozile Warning", "chrome", host, auto);
}


var mozileExtension = new MozileExtension();
mozileExtension._watchInterval = window.setInterval("mozileExtension.watchSharedData()", mozileTimeout);


// Listen for these events, and check to see if Mozile is loaded.

document.addEventListener("focus", mozileExtension.update, false);
document.addEventListener("button", mozileExtension.update, false);
//document.addEventListener("click", mozileExtension.update, false);
document.addEventListener("keydown", mozileExtension.update, false);
document.addEventListener("keyup", mozileExtension.update, false);
document.addEventListener("mouseup", mozileExtension.update, false);
document.addEventListener("mousemove", mozileExtension.update, false);



Documentation generated by JSDoc on Thu Feb 16 20:20:37 2006