Commit graph

1287 commits

Author SHA1 Message Date
Bartosz Dziewoński
9e5c3e9521 Use ResourceLoaderImageModule to serve icons for OOjs UI
Benefits:
* Full per-language icons support. Icons that differ for each language
  (such as the 'Bold' icon) will now always display correctly
  according to user interface language, even on old browsers.
* MediaWiki UI icons support. When the 'mediawiki.ui.icon' module is
  loaded, you can use syntaxes such as below to display any OOUI icons
  (from the packs that were loaded) without involving OOUI itself.
    <div class="mw-ui-icon mw-ui-icon-before mw-ui-icon-check">OK</div>
    <div class="mw-ui-icon mw-ui-icon-after mw-ui-icon-check">OK</div>
    <div class="mw-ui-icon mw-ui-icon-element mw-ui-icon-check">OK</div>

Summary of changes:
* Resources.php:
  * Remove icons CSS files. Include image data JSON files instead.
  * Split the images from 'oojs-ui.styles' module to separate ones.
* OutputPage: Update enableOOUI() method for newly split modules.
* ResourceLoaderImageModule: Make it possible to load image data from
  a JSON file.
* update-oojs-ui.sh: Copy source files rather than distribution for
  icon packs.

This is not an improvement when it comes to code quality, though :(
Issues include some nasty code duplication, using "source code" (image
definitions) from OOUI rather than just distribution files, and hacky
methods to load image data from JSON files live.

Bug: T92551
Change-Id: Id369ecaec7048dcf68ba1e4df748362760533782
2015-04-28 13:48:30 +00:00
Timo Tijhof
9838eeb6f2 resourceloader: Add ResourceLoader::makeInlineScript utility and use it
Plucked from the e86e5f846 which got reverted.

Change-Id: I4bba3f3c31c5181867378ae174537429b49a50df
2015-04-20 19:45:27 +00:00
jenkins-bot
c0cb60d6c8 Merge "SECURITY: Don't execute another user's CSS or JS on preview" 2015-04-01 17:31:57 +00:00
Ori Livneh
1b146857e3 OutputPage: Tiny tweak to jQuery.ready inline script
Changing 'window.jQuery && jQuery.ready()' to 'if ( window.jQuery )
jQuery.ready()' means no *<![CDATA[*/ /*]]>* is required (because we
got rid of the ampersands). It's also more readable and more consistent
with if(window.mw).

Change-Id: I28262efb978c085e732b40f9dc5ddb1bda5c4376
2015-04-01 17:03:54 +00:00
Brad Jorsch
ff95a95437 SECURITY: Don't execute another user's CSS or JS on preview
Someone could theoretically try to hide malicious code in their user
common.js and then trick an admin into previewing it by asking for help.

Bug: T85855
Change-Id: I5a7a75306695859df5d848f6105b81bea0098f0a
2015-04-01 09:55:52 -07:00
Ori.livneh
2b6eb60ce5 Revert "Optimize order of styles and scripts"
The patch did not improve performance. I'd like to think that the increased
control over when inline scripts are executed makes the patch worthwhile
regardless, but that is post hoc justification and possibly a bit of personal
ego. Krinkle agrees that we may use some of the ideas in this patch in the
future but he thinks we're better off not heading down this path before we
have a better sense of where we're going, and I trust his judgment.

This reverts commit e86e5f8460.

Change-Id: I151f74a41dd664b5a0aa5cfd99fcc95e2686a1e6
2015-03-25 04:40:46 +00:00
Ori Livneh
e86e5f8460 Optimize order of styles and scripts
The current ordering of scripts and stylesheets in <head> causes all major
browsers to serialize and defer requests that could be performed in parallel.

The problem is that external stylesheets are loaded before inline scripts. As
Steven Souders explains, "all major browsers preserve the order of CSS and
JavaScript. The stylesheet has to be fully downloaded, parsed, and applied
before the inline script is executed. And the inline script must be executed
before the remaining resources can be downloaded. Therefore, resources that
follow a stylesheet and inline script are blocked from downloading."[1]

