www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit ecfff1393f1937bc04da83984fba6ef6745b5f92
parent b6f78acfd8c4462b7919047219446bc8ca9ad362
Author: Simon Kornblith <simon@simonster.com>
Date:   Mon, 11 Sep 2006 01:05:26 +0000

- closes #225, ability to cite a specific page/paragraph/etc in Word integration. the output isn't quite right at the moment, but the interface works.
- removes net icons that haven't been used in months
- fixes another date bug (the last one, i hope)
- renames CSL class to Scholar.CSL


Diffstat:
Achrome/chromeFiles/content/scholar/addCitationDialog.js | 144+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Achrome/chromeFiles/content/scholar/addCitationDialog.xul | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mchrome/chromeFiles/content/scholar/selectItemsDialog.js | 20+++++++++++++++-----
Mchrome/chromeFiles/content/scholar/xpcom/cite.js | 197++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Mchrome/chromeFiles/content/scholar/xpcom/integration.js | 92++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------
Mchrome/chromeFiles/content/scholar/xpcom/scholar.js | 21+++++++++++++++------
Mchrome/chromeFiles/locale/en-US/scholar/locales.xml | 8++++++++
Mchrome/chromeFiles/locale/en-US/scholar/scholar.dtd | 8++++++--
Mchrome/chromeFiles/locale/en-US/scholar/scholar.properties | 7+++++--
Achrome/chromeFiles/skin/default/scholar/addCitationDialog.css | 18++++++++++++++++++
Dchrome/chromeFiles/skin/default/scholar/capture_colored.png | 0
Dchrome/chromeFiles/skin/default/scholar/capture_gray.png | 0
Achrome/chromeFiles/skin/default/scholar/citation-add-gray.png | 0
Achrome/chromeFiles/skin/default/scholar/citation-add.png | 0
Achrome/chromeFiles/skin/default/scholar/citation-delete-gray.png | 0
Achrome/chromeFiles/skin/default/scholar/citation-delete.png | 0
16 files changed, 512 insertions(+), 127 deletions(-)

