-
Notifications
You must be signed in to change notification settings - Fork 942
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix #339 by normalizing localStorage and browser.storage.local usage #395
Conversation
I'd feel better merging this if we had some test coverage around local storage. This seems like an accident waiting to happen without it :/. Is there any way you could add tests around the original code and make sure all is well after plugging in your changes? We need better coverage anyway :p |
I just applied this patch, and can report the following:
Any chance of this getting updated and merged? |
if (browser.storage.local.get.length === 2) { | ||
// Chrome/Opera/Edge use the callback pattern | ||
return browser.storage.local; | ||
} else if (browser.storage.local.get.length === 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When testing in a Firefox 52a2 WebExtension, this returns 0
, which means Firefox falls back to localStorage.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@esphen true that, I've seen the same (arity is 0 because they implement the functions with dynamic arguments).
The PR has been amended with a commit my team had in our private fork.
fe77c4b
to
a54770f
Compare
@thebigredgeek I agree with you on increasing the coverage, but it won't be me fixing that. Sorry. |
a54770f
to
6e0d190
Compare
if (null == namespaces) { | ||
exports.storage.remove('debug'); | ||
} else { | ||
exports.storage.set('debug', namespaces); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Firefox: Error: Incorrect argument types for storage.StorageArea.set.
6e0d190
to
0dac9b6
Compare
@esphen better? thanks for debugging! (I cannot test at the moment) |
No problem söta bror, I'm just as interested in seeing this land as you! Yep, this is progress. No longer seeing However now I am seeing { debug: "*" } |
I think > browser.storage.local.set({ 'debug': '*' })
< Promise { <state>: "pending" }
> browser.storage.local.get('debug').then(console.log)
< Promise { <state>: "pending" }
< Object { debug: "*" } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We got some more issues to resolve before this will work. Most notable the wonky user-agent check and some async issues.
|
||
if (typeof navigator !== 'undefined' && | ||
typeof navigator.userAgent !== 'undefined') { | ||
isFirefox = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This check is a bit wonky for me because I am using the random agent spoofer extension. Suddenly it stopped working for no particular reason, as it randomizes the agent every now and then.
Can we find a better way to check than this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Try my patch-1-without-ua-sniff
branch https://github.com/andreineculau/debug/tree/patch-1-without-ua-sniff although I find it utterly wrong for an extension to do that even for other extensions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good news: I just tested the following in Firefox:
> browser.storage.local.get('debug', console.log)
< undefined
< Object { debug: "*" }
In other words, you don't actually need any browser detection here, as Firefox supports the callback pattern in addition to the promise pattern.
// Firefox uses the Promise pattern | ||
get: function(key, cb) { | ||
browser.storage.local.get(key).then(cb); | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be
get: function(key, cb) {
browser.storage.local.get(key).then(function(result) {
cb(result && result.debug);
});
},
Or similar
if (typeof process !== 'undefined' && 'env' in process) { | ||
return process.env.DEBUG; | ||
if (exports.storage) { | ||
exports.storage.get('debug', exports.enable); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another problem I am seeing is that enabled
is running before enable
runs here, and thus exports.names
are not set when it is checking for what to enable. This breaks the enabled
check and ensures logging is disabled for the duration of the page load.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't follow you here at all. There's no enabled
and there's no exports.names
. Care to rephrase?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I'll elaborate:
There's no enabled and there's no exports.names
Not in this file, no. We need to jump over to debug.js
to understand what happens. In that file there is a method called enabled
. It is run from createDebug, i.e. when debug('foo')
is called. Currently, we're in a situation where enabled
is very likely to be called before exports.names is set, which is a precondition of that method. Thus we are breaking the contract of enabled
.
exports.names
are set by enable, which is passed as a callback in load. Problem is, now that storage.get
is async, the order which the assignment happens is mixed up. With localStorage
we can assume synchronous behavior and it works, but this is not the case for WebExtensions.
import debug from 'debug';
const log = debug('foo');
log('Hello!'); // <-- Never logs because debug was not enabled when `debug('foo')` was called
setTimeout(() => {
debug('bar')('Hi!'); // <-- (Probably) runs because the promise has resolved and the callback fired
}, 1000);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other words, you're pointing out point no. 2 in the description of this PR
in browsers apps/extensions, due to the async nature, calling debug before we read from browser.storage.local may end up in lost messages
Comments:
- our workaround is to queue up messages, and process them after the local storage value is read
- I see this fixed as part of another issue/PR (the goal is to support chrome.storage.local properly now)
- the risk is rather small that messages are lost, given that the main execution is deferred (setTimeout 0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is correct, I am indeed pointing that out.
Basically what you are arguing is that this PR is making the situation better, as debug
goes from not working at all to working in most cases. I can buy that, but I don't buy that the risk is small. I 100% consistently saw that messages that were logged by a logger assigned directly after the import debug from 'debug';
did not appear.
Let's make it clear that I'm not saying it's a deal breaker. It would be awesome to debug
working. We just may need to make clear that the following is the way you need to be logging in a WebExtension until we can improve it further. Example using React.js:
import debug from 'debug';
// const log = debug('FooComponent'); // <-- DO NOT DO THIS
export default function FooComponent() {
debug('FooComponent')('Rendering FooComponent');
// log('Rendering FooComponent'); // <-- DO NOT DO THIS
return <h1>Foo</h1>;
}
0dac9b6
to
1051435
Compare
@esphen |
1051435
to
ead58f8
Compare
> In other words, you don't actually need any browser detection here, as
Firefox supports the callback pattern *in addition* to the promise
pattern.
@esphen I take your word on Firefox's behaviour (although I haven't read
anything as such about it). The current PR reflects that.
…--
andreineculau.com <http://www.andreineculau.com>
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Verified that the current patch works as intended in my WebExtension.
Provided the maintainers (@thebigredgeek?) is okay with the known bug mentioned in the review, I don't see why we shouldn't merge this and get support for WebExtensions.
@andreineculau are we sure this is still necessary? A lot of fixes have been applied since January :p |
@thebigredgeek oh, in that case, no |
FWIW and posterity that was pure 100% irony
…On Thu, Apr 6, 2017 at 5:35 PM, Andrew E. Rhyne ***@***.***> wrote:
Closed #395 <#395>.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#395 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AArOQVOjWqCX3bVmqEwhET28sWAaea5gks5rtQY4gaJpZM4LVR0V>
.
--
andreineculau.com <http://www.andreineculau.com>
|
Seems like the initial PR (#143) that introduced This lead to another PR (#190) which just added extra complexity to API and is not even documented anywhere. If we reverted pull request #143, WebExtensions support would be restored and we would also remove "support" for Chrome Apps which never really worked. What do you think? |
browser.storage.local
may end up in lost messages