closes #55, export bibliography to printable version

closes #4, Make printable version

- moves functions for creating and deleting hidden browser objects to scholar.js (from ingester.js), since these are necessary for printing as well
- allows saving bibliography in HTML or printing bibliography. style support is not yet complete (pending finalization of 0.9 version of CSL specification).
This commit is contained in:
Simon Kornblith 2006-07-27 23:01:55 +00:00
parent 1d03bf6b71
commit 6305e4cada
9 changed files with 203 additions and 27 deletions

View file

@ -0,0 +1,47 @@
//////////////////////////////////////////////////////////////////////////////
//
// Scholar_File_Interface_Bibliography
//
//////////////////////////////////////////////////////////////////////////////
// Class to provide options for bibliography
Scholar_File_Interface_Bibliography = new function() {
var _io;
this.init = init;
this.acceptSelection = acceptSelection;
/*
* Initialize some variables and prepare event listeners for when chrome is done
* loading
*/
function init() {
_io = window.arguments[0];
var listbox = document.getElementById("style-popup");
var styles = Scholar.Cite.getStyles();
var firstItem = true;
for(i in styles) {
var itemNode = document.createElement("menuitem");
itemNode.setAttribute("value", i);
itemNode.setAttribute("label", styles[i]);
listbox.appendChild(itemNode);
}
// select first item by default
document.getElementById("style-menu").selectedIndex = 0;
if(navigator.userAgent.toLowerCase().indexOf("mac") != -1) {
// hack to eliminate clipboard option for mac users
document.getElementById("output-radio").removeChild(document.getElementById("copy-to-clipboard"));
}
}
function acceptSelection() {
// collect code
_io.style = document.getElementById("style-menu").selectedItem.value;
_io.output = document.getElementById("output-radio").selectedItem.id;
}
}

View file

@ -0,0 +1,29 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE window SYSTEM "chrome://scholar/locale/scholar.dtd">
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&bibliography.title;" buttons="cancel,accept"
ondialogaccept="Scholar_File_Interface_Bibliography.acceptSelection()"
id="scholar-bibliography"
onload="Scholar_File_Interface_Bibliography.init()">
<script src="include.js"/>
<script src="bibliography.js"/>
<hbox>
<label value="&bibliography.style.label;" control="style-menu"/>
<menulist id="style-menu">
<menupopup id="style-popup">
</menupopup>
</menulist>
</hbox>
<groupbox>
<caption label="&bibliography.output.label;"/>
<radiogroup id="output-radio">
<radio id="save-as-html" selected="true" label="&bibliography.saveAsHTML.label;"/>
<radio id="copy-to-clipboard" label="&bibliography.copyToClipboard.label;"/>
<radio id="print" label="&bibliography.print.label;"/>
</radiogroup>
</groupbox>
</dialog>

View file

@ -1,6 +1,7 @@
Scholar_File_Interface = new function() {
this.exportFile = exportFile;
this.importFile = importFile;
this.bibliographyFromProject = bibliographyFromProject;
/*
* Creates Scholar.Translate instance and shows file picker for file export
@ -54,6 +55,16 @@ Scholar_File_Interface = new function() {
}
}
/*
* Creates a bibliography
*/
function bibliographyFromProject() {
var collection = ScholarPane.getSelectedCollection();
if(!collection) throw("error in bibliographyFromProject: no collection currently selected");
_doBibliographyOptions(Scholar.getItems(collection.getID()));
}
/*
* Saves items after they've been imported. We could have a nice little
* "items imported" indicator, too.
@ -61,4 +72,77 @@ Scholar_File_Interface = new function() {
function _importItemDone(obj, item) {
item.save();
}
/*
* Shows bibliography options and creates a bibliography
*/
function _doBibliographyOptions(items) {
var io = new Object();
var newDialog = window.openDialog("chrome://scholar/content/bibliography.xul",
"_blank","chrome,modal,centerscreen", io);
// generate bibliography
var bibliography = Scholar.Cite.getBibliography(io.style, items);
if(io.output == "print") {
// printable bibliography, using a hidden browser
var browser = Scholar.Browser.createHiddenBrowser(window);
browser.contentDocument.write(bibliography);
// this is kinda nasty, but we have to temporarily modify the user's
// settings to eliminate the header and footer. the other way to do
// this would be to attempt to print with an embedded browser, but
// it's not even clear how to attempt to create one
var prefService = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefBranch);
var prefsToClear = ["print.print_headerleft", "print.print_headercenter",
"print.print_headerright", "print.print_footerleft",
"print.print_footercenter", "print.print_footerright"];
var oldPrefs = new Array();
for(var i in prefsToClear) {
oldPrefs[i] = prefService.getCharPref(prefsToClear[i]);
prefService.setCharPref(prefsToClear[i], "");
}
// print
browser.contentWindow.print();
// set the prefs back
for(var i in prefsToClear) {
prefService.setCharPref(prefsToClear[i], oldPrefs[i]);
}
Scholar.Browser.deleteHiddenBrowser(browser);
bibliographyStream.close();
} else if(io.output == "save-as-html") {
// savable bibliography, using a file stream
const nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
.createInstance(nsIFilePicker);
fp.init(window, "Save Bibliography", nsIFilePicker.modeSave);
fp.appendFilters(nsIFilePicker.filterHTML);
var rv = fp.show();
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
// open file
var fStream = Components.classes["@mozilla.org/network/file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);
fStream.init(fp.file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
var html = "";
html +='<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n';
html +='<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">\n';
html +='<head>\n';
html +='<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />\n';
html +='<title>Bibliography</title>\n';
html +='</head>\n';
html +='<body>\n';
html += bibliography;
html +='</body>\n';
html +='</html>\n';
fStream.write(html, html.length);
fStream.close();
}
}
}
}

