- Implemented singleton XPCOM component to store core Scholar objects

More details coming on Basecamp: http://chnm.grouphub.com/W161222

*** Important note: after checking out this code, be sure to delete the compreg.dat and xpti.dat files in your FF profile directory or else the extension will not load. They'll be regenerated when you start FF again, and you won't have to do it again unless we add interfaces or other components. Once I set up the XPI packaging system, this step won't be necessary. ***

- Localization properties are now loaded directly via nsIStringBundleService and available via Scholar.getString(name) -- removed stringbundle from XUL

- Updated status line in bottom right to reflect whether Scholar is loaded correctly or not (temporary, obviously)
This commit is contained in:
Dan Stillman 2006-05-27 00:20:27 +00:00
parent a531966a2c
commit f09def19f7
8 changed files with 171 additions and 41 deletions

View file

@ -1,6 +1,5 @@
var Scholar_browserWindow = Components.classes["@mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator)
.getMostRecentWindow("navigator:browser");
const SCHOLAR_CONFIG = Scholar_browserWindow.SCHOLAR_CONFIG;
var Scholar = Scholar_browserWindow.Scholar;
var Scholar = Components.classes["@chnm.gmu.edu/Scholar;1"]
// Currently uses only nsISupports
//.getService(Components.interfaces.chnmIScholarService).
.getService(Components.interfaces.nsISupports)
.wrappedJSObject;

View file

@ -11,29 +11,42 @@ const SCHOLAR_CONFIG = {
* Core functions
*/
var Scholar = new function(){
var _initialized = false
var _initialized = false;
var _localizedStringBundle;
this.testString = 'Sidebar is not registered';
this.LocalizedStrings;
// Privileged (public) methods
this.init = init;
this.debug = debug;
this.varDump = varDump;
this.getString = getString;
this.flattenArguments = flattenArguments;
this.join = join;
this.Hash = Hash;
/*
* Initialize the extension
*/
function init(){
this.LocalizedStrings = document.getElementById('scholar-strings');
if (!_initialized){
Scholar.DB.updateSchema();
_initialized = true;
return true;
if (_initialized){
return false;
}
return false;
Scholar.DB.updateSchema();
// Load in the localization stringbundle for use by getString(name)
var src = 'chrome://scholar/locale/scholar.properties';
var localeService =
Components.classes["@mozilla.org/intl/nslocaleservice;1"]
.getService(Components.interfaces.nsILocaleService);
var appLocale = localeService.getApplicationLocale();
var stringBundleService =
Components.classes["@mozilla.org/intl/stringbundle;1"]
.getService(Components.interfaces.nsIStringBundleService);
_localizedStringBundle = stringBundleService.createBundle(src, appLocale);
_initialized = true;
return true;
}
@ -117,6 +130,11 @@ var Scholar = new function(){
}
function getString(name){
return _localizedStringBundle.GetStringFromName(name);
}
/*
* Flattens mixed arrays/values in a passed _arguments_ object and returns
* an array of values -- allows for functions to accept both arrays of
@ -226,5 +244,3 @@ Scholar.Hash.prototype.remove = function(in_key){
Scholar.Hash.prototype.has = function(in_key){
return typeof(this.items[in_key]) != 'undefined';
}
window.addEventListener("load", function(e) { Scholar.init(e); }, false);

View file

@ -5,18 +5,21 @@
<overlay id="scholar"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script src="overlay.js"/>
<script src="db.js"/>
<script src="data_access.js"/>
<stringbundleset id="stringbundleset">
<stringbundle id="scholar-strings" src="chrome://scholar/locale/scholar.properties"/>
</stringbundleset>
<!-- Include the global XPCOM object -->
<script src="include.js"/>
<statusbar id="status-bar">
<statusbarpanel onclick="alert(Scholar.testString)" id="my-panel" label="&statusbarpanel.helloworld;"/>
<statusbarpanel id="scholar-load-status" label="Scholar is NOT loaded"/>
</statusbar>
<script>
window.addEventListener('load', function(e){
if (Scholar){
document.getElementById('scholar-load-status').setAttribute('label', 'Scholar is loaded');
}
}, false);
</script>
<menupopup id="menu_ToolsPopup">
<menuseparator id="scholarSeparator" insertbefore="devToolsSeparator"/>
<menuitem id="tools-scholar" insertbefore="devToolsSeparator"

View file

@ -13,7 +13,7 @@ function init()
for(var i = 0; i<itemTypes.length; i++)
{
var menuitem = document.createElement("menuitem");
menuitem.setAttribute("label",Scholar.LocalizedStrings.getString("itemTypes."+itemTypes[i]['name']));
menuitem.setAttribute("label", Scholar.getString("itemTypes."+itemTypes[i]['name']));
menuitem.setAttribute("oncommand","newItem("+itemTypes[i]['id']+")");
addMenu.appendChild(menuitem);
}

View file

@ -11,7 +11,7 @@
width="1000" height="700" screenX="20" screenY="20"
persist="width height screenX screenY sizemode"
windowtype="scholar:window"
onload="Scholar.init(); init();"
onload="init();"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/x-javascript" src="chrome://global/content/globalOverlay.js"/>
@ -19,21 +19,16 @@
<script type="application/x-javascript" src="chrome://global/content/nsTransferable.js"/>
<script type="application/x-javascript" src="chrome://browser/content/utilityOverlay.js"/>
<!-- Include these until we get a global XPCOM object: -->
<script src="overlay.js"/>
<script src="db.js"/>
<script src="data_access.js"/>
<!-- Include the global XPCOM object -->
<script src="include.js"/>
<script src="scholar.js"/>
<script src="treeView.js"/>
<stringbundleset id="stringbundleset"/>
<commandset id="baseMenuCommandSet" />
<keyset id="baseMenuKeyset" />
<keyset id="editMenuKeys"/>
<stringbundle id="scholar-strings" src="chrome://scholar/locale/scholar.properties"/>
<command id="cmd_close" oncommand="closeWindow(true);"/>
<command id="cmd_delete" oncommand="deleteSelection()"/>
<command id="cmd_scholar_newItem" oncommand="newItem(1);"/>

View file

@ -9,10 +9,8 @@
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
style="padding:2em">
<script src="../overlay.js"/>
<script src="../db.js"/>
<script src="../include.js"/>
<script src="test.js"/>
<label>I am a test page.</label>
<label></label>
</window>

View file

@ -1,5 +1,3 @@
<!ENTITY statusbarpanel.helloworld "Hello, World">
<!ENTITY items.title_column "Title">
<!ENTITY items.creator_column "Creator">
<!ENTITY items.source_column "Source">

View file

@ -0,0 +1,121 @@
const SCHOLAR_CONTRACTID = '@chnm.gmu.edu/Scholar;1';
const SCHOLAR_CLASSNAME = 'Firefox Scholar';
const SCHOLAR_CID = Components.ID('{e4c61080-ec2d-11da-8ad9-0800200c9a66}');
const SCHOLAR_IID = Components.interfaces.chnmIScholarService;
const Cc = Components.classes;
const Ci = Components.interfaces;
// Assign the global scope to a variable to passed via wrappedJSObject
var ScholarWrapped = this;
/********************************************************************
* Include the core objects to be stored within XPCOM
*********************************************************************/
Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader)
.loadSubScript("chrome://scholar/content/overlay.js");
Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader)
.loadSubScript("chrome://scholar/content/db.js");
Cc["@mozilla.org/moz/jssubscript-loader;1"]
.getService(Ci.mozIJSSubScriptLoader)
.loadSubScript("chrome://scholar/content/data_access.js");
/********************************************************************/
// Initialize the Scholar service
//
// This runs when ScholarService is first requested.
// Calls to other XPCOM components must be in here rather than in top-level
// code, as other components may not have yet been initialized.
function setupService(){
Scholar.init();
}
function ScholarService(){
this.wrappedJSObject = ScholarWrapped.Scholar;
setupService();
}
/**
* Convenience method to replicate window.alert()
**/
function alert(msg){
Cc["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Ci.nsIPromptService)
.alert(null, "", msg);
}
//
// XPCOM goop
//
ScholarService.prototype = {
QueryInterface: function(iid){
if (!iid.equals(Components.interfaces.nsISupports) &&
!iid.equals(SCHOLAR_IID)){
throw Components.results.NS_ERROR_NO_INTERFACE;
}
return this;
}
};
var ScholarFactory = {
createInstance: function(outer, iid){
if (outer != null){
throw Components.results.NS_ERROR_NO_AGGREGATION;
}
return new ScholarService().QueryInterface(iid);
}
};
var ScholarModule = {
_firstTime: true,
registerSelf: function(compMgr, fileSpec, location, type){
if (!this._firstTime){
throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
}
this._firstTime = false;
compMgr =
compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
compMgr.registerFactoryLocation(SCHOLAR_CID,
SCHOLAR_CLASSNAME,
SCHOLAR_CONTRACTID,
fileSpec,
location,
type);
},
unregisterSelf: function(compMgr, location, type){
compMgr =
compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
compMgr.unregisterFactoryLocation(SCHOLAR_CID, location);
},
getClassObject: function(compMgr, cid, iid){
if (!cid.equals(SCHOLAR_CID)){
throw Components.results.NS_ERROR_NO_INTERFACE;
}
if (!iid.equals(Components.interfaces.nsIFactory)){
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
}
return ScholarFactory;
},
canUnload: function(compMgr){ return true; }
};
function NSGetModule(comMgr, fileSpec){ return ScholarModule; }