-
Notifications
You must be signed in to change notification settings - Fork 143
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
morebits: remove Morebits.queryString #725
Conversation
It's also worth noting that the whole |
Haven't taken a look at the code yet, but wholeheartedly agree with this. I think it was the fluff stuff I was doing earlier this year that made me really wonder why we still bothered with |
.replace(/^(.*?)(&token=[^&]*)(.*)/, '$1$3$2') // shunt token from middle of query string to the end | ||
.replace(/^(token=[^&]*)&(.*)/, '$2&$1'); // shunt token from beginning of query string to the end | ||
} | ||
|
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 wrote this initially as
if (this.query.token) {
var token = this.query.token;
delete this.query.token;
this.query.token = token;
}
followed by $.param(this.query.token), but the delete
operator is purported to cause performance impacts in V8, and isn't used anywhere else in Twinkle. Anyway, the two lines of ugly regex is much better than the 25 lines of ugly code that was there originally in Morebits.queryString.create
!
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.
Much nicer! The original is certainly over-complicated, but I think casting into an array is indeed the generic way to do it (sans jQuery and morebits
of course). Either way, this should work for our specific purposes, so w00t!
Could we make it even tighter, though, by relying on the fact that tokens end in +\
? Would something like the following be sufficient?
queryString = $.param(this.query).replace(/^(.*?)(token=[^%]+%2B%5C)&(.*)/, '$1$3&$2')
It:
- matches until
%
- only matches if something is present (not sure what happens if there's an empty token parameter isn't last, but that shouldn't happen)
- removes the trailing
&
and places one before the terminaltoken
:- if
token
is first, the?
remains for the new first parameter - if
token
is in the middle,token
's&
remains for the upcoming parameter - if
token
is last, there won't be a terminal&
to match and there's nothing to do anyway!
- if
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.
Great work in condensing it down to a single regex replace!
(token=[^%]+%2B%5C)
not so sure whether this is an improvement. While a nice idea, it seems better to me to leave it as
(token=[^&]*)
$.param(this.query) encodes the URI components so &
can't occur as part of the token itself. So encountering an &
means that the token part has ended. So we aren't really tightening up anything right?
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.
NOTE: The code here doesn't account for the other features of Morebits.queryString.create
- omitting parameters with value undefined
and converting array parameters to |
-delimited strings.
This needs to be resolved before merge. Now done.
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.
So that'd be queryString = $.param(this.query).replace(/^(.*?)(token=[^&]+)&(.*)/, '$1$3&$2')
, right? (+
rather than *
)
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.
meh, using *
means an empty token=
also gets moved to the end, which is better right?
Not sure I'll have time before the holidays, but just some history as I start clearing the way:
|
Is it worth attempting to deprecate these first? Maybe swapping in their equivalents would be easiest too start, and catch any edge cases. bI haven't yet checked usages elsewhere, but if there are none as you say @siddharthvp, then maybe that's overkill/assigning too much importance. |
to
if at all it worked before.
I don't think there's any usage worth giving deprecation warnings for. |
query.gapprefix = Morebits.queryString.exists('from') ? Morebits.string.toUpperCaseFirstChar(Morebits.queryString.get('from').replace('+', ' ')) : | ||
Morebits.string.toUpperCaseFirstChar($('input[name=prefix]').val()); | ||
query.gapnamespace = mw.util.getParamValue('namespace') || $('select[name=namespace]').val(); | ||
query.gapprefix = mw.util.getParamValue('prefix') || $('input[name=prefix]').val(); |
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.
Wow! from
is used to paginate, while prefix
is the actual prefix. That is, prefix
defines the list (e.g. prefix=A
) while from
defines what is shown on the user's screen (e.g. prefix=A&from=Amory_Lovins
). batchprotect
has been busted on non-first-page results for a decade, very lame!
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.
Looks pretty good to me, @siddharthvp! As above, I think this is good to do; we're not attempting to support old MW versions, and with with jQuery and mw.util
a lot of this is unnecessary. Maybe there's places we don't want to remove things from the morebits
library, but I'm fine with queryString
going. cc @MusikAnimal, @atlight, and @azatoth in case any of you feel strongly or want to review.
The only thing I do think might be worth holding onto is the See belowMorebits.queryString
function itself, or at least something like it. I'm not familiar with an easy way using jQuery or mw.util
to build an object with each parameter (e.g. new Morebits.queryString(string).params
), am I wrong on that? It's not used by Twinkle, but that feels useful and fairly low overhead.
.replace(/^(.*?)(&token=[^&]*)(.*)/, '$1$3$2') // shunt token from middle of query string to the end | ||
.replace(/^(token=[^&]*)&(.*)/, '$2&$1'); // shunt token from beginning of query string to the end | ||
} | ||
|
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.
Much nicer! The original is certainly over-complicated, but I think casting into an array is indeed the generic way to do it (sans jQuery and morebits
of course). Either way, this should work for our specific purposes, so w00t!
Could we make it even tighter, though, by relying on the fact that tokens end in +\
? Would something like the following be sufficient?
queryString = $.param(this.query).replace(/^(.*?)(token=[^%]+%2B%5C)&(.*)/, '$1$3&$2')
It:
- matches until
%
- only matches if something is present (not sure what happens if there's an empty token parameter isn't last, but that shouldn't happen)
- removes the trailing
&
and places one before the terminaltoken
:- if
token
is first, the?
remains for the new first parameter - if
token
is in the middle,token
's&
remains for the upcoming parameter - if
token
is last, there won't be a terminal&
to match and there's nothing to do anyway!
- if
Do you still think that this is needed @Amorymeltzer? |
💯 TIL! And what dependency, is it not in core?
That's not an issue for me. I was honestly more interested in the default behavior using the current location string, as I thought it could be handy to be able to easily iterate on each of the parameters. It should only make a difference if trying to parse a pseudo link on the page that had the parameter string but not the full url (i.e. someone wrote "You can just append
Nope! 👍 |
@siddharthvp With https://github.com/azatoth/twinkle/compare/dde1faa4143ac42ce8b788034243186e89d1ae1a..5bd60477a2f829cedeaeaae741d628dce77cbc3b am I right that you're done working on this, and I can give it a final review? Looking forward to it! |
@Amorymeltzer yeah 👍 sorry if was being confusing above. |
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 worked out all the merge conflicts locally, so I think this is ready to go with one minor change! Whoo!
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.
One more bug that needs fixing. The this.query
issue I'm fairly confident about, but wouldn't mind your confirmation/testing that this is the best way to deal with this for now.
morebits.js
Outdated
} else if (val !== undefined) { | ||
return encodeURIComponent(i) + '=' + encodeURIComponent(val); | ||
} | ||
}).join('&').replace(/^(.*?)(token=[^&]*)&(.*)/, '$1$3&$2'); |
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.
Okay there's actually another issue here @siddharthvp — for queries with intoken
(e.g. before editing) this leaves the in
behind for another parameter. Not good. We're not going to overhaul the token system right now, so for now I think this should do it:
}).join('&').replace(/^(.*?)(token=[^&]*)&(.*)/, '$1$3&$2'); | |
}).join('&').replace(/^(.*?)((?:in)?token=[^&]*)&(.*)/, '$1$3&$2'); |
But I'm not 100% it's good enough.
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.
Actually, I think that's technically backwards; we don't want to move intoken
(well, I suppose it doesn't really matter) so it'd be better to do something like either:
}).join('&').replace(/^(.*?)(token=[^&]*)&(.*)/, '$1$3&$2'); | |
}).join('&').replace(/^(.*?)[&\?]?(token=[^&]*)&(.*)/, '$1$3&$2'); |
or
}).join('&').replace(/^(.*?)(token=[^&]*)&(.*)/, '$1$3&$2'); | |
}).join('&').replace(/^(.*?)([^in]token=[^&]*)&(.*)/, '$1$3&$2'); |
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.
How about using \b
? It has zero-length match, so I think that should be ideal.
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.
Mmm, yes, I think that's probably right/best/parsimonious
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.
appears to work fine, pushed.
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.
Is there a difference between \b(token...
and (\btoken...
? Off hand I'm not thinking there should be here.
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.
\b
has a zero-length match, so no.
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.
Yeah - I was wondering more about ZWSP and exotics like that, I curious how they "counted." Turns out they're \S
and `\W!
Morebits.queryString is redundant to mw.util.getParamValue(), mw.util.getUrl() and jQuery.param(). All existing usages are easily replaced. Specifically, - Morebits.queryString.get() and Morebits.queryString.exists() are redundant to mw.util.getParamValue() - Morebits.queryString.create() is redundant to mw.util.getUrl() and jQuery.param() While queryString can be also used for constructing query string objects and getting/setting param values in them, this functionality is not used anywhere, nor are there any reasonable potential usecases.
PrefixIndex URLs use `prefix` parameter, not a `from` parameter. Also, mw.util.getParamValue takes care of converting `+` to space, (though queryString also does that since f0866be; before that commit this was a bug) Also, use of Morebits.toUpperCaseFirstChar is unnecessary, that is taken care of by the API.
I'll do some more testing later today, but I think this is good to go! |
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.
Will merge locally, but 🎉
Morebits.queryString is redundant to mw.util.getParamValue(), mw.util.getUrl() and jQuery.param(). All existing usages are easily replaced. Specifically, - Morebits.queryString.get() and Morebits.queryString.exists() are redundant to mw.util.getParamValue() - Morebits.queryString.create() is redundant to mw.util.getUrl() and jQuery.param() While queryString can be also used for constructing query string objects and getting/setting param values in them, this functionality is not used anywhere, nor are there any reasonable potential usecases. Co-authored-by: Siddharth VP <siddharthvp@gmail.com> Co-authored-by: Amory Meltzer <Amorymeltzer@gmail.com>
Fixes wikimedia-gadgets#913, same basic issue as wikimedia-gadgets#627/wikimedia-gadgets#628: if a user has "Do not show page content below diffs" selected in Special:Preferences, wgRevisionId is set to 0 on diffs. While wikimedia-gadgets#628 took care of that for the links on diff pages themselves, trying to rollback from a contribs page was left unfixed. Those links load the diff page then `auto`matically revert, so will run into the same issue. This essentialy reverts back to the check before 3e5ec5b (wikimedia-gadgets#561), albeit by using `mw.util.getParamValue` rather than the no-longer-existing `Morebits.queryString.get` (wikimedia-gadgets#725).
Lost in between adding JSON support (19435c4/wikimedia-gadgets#493) and removing `queryString` (37d6b67/wikimedia-gadgets#725)
Fixes wikimedia-gadgets#913, same basic issue as wikimedia-gadgets#627/wikimedia-gadgets#628: if a user has "Do not show page content below diffs" selected in Special:Preferences, wgRevisionId is set to 0 on diffs. While wikimedia-gadgets#628 took care of that for the links on diff pages themselves, trying to rollback from a contribs page was left unfixed. Those links load the diff page then `auto`matically revert, so will run into the same issue. This essentialy reverts back to the check before 3e5ec5b (wikimedia-gadgets#561), albeit by using `mw.util.getParamValue` rather than the no-longer-existing `Morebits.queryString.get` (wikimedia-gadgets#725).
Lost in between adding JSON support (19435c4/wikimedia-gadgets#493) and removing `queryString` (37d6b67/wikimedia-gadgets#725)
Morebits.queryString is redundant to mw.util.getParamValue(), mw.util.getUrl() and jQuery.param(). All existing usages are easily replaced.
Specifically,
While queryString can be also used for constructing query string objects and getting/setting param values in them, this functionality is not used anywhere, nor are there any reasonable potential usecases.
This is untested, for now.