Merged revisions 2989,2994,2996-2999,3001,3003-3004,3007,3010,3012,3015-3016,3026-3029,3036-3038,3040-3041,3046,3048,3050,3052,3054-3055,3057-3058,3066,3069-3073 from 1.0 branch via svnmerge

This commit is contained in:
Dan Stillman 2008-07-22 05:45:32 +00:00
parent 975e81afab
commit 0f71fdbc35
13 changed files with 1473 additions and 326 deletions

View file

@ -148,7 +148,7 @@
],
"sk-SK": [
"athelas"
"Milan Regec"
],
"sl-SI": [

View file

@ -0,0 +1,102 @@
/*
***** BEGIN LICENSE BLOCK *****
Copyright (c) 2006 Center for History and New Media
George Mason University, Fairfax, Virginia, USA
http://chnm.gmu.edu
Licensed under the Educational Community License, Version 1.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.opensource.org/licenses/ecl1.php
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
***** END LICENSE BLOCK *****
*/
Zotero_Charset_Menu = new function() {
this.populate = populate;
/**
* Populate a character set menu, placing more commonly used character sets
* closer to the top
*
* @param {DOMElement} charsetMenu The menu to populate
* @param {Boolean} showEndian Whether to show endian (e.g., UTF-32) options
**/
function populate(charsetMenu, showEndian) {
var charsetMap = {};
// get charset popup and charset RDF
var charsetPopup = document.createElement("menupopup");
charsetMenu.appendChild(charsetPopup);
var charsetSeparator = document.createElement("menuseparator");
charsetPopup.appendChild(charsetSeparator);
var rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].
getService(Components.interfaces.nsIRDFService);
var RDFCU = Components.classes["@mozilla.org/rdf/container-utils;1"].
getService(Components.interfaces.nsIRDFContainerUtils);
var rdfDataSource = rdfService.GetDataSource("rdf:charset-menu");
var rdfName = rdfService.GetResource("http://home.netscape.com/NC-rdf#Name");
var rdfContainer = Components.classes["@mozilla.org/rdf/container;1"].
createInstance(Components.interfaces.nsIRDFContainer);
rdfContainer.Init(rdfDataSource, rdfService.GetResource("NC:EncodersRoot"));
var charsets = rdfContainer.GetElements();
// add charsets to popup in order
while(charsets.hasMoreElements()) {
var charset = charsets.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
var label = rdfDataSource.GetTarget(charset, rdfName, true).
QueryInterface(Components.interfaces.nsIRDFLiteral);
charset = charset.Value;
label = label.Value;
var isUTF16 = charset.length >= 6 && charset.substr(0, 6) == "UTF-16";
// Show UTF-16 element appropriately depending on showEndian
if(isUTF16 && showEndian == (charset == "UTF-16") ||
(!showEndian && charset == "UTF-32LE")) {
continue;
} else if(charset == "x-mac-roman") {
// use the IANA name
value = "macintosh";
} else if(!showEndian && charset == "UTF-32BE") {
label = "Unicode (UTF-32)";
value = "UTF-32";
}
// add element
var itemNode = document.createElement("menuitem");
itemNode.setAttribute("label", label);
itemNode.setAttribute("value", charset);
charsetMap[charset] = itemNode;
if(isUTF16 || (label.length > 7 &&
label.substr(0, 7) == "Western")) {
charsetPopup.insertBefore(itemNode, charsetSeparator);
} else if(charset == "UTF-8") {
var oldFirst = (charsetPopup.firstChild ? charsetPopup.firstChild : null);
charsetPopup.insertBefore(itemNode, oldFirst);
// also add (without BOM) if requested
if(showEndian) {
var itemNode = document.createElement("menuitem");
itemNode.setAttribute("label", Zotero.getString("charset.UTF8withoutBOM"));
itemNode.setAttribute("value", charset+"xBOM");
charsetMap[charset+"xBOM"] = itemNode;
charsetPopup.insertBefore(itemNode, oldFirst);
}
} else {
charsetPopup.appendChild(itemNode);
}
}
return charsetMap;
}
}

View file

@ -26,6 +26,8 @@
//
//////////////////////////////////////////////////////////////////////////////
const OPTION_PREFIX = "export-option-";
// Class to provide options for export
var Zotero_File_Interface_Export = new function() {
@ -34,6 +36,8 @@ var Zotero_File_Interface_Export = new function() {
this.accept = accept;
this.cancel = cancel;
var _charsets;
/*
* add options to export
*/
@ -46,17 +50,19 @@ var Zotero_File_Interface_Export = new function() {
var translators = window.arguments[0].translators;
var listbox = document.getElementById("format-popup");
// get format popup
var formatPopup = document.getElementById("format-popup");
var formatMenu = document.getElementById("format-menu");
var optionsBox = document.getElementById("translator-options");
var charsetBox = document.getElementById("charset-box");
var selectedTranslator = Zotero.Prefs.get("export.lastTranslator");
// add styles to list
// add styles to format popup
for(var i in translators) {
var itemNode = document.createElement("menuitem");
itemNode.setAttribute("label", translators[i].label);
listbox.appendChild(itemNode);
formatPopup.appendChild(itemNode);
// add options
for(var option in translators[i].displayOptions) {
@ -73,9 +79,9 @@ var Zotero_File_Interface_Export = new function() {
// it interprets as checkboxes
if(typeof(translators[i].displayOptions[option]) == "boolean") {
var checkbox = document.createElement("checkbox");
checkbox.setAttribute("id", "export-option-"+option);
checkbox.setAttribute("id", OPTION_PREFIX+option);
checkbox.setAttribute("label", optionLabel);
optionsBox.appendChild(checkbox);
optionsBox.insertBefore(checkbox, charsetBox);
}
addedOptions[option] = true;
@ -93,6 +99,9 @@ var Zotero_File_Interface_Export = new function() {
formatMenu.selectedIndex = 0;
}
// from charsetMenu.js
_charsets = Zotero_Charset_Menu.populate(document.getElementById(OPTION_PREFIX+"exportCharset"), true);
updateOptions(Zotero.Prefs.get("export.translatorSettings"));
}
@ -105,7 +114,9 @@ var Zotero_File_Interface_Export = new function() {
var translatorOptions = window.arguments[0].translators[index].displayOptions;
if(optionString) {
var options = optionString.split(",");
try {
var options = Zotero.JSON.unserialize(optionString);
} catch(e) {}
}
var optionsBox = document.getElementById("translator-options");
@ -114,8 +125,13 @@ var Zotero_File_Interface_Export = new function() {
for(var i=0; i<optionsBox.childNodes.length; i++) {
// loop through options to see which should be enabled
var node = optionsBox.childNodes[i];
var optionName = node.getAttribute("id").toString().substr(14);
// skip non-options
if(node.id.length <= OPTION_PREFIX.length
|| node.id.substr(0, OPTION_PREFIX.length) != OPTION_PREFIX) {
continue;
}
var optionName = node.id.substr(OPTION_PREFIX.length);
if(translatorOptions[optionName] != undefined) {
// option should be enabled
optionsBox.hidden = undefined;
@ -123,9 +139,9 @@ var Zotero_File_Interface_Export = new function() {
var defValue = translatorOptions[optionName];
if(typeof(defValue) == "boolean") {
if(optionString) {
if(options && options[optionName] !== undefined) {
// if there's a saved prefs string, use it
var isChecked = options.shift();
var isChecked = options[optionName];
} else {
// use defaults
var isChecked = (defValue ? "true" : "false");
@ -135,10 +151,25 @@ var Zotero_File_Interface_Export = new function() {
} else {
// option should be disabled and unchecked to prevent confusion
node.hidden = true;
node.setAttribute("checked", "false");
node.checked = false;
}
}
// handle charset popup
var charsetMenu = document.getElementById(OPTION_PREFIX+"exportCharset");
if(translatorOptions.exportCharset) {
document.getElementById("charset-box").hidden = undefined;
optionsBox.hidden = undefined;
var charset = "UTF-8xBOM";
if(options && options.exportCharset && _charsets[options.exportCharset]) {
charset = options.exportCharset;
} else if(translatorOptions.exportCharset && _charsets[translatorOptions.exportCharset]) {
charset = translatorOptions.exportCharset;
}
charsetMenu.selectedItem = _charsets[charset];
}
window.sizeToContent();
}
@ -158,21 +189,20 @@ var Zotero_File_Interface_Export = new function() {
var optionsAvailable = window.arguments[0].selectedTranslator.displayOptions;
for(var option in optionsAvailable) {
var defValue = optionsAvailable[option];
var element = document.getElementById("export-option-"+option);
var element = document.getElementById(OPTION_PREFIX+option);
if(typeof(defValue) == "boolean") {
if(element.checked == true) {
optionString += ",true";
optionsAvailable[option] = true;
} else {
optionString += ",false";
optionsAvailable[option] = false;
}
if(option == "exportCharset") {
optionsAvailable[option] = element.selectedItem.value;
} else if(typeof(defValue) == "boolean") {
optionsAvailable[option] = !!element.checked;
}
}
// save options
if(optionString) optionString = optionString.substr(1);
Zotero.debug("EXPORT OPTIONS");
Zotero.debug(optionsAvailable);
optionString = Zotero.JSON.serialize(optionsAvailable);
Zotero.debug(optionString);
Zotero.Prefs.set("export.translatorSettings", optionString);
}

View file

@ -1,7 +1,13 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<!DOCTYPE window SYSTEM "chrome://zotero/locale/zotero.dtd">
<!DOCTYPE window [
<!ENTITY % zoteroDTD SYSTEM "chrome://zotero/locale/zotero.dtd" >
%zoteroDTD;
<!ENTITY % charsetDTD SYSTEM "chrome://global/locale/charsetOverlay.dtd" >
%charsetDTD;
]>
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
title="&zotero.exportOptions.title;" buttons="cancel,accept"
ondialogaccept="Zotero_File_Interface_Export.accept()"
ondialogcancel="Zotero_File_Interface_Export.cancel()"
@ -9,7 +15,15 @@
onload="Zotero_File_Interface_Export.init()">
<script src="include.js"/>
<script src="charsetMenu.js"/>
<script src="exportOptions.js"/>
<script type="application/javascript">
<![CDATA[
var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
observerService.notifyObservers(null, "charsetmenu-selected", "other");
]]>
</script>
<vbox id="zotero-export-options-container" flex="1">
<hbox>
@ -19,7 +33,13 @@
</menulist>
</hbox>
<groupbox id="translator-options">
<caption label="&zotero.exportOptions.translatorOptions.label;"/>
<caption id="translator-options-label" label="&zotero.exportOptions.translatorOptions.label;"/>
<vbox id="charset-box" hidden="true">
<separator class="thin"/>
<label value="&zotero.charset.label;:" control="charset-menu"/>
<menulist id="export-option-exportCharset"/>
</vbox>
</groupbox>
</vbox>
</dialog>

View file

@ -44,7 +44,7 @@ Zotero_File_Exporter.prototype.save = function() {
// present options dialog
var io = {translators:translators}
window.openDialog("chrome://zotero/content/exportOptions.xul",
"_blank", "chrome,modal,centerscreen", io);
"_blank", "chrome,modal,centerscreen,resizable=no", io);
if(!io.selectedTranslator) {
return false;
}
@ -209,30 +209,34 @@ var Zotero_File_Interface = new function() {
if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
translation.setLocation(fp.file);
// get translators again, bc now we can check against the file
translation.setHandler("translators", function(obj, item) { _importTranslatorsAvailable(obj, item) });
translators = translation.getTranslators();
if(translators.length) {
// create a new collection to take in imported items
var date = new Date();
_importCollection = Zotero.Collections.add(Zotero.getString("fileInterface.imported")+" "+date.toLocaleString());
// import items
translation.setTranslator(translators[0]);
translation.setHandler("collectionDone", _importCollectionDone);
translation.setHandler("done", _importDone);
Zotero.UnresponsiveScriptIndicator.disable();
// show progress indicator
Zotero_File_Interface.Progress.show(
Zotero.getString("fileInterface.itemsImported"),
function() {
Zotero.DB.beginTransaction();
// translate
translation.translate();
});
} else {
window.alert(Zotero.getString("fileInterface.fileFormatUnsupported"));
}
}
}
function _importTranslatorsAvailable(translation, translators) {
if(translators.length) {
// create a new collection to take in imported items
var date = new Date();
_importCollection = Zotero.Collections.add(Zotero.getString("fileInterface.imported")+" "+date.toLocaleString());
// import items
translation.setTranslator(translators[0]);
translation.setHandler("collectionDone", _importCollectionDone);
translation.setHandler("done", _importDone);
Zotero.UnresponsiveScriptIndicator.disable();
// show progress indicator
Zotero_File_Interface.Progress.show(
Zotero.getString("fileInterface.itemsImported"),
function() {
Zotero.DB.beginTransaction();
// translate
translation.translate();
});
} else {
window.alert(Zotero.getString("fileInterface.fileFormatUnsupported"));
}
}

View file

@ -410,9 +410,9 @@ var ZoteroPane = new function()
return;
}
// Ignore modifiers other than accel-alt (or accel-shift if useShift is on)
// Ignore modifiers other than Ctrl-Alt or Cmd-Shift
if (!((Zotero.isMac ? event.metaKey : event.ctrlKey) &&
useShift ? event.shiftKey : event.altKey)) {
(useShift ? event.shiftKey : event.altKey))) {
return;
}
@ -1400,6 +1400,10 @@ var ZoteroPane = new function()
if (this.itemsView.rowCount>0) {
var enable = [m.exportCollection, m.createBibCollection, m.loadReport];
}
else if (!this.collectionsView.isContainerEmpty(this.collectionsView.selection.currentIndex)) {
var enable = [m.exportCollection];
var disable = [m.createBibCollection, m.loadReport];
}
else
{
var disable = [m.exportCollection, m.createBibCollection, m.loadReport];
@ -2038,13 +2042,15 @@ var ZoteroPane = new function()
var isNative = Zotero.MIME.hasNativeHandler(mimeType, ext);
var internal = Zotero.MIME.hasInternalHandler(mimeType, ext);
var fileURL = attachment.getLocalFileURL();
if (isNative ||
(internal && !Zotero.Prefs.get('launchNonNativeFiles'))) {
this.loadURI(fileURL, event, { attachmentID: itemID});
var url = 'zotero://attachment/' + itemID + '/';
this.loadURI(url, event, { attachmentID: itemID});
}
else {
var fileURL = attachment.getLocalFileURL();
// Some platforms don't have nsILocalFile.launch, so we just load it and
// let the Firefox external helper app window handle it
try {

View file

@ -701,7 +701,7 @@ Zotero.CSL.prototype.formatBibliography = function(itemSet, format) {
if(format == "HTML") {
var coins = Zotero.OpenURL.createContextObject(item.zoteroItem, "1.0");
var span = (coins ? ' <span class="Z3988" title="'+coins.replace("&", "&amp;", "g")+'"></span>' : '');
var span = (coins ? ' <span class="Z3988" title="'+coins.replace("&", "&amp;", "g")+'">&nbsp;</span>' : '');
if(this.class == "note" && isCitation) {
output += "<li>"+string+span+"</li>\r\n";

View file

@ -24,6 +24,18 @@
// Zotero Translate Engine
//
/**
* Set of byte order marks
**/
const BOMs = {
"UTF-8":"\xEF\xBB\xBF",
"UTF-16BE":"\xFE\xFF",
"UTF-16LE":"\xFF\xFE",
"UTF-32BE":"\x00\x00\xFE\xFF",
"UTF-32LE":"\xFF\xFE\x00\x00"
}
/*
* Zotero.Translate: a class for translation of Zotero metadata from and to
* other formats
@ -80,6 +92,7 @@
*
* PRIVATE PROPERTIES:
*
* _charset - character set
* _numericTypes - possible numeric types as a comma-delimited string
* _handlers - handlers for various events (see setHandler)
* _sandbox - sandbox in which translators will be executed
@ -92,7 +105,6 @@
* _storage - the stored string to be treated as input
* _storageLength - the length of the stored string
* _exportFileDirectory - the directory to which files will be exported
* _hasBOM - whether the given file ready to be imported has a BOM or not
*
* WEB-ONLY PROPERTIES:
*
@ -105,7 +117,6 @@
*
* output - export output (if no location has been specified)
*/
Zotero.Translate = function(type, saveItem) {
this.type = type;
@ -471,9 +482,6 @@ Zotero.Translate.prototype.getTranslators = function() {
// do not allow simultaneous instances of getTranslators
if(this._translatorSearch) this._translatorSearch.running = false;
// clear BOM
this._hasBOM = null;
if(Zotero.Translate.cache) {
var translators = Zotero.Translate.cache[this.type];
} else {
@ -543,7 +551,6 @@ Zotero.Translate.prototype.translate = function() {
this._IDMap = new Array();
this._complete = false;
this._itemsDone = false;
this._hasBOM = null;
if(!this.translator || !this.translator.length) {
throw("cannot translate: no translator specified");
@ -593,8 +600,8 @@ Zotero.Translate.prototype.translate = function() {
* parses translator detect code
*/
Zotero.Translate.prototype._parseDetectCode = function(translator) {
this.configOptions = new Array();
this.displayOptions = new Array();
this.configOptions = {};
this.displayOptions = {};
if(translator.detectCode) {
var detectCode = translator.detectCode;
@ -672,7 +679,7 @@ Zotero.Translate.prototype._generateSandbox = function() {
if(this.type == "import") {
// add routines to add new collections
this._sandbox.Zotero.Collection = Zotero.Translate.GenerateZoteroItemClass();
this._sandbox.Zotero.Collection = Zotero.Translate.GenerateZoteroCollectionClass();
// attach the function to be run when a collection is done
this._sandbox.Zotero.Collection.prototype.complete = function() {me._collectionDone(this)};
}
@ -1528,9 +1535,9 @@ Zotero.Translate.prototype._web = function() {
return true;
}
/*
* does the actual search translation
*/
/**
* Does the actual search translation
**/
Zotero.Translate.prototype._search = function() {
try {
this._sandbox.doSearch(this.search);
@ -1542,11 +1549,47 @@ Zotero.Translate.prototype._search = function() {
return true;
}
/*
* does the actual import translation
*/
/**
* Does the actual import translation
**/
Zotero.Translate.prototype._import = function() {
this._importConfigureIO();
this.waitForCompletion = true;
var me = this;
this._importGetCharacterSet(function(charset) { me._importDoComplete(charset) });
return true;
}
/**
* Sniff file if a real file exists
*
* @param {Function} callback A callback function to be executed after sniffing
**/
Zotero.Translate.prototype._importGetCharacterSet = function(callback) {
if(!this._storage) {
// need to check charset
if(this._charset) {
// have charset already; just go on
callback(this._charset);
} else {
// look for charset
var me = this;
Zotero.File.getCharsetFromFile(this.location, "text/plain",
function(charset) {
me._charset = charset;
callback(charset);
});
}
} else {
callback();
}
}
/**
* Complete import (used as callback after sniffing)
**/
Zotero.Translate.prototype._importDoComplete = function(charset) {
this._importConfigureIO(charset);
try {
this._sandbox.doImport();
@ -1558,14 +1601,13 @@ Zotero.Translate.prototype._import = function() {
return false;
}
}
return true;
this._translationComplete(true);
}
/*
* sets up import for IO
* set up import for IO
*/
Zotero.Translate.prototype._importConfigureIO = function() {
Zotero.Translate.prototype._importConfigureIO = function(charset) {
if(this._storage) {
if(this.configOptions.dataMode && this.configOptions.dataMode == "rdf") {
this._rdf = new Object();
@ -1622,32 +1664,43 @@ Zotero.Translate.prototype._importConfigureIO = function() {
}
var filePosition = 0;
var intlStream = this._importDefuseBOM();
if(intlStream) {
// found a UTF BOM at the beginning of the file; don't allow
// translator to set the character set
this._sandbox.Zotero.setCharacterSet = function() {}
this._streams.push(intlStream);
} else {
// allow translator to set charset
this._sandbox.Zotero.setCharacterSet = function(charset) {
// seek
if(filePosition != 0) {
me._inputStream.QueryInterface(Components.interfaces.nsISeekableStream)
.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, filePosition);
me._inputStream.QueryInterface(Components.interfaces.nsIFileInputStream);
}
intlStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(Components.interfaces.nsIConverterInputStream);
try {
intlStream.init(me._inputStream, charset, 65535,
Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
} catch(e) {
throw "Text encoding not supported";
}
me._streams.push(intlStream);
if(charset) { // if have detected charset
Zotero.debug("Using detected character set "+charset);
// seek past BOM
if(charset.length > 3 && charset.substr(0, 3) == "UTF") {
var BOMLength = this._importGetBOMLength();
this._inputStream.QueryInterface(Components.interfaces.nsISeekableStream)
.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, BOMLength);
}
// convert from detected charset
var intlStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(Components.interfaces.nsIConverterInputStream);
intlStream.init(this._inputStream, charset, 65535,
Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
me._streams.push(intlStream);
}
// allow translator to set charset
this._sandbox.Zotero.setCharacterSet = function(charset) {
// seek
if(filePosition != 0) {
me._inputStream.QueryInterface(Components.interfaces.nsISeekableStream)
.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, filePosition);
me._inputStream.QueryInterface(Components.interfaces.nsIFileInputStream);
}
intlStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(Components.interfaces.nsIConverterInputStream);
try {
intlStream.init(me._inputStream, charset, 65535,
Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
} catch(e) {
throw "Text encoding not supported";
}
me._streams.push(intlStream);
}
var str = new Object();
@ -1703,87 +1756,49 @@ Zotero.Translate.prototype._importConfigureIO = function() {
}
}
/*
* searches for a UTF BOM at the beginning of the input stream. if one is found,
* returns an appropriate converter-input-stream for the UTF type, and sets
* _hasBOM to the UTF type. if one is not found, returns false, and sets
* _hasBOM to false to prevent further checking.
/**
* Searches for a UTF BOM at the beginning of the input stream.
*
* @return The length of the UTF BOM.
*/
Zotero.Translate.prototype._importDefuseBOM = function() {
// if already found not to have a BOM, skip
if(this._hasBOM === false) {
return;
}
Zotero.Translate.prototype._importGetBOMLength = function() {
// if not checked for a BOM, open a binary input stream and read
var binStream = Components.classes["@mozilla.org/binaryinputstream;1"].
createInstance(Components.interfaces.nsIBinaryInputStream);
binStream.setInputStream(this._inputStream);
if(!this._hasBOM) {
// if not checked for a BOM, open a binary input stream and read
var binStream = Components.classes["@mozilla.org/binaryinputstream;1"].
createInstance(Components.interfaces.nsIBinaryInputStream);
binStream.setInputStream(this._inputStream);
var possibleBOMs = BOMs;
var couldHaveBOM = true;
var newBOMs, readByte;
while(couldHaveBOM) {
newBOMs = {};
couldHaveBOM = false;
// read the first byte
var byte1 = binStream.read8();
readByte = binStream.read8();
readChar = String.fromCharCode(readByte)
// at the moment, we don't support UTF-32 or UTF-7. while mozilla
// supports these encodings, they add slight additional complexity to
// the function and anyone using them for storing bibliographic metadata
// is insane.
if(byte1 == 0xEF) { // UTF-8: EF BB BF
var byte2 = binStream.read8();
if(byte2 == 0xBB) {
var byte3 = binStream.read8();
if(byte3 == 0xBF) {
this._hasBOM = "UTF-8";
for(var charset in possibleBOMs) {
if(possibleBOMs[charset][0] == readChar) {
if(possibleBOMs[charset].length == 1) {
// have checked entire BOM
return BOMs[charset].length;
} else {
// keep checking
newBOMs[charset] = possibleBOMs[charset].substr(1);
couldHaveBOM = true;
}
}
} else if(byte1 == 0xFE) { // UTF-16BE: FE FF
var byte2 = binStream.read8();
if(byte2 == 0xFF) {
this._hasBOM = "UTF-16BE";
}
} else if(byte1 == 0xFF) { // UTF-16LE: FF FE
var byte2 = binStream.read8();
if(byte2 == 0xFE) {
this._hasBOM = "UTF16-LE";
}
}
if(!this._hasBOM) {
// seek back to begining of file
this._inputStream.QueryInterface(Components.interfaces.nsISeekableStream)
.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, 0);
this._inputStream.QueryInterface(Components.interfaces.nsIFileInputStream);
// say there's no BOM
this._hasBOM = false;
return false;
}
} else {
// if it had a BOM the last time, it has one this time, too. seek to the
// correct position.
if(this._hasBOM == "UTF-8") {
var seekPosition = 3;
} else {
var seekPosition = 2;
}
this._inputStream.QueryInterface(Components.interfaces.nsISeekableStream)
.seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, seekPosition);
this._inputStream.QueryInterface(Components.interfaces.nsIFileInputStream);
possibleBOMs = newBOMs;
}
// if we know what kind of BOM it has, generate an input stream
var intlStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(Components.interfaces.nsIConverterInputStream);
intlStream.init(this._inputStream, this._hasBOM, 65535,
Components.interfaces.nsIConverterInputStream.DEFAULT_REPLACEMENT_CHARACTER);
return intlStream;
return 0;
}
/*
* does the actual export, after code has been loaded and parsed
/**
* Does the actual export, after code has been loaded and parsed
*/
Zotero.Translate.prototype._export = function() {
@ -1793,13 +1808,25 @@ Zotero.Translate.prototype._export = function() {
} else if(this.collection) {
// get items in this collection
this._itemsLeft = this.collection.getChildItems();
if(!this._itemsLeft) {
this._itemsLeft = [];
}
if(this.configOptions.getCollections) {
// get child collections
this._collectionsLeft = Zotero.getCollections(this.collection.id, true);
if(this._collectionsLeft.length) {
// only include parent collection if there are actually children
this._collectionsLeft.unshift(this.collection);
}
// get items in child collections
for each(var collection in this._collectionsLeft) {
this._itemsLeft = this._itemsLeft.concat(collection.getChildItems());
var childItems = collection.getChildItems();
if(childItems) {
this._itemsLeft = this._itemsLeft.concat(childItems);
}
}
}
} else {
@ -1859,8 +1886,9 @@ Zotero.Translate.prototype._export = function() {
return true;
}
/*
* configures IO for export
/**
* Configures the output stream for export and adds writing functions to the
* sandbox
*/
Zotero.Translate.prototype._exportConfigureIO = function() {
if(this.location) {
@ -1888,20 +1916,51 @@ Zotero.Translate.prototype._exportConfigureIO = function() {
} else {
// regular io; write just writes to file
var intlStream = null;
var writtenToStream = false;
var streamCharset = null;
// allow setting of character sets
this._sandbox.Zotero.setCharacterSet = function(charset) {
streamCharset = charset.toUpperCase();
intlStream = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
.createInstance(Components.interfaces.nsIConverterOutputStream);
if(charset == "UTF-8xBOM") charset = "UTF-8";
intlStream.init(fStream, charset, 1024, "?".charCodeAt(0));
};
// if exportCharset option was presented to user, use the result
if(this.displayOptions.exportCharset) {
this._sandbox.Zotero.setCharacterSet(this.displayOptions.exportCharset);
}
this._sandbox.Zotero.write = function(data) {
if(intlStream) {
intlStream.writeString(data);
if(streamCharset) {
if(!writtenToStream && BOMs[streamCharset]) {
// If stream has not yet been written to, and a UTF type
// has been selected, write the BOM
fStream.write(BOMs[streamCharset], BOMs[streamCharset].length);
}
if(streamCharset == "MACINTOSH") {
// fix buggy Mozilla MacRoman
splitData = data.split(/([\r\n]+)/);
Zotero.debug(splitData);
for(var i=0; i<splitData.length; i+=2) {
// write raw newlines straight to the string
intlStream.writeString(splitData[i]);
if(splitData[i+1]) {
fStream.write(splitData[i+1], splitData[i+1].length);
}
}
return;
} else {
intlStream.writeString(data);
}
} else {
fStream.write(data, data.length);
}
writtenToStream = true;
};
}
} else {
@ -2235,54 +2294,68 @@ Zotero.Translate.TranslatorSearch.prototype.execute = function() {
this.translate._parseDetectCode(translator);
if(this.translate.type == "import") {
try {
this.translate._importConfigureIO(); // so it can read
} catch(e) {
Zotero.debug("Translate: "+e+' in opening IO for '+translator.label);
this.execute();
return;
}
}
translator.configOptions = this.translate.configOptions;
translator.displayOptions = this.translate.displayOptions;
if((this.translate.type == "web" && this.translate._sandbox.detectWeb) ||
(this.translate.type == "search" && this.translate._sandbox.detectSearch) ||
(this.translate.type == "import" && this.translate._sandbox.detectImport)) {
var returnValue;
this.currentTranslator = translator;
try {
if(this.translate.type == "web") {
returnValue = this.translate._sandbox.detectWeb(this.translate.document, this.translate.location);
} else if(this.translate.type == "search") {
returnValue = this.translate._sandbox.detectSearch(this.translate.search);
} else if(this.translate.type == "import") {
returnValue = this.translate._sandbox.detectImport();
var me = this;
this.translate._importGetCharacterSet(function(charset) {
try {
me.translate._importConfigureIO(charset); // so it can read
} catch(e) {
Zotero.debug("Translate: "+e+' in opening IO for '+translator.label);
me.execute();
return;
}
} catch(e) {
this.complete(returnValue, e);
return;
}
Zotero.debug("Translate: executed detectCode for "+translator.label);
if(this.translate.type == "web" && this.translate.waitForCompletion) {
this.asyncMode = true;
// don't immediately execute next
return;
} else if(returnValue) {
this.processReturnValue(translator, returnValue);
}
me.runDetectCode(translator);
});
} else {
// add translator even though it has no proper detectCode (usually
// export translators, which have options but do nothing with them)
this.addTranslator(translator);
this.runDetectCode(translator);
}
} else {
this.execute();
}
}
/**
* Sets options and runs detectCode
**/
Zotero.Translate.TranslatorSearch.prototype.runDetectCode = function(translator) {
translator.configOptions = this.translate.configOptions;
translator.displayOptions = this.translate.displayOptions;
if((this.translate.type == "web" && this.translate._sandbox.detectWeb) ||
(this.translate.type == "search" && this.translate._sandbox.detectSearch) ||
(this.translate.type == "import" && this.translate._sandbox.detectImport)) {
var returnValue;
this.currentTranslator = translator;
try {
if(this.translate.type == "web") {
returnValue = this.translate._sandbox.detectWeb(this.translate.document, this.translate.location);
} else if(this.translate.type == "search") {
returnValue = this.translate._sandbox.detectSearch(this.translate.search);
} else if(this.translate.type == "import") {
returnValue = this.translate._sandbox.detectImport();
}
} catch(e) {
this.complete(returnValue, e);
return;
}
Zotero.debug("Translate: executed detectCode for "+translator.label);
if(this.translate.type == "web" && this.translate.waitForCompletion) {
this.asyncMode = true;
// don't immediately execute next
return;
} else if(returnValue) {
this.processReturnValue(translator, returnValue);
}
} else {
// add translator even though it has no proper detectCode (usually
// export translators, which have options but do nothing with them)
this.addTranslator(translator);
}
this.execute();
}
@ -2382,7 +2455,7 @@ Zotero.Translate.GenerateZoteroItemClass = function() {
*/
Zotero.Translate.GenerateZoteroCollectionClass = function() {
var ZoteroCollection = Zotero.Translate.ZoteroCollection = function() {};
var ZoteroCollection = function() {};
return ZoteroCollection;
}

View file

@ -41,6 +41,9 @@ Zotero.Utilities.prototype.formatDate = function(date) {
Zotero.Utilities.prototype.strToDate = function(date) {
return Zotero.Date.strToDate(date);
}
Zotero.Utilities.prototype.strToISO = function(date) {
return Zotero.Date.strToISO(date);
}
/*
* Cleans extraneous punctuation off an author name
@ -669,7 +672,19 @@ Zotero.Utilities.HTTP = new function() {
_stateChange(xmlhttp, onDone, responseCharset);
};
xmlhttp.send(null);
// Temporarily set cookieBehavior to 0 for Firefox 3
// https://www.zotero.org/trac/ticket/1070
try {
var prefService = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefBranch);
var cookieBehavior = prefService.getIntPref("network.cookie.cookieBehavior");
prefService.setIntPref("network.cookie.cookieBehavior", 0);
xmlhttp.send(null);
}
finally {
prefService.setIntPref("network.cookie.cookieBehavior", cookieBehavior);
}
return xmlhttp;
}
@ -709,7 +724,19 @@ Zotero.Utilities.HTTP = new function() {
_stateChange(xmlhttp, onDone, responseCharset);
};
xmlhttp.send(body);
// Temporarily set cookieBehavior to 0 for Firefox 3
// https://www.zotero.org/trac/ticket/1070
try {
var prefService = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefBranch);
var cookieBehavior = prefService.getIntPref("network.cookie.cookieBehavior");
prefService.setIntPref("network.cookie.cookieBehavior", 0);
xmlhttp.send(body);
}
finally {
prefService.setIntPref("network.cookie.cookieBehavior", cookieBehavior);
}
return xmlhttp;
}
@ -730,7 +757,19 @@ Zotero.Utilities.HTTP = new function() {
_stateChange(xmlhttp, onDone);
};
xmlhttp.send(null);
// Temporarily set cookieBehavior to 0 for Firefox 3
// https://www.zotero.org/trac/ticket/1070
try {
var prefService = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefBranch);
var cookieBehavior = prefService.getIntPref("network.cookie.cookieBehavior");
prefService.setIntPref("network.cookie.cookieBehavior", 0);
xmlhttp.send(null);
}
finally {
prefService.setIntPref("network.cookie.cookieBehavior", cookieBehavior);
}
return xmlhttp;
}
@ -759,7 +798,19 @@ Zotero.Utilities.HTTP = new function() {
_stateChange(xmlhttp, onDone);
};
xmlhttp.send(body);
// Temporarily set cookieBehavior to 0 for Firefox 3
// https://www.zotero.org/trac/ticket/1070
try {
var prefService = Components.classes["@mozilla.org/preferences-service;1"].
getService(Components.interfaces.nsIPrefBranch);
var cookieBehavior = prefService.getIntPref("network.cookie.cookieBehavior");
prefService.setIntPref("network.cookie.cookieBehavior", 0);
xmlhttp.send(body);
}
finally {
prefService.setIntPref("network.cookie.cookieBehavior", cookieBehavior);
}
return xmlhttp;
}

View file

@ -121,6 +121,10 @@
<!ENTITY zotero.exportOptions.format.label "Format:">
<!ENTITY zotero.exportOptions.translatorOptions.label "Translator Options">
<!ENTITY zotero.charset.label "Character Encoding">
<!ENTITY zotero.moreEncodings.label "More Encodings">
<!ENTITY zotero.charset.auto "auto detect">
<!ENTITY zotero.citation.keepSorted.label "Keep Sources Sorted">
<!ENTITY zotero.citation.page "Page">

View file

@ -452,7 +452,7 @@ fulltext.indexState.partial = Partial
exportOptions.exportNotes = Export Notes
exportOptions.exportFileData = Export Files
exportOptions.UTF8 = Export as UTF-8
charset.UTF8withoutBOM = Unicode (UTF-8 without BOM)
date.daySuffixes = st, nd, rd, th
date.abbreviation.year = y

View file

@ -619,10 +619,73 @@ function ChromeExtensionHandler() {
};
/*
zotero://attachment/[id]/
*/
var AttachmentExtension = new function() {
this.newChannel = newChannel;
function newChannel(uri) {
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var Zotero = Components.classes["@zotero.org/Zotero;1"]
.getService(Components.interfaces.nsISupports)
.wrappedJSObject;
try {
var errorMsg;
var [id, fileName] = uri.path.substr(1).split('/');
if (parseInt(id) != id) {
return _errorChannel("Attachment id not an integer");
}
var item = Zotero.Items.get(id);
if (!item) {
return _errorChannel("Item not found");
}
var file = item.getFile();
if (!file) {
return _errorChannel("File not found");
}
if (fileName) {
file = file.parent;
file.append(fileName);
if (!file.exists()) {
return _errorChannel("File not found");
}
}
var ph = Components.classes["@mozilla.org/network/protocol;1?name=file"].
createInstance(Components.interfaces.nsIFileProtocolHandler);
fileURI = ph.newFileURI(file);
var channel = ioService.newChannelFromURI(fileURI);
return channel;
}
catch (e) {
Zotero.debug(e);
throw (e);
}
}
function _errorChannel(msg) {
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var uriStr = 'data:text/plain,' + encodeURIComponent(msg);
var dataURI = ioService.newURI(uriStr, null, null);
var channel = ioService.newChannelFromURI(dataURI);
return channel;
}
};
/*
zotero://select/type/id
*/
var SelectExtension = new function(){
this.newChannel = newChannel;
@ -660,19 +723,17 @@ function ChromeExtensionHandler() {
var ReportExtensionSpec = ZOTERO_SCHEME + "://report"
ReportExtensionSpec = ReportExtensionSpec.toLowerCase();
this._extensions[ReportExtensionSpec] = ReportExtension;
var TimelineExtensionSpec = ZOTERO_SCHEME + "://timeline"
TimelineExtensionSpec = TimelineExtensionSpec.toLowerCase();
this._extensions[TimelineExtensionSpec] = TimelineExtension;
var AttachmentExtensionSpec = ZOTERO_SCHEME + "://attachment"
this._extensions[AttachmentExtensionSpec] = AttachmentExtension;
var SelectExtensionSpec = ZOTERO_SCHEME + "://select"
SelectExtensionSpec = SelectExtensionSpec.toLowerCase();
this._extensions[SelectExtensionSpec] = SelectExtension;
}

File diff suppressed because it is too large Load diff