mirror of
https://github.com/zotero/zotero.git
synced 2026-10-08 03:08:19 +00:00
Closes #331, Allow phrase searching from quicksearch
Closes #318, Use word index if available to narrow search scope of fulltext scanner Closes #420, Delete local version of remote scrapers with priority 0 on update - Changed ZoteroPane.buildItemContextMenu() to make updates easier - Changed inTransaction repository update delay to 10 minutes - Fix fulltext search of text files with MIME types that don't begin with 'text/' - ZoteroPane.setItemsPaneMessage(msg) and ZoteroPane.clearItemsPaneMessage() - New textbox binding conditional-timed-textbox to run a test (e.g. on the value) before triggering command - Fulltext content search now supports ANY/ALL instead of just AND (I think)
This commit is contained in:
parent
875ceea852
commit
edfe4b73be
9 changed files with 372 additions and 109 deletions
69
chrome/content/zotero/bindings/conditional-timed-textbox.xml
Normal file
69
chrome/content/zotero/bindings/conditional-timed-textbox.xml
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright (c) 2006 Center for History and New Media
|
||||
George Mason University, Fairfax, Virginia, USA
|
||||
http://chnm.gmu.edu
|
||||
|
||||
Licensed under the Educational Community License, Version 1.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.opensource.org/licenses/ecl1.php
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
***** END LICENSE BLOCK *****
|
||||
-->
|
||||
|
||||
<bindings xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<binding id="conditional-timed-textbox" extends="chrome://global/content/bindings/textbox.xml#timed-textbox">
|
||||
<implementation>
|
||||
<field name="skipTimeout"/>
|
||||
<field name="testcode"/>
|
||||
<field name="onbeforefire"/>
|
||||
<field name="onafterfire"/>
|
||||
<field name="ontestfail"/>
|
||||
|
||||
<method name="_fireCommand">
|
||||
<parameter name="me"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (me.skipTimeout) {
|
||||
me.skipTimeout = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var code = me.getAttribute('testcode');
|
||||
if (!code.length) {
|
||||
code = true;
|
||||
}
|
||||
|
||||
if (eval(code)) {
|
||||
if (me.getAttribute('onbeforefire')) {
|
||||
eval(me.getAttribute('onbeforefire'));
|
||||
}
|
||||
me._timer = null;
|
||||
me.doCommand();
|
||||
if (me.getAttribute('onafterfire')) {
|
||||
eval(me.getAttribute('onafterfire'));
|
||||
}
|
||||
}
|
||||
else {
|
||||
eval(me.getAttribute('ontestfail'));
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
</bindings>
|
||||
|
|
@ -44,6 +44,8 @@ var ZoteroPane = new function()
|
|||
this.deleteSelectedItem = deleteSelectedItem;
|
||||
this.deleteSelectedCollection = deleteSelectedCollection;
|
||||
this.editSelectedCollection = editSelectedCollection;
|
||||
this.handleSearchKeypress = handleSearchKeypress;
|
||||
this.handleSearchInput = handleSearchInput;
|
||||
this.search = search;
|
||||
this.getCollectionsView = getCollectionsView;
|
||||
this.getItemsView = getItemsView;
|
||||
|
|
@ -56,6 +58,8 @@ var ZoteroPane = new function()
|
|||
this.buildCollectionContextMenu = buildCollectionContextMenu;
|
||||
this.buildItemContextMenu = buildItemContextMenu;
|
||||
this.onDoubleClick = onDoubleClick;
|
||||
this.setItemsPaneMessage = setItemsPaneMessage;
|
||||
this.clearItemsPaneMessage = clearItemsPaneMessage;
|
||||
this.contextPopupShowing = contextPopupShowing;
|
||||
this.openNoteWindow = openNoteWindow;
|
||||
this.toggleAbstractForSelectedItem = toggleAbstractForSelectedItem
|
||||
|
|
@ -230,7 +234,6 @@ var ZoteroPane = new function()
|
|||
function newSearch()
|
||||
{
|
||||
var s = new Zotero.Search();
|
||||
s.addCondition('title','contains','');
|
||||
|
||||
var untitled = Zotero.getString('pane.collections.untitled');
|
||||
untitled = Zotero.DB.getNextName('savedSearches', 'savedSearchName',
|
||||
|
|
@ -527,6 +530,36 @@ var ZoteroPane = new function()
|
|||
}
|
||||
|
||||
|
||||
function handleSearchKeypress(textbox, event) {
|
||||
// Events that turn find-as-you-type on
|
||||
if (event.keyCode == event.DOM_VK_ESCAPE) {
|
||||
textbox.value = '';
|
||||
ZoteroPane.setItemsPaneMessage(Zotero.getString('searchInProgress'));
|
||||
setTimeout("document.getElementById('zotero-tb-search').doCommand('cmd_zotero_search'); ZoteroPane.clearItemsPaneMessage();", 1);
|
||||
}
|
||||
else if (event.keyCode == event.DOM_VK_RETURN ||
|
||||
event.keyCode == event.DOM_VK_ENTER) {
|
||||
textbox.skipTimeout = true;
|
||||
ZoteroPane.setItemsPaneMessage(Zotero.getString('searchInProgress'));
|
||||
setTimeout("document.getElementById('zotero-tb-search').doCommand('cmd_zotero_search'); ZoteroPane.clearItemsPaneMessage();", 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function handleSearchInput(textbox, event) {
|
||||
// This is the new length, except, it seems, when the change is a
|
||||
// result of Undo or Redo
|
||||
if (!textbox.value.length) {
|
||||
textbox.skipTimeout = true;
|
||||
ZoteroPane.setItemsPaneMessage(Zotero.getString('searchInProgress'));
|
||||
setTimeout("document.getElementById('zotero-tb-search').doCommand('cmd_zotero_search'); ZoteroPane.clearItemsPaneMessage();", 1);
|
||||
}
|
||||
else if (textbox.value.indexOf('"') != -1) {
|
||||
ZoteroPane.setItemsPaneMessage(Zotero.getString('advancedSearchMode'));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function search()
|
||||
{
|
||||
if(itemsView)
|
||||
|
|
@ -564,7 +597,7 @@ var ZoteroPane = new function()
|
|||
function selectItem(itemID, inLibrary)
|
||||
{
|
||||
if (!itemID) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
if(itemsView)
|
||||
{
|
||||
|
|
@ -769,19 +802,37 @@ var ZoteroPane = new function()
|
|||
|
||||
function buildItemContextMenu()
|
||||
{
|
||||
var m = {
|
||||
showInLibrary: 0,
|
||||
sep1: 1,
|
||||
addNote: 2,
|
||||
attachSnapshot: 3,
|
||||
attachLink: 4,
|
||||
toggleAbstract: 5,
|
||||
sep2: 6,
|
||||
deleteItem: 7,
|
||||
deleteFromLibrary: 8,
|
||||
sep3: 9,
|
||||
exportItems: 10,
|
||||
createBib: 11,
|
||||
loadReport: 12
|
||||
};
|
||||
|
||||
var menu = document.getElementById('zotero-itemmenu');
|
||||
|
||||
var enable = [], disable = [], show = [], hide = [], multiple = '';
|
||||
|
||||
if(itemsView && itemsView.selection.count > 0)
|
||||
{
|
||||
enable.push(0,2,3,4,6,7,8,10,11,12);
|
||||
enable.push(m.showInLibrary, m.addNote, m.attachSnapshot, m.attachLink, m.sep2,
|
||||
m.deleteItem, m.deleteFromLibrary, m.exportItems, m.createBib, m.loadReport);
|
||||
|
||||
// Multiple items selected
|
||||
if (itemsView.selection.count > 1)
|
||||
{
|
||||
var multiple = '.multiple';
|
||||
hide.push(0,1,2,3,4,5,6);
|
||||
hide.push(m.showInLibrary, m.sep1, m.addNote, m.attachSnapshot,
|
||||
m.attachLink, m.toggleAbstract, m.sep2);
|
||||
}
|
||||
// Single item selected
|
||||
else
|
||||
|
|
@ -792,33 +843,33 @@ var ZoteroPane = new function()
|
|||
|
||||
// Show in Library
|
||||
if (!itemsView._itemGroup.isLibrary()) {
|
||||
show.push(0,1);
|
||||
show.push(m.showInLibrary, m.sep1);
|
||||
}
|
||||
else {
|
||||
hide.push(0,1);
|
||||
hide.push(m.showInLibrary, m.sep1);
|
||||
}
|
||||
|
||||
if (item.isRegularItem())
|
||||
{
|
||||
show.push(2,3,4,6);
|
||||
hide.push(5); // abstract
|
||||
show.push(m.addNote, m.attachSnapshot, m.attachLink, m.sep2);
|
||||
hide.push(m.toggleAbstract);
|
||||
}
|
||||
else
|
||||
{
|
||||
hide.push(2,3,4);
|
||||
hide.push(m.addNote, m.attachSnapshot, m.attachLink);
|
||||
|
||||
// Abstract
|
||||
if (item.isNote() && item.getSource()) {
|
||||
show.push(5,6);
|
||||
show.push(m.toggleAbstract, m.sep2);
|
||||
if (item.isAbstract()) {
|
||||
menu.childNodes[5].setAttribute('label', Zotero.getString('pane.items.menu.abstract.unset'));
|
||||
menu.childNodes[m.toggleAbstract].setAttribute('label', Zotero.getString('pane.items.menu.abstract.unset'));
|
||||
}
|
||||
else {
|
||||
menu.childNodes[5].setAttribute('label', Zotero.getString('pane.items.menu.abstract.set'));
|
||||
menu.childNodes[m.toggleAbstract].setAttribute('label', Zotero.getString('pane.items.menu.abstract.set'));
|
||||
}
|
||||
}
|
||||
else {
|
||||
hide.push(5,6);
|
||||
hide.push(m.toggleAbstract, m.sep2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -827,33 +878,34 @@ var ZoteroPane = new function()
|
|||
{
|
||||
// Show in Library
|
||||
if (!itemsView._itemGroup.isLibrary()) {
|
||||
show.push(0,1);
|
||||
show.push(m.showInLibrary, m.sep1);
|
||||
}
|
||||
else {
|
||||
hide.push(0,1);
|
||||
hide.push(m.showInLibrary, m.sep1);
|
||||
}
|
||||
|
||||
disable.push(0,2,3,4,7,8,10,11,12);
|
||||
hide.push(5); // abstract
|
||||
show.push(6); // separator
|
||||
disable.push(m.showInLibrary, m.addNote, m.attachSnapshot, m.attachLink,
|
||||
m.deleteItem, m.deleteFromLibrary, m.exportItems, m.createBib, m.loadReport);
|
||||
hide.push(m.toggleAbstract);
|
||||
show.push(m.sep2);
|
||||
}
|
||||
|
||||
// Remove from collection
|
||||
if (itemsView._itemGroup.isCollection())
|
||||
{
|
||||
menu.childNodes[7].setAttribute('label', Zotero.getString('pane.items.menu.remove' + multiple));
|
||||
show.push(7);
|
||||
menu.childNodes[m.deleteItem].setAttribute('label', Zotero.getString('pane.items.menu.remove' + multiple));
|
||||
show.push(m.deleteItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
hide.push(7);
|
||||
hide.push(m.deleteItem);
|
||||
}
|
||||
|
||||
// Plural if necessary
|
||||
menu.childNodes[8].setAttribute('label', Zotero.getString('pane.items.menu.erase' + multiple));
|
||||
menu.childNodes[10].setAttribute('label', Zotero.getString('pane.items.menu.export' + multiple));
|
||||
menu.childNodes[11].setAttribute('label', Zotero.getString('pane.items.menu.createBib' + multiple));
|
||||
menu.childNodes[12].setAttribute('label', Zotero.getString('pane.items.menu.generateReport' + multiple));
|
||||
menu.childNodes[m.deleteFromLibrary].setAttribute('label', Zotero.getString('pane.items.menu.erase' + multiple));
|
||||
menu.childNodes[m.exportItems].setAttribute('label', Zotero.getString('pane.items.menu.export' + multiple));
|
||||
menu.childNodes[m.createBib].setAttribute('label', Zotero.getString('pane.items.menu.createBib' + multiple));
|
||||
menu.childNodes[m.loadReport].setAttribute('label', Zotero.getString('pane.items.menu.generateReport' + multiple));
|
||||
|
||||
for (var i in disable)
|
||||
{
|
||||
|
|
@ -876,6 +928,7 @@ var ZoteroPane = new function()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Adapted from: http://www.xulplanet.com/references/elemref/ref_tree.html#cmnote-9
|
||||
function onDoubleClick(event, tree)
|
||||
{
|
||||
|
|
@ -901,6 +954,19 @@ var ZoteroPane = new function()
|
|||
}
|
||||
|
||||
|
||||
function setItemsPaneMessage(msg) {
|
||||
document.getElementById('zotero-items-pane-content').selectedIndex = 1;
|
||||
var elem = document.getElementById('zotero-items-pane-message');
|
||||
elem.value = msg;
|
||||
}
|
||||
|
||||
|
||||
function clearItemsPaneMessage() {
|
||||
document.getElementById('zotero-items-pane-content').selectedIndex = 0;
|
||||
document.getElementById('zotero-items-pane-message').value = '';
|
||||
}
|
||||
|
||||
|
||||
// Updates browser context menu options
|
||||
function contextPopupShowing()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -94,6 +94,7 @@
|
|||
<menuitem oncommand="Zotero_Report_Interface.loadItemReport()"/>
|
||||
</popup>
|
||||
</popupset>
|
||||
|
||||
<vbox id="zotero-collections-pane" persist="width" flex="1">
|
||||
<toolbar>
|
||||
<toolbarbutton id="zotero-tb-collection-add" tooltiptext="&zotero.toolbar.newCollection.label;" oncommand="ZoteroPane.newCollection()"/>
|
||||
|
|
@ -129,7 +130,9 @@
|
|||
<splitter id="zotero-tags-splitter"/>
|
||||
<zoterotagselector id="zotero-tag-selector" persist="height,collapsed" oncommand="ZoteroPane.updateTagFilter()"/>
|
||||
</vbox>
|
||||
|
||||
<splitter id="zotero-tree-splitter" resizebefore="closest" resizeafter="closest"/>
|
||||
|
||||
<vbox id="zotero-items-pane" persist="width" flex="1">
|
||||
<toolbar align="center">
|
||||
<toolbarbutton id="zotero-tb-add" tooltiptext="&zotero.toolbar.newItem.label;" type="menu">
|
||||
|
|
@ -151,62 +154,77 @@
|
|||
<toolbarbutton id="zotero-tb-note-add" tooltiptext="&zotero.toolbar.note.standalone;" oncommand="ZoteroPane.newNote(event.shiftKey);"/>
|
||||
<spacer flex="1"/>
|
||||
<label value="&zotero.toolbar.search.label;" control="zotero-tb-search"/>
|
||||
<textbox id="zotero-tb-search" type="timed" timeout="250" command="cmd_zotero_search" dir="reverse"
|
||||
onkeypress="if (event.keyCode == event.DOM_VK_ESCAPE) { this.value = ''; this.doCommand('cmd_zotero_search'); }">
|
||||
<textbox id="zotero-tb-search" type="conditional-timed" timeout="250" command="cmd_zotero_search" dir="reverse"
|
||||
onkeypress="ZoteroPane.handleSearchKeypress(this, event)"
|
||||
oninput="ZoteroPane.handleSearchInput(this, event)"
|
||||
testcode="me.value.indexOf('"') == -1"
|
||||
prefire="ZoteroPane.clearItemsPaneMessage()"
|
||||
ontestfail="ZoteroPane.setItemsPaneMessage(Zotero.getString('advancedSearchMode'))">
|
||||
<toolbarbutton id="zotero-tb-search-cancel" oncommand="this.parentNode.value='';" hidden="true"/>
|
||||
</textbox>
|
||||
</toolbar>
|
||||
<tree
|
||||
id="zotero-items-tree" context="zotero-itemmenu"
|
||||
ondblclick="ZoteroPane.onDoubleClick(event, this);"
|
||||
enableColumnDrag="true"
|
||||
onfocus="if (ZoteroPane.getItemsView().rowCount && !ZoteroPane.getItemsView().selection.count) { ZoteroPane.getItemsView().selection.select(0); }"
|
||||
onkeypress="if (event.keyCode == event.DOM_VK_BACK_SPACE || event.keyCode == event.DOM_VK_DELETE){ ZoteroPane.deleteSelectedItem(); event.preventDefault(); }"
|
||||
onselect="ZoteroPane.itemSelected();"
|
||||
ondraggesture="if (event.target.localName == 'treechildren') nsDragAndDrop.startDrag(event,ZoteroPane.getItemsView());"
|
||||
ondragover="nsDragAndDrop.dragOver(event,ZoteroPane.getItemsView())"
|
||||
ondragdrop="nsDragAndDrop.drop(event,ZoteroPane.getItemsView())"
|
||||
flex="1">
|
||||
<treecols>
|
||||
<treecol
|
||||
id="zotero-items-title-column" primary="true"
|
||||
label="&zotero.items.title_column;"
|
||||
flex="4" persist="width ordinal hidden sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol
|
||||
id="zotero-items-firstCreator-column"
|
||||
label="&zotero.items.creator_column;"
|
||||
flex="1" persist="width ordinal hidden sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol
|
||||
id="zotero-items-numChildren-column"
|
||||
label="&zotero.items.numChildren_column;"
|
||||
persist="width ordinal hidden sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol
|
||||
id="zotero-items-typeIcon-column" hidden="true"
|
||||
label="&zotero.items.type_column;"
|
||||
width="40" persist="width ordinal hidden sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol
|
||||
id="zotero-items-rights-column" hidden="true"
|
||||
label="&zotero.items.rights_column;"
|
||||
flex="1" persist="width ordinal hidden sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol
|
||||
id="zotero-items-dateAdded-column" hidden="true"
|
||||
label="&zotero.items.dateAdded_column;"
|
||||
flex="1" persist="width ordinal hidden sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol
|
||||
id="zotero-items-dateModified-column" hidden="true"
|
||||
label="&zotero.items.dateModified_column;"
|
||||
flex="1" persist="width ordinal hidden sortActive sortDirection"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<deck id="zotero-items-pane-content" selectedIndex="0" flex="1">
|
||||
<tree
|
||||
id="zotero-items-tree" context="zotero-itemmenu"
|
||||
ondblclick="ZoteroPane.onDoubleClick(event, this);"
|
||||
enableColumnDrag="true"
|
||||
onfocus="if (ZoteroPane.getItemsView().rowCount && !ZoteroPane.getItemsView().selection.count) { ZoteroPane.getItemsView().selection.select(0); }"
|
||||
onkeypress="if (event.keyCode == event.DOM_VK_BACK_SPACE || event.keyCode == event.DOM_VK_DELETE){ ZoteroPane.deleteSelectedItem(); event.preventDefault(); }"
|
||||
onselect="ZoteroPane.itemSelected();"
|
||||
ondraggesture="if (event.target.localName == 'treechildren') nsDragAndDrop.startDrag(event,ZoteroPane.getItemsView());"
|
||||
ondragover="nsDragAndDrop.dragOver(event,ZoteroPane.getItemsView())"
|
||||
ondragdrop="nsDragAndDrop.drop(event,ZoteroPane.getItemsView())"
|
||||
flex="1">
|
||||
<treecols>
|
||||
<treecol
|
||||
id="zotero-items-title-column" primary="true"
|
||||
label="&zotero.items.title_column;"
|
||||
flex="4" persist="width ordinal hidden sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol
|
||||
id="zotero-items-firstCreator-column"
|
||||
label="&zotero.items.creator_column;"
|
||||
flex="1" persist="width ordinal hidden sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol
|
||||
id="zotero-items-numChildren-column"
|
||||
label="&zotero.items.numChildren_column;"
|
||||
persist="width ordinal hidden sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol
|
||||
id="zotero-items-typeIcon-column" hidden="true"
|
||||
label="&zotero.items.type_column;"
|
||||
width="40" persist="width ordinal hidden sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol
|
||||
id="zotero-items-rights-column" hidden="true"
|
||||
label="&zotero.items.rights_column;"
|
||||
flex="1" persist="width ordinal hidden sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol
|
||||
id="zotero-items-dateAdded-column" hidden="true"
|
||||
label="&zotero.items.dateAdded_column;"
|
||||
flex="1" persist="width ordinal hidden sortActive sortDirection"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<treecol
|
||||
id="zotero-items-dateModified-column" hidden="true"
|
||||
label="&zotero.items.dateModified_column;"
|
||||
flex="1" persist="width ordinal hidden sortActive sortDirection"/>
|
||||
</treecols>
|
||||
<treechildren/>
|
||||
</tree>
|
||||
|
||||
<!-- Label for displaying messages when items pane is hidden
|
||||
(e.g. "Advanced search mode — press Enter to search.")-->
|
||||
<box pack="center" align="center">
|
||||
<label id="zotero-items-pane-message" />
|
||||
</box>
|
||||
</deck>
|
||||
</vbox>
|
||||
|
||||
<splitter id="zotero-view-splitter" resizebefore="closest" resizeafter="closest"/>
|
||||
|
||||
<vbox id="zotero-item-pane" persist="width">
|
||||
<toolbar align="right">
|
||||
<toolbarbutton id="zotero-tb-fullscreen" tooltiptext="&zotero.toolbar.fullscreen.tooltip;" oncommand="ZoteroPane.fullScreen();"/>
|
||||
|
|
|
|||
|
|
@ -330,7 +330,8 @@ Zotero.Fulltext = new function(){
|
|||
|
||||
// If not binary mode, only scan plaintext files
|
||||
if (!mode || mode.indexOf('Binary')==-1){
|
||||
if (i.getAttachmentMimeType().substr(0,5)!='text/'){
|
||||
if (!Zotero.MIME.isTextType(i.getAttachmentMimeType())) {
|
||||
Zotero.debug('Not scanning MIME type ' + mimeType, 4);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
*/
|
||||
|
||||
Zotero.MIME = new function(){
|
||||
this.isTextType = isTextType;
|
||||
this.isExternalTextExtension = isExternalTextExtension;
|
||||
this.sniffForMIMEType = sniffForMIMEType;
|
||||
this.sniffForBinary = sniffForBinary;
|
||||
|
|
@ -41,6 +42,12 @@ Zotero.MIME = new function(){
|
|||
["<?xml", 'text/xml']
|
||||
];
|
||||
|
||||
var _textTypes = {
|
||||
'application/xhtml+xml': true,
|
||||
'application/xml': true,
|
||||
'application/x-javascript': true
|
||||
};
|
||||
|
||||
// MIME types handled natively by Gecko
|
||||
// DEBUG: There's definitely a better way of getting these
|
||||
var _nativeMIMETypes = {
|
||||
|
|
@ -61,6 +68,12 @@ Zotero.MIME = new function(){
|
|||
};
|
||||
|
||||
|
||||
|
||||
function isTextType(mimeType) {
|
||||
return mimeType.substr(0, 5) == 'text/' || _textTypes[mimeType];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check if file extension should be forced to open externally
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -112,10 +112,10 @@ Zotero.Schema = new function(){
|
|||
}
|
||||
}
|
||||
|
||||
// If transaction already in progress, delay by a few seconds
|
||||
// If transaction already in progress, delay by ten minutes
|
||||
if (Zotero.DB.transactionInProgress()){
|
||||
Zotero.debug('Transaction in progress -- delaying repository check', 4)
|
||||
_setRepositoryTimer(30);
|
||||
_setRepositoryTimer(600);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -530,6 +530,12 @@ Zotero.Schema = new function(){
|
|||
// https://bugzilla.mozilla.org/show_bug.cgi?id=194231
|
||||
xmlnode.normalize();
|
||||
|
||||
// Delete local version of remote translators with priority 0
|
||||
if (xmlnode.getElementsByTagName('priority')[0].firstChild.nodeValue === "0") {
|
||||
var sql = "DELETE FROM translators WHERE translatorID=?";
|
||||
return Zotero.DB.query(sql, {string: xmlnode.getAttribute('id')});
|
||||
}
|
||||
|
||||
var sqlValues = [
|
||||
{string: xmlnode.getAttribute('id')},
|
||||
{string: xmlnode.getAttribute('minVersion')},
|
||||
|
|
|
|||
|
|
@ -176,18 +176,29 @@ Zotero.Search.prototype.addCondition = function(condition, operator, value, requ
|
|||
if (condition=='quicksearch'){
|
||||
this.addCondition('joinMode', 'any');
|
||||
|
||||
// Quicksearch words don't need to be phrases
|
||||
var words = Zotero.Fulltext.semanticSplitter(value);
|
||||
for each(var i in words){
|
||||
var parts = Zotero.SearchConditions.parseSearchString(value);
|
||||
|
||||
for each(var part in parts) {
|
||||
this.addCondition('blockStart');
|
||||
this.addCondition('title', operator, i, false);
|
||||
this.addCondition('field', operator, i, false);
|
||||
this.addCondition('numberfield', operator, i, false);
|
||||
this.addCondition('creator', operator, i, false);
|
||||
this.addCondition('tag', operator, i, false);
|
||||
this.addCondition('note', operator, i, false);
|
||||
this.addCondition('fulltextWord', operator, i, false);
|
||||
this.addCondition('title', operator, part.text, false);
|
||||
this.addCondition('field', operator, part.text, false);
|
||||
this.addCondition('numberfield', operator, part.text, false);
|
||||
this.addCondition('creator', operator, part.text, false);
|
||||
this.addCondition('tag', operator, part.text, false);
|
||||
this.addCondition('note', operator, part.text, false);
|
||||
|
||||
if (part.inQuotes) {
|
||||
this.addCondition('fulltextContent', operator, part.text, false);
|
||||
}
|
||||
else {
|
||||
var splits = Zotero.Fulltext.semanticSplitter(part.text);
|
||||
for each(var split in splits) {
|
||||
this.addCondition('fulltextWord', operator, split, false);
|
||||
}
|
||||
}
|
||||
|
||||
this.addCondition('blockEnd');
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
@ -271,14 +282,53 @@ Zotero.Search.prototype.search = function(){
|
|||
|
||||
var ids = Zotero.DB.columnQuery(this._sql, this._sqlParams);
|
||||
|
||||
if (!ids){
|
||||
return false;
|
||||
var joinMode = 'all';
|
||||
for each(var condition in this._conditions) {
|
||||
if (condition.condition == 'joinMode') {
|
||||
if (condition.operator == 'any') {
|
||||
joinMode = 'any';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Filter results with fulltext search
|
||||
//
|
||||
// If join mode ANY, return the superset of the main search and
|
||||
// (a separate fulltext word search filtered by fulltext content)
|
||||
//
|
||||
// If join mode ALL, return the (union of SQL and fulltext word search)
|
||||
// filtered by fulltext content
|
||||
for each(var condition in this._conditions){
|
||||
if (condition['condition']=='fulltextContent'){
|
||||
var fulltextIDs = Zotero.Fulltext.findTextInItems(ids,
|
||||
// Run a new search against the fulltext word index
|
||||
// for words in this phrase
|
||||
var s = new Zotero.Search();
|
||||
var splits = Zotero.Fulltext.semanticSplitter(condition.value);
|
||||
|
||||
for each(var split in splits){
|
||||
s.addCondition('fulltextWord', condition.operator, split, false);
|
||||
}
|
||||
var fulltextWordIDs = s.search();
|
||||
|
||||
var filter = function(val, index, array) {
|
||||
return hash[val] ?
|
||||
(condition.operator == 'contains') :
|
||||
(condition.operator == 'doesNotContain');
|
||||
}
|
||||
|
||||
// If ALL mode, get union of main search and fulltext word index
|
||||
if (joinMode == 'all') {
|
||||
var hash = {};
|
||||
for each(var id in fulltextWordIDs){
|
||||
hash[id] = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var scopeIDs = fulltextWordIDs;
|
||||
}
|
||||
|
||||
var fulltextIDs = Zotero.Fulltext.findTextInItems(scopeIDs,
|
||||
condition['value'], condition['mode']);
|
||||
|
||||
var hash = {};
|
||||
|
|
@ -286,24 +336,20 @@ Zotero.Search.prototype.search = function(){
|
|||
hash[val.id] = true;
|
||||
}
|
||||
|
||||
switch (condition['operator']){
|
||||
case 'contains':
|
||||
var filter = function(val, index, array){
|
||||
return hash[val] ? true : false;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'doesNotContain':
|
||||
var filter = function(val, index, array){
|
||||
return hash[val] ? false : true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
var filteredIDs = scopeIDs ? scopeIDs.filter(filter) : [];
|
||||
|
||||
var ids = ids.filter(filter);
|
||||
// If join mode ANY, add any new items from the fulltext content
|
||||
// search to the main search results
|
||||
if (joinMode == 'any' && ids) {
|
||||
for each(var id in filteredIDs) {
|
||||
if (ids.indexOf(id) == -1) {
|
||||
ids.push(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ids = filteredIDs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -801,6 +847,7 @@ Zotero.SearchConditions = new function(){
|
|||
this.get = get;
|
||||
this.getStandardConditions = getStandardConditions;
|
||||
this.hasOperator = hasOperator;
|
||||
this.parseSearchString = parseSearchString;
|
||||
this.parseCondition = parseCondition;
|
||||
|
||||
var _initialized = false;
|
||||
|
|
@ -1173,6 +1220,41 @@ Zotero.SearchConditions = new function(){
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parses a search into words and "double-quoted phrases"
|
||||
*
|
||||
* Also strips unpaired quotes at the beginning and end of words
|
||||
*
|
||||
* Returns array of objects containing 'text' and 'inQuotes'
|
||||
*/
|
||||
function parseSearchString(str) {
|
||||
var parts = str.split(/\s*("[^"]*")\s*|"\s|\s"|^"|"$|'\s|\s'|^'|'$|\s/m);
|
||||
var parsed = [];
|
||||
|
||||
for (var i in parts) {
|
||||
var part = parts[i];
|
||||
if (!part.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (part.charAt(0)=='"' && part.charAt(part.length-1)=='"') {
|
||||
parsed.push({
|
||||
text: part.substring(1, part.length-1),
|
||||
inQuotes: true
|
||||
});
|
||||
}
|
||||
else {
|
||||
parsed.push({
|
||||
text: part,
|
||||
inQuotes: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return parsed;
|
||||
}
|
||||
|
||||
|
||||
function parseCondition(condition){
|
||||
var mode = false;
|
||||
var pos = condition.indexOf('/');
|
||||
|
|
|
|||
|
|
@ -228,6 +228,9 @@ fileInterface.noReferencesError = The items you have selected contain no referen
|
|||
fileInterface.bibliographyGenerationError = An error occurred generating your bibliography. Please try again.
|
||||
fileInterface.exportError = An error occurred while trying to export the selected file.
|
||||
|
||||
advancedSearchMode = Advanced search mode — press Enter to search.
|
||||
searchInProgress = Search in progress — press wait.
|
||||
|
||||
searchOperator.is = is
|
||||
searchOperator.isNot = is not
|
||||
searchOperator.contains = contains
|
||||
|
|
|
|||
|
|
@ -31,6 +31,11 @@ toolbar[iconsize="small"] #zotero-toolbar-button:active
|
|||
|
||||
/* Bindings */
|
||||
|
||||
textbox[type="conditional-timed"]
|
||||
{
|
||||
-moz-binding: url('chrome://zotero/content/bindings/conditional-timed-textbox.xml#conditional-timed-textbox');
|
||||
}
|
||||
|
||||
textbox[multiline="true"][type="timed"]
|
||||
{
|
||||
-moz-binding: url('chrome://zotero/content/bindings/timedtextarea.xml#timed-textarea');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue