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 @@ + + + + + + + + + + + + +