Add a version of citation dialog for citing notes

This commit is contained in:
Adomas Venčkauskas 2021-02-08 13:02:09 +02:00 committed by Dan Stillman
parent 7b794cecd7
commit 0fc9037a54
13 changed files with 392 additions and 259 deletions

View file

@ -4,7 +4,7 @@ html > body {
} }
body { body {
line-height: 1.45em; line-height: 1.6em;
font-size: 15px; font-size: 15px;
} }
@ -12,45 +12,42 @@ body[multiline="true"] {
line-height: 26px; line-height: 26px;
} }
#quick-format-dialog { window.citation-dialog {
background: transparent; background: transparent;
-moz-appearance: none; -moz-appearance: none;
padding: 0; padding: 0;
width: 800px; width: 800px;
} }
#quick-format-dialog.progress-bar #quick-format-deck { .citation-dialog.progress-bar .citation-dialog.deck {
height: 37px; height: 32px;
} }
#quick-format-search { .citation-dialog.search {
background: white; background: white;
-moz-appearance: searchfield; padding: 2px 2px 0 2px;
}
#quick-format-search[multiline="true"] {
padding: 2px 2px 0 19.5px;
margin: 2.5px 3.5px; margin: 2.5px 3.5px;
border: 1px solid rgba(0, 0, 0, 0.5); border: 1px solid rgba(0, 0, 0, 0.5);
-moz-appearance: none; -moz-appearance: none;
border-radius: 10px;
} }
#quick-format-search:not([multiline="true"]) { .citation-dialog.search:not([multiline="true"]) {
padding-top: 3.5px; height: 32px !important;
height: 37px !important;
} }
#quick-format-entry { .citation-dialog.entry {
background: -moz-linear-gradient(-90deg, rgb(243,123,119) 0, rgb(180,47,38) 50%, rgb(156,36,27) 50%); background: -moz-linear-gradient(-90deg, rgb(243,123,119) 0, rgb(180,47,38) 50%, rgb(156,36,27) 50%);
padding: 12px; padding: 12px;
} }
#zotero-icon { .note-dialog .citation-dialog.entry {
margin: -2px 0 3px -6px; background: -moz-linear-gradient(-90deg, rgb(249, 231, 179) 0, rgb(228, 193, 94) 50%, rgb(221, 184, 81) 50%);
} }
#quick-format-search[multiline="true"] #zotero-icon { #zotero-icon {
margin: 0 0 1px -13px; margin: -1px 0 0 4px;
-moz-appearance: none;
} }
#citation-properties menulist { #citation-properties menulist {
@ -106,7 +103,6 @@ panel button:-moz-focusring {
box-shadow: 0 0 1px -moz-mac-focusring inset, 0 0 4px 1px -moz-mac-focusring, 0 0 2px 1px -moz-mac-focusring; box-shadow: 0 0 1px -moz-mac-focusring inset, 0 0 4px 1px -moz-mac-focusring, 0 0 2px 1px -moz-mac-focusring;
} }
.quick-format-bubble { .citation-dialog.bubble {
margin-top: 0;
padding: 1px 6px 1px 6px; padding: 1px 6px 1px 6px;
} }

View file

@ -2,18 +2,18 @@ body {
line-height: 1.5em; line-height: 1.5em;
} }
#quick-format-search:not([multiline="true"]) { .citation-dialog.search:not([multiline="true"]) {
height: 29px !important; height: 29px !important;
} }
#quick-format-search { .citation-dialog.search {
background: white; background: white;
padding: 0 2px 0 0; padding: 0 2px 0 0;
border: 1px solid rgba(0, 0, 0, 0.5); border: 1px solid rgba(0, 0, 0, 0.5);
-moz-appearance: textfield; -moz-appearance: textfield;
} }
#quick-format-dialog { window.citation-dialog {
-moz-appearance: none; -moz-appearance: none;
padding: 5px; padding: 5px;
} }

View file

@ -1,9 +1,10 @@
#quick-format-dialog { window.citation-dialog {
background: transparent; background: transparent;
padding: 0; padding: 0;
-moz-appearance: none;
} }
#quick-format-search { .citation-dialog.search {
background: white; background: white;
padding: 2px 2px 2px 0; padding: 2px 2px 2px 0;
border: 1px solid rgba(0, 0, 0, 0.5); border: 1px solid rgba(0, 0, 0, 0.5);
@ -11,22 +12,20 @@
-moz-appearance: none; -moz-appearance: none;
} }
#quick-format-dialog { .citation-dialog.search:not([multiline="true"]) {
background: transparent;
-moz-appearance: none;
padding: 0;
}
#quick-format-search:not([multiline="true"]) {
height: 28px !important; height: 28px !important;
} }
#quick-format-entry { .citation-dialog.entry {
background: -moz-linear-gradient(-90deg, rgb(243,123,119) 0, rgb(180,47,38) 50%, rgb(156,36,27) 50%); background: -moz-linear-gradient(-90deg, rgb(243,123,119) 0, rgb(180,47,38) 50%, rgb(156,36,27) 50%);
padding: 10px; padding: 10px;
} }
#quick-format-entry:not([square="true"]) { .note-dialog .citation-dialog.entry {
background: -moz-linear-gradient(-90deg, rgb(249, 231, 179) 0, rgb(228, 193, 94) 50%, rgb(221, 184, 81) 50%);
}
.citation-dialog.entry:not([square="true"]) {
-moz-border-radius: 15px; -moz-border-radius: 15px;
border-radius: 15px; border-radius: 15px;
} }

View file

@ -0,0 +1,31 @@
/*
***** BEGIN LICENSE BLOCK *****
Copyright © 2021 Center for History and New Media
George Mason University, Fairfax, Virginia, USA
http://zotero.org
This file is part of Zotero.
Zotero is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Zotero is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
***** END LICENSE BLOCK *****
*/
var defaultBubbleizeSelected = Zotero_QuickFormat._bubbleizeSelected;
Zotero_QuickFormat.citingNotes = true;
Zotero_QuickFormat._bubbleizeSelected = async function () {
await defaultBubbleizeSelected();
await Zotero_QuickFormat._accept();
}

View file

@ -0,0 +1,67 @@
<?xml version="1.0"?>
<!--
***** BEGIN LICENSE BLOCK *****
Copyright © 2021 Center for History and New Media
George Mason University, Fairfax, Virginia, USA
http://zotero.org
This file is part of Zotero.
Zotero is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Zotero is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
***** END LICENSE BLOCK *****
-->
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://global/skin/browser.css" type="text/css"?>
<?xml-stylesheet href="chrome://zotero/skin/zotero.css" type="text/css"?>
<?xml-stylesheet href="chrome://zotero/skin/integration.css" type="text/css"?>
<?xml-stylesheet href="chrome://zotero-platform/content/integration.css" type="text/css"?>
<!DOCTYPE window SYSTEM "chrome://zotero/locale/zotero.dtd">
<window
id="insert-note-dialog"
class="citation-dialog note-dialog"
orient="vertical"
title="&zotero.integration.quickFormatDialog.title;"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
persist="screenX screenY"
onkeypress="Zotero_QuickFormat.onKeyPress(event)"
onunload="Zotero_QuickFormat.onUnload()">
<script src="../include.js"/>
<script src="windowDraggingUtils.js" type="text/javascript"/>
<script src="quickFormat.js" type="text/javascript"/>
<script src="insertNoteDialog.js" type="text/javascript"/>
<box orient="horizontal" class="citation-dialog entry">
<deck class="citation-dialog deck" selectedIndex="0" flex="1">
<hbox class="citation-dialog search" flex="1" align="start">
<hbox flex="1">
<iframe class="citation-dialog iframe" ondragstart="event.stopPropagation()" src="data:application/xhtml+xml,%3C!DOCTYPE%20html%20PUBLIC%20%22-//W3C//DTD%20XHTML%201.0%20Strict//EN%22%20%22http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd%22%3E%3Chtml%20xmlns=%22http://www.w3.org/1999/xhtml%22%3E%3Chead%3E%3Clink%20rel=%22stylesheet%22%20type=%22text/css%22%20href=%22chrome://zotero/skin/integration.css%22/%3E%3Clink%20rel=%22stylesheet%22%20type=%22text/css%22%20href=%22chrome://zotero-platform/content/integration.css%22/%3E%3C/head%3E%3Cbody%20contenteditable=%22true%22%20spellcheck=%22false%22%20class=%22citation-dialog%20editor%22/%3E%3C/html%3E"
tabindex="1" flex="1"/>
<vbox class="citation-dialog spinner" style="visibility: hidden">
<image class="zotero-spinner-16"/>
</vbox>
</hbox>
</hbox>
<progressmeter class="citation-dialog progress-meter" mode="undetermined" value="0" flex="1"/>
</deck>
</box>
<panel class="citation-dialog reference-panel" noautofocus="true" norestorefocus="true"
height="0" width="0">
<richlistbox class="citation-dialog reference-list" flex="1"/>
</panel>
</window>