View file

@ -9,7 +9,7 @@ Scholar.Cite = new function() {
function getStyles() {
// TODO: return key/values from database
return ["American Psychological Association"];
return {1:"American Psychological Association"};
}
function getBibliography(style, items) {

View file

@ -4,21 +4,6 @@
Scholar.Ingester = new Object();
Scholar.Ingester.createHiddenBrowser = function(myWindow) {
// Create a hidden browser
var newHiddenBrowser = myWindow.document.createElement("browser");
var windows = myWindow.document.getElementsByTagName("window");
windows[0].appendChild(newHiddenBrowser);
Scholar.debug("created hidden browser");
return newHiddenBrowser;
}
Scholar.Ingester.deleteHiddenBrowser = function(myBrowser) {
// Delete a hidden browser
delete myBrowser;
Scholar.debug("deleted hidden browser");
}
/////////////////////////////////////////////////////////////////
//
// Scholar.Ingester.ProxyMonitor

View file

@ -522,4 +522,31 @@ Scholar.Date = new function(){
return false;
}
}
}
Scholar.Browser = new function() {
this.createHiddenBrowser = createHiddenBrowser;
this.deleteHiddenBrowser = deleteHiddenBrowser;
function createHiddenBrowser(myWindow) {
if(!myWindow) {
var myWindow = Components.classes["@mozilla.org/appshell/appShellService;1"]
.getService(Components.interfaces.nsIAppShellService)
.hiddenDOMWindow;
}
// Create a hidden browser
var newHiddenBrowser = myWindow.document.createElement("browser");
var windows = myWindow.document.getElementsByTagName("window");
windows[0].appendChild(newHiddenBrowser);
Scholar.debug("created hidden browser");
return newHiddenBrowser;
}
function deleteHiddenBrowser(myBrowser) {
// Delete a hidden browser
myBrowser.parentNode.removeChild(myBrowser);
delete myBrowser;
Scholar.debug("deleted hidden browser");
}
}

View file

@ -535,10 +535,7 @@ Scholar.Utilities.HTTP = new function() {
// saveBrowser - whether to save the hidden browser object; usually, you don't
// want to do this, because it makes it easier to leak memory
Scholar.Utilities.HTTP.processDocuments = function(firstDoc, urls, processor, done, exception, saveBrowser) {
var myWindow = Components.classes["@mozilla.org/appshell/appShellService;1"]
.getService(Components.interfaces.nsIAppShellService)
.hiddenDOMWindow;
var hiddenBrowser = Scholar.Ingester.createHiddenBrowser(myWindow);
var hiddenBrowser = Scholar.Browser.createHiddenBrowser();
var prevUrl, url;
try {
@ -566,7 +563,7 @@ Scholar.Utilities.HTTP.processDocuments = function(firstDoc, urls, processor, do
} else {
hiddenBrowser.removeEventListener("load", onLoad, true);
if(!saveBrowser) {
Scholar.Ingester.deleteHiddenBrowser(hiddenBrowser);
Scholar.Browser.deleteHiddenBrowser(hiddenBrowser);
}
done();
}

View file

@ -32,4 +32,11 @@
<!ENTITY selectitems.title "Select Items">
<!ENTITY selectitems.intro.label "Select which items you'd like to add to your library">
<!ENTITY selectitems.cancel.label "Cancel">
<!ENTITY selectitems.select.label "OK">
<!ENTITY selectitems.select.label "OK">
<!ENTITY bibliography.title "Create Bibliography">
<!ENTITY bibliography.style.label "Citation Style:">
<!ENTITY bibliography.output.label "Output Format:">
<!ENTITY bibliography.saveAsHTML.label "Save as HTML">
<!ENTITY bibliography.copyToClipboard.label "Copy to Clipboard">
<!ENTITY bibliography.print.label "Print">

View file

@ -4024,12 +4024,12 @@ MARC_Record.prototype.translate = function(item) {
// Extract series
this._associateDBField(item, ''440'', ''a'', ''series'');
// Extract call number
this._associateDBField(item, ''050'', ''ab'', ''callNumber'');
this._associateDBField(item, ''060'', ''ab'', ''callNumber'');
this._associateDBField(item, ''070'', ''ab'', ''callNumber'');
this._associateDBField(item, ''080'', ''ab'', ''callNumber'');
this._associateDBField(item, ''082'', ''a'', ''callNumber'');
this._associateDBField(item, ''084'', ''ab'', ''callNumber'');
this._associateDBField(item, ''082'', ''a'', ''callNumber'');
this._associateDBField(item, ''080'', ''ab'', ''callNumber'');
this._associateDBField(item, ''070'', ''ab'', ''callNumber'');
this._associateDBField(item, ''060'', ''ab'', ''callNumber'');
this._associateDBField(item, ''050'', ''ab'', ''callNumber'');
// Set type
item.itemType = "book";