The OutputPage::parse() and OutputPage::parseInline() methods behave
misleadingly different from the OutputPage::addWikitext*() methods:
they don't tidy their output, they have different defaults for
interface/content language selection, and they (sometimes) add
wrapper divs. Deprecate these and add new methods with tidy output,
clear language selection, and consistent defaults:
OutputPage::parseAsContent(), OutputPage::parseAsInterface(),
and OutputPage::parseInlineAsInterface().
Unify the implementation of the parse* methods with the addWikiText*
methods, to reduce the likelihood that the behavior will diverge again
in the future.
Bug: T198214
Change-Id: Ica79c2acbc542ef37f971c0be2582ae771a23bd0
We should probably strip the <div> wrapper in OutputPage::parse() as
well: this behavior was added in 1.30, but it only applies when
$interface is false. However, that requires a more careful audit
(a lot more places call parse() than parseInline()) and so I'll defer
that for now.
Change-Id: Iad5412f03af29c04deb653969dd71f6c86f0ae50
Tidy will always be enabled with our future parsers. Hard-deprecate
this method which doesn't tidy the output.
Users of `OutputPage::addWikiText()` will be converted one-by-one to
`OutputPage::addWikiTextAsInterface()` so that any unexpected issues
(deliberately untidy wikitext added, which should be rare) can be
addressed.
Bug: T198214
Depends-On: I778ba9e6efed576605f492c9a073c7203b6c0477
Depends-On: I16529879a3b3aed960c5dc006e2af513d7e91fcd
Change-Id: If8353c37245d9d233d589f82c198668ccb3fce05
This change ensures that the output is tidy, and is necessary to support
future parsers which will not be able to produce untidy output.
Bug: T198214
Change-Id: I743f4185a03403f8d9b9db010ff1ee4e9342e062
This patch introduces a new method,
OutputPage::wrapWikiTextAsInterface(), which wraps the result of
OutputPage::addWikiTextAsInterface() in a tidy and robust way that
won't break if the wrapped message contains double newlines, extra
</div>, or other nasties.
This replaces a common unsafe pattern:
$output->addWikiText( '<div class="..."' .... '</div>' );
Bug: T205624
Change-Id: I1040c7cf0ec1f5c4bef7c06d4486f50d85f2dc0f
We are incrementally removing places where the parser is used with
tidy disabled, since future parsers will not support such operation.
Bug: T198214
Change-Id: I0f417f75a49dfea873e9a2f44d81796a48b9f428
The `Key` header was a draft IETF specification which expired without
becoming a standard. It does not appear to be in active use anywhere.
Change-Id: I3924a1b5ff428b107573d2827c40e4af8adaaeb1
Also stop returning a value from OutputPage::adaptCdnTTL(). There are
no users and the value doesn't seem very helpful: one would probably
expect it to return the new value of mCdnMaxage, but instead it
returns the new value of mCdnMaxageLimit. Better to have no return
value than one that's easily misunderstood (*and* which nobody uses).
Change-Id: Ia9dab86923b839334eab9f6fde17c4aed52130ec
These have been replaced with OutputPage::addWikiTextAsContent().
There is only one apparent use outside core, in the ProofreadPage
extension.
Bug: T198214
Depends-On: I826e463c1623481c11156a55a5b7e1da0aa27b8b
Change-Id: I4b1a9429029bfbbf70b2d5da1b290319ecbbdf3a
Codesearch shows no users of `OutputPage::addWikiTextWithTitle()`,
and no users of `OutputPage::addWikiTextTitle()` (other than the
implicit uses by the other `OutputPage::addWikiText*()` methods).
These methods produce untidy output, which future parsers won't
support.
Bug: T198214
Change-Id: Id5ee3bdfa6c464e3a92af82af7bc7317ca9d07a9
Tidy will always be enabled with our future parsers, and it is fast
and pure PHP now with the Remex implementation, so deprecate all the
untidy variants of 'OutputPage::addWikiText*()' and add new methods
which tidy by default. Clarify the content language/interface
language distinction while we're at it by adding 'AsInterface' to the
name of methods which use the "interface language" by default,
and renaming the 'addWikiText*Tidy' methods to
'addWikiTextAsContent'.
The 'OutputPage::addWikiTextTitle' method has been deprecated, but it
is still used internally as the implementation for the newly-added
methods. It is expected that the shared implementation will move in
the future to a new private method. Setting the `$tidy` parameter of
`OutputPage::addWikiTextTitle` to false is independently deprecated;
for backwards-compatibility with old MW releases you may wish to
continue to invoke OutputPage::addWikiTextTitle() but set $tidy=true;
this will result in the same tidied output that the newly added
methods would produce.
Bug: T198214
Change-Id: Ia58910164baaca608cea3b24333b7d13ed773339
The translate extension registers the LanguageLinks hook which is run by
OutputPage::addParserOutputMetadata with a Title as an argument. If
our mock doesn't provide a valid Title, then
PageTranslationHooks::addLanguageLinks() in Translate will throw a
TypeError in OutputPageTest::testParserOutputCategoryLinks().
Change-Id: I495c51731670f841e5ab752a3a1e014c86ef643d
There are three methods affected: `OutputPage::addWikiTextTidy()`,
`OutputPage::addWikiTextTitleTidy()`, and
`OutputPage::addWikiTextWithTitle()`.
There's a special case in Parser.php which adds the wrapper class from
ParserOptions to the ParserOutput only if "interface mode" is off; the
affected methods default to adding output in "content language" mode
(not "interface language" mode), but they seem to be used for
"interface messages in the content language" (rare) and so should also
be unwrapped. This would make all the `OutputPage::addWikiText*()`
methods consistent.
The `OutputPage::addWikiTextTidy()` method is only used once in the WMF
repositories, where it is used to insert an interface message in the
content language:
91cd2a928f/SpecialProofreadPages.php (40)
The `OutputPage::addWikiTextWithTitle()` method is used by no one:
https://codesearch.wmflabs.org/search/?q=addWikiTextWithTitle%5C(
The `OutputPage::addWikiTextTitleTidy()` method is used only in core:
3888c001a1/includes/EditPage.php (2669)
It seems clear that the output in this case is intended to be
unwrapped as well (the codepath adds its own explicit wrapper).
Ia58910164baaca608cea3b24333b7d13ed773339 will add additional
documentation to clarify the distinction between the different
OutputPage::addWikiText*() methods, but I felt it safer to make
this particular change first as a standalone patch, just in case
it had unexpected side effects or merited further discussion.
Change-Id: I3e5b598d358819191562b56d40ebf1cb6f3cda41
`OutputPageTest::testMakeResourceLoaderLink()` and
`OutputPageTest::testBuildExemptModules()` tried to force
`$wgResourceLoaderDebug=false` before running the test, but they
neglected to clear the resource loader debug cache
(`ResourceLoader::clearCache()`) so the user's local setting of
`$wgResourceLoaderDebug` would be used despite it all.
Change-Id: I3e7dec762c8a02683fc66a630c950b72a4840a9b
We already had a $filterCacheVersion variable, but it was
only used for the internal cache for JS and CSS minification,
which is not enough. If there is a breaking change in either
of these processes, we also need to invalidate version hashes.
This commit renames ResourceLoader::$filterCacheVersion to
ResourceLoader::CACHE_VERSION and takes it into account in
getVersionHash(). Adding it to getDefinitionSummary() is not
sufficient, because content-hashed modules also need to be
invalidated when there's a breaking change in the minifiers.
This cache version can also be incremented when there's a
breaking change in image embedding or LESS compilation,
although content hashing deals with that already, so we
could also add a separate cache version for those that's
only added to getDefinitionSummary().
Bug: T176884
Change-Id: Ife6efa71f310c90b9951afa02212b2cb6766e76d
This seems quite nuclear. I'd actually like to deprecate the
wgCacheEpoch variable more generally in favour of a handful
of more specific version constants, but as starting point,
remove it from the hash used for load.php urls and localStorage
keys.
The latter is also controlled by wgResourceLoaderStorageVersion
already.
Also ref T32956 about a more standalone ResourceLoader.
Change-Id: I913f846090e82d3d822653b9b7ce22233cdb5e90
This existed for internal use by OutputPage, which is no longer
the case as of I11b390f2e4f5e7db.
Also move the unit tests from OutputPageTest,
to ResourceLoaderSkinModuleTest.
Change-Id: I8b23f976f5f89b1005b387a827f75031f5c96141
This was introduced in OutputPage before support for getPreloadLinks()
was added to ResourceLoader. The introduction in ResourceLoader was
actually inspired by this original implementation.
Now that we have it, we should make use of it for this module
as well. Doing so has several benefits:
* Makes the code cleaner by not requiring every skin to implement
the extra boolean method. Instead, it naturally works. If
the skin loads the SkinModule, it gets the preload as well.
If not (such as Minerva, which has a different logo config),
then it also doesn't get the preload link.
Naturally, automatic.
* Makes code cleaner by not having static methods, and by not
having OutputPage call into a Module class.
* Fixes the problem where, if a site's logo is changed, all cached
HTML is preloading the old logo whilst the stylesheet fetches
the newer one. Causing both to be downloaded.
* Still preloads the logo well before it can render.
Change-Id: I11b390f2e4f5e7db8b4506ab547839152888005c
They were accidentally made non-functional in April 2009 by commit
e4d21170. Subsequent commits 2d045fa1, 9e230f30, e275ea28, ae45908c
removed all callers by October 2011. Needless to say, I found no
callers in core or extensions.
It seems we have the functionality in some other way, probably just by
directly calling setHTMLTitle(), so there's no need to revive this
feature.
Bug: T200643
Change-Id: Ifa2537b97cf19e7e91ee33d4ea4c131f7a38ee89
The primary goal here is a defense in depth measure to
stop an attacker who found a bug in the parser allowing
them to insert malicious attributes.
This wouldn't stop someone who could insert a full
script tag (since at current it can't distinguish between
malicious and legit user js). It also would not prevent
DOM-based or reflected XSS for anons, as the nonce value
is guessable for anons when receiving a response cached
by varnish. However, the limited protection of just stopping
stored XSS where the attacker only has control of attributes,
is still a big win in my opinion. (But it wouldn't prevent
someone who has that type of xss from abusing things like
data-ooui attribute).
This will likely break many gadgets. Its expected that any
sort of rollout on Wikimedia will be done very slowly, with
lots of testing and the report-only option to begin with.
This is behind feature flags that are off by default, so
merging this patch should not cause any change in default
behaviour.
This may break some extensions (The most obvious one
is charinsert (See fe648d41005), but will probably need
some testing in report-only mode to see if anything else breaks)
This uses the unsafe-eval option of CSP, in order to
support RL's local storage thingy. For better security,
we may want to remove some of the sillier uses of eval
(e.g. jquery.ui.datepicker.js).
For more info, see spec: https://www.w3.org/TR/CSP2/
Additionally see:
https://www.mediawiki.org/wiki/Requests_for_comment/Content-Security-Policy
Bug: T135963
Change-Id: I80f6f469ba4c0b608385483457df96ccb7429ae5
There has long been a hack for previewing edits to user JS/CSS, where
OutputPage would pass an 'excludepage' parameter to
ResourceLoaderUserModule to tell it not to load one particular page and
would instead embed that page statically. That's nice, but there are
other places where we could use the same thing.
This patch generalizes it:
* DerivativeResourceLoaderContext may now contain a callback for mapping
titles to replacement Content objects.
* ResourceLoaderWikiModule::getContent() uses the overrides, and
requests embedding when they're used. All subclasses in Gerrit should
pick it up automatically.
* OutputPage gains methods for callers to add to the override mapping,
which it passes on to RL. It loses a bunch of the special casing it
had for the 'user' and 'user.styles' modules.
* EditPage sets the overrides on OutputPage when doing the preview, as
does ApiParse for prop=headhtml. TemplateSandbox does too in I83fa0856.
* OutputPage::userCanPreview() gets less specific to editing user CSS
and JS, since RL now handles the embedding based on the actual
modules' dependencies and EditPage only requests it on preview.
ApiParse also gets a new hook to support TemplateSandbox's API
integration (used in I83fa0856).
Bug: T112474
Change-Id: Ib9d2ce42931c1de8372e231314a1f672d7e2ac0e
The siteinfo API response's 'writeapi' value is now hard-set to true,
as are the ResourceLoader variables wgEnableAPI and wgEnableWriteAPI,
to be deprecated later.
Bug: T115414
Change-Id: I54ff9428b247ba203d67aba079149393f323d5a9
Clean up use of @codingStandardsIgnore
- @codingStandardsIgnoreFile -> phpcs:ignoreFile
- @codingStandardsIgnoreLine -> phpcs:ignore
- @codingStandardsIgnoreStart -> phpcs:disable
- @codingStandardsIgnoreEnd -> phpcs:enable
For phpcs:disable always the necessary sniffs are provided.
Some start/end pairs are changed to line ignore
Change-Id: I92ef235849bcc349c69e53504e664a155dd162c8
SVGs could already be used through $wgLogo. However, if a PNG fallback
is desired for older browsers, using SVGs was previously not possible.
This commit adds support for using an SVG image in $wgLogoHD and,
using $wgLogo as the fallback image.
Usage example:
> $wgLogo = '/path/to/png';
> $wgLogoHD = [
> 'svg' => 'path/to/svg',
> ];
Note: When the 'svg' key is set in $wgLogoHD, any '1.5x' and '2x' keys will
no longer be used because SVGs can render optimally on any screen sizes.
@Reedy, @Krinkle and @Brion VIBBER helped me alot with this.
Bug: T86229
Change-Id: I6197d96ce9110f4711ef2c4b198445bc5c6ae110
This fixes two bugs:
* 1) When two modules are requested, and the first one ends with ";"
inside a comment, the second module might become part of
that comment.
* 2) A request with script=only where the requested module content
ends in a statement without ";", but has a comment after it
that does ends with a semicolon, then in debug=false, mw.loader.state()
would be appended directly after the semicolon-less statement because
the check is performed before minification.
Previously:
script> foo()
script> // bar();
states> mw.loader.state( {} );
Became (minified separately):
script> foo()
states> mw.loader.state({});
Became (concatenated)
> foo()mw.loader.state();
Which is invalid code.
Both of these are now fixed.
Bug: T162719
Change-Id: Ic8114c46ce232f5869400eaa40d3027003550533
Regardless of whether other modules exist with group=user or group=site,
these two modules in particular must always be in their own request for
legacy reasons.
This has already always been the case because even in the few cases where
an extension uses this group (eg. MobileFrontend's custom site module) it
would load it instead of another module in that group, never at the same
time. There is one notable exception, which is GlobalCssJs. However the
ext.globalCssJs.user.styles module is usually served from another wiki
which is why that went unnoticed as well. This commit fixes that so that
even if you're viewing a page on the central wiki, the modules are still
in separate requests.
Aside from this one existing edge case, there is also need to add
group=site to gadgets by default so that they load after the DynamicStyles
marker instead of before, which is currently causing problems with the
cascading order (gadget apply before core and skin styles due to being
in the same request group and alphabetically sorting before them).
Semantically, the appropiate solution is group=site, but this wasn't
possible due to core putting "all" group=site modules in the same request
(under the assumption there is only one such module). This commit removes
that fragile assumption.
Bug: T147667
Change-Id: I9eb725c083124d22a9af3bf3d075ade6f3b970a3
Replaces \TestingAccessWrapper (defined in core) with
\Wikimedia\TestingAccessWrapper (defined in the composer package
wikimedia/testing-access-wrapper).
See https://gerrit.wikimedia.org/r/#/q/topic:librarize-testing-access-wrapper
for downstream patches.
The core version of the class is kept around for a while to avoid
circular dependency problems.
Bug: T163434
Change-Id: I52cc257e593da3d6c3b01a909e554a950225aec8
Follows-up 5f55e9c9c2.
If the logo url is from within /w, then ResourceLoaderSkinModule
will (as it should) apply a file hash query to it.
The preloader didn't do that, so it specified the wrong url.
Refactored SkinModule to make this logic re-usable.
Bug: T100999
Change-Id: I1ba11f7c70d1a725ad72754fee4a3f33c2a4c1be
This greatly increases the priority of loading
the logo on browsers that support rel="preload".
Bug: T100999
Change-Id: I0738fcc0a575153dab65016fa87faaa9b8b97a9d
Updated tests to reflect this use case. Currently we assume all web-accessible
paths within ResourceBasePath (e.g "/w") to exist on disk at the same path
in $IP (e.g. "/var/www/mw").
While in theory any number of web server rewrites or aliases could exist,
there is one case in particular that we should support since the information
is available in the configuration: UploadDir and UploadPath. This path may
be rewritten in a way that varies by wiki in multi-wiki installs that share
the same source code. E.g. a server may rewrite "/w/images" to somewhere
else, which means it will not match the directory on disk that is shared
between wikis.
Bug: T155146
Change-Id: I320478c9c262cc012f08b585b48d290594ec2420