fx-compat: Fix search dialogs (#2631)
This commit is contained in:
parent
b78b9cad1f
commit
8face792c0
15 changed files with 1056 additions and 1217 deletions
|
@ -21,10 +21,23 @@
|
|||
onunload="ZoteroAdvancedSearch.onUnload();"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
windowtype="zotero:search">
|
||||
windowtype="zotero:search"
|
||||
style="display: flex;">
|
||||
|
||||
<script>
|
||||
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/zoteroSearch.js", this);
|
||||
</script>
|
||||
|
||||
<script src="include.js"/>
|
||||
<script src="advancedSearch.js"/>
|
||||
|
||||
<popupset>
|
||||
<panel is="autocomplete-richlistbox-popup"
|
||||
id="search-autocomplete-popup"
|
||||
type="autocomplete-richlistbox"
|
||||
noautofocus="true"/>
|
||||
</popupset>
|
||||
|
||||
<vbox id="zotero-search-box-container" flex="1">
|
||||
<vbox id="zotero-search-box-controls">
|
File diff suppressed because it is too large
Load diff
952
chrome/content/zotero/elements/zoteroSearch.js
Normal file
952
chrome/content/zotero/elements/zoteroSearch.js
Normal file
|
@ -0,0 +1,952 @@
|
|||
/*
|
||||
***** BEGIN LICENSE BLOCK *****
|
||||
|
||||
Copyright © 2022 Corporation for Digital Scholarship
|
||||
Vienna, Virginia, USA
|
||||
https://www.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 *****
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
{
|
||||
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
Services.scriptloader.loadSubScript("chrome://global/content/customElements.js", this);
|
||||
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/base.js", this);
|
||||
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/shadowAutocompleteInput.js", this);
|
||||
|
||||
class SearchElementBase extends XULElementBase {
|
||||
get stylesheets() {
|
||||
return [
|
||||
'chrome://global/skin/global.css',
|
||||
'chrome://zotero-platform/content/zoteroSearch.css'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
class ZoteroSearch extends SearchElementBase {
|
||||
content = MozXULElement.parseXULToFragment(`
|
||||
<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="search-box" flex="1" onkeypress="this.getRootNode().host.handleKeyPress(event)">
|
||||
<hbox align="center">
|
||||
<label value="&zotero.search.searchInLibrary;" control="libraryMenu"/>
|
||||
<menulist id="libraryMenu" oncommand="this.getRootNode().host.updateLibrary();" native="true">
|
||||
<menupopup/>
|
||||
</menulist>
|
||||
</hbox>
|
||||
<groupbox>
|
||||
<caption align="center">
|
||||
<label value="&zotero.search.joinMode.prefix;"/>
|
||||
<menulist id="joinModeMenu" oncommand="this.getRootNode().host.updateJoinMode();" native="true">
|
||||
<menupopup>
|
||||
<menuitem label="&zotero.search.joinMode.any;" value="any"/>
|
||||
<menuitem label="&zotero.search.joinMode.all;" value="all" selected="true"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<label value="&zotero.search.joinMode.suffix;"/>
|
||||
</caption>
|
||||
<vbox id="conditions"/>
|
||||
</groupbox>
|
||||
<hbox>
|
||||
<checkbox id="recursiveCheckbox" label="&zotero.search.recursive.label;" oncommand="this.getRootNode().host.updateCheckbox('recursive');" native="true"/>
|
||||
<checkbox id="noChildrenCheckbox" label="&zotero.search.noChildren;" oncommand="this.getRootNode().host.updateCheckbox('noChildren');" native="true"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<checkbox id="includeParentsAndChildrenCheckbox" label="&zotero.search.includeParentsAndChildren;" oncommand="this.getRootNode().host.updateCheckbox('includeParentsAndChildren');" native="true"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
`, ['chrome://zotero/locale/zotero.dtd', 'chrome://zotero/locale/searchbox.dtd']);
|
||||
|
||||
get search() {
|
||||
return this.searchRef;
|
||||
}
|
||||
|
||||
set search(val) {
|
||||
this.searchRef = val;
|
||||
|
||||
var libraryMenu = this.shadowRoot.getElementById('libraryMenu');
|
||||
var libraries = Zotero.Libraries.getAll();
|
||||
Zotero.Utilities.Internal.buildLibraryMenu(
|
||||
libraryMenu, libraries, this.searchRef.libraryID
|
||||
);
|
||||
if (this.searchRef.id) {
|
||||
libraryMenu.disabled = true;
|
||||
}
|
||||
this.updateLibrary();
|
||||
|
||||
|
||||
var conditionsBox = this.shadowRoot.getElementById('conditions');
|
||||
while (conditionsBox.hasChildNodes())
|
||||
conditionsBox.removeChild(conditionsBox.firstChild);
|
||||
|
||||
var conditions = this.search.getConditions();
|
||||
for (let id in conditions) {
|
||||
let condition = conditions[id];
|
||||
// Checkboxes
|
||||
switch (condition.condition) {
|
||||
case 'recursive':
|
||||
case 'noChildren':
|
||||
case 'includeParentsAndChildren':
|
||||
let checkbox = condition.condition + 'Checkbox';
|
||||
this.shadowRoot.getElementById(checkbox).setAttribute('condition', id);
|
||||
this.shadowRoot.getElementById(checkbox).checked = condition.operator == 'true';
|
||||
continue;
|
||||
}
|
||||
|
||||
if (condition.condition == 'joinMode') {
|
||||
this.shadowRoot.getElementById('joinModeMenu').setAttribute('condition', id);
|
||||
this.shadowRoot.getElementById('joinModeMenu').value = condition.operator;
|
||||
}
|
||||
else {
|
||||
this.addCondition(condition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addCondition(ref) {
|
||||
var conditionsBox = this.shadowRoot.getElementById('conditions');
|
||||
var condition = document.createXULElement('zoterosearchcondition');
|
||||
condition.setAttribute('flex', '1');
|
||||
|
||||
conditionsBox.appendChild(condition);
|
||||
|
||||
// Default to an empty 'title' condition
|
||||
if (!ref) {
|
||||
ref = this.search.getCondition(this.search.addCondition("title","contains",""))
|
||||
}
|
||||
|
||||
condition.initWithParentAndCondition(this, ref);
|
||||
|
||||
if (conditionsBox.childNodes.length == 2){
|
||||
conditionsBox.childNodes[0].enableRemoveButton();
|
||||
}
|
||||
else if (conditionsBox.childNodes.length == 1){
|
||||
conditionsBox.childNodes[0].disableRemoveButton();
|
||||
}
|
||||
}
|
||||
|
||||
removeCondition(id) {
|
||||
var conditionsBox = this.shadowRoot.getElementById('conditions');
|
||||
|
||||
this.search.removeCondition(id);
|
||||
|
||||
for (var i = 0, len=conditionsBox.childNodes.length; i < len; i++){
|
||||
if (conditionsBox.childNodes[i].conditionID == id){
|
||||
conditionsBox.removeChild(conditionsBox.childNodes[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (conditionsBox.childNodes.length == 1){
|
||||
conditionsBox.childNodes[0].disableRemoveButton();
|
||||
}
|
||||
}
|
||||
|
||||
updateLibrary() {
|
||||
var menu = this.shadowRoot.getElementById('libraryMenu');
|
||||
var libraryID = parseInt(menu.selectedItem.value);
|
||||
|
||||
if (this.onLibraryChange) {
|
||||
this.onLibraryChange(libraryID);
|
||||
}
|
||||
if (!this.searchRef.id) {
|
||||
this.searchRef.libraryID = libraryID;
|
||||
}
|
||||
|
||||
[...this.shadowRoot.getElementById('conditions').childNodes].forEach(x => x.onLibraryChange());
|
||||
}
|
||||
|
||||
updateJoinMode() {
|
||||
var menu = this.shadowRoot.getElementById('joinModeMenu');
|
||||
if(menu.hasAttribute('condition'))
|
||||
this.search.updateCondition(menu.getAttribute('condition'),'joinMode',menu.value,null);
|
||||
else
|
||||
menu.setAttribute('condition', this.search.addCondition('joinMode',menu.value,null));
|
||||
}
|
||||
|
||||
updateCheckbox(condition) {
|
||||
var checkbox = this.shadowRoot.getElementById(condition + 'Checkbox');
|
||||
var value = checkbox.checked ? 'true' : 'false';
|
||||
if(checkbox.hasAttribute('condition'))
|
||||
{
|
||||
this.search.updateCondition(checkbox.getAttribute('condition'),
|
||||
condition, value, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
checkbox.setAttribute('condition',
|
||||
this.search.addCondition(condition, value, null));
|
||||
}
|
||||
}
|
||||
|
||||
// Calls updateSearch() on all search conditions
|
||||
updateSearch() {
|
||||
var conditionsBox = this.shadowRoot.getElementById('conditions');
|
||||
if (conditionsBox.hasChildNodes()) {
|
||||
for(var i = 0, len=conditionsBox.childNodes.length; i < len; i++) {
|
||||
conditionsBox.childNodes[i].updateSearch();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleKeyPress(event) {
|
||||
switch (event.keyCode) {
|
||||
case event.DOM_VK_RETURN:
|
||||
this.active = true;
|
||||
|
||||
if (event.shiftKey) {
|
||||
this.addCondition();
|
||||
}
|
||||
else {
|
||||
this.doCommand();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
customElements.define("zoterosearch", ZoteroSearch);
|
||||
|
||||
class ZoteroSearchCondition extends SearchElementBase {
|
||||
content = MozXULElement.parseXULToFragment(`
|
||||
<xul:hbox id="search-condition" xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
flex="1">
|
||||
<xul:popupset id="condition-tooltips"/>
|
||||
|
||||
<xul:menulist id="conditionsmenu" oncommand="this.getRootNode().host.onConditionSelected(event.target.value); event.stopPropagation()" native="true">
|
||||
<xul:menupopup onpopupshown="this.getRootNode().host.revealSelectedCondition()">
|
||||
<xul:menu id="more-conditions-menu" label="&zotero.general.more;">
|
||||
<xul:menupopup/>
|
||||
</xul:menu>
|
||||
</xul:menupopup>
|
||||
</xul:menulist>
|
||||
<xul:menulist id="operatorsmenu" oncommand="this.getRootNode().host.onOperatorSelected(); event.stopPropagation()" native="true">
|
||||
<xul:menupopup/>
|
||||
</xul:menulist>
|
||||
<xul:zoterosearchtextbox id="valuefield" flex="1"/>
|
||||
<xul:menulist id="valuemenu" flex="1" hidden="true" native="true">
|
||||
<xul:menupopup/>
|
||||
</xul:menulist>
|
||||
<xul:zoterosearchagefield id="value-date-age" hidden="true" flex="1"/>
|
||||
<xul:label id="remove" class="zotero-clicky zotero-clicky-minus" value="-" onclick="this.getRootNode().host.onRemoveClicked(event)"/>
|
||||
<xul:label id="add" class="zotero-clicky zotero-clicky-plus" value="+" onclick="this.getRootNode().host.onAddClicked(event)"/>
|
||||
</xul:hbox>
|
||||
`, ['chrome://zotero/locale/zotero.dtd', 'chrome://zotero/locale/searchbox.dtd']);
|
||||
|
||||
init() {
|
||||
var operators = [
|
||||
'is',
|
||||
'isNot',
|
||||
'beginsWith',
|
||||
'contains',
|
||||
'doesNotContain',
|
||||
'isLessThan',
|
||||
'isGreaterThan',
|
||||
'isBefore',
|
||||
'isAfter',
|
||||
'isInTheLast'
|
||||
];
|
||||
var operatorsList = this.shadowRoot.getElementById('operatorsmenu');
|
||||
|
||||
// Build operator menu
|
||||
for (let operator of operators) {
|
||||
operatorsList.appendItem(
|
||||
Zotero.getString('searchOperator.' + operator),
|
||||
operator
|
||||
);
|
||||
}
|
||||
|
||||
// Build conditions menu
|
||||
var conditionsMenu = this.shadowRoot.getElementById('conditionsmenu');
|
||||
var moreConditionsMenu = this.shadowRoot.getElementById('more-conditions-menu');
|
||||
var conditions = Zotero.SearchConditions.getStandardConditions();
|
||||
|
||||
for (let condition of conditions) {
|
||||
if (this.isPrimaryCondition(condition.name)) {
|
||||
var menuitem = document.createXULElement('menuitem');
|
||||
menuitem.setAttribute('label', condition.localized);
|
||||
menuitem.setAttribute('value', condition.name);
|
||||
moreConditionsMenu.before(menuitem);
|
||||
}
|
||||
else {
|
||||
var menuitem = moreConditionsMenu.appendItem(
|
||||
condition.localized, condition.name
|
||||
);
|
||||
}
|
||||
|
||||
var baseFields = null;
|
||||
try {
|
||||
baseFields = Zotero.ItemFields.getTypeFieldsFromBase(condition.name);
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
// Add tooltip, building it if it doesn't exist
|
||||
if (baseFields) {
|
||||
if (!this.shadowRoot.getElementById(condition.name + '-tooltip')) {
|
||||
var fieldName = null;
|
||||
try {
|
||||
fieldName = Zotero.ItemFields.getLocalizedString(condition.name);
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
if (fieldName) {
|
||||
var localized = [fieldName];
|
||||
}
|
||||
else {
|
||||
var localized = [];
|
||||
}
|
||||
|
||||
for (let baseField of baseFields) {
|
||||
var str = Zotero.SearchConditions.getLocalizedName(
|
||||
Zotero.ItemFields.getName(baseField)
|
||||
);
|
||||
|
||||
if (localized.indexOf(str) == -1) {
|
||||
localized.push(str);
|
||||
}
|
||||
}
|
||||
localized.sort();
|
||||
|
||||
var tt = document.createXULElement('tooltip');
|
||||
tt.setAttribute('id', condition.name + '-tooltip');
|
||||
tt.setAttribute('noautohide', true);
|
||||
|
||||
var hbox = document.createXULElement('hbox');
|
||||
|
||||
var label = document.createXULElement('label');
|
||||
label.setAttribute('value', Zotero.getString('searchConditions.tooltip.fields'));
|
||||
hbox.appendChild(label);
|
||||
var vbox = document.createXULElement('vbox');
|
||||
for (let str of localized) {
|
||||
let label = document.createXULElement('label');
|
||||
label.setAttribute('value', str);
|
||||
vbox.appendChild(label);
|
||||
}
|
||||
hbox.appendChild(vbox);
|
||||
tt.appendChild(hbox);
|
||||
|
||||
this.shadowRoot.getElementById('condition-tooltips').appendChild(tt);
|
||||
}
|
||||
|
||||
menuitem.setAttribute('tooltip', condition.name + '-tooltip');
|
||||
}
|
||||
}
|
||||
conditionsMenu.selectedIndex = 0;
|
||||
}
|
||||
|
||||
isPrimaryCondition(condition) {
|
||||
switch (condition) {
|
||||
case 'collection':
|
||||
case 'creator':
|
||||
case 'title':
|
||||
case 'date':
|
||||
case 'dateAdded':
|
||||
case 'dateModified':
|
||||
case 'itemType':
|
||||
case 'fileTypeID':
|
||||
case 'publicationTitle':
|
||||
case 'tag':
|
||||
case 'note':
|
||||
case 'childNote':
|
||||
case 'fulltextContent':
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
onConditionSelected(conditionName, reload) {
|
||||
var conditionsMenu = this.shadowRoot.getElementById('conditionsmenu');
|
||||
var operatorsList = this.shadowRoot.getElementById('operatorsmenu');
|
||||
|
||||
// Skip if no condition or correct condition already selected
|
||||
if (!conditionName || (conditionName == this.selectedCondition && !reload)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.selectedCondition = conditionName;
|
||||
this.selectedOperator = operatorsList.value;
|
||||
|
||||
var condition = Zotero.SearchConditions.get(conditionName);
|
||||
var operators = condition.operators;
|
||||
|
||||
conditionsMenu.value = conditionName;
|
||||
// Store in attribute as well because the value doesn't get set properly when
|
||||
// the value is from a menuitem in the More menu, and we need this to select
|
||||
// the previous condition when creating a new row
|
||||
conditionsMenu.setAttribute('data-value', conditionName);
|
||||
|
||||
// Parent state isn't set automatically for submenu selections
|
||||
if (!this.isPrimaryCondition(conditionName)) {
|
||||
conditionsMenu.selectedIndex = -1;
|
||||
conditionsMenu.setAttribute(
|
||||
'label',
|
||||
Zotero.SearchConditions.getLocalizedName(conditionName)
|
||||
);
|
||||
}
|
||||
|
||||
this.updateSubmenuCheckboxes(conditionsMenu);
|
||||
|
||||
// Display appropriate operators for condition
|
||||
var selectThis;
|
||||
for(var i = 0, len = operatorsList.firstChild.childNodes.length; i < len; i++)
|
||||
{
|
||||
var val = operatorsList.firstChild.childNodes[i].getAttribute('value');
|
||||
var hidden = !operators[val];
|
||||
operatorsList.firstChild.childNodes[i].setAttribute('hidden', hidden);
|
||||
if (!hidden && (selectThis == null || this.selectedOperator == val))
|
||||
{
|
||||
selectThis = i;
|
||||
}
|
||||
}
|
||||
operatorsList.selectedIndex = selectThis;
|
||||
|
||||
// Generate drop-down menu instead of textbox for certain conditions
|
||||
switch (conditionName) {
|
||||
case 'collection':
|
||||
var rows = [];
|
||||
|
||||
var libraryID = this.parent.search.libraryID;
|
||||
|
||||
// Add collections
|
||||
let cols = Zotero.Collections.getByLibrary(libraryID, true);
|
||||
for (let col of cols) {
|
||||
// Indent subcollections
|
||||
var indent = '';
|
||||
if (col.level) {
|
||||
for (let j = 1; j < col.level; j++) {
|
||||
indent += ' ';
|
||||
}
|
||||
indent += '- ';
|
||||
}
|
||||
rows.push({
|
||||
name: indent + col.name,
|
||||
value: 'C' + col.key,
|
||||
image: Zotero.Collection.prototype.treeViewImage
|
||||
});
|
||||
}
|
||||
|
||||
// Add saved searches
|
||||
let searches = Zotero.Searches.getByLibrary(libraryID);
|
||||
for (let search of searches) {
|
||||
if (search.id != this.parent.search.id) {
|
||||
rows.push({
|
||||
name: search.name,
|
||||
value: 'S' + search.key,
|
||||
image: Zotero.Search.prototype.treeViewImage
|
||||
});
|
||||
}
|
||||
}
|
||||
this.createValueMenu(rows);
|
||||
break;
|
||||
|
||||
case 'itemType':
|
||||
var rows = Zotero.ItemTypes.getTypes().map(type => ({
|
||||
name: Zotero.ItemTypes.getLocalizedString(type.id),
|
||||
value: type.name
|
||||
}));
|
||||
|
||||
// Sort by localized name
|
||||
var collation = Zotero.getLocaleCollation();
|
||||
rows.sort((a, b) => collation.compareString(1, a.name, b.name));
|
||||
|
||||
this.createValueMenu(rows);
|
||||
break;
|
||||
|
||||
case 'fileTypeID':
|
||||
var rows = Zotero.FileTypes.getTypes().map(type => ({
|
||||
name: Zotero.getString('fileTypes.' + type.name),
|
||||
value: type.id
|
||||
}));
|
||||
|
||||
// Sort by localized name
|
||||
var collation = Zotero.getLocaleCollation();
|
||||
rows.sort((a, b) => collation.compareString(1, a.name, b.name));
|
||||
|
||||
this.createValueMenu(rows);
|
||||
break;
|
||||
|
||||
default:
|
||||
if (operatorsList.value=='isInTheLast')
|
||||
{
|
||||
this.shadowRoot.getElementById('value-date-age').value = this.value;
|
||||
}
|
||||
|
||||
// Textbox
|
||||
else {
|
||||
// If switching from menu to textbox, clear value
|
||||
if (this.shadowRoot.getElementById('valuefield').hidden){
|
||||
this.shadowRoot.getElementById('valuefield').value = '';
|
||||
}
|
||||
// If switching between textbox conditions, get loaded value for new one
|
||||
else {
|
||||
this.shadowRoot.getElementById('valuefield').value = this.value;
|
||||
}
|
||||
|
||||
// Update field drop-down if applicable
|
||||
this.shadowRoot.getElementById('valuefield').update(conditionName, this.mode);
|
||||
}
|
||||
}
|
||||
|
||||
this.onOperatorSelected();
|
||||
}
|
||||
|
||||
onOperatorSelected() {
|
||||
var operatorsList = this.shadowRoot.getElementById('operatorsmenu');
|
||||
|
||||
// Drop-down menu
|
||||
if (this.selectedCondition == 'collection'
|
||||
|| this.selectedCondition == 'itemType'
|
||||
|| this.selectedCondition == 'fileTypeID') {
|
||||
this.shadowRoot.getElementById('valuefield').hidden = true;
|
||||
this.shadowRoot.getElementById('valuemenu').hidden = false;
|
||||
this.shadowRoot.getElementById('value-date-age').hidden = true;
|
||||
}
|
||||
|
||||
// Textbox + units dropdown for isInTheLast operator
|
||||
else if (operatorsList.value=='isInTheLast')
|
||||
{
|
||||
// If switching from text field, clear value
|
||||
if (this.shadowRoot.getElementById('value-date-age').hidden){
|
||||
this.value = '';
|
||||
}
|
||||
this.shadowRoot.getElementById('valuefield').hidden = true;
|
||||
this.shadowRoot.getElementById('valuemenu').hidden = true;
|
||||
this.shadowRoot.getElementById('value-date-age').hidden = false;
|
||||
}
|
||||
|
||||
// Textbox
|
||||
else
|
||||
{
|
||||
// If switching from date age, clear value
|
||||
if (this.shadowRoot.getElementById('valuefield').hidden){
|
||||
this.value = '';
|
||||
}
|
||||
this.shadowRoot.getElementById('valuefield').hidden = false;
|
||||
this.shadowRoot.getElementById('valuemenu').hidden = true;
|
||||
this.shadowRoot.getElementById('value-date-age').hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
createValueMenu(rows) {
|
||||
let valueMenu = this.shadowRoot.getElementById('valuemenu');
|
||||
|
||||
while (valueMenu.hasChildNodes()){
|
||||
valueMenu.removeChild(valueMenu.firstChild);
|
||||
}
|
||||
|
||||
for (let row of rows) {
|
||||
let menuitem = valueMenu.appendItem(row.name, row.value);
|
||||
if (row.image) {
|
||||
menuitem.className = 'menuitem-iconic';
|
||||
menuitem.setAttribute('image', row.image);
|
||||
}
|
||||
}
|
||||
valueMenu.selectedIndex = 0;
|
||||
|
||||
if (this.value)
|
||||
{
|
||||
valueMenu.value = this.value;
|
||||
}
|
||||
|
||||
valueMenu.shadowRoot.querySelector('#label-box > image').style.maxHeight = '16px';
|
||||
}
|
||||
|
||||
initWithParentAndCondition(parent, condition) {
|
||||
this.parent = parent;
|
||||
this.conditionID = condition['id'];
|
||||
var menu = this.shadowRoot.getElementById('conditionsmenu');
|
||||
|
||||
if(this.parent.search)
|
||||
{
|
||||
this.dontupdate = true; //so that the search doesn't get updated while we are creating controls.
|
||||
var prefix = '';
|
||||
|
||||
// Handle special conditions
|
||||
switch (condition.condition) {
|
||||
case 'savedSearch':
|
||||
prefix = 'S';
|
||||
break;
|
||||
|
||||
case 'collection':
|
||||
prefix = 'C';
|
||||
break;
|
||||
}
|
||||
|
||||
// Map certain conditions to other menu items
|
||||
let uiCondition = condition.condition;
|
||||
switch (condition.condition) {
|
||||
case 'savedSearch':
|
||||
uiCondition = 'collection';
|
||||
break;
|
||||
}
|
||||
|
||||
menu.setAttribute('value', uiCondition);
|
||||
|
||||
// Convert datetimes from UTC to localtime
|
||||
if ((condition['condition']=='accessDate' ||
|
||||
condition['condition']=='dateAdded' ||
|
||||
condition['condition']=='dateModified') &&
|
||||
Zotero.Date.isSQLDateTime(condition['value'])){
|
||||
|
||||
condition['value'] =
|
||||
Zotero.Date.dateToSQL(Zotero.Date.sqlToDate(condition['value'], true));
|
||||
}
|
||||
|
||||
this.mode = condition['mode'];
|
||||
this.shadowRoot.getElementById('operatorsmenu').value = condition['operator'];
|
||||
this.value = prefix +
|
||||
(condition.value ? condition.value : '');
|
||||
|
||||
this.dontupdate = false;
|
||||
}
|
||||
|
||||
this.onConditionSelected(menu.value);
|
||||
|
||||
this.shadowRoot.getElementById('conditionsmenu').focus();
|
||||
}
|
||||
|
||||
updateSearch() {
|
||||
if(this.parent && this.parent.search && !this.dontupdate)
|
||||
{
|
||||
var condition = this.selectedCondition;
|
||||
var operator = this.shadowRoot.getElementById('operatorsmenu').value;
|
||||
|
||||
// Regular text field
|
||||
if (!this.shadowRoot.getElementById('valuefield').hidden)
|
||||
{
|
||||
var value = this.shadowRoot.getElementById('valuefield').value;
|
||||
|
||||
// Convert datetimes to UTC before saving
|
||||
switch (condition) {
|
||||
case 'accessDate':
|
||||
case 'dateAdded':
|
||||
case 'dateModified':
|
||||
if (Zotero.Date.isSQLDateTime(value)) {
|
||||
var value = Zotero.Date.dateToSQL(Zotero.Date.sqlToDate(value), true);
|
||||
}
|
||||
}
|
||||
|
||||
// Append mode to condition
|
||||
if (this.shadowRoot.getElementById('valuefield').mode){
|
||||
condition += '/' + this.shadowRoot.getElementById('valuefield').mode;
|
||||
}
|
||||
}
|
||||
|
||||
// isInTheLast operator
|
||||
else if (!this.shadowRoot.getElementById('value-date-age').hidden)
|
||||
{
|
||||
var value = this.shadowRoot.getElementById('value-date-age').value;
|
||||
}
|
||||
|
||||
// Handle special C1234 and S5678 form for
|
||||
// collections and searches
|
||||
else if (condition == 'collection') {
|
||||
var letter = this.shadowRoot.getElementById('valuemenu').value.substr(0,1);
|
||||
if (letter=='C')
|
||||
{
|
||||
condition = 'collection';
|
||||
}
|
||||
else if (letter=='S')
|
||||
{
|
||||
condition = 'savedSearch';
|
||||
}
|
||||
var value = this.shadowRoot.getElementById('valuemenu').value.substr(1);
|
||||
}
|
||||
|
||||
// Regular drop-down menu
|
||||
else
|
||||
{
|
||||
var value = this.shadowRoot.getElementById('valuemenu').value;
|
||||
}
|
||||
this.parent.search.updateCondition(this.conditionID, condition, operator, value);
|
||||
}
|
||||
}
|
||||
|
||||
updateSubmenuCheckboxes(menu) {
|
||||
for (let i = 0; i < menu.itemCount; i++) {
|
||||
let item = menu.getItemAtIndex(i);
|
||||
if (item.localName == 'menuitem') {
|
||||
if (item.getAttribute('value') == this.selectedCondition) {
|
||||
item.setAttribute('checked', true);
|
||||
}
|
||||
else {
|
||||
item.removeAttribute('checked');
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.updateSubmenuCheckboxes(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
revealSelectedCondition(menu) {
|
||||
if (!this.selectedCondition || this.isPrimaryCondition(this.selectedCondition)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!menu) {
|
||||
menu = this.shadowRoot.getElementById('conditionsmenu');
|
||||
}
|
||||
for (let i = 0; i < menu.itemCount; i++) {
|
||||
let item = menu.getItemAtIndex(i);
|
||||
if (item.localName == 'menuitem') {
|
||||
if (item.getAttribute('value') == this.selectedCondition) {
|
||||
menu.open = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var opened = this.revealSelectedCondition(item);
|
||||
if (opened) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
onLibraryChange() {
|
||||
switch (this.selectedCondition) {
|
||||
case 'collection':
|
||||
this.onConditionSelected(this.selectedCondition, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
onRemoveClicked() {
|
||||
if (this.parent){
|
||||
this.parent.removeCondition(this.conditionID);
|
||||
window.sizeToContent()
|
||||
}
|
||||
}
|
||||
|
||||
onAddClicked() {
|
||||
if (this.parent){
|
||||
let ref = this.parent.search.getCondition(
|
||||
this.parent.search.addCondition(
|
||||
this.shadowRoot.getElementById('conditionsmenu').getAttribute('data-value'),
|
||||
this.shadowRoot.getElementById('operatorsmenu').value,
|
||||
""
|
||||
)
|
||||
)
|
||||
this.parent.addCondition(ref);
|
||||
window.sizeToContent();
|
||||
}
|
||||
}
|
||||
|
||||
disableRemoveButton() {
|
||||
var button = this.shadowRoot.getElementById("remove");
|
||||
button.setAttribute('disabled', true);
|
||||
button.removeAttribute('onclick');
|
||||
}
|
||||
|
||||
enableRemoveButton() {
|
||||
var button = this.shadowRoot.getElementById("remove");
|
||||
button.setAttribute('disabled', false);
|
||||
button.setAttribute('onclick', "this.getRootNode().host.onRemoveClicked(event)");
|
||||
}
|
||||
}
|
||||
customElements.define("zoterosearchcondition", ZoteroSearchCondition);
|
||||
|
||||
class ZoteroSearchTextbox extends SearchElementBase {
|
||||
content = MozXULElement.parseXULToFragment(`
|
||||
<xul:stack
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
flex="1">
|
||||
<html:input id="search-textbox"
|
||||
is="shadow-autocomplete-input"
|
||||
autocompletesearch="zotero"
|
||||
autocompletepopup="search-autocomplete-popup"
|
||||
timeout="250"
|
||||
type="search"/>
|
||||
|
||||
<xul:toolbarbutton
|
||||
id="textbox-button"
|
||||
type="menu">
|
||||
<dropmarker type="menu" class="toolbarbutton-menu-dropmarker"/>
|
||||
<xul:menupopup id="textbox-fulltext-menu">
|
||||
<xul:menuitem type="radio" label="&zotero.search.textModes.phrase;"/>
|
||||
<xul:menuitem type="radio" label="&zotero.search.textModes.phraseBinary;"/>
|
||||
<xul:menuitem type="radio" label="&zotero.search.textModes.regexp;"/>
|
||||
<xul:menuitem type="radio" label="&zotero.search.textModes.regexpCS;"/>
|
||||
</xul:menupopup>
|
||||
</xul:toolbarbutton>
|
||||
</xul:stack>
|
||||
`, ['chrome://zotero/locale/zotero.dtd', 'chrome://zotero/locale/searchbox.dtd']);
|
||||
|
||||
get value() {
|
||||
return this.shadowRoot.getElementById('search-textbox').value;
|
||||
}
|
||||
|
||||
set value(val) {
|
||||
this.shadowRoot.getElementById('search-textbox').value = val;
|
||||
}
|
||||
|
||||
get mode() {
|
||||
if (this.getAttribute('hasOptions')!='true'){
|
||||
return false;
|
||||
}
|
||||
|
||||
var menu = this.shadowRoot.getElementById('textbox-fulltext-menu');
|
||||
|
||||
var selectedIndex = -1;
|
||||
for (var i=0; i<menu.childNodes.length; i++){
|
||||
if (menu.childNodes[i].getAttribute('checked')=='true'){
|
||||
selectedIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (selectedIndex){
|
||||
case 0:
|
||||
return false;
|
||||
|
||||
case 1:
|
||||
return 'phraseBinary';
|
||||
|
||||
case 2:
|
||||
return 'regexp';
|
||||
|
||||
case 3:
|
||||
return 'regexpCS';
|
||||
}
|
||||
|
||||
throw new Error('Invalid search textbox popup');
|
||||
}
|
||||
|
||||
update(condition, mode) {
|
||||
var textbox = this.shadowRoot.getElementById('search-textbox');
|
||||
var button = this.shadowRoot.getElementById('textbox-button');
|
||||
|
||||
switch (condition){
|
||||
case 'fulltextContent':
|
||||
var menu = this.shadowRoot.getElementById('textbox-fulltext-menu');
|
||||
this.setAttribute('hasOptions', true);
|
||||
button.setAttribute('hidden', false);
|
||||
|
||||
var selectedIndex = 0;
|
||||
if (mode){
|
||||
switch (mode){
|
||||
case 'phrase':
|
||||
selectedIndex = 0;
|
||||
break;
|
||||
|
||||
case 'phraseBinary':
|
||||
selectedIndex = 1;
|
||||
break;
|
||||
|
||||
case 'regexp':
|
||||
selectedIndex = 2;
|
||||
break;
|
||||
|
||||
case 'regexpCS':
|
||||
selectedIndex = 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
menu.childNodes[selectedIndex].setAttribute('checked', true);
|
||||
textbox.setAttribute('disableautocomplete', 'true');
|
||||
break;
|
||||
|
||||
default:
|
||||
this.setAttribute('hasOptions', false);
|
||||
button.setAttribute('hidden', true);
|
||||
|
||||
// Set textbox to autocomplete mode
|
||||
switch (condition)
|
||||
{
|
||||
// Skip autocomplete for these fields
|
||||
case 'date':
|
||||
case 'note':
|
||||
case 'extra':
|
||||
textbox.setAttribute('disableautocomplete', 'true');
|
||||
break;
|
||||
|
||||
default:
|
||||
textbox.setAttribute('disableautocomplete', 'false');
|
||||
|
||||
// TODO: Provide current libraryID
|
||||
var autocompleteParams = {
|
||||
fieldName: condition
|
||||
};
|
||||
switch (condition) {
|
||||
case 'creator':
|
||||
case 'author':
|
||||
case 'bookAuthor':
|
||||
case 'editor':
|
||||
autocompleteParams.fieldMode = 2;
|
||||
break;
|
||||
}
|
||||
textbox.setAttribute(
|
||||
'autocompletesearchparam',
|
||||
JSON.stringify(autocompleteParams)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
customElements.define("zoterosearchtextbox", ZoteroSearchTextbox);
|
||||
|
||||
class ZoteroSearchAgeField extends SearchElementBase {
|
||||
content = MozXULElement.parseXULToFragment(`
|
||||
<xul:hbox id="search-in-the-last" flex="1"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml">
|
||||
<html:input id="input" style="-moz-box-flex: 1"/>
|
||||
<xul:menulist id="age-list" native="true">
|
||||
<xul:menupopup flex="1">
|
||||
<xul:menuitem label="&zotero.search.date.units.days;" value="days" selected="true"/>
|
||||
<xul:menuitem label="&zotero.search.date.units.months;" value="months"/>
|
||||
<xul:menuitem label="&zotero.search.date.units.years;" value="years"/>
|
||||
</xul:menupopup>
|
||||
</xul:menulist>
|
||||
</xul:hbox>
|
||||
`, ['chrome://zotero/locale/zotero.dtd', 'chrome://zotero/locale/searchbox.dtd']);
|
||||
|
||||
get value() {
|
||||
var input = this.shadowRoot.getElementById('input');
|
||||
var menulist = this.shadowRoot.getElementById('age-list');
|
||||
return input.value + ' '
|
||||
+ menulist.firstChild.childNodes[menulist.selectedIndex].getAttribute('value');
|
||||
}
|
||||
|
||||
set value(val) {
|
||||
var input = this.shadowRoot.getElementById('input');
|
||||
|
||||
var [num, units] = val.split(' ');
|
||||
input.setAttribute('value', num);
|
||||
|
||||
var menulist = this.shadowRoot.getElementById('age-list');
|
||||
var menupopup = menulist.firstChild;
|
||||
|
||||
var selectThis = 0;
|
||||
for (var i=0; i<menupopup.childNodes.length; i++){
|
||||
if (menupopup.childNodes[i].value == units)
|
||||
{
|
||||
selectThis = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
menulist.selectedIndex = selectThis;
|
||||
}
|
||||
}
|
||||
customElements.define("zoterosearchagefield", ZoteroSearchAgeField);
|
||||
}
|
|
@ -41,6 +41,8 @@ function doLoad()
|
|||
searchBox.groups = io.dataIn.groups;
|
||||
searchBox.search = io.dataIn.search;
|
||||
document.getElementById('search-name').value = io.dataIn.name;
|
||||
|
||||
document.addEventListener('dialogaccept', doAccept);
|
||||
}
|
||||
|
||||
function doUnload()
|
||||
|
|
|
@ -5,25 +5,39 @@
|
|||
|
||||
<!DOCTYPE bindings SYSTEM "chrome://zotero/locale/searchbox.dtd">
|
||||
|
||||
<dialog
|
||||
id="zotero-search-dialog"
|
||||
<window
|
||||
title="Search"
|
||||
orient="vertical"
|
||||
buttons="cancel,accept"
|
||||
ondialogaccept="doAccept();"
|
||||
onload="doLoad();"
|
||||
onunload="doUnload();"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
style="padding:2em">
|
||||
<dialog
|
||||
id="zotero-search-dialog"
|
||||
buttons="cancel,accept">
|
||||
|
||||
<script>
|
||||
var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
Services.scriptloader.loadSubScript("chrome://zotero/content/elements/zoteroSearch.js", this);
|
||||
</script>
|
||||
|
||||
<script src="include.js"/>
|
||||
<script src="searchDialog.js"/>
|
||||
|
||||
<popupset>
|
||||
<panel is="autocomplete-richlistbox-popup"
|
||||
id="search-autocomplete-popup"
|
||||
type="autocomplete-richlistbox"
|
||||
noautofocus="true"/>
|
||||
</popupset>
|
||||
|
||||
<vbox id="zotero-search-box-container" flex="1">
|
||||
<hbox align="center">
|
||||
<label value="&zotero.search.name;"/>
|
||||
<textbox id="search-name" width="275" maxlength="80"/>
|
||||
<html:input id="search-name" type="text" width="275" maxlength="80"/>
|
||||
</hbox>
|
||||
<zoterosearch id="search-box" flex="1"/>
|
||||
</vbox>
|
||||
</dialog>
|
||||
</window>
|
|
@ -1124,7 +1124,7 @@ var ZoteroPane = new function()
|
|||
);
|
||||
|
||||
var io = { dataIn: { search: s, name }, dataOut: null };
|
||||
window.openDialog('chrome://zotero/content/searchDialog.xul','','chrome,modal',io);
|
||||
window.openDialog('chrome://zotero/content/searchDialog.xhtml','','chrome,modal',io);
|
||||
if (!io.dataOut) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1155,7 +1155,7 @@ var ZoteroPane = new function()
|
|||
s.addCondition('title', 'contains', '');
|
||||
|
||||
var io = {dataIn: {search: s}, dataOut: null};
|
||||
window.openDialog('chrome://zotero/content/advancedSearch.xul', '', 'chrome,dialog=no,centerscreen', io);
|
||||
window.openDialog('chrome://zotero/content/advancedSearch.xhtml', '', 'chrome,dialog=no,centerscreen', io);
|
||||
};
|
||||
|
||||
this.initItemsTree = async function () {
|
||||
|
@ -2161,7 +2161,7 @@ var ZoteroPane = new function()
|
|||
},
|
||||
dataOut: null
|
||||
};
|
||||
window.openDialog('chrome://zotero/content/searchDialog.xul','','chrome,modal',io);
|
||||
window.openDialog('chrome://zotero/content/searchDialog.xhtml','','chrome,modal',io);
|
||||
if (io.dataOut) {
|
||||
row.ref.fromJSON(io.dataOut.json);
|
||||
yield row.ref.saveTx();
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
#search-box
|
||||
{
|
||||
width: 60em;
|
||||
}
|
||||
|
||||
#search-box > hbox {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
groupbox {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
caption {
|
||||
font: inherit;
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
label:first-child, checkbox:first-child {
|
||||
margin-left: 0 !important;
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
checkbox {
|
||||
margin-right: .5em;
|
||||
}
|
||||
|
||||
#search-condition menulist[id="operatorsmenu"]
|
||||
{
|
||||
width: 15em;
|
||||
}
|
||||
|
||||
#condition-tooltips tooltip
|
||||
{
|
||||
background: red !important;
|
||||
}
|
||||
|
||||
#condition-tooltips row > label
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#search-textbox toolbarbutton
|
||||
{
|
||||
padding: 0;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
#search-textbox:not([hasOptions=true]) toolbarbutton
|
||||
{
|
||||
display: none;
|
||||
}
|
||||
|
||||
#search-textbox .toolbarbutton-text
|
||||
{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#search-textbox .toolbarbutton-menu-dropmarker
|
||||
{
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
#search-in-the-last textbox
|
||||
{
|
||||
min-width: 3em;
|
||||
}
|
|
@ -60,28 +60,6 @@ relatedbox
|
|||
-moz-user-focus: ignore;
|
||||
}
|
||||
|
||||
zoterosearch
|
||||
{
|
||||
-moz-binding: url('chrome://zotero/content/bindings/zoterosearch.xml#search-box');
|
||||
}
|
||||
|
||||
|
||||
zoterosearchcondition
|
||||
{
|
||||
-moz-binding: url('chrome://zotero/content/bindings/zoterosearch.xml#search-condition');
|
||||
}
|
||||
|
||||
zoterosearchtextbox
|
||||
{
|
||||
-moz-binding: url('chrome://zotero/content/bindings/zoterosearch.xml#search-textbox');
|
||||
}
|
||||
|
||||
|
||||
zoterosearchagefield
|
||||
{
|
||||
-moz-binding: url('chrome://zotero/content/bindings/zoterosearch.xml#search-in-the-last');
|
||||
}
|
||||
|
||||
zoteromergegroup {
|
||||
-moz-binding: url('chrome://zotero/content/bindings/merge.xml#merge-group');
|
||||
}
|
||||
|
|
2
scss/_zoteroSearch.scss
Normal file
2
scss/_zoteroSearch.scss
Normal file
|
@ -0,0 +1,2 @@
|
|||
@import "components/zoteroSearch";
|
||||
@import "components/clicky";
|
55
scss/components/_zoteroSearch.scss
Normal file
55
scss/components/_zoteroSearch.scss
Normal file
|
@ -0,0 +1,55 @@
|
|||
#search-box > hbox, #search-box > groupbox {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
groupbox {
|
||||
margin-top: 0;
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
caption {
|
||||
font: inherit;
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
label:first-child:not(tooltip label), checkbox:first-child {
|
||||
margin-left: 0 !important;
|
||||
padding-left: 0 !important;
|
||||
}
|
||||
|
||||
checkbox {
|
||||
margin-right: .5em;
|
||||
}
|
||||
|
||||
#operatorsmenu {
|
||||
width: 15em;
|
||||
}
|
||||
|
||||
#condition-tooltips tooltip
|
||||
{
|
||||
background: red !important;
|
||||
}
|
||||
|
||||
#condition-tooltips hbox > label
|
||||
{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.toolbarbutton-text
|
||||
{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#textbox-button {
|
||||
cursor: default;
|
||||
appearance: none;
|
||||
justify-self: end;
|
||||
margin-inline-end: 8px;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
#search-in-the-last input
|
||||
{
|
||||
min-width: 3em;
|
||||
}
|
1
scss/zoteroSearch-mac.scss
Normal file
1
scss/zoteroSearch-mac.scss
Normal file
|
@ -0,0 +1 @@
|
|||
@import "zoteroSearch";
|
1
scss/zoteroSearch-unix.scss
Normal file
1
scss/zoteroSearch-unix.scss
Normal file
|
@ -0,0 +1 @@
|
|||
@import "zoteroSearch";
|
1
scss/zoteroSearch-win.scss
Normal file
1
scss/zoteroSearch-win.scss
Normal file
|
@ -0,0 +1 @@
|
|||
@import "zoteroSearch";
|
|
@ -19,7 +19,7 @@ describe("Advanced Search", function () {
|
|||
it("should perform a search", function* () {
|
||||
var item = yield createDataObject('item', { setTitle: true });
|
||||
|
||||
var promise = waitForWindow('chrome://zotero/content/advancedSearch.xul');
|
||||
var promise = waitForWindow('chrome://zotero/content/advancedSearch.xhtml');
|
||||
zp.openAdvancedSearchWindow();
|
||||
var searchWin = yield promise;
|
||||
|
||||
|
@ -51,7 +51,7 @@ describe("Advanced Search", function () {
|
|||
var searchWin, searchBox, conditions;
|
||||
|
||||
before(function* () {
|
||||
var promise = waitForWindow('chrome://zotero/content/advancedSearch.xul');
|
||||
var promise = waitForWindow('chrome://zotero/content/advancedSearch.xhtml');
|
||||
zp.openAdvancedSearchWindow();
|
||||
searchWin = yield promise;
|
||||
searchBox = searchWin.document.getElementById('zotero-search-box');
|
||||
|
|
|
@ -73,7 +73,7 @@ describe("ZoteroPane", function() {
|
|||
// TODO: Test changing a condition
|
||||
function (dialog) {},
|
||||
'accept',
|
||||
'chrome://zotero/content/searchDialog.xul'
|
||||
'chrome://zotero/content/searchDialog.xhtml'
|
||||
);
|
||||
var id = yield zp.newSearch();
|
||||
yield promise;
|
||||
|
@ -86,7 +86,7 @@ describe("ZoteroPane", function() {
|
|||
var promise = waitForDialog(
|
||||
function (dialog) {},
|
||||
'cancel',
|
||||
'chrome://zotero/content/searchDialog.xul'
|
||||
'chrome://zotero/content/searchDialog.xhtml'
|
||||
);
|
||||
var id = yield zp.newSearch();
|
||||
yield promise;
|
||||
|
@ -766,7 +766,7 @@ describe("ZoteroPane", function() {
|
|||
describe("#editSelectedCollection()", function () {
|
||||
it("should edit a saved search", function* () {
|
||||
var search = yield createDataObject('search');
|
||||
var promise = waitForWindow('chrome://zotero/content/searchDialog.xul', function (win) {
|
||||
var promise = waitForWindow('chrome://zotero/content/searchDialog.xhtml', function (win) {
|
||||
let searchBox = win.document.getElementById('search-box');
|
||||
var c = searchBox.search.getCondition(
|
||||
searchBox.search.addCondition("title", "contains", "foo")
|
||||
|
@ -783,7 +783,7 @@ describe("ZoteroPane", function() {
|
|||
it("should edit a saved search in a group", function* () {
|
||||
var group = yield getGroup();
|
||||
var search = yield createDataObject('search', { libraryID: group.libraryID });
|
||||
var promise = waitForWindow('chrome://zotero/content/searchDialog.xul', function (win) {
|
||||
var promise = waitForWindow('chrome://zotero/content/searchDialog.xhtml', function (win) {
|
||||
let searchBox = win.document.getElementById('search-box');
|
||||
var c = searchBox.search.getCondition(
|
||||
searchBox.search.addCondition("title", "contains", "foo")
|
||||
|
|
Loading…
Reference in a new issue