Fix post-save textbox focusing bugs in right-hand pane
Fix a couple cases of lost text field focus after an edit, including focusing of the Title field after using New Item when a field is already being edited and has a changed value. Also, in tests, select My Library and wait for items to load when using the loadZoteroPane() support function. We could add a parameter to skip that or move it to a separate function, but the code to detect it is a bit convoluted and it's a prerequisite for many tests, so it's handy to have a function for it.
This commit is contained in:
parent
590649fd49
commit
8fec5ace3a
|
@ -1682,8 +1682,6 @@
|
|||
<parameter name="textbox"/>
|
||||
<body><![CDATA[
|
||||
return Zotero.spawn(function* () {
|
||||
if (textbox.localName == 'textarea') return;
|
||||
|
||||
Zotero.debug('Hiding editor');
|
||||
|
||||
// Prevent autocomplete breakage in Firefox 3
|
||||
|
@ -1785,11 +1783,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
elem = this.createValueElement(
|
||||
val,
|
||||
fieldName,
|
||||
tabindex
|
||||
);
|
||||
var newVal = val;
|
||||
}
|
||||
|
||||
// Fields
|
||||
|
@ -1854,18 +1848,23 @@
|
|||
}
|
||||
}
|
||||
|
||||
this._modifyField(fieldName, value, this.saveOnEdit);
|
||||
yield this._modifyField(fieldName, value, this.saveOnEdit);
|
||||
|
||||
var newVal = this.item.getField(fieldName);
|
||||
}
|
||||
|
||||
// If box is still open (due to field not being modified and there not being
|
||||
// a refresh), close it manually
|
||||
if (textbox && textbox.parentNode) {
|
||||
elem = this.createValueElement(
|
||||
this.item.getField(fieldName),
|
||||
fieldName,
|
||||
tabindex
|
||||
);
|
||||
var box = textbox.parentNode;
|
||||
box.replaceChild(elem,textbox);
|
||||
}
|
||||
|
||||
var box = textbox.parentNode;
|
||||
box.replaceChild(elem,textbox);
|
||||
|
||||
if(field === 'creator') {
|
||||
// Reset creator mode settings here so that flex attribute gets reset
|
||||
this.switchCreatorMode(row, (otherFields.fieldMode ? 1 : 0), true);
|
||||
|
@ -1912,14 +1911,14 @@
|
|||
<parameter name="field"/>
|
||||
<parameter name="value"/>
|
||||
<parameter name="save"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
this.item.setField(field,value);
|
||||
if (save) {
|
||||
this.item.save();
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
<body><![CDATA[
|
||||
return Zotero.spawn(function* () {
|
||||
this.item.setField(field, value);
|
||||
if (save) {
|
||||
yield this.item.save();
|
||||
}
|
||||
}, this);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
|
||||
|
@ -1973,8 +1972,7 @@
|
|||
throw ("Invalid transform mode '" + mode + "' in zoteroitembox.textTransform()");
|
||||
}
|
||||
this._setFieldValue(label, newVal);
|
||||
this._modifyField(label.getAttribute('fieldname'), newVal, this.saveOnEdit);
|
||||
|
||||
this._modifyField(label.getAttribute('fieldname'), newVal, this.saveOnEdit).done();
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -2204,7 +2202,7 @@
|
|||
return Zotero.spawn(function* () {
|
||||
var textboxes = document.getAnonymousNodes(this)[0].getElementsByTagName('textbox');
|
||||
if (textboxes && textboxes.length) {
|
||||
yield this.blurHandler(textboxes[0].inputField);
|
||||
yield this.blurHandler(textboxes[0]);
|
||||
}
|
||||
}, this);
|
||||
]]></body>
|
||||
|
|
|
@ -153,6 +153,23 @@ var ZoteroItemPane = new function() {
|
|||
});
|
||||
|
||||
|
||||
this.blurOpenField = Zotero.Promise.coroutine(function* () {
|
||||
var tabBox = document.getElementById('zotero-view-tabbox');
|
||||
switch (tabBox.selectedIndex) {
|
||||
case 0:
|
||||
var box = _itemBox;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
var box = _tagsBox;
|
||||
break;
|
||||
}
|
||||
if (box) {
|
||||
yield box.blurOpenField();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.addNote = function (popup) {
|
||||
ZoteroPane_Local.newNote(popup, _lastItem.key);
|
||||
}
|
||||
|
|
|
@ -751,6 +751,8 @@ var ZoteroPane = new function()
|
|||
}
|
||||
}
|
||||
|
||||
yield ZoteroItemPane.blurOpenField();
|
||||
|
||||
if (row !== undefined && row !== null) {
|
||||
var collectionTreeRow = this.collectionsView.getRow(row);
|
||||
var libraryID = collectionTreeRow.ref.libraryID;
|
||||
|
|
|
@ -32,20 +32,30 @@ function loadBrowserWindow() {
|
|||
}
|
||||
|
||||
/**
|
||||
* Loads a Zotero pane in a new window. Returns the containing window.
|
||||
* Loads a Zotero pane in a new window and selects My Library. Returns the containing window.
|
||||
*/
|
||||
function loadZoteroPane() {
|
||||
return loadBrowserWindow().then(function(win) {
|
||||
win.ZoteroOverlay.toggleDisplay(true);
|
||||
|
||||
// Hack to wait for pane load to finish. This is the same hack
|
||||
// we use in ZoteroPane.js, so either it's not good enough
|
||||
// there or it should be good enough here.
|
||||
return Zotero.Promise.delay(52).then(function() {
|
||||
return win;
|
||||
});
|
||||
});
|
||||
}
|
||||
var loadZoteroPane = Zotero.Promise.coroutine(function* () {
|
||||
var win = yield loadBrowserWindow();
|
||||
win.ZoteroOverlay.toggleDisplay(true);
|
||||
|
||||
// Hack to wait for pane load to finish. This is the same hack
|
||||
// we use in ZoteroPane.js, so either it's not good enough
|
||||
// there or it should be good enough here.
|
||||
yield Zotero.Promise.delay(52);
|
||||
|
||||
var zp = win.ZoteroPane;
|
||||
var cv = zp.collectionsView;
|
||||
var resolve1, resolve2;
|
||||
var promise1 = new Zotero.Promise(() => resolve1 = arguments[0]);
|
||||
var promise2 = new Zotero.Promise(() => resolve2 = arguments[0]);
|
||||
cv.addEventListener('load', () => resolve1())
|
||||
yield promise1;
|
||||
cv.selection.select(0);
|
||||
zp.addEventListener('itemsLoaded', () => resolve2());
|
||||
yield promise2;
|
||||
|
||||
return win;
|
||||
});
|
||||
|
||||
/**
|
||||
* Waits for a window with a specific URL to open. Returns a promise for the window.
|
||||
|
|
|
@ -4,22 +4,10 @@ describe("Zotero.CollectionTreeView", function() {
|
|||
// Load Zotero pane and select library
|
||||
before(function* () {
|
||||
win = yield loadZoteroPane();
|
||||
var zp = win.ZoteroPane;
|
||||
var cv = zp.collectionsView;
|
||||
var resolve1, resolve2;
|
||||
var promise1 = new Zotero.Promise(() => resolve1 = arguments[0]);
|
||||
var promise2 = new Zotero.Promise(() => resolve2 = arguments[0]);
|
||||
cv.addEventListener('load', () => resolve1())
|
||||
yield promise1;
|
||||
cv.selection.select(0);
|
||||
zp.addEventListener('itemsLoaded', () => resolve2());
|
||||
yield promise2;
|
||||
collectionsView = zp.collectionsView;
|
||||
collectionsView = win.ZoteroPane.collectionsView;
|
||||
});
|
||||
after(function () {
|
||||
if (win) {
|
||||
win.close();
|
||||
}
|
||||
win.close();
|
||||
});
|
||||
|
||||
// Select library
|
||||
|
|
|
@ -4,25 +4,13 @@ describe("Zotero.ItemTreeView", function() {
|
|||
// Load Zotero pane and select library
|
||||
before(function* () {
|
||||
win = yield loadZoteroPane();
|
||||
var zp = win.ZoteroPane;
|
||||
var cv = zp.collectionsView;
|
||||
var resolve1, resolve2;
|
||||
var promise1 = new Zotero.Promise(() => resolve1 = arguments[0]);
|
||||
var promise2 = new Zotero.Promise(() => resolve2 = arguments[0]);
|
||||
cv.addEventListener('load', () => resolve1())
|
||||
yield promise1;
|
||||
cv.selection.select(0);
|
||||
zp.addEventListener('itemsLoaded', () => resolve2());
|
||||
yield promise2;
|
||||
itemsView = zp.itemsView;
|
||||
itemsView = win.ZoteroPane.itemsView;
|
||||
|
||||
var item = new Zotero.Item('book');
|
||||
existingItemID = yield item.save();
|
||||
});
|
||||
after(function () {
|
||||
if (win) {
|
||||
win.close();
|
||||
}
|
||||
win.close();
|
||||
});
|
||||
|
||||
describe("#selectItem()", function () {
|
||||
|
|
37
test/tests/zoteroPaneTest.js
Normal file
37
test/tests/zoteroPaneTest.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
describe("ZoteroPane", function() {
|
||||
var win, doc, zp;
|
||||
|
||||
// Load Zotero pane and select library
|
||||
before(function* () {
|
||||
win = yield loadZoteroPane();
|
||||
doc = win.document;
|
||||
zp = win.ZoteroPane;
|
||||
});
|
||||
|
||||
after(function () {
|
||||
win.close();
|
||||
});
|
||||
|
||||
describe("#newItem", function () {
|
||||
it("should create an item and focus the title field", function* () {
|
||||
yield zp.newItem(Zotero.ItemTypes.getID('book'), {}, null, true);
|
||||
var itemBox = doc.getElementById('zotero-editpane-item-box');
|
||||
var textboxes = doc.getAnonymousNodes(itemBox)[0].getElementsByTagName('textbox');
|
||||
assert.lengthOf(textboxes, 1);
|
||||
assert.equal(textboxes[0].getAttribute('fieldname'), 'title');
|
||||
textboxes[0].blur();
|
||||
yield Zotero.Promise.delay(1);
|
||||
})
|
||||
|
||||
it("should save an entered value when New Item is used", function* () {
|
||||
var value = "Test";
|
||||
var item = yield zp.newItem(Zotero.ItemTypes.getID('book'), {}, null, true);
|
||||
var itemBox = doc.getElementById('zotero-editpane-item-box');
|
||||
var textbox = doc.getAnonymousNodes(itemBox)[0].getElementsByTagName('textbox')[0];
|
||||
textbox.value = value;
|
||||
yield itemBox.blurOpenField();
|
||||
item = yield Zotero.Items.getAsync(item.id);
|
||||
assert.equal(item.getField('title'), value);
|
||||
})
|
||||
});
|
||||
})
|
Loading…
Reference in New Issue
Block a user