';
}
diff --git a/chrome/content/zotero/tools/cslpreview.xul b/chrome/content/zotero/tools/cslpreview.xul
index 711662519a..726a9d0df6 100644
--- a/chrome/content/zotero/tools/cslpreview.xul
+++ b/chrome/content/zotero/tools/cslpreview.xul
@@ -133,7 +133,7 @@
// Generate bibliography
var bibliography = '
' +
+ return '
' +
citations + bibliography + '
';
}
diff --git a/chrome/content/zotero/xpcom/annotate.js b/chrome/content/zotero/xpcom/annotate.js
index 513b44f78a..c8840bf0e3 100644
--- a/chrome/content/zotero/xpcom/annotate.js
+++ b/chrome/content/zotero/xpcom/annotate.js
@@ -22,233 +22,24 @@
const TEXT_TYPE = Components.interfaces.nsIDOMNode.TEXT_NODE;
-//////////////////////////////////////////////////////////////////////////////
-//
-// Zotero.Annotate
-//
-//////////////////////////////////////////////////////////////////////////////
-// general purpose annotation/highlighting methods
-
+/**
+ * Globally accessible functions relating to annotations
+ * @namespace
+ */
Zotero.Annotate = new function() {
var _annotated = {};
- this.annotationColor = "#fff580";
- this.annotationBarColor = "#c0b860";
- this.annotationBorderColor = "#878244";
this.highlightColor = "#fff580";
+ this.alternativeHighlightColor = "#555fa9";
- this.getPathForPoint = getPathForPoint;
- this.getPointForPath = getPointForPath;
- this.getPixelOffset = getPixelOffset;
- this.normalizeRange = normalizeRange;
- this.setAnnotated = setAnnotated;
- this.isAnnotated = isAnnotated;
-
- /*
- * gets a path object, comprising an XPath, text node index, and offset, for
- * a given node.
+ /**
+ * Gets the pixel offset of an item from the top left of a page
+ *
+ * @param {Node} node DOM node to get the pixel offset of
+ * @param {Integer} offset Text offset
+ * @return {Integer[]} X and Y coordinates
*/
- function getPathForPoint(node, offset) {
- Zotero.debug("have node of offset "+offset);
-
- var path = {parent:"", textNode:null, offset:(offset ? offset : null)};
-
- var lastWasTextNode = node.nodeType == TEXT_TYPE;
-
- if(node.parentNode.getAttribute && node.parentNode.getAttribute("zotero")) {
- // if the selected point is inside a highlight node, add offsets of
- // preceding text nodes in this zotero node
- var sibling = node.previousSibling;
- while(sibling) {
- if(sibling.nodeType == TEXT_TYPE) path.offset += sibling.nodeValue.length;
- sibling = sibling.previousSibling;
- }
-
- // use parent node for future purposes
- node = node.parentNode;
- } else if(node.getAttribute && node.getAttribute("zotero")) {
- // if selected point is a zotero node, move it to the last character
- // of the previous node
- node = node.previousSibling;
- if(node.nodeType == TEXT_TYPE) {
- path.offset = node.nodeValue.length;
- lastWasTextNode = true;
- } else {
- path.offset = 0;
- }
- }
-
- lastWasTextNode = lastWasTextNode || node.nodeType == TEXT_TYPE;
-
- if(lastWasTextNode) {
- path.textNode = 1;
- var sibling = node.previousSibling;
- var first = true;
-
- while(sibling) {
- var isZotero = undefined;
- if(sibling.getAttribute) isZotero = sibling.getAttribute("zotero");
-
- if(sibling.nodeType == TEXT_TYPE ||
- (isZotero == "highlight")) {
- // is a text node
- if(first == true) {
- // is still part of the first text node
- if(sibling.getAttribute) {
- // get offset of all child nodes
- for each(var child in sibling.childNodes) {
- if(child && child.nodeType == TEXT_TYPE) {
- path.offset += child.nodeValue.length;
- }
- }
- } else {
- path.offset += sibling.nodeValue.length;
- }
- } else if(!lastWasTextNode) {
- // is part of another text node
- path.textNode++;
- lastWasTextNode = true;
- }
- } else if(!isZotero) { // skip over annotation marker nodes
- // is not a text node
- lastWasTextNode = first = false;
- }
-
- sibling = sibling.previousSibling;
- }
-
- node = node.parentNode;
- } else if(path.offset != 0) {
- for(; path.offset > 0 && node.nextSibling; path.offset--) {
- node = node.nextSibling;
- }
- }
-
- var doc = node.ownerDocument;
-
- while(node && node != doc) {
- var number = 1;
- var sibling = node.previousSibling;
- while(sibling) {
- if(sibling.tagName == node.tagName) number++;
- sibling = sibling.previousSibling;
- }
-
- // don't add highlight nodes
- if(node.tagName) {
- var tag = node.tagName.toLowerCase();
- if(tag == "span") {
- tag += "[not(@zotero)]";
- }
- } else {
- var tag = node.nodeType;
- }
-
- path.parent = "/"+tag+"["+number+"]"+path.parent;
-
- node = node.parentNode;
- }
-
- Zotero.debug("Annotate: got path "+path.parent+", "+path.textNode+", "+path.offset);
-
- return path;
- }
-
- function getPointForPath(parent, textNode, offset, document, nsResolver) {
- var point = {offset:0};
-
- // try to evaluate parent
- try {
- point.node = document.evaluate(parent, document, nsResolver,
- Components.interfaces.nsIDOMXPathResult.ANY_TYPE, null).iterateNext();
- } catch(e) {
- Zotero.debug("Annotate: could not find XPath "+parent+" in getPointForPath");
- return false;
- }
-
- // don't do further processing if this path does not refer to a text node
- if(!textNode) return point;
-
- // parent node must have children if we have a text node index
- if(!point.node.firstChild) {
- Zotero.debug("Annotate: node "+parent+" has no children in getPointForPath");
- return false;
- }
-
- point.node = point.node.firstChild;
- point.offset = offset;
- var lastWasTextNode = false;
- var number = 0;
-
- // find text node
- while(true) {
- var isZotero = undefined;
- if(point.node.getAttribute) isZotero = point.node.getAttribute("zotero");
-
- if(point.node.nodeType == TEXT_TYPE ||
- isZotero == "highlight") {
- if(!lastWasTextNode) {
- number++;
-
- // if we found the node we're looking for, break
- if(number == textNode) break;
-
- lastWasTextNode = true;
- }
- } else if(!isZotero) {
- lastWasTextNode = false;
- }
-
- point.node = point.node.nextSibling;
- // if there's no node, this point is invalid
- if(!point.node) {
- Zotero.debug("Annotate: reached end of node list while searching for text node "+textNode+" of "+parent);
- return false;
- }
- }
-
- // find point.offset
- while(true) {
- // get length of enclosed text node
- if(point.node.getAttribute) {
- // this is a highlighted node; loop through and subtract all
- // offsets, breaking if we reach the end
- var parentNode = point.node;
- point.node = point.node.firstChild;
- while(point.node) {
- if(point.node.nodeType == TEXT_TYPE) {
- // break if end condition reached
- if(point.node.nodeValue.length >= point.offset) return point;
- // otherwise, continue subtracting offsets
- point.offset -= point.node.nodeValue.length;
- }
- point.node = point.node.nextSibling;
- }
- // restore parent node
- point.node = parentNode;
- } else {
- // this is not a highlighted node; use simple node length
- if(point.node.nodeValue.length >= point.offset) return point;
- point.offset -= point.node.nodeValue.length;
- }
-
- // get next node
- point.node = point.node.nextSibling;
- // if next node does not exist or is not a text node, this
- // point is invalid
- if(!point.node || (point.node.nodeType != TEXT_TYPE &&
- (!point.node.getAttribute || !point.node.getAttribute("zotero")))) {
- Zotero.debug("Annotate: could not find point.offset "+point.offset+" for text node "+textNode+" of "+parent);
- return false;
- }
- }
- }
-
- /*
- * gets the pixel offset of an item from the top left of a page. the
- * optional "offset" argument specifies a text offset.
- */
- function getPixelOffset(node, offset) {
+ this.getPixelOffset = function(node, offset) {
var x = 0;
var y = 0;
@@ -261,49 +52,449 @@ Zotero.Annotate = new function() {
return [x, y];
}
- /*
- * Sometimes, Firefox stupidly decides to use node offsets to reference
- * nodes. This is a terrible idea, because Firefox then can't figure out
- * when the node boundary matches another. This fixes it.
+ /**
+ * Gets the annotation ID from a given URL
*/
- function normalizeRange(range) {
- for each(var type in ["start", "end"]) {
- var container = range[type+"Container"];
- var offset = range[type+"Offset"];
-
- if(container.nodeType != TEXT_TYPE && offset) {
- for(; offset > 0 && container.nextSibling; offset--) {
- container = container.nextSibling;
+ this.getAnnotationIDFromURL = function(url) {
+ const attachmentRe = /^zotero:\/\/attachment\/([0-9]+)\/$/;
+ var m = attachmentRe.exec(url);
+ return m ? m[1] : false;
+ }
+
+ /**
+ * Parses CSS/HTML color descriptions
+ *
+ * @return {Integer[]} An array of 3 values from 0 to 255 representing R, G, and B components
+ */
+ this.parseColor = function(color) {
+ const rgbColorRe = /rgb\(([0-9]+), ?([0-9]+), ?([0-9]+)\)/i;
+
+ var colorArray = rgbColorRe.exec(color);
+ if(colorArray) return [parseInt(colorArray[1]), parseInt(colorArray[2]), parseInt(colorArray[3])];
+
+ if(color[0] == "#") color = color.substr(1);
+ try {
+ colorArray = [];
+ for(var i=0; i<6; i+=2) {
+ colorArray.push(parseInt(color.substr(i, 2), 16));
+ }
+ return colorArray;
+ } catch(e) {
+ throw "Annotate: parseColor passed invalid color";
+ }
+ }
+
+ /**
+ * Gets the city block distance between two colors. Accepts colors in the format returned by
+ * Zotero.Annotate.parseColor()
+ *
+ * @param {Integer[]} color1
+ * @param {Integer[]} color2
+ * @return {Integer} The distance
+ */
+ this.getColorDistance = function(color1, color2) {
+ color1 = this.parseColor(color1);
+ color2 = this.parseColor(color2);
+
+ var distance = 0;
+ for(var i=0; i<3; i++) {
+ distance += Math.abs(color1[i] - color2[i]);
+ }
+
+ return distance;
+ }
+
+ /**
+ * Checks to see if a given item is already open for annotation
+ *
+ * @param {Integer} id An item ID
+ * @return {Boolean}
+ */
+ this.isAnnotated = function(id) {
+ const XUL_NAMESPACE = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
+
+ var annotationURL = "zotero://attachment/"+id+"/";
+ var haveBrowser = false;
+
+ var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
+ .getService(Components.interfaces.nsIWindowMediator);
+ var enumerator = wm.getEnumerator("navigator:browser");
+ while(enumerator.hasMoreElements()) {
+ var win = enumerator.getNext();
+ var tabbrowser = win.document.getElementsByTagNameNS(XUL_NAMESPACE, "tabbrowser");
+ if(tabbrowser && tabbrowser.length) {
+ var browsers = tabbrowser[0].browsers;
+ } else {
+ var browsers = win.document.getElementsByTagNameNS(XUL_NAMESPACE, "browser");
+ }
+ for each(var browser in browsers) {
+ if(browser.currentURI) {
+ if(browser.currentURI.spec == annotationURL) {
+ if(haveBrowser) {
+ // require two with this URI
+ return true;
+ } else {
+ haveBrowser = true;
+ }
+ }
}
-
- if(type == "start") {
- range.setStart(container, offset);
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Sometimes, Firefox gives us a node offset inside another node, as opposed to a text offset
+ * This function replaces such offsets with references to the nodes themselves
+ *
+ * @param {Node} node DOM node
+ * @param {Integer} offset Node offset
+ * @return {Node} The DOM node after dereferencing has taken place
+ */
+ this.dereferenceNodeOffset = function(node, offset) {
+ if(offset != 0) {
+ if(offset == node.childNodes.length) {
+ node = node.lastChild;
+ } else if(offset < node.childNodes.length) {
+ node = node.childNodes[offset];
+ } else {
+ throw "Annotate: dereferenceNodeOffset called with invalid offset "+offset;
+ }
+ if(!node) throw "Annotate: dereferenceNodeOffset resolved to invalid node";
+ }
+
+ return node;
+ }
+
+ /**
+ * Normalizes a DOM range, resolving it to a range that begins and ends at a text offset and
+ * remains unchanged when serialized to a Zotero.Annotate.Path object
+ *
+ * @param {Range} selectedRange The range to normalize
+ * @param {Function} nsResolver Namespace resolver function
+ * @return {Zotero.Annotate.Path[]} Start and end paths
+ */
+ this.normalizeRange = function(selectedRange, nsResolver) {
+ var document = selectedRange.startContainer.ownerDocument;
+
+ var container, offset;
+ if(selectedRange.startContainer.nodeType != TEXT_TYPE) {
+ [container, offset] = _getTextNode(selectedRange.startContainer, selectedRange.startOffset, true);
+ selectedRange.setStart(container, offset);
+ }
+ if(selectedRange.endContainer.nodeType != TEXT_TYPE) {
+ [container, offset] = _getTextNode(selectedRange.endContainer, selectedRange.endOffset);
+ selectedRange.setEnd(container, offset);
+ }
+
+ var startPath = new Zotero.Annotate.Path(document, nsResolver);
+ var endPath = new Zotero.Annotate.Path(document, nsResolver);
+ startPath.fromNode(selectedRange.startContainer, selectedRange.startOffset);
+ endPath.fromNode(selectedRange.endContainer, selectedRange.endOffset);
+
+ [container, offset] = startPath.toNode();
+ selectedRange.setStart(container, offset);
+ [container, offset] = endPath.toNode();
+ selectedRange.setEnd(container, offset);
+
+ return [startPath, endPath];
+ }
+
+ /**
+ * Takes a node and finds the relevant text node inside of it
+ *
+ * @private
+ * @param {Node} container Node to get text node of
+ * @param {Integer} offset Node offset (see dereferenceNodeOffset)
+ * @param {Boolean} isStart Whether to treat this node as a start node. We look for the first
+ * text node from the start of start nodes, or the first from the end of end nodes
+ * @return {Array} The node and offset
+ */
+ function _getTextNode(container, offset, isStart) {
+ var childAttribute = isStart ? "firstChild" : "lastChild";
+ var siblingAttribute = isStart ? "nextSibling" : "lastSibling";
+
+ container = Zotero.Annotate.dereferenceNodeOffset(container, offset);
+ if(container.nodeType == TEXT_TYPE) return [container, 0];
+
+ var node = container;
+ while(node) {
+ if(node.nodeType == TEXT_TYPE) {
+ container = node;
+ break;
+ } else {
+ if(node[childAttribute]) {
+ node = node[childAttribute];
+ } else if(node[siblingAttribute]) {
+ node = node[siblingAttribute];
} else {
- range.setEnd(container, offset);
+ node = node.parentNode;
+ if(node.isSameNode(container)) {
+ break;
+ }
}
- }
- }
- }
-
- /*
- * gets and sets annotated status
- */
- function isAnnotated(id) {
- return _annotated[id] == true;
- }
-
- function setAnnotated(id, value) {
- _annotated[id] = !!value;
- }
+ }
+ }
+ return [container, (!isStart && container.nodeType == TEXT_TYPE ? container.nodeValue.length : 0)];
+ }
}
-//////////////////////////////////////////////////////////////////////////////
-//
-// Zotero.Annotations
-//
-//////////////////////////////////////////////////////////////////////////////
-// a set of annotations to correspond to a given page
+/**
+ * Creates a new Zotero.Annotate.Path object from an XPath, text node index, and text offset
+ *
+ * @class A persistent descriptor for a point in the DOM, invariant to modifications of
+ * the DOM produced by highlights and annotations
+ *
+ * @property {String} parent XPath of parent node of referenced text node, or XPath of referenced
+ * element
+ * @property {Integer} textNode Index of referenced text node
+ * @property {Integer} offset Offset of referenced point inside text node
+ *
+ * @constructor
+ * @param {Document} document DOM document this path references
+ * @param {Function} nsResolver Namespace resolver (for XPaths)
+ * @param {String} parent (Optional) XPath of parent node
+ * @param {Integer} textNode (Optional) Text node number
+ * @param {Integer} offset (Optional) Text offset
+ */
+Zotero.Annotate.Path = function(document, nsResolver, parent, textNode, offset) {
+ if(parent !== undefined) {
+ this.parent = parent;
+ this.textNode = textNode;
+ this.offset = offset;
+ }
+ this._document = document;
+ this._nsResolver = nsResolver;
+}
+/**
+ * Converts a DOM node/offset combination to a Zotero.Annotate.Path object
+ *
+ * @param {Node} node The DOM node to reference
+ * @param {Integer} offset The text offset, if the DOM node is a text node
+ */
+Zotero.Annotate.Path.prototype.fromNode = function(node, offset) {
+ if(!node) throw "Annotate: Path() called with invalid node";
+ Zotero.debug("Annotate: Path() called with node "+node.tagName+" offset "+offset);
+
+ this.parent = "";
+ this.textNode = null;
+ this.offset = (offset === 0 || offset ? offset : null);
+
+ var lastWasTextNode = node.nodeType == TEXT_TYPE;
+
+ if(!lastWasTextNode && offset) {
+ node = Zotero.Annotate.dereferenceNodeOffset(node, offset);
+ offset = 0;
+ lastWasTextNode = node.nodeType == TEXT_TYPE;
+ }
+
+ if(node.parentNode.getAttribute && node.parentNode.getAttribute("zotero")) {
+ // if the selected point is inside a Zotero node node, add offsets of preceding
+ // text nodes
+ var first = false;
+ var sibling = node.previousSibling;
+ while(sibling) {
+ if(sibling.nodeType == TEXT_TYPE) this.offset += sibling.nodeValue.length;
+ sibling = sibling.previousSibling;
+ }
+
+ // use parent node for future purposes
+ node = node.parentNode;
+ } else if(node.getAttribute && node.getAttribute("zotero")) {
+ // if selected point is a Zotero node, move it to last character of the previous node
+ node = node.previousSibling ? node.previousSibling : node.parentNode;
+ if(node.nodeType == TEXT_TYPE) {
+ this.offset = node.nodeValue.length;
+ lastWasTextNode = true;
+ } else {
+ this.offset = 0;
+ }
+ }
+ if(!node) throw "Annotate: Path() handled Zotero
inappropriately";
+
+ lastWasTextNode = lastWasTextNode || node.nodeType == TEXT_TYPE;
+
+ if(lastWasTextNode) {
+ this.textNode = 1;
+ var first = true;
+
+ var sibling = node.previousSibling;
+ while(sibling) {
+ var isZotero = (sibling.getAttribute ? sibling.getAttribute("zotero") : false);
+
+ if(sibling.nodeType == TEXT_TYPE ||
+ (isZotero == "highlight")) {
+ // is a text node
+ if(first == true) {
+ // is still part of the first text node
+ if(sibling.getAttribute) {
+ // get offset of all child nodes
+ for each(var child in sibling.childNodes) {
+ if(child && child.nodeType == TEXT_TYPE) {
+ this.offset += child.nodeValue.length;
+ }
+ }
+ } else {
+ this.offset += sibling.nodeValue.length;
+ }
+ } else if(!lastWasTextNode) {
+ // is part of another text node
+ this.textNode++;
+ lastWasTextNode = true;
+ }
+ } else if(!isZotero) { // skip over annotation marker nodes
+ // is not a text node
+ lastWasTextNode = first = false;
+ }
+
+ sibling = sibling.previousSibling;
+ }
+
+ node = node.parentNode;
+ }
+ if(!node) throw "Annotate: Path() resolved text offset inappropriately";
+
+ while(node && !node.isSameNode(this._document)) {
+ var number = 1;
+ var sibling = node.previousSibling;
+ while(sibling) {
+ if(sibling.tagName) {
+ if(sibling.tagName == node.tagName && !sibling.hasAttribute("zotero")) number++;
+ } else {
+ if(sibling.nodeType == node.nodeType) number++;
+ }
+ sibling = sibling.previousSibling;
+ }
+
+ // don't add highlight nodes
+ if(node.tagName) {
+ var tag = node.tagName.toLowerCase();
+ if(tag == "span") {
+ tag += "[not(@zotero)]";
+ }
+ this.parent = "/"+tag+"["+number+"]"+this.parent;
+ } else if(node.nodeType == Components.interfaces.nsIDOMNode.COMMENT_NODE) {
+ this.parent = "/comment()["+number+"]";
+ } else if(node.nodeType == Components.interfaces.nsIDOMNode.TEXT_NODE) {
+ Zotero.debug("Annotate: Path() referenced a text node; this should never happen");
+ this.parent = "/text()["+number+"]";
+ } else {
+ Zotero.debug("Annotate: Path() encountered unrecognized node type");
+ }
+
+ node = node.parentNode;
+ }
+
+ Zotero.debug("Annotate: got path "+this.parent+", "+this.textNode+", "+this.offset);
+}
+
+/**
+ * Converts a Zotero.Annotate.Path object to a DOM/offset combination
+ *
+ * @return {Array} Node and offset
+ */
+Zotero.Annotate.Path.prototype.toNode = function() {
+ Zotero.debug("toNode on "+this.parent+" "+this.textNode+", "+this.offset);
+
+ var offset = 0;
+
+ // try to evaluate parent
+ try {
+ var node = this._document.evaluate(this.parent, this._document, this._nsResolver,
+ Components.interfaces.nsIDOMXPathResult.ANY_TYPE, null).iterateNext();
+ } catch(e) {
+ Zotero.debug("Annotate: could not find XPath "+this.parent+" in Path.toNode()");
+ return [false, false];
+ }
+
+ // don't do further processing if this path does not refer to a text node
+ if(!this.textNode) return [node, offset];
+
+ // parent node must have children if we have a text node index
+ if(!node.hasChildNodes()) {
+ Zotero.debug("Annotate: Parent node has no child nodes, but a text node was specified");
+ return [false, false];
+ }
+
+ node = node.firstChild;
+ offset = this.offset;
+ var lastWasTextNode = false;
+ var number = 0;
+
+ // find text node
+ while(true) {
+ var isZotero = undefined;
+ if(node.getAttribute) isZotero = node.getAttribute("zotero");
+
+ if(node.nodeType == TEXT_TYPE ||
+ isZotero == "highlight") {
+ if(!lastWasTextNode) {
+ number++;
+
+ // if we found the node we're looking for, break
+ if(number == this.textNode) break;
+
+ lastWasTextNode = true;
+ }
+ } else if(!isZotero) {
+ lastWasTextNode = false;
+ }
+
+ node = node.nextSibling;
+ // if there's no node, this point is invalid
+ if(!node) {
+ Zotero.debug("Annotate: reached end of node list while searching for text node "+this.textNode+" of "+this.parent);
+ return [false, false];
+ }
+ }
+
+ // find offset
+ while(true) {
+ // get length of enclosed text node
+ if(node.getAttribute) {
+ // this is a highlighted node; loop through and subtract all
+ // offsets, breaking if we reach the end
+ var parentNode = node;
+ node = node.firstChild;
+ while(node) {
+ if(node.nodeType == TEXT_TYPE) {
+ // break if end condition reached
+ if(node.nodeValue.length >= offset) return [node, offset];
+ // otherwise, continue subtracting offsets
+ offset -= node.nodeValue.length;
+ }
+ node = node.nextSibling;
+ }
+ // restore parent node
+ node = parentNode;
+ } else {
+ // this is not a highlighted node; use simple node length
+ if(node.nodeValue.length >= offset) return [node, offset];
+ offset -= node.nodeValue.length;
+ }
+
+ // get next node
+ node = node.nextSibling;
+ // if next node does not exist or is not a text node, this
+ // point is invalid
+ if(!node || (node.nodeType != TEXT_TYPE && (!node.getAttribute || !node.getAttribute("zotero")))) {
+ Zotero.debug("Annotate: could not find offset "+this.offset+" for text node "+this.textNode+" of "+this.parent);
+ return [false, false];
+ }
+ }
+}
+
+/**
+ * Creates a new Zotero.Annotations object
+ * @class Manages all annotations and highlights for a given item
+ *
+ * @constructor
+ * @param {Zotero_Browser} Zotero_Browser object for the tab in which this item is loaded
+ * @param {Browser} Mozilla Browser object
+ * @param {Integer} itemID ID of the item to be annotated/highlighted
+ */
Zotero.Annotations = function(Zotero_Browser, browser, itemID) {
this.Zotero_Browser = Zotero_Browser;
this.browser = browser;
@@ -316,25 +507,36 @@ Zotero.Annotations = function(Zotero_Browser, browser, itemID) {
this.annotations = new Array();
this.highlights = new Array();
- this.zIndex = 100;
-
- this.load();
+ this.zIndex = 9999;
}
+/**
+ * Creates a new annotation at the cursor position
+ * @return {Zotero.Annotation}
+ */
Zotero.Annotations.prototype.createAnnotation = function() {
var annotation = new Zotero.Annotation(this);
this.annotations.push(annotation);
return annotation;
}
-Zotero.Annotations.prototype.createHighlight = function(selectedRange) {
+/**
+ * Highlights text
+ *
+ * @param {Range} selectedRange Range to highlight
+ * @return {Zotero.Highlight}
+ */
+Zotero.Annotations.prototype.highlight = function(selectedRange) {
+ var startPath, endPath;
+ [startPath, endPath] = Zotero.Annotate.normalizeRange(selectedRange, this.nsResolver);
+
var deleteHighlights = new Array();
var startIn = false, endIn = false;
- // first, see if part of this range is already covered
+ // first, see if part of this range is already
for(var i in this.highlights) {
var compareHighlight = this.highlights[i];
- var compareRange = compareHighlight.range;
+ var compareRange = compareHighlight.getRange();
var startToStart = compareRange.compareBoundaryPoints(Components.interfaces.nsIDOMRange.START_TO_START, selectedRange);
var endToEnd = compareRange.compareBoundaryPoints(Components.interfaces.nsIDOMRange.END_TO_END, selectedRange);
@@ -343,7 +545,6 @@ Zotero.Annotations.prototype.createHighlight = function(selectedRange) {
return compareHighlight;
} else if(startToStart != -1 && endToEnd != 1) {
// if this range is inside selected range, delete
- this.highlights[i] = undefined;
delete this.highlights[i];
} else {
var endToStart = compareRange.compareBoundaryPoints(Components.interfaces.nsIDOMRange.END_TO_START, selectedRange);
@@ -362,129 +563,129 @@ Zotero.Annotations.prototype.createHighlight = function(selectedRange) {
}
}
- if(startIn !== false && endIn !== false) {
- selectedRange.setStart(this.highlights[startIn].range.endContainer,
- this.highlights[startIn].range.endOffset);
- selectedRange.setEnd(this.highlights[endIn].range.endContainer,
- this.highlights[endIn].range.endOffset);
- this.highlights[startIn].initWithRange(selectedRange);
+ if(startIn !== false || endIn !== false) {
+ // starts in and ends in existing highlights
+ if(startIn !== false) {
+ var highlight = this.highlights[startIn];
+ startRange = highlight.getRange();
+ selectedRange.setStart(startRange.startContainer, startRange.startOffset);
+ startPath = highlight.startPath;
+ } else {
+ var highlight = this.highlights[endIn];
+ }
- // delete end range
- this.highlights[endIn] = undefined;
- delete this.highlights[endIn];
+ if(endIn !== false) {
+ endRange = this.highlights[endIn].getRange();
+ selectedRange.setEnd(endRange.endContainer, endRange.endOffset);
+ endPath = this.highlights[endIn].endPath;
+ }
- return startIn;
- } else if(startIn !== false) {
- selectedRange.setStart(this.highlights[startIn].range.startContainer,
- this.highlights[startIn].range.startOffset);
- this.highlights[startIn].initWithRange(selectedRange);
- return this.highlights[startIn];
- } else if(endIn != false) {
- selectedRange.setEnd(this.highlights[endIn].range.endContainer,
- this.highlights[endIn].range.endOffset);
- this.highlights[endIn].initWithRange(selectedRange);
- return this.highlights[endIn];
+ // if bridging ranges, delete end range
+ if(startIn !== false && endIn !== false) {
+ delete this.highlights[endIn];
+ }
+ } else {
+ // need to create a new highlight
+ var highlight = new Zotero.Highlight(this);
+ this.highlights.push(highlight);
}
- Zotero.Annotate.normalizeRange(selectedRange);
- var highlight = new Zotero.Highlight(this);
- highlight.initWithRange(selectedRange);
- this.highlights.push(highlight);
+ // actually generate ranges
+ highlight.initWithRange(selectedRange, startPath, endPath);
+
+ //for(var i in this.highlights) Zotero.debug(i+" = "+this.highlights[i].startPath.offset+" to "+this.highlights[i].endPath.offset+" ("+this.highlights[i].startPath.parent+" to "+this.highlights[i].endPath.parent+")");
return highlight;
}
+/**
+ * Unhighlights text
+ *
+ * @param {Range} selectedRange Range to unhighlight
+ */
Zotero.Annotations.prototype.unhighlight = function(selectedRange) {
- // first, see if part of this range is already covered
+ var startPath, endPath, node, offset;
+ [startPath, endPath] = Zotero.Annotate.normalizeRange(selectedRange, this.nsResolver);
+
+ // first, see if part of this range is already highlighted
for(var i in this.highlights) {
- var compareHighlight = this.highlights[i];
- var compareRange = compareHighlight.range;
+ var updateStart = false;
+ var updateEnd = false;
- Zotero.Annotate.normalizeRange(compareRange);
+ var compareHighlight = this.highlights[i];
+ var compareRange = compareHighlight.getRange();
var startToStart = compareRange.compareBoundaryPoints(Components.interfaces.nsIDOMRange.START_TO_START, selectedRange);
var endToEnd = compareRange.compareBoundaryPoints(Components.interfaces.nsIDOMRange.END_TO_END, selectedRange);
- var done = false;
-
if(startToStart == -1 && endToEnd == 1) {
- Zotero.debug("checkpoint 1");
- // there's a bug in Mozilla's handling of ranges
- var selectStartPoint = Zotero.Annotate.getPathForPoint(selectedRange.startContainer, selectedRange.startOffset);
- var compareStartPoint = Zotero.Annotate.getPathForPoint(compareRange.startContainer, compareRange.startOffset);
- if(selectStartPoint.parent == compareStartPoint.parent &&
- selectStartPoint.textNode == compareStartPoint.textNode &&
- selectStartPoint.offset == compareStartPoint.offset) {
- startToStart = 0;
- } else {
- var selectEndPoint = Zotero.Annotate.getPathForPoint(selectedRange.endContainer, selectedRange.endOffset);
- var compareEndPoint = Zotero.Annotate.getPathForPoint(compareRange.endContainer, compareRange.endOffset);
- if(selectEndPoint.parent == compareEndPoint.parent &&
- selectEndPoint.textNode == compareEndPoint.textNode &&
- selectEndPoint.offset == compareEndPoint.offset) {
- endToEnd = 0;
- } else {
-
- // this will unhighlight the entire end
- compareHighlight.unhighlight(selectedRange.startContainer, selectedRange.startOffset, 2);
-
- var newRange = this.document.createRange();
-
- // need to use point references because they disregard highlights
-
- var startPoint = Zotero.Annotate.getPointForPath(selectEndPoint.parent, selectEndPoint.textNode, selectEndPoint.offset,
- this.document, this.nsResolver);
- var endPoint = Zotero.Annotate.getPointForPath(compareEndPoint.parent, compareEndPoint.textNode, compareEndPoint.offset,
- this.document, this.nsResolver);
- newRange.setStart(startPoint.node, startPoint.offset);
- newRange.setEnd(endPoint.node, endPoint.offset);
-
- // create new node
- var highlight = new Zotero.Highlight(this);
- highlight.initWithRange(newRange);
- this.highlights.push(highlight);
-
- done = true;
- }
+ // need to split range into two highlights
+ var compareEndPath = compareHighlight.endPath;
+
+ // this will unhighlight the entire end
+ compareHighlight.unhighlight(selectedRange.startContainer, selectedRange.startOffset,
+ startPath, Zotero.Highlight.UNHIGHLIGHT_FROM_POINT);
+ var newRange = this.document.createRange();
+
+ // need to use point references because they disregard highlights
+ [node, offset] = endPath.toNode();
+ newRange.setStart(node, offset);
+ [node, offset] = compareEndPath.toNode();
+ newRange.setEnd(node, offset);
+
+ // create new node
+ var highlight = new Zotero.Highlight(this);
+ highlight.initWithRange(newRange, endPath, compareEndPath);
+ this.highlights.push(highlight);
+ break;
+ } else if(startToStart != -1 && endToEnd != 1) {
+ // if this range is inside selected range, delete
+ compareHighlight.unhighlight(null, null, null, Zotero.Highlight.UNHIGHLIGHT_ALL);
+ delete this.highlights[i];
+ updateEnd = updateStart = true;
+ } else if(startToStart == -1) {
+ var startToEnd = compareRange.compareBoundaryPoints(Components.interfaces.nsIDOMRange.START_TO_END, selectedRange);
+ if(startToEnd != -1) {
+ // if the start of the selected range is between the start and end of this range
+ compareHighlight.unhighlight(selectedRange.startContainer, selectedRange.startOffset,
+ startPath, Zotero.Highlight.UNHIGHLIGHT_FROM_POINT);
+ updateEnd = true;
+ }
+ } else {
+ var endToStart = compareRange.compareBoundaryPoints(Components.interfaces.nsIDOMRange.END_TO_START, selectedRange);
+ if(endToStart != 1) {
+ // if the end of the selected range is between the start and end of this range
+ compareHighlight.unhighlight(selectedRange.endContainer, selectedRange.endOffset,
+ endPath, Zotero.Highlight.UNHIGHLIGHT_TO_POINT);
+ updateStart = true;
}
}
- if(!done) {
- if(startToStart != -1 && endToEnd != 1) {
- Zotero.debug("checkpoint 2");
- // if this range is inside selected range, delete
- compareHighlight.unhighlight(null, null, 0);
-
- this.highlights[i] = undefined;
- delete this.highlights[i];
- } else {
- var endToStart = compareRange.compareBoundaryPoints(Components.interfaces.nsIDOMRange.END_TO_START, selectedRange);
- if(endToStart != 1 && endToEnd != -1) {
- Zotero.debug("checkpoint 3");
- // if the end of the selected range is between the start and
- // end of this range
- //compareRange.setStart(selectedRange.endContainer, selectedRange.endOffset);
- compareHighlight.unhighlight(selectedRange.endContainer, selectedRange.endOffset, 1);
- } else {
- var startToEnd = compareRange.compareBoundaryPoints(Components.interfaces.nsIDOMRange.START_TO_END, selectedRange);
- if(startToEnd != -1 && startToStart != 1) {
- Zotero.debug("checkpoint 4");
- // if the start of the selected range is between the
- // start and end of this range
- //compareRange.setEnd(selectedRange.startContainer, selectedRange.startOffset);
- compareHighlight.unhighlight(selectedRange.startContainer, selectedRange.startOffset, 2);
- }
- }
- }
+ // need to update start and end parts of ranges if spans have shifted around
+ if(updateStart) {
+ [node, offset] = startPath.toNode();
+ selectedRange.setStart(node, offset);
+ }
+ if(updateEnd) {
+ [node, offset] = endPath.toNode();
+ selectedRange.setEnd(node, offset);
}
}
+
+ //for(var i in this.highlights) Zotero.debug(i+" = "+this.highlights[i].startPath.offset+" to "+this.highlights[i].endPath.offset+" ("+this.highlights[i].startPath.parent+" to "+this.highlights[i].endPath.parent+")");
}
+/**
+ * Refereshes display of annotations (useful if page is reloaded)
+ */
Zotero.Annotations.prototype.refresh = function() {
for each(var annotation in this.annotations) {
annotation.display();
}
}
+/**
+ * Saves annotations to DB
+ */
Zotero.Annotations.prototype.save = function() {
Zotero.DB.beginTransaction();
try {
@@ -506,6 +707,9 @@ Zotero.Annotations.prototype.save = function() {
}
}
+/**
+ * Loads annotations from DB
+ */
Zotero.Annotations.prototype.load = function() {
// load annotations
var rows = Zotero.DB.query("SELECT * FROM annotations WHERE itemID = ?", [this.itemID]);
@@ -527,19 +731,33 @@ Zotero.Annotations.prototype.load = function() {
}
}
-Zotero.Annotations.prototype.setCollapsed = function(status) {
+/**
+ * Expands annotations if any are collapsed, or collapses highlights if all are expanded
+ */
+Zotero.Annotations.prototype.toggleCollapsed = function() {
+ // look to see if there are any collapsed annotations
+ var status = true;
+ for each(var annotation in this.annotations) {
+ if(annotation.collapsed) {
+ status = false;
+ break;
+ }
+ }
+
+ // set status on all annotations
for each(var annotation in this.annotations) {
annotation.setCollapsed(status);
}
}
-//////////////////////////////////////////////////////////////////////////////
-//
-// Zotero.Annotation
-//
-//////////////////////////////////////////////////////////////////////////////
-// an annotation (usually generated using Zotero.Annotations.createAnnotation())
-
+/**
+ * @class Represents an individual annotation
+ *
+ * @constructor
+ * @property {Boolean} collapsed Whether this annotation is collapsed (minimized)
+ * @param {Zotero.Annotations} annotationsObj The Zotero.Annotations object corresponding to the
+ * page this annotation is on
+ */
Zotero.Annotation = function(annotationsObj) {
this.annotationsObj = annotationsObj;
this.window = annotationsObj.browser.contentWindow;
@@ -549,6 +767,11 @@ Zotero.Annotation = function(annotationsObj) {
this.rows = 5;
}
+/**
+ * Generates annotation from a click event
+ *
+ * @param {Event} e The DOM click event
+ */
Zotero.Annotation.prototype.initWithEvent = function(e) {
var maxOffset = false;
@@ -582,20 +805,23 @@ Zotero.Annotation.prototype.initWithEvent = function(e) {
Zotero.debug("Annotate: added new annotation");
- this.displayWithAbsoluteCoordinates(clickX, clickY);
- this.textarea.select();
+ this.displayWithAbsoluteCoordinates(clickX, clickY, true);
}
+/**
+ * Generates annotation from a DB row
+ *
+ * @param {Object} row The DB row
+ */
Zotero.Annotation.prototype.initWithDBRow = function(row) {
- var point = Zotero.Annotate.getPointForPath(row.parent, row.textNode,
- row.offset, this.document, this.nsResolver);
- if(!point) {
+ var path = new Zotero.Annotate.Path(this.document, this.nsResolver, row.parent, row.textNode, row.offset);
+ [node, offset] = path.toNode();
+ if(!node) {
Zotero.debug("Annotate: could not load annotation "+row.annotationID+" from DB");
return;
}
- this.node = point.node;
-
- if(point.offset) this._generateMarker(point.offset);
+ this.node = node;
+ if(offset) this._generateMarker(offset);
this.x = row.x;
this.y = row.y;
@@ -606,9 +832,13 @@ Zotero.Annotation.prototype.initWithDBRow = function(row) {
this.display();
- this.textarea.value = row.text;
+ var me = this;
+ this.iframe.addEventListener("load", function() { me.textarea.value = row.text }, false);
}
+/**
+ * Saves annotation to DB
+ */
Zotero.Annotation.prototype.save = function() {
var text = this.textarea.value;
@@ -627,7 +857,8 @@ Zotero.Annotation.prototype.save = function() {
}
// fetch path to node
- var path = Zotero.Annotate.getPathForPoint(node, offset);
+ var path = new Zotero.Annotate.Path(this.document, this.nsResolver);
+ path.fromNode(node, offset);
var parameters = [
this.annotationsObj.itemID, // itemID
@@ -652,6 +883,9 @@ Zotero.Annotation.prototype.save = function() {
Zotero.DB.query(query, parameters);
}
+/**
+ * Displays annotation
+ */
Zotero.Annotation.prototype.display = function() {
if(!this.node) throw "Annotation not initialized!";
@@ -667,71 +901,77 @@ Zotero.Annotation.prototype.display = function() {
this.displayWithAbsoluteCoordinates(x, y);
}
-Zotero.Annotation.prototype.displayWithAbsoluteCoordinates = function(absX, absY) {
+/**
+ * Displays annotation given absolute coordinates for its position
+ */
+Zotero.Annotation.prototype.displayWithAbsoluteCoordinates = function(absX, absY, select) {
if(!this.node) throw "Annotation not initialized!";
var startScroll = this.window.scrollMaxX;
- if(!this.div) {
+ if(!this.iframe) {
var me = this;
var body = this.document.getElementsByTagName("body")[0];
- // generate regular div
- this.div = this.document.createElement("div");
- this.div.setAttribute("zotero", "annotation");
- body.appendChild(this.div);
- this.div.style.backgroundColor = Zotero.Annotate.annotationColor;
- this.div.style.padding = "0";
- this.div.style.display = (this.collapsed ? "none" : "block");
- this.div.style.position = "absolute";
- this.div.style.border = "1px solid";
- this.div.style.borderColor = Zotero.Annotate.annotationBorderColor;
- this.div.style.MozOpacity = 0.9;
- this.div.style.zIndex = this.annotationsObj.zIndex;
- this.div.addEventListener("click", function() { me._click() }, false);
- this._addChildElements();
+ const style = "position: absolute; margin: 0; padding: 0; border: none; overflow: hidden; ";
- // generate pushpin div
- this.pushpinDiv = this.document.createElement("div");
- this.pushpinDiv.style.padding = "0";
- this.pushpinDiv.style.display = (this.collapsed ? "block" : "none");
- this.pushpinDiv.style.position = "absolute";
- this.pushpinDiv.style.cursor = "pointer";
- // generate pushpin image
- var img = this.document.createElement("img");
- img.src = "chrome://zotero/skin/annotation-hidden.gif";
- img.title = Zotero.getString("annotations.expand.tooltip");
- img.addEventListener("click", function() {
- me.setCollapsed(false);
+ // generate regular div
+ this.iframe = this.document.createElement("iframe");
+ this.iframe.setAttribute("zotero", "annotation");
+ this.iframe.setAttribute("style", style+" -moz-opacity: 0.9;");
+ this.iframe.setAttribute("src", "zotero://attachment/annotation.html");
+ body.appendChild(this.iframe);
+ this.iframe.addEventListener("load", function() {
+ me._addChildElements(select);
+ me.iframe.style.display = (me.collapsed ? "none" : "block");
}, false);
- this.pushpinDiv.appendChild(img);
+
+ // generate pushpin image
+ this.pushpinDiv = this.document.createElement("img");
+ this.pushpinDiv.setAttribute("style", style+" cursor: pointer;");
+ this.pushpinDiv.setAttribute("src", "zotero://attachment/annotation-hidden.gif");
+ this.pushpinDiv.setAttribute("title", Zotero.getString("annotations.expand.tooltip"));
body.appendChild(this.pushpinDiv);
+ this.pushpinDiv.style.display = (this.collapsed ? "block" : "none");
+ this.pushpinDiv.addEventListener("click", function() { me.setCollapsed(false) }, false);
}
- this.div.style.left = this.pushpinDiv.style.left = absX+"px";
- this.div.style.top = this.pushpinDiv.style.top = absY+"px";
- this.pushpinDiv.style.zIndex = this.div.style.zIndex;
+ this.iframe.style.left = this.pushpinDiv.style.left = absX+"px";
+ this.iframeX = absX;
+ this.iframe.style.top = this.pushpinDiv.style.top = absY+"px";
+ this.iframeY = absY;
+ this.pushpinDiv.style.zIndex = this.iframe.style.zIndex = this.annotationsObj.zIndex;
// move to the left if we're making things scroll
- if(absX + this.div.scrollWidth > this.window.innerWidth) {
- this.div.style.left = (absX-this.div.scrollWidth)+"px";
+ if(absX + this.iframe.scrollWidth > this.window.innerWidth) {
+ this.iframe.style.left = (absX-this.iframe.scrollWidth)+"px";
+ this.iframeX = absX-this.iframe.scrollWidth;
}
}
+/**
+ * Collapses or uncollapses annotation
+ *
+ * @param {Boolean} status True to collapse, false to uncollapse
+ */
Zotero.Annotation.prototype.setCollapsed = function(status) {
- if(status == true) {
- // hide div
- this.div.style.display = "none";
+ if(status == true) { // hide iframe
+ this.iframe.style.display = "none";
this.pushpinDiv.style.display = "block";
- this.pushpinDiv.style.zIndex = this.div.style.zIndex;
this.collapsed = true;
- } else {
- // hide pushpin div
+ } else { // hide pushpin div
this.pushpinDiv.style.display = "none";
- this.div.style.display = "block";
+ this.iframe.style.display = "block";
this.collapsed = false;
}
}
+/**
+ * Generates a marker within a paragraph for this annotation. Such markers will remain in place
+ * even if the DOM is changed, e.g., by highlighting
+ *
+ * @param {Integer} offset Text offset within parent node
+ * @private
+ */
Zotero.Annotation.prototype._generateMarker = function(offset) {
// first, we create a new span at the correct offset in the node
var range = this.document.createRange();
@@ -750,143 +990,100 @@ Zotero.Annotation.prototype._generateMarker = function(offset) {
range.insertNode(this.node);
}
-Zotero.Annotation.prototype._addChildElements = function() {
+/**
+ * Prepare iframe representing this annotation
+ *
+ * @param {Boolean} select Whether to select the textarea once iframe is prepared
+ * @private
+ */
+Zotero.Annotation.prototype._addChildElements = function(select) {
var me = this;
+ this.iframeDoc = this.iframe.contentDocument;
- // top bar
- var bar = this.document.createElement("div");
- bar.style.display = "block";
- bar.style.backgroundColor = Zotero.Annotate.annotationBarColor;
- bar.style.paddingRight = "0";
- bar.style.paddingLeft = bar.style.paddingTop = bar.style.paddingBottom = "1px";
- bar.style.borderBottom = "1px solid";
- bar.style.height = "10px";
- bar.style.borderColor = Zotero.Annotate.annotationBorderColor;
-
- // left box
- var closeDiv = this.document.createElement("div");
- closeDiv.style.display = "block";
- closeDiv.style.position = "absolute";
- closeDiv.style.left = "1px";
- closeDiv.style.top = "1px";
- closeDiv.style.cursor = "pointer";
-
- // close image
- var img = this.document.createElement("img");
- img.src = "chrome://zotero/skin/annotation-close.png";
+ // close
+ var img = this.iframeDoc.getElementById("close");
img.title = Zotero.getString("annotations.close.tooltip");
- img.addEventListener("click", function(event) {
- if(me._confirmDelete(event)) {
- me._delete();
- }
- }, false);
+ img.addEventListener("click", function(e) { me._confirmDelete(e) }, false);
- closeDiv.appendChild(img);
- bar.appendChild(closeDiv);
-
- // right box
- var moveDiv = this.document.createElement("div");
- moveDiv.style.display = "block";
- moveDiv.style.position = "absolute";
- moveDiv.style.right = "1px";
- moveDiv.style.top = "1px";
- moveDiv.style.cursor = "pointer";
-
- // move image
- this.moveImg = this.document.createElement("img");
- this.moveImg.src = "chrome://zotero/skin/annotation-move.png";
+ // move
+ this.moveImg = this.iframeDoc.getElementById("move");
this.moveImg.title = Zotero.getString("annotations.move.tooltip");
- this.moveImg.addEventListener("click", function(e) {
- me._startMove(e);
- }, false);
- moveDiv.appendChild(this.moveImg);
+ this.moveImg.addEventListener("click", function(e) { me._startMove(e) }, false);
- // hide image
- var img = this.document.createElement("img");
- img.src = "chrome://zotero/skin/annotation-hide.png";
+ // hide
+ img = this.iframeDoc.getElementById("collapse");
img.title = Zotero.getString("annotations.collapse.tooltip");
- img.addEventListener("click", function(event) {
- me.setCollapsed(true);
- }, false);
- moveDiv.appendChild(img);
+ img.addEventListener("click", function(e) { me.setCollapsed(true) }, false);
- bar.appendChild(moveDiv);
-
- // grippy
- this.grippyDiv = this.document.createElement("div");
- this.grippyDiv.style.display = "block";
- this.grippyDiv.style.position = "absolute";
- this.grippyDiv.style.right = "0px";
- this.grippyDiv.style.bottom = "0px";
- this.grippyDiv.style.cursor = "se-resize";
- var img = this.document.createElement("img");
- img.src = "chrome://zotero/skin/annotation-grippy.png";
- img.addEventListener("mousedown", function(event) {
- me._startDrag(event);
- }, false);
- this.grippyDiv.appendChild(img);
+ // collapse
+ this.grippyDiv = this.iframeDoc.getElementById("grippy");
+ this.grippyDiv.addEventListener("mousedown", function(e) { me._startDrag(e) }, false);
// text area
- this.textarea = this.document.createElement("textarea");
+ this.textarea = this.iframeDoc.getElementById("text");
this.textarea.setAttribute("zotero", "annotation");
- this.textarea.setAttribute("wrap", "soft");
this.textarea.cols = this.cols;
this.textarea.rows = this.rows;
- this.textarea.style.fontFamily = "Arial, Lucida Grande, FreeSans, sans";
- this.textarea.style.fontSize = "12px";
- this.textarea.style.backgroundColor = Zotero.Annotate.annotationColor;
- this.textarea.style.border = "none";
- this.textarea.style.margin = "3px 3px 5px 3px";
- this.div.appendChild(bar);
- this.div.appendChild(this.grippyDiv);
- this.div.appendChild(this.textarea);
+ this.iframe.style.width = (6+this.textarea.offsetWidth)+"px";
+ this.iframe.style.height = this.iframeDoc.body.offsetHeight+"px";
+ this.iframeDoc.addEventListener("click", function() { me._click() }, false);
- this.colSize = this.textarea.clientWidth/this.cols;
- this.rowSize = this.textarea.clientHeight/this.rows;
+ if(select) this.textarea.select();
}
+/**
+ * Brings annotation to the foreground
+ * @private
+ */
Zotero.Annotation.prototype._click = function() {
// clear current action
this.annotationsObj.Zotero_Browser.toggleMode(null);
// alter z-index
this.annotationsObj.zIndex++
- this.div.style.zIndex = this.annotationsObj.zIndex;
+ this.iframe.style.zIndex = this.pushpinDiv.style.zIndex = this.annotationsObj.zIndex;
}
+/**
+ * Asks user to confirm deletion of this annotation
+ * @private
+ */
Zotero.Annotation.prototype._confirmDelete = function(event) {
- if (this.textarea.value == '' ||
- !Zotero.Prefs.get('annotations.warnOnClose')) {
- return true;
+ if (this.textarea.value == '' || !Zotero.Prefs.get('annotations.warnOnClose')) {
+ var del = true;
+ } else {
+ var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
+ .getService(Components.interfaces.nsIPromptService);
+
+ var dontShowAgain = { value: false };
+ var del = promptService.confirmCheck(
+ this.window,
+ Zotero.getString('annotations.confirmClose.title'),
+ Zotero.getString('annotations.confirmClose.body'),
+ Zotero.getString('general.dontShowWarningAgain'),
+ dontShowAgain
+ );
+
+ if (dontShowAgain.value) {
+ Zotero.Prefs.set('annotations.warnOnClose', false);
+ }
}
- var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
- .getService(Components.interfaces.nsIPromptService);
-
- var dontShowAgain = { value: false };
- var del = promptService.confirmCheck(
- this.window,
- Zotero.getString('annotations.confirmClose.title'),
- Zotero.getString('annotations.confirmClose.body'),
- Zotero.getString('general.dontShowWarningAgain'),
- dontShowAgain
- );
-
- if (dontShowAgain.value) {
- Zotero.Prefs.set('annotations.warnOnClose', false);
- }
-
- return del;
+ if(del) this._delete();
}
+/**
+ * Deletes this annotation
+ * @private
+ */
Zotero.Annotation.prototype._delete = function() {
if(this.annotationID) {
Zotero.DB.query("DELETE FROM annotations WHERE annotationID = ?", [this.annotationID]);
}
// hide div
- this.div.parentNode.removeChild(this.div);
+ this.iframe.parentNode.removeChild(this.iframe);
// delete from list
for(var i in this.annotationsObj.annotations) {
if(this.annotationsObj.annotations[i] == this) {
@@ -895,37 +1092,56 @@ Zotero.Annotation.prototype._delete = function() {
}
}
+/**
+ * Called to begin resizing the annotation
+ *
+ * @param {Event} e DOM event corresponding to click on the grippy
+ * @private
+ */
Zotero.Annotation.prototype._startDrag = function(e) {
var me = this;
- this.clickStartX = this.window.pageXOffset + e.clientX;
- this.clickStartY = this.window.pageYOffset + e.clientY;
+ this.clickStartX = e.screenX;
+ this.clickStartY = e.screenY;
this.clickStartCols = this.textarea.cols;
this.clickStartRows = this.textarea.rows;
- // add a listener to handle mouse moves
- this._handleDrag = function(e) {
- me._doDrag(e);
- }
- this.document.addEventListener("mousemove", this._handleDrag, false);
+ /**
+ * Listener to handle mouse moves
+ * @inner
+ */
+ var handleDrag = function(e) { me._doDrag(e); };
+ this.iframeDoc.addEventListener("mousemove", handleDrag, false);
+ this.document.addEventListener("mousemove", handleDrag, false);
- // add a listener that gets called when things stop happening
- this._endDrag = function() {
+ /**
+ * Listener to call when mouse is let up
+ * @inner
+ */
+ var endDrag = function() {
+ me.iframeDoc.removeEventListener("mousemove", handleDrag, false);
+ me.document.removeEventListener("mousemove", handleDrag, false);
+ me.iframeDoc.removeEventListener("mouseup", endDrag, false);
+ me.document.removeEventListener("mouseup", endDrag, false);
me.dragging = false;
- me.document.removeEventListener("mousemove", me._handleDrag, false);
- me.document.removeEventListener("mouseup", me._endDrag, false);
}
- this.document.addEventListener("mouseup", this._endDrag, false);
+ this.iframeDoc.addEventListener("mouseup", endDrag, false);
+ this.document.addEventListener("mouseup", endDrag, false);
// stop propagation
e.stopPropagation();
e.preventDefault();
}
+/**
+ * Called when mouse is moved while annotation is being resized
+ *
+ * @param {Event} e DOM event corresponding to mouse move
+ * @private
+ */
Zotero.Annotation.prototype._doDrag = function(e) {
- var pixelOffset = Zotero.Annotate.getPixelOffset(this.grippyDiv);
- var x = this.window.pageXOffset + e.clientX - this.clickStartX;
- var y = this.window.pageYOffset + e.clientY - this.clickStartY;
+ var x = e.screenX - this.clickStartX;
+ var y = e.screenY - this.clickStartY;
// update sizes
var colSize = this.textarea.clientWidth/this.textarea.cols;
@@ -940,10 +1156,16 @@ Zotero.Annotation.prototype._doDrag = function(e) {
rows = (rows > 2 ? rows : 2);
this.textarea.rows = this.rows = rows;
- // not sure why this is necessary
- this.div.style.width = (6+this.textarea.offsetWidth)+"px";
+ this.iframe.style.width = (6+this.textarea.offsetWidth)+"px";
+ this.iframe.style.height = this.iframe.contentDocument.body.offsetHeight+"px";
}
+/**
+ * Called to begin moving the annotation
+ *
+ * @param {Event} e DOM event corresponding to click on the grippy
+ * @private
+ */
Zotero.Annotation.prototype._startMove = function(e) {
// stop propagation
e.stopPropagation();
@@ -956,35 +1178,64 @@ Zotero.Annotation.prototype._startMove = function(e) {
var me = this;
// set the handler required to deactivate
+
+ /**
+ * Callback to end move action
+ * @inner
+ */
this.annotationsObj.clearAction = function() {
me.document.removeEventListener("click", me._handleMove, false);
body.style.cursor = "auto";
- me.moveImg.src = "chrome://zotero/skin/annotation-move.png";
+ me.moveImg.src = "zotero://attachment/annotation-move.png";
me.annotationsObj.clearAction = undefined;
}
- // create a handler for clicking
- this._handleMove = function(e) {
+ /**
+ * Listener to handle mouse moves on main page
+ * @inner
+ */
+ var handleMoveMouse1 = function(e) {
+ me.displayWithAbsoluteCoordinates(e.pageX + 1, e.pageY + 1);
+ };
+ /**
+ * Listener to handle mouse moves in iframe
+ * @inner
+ */
+ var handleMoveMouse2 = function(e) {
+ me.displayWithAbsoluteCoordinates(e.pageX + me.iframeX + 1, e.pageY + me.iframeY + 1);
+ };
+ this.document.addEventListener("mousemove", handleMoveMouse1, false);
+ this.iframeDoc.addEventListener("mousemove", handleMoveMouse2, false);
+
+ /**
+ * Listener to finish off move when a click is made
+ * @inner
+ */
+ var handleMove = function(e) {
+ me.document.removeEventListener("mousemove", handleMoveMouse1, false);
+ me.iframeDoc.removeEventListener("mousemove", handleMoveMouse2, false);
+ me.document.removeEventListener("click", handleMove, false);
+
me.initWithEvent(e);
me.annotationsObj.clearAction();
// stop propagation
e.stopPropagation();
e.preventDefault();
- };
+ };
+ this.document.addEventListener("click", handleMove, false);
- this.document.addEventListener("click", this._handleMove, false);
body.style.cursor = "pointer";
- this.moveImg.src = "chrome://zotero/skin/annotation-move-selected.png";
+ this.moveImg.src = "zotero://attachment/annotation-move-selected.png";
}
-//////////////////////////////////////////////////////////////////////////////
-//
-// Zotero.Highlight
-//
-//////////////////////////////////////////////////////////////////////////////
-// a highlight (usually generated using Zotero.Annotations.createHighlight())
-
+/**
+ * @class Represents an individual highlighted range
+ *
+ * @constructor
+ * @param {Zotero.Annotations} annotationsObj The Zotero.Annotations object corresponding to the
+ * page this highlight is on
+ */
Zotero.Highlight = function(annotationsObj) {
this.annotationsObj = annotationsObj;
this.window = annotationsObj.browser.contentWindow;
@@ -994,80 +1245,111 @@ Zotero.Highlight = function(annotationsObj) {
this.spans = new Array();
}
-Zotero.Highlight.prototype.initWithDBRow = function(row) {
- var start = Zotero.Annotate.getPointForPath(row.startParent, row.startTextNode,
- row.startOffset, this.document, this.nsResolver);
- var end = Zotero.Annotate.getPointForPath(row.endParent, row.endTextNode,
- row.endOffset, this.document, this.nsResolver);
- if(!start || !end) {
- Zotero.debug("Highlight: could not initialize from DB row");
- return false;
+/**
+ * Gets the highlighted DOM range
+ * @return {Range} DOM range
+ */
+Zotero.Highlight.prototype.getRange = function() {
+ this.range = this.document.createRange();
+ var startContainer, startOffset, endContainer, endOffset;
+ [startContainer, startOffset] = this.startPath.toNode();
+ [endContainer, endOffset] = this.endPath.toNode();
+
+ if(!startContainer || !endContainer) {
+ throw("Annotate: PATH ERROR in highlight module!");
}
- this.range = this.document.createRange();
- this.range.setStart(start.node, start.offset);
- this.range.setEnd(end.node, end.offset);
-
+ this.range.setStart(startContainer, startOffset);
+ this.range.setEnd(endContainer, endOffset);
+ return this.range;
+}
+
+/**
+ * Generates a highlight representing the given DB row
+ */
+Zotero.Highlight.prototype.initWithDBRow = function(row) {
+ this.startPath = new Zotero.Annotate.Path(this.document, this.nsResolver, row.startParent,
+ row.startTextNode, row.startOffset);
+ this.endPath = new Zotero.Annotate.Path(this.document, this.nsResolver, row.endParent,
+ row.endTextNode, row.endOffset);
+ this.getRange();
this._highlight();
}
-Zotero.Highlight.prototype.initWithRange = function(range) {
+/**
+ * Generates a highlight representing given a DOM range
+ *
+ * @param {Range} range DOM range
+ * @param {Zotero.Annotate.Path} startPath Path representing start of range
+ * @param {Zotero.Annotate.Path} endPath Path representing end of range
+ */
+Zotero.Highlight.prototype.initWithRange = function(range, startPath, endPath) {
+ this.startPath = startPath;
+ this.endPath = endPath;
this.range = range;
this._highlight();
}
-Zotero.Highlight.prototype.save = function(index) {
- var textType = Components.interfaces.nsIDOMNode.TEXT_NODE;
-
- var start = Zotero.Annotate.getPathForPoint(this.range.startContainer, this.range.startOffset);
- var end = Zotero.Annotate.getPathForPoint(this.range.endContainer, this.range.endOffset);
+/**
+ * Saves this highlight to the DB
+ */
+Zotero.Highlight.prototype.save = function() {
+ // don't save defective highlights
+ if(this.startPath.parent == this.endPath.parent
+ && this.startPath.textNode == this.endPath.textNode
+ && this.startPath.offset == this.endPath.offset) {
+ return false;
+ }
var query = "INSERT INTO highlights VALUES (NULL, ?, ?, ?, ?, ?, ?, ?, DATETIME('now'))";
var parameters = [
- this.annotationsObj.itemID, // itemID
- start.parent, // startParent
- start.textNode, // startTextNode
- start.offset, // startOffset
- end.parent, // endParent
- end.textNode, // endTextNode
- end.offset // endOffset
+ this.annotationsObj.itemID, // itemID
+ this.startPath.parent, // startParent
+ (this.startPath.textNode ? this.startPath.textNode : null), // startTextNode
+ (this.startPath.offset || this.startPath.offset === 0 ? this.startPath.offset : null), // startOffset
+ this.endPath.parent, // endParent
+ (this.endPath.textNode ? this.endPath.textNode : null), // endTextNode
+ (this.endPath.offset || this.endPath.offset === 0 ? this.endPath.offset: null) // endOffset
];
Zotero.DB.query(query, parameters);
}
+Zotero.Highlight.UNHIGHLIGHT_ALL = 0;
+Zotero.Highlight.UNHIGHLIGHT_TO_POINT = 1;
+Zotero.Highlight.UNHIGHLIGHT_FROM_POINT = 2;
+
/**
- * Un-highlights a range.
+ * Un-highlights a range
*
- * mode can be:
- * 0: unhighlight all
- * 1: unhighlight from start to point
- * 2: unhighlight from point to end
- **/
-Zotero.Highlight.prototype.unhighlight = function(container, offset, mode) {
- var textType = Components.interfaces.nsIDOMNode.TEXT_NODE;
-
+ * @param {Node} container Node to highlight/unhighlight from, or null if mode == UNHIGHLIGHT_ALL
+ * @param {Integer} offset Text offset, or null if mode == UNHIGHLIGHT_ALL
+ * @param {Zotero.Annotate.Path} path Path representing node, offset combination, or null
+ * if mode == UNHIGHLIGHT_ALL
+ * @param {Integer} mode Unhighlight mode
+ */
+Zotero.Highlight.prototype.unhighlight = function(container, offset, path, mode) {
+ this.getRange();
+
if(mode == 1) {
this.range.setStart(container, offset);
+ this.startPath = path;
} else if(mode == 2) {
this.range.setEnd(container, offset);
+ this.endPath = path;
}
- for(var i=0; i distance1) {
+ span.style.backgroundColor = Zotero.Annotate.alternativeHighlightColor;
+ }
+ }
+ }
+
+ span.appendChild(parent.removeChild(textNode));
+ parent.insertBefore(span, (nextSibling ? nextSibling : null));
}
- var nextSibling = textNode.nextSibling;
- if(nextSibling && nextSibling.getAttribute &&
- nextSibling.getAttribute("zotero") == "highlight") {
- // next node is highlighted
- parent.removeChild(textNode);
- nextSibling.insertBefore(textNode, nextSibling.firstChild);
- return nextSibling;
- }
-
- var previousSibling = textNode.previousSibling;
- if(previousSibling && previousSibling.getAttribute &&
- previousSibling.getAttribute("zotero") == "highlight") {
- // previous node is highlighted
- parent.removeChild(textNode);
- previousSibling.appendChild(textNode);
- return previousSibling;
- }
-
- var span = this.document.createElement("span");
- span.setAttribute("zotero", "highlight");
- span.style.display = "inline";
- span.style.backgroundColor = Zotero.Annotate.highlightColor;
-
- parent.removeChild(textNode);
- span.appendChild(textNode);
- parent.insertBefore(span, (nextSibling ? nextSibling : null));
-
- this.spans.push(span);
-
+ if(span && saveSpan) this.spans.push(span);
return span;
}
+/**
+ * Highlights the space between two nodes at the same level
+ *
+ * @param {Node} start
+ * @param {Node} end
+ * @return {Node} Span containing the first block of highlighted text
+ * @private
+ */
Zotero.Highlight.prototype._highlightSpaceBetween = function(start, end) {
- var meaningfulRe = /[^\s\r\n]/;
-
+ var firstSpan = false;
var node = start;
var text;
@@ -1229,13 +1568,12 @@ Zotero.Highlight.prototype._highlightSpaceBetween = function(start, end) {
var textArray = [node];
} else {
var texts = this.document.evaluate('.//text()', node, this.nsResolver,
- Components.interfaces.nsIDOMXPathResult.ANY_TYPE, null);
+ Components.interfaces.nsIDOMXPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
var textArray = new Array()
while(text = texts.iterateNext()) textArray.push(text);
}
- // do this in the middle, after we're finished with node but before we
- // add any spans
+ // do this in the middle, after we're finished with node but before we add any spans
if(node.isSameNode(end)) {
node = false;
} else {
@@ -1243,7 +1581,13 @@ Zotero.Highlight.prototype._highlightSpaceBetween = function(start, end) {
}
for each(var textNode in textArray) {
- this._highlightTextNode(textNode);
+ if(firstSpan) {
+ this._highlightTextNode(textNode);
+ } else {
+ firstSpan = this._highlightTextNode(textNode);
+ }
}
}
+
+ return firstSpan;
}
\ No newline at end of file
diff --git a/chrome/content/zotero/xpcom/attachments.js b/chrome/content/zotero/xpcom/attachments.js
index 89eef9aa3c..dfd45768e1 100644
--- a/chrome/content/zotero/xpcom/attachments.js
+++ b/chrome/content/zotero/xpcom/attachments.js
@@ -185,7 +185,7 @@ Zotero.Attachments = new function(){
Zotero.debug('Importing attachment from URL');
// Throw error on invalid URLs
- urlRe = /^https?:\/\/[^\s]*$/;
+ var urlRe = /^https?:\/\/[^\s]*$/;
var matches = urlRe.exec(url);
if (!matches) {
throw ("Invalid URL '" + url + "' in Zotero.Attachments.importFromURL()");
@@ -365,7 +365,7 @@ Zotero.Attachments = new function(){
Zotero.debug('Linking attachment from URL');
// Throw error on invalid URLs
- urlRe = /^https?:\/\/[^\s]*$/;
+ var urlRe = /^https?:\/\/[^\s]*$/;
var matches = urlRe.exec(url);
if (!matches) {
throw ("Invalid URL '" + url + "' in Zotero.Attachments.linkFromURL()");
@@ -1099,27 +1099,24 @@ Zotero.Attachments = new function(){
var browser = Zotero.Browser.createHiddenBrowser();
- Zotero.File.addCharsetListener(browser, new function(){
- return function(charset, id){
- var charsetID = Zotero.CharacterSets.getID(charset);
-
+ var callback = function(charset, args) {
+ var charsetID = Zotero.CharacterSets.getID(charset);
+ if (charsetID) {
var disabled = Zotero.Notifier.disable();
-
var item = Zotero.Items.get(itemID);
item.attachmentCharset = charsetID;
item.save();
-
if (disabled) {
Zotero.Notifier.enable();
}
-
- // Chain fulltext indexer inside the charset callback,
- // since it's asynchronous and a prerequisite
- Zotero.Fulltext.indexDocument(browser.contentDocument, itemID);
-
- Zotero.Browser.deleteHiddenBrowser(browser);
- };
- }, itemID);
+ }
+
+ // Chain fulltext indexer inside the charset callback,
+ // since it's asynchronous and a prerequisite
+ Zotero.Fulltext.indexDocument(browser.contentDocument, itemID);
+ };
+
+ Zotero.File.addCharsetListener(browser, callback, itemID);
var url = Components.classes["@mozilla.org/network/protocol;1?name=file"]
.getService(Components.interfaces.nsIFileProtocolHandler)
diff --git a/chrome/content/zotero/xpcom/cite.js b/chrome/content/zotero/xpcom/cite.js
index cb3b889ffa..8b8828f32e 100644
--- a/chrome/content/zotero/xpcom/cite.js
+++ b/chrome/content/zotero/xpcom/cite.js
@@ -2252,8 +2252,8 @@ Zotero.CSL.Item._optionalTypeMap = {
audioRecording:"song", // ??
presentation:"speech",
videoRecording:"motion_picture",
- tvBroadcast:"motion_picture",
- radioBroadcast:"motion_picture",
+ tvBroadcast:"broadcast",
+ radioBroadcast:"broadcast",
podcast:"song", // ??
computerProgram:"book" // ??
};
diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js
index d61b0266e1..a5df127cd3 100644
--- a/chrome/content/zotero/xpcom/data/item.js
+++ b/chrome/content/zotero/xpcom/data/item.js
@@ -2210,6 +2210,7 @@ Zotero.Item.prototype.getFile = function(row, skipExistsCheck) {
Zotero.Item.prototype.renameAttachmentFile = function(newName, overwrite) {
var file = this.getFile();
if (!file) {
+ Zotero.debug("Attachment file not found in renameAttachmentFile()", 2);
return false;
}
@@ -2234,6 +2235,8 @@ Zotero.Item.prototype.renameAttachmentFile = function(newName, overwrite) {
return true;
}
catch (e) {
+ Zotero.debug(e);
+ Components.utils.reportError(e);
return -2;
}
}
diff --git a/chrome/content/zotero/xpcom/file.js b/chrome/content/zotero/xpcom/file.js
index 1750801c4e..7a65c534e3 100644
--- a/chrome/content/zotero/xpcom/file.js
+++ b/chrome/content/zotero/xpcom/file.js
@@ -181,7 +181,7 @@ Zotero.File = new function(){
/*
* Not implemented, but it'd sure be great if it were
*/
- function getCharsetFromString(str){
+ function getCharsetFromByteArray(arr) {
}
@@ -213,7 +213,10 @@ Zotero.File = new function(){
.getService(Components.interfaces.nsIFileProtocolHandler)
.getURLSpecFromFile(file);
- this.addCharsetListener(browser, callback, args);
+ this.addCharsetListener(browser, function (charset, args) {
+ callback(charset, args);
+ Zotero.Browser.deleteHiddenBrowser(browser);
+ }, args);
browser.loadURI(url);
}
diff --git a/chrome/content/zotero/xpcom/mime.js b/chrome/content/zotero/xpcom/mime.js
index 7750fbcf45..8a53d26873 100644
--- a/chrome/content/zotero/xpcom/mime.js
+++ b/chrome/content/zotero/xpcom/mime.js
@@ -66,6 +66,8 @@ Zotero.MIME = new function(){
'text/css': true,
'image/jpeg': true,
'image/gif': true,
+ 'image/png': true,
+ 'image/svg+xml': true,
'text/xml': true,
'application/xhtml+xml': true,
'application/xml': true,
diff --git a/chrome/content/zotero/xpcom/search.js b/chrome/content/zotero/xpcom/search.js
index 5eff9ee3b6..054138d668 100644
--- a/chrome/content/zotero/xpcom/search.js
+++ b/chrome/content/zotero/xpcom/search.js
@@ -1387,7 +1387,8 @@ Zotero.Search.prototype._buildQuery = function(){
if (includeParentsAndChildren || includeChildren) {
var childrenSQL = "SELECT itemID FROM itemAttachments WHERE "
+ "sourceItemID IN (" + condSQL + ") UNION "
- + "SELECT itemID FROM itemNotes WHERE sourceItemID IN (" + condSQL + ")";
+ + "SELECT itemID FROM itemNotes "
+ + "WHERE sourceItemID IN (" + condSQL + ")";
var childSQLParams = condSQLParams.concat(condSQLParams);
}
diff --git a/chrome/content/zotero/xpcom/translate.js b/chrome/content/zotero/xpcom/translate.js
index 824f5b15a4..73ab611748 100644
--- a/chrome/content/zotero/xpcom/translate.js
+++ b/chrome/content/zotero/xpcom/translate.js
@@ -437,7 +437,7 @@ Zotero.Translate.prototype.runHandler = function(type, argument) {
var returnValue = undefined;
if(this._handlers[type]) {
for(var i in this._handlers[type]) {
- Zotero.debug("Translate: running handler "+i+" for "+type);
+ Zotero.debug("Translate: running handler "+i+" for "+type, 5);
try {
if(this._parentTranslator) {
returnValue = this._handlers[type][i](null, argument);
@@ -453,7 +453,7 @@ Zotero.Translate.prototype.runHandler = function(type, argument) {
} else {
// otherwise, fail silently, so as not to interfere with
// interface cleanup
- Zotero.debug("Translate: "+e+' in handler '+i+' for '+type);
+ Zotero.debug("Translate: "+e+' in handler '+i+' for '+type, 5);
}
}
}
@@ -492,7 +492,7 @@ Zotero.Translate.prototype.getTranslators = function() {
this._setSandboxMode("detect");
var possibleTranslators = new Array();
- Zotero.debug("Translate: searching for translators for "+(this.path ? this.path : "an undisclosed location"));
+ Zotero.debug("Translate: Searching for translators for "+(this.path ? this.path : "an undisclosed location"), 3);
// see which translators can translate
this._translatorSearch = new Zotero.Translate.TranslatorSearch(this, translators);
@@ -518,7 +518,7 @@ Zotero.Translate.prototype._loadTranslator = function() {
// parse detect code for the translator
this._parseDetectCode(this.translator[0]);
- Zotero.debug("Translate: parsing code for "+this.translator[0].label);
+ Zotero.debug("Translate: Parsing code for "+this.translator[0].label, 4);
try {
Components.utils.evalInSandbox(this.translator[0].code, this._sandbox);
@@ -526,7 +526,7 @@ Zotero.Translate.prototype._loadTranslator = function() {
if(this._parentTranslator) {
throw(e);
} else {
- this._debug(e+' in parsing code for '+this.translator[0].label);
+ this._debug(e+' in parsing code for '+this.translator[0].label, 3);
this._translationComplete(false, e);
return false;
}
@@ -611,7 +611,7 @@ Zotero.Translate.prototype._parseDetectCode = function(translator) {
try {
Components.utils.evalInSandbox(detectCode, this._sandbox);
} catch(e) {
- this._debug(e+' in parsing detectCode for '+translator.label);
+ this._debug(e+' in parsing detectCode for '+translator.label, 3);
return;
}
}
@@ -620,50 +620,37 @@ Zotero.Translate.prototype._parseDetectCode = function(translator) {
/*
* generates a sandbox for scraping/scraper detection
*/
-Zotero.Translate._searchSandboxRegexp = new RegExp();
-Zotero.Translate._searchSandboxRegexp.compile("^http://[\\w.]+/");
Zotero.Translate.prototype._generateSandbox = function() {
var me = this;
- if(this.type == "web" || this.type == "search") {
- // get sandbox URL
- var sandboxLocation = "http://www.example.com/";
- if(this.type == "web") {
- // use real URL, not proxied version, to create sandbox
- sandboxLocation = this.document.defaultView;
- Zotero.debug("Translate: binding sandbox to "+this.document.location.href);
- } else {
- // generate sandbox for search by extracting domain from translator
- // target, if one exists
+ // get sandbox URL
+ var sandboxLocation = "http://www.example.com/";
+ if(this.type == "web") {
+ // use real URL, not proxied version, to create sandbox
+ sandboxLocation = this.document.defaultView;
+ Zotero.debug("Translate: Binding sandbox to "+this.document.location.href, 4);
+ } else {
+ if (this.type == "search") {
+ // generate sandbox for search by extracting domain from translator target
if(this.translator && this.translator[0] && this.translator[0].target) {
// so that web translators work too
+ const searchSandboxRe = /^http:\/\/[\w.]+\//;
var tempURL = this.translator[0].target.replace(/\\/g, "").replace(/\^/g, "");
- var m = Zotero.Translate._searchSandboxRegexp.exec(tempURL);
- if(m) {
- sandboxLocation = m[0];
- }
+ var m = searchSandboxRe.exec(tempURL);
+ if(m) sandboxLocation = m[0];
}
- Zotero.debug("Translate: binding sandbox to "+sandboxLocation);
}
- this._sandbox = new Components.utils.Sandbox(sandboxLocation);
-
- this._sandbox.Zotero = new Object();
-
- // add ingester utilities
- this._sandbox.Zotero.Utilities = new Zotero.Utilities.Ingester(this);
- this._sandbox.Zotero.Utilities.HTTP = new Zotero.Utilities.Ingester.HTTP(this);
-
- // set up selectItems handler
- this._sandbox.Zotero.selectItems = function(options) { return me._selectItems(options) };
- } else {
- // use null URL to create sandbox. no idea why a blank string doesn't
- // work on all installations, but this should fix things.
- this._sandbox = new Components.utils.Sandbox("http://www.example.com/");
- this._sandbox.Zotero = new Object();
-
- this._sandbox.Zotero.Utilities = new Zotero.Utilities();
+ Zotero.debug("Translate: Binding sandbox to "+sandboxLocation, 4);
}
+ // set up sandbox
+ this._sandbox = new Components.utils.Sandbox(sandboxLocation);
+ this._sandbox.Zotero = new Object();
+
+ // add utilities
+ this._sandbox.Zotero.Utilities = new Zotero.Utilities.Translate(this);
+ this._sandbox.Zotero.Utilities.HTTP = this._sandbox.Zotero.Utilities;
+
if(this.type == "export") {
// add routines to retrieve items and collections
this._sandbox.Zotero.nextItem = function() { return me._exportGetItem() };
@@ -678,13 +665,16 @@ Zotero.Translate.prototype._generateSandbox = function() {
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)};
+ } else if(this.type == "web" || this.type == "search") {
+ // set up selectItems handler
+ this._sandbox.Zotero.selectItems = function(options) { return me._selectItems(options) };
}
}
this._sandbox.XPathResult = Components.interfaces.nsIDOMXPathResult;
// for debug messages
- this._sandbox.Zotero.debug = function(string) {me._debug(string)};
+ this._sandbox.Zotero.debug = function(string) {me._debug(string, 4)};
// for adding configuration options
this._sandbox.Zotero.configure = function(option, value) {me._configure(option, value) };
@@ -706,7 +696,7 @@ Zotero.Translate.prototype._generateSandbox = function() {
// note that setLocation() is not allowed
var safeTranslator = new Object();
safeTranslator.setSearch = function(arg) { return translation.setSearch(arg) };
- safeTranslator.setBrowser = function(arg) { return translation.setBrowser(arg) };
+ safeTranslator.setDocument = function(arg) { return translation.setDocument(arg) };
safeTranslator.setHandler = function(arg1, arg2) { translation.setHandler(arg1, arg2) };
safeTranslator.setString = function(arg) { translation.setString(arg) };
safeTranslator.setTranslator = function(arg) { return translation.setTranslator(arg) };
@@ -799,7 +789,7 @@ Zotero.Translate.prototype._setSandboxMode = function(mode) {
*/
Zotero.Translate.prototype._configure = function(option, value) {
this.configOptions[option] = value;
- Zotero.debug("Translate: setting configure option "+option+" to "+value);
+ Zotero.debug("Translate: Setting configure option "+option+" to "+value, 4);
}
/*
@@ -811,7 +801,7 @@ Zotero.Translate.prototype._configure = function(option, value) {
*/
Zotero.Translate.prototype._addOption = function(option, value) {
this.displayOptions[option] = value;
- Zotero.debug("Translate: setting display option "+option+" to "+value);
+ Zotero.debug("Translate: Setting display option "+option+" to "+value, 4);
}
/*
@@ -884,8 +874,8 @@ Zotero.Translate.prototype._translationComplete = function(returnValue, error) {
if(this.type == "search" && !this._itemsDone) {
// if we're performing a search and didn't get any results, go on
// to the next translator
- Zotero.debug("Translate: could not find a result using "+this.translator[0].label+": \n"
- +this._generateErrorString(error));
+ Zotero.debug("Translate: Could not find a result using "+this.translator[0].label+": \n"
+ +this._generateErrorString(error), 3);
if(this.translator.length > 1) {
this.translator.shift();
this.translate();
@@ -903,7 +893,7 @@ Zotero.Translate.prototype._translationComplete = function(returnValue, error) {
// report error to debug log
var errorString = this._generateErrorString(error);
- this._debug("Translation using "+(this.translator && this.translator[0] && this.translator[0].label ? this.translator[0].label : "no translator")+" failed: \n"+errorString);
+ this._debug("Translation using "+(this.translator && this.translator[0] && this.translator[0].label ? this.translator[0].label : "no translator")+" failed: \n"+errorString, 2);
if(this.type == "web") {
// report translation error for webpages
@@ -937,12 +927,8 @@ Zotero.Translate.prototype._generateErrorString = function(error) {
}
errorString += "\nurl => "+this.path
- + "\nextensions.zotero.cacheTranslatorData => "+Zotero.Prefs.get("cacheTranslatorData")
- // TODO: Currently using automaticSnapshots pref for everything
- // Eventually downloadAssociatedFiles may be a separate pref
- // for PDFs and other large files
- + "\nextensions.zotero.downloadAssociatedFiles => "+Zotero.Prefs.get("downloadAssociatedFiles");
- + "\nextensions.zotero.automaticSnapshots => "+Zotero.Prefs.get("automaticSnapshots");
+ + "\ndownloadAssociatedFiles => "+Zotero.Prefs.get("downloadAssociatedFiles")
+ + "\nautomaticSnapshots => "+Zotero.Prefs.get("automaticSnapshots");
return errorString.substr(1);
}
@@ -951,10 +937,10 @@ Zotero.Translate.prototype._generateErrorString = function(error) {
*/
Zotero.Translate.prototype._reportTranslationFailure = function(errorData) {
if(this.translator[0].inRepository && Zotero.Prefs.get("reportTranslationFailure")) {
- var postBody = "ids[]="+escape(this.translator[0].translatorID)+
- "&lastUpdated="+escape(this.translator[0].lastUpdated)+
- "&extVersion="+escape(Zotero.version)+
- "&errorData="+escape(errorData);
+ var postBody = "id=" + encodeURIComponent(this.translator[0].translatorID) +
+ "&lastUpdated=" + encodeURIComponent(this.translator[0].lastUpdated) +
+ "&diagnostic=" + encodeURIComponent(Zotero.getSystemInfo()) +
+ "&errorData=" + encodeURIComponent(errorData);
Zotero.Utilities.HTTP.doPost("http://www.zotero.org/repo/report", postBody);
}
}
@@ -1081,7 +1067,7 @@ Zotero.Translate.prototype._itemDone = function(item, attachedTo) {
if(this._parentTranslator) {
var pt = this._parentTranslator;
item.complete = function() { pt._itemDone(this) };
- Zotero.debug("Translate: calling done from parent sandbox");
+ Zotero.debug("Translate: Calling done from parent sandbox", 4);
}
this.runHandler("itemDone", item);
return;
@@ -1111,14 +1097,14 @@ Zotero.Translate.prototype._itemDone = function(item, attachedTo) {
// create new item
if(type == "attachment") {
if(this.type != "import") {
- Zotero.debug("Translate: discarding standalone attachment");
+ Zotero.debug("Translate: Discarding standalone attachment", 2);
return;
}
- Zotero.debug("Translate: adding attachment");
+ Zotero.debug("Translate: Adding attachment", 4);
if(!item.url && !item.path) {
- Zotero.debug("Translate: ignoring attachment: no path or URL specified");
+ Zotero.debug("Translate: Ignoring attachment: no path or URL specified", 2);
return;
}
@@ -1130,7 +1116,7 @@ Zotero.Translate.prototype._itemDone = function(item, attachedTo) {
item.path = item.url;
item.url = false;
} else if(protocol != "http" && protocol != "https") {
- Zotero.debug("Translate: unrecognized protocol "+protocol);
+ Zotero.debug("Translate: Unrecognized protocol "+protocol, 2);
return;
}
}
@@ -1142,10 +1128,10 @@ Zotero.Translate.prototype._itemDone = function(item, attachedTo) {
(item.mimeType ? item.mimeType : undefined),
(item.title ? item.title : undefined));
} catch(e) {
- Zotero.debug("Translate: error adding attachment "+item.url);
+ Zotero.debug("Translate: Error adding attachment "+item.url, 2);
return;
}
- Zotero.debug("Translate: created attachment; id is "+myID);
+ Zotero.debug("Translate: Created attachment; id is "+myID, 4);
var newItem = Zotero.Items.get(myID);
} else {
// generate nsIFile
@@ -1205,7 +1191,11 @@ Zotero.Translate.prototype._itemDone = function(item, attachedTo) {
for(var j in data) {
// try to assign correct creator type
if(data[j].creatorType) {
- var creatorTypeID = Zotero.CreatorTypes.getID(data[j].creatorType);
+ try {
+ var creatorType = Zotero.CreatorTypes.getID(data[j].creatorType);
+ } catch(e) {
+ Zotero.debug("Translate: Invalid creator type "+data[j].creatorType+" for creator index "+j, 2);
+ }
}
if(!creatorTypeID) {
var creatorTypeID = 1;
@@ -1240,14 +1230,14 @@ Zotero.Translate.prototype._itemDone = function(item, attachedTo) {
// try to map from base field
if(Zotero.ItemFields.isBaseField(fieldID)) {
var fieldID = Zotero.ItemFields.getFieldIDFromTypeAndBase(typeID, fieldID);
- if(fieldID) Zotero.debug("Translate: mapping "+field+" to "+Zotero.ItemFields.getName(fieldID));
+ if(fieldID) Zotero.debug("Translate: Mapping "+field+" to "+Zotero.ItemFields.getName(fieldID), 5);
}
// if field is valid for this type, set field
if(fieldID && Zotero.ItemFields.isValidForType(fieldID, typeID)) {
newItem.setField(fieldID, data);
} else {
- Zotero.debug("Translate: discarded field "+field+" for item: field not valid for type "+type);
+ Zotero.debug("Translate: Discarded field "+field+" for item: field not valid for type "+type, 3);
}
}
}
@@ -1316,11 +1306,13 @@ Zotero.Translate.prototype._itemDone = function(item, attachedTo) {
var downloadAssociatedFiles = Zotero.Prefs.get("downloadAssociatedFiles");
// handle attachments
- if(item.attachments && this.saveAttachments && (automaticSnapshots || downloadAssociatedFiles)) {
+ if(item.attachments && this.saveAttachments &&
+ // DEBUG: is "this.type == 'import'" still necessary with this.saveAttachments?
+ (this.type == 'import' || automaticSnapshots || downloadAssociatedFiles)) {
for each(var attachment in item.attachments) {
if(this.type == "web") {
if(!attachment.url && !attachment.document) {
- Zotero.debug("Translate: not adding attachment: no URL specified");
+ Zotero.debug("Translate: Not adding attachment: no URL specified", 2);
} else {
if(attachment.snapshot === false) {
if(!automaticSnapshots) {
@@ -1334,7 +1326,7 @@ Zotero.Translate.prototype._itemDone = function(item, attachedTo) {
(attachment.title ? attachment.title : attachment.document.title));
} else {
if(!attachment.mimeType || !attachment.title) {
- Zotero.debug("Translate: NOTICE: either mimeType or title is missing; attaching file will be slower");
+ Zotero.debug("Translate: Either mimeType or title is missing; attaching file will be slower", 3);
}
try {
@@ -1342,7 +1334,7 @@ Zotero.Translate.prototype._itemDone = function(item, attachedTo) {
(attachment.mimeType ? attachment.mimeType : undefined),
(attachment.title ? attachment.title : undefined));
} catch(e) {
- Zotero.debug("Translate: error adding attachment "+attachment.url);
+ Zotero.debug("Translate: Error adding attachment "+attachment.url, 2);
}
}
} else if(attachment.document
@@ -1354,7 +1346,7 @@ Zotero.Translate.prototype._itemDone = function(item, attachedTo) {
try {
Zotero.Attachments.importFromDocument(attachment.document, myID, attachment.title);
} catch(e) {
- Zotero.debug("Translate: error attaching document");
+ Zotero.debug("Translate: Error attaching document", 2);
}
// Save attachment if snapshot pref enabled or not HTML
// (in which case downloadAssociatedFiles applies)
@@ -1386,7 +1378,7 @@ Zotero.Translate.prototype._itemDone = function(item, attachedTo) {
try {
Zotero.Attachments.importFromURL(attachment.url, myID, title, fileBaseName);
} catch(e) {
- Zotero.debug("Zotero.Translate: error adding attachment "+attachment.url);
+ Zotero.debug("Translate: Error adding attachment "+attachment.url, 2);
}
}
}
@@ -1493,10 +1485,10 @@ Zotero.Translate.prototype._processCollection = function(collection, parentID) {
} else {
// add mapped items to collection
if(this._IDMap[child.id]) {
- Zotero.debug("Translate: adding "+this._IDMap[child.id]);
+ Zotero.debug("Translate: Adding "+this._IDMap[child.id], 5);
newCollection.addItem(this._IDMap[child.id]);
} else {
- Zotero.debug("Translate: could not map "+child.id+" to an imported item");
+ Zotero.debug("Translate: Could not map "+child.id+" to an imported item", 2);
}
}
}
@@ -1507,10 +1499,13 @@ Zotero.Translate.prototype._processCollection = function(collection, parentID) {
/*
* logs a debugging message
*/
-Zotero.Translate.prototype._debug = function(string) {
+Zotero.Translate.prototype._debug = function(string, level) {
// if handler does not return anything explicitly false, show debug
// message in console
- if(this.runHandler("debug", string) !== false) Zotero.debug(string, 4);
+ if(this.runHandler("debug", string) !== false) {
+ if(typeof string == "string") string = "Translate: "+string;
+ Zotero.debug(string, level);
+ }
}
/*
@@ -1550,41 +1545,41 @@ Zotero.Translate.prototype._search = function() {
**/
Zotero.Translate.prototype._import = function() {
this.waitForCompletion = true;
- var me = this;
- this._importGetCharacterSet(function(charset) { me._importDoComplete(charset) });
- return true;
+ this._importSniffCharacterSet();
}
/**
- * Sniff file if a real file exists
- *
- * @param {Function} callback A callback function to be executed after sniffing
- **/
-Zotero.Translate.prototype._importGetCharacterSet = function(callback) {
+ * Sniff file for its character set, then proceed with the rest of translation
+ */
+Zotero.Translate.prototype._importSniffCharacterSet = function(callback) {
if(!this._storage) {
- // need to check charset
-
if(this._charset) {
// have charset already; just go on
- callback(this._charset);
+ this._importDoneSniffing(this._charset);
} else {
- // look for charset
- var me = this;
- Zotero.File.getCharsetFromFile(this.location, "text/plain",
- function(charset) {
- me._charset = charset;
- callback(charset);
- });
+ // need to check charset
+ importCharset = Zotero.Prefs.get("import.charset");
+ if(importCharset == "auto") {
+ // look for charset
+ var me = this;
+ Zotero.File.getCharsetFromFile(this.location, "text/plain",
+ function(charset) {
+ me._charset = charset;
+ me._importDoneSniffing(charset);
+ });
+ } else {
+ this._importDoneSniffing(importCharset);
+ }
}
} else {
- callback();
+ this._importDoneSniffing();
}
}
/**
* Complete import (used as callback after sniffing)
**/
-Zotero.Translate.prototype._importDoComplete = function(charset) {
+Zotero.Translate.prototype._importDoneSniffing = function(charset) {
this._importConfigureIO(charset);
try {
@@ -1659,19 +1654,22 @@ Zotero.Translate.prototype._importConfigureIO = function(charset) {
this._streams.push(this._inputStream);
}
- var filePosition = 0;
-
- if(charset) { // if have detected charset
- Zotero.debug("Using detected character set "+charset);
+ var bomLength = 0;
+ if(charset === undefined || (charset && charset.length > 3 && charset.substr(0, 3) == "UTF")) {
// 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);
- }
-
+ var bomCharset = this._importGetBOM();
+ var bomLength = (bomCharset ? BOMs[bomCharset].length : 0);
+ this._inputStream.QueryInterface(Components.interfaces.nsISeekableStream)
+ .seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, bomLength);
+ if(bomCharset) charset = this._charset = bomCharset;
+ }
+
+ var intlStream = null;
+ if(charset) {
+ // if have detected charset
+ Zotero.debug("Translate: Using detected character set "+charset, 3);
// convert from detected charset
- var intlStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
+ 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);
@@ -1680,12 +1678,9 @@ Zotero.Translate.prototype._importConfigureIO = function(charset) {
// 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);
- }
+ // seek back to the beginning
+ me._inputStream.QueryInterface(Components.interfaces.nsISeekableStream)
+ .seek(Components.interfaces.nsISeekableStream.NS_SEEK_SET, bomLength);
intlStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(Components.interfaces.nsIConverterInputStream);
@@ -1695,7 +1690,6 @@ Zotero.Translate.prototype._importConfigureIO = function(charset) {
} catch(e) {
throw "Text encoding not supported";
}
-
me._streams.push(intlStream);
}
@@ -1710,7 +1704,6 @@ Zotero.Translate.prototype._importConfigureIO = function(charset) {
var amountRead = me._inputStream.readLine(str);
}
if(amountRead) {
- filePosition += amountRead;
return str.value;
} else {
return false;
@@ -1725,7 +1718,6 @@ Zotero.Translate.prototype._importConfigureIO = function(charset) {
var amountRead = intlStream.readString(amount, str);
if(amountRead) {
- filePosition += amountRead;
return str.value;
} else {
return false;
@@ -1740,7 +1732,6 @@ Zotero.Translate.prototype._importConfigureIO = function(charset) {
// read from the scriptable input stream
var string = sStream.read(amount);
- filePosition += string.length;
return string;
}
}
@@ -1757,7 +1748,7 @@ Zotero.Translate.prototype._importConfigureIO = function(charset) {
*
* @return The length of the UTF BOM.
*/
-Zotero.Translate.prototype._importGetBOMLength = function() {
+Zotero.Translate.prototype._importGetBOM = 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);
@@ -1778,7 +1769,7 @@ Zotero.Translate.prototype._importGetBOMLength = function() {
if(possibleBOMs[charset][0] == readChar) {
if(possibleBOMs[charset].length == 1) {
// have checked entire BOM
- return BOMs[charset].length;
+ return charset;
} else {
// keep checking
newBOMs[charset] = possibleBOMs[charset].substr(1);
@@ -1790,7 +1781,7 @@ Zotero.Translate.prototype._importGetBOMLength = function() {
possibleBOMs = newBOMs;
}
- return 0;
+ return null;
}
/**
@@ -1940,7 +1931,6 @@ Zotero.Translate.prototype._exportConfigureIO = function() {
if(streamCharset == "MACINTOSH") {
// fix buggy Mozilla MacRoman
splitData = data.split(/([\r\n]+)/);
- Zotero.debug(splitData);
for(var i=0; is with /ns
+/**
+ * Eliminates HTML tags, replacing <br>s with newlines
+ * @type String
*/
-Zotero.Utilities.prototype.cleanTags = function(x) {
+Zotero.Utilities.prototype.cleanTags = function(/**String*/ x) {
if(typeof(x) != "string") {
throw "cleanTags: argument must be a string";
}
@@ -150,15 +142,15 @@ Zotero.Utilities.prototype.cleanTags = function(x) {
return x.replace(/<[^>]+>/g, "");
}
-/*
- * Encode special XML/HTML characters
- *
- * Certain entities can be inserted manually:
- *
- * =>
- * => …
+/**
+ * Encode special XML/HTML characters
+ *
+ * Certain entities can be inserted manually:
+ * <ZOTEROBREAK/> => <br/>
+ * <ZOTEROHELLIP/> => …
+ * @type String
*/
-Zotero.Utilities.prototype.htmlSpecialChars = function(str) {
+Zotero.Utilities.prototype.htmlSpecialChars = function(/**String*/ str) {
if (typeof str != 'string') {
throw "Argument '" + str + "' must be a string in Zotero.Utilities.htmlSpecialChars()";
}
@@ -190,27 +182,28 @@ Zotero.Utilities.prototype.htmlSpecialChars = function(str) {
return newString;
}
-
-Zotero.Utilities.prototype.unescapeHTML = function(str) {
+/**
+ * Decodes HTML entities within a string, returning plain text
+ * @type String
+ */
+Zotero.Utilities.prototype.unescapeHTML = function(/**String*/ str) {
var nsISUHTML = Components.classes["@mozilla.org/feed-unescapehtml;1"]
.getService(Components.interfaces.nsIScriptableUnescapeHTML);
return nsISUHTML.unescape(str);
}
-
-/*
- * Parses a text string for HTML/XUL markup and returns an array of parts
+/**
+ * Parses a text string for HTML/XUL markup and returns an array of parts. Currently only finds
+ * HTML links (<a> tags)
*
- * Currently only finds HTML links ( tags)
- *
- * Returns an array of objects with the following form:
- * {
+ * @return {Array} An array of objects with the following form:
+ * {
* type: 'text'|'link',
* text: "text content",
* [ attributes: { key1: val [ , key2: val, ...] }
- * }
+ * }
*/
-Zotero.Utilities.prototype.parseMarkup = function(str) {
+Zotero.Utilities.prototype.parseMarkup = function(/**String*/ str) {
var parts = [];
var splits = str.split(/( ]+>[^<]*<\/a>)/);
@@ -245,7 +238,6 @@ Zotero.Utilities.prototype.parseMarkup = function(str) {
return parts;
}
-
Zotero.Utilities.prototype.min3 = function (a, b, c) {
var min = a;
if (b < min) {
@@ -285,8 +277,11 @@ Zotero.Utilities.prototype.levenshtein = function (a, b) {
}
-/*
+/**
* Test if a string is an integer
+ *
+ * @deprecated Use isNaN(parseInt(x))
+ * @type Boolean
*/
Zotero.Utilities.prototype.isInt = function(x) {
if(parseInt(x) == x) {
@@ -295,7 +290,6 @@ Zotero.Utilities.prototype.isInt = function(x) {
return false;
}
-
/**
* Generate a random integer between min and max inclusive
*
@@ -370,20 +364,17 @@ Zotero.Utilities.prototype.md5 = function(str) {
}
-/*
- * Get current zotero version
+/**
+ * Parse a page range
+ *
+ * @param {String} Page range to parse
+ * @return {Integer[]} Start and end pages
*/
-Zotero.Utilities.prototype.getVersion = function() {
- return Zotero.version;
-}
-
-/*
- * Get a page range, given a user-entered set of pages
- */
-Zotero.Utilities.prototype._pageRangeRegexp = /^\s*([0-9]+)-([0-9]+)\s*$/;
Zotero.Utilities.prototype.getPageRange = function(pages) {
+ const pageRangeRegexp = /^\s*([0-9]+)-([0-9]+)\s*$/
+
var pageNumbers;
- var m = this._pageRangeRegexp.exec(pages);
+ var m = pageRangeRegexp.exec(pages);
if(m) {
// A page range
pageNumbers = [m[1], m[2]];
@@ -394,13 +385,13 @@ Zotero.Utilities.prototype.getPageRange = function(pages) {
return pageNumbers;
}
-/*
- * provide inArray function
- */
-Zotero.Utilities.prototype.inArray = Zotero.inArray;
-
-/*
- * pads a number or other string with a given string on the left
+/**
+ * Pads a number or other string with a given string on the left
+ *
+ * @param {String} string String to pad
+ * @param {String} pad String to use as padding
+ * @length {Integer} length Length of new padded string
+ * @type String
*/
Zotero.Utilities.prototype.lpad = function(string, pad, length) {
string = string ? string + '' : '';
@@ -410,8 +401,11 @@ Zotero.Utilities.prototype.lpad = function(string, pad, length) {
return string;
}
-/*
- * returns true if an item type exists, false if it does not
+/**
+ * Tests if an item type exists
+ *
+ * @param {String} type Item type
+ * @type Boolean
*/
Zotero.Utilities.prototype.itemTypeExists = function(type) {
if(Zotero.ItemTypes.getID(type)) {
@@ -421,8 +415,11 @@ Zotero.Utilities.prototype.itemTypeExists = function(type) {
}
}
-/*
- * returns an array of all (string) creatorTypes valid for a (string) itemType
+/**
+ * Find valid creator types for a given item type
+ *
+ * @param {String} type Item type
+ * @return {String[]} Creator types
*/
Zotero.Utilities.prototype.getCreatorsForType = function(type) {
var types = Zotero.CreatorTypes.getTypesForItemType(Zotero.ItemTypes.getID(type));
@@ -433,8 +430,12 @@ Zotero.Utilities.prototype.getCreatorsForType = function(type) {
return cleanTypes;
}
-/*
- * returns a localized creatorType name
+/**
+ * Gets a creator type name, localized to the current locale
+ *
+ * @param {String} type Creator type
+ * @param {String} Localized creator type
+ * @type Boolean
*/
Zotero.Utilities.prototype.getLocalizedCreatorType = function(type) {
try {
@@ -444,10 +445,12 @@ Zotero.Utilities.prototype.getLocalizedCreatorType = function(type) {
}
}
-/*
- * Cleans a title, capitalizing the proper words and replacing " :" with ":"
+/**
+ * Cleans a title, converting it to title case and replacing " :" with ":"
*
- * Follows capitalizeTitles pref, unless |force| is true
+ * @param {String} string
+ * @param {Boolean} force Forces title case conversion, even if the capitalizeTitles pref is off
+ * @type String
*/
Zotero.Utilities.prototype.capitalizeTitle = function(string, force) {
string = this.trimInternal(string);
@@ -459,26 +462,50 @@ Zotero.Utilities.prototype.capitalizeTitle = function(string, force) {
return string;
}
-/*
- * END ZOTERO FOR FIREFOX EXTENSIONS
+/**
+ * @class All functions accessible from within Zotero.Utilities namespace inside sandboxed
+ * translators
+ *
+ * @constructor
+ * @augments Zotero.Utilities
+ * @borrows Zotero.inArray as this.inArray
+ * @borrows Zotero.Date.formatDate as this.formatDate
+ * @borrows Zotero.Date.strToDate as this.strToDate
+ * @borrows Zotero.Date.strToISO as this.strToISO
+ * @borrows Zotero.OpenURL.lookupContextObject as this.lookupContextObject
+ * @borrows Zotero.OpenURL.parseContextObject as this.parseContextObject
+ * @borrows Zotero.Utilities.HTTP.processDocuments as this.processDocuments
+ * @borrows Zotero.Utilities.HTTP.doPost as this.doPost
+ * @param {Zotero.Translate} translate
*/
-
-/////////////////////////////////////////////////////////////////
-//
-// Zotero.Utilities.Ingester
-//
-/////////////////////////////////////////////////////////////////
-// Zotero.Utilities.Ingester extends Zotero.Utilities, offering additional
-// classes relating to data extraction specifically from HTML documents.
-
-Zotero.Utilities.Ingester = function(translate, proxiedURL) {
+Zotero.Utilities.Translate = function(translate) {
this.translate = translate;
}
-Zotero.Utilities.Ingester.prototype = new Zotero.Utilities();
+Zotero.Utilities.Translate.prototype = new Zotero.Utilities();
+Zotero.Utilities.Translate.prototype.inArray = Zotero.inArray;
+Zotero.Utilities.Translate.prototype.formatDate = Zotero.Date.formatDate;
+Zotero.Utilities.Translate.prototype.strToDate = Zotero.Date.strToDate;
+Zotero.Utilities.Translate.prototype.strToISO = Zotero.Date.strToISO;
+Zotero.Utilities.Translate.prototype.lookupContextObject = Zotero.OpenURL.lookupContextObject;
+Zotero.Utilities.Translate.prototype.parseContextObject = Zotero.OpenURL.parseContextObject;
-// Takes an XPath query and returns the results
-Zotero.Utilities.Ingester.prototype.gatherElementsOnXPath = function(doc, parentNode, xpath, nsResolver) {
+/**
+ * Gets the current Zotero version
+ *
+ * @type String
+ */
+Zotero.Utilities.prototype.getVersion = function() {
+ return Zotero.version;
+}
+
+/**
+ * Takes an XPath query and returns the results
+ *
+ * @deprecated Use doc.evaluate() directly instead
+ * @type Node[]
+ */
+Zotero.Utilities.Translate.prototype.gatherElementsOnXPath = function(doc, parentNode, xpath, nsResolver) {
var elmts = [];
var iterator = doc.evaluate(xpath, parentNode, nsResolver, Components.interfaces.nsIDOMXPathResult.ANY_TYPE,null);
@@ -491,13 +518,13 @@ Zotero.Utilities.Ingester.prototype.gatherElementsOnXPath = function(doc, parent
return elmts;
}
-/*
+/**
* Gets a given node as a string containing all child nodes
*
- * WARNING: This is DEPRECATED and may be removed in the final release. Use
- * doc.evaluate and the "nodeValue" or "textContent" property
+ * @deprecated Use doc.evaluate and the "nodeValue" or "textContent" property
+ * @type String
*/
-Zotero.Utilities.Ingester.prototype.getNodeString = function(doc, contextNode, xpath, nsResolver) {
+Zotero.Utilities.Translate.prototype.getNodeString = function(doc, contextNode, xpath, nsResolver) {
var elmts = this.gatherElementsOnXPath(doc, contextNode, xpath, nsResolver);
var returnVar = "";
for(var i=0; i textContent pairs, suitable for passing to
+ * Zotero.selectItems from within a translator
*/
-Zotero.Utilities.Ingester.prototype.getItemArray = function(doc, inHere, urlRe, rejectRe) {
+Zotero.Utilities.Translate.prototype.getItemArray = function(doc, inHere, urlRe, rejectRe) {
var availableItems = new Object(); // Technically, associative arrays are objects
// Require link to match this
@@ -559,53 +593,54 @@ Zotero.Utilities.Ingester.prototype.getItemArray = function(doc, inHere, urlRe,
return availableItems;
}
-Zotero.Utilities.Ingester.prototype.lookupContextObject = function(co, done, error) {
- return Zotero.OpenURL.lookupContextObject(co, done, error);
+/**
+ * Load a single document in a hidden browser
+ *
+ * @deprecated Use processDocuments with a single URL
+ * @see Zotero.Utilities.Translate#processDocuments
+ */
+Zotero.Utilities.Translate.prototype.loadDocument = function(url, succeeded, failed) {
+ Zotero.debug("Zotero.Utilities.loadDocument is deprecated; please use processDocuments in new code");
+ this.processDocuments([url], succeeded, null, failed);
}
-Zotero.Utilities.Ingester.prototype.parseContextObject = function(co, item) {
- return Zotero.OpenURL.parseContextObject(co, item);
-}
-
-
-// Ingester adapters for Zotero.Utilities.HTTP to handle proxies
-
-Zotero.Utilities.Ingester.prototype.loadDocument = function(url, succeeded, failed) {
- this.processDocuments([ url ], succeeded, null, failed);
-}
-
-Zotero.Utilities.Ingester._protocolRe = new RegExp();
-Zotero.Utilities.Ingester._protocolRe.compile("^(?:(?:http|https|ftp):|[^:](?:/.*)?$)", "i");
-Zotero.Utilities.Ingester.prototype.processDocuments = function(urls, processor, done, exception) {
+/**
+ * Already documented in Zotero.Utilities.HTTP
+ * @ignore
+ */
+Zotero.Utilities.Translate.prototype.processDocuments = function(urls, processor, done, exception) {
if(this.translate.locationIsProxied) {
- for(var i in urls) {
- if(this.translate.locationIsProxied) {
- urls[i] = Zotero.Proxies.properToProxy(urls[i]);
- }
- // check for a protocol colon
- if(!Zotero.Utilities.Ingester._protocolRe.test(urls[i])) {
- throw("invalid URL in processDocuments");
+ if(typeof(urls) == "string") {
+ urls = [this._convertURL(urls)];
+ } else {
+ for(var i in urls) {
+ urls[i] = this._convertURL(urls[i]);
}
}
}
- // unless the translator has proposed some way to handle an error, handle it
+ // Unless the translator has proposed some way to handle an error, handle it
// by throwing a "scraping error" message
if(!exception) {
var translate = this.translate;
- exception = function(e) {
+ var exception = function(e) {
translate.error(false, e);
}
}
- Zotero.Utilities.HTTP.processDocuments(null, urls, processor, done, exception);
+ Zotero.Utilities.HTTP.processDocuments(urls, processor, done, exception);
}
-Zotero.Utilities.Ingester.HTTP = function(translate) {
- this.translate = translate;
-}
-
-Zotero.Utilities.Ingester.HTTP.prototype.doGet = function(urls, processor, done, responseCharset) {
+/**
+* Send an HTTP GET request via XMLHTTPRequest
+*
+* @param {String|String[]} urls URL(s) to request
+* @param {Function} processor Callback to be executed for each document loaded
+* @param {Function} done Callback to be executed after all documents have been loaded
+* @param {String} responseCharset Character set to force on the response
+* @return {Boolean} True if the request was sent, or false if the browser is offline
+*/
+Zotero.Utilities.Translate.prototype.doGet = function(urls, processor, done, responseCharset) {
var callAgain = false;
if(typeof(urls) == "string") {
@@ -615,12 +650,7 @@ Zotero.Utilities.Ingester.HTTP.prototype.doGet = function(urls, processor, done,
var url = urls.shift();
}
- if(this.translate.locationIsProxied) {
- url = Zotero.Proxies.properToProxy(url);
- }
- if(!Zotero.Utilities.Ingester._protocolRe.test(url)) {
- throw("invalid URL in processDocuments");
- }
+ url = this._convertURL(url);
var me = this;
@@ -643,13 +673,12 @@ Zotero.Utilities.Ingester.HTTP.prototype.doGet = function(urls, processor, done,
}, responseCharset);
}
-Zotero.Utilities.Ingester.HTTP.prototype.doPost = function(url, body, onDone, requestContentType, responseCharset) {
- if(this.translate.locationIsProxied) {
- url = Zotero.Proxies.properToProxy(url);
- }
- if(!Zotero.Utilities.Ingester._protocolRe.test(url)) {
- throw("invalid URL in processDocuments");
- }
+/**
+ * Already documented in Zotero.Utilities.HTTP
+ * @ignore
+ */
+Zotero.Utilities.Translate.prototype.doPost = function(url, body, onDone, requestContentType, responseCharset) {
+ url = this._convertURL(url);
var translate = this.translate;
Zotero.Utilities.HTTP.doPost(url, body, function(xmlhttp) {
@@ -661,72 +690,99 @@ Zotero.Utilities.Ingester.HTTP.prototype.doPost = function(url, body, onDone, re
}, requestContentType, responseCharset);
}
-// These are front ends for XMLHttpRequest. XMLHttpRequest can't actually be
-// accessed outside the sandbox, and even if it could, it wouldn't let scripts
-// access across domains, so everything's replicated here.
-Zotero.Utilities.HTTP = new function() {
- this.doGet = doGet;
- this.doPost = doPost;
- this.doHead = doHead;
- this.browserIsOffline = browserIsOffline;
+/**
+ * Translate a URL to a form that goes through the appropriate proxy, or convert a relative URL to
+ * an absolute one
+ *
+ * @param {String} url
+ * @type String
+ * @private
+ */
+Zotero.Utilities.Translate.prototype._convertURL = function(url) {
+ const protocolRe = /^(?:(?:http|https|ftp):)/i;
+ const fileRe = /^[^:]*/;
+ if(this.translate.locationIsProxied) {
+ url = Zotero.Ingester.ProxyMonitor.properToProxy(url);
+ }
+ if(protocolRe.test(url)) return url;
+ if(!fileRe.test(url)) {
+ throw "Invalid URL supplied for HTTP request";
+ } else {
+ return Components.classes["@mozilla.org/network/io-service;1"].
+ getService(Components.interfaces.nsIIOService).
+ newURI(this.translate.location, "", null).resolve(url);
+ }
+}
+
+/**
+ * Functions for performing HTTP requests, both via XMLHTTPRequest and using a hidden browser
+ * @namespace
+ */
+Zotero.Utilities.HTTP = new function() {
this.WebDAV = {};
+
/**
* Send an HTTP GET request via XMLHTTPRequest
- *
- * Returns false if browser is offline
- *
- * doGet can be called as:
- * Zotero.Utilities.HTTP.doGet(url, onDone)
- *
- * Returns the XMLHTTPRequest object
- **/
- function doGet(url, onDone, responseCharset) {
+ *
+ * @param {String} url URL to request
+ * @param {Function} onDone Callback to be executed upon request completion
+ * @param {Function} onError Callback to be executed if an error occurs. Not implemented
+ * @param {String} responseCharset Character set to force on the response
+ * @return {Boolean} True if the request was sent, or false if the browser is offline
+ */
+ this.doGet = function(url, onDone, responseCharset) {
Zotero.debug("HTTP GET "+url);
if (this.browserIsOffline()){
return false;
}
+ /*
var xmlhttp = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance();
// Prevent certificate/authentication dialogs from popping up
xmlhttp.mozBackgroundRequest = true;
xmlhttp.open('GET', url, true);
+ */
- xmlhttp.onreadystatechange = function(){
+ // Workaround for "Accept third-party cookies" being off in Firefox 3.0.1
+ // https://www.zotero.org/trac/ticket/1070
+ const Cc = Components.classes;
+ const Ci = Components.interfaces;
+ var ds = Cc["@mozilla.org/webshell;1"].
+ createInstance(Components.interfaces.nsIDocShellTreeItem).
+ QueryInterface(Ci.nsIInterfaceRequestor);
+ ds.itemType = Ci.nsIDocShellTreeItem.typeContent;
+ var xmlhttp = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+ createInstance(Ci.nsIXMLHttpRequest);
+ xmlhttp.mozBackgroundRequest = true;
+ xmlhttp.open("GET", url, true);
+ xmlhttp.channel.loadGroup = ds.getInterface(Ci.nsILoadGroup);
+ xmlhttp.channel.loadFlags |= Ci.nsIChannel.LOAD_DOCUMENT_URI;
+
+ /** @ignore */
+ xmlhttp.onreadystatechange = function() {
_stateChange(xmlhttp, onDone, responseCharset);
};
- // 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);
- }
+ xmlhttp.send(null);
return xmlhttp;
}
-
/**
* Send an HTTP POST request via XMLHTTPRequest
*
- * Returns false if browser is offline
- *
- * doPost can be called as:
- * Zotero.Utilities.HTTP.doPost(url, body, onDone)
- *
- * Returns the XMLHTTPRequest object
- **/
- function doPost(url, body, onDone, requestContentType, responseCharset) {
+ * @param {String} url URL to request
+ * @param {String} body Request body
+ * @param {Function} onDone Callback to be executed upon request completion
+ * @param {String} requestContentType Request content type (usually
+ * application/x-www-form-urlencoded)
+ * @param {String} responseCharset Character set to force on the response
+ * @return {Boolean} True if the request was sent, or false if the browser is offline
+ */
+ this.doPost = function(url, body, onDone, requestContentType, responseCharset) {
var bodyStart = body.substr(0, 1024);
// Don't display password in console
bodyStart = bodyStart.replace(/password=[^&]+/, 'password=********');
@@ -736,73 +792,91 @@ Zotero.Utilities.HTTP = new function() {
bodyStart + '... (' + body.length + ' chars)' : bodyStart)
+ " to " + url);
+
if (this.browserIsOffline()){
return false;
}
+ /*
var xmlhttp = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance();
// Prevent certificate/authentication dialogs from popping up
xmlhttp.mozBackgroundRequest = true;
xmlhttp.open('POST', url, true);
+ */
+
+ // Workaround for "Accept third-party cookies" being off in Firefox 3.0.1
+ // https://www.zotero.org/trac/ticket/1070
+ const Cc = Components.classes;
+ const Ci = Components.interfaces;
+ var ds = Cc["@mozilla.org/webshell;1"].
+ createInstance(Components.interfaces.nsIDocShellTreeItem).
+ QueryInterface(Ci.nsIInterfaceRequestor);
+ ds.itemType = Ci.nsIDocShellTreeItem.typeContent;
+ var xmlhttp = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+ createInstance(Ci.nsIXMLHttpRequest);
+ xmlhttp.mozBackgroundRequest = true;
+ xmlhttp.open("POST", url, true);
+ xmlhttp.channel.loadGroup = ds.getInterface(Ci.nsILoadGroup);
+ xmlhttp.channel.loadFlags |= Ci.nsIChannel.LOAD_DOCUMENT_URI;
+
xmlhttp.setRequestHeader("Content-Type", (requestContentType ? requestContentType : "application/x-www-form-urlencoded" ));
+ /** @ignore */
xmlhttp.onreadystatechange = function(){
_stateChange(xmlhttp, onDone, responseCharset);
};
- // 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);
- }
+ xmlhttp.send(body);
return xmlhttp;
}
-
- function doHead(url, onDone) {
+ /**
+ * Send an HTTP HEAD request via XMLHTTPRequest
+ *
+ * @param {String} url URL to request
+ * @param {Function} onDone Callback to be executed upon request completion
+ * @return {Boolean} True if the request was sent, or false if the browser is offline
+ */
+ this.doHead = function(url, onDone) {
Zotero.debug("HTTP HEAD "+url);
if (this.browserIsOffline()){
return false;
}
+ /*
var xmlhttp = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance();
// Prevent certificate/authentication dialogs from popping up
xmlhttp.mozBackgroundRequest = true;
xmlhttp.open('HEAD', url, true);
+ */
+ // Workaround for "Accept third-party cookies" being off in Firefox 3.0.1
+ // https://www.zotero.org/trac/ticket/1070
+ const Cc = Components.classes;
+ const Ci = Components.interfaces;
+ var ds = Cc["@mozilla.org/webshell;1"].
+ createInstance(Components.interfaces.nsIDocShellTreeItem).
+ QueryInterface(Ci.nsIInterfaceRequestor);
+ ds.itemType = Ci.nsIDocShellTreeItem.typeContent;
+ var xmlhttp = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+ createInstance(Ci.nsIXMLHttpRequest);
+ xmlhttp.open("HEAD", url, true);
+ xmlhttp.channel.loadGroup = ds.getInterface(Ci.nsILoadGroup);
+ xmlhttp.channel.loadFlags |= Ci.nsIChannel.LOAD_DOCUMENT_URI;
+
+ /** @ignore */
xmlhttp.onreadystatechange = function(){
_stateChange(xmlhttp, onDone);
};
- // 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);
- }
+ xmlhttp.send(null);
return xmlhttp;
}
-
/**
* Send an HTTP OPTIONS request via XMLHTTPRequest
*
@@ -825,34 +899,18 @@ Zotero.Utilities.HTTP = new function() {
// Prevent certificate/authentication dialogs from popping up
xmlhttp.mozBackgroundRequest = true;
xmlhttp.open('OPTIONS', uri.spec, true);
-
+ /** @ignore */
xmlhttp.onreadystatechange = function() {
_stateChange(xmlhttp, callback);
};
-
- // 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);
- }
-
+ xmlhttp.send(null);
return xmlhttp;
}
-
//
// WebDAV methods
//
-
/**
* Send a WebDAV PROP* request via XMLHTTPRequest
*
@@ -1042,12 +1100,101 @@ Zotero.Utilities.HTTP = new function() {
}
- function browserIsOffline() {
+ /**
+ * Checks if the browser is currently in "Offline" mode
+ *
+ * @type Boolean
+ */
+ this.browserIsOffline = function() {
return Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService).offline;
}
+ /**
+ * Load one or more documents in a hidden browser
+ *
+ * @param {String|String[]} urls URL(s) of documents to load
+ * @param {Function} processor Callback to be executed for each document loaded
+ * @param {Function} done Callback to be executed after all documents have been loaded
+ * @param {Function} exception Callback to be executed if an exception occurs
+ */
+ this.processDocuments = function(urls, processor, done, exception) {
+ /**
+ * Removes event listener for the load event and deletes the hidden browser
+ */
+ var removeListeners = function() {
+ hiddenBrowser.removeEventListener(loadEvent, onLoad, true);
+ Zotero.Browser.deleteHiddenBrowser(hiddenBrowser);
+ }
+
+ /**
+ * Loads the next page
+ * @inner
+ */
+ var doLoad = function() {
+ if(urls.length) {
+ var url = urls.shift();
+ try {
+ Zotero.debug("loading "+url);
+ hiddenBrowser.loadURI(url);
+ } catch(e) {
+ removeListeners();
+ if(exception) {
+ exception(e);
+ return;
+ } else {
+ throw(e);
+ }
+ }
+ } else {
+ removeListeners();
+ if(done) done();
+ }
+ };
+
+ /**
+ * Callback to be executed when a page load completes
+ * @inner
+ */
+ var onLoad = function() {
+ Zotero.debug(hiddenBrowser.contentDocument.location.href+" has been loaded");
+ if(hiddenBrowser.contentDocument.location.href != prevUrl) { // Just in case it fires too many times
+ prevUrl = hiddenBrowser.contentDocument.location.href;
+ try {
+ processor(hiddenBrowser.contentDocument);
+ } catch(e) {
+ removeListeners();
+ if(exception) {
+ exception(e);
+ return;
+ } else {
+ throw(e);
+ }
+ }
+ doLoad();
+ }
+ };
+
+ if(typeof(urls) == "string") urls = [urls];
+
+ var prevUrl;
+ var loadEvent = Zotero.isFx2 ? "load" : "pageshow";
+
+ var hiddenBrowser = Zotero.Browser.createHiddenBrowser();
+ hiddenBrowser.docShell.allowImages = false;
+ hiddenBrowser.addEventListener(loadEvent, onLoad, true);
+
+ doLoad();
+ }
+ /**
+ * Handler for XMLHttpRequest state change
+ *
+ * @param {nsIXMLHttpRequest} XMLHttpRequest whose state just changed
+ * @param {Function} [onDone] Callback for request completion
+ * @param {String} [responseCharset] Character set to force on the response
+ * @private
+ */
function _stateChange(xmlhttp, callback, responseCharset, data) {
switch (xmlhttp.readyState){
// Request not yet made
@@ -1075,99 +1222,12 @@ Zotero.Utilities.HTTP = new function() {
}
}
-// Downloads and processes documents with processor()
-// firstDoc - the first document to process with the processor (if null,
-// first document is processed without processor)
-// urls - an array of URLs to load
-// processor - a function to execute to process each document
-// done - a function to execute when all document processing is complete
-// exception - a function to execute if an exception occurs (exceptions are
-// also logged in the Zotero for Firefox log)
-// saveBrowser - whether to save the hidden browser object; usually, you don't
-// want to do this, because it makes it easier to leak memory
-Zotero.Utilities.HTTP.processDocuments = function(firstDoc, urls, processor, done, exception, saveBrowser) {
- var hiddenBrowser = Zotero.Browser.createHiddenBrowser();
- hiddenBrowser.docShell.allowImages = false;
- var prevUrl, url;
-
- if (urls.length == 0) {
- if(firstDoc) {
- processor(firstDoc, done);
- } else {
- done();
- }
- return;
- }
- var urlIndex = -1;
-
- var removeListeners = function() {
- hiddenBrowser.removeEventListener("pageshow", onLoad, true);
- if(!saveBrowser) {
- Zotero.Browser.deleteHiddenBrowser(hiddenBrowser);
- }
- }
- var doLoad = function() {
- urlIndex++;
- if (urlIndex < urls.length) {
- url = urls[urlIndex];
- try {
- Zotero.debug("loading "+url);
- hiddenBrowser.loadURI(url);
- } catch (e) {
- removeListeners();
- if(exception) {
- exception(e);
- return;
- } else {
- throw(e);
- }
- }
- } else {
- removeListeners();
- if(done) {
- done();
- }
- }
- };
- var onLoad = function() {
- Zotero.debug(hiddenBrowser.contentDocument.location.href+" has been loaded");
- if(hiddenBrowser.contentDocument.location.href != prevUrl) { // Just in case it fires too many times
- prevUrl = hiddenBrowser.contentDocument.location.href;
- try {
- processor(hiddenBrowser.contentDocument);
- } catch (e) {
- removeListeners();
- if(exception) {
- exception(e);
- return;
- } else {
- throw(e);
- }
- }
- doLoad();
- }
- };
- var init = function() {
- hiddenBrowser.addEventListener("pageshow", onLoad, true);
-
- if (firstDoc) {
- processor(firstDoc, doLoad);
- } else {
- doLoad();
- }
- }
-
- init();
-}
-
-
-/*
- * This would probably be better as a separate XPCOM service
+/**
+ * @namespace
*/
-Zotero.Utilities.AutoComplete = new function(){
- this.getResultComment = getResultComment;
-
- function getResultComment(textbox){
+// This would probably be better as a separate XPCOM service
+Zotero.Utilities.AutoComplete = new function() {
+ this.getResultComment = function (textbox){
var controller = textbox.controller;
for (var i=0; i
+
+
+
+
diff --git a/chrome/locale/en-US/zotero/zotero.dtd b/chrome/locale/en-US/zotero/zotero.dtd
index 235a157c40..e9b53c3088 100644
--- a/chrome/locale/en-US/zotero/zotero.dtd
+++ b/chrome/locale/en-US/zotero/zotero.dtd
@@ -123,7 +123,6 @@
-
diff --git a/chrome/locale/en-US/zotero/zotero.properties b/chrome/locale/en-US/zotero/zotero.properties
index 91fd50ba99..4ffa07555e 100644
--- a/chrome/locale/en-US/zotero/zotero.properties
+++ b/chrome/locale/en-US/zotero/zotero.properties
@@ -455,6 +455,7 @@ fulltext.indexState.partial = Partial
exportOptions.exportNotes = Export Notes
exportOptions.exportFileData = Export Files
charset.UTF8withoutBOM = Unicode (UTF-8 without BOM)
+charset.autoDetect = (auto detect)
date.daySuffixes = st, nd, rd, th
date.abbreviation.year = y
diff --git a/chrome/skin/default/zotero/annotate-add-selected.png b/chrome/skin/default/zotero/annotate-add-selected.png
index 89246e3695..9a07136d94 100644
Binary files a/chrome/skin/default/zotero/annotate-add-selected.png and b/chrome/skin/default/zotero/annotate-add-selected.png differ
diff --git a/chrome/skin/default/zotero/annotate-add.png b/chrome/skin/default/zotero/annotate-add.png
index 9fbf8f7f47..75e78dede2 100644
Binary files a/chrome/skin/default/zotero/annotate-add.png and b/chrome/skin/default/zotero/annotate-add.png differ
diff --git a/chrome/skin/default/zotero/annotate-collapse-all.png b/chrome/skin/default/zotero/annotate-collapse-all.png
deleted file mode 100644
index d0131e934e..0000000000
Binary files a/chrome/skin/default/zotero/annotate-collapse-all.png and /dev/null differ
diff --git a/chrome/skin/default/zotero/annotate-collapse.png b/chrome/skin/default/zotero/annotate-collapse.png
new file mode 100644
index 0000000000..39433cf78a
Binary files /dev/null and b/chrome/skin/default/zotero/annotate-collapse.png differ
diff --git a/chrome/skin/default/zotero/annotate-expand-all.png b/chrome/skin/default/zotero/annotate-expand-all.png
deleted file mode 100644
index aac23982d8..0000000000
Binary files a/chrome/skin/default/zotero/annotate-expand-all.png and /dev/null differ
diff --git a/chrome/skin/default/zotero/annotate-highlight-selected.png b/chrome/skin/default/zotero/annotate-highlight-selected.png
index d0a9570ff7..e10c600ba2 100644
Binary files a/chrome/skin/default/zotero/annotate-highlight-selected.png and b/chrome/skin/default/zotero/annotate-highlight-selected.png differ
diff --git a/chrome/skin/default/zotero/annotate-highlight.png b/chrome/skin/default/zotero/annotate-highlight.png
index 0ee13e0c11..25bb5b677f 100644
Binary files a/chrome/skin/default/zotero/annotate-highlight.png and b/chrome/skin/default/zotero/annotate-highlight.png differ
diff --git a/chrome/skin/default/zotero/annotate-unhighlight-selected.png b/chrome/skin/default/zotero/annotate-unhighlight-selected.png
index 3d46b73c30..9248bc8125 100644
Binary files a/chrome/skin/default/zotero/annotate-unhighlight-selected.png and b/chrome/skin/default/zotero/annotate-unhighlight-selected.png differ
diff --git a/chrome/skin/default/zotero/annotate-unhighlight.png b/chrome/skin/default/zotero/annotate-unhighlight.png
index 3f6f40dc31..ea81265950 100644
Binary files a/chrome/skin/default/zotero/annotate-unhighlight.png and b/chrome/skin/default/zotero/annotate-unhighlight.png differ
diff --git a/chrome/skin/default/zotero/annotation.css b/chrome/skin/default/zotero/annotation.css
new file mode 100644
index 0000000000..4be72d9df6
--- /dev/null
+++ b/chrome/skin/default/zotero/annotation.css
@@ -0,0 +1,54 @@
+body {
+ margin: 0;
+ padding: 0;
+ background-color: #fff580;
+ border: 1px solid #878244;
+ width: auto;
+}
+
+#bar {
+ display: block;
+ padding: 1px 1px 1px 0;
+ background-color: #c0b860;
+ border-bottom: 1px solid #878244;
+ height: 10px;
+}
+
+#close, #move, #collapse {
+ position: absolute;
+ display: block;
+ top: 2px;
+ cursor: pointer;
+ width: 10px;
+ height: 10px;
+}
+
+#close {
+ left: 1px;
+}
+
+#move {
+ right: 14px;
+}
+
+#collapse {
+ right: 2px;
+}
+
+#grippy {
+ position: absolute;
+ display: block;
+ right: 0;
+ bottom: 0;
+ cursor: se-resize;
+ width: 8px;
+ height: 8px;
+}
+
+#text {
+ font-family: Arial, Lucida Grande, FreeSans, sans;
+ font-size: 12px;
+ border: none;
+ margin: 3px 2px 5px 2px;
+ background-color: #fff580;
+}
\ No newline at end of file
diff --git a/chrome/skin/default/zotero/annotation.html b/chrome/skin/default/zotero/annotation.html
new file mode 100644
index 0000000000..45b262848d
--- /dev/null
+++ b/chrome/skin/default/zotero/annotation.html
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/chrome/skin/default/zotero/overlay.css b/chrome/skin/default/zotero/overlay.css
index 9e83ef9b31..b168509fa2 100644
--- a/chrome/skin/default/zotero/overlay.css
+++ b/chrome/skin/default/zotero/overlay.css
@@ -345,12 +345,7 @@
#zotero-annotate-tb-collapse
{
- list-style-image: url('chrome://zotero/skin/annotate-collapse-all.png');
-}
-
-#zotero-annotate-tb-expand
-{
- list-style-image: url('chrome://zotero/skin/annotate-expand-all.png');
+ list-style-image: url('chrome://zotero/skin/annotate-collapse.png');
}
#zotero-annotate-tb-highlight
diff --git a/chrome/skin/default/zotero/report/detail_screen.css b/chrome/skin/default/zotero/report/detail_screen.css
index 42738164ff..615dd11bdd 100644
--- a/chrome/skin/default/zotero/report/detail_screen.css
+++ b/chrome/skin/default/zotero/report/detail_screen.css
@@ -28,7 +28,6 @@ ul.report {
font-size: 1.4em;
width: 680px;
margin: 0 auto;
- overflow: auto;
padding: 20px 20px;
}
diff --git a/components/zotero-protocol-handler.js b/components/zotero-protocol-handler.js
index 87b7e27327..a1d442a149 100644
--- a/components/zotero-protocol-handler.js
+++ b/components/zotero-protocol-handler.js
@@ -73,6 +73,8 @@ function ChromeExtensionHandler() {
var ReportExtension = new function(){
this.newChannel = newChannel;
+ this.__defineGetter__('loadAsChrome', function () { return true; });
+
function newChannel(uri){
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
@@ -413,7 +415,9 @@ function ChromeExtensionHandler() {
var TimelineExtension = new function(){
this.newChannel = newChannel;
-
+
+ this.__defineGetter__('loadAsChrome', function () { return true; });
+
/*
queryString key abbreviations: intervals = i | dateType = t | timelineDate = d
@@ -625,6 +629,8 @@ function ChromeExtensionHandler() {
var AttachmentExtension = new function() {
this.newChannel = newChannel;
+ this.__defineGetter__('loadAsChrome', function () { return false; });
+
function newChannel(uri) {
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
@@ -638,15 +644,29 @@ function ChromeExtensionHandler() {
var [id, fileName] = uri.path.substr(1).split('/');
if (parseInt(id) != id) {
- return _errorChannel("Attachment id not an integer");
+ // Proxy annotation icons
+ if (id.match(/^annotation.*\.(png|html|css|gif)$/)) {
+ var chromeURL = 'chrome://zotero/skin/' + id;
+ var file = Zotero.convertChromeURLToFile(chromeURL);
+ if (!file.exists()) {
+ Zotero.debug(file.path + " not found");
+ Components.utils.reportError(file.path + " not found");
+ return _errorChannel("File not found");
+ }
+ }
+ else {
+ return _errorChannel("Attachment id not an integer");
+ }
}
- var item = Zotero.Items.get(id);
- if (!item) {
- return _errorChannel("Item not found");
+ if (!file) {
+ var item = Zotero.Items.get(id);
+ if (!item) {
+ return _errorChannel("Item not found");
+ }
+ var file = item.getFile();
}
- var file = item.getFile();
if (!file) {
return _errorChannel("File not found");
}
@@ -661,7 +681,7 @@ function ChromeExtensionHandler() {
var ph = Components.classes["@mozilla.org/network/protocol;1?name=file"].
createInstance(Components.interfaces.nsIFileProtocolHandler);
- fileURI = ph.newFileURI(file);
+ var fileURI = ph.newFileURI(file);
var channel = ioService.newChannelFromURI(fileURI);
return channel;
}
@@ -688,7 +708,7 @@ function ChromeExtensionHandler() {
*/
var SelectExtension = new function(){
this.newChannel = newChannel;
-
+
function newChannel(uri) {
var ioService = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
@@ -745,8 +765,11 @@ ChromeExtensionHandler.prototype = {
defaultPort : -1,
- protocolFlags : Components.interfaces.nsIProtocolHandler.URI_STD,
-
+ protocolFlags :
+ Components.interfaces.nsIProtocolHandler.URI_NORELATIVE |
+ Components.interfaces.nsIProtocolHandler.URI_NOAUTH |
+ Components.interfaces.nsIProtocolHandler.URI_IS_LOCAL_FILE,
+
allowPort : function(port, scheme) {
return false;
},
@@ -755,7 +778,6 @@ ChromeExtensionHandler.prototype = {
var newURL = Components.classes["@mozilla.org/network/standard-url;1"]
.createInstance(Components.interfaces.nsIStandardURL);
newURL.init(1, -1, spec, charset, baseURI);
-
return newURL.QueryInterface(Components.interfaces.nsIURI);
},
@@ -771,11 +793,11 @@ ChromeExtensionHandler.prototype = {
try {
var uriString = uri.spec.toLowerCase();
- for (extSpec in this._extensions) {
+ for (var extSpec in this._extensions) {
var ext = this._extensions[extSpec];
if (uriString.indexOf(extSpec) == 0) {
- if (this._systemPrincipal == null) {
+ if (ext.loadAsChrome && this._systemPrincipal == null) {
var chromeURI = chromeService.newURI(DUMMY_CHROME_URL, null, null);
var chromeChannel = chromeService.newChannel(chromeURI);
@@ -796,8 +818,8 @@ ChromeExtensionHandler.prototype = {
chromeRequest.cancel(0x804b0002); // BINDING_ABORTED
}
- if (this._systemPrincipal != null) {
- // applying cached system principal to extension channel
+ // Apply cached system principal to extension channel
+ if (ext.loadAsChrome) {
extChannel.owner = this._systemPrincipal;
}
diff --git a/defaults/preferences/zotero.js b/defaults/preferences/zotero.js
index 4d43978f78..e7cebfc252 100644
--- a/defaults/preferences/zotero.js
+++ b/defaults/preferences/zotero.js
@@ -69,6 +69,8 @@ pref("extensions.zotero.export.lastStyle", 'http://www.zotero.org/styles/chicago
pref("extensions.zotero.export.bibliographySettings", 'save-as-rtf');
pref("extensions.zotero.export.bibliographyLocale", '');
pref("extensions.zotero.export.citePaperJournalArticleURL", false);
+pref("extensions.zotero.export.displayCharsetOption", false);
+pref("extensions.zotero.import.charset", "auto");
pref("extensions.zotero.export.quickCopy.setting", 'bibliography=http://www.zotero.org/styles/chicago-note');
diff --git a/scrapers.sql b/scrapers.sql
index 0b86c08030..d77f15f924 100644
--- a/scrapers.sql
+++ b/scrapers.sql
@@ -22,9 +22,9 @@
-- Set the following timestamp to the most recent scraper update date
-REPLACE INTO version VALUES ('repository', STRFTIME('%s', '2008-07-20 01:40:00'));
+REPLACE INTO version VALUES ('repository', STRFTIME('%s', '2008-08-29 04:10:00'));
-REPLACE INTO translators VALUES ('96b9f483-c44d-5784-cdad-ce21b984fe01', '1.0.0b4.r1', '', '2008-06-16 21:30:00', '1', '100', '4', 'Amazon.com', 'Sean Takats and Michael Berkowitz', '^https?://(?:www\.)?amazon',
+REPLACE INTO translators VALUES ('96b9f483-c44d-5784-cdad-ce21b984fe01', '1.0.0b4.r1', '', '2008-08-22 20:30:00', '1', '100', '4', 'Amazon.com', 'Sean Takats and Michael Berkowitz', '^https?://(?:www\.)?amazon',
'function detectWeb(doc, url) {
var suffixRe = new RegExp("https?://(?:www\.)?amazon\.([^/]+)/");
@@ -84,7 +84,7 @@ REPLACE INTO translators VALUES ('96b9f483-c44d-5784-cdad-ce21b984fe01', '1.0.0b
}
if (suffix == ".com") suffix = "com";
if(m) {
- var xpath = ''//div[@class="productTitle"]/a'';
+ var xpath = ''//div[@class="productTitle"]/a | //a[span[@class="srTitle"]]'';
var elmts = doc.evaluate(xpath, doc, nsResolver, XPathResult.ANY_TYPE, null);
var elmt = elmts.iterateNext();
var asins = new Array();
@@ -196,9 +196,10 @@ REPLACE INTO translators VALUES ('96b9f483-c44d-5784-cdad-ce21b984fe01', '1.0.0b
if (xml..ISBN.length()){
newItem.ISBN = Zotero.Utilities.cleanString(xml..ISBN[0].text().toString());
}
- if (xml..NumberOfPages.length()){
- newItem.pages = Zotero.Utilities.cleanString(xml..NumberOfPages[0].text().toString());
- }
+// Uncomment when numPages field is added to schema
+// if (xml..NumberOfPages.length()){
+// newItem.numPages = Zotero.Utilities.cleanString(xml..NumberOfPages[0].text().toString());
+// }
var title = Zotero.Utilities.cleanString(xml..Title[0].text().toString());
if(title.lastIndexOf("(") != -1 && title.lastIndexOf(")") == title.length-1) {
title = title.substring(0, title.lastIndexOf("(")-1);
@@ -1093,7 +1094,7 @@ REPLACE INTO translators VALUES ('88915634-1af6-c134-0171-56fd198235ed', '1.0.0b
Zotero.wait();
}');
-REPLACE INTO translators VALUES ('176948f7-9df8-4afc-ace7-4c1c7318d426', '1.0.0b4.r5', '', '2008-07-16 15:35:45', '0', '100', '4', 'ESpacenet', 'Gilles Poulain', 'http://v3.espacenet.com/',
+REPLACE INTO translators VALUES ('176948f7-9df8-4afc-ace7-4c1c7318d426', '1.0.0b4.r5', '', '2008-07-24 05:15:00', '0', '100', '4', 'ESpacenet', 'Gilles Poulain', 'http://v3.espacenet.com/',
'function detectWeb(doc, url) {
if(doc.location.href.match("results?")) {
@@ -1255,7 +1256,1013 @@ function scrape(doc,url) {
newArticle.complete();
}');
-REPLACE INTO translators VALUES ('4da40f07-904b-4472-93b6-9bea1fe7d4df', '1.0.0b4.r5', '', '2008-07-16 11:17:32', '0', '100', '4', 'Canada.com', 'Adam Crymble', 'http://www.canada.com',
+REPLACE INTO translators VALUES ('f6717cbb-2771-4043-bde9-dbae19129bb3', '1.0.0b4.r5', '', '2008-07-24 05:15:00', '0', '100', '4', 'Archeion', 'Adam Crymble', 'http://archeion-aao',
+'function detectWeb(doc, url) {
+ if (doc.evaluate(''//td[@class="full"]/a'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "multiple";
+ } else if (doc.evaluate(''//div[@class="main"]/h1'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "book";
+ }
+}',
+'//Archeion translator. code by Adam Crymble
+//The way the site is formatted, I can''t split the creators up logically. I have left them off for now.
+
+function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ newItem = new Zotero.Item("book");
+
+ var xPathHeadings = doc.evaluate(''//th'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathContent = doc.evaluate(''//table[@class="results"]/tbody/tr/td'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathCount = doc.evaluate(''count (//th)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var fieldTitle;
+ var dataTags = new Object();
+ var multiAuthorCheck = new Array();
+
+
+ for (var i = 0; i < xPathCount.numberValue; i++) {
+ fieldTitle=xPathHeadings.iterateNext().textContent.replace(/\s+/g, '''');
+
+ //This was Michael Berkowitz''s suggested Fix.
+
+ /*var ts = doc.getElementsByTagName(("table"), 1) = ts.length, ar = [];
+ while ((i--)) {
+ if (ts[i].className&&ts[i].className.match("results")) {
+ ar[ar.length] = ts[i].getElementsByTagName("td")[0].split(/\ /);
+ }
+ }
+ Zotero.debug(ar[0][0]); */
+
+ //COULDN"T SPLIT BY ("\n") TO SEPARATE MULTIPLE CREATORS.
+ if (fieldTitle == "Creator:" | fieldTitle == "Créateur:") {
+ fieldTitle == "Creator:";
+
+ var authorContent = xPathContent.iterateNext().textContent;
+ //Zotero.debug(authorContent);
+
+ //if (authorContent.match('' (*) '')) {
+ // Zotero.debug(doc.title);
+ //}
+
+
+
+ //var test = authorContent.split(/\ /);
+ //Zotero.debug(test);
+
+ authors = authorContent.match(/\w+,?\s+[\w\(\)\.]+/g);
+
+ //Zotero.debug(authors);
+
+
+ for (i = 0; i < authors.length; i++) {
+
+ var author = authors[i].split(", ");
+
+ if (author.length < 2) {
+
+ dataTags["Creator:"] = author[0];
+ newItem.creators.push({lastName: dataTags["Creator:"], creatorType: "creator"});
+
+ } else {
+
+ dataTags["Creator:"] = (author[1] + (" ") + author[0]);
+ //Zotero.debug(authorArranged);
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(dataTags["Creator:"], "creator"));
+ }
+ }
+
+ } else {
+
+
+
+ dataTags[fieldTitle] = Zotero.Utilities.cleanTags(xPathContent.iterateNext().textContent);
+ //Zotero.debug(fieldTitle);
+ }
+ }
+
+ associateData (newItem, dataTags, "Datesofmaterial:", "date");
+ associateData (newItem, dataTags, "Repository:", "repository");
+ associateData (newItem, dataTags, "ReferenceNumber:", "callNumber");
+ associateData (newItem, dataTags, "PhysicalDescription:", "extra");
+ associateData (newItem, dataTags, "Scopeandcontent", "abstractNote");
+
+ associateData (newItem, dataTags, "Dates:", "date");
+ associateData (newItem, dataTags, "Centred''archives:", "repository");
+ associateData (newItem, dataTags, "Numéroderéférence:", "callNumber");
+ associateData (newItem, dataTags, "Descriptionmatérielle:", "extra");
+ associateData (newItem, dataTags, "Portéeetcontenu", "abstractNote");
+
+ newItem.title = doc.evaluate(''//h1'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ newItem.url = doc.location.href;
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+ var xPathLinks = doc.evaluate(''//td[@class="full"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var linksCounter = doc.evaluate(''count (//td[@class="full"]/a)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathTitles = doc.evaluate(''//table[@class="results"]/tbody/tr[1]/td'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_link;
+ for (var i = 0; i < linksCounter.numberValue; i++) {
+ next_link = xPathLinks.iterateNext().href;
+ items[next_link] = xPathTitles.iterateNext().textContent;
+
+ }
+
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+
+}
+');
+
+
+REPLACE INTO translators VALUES ('d9a16cf3-8b86-4cab-8610-dbd913ad1a44', '1.0.0b4.r5', '', '2008-07-24 05:30:00', '0', '100', '4', 'Archives Canada-France', 'Adam Crymble', 'http://bd.archivescanadafrance.org',
+'function detectWeb(doc, url) {
+
+ if (doc.location.href.match("doc.xsp?")) {
+ return "book";
+ } else if (doc.evaluate(''//li/a'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "multiple";
+ } else if (doc.evaluate(''//td[1][@class="icones"]/a'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "multiple";
+ }
+}',
+'function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+ var tagsContent = new Array();
+ var fieldTitle;
+
+ var newItem = new Zotero.Item("book");
+ var xPathHeaders = ''//td[2]/div[@class="ead-c"]/div[@class="ead-did"]/table[@class="ead-did"]/tbody/tr/td[1]'';
+
+ if (doc.evaluate(xPathHeaders, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var headers = doc.evaluate(xPathHeaders, doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var contents = doc.evaluate(''//td[2][@class="did-content"]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ while (fieldTitle = headers.iterateNext()) {
+ fieldTitle = fieldTitle.textContent.replace(/\s+/g, '''');
+ if (fieldTitle == "Origination" || fieldTitle == "Origine") {
+ fieldTitle = "Origination";
+ }
+ dataTags[fieldTitle] = Zotero.Utilities.cleanTags(contents.iterateNext().textContent.replace(/^\s*|\s*$/g, ''''));
+ }
+
+ if (dataTags["Origination"]) {
+ var author = dataTags["Origination"];
+ if (!author.match(", ")) {
+ newItem.creators.push({lastName: author, creatorType: "author"});
+ } else {
+ var authors = author.split(", ");
+ author = authors[1] + " " + authors[0];
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ }
+ }
+ }
+
+
+ if (doc.evaluate(''//h1[@class="doc-title"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newItem.title = doc.evaluate(''//h1[@class="doc-title"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ } else if (doc.evaluate(''//td[2]/div[@class="notice"]/p'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newItem.title = doc.evaluate(''//td[2]/div[@class="notice"]/p'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ } else {
+ newItem.title = doc.title + " Title Not Found";
+ }
+
+ associateData (newItem, dataTags, "PhysicalDescription", "pages");
+ associateData (newItem, dataTags, "Descriptionmatérielle", "pages");
+
+ associateData (newItem, dataTags, "Repository", "repository");
+ associateData (newItem, dataTags, "Lieudeconservation", "repository");
+
+ associateData (newItem, dataTags, "LanguageoftheMaterial", "language");
+ associateData (newItem, dataTags, "Langue", "language");
+
+ associateData (newItem, dataTags, "Identifier", "callNumber");
+ associateData (newItem, dataTags, "Cote", "callNumber");
+
+ associateData (newItem, dataTags, "Datesextrêmes", "date");
+ associateData (newItem, dataTags, "Dates", "date");
+
+ newItem.url = doc.location.href;
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+
+ var items = new Object();
+
+ if (doc.evaluate(''//td[1][@class="icones"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var titles = doc.evaluate(''//td[2][@class="ressource"]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var titlesCount = doc.evaluate(''count (//td[2][@class="ressource"])'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var links = doc.evaluate(''//td[1][@class="icones"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_link;
+
+ for (var i = 0; i < titlesCount.numberValue; i++) {
+ next_link = links.iterateNext().href;
+ if (!next_link.match("doc.xsp")) {
+ next_link = links.iterateNext().href;
+ }
+ items[next_link] = titles.iterateNext().textContent;
+ }
+ }
+
+ if (doc.evaluate(''//li/a'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var titles = doc.evaluate(''//li/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ items[next_title.href] = next_title.textContent;
+ }
+ }
+
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+
+ } else if (doc.evaluate(''//div[@class="ancestor"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+
+ var link = doc.evaluate(''//div[@class="ancestor"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().href;
+
+ articles = [link];
+ } else {
+ articles = [url]
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('661fc39a-2500-4710-8285-2d67ddc00a69', '1.0', '', '2008-07-24 09:20:44', '0', '100', '4', 'Artefacts Canada', 'Adam Crymble', 'http://daryl.chin.gc.ca',
+'function detectWeb(doc, url) {
+ var multi1 = '''';
+ var single1 = '''';
+
+ if (doc.evaluate(''//div[@id="mainContent"]/table/tbody/tr/td[1]/h1'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+
+ multi1 = doc.evaluate(''//div[@id="mainContent"]/table/tbody/tr/td[1]/h1'', doc, null, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ }
+
+ var xpath = ''//tbody/tr[1]/td[2]/span'';
+ if (doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ single1 = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ }
+
+ if (multi1.match("Search Results") || multi1.match("Résultats de recherche")) {
+ return "multiple";
+ } else if (single1.match("Document") || single1.match("Enregistrement")) {
+ return "artwork";
+ }
+
+}',
+'function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+ var tagsContent = new Array();
+ var fieldTitle;
+
+ var newItem = new Zotero.Item("artwork");
+
+ var headers = doc.evaluate(''//td[1][@class="leftResTitle"]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var contents = doc.evaluate(''//td[2][@class="pageText"]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ while (fieldTitle = headers.iterateNext()) {
+ fieldTitle = fieldTitle.textContent.replace(/\s+/g, '''');
+ if (fieldTitle == "Titre:") {
+ fieldTitle = "Title:";
+ } else if (fieldTitle == "Nomdel''objet:") {
+ fieldTitle = "NameofObject:";
+ } else if (fieldTitle == "Sujetouimage:") {
+ fieldTitle = "Subject/Image:";
+ } else if (fieldTitle == "Numérod''accession:") {
+ fieldTitle = "AccessionNumber:";
+ } else if (fieldTitle == "Artisteouartisan:") {
+ fieldTitle = "Artist/Maker:";
+ } else if (fieldTitle == "Fabricant:") {
+ fieldTitle = "Manufacturer:";
+ }
+
+ dataTags[fieldTitle] = contents.iterateNext().textContent.replace(/^\s*|\s*$/g, '''')
+ }
+
+ Zotero.debug(dataTags);
+
+ if (dataTags["Artist/Maker:"]) {
+ if (dataTags["Artist/Maker:"].match(", ")) {
+ var authors = dataTags["Artist/Maker:"].split(", ");
+ authors = authors[0] + '' '' + authors[1];
+ newItem.creators.push(authors, "creator");
+ } else {
+ newItem.creators.push(dataTags["Artist/Make:"], "creator");
+ }
+ }
+
+ if (dataTags["Manufacturer:"]) {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(dataTags["Manufacturer:"], "creator"));
+ }
+
+ if (dataTags["AccessionNumber:"]) {
+ newItem.locInArchive = "Accession Number: " + dataTags["AccessionNumber:"];
+ }
+
+ if (dataTags["Subject/Image:"]) {
+ if (dataTags["Subject/Image:"].match(/\n/)) {
+ var subjects = dataTags["Subject/Image:"].split(/\n/);
+ for (var i = 0; i < subjects.length; i++) {
+ newItem.tags[i] = subjects[i];
+ }
+ } else {
+ newItem.tags[0] = dataTags["Subject/Image:"].match(/\n/);
+ }
+ }
+
+ if (dataTags["Title:"]) {
+ associateData (newItem, dataTags, "Title:", "title");
+ associateData (newItem, dataTags, "NameofObject:", "medium");
+ } else if (dataTags["NameofObject:"]) {
+ associateData (newItem, dataTags, "NameofObject:", "title");
+ } else {
+ newItem.title = "No Title Found";
+ }
+
+ associateData (newItem, dataTags, "LatestProductionDate:", "date");
+ associateData (newItem, dataTags, "Datedefindeproduction:", "date");
+
+ associateData (newItem, dataTags, "Institution:", "repository");
+ associateData (newItem, dataTags, "Établissement:", "repository");
+
+ associateData (newItem, dataTags, "Description:", "description");
+
+ associateData (newItem, dataTags, "Medium:", "medium");
+ associateData (newItem, dataTags, "Médium:", "medium");
+
+ newItem.url = doc.location.href;
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//tr[1]/td[2][@class="pageText"]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var links = doc.evaluate(''//td/a[@class="moreInfoink"]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+
+ items[links.iterateNext().href] = next_title.textContent;
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}
+');
+
+REPLACE INTO translators VALUES ('fef07360-ee97-4f67-b022-6f64d5ec0c25', '1.0.0b4.r5', '', '2008-08-04 07:10:00', '0', '100', '4', 'KOBV', 'Gunar Maiwald', '^http://vs13.kobv.de/V/',
+'function detectWeb(doc, url) {
+ if (doc.evaluate(''//tr /td[@class="no_wrap_center"]/a'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "multiple";
+ }
+ else if (doc.evaluate(''//tr/th[@class="no_wrap"]'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "book";
+ }
+}',
+'function scrape(doc) {
+ var translator = Zotero.loadTranslator("import");
+ translator.setTranslator("a6ee60df-1ddc-4aae-bb25-45e0537be973");
+ var marc = translator.getTranslatorObject();
+
+ var xpath =''//li/a[@title="Ansicht des bibliothekarischen Formats"]'';
+ var hrefs = doc.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null);
+ var href;
+
+ while (href = hrefs.iterateNext()) {
+ var url = href.getAttribute("href");
+ url += "&format=005";
+
+ Zotero.Utilities.processDocuments([url], function(newDoc) {
+ var record = new marc.record();
+ var xpath = ''//table//tr'';
+ var elmts = newDoc.evaluate(xpath, newDoc, null, XPathResult.ANY_TYPE, null);
+ var elmt;
+
+ while (elmt = elmts.iterateNext()) {
+ var field = Zotero.Utilities.trimInternal(newDoc.evaluate(''./td[1]'', elmt, null, XPathResult.ANY_TYPE, null).iterateNext().textContent);
+ var value = Zotero.Utilities.trimInternal(newDoc.evaluate(''./td[2]'', elmt, null, XPathResult.ANY_TYPE, null).iterateNext().textContent);
+ value = value.replace(/\|([a-z]) /g,marc.subfieldDelimiter+"$1");
+ var code = field.substring(0,3);
+ var ind = field.substr(3);
+
+ // QnD for Authors:
+ if (code == "100" && ind == "11" && value.match(marc.subfieldDelimiter+"b")) {
+ var values = value.split(marc.subfieldDelimiter);
+ var forename = values[1].substr(1);
+ var surname = values[2].substr(1);
+ value = marc.subfieldDelimiter+"a"+surname+", "+forename;
+ ind = 1;
+ }
+ record.addField(code, ind, value);
+ }
+
+ var newItem = new Zotero.Item();
+ record.translate(newItem);
+ newItem.complete();
+
+ }, function() { Zotero.done; });
+ Zotero.wait();
+ }
+}
+
+
+function doWeb(doc, url) {
+ var xpath1 = ''//table/tbody/tr/td[@class="no_wrap_center"]/a'';
+ var xpath2 = ''//table/tbody/tr/th[@class="no_wrap"]'';
+ var newUrls = new Array();
+
+ if (doc.evaluate(xpath1, doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var items = Zotero.Utilities.getItemArray(doc, doc, ''^http://vs13.kobv.de/V/.*format=999$'',''^[0-9]+$'');
+ items = Zotero.selectItems(items);
+ for (var url in items) {
+ newUrls.push(url);
+ }
+ }
+
+ else if (doc.evaluate(xpath2, doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newUrls.push(url);
+ }
+
+ Zotero.Utilities.processDocuments(newUrls, scrape, function() { Zotero.done; });
+ Zotero.wait();
+}');
+
+REPLACE INTO translators VALUES ('39ea814e-8fdb-486c-a88d-59479f341066', '1.0.0b4.r5', '', '2008-07-24 05:15:00', '0', '100', '4', 'Bibliotheque UQAM', 'Adam Crymble', 'http://www.manitou.uqam.ca',
+'function detectWeb(doc, url) {
+
+ if (doc.evaluate(''//center/table/tbody/tr[1]/td/input'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "multiple";
+ } else if (doc.title.match("détails")) {
+ return "book";
+ }
+}',
+'function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == "x" ) return namespace; else return null;
+ } : null;
+
+ var newItem = new Zotero.Item("book");
+
+ var dataTags = new Object();
+ var tagsContent = new Array();
+ var contents;
+ var newItemAuthors1 = new Array();
+ var newItemAuthors2 = new Array();
+
+ var xPathHeadings = doc.evaluate(''//p/table/tbody/tr/td[1]/b'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathContents = doc.evaluate(''//p/table/tbody/tr/td[2]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathCount = doc.evaluate(''count (//p/table/tbody/tr/td[1]/b)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var dump = xPathHeadings.iterateNext();
+
+ for (i=0; i 0) {
+ dataTags["author"] = dataTags["author"].substr(0, parenthesis);
+ }
+ dataTags["author"] = dataTags["author"].replace(/^\s*|\s*$/g, '''');
+ }
+
+ } else if (fieldTitle == "Auteurs:") {
+
+ dataTags[fieldTitle] = contents;
+
+ var multiAuthors = dataTags["Auteurs:"].split(/\n/);
+ for (var j = 0; j < multiAuthors.length; j++) {
+ var parenthesis = multiAuthors[j].indexOf("(");
+
+ if (parenthesis > 0) {
+ multiAuthors[j] = multiAuthors[j].substr(0, parenthesis);
+ }
+
+ if (multiAuthors[j] != "" && multiAuthors[j] != '' '') {
+ if (multiAuthors[j].match(", ")) {
+ var authorName = multiAuthors[j].split(",");
+ newItemAuthors1.push(authorName[1] + (" ") + authorName[0]);
+ } else {
+ newItemAuthors2.push(multiAuthors[j]);
+ }
+ }
+ }
+
+ } else if (fieldTitle == "Éditeur:") {
+ dataTags[fieldTitle] = contents;
+ var imprintSplit = dataTags["Éditeur:"].split(": ");
+ if (imprintSplit.length > 1) {
+ newItem.place = imprintSplit[0].replace(/^\s*|\s*$/g, '''');
+ var publisherDate = imprintSplit[1].split(", ");
+
+ newItem.publisher = publisherDate[0].replace(/^\s*|\s*$/g, '''');
+
+ if (publisherDate.length > 1) {
+
+ newItem.date = publisherDate[1].replace(/^\s*|\s*$/g, '''');
+ }
+ } else {
+ newItem.publisher = dataTags["Éditeur:"];
+ }
+
+ } else if (fieldTitle == "Sujet:") {
+ dataTags[fieldTitle] = contents;
+
+ if (dataTags["Sujet:"].match("\n")) {
+
+ tagsContent = (dataTags["Sujet:"].split(/\n/));
+
+ }
+
+ } else {
+
+ dataTags[fieldTitle] = contents.replace(/^\s*|\s*$/g, '''');
+ }
+ }
+
+//pushes tags
+
+ for (var y = 0; y < tagsContent.length; y++) {
+ if (tagsContent[y]!='''' && tagsContent[y]!= " ") {
+ var parenthesis = tagsContent[y].indexOf("(");
+ if (parenthesis > 0) {
+ tagsContent[y] = tagsContent[y].substr(0, parenthesis);
+ }
+ newItem.tags[y] = tagsContent[y];
+ }
+ }
+
+//because newItem is not defined until after the authors have, authors must be put into Zotero outside the main for loop.
+ if (dataTags["author"]) {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(dataTags["author"], "author"));
+ }
+
+ for (var i = 0; i < newItemAuthors1.length; i++) {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(newItemAuthors1[i], "author"));
+ }
+
+ for (var i = 0; i < newItemAuthors2.length; i++) {
+ newItem.creators.push({lastName: newItemAuthors2[i], creatorType: "creator"});
+ }
+
+//trims title as best as possible
+ if (dataTags["Titre:"].match(/\[/)) {
+ var splitter = dataTags["Titre:"].indexOf("[");
+ }
+
+ if (dataTags["Titre:"].match("/")) {
+ var splitter1 = dataTags["Titre:"].indexOf("/");
+ }
+
+ if (splitter1 > -1 && splitter > -1) {
+ if (splitter1 > splitter) {
+ dataTags["Titre:"] = dataTags["Titre:"].substr(0, splitter);
+ } else {
+ dataTags["Titre:"] = dataTags["Titre:"].substr(0, splitter1);
+ }
+ } else if (splitter1 > -1) {
+ dataTags["Titre:"] = dataTags["Titre:"].substr(0, splitter1);
+ } else if (splitter > -1) {
+ dataTags["Titre:"] = dataTags["Titre:"].substr(0, splitter);
+ }
+
+ associateData (newItem, dataTags, "Titre:", "title");
+ associateData (newItem, dataTags, "Numéro:", "ISBN");
+ associateData (newItem, dataTags, "Description:", "pages");
+ associateData (newItem, dataTags, "Banque:", "repository");
+ associateData (newItem, dataTags, "Langue:", "language");
+ associateData (newItem, dataTags, "Localisation:", "Loc. in Archive");
+
+ newItem.url = doc.location.href;
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+ var titles = doc.evaluate(''/html/body/table/tbody/tr/td/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ for (var i = 0; i < 4; i++) {
+ var dump = titles.iterateNext();
+ }
+
+ var next_title;
+
+ while (next_title = titles.iterateNext()) {
+ items[next_title.href] = next_title.textContent;
+ Zotero.debug(next_title.href);
+ Zotero.debug(next_title.textContent);
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+REPLACE INTO translators VALUES ('6f9aa90d-6631-4459-81ef-a0758d2e3921', '1.0.0b4.r5', '', '2008-07-24 05:15:00', '0', '100', '4', 'Blogger', 'Adam Crymble', 'blogspot.com',
+'function detectWeb(doc, url) {
+
+ if (doc.evaluate(''//h3[@class="post-title entry-title"]/a'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var entryCount = doc.evaluate(''count (//h3[@class="post-title entry-title"]/a)'', doc, null, XPathResult.ANY_TYPE, null);
+ }
+
+ if (entryCount.numberValue == 1) {
+ return "blogPost";
+ } else if (entryCount.numberValue > 1) {
+ return "multiple";
+ }
+
+}',
+'//Blogger translator. Code by Adam Crymble
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var tagsContent = new Array();
+
+ var newItem = new Zotero.Item("blogPost");
+
+ //title
+ if (doc.evaluate(''//h3[@class="post-title entry-title"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+
+ newItem.title = doc.evaluate(''//h3[@class="post-title entry-title"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ } else {
+ newItem.title = doc.title;
+ }
+
+ //author, if available
+ if (doc.evaluate(''//span[@class="post-author vcard"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var author = doc.evaluate(''//span[@class="post-author vcard"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent.replace(/^\s*|\s*$/g, '''');
+ var author = author.toLowerCase();
+
+ if (author.match(/\sby\s/)) {
+ var shortenAuthor = author.indexOf(" by");
+ author = author.substr(shortenAuthor + 3).replace(/^\s*|\s$/g, '''');
+ }
+ var words = author.split(/\s/);
+ for (var i in words) {
+ words[i] = words[i][0].toUpperCase() + words[i].substr(1).toLowerCase();
+ }
+ author = words.join(" ");
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ }
+
+ //date, if available
+ if (doc.evaluate(''//h2[@class="date-header"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newItem.date = doc.evaluate(''//h2[@class="date-header"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ }
+
+ //tags, if available
+ if (doc.evaluate(''//span[@class="post-labels"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var tags = doc.evaluate(''//span[@class="post-labels"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var tags1;
+ while (tags1 = tags.iterateNext()) {
+ tagsContent.push(tags1.textContent);
+ }
+
+ for (var i = 0; i < tagsContent.length; i++) {
+ newItem.tags[i] = tagsContent[i];
+ }
+ }
+
+ var blogTitle1 = doc.title.split(":");
+ newItem.blogTitle = blogTitle1[0];
+
+ newItem.url = doc.location.href;
+
+ newItem.complete();
+}
+
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//h3[@class="post-title entry-title"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var titles1 = doc.evaluate(''//li[@class="archivedate expanded"]/ul[@class="posts"]/li/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ items[next_title.href] = next_title.textContent;
+ }
+
+ while (next_title = titles1.iterateNext()) {
+ items[next_title.href] = next_title.textContent;
+ }
+
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+REPLACE INTO translators VALUES ('f9373e49-e6ac-46f7-aafe-bb24a2fbc3f0', '1.0.0b4.r5', '', '2008-06-27 10:04:26', '0', '100', '4', 'Bracero History Archive', 'Adam Crymble', 'http://braceroarchive.org',
+'function detectWeb(doc, url) {
+ if (doc.title.match("Item")) {
+ return "book";
+ } else if (doc.evaluate(''//div[@class="item-meta"]/h2/a'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "multiple";
+ }
+}',
+'//Bracero History Archive translator; Code by Adam Crymble
+
+function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+ var fieldTitle;
+ var contents1;
+
+ var headers = doc.evaluate(''//h3'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var contents = doc.evaluate(''//div[@class="field"]/div'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathCount = doc.evaluate(''count (//div[@class="field"]/div)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ for (i=0; i1) {
+ for (var i = 0; i < inventors.length; i++) {
+ parenthesis = inventors[i].indexOf("(");
+ inventors[i] = inventors[i].substr(0, parenthesis).replace(/^\s*|\s*$/g, '''');
+ if (inventors[i].match(", ")) {
+ var inventors1 = inventors[i].split(", ");
+ inventors[i] = inventors1[1] + " " + inventors1[0];
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(inventors[i], "inventor"));
+ } else {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(inventors[i], "inventor"));
+ }
+ }
+
+ } else {
+ Zotero.debug(doc.title);
+ parenthesis = dataTags["Inventors:"].indexOf("(");
+ dataTags["Inventors:"] = dataTags["Inventors:"].substr(0, parenthesis).replace(/^\s*|\s*$/g, '''');
+
+ if (dataTags["Inventors:"].match(", ")) {
+ var inventors1 = dataTags["Inventors:"].split(", ");
+ dataTags["Inventors:"] = inventors1[1] + " " + inventors1[0];
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(dataTags["Inventors:"], "inventor"));
+ } else {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(dataTags["Inventors:"], "inventor"));
+ }
+ }
+ }
+
+ associateData (newItem, dataTags, "Title:", "title");
+ associateData (newItem, dataTags, "Abstract:", "abstract");
+ associateData (newItem, dataTags, "DocumentTypeandNumber:", "patentNumber");
+ associateData (newItem, dataTags, "ApplicationNumber:", "applicationNumber");
+ associateData (newItem, dataTags, "PublicationDate:", "issueDate");
+ associateData (newItem, dataTags, "Assignee:", "assignee");
+
+ newItem.url = doc.location.href;
+
+ newItem.complete();
+}
+
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//table[@class="listing_table"]/tbody/tr/td[3]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ items[next_title.href] = next_title.textContent;
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('4ea89035-3dc4-4ae3-b22d-726bc0d83a64', '1.0.0b4.r5', '', '2008-07-24 05:30:00', '0', '100', '4', 'Gale - Cengage Learning', 'Adam Crymble', 'http://www.gale.cengage.com',
+'function detectWeb(doc, url) {
+
+ if (doc.evaluate(''//td[3]/a'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "multiple";
+ } else if (doc.evaluate(''//div[@id="title_main"]/h2'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "book";
+ }
+
+
+
+}',
+'//Gale Cengage Learning - Catalog translator. Code by Adam Crymble.
+
+function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+ var titles1;
+
+ var newItem = new Zotero.Item("book");
+
+ var credits = doc.evaluate(''//div[@id="credits"]/ul/li'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathCount = doc.evaluate(''count (//div[@id="credits"]/ul/li)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var creditsArray = new Array();
+
+ for (var i = 0; i < xPathCount.numberValue; i++) {
+ creditsArray.push(credits.iterateNext().textContent.replace(/^\s*|\s*$/g, ''''));
+ }
+
+ if (doc.evaluate(''//div[@id="title_main"]/h2'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ titles1 = doc.evaluate(''//div[@id="title_main"]/h2'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent.replace(/^\s*|\s*$/g, '''');
+ }
+
+ if (titles1.match(/\w/) && creditsArray[0].match(/\w/)) {
+ newItem.title = titles1 + ": " + creditsArray[0];
+ } else if (titles1.match(/\w/) && !creditsArray[0].match(/\w/)) {
+ newItem.title = titles1;
+ } else {
+ newItem.title = "No Title Found."
+ }
+
+ for (var i = 1; i < creditsArray.length; i++) {
+
+ if (creditsArray[i].match("Author ")) {
+ var author = creditsArray[i].split("Author ");
+ author = author[1];
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ } else if (creditsArray[i].match("Published by ")) {
+ var publisher1 = creditsArray[i].split("Published by ");
+ newItem.publisher = publisher1[1];
+ } else if (creditsArray[i].match("Volume")) {
+ var volume1 = creditsArray[i].split("Volume");
+ newItem.volume = volume1[1];
+ }
+
+ }
+
+ if (doc.evaluate(''//div[@id="description"]/p'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newItem.abstractNote = doc.evaluate(''//div[@id="description"]/p'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ }
+
+ var pageContents = doc.evaluate(''//div[@id="detail"]/ul/li'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var allContents = new Array();
+ var contents;
+ var fieldTitle;
+
+ while (contents = pageContents.iterateNext()) {
+ allContents.push(contents.textContent);
+ }
+
+ for (i=0; i -1; i --) {
+
+ fieldContent[duplicates[i]-1] = fieldContent[duplicates[i]-1] + "; " + fieldContent[duplicates[i]];
+ fieldContent[duplicates[i]] = '''';
+ }
+
+ for (var i = 0; i < fieldContent.length-1; i++) {
+ if (fieldContent[i].match(/\w/)) {
+ cleanContent.push(fieldContent[i]);
+ }
+ }
+
+ var headers = doc.evaluate(''//form/table/tbody/tr/th'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ //field title and cleancontent have the same number of entries; These are then associated and put into dataTags object.
+ for (var i = 0; i < cleanContent.length; i++) {
+ fieldTitle = headers.iterateNext().textContent.replace(/\s+/g, '''');
+ if (fieldTitle.match(/\w/)) {
+
+ } else {
+ fieldTitle = headers.iterateNext().textContent.replace(/\s+/g, '''');
+ }
+ dataTags[fieldTitle] = cleanContent[i];
+
+ }
+
+ //The data is all now in the dataTags object. It needs only to be formatted and put in the proper Zotero fields.
+
+ //fixing up any content that needs a different format for Zotero and then pushing it into Zotero.
+ if (dataTags["Notes:"]) {
+ if (dataTags["Notes:"].match("; ")) {
+ var notes1 = dataTags["Notes:"].split("; ");
+ var notes2 = '''';
+
+ for (var i = 0; i < notes1.length; i++) {
+
+ if (notes2.match(/\w/)) {
+ notes2 = notes2 + "; " + notes1[i];
+ } else {
+ notes2 = notes1[i];
+ }
+ }
+ dataTags["Notes:"] = notes2;
+ }
+ }
+
+ if (dataTags["Subjects:"]) {
+ if (dataTags["Subjects:"].match("; ")) {
+ tagsContent = dataTags["Subjects:"].split("; ");
+ } else {
+ newItem.tags = dataTags["Subjects:"];
+ var noMoreTags = 1;
+ }
+ if (noMoreTags != 1) {
+ for (var i = 0; i < tagsContent.length; i++) {
+ newItem.tags[i] = tagsContent[i];
+ }
+ }
+ }
+
+ if (dataTags["Author:"]) {
+ if (dataTags["Author:"].match(", ")) {
+ var author = dataTags["Author:"].split('', '');
+ author = author[1].substr(0, author[1].length) + " " + author[0];
+ author = author.replace(/\./, '''');
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ }
+ }
+
+ if (dataTags["CorporateAuthor:"]) {
+ newItem.creators.push({lastName: dataTags["CorporateAuthor:"], creatorType: "creator"});
+ }
+
+ if (dataTags["Location:"]) {
+ newItem.extra = "Location in Library: " + " " + dataTags["Location:"];
+ }
+
+ if (dataTags["PersistentLinkforthisRecord:"]) {
+ associateData (newItem, dataTags, "PersistentLinkforthisRecord:", "url");
+ } else {
+ newItem.url = doc.location.href;
+ }
+
+ //Publishing info is split in a best guess format.
+ //If not all of Place, Publisher and Date are present, or they are in an unstandard format, the information is stored in Publisher.
+ if (dataTags["PublicationInformation:"]) {
+ if (dataTags["PublicationInformation:"].match(": ")) {
+ var colon = dataTags["PublicationInformation:"].indexOf(":");
+ var place1 = dataTags["PublicationInformation:"].substr(0, colon);
+ newItem.place = place1;
+ var publisher1 = dataTags["PublicationInformation:"].substr(colon);
+ if (publisher1.match(", ")) {
+ var date1 = publisher1.split(", ");
+ newItem.publisher = date1[0];
+ if (date1[1].match(/\d/)) {
+ newItem.date = date1[1];
+ }
+ } else {
+ newItem.date = publisher1;
+ }
+ } else {
+ newItem.publisher = dataTags["PublicationInformation:"];
+ }
+ }
+
+ associateData (newItem, dataTags, "Title:", "title");
+ associateData (newItem, dataTags, "Series:", "series");
+ associateData (newItem, dataTags, "Description:", "description");
+ associateData (newItem, dataTags, "ISBN:", "ISBN");
+ associateData (newItem, dataTags, "Notes:", "abstractNote");
+ associateData (newItem, dataTags, "CallNumber:", "callNumber");
+ associateData (newItem, dataTags, "Edition:", "edition");
+
+ newItem.notes.push({title:"Title", note:"Site is designed to timeout user. This may prevent Zotero from saving a screen capture."});
+
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var typeOfPage = doc.evaluate(''//table/tbody/tr/th[3]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ Zotero.debug(typeOfPage);
+
+ if (typeOfPage.match("Title")) {
+ var titles = doc.evaluate(''//table/tbody/tr/td[3]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ } else {
+ var titles = doc.evaluate(''//table[2]/tbody/tr/td[2]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ }
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ items[next_title.href] = next_title.textContent;
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('330f283f-12e9-4421-aa59-e17ec5f4aa37', '1.0.0b4.r5', '', '2008-08-21 15:45:00', '0', '100', '4', 'Glenbow Library', 'Adam Crymble', 'http://ww2.glenbow.org/',
+'function detectWeb(doc, url) {
+
+ if (doc.title.match("Library Main Catalogue Search Results") && doc.location.href.match("GET_RECORD")) {
+ return "book";
+ } else if
+ (doc.title.match("Library Map Collection Search Results") && doc.location.href.match("GET_RECORD")) {
+ return "map";
+
+ } else if
+ (doc.title.match("Library Main Catalogue Search Results") && !(doc.location.href.match("GET_RECORD"))) {
+ return "multiple";
+ } else if
+ (doc.title.match("Map Collection Search Results") && !(doc.location.href.match("GET_RECORD"))) {
+ return "multiple";
+ }
+}',
+'//Translator for the Glenbow Museum Collection. Code by Adam Crymble
+//Only works for Library Main Catalogue and Map Collection. The other categories do not have stable URLs for individual entries.
+
+
+function associateContent (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape (doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ } : null;
+
+ var fieldTitle = new Array();
+ var tagsContent = new Array();
+
+ if (detectWeb(doc, url) == "book") {
+
+ newItem = new Zotero.Item("book");
+ authorType= "author";
+
+ } else if (detectWeb(doc, url) == "map") {
+
+ newItem = new Zotero.Item("map");
+ authorType= "cartographer";
+ }
+
+ var dataTags= new Object();
+ var authorType;
+ var organizeName;
+
+ if (doc.evaluate(''//tr/td/p'', doc, nsResolver, XPathResult.ANY_TYPE, null)) {
+ var xPathContent = doc.evaluate(''//tr/td/p'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathCount = doc.evaluate(''count (//tr/td/p)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ for (var i = 0; i < xPathCount.numberValue; i++) {
+
+ fieldTitle= xPathContent.iterateNext().textContent;
+
+ var separate = fieldTitle.indexOf(":");
+ var fieldTitle1 = fieldTitle.substr(0, separate);
+ fieldTitle1 = fieldTitle1.replace(/\s+/g, '''');
+
+ var fieldContent = fieldTitle.substr(separate + 2);
+
+ dataTags[fieldTitle1] = (fieldContent);
+
+ }
+
+
+ //names start
+ if (dataTags["Names"]) {
+
+ //if there are multiple authors:
+ if (dataTags["Names"].match("\n")) {
+ var multipleNames = dataTags["Names"].split("\n");
+
+ for (j = 0; j < multipleNames.length; j++) {
+ if (detectWeb(doc, url) == "book") {
+ multipleNames[j] = multipleNames[j].substr(3);
+
+ } else if (detectWeb(doc, url) == "map") {
+ multipleNames[j] = multipleNames[j];
+ }
+
+ if (multipleNames[j].match(/\,/)) {
+
+ organizeName = multipleNames[j].split(",");
+ organizeName = (organizeName[1] + (" ") + organizeName[0]);
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(organizeName, authorType));
+
+ } else {
+ newItem.creators.push({lastName: multipleNames[j], creatorType: authorType});
+ }
+
+ }
+
+ //if there is 1 human author
+ } else if (dataTags["Names"].match(/\,/)) {
+ if (detectWeb(doc, url) == "book") {
+ var organizeName = dataTags["Names"].substr(3).split(",");
+
+ } else if (detectWeb(doc, url) == "map") {
+ var organizeName = dataTags["Names"].split(",");
+ }
+
+ organizeName = (organizeName[1] + (" ") + organizeName[0]);
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(organizeName,authorType));
+
+ //if there is 1 corporate author
+ } else {
+ if (detectWeb(doc, url) == "book") {
+ newItem.creators.push({lastName: dataTags["Names"].substr(3), creatorType: authorType});
+
+ } else if (detectWeb(doc, url) == "map") {
+ newItem.creators.push({lastName: dataTags["Names"], creatorType: authorType});
+
+ }
+ }
+ }
+
+ //tags start
+ if (dataTags["Subjects"]) {
+ if (dataTags["Subjects"].match("\n")) {
+ var multipleSubjects= dataTags["Subjects"].split("\n");
+
+ for (j = 0; j < multipleSubjects.length; j++) {
+ multipleSubjects[j] = multipleSubjects[j].substr(3);
+ tagsContent.push(Zotero.Utilities.cleanTags(multipleSubjects[j]));
+ }
+ } else {
+ dataTags["Subjects"] = dataTags["Subjects"].substr(3);
+ tagsContent.push(Zotero.Utilities.cleanTags(dataTags["Subjects"]));
+ }
+
+ for (var y = 0; y < tagsContent.length; y++) {
+ newItem.tags[y] = tagsContent[y];
+ }
+ }
+
+ //book publisher info start
+ if (dataTags["PublishingInformation"]) {
+ dataTags["PublishingInformation"] = dataTags["PublishingInformation"].replace(/\[|\]*/g, '''');
+
+ var pubLoc= dataTags["PublishingInformation"].split(":");
+ if (pubLoc[1]) {
+ dataTags["Place"] = pubLoc[0];
+
+ var pubAndDate = pubLoc[1].split(",");
+ dataTags["Publisher"] = pubAndDate[0];
+ dataTags["Date"] = pubAndDate[1];
+ } else {
+ associateContent (newItem, dataTags, "PublishingInformation", "date");
+ }
+ }
+
+ //accession number start
+ if (dataTags["Accessionnumber"]) {
+
+ dataTags["Accessionnumber"] = ("Accession number: " + dataTags["Accessionnumber"]);
+ }
+
+ if (dataTags["CallNumber"]) {
+ if (dataTags["CallNumber"] == '' '') {
+ dataTags["CallNumber"] = "None";
+ Zotero.debug(dataTags["CallNumber"]);
+ }
+ }
+ }
+ associateContent (newItem, dataTags, "CallNumber", "callNumber");
+ associateContent (newItem, dataTags, "Title", "title");
+ associateContent (newItem, dataTags, "Place", "place");
+ associateContent (newItem, dataTags, "Publisher", "publisher");
+ associateContent (newItem, dataTags, "Date", "date");
+ associateContent (newItem, dataTags, "Description", "pages");
+ associateContent (newItem, dataTags, "Edition", "edition");
+ associateContent (newItem, dataTags, "Notes", "abstractNote");
+ associateContent (newItem, dataTags, "Accessionnumber", "extra");
+ associateContent (newItem, dataTags, "Scale", "scale");
+
+ newItem.url = doc.location.href;
+ if (!newItem.title) newItem.title = "New Search Terms Suggested"
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+ var dataTags = new Object();
+ var titleList = new Array();
+ var uris = new Array();
+ var next_title= new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+
+ //checks multiple entries for a link to a single entry page.
+ if (doc.evaluate(''//td/div[@class="floatRight"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null)) {
+
+ var items = new Object();
+ var titles = doc.evaluate(''//td/p'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var xPathMultiCount = doc.evaluate(''count (//td/p)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+
+ for (var i = 0; i < xPathMultiCount.numberValue; i++) {
+
+ articles= titles.iterateNext().textContent;
+
+ var separateMulti = articles.indexOf(":");
+ var articles1 = articles.substr(0, separateMulti);
+ articles1 = articles1.replace(/\s+/g, '''');
+
+ var multiContent = articles.substr(separateMulti + 2);
+
+ dataTags[articles1] = (multiContent);
+
+ if (articles1 == "Title") {
+ titleList.push(dataTags["Title"]);
+ }
+ if (articles1 == "See") {
+ titleList.push("skip");
+ }
+ }
+ var links = doc.evaluate(''//td/div[@class="floatRight"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathLinksCount = doc.evaluate(''count (//td/div[@class="floatRight"]/a)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ for (i=0; i 3) {
+ newItem.creators.push({lastName: split1[0], creatorType: "creator"});
+ } else {
+
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(split1[0], "author"));
+ }
+ }
+
+ //title
+ split2 = split1[1].split(''." '');
+ newItem.title = split2[0];
+
+ //repository
+ split3 = split2[1].split("Lives, ");
+
+ //object number
+ split4 = split3[1].split(" (");
+ newItem.callNumber = split4[0];
+
+ //date posted and URL
+ split5 = split4[1].split(")<");
+ newItem.date = split5[0];
+
+ } else {
+
+ var split1 = cite.split(". ");
+ Zotero.debug(split1);
+
+ //author
+ var author = split1[0].split(/\, /);
+ author = author[1] + '' '' + author[0];
+ Zotero.debug(author);
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+
+ //title
+ newItem.title = split1[1];
+
+ //place
+ var place1 = split1[2].split(":");
+ newItem.place = place1[0];
+
+ //date
+ var date1 = split1[2].split (", ");
+ newItem.date = date1[1];
+
+ //publisher
+ newItem.publisher = date1[0].replace(place1[0], '''').substr(2);
+ }
+
+ newItem.url = doc.location.href;
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//h3/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+
+ while (next_title = titles.iterateNext()) {
+
+ items[next_title.href] = next_title.textContent;
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('c9338ed5-b512-4967-8ffe-ab9c973559ef', '1.0.0b4.r5', '', '2008-08-04 07:10:00', '0', '100', '4', 'The Hamilton Spectator', 'Adam Crymble', 'http://www.thespec.com',
+'function detectWeb(doc, url) {
+ if (doc.location.href.match("search")) {
+ return "multiple";
+ } else if (doc.location.href.match("article")) {
+ return "newspaperArticle";
+ }
+}',
+'//Hamilton Spectator translator. code by Adam Crymble
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var newItem = new Zotero.Item("newspaperArticle");
+
+ if (doc.title.match("TheSpec.com - ")) {
+ var lineBreak = doc.title.lastIndexOf(" - ");
+ newItem.section = doc.title.substr(14, lineBreak-14);
+ }
+
+ var xPathAbstract = ''//span[@class="subhead1"][@id="ctl00_ContentPlaceHolder_article_NavWebPart_Article_ctl00___SubTitle1__"]'';
+ if (doc.evaluate(xPathAbstract, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newItem.abstractNote = doc.evaluate(xPathAbstract, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ }
+
+ var xPathAuthor1 = ''//span[@class="articleAuthor"][@id="ctl00_ContentPlaceHolder_article_NavWebPart_Article_ctl00___Author1__"]'';
+ if (doc.evaluate(xPathAuthor1, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var author1 = doc.evaluate(xPathAuthor1, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ if (author1.match(", ")) {
+ author1 = author1.split(", ");
+ author1 = author1[0];
+ }
+ var words = author1.toLowerCase().split(/\s/);
+
+ for (var i in words) {
+ words[i] = words[i][0].toUpperCase() + words[i].substr(1).toLowerCase();
+ }
+
+ author1 = words.join(" ");
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author1, "author"));
+ }
+
+ var xPathAuthor2 = ''//span[@class="articleAuthor"][@id="ctl00_ContentPlaceHolder_article_NavWebPart_Article_ctl00___Author2__"]'';
+ if (doc.evaluate(xPathAuthor2, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var author2 = doc.evaluate(xPathAuthor2, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ if (author2.match(", ")) {
+ author2 = author2.split(", ");
+ author2 = author2[0];
+ }
+ var words = author2.toLowerCase().split(/\s/);
+
+ for (var i in words) {
+ words[i] = words[i][0].toUpperCase() + words[i].substr(1).toLowerCase();
+ }
+
+ author2 = words.join(" ");
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author2, "author"));
+ }
+
+ var xPathTitle = ''//span[@class="headlineArticle"][@id="ctl00_ContentPlaceHolder_article_NavWebPart_Article_ctl00___Title__"]'';
+ newItem.title = doc.evaluate(xPathTitle, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ newItem.url = doc.location.href;
+ newItem.publicationTitle = "The Hamilton Spectator";
+
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ if (next_title.href.match("article") && !next_title.href.match("229246") && !next_title.textContent.match(/\s\s\s/)) {
+ items[next_title.href] = next_title.textContent;
+ }
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('9418dcc2-cc1e-432b-b7a6-7b00b7402d2f', '1.0.0b4.r5', '', '2008-08-21 15:45:00', '0', '100', '4', 'Hurricane Digital Memory Bank', 'Adam Crymble', 'http://hurricanearchive.org',
+'function detectWeb(doc, url) {
+
+ if (doc.evaluate(''//p[@id="cite-as"]'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "book";
+ } else if (doc.evaluate(''//p[@class="object_description"]/a'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()){
+ return "multiple";
+ }
+}',
+'//Hurricane Digital Memory Bank translator; Code by Adam Crymble
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var newItem = new Zotero.Item("book");
+
+ var dataTags = new Object();
+ var tagsContent = new Array();
+ var tags;
+ var cite = doc.evaluate(''//p[@id="cite-as"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ var split1 = new Array();
+ var split2 = new Array();
+ var split3 = new Array();
+ var split4 = new Array();
+ var split5 = new Array();
+
+ //author
+ split1 = cite.split('', "'');
+ var authorWords = split1[0].split(/\b\s/);
+ if (authorWords.length > 3) {
+ newItem.creators.push({lastName: split1[0], creatorType: "creator"});
+ } else {
+
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(split1[0], "author"));
+ }
+
+ //title
+ split2 = split1[1].split(''." '');
+ newItem.title = split2[0];
+
+ //repository
+ split3 = split2[1].split("Bank, ");
+
+ //object number
+ split4 = split3[1].split(" (");
+ newItem.callNumber = split4[0];
+
+ //date posted and URL
+ split5 = split4[1].split(")<");
+ newItem.date = split5[0];
+
+ //tags
+ if (doc.evaluate(''//ul[@class="taglist"][@id="tags"]/li'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var xPathTags = doc.evaluate(''//ul[@class="taglist"][@id="tags"]/li'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var tagsCount = doc.evaluate(''count (//ul[@class="taglist"][@id="tags"]/li)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ for (var i =0; i < tagsCount.numberValue; i++) {
+ newItem.tags[i] = xPathTags.iterateNext().textContent;
+ }
+ }
+
+ newItem.url = doc.location.href;
+
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+
+ var links = doc.evaluate(''//p[@class="object_description"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var titles = doc.evaluate(''//p[@class="object_description"]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+
+ while (next_title = titles.iterateNext()) {
+
+ items[links.iterateNext().href] = next_title.textContent;
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('add79dfd-7951-4c72-af1d-ce1d50aa4fb4', '1.0.0b4.r5', '', '2008-06-30 17:43:00', '0', '100', '4', 'informIT database', 'Adam Crymble', 'http://www.informit.com',
+'function detectWeb(doc, url) {
+ if (doc.title.match("Search Results")) {
+ return "multiple";
+ } else if (doc.location.href.match("topics")) {
+ return "multiple";
+
+ } else if (doc.location.href.match("product")) {
+ return "book";
+ } else if (doc.location.href.match("guides")) {
+ return "book";
+
+ } else if (doc.location.href.match("library")) {
+ return "bookSection";
+ } else if (doc.location.href.match(/articles\/article/)) {
+ return "bookSection";
+ }
+}',
+'//informIT database translator. Code by Adam Crymble
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+
+ //FOR GUIDES
+ if (doc.location.href.match("guides")) {
+ var newItem = new Zotero.Item("book");
+ newItem.title = doc.evaluate(''//h1'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ var authors = doc.evaluate(''//div[@class="titling"]/p/a'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ }
+
+ //FOR ARTICLES
+ if (doc.location.href.match(/articles\/article/)) {
+ var newItem = new Zotero.Item("bookSection");
+
+ var contents = doc.evaluate(''//div[@id="articleHeader"]/ul/li'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathCount = doc.evaluate(''count (//div[@id="articleHeader"]/ul/li)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var authors = contents.iterateNext().textContent.substr(3);
+
+ if (doc.evaluate(''//div[@class="relatedBook"]/p/a'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newItem.bookTitle = doc.evaluate(''//div[@class="relatedBook"]/p/a'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ }
+
+ newItem.date = contents.iterateNext().textContent;
+
+ var rights1;
+ if (xPathCount.numberValue> 2) {
+ newItem.rights = contents.iterateNext().textContent;
+ }
+
+ newItem.title = doc.evaluate(''//h1'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ } else if (doc.evaluate(''//ul[@class="bibliography"]/li'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+
+
+ //FOR STORE BOOKS
+ var newItem = new Zotero.Item("book");
+
+ var contents = doc.evaluate(''//ul[@class="bibliography"]/li'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathCount = doc.evaluate(''count (//ul[@class="bibliography"]/li)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ for (i=0; i0 && noMoreAuthor != 1) {
+
+ for (var i = 0; i < authors.length; i++) {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(authors[i], "author"));
+ }
+ }
+
+ newItem.url = doc.location.href;
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+ var next_title;
+
+ //xPath for Topics pages, else xPaths for regular search pages.
+ if (doc.location.href.match("topics")) {
+ var titles = doc.evaluate(''//div[@class="productList articles"]/dl/dt/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ } else {
+ var titles = doc.evaluate(''//td[3][@class="results"]/ul/li/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var chapters = doc.evaluate(''//dt/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ }
+
+ while (next_title = titles.iterateNext()) {
+ items[next_title.href] = next_title.textContent;
+ }
+
+ if (doc.title.match("Search Results")) {
+ while (next_title = chapters.iterateNext()) {
+ items[next_title.href] = next_title.textContent;
+ }
+ }
+
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('db0f4858-10fa-4f76-976c-2592c95f029c', '1.0.0b4.r5', '', '2008-07-24 05:30:00', '0', '100', '4', 'Internet Archive', 'Adam Crymble', 'http://www.archive.org',
+'function detectWeb(doc, url) {
+ var mediaType = "1";
+
+ if (doc.evaluate(''//h3'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ mediaType = doc.evaluate(''//h3'', doc, null, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ } else if (doc.evaluate(''//div[@class="box"][@id="spotlight"]/h1'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ mediaType = doc.evaluate(''//div[@class="box"][@id="spotlight"]/h1'', doc, null, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ }else if (doc.evaluate(''//div[@class="box"]/h1'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ mediaType = doc.evaluate(''//div[@class="box"]/h1'', doc, null, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ }
+
+ if (mediaType == "The Item") {
+ return "artwork";
+ } else if ( mediaType.match("Spotlight")) {
+ return "book";
+ }else if (mediaType.match("book")) {
+ return "book";
+ } else if (mediaType.match("movie")) {
+ return "videoRecording";
+ } else if (mediaType.match("audio")) {
+ return "audioRecording";
+ } else if (doc.location.href.match("search") && mediaType == "1") {
+ return "multiple";
+ }
+}',
+'//Internet Archive Translator. Code by Adam Crymble
+
+function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+
+ var tagsContent = new Array();
+ var fieldContents = new Array();
+ var fieldTitleLength;
+
+ var fieldTitle;
+ var scrapeType = 0;
+
+ var mediaType1 = detectWeb(doc, url);
+
+ if (mediaType1 == "artwork") {
+
+ var newItem = new Zotero.Item("artwork");
+
+ //split contents by linebreak and push into an array if it is not empty
+ var contents = doc.evaluate(''//div[@id="col2"]/div[@class="box"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent.split(/\n/);
+ for (var i = 0; i < contents.length; i++) {
+ if (contents[i].match(/\w/)) {
+ fieldContents.push(contents[i]);
+ }
+ }
+ var headers = doc.evaluate(''//div[@id="col2"]/div[@class="box"]/b'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var headersCount = doc.evaluate(''count (//div[@id="col2"]/div[@class="box"]/b)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ for (var k = 0; k < headersCount.numberValue; k++) {
+ fieldTitle = headers.iterateNext().textContent.toLowerCase();
+ fieldTitleLength = fieldTitle.length;
+ var fieldTitleSpot;
+
+ for (var j = 0; j < fieldContents.length; j++) {
+ if (fieldContents[j].match(fieldTitle)) {
+ fieldTitleSpot = fieldContents[j].indexOf(fieldTitle);
+ if (fieldTitleSpot != 0) {
+ fieldContents[j] = fieldContents[j].substr(fieldTitleSpot + fieldTitleLength);
+ } else {
+ fieldContents[j] = fieldContents[j].substr(fieldTitleLength);
+ }
+
+ dataTags[fieldTitle] = fieldContents[j].replace(/^\s*|\s*$/g, '''');
+ fieldContents[j] = '''';
+ }
+ }
+ }
+
+ } else if (mediaType1 == "book") {
+ var newItem = new Zotero.Item("book");
+
+ if (doc.evaluate(''//div[@class="darkBorder roundbox"][@id="main"]/table/tbody/tr/td[1]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var headers = doc.evaluate(''//div[@class="darkBorder roundbox"][@id="main"]/table/tbody/tr/td[1]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var contents = doc.evaluate(''//div[@class="darkBorder roundbox"][@id="main"]/table/tbody/tr/td[2]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = headers.iterateNext()) {
+ fieldTitle = next_title.textContent.toLowerCase().replace(/\s+/g, '''');
+ if (!fieldTitle.match(":")) {
+ fieldTitle = fieldTitle + ":";
+ }
+ fieldContent = contents.iterateNext().textContent.replace(/^\s*|\s*$/g, '''');
+ dataTags[fieldTitle] = fieldContent;
+ }
+ }
+
+ } else if (mediaType1 == "videoRecording") {
+ var newItem = new Zotero.Item("videoRecording");
+ scrapeType = 1;
+
+ } else if (mediaType1 == "audioRecording") {
+ var newItem = new Zotero.Item("audioRecording");
+ scrapeType = 1;
+ }
+
+ if (scrapeType == 1) {
+ var xPathHeaders = ''//div[@class="darkBorder roundbox"][@id="main"]/p[@class="content"]/span[@class="key"]'';
+
+ if (doc.evaluate(''xPathHeaders'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var headers = doc.evaluate(''xPathHeaders'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var contents = doc.evaluate(''//span[@class="value"]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = headers.iterateNext()) {
+ fieldTitle = next_title.textContent.toLowerCase().replace(/\s+/g, '''');
+ fieldContent = contents.iterateNext().textContent.replace(/^\s*|\s*$/g, '''');
+ dataTags[fieldTitle] = fieldContent;
+ }
+ }
+ }
+
+ if (dataTags["creator:"]) {
+ var author = dataTags["creator:"];
+ if (author.match(", ")) {
+ var authors = author.split(", ");
+ author = authors[1] + " " + authors[0];
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "creator"));
+ } else {
+ newItem.creators.push({lastName: author, creatorType: "creator"});
+ }
+ }
+
+ if (dataTags["author:"]) {
+ var author = dataTags["author:"];
+ if (author.match(", ")) {
+ var authors = author.split(", ");
+ author = authors[1] + " " + authors[0];
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ } else {
+ newItem.creators.push({lastName: author, creatorType: "author"});
+ }
+ }
+
+ if (doc.evaluate(''//div[@class="box"][@id="description"]/h1'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newItem.title = doc.evaluate(''//div[@class="box"][@id="description"]/h1'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ } else if (doc.evaluate(''//div[@class="darkBorder roundbox"][@id="main"]/h1'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newItem.title = doc.evaluate(''//div[@class="darkBorder roundbox"][@id="main"]/h1'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ } else {
+ newItem.title = doc.title;
+ }
+
+ var tagsCount = "none";
+ if (dataTags["keywords:"]) {
+ if (dataTags["keywords:"].match(";")) {
+ var tagsContent = (dataTags["keywords:"].split(";"));
+ tagsCount = "multiple";
+ } else if (dataTags["keywords:"].match(", ")) {
+ var tagsContent = (dataTags["keywords:"].split(", "));
+ tagsCount = "multiple";
+ } else {
+ var tagsContent = (dataTags["keywords:"]);
+ tagsCount = "one";
+ }
+ if (tagsCount == "multiple") {
+ for (var i = 0; i < tagsContent.length; i++) {
+ newItem.tags[i] = tagsContent[i];
+ }
+ } else if (tagsCount == "one") {
+ newItem.tags = tagsContent;
+ }
+ }
+
+ if (dataTags["publisher:"]) {
+ if (dataTags["publisher:"].match(":")) {
+ var place1 = dataTags["publisher:"].split(":");
+ newItem.place = place1[0];
+ newItem.publisher = place1[1];
+ } else {
+ associateData (newItem, dataTags, "publisher:", "publisher");
+ }
+ }
+
+ if (dataTags["rights:"]) {
+ associateData (newItem, dataTags, "rights:", "rights");
+ } else if (dataTags["creativecommonslicense:"]) {
+ newItem.rights = "Creative Commons License: " + dataTags["creativecommonslicense:"];
+ }
+
+ associateData (newItem, dataTags, "title:", "title");;
+ associateData (newItem, dataTags, "date:", "date");
+ associateData (newItem, dataTags, "callnumber:", "callNumber");
+
+ newItem.url = doc.location.href;
+
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//td[2][@class="hitCell"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var titlesCount = doc.evaluate(''count (//td[2][@class="hitCell"]/a)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ Zotero.debug(titlesCount.numberValue);
+
+ var next_title;
+ for (var i = 0; i < titlesCount.numberValue; i++) {
+ next_title = titles.iterateNext();
+
+ while (!next_title.href.match(/details/)) {
+ i++;
+ if (i == titlesCount.numberValue) {
+ Zotero.debug(i);
+ break;
+ }
+ next_title = titles.iterateNext();
+ }
+
+ if (next_title.href.match(/details/)) {
+ items[next_title.href] = next_title.textContent;
+ }
+ }
+
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('d1605270-d7dc-459f-9875-74ad8dde1f7d', '1.0.0b4.r5', '', '2008-08-21 15:45:00', '0', '100', '4', 'Le Devoir', 'Adam Crymble', 'http://www.ledevoir.com',
+'function detectWeb(doc, url) {
+ if (doc.location.href.match("Recherche")) {
+ return "multiple";
+ } else if (doc.evaluate(''//div[@id="autresArticles"]/p'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "newspaperArticle";
+ }
+}',
+'//Le Devoir Translator. Code by Adam Crymble
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var tagsContent = new Array();
+
+ var newItem = new Zotero.Item("newspaperArticle");
+
+ var contents = doc.evaluate(''//div[@id="autresArticles"]/p'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var j = 0;
+ var n = 0;
+ var contentsArray = new Array();
+ var contents1;
+
+ while (contents1 = contents.iterateNext()) {
+ contentsArray.push(contents1.textContent);
+ j++;
+ }
+
+ var author;
+ var author1;
+ var author2;
+
+ if (j > 1) {
+ for (var i in contentsArray) {
+ if (contentsArray[i].match("Édition du ")) {
+ var date1 = contentsArray[i].split("Édition du ");
+
+ newItem.date = date1[1];
+
+ if (date1[0].match(/\w/)) {
+
+ author = date1[0];
+ if (author.match(/\n/)) {
+ author1 = author.split(/\n/);
+
+ for (var k = 0; k < author1.length; k++) {
+ if (author1[k].match(/\w/) && author1[k].match(", ")) {
+ author2 = author1[k].split(", ");
+ if (author2[0].match(/\w/)) {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author2[0], "author"));
+ } else {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author2[1], "author"));
+ }
+ } else if (author1[k].match(/\w/) && !author1[k].match(", ")) {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author1[k], "author"));
+ }
+ }
+ } else if (author.match(" et ")) {
+ author1 = author.split(" et ");
+ for (var k in author1) {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author1[k], "author"));
+ }
+ } else if (author.match(", ")) {
+ author1 = author.split(", ");
+ for (var k in author1) {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author1[k], "author"));
+ }
+ } else {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(date1[0], "author"));
+ }
+ }
+ } else if (contentsArray[i].match("Mots clés")) {
+ contentsArray[i] = contentsArray[i].substr(11);
+ if (contentsArray[i].match(", ")) {
+ tagsContent = contentsArray[i].split(", ");
+ } else {
+ newItem.tags = ontentsArray[i];
+ n = 1;
+ }
+ }
+ }
+ }
+
+ if (n == 0 && tagsContent.length>1) {
+ for (var i = 0; i < tagsContent.length; i++) {
+ newItem.tags[i] = tagsContent[i];
+ }
+ }
+
+ newItem.title = doc.title;
+ newItem.url = doc.location.href;
+ newItem.publicationTitle = "Le Devoir";
+ newItem.ISSN = "0319-0722";
+
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//td[2]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ items[next_title.href] = next_title.textContent;
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('22d17fb9-ae32-412e-bcc4-7650ed3359bc', '1.0.0b4.r5', '', '2008-08-21 15:45:00', '0', '100', '4', 'Musee du Louvre', 'Adam Crymble', 'http://www.louvre.fr',
+'function detectWeb(doc, url) {
+ if (doc.location.href.match("recherche")) {
+ return "multiple";
+ } else if (doc.evaluate(''//div[@class="alignRight"]/a/img'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "artwork";
+ }
+
+}',
+'//Translator Musee du Louvre. Code by Adam Crymble
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+ var tagsContent = new Array();
+
+ var newItem = new Zotero.Item("artwork");
+
+ //tags
+ var metaTagHTML = doc.getElementsByTagName("meta");
+ for (var i = 0 ; i < metaTagHTML.length ; i++) {
+ dataTags[metaTagHTML[i].getAttribute("name")] = Zotero.Utilities.cleanTags(metaTagHTML[i].getAttribute("content"));
+ }
+
+ newItem.abstractNote = dataTags["description"];
+
+ if (dataTags["keywords"]) {
+ if (dataTags["keywords"].match(", ")) {
+ tagsContent = tagsContent = dataTags["keywords"].split(", ");
+ } else if (dataTags["keywords"].split("、")) {
+ tagsContent = dataTags["keywords"].split("、");
+ }
+ }
+
+ for (var i = 0; i < tagsContent.length; i++) {
+ newItem.tags[i] = tagsContent[i];
+ }
+
+ //date
+ var xPathDate = ''//td[@class="txtContent"]/span[@class="txtContentSmall"]'';
+
+ if (doc.evaluate(xPathDate, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+
+ newItem.date = doc.evaluate(xPathDate, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ }
+
+ //creator
+ var xPathCreator = ''//td[@class="txtContent"]/strong'';
+ if (doc.evaluate(xPathCreator, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var creator = doc.evaluate(xPathCreator, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent.toLowerCase();
+
+ var comma = 0;
+ var parenthesis = 0;
+ var commaSpot;
+ var parenthesisSpot;
+
+ if (creator.match(", ")) {
+ comma = 1;
+ commaSpot = creator.indexOf(",");
+ }
+
+ if (creator.match(/\(/)) {
+ parenthesis = 1;
+ parenthesisSpot = creator.indexOf(" (");
+ }
+
+ if (comma == 1 && parenthesis == 1) {
+ if (commaSpot < parenthesisSpot) {
+ creator = creator.substr(0, commaSpot);
+ } else {
+ creator = creator.substr(0, parenthesisSpot);
+ }
+ } else if (comma == 1 && parenthesis == 0) {
+ creator = creator.substr(0, commaSpot);
+ } else if (comma == 0 && parenthesis == 1) {
+ creator = creator.substr(0, parenthesisSpot);
+ }
+
+ var words = creator.split(" ");
+
+ for (var j in words) {
+ if (words[j] != "" && words[j] != '' '') {
+ if (words[j].match("-")) {
+ Zotero.debug(words[j]);
+ var hyphen = words[j].split("-");
+ hyphen[0] = hyphen[0][0].toUpperCase() + hyphen[0].substr(1).toLowerCase() + "-";
+ hyphen[1] = hyphen[1][0].toUpperCase() + hyphen[1].substr(1).toLowerCase();
+ words[j] = hyphen[0] + hyphen[1];
+ } else {
+ words[j] = words[j][0].toUpperCase() + words[j].substr(1).toLowerCase();
+ }
+ }
+ }
+ creator = words.join(" ");
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(creator, "artist"));
+ }
+
+
+ //title
+ var title1 = doc.title.split(" |");
+ Zotero.debug(title1[0]);
+ newItem.title = title1[0];
+
+ //extra
+ if (doc.evaluate(''//h1'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+
+ var collection1 = doc.evaluate(''//h1'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ newItem.extra = collection1.replace(/^\s*|\s*$/g, '''');
+ }
+
+ newItem.repository = "Musée du Louvre";
+ newItem.url = doc.location.href;
+
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var links = doc.evaluate(''//td[4][@class="alignTop"]/a[@class="lkContent"]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var titles = doc.evaluate(''//h4'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ items[links.iterateNext().href] = next_title.textContent;
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('5b02e8d4-d8fb-4143-af3d-3576d4c1b49c', '1.0.0b4.r5', '', '2008-08-21 15:45:00', '0', '100', '4', 'National Archives of South Africa', 'Adam Crymble', 'http://www.national.archsrch.gov.za',
+'function detectWeb(doc, url) {
+ if (doc.title.match("Results Summary")) {
+ return "multiple";
+ } else if (doc.title.match("Results Detail")) {
+ return "book";
+ }
+}',
+'//National Archives of South Africa Translator. Code by Adam Crymble
+
+function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+ var tagsContent = new Array();
+ var fieldTitle;
+
+ var newItem = new Zotero.Item("book");
+
+
+ var headers = doc.evaluate(''//td[2]/pre/b'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathCount = doc.evaluate(''count (//td[2]/pre/b)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var contents = doc.evaluate(''//td[2]/pre'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ var headersArray = new Array();
+ var oneHeader = '''';
+
+ if (xPathCount.numberValue > 1) {
+ for (var i = 0; i < xPathCount.numberValue; i++) {
+ fieldTitle = headers.iterateNext().textContent;
+ headersArray.push(fieldTitle);
+ }
+ } else {
+ oneHeader = (headers.iterateNext().textContent);
+ }
+
+ var contentsArray = new Array();
+ var j = 0;
+
+ if (oneHeader.length<1) {
+
+ for (var i = headersArray.length-1; i> -1; i--) {
+
+ var fieldIndex = contents.indexOf(headersArray[i]);
+ var shorten = headersArray[i].length;
+
+ contentsArray.push(contents.substr(fieldIndex));
+ contents = contents.substr(0, fieldIndex);
+ fieldTitle = headersArray[i].replace(/\s+/g, '''');
+
+ dataTags[fieldTitle] = contentsArray[j].substr(shorten).replace(/^\s*|\s+$/g, '''');
+ j++;
+ }
+ }
+
+ associateData (newItem, dataTags, "DEPOT", "repository");
+ associateData (newItem, dataTags, "REFERENCE", "callNumber");
+ associateData (newItem, dataTags, "STARTING", "date");
+ associateData (newItem, dataTags, "ENDING", "date");
+ associateData (newItem, dataTags, "VOLUME_NO", "volume");
+ associateData (newItem, dataTags, "REMARKS", "extra");
+ associateData (newItem, dataTags, "SUMMARY", "abstractNote");
+
+ if (dataTags["DESCRIPTION"]) {
+ associateData (newItem, dataTags, "DESCRIPTION", "title");
+ } else {
+ newItem.title = "No Title Found";
+ }
+
+ newItem.url = doc.location.href;
+
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//td/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var lastLink;
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+
+ if (!next_title.textContent.match(/^\d\d\d\d/) && !next_title.textContent.match(/\\/) && next_title.textContent.length>3 && next_title.textContent.match(/\w/)) {
+ Zotero.debug(next_title.textContent);
+ items[next_title.href] = next_title.textContent;
+ }
+
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('ed28758b-9c39-4e1c-af89-ce1c9202b70f', '1.0.0b4.r5', '', '2008-08-21 15:45:00', '0', '100', '4', 'National Gallery of Art - U.S.A.', 'Adam Crymble', 'http://www.nga.gov/',
+'function detectWeb(doc, url) {
+ var single = 0;
+
+ if (doc.evaluate(''//div[@class="content"]/img'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()){
+ var pageType = doc.evaluate(''//div[@class="content"]/img'', doc, null, XPathResult.ANY_TYPE, null).iterateNext().src;
+ }
+
+ if (doc.location.href.match("tinfo") || doc.title.match("timage")) {
+ single = "1";
+ }
+
+
+
+ if (doc.title.match("Image") && doc.location.href.match("fcgi")) {
+ return "artwork";
+ }
+
+ if (pageType.match("search_test")) {
+ return "multiple";
+ } else if (doc.location.href.match("artistid")) {
+ return "multiple";
+ } else if (single == "1" && pageType.match("collections_test")) {
+ return "artwork";
+ }
+}',
+'//National Gallery USA translator. Code by Adam Crymble
+
+function scrape(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var style = 0;
+ var title1;
+ var newItem = new Zotero.Item("artwork");
+
+ //determines page layout type
+
+ //single entry with thumbnail
+ if (doc.evaluate(''//div[@class="BodyText"]/table/tbody/tr/td[2]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+
+ var content = doc.evaluate(''//div[@class="BodyText"]/table/tbody/tr/td[2]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent.split(/\n/);
+ style = 1;
+
+ //single entry without thumbnail (2 variations)
+ } else if (doc.evaluate(''//div[@class="BodyText"]/table/tbody/tr/td'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+
+ var content = doc.evaluate(''//div[@class="BodyText"]/table/tbody/tr/td'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent.split(/\n/);
+
+ if (content[1].match("Rendered")) {
+ style = 3;
+ } else {
+ style = 1;
+ }
+
+ //single entry with large image.
+ } else if (doc.evaluate(''//tr[2]/td[1]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+
+ var content = doc.evaluate(''//tr[2]/td[1]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent.split(/\n/);
+ style = 2;
+ }
+
+ if (style == 1) {
+
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(content[1], "artist"));
+
+
+ var titleDate = content[3].split(", ");
+ title1 = titleDate[0];
+
+ if (titleDate.length>2) {
+ for (var j = 1; j < titleDate.length-1; j++) {
+ title1 = (title1 + ", " + titleDate[j]);
+ }
+ }
+ newItem.title = title1;
+
+ if (titleDate.length > 1) {
+ newItem.date = titleDate[titleDate.length-1];
+ }
+
+ newItem.extra = ("Aquisition: " + content[content.length-3]);
+ newItem.callNumber = content[content.length-2];
+
+ } else if (style == 2) {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(content[0], "artist"));
+
+ var date = content[1].split(", ");
+
+ title1 = date[0];
+
+ if (date.length>2) {
+ for (var j = 1; j < date.length-1; j++) {
+ title1 = (title1 + ", " + date[j]);
+ }
+ }
+
+ newItem.title = title1;
+
+ newItem.date = date[date.length-1];
+
+ var acquisition = content[2].split(/\d/);
+ newItem.extra = ("Aquisition: " + acquisition[0]);
+
+ } else if (style == 3) {
+
+ var titleAuthor = content[1].split("Rendered by ");
+
+ newItem.title = titleAuthor[0];
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(titleAuthor[1], "artist"));
+
+ newItem.callNumber = content[content.length-2];
+
+ }
+
+ newItem.url = doc.location.href;
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ if (doc.location.href.match("artistid")) {
+ var titles = doc.evaluate(''//ul/li/b/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ } else {
+ var titles = doc.evaluate(''//ul/li/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ }
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ if (next_title.textContent.match("image available")) {
+ next_title = titles.iterateNext();
+ }
+ items[next_title.href] = next_title.textContent;
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('54ac4ec1-9d07-45d3-9d96-48bed3411fb6', '1.0.0b4.r5', '', '2008-08-11 20:40:00', '0', '100', '4', 'National Library of Australia (new catalog)', 'Mark Triggs and Steve McPhillips', 'catalogue.nla.gov.au',
+'function detectWeb(doc, url) {
+ if (url.match("/Record/[0-9]+")) {
+ var format = Zotero.Utilities.cleanString(doc.getElementById("myformat").textContent);
+
+ if (format == "Audio") {
+ return "audioRecording";
+ }
+ else if (format == "Book") {
+ return "book";
+ }
+ else if (format == "Journal/Newspaper") {
+ return "journalArticle";
+ }
+ else if (format == "Manuscript") {
+ return "manuscript";
+ }
+ else if (format == "Map") {
+ return "map";
+ }
+ else if (format == "Music") {
+ return "audioRecording";
+ }
+ else if (format == "Online") {
+ return "webpage";
+ }
+ else if (format == "Picture") {
+ return "artwork";
+ }
+ else if (format == "Video") {
+ return "videoRecording";
+ }
+ else {
+ return "book";
+ }
+ } else if (url.match ("/Search/Home") &&
+ doc.getElementById ("resultItemLine1")) {
+ return "multiple";
+ }
+}',
+'function as_array(obj) {
+ if (obj instanceof Array) {
+ return obj;
+ } else {
+ return [obj];
+ }
+}
+
+
+function load_item(responseText, requestObject, format) {
+ metadata = eval("(" + Zotero.Utilities.cleanString(responseText) + ")");
+
+ var newItem = new Zotero.Item(format);
+
+ /* load in our authors */
+ if (metadata.authors) {
+ for (var i=0; i< metadata.authors.length ; i++) {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor
+ (metadata.authors[i], "author", true));
+ }
+ }
+
+ /* and our tags */
+ if (metadata.tags) {
+ for (var i=0; i< metadata.tags.length ; i++) {
+ newItem.tags.push(metadata.tags[i]);
+ }
+ }
+
+ /* and our summary */
+ if (metadata.notes) {
+ newItem.notes.push ({"note": metadata.notes});
+ }
+
+ /* and everything else */
+ for (var attr in metadata) {
+ if (!newItem[attr]) {
+ newItem[attr] = metadata[attr];
+ }
+ }
+ newItem.repository = "National Library of Australia";
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ format = detectWeb(doc, url);
+
+ items = [];
+ if (format == "multiple") {
+ for (var url in Zotero.selectItems((Zotero.Utilities.getItemArray
+ (doc, doc, "/Record/[0-9]+")))) {
+ items.push(url);
+ }
+ } else {
+ items.push(url);
+ }
+
+ if (items.length > 0) {
+ Zotero.Utilities.processDocuments(items, function(onedoc) {
+ handleDocument(onedoc);
+ }, function() { Zotero.done; });
+
+ Zotero.wait();
+ }
+}
+
+
+function handleDocument(doc) {
+ bibid = doc.location.href.match("^.*\/Record/([0-9]+)")[1];
+ format = detectWeb(doc, doc.location.href);
+ Zotero.Utilities.HTTP.doGet("http://catalogue.nla.gov.au/Record/" +
+ bibid +
+ "/Export?style=zotero",
+ function(text, obj) {
+ load_item(text, obj, format);
+ });
+}');
+
+
+REPLACE INTO translators VALUES ('45763818-8530-49c6-a069-34acdee1a096', '1.0.0b4.r5', '', '2008-08-11 20:40:00', '0', '100', '4', 'National Library of New Zealand', 'Adam Crymble', 'http://nlnzcat.natlib',
+'function detectWeb(doc, url) {
+
+ if (doc.title.match("Quick Record View")) {
+ return "book";
+ } else if (doc.title.match("Details Record View")) {
+ return "book";
+ } else if (doc.title.match("Catalogue Titles")) {
+ return "multiple";
+ }
+}',
+'//National Library of New Zealand translator. Code by Adam Crymble
+
+function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+ var tagsContent = new Array();
+ var headersArray = new Array();
+ var contentsArray = new Array();
+ var fieldTitle;
+ var j = 0;
+
+ var newItem = new Zotero.Item("book");
+
+ var headers = doc.evaluate(''//form/table/tbody/tr/th'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathCount = doc.evaluate(''count (//form/table/tbody/tr/th)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var contents = doc.evaluate(''//table[2]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ for (var i = 0; i < xPathCount.numberValue; i++) {
+ fieldTitle = headers.iterateNext().textContent;
+ if (fieldTitle.match(/\w/)) {
+ headersArray.push(fieldTitle);
+ }
+ }
+
+ for (var i = headersArray.length-1; i> -1; i--) {
+
+ var fieldIndex = contents.lastIndexOf(headersArray[i]);
+ contentsArray.push(contents.substr(fieldIndex));
+ contents = contents.substr(0, fieldIndex);
+
+ fieldTitle = headersArray[i].replace(/\s+/g, '''');
+
+ dataTags[fieldTitle] = contentsArray[j].substr(headersArray[i].length).replace(/^\s*|\s+$/g, '''');
+ j++;
+ }
+
+ if (dataTags["Author:"]) {
+ var author = dataTags["Author:"];
+ if (author.match(", ")) {
+ var authors = author.split(", ");
+ author = authors[1] + " " + authors[0];
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ } else {
+ newItem.creators.push({lastName: author, creatorType: "creator"});
+ }
+ }
+
+ if (dataTags["Publisher:"]) {
+ if (dataTags["Publisher:"].match(": ")) {
+ var place1 = dataTags["Publisher:"].indexOf(": ");
+ newItem.place = dataTags["Publisher:"].substr(0, place1);
+ var publisher1 = dataTags["Publisher:"].substr(place1 + 2);
+
+ if (publisher1.match(", ")) {
+ var date1 = publisher1.lastIndexOf(", ");
+ newItem.date = publisher1.substr(date1 +2);
+ newItem.publisher = publisher1.substr(0, date1);
+ } else {
+ newItem.publisher = publisher1;
+ }
+ } else {
+ newItem.publisher = publisher1;
+ }
+ }
+
+ if (dataTags["Subject:"]) {
+ if (dataTags["Subject:"].match(/\n/)) {
+ tagsContent = dataTags["Subject:"].split(/\n/)
+ for (var i = 0; i < tagsContent.length; i++) {
+ if (tagsContent[i].match(/\w/)) {
+ newItem.tags[i] = tagsContent[i];
+ }
+ }
+ } else {
+ newItem.tags = dataTags["Subject:"]
+ }
+ }
+
+ if (dataTags["LCSubject:"]) {
+ if (dataTags["LCSubject:"].match(/\n/)) {
+ tagsContent = dataTags["LCSubject:"].split(/\n/)
+ var k = 0;
+ for (var i = 0; i < tagsContent.length; i++) {
+ if (tagsContent[i].match(/\w/)) {
+ newItem.tags[k] = tagsContent[i];
+ k++;
+ }
+ }
+ } else {
+ newItem.tags = dataTags["LCSubject:"]
+ }
+ }
+
+ associateData (newItem, dataTags, "Title:", "title");
+ associateData (newItem, dataTags, "Description:", "pages");
+ associateData (newItem, dataTags, "CallNumber:", "callNumber");
+ associateData (newItem, dataTags, "Location:", "repository");
+
+ newItem.url = doc.location.href;
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//form/table/tbody/tr/td/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ if (next_title.textContent.match(/\w/)) {
+ items[next_title.href] = next_title.textContent;
+ }
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('1c5b122c-7e58-4cd5-932b-93f5ca0b7e1a', '1.0.0b4.r5', '', '2008-08-11 20:40:00', '0', '100', '4', 'National Post', 'Adam Crymble', 'http://www.(national|financial)post.com/',
+'function detectWeb(doc, url) {
+
+ if (doc.title.match("Search Results")) {
+ return "multiple";
+ } else if (doc.location.href.match("story")) {
+ return "newspaperArticle";
+ } else if (doc.location.href.match("blog")) {
+ return "blogPost";
+ }
+
+}',
+'function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == "x" ) return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+ var author = new Array();
+
+ var mediaType = detectWeb(doc,doc.location.href);
+ if (mediaType == "newspaperArticle") {
+ var newItem = new Zotero.Item("newspaperArticle");
+
+ //metadata
+ var dataTagHTML = doc.getElementsByTagName("meta");
+ for (var i = 0 ; i < dataTagHTML.length ; i++) {
+ dataTags[dataTagHTML[i].getAttribute("name")] = Zotero.Utilities.cleanTags(dataTagHTML[i].getAttribute("content"));
+ }
+
+ associateData (newItem, dataTags, "Description", "abstractNote");
+ associateData (newItem, dataTags, "PubDate", "date");
+
+ //author
+ if (dataTags["Author"]) {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(dataTags["Author"], "author"));
+ } else {
+
+ author = doc.evaluate(''//strong'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent.split(",");
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author[0], "author"));
+ }
+
+ } else if (mediaType == "blogPost") {
+
+ var newItem = new Zotero.Item("blogPost");
+
+ var blog = doc.evaluate(''//div[@class="entryviewfooter"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ blog = blog.replace("Posted:", '''').split("by");
+ newItem.date = blog[0].replace(/^\s*|\s*$/g, '''');
+
+ var author = doc.evaluate(''//span[@class="MoreRecentPostsAuthor"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent.replace("by ", '''');
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ }
+
+ Zotero.debug(doc.location.href);
+ newItem.url = doc.location.href;
+
+ // This is ACTUALLY returning This URL: http://www.nationalpost.com/components/npemail.aspx?id=591742&ref=http://www.nationalpost.com/story.html
+
+
+ var title1 = doc.title;
+ Zotero.debug(title1);
+
+ newItem.title = title1;
+ newItem.publication = "The National Post";
+ newItem.ISSN = "1486-8008";
+
+ newItem.complete();
+}
+
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+ var titles = doc.evaluate(''//h3[@class="alt"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ if (next_title.href.match("nationalpost")) {
+ items[next_title.href] = next_title.textContent;
+ Zotero.debug(next_title.href);
+ Zotero.debug(next_title.textContent);
+ }
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+
+
+
+}');
+
+
+REPLACE INTO translators VALUES ('b10bf941-12e9-4188-be04-f6357fa594a0', '1.0.0b4.r5', '', '2008-08-11 20:40:00', '0', '100', '4', 'Old Bailey Online', 'Adam Crymble', 'http://www.oldbaileyonline.org/',
+'function detectWeb(doc, url) {
+ if (doc.location.href.match("search")) {
+ return "multiple";
+ } else if (doc.location.href.match("browse")) {
+ return "case";
+ }
+}',
+'//Old Bailey Online translator. Code by Adam Crymble
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var tagsContent = new Array();
+ var fieldTitle;
+
+ var newItem = new Zotero.Item("case");
+
+ var headers = doc.evaluate(''//div[@class="apparatus"]/b'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var contents = doc.evaluate(''//div[@class="apparatus"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ var xPathCount = doc.evaluate(''count (//div[@class="apparatus"]/b)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var headersArray = new Array();
+ var oneHeader = '''';
+
+ if (xPathCount.numberValue > 1) {
+ for (var i = 0; i < xPathCount.numberValue; i++) {
+ fieldTitle = headers.iterateNext().textContent;
+ headersArray.push(fieldTitle);
+ }
+ } else {
+ oneHeader = (headers.iterateNext().textContent);
+ }
+
+ var contentsArray = new Array();
+ var j = 0;
+
+ if (oneHeader.length<1) {
+
+ for (var i = headersArray.length-1; i> -1; i--) {
+
+ var fieldIndex = contents.indexOf(headersArray[i]);
+
+ contentsArray.push(contents.substr(fieldIndex));
+ contents = contents.substr(0, fieldIndex);
+ fieldTitle = headersArray[i].replace(/\s+/g, '''');
+
+ if (fieldTitle != "ReferenceNumber:") {
+ tagsContent.push(contentsArray[j]);
+ } else {
+ newItem.extra = contentsArray[j];
+ }
+ j++;
+ }
+ } else {
+
+ if (oneHeader.match("Reference")) {
+
+ newItem.extra = contents;
+ } else {
+ newItem.tags = contents;
+ var noMoreTags = 1;
+ }
+ }
+
+ if (noMoreTags != 1) {
+ for (var i = 0; i < tagsContent.length; i++) {
+ newItem.tags[i] = tagsContent[i];
+ }
+ }
+
+ newItem.title = doc.evaluate(''//div[@class="sessionsPaperTitle"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ newItem.url = doc.location.href;
+
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//li/p[@class="srchtitle"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ items[next_title.href] = next_title.textContent;
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else if (doc.evaluate(''//div[@id="main2"]/p/a'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+
+ var xmlOrText = doc.evaluate(''//div[@id="main2"]/p/a'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext();
+
+ if (xmlOrText.textContent.match("Text")) {
+ articles = [xmlOrText.href];
+
+ } else {
+ articles = [url];
+ }
+ }
+
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('96b54986-16c7-45ea-b296-fde962d658b2', '1.0.0b4.r5', '', '2008-07-24 05:30:00', '0', '100', '4', 'The Open Library', 'Adam Crymble', 'http://openlibrary.org',
+'function detectWeb(doc, url) {
+
+ if (doc.location.href.match("search")) {
+ return "multiple";
+ } else if (doc.evaluate(''//div[@class="title-pad"]'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "book";
+ }
+
+}',
+'//Open Library Translator. Code by Adam Crymble
+
+function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+ var tagsContent = new Array();
+ var fieldTitle;
+
+ var newItem = new Zotero.Item("book");
+
+ newItem.title = doc.evaluate(''//div[@class="title-pad"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ if (doc.evaluate(''//div[@id="header"]/div[@class="subtitle"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newItem.abstractNote = doc.evaluate(''//div[@id="header"]/div[@class="subtitle"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ }
+
+ var m = 0;
+ if (doc.evaluate(''//div[@id="statement"]/span[@class="book-details-italic"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var publisher = doc.evaluate(''//div[@id="statement"]/span[@class="book-details-italic"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ var publisher1 = publisher.split(/\n/);
+ for (var i= 0; i < publisher1.length; i++) {
+ publisher1[i] = publisher1[i].replace(/^\s*|\s+$/g, '''');
+ if (publisher1[i].match("Published in ")) {
+ newItem.date = publisher1[i].substr(13, publisher1[i].length-3);
+ m = i+1;
+ } else if (publisher1[i].match(/\(/)) {
+ newItem.place = publisher1[i];
+ }
+ }
+
+ if (m > 0) {
+ newItem.publisher = publisher1[m];
+ }
+ }
+
+ var headers = doc.evaluate(''//td[1]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var contents = doc.evaluate(''//td[2]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathCount = doc.evaluate(''count (//td[1])'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ for (i=0; i 3) {
+
+ var words = author.split(", ");
+ for (var k in words) {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(words[k], "author"));
+ }
+
+ } else {
+
+ var words = author.split(", ");
+ author = words[1] + " " + words[0];
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ break;
+ }
+ }
+ } else {
+
+ newItem.creators.push({lastName: author, creatorType: "creator"});
+ break;
+ }
+ }
+ }
+ }
+
+ var m = 0;
+ if (dataTags["Subject:"]) {
+ if (dataTags["Subject:"].match(/\n/)) {
+ tagsContent = dataTags["Subject:"].split(/\n/);
+ for (var i = 0; i < tagsContent.length; i++) {
+ if (tagsContent[i].match(/\w/)) {
+ newItem.tags[m] = tagsContent[i];
+ m++;
+ }
+ }
+ } else {
+ newItem.tags = dataTags["Subject:"];
+ }
+ }
+
+ if (dataTags["ISBN13:"]) {
+ newItem.extra = "ISBN 13: " + dataTags["ISBN13:"];
+ }
+
+ associateData (newItem, dataTags, "Language:", "language");
+ associateData (newItem, dataTags, "ISBN10:", "ISBN");
+ associateData (newItem, dataTags, "Series:", "series");
+ associateData (newItem, dataTags, "Edition:", "edition");
+ associateData (newItem, dataTags, "Pagination:", "pages");
+
+ newItem.url = doc.location.href;
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//td[2][@class="result-text"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ items[next_title.href] = next_title.textContent;
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('6871e8c5-f935-4ba1-8305-0ba563ce3941', '1.0.0b4.r5', '', '2008-08-11 20:40:00', '0', '100', '4', 'PEI Archival Information Network', 'Adam Crymble', 'http://www.archives.pe.ca',
+'function detectWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ if (doc.evaluate(''//td[2]/table/tbody/tr/td/p'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent.match("Search")) {
+ return "multiple";
+
+ } else if (doc.evaluate(''//td[2]/table/tbody/tr/td/p'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent.match("Display")){
+ return "book";
+ }
+}',
+'//PEI Archival Information Network translator: Code by Adam Crymble
+
+var authors;
+
+function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function authors1() {
+ for (var k = 0; k< authors.length; k++) {
+ if (authors[k].match(", ")) {
+ var author = authors[k].split(", ");
+ authors[k] = (author[1] + (" ") + author[0].replace(/^\s*|\s*$/g, ''''));
+
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(authors[k], "author"));
+
+ } else {
+
+ newItem.creators.push({lastName: authors[k], creatorType: "creator"});
+ }
+ }
+}
+
+function scrape(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+ var fieldTitle;
+ var contents;
+ var tagsContent = new Array();
+
+ newItem = new Zotero.Item("book");
+
+ var xPathHeadings = doc.evaluate(''//small/b'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathContents = doc.evaluate(''//dd'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathCount = doc.evaluate(''count (//small/b)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ for (i=0; i1) {
+ for (k in author1) {
+ var words = author1[k].toLowerCase().split(/\s/);
+
+ for (var i in words) {
+ words[i] = words[i][0].toUpperCase() + words[i].substr(1).toLowerCase();
+ }
+
+ author1[k] = words.join(" ");
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author1[k], "author"));
+ }
+ } else {
+
+ var words = author1[0].toLowerCase().split(/\s/);
+ for (var i in words) {
+ words[i] = words[i][0].toUpperCase() + words[i].substr(1).toLowerCase();
+ }
+ author1[0] = words.join(" ");
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author1[0], "author"));
+ }
+ }
+
+ var xPathTitle = ''//span[@class="headlineArticle"][@id="ctl00_ContentPlaceHolder_article_NavWebPart_Article_ctl00___Title__"]'';
+ newItem.title = doc.evaluate(xPathTitle, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ newItem.url = doc.location.href;
+ newItem.publicationTitle = "The Toronto Star";
+ newItem.ISSN = "0319-0781";
+
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ if (next_title.href.match("http://www.thestar.com") && next_title.href.match("article") && !next_title.href.match("generic") && !next_title.href.match("static")) {
+ items[next_title.href] = next_title.textContent;
+ }
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('35d6c82d-4749-4cc5-9e12-2924307df28f', '1.0.0b4.r5', '', '2008-08-06 17:00:00', '0', '100', '4', 'UBC Library Catalog', 'Adam Crymble', 'http://webcat(1||2).library.ubc',
+'function detectWeb(doc, url) {
+
+ if (doc.evaluate(''//tbody/tr/td[1]/b'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "multiple";
+ } else if (doc.evaluate(''//center/h4/i/strong/bdo'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "book";
+ }
+}',
+'//UBC Library Catalog translator. Code by Adam Crymble
+
+function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+ var tagsContent = new Array();
+ var headersArray = new Array();
+ var fieldTitle;
+
+ var newItem = new Zotero.Item("book");
+
+ var headers = doc.evaluate(''//form/table/tbody/tr/th'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathCount= doc.evaluate(''count (//form/table/tbody/tr/th)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var contents = doc.evaluate(''//form/table'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var dump = contents.iterateNext();
+
+
+ for (var i = 0; i < xPathCount.numberValue; i++) {
+ fieldTitle = headers.iterateNext().textContent;
+ if (fieldTitle.match(/\w/)) {
+ headersArray.push(fieldTitle);
+ }
+ }
+
+ var contentsArray = new Array();
+ var j = 0;
+ contents = contents.iterateNext().textContent.replace(/\s\s/g, '''');
+
+ for (var i = headersArray.length-1; i> -1; i--) {
+
+ var fieldIndex = contents.lastIndexOf(headersArray[i]);
+
+ var headerLength = headersArray[i].length;
+
+ contentsArray.push(contents.substr(fieldIndex+headerLength));
+ contents = contents.substr(0, fieldIndex);
+
+ fieldTitle = headersArray[i].replace(/\s+/g, '''');
+ if (fieldTitle == "Subject(s):") {
+ if (contentsArray[j].match(". ")) {
+ var tagsContent = contentsArray[j].split(". ")
+ } else if (contentsArray[j].match(/\n/)) {
+ var tagsContent = contentsArray[j].split(/\n/);
+ } else {
+ newItem.tags = contentsArray[j];
+ var noMoreTags = 1;
+ }
+
+ }
+ dataTags[fieldTitle] = contentsArray[j].replace(/^\s*|\s+$/g, '''');
+
+ j++;
+ }
+
+ j = 0;
+
+ if (noMoreTags != 1) {
+ for (var i = 0; i < tagsContent.length; i++) {
+ if (tagsContent[i].match(/\w/)) {
+ newItem.tags[j] = tagsContent[i].replace(/^\s*|\s+$/g, '''');
+ j++;
+ }
+ }
+ }
+
+ if (dataTags["MainAuthor:"]) {
+ var author = dataTags["MainAuthor:"];
+ if (author.match(", ")) {
+ var authors = author.split(", ");
+ author = authors[1] + " " + authors[0];
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ } else {
+ newItem.creators.push({lastName: author, creatorType: "creator"});
+ }
+ }
+
+ if (dataTags["OtherAuthor(s):"]) {
+ var author = dataTags["OtherAuthor(s):"];
+
+ if (author.match(", ")) {
+ var authors = author.split(", ");
+ author = authors[1] + " " + authors[0];
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ } else {
+ newItem.creators.push({lastName: author, creatorType: "creator"});
+ }
+ }
+
+ if (dataTags["Published:"]) {
+ if (dataTags["Published:"].match(": ")) {
+ var imprint = dataTags["Published:"];
+
+ var place1 = imprint.indexOf(": ");
+
+ newItem.place = imprint.substr(0, place1);
+
+ var imprint2 = imprint.substr(place1+2);
+
+ if (imprint2.match(/\d\d\d/)) {
+ var date1 = imprint2.lastIndexOf(/\d\d\d/);
+ var date2 = imprint2.substr(date1-4);
+ newItem.date = date2;
+ newItem.publisher = imprint2.substr(0, imprint2.length-(newItem.date.length+2));
+ } else {
+ newItem.publisher = imprint2;
+ }
+ } else {
+ newItem.publisher = dataTags["Published:"]
+ }
+ }
+
+ associateData (newItem, dataTags, "Title:", "title");
+ associateData (newItem, dataTags, "CallNumber:", "callNumber");
+ associateData (newItem, dataTags, "Description:", "pages");
+ associateData (newItem, dataTags, "Location:", "repository");
+
+ newItem.url = doc.location.href;
+
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//form/table/tbody/tr/td/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ items[next_title.href] = next_title.textContent;
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('f8b5501a-1acc-4ffa-a0a5-594add5e6bd3', '1.0.0b4.r5', '', '2008-08-06 17:00:00', '0', '100', '4', 'US National Archives Research Catalog', 'Adam Crymble', 'http://arcweb.archives.gov',
+'function detectWeb(doc, url) {
+ if (doc.location.href.match("ShowArchivalDescriptions") || doc.location.href.match("ShowDODescriptions")) {
+ return "multiple";
+ } else if (doc.location.href.match("ShowFullRecord") && doc.location.href.match("showFullDescriptionTabs/details")) {
+ return "book";
+ }
+}',
+'//US National Archives. Code by Adam Crymble
+
+function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+ var fieldTitle;
+
+ var newItem = new Zotero.Item("book");
+
+ var contents2 = doc.evaluate(''//td[1]/div[@class="sT"]/p'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ for (var i = 0; i < 3; i++) {
+ if (i == 0) {
+ newItem.title = contents2.iterateNext().textContent.replace(/^\s*|\s+$/g, '''');
+ } else if (i == 1) {
+ newItem.extra = contents2.iterateNext().textContent.replace(/^\s*|\s+$/g, '''');
+ } else if (i == 2) {
+ newItem.locInArchive= contents2.iterateNext().textContent.replace(/^\s*|\s+$/g, '''');
+ }
+ }
+
+ var headers = doc.evaluate(''//tbody/tr/th'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var contents = doc.evaluate(''//body/div[@class="genPad"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ var xPathCount = doc.evaluate(''count (//tbody/tr/th)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var headersArray = new Array();
+ var oneHeader = '''';
+
+ if (xPathCount.numberValue > 1) {
+ for (var i = 0; i < xPathCount.numberValue; i++) {
+ fieldTitle = headers.iterateNext().textContent;
+ headersArray.push(fieldTitle);
+ }
+ } else {
+ oneHeader = (headers.iterateNext().textContent);
+ }
+
+ var contentsArray = new Array();
+ var j = 0;
+
+ if (oneHeader.length<1) {
+
+ for (var i = headersArray.length-1; i> -1; i--) {
+
+ var fieldIndex = contents.lastIndexOf(headersArray[i]);
+ var fieldIndexLength = headersArray[i].length;
+
+ contentsArray.push(contents.substr(fieldIndex));
+ contents = contents.substr(0, fieldIndex);
+ fieldTitle = headersArray[i].replace(/\s+/g, '''');
+
+ dataTags[fieldTitle] = contentsArray[j].substr(fieldIndexLength).replace(/^\s*|\s+$/g, '''');
+
+ j++;
+ }
+ }
+ j = 0;
+ var k = 0;
+ var tagsContent = new Array();
+
+ if (dataTags["IndexTerms:"]) {
+ if (dataTags["IndexTerms:"].match(/\n/)){
+ var tagsContent = dataTags["IndexTerms:"].split(/\n/);
+ } else {
+ if (!dataTags["IndexTerms:"].match("Subjects Represented in the Archival Material")) {
+ newItem.tags = dataTags["IndexTerms:"];
+ }
+ }
+ if (tagsContent.length > 1) {
+ for (var i = 0; i < tagsContent.length; i++) {
+ if (tagsContent[i].match(/\w/)) {
+ if (k == 1) {
+ newItem.tags[j] = tagsContent[i];
+ j++;
+ }
+ k = 1;
+ }
+ }
+ }
+ }
+
+ associateData (newItem, dataTags, "ProductionDate(s):", "date");
+ associateData (newItem, dataTags, "PartOf:", "series");
+ associateData (newItem, dataTags, "VariantControlNumber(s):", "callNumber");
+
+ if (dataTags["Creator(s):"]) {
+ var author = dataTags["Creator(s):"];
+ if (author.match(", ")) {
+ var authors = author.split(", ");
+ author = authors[1] + " " + authors[0];
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ } else {
+ newItem.creators.push({lastName: author, creatorType: "creator"});
+ }
+ }
+
+ newItem.url = doc.location.href;
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ if (doc.evaluate(''//div[@class="sT"]/p/strong[@class="sFC"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var titles = doc.evaluate(''//div[@class="sT"]/p/strong[@class="sFC"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ } else if (doc.evaluate(''//td[3]/div[@class="sT"]/p/strong[@class="sFC"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var titles = doc.evaluate(''//td[3]/div[@class="sT"]/p/strong[@class="sFC"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ }
+
+
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ items[next_title.href] = next_title.textContent;
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('1d82cbdf-703d-4f96-9ae2-246af21bb96e', '1.0.0b4.r5', '', '2008-08-06 17:00:00', '0', '100', '4', 'Winnipeg Free Press', 'Adam Crymble', 'http://www.winnipegfreepress',
+'function detectWeb(doc, url) {
+ if (doc.location.href.match("articles") || doc.location.href.match("story")) {
+ return "newspaperArticle";
+ }
+}',
+'//Winnipeg Free Press Translator. Code by Adam Crymble
+//works for single entries only.
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var newItem = new Zotero.Item("newspaperArticle");
+
+ newItem.title = doc.evaluate(''//h3'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent.replace(/^\s*|\s*$/g, '''');
+
+ if (doc.evaluate(''//div[@id="middlecol"]/h4'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newItem.abstractNote = doc.evaluate(''//div[@id="middlecol"]/h4'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent.replace(/^\s*|\s*$/g, '''');
+ }
+
+ if (doc.evaluate(''//div[@id="bylines"]/p[@class="byline"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var byline = doc.evaluate(''//p[@class="byline"]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var k = 0;
+ var byLineArray = new Array();
+ var nextByLine;
+
+ while (nextByLine = byline.iterateNext()) {
+ byLineArray.push(nextByLine.textContent.replace(/^\s*|\s*$/g, ''''));
+ k++;
+ }
+
+ if (k>1) {
+ for (var i = 0; i < byLineArray.length; i++) {
+ if (byLineArray[i].match("Updated:")) {
+ newItem.date = byLineArray[i].substr(9).replace(/^\s*|\s*$/g, '''');
+ } else if (byLineArray[i].match("bylineParse") && byLineArray[i].substr(13).match(/\w/)) {
+
+ var author = (byLineArray[i].substr(13));
+ var authorLength = author.length/2;
+ var author = author.substr(0 + authorLength);
+ var m = 0;
+
+ if (author.match(" - ")) {
+ var author = author.split('' - '');
+ } else if (author.match(", ")) {
+ var author = author.split('', '');
+ } else if (author.match(/ By /)) {
+ var author = author.split(/By/);
+ author[0] = author[1];
+ } else if (author.match(/By:/)) {
+ var author = author.split(/By:/);
+ author[0] = author[1];
+ } else {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ m = 1;
+ }
+
+ if (m == 0) {
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author[0], "author"));
+ }
+ }
+ }
+ }
+ }
+
+ newItem.publicationTitle = "Winnipeg Free Press";
+ newItem.url = doc.location.href;
+ newItem.complete();
+}
+
+function doWeb (doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ }: null;
+
+ var uris= new Array();
+ uris.push(url);
+ Zotero.Utilities.processDocuments(uris, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('dbfcaa3e-082a-45a4-9619-9892f49399c1', '1.0.0b4.r5', '', '2008-08-06 17:00:00', '0', '100', '4', 'Cyberpresse', 'Adam Crymble', 'http://www.cyberpresse.ca',
+'function detectWeb (doc, url) {
+ if (doc.location.href.match("article")) {
+ return "newspaperArticle";
+ }
+}',
+'//Cyberpresse translator. Code by Adam Crymble
+
+function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+ var tagsContent = new Array();
+ var fieldTitle;
+
+ var newItem = new Zotero.Item("newspaperArticle");
+
+ if (doc.title.match("|")) {
+
+ var titleStuff = doc.title.split("|");
+ if (titleStuff[0].match(":")) {
+ var authorTitle = titleStuff[0].split(":");
+ newItem.title = authorTitle[1];
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(authorTitle[0], "author"));
+
+ } else {
+ newItem.title = titleStuff[0];
+ }
+
+ } else {
+ newItem.title = doc.title;
+ }
+
+ var dataTagHTML = doc.getElementsByTagName("meta");
+ for (var i = 0 ; i < dataTagHTML.length ; i++) {
+ dataTags[dataTagHTML[i].getAttribute("name")] = Zotero.Utilities.cleanTags(dataTagHTML[i].getAttribute("content"));
+ }
+
+ if (doc.evaluate(''//div[@id="nouvelle"]/p[@class="auteur"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var author = doc.evaluate(''//div[@id="nouvelle"]/p[@class="auteur"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ }
+
+ if (doc.evaluate(''//div[@id="nouvelle"]/p[@class="date"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newItem.date = doc.evaluate(''//div[@id="nouvelle"]/p[@class="date"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ }
+
+ associateData (newItem, dataTags, "summary", "abstractNote");
+ associateData (newItem, dataTags, "mediaarticle", "publicationTitle");
+
+ newItem.url = doc.location.href;
+
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+
+ var articles = new Array();
+
+ articles = [url];
+
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('1eb5eb03-26ab-4015-bd0d-65487734744a', '1.0.0b4.r5', '', '2008-08-06 17:00:00', '0', '100', '4', 'Bibliotheque et Archives Nationale du Quebec (Pistard)', 'Adam Crymble', 'http://pistard.banq.qc.ca',
+'function detectWeb (doc, url) {
+
+ if (doc.title.match("Liste détaillée des fonds")) {
+ return "multiple";
+ } else if (doc.title.match("Description fonds")) {
+ return "book";
+ }
+}',
+'//Bibliotheque et Archives National du Quebec. Code by Adam Crymble
+
+function associateData (newItem, dataTags, field, zoteroField) {
+ if (dataTags[field]) {
+ newItem[zoteroField] = dataTags[field];
+ }
+}
+
+function scrape(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var dataTags = new Object();
+ var fieldTitle;
+ var tagsContent= new Array();
+
+ var newItem = new Zotero.Item("book");
+
+ var headers = doc.evaluate(''//strong'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var xPathCount = doc.evaluate(''count (//strong)'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var contents = doc.evaluate(''//div[@id="Content"]/div/table'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ var headersArray = new Array();
+ var oneHeader = '''';
+
+ if (xPathCount.numberValue > 1) {
+ for (var i = 0; i < xPathCount.numberValue; i++) {
+ fieldTitle = headers.iterateNext().textContent;
+ headersArray.push(fieldTitle);
+ }
+ } else {
+ oneHeader = (headers.iterateNext().textContent);
+ }
+
+ var contentsArray = new Array();
+ var j = 0;
+
+ if (oneHeader.length<1) {
+
+ for (var i = headersArray.length-1; i> -1; i--) {
+
+ var fieldIndex = contents.indexOf(headersArray[i]);
+ var removeHeader = headersArray[i].length;
+
+ contentsArray.push(contents.substr(fieldIndex));
+ contents = contents.substr(0, fieldIndex);
+ fieldTitle = headersArray[i].replace(/\s+/g, '''');
+
+ dataTags[fieldTitle] = contentsArray[j].substr(removeHeader).replace(/^\s*|\s+$/g, '''');
+ j++;
+ }
+ }
+ Zotero.debug(dataTags);
+
+ if (dataTags["Titre,Dates,Quantité"]) {
+ if (dataTags["Titre,Dates,Quantité"].match(/\n/)) {
+ var splitTitle = dataTags["Titre,Dates,Quantité"].split(/\n/);
+ if (splitTitle[0].match(/\w/)) {
+ newItem.title = splitTitle[0].replace(/^\s*|\s+$/g, '''');
+ }
+ for (var i = 0; i < splitTitle.length; i++) {
+ if (splitTitle[i].match("/ ")) {
+ var author = splitTitle[i].replace(/^\s*|\s+$/g, '''').substr(2);
+ newItem.creators.push({lastName: author, creatorType: "creator"});
+ }
+ }
+ }
+ } else {
+ newItem.title = doc.title;
+ }
+
+
+ var k = 0;
+ if (dataTags["Termesrattachés"]) {
+
+ if (dataTags["Termesrattachés"].match(/\n/)) {
+ tagsContent = dataTags["Termesrattachés"].split(/\n/);
+ for (var i in tagsContent) {
+ if (tagsContent[i].match(/\w/)) {
+ newItem.tags[k] = tagsContent[i].replace(/^\s+|\s*$/g, '''');
+ k++;
+ }
+ }
+ } else {
+ newItem.tags[0] = dataTags["Termesrattachés"];
+ }
+ }
+
+ associateData (newItem, dataTags, "Languedesdocuments", "language");
+ associateData (newItem, dataTags, "Cote:", "callNumber");
+ associateData (newItem, dataTags, "Collation", "pages");
+ associateData (newItem, dataTags, "Centre:", "place");
+ associateData (newItem, dataTags, "Portéeetcontenu", "abstractNote");
+
+ newItem.url = doc.location.href;
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//td[2]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ if (next_title.href.match("description_fonds")) {
+ items[next_title.href] = next_title.textContent;
+ }
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('04c0db88-a7fc-4d1a-9cf7-471d0990acb1', '1.0.0b4.r5', '', '2008-08-06 17:00:00', '0', '100', '4', 'Christian Science Monitor', 'Adam Crymble', 'http://(features.csmonitor|www.csmonitor).com',
+'function detectWeb(doc, url) {
+ if (doc.location.href.match("search")) {
+ return "multiple";
+ } else if (doc.location.href.match("features")) {
+ return "newspaperArticle";
+ } else if (doc.evaluate(''//div[@id="storyContent"]/h1'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "newspaperArticle";
+ }
+}',
+'//Christian Science Monitor translator. Code by Adam Crymble.
+
+function scrape(doc, url) {
+
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var newItem = new Zotero.Item("newspaperArticle");
+
+
+ if (doc.location.href.match("features.csmonitor")) {
+
+ newItem.title = doc.title;
+
+
+ if (doc.evaluate(''//div[@class="story"][@id="main"]/p/strong'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newItem.abstractNote = doc.evaluate(''//div[@class="story"][@id="main"]/p/strong'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ }
+
+ if (doc.evaluate(''//h3/span[@class="time-date"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newItem.date = doc.evaluate(''//h3/span[@class="time-date"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent.replace(" edition", '''');
+ }
+
+ if (doc.evaluate(''//h3/span'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+
+ var author = doc.evaluate(''//h3/span'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ if (author.match("By ")) {
+ author = author.substr(3);
+ }
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ }
+
+ var title1 = doc.title;
+
+ //Some entries do not work for some reason unbeknownst to me; this flag catches the problem and prevents an error, but doesn''t save the data properly.
+ if (title1.match("csmonitor")) {
+ newItem.title = title1.substr(0, title1.length-15);
+ } else {
+ newItem.title = "This Entry Cannot Be Saved";
+ newItem.abstractNote = "Entry must be entered manually";
+ }
+
+
+
+ } else {
+
+ //title
+ if (doc.evaluate(''//div[@id="storyContent"]/h1'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+
+ var title1 = doc.evaluate(''//div[@id="storyContent"]/h1'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ var words = title1.split(" ");
+ for (var i in words) {
+ words[i] = words[i][0].toUpperCase() + words[i].substr(1).toLowerCase();
+ }
+ title1 = words.join(" ");
+ newItem.title = title1;
+ } else {
+ newItem.title = "no title found";
+ }
+
+ //abstract note
+ if (doc.evaluate(''//div[@id="storyContent"]/h2'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ newItem.abstractNote = doc.evaluate(''//div[@id="storyContent"]/h2'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ }
+
+ //date
+ if (doc.evaluate(''//div[@id="storyContent"]/p[@class="postdate"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var date1 = doc.evaluate(''//div[@id="storyContent"]/p[@class="postdate"]'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ date1 = date1.replace(/from the /g, '''');
+ date1 = date1.replace(/ edition/g, '''');
+ newItem.date = date1;
+ }
+
+ //author
+ if (doc.evaluate(''//address[@class="byline"]/strong'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
+ var author = doc.evaluate(''//address[@class="byline"]/strong'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+
+ if (author.match("By ")) {
+ author = author.substr(3);
+ }
+ var words = author.split(" ");
+ for (var i in words) {
+ words[i] = words[i][0].toUpperCase() + words[i].substr(1).toLowerCase();
+ }
+ author = words.join(" ");
+ newItem.creators.push(Zotero.Utilities.cleanAuthor(author, "author"));
+ }
+
+ }
+
+ newItem.publicationTitle = "Christian Science Monitor";
+ newItem.url = doc.location.href;
+
+ newItem.complete();
+}
+
+function doWeb(doc, url) {
+ var namespace = doc.documentElement.namespaceURI;
+ var nsResolver = namespace ? function(prefix) {
+ if (prefix == ''x'') return namespace; else return null;
+ } : null;
+
+ var articles = new Array();
+
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+
+ var titles = doc.evaluate(''//p[@id="searchResultRow"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+
+ var next_title;
+ while (next_title = titles.iterateNext()) {
+ if (!next_title.href.match("features")) {
+ items[next_title.href] = next_title.textContent;
+ }
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ articles.push(i);
+ }
+ } else {
+ articles = [url];
+ }
+ Zotero.Utilities.processDocuments(articles, scrape, function() {Zotero.done();});
+ Zotero.wait();
+}');
+
+
+REPLACE INTO translators VALUES ('138de272-0d2a-4ab5-8cfb-0fd879958d04', '1.0.0b4.r5', '', '2008-07-25 17:40:00', '0', '100', '4', 'AdvoCAT', 'Adam Crymble', '^http://(142.57.32.51|library.lsuc.on.ca)',
'function detectWeb(doc, url) {
if (doc.location.href.match("Search_Code")) {
return "multiple";
@@ -1410,7 +7662,6 @@ REPLACE INTO translators VALUES ('138de272-0d2a-4ab5-8cfb-0fd879958d04', '1.0.0b
}
function scrape(doc, url) {
-
var namespace = doc.documentElement.namespaceURI;
var nsResolver = namespace ? function(prefix) {
if (prefix == ''x'') return namespace; else return null;
@@ -1501,6 +7752,7 @@ function doWeb(doc, url) {
Zotero.wait();
}');
+
REPLACE INTO translators VALUES ('add79dfd-7951-4c72-af1d-ce1d50aa4fb4', '1.0.0b4.r5', '', '2008-07-07 14:50:00', '0', '100', '4', 'informIT database', 'Adam Crymble', 'http://www.informit.com',
'function detectWeb(doc, url) {
if (doc.title.match("Search Results")) {
@@ -1674,6 +7926,113 @@ function doWeb(doc, url) {
Zotero.wait();
}');
+REPLACE INTO translators VALUES ('e9632edc-8032-4dc5-b2d4-284d481583e6', '1.0', '', '2008-08-06 17:00:00', '0', '100', '4', 'SAE International', 'Michael Berkowitz', 'http://www.sae.org/',
+'function detectWeb(doc, url) {
+ if (doc.evaluate(''//td[2][@class="search-results"]/a'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "multiple";
+ } else if (url.match(/\/books\//)) {return "book";}
+ else if (url.match(/\/papers\//)) {return "conferencePaper";}
+}',
+'function doWeb(doc, url) {
+ var arts = new Array();
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+ var links = doc.evaluate(''//td[2][@class="search-results"]/a'', doc, null, XPathResult.ANY_TYPE, null);
+ var link;
+ while (link = links.iterateNext()) {
+ items[link.href] = link.textContent;
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ arts.push(i);
+ }
+ } else {
+ arts = [url];
+ }
+ Zotero.Utilities.processDocuments(arts, function(doc) {
+ var type = detectWeb(doc, doc.location.href);
+ if (type == "paper") {
+ var data = new Object();
+ var metas = doc.evaluate(''//meta'', doc, null, XPathResult.ANY_TYPE, null);
+ var meta;
+ while (meta = metas.iterateNext()) {
+ name = meta.name;
+ content = meta.content;
+ if (data[name]) {
+ data[name] = data[name] + ";" + content;
+ } else {
+ data[name] = content;
+ }
+ }
+ var item = new Zotero.Item("conferencePaper");
+ item.title = doc.evaluate(''//title'', doc, null, XPathResult.ANY_TYPe, null).iterateNext().textContent;
+ item.data = data[''publ_date''];
+ item.url = data[''identifier_url''];
+ var authors = data[''author''].split(/\s+;/);
+ for each (var aut in authors) {
+ item.creators.push(Zotero.Utilities.cleanAuthor(aut, "author"));
+ }
+ item.abstractNote = Zotero.Utilities.trimInternal(doc.evaluate(''//td[1][@class="spg spg-left"]/p[strong[contains(text(), "Abstract")]]'', doc, null, XPathResult.ANY_TYPE, null).iterateNext().textContent.substr(9));
+ } else if (type = "book") {
+ var item = new Zotero.Item("book");
+ var data = doc.evaluate(''//p[strong[contains(text(), "ISBN")]]'', doc, null, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ item.ISBN = data.match(/ISBN Number:\s+([\d\-]+)/)[1];
+ item.date = data.match(/Date Published:\s+(.*)\n/)[1];
+ item.url = doc.location.href;
+ item.title = Zotero.Utilities.trimInternal(doc.evaluate(''//title'', doc, null, XPathResult.ANY_TYPE, null).iterateNext().textContent);
+ item.abstractNote = Zotero.Utilities.trimInternal(doc.evaluate(''//td[1][@class="spg spg-left"]/p[contains(text(), ".")]'', doc, null, XPathResult.ANY_TYPE, null).iterateNext().textContent);
+ }
+ item.attachments = [{url:item.url, title:item.title, mimeType:"text/html"}];
+ item.complete();
+ }, function() {Zotero.done;});
+ Zotero.wait();
+}');
+
+REPLACE INTO translators VALUES ('48d3b115-7e09-4134-ad5d-0beda6296761', '1.0', '', '2008-08-06 17:00:00', '0', '100', '4', 'SPIE Digital Library', 'Michael Berkowitz', 'http://spiedl.aip.org/',
+'function detectWeb(doc, url) {
+ if (doc.evaluate(''//table[@class="searchResultsTable"]'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "multiple";
+ } else if (doc.evaluate(''//div[@id="articletoolsdisplay"]'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
+ return "journalArticle";
+ }
+}',
+'//http://spiedl.aip.org/getabs/servlet/GetCitation?fn=view_isi&source=scitation&PrefType=ARTICLE&PrefAction=Add+Selected&SelectCheck=JBOPFO000013000002024024000001&downloadcitation=+Go+
+
+function doWeb(doc, url) {
+ var arts = new Array();
+ if (detectWeb(doc, url) == "multiple") {
+ var items = new Object();
+ var results = doc.evaluate(''//table[@class="searchResultsTable"]/tbody/tr'', doc, null, XPathResult.ANY_TYPE, null);
+ var result;
+ while (result = results.iterateNext()) {
+ var title = doc.evaluate(''.//td[3]/a[1]'', result, null, XPathResult.ANY_TYPE, null).iterateNext().textContent;
+ var id = doc.evaluate(''.//td[2]/input'', result, null, XPathResult.ANY_TYPE, null).iterateNext().value;
+ items[id] = title;
+ }
+ items = Zotero.selectItems(items);
+ for (var i in items) {
+ arts.push(i);
+ }
+ } else {
+ var id = doc.evaluate(''//input[@name="SelectCheck"]'', doc, null, XPathResult.ANY_TYPE, null).iterateNext().value;
+ arts = [id];
+ }
+
+ var getstr1 = ''http://'' + doc.location.host + ''/getabs/servlet/GetCitation?fn=view_isi&source=scitation&PrefType=ARTICLE&PrefAction=Add+Selected&SelectCheck='';
+ var getstr2 = ''&downloadcitation=+Go+'';
+ for each (var id in arts) {
+ var get = getstr1 + id + getstr2;
+ Zotero.Utilities.HTTP.doGet(get, function(text) {
+ Zotero.debug(text);
+ var translator = Zotero.loadTranslator("import");
+ translator.setTranslator("32d59d2d-b65a-4da4-b0a3-bdd3cfb979e7");
+ translator.setString(text);
+ translator.translate();
+ });
+ }
+
+}');
+
REPLACE INTO translators VALUES ('87766765-919e-4d3b-9071-3dd7efe984c8', '1.0.0b4.r5', '', '2008-07-16 20:10:00', '1', '100', '4', 'Revues.org', 'Michael Berkowitz', 'http://.*\.revues\.org',
'function detectWeb(doc, url) {
if (doc.evaluate(''//div[@id="inside"]/div[@class="sommaire"]/dl[@class="documents"]/dd[@class="titre"]/a'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()
@@ -4190,7 +10549,7 @@ function doWeb(doc, url) {
Zotero.wait();
}');
-REPLACE INTO translators VALUES ('fc410e64-0252-4cd3-acb1-25e584775fa2', '1.0.0b4.r5', '', '2008-06-08 23:00:00', '0', '100', '4', 'National Library of Australia', 'Michael Berkowitz', 'http://librariesaustralia.nla.gov.au/',
+REPLACE INTO translators VALUES ('fc410e64-0252-4cd3-acb1-25e584775fa2', '1.0.0b4.r5', '', '2008-08-21 15:45:00', '0', '100', '4', 'National Library of Australia', 'Michael Berkowitz', 'http://librariesaustralia.nla.gov.au/',
'function detectWeb(doc, url) {
if (url.match("action=Search")) {
return "multiple";
@@ -4224,21 +10583,20 @@ REPLACE INTO translators VALUES ('fc410e64-0252-4cd3-acb1-25e584775fa2', '1.0.0b
}
item = new Zotero.Item("book");
item.title = Zotero.Utilities.trimInternal(data[''Title:''].match(/^[^/]+/)[0]);
- if (data[''Author:''].match(/\w+/)) item.creators.push(Zotero.Utilities.cleanAuthor(data[''Author:''], "author", true));
+ if (data[''Author:'']) item.creators.push(Zotero.Utilities.cleanAuthor(data[''Author:''], "author", true));
if (data[''Published:''].match(/\w+/)) {
- var pub = data[''Published:''].match(/^([^:]+):([^,]+),(.*)$/);
+ var pub = data[''Published:''].match(/^([^:]+):(.*)\s+([^\s]+)$/);
item.location = Zotero.Utilities.trimInternal(pub[1]);
item.publisher = Zotero.Utilities.trimInternal(pub[2]);
item.date = Zotero.Utilities.trimInternal(pub[3].replace(/\D/g, ""));
}
if (data[''Subjects:'']) {
var kws = data[''Subjects:''].split(".");
- Zotero.debug(kws);
for each (var key in kws) {
if (key.match(/\w+/)) item.tags.push(key);
}
}
- if (data[''ISBN:''].match(/\w+/)) item.ISBN = Zotero.Utilities.trimInternal(data[''ISBN:''].match(/^[^(]+/)[0]);
+ if (data[''ISBN:'']) item.ISBN = Zotero.Utilities.trimInternal(data[''ISBN:''].match(/^[^(]+/)[0]);
item.complete();
}, function() {Zotero.done;});
Zotero.wait();
@@ -5713,7 +12071,7 @@ REPLACE INTO translators VALUES ('bdaac15c-b0ee-453f-9f1d-f35d00c7a994', '1.0.0b
Zotero.wait();
}');
-REPLACE INTO translators VALUES ('5278b20c-7c2c-4599-a785-12198ea648bf', '1.0.0b4.r5', '', '2008-05-19 19:00:00', '1', '100', '4', 'ARTstor', 'Ameer Ahmed and Michael Berkowitz', 'http://[^/]*web2.artstor.org[^/]*',
+REPLACE INTO translators VALUES ('5278b20c-7c2c-4599-a785-12198ea648bf', '1.0.0b4.r5', '', '2008-08-29 14:26:14', '1', '100', '4', 'ARTstor', 'Ameer Ahmed and Michael Berkowitz', 'http://[^/]artstor.org[^/]*',
'function detectWeb(doc, url) {
if (url.match(/(S|s)earch/) && (doc.evaluate(''//div[@id="thumbContentWrap"]/div'', doc, null, XPathResult.ANY_TYPE, null).iterateNext().textContent.match(/\w+/))) return "multiple"
}',
@@ -8360,7 +14718,7 @@ function doWeb(doc, url) {
Zotero.wait();
}');
-REPLACE INTO translators VALUES ('7cb0089b-9551-44b2-abca-eb03cbf586d9', '1.0.0b4.r5', '', '2008-03-30 08:00:00', '0', '100', '4', 'BioOne', 'Michael Berkowitz', 'http://[^/]*www.bioone.org[^/]*/',
+REPLACE INTO translators VALUES ('7cb0089b-9551-44b2-abca-eb03cbf586d9', '1.0.0b4.r5', '', '2008-08-04 07:10:00', '0', '100', '4', 'BioOne', 'Michael Berkowitz', 'http://[^/]*www.bioone.org[^/]*/',
'function detectWeb(doc, url) {
if (url.indexOf("searchtype") != -1) {
return "multiple";
@@ -8373,17 +14731,8 @@ REPLACE INTO translators VALUES ('7cb0089b-9551-44b2-abca-eb03cbf586d9', '1.0.0b
return "http://www.bioone.org/perlserv/?request=cite-builder&doi=" + str;
}
-function getPDFurl(item) {
- var bits = new Array(
- item.DOI.match(/\/([^(]+)\(/)[1],
- item.volume,
- item.issue,
- item.pages.match(/^([^-]+)\-/)[1]
- );
- return "http://www.bioone.org/archive/" + bits.slice(0,3).join("/") + "/pdf/i" + bits.join("-") + ".pdf";
-}
-
function doWeb(doc, url) {
+ var host = doc.location.host;
var articles = new Array();
if (detectWeb(doc, url) == "multiple") {
var items = new Object();
@@ -8401,7 +14750,6 @@ function doWeb(doc, url) {
} else {
articles = [createCitationURL(url)];
}
- Zotero.debug(articles);
Zotero.Utilities.processDocuments(articles, function(newDoc) {
var newlink = newDoc.evaluate(''//a[contains(@href, "refman")]'', newDoc, null, XPathResult.ANY_TYPE, null).iterateNext().href;
Zotero.Utilities.HTTP.doGet(newlink, function(text) {
@@ -8411,7 +14759,7 @@ function doWeb(doc, url) {
translator.setHandler("itemDone", function(obj, item) {
item.url = decodeURIComponent(item.url);
item.DOI = item.url.match(/http:\/\/dx\.doi\.org\/(.*)$/)[1];
- var pdfurl = getPDFurl(item);
+ var pdfurl = ''http://'' + host + ''/perlserv/?request=get-pdf&doi='' + item.DOI;
item.attachments = [
{url:item.url, title:item.title, mimeType:"text/html"},
{url:pdfurl, title:"BioOne Full Text PDF", mimeType:"application/pdf"}
@@ -10440,7 +16788,7 @@ REPLACE INTO translators VALUES ('8b35ab14-f18a-4f69-8472-b2df18c984da', '1.0.0b
Zotero.wait();
}');
-REPLACE INTO translators VALUES ('1885b93c-cf37-4b25-aef5-283f42eada9d', '1.0.0b4.r5', '', '2008-02-01 19:30:00', '0', '100', '4', 'Informaworld', 'Michael Berkowitz', 'http://www.informaworld.com',
+REPLACE INTO translators VALUES ('1885b93c-cf37-4b25-aef5-283f42eada9d', '1.0.0b4.r5', '', '2008-08-19 10:30:00', '0', '100', '4', 'Informaworld', 'Michael Berkowitz', 'http://www.informaworld.com',
'function detectWeb(doc, url) {
if (url.indexOf("quicksearch") != -1) {
return "multiple";
@@ -10502,7 +16850,7 @@ REPLACE INTO translators VALUES ('1885b93c-cf37-4b25-aef5-283f42eada9d', '1.0.0b
}
thing = stuff.iterateNext();
}
-
+ var pdfurl = newDoc.evaluate(''//div[@id="content"]/div/a[1]'', newDoc, null, XPathResult.ANY_TYPE, null).iterateNext().href;
var id = newDoc.location.href.match(/content=([\w\d]+)/);
var post = ''tab=citation&selecteditems='' + id[1].substr(1) + ''&content='' + id[1] + ''&citstyle=refworks&showabs=false&format=file'';
Zotero.Utilities.HTTP.doPost(''http://www.informaworld.com/smpp/content'', post, function(text) {
@@ -10516,7 +16864,6 @@ REPLACE INTO translators VALUES ('1885b93c-cf37-4b25-aef5-283f42eada9d', '1.0.0b
translator.setString(text);
translator.setHandler("itemDone", function(obj, item) {
var type = text.match(/TY\s+\-\s+([^\n]*)/)[1];
- Zotero.debug(type);
if (type == "Journal") {
item.itemType = "journalArticle";
} else if (type == "Book, Whole") {
@@ -10527,6 +16874,7 @@ REPLACE INTO translators VALUES ('1885b93c-cf37-4b25-aef5-283f42eada9d', '1.0.0b
if (doi) {
item.DOI = doi;
}
+ item.attachments.push({url:pdfurl, title:item.title, mimeType:''application/pdf''});
item.complete();
});
translator.translate();
@@ -10576,7 +16924,7 @@ REPLACE INTO translators VALUES ('f880bf79-d42f-4337-b0d2-7a7de4a48b7d', '1.0.0b
}
}');
-REPLACE INTO translators VALUES ('0cdc6a07-38cf-4ec1-b9d5-7a3c0cc89b15', '1.0.0b4.r5', '', '2008-01-30 21:00:00', '0', '100', '4', 'OSTI Energy Citations', 'Michael Berkowitz', 'http://www.osti.gov/energycitations',
+REPLACE INTO translators VALUES ('0cdc6a07-38cf-4ec1-b9d5-7a3c0cc89b15', '1.0.0b4.r5', '', '2008-08-20 15:20:00', '0', '100', '4', 'OSTI Energy Citations', 'Michael Berkowitz', 'http://www.osti.gov/energycitations',
'function detectWeb(doc, url) {
if (doc.evaluate(''//table[@class="searchresults"]//a[@class="citation"]'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
return "multiple";
@@ -10602,8 +16950,9 @@ REPLACE INTO translators VALUES ('0cdc6a07-38cf-4ec1-b9d5-7a3c0cc89b15', '1.0.0b
urls = [url.match(/osti_id=\d+/)[0]];
}
for (var i = 0 ; i < urls.length ; i++) {
- var getstr = ''http://www.osti.gov/energycitations/endnote?osti_id=140097'';
+ var getstr = ''http://www.osti.gov/energycitations/endnote?'' + urls[i];
Zotero.Utilities.HTTP.doGet(getstr, function(text) {
+ Zotero.debug(text);
text = text.replace(/(%.)/g, "$1 ");
var trans = Zotero.loadTranslator("import");
trans.setTranslator("881f60f2-0802-411a-9228-ce5f47b64c7d");
@@ -10836,7 +17185,7 @@ REPLACE INTO translators VALUES ('303c2744-ea37-4806-853d-e1ca67be6818', '1.0.0b
Zotero.wait();
}');
-REPLACE INTO translators VALUES ('27ee5b2c-2a5a-4afc-a0aa-d386642d4eed', '1.0.0b4.r5', '', '2008-07-16 20:10:00', '1', '100', '4', 'PubMed Central', 'Michael Berkowitz', 'http://[^/]*.nih.gov/',
+REPLACE INTO translators VALUES ('27ee5b2c-2a5a-4afc-a0aa-d386642d4eed', '1.0.0b4.r5', '', '2008-08-06 17:00:00', '1', '100', '4', 'PubMed Central', 'Michael Berkowitz', 'http://[^/]*.nih.gov/',
'function detectWeb(doc, url) {
if (doc.evaluate(''//table[@id="ResultPanel"]//td[2]'', doc, null, XPathResult.ANY_TYPE, null).iterateNext()) {
return "multiple";
@@ -10899,9 +17248,17 @@ REPLACE INTO translators VALUES ('27ee5b2c-2a5a-4afc-a0aa-d386642d4eed', '1.0.0b
newItem.attachments.push({url:tags["pdf_url"], title:"PubMed Central Full Text PDF", mimeType:"application/pdf"});
}
newItem.url = tags["fulltext_html_url"];
+ if (!newItem.url) newItem.url = tags["abstract_html_url"];
newItem.extra = text.match(/PMC\d+/)[0];
newItem.journalAbbreviation = text.match(/span class=\"citation-abbreviation\">([^<]+))[1];
- newItem.pages = text.match(/span class=\"citation-flpages\">([^<]+))[1].replace(/[\.:\s]/g, "")
+ newItem.pages = text.match(/span class=\"citation-flpages\">([^<]+))[1].replace(/[\.:\s]/g, "");
+
+ if (text.match(/Abstract<\/div>([^<]+))) {
+ var abstract = text.match(/Abstract<\/div>([^<]+))[1];
+ } else if (text.match(/\"section-content\">([^<]+)/)) {
+ var abstract = text.match(/\"section-content\">([^<]+)/)[1];
+ }
+ if (abstract) newItem.abstractNote = abstract;
newItem.complete();
});
}
@@ -11236,7 +17593,7 @@ REPLACE INTO translators VALUES ('b86bb082-6310-4772-a93c-913eaa3dfa1b', '1.0.0b
}
}');
-REPLACE INTO translators VALUES ('d9be934c-edb9-490c-a88d-34e2ee106cd7', '1.0.0b4.r5', '', '2008-05-21 19:15:00', '0', '100', '4', 'Time.com', 'Michael Berkowitz', 'http://www.time.com/time/',
+REPLACE INTO translators VALUES ('d9be934c-edb9-490c-a88d-34e2ee106cd7', '1.0.0b4.r5', '', '2008-08-04 07:10:00', '0', '100', '4', 'Time.com', 'Michael Berkowitz', 'http://www.time.com/time/',
'function detectWeb(doc, url) {
if (doc.title == "TIME Magazine - Search Results") {
return "multiple";
@@ -11251,7 +17608,7 @@ REPLACE INTO translators VALUES ('d9be934c-edb9-490c-a88d-34e2ee106cd7', '1.0.0b
var xpath3 = ''//div[@class="copy"]/div[@class="byline"]'';
if ((doc.evaluate(xpath, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext() || doc.evaluate(xpath2, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext() || doc.evaluate(xpath3, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) ) {
if (url.substr(-4,4) == "html") {
- return "newspaperArticle";
+ return "magazineArticle";
}
}
}
@@ -11264,8 +17621,8 @@ REPLACE INTO translators VALUES ('d9be934c-edb9-490c-a88d-34e2ee106cd7', '1.0.0b
}
function scrape(doc, url) {
- var newItem = new Zotero.Item("newspaperArticle");
- newItem.publicationTitle = "Time Magazine";
+ var newItem = new Zotero.Item("magazineArticle");
+ newItem.publicationTitle = "Time";
newItem.ISSN = "0040-718X";
newItem.url = doc.location.href;
var metaTags = new Object();
@@ -11277,8 +17634,10 @@ function scrape(doc, url) {
if (metaTags["head"]) {
associateMeta(newItem, metaTags, "head", "title");
+ } else if (doc.title.length > 7) {
+ newItem.title = doc.title.substr(0, doc.title.length - 7);
} else {
- newItem.title = doc.title.substr(0, doc.title.length - 7);
+ newItem.title = "No Title";
}
if (metaTags["description"]) {
@@ -11346,6 +17705,7 @@ function scrape(doc, url) {
}
}
}
+ newItem.attachments.push({document:doc, title:doc.title});
newItem.complete();
}
@@ -15937,7 +22297,7 @@ REPLACE INTO translators VALUES ('774d7dc2-3474-2684-392c-f787789ec63d', '1.0.0b
Zotero.wait();
}');
-REPLACE INTO translators VALUES ('63a0a351-3131-18f4-21aa-f46b9ac51d87', '1.0.0b3.r1', '', '2006-12-15 15:11:00', 1, 100, 4, 'Library Catalog (VTLS)', 'Simon Kornblith', '/chameleon(?:\?|$)',
+REPLACE INTO translators VALUES ('63a0a351-3131-18f4-21aa-f46b9ac51d87', '1.0.0b3.r1', '', '2008-08-11 20:40:00', '1', '100', '4', 'Library Catalog (VTLS)', 'Simon Kornblith', '/chameleon(?:\?|$)',
'function detectWeb(doc, url) {
var node = doc.evaluate(''//tr[@class="intrRow"]/td/table/tbody/tr[th]'', doc, null, XPathResult.ANY_TYPE, null).iterateNext();
if(node) {
@@ -15947,7 +22307,7 @@ REPLACE INTO translators VALUES ('63a0a351-3131-18f4-21aa-f46b9ac51d87', '1.0.0b
if(node) {
return "book";
}
-}',
+}',
'function doWeb(doc, url) {
var namespace = doc.documentElement.namespaceURI;
var nsResolver = namespace ? function(prefix) {
@@ -16029,15 +22389,21 @@ REPLACE INTO translators VALUES ('63a0a351-3131-18f4-21aa-f46b9ac51d87', '1.0.0b
var record = new marc.record();
- var xpath = ''//table[@class="outertable"]/tbody/tr[td[4]]'';
+// var xpath = ''//table[@class="outertable"]/tbody/tr[td[4]]''; //old xpath
+// xpaths from virginia college of osteopathic medicine
+// /html/body/table[@class="header2"]/tbody/tr/td[2]/table/tbody/tr/td/table/tbody/tr/td/table[@class="marctable"]/tbody/tr/td[1][@class="marcTag"]
+// /html/body/table[@class="header2"]/tbody/tr/td[2]/table/tbody/tr/td/table/tbody/tr/td/table[@class="marctable"]/tbody/tr/td[2]
+// /html/body/table[@class="header2"]/tbody/tr/td[2]/table/tbody/tr/td/table/tbody/tr/td/table[@class="marctable"]/tbody/tr/td[3]
+// /html/body/table[@class="header2"]/tbody/tr/td[2]/table/tbody/tr/td/table/tbody/tr/td/table[@class="marctable"]/tbody/tr/td[4][@class="marcSubfields"]
+ var xpath = ''//table[@class="marctable"]/tbody/tr[td[4]]'';
var elmts = newDoc.evaluate(xpath, newDoc, nsResolver,
XPathResult.ANY_TYPE, null);
while(elmt = elmts.iterateNext()) {
- var field = doc.evaluate(''./TD[1]/text()[1]'', elmt, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().nodeValue;
- var ind1 = doc.evaluate(''./TD[2]/text()[1]'', elmt, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().nodeValue;
- var ind2 = doc.evaluate(''./TD[3]/text()[1]'', elmt, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().nodeValue;
- var value = doc.evaluate(''./TD[4]/text()[1]'', elmt, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().nodeValue;
+ var field = newDoc.evaluate(''./TD[1]/text()[1]'', elmt, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().nodeValue;
+ var ind1 = newDoc.evaluate(''./TD[2]/text()[1]'', elmt, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().nodeValue;
+ var ind2 = newDoc.evaluate(''./TD[3]/text()[1]'', elmt, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().nodeValue;
+ var value = newDoc.evaluate(''./TD[4]/text()[1]'', elmt, nsResolver, XPathResult.ANY_TYPE, null).iterateNext().nodeValue;
value = value.replace(/\\([a-z]) /g, marc.subfieldDelimiter+"$1");
record.addField(field, ind1+ind2, value);
@@ -16313,7 +22679,7 @@ REPLACE INTO translators VALUES ('0f9fc2fc-306e-5204-1117-25bca009dffc', '1.0.0b
Zotero.wait();
}');
-REPLACE INTO translators VALUES ('c54d1932-73ce-dfd4-a943-109380e06574', '1.0.0b4.r1', '', '2008-03-25 00:50:00', '1', '100', '4', 'Project MUSE', 'Simon Kornblith', 'https?://[^/]*muse\.jhu\.edu[^/]*/(?:journals/[^/]+/[^/]+/[^/]+\.html|search/results)',
+REPLACE INTO translators VALUES ('c54d1932-73ce-dfd4-a943-109380e06574', '1.0.0b4.r1', '', '2008-08-21 15:45:00', '1', '100', '4', 'Project MUSE', 'Simon Kornblith', 'https?://[^/]*muse\.jhu\.edu[^/]*/(?:journals/[^/]+/[^/]+/[^/]+\.html|search/results)',
'function detectWeb(doc, url) {
var searchRe = new RegExp("^https?://[^/]+/search/results");
if(searchRe.test(url)) {
@@ -16329,22 +22695,22 @@ REPLACE INTO translators VALUES ('c54d1932-73ce-dfd4-a943-109380e06574', '1.0.0b
} : null;
var searchRe = new RegExp("^https?://[^/]+/search/results");
- if(searchRe.test(doc.location.href)) {
+ if(detectWeb(doc, url) == "multiple") {
var items = new Array();
var attachments = new Array();
var pdfRe = /\.pdf$/i;
var htmlRe = /\.html$/i;
- var tableRows = doc.evaluate(''/html/body/table[@class="navbar"]/tbody/tr/td//form/table'',
+ var tableRows = doc.evaluate(''//div[@id="advancedsearch"]/save_form/table//tr'',
doc, nsResolver, XPathResult.ANY_TYPE, null);
var tableRow;
// Go through table rows
while(tableRow = tableRows.iterateNext()) {
// aid (article id) is what we need to get it all as one file
- var input = doc.evaluate(''./tbody/tr/td/input[@name="aid"]'', tableRow, nsResolver, XPathResult.ANY_TYPE, null).iterateNext();
- var title = doc.evaluate(''.//b/i/text()'', tableRow, nsResolver, XPathResult.ANY_TYPE, null).iterateNext();
- if(input && input.value && title && title.nodeValue) {
- items[input.value] = title.nodeValue;
+ var input = doc.evaluate(''.//input[@name="aid"]'', tableRow, nsResolver, XPathResult.ANY_TYPE, null).iterateNext();
+ var title = doc.evaluate(''.//div[@class="title"]'', tableRow, nsResolver, XPathResult.ANY_TYPE, null).iterateNext();
+ if(input && input.value && title && title.textContent) {
+ items[input.value] = title.textContent;
var aTags = tableRow.getElementsByTagName("a");
@@ -16363,7 +22729,6 @@ REPLACE INTO translators VALUES ('c54d1932-73ce-dfd4-a943-109380e06574', '1.0.0b
}
}
}
-
items = Zotero.selectItems(items);
if(!items) {
return true;
@@ -16429,7 +22794,7 @@ REPLACE INTO translators VALUES ('c54d1932-73ce-dfd4-a943-109380e06574', '1.0.0b
}
}');
-REPLACE INTO translators VALUES ('fcf41bed-0cbc-3704-85c7-8062a0068a7a', '1.0.0b3.r1', '', '2008-07-21 09:38:53', '1', '100', '4', 'NCBI PubMed', 'Simon Kornblith and Michael Berkowitz', 'http://[^/]*www\.ncbi\.nlm\.nih\.gov[^/]*/(pubmed|sites/entrez|entrez/query\.fcgi\?.*db=PubMed)',
+REPLACE INTO translators VALUES ('fcf41bed-0cbc-3704-85c7-8062a0068a7a', '1.0.0b3.r1', '', '2008-08-29 04:10:00', '1', '100', '4', 'NCBI PubMed', 'Simon Kornblith and Michael Berkowitz', 'http://[^/]*www\.ncbi\.nlm\.nih\.gov[^/]*/(pubmed|sites/entrez|entrez/query\.fcgi\?.*db=PubMed)',
'function detectWeb(doc, url) {
var namespace = doc.documentElement.namespaceURI;
var nsResolver = namespace ? function(prefix) {
@@ -16510,8 +22875,11 @@ function detectSearch(item) {
if(issn) {
newItem.ISSN = issn;
}
-
- newItem.journalAbbreviation = Zotero.Utilities.superCleanString(citation.Article.Journal.ISOAbbreviation.text().toString());
+
+ if(citation.MedlineJournalInfo.MedlineTA.length()) {
+ newItem.journalAbbreviation = Zotero.Utilities.superCleanString(citation.MedlineJournalInfo.MedlineTA.text().toString());
+ }
+// newItem.journalAbbreviation = Zotero.Utilities.superCleanString(citation.Article.Journal.ISOAbbreviation.text().toString());
if(article.Journal.Title.length()) {
newItem.publicationTitle = Zotero.Utilities.superCleanString(article.Journal.Title.text().toString());
} else if(citation.MedlineJournalInfo.MedlineTA.length()) {
@@ -18361,7 +24729,7 @@ function doWeb(doc, url) {
Zotero.wait();
}');
-REPLACE INTO translators VALUES ('d0b1914a-11f1-4dd7-8557-b32fe8a3dd47', '1.0.0b3.r1', '', '2008-07-02 11:00:00', '1', '100', '4', 'EBSCOhost', 'Simon Kornblith and Michael Berkowitz', 'https?://[^/]+/(?:bsi|ehost)/(?:results|detail|folder)',
+REPLACE INTO translators VALUES ('d0b1914a-11f1-4dd7-8557-b32fe8a3dd47', '1.0.0b3.r1', '', '2008-08-06 17:00:00', '1', '100', '4', 'EBSCOhost', 'Simon Kornblith and Michael Berkowitz', 'https?://[^/]+/(?:bsi|ehost)/(?:results|detail|folder)',
'function detectWeb(doc, url) {
var namespace = doc.documentElement.namespaceURI;
var nsResolver = namespace ? function(prefix) {
@@ -18374,21 +24742,22 @@ REPLACE INTO translators VALUES ('d0b1914a-11f1-4dd7-8557-b32fe8a3dd47', '1.0.0b
if(searchResult) {
return "multiple";
}
-
- var xpath = ''//div[@class="record-display"]/dl[@class="citation-fields"]/dt[text() = "Persistent link to this record:"''
- +''or text() = "Vínculo persistente a este informe:"''
- +''or text() = "Lien permanent à cette donnée:"''
- +''or text() = "Permanenter Link zu diesem Datensatz:"''
- +''or text() = "Link permanente al record:"''
- +''or text() = "Link permanente para este registro:"''
- +''or text() = "本記錄固定連結:"''
- +''or text() = "此记录的永久链接:"''
- +''or text() = "このレコードへのパーシスタント リンク:"''
- +''or text() = "레코드 링크 URL:"''
- +''or text() = "Постоянная ссылка на эту запись:"''
- +''or text() = "Bu kayda sürekli bağlantı:"''
- +''or text() = "Μόνιμος σύνδεσμος σε αυτό το αρχείο:"]'';
-
+/*
+ var xpath = ''//div[@class="citation-wrapping-div"]/dl[@class="citation-fields"]/dt[starts-with(text(), "Persistent link to this record")''
+ +'' or starts-with(text(), "Vínculo persistente a este informe")''
+ +'' or starts-with(text(), "Lien permanent à cette donnée")''
+ +'' or starts-with(text(), "Permanenter Link zu diesem Datensatz")''
+ +'' or starts-with(text(), "Link permanente al record")''
+ +'' or starts-with(text(), "Link permanente para este registro")''
+ +'' or starts-with(text(), "本記錄固定連結")''
+ +'' or starts-with(text(), "此记录的永久链接")''
+ +'' or starts-with(text(), "このレコードへのパーシスタント リンク")''
+ +'' or starts-with(text(), "레코드 링크 URL")''
+ +'' or starts-with(text(), "Постоянная ссылка на эту запись")''
+ +'' or starts-with(text(), "Bu kayda sürekli bağlantı")''
+ +'' or starts-with(text(), "Μόνιμος σύνδεσμος σε αυτό το αρχείο")]'';
+*/
+ var xpath = ''//input[@id="ctl00_ctl00_MainContentArea_MainContentArea_topDeliveryControl_deliveryButtonControl_lnkExportImage"]'';
var persistentLink = doc.evaluate(xpath, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext();
if(persistentLink) {
return "journalArticle";
@@ -18401,6 +24770,26 @@ function fullEscape(text) {
return escape(text).replace(/\//g, "%2F").replace(/\+/g, "%2B");
}
+function generateDeliverString(nsResolver, doc){
+ var hiddenInputs = doc.evaluate(''//input[@type="hidden" and not(contains(@name, "folderHas"))]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ var hiddenInput;
+ var deliverString ="";
+ while(hiddenInput = hiddenInputs.iterateNext()) {
+ deliverString = deliverString+hiddenInput.name.replace(/\$/g, "%24")+"="+encodeURIComponent(hiddenInput.value) + "&";
+ }
+ var otherHiddenInputs = doc.evaluate(''//input[@type="hidden" and contains(@name, "folderHas")]'', doc, nsResolver, XPathResult.ANY_TYPE, null);
+ while(hiddenInput = otherHiddenInputs.iterateNext()) {
+ deliverString = deliverString+hiddenInput.name.replace(/\$/g, "%24")+"="+escape(hiddenInput.value).replace(/\//g, "%2F").replace(/%20/g, "+") + "&";
+ }
+
+
+ deliverString = deliverString
+ +"&ctl00%24ctl00%24MainContentArea%24MainContentArea%24topDeliveryControl%24deliveryButtonControl%24lnkExportImage.x=5"
+ +"&ctl00%24ctl00%24MainContentArea%24MainContentArea%24topDeliveryControl%24deliveryButtonControl%24lnkExportImage.y=14";
+
+ return deliverString;
+}
+
/*
* given the text of the delivery page, downloads an item
*/
@@ -18410,7 +24799,7 @@ function downloadFunction(text) {
var deliveryURL = m[1].replace(/&/g, "&");
m = customViewStateMatch.exec(text);
var downloadString = "__EVENTTARGET=&__EVENTARGUMENT=&__CUSTOMVIEWSTATE="+fullEscape(m[1])+"&__VIEWSTATE=&ctl00%24ctl00%24MainContentArea%24MainContentArea%24ctl00%24btnSubmit=Save&ctl00%24ctl00%24MainContentArea%24MainContentArea%24ctl00%24BibFormat=1&ajax=enabled";
-
+
Zotero.Utilities.HTTP.doPost(host+"/ehost/"+deliveryURL,
downloadString, function(text) { // get marked records as RIS
// load translator for RIS
@@ -18424,6 +24813,7 @@ function downloadFunction(text) {
if (text.match("L3")) {
item.DOI = text.match(/L3\s+\-\s*(.*)/)[1];
}
+ item.itemType = "journalArticle";
item.complete();
});
translator.translate();
@@ -18446,12 +24836,8 @@ function doWeb(doc, url) {
XPathResult.ANY_TYPE, null).iterateNext();
if(searchResult) {
- var titlex = ''//div[@class="result-list-record" or @class="folder-item-detail"]/a'';
- if (doc.evaluate(titlex, doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext()) {
- var titles = doc.evaluate(titlex, doc, nsResolver, XPathResult.ANY_TYPE, null);
- } else {
- var titles = doc.evaluate(''//div[@class="result-list-record" or @class="folder-item-detail"]/span[@class="medium-font"]/a'', doc, nsResolver, XPathResult.ANY_TYPE, null);
- }
+ var titlex = ''//div[@class="result-list-record" or @class="folder-item-detail"]/span/a'';
+ var titles = doc.evaluate(titlex, doc, nsResolver, XPathResult.ANY_TYPE, null);
var items = new Object();
var title;
while (title = titles.iterateNext()) {
@@ -18469,19 +24855,16 @@ function doWeb(doc, url) {
}
Zotero.Utilities.processDocuments(uris, function(newDoc){
- var customViewState = newDoc.evaluate(''//input[@name="__CUSTOMVIEWSTATE"]'', newDoc, nsResolver,
- XPathResult.ANY_TYPE, null).iterateNext();
- customViewState = fullEscape(customViewState.value);
- var deliverString = "__EVENTTARGET=ctl00%24ctl00%24MainContentArea%24MainContentArea%24topDeliveryControl%24deliveryButtonControl%24lnkExport&__EVENTARGUMENT=&__CUSTOMVIEWSTATE="+customViewState+"&__VIEWSTATE=&ajax=enabled";
- Zotero.Utilities.HTTP.doPost(newDoc.location.href, deliverString, downloadFunction);
+ var postURL = newDoc.evaluate(''//form[@name="aspnetForm"]/@action'', newDoc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext();
+ postURL = host+"/ehost/"+postURL.nodeValue;
+ var deliverString = generateDeliverString(nsResolver, newDoc);
+ Zotero.Utilities.HTTP.doPost(postURL, deliverString, downloadFunction);
});
} else {
- // get view state for post string
- var customViewState = doc.evaluate(''//input[@name="__CUSTOMVIEWSTATE"]'', doc, nsResolver,
- XPathResult.ANY_TYPE, null).iterateNext();
- customViewState = fullEscape(customViewState.value);
- var deliverString = "__EVENTTARGET=ctl00%24ctl00%24MainContentArea%24MainContentArea%24topDeliveryControl%24deliveryButtonControl%24lnkExport&__EVENTARGUMENT=&__CUSTOMVIEWSTATE="+customViewState+"&__VIEWSTATE=&ajax=enabled";
- Zotero.Utilities.HTTP.doPost(url, deliverString, downloadFunction);
+ var postURL = doc.evaluate(''//form[@name="aspnetForm"]/@action'', doc, nsResolver, XPathResult.ANY_TYPE, null).iterateNext();
+ postURL = host+"/ehost/"+postURL.nodeValue;
+ var deliverString = generateDeliverString(nsResolver, doc);
+ Zotero.Utilities.HTTP.doPost(postURL, deliverString, downloadFunction);
}
Zotero.wait();
}');
@@ -19209,9 +25592,9 @@ REPLACE INTO translators VALUES ('8917b41c-8527-4ee7-b2dd-bcbc3fa5eabd', '1.0.0b
Zotero.wait();
}');
-REPLACE INTO translators VALUES ('ecddda2e-4fc6-4aea-9f17-ef3b56d7377a', '1.0.0b3.r1', '', '2008-07-07 17:00:00', '1', '100', '4', 'arXiv.org', 'Sean Takats and Michael Berkowitz', 'http://(?:(www|uk)\.)?(?:(arxiv\.org|xxx.lanl.gov)/(?:find/\w|list/\w|abs/)|eprintweb.org/S/(?:search|archive|article)(?!.*refs$)(?!.*cited$))',
+REPLACE INTO translators VALUES ('ecddda2e-4fc6-4aea-9f17-ef3b56d7377a', '1.0.0b3.r1', '', '2008-08-04 07:10:00', '1', '100', '4', 'arXiv.org', 'Sean Takats and Michael Berkowitz', 'http://(?:([^\.]+\.))?(?:(arxiv\.org|xxx.lanl.gov)/(?:find/\w|list/\w|abs/)|eprintweb.org/S/(?:search|archive|article)(?!.*refs$)(?!.*cited$))',
'function detectWeb(doc, url) {
- var searchRe = /^http:\/\/(?:(www|uk)\.)?(?:(arxiv\.org|xxx\.lanl\.gov)\/(?:find|list)|eprintweb.org\/S\/(?:archive|search$))/;
+ var searchRe = /^http:\/\/(?:([^\.]+\.))?(?:(arxiv\.org|xxx\.lanl\.gov)\/(?:find|list)|eprintweb.org\/S\/(?:archive|search$))/;
if(searchRe.test(url)) {
return "multiple";
} else {
@@ -19550,14 +25933,14 @@ REPLACE INTO translators VALUES ('fe728bc9-595a-4f03-98fc-766f1d8d0936', '1.0.0b
Zotero.wait();
}');
-REPLACE INTO translators VALUES ('b6d0a7a-d076-48ae-b2f0-b6de28b194e', '1.0.0b3.r1', '', '2008-06-15 17:10:00', '1', '100', '4', 'ScienceDirect', 'Michael Berkowitz', 'https?://www\.sciencedirect\.com[^/]*/science(\/article)?(\?(?:.+\&|)ob=(?:ArticleURL|ArticleListURL|PublicationURL))?',
+REPLACE INTO translators VALUES ('b6d0a7a-d076-48ae-b2f0-b6de28b194e', '1.0.0b3.r1', '', '2008-07-24 05:15:00', '1', '100', '4', 'ScienceDirect', 'Michael Berkowitz', 'https?://[^/]*www\.sciencedirect\.com[^/]*/science(\/article)?(\?(?:.+\&|)ob=(?:ArticleURL|ArticleListURL|PublicationURL))?',
'function detectWeb(doc, url) {
if ((url.indexOf("_ob=DownloadURL") != -1) || doc.title == "ScienceDirect Login") {
return false;
}
- if((url.indexOf("_ob=ArticleURL") == -1 && url.indexOf("/article/") == -1) || url.indexOf("/journal/") != -1) {
+ if((!url.match("pdf") && url.indexOf("_ob=ArticleURL") == -1 && url.indexOf("/article/") == -1) || url.indexOf("/journal/") != -1) {
return "multiple";
- } else {
+ } else if (!url.match("pdf")) {
return "journalArticle";
}
}',
@@ -19791,7 +26174,7 @@ REPLACE INTO translators VALUES ('19643c25-a4b2-480d-91b7-4e0b761fb6ad', '1.0.0b
Zotero.wait();
}');
-REPLACE INTO translators VALUES ('d75381ee-7d8d-4a3b-a595-b9190a06f43f', '1.0.0b3.r1', '', '2007-04-05 19:45:00', '0', '100', '4', 'Scitation', 'Eugeniy Mikhailov', '^https?://(?:www\.)?scitation.aip.org',
+REPLACE INTO translators VALUES ('d75381ee-7d8d-4a3b-a595-b9190a06f43f', '1.0.0b3.r1', '', '2008-08-21 11:32:13', '0', '100', '4', 'Scitation', 'Eugeniy Mikhailov', '^https?://(?:www\.)?scitation.aip.org',
'function detectWeb(doc, url) {
var namespace = doc.documentElement.namespaceURI;
var nsResolver = namespace ? function(prefix) {
@@ -19846,8 +26229,12 @@ REPLACE INTO translators VALUES ('d75381ee-7d8d-4a3b-a595-b9190a06f43f', '1.0.0b
// load translator for RIS
var translator = Zotero.loadTranslator("import");
translator.setTranslator("32d59d2d-b65a-4da4-b0a3-bdd3cfb979e7");
- Zotero.debug(text);
translator.setString(text);
+ translator.setHandler("itemDone", function(obj, item) {
+ var doi = text.match(/ER\s{2}\-\s.*org\/(.*)\n/)[1];
+ if (doi) item.DOI = doi;
+ item.complete();
+ });
translator.translate();
Zotero.done();
@@ -22530,7 +28917,7 @@ REPLACE INTO translators VALUES ('af4cf622-eaca-450b-bd45-0f4ba345d081', '1.0.0b
Zotero.wait();
}');
-REPLACE INTO translators VALUES ('0e2235e7-babf-413c-9acf-f27cce5f059c', '1.0.0b4.r1', '', '2007-03-22 15:55:00', 1, 50, 3, 'MODS', 'Simon Kornblith', 'xml',
+REPLACE INTO translators VALUES ('0e2235e7-babf-413c-9acf-f27cce5f059c', '1.0.8', '', '2008-08-20 01:05:28', 1, 50, 3, 'MODS', 'Simon Kornblith', 'xml',
'Zotero.addOption("exportNotes", true);
function detectImport() {
@@ -22861,7 +29248,6 @@ function doImport() {
};
- var text = "";
var read;
// read until we see if the file begins with a parse instruction
@@ -22888,13 +29274,14 @@ function doImport() {
}
} else {
Zotero.setCharacterSet("utf-8");
- text += firstPart;
}
// read in 16384 byte increments
+ var text = "";
while(read = Zotero.read(16384)) {
text += read;
}
+ text = text.replace(/<\?xml[^>]+\?>/, "");
// parse with E4X
var m = new Namespace("http://www.loc.gov/mods/v3");
@@ -24269,10 +30656,10 @@ function doImport() {
}
}');
-REPLACE INTO translators VALUES ('32d59d2d-b65a-4da4-b0a3-bdd3cfb979e7', '1.0.2', '', '2008-07-17 22:05:00', '1', '100', '3', 'RIS', 'Simon Kornblith', 'ris',
+REPLACE INTO translators VALUES ('32d59d2d-b65a-4da4-b0a3-bdd3cfb979e7', '1.0.2', '', '2008-07-24 23:50:00', '1', '100', '3', 'RIS', 'Simon Kornblith', 'ris',
'Zotero.configure("dataMode", "line");
Zotero.addOption("exportNotes", true);
-Zotero.addOption("exportCharset", "UTF-8xBOM");
+Zotero.addOption("exportCharset", "UTF-8");
function detectImport() {
var line;
@@ -24779,9 +31166,9 @@ function doExport() {
}
}');
-REPLACE INTO translators VALUES ('881f60f2-0802-411a-9228-ce5f47b64c7d', '1.0.0b4.r5', '', '2008-07-17 22:05:00', '1', '100', '3', 'Refer/BibIX', 'Simon Kornblith', 'txt',
+REPLACE INTO translators VALUES ('881f60f2-0802-411a-9228-ce5f47b64c7d', '1.0.0b4.r5', '', '2008-07-24 23:50:00', '1', '100', '3', 'Refer/BibIX', 'Simon Kornblith', 'txt',
'Zotero.configure("dataMode", "line");
-Zotero.addOption("exportCharset", "UTF-8xBOM");
+Zotero.addOption("exportCharset", "UTF-8");
function detectImport() {
var lineRe = /%[A-Z0-9\*\$] .+/;
@@ -25052,7 +31439,7 @@ function doExport() {
}
}');
-REPLACE INTO translators VALUES ('9cb70025-a888-4a29-a210-93ec52da40d4', '1.0.0b4.r1', '', '2008-07-17 22:05:00', '1', '200', '3', 'BibTeX', 'Simon Kornblith', 'bib',
+REPLACE INTO translators VALUES ('9cb70025-a888-4a29-a210-93ec52da40d4', '1.0.0b4.r1', '', '2008-08-06 13:00:00', '1', '200', '3', 'BibTeX', 'Simon Kornblith', 'bib',
'Zotero.configure("dataMode", "block");
Zotero.addOption("exportCharset", "UTF-8");
@@ -25096,6 +31483,7 @@ var fieldMap = {
copyright:"rights",
isbn:"ISBN",
issn:"ISSN",
+ lccn:"callNumber",
location:"archiveLocation",
url:"url",
doi:"DOI",
@@ -26920,6 +33308,8 @@ function buildCiteKey (item,citekeys) {
function doExport() {
//Zotero.write("% BibTeX export generated by Zotero "+Zotero.Utilities.getVersion());
+ // to make sure the BOM gets ignored
+ Zotero.write("\n");
var first = true;
var citekeys = new Object();
@@ -26948,7 +33338,7 @@ function doExport() {
}
if(item.publicationTitle) {
- if(item.itemType == "chapter" || item.itemType == "conferencePaper") {
+ if(item.itemType == "bookSection" || item.itemType == "conferencePaper") {
writeField("booktitle", item.publicationTitle);
} else {
writeField("journal", item.publicationTitle);