Merge branch 'kill-e4x'

Conflicts:
	chrome/content/zotero/xpcom/integration.js
This commit is contained in:
Simon Kornblith 2012-06-25 00:42:32 -04:00
commit 57c3d190b4
7 changed files with 135 additions and 1590 deletions

View File

@ -293,13 +293,14 @@ Zotero.Cite.makeFormattedBibliography = function(cslEngine, format) {
if(lineSpacing == NaN) throw "Invalid linespacing"; if(lineSpacing == NaN) throw "Invalid linespacing";
var str; var str;
default xml namespace = ''; with({});
try { try {
XML.prettyPrinting = false; var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
XML.ignoreWhitespace = false; .createInstance(Components.interfaces.nsIDOMParser),
var xml = new XML(html); doc = parser.parseFromString(html, "application/xml");
var multiField = !!xml..div.(@class == "csl-left-margin").length(); var leftMarginDivs = Zotero.Utilities.xpath(doc, '//div[@class="csl-left-margin"]'),
multiField = !!leftMarginDivs.length,
clearEntries = multiField;
// One of the characters is usually a period, so we can adjust this down a bit // One of the characters is usually a period, so we can adjust this down a bit
maxOffset = Math.max(1, maxOffset - 2); maxOffset = Math.max(1, maxOffset - 2);
@ -307,7 +308,9 @@ Zotero.Cite.makeFormattedBibliography = function(cslEngine, format) {
// Force a minimum line height // Force a minimum line height
if(lineSpacing <= 1.35) lineSpacing = 1.35; if(lineSpacing <= 1.35) lineSpacing = 1.35;
xml.@style += "line-height: " + lineSpacing + "; "; var style = doc.documentElement.getAttribute("style");
if(!style) style = "";
style += "line-height: " + lineSpacing + "; ";
if(hangingIndent) { if(hangingIndent) {
if (multiField && !secondFieldAlign) { if (multiField && !secondFieldAlign) {
@ -315,32 +318,28 @@ Zotero.Cite.makeFormattedBibliography = function(cslEngine, format) {
} }
// If only one field, apply hanging indent on root // If only one field, apply hanging indent on root
else if (!multiField) { else if (!multiField) {
xml.@style += "padding-left: " + hangingIndent + "em; text-indent:-" + hangingIndent + "em;"; style += "padding-left: " + hangingIndent + "em; text-indent:-" + hangingIndent + "em;";
} }
} }
var leftMarginDivs = xml..div.(@class == "csl-left-margin"); if(style) doc.documentElement.setAttribute("style", style);
var clearEntries = leftMarginDivs.length() > 0;
// csl-entry // csl-entry
var divs = xml..div.(@class == "csl-entry"); var divs = Zotero.Utilities.xpath(doc, '//div[@class="csl-entry"]');
var num = divs.length(); for(var i=0, n=divs.length; i<n; i++) {
var i = 0; var div = divs[i],
for each(var div in divs) { divStyle = div.getAttribute("style");
var first = i == 0; if(!divStyle) divStyle = "";
var last = i == num - 1;
if (clearEntries) { if (clearEntries) {
div.@style += "clear: left; "; divStyle += "clear: left; ";
} }
if(entrySpacing) { if(entrySpacing && i !== n - 1) {
if(!last) { divStyle += "margin-bottom: " + entrySpacing + "em;";
div.@style += "margin-bottom: " + entrySpacing + "em;";
}
} }
i++; if(divStyle) div.setAttribute("style", divStyle);
} }
// Padding on the label column, which we need to include when // Padding on the label column, which we need to include when
@ -349,32 +348,44 @@ Zotero.Cite.makeFormattedBibliography = function(cslEngine, format) {
// div.csl-left-margin // div.csl-left-margin
for each(var div in leftMarginDivs) { for each(var div in leftMarginDivs) {
div.@style = "float: left; padding-right: " + rightPadding + "em;"; var divStyle = div.getAttribute("style");
if(!divStyle) divStyle = "";
divStyle = "float: left; padding-right: " + rightPadding + "em;";
// Right-align the labels if aligning second line, since it looks // Right-align the labels if aligning second line, since it looks
// better and we don't need the second line of text to align with // better and we don't need the second line of text to align with
// the left edge of the label // the left edge of the label
if (secondFieldAlign) { if (secondFieldAlign) {
div.@style += "text-align: right; width: " + maxOffset + "em;"; divStyle += "text-align: right; width: " + maxOffset + "em;";
} }
div.setAttribute("style", divStyle);
} }
// div.csl-right-inline // div.csl-right-inline
for each(var div in xml..div.(@class == "csl-right-inline")) { for each(var div in Zotero.Utilities.xpath(doc, '//div[@class="csl-right-inline"]')) {
div.@style = "margin: 0 .4em 0 " + (secondFieldAlign ? maxOffset + rightPadding : "0") + "em;"; var divStyle = div.getAttribute("style");
if(!divStyle) divStyle = "";
divStyle = "margin: 0 .4em 0 " + (secondFieldAlign ? maxOffset + rightPadding : "0") + "em;";
if (hangingIndent) { if (hangingIndent) {
div.@style += "padding-left: " + hangingIndent + "em; text-indent:-" + hangingIndent + "em;"; divSstyle += "padding-left: " + hangingIndent + "em; text-indent:-" + hangingIndent + "em;";
} }
div.setAttribute("style", divStyle);
} }
// div.csl-indent // div.csl-indent
for each(var div in xml..div.(@class == "csl-indent")) { for each(var div in Zotero.Utilities.xpath(doc, '//div[@class="csl-indent"]')) {
div.@style = "margin: .5em 0 0 2em; padding: 0 0 .2em .5em; border-left: 5px solid #ccc;"; div.setAttribute("style", "margin: .5em 0 0 2em; padding: 0 0 .2em .5em; border-left: 5px solid #ccc;");
} }
//Zotero.debug(xml); //Zotero.debug(xml);
str = xml.toXMLString(); var s = Components.classes["@mozilla.org/xmlextras/xmlserializer;1"]
.createInstance(Components.interfaces.nsIDOMSerializer);
str = s.serializeToString(doc);
} finally { } finally {
XML.prettyPrinting = true; XML.prettyPrinting = true;
XML.ignoreWhitespace = true; XML.ignoreWhitespace = true;

File diff suppressed because it is too large Load Diff

View File

@ -2992,55 +2992,35 @@ Zotero.Integration.DocumentData = function(string) {
* Serializes document-specific data as XML * Serializes document-specific data as XML
*/ */
Zotero.Integration.DocumentData.prototype.serializeXML = function() { Zotero.Integration.DocumentData.prototype.serializeXML = function() {
var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"] var prefs = "";
.createInstance(Components.interfaces.nsIDOMParser);
var doc = parser.parseFromString("<data/>", "application/xml");
var xmlData = doc.documentElement;
xmlData.setAttribute("data-version", DATA_VERSION);
xmlData.setAttribute("zotero-version", Zotero.version);
var session = doc.createElement("session");
session.setAttribute("id", this.sessionID);
xmlData.appendChild(session);
var style = doc.createElement("style");
style.setAttribute("id", this.style.styleID);
style.setAttribute("hasBibliography", this.style.hasBibliography ? 1 : 0);
style.setAttribute("bibliographyStyleHasBeenSet", this.style.bibliographyStyleHasBeenSet ? 1 : 0);
xmlData.appendChild(style);
var prefs = doc.createElement("prefs");
for(var pref in this.prefs) { for(var pref in this.prefs) {
var prefXML = doc.createElement("pref"); prefs += '<pref name="'+Zotero.Utilities.htmlSpecialChars(pref)+'" '+
prefXML.setAttribute("name", pref); 'value="'+Zotero.Utilities.htmlSpecialChars(this.prefs[pref])+'"/>';
prefXML.setAttribute("value", this.prefs[pref]);
prefs.appendChild(prefXML);
} }
xmlData.appendChild(prefs);
var domSerializer = Components.classes["@mozilla.org/xmlextras/xmlserializer;1"] return '<data data-version="'+Zotero.Utilities.htmlSpecialChars(DATA_VERSION)+'" '+
.createInstance(Components.interfaces.nsIDOMSerializer); 'zotero-version="'+Zotero.Utilities.htmlSpecialChars(Zotero.version)+'">'+
return domSerializer.serializeToString(doc); '<session id="'+Zotero.Utilities.htmlSpecialChars(this.sessionID)+'"/>'+
'<style id="'+Zotero.Utilities.htmlSpecialChars(this.style.styleID)+'" '+
'hasBibliography="'+(this.style.hasBibliography ? "1" : "0")+'" '+
'bibliographyStyleHasBeenSet="'+(this.style.bibliographyStyleHasBeenSet ? "1" : "0)+'"/>'+
(prefs ? '<prefs>'+prefs+'</prefs>' : '<prefs/>')+'</data>';
}; };
/** /**
* Unserializes document-specific XML * Unserializes document-specific XML
*/ */
Zotero.Integration.DocumentData.prototype.unserializeXML = function(xmlData) { Zotero.Integration.DocumentData.prototype.unserializeXML = function(xmlData) {
var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"] var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
.createInstance(Components.interfaces.nsIDOMParser); .createInstance(Components.interfaces.nsIDOMParser),
xmlData = parser.parseFromString(xmlData, "application/xml").documentElement; doc = parser.parseFromString(xmlData, "application/xml");
this.sessionID = Zotero.Utilities.xpathText(xmlData, "session/@id"); this.sessionID = Zotero.Utilities.xpathText(doc, '/data/session[1]/@id');
this.style = { this.style = {"styleID":Zotero.Utilities.xpathText(doc, '/data/style[1]/@id'),
"styleID":Zotero.Utilities.xpathText(xmlData, "style/@id"), "hasBibliography":(Zotero.Utilities.xpathText(doc, '/data/style[1]/@hasBibliography') == 1),
"hasBibliography":(Zotero.Utilities.xpathText(xmlData, "style/@hasBibliography") == "1"), "bibliographyStyleHasBeenSet":(Zotero.Utilities.xpathText(doc, '/data/style[1]/@bibliographyStyleHasBeenSet') == 1)};
"bibliographyStyleHasBeenSet":(Zotero.Utilities.xpathText(xmlData, "style/@bibliographyStyleHasBeenSet") == "1")
};
this.prefs = {}; this.prefs = {};
for each(var pref in Zotero.Utilities.xpath(xmlData, "prefs/pref")) { for each(var pref in Zotero.Utilities.xpath(doc, '/data/prefs[1]/pref')) {
var name = pref.getAttribute("name"); var name = pref.getAttribute("name");
var value = pref.getAttribute("value"); var value = pref.getAttribute("value");
if(value === "true") { if(value === "true") {
@ -3052,9 +3032,9 @@ Zotero.Integration.DocumentData.prototype.unserializeXML = function(xmlData) {
this.prefs[name] = value; this.prefs[name] = value;
} }
if(this.prefs["storeReferences"] === undefined) this.prefs["storeReferences"] = false; if(this.prefs["storeReferences"] === undefined) this.prefs["storeReferences"] = false;
this.zoteroVersion = xmlData.getAttribute("zotero-version"); this.zoteroVersion = doc.documentElement.getAttribute("zotero-version");
if(!this.zoteroVersion) this.zoteroVersion = "2.0"; if(!this.zoteroVersion) this.zoteroVersion = "2.0";
this.dataVersion = xmlData.getAttribute("data-version"); this.dataVersion = doc.documentElement.getAttribute("data-version");
if(!this.dataVersion) this.dataVersion = 2; if(!this.dataVersion) this.dataVersion = 2;
}; };

View File

@ -36,6 +36,10 @@ Zotero.Styles = new function() {
this.ios = Components.classes["@mozilla.org/network/io-service;1"]. this.ios = Components.classes["@mozilla.org/network/io-service;1"].
getService(Components.interfaces.nsIIOService); getService(Components.interfaces.nsIIOService);
this.ns = {
"csl":"http://purl.org/net/xbiblio/csl"
};
/** /**
* Initializes styles cache, loading metadata for styles into memory * Initializes styles cache, loading metadata for styles into memory
*/ */
@ -68,8 +72,11 @@ Zotero.Styles = new function() {
var i = 0; var i = 0;
var contents = dir.directoryEntries; var contents = dir.directoryEntries;
while(contents.hasMoreElements()) { while(contents.hasMoreElements()) {
var file = contents.getNext().QueryInterface(Components.interfaces.nsIFile); var file = contents.getNext().QueryInterface(Components.interfaces.nsIFile),
if(!file.leafName || file.leafName[0] == "." || file.isDirectory()) continue; filename = file.leafName;
if(!filename || filename[0] === "."
|| filename.substr(-4).toLowerCase() !== ".csl"
|| file.isDirectory()) continue;
try { try {
var style = new Zotero.Style(file); var style = new Zotero.Style(file);
@ -149,78 +156,56 @@ Zotero.Styles = new function() {
* are silenced as well * are silenced as well
*/ */
this.install = function(style, loadURI, hidden) { this.install = function(style, loadURI, hidden) {
// "with ({});" needed to fix default namespace scope issue
// See https://bugzilla.mozilla.org/show_bug.cgi?id=330572
default xml namespace = "http://purl.org/net/xbiblio/csl"; with ({});
const pathRe = /[^\/]+$/; const pathRe = /[^\/]+$/;
if(!_initialized || !this.cacheTranslatorData) this.init(); if(!_initialized || !this.cacheTranslatorData) this.init();
var type = "csl";
// handle nsIFiles // handle nsIFiles
var styleFile = null; var styleFile = null;
if(style instanceof Components.interfaces.nsIFile) { if(style instanceof Components.interfaces.nsIFile) {
styleFile = style; styleFile = style;
loadURI = style.leafName; loadURI = style.leafName;
if(loadURI.substr(-4) == ".ens") {
type = "ens";
style = Zotero.File.getBinaryContents(styleFile);
} else {
style = Zotero.File.getContents(styleFile); style = Zotero.File.getContents(styleFile);
} }
}
var error = false; var error = false;
try { try {
if(type == "ens") {
// EN style
var type = "ens";
var enConverter = new Zotero.ENConverter(style);
var xml = enConverter.parse();
} else {
// CSL // CSL
var xml = this.cleanXML(style); var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
if (!xml.name()) { .createInstance(Components.interfaces.nsIDOMParser),
doc = parser.parseFromString(style, "application/xml");
if (!doc.documentElement.localName) {
throw new Error("File is not XML"); throw new Error("File is not XML");
} }
}
} catch(e) { } catch(e) {
error = e; error = e;
} }
if(!xml || error) { if(!doc || error) {
if(!hidden) alert(Zotero.getString('styles.installError', loadURI)); if(!hidden) alert(Zotero.getString('styles.installError', loadURI));
if(error) throw error; if(error) throw error;
return false; return false;
} }
var source = null; var styleID = Zotero.Utilities.xpathText(doc, '/csl:style/csl:info[1]/csl:id[1]',
var styleID = xml.info.id.toString(); Zotero.Styles.ns);
if(type == "ens") {
var title = styleFile.leafName.substr(0, styleFile.leafName.length-4);
var fileName = styleFile.leafName;
} else {
// get file name from URL // get file name from URL
var m = pathRe.exec(styleID); var m = pathRe.exec(styleID);
var fileName = Zotero.File.getValidFileName(m ? m[0] : styleID); var fileName = Zotero.File.getValidFileName(m ? m[0] : styleID);
var title = xml.info.title.toString(); var title = Zotero.Utilities.xpathText(doc, '/csl:style/csl:info[1]/csl:title[1]',
Zotero.Styles.ns);
// look for a parent // look for a parent
for each(var link in xml.info.link) { var source = Zotero.Utilities.xpathText(doc,
if(link.@rel == "source" || link.@rel == "independent-parent") { '/csl:style/csl:info[1]/csl:link[@rel="source" or @rel="independent-parent"][1]/@href',
source = link.@href.toString(); Zotero.Styles.ns);
if(source == styleID) { if(source == styleID) {
if(!hidden) alert(Zotero.getString('styles.installError', loadURI)); if(!hidden) alert(Zotero.getString('styles.installError', loadURI));
throw "Style with ID "+this.styleID+" references itself as source"; throw "Style with ID "+styleID+" references itself as source";
}
break;
}
}
} }
// ensure csl or ens extension // ensure csl extension
if(fileName.substr(-4).toLowerCase() != "."+type) fileName += "."+type; if(fileName.substr(-4).toLowerCase() != ".csl") fileName += ".csl";
var destFile = Zotero.getStylesDirectory(); var destFile = Zotero.getStylesDirectory();
var destFileHidden = destFile.clone(); var destFileHidden = destFile.clone();
@ -255,9 +240,8 @@ Zotero.Styles = new function() {
// also look for an existing style with the same title // also look for an existing style with the same title
if(!existingFile) { if(!existingFile) {
var styleTitle = xml.info.title.toString();
for each(var existingStyle in this.getAll()) { for each(var existingStyle in this.getAll()) {
if(styleTitle === existingStyle.title) { if(title === existingStyle.title) {
existingFile = existingStyle.file; existingFile = existingStyle.file;
existingTitle = existingStyle.title; existingTitle = existingStyle.title;
break; break;
@ -320,13 +304,6 @@ Zotero.Styles = new function() {
return false; return false;
} }
this.cleanXML = function(str) {
// this is where this should happen
str = str.replace(/\s*<\?[^>]*\?>\s*\n/g, "");
var ret = new XML(str);
return ret;
}
/** /**
* Finishes installing a style, copying the file, reloading the style cache, and refreshing the * Finishes installing a style, copying the file, reloading the style cache, and refreshing the
* styles list in any open windows * styles list in any open windows
@ -365,7 +342,7 @@ Zotero.Styles = new function() {
* @class Represents a style file and its metadata * @class Represents a style file and its metadata
* @property {nsIFile} file The path to the style file * @property {nsIFile} file The path to the style file
* @property {String} styleID * @property {String} styleID
* @property {String} type "csl" for CSL styles, "ens" for legacy styles * @property {String} type "csl" for CSL styles
* @property {String} title * @property {String} title
* @property {String} updated SQL-style date updated * @property {String} updated SQL-style date updated
* @property {String} class "in-text" or "note" * @property {String} class "in-text" or "note"
@ -384,43 +361,33 @@ Zotero.Style = function(arg) {
throw "Invalid argument passed to Zotero.Style"; throw "Invalid argument passed to Zotero.Style";
} }
var extension = (typeof arg === "string" ? ".csl" : arg.leafName.substr(-4).toLowerCase());
if(extension == ".ens") {
this.type = "ens";
this.styleID = Zotero.Styles.ios.newFileURI(this.file).spec;
this.title = this.file.leafName.substr(0, this.file.leafName.length-4);
this.updated = Zotero.Date.dateToSQL(new Date(this.file.lastModifiedTime));
this._version = "0.8";
} else if(extension == ".csl") {
// "with ({});" needed to fix default namespace scope issue
// See https://bugzilla.mozilla.org/show_bug.cgi?id=330572
default xml namespace = "http://purl.org/net/xbiblio/csl"; with ({});
this.type = "csl"; this.type = "csl";
var xml = Zotero.Styles.cleanXML(typeof arg === "string" ? arg : Zotero.File.getContents(arg)); var style = typeof arg === "string" ? arg : Zotero.File.getContents(arg),
parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
.createInstance(Components.interfaces.nsIDOMParser),
doc = parser.parseFromString(style, "application/xml");
this.styleID = xml.info.id.toString(); this.styleID = Zotero.Utilities.xpathText(doc, '/csl:style/csl:info[1]/csl:id[1]',
this.title = xml.info.title.toString(); Zotero.Styles.ns);
this.updated = xml.info.updated.toString().replace(/(.+)T([^\+]+)\+?.*/, "$1 $2"); this.title = Zotero.Utilities.xpathText(doc, '/csl:style/csl:info[1]/csl:title[1]',
this.categories = [category.@term.toString() for each(category in xml.info) if(category.@term.length())]; Zotero.Styles.ns);
this._class = xml.@class.toString(); this.updated = Zotero.Utilities.xpathText(doc, '/csl:style/csl:info[1]/csl:updated[1]',
this._hasBibliography = !!xml.bibliography.length(); Zotero.Styles.ns).replace(/(.+)T([^\+]+)\+?.*/, "$1 $2");
this._version = xml.@version.toString(); this.categories = [category.getAttribute("term")
if(this._version == "") this._version = "0.8"; for each(category in Zotero.Utilities.xpath(doc,
'/csl:style/csl:info[1]/csl:category', Zotero.Styles.ns))
if(category.hasAttribute("term"))];
this._class = doc.documentElement.getAttribute("class");
this._hasBibliography = !!doc.getElementsByTagName("bibliography").length;
this._version = doc.documentElement.getAttribute("version");
if(!this._version) this._version = "0.8";
this.source = null; this.source = Zotero.Utilities.xpathText(doc,
for each(var link in xml.info.link) { '/csl:style/csl:info[1]/csl:link[@rel="source" or @rel="independent-parent"][1]/@href',
if(link.@rel == "source" || link.@rel == "independent-parent") { Zotero.Styles.ns);
this.source = link.@href.toString(); if(this.source === this.styleID) {
if(this.source == this.styleID) {
throw "Style with ID "+this.styleID+" references itself as source"; throw "Style with ID "+this.styleID+" references itself as source";
this.source = null;
}
break;
}
}
} }
} }
@ -513,13 +480,6 @@ function() {
} }
return parentStyle.hasBibliography; return parentStyle.hasBibliography;
} }
if(!this._hasBibliography) {
// if we don't know whether this style has a bibliography, it's because it's an ens style
// and we have to parse it to know
this.getXML();
}
return this._hasBibliography; return this._hasBibliography;
}); });
@ -548,24 +508,9 @@ function() {
* @type String * @type String
*/ */
Zotero.Style.prototype.getXML = function() { Zotero.Style.prototype.getXML = function() {
// "with ({});" needed to fix default namespace scope issue
// See https://bugzilla.mozilla.org/show_bug.cgi?id=330572
default xml namespace = "http://purl.org/net/xbiblio/csl"; with ({});
if(this.type == "ens") {
// EN style
var string = Zotero.File.getBinaryContents(this.file);
var enConverter = new Zotero.ENConverter(string, null, this.title);
var xml = enConverter.parse();
this._class = xml.@class.toString();
this._hasBibliography = !!xml.bibliography.length();
return xml.toXMLString();
} else {
var indepFile = this.independentFile; var indepFile = this.independentFile;
if(indepFile) return Zotero.File.getContents(indepFile); if(indepFile) return Zotero.File.getContents(indepFile);
return this.string; return this.string;
}
}; };
/** /**

View File

@ -304,24 +304,19 @@ Zotero.Utilities = {
* @type String * @type String
*/ */
"htmlSpecialChars":function(/**String*/ str) { "htmlSpecialChars":function(/**String*/ str) {
if (typeof str != 'string') { if (typeof str != 'string') str = str.toString();
throw "Argument '" + str + "' must be a string in Zotero.Utilities.htmlSpecialChars()";
}
if (!str) { if (!str) {
return ''; return '';
} }
var chars = ['&', '"',"'",'<','>']; return str
var entities = ['amp', 'quot', 'apos', 'lt', 'gt']; .replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
var newString = str; .replace(/'/g, '&apos;')
for (var i = 0; i < chars.length; i++) { .replace(/</g, '&lt;')
var re = new RegExp(chars[i], 'g'); .replace(/>/g, '&gt;')
newString = newString.replace(re, '&' + entities[i] + ';'); .replace(/&lt;ZOTERO([^\/]+)\/&gt;/g, function (str, p1, offset, s) {
}
newString = newString.replace(/&lt;ZOTERO([^\/]+)\/&gt;/g, function (str, p1, offset, s) {
switch (p1) { switch (p1) {
case 'BREAK': case 'BREAK':
return '<br/>'; return '<br/>';
@ -331,8 +326,6 @@ Zotero.Utilities = {
return p1; return p1;
} }
}); });
return newString;
}, },
/** /**

View File

@ -78,7 +78,6 @@ const xpcomFilesLocal = [
'data/tags', 'data/tags',
'db', 'db',
'duplicates', 'duplicates',
'enstyle',
'fulltext', 'fulltext',
'id', 'id',
'integration', 'integration',

@ -1 +1 @@
Subproject commit 8c31f2f65be16563f4cd13d4598f9f697c7efdad Subproject commit 6a94601503b6e1c0e1b1e483a5b1d6a8610017e6