jenkins-bot has submitted this change and it was merged.
Change subject: Allow lazy loading of references (feature flagged)
......................................................................
Allow lazy loading of references (feature flagged)
When enabled this replaces the list of references with
a link to a non-existent special page which is passed
the parameters it needs to render the list of referenes
When a reference is clicked it fires off a request to the API
to get the references object.
This needs various changes in the Cite API which are listed
below.
Changes:
* When feature flag enabled sub and sup tags are hidden. URLS for
these will be rewritten when Special:References fallback is in place
* setup function of references module now requires the page object
* getReference private method now requires page to be passed
* Introduce private method getReferenceData which obtains
references via API or from DOM depending on feature flag
* mobile.references now uses the editor gateway so it can parse
reference raw wikitext (hopefully this can be removed at later date)
* Refactor tests for reference to use a template and not trigger
DOM events
* New style module added for beta skin
* Error handling when reference lookup fails
Depends-On: I81a965bcb47d17df18f1e415e3c25f88f6b48ffc
Bug: T125896
Change-Id: I287608a8fdfa61fe2d9270ab7df4da9bca3aef4c
---
M extension.json
M i18n/en.json
M i18n/qqq.json
M includes/MobileFormatter.php
M includes/MobileFrontend.hooks.php
M includes/skins/SkinMinervaBeta.php
M resources/mobile.references/ReferencesDrawer.hogan
M resources/mobile.references/ReferencesDrawer.js
A resources/mobile.references/images/error.png
M resources/mobile.references/references.js
M resources/mobile.references/references.less
A resources/skins.minerva.content.styles.beta/styles.less
A resources/skins.minerva.content.styles.beta/text.less
M resources/skins.minerva.content.styles/text.less
M resources/skins.minerva.scripts/init.js
M tests/qunit/mobile.references/test_references.js
A tests/qunit/tests.mobilefrontend/references.html
17 files changed, 265 insertions(+), 50 deletions(-)
Approvals:
Jhernandez: Looks good to me, approved
jenkins-bot: Verified
diff --git a/extension.json b/extension.json
index fd7e954..2a79941 100644
--- a/extension.json
+++ b/extension.json
@@ -142,6 +142,16 @@
"resources/skins.minerva.content.styles/styles.less"
]
},
+ "skins.minerva.content.styles.beta": {
+ "targets": [
+ "mobile",
+ "desktop"
+ ],
+ "position": "top",
+ "styles": [
+
"resources/skins.minerva.content.styles.beta/styles.less"
+ ]
+ },
"mobile.pagelist.styles": {
"targets": [
"mobile",
@@ -1090,10 +1100,12 @@
],
"dependencies": [
"mobile.drawers",
+ "mobile.editor.api",
"mobile.references.images",
"mobile.loggingSchemas"
],
"messages": [
+ "mobile-frontend-references-citation-error",
"mobile-frontend-references-citation"
],
"styles": [
@@ -2030,6 +2042,10 @@
"base": false,
"beta": false
},
+ "MFLazyLoadReferences": {
+ "base": false,
+ "beta": false
+ },
"MFNoMobileCategory": false,
"MFNoMobilePages": [],
"MFNearbyRange": 10000,
diff --git a/i18n/en.json b/i18n/en.json
index 6e0bb03..75e3d04 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -271,6 +271,8 @@
"mobile-frontend-privacy-link-text": "Privacy",
"mobile-frontend-random-button": "Random",
"mobile-frontend-references-citation": "Citation",
+ "mobile-frontend-references-citation-error": "An error occurred and it
was not possible to load this citation.",
+ "mobile-frontend-references-list": "View full list of citations",
"mobile-frontend-regular-site": "Desktop view",
"mobile-frontend-requires-mobile": "This page is not available on
desktop. Please click the mobile view link at the bottom of the page.",
"mobile-frontend-requires-optin": "This page is not available unless
you opt into our beta mode. Visit the [[Special:MobileOptions|settings page]]
to opt in.",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index c372ecc..d128763 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -269,6 +269,8 @@
"mobile-frontend-privacy-link-text": "Custom version of \"Privacy
policy\" link text for mobile footer, intended to be as brief as possible to
take up as little screen real estate as possible.\n{{Identical|Privacy}}",
"mobile-frontend-random-button": "This is the label of one of the
buttons that appear if you click the wiki logo near the search box.\n\nThis
buttons takes the user to a random page.\n{{Identical|Random}}",
"mobile-frontend-references-citation": "The title of the reference
drawer that opens up when a reference link is clicked.\n{{Identical|Citation}}",
+ "mobile-frontend-references-citation-error": "Error message body that
shows when a citation fails to load via the API.",
+ "mobile-frontend-references-list": "Label for a link to the list of the
citations in the article.",
"mobile-frontend-regular-site": "When on the mobile site, this text
links to the normal page for desktop computers",
"mobile-frontend-requires-mobile": "Message that shows when a special
page does not have a desktop equivalent.\n\nPoints user to mobile view link at
bottom of page to switch to mobile.\n\nThis should be consistent with
{{msg-mw|Mobile-frontend-view}}.",
"mobile-frontend-requires-optin": "Message that shows when a page
requires beta mode to work. Wikitext that links to [[Special:MobileOptions]]
page.",
diff --git a/includes/MobileFormatter.php b/includes/MobileFormatter.php
index 714f47f..2bb0784 100644
--- a/includes/MobileFormatter.php
+++ b/includes/MobileFormatter.php
@@ -106,8 +106,9 @@
*/
public function filterContent( $removeDefaults = true ) {
$ctx = MobileContext::singleton();
- $mfRemovableClasses = $ctx->getMFConfig()
- ->get( 'MFRemovableClasses' );
+ $config = $ctx->getMFConfig();
+ $isBeta = $ctx->isBetaGroupMember();
+ $mfRemovableClasses = $config->get( 'MFRemovableClasses' );
if ( $removeDefaults ) {
$this->remove( $mfRemovableClasses['base'] );
@@ -116,15 +117,23 @@
}
}
+ $mfReferences = $config->get( 'MFLazyLoadReferences' );
+ if ( $mfReferences ) {
+ if ( $mfReferences['base'] ||
+ ( $isBeta && $mfReferences['beta'] )
+ ) {
+ $this->doRewriteReferencesForLazyLoading();
+ }
+ }
+
if ( $this->removeMedia ) {
$this->doRemoveImages();
} else {
- $mfLazyLoadImages = $ctx->getMFConfig()
- ->get( 'MFLazyLoadImages' );
+ $mfLazyLoadImages = $config->get( 'MFLazyLoadImages' );
if (
- $mfLazyLoadImages['base'] ||
- ( $ctx->isBetaGroupMember() &&
$mfLazyLoadImages['beta'] )
+ $mfLazyLoadImages['base'] ||
+ ( $isBeta && $mfLazyLoadImages['beta'] )
) {
$this->doRewriteImagesForLazyLoading();
}
@@ -134,6 +143,39 @@
}
/**
+ * Replaces any references list with a link to Special:References
+ */
+ private function doRewriteReferencesForLazyLoading() {
+ $doc = $this->getDoc();
+ // Accessing by tag is cheaper than class
+ $nodes = $doc->getElementsByTagName( 'ol' );
+ // PHP's DOM classes are recursive
+ // but since we are manipulating the DOMList we have to
+ // traverse it backwards
+ // see http://php.net/manual/en/class.domnodelist.php
+ $listId = $nodes->length - 1;
+ for ( $i = $listId; $i >= 0; $i-- ) {
+ $list = $nodes->item( $i );
+
+ // Use class to decide it is a list of references
+ if ( strpos( $list->getAttribute( 'class' ),
'references' ) !== false ) {
+ $parent = $list->parentNode;
+ $placeholder = $doc->createElement( 'a',
+ wfMessage(
'mobile-frontend-references-list' ) );
+ $placeholder->setAttribute( 'class',
'mf-lazy-references-placeholder' );
+ // Note to render a reference we need to know
its listId and title.
+ // Note: You can have multiple <references> tag
on the same page
+ $citePath = "$listId/" .
$this->title->getPrefixedText();
+ // FIXME: Currently a broken link see
https://phabricator.wikimedia.org/T125897
+ $placeholder->setAttribute( 'href',
+ SpecialPage::getTitleFor( 'Cite',
$citePath )->getLocalUrl() );
+ $parent->replaceChild( $placeholder, $list );
+ $listId -= 1;
+ }
+ }
+ }
+
+ /**
* Enables images to be loaded asynchronously
*/
private function doRewriteImagesForLazyLoading() {
diff --git a/includes/MobileFrontend.hooks.php
b/includes/MobileFrontend.hooks.php
index 32c8725..b221b5e 100644
--- a/includes/MobileFrontend.hooks.php
+++ b/includes/MobileFrontend.hooks.php
@@ -296,6 +296,7 @@
'issues.hogan' =>
'tests/qunit/tests.mobilefrontend/issues.hogan',
'page.html' =>
'tests/qunit/tests.mobilefrontend/page.html',
'page2.html' =>
'tests/qunit/tests.mobilefrontend/page2.html',
+ 'references.html' =>
'tests/qunit/tests.mobilefrontend/references.html',
),
'localBasePath' => $localBasePath,
'remoteExtPath' => 'MobileFrontend',
@@ -438,6 +439,7 @@
'wgMFLicense' => MobileFrontendSkinHooks::getLicense(
'editor' ),
'wgMFSchemaEditSampleRate' => $config->get(
'MFSchemaEditSampleRate' ),
'wgMFLazyLoadImages' => $config->get(
'MFLazyLoadImages' ),
+ 'wgMFLazyLoadReferences' => $config->get(
'MFLazyLoadReferences' ),
'wgMFSchemaMobileWebLanguageSwitcherSampleRate' =>
$config->get(
'MFSchemaMobileWebLanguageSwitcherSampleRate' ),
'wgMFExperiments' => $config->get( 'MFExperiments' ),
diff --git a/includes/skins/SkinMinervaBeta.php
b/includes/skins/SkinMinervaBeta.php
index b543fab..57fd66f 100644
--- a/includes/skins/SkinMinervaBeta.php
+++ b/includes/skins/SkinMinervaBeta.php
@@ -128,6 +128,7 @@
if ( $title->isMainPage() ) {
$styles[] = 'skins.minerva.mainPage.beta.styles';
}
+ $styles[] = 'skins.minerva.content.styles.beta';
return $styles;
}
diff --git a/resources/mobile.references/ReferencesDrawer.hogan
b/resources/mobile.references/ReferencesDrawer.hogan
index 6f05c4e..d4d3bd3 100644
--- a/resources/mobile.references/ReferencesDrawer.hogan
+++ b/resources/mobile.references/ReferencesDrawer.hogan
@@ -2,5 +2,8 @@
{{{citation}}}
{{{cancelButton}}}
</div>
+{{#error}}<div class="error">{{/error}}
<sup>{{title}}</sup>
-{{{text}}}
+{{#text}}{{{text}}}{{/text}}
+{{^text}}{{{spinner}}}{{/text}}
+{{#error}}</div>{{/error}}
\ No newline at end of file
diff --git a/resources/mobile.references/ReferencesDrawer.js
b/resources/mobile.references/ReferencesDrawer.js
index 12b20f4..e961c7e 100644
--- a/resources/mobile.references/ReferencesDrawer.js
+++ b/resources/mobile.references/ReferencesDrawer.js
@@ -1,5 +1,6 @@
( function ( M, $ ) {
var Drawer = M.require( 'mobile.drawers/Drawer' ),
+ icons = M.require( 'mobile.startup/icons' ),
Icon = M.require( 'mobile.startup/Icon' ),
SchemaMobileWebUIClickTracking = M.require(
'mobile.loggingSchemas/SchemaMobileWebUIClickTracking'
),
@@ -19,8 +20,10 @@
/**
* @cfg {Object} defaults Default options hash.
* @cfg {String} defaults.cancelButton HTML of the button that
closes the drawer.
+ * @cfg {Boolean} defaults.error whether an error message is
being shown
*/
defaults: $.extend( {}, Drawer.prototype.defaults, {
+ spinner: icons.spinner().toHtmlString(),
cancelButton: new Icon( {
name: 'close-gray',
additionalClassNames: 'cancel',
diff --git a/resources/mobile.references/images/error.png
b/resources/mobile.references/images/error.png
new file mode 100644
index 0000000..0476228
--- /dev/null
+++ b/resources/mobile.references/images/error.png
Binary files differ
diff --git a/resources/mobile.references/references.js
b/resources/mobile.references/references.js
index 371c865..3cdb910 100644
--- a/resources/mobile.references/references.js
+++ b/resources/mobile.references/references.js
@@ -1,24 +1,104 @@
( function ( M, $ ) {
- var ReferencesDrawer, drawer;
+ var drawer, referencesData,
+ context = M.require( 'mobile.context/context' ),
+ isBeta = context.isBetaGroupMember(),
+ ReferencesDrawer = M.require(
'mobile.references/ReferencesDrawer' );
+
+ /**
+ * Return a data structure indexing all references in the given page.
+ * @method
+ * @ignore
+ * @param {Page} page to retrieve references for
+ * @returns {jQuery.Deferred} resolving with an Object indexing all
references
+ */
+ function getReferenceData( page ) {
+ var api,
+ d = $.Deferred();
+
+ if ( referencesData ) {
+ d.resolve( referencesData );
+ } else {
+ api = new mw.Api();
+ api.get( {
+ action: 'query',
+ prop: 'references',
+ formatversion: 2,
+ titles: [ page.getTitle() ]
+ } ).then( function ( data ) {
+ if ( data && data.query && data.query.pages &&
data.query.pages.length ) {
+ referencesData =
data.query.pages[0].references;
+ } else {
+ referencesData = {};
+ }
+ d.resolve( referencesData );
+ } ).fail( $.proxy( d, 'reject' ) );
+ }
+ return d;
+ }
/**
* Return the matched reference among the children of ol.references
* @method
* @ignore
* @param {String} id CSS selector
- * @returns {jQuery.Object} reference that matches id
+ * @param {Page} page to retrieve reference for
+ * @returns {jQuery.Deferred} resolves with an Object representing
reference
*/
- function getReference( id ) {
- // Escape (almost) all CSS selector meta characters
- // see
http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
- var meta = /[!"$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g;
+ function getReference( id, page ) {
+ var $el,
+ config = mw.config.get( 'wgMFLazyLoadReferences' ),
+ EditorGateway = M.require(
'mobile.editor.api/EditorGateway' ),
+ editorGateway = new EditorGateway( {
+ api: new mw.Api(),
+ title: page.getTitle()
+ } ),
+ d = $.Deferred(),
+ // Escape (almost) all CSS selector meta characters
+ // see
http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+ meta = /[!"$%&'()*+,.\/:;<=>?@[\\\]^`{|}~]/g;
+
id = id.replace( meta, '\\$&' );
- // Use find rather than string concatenation
- return $( 'ol.references' ).find( id );
+ if ( config.base || ( isBeta && config.beta ) ) {
+ id = id.substr( 1, id.length );
+ // FIXME: Use a gateway for this (?)
+ getReferenceData( page ).then( function ( references ) {
+ var ref = references[id];
+ if ( !ref ) {
+ d.reject();
+ } else if ( ref.html ) {
+ // use cached version to avoid lookup
+ d.resolve( {
+ text: ref.html
+ } );
+ } else {
+ // reference was provided raw so we now
need to parse it.
+ editorGateway.getPreview( {
+ text: ref.text
+ } ).done( function ( parsedText ) {
+ // cache for later use
+ ref.html = parsedText;
+ d.resolve( {
+ text: parsedText
+ } );
+ } ).fail( $.proxy( d, 'reject' ) );
+ }
+ } ).fail( $.proxy( d, 'reject' ) );
+ } else {
+ // Use find rather than string concatenation
+ $el = page.$( 'ol.references' ).find( id );
+ if ( $el.length ) {
+ d.resolve( {
+ text: $el.html()
+ } );
+ } else {
+ d.reject();
+ }
+ }
+ return d;
}
/**
- * Show reference
+ * Event handler to show reference when a reference link is clicked
* @method
* @ignore
* @param {jQuery.Event} ev Event object
@@ -28,17 +108,32 @@
href = $dest.attr( 'href' );
if ( !drawer ) {
+ // Note we only initialise here to avoid adding to DOM
unnecessarily
+ // (Drawer currently auto appends within the postRender
function )
drawer = new ReferencesDrawer();
}
- drawer.render( {
- title: $dest.text(),
- text: getReference( href ).html()
+ getReference( href, $dest.data( 'page' ) ).done( function (
reference ) {
+ drawer.render( {
+ title: $dest.text(),
+ text: reference.text
+ } );
+ } ).fail( function () {
+ drawer.render( {
+ error: true,
+ title: $dest.text(),
+ text: mw.msg(
'mobile-frontend-references-citation-error' )
+ } );
} );
+
ev.preventDefault();
// don't hide drawer (stop propagation of click) if it is
already shown (e.g. click another reference)
if ( drawer.isVisible() ) {
ev.stopPropagation();
} else {
+ // flush any existing reference information
+ drawer.render( {
+ text: undefined
+ } );
// use setTimeout so that browser calculates dimensions
before show()
setTimeout( $.proxy( drawer, 'show' ), 0 );
}
@@ -48,20 +143,17 @@
* Make references clickable and show a drawer when clicked on.
* @method
* @ignore
- * @param {Page} [page] Defaults to $( '#bodyContent' )
+ * @param {Page} page Defaults to $( '#bodyContent' )
*/
function setup( page ) {
- var $container = page ? page.$el : $( '#bodyContent' );
-
- mw.loader.using( 'mobile.references' ).done( function () {
- ReferencesDrawer = M.require(
'mobile.references/ReferencesDrawer' );
- $container.find( 'sup a' ).off( 'click' ).on( 'click',
showReference );
- $container.find( '.mw-cite-backlink a' ).off( 'click' );
- } );
-
+ page.$( 'sup a' ).off( 'click' )
+ .data( 'page', page )
+ .on( 'click', showReference );
+ page.$( '.mw-cite-backlink a' ).off( 'click' );
}
M.define( 'mobile.references/references', {
+ getReference: getReference,
setup: setup
} );
diff --git a/resources/mobile.references/references.less
b/resources/mobile.references/references.less
index d91d951..1db5f11 100644
--- a/resources/mobile.references/references.less
+++ b/resources/mobile.references/references.less
@@ -24,6 +24,12 @@
color: #5880C0;
}
+ .error {
+ .background-image('images/error.png');
+ padding-left: 20px;
+ background-repeat: no-repeat;
+ }
+
.cite {
padding-bottom: 20px;
diff --git a/resources/skins.minerva.content.styles.beta/styles.less
b/resources/skins.minerva.content.styles.beta/styles.less
new file mode 100644
index 0000000..58c2e68
--- /dev/null
+++ b/resources/skins.minerva.content.styles.beta/styles.less
@@ -0,0 +1 @@
+@import "text.less";
diff --git a/resources/skins.minerva.content.styles.beta/text.less
b/resources/skins.minerva.content.styles.beta/text.less
new file mode 100644
index 0000000..e6de9c0
--- /dev/null
+++ b/resources/skins.minerva.content.styles.beta/text.less
@@ -0,0 +1,8 @@
+// In beta since we lazy load and there is currently no fallback so hide
+// FIXME: This should either be removed or be applied to stable by April 2016.
+.client-nojs .beta {
+ sup,
+ sub {
+ display: none;
+ }
+}
diff --git a/resources/skins.minerva.content.styles/text.less
b/resources/skins.minerva.content.styles/text.less
index 44299a0..ba3792e 100644
--- a/resources/skins.minerva.content.styles/text.less
+++ b/resources/skins.minerva.content.styles/text.less
@@ -71,4 +71,4 @@
font-size: 0.75em;
// Avoid line-height issues caused by sup and sub
line-height: 1;
-}
\ No newline at end of file
+}
diff --git a/resources/skins.minerva.scripts/init.js
b/resources/skins.minerva.scripts/init.js
index 60c2449..bafb1d4 100644
--- a/resources/skins.minerva.scripts/init.js
+++ b/resources/skins.minerva.scripts/init.js
@@ -8,6 +8,7 @@
loader = M.require( 'mobile.overlays/moduleLoader' ),
router = M.require( 'mobile.startup/router' ),
context = M.require( 'mobile.context/context' ),
+ // FIXME: Don't pull in the mobile.references library on
startup. Lazy load it when needed
references = M.require( 'mobile.references/references' ),
cleanuptemplates = M.require( 'mobile.issues/cleanuptemplates'
),
useNewMediaViewer = context.isBetaGroupMember(),
@@ -216,7 +217,7 @@
$( function () {
initButton();
initMediaViewer();
- references.setup();
+ references.setup( page );
} );
// Access the beta optin experiment if available.
diff --git a/tests/qunit/mobile.references/test_references.js
b/tests/qunit/mobile.references/test_references.js
index 168237c..7a4d3c5 100644
--- a/tests/qunit/mobile.references/test_references.js
+++ b/tests/qunit/mobile.references/test_references.js
@@ -1,33 +1,57 @@
( function ( $, M ) {
var R = mw.mobileFrontend.require( 'mobile.references/references' ),
- ReferencesDrawer = M.require(
'mobile.references/ReferencesDrawer' );
+ Page = M.require( 'mobile.startup/Page' );
QUnit.module( 'MobileFrontend references.js', {
setup: function () {
- $( '<div id="mfe-test-references">' +
- '<sup id="cite_ref-1" class="reference"><a
href="#cite_note-1">[1]</a></sup>' +
- '<ol class="references">' +
- '<li id="cite_note-1">' +
- '<span
class="mw-cite-backlink"><a href="#cite_ref-1">↑</a></span> <span
class="reference-text">hello</span>' +
- '</li>' +
- '</ol>'
- ).appendTo( '#qunit-fixture' );
- // prevent events from being logged.
- this.sandbox.stub( ReferencesDrawer.prototype, 'show' );
- },
- teardown: function () {
- $( '#mfe-test-references' ).remove();
+ this.$container = mw.template.get(
'tests.mobilefrontend', 'references.html' )
+ .render().appendTo( '#qunit-fixture' );
+ this.page = new Page( {
+ el: this.$container,
+ title: 'Reftest'
+ } );
+ // we use Page object which calls getUrl which uses
config variables.
+ this.sandbox.stub( mw.util, 'getUrl' ).returns(
'/wiki/Reftest' );
}
} );
- QUnit.test( 'Standard', 2, function ( assert ) {
- R.setup( {
- $el: $( '#mfe-test-references' )
+ QUnit.test( 'Standard', 1, function ( assert ) {
+ this.sandbox.stub( mw.config, 'get' ).withArgs(
'wgMFLazyLoadReferences' ).returns( {
+ beta: false,
+ base: false
} );
- $( '#mfe-test-references sup a' ).trigger( 'click' );
- assert.strictEqual( $( '.drawer.references sup' ).text(), '[1]'
);
- assert.strictEqual( $( '.drawer.references .reference-text'
).text(), 'hello' );
+ R.getReference( '#cite_note-1', this.page ).done( function (
ref ) {
+ assert.strictEqual( $( '<div>' ).html( ref.text ).find(
'.reference-text' ).text(), 'hello' );
+ } );
+ } );
+
+ QUnit.test( 'Lazy loaded', 1, function ( assert ) {
+ this.sandbox.stub( mw.Api.prototype, 'get' ).returns(
+ $.Deferred().resolve( {
+ query: {
+ pages: [
+ {
+ references: {
+ 'cite_note-1': {
+ key: 1,
+ //
include html to avoid hitting EditorGateway
+ html:
'<i>so lazy</i>',
+ text:
'\'\'so lazy\'\''
+ }
+ }
+ }
+ ]
+ }
+ } )
+ );
+ this.sandbox.stub( mw.config, 'get' ).withArgs(
'wgMFLazyLoadReferences' ).returns( {
+ beta: true,
+ base: true
+ } );
+ R.getReference( '#cite_note-1', this.page ).done( function (
ref ) {
+ assert.strictEqual( ref.text, '<i>so lazy</i>' );
+ } );
} );
} )( jQuery, mw.mobileFrontend );
diff --git a/tests/qunit/tests.mobilefrontend/references.html
b/tests/qunit/tests.mobilefrontend/references.html
new file mode 100644
index 0000000..aaff3be
--- /dev/null
+++ b/tests/qunit/tests.mobilefrontend/references.html
@@ -0,0 +1,12 @@
+<div id="mfe-test-references">
+ <sup id="cite_ref-1" class="reference">
+ <a href="#cite_note-1">[1]</a>
+ </sup>
+ <ol class="references">
+ <li id="cite_note-1">
+ <span class="mw-cite-backlink">
+ <a href="#cite_ref-1">↑</a>
+ </span> <span class="reference-text">hello</span>
+ </li>
+ </ol>
+</div>
\ No newline at end of file
--
To view, visit https://gerrit.wikimedia.org/r/271434
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I287608a8fdfa61fe2d9270ab7df4da9bca3aef4c
Gerrit-PatchSet: 17
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: Jdlrobson <[email protected]>
Gerrit-Reviewer: Bmansurov <[email protected]>
Gerrit-Reviewer: Jdlrobson <[email protected]>
Gerrit-Reviewer: Jhernandez <[email protected]>
Gerrit-Reviewer: Jhobs <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits