Closed
Bug 1265847
Opened 9 years ago
Closed 9 years ago
Implement browser.history.onVisitRemoved
Categories
(WebExtensions :: Untriaged, defect)
WebExtensions
Untriaged
Tracking
(firefox50 fixed)
Tracking | Status | |
---|---|---|
firefox50 | --- | fixed |
People
(Reporter: bsilverberg, Assigned: bsilverberg)
References
Details
(Whiteboard: [history]triaged)
Attachments
(1 file)
Assignee | ||
Updated•9 years ago
|
Assignee | ||
Comment 1•9 years ago
|
||
Combining this with the bug for onVisited.
Status: ASSIGNED → RESOLVED
Iteration: --- → 49.2 - May 23
Closed: 9 years ago
Resolution: --- → DUPLICATE
Assignee | ||
Comment 2•9 years ago
|
||
I'm splitting these two methods into two bugs again, as one is dependent on some native code changes.
Status: RESOLVED → REOPENED
Resolution: DUPLICATE → ---
Assignee | ||
Updated•9 years ago
|
Status: REOPENED → ASSIGNED
Iteration: 49.2 - May 23 → 49.3 - Jun 6
Assignee | ||
Comment 3•9 years ago
|
||
Review commit: https://reviewboard.mozilla.org/r/56306/diff/#index_header
See other reviews: https://reviewboard.mozilla.org/r/56306/
Attachment #8757941 -
Flags: review?(aswan)
Comment 4•9 years ago
|
||
Comment on attachment 8757941 [details]
Bug 1265847 - Implement browser.history.onVisitRemoved,
https://reviewboard.mozilla.org/r/56306/#review53606
::: browser/components/extensions/ext-history.js:61
(Diff revision 1)
> +
> +// WeakMap[Extension -> observer]
> +var observerMap = new WeakMap();
> +
> +/* eslint-disable mozilla/balanced-listeners */
> +extensions.on("startup", (type, extension) => {
This creates an observer for every webextension whether or not the extension cares about history events? Why not create this on demand only when there is a listener?
::: browser/components/extensions/ext-history.js:135
(Diff revision 1)
> return Promise.resolve(results);
> },
> +
> + onVisitRemoved: new EventManager(context, "history.onVisitRemoved", fire => {
> + let listener = (event, data) => {
> + fire(data, true);
I think you want `this.context.runSafe(fire, data)`
also what is the second argument?
::: browser/components/extensions/test/browser/browser_ext_history.js:113
(Diff revision 1)
> + for (let index of [0, 5, 6]) {
> + let url = visits[index].uri.spec;
> + ok(removedUrls.includes(url), `${url} received by onVisitRemoved`);
> + }
Seems like you should test the exact contents of removedUrls, if the event was triggered too many times for instance, you would have extra entries here but the test would pass.
Also, there should be multiple entries for the base URL, once for each of the deleteRange calls, it would be good to verify that.
Attachment #8757941 -
Flags: review?(aswan)
Assignee | ||
Comment 5•9 years ago
|
||
Comment on attachment 8757941 [details]
Bug 1265847 - Implement browser.history.onVisitRemoved,
Review request updated; see interdiff: https://reviewboard.mozilla.org/r/56306/diff/1-2/
Attachment #8757941 -
Attachment description: MozReview Request: Bug 1265847 - Implement browser.history.onVisitRemoved, r?aswan → Bug 1265847 - Implement browser.history.onVisitRemoved,
Attachment #8757941 -
Flags: review?(aswan)
Assignee | ||
Comment 6•9 years ago
|
||
https://reviewboard.mozilla.org/r/56306/#review53606
> I think you want `this.context.runSafe(fire, data)`
> also what is the second argument?
I wrote this to be similar to what's done in ext-notifications.js [1]. It looks like the implemementation of `fire` in `EventManager` does just what you suggest [2], so it seems like just calling `fire` would do the same.
As for what the second argument is, I have no idea. I must have brought that across from ext-notifications.js. I don't think it's used for anything so I will remove it.
[1] https://dxr.mozilla.org/mozilla-central/source/toolkit/components/extensions/ext-notifications.js#134
[2] https://dxr.mozilla.org/mozilla-central/source/toolkit/components/extensions/ExtensionUtils.jsm#624
> Seems like you should test the exact contents of removedUrls, if the event was triggered too many times for instance, you would have extra entries here but the test would pass.
> Also, there should be multiple entries for the base URL, once for each of the deleteRange calls, it would be good to verify that.
I don't think the order of the items in `removedUrls` can be guaranteed, so we probably shouldn't check each entry by index. I did add a check that `removedUrls` is of the length we expect, and I think that combined with checking that each URL we expect to be in there is in fact in there is proof that `onVisitRemoved` was called exactly as expected.
There will not be multiple entries for any URL because `onVisitRemoved` isn't called for each visit, it's only called when all visits for a particular URL are removed. I know this is conterintuitive based on the name (which should really be called `onUrlRemoved`), but it is how it works in Chrome. This was discussed quite a bit in bug 1265845 (comments 8 - 11) [1] if you want to take a look.
[1] https://bugzilla.mozilla.org/show_bug.cgi?id=1265845#c8
Comment 7•9 years ago
|
||
https://reviewboard.mozilla.org/r/56306/#review53606
> I wrote this to be similar to what's done in ext-notifications.js [1]. It looks like the implemementation of `fire` in `EventManager` does just what you suggest [2], so it seems like just calling `fire` would do the same.
>
> As for what the second argument is, I have no idea. I must have brought that across from ext-notifications.js. I don't think it's used for anything so I will remove it.
>
> [1] https://dxr.mozilla.org/mozilla-central/source/toolkit/components/extensions/ext-notifications.js#134
> [2] https://dxr.mozilla.org/mozilla-central/source/toolkit/components/extensions/ExtensionUtils.jsm#624
Ah, I overlooked that you're not using SingletonEventManager, can you switch to it (from EventManager)
> I don't think the order of the items in `removedUrls` can be guaranteed, so we probably shouldn't check each entry by index. I did add a check that `removedUrls` is of the length we expect, and I think that combined with checking that each URL we expect to be in there is in fact in there is proof that `onVisitRemoved` was called exactly as expected.
>
> There will not be multiple entries for any URL because `onVisitRemoved` isn't called for each visit, it's only called when all visits for a particular URL are removed. I know this is conterintuitive based on the name (which should really be called `onUrlRemoved`), but it is how it works in Chrome. This was discussed quite a bit in bug 1265845 (comments 8 - 11) [1] if you want to take a look.
>
> [1] https://bugzilla.mozilla.org/show_bug.cgi?id=1265845#c8
Oh, how confusing. Then would it make sense to test that onVisitRemoved doesn't get invoked on your first deleteRange() call (since there are still some visits for that url)?
Assignee | ||
Comment 8•9 years ago
|
||
Comment on attachment 8757941 [details]
Bug 1265847 - Implement browser.history.onVisitRemoved,
Review request updated; see interdiff: https://reviewboard.mozilla.org/r/56306/diff/2-3/
Assignee | ||
Comment 9•9 years ago
|
||
https://reviewboard.mozilla.org/r/56306/#review53606
> Ah, I overlooked that you're not using SingletonEventManager, can you switch to it (from EventManager)
Done!
> Oh, how confusing. Then would it make sense to test that onVisitRemoved doesn't get invoked on your first deleteRange() call (since there are still some visits for that url)?
Ok, I did that, but I don't think there's a guarantee that it will prove anything. I don't think there is a risk of a failure, but it could be a false positive. That's because I am returning the contents of `removedUrls` after the call to `delete-range` finishes, but there's no guarantee that the `onVisitRemoved` handler would have finished by then, if it were to be called. I'm not really too concerned about that though.
Assignee | ||
Comment 10•9 years ago
|
||
Comment 11•9 years ago
|
||
Comment on attachment 8757941 [details]
Bug 1265847 - Implement browser.history.onVisitRemoved,
https://reviewboard.mozilla.org/r/56306/#review54498
looks good, just minor feedback.
::: browser/components/extensions/ext-history.js:57
(Diff revision 3)
> +function getExtensionObserver(extension) {
> + if (!observerMap.has(extension)) {
> + let observer = {
> + onDeleteURI: function(uri, guid, reason) {
> + this.emit("visitRemoved", {allHistory: false, urls: [uri.spec]});
> + },
> + onVisit: function() {},
> + onBeginUpdateBatch: function() {},
> + onEndUpdateBatch: function() {},
> + onTitleChanged: function() {},
> + onClearHistory: function() {
> + this.emit("visitRemoved", {allHistory: true});
> + },
> + onPageChanged: function() {},
> + onFrecencyChanged: function() {},
> + onManyFrecenciesChanged: function() {},
> + onDeleteVisits: function(uri, time, guid, reason) {
> + this.emit("visitRemoved", {allHistory: false, urls: [uri.spec]});
> + },
> + };
> + EventEmitter.decorate(observer);
> + PlacesUtils.history.addObserver(observer, false);
> + observerMap.set(extension, observer);
> + }
> + return observerMap.get(extension);
> +}
I think my original comment wasn't very clear, this will create a separate observer per extension if there are multiple extensions listening for events. There's nothing extension-specific in the observer though, a single observer could serve all the extensions.
However, I don't think this is a big deal and not worth changing, just wanted to make sure that idea got communicated clearly...
::: browser/components/extensions/test/browser/browser_ext_history.js:17
(Diff revision 3)
> +
> + browser.history.onVisitRemoved.addListener(data => {
> + if (data.allHistory) {
> + historyClearedCount++;
> + } else {
> + removedUrls.push(data.urls[0]);
this seems to assume that the length of urls is exactly 1. either add a test that that's true or use concat()
Attachment #8757941 -
Flags: review?(aswan) → review+
Assignee | ||
Comment 12•9 years ago
|
||
Comment on attachment 8757941 [details]
Bug 1265847 - Implement browser.history.onVisitRemoved,
Review request updated; see interdiff: https://reviewboard.mozilla.org/r/56306/diff/3-4/
Assignee | ||
Comment 13•9 years ago
|
||
https://reviewboard.mozilla.org/r/56306/#review54498
> I think my original comment wasn't very clear, this will create a separate observer per extension if there are multiple extensions listening for events. There's nothing extension-specific in the observer though, a single observer could serve all the extensions.
> However, I don't think this is a big deal and not worth changing, just wanted to make sure that idea got communicated clearly...
Yeah, I guess I didn't understand what you were getting at. As long as I needed to update the patch, I figured I might as well make this change too, so I did.
Assignee | ||
Comment 14•9 years ago
|
||
Assignee | ||
Updated•9 years ago
|
Keywords: checkin-needed
Comment 15•9 years ago
|
||
Pushed by ntim.bugs@gmail.com:
https://hg.mozilla.org/integration/fx-team/rev/3445f2c6868e
Implement browser.history.onVisitRemoved. r=aswan
Keywords: checkin-needed
Comment 16•9 years ago
|
||
bugherder |
Status: ASSIGNED → RESOLVED
Closed: 9 years ago → 9 years ago
status-firefox50:
--- → fixed
Resolution: --- → FIXED
Target Milestone: --- → mozilla50
Comment 17•9 years ago
|
||
bugherder |
Updated•7 years ago
|
Product: Toolkit → WebExtensions
You need to log in
before you can comment on or make changes to this bug.
Description
•