Relations overhaul (requires new DB upgrade from 4.0)
Relations are now properties of collections and items rather than
first-class objects, stored in separate collectionRelations and
itemRelations tables with ids for subjects, with foreign keys to the
associated data objects.
Related items now use dc:relation relations rather than a separate table
(among other reasons, because API syncing won't necessarily sync both
items at the same time, so they can't be stored by id).
The UI assigns related-item relations bidirectionally, and checks for
related-item and linked-object relations are done unidirectionally by
default.
dc:isReplacedBy is now dc:replaces, so that the subject is an existing
object, and the predicate is now named
Zotero.Attachments.replacedItemPredicate.
Some additional work is still needed, notably around following
replaced-item relations, and migration needs to be tested more fully,
but this seems to mostly work.
2015-06-02 00:09:39 +00:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
describe("Related Box", function () {
|
|
|
|
var win, doc, itemsView;
|
|
|
|
|
|
|
|
before(function* () {
|
|
|
|
win = yield loadZoteroPane();
|
|
|
|
doc = win.document;
|
|
|
|
itemsView = win.ZoteroPane.itemsView;
|
|
|
|
});
|
|
|
|
after(function () {
|
|
|
|
win.close();
|
|
|
|
})
|
|
|
|
|
2021-09-14 05:48:36 +00:00
|
|
|
it("should update if a related item is renamed", async function () {
|
|
|
|
var title1 = 'aaaaaa';
|
|
|
|
var title2 = 'bbbbbb';
|
|
|
|
var item1 = await createDataObject('item', { title: title1 });
|
|
|
|
var item2 = await createDataObject('item', { title: title2 });
|
|
|
|
item1.addRelatedItem(item2);
|
|
|
|
await item1.saveTx();
|
|
|
|
item2.addRelatedItem(item1);
|
|
|
|
await item2.saveTx();
|
|
|
|
|
|
|
|
// Select the Related pane
|
|
|
|
var tabbox = doc.getElementById('zotero-view-tabbox');
|
|
|
|
tabbox.selectedIndex = 3;
|
|
|
|
var relatedbox = doc.getElementById('zotero-editpane-related');
|
|
|
|
|
|
|
|
// Wait for relations list to populate
|
|
|
|
do {
|
|
|
|
await Zotero.Promise.delay(50);
|
|
|
|
}
|
|
|
|
while (!relatedbox.id('relatedRows').childNodes.length);
|
|
|
|
|
|
|
|
assert.include(doc.getAnonymousNodes(relatedbox)[0].innerHTML, title1);
|
|
|
|
|
|
|
|
title1 = 'cccccc';
|
|
|
|
item1.setField('title', title1);
|
|
|
|
await item1.saveTx();
|
|
|
|
|
|
|
|
// New title should appear in list
|
|
|
|
do {
|
|
|
|
await Zotero.Promise.delay(50);
|
|
|
|
}
|
|
|
|
while (!doc.getAnonymousNodes(relatedbox)[0].innerHTML.includes(title1));
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should update if a related item is deleted", async function () {
|
|
|
|
var title1 = 'aaaaaa';
|
|
|
|
var title2 = 'bbbbbb';
|
|
|
|
var item1 = await createDataObject('item', { title: title1 });
|
|
|
|
var item2 = await createDataObject('item', { title: title2 });
|
|
|
|
item1.addRelatedItem(item2);
|
|
|
|
await item1.saveTx();
|
|
|
|
item2.addRelatedItem(item1);
|
|
|
|
await item2.saveTx();
|
|
|
|
|
|
|
|
// Select the Related pane
|
|
|
|
var tabbox = doc.getElementById('zotero-view-tabbox');
|
|
|
|
tabbox.selectedIndex = 3;
|
|
|
|
var relatedbox = doc.getElementById('zotero-editpane-related');
|
|
|
|
|
|
|
|
// Wait for relations list to populate
|
|
|
|
do {
|
|
|
|
await Zotero.Promise.delay(50);
|
|
|
|
}
|
|
|
|
while (!relatedbox.id('relatedRows').childNodes.length);
|
|
|
|
|
|
|
|
assert.include(doc.getAnonymousNodes(relatedbox)[0].innerHTML, title1);
|
|
|
|
|
|
|
|
await item1.eraseTx();
|
|
|
|
|
|
|
|
// Deleted item should be removed from list
|
|
|
|
do {
|
|
|
|
await Zotero.Promise.delay(50);
|
|
|
|
}
|
|
|
|
while (doc.getAnonymousNodes(relatedbox)[0].innerHTML.includes(title1));
|
|
|
|
});
|
|
|
|
|
Relations overhaul (requires new DB upgrade from 4.0)
Relations are now properties of collections and items rather than
first-class objects, stored in separate collectionRelations and
itemRelations tables with ids for subjects, with foreign keys to the
associated data objects.
Related items now use dc:relation relations rather than a separate table
(among other reasons, because API syncing won't necessarily sync both
items at the same time, so they can't be stored by id).
The UI assigns related-item relations bidirectionally, and checks for
related-item and linked-object relations are done unidirectionally by
default.
dc:isReplacedBy is now dc:replaces, so that the subject is an existing
object, and the predicate is now named
Zotero.Attachments.replacedItemPredicate.
Some additional work is still needed, notably around following
replaced-item relations, and migration needs to be tested more fully,
but this seems to mostly work.
2015-06-02 00:09:39 +00:00
|
|
|
describe("Add button", function () {
|
|
|
|
it("should add a related item", function* () {
|
|
|
|
var item1 = yield createDataObject('item');
|
|
|
|
var item2 = yield createDataObject('item');
|
|
|
|
|
|
|
|
// Select the Related pane
|
|
|
|
var tabbox = doc.getElementById('zotero-view-tabbox');
|
|
|
|
tabbox.selectedIndex = 3;
|
|
|
|
var relatedbox = doc.getElementById('zotero-editpane-related');
|
|
|
|
assert.lengthOf(relatedbox.id('relatedRows').childNodes, 0);
|
|
|
|
|
|
|
|
// Click the Add button to open the Select Items dialog
|
|
|
|
setTimeout(function () {
|
|
|
|
relatedbox.id('addButton').click();
|
|
|
|
});
|
|
|
|
var selectWin = yield waitForWindow('chrome://zotero/content/selectItemsDialog.xul');
|
|
|
|
// wrappedJSObject isn't working on zotero-collections-tree for some reason, so
|
|
|
|
// just wait for the items tree to be created and select it directly
|
|
|
|
do {
|
XUL -> JS tree megacommit
- Just a single huge commit. This has been developed over too long a
time, required many tiny changes across too many files and has seen too
many iterations to be separated into separate commits.
The original branch with all the messy commits will be kept around for
posterity
https://github.com/zotero/zotero/compare/bb220ad0f2d6bf0eca6df6d225d3d358cb50a27b...adomasven:feature/react-item-tree
- Replaces XUL <tree> element across the whole zotero client codebase
with a custom supermegafast virtualized-table inspired by
react-virtualized yet mimicking old XUL treeview API. The
virtualized-table sits on top on a raw-to-the-metal,
interpreted-at-runtime JS based windowing solution inspired by
react-window. React-based solutions could not be used because they were
slow and Zotero UI needs to be responsive and be able to
display thousands of rows in a treeview without any slowdowns.
- Attempts were made at making this screen-reader friendly, but yet to
be tested with something like JAWS
- RTL-friendly
- Styling and behaviour across all platforms was copied as closely as
possible to the original XUL tree
- Instead of row-based scroll snapping this has smooth-scrolling. If
you're using arrow keys to browse through the tree then it effectively
snap-scrolls. Current CSS snap scroll attributes do not seem to work in
the way we would require even on up-to-date browsers, yet alone the ESR
version of FX that Zotero is on. JS solutions are either terrible for
performance or produce inexcusable jitter.
- When dragging-and-dropping items the initial drag freezes the UI for
a fairly jarring amount of time. Does not seem to be fixable due to
the synchronous code that needs to be run in the dragstart handler.
Used to be possible to run that code async with the XUL tree.
- Item tree column picker no longer has a dedicated button. Just
right-click the columns. The column preferences (width, order, etc) are
no longer handled by XUL, which required a custom serialization and
storage solution that throws warnings in the developer console due to
the amount of data being stored. Might cause temporary freezing on HDDs
upon column resize/reorder/visibility toggling.
- Context menu handling code basically unchanged, but any UI changes
that plugins may have wanted to do (including adding new columns) will
have to be redone by them. No serious thought has gone into how plugin
developers would achieve that yet.
- Opens up the possibility for awesome alternative ways to render the
tree items, including things like multiple-row view for the item tree,
which has been requested for a long while especially by users switching
from other referencing software
2020-06-03 07:29:46 +00:00
|
|
|
var selectItemsView = selectWin.itemsView;
|
|
|
|
var selectCollectionsView = selectWin.collectionsView;
|
Relations overhaul (requires new DB upgrade from 4.0)
Relations are now properties of collections and items rather than
first-class objects, stored in separate collectionRelations and
itemRelations tables with ids for subjects, with foreign keys to the
associated data objects.
Related items now use dc:relation relations rather than a separate table
(among other reasons, because API syncing won't necessarily sync both
items at the same time, so they can't be stored by id).
The UI assigns related-item relations bidirectionally, and checks for
related-item and linked-object relations are done unidirectionally by
default.
dc:isReplacedBy is now dc:replaces, so that the subject is an existing
object, and the predicate is now named
Zotero.Attachments.replacedItemPredicate.
Some additional work is still needed, notably around following
replaced-item relations, and migration needs to be tested more fully,
but this seems to mostly work.
2015-06-02 00:09:39 +00:00
|
|
|
yield Zotero.Promise.delay(50);
|
|
|
|
}
|
XUL -> JS tree megacommit
- Just a single huge commit. This has been developed over too long a
time, required many tiny changes across too many files and has seen too
many iterations to be separated into separate commits.
The original branch with all the messy commits will be kept around for
posterity
https://github.com/zotero/zotero/compare/bb220ad0f2d6bf0eca6df6d225d3d358cb50a27b...adomasven:feature/react-item-tree
- Replaces XUL <tree> element across the whole zotero client codebase
with a custom supermegafast virtualized-table inspired by
react-virtualized yet mimicking old XUL treeview API. The
virtualized-table sits on top on a raw-to-the-metal,
interpreted-at-runtime JS based windowing solution inspired by
react-window. React-based solutions could not be used because they were
slow and Zotero UI needs to be responsive and be able to
display thousands of rows in a treeview without any slowdowns.
- Attempts were made at making this screen-reader friendly, but yet to
be tested with something like JAWS
- RTL-friendly
- Styling and behaviour across all platforms was copied as closely as
possible to the original XUL tree
- Instead of row-based scroll snapping this has smooth-scrolling. If
you're using arrow keys to browse through the tree then it effectively
snap-scrolls. Current CSS snap scroll attributes do not seem to work in
the way we would require even on up-to-date browsers, yet alone the ESR
version of FX that Zotero is on. JS solutions are either terrible for
performance or produce inexcusable jitter.
- When dragging-and-dropping items the initial drag freezes the UI for
a fairly jarring amount of time. Does not seem to be fixable due to
the synchronous code that needs to be run in the dragstart handler.
Used to be possible to run that code async with the XUL tree.
- Item tree column picker no longer has a dedicated button. Just
right-click the columns. The column preferences (width, order, etc) are
no longer handled by XUL, which required a custom serialization and
storage solution that throws warnings in the developer console due to
the amount of data being stored. Might cause temporary freezing on HDDs
upon column resize/reorder/visibility toggling.
- Context menu handling code basically unchanged, but any UI changes
that plugins may have wanted to do (including adding new columns) will
have to be redone by them. No serious thought has gone into how plugin
developers would achieve that yet.
- Opens up the possibility for awesome alternative ways to render the
tree items, including things like multiple-row view for the item tree,
which has been requested for a long while especially by users switching
from other referencing software
2020-06-03 07:29:46 +00:00
|
|
|
while (!selectItemsView || !selectCollectionsView);
|
|
|
|
yield selectCollectionsView.waitForLoad();
|
|
|
|
yield selectItemsView.waitForLoad();
|
Relations overhaul (requires new DB upgrade from 4.0)
Relations are now properties of collections and items rather than
first-class objects, stored in separate collectionRelations and
itemRelations tables with ids for subjects, with foreign keys to the
associated data objects.
Related items now use dc:relation relations rather than a separate table
(among other reasons, because API syncing won't necessarily sync both
items at the same time, so they can't be stored by id).
The UI assigns related-item relations bidirectionally, and checks for
related-item and linked-object relations are done unidirectionally by
default.
dc:isReplacedBy is now dc:replaces, so that the subject is an existing
object, and the predicate is now named
Zotero.Attachments.replacedItemPredicate.
Some additional work is still needed, notably around following
replaced-item relations, and migration needs to be tested more fully,
but this seems to mostly work.
2015-06-02 00:09:39 +00:00
|
|
|
|
|
|
|
// Select the other item
|
XUL -> JS tree megacommit
- Just a single huge commit. This has been developed over too long a
time, required many tiny changes across too many files and has seen too
many iterations to be separated into separate commits.
The original branch with all the messy commits will be kept around for
posterity
https://github.com/zotero/zotero/compare/bb220ad0f2d6bf0eca6df6d225d3d358cb50a27b...adomasven:feature/react-item-tree
- Replaces XUL <tree> element across the whole zotero client codebase
with a custom supermegafast virtualized-table inspired by
react-virtualized yet mimicking old XUL treeview API. The
virtualized-table sits on top on a raw-to-the-metal,
interpreted-at-runtime JS based windowing solution inspired by
react-window. React-based solutions could not be used because they were
slow and Zotero UI needs to be responsive and be able to
display thousands of rows in a treeview without any slowdowns.
- Attempts were made at making this screen-reader friendly, but yet to
be tested with something like JAWS
- RTL-friendly
- Styling and behaviour across all platforms was copied as closely as
possible to the original XUL tree
- Instead of row-based scroll snapping this has smooth-scrolling. If
you're using arrow keys to browse through the tree then it effectively
snap-scrolls. Current CSS snap scroll attributes do not seem to work in
the way we would require even on up-to-date browsers, yet alone the ESR
version of FX that Zotero is on. JS solutions are either terrible for
performance or produce inexcusable jitter.
- When dragging-and-dropping items the initial drag freezes the UI for
a fairly jarring amount of time. Does not seem to be fixable due to
the synchronous code that needs to be run in the dragstart handler.
Used to be possible to run that code async with the XUL tree.
- Item tree column picker no longer has a dedicated button. Just
right-click the columns. The column preferences (width, order, etc) are
no longer handled by XUL, which required a custom serialization and
storage solution that throws warnings in the developer console due to
the amount of data being stored. Might cause temporary freezing on HDDs
upon column resize/reorder/visibility toggling.
- Context menu handling code basically unchanged, but any UI changes
that plugins may have wanted to do (including adding new columns) will
have to be redone by them. No serious thought has gone into how plugin
developers would achieve that yet.
- Opens up the possibility for awesome alternative ways to render the
tree items, including things like multiple-row view for the item tree,
which has been requested for a long while especially by users switching
from other referencing software
2020-06-03 07:29:46 +00:00
|
|
|
yield selectItemsView.selectItem(item1.id);
|
Relations overhaul (requires new DB upgrade from 4.0)
Relations are now properties of collections and items rather than
first-class objects, stored in separate collectionRelations and
itemRelations tables with ids for subjects, with foreign keys to the
associated data objects.
Related items now use dc:relation relations rather than a separate table
(among other reasons, because API syncing won't necessarily sync both
items at the same time, so they can't be stored by id).
The UI assigns related-item relations bidirectionally, and checks for
related-item and linked-object relations are done unidirectionally by
default.
dc:isReplacedBy is now dc:replaces, so that the subject is an existing
object, and the predicate is now named
Zotero.Attachments.replacedItemPredicate.
Some additional work is still needed, notably around following
replaced-item relations, and migration needs to be tested more fully,
but this seems to mostly work.
2015-06-02 00:09:39 +00:00
|
|
|
selectWin.document.documentElement.acceptDialog();
|
|
|
|
|
|
|
|
// Wait for relations list to populate
|
|
|
|
do {
|
|
|
|
yield Zotero.Promise.delay(50);
|
|
|
|
}
|
|
|
|
while (!relatedbox.id('relatedRows').childNodes.length);
|
|
|
|
|
|
|
|
assert.lengthOf(relatedbox.id('relatedRows').childNodes, 1);
|
|
|
|
|
|
|
|
var items = item1.relatedItems;
|
|
|
|
assert.lengthOf(items, 1);
|
|
|
|
assert.equal(items[0], item2.key);
|
|
|
|
|
|
|
|
// Relation should be assigned bidirectionally
|
|
|
|
var items = item2.relatedItems;
|
|
|
|
assert.lengthOf(items, 1);
|
|
|
|
assert.equal(items[0], item1.key);
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
describe("Remove button", function () {
|
|
|
|
it("should remove a related item", function* () {
|
|
|
|
var item1 = yield createDataObject('item');
|
|
|
|
var item2 = yield createDataObject('item');
|
|
|
|
|
|
|
|
item1.addRelatedItem(item2);
|
Deasyncification :back: :cry:
While trying to get translation and citing working with asynchronously
generated data, we realized that drag-and-drop support was going to
be...problematic. Firefox only supports synchronous methods for
providing drag data (unlike, it seems, the DataTransferItem interface
supported by Chrome), which means that we'd need to preload all relevant
data on item selection (bounded by export.quickCopy.dragLimit) and keep
the translate/cite methods synchronous (or maintain two separate
versions).
What we're trying instead is doing what I said in #518 we weren't going
to do: loading most object data on startup and leaving many more
functions synchronous. Essentially, this takes the various load*()
methods described in #518, moves them to startup, and makes them operate
on entire libraries rather than individual objects.
The obvious downside here (other than undoing much of the work of the
last many months) is that it increases startup time, potentially quite a
lot for larger libraries. On my laptop, with a 3,000-item library, this
adds about 3 seconds to startup time. I haven't yet tested with larger
libraries. But I'm hoping that we can optimize this further to reduce
that delay. Among other things, this is loading data for all libraries,
when it should be able to load data only for the library being viewed.
But this is also fundamentally just doing some SELECT queries and
storing the results, so it really shouldn't need to be that slow (though
performance may be bounded a bit here by XPCOM overhead).
If we can make this fast enough, it means that third-party plugins
should be able to remain much closer to their current designs. (Some
things, including saving, will still need to be made asynchronous.)
2016-03-07 21:05:51 +00:00
|
|
|
yield item1.saveTx();
|
Relations overhaul (requires new DB upgrade from 4.0)
Relations are now properties of collections and items rather than
first-class objects, stored in separate collectionRelations and
itemRelations tables with ids for subjects, with foreign keys to the
associated data objects.
Related items now use dc:relation relations rather than a separate table
(among other reasons, because API syncing won't necessarily sync both
items at the same time, so they can't be stored by id).
The UI assigns related-item relations bidirectionally, and checks for
related-item and linked-object relations are done unidirectionally by
default.
dc:isReplacedBy is now dc:replaces, so that the subject is an existing
object, and the predicate is now named
Zotero.Attachments.replacedItemPredicate.
Some additional work is still needed, notably around following
replaced-item relations, and migration needs to be tested more fully,
but this seems to mostly work.
2015-06-02 00:09:39 +00:00
|
|
|
item2.addRelatedItem(item1);
|
Deasyncification :back: :cry:
While trying to get translation and citing working with asynchronously
generated data, we realized that drag-and-drop support was going to
be...problematic. Firefox only supports synchronous methods for
providing drag data (unlike, it seems, the DataTransferItem interface
supported by Chrome), which means that we'd need to preload all relevant
data on item selection (bounded by export.quickCopy.dragLimit) and keep
the translate/cite methods synchronous (or maintain two separate
versions).
What we're trying instead is doing what I said in #518 we weren't going
to do: loading most object data on startup and leaving many more
functions synchronous. Essentially, this takes the various load*()
methods described in #518, moves them to startup, and makes them operate
on entire libraries rather than individual objects.
The obvious downside here (other than undoing much of the work of the
last many months) is that it increases startup time, potentially quite a
lot for larger libraries. On my laptop, with a 3,000-item library, this
adds about 3 seconds to startup time. I haven't yet tested with larger
libraries. But I'm hoping that we can optimize this further to reduce
that delay. Among other things, this is loading data for all libraries,
when it should be able to load data only for the library being viewed.
But this is also fundamentally just doing some SELECT queries and
storing the results, so it really shouldn't need to be that slow (though
performance may be bounded a bit here by XPCOM overhead).
If we can make this fast enough, it means that third-party plugins
should be able to remain much closer to their current designs. (Some
things, including saving, will still need to be made asynchronous.)
2016-03-07 21:05:51 +00:00
|
|
|
yield item2.saveTx();
|
Relations overhaul (requires new DB upgrade from 4.0)
Relations are now properties of collections and items rather than
first-class objects, stored in separate collectionRelations and
itemRelations tables with ids for subjects, with foreign keys to the
associated data objects.
Related items now use dc:relation relations rather than a separate table
(among other reasons, because API syncing won't necessarily sync both
items at the same time, so they can't be stored by id).
The UI assigns related-item relations bidirectionally, and checks for
related-item and linked-object relations are done unidirectionally by
default.
dc:isReplacedBy is now dc:replaces, so that the subject is an existing
object, and the predicate is now named
Zotero.Attachments.replacedItemPredicate.
Some additional work is still needed, notably around following
replaced-item relations, and migration needs to be tested more fully,
but this seems to mostly work.
2015-06-02 00:09:39 +00:00
|
|
|
|
|
|
|
// Select the Related pane
|
|
|
|
var tabbox = doc.getElementById('zotero-view-tabbox');
|
|
|
|
tabbox.selectedIndex = 3;
|
|
|
|
var relatedbox = doc.getElementById('zotero-editpane-related');
|
|
|
|
|
|
|
|
// Wait for relations list to populate
|
|
|
|
do {
|
|
|
|
yield Zotero.Promise.delay(50);
|
|
|
|
}
|
|
|
|
while (!relatedbox.id('relatedRows').childNodes.length);
|
|
|
|
|
|
|
|
doc.getAnonymousNodes(relatedbox)[0]
|
|
|
|
.getElementsByAttribute('value', '-')[0]
|
|
|
|
.click();
|
|
|
|
|
|
|
|
// Wait for relations list to clear
|
|
|
|
do {
|
|
|
|
yield Zotero.Promise.delay(50);
|
|
|
|
}
|
|
|
|
while (relatedbox.id('relatedRows').childNodes.length);
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|