diff --git a/.gitmodules b/.gitmodules index f70921805c..96573462c7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -29,3 +29,15 @@ [submodule "resource/SingleFile"] path = resource/SingleFile url = https://github.com/gildas-lormeau/SingleFile.git +[submodule "pdf-reader"] + path = pdf-reader + url = https://github.com/zotero/pdf-reader.git + branch = master +[submodule "pdf-worker"] + path = pdf-worker + url = https://github.com/zotero/pdf-worker.git + branch = master +[submodule "zotero-note-editor"] + path = zotero-note-editor + url = https://github.com/zotero/zotero-note-editor.git + branch = master diff --git a/chrome/content/zotero/bindings/noteeditor.xml b/chrome/content/zotero/bindings/noteeditor.xml index f5f769c58c..efc309c138 100644 --- a/chrome/content/zotero/bindings/noteeditor.xml +++ b/chrome/content/zotero/bindings/noteeditor.xml @@ -1,39 +1,39 @@ - - + + - + "view" ed.setMode('readonly')); - } - break; - - case 'edit': - if (this.noteField) { - this.noteField.onInit(ed => ed.setMode('design')); - } - this.editable = true; - this.saveOnEdit = true; - this.parentClickHandler = this.selectParent; - this.keyDownHandler = this.handleKeyDown; - this.commandHandler = this.save; - this.displayTags = true; - this.displayRelated = true; - break; - - default: - throw ("Invalid mode '" + val + "' in noteeditor.xml"); - } - - this._mode = val; - document.getAnonymousNodes(this)[0].setAttribute('mode', val); - this._id('links-box').mode = val; - ]]> + // Duplicate default property settings here + this.editable = false; + this.saveOnEdit = false; + this.displayTags = false; + this.displayRelated = false; + this.displayButton = false; + + switch (val) { + case 'view': + case 'merge': + this.editable = false; + break; + + case 'edit': + this.editable = true; + this.saveOnEdit = true; + this.parentClickHandler = this.selectParent; + this.keyDownHandler = this.handleKeyDown; + this.commandHandler = this.save; + this.displayTags = true; + this.displayRelated = true; + break; + + default: + throw ("Invalid mode '" + val + "' in noteeditor.xml"); + } + + this._mode = val; + document.getAnonymousNodes(this)[0].setAttribute('mode', val); + this._id('links-box').mode = val; + this._id('links-container').hidden = !(this.displayTags && this.displayRelated); + this._id('links-box').refresh(); + ]]> - + @@ -102,31 +166,59 @@ ]]> - - - + + return (async () => { + // `item` field can be set before the constructor is called + // (which happens in the merge dialog i.e.), therefore we wait for + // the initialization + let n = 0; + while (!this._initialized && !this._destroyed) { + if (n >= 1000) { + throw new Error('Waiting for noteeditor initialization failed'); + } + await Zotero.Promise.delay(10); + n++; + } + + // The binding can also be immediately destrcutred + // (which also happens in the marge dialog) + if (this._destroyed) { + return; + } + + if (!val) this._item = null; + if (this._item && this._item.id === val.id) return; + + this._lastHtmlValue = val.getNote(); + + this._editor = new Zotero.NoteEditor(); + this._editor.init({ + item: val, + window: document.getAnonymousElementByAttribute(this, "anonid", "rt-view1").contentWindow, + readOnly: !this.editable, + onNavigate: this._navigateHandler + }); + + this._item = val; + + var parentKey = this._item.parentKey; + if (parentKey) { + this.parentItem = Zotero.Items.getByLibraryAndKey(this._item.libraryID, parentKey); + } + + this._id('links-box').item = this._item; + })(); + ]]> - + - - - - + + + + + + + - - - - - - - - + - - - - - - - - - - - - - - + + return (async () => { + + })(); + ]]> - + { - if (!noteField.hasFocus()) { - document.getElementById(id).focus(); - } - }, 0); - } - return; - } - - break; - } - ]]> - - - - - - { + // if (!noteField.hasFocus()) { + // document.getElementById(id).focus(); + // } + // }, 0); + // } + // return; + // } + // + // break; + // } ]]> - - + + - + { + if (this._iframe && this._iframe.contentWindow) { + this._iframe.focus(); + this._editor.focus(); + } + + }, 500); + ]]> - + - + - + - - + + - + + this.id('related').mode = val; + this.id('tags').mode = val; + ]]> + this._parentItem = val; + + var parentText = this.id('parentText'); + if (parentText.firstChild) { + parentText.removeChild(parentText.firstChild); + } + + if (this._parentItem && this.getAttribute('notitle') != '1') { + this.id('parent-row').hidden = undefined; + this.id('parentLabel').value = Zotero.getString('pane.item.parentItem'); + parentText.appendChild(document.createTextNode(this._parentItem.getDisplayTitle(true))); + } + ]]> + this.id('tags').reload(); + var x = this.boxObject.screenX; + var y = this.boxObject.screenY; + this.id('tagsPopup').openPopupAtScreen(x, y, false); + + // If editable and no existing tags, open new empty row + var tagsBox = this.id('tags'); + if (tagsBox.mode == 'edit' && tagsBox.count == 0) { + this.id('tags').newTag(); + } + ]]> - + + this.updateTagsSummary(); + this.updateRelatedSummary(); + ]]> - + + var v = this.id('tags').summary; + + if (!v || v == "") { + v = "[" + Zotero.getString('pane.item.noteEditor.clickHere') + "]"; + } + + this.id('tagsLabel').value = Zotero.getString('itemFields.tags') + + Zotero.getString('punctuation.colon'); + this.id('tagsClick').value = v; + ]]> 0) { - var x = this.boxObject.screenX; - var y = this.boxObject.screenY; - this.id('relatedPopup').openPopupAtScreen(x, y, false); - } - else { - this.id('related').add(); - } - ]]> + var relatedList = this.item.relatedItems; + if (relatedList.length > 0) { + var x = this.boxObject.screenX; + var y = this.boxObject.screenY; + this.id('relatedPopup').openPopupAtScreen(x, y, false); + } + else { + this.id('related').add(); + } + ]]> + var v = this.id('related').summary; + + if (!v || v == "") { + v = "[" + Zotero.getString('pane.item.noteEditor.clickHere') + "]"; + } + + this.id('relatedLabel').value = Zotero.getString('itemFields.related') + + Zotero.getString('punctuation.colon'); + this.id('relatedClick').value = v; + ]]> + + if (document.getElementById('zotero-pane')) { + var zp = ZoteroPane; + } + else { + var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"] + .getService(Components.interfaces.nsIWindowMediator); + + var lastWin = wm.getMostRecentWindow("navigator:browser"); + + if (!lastWin) { + var lastWin = window.open(); + } + + if (lastWin.ZoteroOverlay && !lastWin.ZoteroPane.isShowing()) { + lastWin.ZoteroOverlay.toggleDisplay(true); + } + + var zp = lastWin.ZoteroPane; + } + + Zotero.spawn(function* () { + var parentID = this.item.parentID; + yield zp.clearQuicksearch(); + zp.selectItem(parentID); + }, this); + ]]> @@ -541,15 +487,18 @@ - + - + @@ -562,17 +511,17 @@ seems to get triggered by these events for reasons that are less than clear) so that we can manually refresh the popup if it's open after autocomplete is used to prevent it from becoming unresponsive - + Note: Code in tagsbox.xml is dependent on the DOM path between the tagsbox and tagsLabel above, so be sure to update fixPopup() if it changes --> + onpopupshown="if (!document.commandDispatcher.focusedElement || document.commandDispatcher.focusedElement.tagName=='xul:label'){ /* DEBUG: it would be nice to make this work -- if (this.firstChild.count==0){ this.firstChild.newTag(); } */ this.setAttribute('showing', 'true'); }" + onpopuphidden="if (!document.commandDispatcher.focusedElement || document.commandDispatcher.focusedElement.tagName=='xul:label'){ this.setAttribute('showing', 'false'); }"> - \ No newline at end of file + diff --git a/chrome/content/zotero/containers/containers.xul b/chrome/content/zotero/containers/containers.xul index bb5b6f9d54..1ed3952f12 100644 --- a/chrome/content/zotero/containers/containers.xul +++ b/chrome/content/zotero/containers/containers.xul @@ -26,9 +26,11 @@ + + \ No newline at end of file diff --git a/chrome/content/zotero/containers/noteEditor.xul b/chrome/content/zotero/containers/noteEditor.xul new file mode 100644 index 0000000000..e0c0d45b35 --- /dev/null +++ b/chrome/content/zotero/containers/noteEditor.xul @@ -0,0 +1,35 @@ + + + %globalDTD; + %zoteroDTD; + ]> + + + + + + \ No newline at end of file diff --git a/chrome/content/zotero/containers/noteEditorContainer.js b/chrome/content/zotero/containers/noteEditorContainer.js new file mode 100644 index 0000000000..6411442214 --- /dev/null +++ b/chrome/content/zotero/containers/noteEditorContainer.js @@ -0,0 +1,594 @@ +class NoteEditor { + constructor() { + this.instanceID = Zotero.Utilities.randomString(); + Zotero.Notes.editorInstances.push(this); + Zotero.debug('Creating a new editor instance'); + } + + async init(options) { + this.id = options.item.id; + + this.item = options.item; + // this._onNavigate = options.onNavigate; + this.saveOnEdit = true; + this.state = options.state; + this.citations = []; + this.disableSaving = false; + this._readOnly = options.readOnly; + this.window = options.window; + + await this.waitForEditor(); + // Zotero.Notes.updateURIs(h1); + + // Run Cut/Copy/Paste with chrome privileges + this.window.wrappedJSObject.zoteroExecCommand = function (doc, command, ui, value) { + // Is that safe enough? + if (!['cut', 'copy', 'paste'].includes(command)) { + return; + } + return doc.execCommand(command, ui, value); + } + + this.window.addEventListener('message', this.listener); + this.quickFormatWindow = null; + let data = this.state ? { state: this.state } : { html: this.item.getNote() }; + this.postMessage({ + op: 'init', ...data, + libraryId: this.item.libraryID, + key: this.item.key, + readOnly: this._readOnly + }); + } + + uninit() { + this.window.removeEventListener('message', this.listener); + let index = Zotero.Notes.editorInstances.indexOf(this); + if (index >= 0) { + Zotero.Notes.editorInstances.splice(index, 1); + } + } + + async waitForEditor() { + let n = 0; + while (!this.window) { + if (n >= 1000) { + throw new Error('Waiting for editor failed '); + } + await Zotero.Promise.delay(10); + n++; + } + } + + postMessage(message) { + this.window.postMessage({ instanceId: this.instanceID, message }, '*'); + } + + listener = async (e) => { + if (e.data.instanceId !== this.instanceID) { + return; + } + // Zotero.debug('Message received from editor ' + e.data.instanceId + ' ' + this.instanceID + ' ' + e.data.message.op); + + let message = e.data.message; + + if (message.op === 'getItemData') { + let parent = message.parent; + let item = await Zotero.Items.getAsync(message.itemId); + if (parent && item && item.parentID) { + item = await Zotero.Items.getAsync(item.parentID); + } + if (item) { + let data = { + uri: Zotero.URI.getItemURI(item), + backupText: this.getBackupStr(item) + }; + } + } + else if (message.op === 'insertObject') { + let { type, data, pos } = message; + + if (type === 'zotero/item') { + let ids = data.split(',').map(id => parseInt(id)); + let citations = []; + for (let id of ids) { + let item = await Zotero.Items.getAsync(id); + if (!item) { + continue; + } + citations.push({ + citationItems: [{ + uri: Zotero.URI.getItemURI(item), + backupText: this.getBackupStr(item) + }], + properties: {} + }); + } + this.postMessage({ op: 'insertCitations', citations, pos }); + } + else if (type === 'zotero/annotation') { + let annotations = JSON.parse(data); + let list = []; + for (let annotation of annotations) { + let attachmentItem = await Zotero.Items.getAsync(annotation.itemId); + if (!attachmentItem) { + continue; + } + let citationItem = attachmentItem.parentID && await Zotero.Items.getAsync(attachmentItem.parentID) || attachmentItem; + annotation.uri = Zotero.URI.getItemURI(attachmentItem); + let citation = { + citationItems: [{ + uri: Zotero.URI.getItemURI(citationItem), + backupText: this.getBackupStr(citationItem), + locator: annotation.pageLabel + }], + properties: {} + }; + list.push({ annotation, citation }); + } + this.postMessage({ op: 'insertAnnotationsAndCitations', list, pos }); + } + } + else if (message.op === 'navigate') { + if (this._onNavigate) { + this._onNavigate(message.uri, { position: message.position }); + } + else { + await Zotero.Viewer.openURI(message.uri, { position: message.position }); + } + } + else if (message.op === 'openURL') { + var zp = typeof ZoteroPane !== 'undefined' ? ZoteroPane : window.opener.ZoteroPane; + zp.loadURI(message.url); + } + else if (message.op === 'showInLibrary') { + let zp = Zotero.getActiveZoteroPane(); + if (zp) { + let item = await Zotero.URI.getURIItem(message.itemURI); + if (item) { + zp.selectItems([item.id]); + let win = Zotero.getMainWindow(); + if (win) { + win.focus(); + } + } + } + } + else if (message.op === 'update') { + this.save(message.noteData); + } + else if (message.op === 'getFormattedCitations') { + let formattedCitations = await this.getFormattedCitations(message.citations); + for (let newCitation of message.citations) { + if (!this.citations.find(citation => citation.id === newCitation.id)) { + this.citations.push(newCitation); + } + } + this.postMessage({ + op: 'setFormattedCitations', + formattedCitations + }); + } + else if (message.op === 'quickFormat') { + let id = message.id; + let citation = message.citation; + citation = JSON.parse(JSON.stringify(citation)); + let availableCitationItems = []; + for (let citationItem of citation.citationItems) { + let item = await Zotero.URI.getURIItem(citationItem.uri); + if (item) { + availableCitationItems.push({ ...citationItem, id: item.id }); + } + } + citation.citationItems = availableCitationItems; + let libraryID = this.item.libraryID; + this.quickFormatDialog(id, citation, [libraryID]); + } + else if (message.op === 'updateImages') { + for (let image of message.added) { + let blob = this.dataURLtoBlob(image.dataUrl); + let imageAttachment = await Zotero.Attachments.importEmbeddedImage({ + blob, + parentItemID: this.item.id, + itemKey: image.attachmentKey, + saveOptions: { + notifierData: { + noteEditorID: this.instanceID + } + } + }); + } + let attachmentItems = this.item.getAttachments().map(id => Zotero.Items.get(id)); + let abandonedItems = attachmentItems.filter(item => !message.all.includes(item.key)); + for (let item of abandonedItems) { + await item.eraseTx(); + } + } + else if (message.op === 'requestImage') { + let { attachmentKey } = message; + var item = Zotero.Items.getByLibraryAndKey(this.item.libraryID, attachmentKey); + if (!item) return; + let path = await item.getFilePathAsync(); + let buf = await OS.File.read(path, {}); + buf = new Uint8Array(buf).buffer; + let dataURL = 'data:' + item.attachmentContentType + ';base64,' + this.arrayBufferToBase64(buf); + this.postMessage({ + op: 'updateImage', + attachmentKey, + dataUrl: dataURL + }); + } + else if (message.op === 'popup') { + this.openPopup(message.x, message.y, message.items); + } + } + + openPopup(x, y, items) { + let popup = document.getElementById('editor-menu'); + popup.hidePopup(); + + while (popup.firstChild) { + popup.removeChild(popup.firstChild); + } + + for (let item of items) { + let menuitem = document.createElement('menuitem'); + menuitem.setAttribute('value', item[0]); + menuitem.setAttribute('label', item[1]); + menuitem.addEventListener('command', () => { + this.postMessage({ + op: 'contextMenuAction', + ctxAction: item[0], + payload: item.payload + }); + }); + popup.appendChild(menuitem); + } + + popup.openPopupAtScreen(x, y, true); + } + + async save(noteData) { + if (!noteData) return; + let { state, html } = noteData; + if (html === undefined) return; + try { + if (this.disableSaving) { + Zotero.debug('Saving is disabled'); + return; + } + + if (this._readOnly) { + Zotero.debug('Not saving read-only note'); + return; + } + if (html === null) { + Zotero.debug('Note value not available -- not saving', 2); + return; + } + // Update note + if (this.item) { + let changed = this.item.setNote(html); + if (changed && this.saveOnEdit) { + // this.noteField.changed = false; + await this.item.saveTx({ + notifierData: { + noteEditorID: this.instanceID, + state + } + }); + } + } + else { + // Create a new note + var item = new Zotero.Item('note'); + if (this.parentItem) { + item.libraryID = this.parentItem.libraryID; + } + item.setNote(html); + if (this.parentItem) { + item.parentKey = this.parentItem.key; + } + if (this.saveOnEdit) { + var id = await item.saveTx(); + + if (!this.parentItem && this.collection) { + this.collection.addItem(id); + } + } + } + } + catch (e) { + Zotero.logError(e); + if (this.hasAttribute('onerror')) { + let fn = new Function('', this.getAttribute('onerror')); + fn.call(this) + } + if (this.onError) { + this.onError(e); + } + } + } + + focus = () => { + + } + + getNoteDataSync = () => { + if (!this._readOnly && !this.disableSaving && this.window) { + return this.window.wrappedJSObject.getDataSync(); + } + return null; + }; + + /** + * Builds the string to go inside a bubble + */ + _buildBubbleString(citationItem, str) { + // Locator + if (citationItem.locator) { + if (citationItem.label) { + // TODO localize and use short forms + var label = citationItem.label; + } + else if (/[\-–,]/.test(citationItem.locator)) { + var label = 'pp.'; + } + else { + var label = 'p.'; + } + + str += ', ' + label + ' ' + citationItem.locator; + } + + // Prefix + if (citationItem.prefix && Zotero.CiteProc.CSL.ENDSWITH_ROMANESQUE_REGEXP) { + str = citationItem.prefix + + (Zotero.CiteProc.CSL.ENDSWITH_ROMANESQUE_REGEXP.test(citationItem.prefix) ? ' ' : '') + + str; + } + + // Suffix + if (citationItem.suffix && Zotero.CiteProc.CSL.STARTSWITH_ROMANESQUE_REGEXP) { + str += (Zotero.CiteProc.CSL.STARTSWITH_ROMANESQUE_REGEXP.test(citationItem.suffix) ? ' ' : '') + + citationItem.suffix; + } + + return str; + } + + async updateCitationsForURIs(uris) { + let citations = this.citations + .filter(citation => citation.citationItems + .some(citationItem => uris.includes(citationItem.uri))); + + if (citations.length) { + let formattedCitations = await this.getFormattedCitations(citations); + this.postMessage({ + op: 'setFormattedCitations', + formattedCitations + }); + } + } + + getFormattedCitations = async (citations) => { + let formattedCitations = {}; + for (let citation of citations) { + formattedCitations[citation.id] = await this.getFormattedCitation(citation); + } + return formattedCitations; + } + + getFormattedCitation = async (citation) => { + let formattedItems = []; + for (let citationItem of citation.citationItems) { + let item = await Zotero.URI.getURIItem(citationItem.uri); + if (item && !item.deleted) { + formattedItems.push(this._buildBubbleString(citationItem, this.getBackupStr(item))); + } + else { + let formattedItem = this._buildBubbleString(citationItem, citationItem.backupText); + formattedItem = `${formattedItem}`; + formattedItems.push(formattedItem); + } + } + return formattedItems.join(';'); + } + + getBackupStr(item) { + var str = item.getField('firstCreator'); + + // Title, if no creator (getDisplayTitle in order to get case, e-mail, statute which don't have a title field) + if (!str) { + str = Zotero.getString('punctuation.openingQMark') + item.getDisplayTitle() + Zotero.getString('punctuation.closingQMark'); + } + + // Date + var date = item.getField('date', true, true); + if (date && (date = date.substr(0, 4)) !== '0000') { + str += ', ' + date; + } + return str; + } + + arrayBufferToBase64(buffer) { + var binary = ''; + var bytes = new Uint8Array(buffer); + var len = bytes.byteLength; + for (var i = 0; i < len; i++) { + binary += String.fromCharCode(bytes[i]); + } + return self.btoa(binary); + } + + dataURLtoBlob(dataurl) { + let parts = dataurl.split(','); + let mime = parts[0].match(/:(.*?);/)[1]; + if (parts[0].indexOf('base64') !== -1) { + let bstr = atob(parts[1]); + let n = bstr.length; + let u8arr = new Uint8Array(n); + while (n--) { + u8arr[n] = bstr.charCodeAt(n); + } + + return new self.Blob([u8arr], { type: mime }); + } + return null; + } + + quickFormatDialog(id, citationData, filterLibraryIDs) { + let that = this; + let win; + /** + * Citation editing functions and propertiesaccessible to quickFormat.js and addCitationDialog.js + */ + let CI = function (citation, sortable, fieldIndexPromise, citationsByItemIDPromise, previewFn) { + this.citation = citation; + this.sortable = sortable; + this.filterLibraryIDs = filterLibraryIDs; + this.disableClassicDialog = true; + } + + CI.prototype = { + /** + * Execute a callback with a preview of the given citation + * @return {Promise} A promise resolved with the previewed citation string + */ + preview: function () { + Zotero.debug('CI: preview') + }, + + /** + * Sort the citationItems within citation (depends on this.citation.properties.unsorted) + * @return {Promise} A promise resolved with the previewed citation string + */ + sort: function () { + Zotero.debug('CI: sort') + return async function () { + }; + }, + + /** + * Accept changes to the citation + * @param {Function} [progressCallback] A callback to be run when progress has changed. + * Receives a number from 0 to 100 indicating current status. + */ + accept: async function (progressCallback) { + Zotero.debug('CI: accept'); + if (progressCallback) progressCallback(100); + + if (win) { + win.close(); + } + + let citation = { + citationItems: this.citation.citationItems, + properties: this.citation.properties + } + + for (let citationItem of citation.citationItems) { + let itm = await Zotero.Items.getAsync(citationItem.id); + delete citationItem.id; + citationItem.uri = Zotero.URI.getItemURI(itm); + citationItem.backupText = that.getBackupStr(itm); + } + + let formattedCitation = await that.getFormattedCitation(citation); + + if (this.citation.citationItems.length) { + that.postMessage({ + op: 'setCitation', + id, citation, formattedCitation + }); + } + }, + + /** + * Get a list of items used in the current document + * @return {Promise} A promise resolved by the items + */ + getItems: async function () { + Zotero.debug('CI: getItems') + return []; + } + } + + + let Citation = class { + constructor(citationField, data, noteIndex) { + if (!data) { + data = { citationItems: [], properties: {} }; + } + this.citationID = data.citationID; + this.citationItems = data.citationItems; + this.properties = data.properties; + this.properties.noteIndex = noteIndex; + + this._field = citationField; + } + + /** + * Load citation item data + * @param {Boolean} [promptToReselect=true] - will throw a MissingItemException if false + * @returns {Promise{Number}} + * - Zotero.Integration.NO_ACTION + * - Zotero.Integration.UPDATE + * - Zotero.Integration.REMOVE_CODE + * - Zotero.Integration.DELETE + */ + loadItemData() { + Zotero.debug('Citation: loadItemData'); + } + + async handleMissingItem(idx) { + Zotero.debug('Citation: handleMissingItem'); + } + + async prepareForEditing() { + Zotero.debug('Citation: prepareForEditing'); + } + + toJSON() { + Zotero.debug('Citation: toJSON'); + } + + /** + * Serializes the citation into CSL code representation + * @returns {string} + */ + serialize() { + Zotero.debug('Citation: serialize'); + } + }; + + if (that.quickFormatWindow) { + that.quickFormatWindow.close(); + that.quickFormatWindow = null; + } + + let citation = new Citation(); + citation.citationItems = citationData.citationItems; + citation.properties = citationData.properties; + let styleID = Zotero.Prefs.get('export.lastStyle'); + let locale = Zotero.Prefs.get('export.lastLocale'); + let csl = Zotero.Styles.get(styleID).getCiteProc(locale); + var io = new CI(citation, csl.opt.sort_citations); + + + var allOptions = 'chrome,centerscreen'; + // without this, Firefox gets raised with our windows under Compiz + if (Zotero.isLinux) allOptions += ',dialog=no'; + // if(options) allOptions += ','+options; + + var mode = (!Zotero.isMac && Zotero.Prefs.get('integration.keepAddCitationDialogRaised') + ? 'popup' : 'alwaysRaised') + ',resizable=false,centerscreen'; + + win = that.quickFormatWindow = Components.classes['@mozilla.org/embedcomp/window-watcher;1'] + .getService(Components.interfaces.nsIWindowWatcher) + .openWindow(null, 'chrome://zotero/content/integration/quickFormat.xul', '', mode, { + wrappedJSObject: io + }); + } +} + +Zotero.NoteEditor = NoteEditor; diff --git a/chrome/content/zotero/integration/quickFormat.js b/chrome/content/zotero/integration/quickFormat.js index bf32e7cd4f..fd3bffbab8 100644 --- a/chrome/content/zotero/integration/quickFormat.js +++ b/chrome/content/zotero/integration/quickFormat.js @@ -56,6 +56,10 @@ var Zotero_QuickFormat = new function () { Zotero.debug(`Quick Format received citation:`); Zotero.debug(JSON.stringify(io.citation.toJSON())); + if (io.disableClassicDialog) { + document.getElementById('classic-view').hidden = true; + } + // Only hide chrome on Windows or Mac if(Zotero.isMac) { document.documentElement.setAttribute("drawintitlebar", true); @@ -309,6 +313,10 @@ var Zotero_QuickFormat = new function () { .forEach(feed => s.addCondition("libraryID", "isNot", feed.libraryID)); s.addCondition("quicksearch-titleCreatorYear", "contains", str); s.addCondition("itemType", "isNot", "attachment"); + if (io.filterLibraryIDs) { + io.filterLibraryIDs.forEach(id => s.addCondition("libraryID", "is", id)); + } + haveConditions = true; } } diff --git a/chrome/content/zotero/itemPane.js b/chrome/content/zotero/itemPane.js index 904da3bfc9..33a7f11d88 100644 --- a/chrome/content/zotero/itemPane.js +++ b/chrome/content/zotero/itemPane.js @@ -259,25 +259,25 @@ var ZoteroItemPane = new function() { _selectedNoteID = item.id; // If an external note window is open for this item, don't show the editor - if (ZoteroPane.findNoteWindow(item.id)) { - this.showNoteWindowMessage(); - return; - } + // if (ZoteroPane.findNoteWindow(item.id)) { + // this.showNoteWindowMessage(); + // return; + // } var noteEditor = document.getElementById('zotero-note-editor'); // If loading new or different note, disable undo while we repopulate the text field // so Undo doesn't end up clearing the field. This also ensures that Undo doesn't // undo content from another note into the current one. - var clearUndo = noteEditor.item ? noteEditor.item.id != item.id : false; + // var clearUndo = noteEditor.item ? noteEditor.item.id != item.id : false; noteEditor.mode = editable ? 'edit' : 'view'; noteEditor.parent = null; noteEditor.item = item; - if (clearUndo) { - noteEditor.clearUndo(); - } + // if (clearUndo) { + // noteEditor.clearUndo(); + // } document.getElementById('zotero-view-note-button').hidden = !editable; document.getElementById('zotero-item-pane-content').selectedIndex = 2; @@ -285,7 +285,7 @@ var ZoteroItemPane = new function() { this.showNoteWindowMessage = function () { - ZoteroPane.setItemPaneMessage(Zotero.getString('pane.item.notes.editingInWindow')); + // ZoteroPane.setItemPaneMessage(Zotero.getString('pane.item.notes.editingInWindow')); }; diff --git a/chrome/content/zotero/itemPane.xul b/chrome/content/zotero/itemPane.xul index 81796b2649..a2d61c11b6 100644 --- a/chrome/content/zotero/itemPane.xul +++ b/chrome/content/zotero/itemPane.xul @@ -115,7 +115,7 @@ --> + onerror="return;ZoteroPane.displayErrorMessage(); /*this.mode = 'view'*/"/>