In other words: the browser could start loading body images, but it refuses to
do that until it has executed inline scripts in head. And it refuses to execute
those scripts until the external CSS is downloaded, parsed and applied. You can
see the effect of this in this image, showing the request waterfall for
[[en:Gothic Alphabet]]: [2]. Notice how no images were requested before the
browser had finished processing the three load.php requests at the top.

To fix this, we want to move the inline scripts above the external CSS. This is
a little bit tricky, because the inline scripts depend on mw.loader, which is
loaded via an external script. If we move the external script so that it too is
above the external stylesheet, we force the browser to serialize requests,
because the browser will not retrieve the external CSS until it has retrieved
and executed the external JS code. So what we want is to move the inline
scripts above the external stylesheet, but keep the external script (which the
inline scripts depend on) below the external stylesheet.

We can do this by wrapping the inline script code in a closure (which binds
'mw') and enqueuing the closure in a global array which will be processed by
the startup module at just the right time.

Net result: external CSS and JS is retrieved in parallel, retrieval of images
(and other external assets) is unblocked, but the order in which code is
evaluated remains the same.

[1]: <http://www.stevesouders.com/blog/2009/05/06/positioning-inline-scripts/>
[2]: <http://people.wikimedia.org/~ori/enwiki-waterfall.png> (excerpted from
 <http://www.webpagetest.org/result/150316_0C_7MB/1/details/>.

Change-Id: I98d383a6299ffbd10210431544a505338ca8643f
2015-03-17 03:10:49 +01:00
jenkins-bot
6630d3c7e0 Merge "Use underscores in help links" 2015-03-12 14:56:31 +00:00
umherirrender
507902203a Use underscores in help links
Replace spaces by underscore to build correct links to wiki pages. IE11
will show %20 for spaces. Also use urlencode to make the url safe.

Follow-Up: I2934b1708a0d207dcf3d940264f140613646f203
Change-Id: I5ef08441406e96aa9749476af0a81fc11fa4e4d6
2015-03-12 14:43:22 +00:00
Timo Tijhof
3ed7b27f7b OutputPage: Condition-wrap the <script> for 'user.groups'
Follows-up 9d390a09cd. It already wraps the only=script requests
for 'site' and 'user', but forgot about 'user.groups' which is
not 'scripts' but 'combined' (as regular module requests).

That request responds with mw.loader.implement whih will be absent
if the environment is unsupported.

With normal module requests, this is naturally covered by those
requests not being fired from mw.loader in the first place but
with hardcoded requests like these the condition wrap with
document.write is unfortunately required in the current reality.

Change-Id: Ib3a7378d0c44e601760fbbc5174da09bd7b7f492
2015-03-11 19:33:24 +00:00
Federico Leva
6ab33238a2 Don't require JavaScript for addHelpLink styles
And avoid wfMessage.
Followup to 376c0a13df

Bug: T45591
Change-Id: I2f02c2a4db609356ff8be30f260490d19f3226d1
2015-03-07 18:59:35 +01:00
jenkins-bot
5907e840cc Merge "Add top help link to MediaWiki.org in several pages via indicator" 2015-03-04 16:15:53 +00:00
Nemo bis
376c0a13df Add top help link to MediaWiki.org in several pages via indicator
All the chosen targets are translatable public domain help pages
on MediaWiki.org. Mostly special pages and actions for privileged
users for now.

Adapted from the Translate extension, credit to Niklas Laxström
(TranslateUtils::addSpecialHelpLink).

Depends on 6f5b29ff4e, whose commit
message has a typo addIndicator() instead of setIndicator().

Bug: T45591
Change-Id: I2934b1708a0d207dcf3d940264f140613646f203
2015-03-04 10:59:03 +01:00
Aaron Schulz
4111ff0dc3 Removed obsolete "containsOldMagic" code
Change-Id: Id225347e0599a6f79b30b0793cce7d97daed46f2
2015-02-15 14:41:49 -08:00
jenkins-bot
2f17fff894 Merge "Add OutputPage::enableOOUI() to set up OOUI stuff when needed" 2015-01-28 23:33:50 +00:00
YuviPanda
4a9840e271 Add option to output referrer policy meta tag
Bug: T87276
Change-Id: I9ea4797c4d292cd4565f47b88e605b4e7afdb1d1
2015-01-20 17:21:13 -08:00
Bartosz Dziewoński
b4255eab0b Add OutputPage::enableOOUI() to set up OOUI stuff when needed
Initialize OOUI theme and set OOUI element directionality, load
necessary RL modules.