View file

@ -38,6 +38,10 @@ var Zotero_ProgressBar = new function () {
io.onLoad(_onProgress); io.onLoad(_onProgress);
} }
if (io.isNote) {
document.documentElement.classList.add('note-dialog');
}
// Only hide chrome on Windows or Mac // Only hide chrome on Windows or Mac
if(Zotero.isMac) { if(Zotero.isMac) {
document.documentElement.setAttribute("drawintitlebar", true); document.documentElement.setAttribute("drawintitlebar", true);
@ -45,12 +49,12 @@ var Zotero_ProgressBar = new function () {
document.documentElement.setAttribute("hidechrome", true); document.documentElement.setAttribute("hidechrome", true);
} }
new WindowDraggingElement(document.getElementById("quick-format-dialog"), window); new WindowDraggingElement(document.querySelector(".citation-dialog"), window);
// With fx60 and drawintitlebar=true Firefox calculates the minHeight // With fx60 and drawintitlebar=true Firefox calculates the minHeight
// as titlebar+maincontent, so we have hack around that here. // as titlebar+maincontent, so we have hack around that here.
if (Zotero.isMac && Zotero.platformMajorVersion >= 60) { if (Zotero.isMac && Zotero.platformMajorVersion >= 60) {
document.getElementById("quick-format-entry").style.marginBottom = "-22px"; document.querySelector(".citation-dialog.entry").style.marginBottom = "-22px";
} }
} }
@ -75,7 +79,7 @@ var Zotero_ProgressBar = new function () {
* Called when progress changes * Called when progress changes
*/ */
function _onProgress(percent) { function _onProgress(percent) {
var meter = document.getElementById("quick-format-progress-meter"); var meter = document.querySelector(".citation-dialog.progress-meter");
if(percent === null) { if(percent === null) {
meter.mode = "undetermined"; meter.mode = "undetermined";
} else { } else {

View file

@ -31,8 +31,8 @@
<!DOCTYPE window SYSTEM "chrome://zotero/locale/zotero.dtd"> <!DOCTYPE window SYSTEM "chrome://zotero/locale/zotero.dtd">
<window <window
id="quick-format-dialog" id="progress-bar"
class="progress-bar" class="citation-dialog progress-bar"
orient="vertical" orient="vertical"
title="&zotero.progress.title;" title="&zotero.progress.title;"
xmlns:html="http://www.w3.org/1999/xhtml" xmlns:html="http://www.w3.org/1999/xhtml"
@ -43,9 +43,9 @@
<script src="windowDraggingUtils.js" type="text/javascript"/> <script src="windowDraggingUtils.js" type="text/javascript"/>
<script src="progressBar.js" type="text/javascript"/> <script src="progressBar.js" type="text/javascript"/>
<box orient="horizontal" id="quick-format-entry"> <box orient="horizontal" class="citation-dialog entry">
<deck id="quick-format-deck" selectedIndex="0" flex="1"> <deck class="citation-dialog deck" selectedIndex="0" flex="1">
<progressmeter id="quick-format-progress-meter" mode="undetermined" value="0" flex="1"/> <progressmeter class="citation-dialog progress-meter" mode="undetermined" value="0" flex="1"/>
</deck> </deck>
</box> </box>
</window> </window>

View file

@ -34,7 +34,7 @@ var Zotero_QuickFormat = new function () {
const numRe = /^[0-9\-]+$/; const numRe = /^[0-9\-]+$/;
var initialized, io, qfs, qfi, qfiWindow, qfiDocument, qfe, qfb, qfbHeight, qfGuidance, var initialized, io, qfs, qfi, qfiWindow, qfiDocument, qfe, qfb, qfbHeight, qfGuidance,
keepSorted, showEditor, referencePanel, referenceBox, referenceHeight = 0, keepSorted, showEditor, referencePanel, referenceBox, referenceHeight = 0,
separatorHeight = 0, currentLocator, currentLocatorLabel, currentSearchTime, dragging, separatorHeight = 0, currentLocator, currentLocatorLabel, currentSearchTime, dragging,
panel, panelPrefix, panelSuffix, panelSuppressAuthor, panelLocatorLabel, panelLocator, panel, panelPrefix, panelSuffix, panelSuppressAuthor, panelLocatorLabel, panelLocator,
panelLibraryLink, panelInfo, panelRefersToBubble, panelFrameHeight = 0, accepted = false; panelLibraryLink, panelInfo, panelRefersToBubble, panelFrameHeight = 0, accepted = false;
@ -69,18 +69,18 @@ var Zotero_QuickFormat = new function () {
// Include a different key combo in message on Mac // Include a different key combo in message on Mac
if(Zotero.isMac) { if(Zotero.isMac) {
var qf = document.getElementById('quick-format-guidance'); var qf = document.querySelector('.citation-dialog.guidance');
qf.setAttribute('about', qf.getAttribute('about') + "Mac"); qf && qf.setAttribute('about', qf.getAttribute('about') + "Mac");
} }
new WindowDraggingElement(document.getElementById("quick-format-dialog"), window); new WindowDraggingElement(document.querySelector("window.citation-dialog"), window);
qfs = document.getElementById("quick-format-search"); qfs = document.querySelector(".citation-dialog.search");
qfi = document.getElementById("quick-format-iframe"); qfi = document.querySelector(".citation-dialog.iframe");
qfb = document.getElementById("quick-format-entry"); qfb = document.querySelector(".citation-dialog.entry");
qfbHeight = qfb.scrollHeight; qfbHeight = qfb.scrollHeight;
referencePanel = document.getElementById("quick-format-reference-panel"); referencePanel = document.querySelector(".citation-dialog.reference-panel");
referenceBox = document.getElementById("quick-format-reference-list"); referenceBox = document.querySelector(".citation-dialog.reference-list");
if (Zotero.isWin) { if (Zotero.isWin) {
referencePanel.style.marginTop = "-29px"; referencePanel.style.marginTop = "-29px";
@ -95,24 +95,9 @@ var Zotero_QuickFormat = new function () {
qfb.style.marginBottom = "-28px"; qfb.style.marginBottom = "-28px";
} }
// add labels to popup
var locators = Zotero.Cite.labels;
var menu = document.getElementById("locator-label");
var labelList = document.getElementById("locator-label-popup");
for(var locator of locators) {
var locatorLabel = Zotero.getString('citation.locator.'+locator.replace(/\s/g,''));
// add to list of labels
var child = document.createElement("menuitem");
child.setAttribute("value", locator);
child.setAttribute("label", locatorLabel);
labelList.appendChild(child);
}
menu.selectedIndex = 0;
keepSorted = document.getElementById("keep-sorted"); keepSorted = document.getElementById("keep-sorted");
showEditor = document.getElementById("show-editor"); showEditor = document.getElementById("show-editor");
if(io.sortable) { if(keepSorted && io.sortable) {
keepSorted.hidden = false; keepSorted.hidden = false;
if(!io.citation.properties.unsorted) { if(!io.citation.properties.unsorted) {
keepSorted.setAttribute("checked", "true"); keepSorted.setAttribute("checked", "true");
@ -121,13 +106,31 @@ var Zotero_QuickFormat = new function () {
// Nodes for citation properties panel // Nodes for citation properties panel
panel = document.getElementById("citation-properties"); panel = document.getElementById("citation-properties");
panelPrefix = document.getElementById("prefix"); if (panel) {
panelSuffix = document.getElementById("suffix"); panelPrefix = document.getElementById("prefix");
panelSuppressAuthor = document.getElementById("suppress-author"); panelSuffix = document.getElementById("suffix");
panelLocatorLabel = document.getElementById("locator-label"); panelSuppressAuthor = document.getElementById("suppress-author");
panelLocator = document.getElementById("locator"); panelLocatorLabel = document.getElementById("locator-label");
panelInfo = document.getElementById("citation-properties-info"); panelLocator = document.getElementById("locator");
panelLibraryLink = document.getElementById("citation-properties-library-link"); panelInfo = document.getElementById("citation-properties-info");
panelLibraryLink = document.getElementById("citation-properties-library-link");
// add labels to popup
var locators = Zotero.Cite.labels;
var menu = document.getElementById("locator-label");
var labelList = document.getElementById("locator-label-popup");
for(var locator of locators) {
var locatorLabel = Zotero.getString('citation.locator.'+locator.replace(/\s/g,''));
// add to list of labels
var child = document.createElement("menuitem");
child.setAttribute("value", locator);
child.setAttribute("label", locatorLabel);
labelList.appendChild(child);
}
menu.selectedIndex = 0;
}
// Don't need to set noautohide dynamically on these platforms, so do it now // Don't need to set noautohide dynamically on these platforms, so do it now
if(Zotero.isMac || Zotero.isWin) { if(Zotero.isMac || Zotero.isWin) {
@ -138,9 +141,12 @@ var Zotero_QuickFormat = new function () {
qfiDocument = qfi.contentDocument; qfiDocument = qfi.contentDocument;
qfb.addEventListener("click", _onQuickSearchClick, false); qfb.addEventListener("click", _onQuickSearchClick, false);
qfb.addEventListener("keypress", _onQuickSearchKeyPress, false); qfb.addEventListener("keypress", _onQuickSearchKeyPress, false);
qfe = qfiDocument.getElementById("quick-format-editor"); qfe = qfiDocument.querySelector(".citation-dialog.editor");
qfe.addEventListener("drop", _onBubbleDrop, false); qfe.addEventListener("drop", _onBubbleDrop, false);
qfe.addEventListener("paste", _onPaste, false); qfe.addEventListener("paste", _onPaste, false);
if (Zotero_QuickFormat.citingNotes) {
_quickFormat();
}
} }
} }
@ -164,8 +170,8 @@ var Zotero_QuickFormat = new function () {
Zotero.debug(`Moving window to ${targetX}, ${targetY}`); Zotero.debug(`Moving window to ${targetX}, ${targetY}`);
window.moveTo(targetX, targetY); window.moveTo(targetX, targetY);
} }
qfGuidance = document.getElementById('quick-format-guidance'); qfGuidance = document.querySelector('.citation-dialog.guidance');
qfGuidance.show(); qfGuidance && qfGuidance.show();
_refocusQfe(); _refocusQfe();
})(); })();
@ -229,6 +235,20 @@ var Zotero_QuickFormat = new function () {
return node ? node.wholeText : false; return node ? node.wholeText : false;
} }
/**
* Updates currentLocator based on a string
* @param {String} str String to search for locator
* @return {String} str without locator
*/
function _updateLocator(str) {
m = locatorRe.exec(str);
if(m && (m[1] || m[2] || m[3].length !== 4) && m.index > 0) {
currentLocator = m[3];
str = str.substr(0, m.index)+str.substring(m.index+m[0].length);
}
return str;
}
/** /**
* Does the dirty work of figuring out what the user meant to type * Does the dirty work of figuring out what the user meant to type
*/ */
@ -311,7 +331,7 @@ var Zotero_QuickFormat = new function () {
// Exclude feeds // Exclude feeds
Zotero.Feeds.getAll() Zotero.Feeds.getAll()
.forEach(feed => s.addCondition("libraryID", "isNot", feed.libraryID)); .forEach(feed => s.addCondition("libraryID", "isNot", feed.libraryID));
if (io.allowCitingNotes) { if (Zotero_QuickFormat.citingNotes) {
s.addCondition("quicksearch-titleCreatorYearNote", "contains", str); s.addCondition("quicksearch-titleCreatorYearNote", "contains", str);
} }
else { else {
@ -325,57 +345,72 @@ var Zotero_QuickFormat = new function () {
} }
} }
if(haveConditions) { if (!haveConditions && Zotero_QuickFormat.citingNotes) {
s = new Zotero.Search();
str = "";
s.addCondition("quicksearch-titleCreatorYearNote", "contains", str);
haveConditions = true;
}
if (haveConditions) {
var searchResultIDs = (haveConditions ? (yield s.search()) : []); var searchResultIDs = (haveConditions ? (yield s.search()) : []);
// Show items list without cited items to start // Show items list without cited items to start
yield _updateItemList(false, false, str, searchResultIDs); yield _updateItemList({ searchString: str, searchResultIDs });
// Check to see which search results match items already in the document // Check to see which search results match items already in the document
var citedItems, completed = false, isAsync = false; var citedItems, completed = !!Zotero_QuickFormat.citingNotes, isAsync = false;
// Save current search time so that when we get items, we know whether it's too late to // Save current search time so that when we get items, we know whether it's too late to
// process them or not // process them or not
var lastSearchTime = currentSearchTime = Date.now(); var lastSearchTime = currentSearchTime = Date.now();
// This may or may not be synchronous // This may or may not be synchronous
io.getItems().then(function(citedItems) { if (!Zotero_QuickFormat.citingNotes) {
// Don't do anything if panel is already closed io.getItems().then(function(citedItems) {
if(isAsync && // Don't do anything if panel is already closed
((referencePanel.state !== "open" && referencePanel.state !== "showing") if(isAsync &&
|| lastSearchTime !== currentSearchTime)) return; ((referencePanel.state !== "open" && referencePanel.state !== "showing")
|| lastSearchTime !== currentSearchTime)) return;
completed = true; completed = true;
if(str.toLowerCase() === Zotero.getString("integration.ibid").toLowerCase()) { if(str.toLowerCase() === Zotero.getString("integration.ibid").toLowerCase()) {
// If "ibid" is entered, show all cited items // If "ibid" is entered, show all cited items
citedItemsMatchingSearch = citedItems; citedItemsMatchingSearch = citedItems;
} else { } else {
Zotero.debug("Searching cited items"); Zotero.debug("Searching cited items");
// Search against items. We do this here because it's possible that some of these // Search against items. We do this here because it's possible that some of these
// items are only in the doc, and not in the DB. // items are only in the doc, and not in the DB.
var splits = Zotero.Fulltext.semanticSplitter(str), var splits = Zotero.Fulltext.semanticSplitter(str),
citedItemsMatchingSearch = []; citedItemsMatchingSearch = [];
for(var i=0, iCount=citedItems.length; i<iCount; i++) { for(var i=0, iCount=citedItems.length; i<iCount; i++) {
// Generate a string to search for each item // Generate a string to search for each item
let item = citedItems[i]; let item = citedItems[i];
let itemStr = item.getCreators() let itemStr = item.getCreators()
.map(creator => creator.firstName + " " + creator.lastName) .map(creator => creator.firstName + " " + creator.lastName)
.concat([item.getField("title"), item.getField("date", true, true).substr(0, 4)]) .concat([item.getField("title"), item.getField("date", true, true).substr(0, 4)])
.join(" "); .join(" ");
// See if words match // See if words match
for(var j=0, jCount=splits.length; j<jCount; j++) { for(var j=0, jCount=splits.length; j<jCount; j++) {
var split = splits[j]; var split = splits[j];
if(itemStr.toLowerCase().indexOf(split) === -1) break; if(itemStr.toLowerCase().indexOf(split) === -1) break;
}
// If matched, add to citedItemsMatchingSearch
if(j === jCount) citedItemsMatchingSearch.push(item);
} }
Zotero.debug("Searched cited items");
// If matched, add to citedItemsMatchingSearch
if(j === jCount) citedItemsMatchingSearch.push(item);
} }
Zotero.debug("Searched cited items");
}
_updateItemList(citedItems, citedItemsMatchingSearch, str, searchResultIDs, isAsync); _updateItemList({
}); citedItems,
citedItemsMatchingSearch,
searchString: str,
searchResultIDs,
preserveSelection: isAsync
});
});
}
if(!completed) { if(!completed) {
// We are going to have to wait until items have been retrieved from the document. // We are going to have to wait until items have been retrieved from the document.
@ -386,30 +421,26 @@ var Zotero_QuickFormat = new function () {
} }
} else { } else {
// No search conditions, so just clear the box // No search conditions, so just clear the box
_updateItemList([], [], "", []); _updateItemList({ citedItems: [] });
} }
}); });
/**
* Updates currentLocator based on a string
* @param {String} str String to search for locator
* @return {String} str without locator
*/
function _updateLocator(str) {
m = locatorRe.exec(str);
if(m && (m[1] || m[2] || m[3].length !== 4) && m.index > 0) {
currentLocator = m[3];
str = str.substr(0, m.index)+str.substring(m.index+m[0].length);
}
return str;
}
/** /**
* Updates the item list * Updates the item list
*/ */
var _updateItemList = Zotero.Promise.coroutine(function* (citedItems, citedItemsMatchingSearch, var _updateItemList = async function (options = {}) {
searchString, searchResultIDs, preserveSelection) { options = Object.assign({
citedItems: false,
citedItemsMatchingSearch: false,
searchString: "",
searchResultIDs: [],
preserveSelection: false
}, options);
let { citedItems, citedItemsMatchingSearch, searchString,
searchResultIDs, preserveSelection } = options
var selectedIndex = 1, previousItemID; var selectedIndex = 1, previousItemID;
if (Zotero_QuickFormat.citingNotes) citedItems = [];
// Do this so we can preserve the selected item after cited items have been loaded // Do this so we can preserve the selected item after cited items have been loaded
if(preserveSelection && referenceBox.selectedIndex !== -1 && referenceBox.selectedIndex !== 2) { if(preserveSelection && referenceBox.selectedIndex !== -1 && referenceBox.selectedIndex !== 2) {
@ -466,8 +497,8 @@ var Zotero_QuickFormat = new function () {
if(searchResultIDs.length && (!citedItemsMatchingSearch || citedItemsMatchingSearch.length < 50)) { if(searchResultIDs.length && (!citedItemsMatchingSearch || citedItemsMatchingSearch.length < 50)) {
// Search results might be in an unloaded library, so get items asynchronously and load // Search results might be in an unloaded library, so get items asynchronously and load
// necessary data // necessary data
var items = yield Zotero.Items.getAsync(searchResultIDs); var items = await Zotero.Items.getAsync(searchResultIDs);
yield Zotero.Items.loadDataTypes(items); await Zotero.Items.loadDataTypes(items);
searchString = searchString.toLowerCase(); searchString = searchString.toLowerCase();
var collation = Zotero.getLocaleCollation(); var collation = Zotero.getLocaleCollation();
@ -544,7 +575,7 @@ var Zotero_QuickFormat = new function () {
referenceBox.selectedIndex = selectedIndex; referenceBox.selectedIndex = selectedIndex;
referenceBox.ensureIndexIsVisible(selectedIndex); referenceBox.ensureIndexIsVisible(selectedIndex);
} }
}); };
/** /**
* Builds a string describing an item. We avoid CSL here for speed. * Builds a string describing an item. We avoid CSL here for speed.
@ -620,23 +651,23 @@ var Zotero_QuickFormat = new function () {
*/ */
function _buildListItem(item) { function _buildListItem(item) {
var titleNode = document.createElement("label"); var titleNode = document.createElement("label");
titleNode.setAttribute("class", "quick-format-title"); titleNode.setAttribute("class", "citation-dialog title");
titleNode.setAttribute("flex", "1"); titleNode.setAttribute("flex", "1");
titleNode.setAttribute("crop", "end"); titleNode.setAttribute("crop", "end");
titleNode.setAttribute("value", item.getDisplayTitle()); titleNode.setAttribute("value", item.getDisplayTitle());
var infoNode = document.createElement("hbox"); var infoNode = document.createElement("hbox");
infoNode.setAttribute("class", "quick-format-info"); infoNode.setAttribute("class", "citation-dialog info");
_buildItemDescription(item, infoNode); _buildItemDescription(item, infoNode);
// add to rich list item // add to rich list item
var rll = document.createElement("richlistitem"); var rll = document.createElement("richlistitem");
rll.setAttribute("orient", "vertical"); rll.setAttribute("orient", "vertical");
rll.setAttribute("class", "quick-format-item"); rll.setAttribute("class", "citation-dialog item");
rll.setAttribute("zotero-item", item.cslItemID ? item.cslItemID : item.id); rll.setAttribute("zotero-item", item.cslItemID ? item.cslItemID : item.id);
rll.appendChild(titleNode); rll.appendChild(titleNode);
rll.appendChild(infoNode); rll.appendChild(infoNode);
rll.addEventListener("click", _bubbleizeSelected, false); rll.addEventListener("click", Zotero_QuickFormat._bubbleizeSelected, false);
return rll; return rll;
} }
@ -646,7 +677,7 @@ var Zotero_QuickFormat = new function () {
*/ */
function _buildListSeparator(labelText, loading) { function _buildListSeparator(labelText, loading) {
var titleNode = document.createElement("label"); var titleNode = document.createElement("label");
titleNode.setAttribute("class", "quick-format-separator-title"); titleNode.setAttribute("class", "citation-dialog separator-title");
titleNode.setAttribute("flex", "1"); titleNode.setAttribute("flex", "1");
titleNode.setAttribute("crop", "end"); titleNode.setAttribute("crop", "end");
titleNode.setAttribute("value", labelText); titleNode.setAttribute("value", labelText);
@ -655,7 +686,7 @@ var Zotero_QuickFormat = new function () {
var rll = document.createElement("richlistitem"); var rll = document.createElement("richlistitem");
rll.setAttribute("orient", "vertical"); rll.setAttribute("orient", "vertical");
rll.setAttribute("disabled", true); rll.setAttribute("disabled", true);
rll.setAttribute("class", loading ? "quick-format-loading" : "quick-format-separator"); rll.setAttribute("class", loading ? "citation-dialog loading" : "citation-dialog separator");
rll.appendChild(titleNode); rll.appendChild(titleNode);
rll.addEventListener("mousedown", _ignoreClick, true); rll.addEventListener("mousedown", _ignoreClick, true);
rll.addEventListener("click", _ignoreClick, true); rll.addEventListener("click", _ignoreClick, true);
@ -729,7 +760,7 @@ var Zotero_QuickFormat = new function () {
// a XUL label for these things works best. A regular span causes issues with moving the // a XUL label for these things works best. A regular span causes issues with moving the
// cursor. // cursor.
var bubble = qfiDocument.createElement("span"); var bubble = qfiDocument.createElement("span");
bubble.setAttribute("class", "quick-format-bubble"); bubble.setAttribute("class", "citation-dialog bubble");
bubble.setAttribute("draggable", "true"); bubble.setAttribute("draggable", "true");
bubble.textContent = str; bubble.textContent = str;
bubble.addEventListener("click", _onBubbleClick, false); bubble.addEventListener("click", _onBubbleClick, false);
@ -760,31 +791,10 @@ var Zotero_QuickFormat = new function () {
/** /**
* Converts the selected item to a bubble * Converts the selected item to a bubble
*/ */
var _bubbleizeSelected = Zotero.Promise.coroutine(function* () { this._bubbleizeSelected = Zotero.Promise.coroutine(function* () {
if(!referenceBox.hasChildNodes() || !referenceBox.selectedItem) return false; if(!referenceBox.hasChildNodes() || !referenceBox.selectedItem) return false;
var ps = Services.prompt;
var citationItem = {"id":referenceBox.selectedItem.getAttribute("zotero-item")}; var citationItem = {"id":referenceBox.selectedItem.getAttribute("zotero-item")};
var item = Zotero.Cite.getItem(citationItem.id);
var nodes = Array.from(qfe.childNodes).filter(node => node.tagName == 'span');
if (nodes[0] && nodes[0].dataset && JSON.parse(nodes[0].dataset.citationItem).isNote) {
ps.alert(null,
Zotero.getString('general.warning'),
Zotero.getString('integration.cannotInsertItemWithNote'));
return false;
}
if (item && item.isNote()) {
document.getElementById('classic-view').hidden = true;
if (nodes.length) {
if (!ps.confirm(null,
Zotero.getString('general.warning'),
Zotero.getString('integration.noteCiteItemsRemoved'))) {
return false;
}
_clearCitation();
citationItem.isNote = true;
}
}
if (typeof citationItem.id === "string" && citationItem.id.indexOf("/") !== -1) { if (typeof citationItem.id === "string" && citationItem.id.indexOf("/") !== -1) {
citationItem.uris = item.cslURIs; citationItem.uris = item.cslURIs;
citationItem.itemData = item.cslItemData; citationItem.itemData = item.cslItemData;
@ -860,13 +870,13 @@ var Zotero_QuickFormat = new function () {
var childNodes = referenceBox.childNodes, numReferences = 0, numSeparators = 0, var childNodes = referenceBox.childNodes, numReferences = 0, numSeparators = 0,
firstReference, firstSeparator, height; firstReference, firstSeparator, height;
for(var i=0, n=childNodes.length; i<n && numReferences < SHOWN_REFERENCES; i++) { for(var i=0, n=childNodes.length; i<n && numReferences < SHOWN_REFERENCES; i++) {
if(childNodes[i].className === "quick-format-item") { if(childNodes[i].className === "citation-dialog item") {
numReferences++; numReferences++;
if(!firstReference) { if(!firstReference) {
firstReference = childNodes[i]; firstReference = childNodes[i];
if(referenceBox.selectedIndex === -1) referenceBox.selectedIndex = i; if(referenceBox.selectedIndex === -1) referenceBox.selectedIndex = i;
} }
} else if(childNodes[i].className === "quick-format-separator") { } else if(childNodes[i].className === "citation-dialog separator") {
numSeparators++; numSeparators++;
if(!firstSeparator) firstSeparator = childNodes[i]; if(!firstSeparator) firstSeparator = childNodes[i];
} }
@ -921,7 +931,6 @@ var Zotero_QuickFormat = new function () {
} }
} }
} }
referencePanel.sizeTo(window.outerWidth-30, referencePanel.sizeTo(window.outerWidth-30,
numReferences*referenceHeight+numSeparators*separatorHeight+panelFrameHeight); numReferences*referenceHeight+numSeparators*separatorHeight+panelFrameHeight);
if(!panelShowing) _openReferencePanel(); if(!panelShowing) _openReferencePanel();
@ -936,29 +945,29 @@ var Zotero_QuickFormat = new function () {
* Opens the reference panel and potentially refocuses the main text box * Opens the reference panel and potentially refocuses the main text box
*/ */
function _openReferencePanel() { function _openReferencePanel() {
if(!Zotero.isMac && !Zotero.isWin) { var panelShowing = referencePanel.state === "open" || referencePanel.state === "showing";
if (!panelShowing && !Zotero.isMac && !Zotero.isWin) {
// noautohide and noautofocus are incompatible on Linux // noautohide and noautofocus are incompatible on Linux
// https://bugzilla.mozilla.org/show_bug.cgi?id=545265 // https://bugzilla.mozilla.org/show_bug.cgi?id=545265
referencePanel.setAttribute("noautohide", "false"); referencePanel.setAttribute("noautohide", "false");
}
referencePanel.openPopup(document.documentElement, "after_start", 15,
qfb.clientHeight-window.clientHeight, false, false, null);
if(!Zotero.isMac && !Zotero.isWin) {
// reinstate noautohide after the window is shown // reinstate noautohide after the window is shown
referencePanel.addEventListener("popupshowing", function() { referencePanel.addEventListener("popupshowing", function() {
referencePanel.removeEventListener("popupshowing", arguments.callee, false); referencePanel.removeEventListener("popupshowing", arguments.callee, false);
referencePanel.setAttribute("noautohide", "true"); referencePanel.setAttribute("noautohide", "true");
}, false); }, false);
} }
referencePanel.openPopup(document.documentElement, "after_start", 15,
qfb.clientHeight-window.clientHeight, false, false, null);
} }
/** /**
* Clears all citations * Clears all citations
*/ */
function _clearCitation() { function _clearCitation() {
var citations = qfe.getElementsByClassName("quick-format-bubble"); var citations = qfe.getElementsByClassName("citation-dialog bubble");
while(citations.length) { while(citations.length) {
citations[0].parentNode.removeChild(citations[0]); citations[0].parentNode.removeChild(citations[0]);
} }
@ -969,7 +978,7 @@ var Zotero_QuickFormat = new function () {
*/ */
function _showCitation(insertBefore) { function _showCitation(insertBefore) {
if(!io.citation.properties.unsorted if(!io.citation.properties.unsorted
&& keepSorted.hasAttribute("checked") && keepSorted && keepSorted.hasAttribute("checked")
&& io.citation.sortedItems && io.citation.sortedItems
&& io.citation.sortedItems.length) { && io.citation.sortedItems.length) {
for(var i=0, n=io.citation.sortedItems.length; i<n; i++) { for(var i=0, n=io.citation.sortedItems.length; i<n; i++) {
@ -1001,7 +1010,7 @@ var Zotero_QuickFormat = new function () {
} }
if(io.sortable) { if(io.sortable) {
if(keepSorted.hasAttribute("checked")) { if(keepSorted && keepSorted.hasAttribute("checked")) {
delete io.citation.properties.unsorted; delete io.citation.properties.unsorted;
} else { } else {
io.citation.properties.unsorted = true; io.citation.properties.unsorted = true;
@ -1026,8 +1035,8 @@ var Zotero_QuickFormat = new function () {
* Generates the preview and sorts citations * Generates the preview and sorts citations
*/ */
var _previewAndSort = Zotero.Promise.coroutine(function* () { var _previewAndSort = Zotero.Promise.coroutine(function* () {
var shouldKeepSorted = keepSorted.hasAttribute("checked"), var shouldKeepSorted = keepSorted && keepSorted.hasAttribute("checked"),
editorShowing = showEditor.hasAttribute("checked"); editorShowing = showEditor && showEditor.hasAttribute("checked");
if(!shouldKeepSorted && !editorShowing) return; if(!shouldKeepSorted && !editorShowing) return;
_updateCitationObject(); _updateCitationObject();
@ -1038,7 +1047,7 @@ var Zotero_QuickFormat = new function () {
_showCitation(); _showCitation();
// select past last citation // select past last citation
var lastBubble = qfe.getElementsByClassName("quick-format-bubble"); var lastBubble = qfe.getElementsByClassName("citation-dialog bubble");
lastBubble = lastBubble[lastBubble.length-1]; lastBubble = lastBubble[lastBubble.length-1];
_moveCursorToEnd(); _moveCursorToEnd();
@ -1088,7 +1097,7 @@ var Zotero_QuickFormat = new function () {
* Called when progress changes * Called when progress changes
*/ */
function _onProgress(percent) { function _onProgress(percent) {
var meter = document.getElementById("quick-format-progress-meter"); var meter = document.querySelector(".citation-dialog .progress-meter");
if(percent === null) { if(percent === null) {
meter.mode = "undetermined"; meter.mode = "undetermined";
} else { } else {
@ -1100,12 +1109,12 @@ var Zotero_QuickFormat = new function () {
/** /**
* Accepts current selection and adds citation * Accepts current selection and adds citation
*/ */
function _accept() { this._accept = function() {
if(accepted) return; if(accepted) return;
accepted = true; accepted = true;
try { try {
_updateCitationObject(); _updateCitationObject();
document.getElementById("quick-format-deck").selectedIndex = 1; document.querySelector(".citation-dialog.deck").selectedIndex = 1;
io.accept(_onProgress); io.accept(_onProgress);
} catch(e) { } catch(e) {
Zotero.debug(e); Zotero.debug(e);
@ -1132,11 +1141,6 @@ var Zotero_QuickFormat = new function () {
io.citation.citationItems = []; io.citation.citationItems = [];
io.accept(); io.accept();
} }
else if (['Backspace', 'Delete'].includes(event.key)) {
var nodes = Array.from(qfe.childNodes).filter(node => node.tagName == 'span');
document.getElementById('classic-view').hidden =
nodes[0] && nodes[0].dataset && JSON.parse(nodes[0].dataset.citationItem).isNote;
}
}; };
/** /**
@ -1182,7 +1186,7 @@ var Zotero_QuickFormat = new function () {
*/ */
function _resetSearchTimer() { function _resetSearchTimer() {
// Show spinner // Show spinner
var spinner = document.getElementById('quick-format-spinner'); var spinner = document.querySelector('.citation-dialog.spinner');
spinner.style.visibility = ''; spinner.style.visibility = '';
// Cancel current search if active // Cancel current search if active
if (_searchPromise && _searchPromise.isPending()) { if (_searchPromise && _searchPromise.isPending()) {
@ -1228,8 +1232,8 @@ var Zotero_QuickFormat = new function () {
var keyCode = event.keyCode; var keyCode = event.keyCode;
if (keyCode === event.DOM_VK_RETURN) { if (keyCode === event.DOM_VK_RETURN) {
event.preventDefault(); event.preventDefault();
if(!(yield _bubbleizeSelected()) && !_getEditorContent()) { if(!(yield Zotero_QuickFormat._bubbleizeSelected()) && !_getEditorContent()) {
_accept(); Zotero_QuickFormat._accept();
} }
} else if (keyCode === event.DOM_VK_ESCAPE) { } else if (keyCode === event.DOM_VK_ESCAPE) {
// Handled in the event handler up, but we have to cancel it here // Handled in the event handler up, but we have to cancel it here
@ -1237,7 +1241,7 @@ var Zotero_QuickFormat = new function () {
return; return;
} else if(keyCode === event.DOM_VK_TAB || event.charCode === 59 /* ; */) { } else if(keyCode === event.DOM_VK_TAB || event.charCode === 59 /* ; */) {
event.preventDefault(); event.preventDefault();
_bubbleizeSelected(); Zotero_QuickFormat._bubbleizeSelected();
} else if(keyCode === event.DOM_VK_BACK_SPACE || keyCode === event.DOM_VK_DELETE) { } else if(keyCode === event.DOM_VK_BACK_SPACE || keyCode === event.DOM_VK_DELETE) {
var bubble = _getSelectedBubble(keyCode === event.DOM_VK_DELETE); var bubble = _getSelectedBubble(keyCode === event.DOM_VK_DELETE);
@ -1372,7 +1376,7 @@ var Zotero_QuickFormat = new function () {
var bubble = _insertBubble(JSON.parse(dragging.dataset.citationItem), range); var bubble = _insertBubble(JSON.parse(dragging.dataset.citationItem), range);
// If moved out of order, turn off "Keep Sources Sorted" // If moved out of order, turn off "Keep Sources Sorted"
if(io.sortable && keepSorted.hasAttribute("checked") && oldPosition !== -1 && if(io.sortable && keepSorted && keepSorted.hasAttribute("checked") && oldPosition !== -1 &&
oldPosition != _getBubbleIndex(bubble)) { oldPosition != _getBubbleIndex(bubble)) {
keepSorted.removeAttribute("checked"); keepSorted.removeAttribute("checked");
} }

View file

@ -33,6 +33,7 @@
<window <window
id="quick-format-dialog" id="quick-format-dialog"
class="citation-dialog"
orient="vertical" orient="vertical"
title="&zotero.integration.quickFormatDialog.title;" title="&zotero.integration.quickFormatDialog.title;"
xmlns:html="http://www.w3.org/1999/xhtml" xmlns:html="http://www.w3.org/1999/xhtml"
@ -45,39 +46,40 @@
<script src="windowDraggingUtils.js" type="text/javascript"/> <script src="windowDraggingUtils.js" type="text/javascript"/>
<script src="quickFormat.js" type="text/javascript"/> <script src="quickFormat.js" type="text/javascript"/>
<box orient="horizontal" id="quick-format-entry"> <box orient="horizontal" class="citation-dialog entry">
<deck id="quick-format-deck" selectedIndex="0" flex="1"> <deck class="citation-dialog deck" selectedIndex="0" flex="1">
<hbox id="quick-format-search" flex="1" align="start"> <hbox class="citation-dialog search" flex="1" align="start">
<hbox flex="1"> <hbox flex="1">
<toolbarbutton id="zotero-icon" type="menu"> <toolbarbutton id="zotero-icon" type="menu">
<menupopup> <menupopup>
<menuitem id="keep-sorted" label="&zotero.citation.keepSorted.label;" <menuitem id="keep-sorted" label="&zotero.citation.keepSorted.label;"
oncommand="Zotero_QuickFormat.onKeepSortedCommand()" type="checkbox" oncommand="Zotero_QuickFormat.onKeepSortedCommand()" type="checkbox"
hidden="true"/> hidden="true"/>
<menuitem id="show-editor" label="&zotero.integration.showEditor.label;" <menuitem id="show-editor" label="&zotero.integration.showEditor.label;"
oncommand="Zotero_QuickFormat.onShowEditorCommand()" type="checkbox" oncommand="Zotero_QuickFormat.onShowEditorCommand()" type="checkbox"
hidden="true"/> hidden="true"/>
<menuitem id="classic-view" label="&zotero.integration.classicView.label;" <menuitem id="classic-view" label="&zotero.integration.classicView.label;"
oncommand="Zotero_QuickFormat.onClassicViewCommand()"/> oncommand="Zotero_QuickFormat.onClassicViewCommand()"/>
</menupopup> </menupopup>
</toolbarbutton> </toolbarbutton>
<iframe id="quick-format-iframe" ondragstart="event.stopPropagation()" src="data:application/xhtml+xml,%3C!DOCTYPE%20html%20PUBLIC%20%22-//W3C//DTD%20XHTML%201.0%20Strict//EN%22%20%22http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd%22%3E%3Chtml%20xmlns=%22http://www.w3.org/1999/xhtml%22%3E%3Chead%3E%3Clink%20rel=%22stylesheet%22%20type=%22text/css%22%20href=%22chrome://zotero/skin/integration.css%22/%3E%3Clink%20rel=%22stylesheet%22%20type=%22text/css%22%20href=%22chrome://zotero-platform/content/integration.css%22/%3E%3C/head%3E%3Cbody%20contenteditable=%22true%22%20spellcheck=%22false%22%20id=%22quick-format-editor%22/%3E%3C/html%3E"
tabindex="1" flex="1"/> <iframe class="citation-dialog iframe" ondragstart="event.stopPropagation()" src="data:application/xhtml+xml,%3C!DOCTYPE%20html%20PUBLIC%20%22-//W3C//DTD%20XHTML%201.0%20Strict//EN%22%20%22http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd%22%3E%3Chtml%20xmlns=%22http://www.w3.org/1999/xhtml%22%3E%3Chead%3E%3Clink%20rel=%22stylesheet%22%20type=%22text/css%22%20href=%22chrome://zotero/skin/integration.css%22/%3E%3Clink%20rel=%22stylesheet%22%20type=%22text/css%22%20href=%22chrome://zotero-platform/content/integration.css%22/%3E%3C/head%3E%3Cbody%20contenteditable=%22true%22%20spellcheck=%22false%22%20class=%22citation-dialog%20editor%22/%3E%3C/html%3E"
<vbox id="quick-format-spinner" style="visibility: hidden"> tabindex="1" flex="1"/>
<vbox class="citation-dialog spinner" style="visibility: hidden">
<image class="zotero-spinner-16"/> <image class="zotero-spinner-16"/>
</vbox> </vbox>
</hbox> </hbox>
</hbox> </hbox>
<progressmeter id="quick-format-progress-meter" mode="undetermined" value="0" flex="1"/> <progressmeter class="citation-dialog progress-meter" mode="undetermined" value="0" flex="1"/>
</deck> </deck>
</box> </box>
<panel id="quick-format-reference-panel" noautofocus="true" norestorefocus="true" <panel class="citation-dialog reference-panel" noautofocus="true" norestorefocus="true"
height="0" width="0"> height="0" width="0">
<richlistbox id="quick-format-reference-list" flex="1"/> <richlistbox class="citation-dialog reference-list" flex="1"/>
</panel> </panel>
<panel id="citation-properties" type="arrow" orient="vertical" <panel id="citation-properties" type="arrow" orient="vertical"
onkeypress="Zotero_QuickFormat.onPanelKeyPress(event)" onkeypress="Zotero_QuickFormat.onPanelKeyPress(event)"
onpopuphidden="Zotero_QuickFormat.onCitationPropertiesClosed(event)"> onpopuphidden="Zotero_QuickFormat.onCitationPropertiesClosed(event)">
<vbox flex="1"> <vbox flex="1">
<description id="citation-properties-title"/> <description id="citation-properties-title"/>
<hbox id="citation-properties-info"/> <hbox id="citation-properties-info"/>
@ -90,25 +92,25 @@
<rows> <rows>
<row align="center"> <row align="center">
<menulist id="locator-label" sizetopopup="none" <menulist id="locator-label" sizetopopup="none"
oncommand="Zotero_QuickFormat.onCitationPropertiesChanged(event)"> oncommand="Zotero_QuickFormat.onCitationPropertiesChanged(event)">
<menupopup id="locator-label-popup"/> <menupopup id="locator-label-popup"/>
</menulist> </menulist>
<textbox id="locator" flex="1" <textbox id="locator" flex="1"
oninput="window.setTimeout(function(event) { Zotero_QuickFormat.onCitationPropertiesChanged(event) }, 0)"/> oninput="window.setTimeout(function(event) { Zotero_QuickFormat.onCitationPropertiesChanged(event) }, 0)"/>
</row> </row>
<row align="center"> <row align="center">
<label value="&zotero.citation.prefix.label;"/> <label value="&zotero.citation.prefix.label;"/>
<textbox class="citation-textbox" id="prefix" flex="1" <textbox class="citation-textbox" id="prefix" flex="1"
oninput="window.setTimeout(function(event) { Zotero_QuickFormat.onCitationPropertiesChanged(event) }, 0)"/> oninput="window.setTimeout(function(event) { Zotero_QuickFormat.onCitationPropertiesChanged(event) }, 0)"/>
</row> </row>
<row align="center"> <row align="center">
<label value="&zotero.citation.suffix.label;"/> <label value="&zotero.citation.suffix.label;"/>
<textbox class="citation-textbox" id="suffix" flex="1" <textbox class="citation-textbox" id="suffix" flex="1"
oninput="window.setTimeout(function(event) { Zotero_QuickFormat.onCitationPropertiesChanged(event) }, 0)"/> oninput="window.setTimeout(function(event) { Zotero_QuickFormat.onCitationPropertiesChanged(event) }, 0)"/>
</row> </row>
<html:div> <html:div>
<html:input type="checkbox" id="suppress-author" <html:input type="checkbox" id="suppress-author"
onchange="Zotero_QuickFormat.onCitationPropertiesChanged(event)"/> onchange="Zotero_QuickFormat.onCitationPropertiesChanged(event)"/>
<html:label for="suppress-author"> <html:label for="suppress-author">
&zotero.citation.suppressAuthor.label; &zotero.citation.suppressAuthor.label;
</html:label> </html:label>
@ -119,6 +121,6 @@
<button id="citation-properties-library-link" onclick="Zotero_QuickFormat.showInLibrary()"/> <button id="citation-properties-library-link" onclick="Zotero_QuickFormat.showInLibrary()"/>
</vbox> </vbox>
</panel> </panel>
<zoteroguidancepanel id="quick-format-guidance" about="quickFormat" <zoteroguidancepanel class="citation-dialog guidance" about="quickFormat"
for="zotero-icon" x="26"/> for="zotero-icon" x="26"/>
</window> </window>

View file

@ -306,6 +306,11 @@ Zotero.Search.prototype.addCondition = function (condition, operator, value, req
var parts = Zotero.SearchConditions.parseSearchString(value); var parts = Zotero.SearchConditions.parseSearchString(value);
for (let part of parts) { for (let part of parts) {
if (condition == 'quicksearch-titleCreatorYearNote') {
this.addCondition('note', operator, part.text, false);
continue;
}
this.addCondition('blockStart'); this.addCondition('blockStart');
// Allow searching for exact object key // Allow searching for exact object key
@ -319,10 +324,6 @@ Zotero.Search.prototype.addCondition = function (condition, operator, value, req
this.addCondition('shortTitle', operator, part.text, false); this.addCondition('shortTitle', operator, part.text, false);
this.addCondition('court', operator, part.text, false); this.addCondition('court', operator, part.text, false);
this.addCondition('year', operator, part.text, false); this.addCondition('year', operator, part.text, false);
if (condition == 'quicksearch-titleCreatorYearNote') {
this.addCondition('note', operator, part.text, false);
}
} }
else { else {
this.addCondition('field', operator, part.text, false); this.addCondition('field', operator, part.text, false);
@ -353,8 +354,7 @@ Zotero.Search.prototype.addCondition = function (condition, operator, value, req
this.addCondition('noChildren', 'true'); this.addCondition('noChildren', 'true');
} }
else if (condition == 'quicksearch-titleCreatorYearNote') { else if (condition == 'quicksearch-titleCreatorYearNote') {
this.addCondition('itemType', 'isNot', 'attachment'); this.addCondition('itemType', 'is', 'note');
this.addCondition('itemType', 'isNot', 'annotation');
} }
return false; return false;

View file

@ -160,7 +160,7 @@ Zotero.Integration = new function() {
/** /**
* Executes an integration command, first checking to make sure that versions are compatible * Executes an integration command, first checking to make sure that versions are compatible
*/ */
this.execCommand = async function(agent, command, docId) { this.execCommand = async function(agent, command, docId, templateVersion) {
var document, session, documentImported; var document, session, documentImported;
if (Zotero.Integration.currentDoc) { if (Zotero.Integration.currentDoc) {
@ -194,7 +194,7 @@ Zotero.Integration = new function() {
} }
Zotero.Integration.currentDoc = document = await documentPromise; Zotero.Integration.currentDoc = document = await documentPromise;
[session, documentImported] = await Zotero.Integration.getSession(application, document, agent); [session, documentImported] = await Zotero.Integration.getSession(application, document, agent, command == 'addNote');
Zotero.Integration.currentSession = session; Zotero.Integration.currentSession = session;
// TODO: figure this out // TODO: figure this out
// Zotero.Notifier.trigger('delete', 'collection', 'document'); // Zotero.Notifier.trigger('delete', 'collection', 'document');
@ -372,10 +372,10 @@ Zotero.Integration = new function() {
* Either loads a cached session if doc communicated since restart or creates a new one * Either loads a cached session if doc communicated since restart or creates a new one
* @return {Zotero.Integration.Session} Promise * @return {Zotero.Integration.Session} Promise
*/ */
this.getSession = async function (app, doc, agent) { this.getSession = async function (app, doc, agent, isNote) {
let documentImported = false; let documentImported = false;
try { try {
var progressBar = new Zotero.Integration.Progress(4, Zotero.isMac && agent != 'http'); var progressBar = new Zotero.Integration.Progress(4, isNote, Zotero.isMac && agent != 'http');
progressBar.show(); progressBar.show();
var dataString = await doc.getDocumentData(), var dataString = await doc.getDocumentData(),
@ -597,6 +597,29 @@ Zotero.Integration.Interface.prototype.addEditCitation = async function (docFiel
} }
}; };
/**
* Edits the citation at the cursor position if one exists, or else adds a new one.
* @return {Promise}
*/
Zotero.Integration.Interface.prototype.addNote = async function () {
await this._session.init(false, false);
if ((!await this._doc.canInsertField(this._session.data.prefs['fieldType']))) {
throw new Zotero.Exception.Alert("integration.error.cannotInsertHere", [],
"integration.error.title");
}
let citations = await this._session.cite(null, true);
if (this._session.data.prefs.delayCitationUpdates) {
for (let citation of citations) {
await this._session.writeDelayedCitation(citation._field, citation);
}
}
else {
return this._session.updateDocument(FORCE_CITATIONS_FALSE, false, false);
}
};
/** /**
* Adds a bibliography to the current document. * Adds a bibliography to the current document.
* @return {Promise} * @return {Promise}
@ -1262,7 +1285,7 @@ Zotero.Integration.Session.prototype._updateDocument = async function(forceCitat
* display the citation dialog and perform any field/text inserts after * display the citation dialog and perform any field/text inserts after
* the dialog edits are accepted * the dialog edits are accepted
*/ */
Zotero.Integration.Session.prototype.cite = async function (field) { Zotero.Integration.Session.prototype.cite = async function (field, addNote=false) {
var newField; var newField;
var citation; var citation;
@ -1337,8 +1360,7 @@ Zotero.Integration.Session.prototype.cite = async function (field) {
var io = new Zotero.Integration.CitationEditInterface( var io = new Zotero.Integration.CitationEditInterface(
citation, this.style.opt.sort_citations, citation, this.style.opt.sort_citations,
fieldIndexPromise, citationsByItemIDPromise, previewFn, fieldIndexPromise, citationsByItemIDPromise, previewFn
this._app.supportsTextInsertion
); );
Zotero.debug(`Editing citation:`); Zotero.debug(`Editing citation:`);
Zotero.debug(JSON.stringify(citation.toJSON())); Zotero.debug(JSON.stringify(citation.toJSON()));
@ -1346,11 +1368,18 @@ Zotero.Integration.Session.prototype.cite = async function (field) {
if (Zotero.Prefs.get("integration.useClassicAddCitationDialog")) { if (Zotero.Prefs.get("integration.useClassicAddCitationDialog")) {
Zotero.Integration.displayDialog('chrome://zotero/content/integration/addCitationDialog.xul', Zotero.Integration.displayDialog('chrome://zotero/content/integration/addCitationDialog.xul',
'alwaysRaised,resizable', io); 'alwaysRaised,resizable', io);
} else { }
else {
var mode = (!Zotero.isMac && Zotero.Prefs.get('integration.keepAddCitationDialogRaised') var mode = (!Zotero.isMac && Zotero.Prefs.get('integration.keepAddCitationDialogRaised')
? 'popup' : 'alwaysRaised')+',resizable=false'; ? 'popup' : 'alwaysRaised')+',resizable=false';
Zotero.Integration.displayDialog('chrome://zotero/content/integration/quickFormat.xul', if (addNote) {
mode, io); Zotero.Integration.displayDialog('chrome://zotero/content/integration/insertNoteDialog.xul',
mode, io);
}
else {
Zotero.Integration.displayDialog('chrome://zotero/content/integration/quickFormat.xul',
mode, io);
}
} }
// ------------------- // -------------------
@ -1498,13 +1527,12 @@ Zotero.Integration.Session.prototype._insertItemsIntoDocument = async function (
* Citation editing functions and propertiesaccessible to quickFormat.js and addCitationDialog.js * Citation editing functions and propertiesaccessible to quickFormat.js and addCitationDialog.js
*/ */
Zotero.Integration.CitationEditInterface = function(items, sortable, fieldIndexPromise, Zotero.Integration.CitationEditInterface = function(items, sortable, fieldIndexPromise,
citationsByItemIDPromise, previewFn, allowCitingNotes=false){ citationsByItemIDPromise, previewFn){
this.citation = items; this.citation = items;
this.sortable = sortable; this.sortable = sortable;
this.previewFn = previewFn; this.previewFn = previewFn;
this._fieldIndexPromise = fieldIndexPromise; this._fieldIndexPromise = fieldIndexPromise;
this._citationsByItemIDPromise = citationsByItemIDPromise; this._citationsByItemIDPromise = citationsByItemIDPromise;
this.allowCitingNotes = allowCitingNotes;
// Not available in quickFormat.js if this unspecified // Not available in quickFormat.js if this unspecified
this.wrappedJSObject = this; this.wrappedJSObject = this;
@ -3170,11 +3198,12 @@ Zotero.Integration.Progress = class {
* except for http agents (i.e. google docs), where even opening the citation dialog may potentially take * except for http agents (i.e. google docs), where even opening the citation dialog may potentially take
* a long time and having no indication of progress is worse than bringing the Zotero window to the front * a long time and having no indication of progress is worse than bringing the Zotero window to the front
*/ */
constructor(segmentCount=4, dontDisplay=false) { constructor(segmentCount=4, isNote=false, dontDisplay=false) {
this.segments = Array.from({length: segmentCount}, () => undefined); this.segments = Array.from({length: segmentCount}, () => undefined);
this.timer = new Zotero.Integration.Timer(); this.timer = new Zotero.Integration.Timer();
this.segmentIdx = 0; this.segmentIdx = 0;
this.dontDisplay = dontDisplay; this.dontDisplay = dontDisplay;
this.isNote = isNote;
} }
update() { update() {
@ -3214,6 +3243,7 @@ Zotero.Integration.Progress = class {
this.update(); this.update();
}.bind(this)}; }.bind(this)};
io.wrappedJSObject = io; io.wrappedJSObject = io;
io.isNote = this.isNote;
this.window = Components.classes["@mozilla.org/embedcomp/window-watcher;1"] this.window = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher) .getService(Components.interfaces.nsIWindowWatcher)
.openWindow(null, 'chrome://zotero/content/integration/progressBar.xul', '', options, io); .openWindow(null, 'chrome://zotero/content/integration/progressBar.xul', '', options, io);

View file

@ -91,22 +91,22 @@
max-height: 100px; max-height: 100px;
} }
.quick-format-title { .citation-dialog.title {
margin: 0; margin: 0;
font-weight: bold; font-weight: bold;
overflow: hidden; overflow: hidden;
} }
.quick-format-info { .citation-dialog.info {
margin: 0; margin: 0;
overflow: hidden; overflow: hidden;
} }
.quick-format-info > label { .citation-dialog.info > label {
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
.quick-format-bubble { .citation-dialog.bubble {
border-radius: 8px; border-radius: 8px;
background-color: #dee7f8; background-color: #dee7f8;
border-style: solid; border-style: solid;
@ -120,25 +120,25 @@
-moz-user-select: all; -moz-user-select: all;
} }
.quick-format-bubble:hover { .citation-dialog.bubble:hover {
background-color: #bbcef1; background-color: #bbcef1;
border-color: #6d95e0; border-color: #6d95e0;
} }
.quick-format-bubble[selected="true"] { .citation-dialog.bubble[selected="true"] {
border-radius: 8px !important; border-radius: 8px !important;
background-color: #598bec; background-color: #598bec;
color: #fff; color: #fff;
} }
#quick-format-search { .citation-dialog.search {
margin: 0; margin: 0;
padding: 0; padding: 0;
padding-top: 0; padding-top: 0;
padding-bottom: 0; padding-bottom: 0;
} }
#quick-format-iframe { .citation-dialog.iframe {
margin-left: 4px; margin-left: 4px;
height: 9999px; height: 9999px;
} }
@ -150,25 +150,25 @@ body {
overflow: hidden; overflow: hidden;
} }
#quick-format-spinner { .citation-dialog.spinner {
margin-top: 2px; margin-top: 2px;
margin-right: 8px; margin-right: 8px;
} }
.quick-format-item { .citation-dialog.item {
font-size: 12px; font-size: 12px;
font: -moz-field; font: -moz-field;
-moz-user-focus: normal; -moz-user-focus: normal;
padding: 3px 5px 3px 10px; padding: 3px 5px 3px 10px;
} }
.quick-format-item:not(:last-child), .quick-format-separator:not(:last-child) { .citation-dialog.item:not(:last-child), .citation-dialog.separator:not(:last-child) {
border-style: solid; border-style: solid;
border-width: 0 0 1px 0; border-width: 0 0 1px 0;
border-color: #BBB; border-color: #BBB;
} }
.quick-format-separator { .citation-dialog.separator {
font-size: 12px; font-size: 12px;
font: -moz-field; font: -moz-field;
-moz-user-focus: ignore; -moz-user-focus: ignore;
@ -180,7 +180,7 @@ richlistitem[selected="true"] {
color: HighlightText; color: HighlightText;
} }
#quick-format-reference-panel { .citation-dialog.reference-panel {
margin: 0; margin: 0;
padding: 0; padding: 0;
border: none; border: none;
@ -189,7 +189,7 @@ richlistitem[selected="true"] {
-moz-user-focus: ignore; -moz-user-focus: ignore;
} }
#quick-format-reference-list { .citation-dialog.reference-list {
margin: 0; margin: 0;
padding: 0; padding: 0;
-moz-user-focus: ignore; -moz-user-focus: ignore;
@ -241,6 +241,6 @@ panel button .button-text {
margin: 0 !important; margin: 0 !important;
} }
#quick-format-dialog { window.citation-dialog {
width: 600px; width: 600px;
} }

View file

@ -115,7 +115,7 @@ describe("Zotero.Integration", function () {
* @param {Number} fieldType * @param {Number} fieldType
* @return {Field[]} * @return {Field[]}
*/ */
convertPlaceholdersToFields: function (codes, placeholderIDs, noteType, fieldType) { convertPlaceholdersToFields: function (codes, noteType, fieldType) {
return codes.map(code => { return codes.map(code => {
let field = new DocumentPluginDummy.Field(this); let field = new DocumentPluginDummy.Field(this);
field.code = code; field.code = code;