Custom page preview for disambiguation pages

Creating a different page preview for disambiguation pages.

This patch:
- modifies the Preview model to accept a new 'type' property
- modifies the Restbase Gateway to pass the 'type' prop to the Preview model
- creates a new template to accept both generic/disambig previews
- modifies the renderer to render the new template
- generates icons for new template through resource loader
- adds new i18n strings
- modifies event-logging "preview seen" event to send new "disambiguation" previewType
- updates event logging schema version
- adds tests for Preview model and renderer for new preview type
- does way too much? yes, yes it does.

Bug: T168392
Change-Id: Idc936cc3eabbdd99a3d98f43c66b4cdbb7d24917
This commit is contained in:
Jan Drewniak 2018-03-07 12:10:53 +01:00 committed by jdlrobson
parent deaaf0961b
commit 1e946a379d
23 changed files with 787 additions and 3485 deletions

View file

@ -53,7 +53,7 @@
]
},
"EventLoggingSchemas": {
"Popups": 17540736,
"Popups": 17807993,
"VirtualPageView": 17742133
},
"config": {
@ -84,10 +84,11 @@
"ext.popups.images": {
"selector": ".mw-ui-icon-{name}:before",
"class": "ResourceLoaderImageModule",
"prefix": "mw-ui",
"images": {
"popups-settings": "resources/ext.popups.images/cog.svg",
"popups-close": "resources/ext.popups.images/close.svg"
"popups-close": "resources/ext.popups.images/close.svg",
"preview-generic": "resources/ext.popups.images/sad-face.svg",
"preview-disambiguation": "resources/ext.popups.images/multiple-articles.svg"
}
},
"ext.popups": {
@ -101,7 +102,7 @@
],
"templates": {
"preview.mustache": "resources/ext.popups.main/templates/preview.mustache",
"preview-empty.mustache": "resources/ext.popups.main/templates/preview-empty.mustache",
"preview-generic.mustache": "resources/ext.popups.main/templates/preview-generic.mustache",
"settings.mustache": "resources/ext.popups.main/templates/settings.mustache"
},
"styles": [
@ -129,7 +130,9 @@
"popups-settings-help-ok",
"popups-send-feedback",
"popups-preview-no-preview",
"popups-preview-footer-read"
"popups-preview-footer-read",
"popups-preview-disambiguation",
"popups-preview-disambiguation-link"
],
"dependencies": [
"ext.popups.images",

View file

@ -20,6 +20,8 @@
"popups-send-feedback": "Send Feedback (external link)",
"popups-preview-no-preview": "There was an issue displaying this preview",
"popups-preview-footer-read": "Go to this page",
"popups-preview-disambiguation": "This title relates to more than one page",
"popups-preview-disambiguation-link": "View similar pages",
"prefs-reading": "Reading preferences",
"popups-prefs-optin-title": "Page previews\n\n<em>Get quick previews of a topic while reading a page</em>",
"popups-prefs-optin-enabled-label": "Enable",

View file

@ -27,6 +27,8 @@
"popups-send-feedback": "Tooltip for the send feedback icon on the hovercard. Should mention that its an external link.\n{{Identical|Send feedback}}",
"popups-preview-no-preview": "The message shown to the user when a preview can't be generated.",
"popups-preview-footer-read": "The link shown to the user when a preview can't be generated.",
"popups-preview-disambiguation": "The description shown on a preview for a disambiguation page",
"popups-preview-disambiguation-link": "The link shown on a preview for a disambiguation page",
"prefs-reading": "Title for 'Reading preferences' section on preferences page",
"popups-prefs-optin-title": "Title for Page Previews option\n\n<em>Description for Page previews option</em>",
"popups-prefs-optin-enabled-label": "Label for Page Previews opt in\n{{Identical|Enable}}",

3884
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,7 @@
"bundlesize": [
{
"path": "resources/dist/index.js",
"maxSize": "11.5KB"
"maxSize": "12KB"
}
]
}

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="26" height="32" xmlns="http://www.w3.org/2000/svg">
<g id="Page-1" fill="none" fill-rule="evenodd">
<g id="multiple-articles" fill="#C8CCD1" fill-rule="nonzero">
<path d="M22.4 0a3.2 3.2 0 0 1 3.2 3.2v22.4h-3.2V3.2H4.8V0h17.6zM3.2 32A3.2 3.2 0 0 1 0 28.8V8a3.2 3.2 0 0 1 3.2-3.2h14.4A3.2 3.2 0 0 1 20.8 8v20.8a3.2 3.2 0 0 1-3.2 3.2H3.2zm8-24v8h6.4V8h-6.4zm-8 0v1.6h6.4V8H3.2zm0 3.2v1.6h6.4v-1.6H3.2zm0 3.2V16h6.4v-1.6H3.2zm0 3.2v1.6h14.4v-1.6H3.2zm0 3.2v1.6h14.4v-1.6H3.2zm0 3.2v1.6h14.4V24H3.2z" id="Shape"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 614 B

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="37" height="27" xmlns="http://www.w3.org/2000/svg">
<g id="Page-1" fill="none" fill-rule="evenodd">
<g id="sad-face" fill="#C8CCD1">
<path d="M5.475.7v20.075L0 26.25h31.025c3.102 0 5.475-2.372 5.475-5.475V.7H5.475zm20.44 4.562c1.277 0 2.19 1.095 2.19 2.19 0 1.096-.913 2.373-2.19 2.373-1.278 0-2.19-1.095-2.19-2.19s1.095-2.373 2.19-2.373zm-9.855 0c1.277 0 2.19 1.095 2.19 2.19 0 1.096-1.095 2.373-2.19 2.373s-2.19-1.095-2.19-2.19.913-2.373 2.19-2.373zm4.928 8.213c-7.153 0-8.415 7.012-8.415 7.012s2.805-1.403 8.415-1.403c5.61 0 8.414 1.403 8.414 1.403S28 13.475 20.988 13.475z" id="Shape"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 695 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 796 B

View file

@ -1,5 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="37" height="27" viewBox="0 0 37 27">
<title>sad face</title>
<path fill="#c8ccd1" fill-rule="evenodd" d="M5.475.7v20.075L0 26.25h31.025c3.102 0 5.475-2.372 5.475-5.475V.7H5.475zm20.44 4.562c1.277 0 2.19 1.095 2.19 2.19 0 1.096-.913 2.373-2.19 2.373-1.278 0-2.19-1.095-2.19-2.19s1.095-2.373 2.19-2.373zm-9.855 0c1.277 0 2.19 1.095 2.19 2.19 0 1.096-1.095 2.373-2.19 2.373s-2.19-1.095-2.19-2.19.913-2.373 2.19-2.373zm4.928 8.213c-7.153 0-8.415 7.012-8.415 7.012s2.805-1.403 8.415-1.403c5.61 0 8.414 1.403 8.414 1.403S28 13.475 20.988 13.475z"/>
</svg>

Before

Width:  |  Height:  |  Size: 638 B

View file

@ -56,14 +56,9 @@
}
}
.mwe-popups-sade-face-icon {
display: block;
width: 37px;
height: 27px;
margin: 16px 16px 0;
background-position: center center;
background-repeat: no-repeat;
.background-image-svg( '../images/sad-face.svg', '../images/sad-face.png' );
/* slightly shrinking disambiguation icon */
.mw-ui-icon.mw-ui-icon-element.mw-ui-icon-preview-disambiguation:before {
background-size: 90% auto;
}
.mwe-popups {
@ -99,6 +94,12 @@
}
}
.mwe-popups-title {
display: block;
font-weight: bold;
margin: 0 16px;
}
.mwe-popups-extract {
// T156800, T139297: "Pad" the extract horizontally using a margin so the
// SVG element is forced not to occlude the truncating pseudo-element and
@ -209,10 +210,13 @@
}
}
&.mwe-popups-is-empty {
&.mwe-popups-type-generic,
&.mwe-popups-type-disambiguation {
.mwe-popups-extract {
min-height: auto;
padding-top: 4px;
margin-bottom: 60px;
margin-top: 0;
}
.mwe-popups-read-link {

View file

@ -1,13 +0,0 @@
<div class="mwe-popups mwe-popups-is-empty" role="tooltip" aria-hidden>
<div class="mwe-popups-container">
<div class="mwe-popups-sade-face-icon"></div>
<a href="{{url}}" class="mwe-popups-extract">{{extractMsg}}</a>
<footer>
{{! If the preview "is empty", i.e. a preview can't be generated, then we
show a link to the page to make it clear that the preview can be
clicked. }}
<a href="{{url}}" class="mwe-popups-read-link">{{readMsg}}</a>
</footer>
</div>
</div>

View file

@ -0,0 +1,14 @@
<div class="mwe-popups mwe-popups-type-{{type}}" role="tooltip" aria-hidden>
<div class="mwe-popups-container">
<div class="mw-ui-icon mw-ui-icon-element mw-ui-icon-large mw-ui-icon-preview-{{type}}"></div>
{{#showTitle}}
<strong class="mwe-popups-title">{{title}}</strong>
{{/showTitle}}
<a href="{{url}}" class="mwe-popups-extract">
{{extractMsg}}
</a>
<footer>
<a href="{{url}}" class="mwe-popups-read-link">{{linkMsg}}</a>
</footer>
</div>
</div>

View file

@ -4,7 +4,7 @@
import types from './actionTypes';
import wait from './wait';
import { createNullModel } from './preview/model';
import { createNullModel, previewTypes } from './preview/model';
var $ = jQuery,
mw = window.mediaWiki,
@ -306,13 +306,17 @@ export function previewShow( token ) {
var state = getState(),
preview = state.preview,
fetchResponse = preview && preview.fetchResponse,
currentToken = preview && preview.activeToken;
currentToken = preview && preview.activeToken,
validType = fetchResponse && [
previewTypes.TYPE_PAGE,
previewTypes.TYPE_DISAMBIGUATION
].indexOf( fetchResponse.type ) > -1;
if (
// Check the pageview can still be associated with original event
currentToken && currentToken === token &&
// and the preview is still active and of type `page`
fetchResponse && fetchResponse.type === 'page'
fetchResponse && validType
) {
dispatch( {
type: types.PREVIEW_SEEN,

View file

@ -136,6 +136,7 @@ function convertPageToModel( page ) {
page.pagelanguagehtmlcode,
page.pagelanguagedir,
page.extract,
page.type,
page.thumbnail,
page.pageid
);

View file

@ -186,6 +186,7 @@ function convertPageToModel( page, thumbSize, extractParser ) {
page.lang,
page.dir,
extractParser( page ),
page.type,
page.thumbnail ?
generateThumbnailData(
page.thumbnail, page.originalimage, thumbSize

View file

@ -3,16 +3,25 @@
*/
/**
* @constant {String}
* Page Preview types as defined in Schema:Popups
* https://meta.wikimedia.org/wiki/Schema:Popups
*
* @constant {Object}
*/
export var TYPE_GENERIC = 'generic';
/**
* @constant {String}
*/
export var TYPE_PAGE = 'page'; // eslint-disable-line one-var
var previewTypes = {
/** empty preview */
TYPE_GENERIC: 'generic',
/** standard preview */
TYPE_PAGE: 'page',
/** disambiguation preview */
TYPE_DISAMBIGUATION: 'disambiguation'
};
export { previewTypes };
/**
* Preview Model
*
* @typedef {Object} PreviewModel
* @property {String} title
* @property {String} url The canonical URL of the page being previewed
@ -21,7 +30,7 @@ export var TYPE_PAGE = 'page'; // eslint-disable-line one-var
* @property {?Array} extract `undefined` if the extract isn't
* viable, e.g. if it's empty after having ellipsis and parentheticals
* removed; this can be used to present default or error states
* @property {String} type Either "extract" or "generic"
* @property {String} type One of TYPE_GENERIC, TYPE_PAGE, TYPE_DISAMBIGUATION
* @property {?Object} thumbnail
*
* @global
@ -35,6 +44,7 @@ export var TYPE_PAGE = 'page'; // eslint-disable-line one-var
* @param {String} languageCode
* @param {String} languageDirection Either "ltr" or "rtl"
* @param {?Array} extract
* @param {String} type
* @param {?Object} thumbnail
* @param {?Number} pageId
* @return {PreviewModel}
@ -45,10 +55,12 @@ export function createModel(
languageCode,
languageDirection,
extract,
type,
thumbnail,
pageId
) {
var processedExtract = processExtract( extract );
var processedExtract = processExtract( extract ),
previewType = getPreviewType( type, processedExtract );
return {
title: title,
@ -56,7 +68,7 @@ export function createModel(
languageCode: languageCode,
languageDirection: languageDirection,
extract: processedExtract,
type: processedExtract === undefined ? TYPE_GENERIC : TYPE_PAGE,
type: previewType,
thumbnail: thumbnail,
pageId: pageId
};
@ -90,3 +102,37 @@ function processExtract( extract ) {
}
return extract;
}
/**
* Determines the preview type based on whether or not:
* a. Is the preview empty.
* b. The preview type matches one of previewTypes.
* c. Assume standard page preview if both above are false
*
* @param {String} type
* @param {string} [processedExtract]
* @return {String} one of TYPE_GENERIC, TYPE_PAGE, TYPE_DISAMBIGUATION.
*/
function getPreviewType( type, processedExtract ) {
if ( processedExtract === undefined ) {
return previewTypes.TYPE_GENERIC;
}
switch ( type ) {
case previewTypes.TYPE_GENERIC:
case previewTypes.TYPE_DISAMBIGUATION:
case previewTypes.TYPE_PAGE:
return type;
default:
/**
* Assume type="page" if extract exists & not one of previewTypes.
* Note:
* - Restbase response includes "type" prop but other gateways don't.
* - event-logging Schema:Popups requires type="page" but restbase
* provides type="standard". Model must conform to event-logging schema.
*/
return previewTypes.TYPE_PAGE;
}
}

View file

@ -3,6 +3,7 @@
*/
import wait from '../wait';
import { previewTypes } from '../preview/model';
var mw = window.mediaWiki,
$ = jQuery,
@ -92,9 +93,8 @@ export function init() {
* @return {ext.popups.Preview}
*/
export function render( model ) {
// `undefined` is the default extract for null objects.
var preview = model.extract === undefined ?
createEmptyPreview( model ) : createPreview( model );
var preview = createPreviewWithType( model );
return {
@ -132,6 +132,24 @@ export function render( model ) {
}
};
}
/**
* Creates an instance of a Preview based on
* the type property of the PreviewModel
*
* @param {ext.popups.PreviewModel} model
* @return {ext.popups.Preview}
*/
export function createPreviewWithType( model ) {
switch ( model.type ) {
case previewTypes.TYPE_PAGE:
return createPagePreview( model );
case previewTypes.TYPE_DISAMBIGUATION:
return createDisambiguationPreview( model );
default:
return createEmptyPreview( model );
}
}
/**
* Creates an instance of the DTO backing a preview.
@ -139,7 +157,7 @@ export function render( model ) {
* @param {ext.popups.PreviewModel} model
* @return {ext.popups.Preview}
*/
export function createPreview( model ) {
export function createPagePreview( model ) {
var templateData,
thumbnail = createThumbnail( model.thumbnail ),
hasThumbnail = thumbnail !== null,
@ -185,10 +203,36 @@ export function createEmptyPreview( model ) {
templateData = $.extend( {}, model, {
extractMsg: mw.msg( 'popups-preview-no-preview' ),
readMsg: mw.msg( 'popups-preview-footer-read' )
linkMsg: mw.msg( 'popups-preview-footer-read' )
} );
$el = mw.template.get( 'ext.popups.main', 'preview-empty.mustache' )
$el = mw.template.get( 'ext.popups.main', 'preview-generic.mustache' )
.render( templateData );
return {
el: $el,
hasThumbnail: false,
isTall: false
};
}
/**
* Creates an instance of the disambiguation preview.
*
* @param {ext.popups.PreviewModel} model
* @return {ext.popups.Preview}
*/
export function createDisambiguationPreview( model ) {
var templateData,
$el;
templateData = $.extend( {}, model, {
showTitle: true,
extractMsg: mw.msg( 'popups-preview-disambiguation' ),
linkMsg: mw.msg( 'popups-preview-disambiguation-link' )
} );
$el = mw.template.get( 'ext.popups.main', 'preview-generic.mustache' )
.render( templateData );
return {

View file

@ -41,6 +41,7 @@ var DEFAULT_CONSTANTS = {
'en',
'ltr',
[ document.createTextNode( 'Richard Paul "Rick" Astley is an English singer, songwriter, musician, and radio personality. His 1987 song, "Never Gonna Give You Up" was a No. 1 hit single in 25 countries. By the time of his retirement in 1993, Astley had sold approximately 40 million records worldwide.\nAstley made a comeback in 2007, becoming an Internet phenomenon when his video "Never Gonna Give You Up" became integral to the meme known as "rickrolling". Astley was voted "Best Act Ever" by Internet users at the' ) ],
undefined,
{
height: 300,
source: 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Rick_Astley_-_Pepsifest_2009.jpg/200px-Rick_Astley_-_Pepsifest_2009.jpg',
@ -201,6 +202,7 @@ QUnit.test( 'MediaWiki API gateway handles missing pages ', function ( assert )
'en',
'ltr',
undefined,
undefined,
undefined
),
api = {

View file

@ -6,6 +6,7 @@ var DEFAULT_CONSTANTS = {
endpoint: '/api/rest_v1/page/summary/'
},
RESTBASE_RESPONSE = {
type: 'standard',
title: 'Barack Obama',
extract: 'Barack Hussein Obama II born August 4, 1961) ...',
thumbnail: {
@ -24,6 +25,7 @@ var DEFAULT_CONSTANTS = {
description: '44th President of the United States of America'
},
SVG_RESTBASE_RESPONSE = {
type: 'standard',
title: 'Barack Obama',
extract: 'Barack Hussein Obama II born August 4, 1961) ...',
thumbnail: {
@ -42,6 +44,7 @@ var DEFAULT_CONSTANTS = {
description: '44th President of the United States of America'
},
RESTBASE_RESPONSE_WITHOUT_IMAGE = {
type: 'standard',
title: 'Barack Obama',
extract: 'Barack Hussein Obama II born August 4, 1961) ...',
lang: 'en',
@ -59,6 +62,7 @@ var DEFAULT_CONSTANTS = {
// See https://phabricator.wikimedia.org/T158632#3071104 onward for additional
// context.
RESTBASE_RESPONSE_WITH_SMALL_IMAGE = {
type: 'standard',
title: 'PreviewsNonFreeImage/sandbox',
extract: 'Hello, I am the non-free image and parenthetical page (YOU CAN\'T SEE THIS). My preview should contain an image that is not free. My preview should contain a parenthetical you cannot see..',
thumbnail: {
@ -78,6 +82,7 @@ var DEFAULT_CONSTANTS = {
},
// As above, a no "px-" thumbnail is provided which is not customizable.
RESTBASE_RESPONSE_WITH_NO_PX_IMAGE = {
type: 'standard',
title: 'Barack Obama',
extract: 'Barack Hussein Obama II born August 4, 1961) ...',
thumbnail: {
@ -96,6 +101,7 @@ var DEFAULT_CONSTANTS = {
description: '44th President of the United States of America'
},
RESTBASE_RESPONSE_WITH_LANDSCAPE_IMAGE = {
type: 'standard',
title: 'Landscape',
extract: 'Landscape',
thumbnail: {
@ -113,17 +119,34 @@ var DEFAULT_CONSTANTS = {
dir: 'ltr',
timestamp: '2017-02-17T22:29:56Z'
},
RESTBASE_RESPONSE_DISAMBIGUATION = {
type: 'disambiguation',
title: 'Barack (disambiguation)',
extract: 'Barack Hussein Obama II born August 4, 1961) ...',
lang: 'en',
dir: 'ltr',
timestamp: '2017-02-17T22:29:56Z'
},
RESTBASE_RESPONSE_PREVIEW_MODEL = createModel(
'Barack Obama',
'url/Barack Obama', // Generated in the stub below
'en',
'ltr',
'!Barack Hussein Obama II born August 4, 1961) ...!',
'standard',
{
source: 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/President_Barack_Obama.jpg/409px-President_Barack_Obama.jpg',
width: 409,
height: 512
}
),
RESTBASE_RESPONSE_DISAMBIGUATION_MODEL = createModel(
'Barack (disambiguation)',
'url/Barack (disambiguation)',
'en',
'ltr',
'!Barack Hussein Obama II born August 4, 1961) ...!',
'disambiguation'
);
function provideParsedExtract( page ) {
@ -173,6 +196,16 @@ QUnit.test( 'RESTBase gateway is correctly converting the page data to a model',
);
} );
QUnit.test( 'RESTBase gateway is correctly converting the page data to a disambiguation model', function ( assert ) {
var gateway = createRESTBaseGateway();
assert.deepEqual(
gateway.convertPageToModel( RESTBASE_RESPONSE_DISAMBIGUATION,
512, provideParsedExtract ),
RESTBASE_RESPONSE_DISAMBIGUATION_MODEL
);
} );
QUnit.test( 'RESTBase gateway doesn\'t stretch thumbnails', function ( assert ) {
var model,
gateway = createRESTBaseGateway();

View file

@ -1,4 +1,4 @@
import { createModel, TYPE_PAGE, TYPE_GENERIC }
import { createModel, previewTypes }
from '../../../src/preview/model';
QUnit.module( 'ext.popups.preview#createModel' );
@ -11,6 +11,7 @@ QUnit.test( 'it should copy the basic properties', function ( assert ) {
'en',
'ltr',
'Foo bar baz.',
'standard',
thumbnail
);
@ -18,35 +19,50 @@ QUnit.test( 'it should copy the basic properties', function ( assert ) {
assert.strictEqual( model.url, 'https://en.wikipedia.org/wiki/Foo' );
assert.strictEqual( model.languageCode, 'en' );
assert.strictEqual( model.languageDirection, 'ltr' );
assert.strictEqual( model.type, previewTypes.TYPE_PAGE );
assert.strictEqual( model.thumbnail, thumbnail );
} );
QUnit.test( 'it computes the type property', function ( assert ) {
var model;
function createModelWithExtract( extract ) {
function createModelWith( { extract, type } ) {
return createModel(
'Foo',
'https://en.wikipedia.org/wiki/Foo',
'en',
'ltr',
extract
extract,
type
);
}
model = createModelWithExtract( 'Foo' );
assert.strictEqual(
model.type,
TYPE_PAGE,
'A non-generic ("page") preview has an extract.'
createModelWith( { extract: 'Foo', type: 'standard' } ).type,
previewTypes.TYPE_PAGE,
'A non-generic ("page") preview has an extract and type "standard" property.'
);
model = createModelWithExtract( '' );
assert.strictEqual(
createModelWith( { extract: 'Foo', type: undefined } ).type,
previewTypes.TYPE_PAGE,
'A non-generic ("page") preview has an extract with an undefined "type" property.'
);
assert.strictEqual(
model.type,
TYPE_GENERIC,
'A generic preview has an undefined extract.'
createModelWith( { extract: undefined, type: undefined } ).type,
previewTypes.TYPE_GENERIC,
'A generic ("empty") preview has an undefined extract and an undefined "type" property.'
);
assert.strictEqual(
createModelWith( { extract: undefined, type: 'standard' } ).type,
previewTypes.TYPE_GENERIC,
'A generic ("empty") preview has an undefined extract regardless of "type".'
);
assert.strictEqual(
createModelWith( { extract: 'Foo', type: 'disambiguation' } ).type,
previewTypes.TYPE_DISAMBIGUATION,
'A disambiguation preview has an extract and type ("disambiguation") property.'
);
} );

View file

@ -1,9 +1,11 @@
import * as renderer from '../../../src/ui/renderer';
import { createNullModel } from '../../../src/preview/model';
import { createNullModel, previewTypes } from '../../../src/preview/model';
var $ = jQuery,
MSG_NO_PREVIEW = 'There was an issue displaying this preview',
MSG_GO_TO_PAGE = 'Go to this page';
MSG_GO_TO_PAGE = 'Go to this page',
MSG_DISAMBIGUATION = 'This title relates to more than one page',
MSG_DISAMBIGUATION_LINK = 'View similar pages';
/**
* A utility function that creates a bare bones preview
@ -13,7 +15,7 @@ var $ = jQuery,
* @param {ext.popups.Thumbnail} [thumbnail]
* @return {ext.popups.Preview}
*/
function createPreview( isTall, hasThumbnail, thumbnail ) {
function createPagePreview( isTall, hasThumbnail, thumbnail ) {
return {
el: $( '<div>' )
.append( hasThumbnail ? $( '<image>' ) : '' )
@ -56,6 +58,10 @@ QUnit.module( 'ext.popups#renderer', {
return MSG_NO_PREVIEW;
case 'popups-preview-footer-read':
return MSG_GO_TO_PAGE;
case 'popups-preview-disambiguation':
return MSG_DISAMBIGUATION;
case 'popups-preview-disambiguation-link':
return MSG_DISAMBIGUATION_LINK;
}
};
@ -95,13 +101,14 @@ QUnit.test( 'createPokeyMasks', function ( assert ) {
} );
} );
QUnit.test( 'createPreview', function ( assert ) {
QUnit.test( 'createPagePreview', function ( assert ) {
var model = {
title: 'Test',
url: 'https://en.wikipedia.org/wiki/Test',
languageCode: 'en',
languageDirection: 'ltr',
extract: 'This is a test page.',
type: previewTypes.TYPE_PAGE,
thumbnail: {
source: 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/President_Barack_Obama.jpg/409px-President_Barack_Obama.jpg',
width: 409,
@ -121,7 +128,7 @@ QUnit.test( 'createPreview', function ( assert ) {
}
};
preview = renderer.createPreview( model );
preview = renderer.createPreviewWithType( model );
assert.equal( preview.hasThumbnail, true, 'Preview has thumbnail.' );
assert.deepEqual(
@ -148,13 +155,14 @@ QUnit.test( 'createEmptyPreview(model)', function ( assert ) {
languageCode: 'en',
languageDirection: 'ltr',
extract: 'This is a test page.',
type: previewTypes.TYPE_GENERIC,
thumbnail: {
source: 'https://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/President_Barack_Obama.jpg/409px-President_Barack_Obama.jpg',
width: 409,
height: 512
}
},
emptyPreview = renderer.createEmptyPreview( model );
emptyPreview = renderer.createPreviewWithType( model );
assert.equal(
emptyPreview.hasThumbnail,
@ -174,7 +182,7 @@ QUnit.test( 'createEmptyPreview(model)', function ( assert ) {
this.renderSpy.getCall( 0 ).args[ 0 ],
$.extend( {}, model, {
extractMsg: MSG_NO_PREVIEW,
readMsg: MSG_GO_TO_PAGE
linkMsg: MSG_GO_TO_PAGE
} ),
'Template is called with the correct data.'
);
@ -182,7 +190,7 @@ QUnit.test( 'createEmptyPreview(model)', function ( assert ) {
QUnit.test( 'createEmptyPreview(null model)', function ( assert ) {
var model = createNullModel( 'Test', '/wiki/Test' ),
emptyPreview = renderer.createEmptyPreview( model );
emptyPreview = renderer.createPreviewWithType( model );
assert.equal(
emptyPreview.hasThumbnail,
@ -202,14 +210,50 @@ QUnit.test( 'createEmptyPreview(null model)', function ( assert ) {
this.renderSpy.getCall( 0 ).args[ 0 ],
$.extend( {}, model, {
extractMsg: MSG_NO_PREVIEW,
readMsg: MSG_GO_TO_PAGE
linkMsg: MSG_GO_TO_PAGE
} ),
'Template is called with the correct data.'
);
} );
QUnit.test( 'createDisambiguationPreview(model)', function ( assert ) {
var model = {
title: 'Barack (disambiguation)',
url: 'url/Barack (disambiguation)',
languageCode: 'en',
languageDirection: 'ltr',
extract: 'Barack Hussein Obama II born August 4, 1961) ...',
type: previewTypes.TYPE_DISAMBIGUATION
},
preview = renderer.createPreviewWithType( model );
assert.equal(
preview.hasThumbnail,
false,
'Disambiguation preview doesn\'t have a thumbnail.'
);
assert.equal(
preview.isTall,
false,
'Disambiguation preview is never tall.'
);
assert.ok( this.renderSpy.calledOnce, 'Template has been rendered.' );
assert.deepEqual(
this.renderSpy.getCall( 0 ).args[ 0 ],
$.extend( {}, model, {
showTitle: true,
extractMsg: MSG_DISAMBIGUATION,
linkMsg: MSG_DISAMBIGUATION_LINK
} ),
'Template is called with the correct data.'
);
} );
QUnit.test( 'bindBehavior - preview dwell', function ( assert ) {
var preview = createPreview(),
var preview = createPagePreview(),
behavior = createBehavior( this.sandbox );
renderer.bindBehavior( preview, behavior );
@ -223,7 +267,7 @@ QUnit.test( 'bindBehavior - preview dwell', function ( assert ) {
} );
QUnit.test( 'bindBehavior - preview abandon', function ( assert ) {
var preview = createPreview(),
var preview = createPagePreview(),
behavior = createBehavior( this.sandbox );
renderer.bindBehavior( preview, behavior );
@ -236,7 +280,7 @@ QUnit.test( 'bindBehavior - preview abandon', function ( assert ) {
} );
QUnit.test( 'bindBehavior - preview click', function ( assert ) {
var preview = createPreview(),
var preview = createPagePreview(),
behavior = createBehavior( this.sandbox );
renderer.bindBehavior( preview, behavior );
@ -251,7 +295,7 @@ QUnit.test( 'bindBehavior - preview click', function ( assert ) {
} );
QUnit.test( 'bindBehavior - settings link click', function ( assert ) {
var preview = createPreview(),
var preview = createPagePreview(),
behavior = createBehavior( this.sandbox );
renderer.bindBehavior( preview, behavior );
@ -266,7 +310,7 @@ QUnit.test( 'bindBehavior - settings link click', function ( assert ) {
} );
QUnit.test( 'bindBehavior - settings link URL', function ( assert ) {
var preview = createPreview(),
var preview = createPagePreview(),
behavior = createBehavior( this.sandbox );
renderer.bindBehavior( preview, behavior );
@ -279,7 +323,7 @@ QUnit.test( 'bindBehavior - settings link URL', function ( assert ) {
} );
QUnit.test( 'show', function ( assert ) {
var preview = createPreview(),
var preview = createPagePreview(),
event = {
pageX: 252,
pageY: 1146,
@ -1028,7 +1072,7 @@ QUnit.test( '#getClasses when a tall thumbnail is available', function ( assert
} );
QUnit.test( '#layoutPreview - no thumbnail', function ( assert ) {
var preview = createPreview( false, false, null ),
var preview = createPagePreview( false, false, null ),
layout = {
flippedX: false,
flippedY: false,
@ -1058,7 +1102,7 @@ QUnit.test( '#layoutPreview - no thumbnail', function ( assert ) {
} );
QUnit.test( '#layoutPreview - tall preview, flipped X, has thumbnail', function ( assert ) {
var preview = createPreview( true, true, { height: 200 } ),
var preview = createPagePreview( true, true, { height: 200 } ),
layout = {
flippedX: true,
flippedY: false,
@ -1097,7 +1141,7 @@ QUnit.test( '#layoutPreview - tall preview, flipped X, has thumbnail', function
} );
QUnit.test( '#layoutPreview - portrait preview, flipped X, has thumbnail, small height', function ( assert ) {
var preview = createPreview( false, true, { height: 199 } ),
var preview = createPagePreview( false, true, { height: 199 } ),
layout = {
flippedX: true,
flippedY: false,
@ -1137,7 +1181,7 @@ QUnit.test( '#layoutPreview - portrait preview, flipped X, has thumbnail, small
} );
QUnit.test( '#layoutPreview - portrait preview, flipped X, has thumbnail, big height', function ( assert ) {
var preview = createPreview( false, true, { height: 201 } ),
var preview = createPagePreview( false, true, { height: 201 } ),
layout = {
flippedX: true,
flippedY: false,
@ -1177,7 +1221,7 @@ QUnit.test( '#layoutPreview - portrait preview, flipped X, has thumbnail, big he
} );
QUnit.test( '#layoutPreview - tall preview, has thumbnail, flipped Y', function ( assert ) {
var preview = createPreview( true, true, { height: 200 } ),
var preview = createPagePreview( true, true, { height: 200 } ),
layout = {
flippedX: false,
flippedY: true,
@ -1215,7 +1259,7 @@ QUnit.test( '#layoutPreview - tall preview, has thumbnail, flipped Y', function
} );
QUnit.test( '#layoutPreview - tall preview, has thumbnail, flipped X and Y', function ( assert ) {
var preview = createPreview( true, true, { height: 200 } ),
var preview = createPagePreview( true, true, { height: 200 } ),
layout = {
flippedX: true,
flippedY: true,
@ -1254,7 +1298,7 @@ QUnit.test( '#layoutPreview - tall preview, has thumbnail, flipped X and Y', fun
} );
QUnit.test( '#layoutPreview - portrait preview, has thumbnail, flipped X and Y', function ( assert ) {
var preview = createPreview( false, true, { height: 200 } ),
var preview = createPagePreview( false, true, { height: 200 } ),
layout = {
flippedX: true,
flippedY: true,