Bug: T85767
Change-Id: I9aa430969e4250bd2bd6c396b6133a35ca5bf46b
2015-01-16 15:10:57 -08:00
Federico Leva
b28cdb98f0 Typofix in wrapWikiMsg() comment, smoother sentence
Change-Id: Ic0ebc94cec68ee1515d4c98d49b26a6f9148e95e
2015-01-15 19:54:39 +00:00
Ricordisamoa
2ae155da52 Fix phpcs errors in includes/
Mostly Squiz.WhiteSpace.SuperfluousWhitespace.EmptyLines

Change-Id: I678b2f0902f11cd1dfa1611b9da24e7237df9122
2015-01-08 20:15:07 +01:00
Chad Horohoe
aa21e125a3 Remove obvious function-level profiling
Xhprof generates this data now. Custom profiling of various
sub-function units are kept.

Calls to profiler represented about 3% of page execution
time on Special:BlankPage (1.5% in/out); after this change
it's down to about 0.98% of page execution time.

Change-Id: Id9a1dc9d8f80bbd52e42226b724a1e1213d07af7
2015-01-07 11:14:24 -08:00
Timo Tijhof
ba50b32556 SpecialJavaScriptTest: Add export feature
Add an 'export' subpage to SpecialJavaScriptTest which allows
one to request a self-sufficient JavaScript payload that will
bootstrap a ResourceLoader client and load the test suites.

This is needed for using Karma (which only loads JavaScript,
no full html pages). As such elements from the Skin and OutputPage
will not exist. While all QUnit tests in MediaWiki core and
most extensions I've seen already use #qunit-fixture, this is
now required. This to prevent leakage of elements from one
test to another, but it also prevents tests from depending
on elements provided by the server.

While the Karma setup is still in the pipeline (might land before
this commit loses WIP status), for now this can be tested via
the 'Special:JavaScriptTest/qunit/plain' subpage.

Refactor:
* Use HTTP status code 404 in the response for "noframework".
* Simplify HTML footprint by using <div id="qunit"> instead of
  hardcoding the full structure. This feature was added to QUnit
  since v1.3.0 (Feb 2012), we're using v1.14.0 (Jan 2014).
  QUnit's header is automatically derived from document.title.
* Remove redundant addModules() for 'test.mediawiki.qunit.testrunner'.
  This is already added by default.
* Move allowClickjacking() call so that it applies to other modes
  as well. The exported javascript needs to have wgBreakFrame set
  to false so that test runners can frame it.
* Change mediawiki.special.javaScriptTest to not depend on QUnit.
  It caused QUnit to load on error pages. And in theory the page
  is suited for other frameworks and shouldn't load QUnit this way.

Bug: T74063
Change-Id: I3d4d0df43bb426d9579eb0349b8b5477281a7cfc
2015-01-05 17:59:33 +00:00
gladoscc
e4701c646c Document OutputPage::$mPreventClickjacking
Change-Id: I3b4f967743c810c5cbef094b3e30807cf0a668ca
2015-01-01 22:24:27 +11:00
Reedy
4d9143c7f5 Add lots of @throws
Change-Id: I09d0c13070f966fcf23d2638d8fc1328279a5995
2014-12-24 13:49:20 +00:00
Ricordisamoa
12dec5d85d Fix some stuttering in comments and documentation
Change-Id: I9c0088b9aab37335203cad45a1d6fa8ac3f43321
2014-12-17 19:44:10 +00:00
Aaron Schulz
e369f66d00 Replace wfRunHooks calls with direct Hooks::run calls
* This avoids the overhead of an extra function call

Change-Id: I8ee996f237fd111873ab51965bded3d91e61e4dd
2014-12-10 12:26:59 -08:00
umherirrender
7da1cbc78c Fix backlink for RevertAction
RevertAction::getDescription cannot set subtitle on OutputPage,
because the subtitle on OutputPage gets cleared before the
result of getDescription is added and than the subtitle is gone.

Refactored the code for building the backlink into a static function
and use it.

