diff --git a/chrome/content/zotero/integration/quickFormat.js b/chrome/content/zotero/integration/quickFormat.js
new file mode 100644
index 000000000..d4f5be640
--- /dev/null
+++ b/chrome/content/zotero/integration/quickFormat.js
@@ -0,0 +1,649 @@
+/*
+ ***** BEGIN LICENSE BLOCK *****
+
+ Copyright © 2009 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 .
+
+ ***** END LICENSE BLOCK *****
+*/
+
+var Zotero_QuickFormat = new function () {
+ var io, qft, qftWindow, qftDocument, qfe,
+ qfb, qfbHeight,
+ referenceBox, referenceHeight,
+ dragX, dragY, curLocator, curLocatorLabel,
+ curIDs = [], curResizer, dragging;
+ const SHOWN_REFERENCES = 7;
+
+ /**
+ * Initialize add citation dialog
+ */
+ this.onLoad = function() {
+ qft = document.getElementById("quick-format-search");
+ qfb = document.getElementById("quick-format-entry");
+ qfbHeight = qfb.scrollHeight;
+ referenceBox = document.getElementById("quick-format-reference-list");
+ qftWindow = qft.contentWindow;
+ qftDocument = qft.contentDocument;
+ qfb.addEventListener("keypress", _onQuickSearchKeyPress, false);
+ qfe = qftDocument.getElementById("quick-format-editor");
+ qfe.focus();
+
+ // Add labels to popup
+ var locators = Zotero.Cite.labels;
+ var menu = document.getElementById("locator-label");
+ var labelList = document.getElementById("locator-label-popup");
+ for each(var locator in locators) {
+ // TODO localize
+ var locatorLabel = locator[0].toUpperCase()+locator.substr(1);
+
+ // add to list of labels
+ var child = document.createElement("menuitem");
+ child.setAttribute("value", locator);
+ child.setAttribute("label", locatorLabel);
+ labelList.appendChild(child);
+ }
+ menu.selectedIndex = 0;
+
+ // load citation data
+ io = window.arguments[0].wrappedJSObject;
+ if(io.citation.citationItems.length) {
+ // hack to get spacing right
+ var evt = qftDocument.createEvent("KeyboardEvent");
+ evt.initKeyEvent("keypress", true, true, qftWindow,
+ 0, 0, 0, 0,
+ 0, " ".charCodeAt(0))
+ qfe.dispatchEvent(evt);
+ window.setTimeout(function() {
+ var node = qfe.firstChild;
+ node.nodeValue = "";
+
+ for(var i=0; i 50) ids = ids.slice(0, 50);
+ var items = Zotero.Items.get(ids);
+ for(var i=0, n=items.length; is
+ var elements = qfe.getElementsByTagName("br");
+ for(var i=0, n=elements.length; i 20) {
+ qft.style.height = (22-16+qfeHeight+(qft.style.height == "22px" ? 2 : -2))+"px";
+ qfe.style.lineHeight = "18px";
+ qft.setAttribute("multiline", true);
+ } else {
+ qft.style.height = "22px";
+ qfe.style.lineHeight = "16px";
+ qft.removeAttribute("multiline");
+ }
+ if(curResizer) curResizer.stop();
+ curResizer = new Resizer(window, null, height, 10, 100);
+ curResizer.animate();
+ }
+
+ /**
+ * Accepts current selection and adds citation
+ */
+ _accept = function() {
+ var nodes = qfe.childNodes;
+ io.citation.citationItems = [];
+ for(var i=0, n=nodes.length; i');
+ event.stopPropagation();
+ }
+
+ /**
+ * Replaces the dummy element with a node to make dropping work
+ */
+ function _onBubbleDrop(event) {
+ window.setTimeout(function() {
+ var el = qftDocument.getElementById("zotero-drag");
+ if(el) {
+ _insertBubble(dragging, el);
+ Zotero.debug(dragging);
+ el.parentNode.removeChild(el);
+ }
+ }, 0);
+ }
+
+ /**
+ * Handle a click on a bubble
+ */
+ function _onBubbleClick(event) {
+ var target = event.target;
+ var panel = document.getElementById("citation-properties");
+ var prefix = document.getElementById("prefix");
+ var suffix = document.getElementById("suffix");
+ var suppressAuthor = document.getElementById("suppress-author");
+ var locatorLabel = document.getElementById("locator-label");
+ var locator = document.getElementById("locator");
+
+ prefix.value = target.citationItem["prefix"] ? target.citationItem["prefix"] : "";
+ suffix.value = target.citationItem["suffix"] ? target.citationItem["suffix"] : "";
+ if(target.citationItem["label"]) {
+ var option = locatorLabel.getElementsByAttribute("value", target.citationItem["label"]);
+ if(option.length) {
+ locatorLabel.selectedItem = option[0];
+ } else {
+ locatorLabel.selectedIndex = 0;
+ }
+ } else {
+ locatorLabel.selectedIndex = 0;
+ }
+ locator.value = target.citationItem["locator"] ? target.citationItem["locator"] : "";
+ suppressAuthor.checked = !!target.citationItem["suppress-author"];
+
+ target.setAttribute("selected", "true");
+ panel.openPopup(target, "after_start",
+ target.clientWidth/2, 0, false, false, event);
+
+ var closeListener = function(event) {
+ panel.removeEventListener("popuphidden", closeListener, false);
+ target.removeAttribute("selected");
+ if(prefix.value) {
+ target.citationItem["prefix"] = prefix.value;
+ } else {
+ delete target.citationItem["prefix"];
+ }
+ if(suffix.value) {
+ target.citationItem["suffix"] = suffix.value;
+ } else {
+ delete target.citationItem["suffix"];
+ }
+ if(locatorLabel.selectedIndex !== 0) {
+ target.citationItem["label"] = locatorLabel.selectedItem.value;
+ } else {
+ delete target.citationItem["label"];
+ }
+ if(locator.value) {
+ target.citationItem["locator"] = locator.value;
+ } else {
+ delete target.citationItem["locator"];
+ }
+ if(suppressAuthor.checked) {
+ target.citationItem["suppress-author"] = true;
+ } else {
+ delete target.citationItem["suppress-author"];
+ }
+ target.value = _buildBubbleString(target.citationItem);
+ }
+ panel.addEventListener("popuphidden", closeListener, false);
+ }
+
+ /**
+ * Called when the user begins to drag the window
+ */
+ this.onDragStart = function(el, event) {
+ dragX = event.clientX;
+ dragY = event.clientY;
+ window.addEventListener("mousemove", _onDrag, false);
+ window.addEventListener("mouseup", function() { window.removeEventListener("mousemove", _onDrag, false) }, false);
+ }
+
+ /**
+ * Called during the window drag
+ */
+ function _onDrag(event) {
+ window.moveTo(event.screenX-dragX, event.screenY-dragY);
+ }
+
+ /**
+ * Makes "Enter" work in the panel
+ */
+ this.onPanelKeyPress = function(event) {
+ if(keyCode === event.DOM_VK_RETURN || keyCode === event.DOM_VK_ENTER) {
+ event.target.hidePopup();
+ }
+ };
+
+ /**
+ * Resizes windows
+ * @constructor
+ */
+ var Resizer = function(window, targetWidth, targetHeight, steps, time) {
+ this.curWidth = window.innerWidth;
+ this.curHeight = window.innerHeight;
+ this.difX = (targetWidth ? targetWidth - this.curWidth : 0);
+ this.difY = (targetHeight ? targetHeight - this.curHeight : 0);
+ this.step = 0;
+ this.steps = steps;
+ this.timeout = time/steps;
+
+ var me = this;
+ this._animateCallback = function() { me.animate() };
+ };
+
+ /**
+ * Performs a step of the animation
+ */
+ Resizer.prototype.animate = function() {
+ if(this.stopped) return;
+ this.step++;
+ window.resizeTo(this.curWidth+Math.round(this.step*this.difX/this.steps),
+ this.curHeight+Math.round(this.step*this.difY/this.steps));
+ if(this.step !== this.steps) {
+ window.setTimeout(this._animateCallback, this.timeout);
+ }
+ };
+
+ /**
+ * Halts resizing
+ */
+ Resizer.prototype.stop = function() {
+ this.stopped = true;
+ };
+}
+
+window.addEventListener("load", Zotero_QuickFormat.onLoad, false);
\ No newline at end of file
diff --git a/chrome/content/zotero/integration/quickFormat.xul b/chrome/content/zotero/integration/quickFormat.xul
new file mode 100644
index 000000000..8f6b18f27
--- /dev/null
+++ b/chrome/content/zotero/integration/quickFormat.xul
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/chrome/content/zotero/xpcom/integration.js b/chrome/content/zotero/xpcom/integration.js
index c75ea060d..3e0519d54 100644
--- a/chrome/content/zotero/xpcom/integration.js
+++ b/chrome/content/zotero/xpcom/integration.js
@@ -1803,7 +1803,11 @@ Zotero.Integration.Session.prototype.editCitation = function(index, noteIndex, c
// citeproc-js style object for use of third-party extension
io.style = this.style;
- this._displayDialog('chrome://zotero/content/integration/addCitationDialog.xul', 'resizable', io);
+ if(Zotero.Prefs.get("integration.quickFormat")) {
+ this._displayDialog('chrome://zotero/content/integration/quickFormat.xul', io);
+ } else {
+ this._displayDialog('chrome://zotero/content/integration/addCitationDialog.xul', 'resizable', io);
+ }
if(io.citation.citationItems.length) { // we have an item
this.addCitation(index, noteIndex, io.citation);
diff --git a/chrome/skin/default/zotero/integration.css b/chrome/skin/default/zotero/integration.css
index ccb809d04..9932650ea 100644
--- a/chrome/skin/default/zotero/integration.css
+++ b/chrome/skin/default/zotero/integration.css
@@ -1,3 +1,34 @@
+/*
+ ***** BEGIN LICENSE BLOCK *****
+
+ Copyright © 2011 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 .
+
+ Parts of this code are derived from mozilla.org code.
+
+ The Initial Developer of this Original Code is Netscape Communications Corporation.
+ Portions created by the Initial Developer are Copyright (C) 1998-1999
+ the Initial Developer. All Rights Reserved.
+
+ ***** END LICENSE BLOCK *****
+*/
+
#up {
list-style-image: url('chrome://zotero/skin/citation-up.png');
}
@@ -58,4 +89,142 @@
#editor {
margin-top: 10px;
max-height: 100px;
+}
+
+.quick-format-title {
+ margin: 0;
+ font-weight: bold;
+ overflow: hidden;
+}
+
+.quick-format-info {
+ margin: 0;
+ overflow: hidden;
+}
+.quick-format-info > label {
+ margin: 0;
+ padding: 0;
+}
+
+.quick-format-bubble {
+ -moz-border-radius: 8px;
+ background-color: #dee7f8;
+ border-style: solid;
+ border-width: 1px;
+ border-color: #a8c0ec;
+ padding: 0 6px 0 6px;
+ margin: -1px 2px 0 2px;
+ -moz-user-select: all;
+}
+
+.quick-format-bubble:hover {
+ background-color: #bbcef1;
+ border-color: #6d95e0;
+}
+
+.quick-format-bubble:hover {
+ background-color: #bbcef1;
+}
+
+.quick-format-bubble[selected="true"] {
+ -moz-border-radius: 8px !important;
+ background-color: #598bec;
+ color: #fff;
+}
+
+#quick-format-search {
+ margin: 0;
+ padding: 0;
+ background: white;
+ height: 22px;
+ padding-top: 0;
+ padding-bottom: 0;
+ -moz-appearance: searchfield;
+}
+
+#quick-format-search[multiline="true"] {
+ padding: 1px 2px 0 18px;
+ border: 1px solid rgba(0, 0, 0, 0.5);
+ border-radius: 8px;
+ -moz-appearance: none;
+}
+
+body {
+ margin: 0 2px 0 2px;
+ padding: 0;
+ font: -moz-field;
+ font-size: 11px;
+ line-height: 18px;
+ overflow: hidden;
+}
+
+.quick-format-item {
+ font-size: 12px;
+ font: -moz-field;
+ -moz-user-focus: normal;
+ padding: 5px;
+ max-height: 39px;
+}
+
+.quick-format-item:not(:last-child) {
+ border-style: solid;
+ border-width: 0 0 1px 0;
+ border-color: #BBB;
+}
+
+richlistitem[selected="true"] {
+ background: Highlight;
+ color: HighlightText;
+}
+
+#quick-format-entry {
+ background: -moz-linear-gradient(-90deg, rgb(243,123,119) 0, rgb(180,47,38) 50%, rgb(156,36,27) 50%);
+ -moz-border-radius:15px;
+ padding: 10px;
+}
+
+#quick-format-reference-list {
+ margin: 0 15px 0 15px;
+ background: white;
+ opacity: 0.9;
+ -moz-user-focus: ignore;
+}
+
+#citation-properties menulist {
+ -moz-appearance: none; color: #fff;
+ text-shadow: 0 -1px 0 rgba(0,0,0,.5);
+ border-radius: 12px;
+ border: 1px solid rgba(0,0,0,.65);
+ background: -moz-linear-gradient(rgba(110,110,110,.9), rgba(70,70,70,.9) 49%, rgba(50,50,50,.9) 51%, rgba(40,40,40,.9));
+ box-shadow: inset 0 1px 0 rgba(255,255,255,.2), inset 0 0 1px rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);
+ background-clip: padding-box;
+ background-origin: padding-box;
+ padding: 2px 9px;
+ border-radius: 3px;
+ min-height: 22px;
+ -moz-padding-start: 4px;
+ -moz-padding-end: 0;
+}
+
+#citation-properties menulist:-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;
+}
+
+#citation-properties menulist[open="true"],
+#citation-properties menulist:hover:active {
+ background: -moz-linear-gradient(rgba(40,40,40,.9), rgba(70,70,70,.9));
+ box-shadow: inset 0 0 3px rgba(0,0,0,.2), inset 0 1px 7px rgba(0,0,0,.4), 0 1px 0 rgba(255,255,255,.1);
+}
+
+#citation-properties menulist > .menulist-dropmarker {
+ -moz-appearance: none;
+ display: -moz-box;
+ background-color: transparent;
+ border: 0;
+ margin: 0;
+ padding: 0;
+}
+
+#citation-properties menulist > .menulist-dropmarker > .dropmarker-icon {
+ list-style-image: url("chrome://browser/skin/hud-style-dropmarker-double-arrows.png");
}
\ No newline at end of file
diff --git a/defaults/preferences/zotero.js b/defaults/preferences/zotero.js
index 7fb63053c..cfa07f120 100644
--- a/defaults/preferences/zotero.js
+++ b/defaults/preferences/zotero.js
@@ -105,6 +105,7 @@ pref("extensions.zotero.export.quickCopy.compatibility.word", false);
// Integration settings
pref("extensions.zotero.integration.port", 50001);
pref("extensions.zotero.integration.autoRegenerate", -1); // -1 = ask; 0 = no; 1 = yes
+pref("extensions.zotero.integration.quickFormat", false);
// Connector settings
pref("extensions.zotero.httpServer.enabled", false); // TODO enabled for testing only