diff --git a/chrome/chromeFiles/content/scholar/addCitationDialog.js b/chrome/chromeFiles/content/scholar/addCitationDialog.js @@ -0,0 +1,143 @@ +/* + Zotero + Copyright (C) 2006 Center for History and New Media, George Mason University, Fairfax, VA + http://chnm.gmu.edu/ +*/ + +var Scholar_Citation_Dialog = new function () { + var _itemLocators = new Object(); + var _itemLocatorTypes = new Object(); + var _multipleSourcesOn = false; + var _lastSelected = null; + + this.load = load; + this.toggleMultipleSources = toggleMultipleSources; + this.treeItemSelected = treeItemSelected; + this.listItemSelected = listItemSelected; + this.addCitation = addCitation; + this.deleteCitation = deleteCitation; + this.accept = accept; + + function load() { + document.getElementById("multiple-sources-button").label = Scholar.getString("citation.multipleSources"); + + // load (from selectItemsDialog.js) + doLoad(); + } + + function toggleMultipleSources() { + if(_multipleSourcesOn) { + document.getElementById("multiple-sources").hidden = true; + document.getElementById("add-citation-dialog").width = "600"; + document.getElementById("multiple-sources-button").label = Scholar.getString("citation.multipleSources"); + window.sizeToContent(); + window.moveTo((window.screenX+75), window.screenY); + } else { + document.getElementById("multiple-sources").hidden = undefined; + document.getElementById("add-citation-dialog").width = "750"; + document.getElementById("multiple-sources-button").label = Scholar.getString("citation.singleSource"); + window.sizeToContent(); + window.moveTo((window.screenX-75), window.screenY); + } + + _multipleSourcesOn = !_multipleSourcesOn; + } + + function treeItemSelected() { + if(_multipleSourcesOn) { + // get selected item (from selectItemsDialog.js) + var item = getSelectedItems(true); + + // if item has already been added, disable add button + document.getElementById("citation-add").disabled = (!item.length || _itemLocators[item[0]] != undefined ? true : false); + } + } + + function listItemSelected() { + var pagesBox = document.getElementById("item-locator"); + var locatorTypeBox = document.getElementById("item-locator-type"); + if(_lastSelected) { + _itemLocators[_lastSelected.value] = pagesBox.value; + _itemLocatorTypes[_lastSelected.value] = locatorTypeBox.selectedIndex; + } + + var selectedListItem = document.getElementById("citation-list").getSelectedItem(0); + + if(selectedListItem) { + document.getElementById("citation-delete").disabled = pagesBox.disabled = locatorTypeBox.disabled = false; + pagesBox.value = _itemLocators[selectedListItem.value]; + locatorTypeBox.selectedIndex = _itemLocatorTypes[selectedListItem.value]; + } else { + document.getElementById("citation-delete").disabled = pagesBox.disabled = locatorTypeBox.disabled = true; + pagesBox.value = ""; + locatorTypeBox.selectedIndex = -1; + } + + _lastSelected = selectedListItem; + } + + function addCitation() { + // get selected item (from selectItemsDialog.js) + var item = getSelectedItems(); + item = item[0]; + var itemID = item.getID(); + + // add to list + var itemNode = document.createElement("listitem"); + itemNode.setAttribute("value", itemID); + itemNode.setAttribute("label", item.getField("title")); + itemNode.setAttribute("class", "listitem-iconic"); + itemNode.setAttribute("image", "chrome://scholar/skin/treeitem-"+Scholar.ItemTypes.getName(item.getType())+".png"); + document.getElementById("citation-list").appendChild(itemNode); + + // don't let someone select it again + document.getElementById("citation-add").disabled = true; + + // flag + _itemLocators[itemID] = document.getElementById("tree-locator").value; + _itemLocatorTypes[itemID] = document.getElementById("tree-locator-type").selectedIndex; + document.getElementById("tree-locator").value = ""; + } + + function deleteCitation() { + var citationList = document.getElementById("citation-list"); + var selectedListItem = citationList.getSelectedItem(0); + + // remove from _itemLocators + _itemLocators[selectedListItem.value] = _itemLocatorType[selectedListItem.value] = undefined; + + // remove from list + citationList.removeChild(selectedListItem); + } + + function accept() { + var io = window.arguments[0]; + if(_multipleSourcesOn) { + treeItemSelected(); // store locator info + + var citationList = document.getElementById("citation-list"); + var listLength = citationList.childNodes.length; + + if(listLength) { + io.items = new Array(); + io.locatorTypes = new Array(); + io.locators = new Array(); + + for(var i=0; i<listLength; i++) { + var itemID = citationList.childNodes[i].value; + io.items.push(itemID); + io.locatorTypes.push(_itemLocatorTypes[itemID]); + io.locators.push(_itemLocators[itemID]); + } + } + } else { + // get selected item (from selectItemsDialog.js) + io.items = getSelectedItems(true); + + if(io.items.length) { + io.locatorTypes = new Array(document.getElementById("tree-locator-type").selectedItem.value); + io.locators = new Array(document.getElementById("tree-locator").value); + } + } + } +} +\ No newline at end of file diff --git a/chrome/chromeFiles/content/scholar/addCitationDialog.xul b/chrome/chromeFiles/content/scholar/addCitationDialog.xul @@ -0,0 +1,124 @@ +<?xml version="1.0"?> +<!-- + Zotero + Copyright (C) 2006 Center for History and New Media, George Mason University, Fairfax, VA + http://chnm.gmu.edu/ +--> +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> +<?xml-stylesheet href="chrome://scholar/skin/scholar.css" type="text/css"?> +<?xml-stylesheet href="chrome://scholar/skin/overlay.css" type="text/css"?> +<?xml-stylesheet href="chrome://scholar/skin/addCitationDialog.css" type="text/css"?> +<!DOCTYPE window SYSTEM "chrome://scholar/locale/scholar.dtd"> + +<dialog + id="add-citation-dialog" + orient="vertical" + title="Add Citation" + width="600" height="450" + onload="Scholar_Citation_Dialog.load();" + onunload="doUnload();" + ondialogaccept="Scholar_Citation_Dialog.accept();" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + style="padding:2em"> + + <script src="include.js"/> + <script src="selectItemsDialog.js"/> + <script src="addCitationDialog.js"/> + + <hbox flex="1"> + <vbox flex="1"> + <hbox align="center" pack="end"> + <label value="&toolbar.search.label;" control="tb-search"/> + <textbox id="tb-search" type="timed" timeout="250" oncommand="onSearch()" dir="reverse" onkeypress="if(event.keyCode == event.DOM_VK_ESCAPE) { this.value = ''; this.doCommand('cmd_scholar_search'); return false; }"> + <toolbarbutton id="tb-search-cancel" oncommand="this.parentNode.value='';" hidden="true"/> + </textbox> + </hbox> + + <hbox flex="1"> + <tree id="collections-tree" + style="width: 200px;" hidecolumnpicker="true" seltype="single" + onselect="onCollectionSelected();"> + <treecols> + <treecol + id="name_column" + label="&collections.name_column;" + flex="1" + primary="true"/> + </treecols> + <treechildren/> + </tree> + + <tree id="items-tree" + flex="1" hidecolumnpicker="true" seltype="single" + onselect="Scholar_Citation_Dialog.treeItemSelected();"> + <treecols> + <treecol + id="title" primary="true" + label="&items.title_column;" + flex="4" persist="width ordinal hidden sortActive sortDirection"/> + <splitter class="tree-splitter"/> + <treecol + id="firstCreator" + label="&items.creator_column;" + flex="1" persist="width ordinal hidden sortActive sortDirection"/> + <splitter class="tree-splitter"/> + <treecol + id="dateAdded" hidden="true" + label="&items.dateAdded_column;" + flex="1" persist="width ordinal hidden sortActive sortDirection"/> + <splitter class="tree-splitter"/> + <treecol + id="dateModified" hidden="true" + label="&items.dateModified_column;" + flex="1" persist="width ordinal hidden sortActive sortDirection"/> + </treecols> + <treechildren/> + </tree> + </hbox> + + <hbox> + <menulist id="tree-locator-type"> + <menupopup id="tree-locator-type-popup"> + <menuitem value="p" label="&citation.page;" selected="1"/> + <menuitem value="g" label="&citation.paragraph;"/> + <menuitem value="l" label="&citation.line;"/> + </menupopup> + </menulist> + <textbox id="tree-locator" flex="1"/> + </hbox> + </vbox> + + <hbox hidden="true" id="multiple-sources"> + <vbox pack="center"> + <toolbarbutton id="citation-add" oncommand="Scholar_Citation_Dialog.addCitation()" disabled="true"/> + <toolbarbutton id="citation-delete" oncommand="Scholar_Citation_Dialog.deleteCitation()" disabled="true"/> + </vbox> + <vbox> + <listbox id="citation-list" flex="1" seltype="single" + onselect="Scholar_Citation_Dialog.listItemSelected();"></listbox> + <hbox> + <menulist id="item-locator-type" disabled="true"> + <menupopup id="item-locator-type-popup"> + <menuitem value="p" label="&citation.page;"/> + <menuitem value="g" label="&citation.paragraph;"/> + <menuitem value="l" label="&citation.line;"/> + </menupopup> + </menulist> + <textbox id="item-locator"/> + </hbox> + </vbox> + </hbox> + </hbox> + + <hbox> + <vbox> + <button id="multiple-sources-button" oncommand="Scholar_Citation_Dialog.toggleMultipleSources()"/> + </vbox> + <vbox flex="1" align="end"> + <hbox> + <button dlgtype="cancel"/> + <button dlgtype="accept"/> + </hbox> + </vbox> + </hbox> +</dialog> diff --git a/chrome/chromeFiles/content/scholar/selectItemsDialog.js b/chrome/chromeFiles/content/scholar/selectItemsDialog.js @@ -21,7 +21,7 @@ function doLoad() document.getElementById('collections-tree').view = collectionsView; // move to center of screen - window.sizeToContent() + window.sizeToContent(); window.moveTo( (self.screen.width-window.innerWidth)/2, (self.screen.height-window.innerHeight)/2 @@ -67,18 +67,28 @@ function onItemSelected() } -function doAccept() -{ +function getSelectedItems(byID) { var start = new Object(); var end = new Object(); - io.dataOut = new Array(); + var returnArray = new Array(); for(var i = 0, rangeCount = itemsView.selection.getRangeCount(); i < rangeCount; i++) { itemsView.selection.getRangeAt(i,start,end); for(var j = start.value; j <= end.value; j++) { - io.dataOut.push(itemsView._getItemAtRow(j).ref.getID()); + if(byID) { + returnArray.push(itemsView._getItemAtRow(j).ref.getID()); + } else { + returnArray.push(itemsView._getItemAtRow(j).ref); + } } } + + return returnArray; +} + +function doAccept() +{ + io.dataOut = getSelectedItems(true); } \ No newline at end of file diff --git a/chrome/chromeFiles/content/scholar/xpcom/cite.js b/chrome/chromeFiles/content/scholar/xpcom/cite.js @@ -39,7 +39,7 @@ Scholar.Cite = new function() { var style = Scholar.DB.valueQuery(sql, [cslID]); // create a CSL instance - _lastCSL = new CSL(style); + _lastCSL = new Scholar.CSL(style); _lastStyle = cslID; } return _lastCSL; @@ -51,14 +51,14 @@ Scholar.Cite = new function() { * this is abstracted as a separate class for the benefit of anyone who doesn't * want to use the Scholar data model, but does want to use CSL in JavaScript */ -CSL = function(csl) { - this._csl = new XML(CSL._cleanXML(csl)); +Scholar.CSL = function(csl) { + this._csl = new XML(Scholar.CSL._cleanXML(csl)); // initialize CSL - CSL.init(); + Scholar.CSL.init(); // load localizations - this._terms = CSL._parseLocales(this._csl.terms); + this._terms = Scholar.CSL._parseLocales(this._csl.terms); // load class defaults this.class = this._csl["@class"].toString(); @@ -66,8 +66,8 @@ CSL = function(csl) { this._defaults = new Object(); // load class defaults - if(CSL._classDefaults[this.class]) { - var classDefaults = CSL._classDefaults[this.class]; + if(Scholar.CSL._classDefaults[this.class]) { + var classDefaults = Scholar.CSL._classDefaults[this.class]; for(var i in classDefaults) { this._defaults[i] = classDefaults[i]; } @@ -91,7 +91,7 @@ CSL = function(csl) { * must be called prior to generating citations or bibliography with a new set * of items */ -CSL.prototype.preprocessItems = function(items) { +Scholar.CSL.prototype.preprocessItems = function(items) { Scholar.debug("CSL: preprocessing items"); this._ignore = null; @@ -113,7 +113,7 @@ CSL.prototype.preprocessItems = function(items) { item._csl.translators = creators[2]; // parse date - item._csl.date = CSL.prototype._processDate(item.getField("date")); + item._csl.date = Scholar.CSL.prototype._processDate(item.getField("date")); } // clear disambiguation and subsequent author substitute if(item._csl.disambiguation) item._csl.date.disambiguation = undefined; @@ -187,21 +187,36 @@ CSL.prototype.preprocessItems = function(items) { /* * create a citation (in-text or footnote) */ -CSL.prototype.createCitation = function(items, types, locators, format) { - Scholar.debug("CSL: creating citation for item "+items[0].getID()); - - if(types == 2) { - var string = this._getTerm("ibid", (items.length > 1 ? true : false)); +Scholar.CSL.prototype.createCitation = function(citation, format) { + if(citation.citationType == 2) { + var string = this._getTerm("ibid"); string = string[0].toUpperCase()+string.substr(1); } else { var string = ""; - for(var i in items) { + for(var i in citation.itemIDs) { if(this._cit.format && this._cit.format.delimiter && string) { // add delimiter if one exists, and this isn't the first element // with content string += this._cit.format.delimiter; } - string += this._getCitation(items[i], (types[i] == 1 ? "first" : "subsequent"), format, this._cit); + + var locatorType = false; + var locator = false; + if(citation.locators) { + if(citation.locatorTypes[i] == "p") { + locatorType = "page"; + } else if(citation.locatorTypes[i] == "g") { + locatorType = "paragraph"; + } else if(citation.locatorTypes[i] == "l") { + locatorType = "line"; + } + + locator = citation.locators[i]; + } + + string += this._getCitation(Scholar.Items.get(citation.itemIDs[i]), + (citation.citationType[i] == 1 ? "first" : "subsequent"), + locatorType, locator, format, this._cit); } } @@ -223,7 +238,7 @@ CSL.prototype.createCitation = function(items, types, locators, format) { * create a bibliography * (items is expected to be an array of items) */ -CSL.prototype.createBibliography = function(items, format) { +Scholar.CSL.prototype.createBibliography = function(items, format) { // process this._items var output = ""; @@ -245,7 +260,7 @@ CSL.prototype.createBibliography = function(items, format) { for(var i in items) { var item = items[i]; - var string = this._getCitation(item, "first", format, this._bib); + var string = this._getCitation(item, "first", false, false, format, this._bib); if(!string) { continue; } @@ -306,7 +321,7 @@ CSL.prototype.createBibliography = function(items, format) { } // for elements that inherit defaults from each other -CSL._inherit = { +Scholar.CSL._inherit = { author:"contributor", editor:"contributor", translator:"contributor", @@ -318,8 +333,8 @@ CSL._inherit = { edition:"version" } // for class definitions -CSL._classDefaults = new Object(); -CSL._classDefaults["author-date"] = { +Scholar.CSL._classDefaults = new Object(); +Scholar.CSL._classDefaults["author-date"] = { author:{ substitute:[ {name:"editor"}, @@ -332,15 +347,15 @@ CSL._classDefaults["author-date"] = { } }; -CSL.ns = "http://purl.org/net/xbiblio/csl"; +Scholar.CSL.ns = "http://purl.org/net/xbiblio/csl"; /* * initializes CSL interpreter */ -CSL.init = function() { - if(!CSL._xmlLang) { +Scholar.CSL.init = function() { + if(!Scholar.CSL._xmlLang) { // get XML lang - CSL._xmlLang = Scholar.locale; + Scholar.CSL._xmlLang = Scholar.locale; // read locales.xml from directory var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]. @@ -350,61 +365,61 @@ CSL.init = function() { req.send(null); // get default terms - var locales = new XML(CSL._cleanXML(req.responseText)); - CSL._defaultTerms = CSL._parseLocales(locales); + var locales = new XML(Scholar.CSL._cleanXML(req.responseText)); + Scholar.CSL._defaultTerms = Scholar.CSL._parseLocales(locales); } } /* * returns an array of short or long month strings */ -CSL.getMonthStrings = function(form) { - CSL.init(); - return CSL._defaultTerms[form]["_months"]; +Scholar.CSL.getMonthStrings = function(form) { + Scholar.CSL.init(); + return Scholar.CSL._defaultTerms[form]["_months"]; } /* * removes parse instructions from XML */ -CSL._cleanXML = function(xml) { +Scholar.CSL._cleanXML = function(xml) { return xml.replace(/<\?[^>]*\?>/g, ""); } /* - * parses locale strings into CSL._defaultTerms + * parses locale strings into Scholar.CSL._defaultTerms */ -CSL._parseLocales = function(termXML) { +Scholar.CSL._parseLocales = function(termXML) { // return defaults if there are no terms if(!termXML.length()) { - return (CSL._defaultTerms ? CSL._defaultTerms : {}); + return (Scholar.CSL._defaultTerms ? Scholar.CSL._defaultTerms : {}); } var xml = new Namespace("http://www.w3.org/XML/1998/namespace"); // get proper locale - var locale = termXML.locale.(@xml::lang == CSL._xmlLang); + var locale = termXML.locale.(@xml::lang == Scholar.CSL._xmlLang); if(!locale.length()) { - var xmlLang = CSL._xmlLang.substr(0, 2); + var xmlLang = Scholar.CSL._xmlLang.substr(0, 2); locale = termXML.locale.(@xml::lang == xmlLang); } if(!locale.length()) { // return defaults if there are no locales - return (CSL._defaultTerms ? CSL._defaultTerms : {}); + return (Scholar.CSL._defaultTerms ? Scholar.CSL._defaultTerms : {}); } var termArray = new Object(); termArray["default"] = new Object(); - if(CSL._defaultTerms) { + if(Scholar.CSL._defaultTerms) { // ugh. copy default array. javascript dumb. - for(var i in CSL._defaultTerms) { + for(var i in Scholar.CSL._defaultTerms) { termArray[i] = new Object(); - for(var j in CSL._defaultTerms[i]) { - if(typeof(CSL._defaultTerms[i]) == "object") { - termArray[i][j] = [CSL._defaultTerms[i][j][0], - CSL._defaultTerms[i][j][1]]; + for(var j in Scholar.CSL._defaultTerms[i]) { + if(typeof(Scholar.CSL._defaultTerms[i]) == "object") { + termArray[i][j] = [Scholar.CSL._defaultTerms[i][j][0], + Scholar.CSL._defaultTerms[i][j][1]]; } else { - termArray[i][j] = CSL._defaultTerms[i][j]; + termArray[i][j] = Scholar.CSL._defaultTerms[i][j]; } } } @@ -465,7 +480,7 @@ CSL._parseLocales = function(termXML) { /* * parses attributes and children for a CSL field */ -CSL.prototype._parseFieldAttrChildren = function(element, desc, ignoreChildren) { +Scholar.CSL.prototype._parseFieldAttrChildren = function(element, desc, ignoreChildren) { if(!desc) { var desc = new Object(); } @@ -489,7 +504,7 @@ CSL.prototype._parseFieldAttrChildren = function(element, desc, ignoreChildren) // add children to children array for each(var child in children) { - if(child.namespace() == CSL.ns) { // ignore elements in other + if(child.namespace() == Scholar.CSL.ns) { // ignore elements in other // namespaces // parse recursively var name = child.localName(); @@ -501,7 +516,7 @@ CSL.prototype._parseFieldAttrChildren = function(element, desc, ignoreChildren) var chooseChildren = child.choose.children(); for each(var choose in chooseChildren) { - if(choose.namespace() == CSL.ns) { + if(choose.namespace() == Scholar.CSL.ns) { var option = new Object(); option.name = choose.localName(); this._parseFieldAttrChildren(choose, option); @@ -527,9 +542,9 @@ CSL.prototype._parseFieldAttrChildren = function(element, desc, ignoreChildren) /* * parses a list of fields into a defaults associative array */ -CSL.prototype._parseFieldDefaults = function(ref) { +Scholar.CSL.prototype._parseFieldDefaults = function(ref) { for each(var element in ref.children()) { - if(element.namespace() == CSL.ns) { // ignore elements in other namespaces + if(element.namespace() == Scholar.CSL.ns) { // ignore elements in other namespaces var name = element.localName(); Scholar.debug("CSL: parsing field defaults for "+name); var fieldDesc = this._parseFieldAttrChildren(element); @@ -547,10 +562,10 @@ CSL.prototype._parseFieldDefaults = function(ref) { /* * parses a list of fields into an array of objects */ -CSL.prototype._parseFields = function(ref, position, type, bibCitElement, inheritFormat) { +Scholar.CSL.prototype._parseFields = function(ref, position, type, bibCitElement, inheritFormat) { var typeDesc = new Array(); for each(var element in ref) { - if(element.namespace() == CSL.ns) { // ignore elements in other namespaces + if(element.namespace() == Scholar.CSL.ns) { // ignore elements in other namespaces var itemDesc = new Object(); itemDesc.name = element.localName(); @@ -595,7 +610,7 @@ CSL.prototype._parseFields = function(ref, position, type, bibCitElement, inheri /* * parses an et al field */ -CSL.prototype._parseEtAl = function(etAl, bibCitElement) { +Scholar.CSL.prototype._parseEtAl = function(etAl, bibCitElement) { if(etAl.length()) { bibCitElement.etAl = new Object(); @@ -623,7 +638,7 @@ CSL.prototype._parseEtAl = function(etAl, bibCitElement) { * parses cs-format attributes into just a prefix and a suffix; accepts an * optional array of cs-format */ -CSL.prototype._parseBibliographyOptions = function() { +Scholar.CSL.prototype._parseBibliographyOptions = function() { if(!this._csl.bibliography.length()) { return; } @@ -687,7 +702,7 @@ CSL.prototype._parseBibliographyOptions = function() { * parses cs-format attributes into just a prefix and a suffix; accepts an * optional array of cs-format */ -CSL.prototype._parseCitationOptions = function() { +Scholar.CSL.prototype._parseCitationOptions = function() { var citation = this._csl.citation; this._cit = new Object(); @@ -708,7 +723,7 @@ CSL.prototype._parseCitationOptions = function() { * determine available reference types and add their XML objects to the tree * (they will be parsed on the fly when necessary; see _parseReferenceType) */ -CSL.prototype._parseTypes = function(itemElements, bibCitElement) { +Scholar.CSL.prototype._parseTypes = function(itemElements, bibCitElement) { Scholar.debug("CSL: parsing item elements"); bibCitElement._types = new Object(); @@ -749,7 +764,7 @@ CSL.prototype._parseTypes = function(itemElements, bibCitElement) { /* * convert reference types to native structures for speed */ -CSL.prototype._getTypeObject = function(position, reftype, bibCitElement) { +Scholar.CSL.prototype._getTypeObject = function(position, reftype, bibCitElement) { if(!bibCitElement._types[position][reftype]) { // no type available return false; @@ -770,7 +785,7 @@ CSL.prototype._getTypeObject = function(position, reftype, bibCitElement) { /* * merges two elements, letting the second override the first */ -CSL.prototype._merge = function(element1, element2) { +Scholar.CSL.prototype._merge = function(element1, element2) { var mergedElement = new Object(); for(var i in element1) { mergedElement[i] = element1[i]; @@ -785,11 +800,11 @@ CSL.prototype._merge = function(element1, element2) { * gets defaults for a specific element; handles various inheritance rules * (contributor, locator) */ -CSL.prototype._getFieldDefaults = function(elementName) { +Scholar.CSL.prototype._getFieldDefaults = function(elementName) { // first, see if there are specific defaults if(this._defaults[elementName]) { - if(CSL._inherit[elementName]) { - var inheritedDefaults = this._getFieldDefaults(CSL._inherit[elementName]); + if(Scholar.CSL._inherit[elementName]) { + var inheritedDefaults = this._getFieldDefaults(Scholar.CSL._inherit[elementName]); for(var i in inheritedDefaults) { // will only be called if there // is merging necessary return this._merge(inheritedDefaults, this._defaults[elementName]); @@ -798,8 +813,8 @@ CSL.prototype._getFieldDefaults = function(elementName) { return this._defaults[elementName]; } // next, try to get defaults from the item from which this item inherits - if(CSL._inherit[elementName]) { - return this._getFieldDefaults(CSL._inherit[elementName]); + if(Scholar.CSL._inherit[elementName]) { + return this._getFieldDefaults(Scholar.CSL._inherit[elementName]); } // finally, return an empty object return {}; @@ -808,7 +823,7 @@ CSL.prototype._getFieldDefaults = function(elementName) { /* * gets a term, in singular or plural form */ -CSL.prototype._getTerm = function(term, plural, form) { +Scholar.CSL.prototype._getTerm = function(term, plural, form) { if(!form) { form = "long"; } @@ -831,7 +846,7 @@ CSL.prototype._getTerm = function(term, plural, form) { /* * escapes a string for a given format */ -CSL.prototype._escapeString = function(string, format) { +Scholar.CSL.prototype._escapeString = function(string, format) { if(format == "HTML") { // replace HTML entities string = string.replace(/&/g, "&amp;"); @@ -865,7 +880,7 @@ CSL.prototype._escapeString = function(string, format) { /* * formats a string according to the cs-format attributes on element */ -CSL.prototype._formatString = function(element, string, format, dontEscape) { +Scholar.CSL.prototype._formatString = function(element, string, format, dontEscape) { if(!string) return ""; if(typeof(string) != "string") { string = string.toString(); @@ -943,7 +958,7 @@ CSL.prototype._formatString = function(element, string, format, dontEscape) { * formats a locator (pages, volume, issue) or an identifier (isbn, doi) * note that label should be null for an identifier */ -CSL.prototype._formatLocator = function(identifier, element, number, format) { +Scholar.CSL.prototype._formatLocator = function(identifier, element, number, format) { var data = ""; if(number) { @@ -975,7 +990,7 @@ CSL.prototype._formatLocator = function(identifier, element, number, format) { * format the date in format supplied by element from the date object * returned by this._processDate */ -CSL.prototype._formatDate = function(element, date, format) { +Scholar.CSL.prototype._formatDate = function(element, date, format) { if(format == "disambiguate") { // for disambiguation, return only the year return date.year; @@ -1032,7 +1047,7 @@ CSL.prototype._formatDate = function(element, date, format) { * serializes an element into a string suitable to prevent substitutes from * recurring in the same style */ -CSL.prototype._serializeElement = function(name, element) { +Scholar.CSL.prototype._serializeElement = function(name, element) { var string = name; if(element.relation) { string += " relation:"+element.relation; @@ -1046,7 +1061,7 @@ CSL.prototype._serializeElement = function(name, element) { /* * pads a number or other string with a given string on the left */ -CSL.prototype._lpad = function(string, pad, length) { +Scholar.CSL.prototype._lpad = function(string, pad, length) { while(string.length < length) { string = pad + string; } @@ -1056,7 +1071,7 @@ CSL.prototype._lpad = function(string, pad, length) { /* * handles sorting of items */ -CSL.prototype._compareItem = function(a, b, opt) { +Scholar.CSL.prototype._compareItem = function(a, b, opt) { for(var i in this._bib.sortOrder) { var sortElement = this._bib.sortOrder[i]; @@ -1079,7 +1094,7 @@ CSL.prototype._compareItem = function(a, b, opt) { * process creator objects; if someone had a creator model that handled * non-Western names better than ours, this would be the function to change */ -CSL.prototype._processCreators = function(type, element, creators, format, bibCitElement) { +Scholar.CSL.prototype._processCreators = function(type, element, creators, format, bibCitElement) { var maxCreators = creators.length; if(!maxCreators) return; @@ -1186,7 +1201,7 @@ CSL.prototype._processCreators = function(type, element, creators, format, bibCi /* * get a citation, given an item and bibCitElement */ -CSL.prototype._getCitation = function(item, position, format, bibCitElement) { +Scholar.CSL.prototype._getCitation = function(item, position, locatorType, locator, format, bibCitElement) { Scholar.debug("CSL: generating citation for item "+item.getID()); if(!bibCitElement._types[position]) { @@ -1218,7 +1233,8 @@ CSL.prototype._getCitation = function(item, position, format, bibCitElement) { var string = ""; for(var j in type) { var value = this._getFieldValue(type[j].name, type[j], item, format, - bibCitElement, position, typeName); + bibCitElement, position, locatorType, + locator, typeName); string += value; } @@ -1228,7 +1244,9 @@ CSL.prototype._getCitation = function(item, position, format, bibCitElement) { /* * processes an element from a (pre-processed) item into text */ -CSL.prototype._getFieldValue = function(name, element, item, format, bibCitElement, position, typeName) { +Scholar.CSL.prototype._getFieldValue = function(name, element, item, format, + bibCitElement, position, + locatorType, locator, typeName) { var data = ""; var itemID = item.getID(); @@ -1325,11 +1343,18 @@ CSL.prototype._getFieldValue = function(name, element, item, format, bibCitEleme data = this._formatLocator(name, element, field, format); } } else if(name == "pages") { - if(typeName != "book") { + if(locatorType == "page") { + var field = locator; + } else if(typeName != "book") { var field = item.getField("pages"); - if(field) { - data = this._formatLocator("page", element, field, format); - } + } + + if(field) { + data = this._formatLocator("page", element, field, format); + } + } else if(name == "locator") { + if(locator) { + data = this._formatLocator(locatorType, element, locator, format); } } else if(name == "edition") { data = item.getField("edition"); @@ -1379,8 +1404,8 @@ CSL.prototype._getFieldValue = function(name, element, item, format, bibCitEleme substituteElement); var inheritElement; - if(CSL._inherit[substituteElement.name] && CSL._inherit[name] - && CSL._inherit[substituteElement.name] == CSL._inherit[name]) { + if(Scholar.CSL._inherit[substituteElement.name] && Scholar.CSL._inherit[name] + && Scholar.CSL._inherit[substituteElement.name] == Scholar.CSL._inherit[name]) { // if both substituteElement and the parent element inherit from // the same base element, apply styles here inheritElement = element; @@ -1431,7 +1456,7 @@ CSL.prototype._getFieldValue = function(name, element, item, format, bibCitEleme * THE FOLLOWING CODE IS SCHOLAR-SPECIFIC * gets a list of possible CSL types, in order of preference, for an item */ - CSL._optionalTypeMappings = { + Scholar.CSL._optionalTypeMappings = { journalArticle:"article-journal", magazineArticle:"article-magazine", newspaperArticle:"article-newspaper", @@ -1444,7 +1469,7 @@ CSL.prototype._getFieldValue = function(name, element, item, format, bibCitEleme website:"webpage" }; // TODO: check with Elena/APA/MLA on this -CSL._fallbackTypeMappings = { +Scholar.CSL._fallbackTypeMappings = { book:"book", bookSection:"chapter", journalArticle:"article", @@ -1459,18 +1484,18 @@ CSL._fallbackTypeMappings = { website:"article" }; -CSL.prototype._getTypeFromItem = function(item) { +Scholar.CSL.prototype._getTypeFromItem = function(item) { var scholarType = Scholar.ItemTypes.getName(item.getType()); // get type Scholar.debug("CSL: parsing item of Scholar type "+scholarType); - return [CSL._optionalTypeMappings[scholarType], CSL._fallbackTypeMappings[scholarType]]; + return [Scholar.CSL._optionalTypeMappings[scholarType], Scholar.CSL._fallbackTypeMappings[scholarType]]; } /* * separate creators object into authors, editors, and translators */ -CSL.prototype._separateItemCreators = function(item) { +Scholar.CSL.prototype._separateItemCreators = function(item) { var authors = new Array(); var editors = new Array(); var translators = new Array(); @@ -1499,7 +1524,7 @@ CSL.prototype._separateItemCreators = function(item) { /* * return an object containing year, month, and day */ -CSL.prototype._processDate = function(string) { +Scholar.CSL.prototype._processDate = function(string) { return Scholar.Date.strToDate(string); } /* diff --git a/chrome/chromeFiles/content/scholar/xpcom/integration.js b/chrome/chromeFiles/content/scholar/xpcom/integration.js @@ -365,18 +365,18 @@ Scholar.Integration.SOAP = new function() { for(var i=3; i<vars.length; i+=2) { if(vars[i+1] == "X") { // get a new citation for a field with an X - var io = {dataIn: null, dataOut: null}; - window.openDialog('chrome://scholar/content/selectItemsDialog.xul','', + var io = new Object(); + window.openDialog('chrome://scholar/content/addCitationDialog.xul','', 'chrome,popup,modal', io, true); + + citation = new Scholar.Integration.Citation(vars[i], "!"); + updatedCitations[citation.index] = true; - if(io.dataOut) { // cancel was not pressed - citation = new Scholar.Integration.Citation(vars[i], - io.dataOut.join(",")+"_"+Scholar.randomString()); - updatedCitations[citation.index] = true; + if(io.items) { // cancel was not pressed + citation.setData(io.items, io.locators, io.locatorTypes); + citation.regenerateFieldName(); citation.updateField = true; } else { // cancel pressed - citation = new Scholar.Integration.Citation(vars[i], "!"); - updatedCitations[citation.index] = true; citation.deleteCitation = true; continue; } @@ -416,9 +416,9 @@ Scholar.Integration.SOAP = new function() { } } - if(isDuplicate || citation.field == "X") { + if(isDuplicate) { // generate a new field name for duplicated fields - citation.field = itemIDString+"_"+Scholar.randomString(); + citation.regenerateFieldName(); updatedCitations[citation.index] = true; citation.updateField = true; } @@ -554,16 +554,55 @@ Scholar.Integration.Citation = function(index, field) { this.itemIDString = field.substr(0, underscoreIndex); var lastIndex = field.lastIndexOf("_"); - if(lastIndex != underscoreIndex) { - this.locators = field.substr(underscoreIndex+1, lastIndex-underscoreIndex-1).split(","); + if(lastIndex != underscoreIndex+1) { + this.locatorString = field.substr(underscoreIndex+1, lastIndex-underscoreIndex-1); } else { - this.locators = false; + this.locatorString = false; } - this.itemIDs = this.itemIDString.split(","); - } - if(field != "_") { + this.serialization = this.itemIDString+"_"+this.locatorString; + this.itemIDs = this.itemIDString.split("|"); + } +} +/* + * generates a new field name based on available information + */ +Scholar.Integration.Citation.prototype.regenerateFieldName = function() { + this.field = this.itemIDString+"_"+this.locatorString+"_"+Scholar.randomString(); +} + +/* + * updates itemIDString and locatorString based on data + */ +Scholar.Integration.Citation.prototype.setData = function(itemIDs, locators, locatorTypes) { + this.itemIDs = itemIDs; + this.itemIDString = itemIDs.join("|"); + + this.locators = locators; + this.locatorTypes = locatorTypes; + + this.locatorString = ""; + for(var i in locators) { + this.locatorString += locatorTypes[i]+locators[i].replace("|", ""); + } + + this.serialization = this.itemIDString+"_"+this.locatorString; +} + +/* + * loads locators from locatorString, if not already loaded + */ +Scholar.Integration.Citation.prototype.loadLocators = function() { + if(this.locators) return; + + this.locators = new Array(); + this.locatorTypes = new Array(); + + var locators = this.locatorString.split("|"); + for each(var locator in locators) { + this.locatorTypes.push(locator[0]); + this.locators.push(locator.substr(1)); } } @@ -701,17 +740,17 @@ Scholar.Integration.CitationFactory.prototype.updateItems = function(citationSet for each(var citation in citationSet.citationsByID[itemID]) { updateCitations[citation.index] = true; citation.updateText = true; - this.cache[citation.itemIDString] = null; + this.cache[citation.serialization] = null; } } else if(updateCheck[itemID]) { // check against cache to see if updated item has changed for each(var citation in citationSet.citationsByID[itemID]) { - if(this.cache[citation.itemIDString][citation.serializedType]) { + if(this.cache[citation.serializedType][citation.serialization]) { var citationText = this.getCitation(citation, tempCache); - if(citationText != this.cache[citation.itemIDString][citation.serializedType]) { + if(citationText != this.cache[citation.serializedType][citation.serialization]) { updateCitations[citation.index] = true; citation.updateText = true; - this.cache[citation.itemIDString][citation.serializedType] = citationText; + this.cache[citation.serializedType][citation.serialization] = citationText; } } } @@ -725,16 +764,17 @@ Scholar.Integration.CitationFactory.prototype.updateItems = function(citationSet Scholar.Integration.CitationFactory.prototype.getCitation = function(citation, usingCache) { if(!usingCache) usingCache = this.cache; - if(usingCache[citation.itemIDString] && usingCache[citation.itemIDString][citation.serializedType]) { - return usingCache[citation.itemIDString][citation.serializedType]; + if(usingCache[citation.serializedType] && usingCache[citation.serializedType][citation.serialization]) { + return usingCache[citation.serializedType][citation.serialization]; } - var citationText = this.style.createCitation(Scholar.Items.get(citation.itemIDs), citation.citationType, citation.locators, "Integration"); + citation.loadLocators(); + var citationText = this.style.createCitation(citation, "Integration"); - if(!usingCache[citation.itemIDString]) { - usingCache[citation.itemIDString] = new Object(); + if(!usingCache[citation.serializedType]) { + usingCache[citation.serializedType] = new Object(); } - usingCache[citation.itemIDString][citation.serializedType] = citationText; + usingCache[citation.serializedType][citation.serialization] = citationText; return citationText; } diff --git a/chrome/chromeFiles/content/scholar/xpcom/scholar.js b/chrome/chromeFiles/content/scholar/xpcom/scholar.js @@ -746,7 +746,7 @@ Scholar.Date = new function(){ // get short month strings from CSL interpreter if(!months) { - var months = CSL.getMonthStrings("short"); + var months = Scholar.CSL.getMonthStrings("short"); } if(!_monthRe) { // then, see if have anything resembling a month anywhere @@ -762,12 +762,21 @@ Scholar.Date = new function(){ // then, see if there's a day if(!_dayRe) { var daySuffixes = Scholar.getString("date.daySuffixes").replace(/, ?/g, "|"); - _dayRe = new RegExp("^(.*)\\b([0-9]{1,2})(?:"+daySuffixes+")?\\b(.*)$", "i"); + _dayRe = new RegExp("\\b([0-9]{1,2})(?:"+daySuffixes+")?\\b(.*)", "i"); } var m = _dayRe.exec(date.part); if(m) { - date.day = parseInt(m[2], 10); - date.part = m[1]+m[3]; + date.day = parseInt(m[1], 10); + + if(m.index > 0) { + date.part = date.part.substr(0, m.index); + if(m[2]) { + date.part += " "+m[2];; + } + } else { + date.part = m[2]; + } + Scholar.debug("DATE: got day ("+date.day+", "+date.part+")"); } } @@ -794,11 +803,11 @@ Scholar.Date = new function(){ } if(!months) { - var months = CSL.getMonthStrings("short"); + var months = Scholar.CSL.getMonthStrings("short"); } if(date.month != undefined && months[date.month]) { // get short month strings from CSL interpreter - var months = CSL.getMonthStrings("long"); + var months = Scholar.CSL.getMonthStrings("long"); string += months[date.month]; if(date.day) { string += " "+date.day+", "; diff --git a/chrome/chromeFiles/locale/en-US/scholar/locales.xml b/chrome/chromeFiles/locale/en-US/scholar/locales.xml @@ -19,6 +19,10 @@ <single>paragraph</single> <multiple>paragraph</multiple> </term> + <term name="line"> + <single>line</single> + <multiple>line</multiple> + </term> <term name="volume">volume</term> <term name="issue">number</term> @@ -31,6 +35,10 @@ <single>¶</single> <multiple>¶¶</multiple> </term> + <term name="line" form="short"> + <single>line</single> + <multiple>line</multiple> + </term> <term name="volume" form="short">vol</term> <term name="issue" form="short">no</term> diff --git a/chrome/chromeFiles/locale/en-US/scholar/scholar.dtd b/chrome/chromeFiles/locale/en-US/scholar/scholar.dtd @@ -70,4 +70,8 @@ <!ENTITY search.match "Match"> <!ENTITY search.any "any"> <!ENTITY search.all "all"> -<!ENTITY search.following "of the following"> -\ No newline at end of file +<!ENTITY search.following "of the following"> + +<!ENTITY citation.page "Page"> +<!ENTITY citation.paragraph "Paragraph"> +<!ENTITY citation.line "Line"> +\ No newline at end of file diff --git a/chrome/chromeFiles/locale/en-US/scholar/scholar.properties b/chrome/chromeFiles/locale/en-US/scholar/scholar.properties @@ -131,4 +131,7 @@ searchConditions.dateModified = Date Modified exportOptions.exportNotes = Export Notes exportOptions.exportFileData = Export Files -date.daySuffixes = st, nd, rd, th -\ No newline at end of file +date.daySuffixes = st, nd, rd, th + +citation.multipleSources = Multiple Sources... +citation.singleSource = Single Source... +\ No newline at end of file diff --git a/chrome/chromeFiles/skin/default/scholar/addCitationDialog.css b/chrome/chromeFiles/skin/default/scholar/addCitationDialog.css @@ -0,0 +1,17 @@ +#citation-add { + list-style-image: url('chrome://scholar/skin/citation-add.png'); +} +#citation-add[disabled="true"] { + list-style-image: url('chrome://scholar/skin/citation-add-gray.png'); +} + +#citation-delete { + list-style-image: url('chrome://scholar/skin/citation-delete.png'); +} +#citation-delete[disabled="true"] { + list-style-image: url('chrome://scholar/skin/citation-delete-gray.png'); +} + +#item-locator { + max-width:100px; +} +\ No newline at end of file diff --git a/chrome/chromeFiles/skin/default/scholar/capture_colored.png b/chrome/chromeFiles/skin/default/scholar/capture_colored.png Binary files differ. diff --git a/chrome/chromeFiles/skin/default/scholar/capture_gray.png b/chrome/chromeFiles/skin/default/scholar/capture_gray.png Binary files differ. diff --git a/chrome/chromeFiles/skin/default/scholar/citation-add-gray.png b/chrome/chromeFiles/skin/default/scholar/citation-add-gray.png Binary files differ. diff --git a/chrome/chromeFiles/skin/default/scholar/citation-add.png b/chrome/chromeFiles/skin/default/scholar/citation-add.png Binary files differ. diff --git a/chrome/chromeFiles/skin/default/scholar/citation-delete-gray.png b/chrome/chromeFiles/skin/default/scholar/citation-delete-gray.png Binary files differ. diff --git a/chrome/chromeFiles/skin/default/scholar/citation-delete.png b/chrome/chromeFiles/skin/default/scholar/citation-delete.png Binary files differ.