Change-Id: Iedad0b8e040035a9a10a0b140d2322357e6b539a
2014-12-05 14:28:18 +00:00
Kunal Mehta
0406f3d61b OutputPage: Add accessors for some protected properties
Bug: T76168
Change-Id: Iee11c217b6b0d35acfdfac916814521acda2b1a4
2014-12-03 09:40:15 -08:00
jenkins-bot
7cfeed5ad6 Merge "Expose ID of relevant page in JS variables" 2014-11-19 04:01:50 +00:00
Kunal Mehta
b2bb4f8bf2 Make allowing site-wide styles on restricted special pages a config option
This mostly reverts commit 614d7e5c27.

Many wikis use MediaWiki:Common.css and associated pages to create a
custom "theme" for their wiki, which would no longer load on login
or preference pages, creating an inconsistent UI.

This re-adds the difference in module origin for different types
(styles, scripts, etc.), and now OutputPage::disallowUserJs()
checks the value of the "AllowSiteCSSOnRestrictedPages" config setting
to determine whether to allow site-wide CSS styles or not.

By default this feature is disabled to be secure by default.

Bug: 71621
Change-Id: I1bf4dd1845b6952c3985e179fbea48181ffb8907
2014-11-07 14:50:33 -08:00
Alex Monk
650aa90f38 Expose ID of relevant page in JS variables
Bug: 53774
Change-Id: I06cd037804daba59e4f42e3be5f2883a82fcaa27
2014-11-03 23:41:32 +00:00
Bartosz Dziewoński
6f5b29ff4e Implement page status indicators
Page status indicators are icons (or short text snippets) usually
displayed in the top-right corner of the page, outside of the main
content. Basically, <indicator name="foo">[[File:Foo.svg|20px]]</indicator>
may be used on a page to place the icon in the indicator area. They
are also known as top icons, page icons, heading icons or title icons.

I found the discussion on bug 23796 highly illuminating. I suggest
that everyone read it before suggesting different design choices.

I spent some time with a thesaurus pondering the name. "Emblems" and
"badges" were also considered, but the former has a much more limited
meaning and the latter is already taken by Wikidata, with a similar
but subtly different feature set. I am not aware of any naming
conflicts ;) besides new talk page message "indicator" (used by core
and Echo in some documents) and OOjs UI indicators (tiny icons like
the arrow on a dropdown form element), which shouldn't be confusing.

Potential use cases include:
* "Lock" indicators for page protection levels
* Featured/good article indicators
* Redirect shortcuts display ("WP:VPT")
* Links to help/manual for special pages
* Coordinates?… or globe icon for inline pop-up maps

Design features:
* Skin-customizable. Skins can fully control where and how indicators
  are shown, or may just do <?php echo $this->getIndicators(); ?> to
  output the default structure. By default they are not shown at all.
* Extension-customizable. Extensions can call ParserOutput::addIndicator()
  to insert an indicator from one of the numerous parser hooks.
