This might be a matter of personal preference. Not sure if it's
worth it. Both is well readable. On the other hand, the method
exists. Why not use it?
Change-Id: Id66fc6c888db6ae1cf28e60a51f90d9ae2cdb6ee
This reverts commit 7aaaf51dfd.
Reason for revert: This is not right and doesn't work either.
See T351461#9358034 for why this strategy will not work right now.
We need a different strategy to prevent duplicate transforms if
they continue.
Change-Id: I97efee9197359ecdccdf89a0be850a707a11cc98
* getText() could be called multiple times on a ParserCache object
which would fire the ParserOutputPostCacheTransform handler
multiple times.
But, I could not track down how this could happen right now.
* As a separate issue, while conceptually there are no restrictions
against calling getText() multiple times, there is a semantics and
performance issue if that did actually happen. getText() does a
bunch of transformations and makes no effort to avoid duplicate
work. It will accumulate more transformations over time via the
OutputTranform pipeline and it is preferable for getText() and/or
the OutputTransform pipeline to guarantee semantics where the
pipeline won't be run multiple times on the same content. That will
free both hook handlers (like this) and the transforms themselves
to avoid checks as in this patch.
This patch should be reverted once such a change is made to core.
Bug: T351461
Change-Id: If5dfa0954e3fd2b7dbea1ed29b475be07f0f3986
* This patch enables DT to work with Parsoid HTML without changing
the functionality for legacy HTML.
* The code comments document some of the decisions being made here.
Some of these decisions are temporary and need better solutions
but this patch will let us run visual diff tests and expose any
other latent bugs.
TODO
----
* We need to add new tests to verify CommentFormatter expectations
for Parsoid HTML. I'll tackle this in a followup patch.
Known issues:
-------------
* Performance: Since the getText() transformed output in ParserOutput
is not cached, if DiscussionTools is to switch over to Parsoid HTML,
we have to add some form of caching of the transformed output because
transformHtml can take a couple seconds in the p99 case which is too
long to render uncached!
* Longer-term: Since this hook is called when getText() is
called, all calls to getText() will now invoke this handler
(which will return but still has to do a bunch of checks to
determine this won't apply). Presumably, transformHtml() is
idempotent because when some other code (other extensions, for ex)
calls getText(), we will run the transfromHtml() on previously
transformed content.
My understanding is that getText() is going the way of the dodo
and that getText() callers will have to explicit call the output
transform pipeline code (and presumably this issue of repeatedly
calling the same transforms on previously transformed content will
be addressed there).
* Some CSS doesn't apply to Parsoid HTML because intervening <section>
tags interfere with existing query selectors -- will be addressed
separately.
Bug: T341010
Change-Id: I9846193656cdc658f5237df0a133d9d4dcc20d00
According to EventLogging 'editattemptstep' data the error hasn't
happened in the last 90 days, and according to Logstash data the
warning hasn't happened in the last 90 days either.
The problem this guards against shouldn't be possible in a world
without RESTBase, but keep the checks as assertions just in case.
Change-Id: Id7eaf14294f8a7bb877f6a0e00a90976e560fc54
While this method is not a huge bottleneck in this codebase it still
sticks out because it calls end() and array_pop() literally millions
of times. (Tested by running the unit test suite, which currently
takes about 30 seconds on my machine.)
Because of the way the method is used in this codebase (see especially
ImmutableRange::computePosition) $a is almost always a sub-element of
$b, or the other way around. It's almost never necessary to go all the
way up to the root element. We can use this additional knowledge and
stop much, much earlier. The extra code is worth it because we know it
will succeed very, very often.
When I measure the runtime of this method alone it goes down to less
than 1% of the previous runtime. The final loop at the end of the
method is almost never executed now (about 30 times in 15,000).
I also micro-benchmarked the final loop and optimized it to work with
passive array-indexes instead of actively manipulating the array with
array_pop().
Change-Id: Iffcaa8848780a85fde38e322649050c687567f29
It does the same as before.
I think performance is not a concern here, and wasn't my motivation
either. But I hope this makes the code easier to read and to reason
with.
I added a pure unit test case (without involving an actual Language
object) to cover the previously uncovered digits feature.
Change-Id: I6a0fc86035817eabb42b55e58183ae094c052aa6
I was curious why running the CommentParserTest takes so long. I
found this is one of the bottlenecks because it's called so often,
but many link titles that are parsed as user names turn out to be
something else. This little hack speeds up the test by 15% and has
probably a similar impact in production scenarios.
Change-Id: I5a0b3a49ba5793c8a345baaa7118fed500c082b6
I was curious why running some of the PHPUnit tests in this code base
takes so long. While I could not spot an obvious bottleneck I found
a lot of code that is extremely hot, e.g. called a hundred thousand
times. A few obvious optimizations are possible in this code, e.g.
not calling the surprisingly expensive DOMCompat::getClassList
multiple times.
Change-Id: If22bbc1aedd2c36db1ab2343de5737009050b7bb
There is nothing in this preg_replace call that needs to be executed
"as code". A normal preg_replace can do the same.
The pattern looks a bit different but really does have the exact same
effect as before.
Change-Id: I3597d632f2ecbe5b7ccef39a394075327c9bea79
MediaWiki's PHPCS plugin requires documentation comments on all
properties, unless those properties are typed.
This has potential to introduce bugs – in particular, because typed
properties without a default value will throw an exception if their
value is accessed before it's defined, while previously they defaulted
to null. I fixed this when I found it (making them nullable and null
by default), but I may have missed some cases.
Change-Id: If5b1f4d542ce3e1b69327ee4283f7c3e133a62a0
Why:
- Per T338534, we want to display the overflow menu next to topics and
comments. Supporting topic-level placement is a little more
complicated, so just go with comments for now.
What:
- Rework the is-mobile check to allow the code to run on desktop/mobile,
while excluding topic-level replacement on desktop (T342627)
Bug: T338534
Bug: T342625
Change-Id: I520c377120e16aa3a6fedcc8c39075958a942e4c
Why:
- The button should only display for Minerva
What:
- Consult the skin name before adding the "Edit" button to the menu
Bug: T342251
Change-Id: I52cf2ca0663a4de0ee7add82910e745bcabf1c5f
'editable' refers to the section being editable, and is only for
use by heading items, not individual comments.
Change-Id: I3fb5841609c40a928071cea8987cf035ade464c2
Since 92f5cfd8 we support "mw-notalk" to suppressing comment detection
in pages or sections.
Until now, it only worked when the comment timestamp was surrounded by
a marked element. However, when a marked element was directly adjacent
to a comment, it would sometimes become a part of the comment range.
This can no longer happen now.
Existing use cases for this were the {{outdent}} and {{tracked}}
templates, which we handle specially since 50ad5bb2 and ddd391b6.
It's a bit ugly to hardcode specific templates like that, and this
provides a better solution for the future. The added test case
displays some other potential uses.
Bug: T324132
Change-Id: I7ffd299ef5957b35da8d01f9a0ed5a7a9a78be83
Only needed for phan, under php8.1 this internal
function is deprecated about null.
The property $subscriptionName is not null when $subscriptionTitle is
not null and current code is safe, but phan cannot see the dependency
between both properties
Change-Id: I9e67309ec25a70c5de91d7f3e8f18447f205a4e4
Why:
- We want to provide contextual actions adjacent to comments, not just
topic headings.
What:
- Consolidate the logic for embedding the overflow menu button HTML into
a function, and add this for both topic and comment items.
- For this patch, this is done only for mobile; in a follow-up patch, we
can add support for desktop
- This doesn't use a feature flag as 1) no one is implementing the
DiscussionTools hook yet, 2) the 'edit' menu item is disabled at the
comment level. Merging this change would be a no-op until an extension
implements the DiscussionToolsAddOverflowMenuItemsHook.
Bug: T342251
Change-Id: I15a151f151e2fa04398876b559d93d45c42f6ef6
Why:
- We want to allow extensions to register interactive menu items in the
overflow menu.
What:
- Create a PHP hook to allow extensions to provide menu items
for rendering in the overflow menu
- The hook allows for registering resource loader modules required by
the menu item
- The hook passes in some contextual information, like the thread
item data, context source object, and if the page is editable
- Create a JS hook that fires when a user selects one of the menu items
- Example implementation: Ie9afbedb4f24cbd75eb48bb21dc9f6d8d732d853
Misc:
- Remove b/c code that existed to handle a transitional period where
JSON encoded overflow menu data did not necessarily exist in the
parser cache
- Rename code instances of ellipsis button / data / menu to refer to
"overflow menu"
- Some renames will have to wait until parser cache is updated; these
are noted with TODOs
Bug: T342251
Change-Id: I5f2a51791f8ba7619d1399a4b93111e9bb44e172
In T339882 we thought that these rows are harmless, but for the
specific case of itr_items_id that's not true.
Bug: T343859
Change-Id: Iebfa583d7d4b00a59291f91ec84c41241d5469d4
For some reason this apostrophe is treated like the start of a string
by Gerrit's syntax highlighting, messing up the whole file. It annoys
me very much.
Change-Id: Ie1ce88eefda6ae2a8a73237556affba4cbc6db4b
This approach is borrowed from PageQueryPage in MediaWiki core,
and used in a few other places as well.
Bug: T345648
Change-Id: I7fbc3c3c1133da78eb9f15de9b2a51a90bcd1980
Check whether the page given to DiscussionToolsDebug exists or not.
Without the check, it throws Wikimedia\Assert\PreconditionException.
Add 'exists' => true in the getFormFields() array.
Bug: T338480
Change-Id: I57222f60cb5c5645e6bc97b86be22c502c85d650
When rendering a preview of the comment in order to check whether it's
signed, use the previously acquired temporary user username for the
signature.
Depends-On: Iec8a15dadd595bed0f7e54f907fbb8e192b45cf3
Bug: T331397
Change-Id: I7aeb1cc4c107ed752dc805405780a7609a6d4d3c
What:
Growth wants to use ApiDiscussionToolsEdit to
post questions on behalf of new users (to make use
of the auto-subscribing logic DiscussionTools has).
This seems like a good moment to make the API
non-internal.
What:
* Add support for 'tags' parameter
(this doesn't actually work w/o the depends-on)
* Add autosubscribe parameter to give more control
to callers over whether autosubscription is used.
* Remove isInternal()
Bug: T343339
Bug: T333632
Depends-On: I0ac60ca8473fe28461b2da60f9911baac4994388
Change-Id: I39727de40557d2494f4d60bf224490caaedfdee1
Parsoid can be expected to throw limit exceeded exceptions so a more
graceful response should be provided.
Bug: T325298
Change-Id: I6bedc7639a68311d5247331d5e53f88c004ebc5e
For some unknown reason our updates are being processed more than once
at the same time. Ignore or work around the "duplicate entry" errors
caused by that.
Bug: T323080
Bug: T341811
Change-Id: Iaae1dc2d5ed5bf4ac6760fb1d39dc21f2af89e9a
This reverts 08e1073f58 (T322701),
which does not work, and instead uses the same solution as
4439e934429617cc77f34cc9c783f0b52a06c920 (T247553).
Bug: T339882
Change-Id: I1b6772b1cdfd0d7e1c603333a2e43152d3591c38
Our IDs and names are correctly written with underscores, but allow
spaces too for consistency with the behavior of internal wiki links
when linking to a subpage of Special:FindComment.
Change-Id: Ib9f67ac02d963395db9d56951946b9747a410a88
Our edit API now recognizes topic subjects in the message body,
generates edit summaries from them, and optionally returns an error
if no subject is provided.
Bug: T334163
Bug: T338390
Change-Id: Iac3778a4a88a4def234be9d10b80d9796d35bceb
It wasn't appearing in normal previews thanks to some redundant checks
elsewhere, but it was appearing in our own internal previews using
ApiDiscussionToolsTrait::previewMessage(). It wasn't causing any
problems until change Iac3778a4a88a4def234be9d10b80d9796d35bceb, which
detects headings in the preview, and it was detecting the empty state
heading.
Follow-up to commits 8fb467896f and
ab40ef62c0, where I replaced a HTML
comment with ParserOutput extension data to indicate this, and then
accidentally removed the cleanup code from removeInteractiveTools()
with no replacement.
Change-Id: I4b650f82c711d65e200758e981ce338202deeaa6
https://wikipesija.org is currently using ISO 8601 as the default date
format. The format is xnY-xnm-xnd"T"xnH:xni:xns and 'xn', 'm', and 's'
need support added.
Change-Id: I235098a578eb92ddd23ea47fa23d60df4b28f590
Sometimes we call this API and then reload the page (or navigate to
another URL), without using the page content it returns. Save some
work and some data transfer and don't generate it in those cases.
Depends-On: Ic5fac61f3ef9b2dfce6ff757f1d414a9f41f217d
Change-Id: If1aea90488e3f22cc31ac1f360139ae65acf000a
* Add @var comments to untyped getService() calls so IDEs and tools
are able to understand where the callers are.
* Use the more specific IReadableDatabase where possible.
* Fix missing import.
Change-Id: I9c1153cb9fe872227753628a947f40bd5ee447fa
This existed to do a staged rollout to WMF wikis, which was
finished in March 2021 (T276497).
Bug: T322497
Change-Id: I8851f0243e6920d93f3eb1870d1604bf201ed5a4
Special:DiscussionToolsDebug falsely promised that the API delivers
the same information, but in fact the API included the signatures in
each comment's HTML unconditionally. Allow excluding them.
Change-Id: Ie1e38d28bed0b6d5713d9051b84cc08a23da94c2
This temporary message has been shown for long enough.
This mostly reverts:
* d0eec56f6d
* f24a73a05a
* bd40523843
Bug: T322495
Change-Id: Ic1762e170547fba8b5fda225eff21e515ace512d
Also merge setMwGlobals() calls because they are really expensive.
Also utilize the more readable str_contains() and related.
Change-Id: Iebde6aa17c2e366f0c0a98fe13a454f6a06c299b
Strip it out from applying to logged out users and make the test work
for multiple features
Bug: T333715
Change-Id: Id15a8a99c2ea8e6fc14fc83baf2ed6ebaaf754c8
Unsubscribing was already available from Special:TopicSubscriptions
when JavaScript is disabled.
* Add links to subscribe/unsubscribe in CommentFormatter
* Update links in skin navigation
* Add support for subscribing in the actions
Bug: T321431
Change-Id: If3c4bf7df309d0d98237c3b7b9c129cc2f72cda3
* Remove the hook we used to disable that feature
* Remove CSS that only applied when it was enabled
* Update code comments that referred to it
Bug: T319145
Change-Id: If21a04f6a087289d8249a786f7c991e5e12c9bed
This can be done within sections using CSS:
* mw-notalk
Or at a page level using a magic word:
* __NOTALK__
"notalk" suppresses all comment detection, treating the content as
not containing any comments even if there are signatures present.
Bug: T295553
Bug: T249293
Change-Id: Ic1d7294bafcf7071e16838e70684ecadd7bc6fd3
This can be done within sections using CSS:
* mw-archivedtalk
Or at a page level using a magic word:
* __ARCHIVEDTALK__
"archivedtalk" still detects the comments, but disables features
as appropriate for an archived conversion, i.e. the reply tool.
Bug: T295553
Bug: T249293
Change-Id: Ic47693e9a2f53f92563ccdd50203fb55c12d0493
In local testing, this reduces the amount of data loaded by
Special:JavaScriptTest from 27 MB to 20 MB.
Change-Id: I37f0f677751031cc965d1921a62871154bbe9201
The tracking category is disabled by default and has to be
enabled by overriding the localisation message
'MediaWiki:Discussiontools-comments-before-first-heading-category'.
Bug: T324139
Change-Id: I6e4818e9421f76aec814444b2da9f5d8585c75fd
Some mass messages appear on hundreds or thousands of pages and it's
not good to try to list them all.
Change-Id: Ib903d67ba4fd9d85790ef4271933991b9b6f3834
It demonstrates how the DiscussionTools extension recognizes
the threads and comments present on a page, to help in debugging
or understanding its behavior.
Co-Authored-By: Ed Sanders <esanders@wikimedia.org>
Change-Id: Idbc90bd8d7742615178331889daae5f94a007fcc
We started using marker comments (HTML comments with special content
inserted into the page) for the reply buttons back in the day, because
we needed to indicate their location in the HTML. Later we used the
same idea for things which aren't actually tied to a specific location
in the HTML, such as boolean data like __DTEMPTYTALKPAGE__. There is a
better way to do this.
This commit stop writing the HTML comments, which are no longer used,
and cleans up the tests.
Bug: T328980
Change-Id: I37541356830945cc9abcc79d4c445ff6f2449759
(cherry picked from commit ab40ef62c0)
PHP logging code is not moved.
* Use the new mw.track() handlers from WikimediaEvents
* Ensure that 'integration' and 'editor_interface' are set on init
events, since they're not hard-coded in the handler any more
* Remove the setting of 'editingStatsId' tracking parameter,
now happens in WikimediaEvents (by way of VE ArticleTargetSaver)
* Remove code connecting ve.track to mw.track, now happens in VE
This must be merged together with WikimediaEvents change
Iace4d53a972396ca5b8713000570cc47c9986034 (but we can't use
Depends-On, because CI requires code here to be removed first).
Bug: T332438
Change-Id: I0ef0a96aafdf89a4ebe32131a85b18c25744bb2c
Exclude the main namespace unless it allows signatures.
Allow this feature to be disabled via config so
we can do a slow rollout.
Bug: T331635
Change-Id: If46bff5620c5245d5b82653ee96282532fd00c28
To avoid affecting existing preload forms, the new topic tool is only
used when the 'dtpreload' query parameter is also set.
Bug: T269310
Change-Id: I4ee024cc4760542790319f302f42b1b2389ac897
We started using marker comments (HTML comments with special content
inserted into the page) for the reply buttons back in the day, because
we needed to indicate their location in the HTML. Later we used the
same idea for things which aren't actually tied to a specific location
in the HTML, such as boolean data like __DTEMPTYTALKPAGE__. There is a
better way to do this.
This commit starts reading from ParserOutput::getExtensionData(),
which was generated by the previous commit, and should be present
in all cached ParserOutput objects by the time we merge this.
Bug: T328980
Change-Id: I9f7a907836b86f25567fd4b352464d62d76e20e4
(cherry picked from commit 0ac420ecbc)
This reverts commit 0ac420ecbc.
Reason for revert: this was supposed to be merged later; revert it now and reapply in a bit
Change-Id: I33fb07856152c2401b3a071c143f27f1e9753287
We started using marker comments (HTML comments with special content
inserted into the page) for the reply buttons back in the day, because
we needed to indicate their location in the HTML. Later we used the
same idea for things which aren't actually tied to a specific location
in the HTML, such as boolean data like __DTEMPTYTALKPAGE__. There is a
better way to do this.
This commit starts reading from ParserOutput::getExtensionData(),
which was generated by the previous commit, and should be present
in all cached ParserOutput objects by the time we merge this.
Bug: T328980
Change-Id: I4bf81ef3fd904f4d920d0756370c9bfa0a10a774
We started using marker comments (HTML comments with special content
inserted into the page) for the reply buttons back in the day, because
we needed to indicate their location in the HTML. Later we used the
same idea for things which aren't actually tied to a specific location
in the HTML, such as boolean data like __DTEMPTYTALKPAGE__. There is a
better way to do this.
This commit starts writing data to ParserOutput::setExtensionData(),
which will be used in a later commit to be merged separately to avoid
issues with cached ParserOutput objects.
Bug: T328980
Change-Id: Ieb7bc3f83a402f9ebb096ed63336c77073bd2e7c
Instead of generating the TOC HTML additions immediately, store
the data we need using ParserOutput::setExtensionData(), and use
the OutputPageParserOutput hook to fetch it and generate the HTML.
We check that the stored data is present before using it to avoid
issues with cached ParserOutput objects.
Bug: T328122
Change-Id: I7d4988cd568f10b7995a4d744e0ec6e7ce081b0e
Other DT markers are removed because we return the body text, but
in this case we return subtitle text to be inserted elsewhere.
Instead pass $text by reference so it can be modified directly.
Change-Id: I9fe4194681cd3737661dca3c8a16e30a6001bd73
This code was unnecessarily copied from VE. It's not needed for
anything in this extension, and it causes the headings to be treated
as modified by selser, which in turn causes dirty diffs.
Bug: T328268
Change-Id: Ibdbed430f2ff28d0ea2e67644075c1621d9fae53
ParserOutput::getTOCHTML() is being deprecated, and all skins are now
generating the TOC from the TOCData returned by
ParserOutput::getTOCData(). The SHOW_TOC flag was introduced in core
to determine if the TOC should be shown, but Vector-2022 *may* begin to
use other heuristics to determine whether to show the TOC (T315862).
We're conservatively going to process the TOC as long as there is
TOC present to process.
Bug: T328072
Change-Id: I38b439c6752157dbee9b09c9f5443a740dbaabf4
Otherwise, when a transclusion covers a section boundary, both whole
sections are considered to be transcluded.
We already use this method everywhere else (by way of
HookUtils::parseRevisionParsoidHtml), and VisualEditor also applies
the same transformation (mw.libs.ve.unwrapParsoidSections) before
opening the page for editing.
Bug: T327704
Change-Id: I9d8288e2740d816edb9cbc01d7e5642d52c610d3
Change code to match the documented consensus formed on T321683:
https://www.mediawiki.org/wiki/Manual:Coding_conventions/PHP#Exception_handling
* Do not directly throw Exception, Error or MWException
* Document checked exceptions with @throws
* Do not document unchecked exceptions
For this extension, I think it makes sense to consider DOMException an
unchecked exception too (in addition to the usual LogicException and
RuntimeException).
Depends-On: Id07e301c3f20afa135e5469ee234a27354485652
Depends-On: I869af06896b9757af18488b916211c5a41a8c563
Depends-On: I42d9b7465d1406a22ef1b3f6d8de426c60c90e2c
Change-Id: Ic9d9efd031a87fa5a93143f714f0adb20f0dd956
The alias stored in the language files is with underscores,
but the value is compared in CommentParser against text with spaces
Affected languages: bjn, hu, id, jv, kaa, tl, tpi, vi, war
Bug: T327021
Change-Id: I8626627d10a240973e631e24508937a9eee9fb14
We need to be careful about flooding the parser cache with parsoid
content. For this reason, we currently only write to PC for a certain
sample of edits. This logic is implemented in core in
ParsoidHandler::allowParserCacheWrite and controlled by the
TemporaryParsoidHandlerParserCacheWriteRatio setting.
DiscussionTools triggers parsoid PC writes when handling the
RevisionDataUpdates hook, so it should use the same sampling.
Change-Id: Ic33f57b10ae53f431a3c3484c4853e88bf80f47a
Test ServiceWiring.php using tests copied from CentralAuth. Because
phpunit does not support marking a file as covered, the ServiceWiring
file is ignored for code coverage as the tests fully cover the file.
Change-Id: I7da8d74fec84a5aa9c77bc0678ad8f55b550893a