* Wiki-customizable. In addition to just using the parser functions,
  on-wiki styles and scripts can use the provided classes and ids
  (.mw-indicator, #mw-indicator-<name>) to customize their display.

Design limitations:
* Every indicator must have a unique identifier (name). It's not
  possible to create arrays, or to have several indicators with the
  same name. In case of duplicates, the latest occurrence of the
  parser function wins.
* Indicators are displayed ordered by their names (and not occurrence
  order). This ensures consistency across pages and provides a simple
  means of ordering or grouping them.
* Indicators are not stored, tracked or accessible outside of
  ParserOutput (in particular they're not in the page_props table).
  They are intended to merely reflect the content or metadata that is
  already present on the page, and not be data themselves. If you ever
  think you need to list pages with a given status indicator, instead
  figure out what it means and use the appropriate tracking category,
  special page report, already existing page_prop, or other means.

Corresponding patch in Vector: I90a8ae15ac8275d084ea5f47b6b2684d5e6c7412.
I'll implement support in the other three skins included in the tarball
and document it on mediawiki.org after this is merged.

Bug: 23796
Change-Id: I2389ff9a5332a2b1d033eb75f0946e5241cfaaf4
2014-10-17 15:49:15 -07:00
umherirrender
ce08326cda Break long lines
Change-Id: I8d4e883058c21023273df88439cd145888833115
2014-10-14 19:30:43 +00:00
umherirrender
0eaa6b5334 Use config for $wgLanguageCode in OutputPage.php
Follow-Up: I5e0ebc173631d1d1052de7ccee4ef839c7c1767f
Change-Id: Idd7fab9f8bf47fc303b5923327da67905e12e527
2014-10-10 14:58:03 +02:00
Kevin Israel
95954ab86c Deprecate OutputPage::rateLimited()
Change-Id: I140e6af9dde090b9f8611e7b53a650061f2e84eb
2014-10-07 12:35:59 +02:00
Kevin Israel
202db653c3 Deprecate OutputPage::readOnlyPage()
Also, as this method is never called with an argument in any Gerrit-hosted
extension, shortened it to just `throw new ReadOnlyError;` on the assumption
that the removed portion was only left in for EditPage.

Change-Id: Icc2fc166b155eac548dfd5f3e67b0b1f92ef90d3
2014-10-07 12:34:56 +02:00
jenkins-bot
8fc9ade3a8 Merge "Added some profiling calls" 2014-10-02 21:18:41 +00:00
Timo Tijhof
614d7e5c27 SECURITY: OutputPage: Remove separation of css and js module allowance
* No longer segment module origin allowance by an "only=" content
type. Both can be sensitive security-wise and there's no valid
use case for allowing CSS anywhere you want to disallow JS. Both
can significantly impact the user interface and cause unintended
actions to be taken on the user's behalf, or desired actions to
be made practically impossible.

* While at it, also remove the ability to set the module allowance
directly. The reduceAllowedModuleOrigin method is all we need.
I couldn't find usage or mention of setAllowedModules() in
mediawiki-core nor in any other Wikimedia-hosted repository.

Bug: 70672
Change-Id: I308e794daca27a9380c67be350f8ab51f9c2de34
2014-10-01 22:48:29 +02:00
Aaron Schulz
6f7292ad29 Added some profiling calls
Change-Id: Icb024c86e86a030fdea874cf5aa47fd0329e6133
2014-10-01 10:14:27 -07:00
umherirrender
df24b7209d Fixed spacing
- Added newline at end of file
- Removed double spaces/newlines
- Added space after if/function and parentheses/brackets
- Removed space before comma/cast
- Fixed indent of some lines

Change-Id: I29867ffdffdfb7d2b56997e9393497c7dc12f7d3
2014-09-29 20:46:19 +02:00
Bartosz Dziewoński
4c01f8b2bc Make "/*@noflip*/ /*@embed*/" annotation work without CSSJanus hacks
This reverts most of commit 2d842f1425,
leaving only the test added in it, and reimplements the same
functionality better.

Instead of stripping /*@noflip*/ annotations in CSSJanus, which is
incompatible with other implementations that preserve it, extend
CSSMin to allow other CSS comments to be present before the
rule-global @embed annotation. (This required making the regex logic
in it even worse than it was, but it's actually slightly less terrible
than I expected it would be. Good thing we have tests!)

Bug: 69698
Change-Id: I58603ef64f7d7cdc6461b34721a4d6b15f15ad79
2014-09-23 22:47:54 +00:00
Timo Tijhof
9d390a09cd resourceloader: Condition-wrap the HTML tag instead of JS response
Follows-up 9272bc6c47, 03c503da22, 1e063f6078.

One can't wrap arbitrary JavaScript in an if-statement and have
its inner-body mean exactly the same.

Certain statements are only allowed in the top of a scope (such
as hoisted function declarations). These are not allowed inside
a block. They're fine in both global scope and local function
scope, but not inside an if-block of any scope.

The ECMAScript spec only describes what is an allowed token.
Any unexpected token should result in a SyntaxError.

Chrome's implementation (V8) allows function declarations in
blocks and hoists them to *outside* the condition. Firefox's
SpiderMonkey silently ignores the statement. Neither throw a
SyntaxError.

Rgular ResourceLoader responses only contain mw.loader.implement()
and mw.loader.state() call which could be wrapped without issues.
However such responses don't need wrapping as they're only made
by mediawiki.js (in which case mw is obviously loaded). The
wrapping is for legacy scripts that execute in the global scope.

For those, let's wrap the script tag itself (instead of the
response). That seems like the most water-tight and semantically
correct solution.

Had to bring in $isRaw from ResourceLoader.php, else the startup
module would have been wrapped as well (added regression test).

Bug: 69924
Change-Id: Iedda0464f734ba5f7a884726487f6c7e07d444f1
2014-09-09 15:54:16 +00:00
Timo Tijhof
5553be79b9 OutputPage: Restore ResourceLoader condition wrap for embedded modules
Follows-up 9272bc6c47, 03c503da22.

* In 9272bc6c47, the condition wrap was removed from
  OutputPage for no reason. This went unnnoticed as I had also
  accidentally made the cond wrap in makeModuleResponse apply
  to both only=scripts and regular (faux) responses, such as by
  OutputPage embedding private modules.

* In 03c503da22, the latter bug was fixed, thus exposing the former.

This wrapper belongs in OutputPage, not in ResourceLoader. It's
OutputPage making the loader request. And just like in other places,
it's the "client"'s responsibility to ensure the request is either not
made or wrapped appropriately.

The test for "private module (only=scripts)" could be removed but
I'll keep it so we can see how this changes in the future. It's
a case that can't ever happen, but if it would, it currently gets
a double condition wrapper, which is fine.

Change-Id: Id333e4958ed769831fabca02164c1e8505962d57
2014-09-02 11:05:13 +02:00
jenkins-bot
08e50bcecd Merge "Make "/*@noflip*/ /*@embed*/" annotation work" 2014-08-29 19:45:06 +00:00
Tim Starling
91d8a51825 Don't send rel=canonical to variant-neutral page
This has been the subject of multiple complaints from Google, it
apparently prevents them from properly indexing the variant-specific
pages. Instead, send the variant-independent link as rel=alternate
hreflang=x-default, which is recommended by Google as the preferred way
of specifying "auto-redirecting homepages" in this help page:

https://support.google.com/webmasters/answer/189077?hl=en

Send rel=alternate links unconditionally, since that is also recommended
by that help page: "each language page must identify all language
versions, including itself".

Remove $wgCanonicalLanguageLinks since it would be rather pointless and
poorly named if it only controlled rel=alternate links.

Bug: 52429
Change-Id: Ic75717f6e4ac1f73aa600c2e1bdb9c60e607edb4
2014-08-26 14:38:40 -07:00
jenkins-bot
f311f96e98 Merge "Use config instead of globals for OutputPage" 2014-08-23 20:21:44 +00:00
jenkins-bot
d4bd78dbfb Merge "OutputPage: addParserOutput*() family doesn't need to take a reference" 2014-08-23 19:59:49 +00:00
Bartosz Dziewoński
4bb54bbe30 OutputPage: addParserOutput*() family doesn't need to take a reference
We never assign to the variable, only call some (mutating) methods on
the object. With PHP 5 we don't need to pass this by reference.

The functions that evolved into this family were originally added in
r12337, back then we probably still ran on PHP 4 or something.

Change-Id: Ib4ab141ca6d803f9df0351b1f65c7e9955c37d57
2014-08-23 19:48:27 +00:00
umherirrender
5dfeff23ae Use config instead of globals for OutputPage
Change-Id: I5e0ebc173631d1d1052de7ccee4ef839c7c1767f
2014-08-23 10:52:41 +02:00
umherirrender
dfb1976bd5 Pass config to ResourceLoader from OutputPage
Change-Id: Iae99ab65a254fc3fe3acac764a068470f99af1c4
2014-08-22 22:13:16 +02:00
Kevin Israel
dd5c1b7fb7 Title::getContentModel(): load from DB if necessary
Also don't cast $model to int in LinkCache::addGoodLinkObj(); content
model IDs are non-numeric strings, not integers, so that field was
always populated with the value 0. Because 0 is a falsy value, this
caused subsequent calls to Title::getContentModel() to return the
default model rather than the correct one.

Also (hopefully) fixed every single query that could cause a
LinkCache entry to be added without the content model.

Bug: 69789
Change-Id: I94f06baf406afa538cd2b10139598442f9fc6759
2014-08-20 19:44:17 -04:00