{"version":3,"sources":["webpack://mfModules.[name]/./src/mobile.startup/LanguageInfo.js","webpack://mfModules.[name]/./src/mobile.startup/languageOverlay/getDeviceLanguage.js","webpack://mfModules.[name]/./src/mobile.startup/languageOverlay/languageInfoOverlay.js","webpack://mfModules.[name]/./src/mobile.startup/languageOverlay/languageOverlay.js","webpack://mfModules.[name]/./src/mobile.startup/loadingOverlay.js","webpack://mfModules.[name]/./src/mobile.startup/mediaViewer/overlay.js","webpack://mfModules.[name]/./src/mobile.startup/mobile.startup.js","webpack://mfModules.[name]/./src/mobile.startup/promisedView.js","webpack://mfModules.[name]/./src/mobile.startup/references/ReferencesGateway.js","webpack://mfModules.[name]/./src/mobile.startup/references/ReferencesHtmlScraperGateway.js","webpack://mfModules.[name]/./src/mobile.startup/references/references.js","webpack://mfModules.[name]/./src/mobile.startup/search/SearchGateway.js","webpack://mfModules.[name]/./src/mobile.startup/search/SearchHeaderView.js","webpack://mfModules.[name]/./src/mobile.startup/search/SearchOverlay.js","webpack://mfModules.[name]/./src/mobile.startup/search/SearchResultsView.js","webpack://mfModules.[name]/./src/mobile.startup/search/searchHeader.js","webpack://mfModules.[name]/./src/mobile.startup/time.js"],"names":["util","require","actionParams","LanguageInfo","api","this","prototype","getLanguages","get","meta","liprop","then","resp","filteredLanguages","Object","keys","query","languageinfo","forEach","key","language","code","toLowerCase","bcp47","autonym","push","Deferred","reject","languages","map","data","url","lang","langname","name","title","module","exports","navigator","userLanguage","browserLanguage","systemLanguage","undefined","m","getDeviceLanguage","Overlay","promisedView","loadLanguageInfoSearcher","languageInfo","showSuggestedLanguages","mw","loader","using","variants","deviceLanguage","languageInfoOverlay","make","heading","msg","className","test","loadLanguageSearcher","pageGateway","getPageLanguages","config","onOpen","searcher","hook","fire","onBannerClick","languageOverlay","icons","overlay","noHeader","spinner","$el","appendTo","find","header","options","headers","cancel","Promise","all","ImageCarousel","moduleLoader","mfExtend","time","View","PageGateway","Browser","Button","Icon","ReferencesGateway","ReferencesHtmlScraperGateway","Page","currentPage","PageHTMLParser","currentPageHTMLParser","Anchor","Skin","OverlayManager","loadingOverlay","Drawer","CtaDrawer","showOnPageReload","toast","Watchstar","eventBusSingleton","Toggler","toc","TableOfContents","parseHTML","references","search","SearchOverlay","SearchGateway","lazyImages","lazyImageLoader","mediaViewer","amcOutreach","Section","mobileFrontend","define","promise","view","append","newView","replaceWith","errorView","getReference","ERROR_NOT_EXIST","ERROR_OTHER","apply","arguments","EXTERNAL_LINK_CLASS","getReferenceFromContainer","id","$container","$ol","$parent","result","escapeSelector","length","closest","hasClass","parent","addClass","resolve","text","getReferenceHtml","parentText","$reference","first","html","hash","page","pageHTMLParser","percentDecodeFragment","slice","makeOnNestedReferenceClickHandler","onNestedReferenceClick","ev","target","currentTarget","querySelector","getAttribute","textContent","referenceDrawer","props","errorIcon","error","isSmall","extend","showCollapseIcon","events","preventDefault","children","type","additionalClassNames","showReference","refNumber","gateway","onShowNestedReference","reference","drawer","href","nestedDrawer","log","warn","document","body","appendChild","hide","show","err","pageJSONParser","extendSearchParams","searchCache","generator","searchNamespace","getApiData","prefix","redirects","pilimit","pithumbsize","tiny","_createSearchRegEx","str","replace","RegExp","_highlightSearchTerm","label","term","_getPage","pageInfo","parse","displayTitle","displaytext","index","_processData","self","results","pages","sort","a","b","xhr","request","isCached","jqXHR","searchId","getResponseHeader","abort","Boolean","SearchHeaderView","autocapitalize","value","onInput","clearIcon","template","tagName","click","val","trigger","bind","attr","searchHeader","SearchResultsView","WatchstarPageList","params","placeholderMsg","action","performSearch","defaultSearchPage","headerChrome","isBorderBox","stopPropagation","call","gatewayClass","router","currentSearchId","onClickSearchContent","$form","parentNode","setTimeout","onClickOverlayContent","hideKeyboardOnScroll","$input","onClickResult","$link","back","clickUri","Uri","location","searchToken","navigateTo","path","toString","useReplaceState","window","postRender","timer","searchResults","searchContentLabel","noResultsMsg","searchContentNoResultsMsg","message","clearSearch","$spinner","clearTimeout","$searchContent","$resultContainer","addEventListener","activeElement","on","searchData","delay","showKeyboard","len","setSelectionRange","lastQuery","_pendingQuery","toggleClass","filter","funnel","el","$results","resetSearch","feedback","prompt","feedbackLink","prepend","formHeader","units","limits","timeAgo","timestampDelta","i","Math","round","unit","getTimeAgoDelta","timestamp","Date","now","isNow","delta","getLastModifiedMessage","ts","username","gender","historyUrl","lastEditedElement","usernameElement","linkAll","args","seconds","minutes","hours","days","months","years","convertNumber","getUrl","getRegistrationMessage","parseInt","isRecent","indexOf"],"mappings":"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","file":"mobile.startup.js","sourcesContent":["var util = require( './util.js' ),\n\tactionParams = require( './actionParams' );\n\n/**\n * API for providing language data.\n *\n * @class LanguageInfo\n * @param {mw.Api} api\n */\nfunction LanguageInfo( api ) {\n\tthis.api = api;\n}\n\nLanguageInfo.prototype = {\n\n\t/**\n\t * Get languageinfo API data from the local wiki, and transform it into a\n\t * format usable by LanguageSearcher.\n\t *\n\t * @memberof LanguageInfo\n\t * @instance\n\t * @returns {jQuery.Deferred}\n\t */\n\tgetLanguages: function () {\n\t\treturn this.api.get( actionParams( {\n\t\t\tmeta: 'languageinfo',\n\t\t\tliprop: 'code|autonym|name|bcp47'\n\t\t} ) ).then( function ( resp ) {\n\t\t\tconst filteredLanguages = [];\n\t\t\t// Filter out legacy languages and require an autonym.\n\t\t\t// If the bcp47 (https://w.wiki/Y7A) does not match the language\n\t\t\t// code, that is in an indication that the language code is outdated\n\t\t\t// and should not be used.\n\t\t\tObject.keys( resp.query.languageinfo ).forEach( function ( key ) {\n\t\t\t\tconst language = resp.query.languageinfo[key];\n\t\t\t\tif ( ( language.code.toLowerCase() === language.bcp47.toLowerCase() ) &&\n\t\t\t\t\tlanguage.autonym ) {\n\t\t\t\t\tfilteredLanguages.push( language );\n\t\t\t\t}\n\t\t\t} );\n\t\t\treturn filteredLanguages;\n\t\t}, function () {\n\t\t\treturn util.Deferred().reject();\n\t\t} ).then( function ( filteredLanguages ) {\n\t\t\treturn {\n\t\t\t\tlanguages: filteredLanguages.map( function ( data ) {\n\t\t\t\t\tdata.url = '#';\n\t\t\t\t\tdata.lang = data.code;\n\t\t\t\t\tdata.langname = data.name;\n\t\t\t\t\t// FIXME: This isn't a \"title\" in the sense of a MediaWiki\n\t\t\t\t\t// Title, and it is rendered as a subheader in the list\n\t\t\t\t\t// item, so a different name would be wiser, both here and\n\t\t\t\t\t// in LanguageSearcher's template. Also it would arguably\n\t\t\t\t\t// be more intuitive for the language name (localized) to\n\t\t\t\t\t// appear as the main emphasized element of each language\n\t\t\t\t\t// list element; but instead the autonym has that role.\n\t\t\t\t\t// A more thorough refactoring of LanguageSearcher to allow\n\t\t\t\t\t// for generic header/subheader elements is left for a\n\t\t\t\t\t// follow-up.\n\t\t\t\t\tdata.title = data.name;\n\t\t\t\t\treturn data;\n\t\t\t\t} )\n\t\t\t};\n\t\t}, function () {\n\t\t\treturn util.Deferred().reject();\n\t\t} );\n\t}\n};\n\nmodule.exports = LanguageInfo;\n","/**\n * Return the language code of the device in lowercase\n *\n * @ignore\n * @param {window.navigator} navigator\n * @return {string|undefined}\n */\nfunction getDeviceLanguage( navigator ) {\n\tconst lang = navigator.languages ?\n\t\tnavigator.languages[ 0 ] :\n\t\tnavigator.language || navigator.userLanguage ||\n\t\t\t\tnavigator.browserLanguage || navigator.systemLanguage;\n\n\treturn lang ? lang.toLowerCase() : undefined;\n}\n\nmodule.exports = getDeviceLanguage;\n","const\n\tm = require( '../moduleLoaderSingleton' ),\n\tgetDeviceLanguage = require( './getDeviceLanguage' ),\n\tOverlay = require( '../Overlay' ),\n\tpromisedView = require( '../promisedView' );\n\n/**\n * @ignore\n * @param {LanguageInfo} languageInfo\n * @param {boolean} showSuggestedLanguages If the suggested languages section\n * should be rendered.\n * @return {jQuery.Promise} Resolves to LanguageSearcher\n */\nfunction loadLanguageInfoSearcher( languageInfo, showSuggestedLanguages ) {\n\treturn mw.loader.using( 'mobile.languages.structured' ).then( function () {\n\t\treturn languageInfo.getLanguages();\n\t} ).then( function ( data ) {\n\t\tconst LanguageSearcher = m.require( 'mobile.languages.structured/LanguageSearcher' );\n\t\treturn new LanguageSearcher( {\n\t\t\tlanguages: data.languages,\n\t\t\tvariants: data.variants,\n\t\t\tshowSuggestedLanguages: showSuggestedLanguages,\n\t\t\tdeviceLanguage: getDeviceLanguage( navigator )\n\t\t} );\n\n\t} );\n}\n\n/**\n * Factory function that returns a language info featured instance of an Overlay\n *\n * @param {LanguageInfo} languageInfo\n * @param {boolean} showSuggestedLanguages If the suggested languages section\n * should be rendered.\n * @return {Overlay}\n */\nfunction languageInfoOverlay( languageInfo, showSuggestedLanguages ) {\n\treturn Overlay.make(\n\t\t{\n\t\t\theading: mw.msg( 'mobile-frontend-language-heading' ),\n\t\t\tclassName: 'overlay language-info-overlay'\n\t\t}, promisedView( loadLanguageInfoSearcher( languageInfo, showSuggestedLanguages ) )\n\t);\n}\n\n// To make knowing when async logic has resolved easier in tests\nlanguageInfoOverlay.test = {\n\tloadLanguageInfoSearcher: loadLanguageInfoSearcher\n};\n\nmodule.exports = languageInfoOverlay;\n","const\n\tm = require( '../moduleLoaderSingleton' ),\n\tgetDeviceLanguage = require( './getDeviceLanguage' ),\n\tOverlay = require( '../Overlay' ),\n\tpromisedView = require( '../promisedView' );\n\n/**\n * @ignore\n * @param {PageGateway} pageGateway\n * getPageLanguages API call.\n * @return {jQuery.Promise} Resolves to LanguageSearcher\n */\nfunction loadLanguageSearcher( pageGateway ) {\n\treturn mw.loader.using( 'mobile.languages.structured' ).then( function () {\n\t\treturn pageGateway.getPageLanguages( mw.config.get( 'wgPageName' ), mw.config.get( 'wgUserLanguage' ) );\n\t} ).then( function ( data ) {\n\t\tconst LanguageSearcher = m.require( 'mobile.languages.structured/LanguageSearcher' );\n\n\t\treturn new LanguageSearcher( {\n\t\t\tlanguages: data.languages,\n\t\t\tvariants: data.variants,\n\t\t\tshowSuggestedLanguages: true,\n\t\t\tdeviceLanguage: getDeviceLanguage( navigator ),\n\t\t\tonOpen: ( searcher ) => {\n\t\t\t\tmw.hook( 'mobileFrontend.languageSearcher.onOpen' ).fire( searcher );\n\t\t\t},\n\t\t\tonBannerClick: () => {\n\t\t\t\tmw.hook( 'mobileFrontend.languageSearcher.onBannerClick' ).fire();\n\t\t\t}\n\t\t} );\n\t} );\n}\n\n/**\n * Factory function that returns a language featured instance of an Overlay\n *\n * @param {PageGateway} pageGateway\n * @return {Overlay}\n */\nfunction languageOverlay( pageGateway ) {\n\treturn Overlay.make(\n\t\t{\n\t\t\theading: mw.msg( 'mobile-frontend-language-heading' ),\n\t\t\tclassName: 'overlay language-overlay'\n\t\t}, promisedView( loadLanguageSearcher( pageGateway ) )\n\t);\n}\n\n// To make knowing when async logic has resolved easier in tests\nlanguageOverlay.test = {\n\tloadLanguageSearcher: loadLanguageSearcher\n};\n\nmodule.exports = languageOverlay;\n","var\n\ticons = require( './icons' ),\n\tOverlay = require( './Overlay' );\n\n/**\n * Overlay that initially shows loading animation until\n * caller hides it with .hide()\n *\n * @return {Overlay}\n */\nfunction loadingOverlay() {\n\tvar overlay = new Overlay( {\n\t\tclassName: 'overlay overlay-loading',\n\t\tnoHeader: true\n\t} );\n\ticons.spinner().$el.appendTo( overlay.$el.find( '.overlay-content' ) );\n\treturn overlay;\n}\n\nmodule.exports = loadingOverlay;\n","var m = require( '../moduleLoaderSingleton' ),\n\tpromisedView = require( '../promisedView' ),\n\tutil = require( '../util' ),\n\theader = require( '../headers' ).header,\n\ticons = require( '../icons' ),\n\tOverlay = require( '../Overlay' );\n\n/**\n * Produce an overlay for mediaViewer\n *\n * @param {Object} options\n * @return {Overlay}\n */\nfunction mediaViewerOverlay( options ) {\n\tvar overlay = Overlay.make(\n\t\t{\n\t\t\theaders: [\n\t\t\t\theader( '', [], icons.cancel( 'gray' ) )\n\t\t\t],\n\t\t\tclassName: 'overlay media-viewer'\n\t\t},\n\t\tpromisedView(\n\t\t\tutil.Promise.all( [\n\t\t\t\tmw.loader.using( 'mobile.mediaViewer' )\n\t\t\t] ).then( function () {\n\t\t\t\tvar ImageCarousel = m.require( 'mobile.mediaViewer' ).ImageCarousel;\n\t\t\t\treturn new ImageCarousel( options );\n\t\t\t} )\n\t\t)\n\t);\n\n\treturn overlay;\n}\n\nmodule.exports = mediaViewerOverlay;\n","var\n\tmoduleLoader = require( './moduleLoaderSingleton' ),\n\tutil = require( './util' );\n\n// Expose the entry chunk through libraryTarget and library. This allows\n// arbitrary file access via ResourceLoader like\n// `mfModules['mobile.startup'].moduleLoader.require('mobile.startup/LoadingOverlay')`.\nmodule.exports = {\n\tmoduleLoader: moduleLoader,\n\tmfExtend: require( './mfExtend' ),\n\ttime: require( './time' ),\n\tutil,\n\theaders: require( './headers' ),\n\tView: require( './View' ),\n\tPageGateway: require( './PageGateway' ),\n\tLanguageInfo: require( './LanguageInfo' ),\n\tBrowser: require( './Browser' ),\n\tButton: require( './Button' ),\n\tIcon: require( './Icon' ),\n\tReferencesGateway: require( './references/ReferencesGateway' ),\n\tReferencesHtmlScraperGateway: require( './references/ReferencesHtmlScraperGateway' ),\n\ticons: require( './icons' ),\n\tPage: require( './Page' ),\n\tcurrentPage: require( './currentPage' ),\n\tPageHTMLParser: require( './PageHTMLParser' ),\n\tcurrentPageHTMLParser: require( './currentPageHTMLParser' ),\n\tAnchor: require( './Anchor' ),\n\tSkin: require( './Skin' ),\n\tOverlayManager: require( './OverlayManager' ),\n\tOverlay: require( './Overlay' ),\n\tloadingOverlay: require( './loadingOverlay' ),\n\tDrawer: require( './Drawer' ),\n\tCtaDrawer: require( './CtaDrawer' ),\n\tshowOnPageReload: require( './showOnPageReload' ),\n\t// For Minerva compatibility (access deprecated)\n\ttoast: require( './showOnPageReload' ),\n\tWatchstar: require( './watchstar/watchstar' ),\n\teventBusSingleton: require( './eventBusSingleton' ),\n\tpromisedView: require( './promisedView' ),\n\tToggler: require( './Toggler' ),\n\ttoc: {\n\t\t// In case any old version of Minerva is cached.\n\t\tTableOfContents: () => {\n\t\t\treturn {\n\t\t\t\t// in the unlikely event old Minerva code got loaded with new MF.\n\t\t\t\t$el: util.parseHTML( '<div>' )\n\t\t\t};\n\t\t}\n\t},\n\treferences: require( './references/references' ),\n\tsearch: {\n\t\tSearchOverlay: require( './search/SearchOverlay' ),\n\t\tSearchGateway: require( './search/SearchGateway' )\n\t},\n\tlazyImages: {\n\t\tlazyImageLoader: require( './lazyImages/lazyImageLoader' )\n\t},\n\tlanguageOverlay: require( './languageOverlay/languageOverlay' ),\n\tlanguageInfoOverlay: require( './languageOverlay/languageInfoOverlay' ),\n\tmediaViewer: {\n\t\toverlay: require( './mediaViewer/overlay' )\n\t},\n\tamcOutreach: require( './amcOutreach/amcOutreach' ),\n\tSection: require( './Section' )\n};\n\nmw.mobileFrontend = moduleLoader;\n\n// Setup a single export for new modules to fold all of the above lines into.\n// One export to rule them all!\nmoduleLoader.define( 'mobile.startup', module.exports );\n","var\n\ticons = require( './icons' ),\n\tView = require( './View' );\n\n/**\n * It's a view that spins until the promise resolves!\n * If the promise successfully resolves, the newView will be shown. if the\n * promise rejects and rejects to a view, the errorView will be shown.\n *\n * @param {jQuery.Promise} promise\n * @return {View}\n */\nfunction promisedView( promise ) {\n\tvar view = new View( {\n\t\tclassName: 'promised-view'\n\t} );\n\tview.$el.append( icons.spinner().$el );\n\tpromise.then( function ( newView ) {\n\t\tview.$el.replaceWith( newView.$el );\n\t\t// update the internal reference.\n\t\tview.$el = newView.$el;\n\t}, function ( errorView ) {\n\t\tif ( !errorView || !errorView.$el ) {\n\t\t\t// return early to keep backwards compatibility with clients of\n\t\t\t// promisedView that do not reject to an error view\n\t\t\treturn;\n\t\t}\n\n\t\tview.$el.replaceWith( errorView.$el );\n\t\t// update the internal reference.\n\t\tview.$el = errorView.$el;\n\t} );\n\n\treturn view;\n}\n\nmodule.exports = promisedView;\n","/**\n * Abstract base class\n * Gateway for retrieving references\n *\n * @class ReferencesGateway\n * @abstract\n *\n * @param {mw.Api} api\n */\nfunction ReferencesGateway( api ) {\n\tthis.api = api;\n}\n\n/**\n * Return the matched reference via API or DOM query\n *\n * @memberof ReferencesGateway\n * @instance\n * @param {string} id CSS selector\n * @param {Page} page to find reference for\n * @param {PageHTMLParser} pageHTMLParser\n * @return {jQuery.Promise} resolves with an Object representing reference\n *  with a `text` property\n *  The promise should be rejected with ReferenceGateway.ERROR_NOT_EXIST:\n *  if the reference is not found.\n *  If for some reason locating the reference fails return ReferenceGateway.ERROR_OTHER.\n */\nReferencesGateway.prototype.getReference = null;\n\n/**\n * @memberof ReferencesGateway\n * @property ERROR_NOT_EXIST error code to be returned by getReference\n *  when a reference does not exist.\n */\nReferencesGateway.ERROR_NOT_EXIST = 'NOT_EXIST_ERROR';\n/**\n * @memberof ReferencesGateway\n * @property ERROR_OTHER error code to be returned by getReference\n *  under any other circumstance not covered\n *  by ERROR_NOT_EXIST. It should be used if it is unclear whether a reference exists or not.\n */\nReferencesGateway.ERROR_OTHER = 'OTHER_ERROR';\n\nmodule.exports = ReferencesGateway;\n","var ReferencesGateway = require( './ReferencesGateway' ),\n\tmfExtend = require( './../mfExtend' ),\n\tutil = require( './../util' );\n\n/**\n * Gateway for retrieving references via the content of the Page\n *\n * @class ReferencesHtmlScraperGateway\n * @extends ReferencesGateway\n * @inheritdoc\n */\nfunction ReferencesHtmlScraperGateway() {\n\tReferencesGateway.apply( this, arguments );\n}\n\nmfExtend( ReferencesHtmlScraperGateway, ReferencesGateway, {\n\t/**\n\t * @memberof ReferencesHtmlScraperGateway\n\t * @property EXTERNAL_LINK_CLASS a CSS class to place on external links\n\t * in addition to the default 'external' class.\n\t */\n\tEXTERNAL_LINK_CLASS: 'external--reference',\n\t/**\n\t * @memberof ReferencesHtmlScraperGateway\n\t * @instance\n\t * @param {string} id ID of a DOM element in the page.\n\t * @param {jQuery.Object} $container to scan for an element\n\t * @return {jQuery.Promise} that can be used by getReference\n\t */\n\tgetReferenceFromContainer: function ( id, $container ) {\n\t\tvar $el, $ol, $parent,\n\t\t\tresult = util.Deferred();\n\n\t\t$el = $container.find( '#' + util.escapeSelector( id ) );\n\t\tif ( $el.length ) {\n\t\t\t// This finds either the inner <ol class=\"mw-extended-references\">, or the outer\n\t\t\t// <ol class=\"references\">\n\t\t\t$ol = $el.closest( 'ol' );\n\t\t\tif ( $ol.hasClass( 'mw-extended-references' ) ) {\n\t\t\t\t$parent = $ol.parent();\n\t\t\t}\n\t\t\t// The following classes are used here:\n\t\t\t// * external--reference\n\t\t\t// * other values of EXTERNAL_LINK_CLASS in sub-classes\n\t\t\t( $parent || $el ).find( '.external' ).addClass( this.EXTERNAL_LINK_CLASS );\n\t\t\tresult.resolve( {\n\t\t\t\ttext: this.getReferenceHtml( $el ),\n\t\t\t\tparentText: this.getReferenceHtml( $parent )\n\t\t\t} );\n\t\t} else {\n\t\t\tresult.reject( ReferencesGateway.ERROR_NOT_EXIST );\n\t\t}\n\t\treturn result.promise();\n\t},\n\t/**\n\t * @param {jQuery.Object|undefined} $reference\n\t * @returns {string}\n\t */\n\tgetReferenceHtml: function ( $reference ) {\n\t\treturn $reference ?\n\t\t\t$reference.find( '.mw-reference-text, .reference-text' ).first().html() :\n\t\t\t'';\n\t},\n\t/**\n\t * @inheritdoc\n\t * @memberof ReferencesHtmlScraperGateway\n\t * @instance\n\t * @param {string} hash Hash fragment with leading '#'\n\t * @param {Page} page (unused)\n\t * @param {PageHTMLParser} pageHTMLParser\n\t */\n\tgetReference: function ( hash, page, pageHTMLParser ) {\n\t\tvar id = mw.util.percentDecodeFragment( hash.slice( 1 ) );\n\t\t// If an id is not found it's possible the id passed needs decoding (per T188547).\n\t\treturn this.getReferenceFromContainer( id, pageHTMLParser.$el.find( 'ol.references' ) );\n\t}\n} );\n\nmodule.exports = ReferencesHtmlScraperGateway;\n","var references,\n\tDrawer = require( '../Drawer' ),\n\tutil = require( '../util' ),\n\ticons = require( '../icons' ),\n\tReferencesGateway = require( './ReferencesGateway' ),\n\tIcon = require( '../Icon' );\n\n/**\n * Create a callback for clicking references\n *\n * @param {Function} onNestedReferenceClick\n * @return {Function}\n */\nfunction makeOnNestedReferenceClickHandler( onNestedReferenceClick ) {\n\treturn ( ev ) => {\n\t\tconst target = ev.currentTarget.querySelector( 'a' );\n\t\tif ( target ) {\n\t\t\tonNestedReferenceClick(\n\t\t\t\ttarget.getAttribute( 'href' ),\n\t\t\t\ttarget.textContent\n\t\t\t);\n\t\t\t// Don't hide the already shown drawer via propagation\n\t\t\treturn false;\n\t\t}\n\t};\n}\n\n/**\n * Drawer for references\n *\n * @uses Icon\n * @param {Object} props\n * @param {boolean} [props.error] whether an error has occurred\n * @param {string} props.title of reference e.g [1]\n * @param {string} props.text is the HTML of the reference\n * @param {string} [props.parentText] is the HTML of the parent reference if there is one\n * @param {Function} [props.onNestedReferenceClick] callback for when a reference\n *  inside the reference is clicked.\n * @return {Drawer}\n */\nfunction referenceDrawer( props ) {\n\tconst errorIcon = props.error ? new Icon( {\n\t\tname: 'error',\n\t\tisSmall: true\n\t} ).$el : null;\n\treturn new Drawer(\n\t\tutil.extend(\n\t\t\t{\n\t\t\t\tshowCollapseIcon: false,\n\t\t\t\tclassName: 'drawer position-fixed text references-drawer',\n\t\t\t\tevents: {\n\t\t\t\t\t'click sup a': function ( ev ) {\n\t\t\t\t\t\t// Stop default scroll to hash fragment behaviour.\n\t\t\t\t\t\tev.preventDefault();\n\t\t\t\t\t},\n\t\t\t\t\t'click sup': props.onNestedReferenceClick &&\n\t\t\t\t\t\tmakeOnNestedReferenceClickHandler( props.onNestedReferenceClick )\n\t\t\t\t},\n\t\t\t\tchildren: [\n\t\t\t\t\tutil.parseHTML( '<div>' )\n\t\t\t\t\t\t.addClass( 'references-drawer__header' )\n\t\t\t\t\t\t.append( [\n\t\t\t\t\t\t\tnew Icon( {\n\t\t\t\t\t\t\t\tisSmall: true,\n\t\t\t\t\t\t\t\tname: 'reference',\n\t\t\t\t\t\t\t\ttype: ''\n\t\t\t\t\t\t\t} ).$el,\n\t\t\t\t\t\t\tutil.parseHTML( '<span>' ).addClass( 'references-drawer__title' ).text( mw.msg( 'mobile-frontend-references-citation' ) ),\n\t\t\t\t\t\t\ticons.cancel( 'gray', {\n\t\t\t\t\t\t\t\tisSmall: true,\n\t\t\t\t\t\t\t\ttype: 'element',\n\t\t\t\t\t\t\t\tadditionalClassNames: 'mw-ui-icon-flush-right'\n\t\t\t\t\t\t\t} ).$el\n\t\t\t\t\t\t] ),\n\t\t\t\t\t// Add .mw-parser-output so that TemplateStyles styles apply (T244510)\n\t\t\t\t\tutil.parseHTML( '<div>' ).addClass( 'mw-parser-output' ).append( [\n\t\t\t\t\t\terrorIcon,\n\t\t\t\t\t\tprops.parentText ?\n\t\t\t\t\t\t\tutil.parseHTML( '<div>' ).html( props.parentText ) :\n\t\t\t\t\t\t\t'',\n\t\t\t\t\t\tutil.parseHTML( '<sup>' ).text( props.title ),\n\t\t\t\t\t\tprops.text ?\n\t\t\t\t\t\t\tutil.parseHTML( '<span>' ).html( ' ' + props.text ) :\n\t\t\t\t\t\t\ticons.spinner().$el\n\t\t\t\t\t] )\n\t\t\t\t]\n\t\t\t},\n\t\t\tprops\n\t\t)\n\t);\n}\n\nreferences = {\n\ttest: {\n\t\tmakeOnNestedReferenceClickHandler\n\t},\n\treferenceDrawer,\n\t/**\n\t * Fetch and render nested reference upon click\n\t *\n\t * @param {string} id of the reference to be retrieved\n\t * @param {Page} page to locate reference for\n\t * @param {string} refNumber the number it identifies as in the page\n\t * @param {PageHTMLParser} pageHTMLParser\n\t * @param {Gateway} gateway\n\t * @param {Object} props for referenceDrawer\n\t * @param {Function} onShowNestedReference function call when a nested reference is triggered.\n\t * @return {jQuery.Deferred}\n\t */\n\tshowReference: function ( id, page, refNumber, pageHTMLParser, gateway, props,\n\t\tonShowNestedReference\n\t) {\n\t\treturn gateway.getReference( id, page, pageHTMLParser ).then( function ( reference ) {\n\t\t\tconst drawer = referenceDrawer( util.extend( {\n\t\t\t\ttitle: refNumber,\n\t\t\t\ttext: reference.text,\n\t\t\t\tparentText: reference.parentText,\n\t\t\t\tonNestedReferenceClick: function ( href, text ) {\n\t\t\t\t\treferences.showReference(\n\t\t\t\t\t\thref,\n\t\t\t\t\t\tpage,\n\t\t\t\t\t\ttext,\n\t\t\t\t\t\tpageHTMLParser,\n\t\t\t\t\t\tgateway\n\t\t\t\t\t).then( ( nestedDrawer ) => {\n\t\t\t\t\t\tif ( props.onShowNestedReference ) {\n\t\t\t\t\t\t\tonShowNestedReference( drawer, nestedDrawer );\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tmw.log.warn( 'Please provide onShowNestedReferences parameter.' );\n\t\t\t\t\t\t\tdocument.body.appendChild( nestedDrawer.$el[ 0 ] );\n\t\t\t\t\t\t\tdrawer.hide();\n\t\t\t\t\t\t\tnestedDrawer.show();\n\t\t\t\t\t\t}\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}, props ) );\n\t\t\treturn drawer;\n\t\t}, function ( err ) {\n\t\t\t// If non-existent reference nothing to do.\n\t\t\tif ( err === ReferencesGateway.ERROR_NOT_EXIST ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\treturn referenceDrawer( {\n\t\t\t\terror: true,\n\t\t\t\ttitle: refNumber,\n\t\t\t\ttext: mw.msg( 'mobile-frontend-references-citation-error' )\n\t\t\t} );\n\t\t} );\n\t}\n};\n\nmodule.exports = references;\n","var\n\tpageJSONParser = require( '../page/pageJSONParser' ),\n\tutil = require( '../util' ),\n\textendSearchParams = require( '../extendSearchParams' );\n\n/**\n * @class SearchGateway\n * @uses mw.Api\n * @param {mw.Api} api\n */\nfunction SearchGateway( api ) {\n\tthis.api = api;\n\tthis.searchCache = {};\n\tthis.generator = mw.config.get( 'wgMFSearchGenerator' );\n}\n\nSearchGateway.prototype = {\n\t/**\n\t * The namespace to search in.\n\t *\n\t * @memberof SearchGateway\n\t * @instance\n\t * @type {number}\n\t */\n\tsearchNamespace: 0,\n\n\t/**\n\t * Get the data used to do the search query api call.\n\t *\n\t * @memberof SearchGateway\n\t * @instance\n\t * @param {string} query to search for\n\t * @return {Object}\n\t */\n\tgetApiData: function ( query ) {\n\t\tvar prefix = this.generator.prefix,\n\t\t\tdata = extendSearchParams( 'search', {\n\t\t\t\tgenerator: this.generator.name\n\t\t\t} );\n\n\t\tdata.redirects = '';\n\n\t\tdata['g' + prefix + 'search'] = query;\n\t\tdata['g' + prefix + 'namespace'] = this.searchNamespace;\n\t\tdata['g' + prefix + 'limit'] = 15;\n\n\t\t// If PageImages is being used configure further.\n\t\tif ( data.pilimit ) {\n\t\t\tdata.pilimit = 15;\n\t\t\tdata.pithumbsize = mw.config.get( 'wgMFThumbnailSizes' ).tiny;\n\t\t}\n\t\treturn data;\n\t},\n\n\t/**\n\t * Escapes regular expression wildcards (metacharacters) by adding a \\\\ prefix\n\t *\n\t * @memberof SearchGateway\n\t * @instance\n\t * @param {string} str a string\n\t * @return {Object} a regular expression that can be used to search for that str\n\t * @private\n\t */\n\t_createSearchRegEx: function ( str ) {\n\t\t// '\\[' can be unescaped, but leave it balanced with '`]'\n\t\t// eslint-disable-next-line no-useless-escape\n\t\tstr = str.replace( /[-\\[\\]{}()*+?.,\\\\^$|#\\s]/g, '\\\\$&' );\n\t\treturn new RegExp( '^(' + str + ')', 'ig' );\n\t},\n\n\t/**\n\t * Takes a label potentially beginning with term\n\t * and highlights term if it is present with strong\n\t *\n\t * @memberof SearchGateway\n\t * @instance\n\t * @param {string} label a piece of text\n\t * @param {string} term a string to search for from the start\n\t * @return {string} safe html string with matched terms encapsulated in strong tags\n\t * @private\n\t */\n\t_highlightSearchTerm: function ( label, term ) {\n\t\tlabel = util.parseHTML( '<span>' ).text( label ).html();\n\t\tterm = util.parseHTML( '<span>' ).text( term ).html();\n\n\t\treturn label.replace( this._createSearchRegEx( term ), '<strong>$1</strong>' );\n\t},\n\n\t/**\n\t * Return data used for creating {Page} objects\n\t *\n\t * @memberof SearchGateway\n\t * @instance\n\t * @param {string} query to search for\n\t * @param {Object} pageInfo from the API\n\t * @return {Object} data needed to create a {Page}\n\t * @private\n\t */\n\t_getPage: function ( query, pageInfo ) {\n\t\tvar page = pageJSONParser.parse( pageInfo );\n\n\t\t// If displaytext is set in the generator result (eg. by Wikibase),\n\t\t// use that as display title.\n\t\t// Otherwise default to the page's title.\n\t\t// FIXME: Given that displayTitle could have html in it be safe and just highlight text.\n\t\t// Note that highlightSearchTerm does full HTML escaping before highlighting.\n\t\tpage.displayTitle = this._highlightSearchTerm(\n\t\t\tpageInfo.displaytext ? pageInfo.displaytext : page.title,\n\t\t\tquery\n\t\t);\n\t\tpage.index = pageInfo.index;\n\n\t\treturn page;\n\t},\n\n\t/**\n\t * Process the data returned by the api call.\n\t *\n\t * @memberof SearchGateway\n\t * @instance\n\t * @param {string} query to search for\n\t * @param {Object} data from api\n\t * @return {Array}\n\t * @private\n\t */\n\t_processData: function ( query, data ) {\n\t\tvar self = this,\n\t\t\tresults = [];\n\n\t\tif ( data.query ) {\n\n\t\t\tresults = data.query.pages || {};\n\t\t\tresults = Object.keys( results ).map( function ( id ) {\n\t\t\t\treturn self._getPage( query, results[ id ] );\n\t\t\t} );\n\t\t\t// sort in order of index\n\t\t\tresults.sort( function ( a, b ) {\n\t\t\t\treturn a.index - b.index;\n\t\t\t} );\n\t\t}\n\n\t\treturn results;\n\t},\n\n\t/**\n\t * Perform a search for the given query.\n\t *\n\t * @memberof SearchGateway\n\t * @instance\n\t * @param {string} query to search for\n\t * @return {jQuery.Deferred}\n\t */\n\tsearch: function ( query ) {\n\t\tvar xhr, request,\n\t\t\tself = this;\n\n\t\tif ( !this.isCached( query ) ) {\n\t\t\txhr = this.api.get( this.getApiData( query ) );\n\t\t\trequest = xhr\n\t\t\t\t.then( function ( data, jqXHR ) {\n\t\t\t\t\t// resolve the Deferred object\n\t\t\t\t\treturn {\n\t\t\t\t\t\tquery: query,\n\t\t\t\t\t\tresults: self._processData( query, data ),\n\t\t\t\t\t\tsearchId: jqXHR && jqXHR.getResponseHeader( 'x-search-id' )\n\t\t\t\t\t};\n\t\t\t\t}, function () {\n\t\t\t\t\t// reset cached result, it maybe contains no value\n\t\t\t\t\tself.searchCache[query] = undefined;\n\t\t\t\t} );\n\n\t\t\t// cache the result to prevent the execution of one search query twice\n\t\t\t// in one session\n\t\t\tthis.searchCache[query] = request.promise( {\n\t\t\t\tabort: function () { xhr.abort(); }\n\t\t\t} );\n\t\t}\n\n\t\treturn this.searchCache[query];\n\t},\n\n\t/**\n\t * Check if the search has already been performed in given session.\n\t *\n\t * @memberof SearchGateway\n\t * @instance\n\t * @param {string} query\n\t * @return {boolean}\n\t */\n\tisCached: function ( query ) {\n\t\treturn Boolean( this.searchCache[ query ] );\n\t}\n};\n\nmodule.exports = SearchGateway;\n","const util = require( '../util' ),\n\tView = require( '../View' ),\n\tIcon = require( '../Icon' );\n\n/**\n * @extends View\n */\nclass SearchHeaderView extends View {\n\t/**\n\t * constructor\n\t *\n\t * @inheritdoc\n\t * @param {Object} props\n\t * @param {Function} props.onInput executed every time input changes\n\t * @param {string} props.placeholderMsg\n\t * @param {string} props.action\n\t * @parm {string} [props.autocapitalize] none or sentences\n\t * @param {string} [props.searchTerm] default\n\t */\n\tconstructor( props ) {\n\t\tsuper(\n\t\t\tutil.extend( {\n\t\t\t\tautocapitalize: 'sentences'\n\t\t\t}, props, {\n\t\t\t\tevents: {\n\t\t\t\t\t'input input': 'onInput'\n\t\t\t\t}\n\t\t\t} )\n\t\t);\n\t}\n\t/** @inheritdoc */\n\tonInput( ev ) {\n\t\tconst query = ev.target.value;\n\t\tthis.options.onInput( query );\n\t\tif ( query ) {\n\t\t\tthis.clearIcon.$el.show();\n\t\t} else {\n\t\t\tthis.clearIcon.$el.hide();\n\t\t}\n\t}\n\t/** @inheritdoc */\n\tget isTemplateMode() {\n\t\treturn true;\n\t}\n\t/** @inheritdoc */\n\tget template() {\n\t\treturn util.template( `<div class=\"overlay-title search-header-view\">\n\t\t<form method=\"get\" action=\"{{action}}\" class=\"search-box\">\n\t\t<input class=\"search mw-ui-background-icon-search\" type=\"search\" name=\"search\"\n\t\t\tautocapitalize=\"{{autocapitalize}}\"\n\t\t\tautocomplete=\"off\" placeholder=\"{{placeholderMsg}}\" aria-label=\"{{placeholderMsg}}\" value=\"{{searchTerm}}\">\n\t\t<input type=\"hidden\" name=\"title\" value=\"{{defaultSearchPage}}\">\n\t\t</form>\n</div>` );\n\t}\n\t/** @inheritdoc */\n\tpostRender() {\n\t\tconst clearIcon = new Icon( {\n\t\t\ttagName: 'button',\n\t\t\tname: 'clear',\n\t\t\tisSmall: true,\n\t\t\tlabel: mw.msg( 'mobile-frontend-clear-search' ),\n\t\t\tadditionalClassNames: 'clear',\n\t\t\tevents: {\n\t\t\t\tclick: function () {\n\t\t\t\t\tthis.$el.find( 'input' ).val( '' ).trigger( 'focus' );\n\t\t\t\t\tthis.options.onInput( '' );\n\t\t\t\t\tclearIcon.$el.hide();\n\t\t\t\t\t// In beta the clear button is on top of the search input.\n\t\t\t\t\t// Stop propagation so that the input doesn't receive the click.\n\t\t\t\t\treturn false;\n\t\t\t\t}.bind( this )\n\t\t\t}\n\t\t} );\n\t\tthis.clearIcon = clearIcon;\n\t\tclearIcon.$el.hide();\n\t\tclearIcon.$el.attr( 'aria-hidden', 'true' );\n\t\tthis.$el.find( 'form' ).append( clearIcon.$el );\n\t}\n}\n\nmodule.exports = SearchHeaderView;\n","var\n\tmfExtend = require( '../mfExtend' ),\n\tOverlay = require( '../Overlay' ),\n\tutil = require( '../util' ),\n\tsearchHeader = require( './searchHeader' ),\n\tSearchResultsView = require( './SearchResultsView' ),\n\tWatchstarPageList = require( '../watchstar/WatchstarPageList' ),\n\tSEARCH_DELAY = 300,\n\tSEARCH_SPINNER_DELAY = 2000;\n\n/**\n * Overlay displaying search results\n *\n * @class SearchOverlay\n * @extends Overlay\n * @uses SearchGateway\n * @uses Icon\n *\n * @param {Object} params Configuration options\n * @param {string} params.placeholderMsg Search input placeholder text.\n * @param {string} [params.action] of form defaults to the value of wgScript\n * @param {string} [params.defaultSearchPage] The default search page e.g. Special:Search\n * @param {SearchGateway} [params.gateway]\n */\nfunction SearchOverlay( params ) {\n\tvar header = searchHeader(\n\t\t\tparams.placeholderMsg,\n\t\t\tparams.action || mw.config.get( 'wgScript' ),\n\t\t\tfunction ( query ) {\n\t\t\t\tthis.performSearch( query );\n\t\t\t}.bind( this ),\n\t\t\tparams.defaultSearchPage || '',\n\t\t\tparams.autocapitalize\n\t\t),\n\t\toptions = util.extend( true, {\n\t\t\theaderChrome: true,\n\t\t\tisBorderBox: false,\n\t\t\tclassName: 'overlay search-overlay',\n\t\t\theaders: [ header ],\n\t\t\tevents: {\n\t\t\t\t'click .search-content': 'onClickSearchContent',\n\t\t\t\t'click .overlay-content': 'onClickOverlayContent',\n\t\t\t\t'click .overlay-content > div': function ( ev ) {\n\t\t\t\t\tev.stopPropagation();\n\t\t\t\t},\n\t\t\t\t'touchstart .results': 'hideKeyboardOnScroll',\n\t\t\t\t'mousedown .results': 'hideKeyboardOnScroll',\n\t\t\t\t'click .results a': 'onClickResult'\n\t\t\t}\n\t\t},\n\t\tparams );\n\n\tthis.header = header;\n\tOverlay.call( this, options );\n\n\tthis.api = options.api;\n\t// eslint-disable-next-line new-cap\n\tthis.gateway = options.gateway || new options.gatewayClass( this.api );\n\n\tthis.router = options.router;\n\n\tthis.currentSearchId = null;\n}\n\nmfExtend( SearchOverlay, Overlay, {\n\n\t/**\n\t * Initialize 'search within pages' functionality\n\t *\n\t * @memberof SearchOverlay\n\t * @instance\n\t */\n\tonClickSearchContent: function () {\n\t\tvar\n\t\t\t$form = this.$el.find( 'form' ),\n\t\t\t$el = $form[ 0 ].parentNode;\n\n\t\t// Add fulltext input to force fulltext search\n\t\tthis.parseHTML( '<input>' )\n\t\t\t.attr( {\n\t\t\t\ttype: 'hidden',\n\t\t\t\tname: 'fulltext',\n\t\t\t\tvalue: 'search'\n\t\t\t} )\n\t\t\t.appendTo( $form );\n\t\t// history.back queues a task so might run after this call. Thus we use setTimeout\n\t\t// http://www.w3.org/TR/2011/WD-html5-20110113/webappapis.html#queue-a-task\n\t\tsetTimeout( function () {\n\t\t\t// Firefox doesn't allow submission of a form not in the DOM\n\t\t\t// so temporarily re-add it if it's gone.\n\t\t\tif ( !$form[ 0 ].parentNode ) {\n\t\t\t\t$form.appendTo( $el );\n\t\t\t}\n\t\t\t$form.trigger( 'submit' );\n\t\t}, 0 );\n\t},\n\n\t/**\n\t * Tapping on background only should hide the overlay\n\t *\n\t * @memberof SearchOverlay\n\t * @instance\n\t */\n\tonClickOverlayContent: function () {\n\t\tthis.$el.find( '.cancel' ).trigger( 'click' );\n\t},\n\n\t/**\n\t * Hide the keyboard when scrolling starts (avoid weird situation when\n\t * user taps on an item, the keyboard hides and wrong item is clicked).\n\t *\n\t * @memberof SearchOverlay\n\t * @instance\n\t */\n\thideKeyboardOnScroll: function () {\n\t\tthis.$input.trigger( 'blur' );\n\t},\n\n\t/**\n\t * Handle the user clicking a result.\n\t *\n\t * @memberof SearchOverlay\n\t * @instance\n\t * @param {jQuery.Event} ev\n\t */\n\tonClickResult: function ( ev ) {\n\t\tvar\n\t\t\tself = this,\n\t\t\t$link = this.$el.find( ev.currentTarget );\n\t\t/**\n\t\t * Fired when the user clicks a search result\n\t\t *\n\t\t * @type {Object}\n\t\t * @property {jQuery.Object} result The jQuery-wrapped DOM element that\n\t\t *  the user clicked\n\t\t * @property {number} resultIndex The zero-based index of the\n\t\t *  result in the set of results\n\t\t * @property {jQuery.Event} originalEvent The original event\n\t\t */\n\t\t// FIXME: ugly hack that removes search from browser history\n\t\t// when navigating to search results\n\t\tev.preventDefault();\n\t\tthis.router.back().then( function () {\n\t\t\t// T308288: Appends the current search id as a url param on clickthroughs\n\t\t\tif ( this.currentSearchId ) {\n\t\t\t\tvar clickUri = new mw.Uri( location.href );\n\t\t\t\tclickUri.query.searchToken = this.currentSearchId;\n\t\t\t\tself.router.navigateTo( document.title, {\n\t\t\t\t\tpath: clickUri.toString(),\n\t\t\t\t\tuseReplaceState: true\n\t\t\t\t} );\n\t\t\t\tthis.currentSearchId = null;\n\t\t\t}\n\t\t\t// Router.navigate does not support changing href.\n\t\t\t// FIXME: Needs upstream change T189173\n\t\t\t// eslint-disable-next-line no-restricted-properties\n\t\t\twindow.location.href = $link.attr( 'href' );\n\t\t} );\n\t},\n\n\t/**\n\t * @inheritdoc\n\t * @memberof SearchOverlay\n\t * @instance\n\t */\n\tpostRender: function () {\n\t\tvar self = this,\n\t\t\tsearchResults = new SearchResultsView( {\n\t\t\t\tsearchContentLabel: mw.msg( 'mobile-frontend-search-content' ),\n\t\t\t\tnoResultsMsg: mw.msg( 'mobile-frontend-search-no-results' ),\n\t\t\t\tsearchContentNoResultsMsg: mw.message( 'mobile-frontend-search-content-no-results' ).parse()\n\t\t\t} ),\n\t\t\ttimer;\n\n\t\tthis.$el.find( '.overlay-content' ).append( searchResults.$el );\n\t\tOverlay.prototype.postRender.call( this );\n\n\t\t// FIXME: `this.$input` should not be set. Isolate to searchHeader function\n\t\tthis.$input = this.$el.find( this.header ).find( 'input' );\n\t\t// FIXME: `this.$searchContent` should not be set. Isolate to SearchResultsView class.\n\t\tthis.$searchContent = searchResults.$el.hide();\n\t\t// FIXME: `this.$resultContainer` should not be set. Isolate to SearchResultsView class.\n\t\tthis.$resultContainer = searchResults.$el.find( '.results-list-container' );\n\n\t\t// On iOS a touchstart event while the keyboard is open will result in a scroll\n\t\t// leading to an accidental click (T299846)\n\t\t// Stopping propagation when the input is focused will prevent scrolling while\n\t\t// the keyboard is collapsed.\n\t\tthis.$resultContainer[ 0 ].addEventListener( 'touchstart', ( ev ) => {\n\t\t\tif ( document.activeElement === this.$input[0] ) {\n\t\t\t\tev.stopPropagation();\n\t\t\t}\n\t\t} );\n\n\t\t/**\n\t\t * Hide the spinner and abort timed spinner shows.\n\t\t * FIXME: Given this manipulates SearchResultsView this should be moved into that class\n\t\t */\n\t\tfunction clearSearch() {\n\t\t\tself.$spinner.hide();\n\t\t\tclearTimeout( timer );\n\t\t}\n\n\t\t// Show a spinner on top of search results\n\t\t// FIXME: Given this manipulates SearchResultsView this should be moved into that class\n\t\tthis.$spinner = searchResults.$el.find( '.spinner-container' );\n\t\tthis.on( 'search-start', function ( searchData ) {\n\t\t\tif ( timer ) {\n\t\t\t\tclearSearch();\n\t\t\t}\n\t\t\ttimer = setTimeout( function () {\n\t\t\t\tself.$spinner.show();\n\t\t\t}, SEARCH_SPINNER_DELAY - searchData.delay );\n\t\t} );\n\t\tthis.on( 'search-results', clearSearch );\n\t},\n\n\t/**\n\t * Trigger a focus() event on search input in order to\n\t * bring up the virtual keyboard.\n\t *\n\t * @memberof SearchOverlay\n\t * @instance\n\t */\n\tshowKeyboard: function () {\n\t\tvar len = this.$input.val().length;\n\t\tthis.$input.trigger( 'focus' );\n\t\t// Cursor to the end of the input\n\t\tif ( this.$input[0].setSelectionRange ) {\n\t\t\tthis.$input[0].setSelectionRange( len, len );\n\t\t}\n\t},\n\n\t/**\n\t * @inheritdoc\n\t * @memberof SearchOverlay\n\t * @instance\n\t */\n\tshow: function () {\n\t\t// Overlay#show defines the actual overlay visibility.\n\t\tOverlay.prototype.show.apply( this, arguments );\n\n\t\tthis.showKeyboard();\n\t},\n\n\t/**\n\t * Perform search and render results inside current view.\n\t * FIXME: Much of the logic for caching and pending queries inside this function should\n\t * actually live in SearchGateway, please move out.\n\t *\n\t * @memberof SearchOverlay\n\t * @instance\n\t * @param {string} query\n\t */\n\tperformSearch: function ( query ) {\n\t\tvar\n\t\t\tself = this,\n\t\t\tapi = this.api,\n\t\t\tdelay = this.gateway.isCached( query ) ? 0 : SEARCH_DELAY;\n\n\t\t// it seems the input event can be fired when virtual keyboard is closed\n\t\t// (Chrome for Android)\n\t\tif ( query !== this.lastQuery ) {\n\t\t\tif ( self._pendingQuery ) {\n\t\t\t\tself._pendingQuery.abort();\n\t\t\t}\n\t\t\tclearTimeout( this.timer );\n\n\t\t\tif ( query.length ) {\n\t\t\t\tthis.timer = setTimeout( function () {\n\t\t\t\t\tvar xhr;\n\t\t\t\t\txhr = self.gateway.search( query );\n\t\t\t\t\tself._pendingQuery = xhr.then( function ( data ) {\n\t\t\t\t\t\tthis.currentSearchId = data.searchId;\n\t\t\t\t\t\t// FIXME: Given this manipulates SearchResultsView\n\t\t\t\t\t\t// this should be moved into that class\n\t\t\t\t\t\t// check if we're getting the rights response in case of out of\n\t\t\t\t\t\t// order responses (need to get the current value of the input)\n\t\t\t\t\t\tif ( data && data.query === self.$input.val() ) {\n\t\t\t\t\t\t\tself.$el.toggleClass( 'no-results', data.results.length === 0 );\n\t\t\t\t\t\t\tself.$searchContent\n\t\t\t\t\t\t\t\t.show()\n\t\t\t\t\t\t\t\t.find( 'p' )\n\t\t\t\t\t\t\t\t.hide()\n\t\t\t\t\t\t\t\t.filter( data.results.length ? '.with-results' : '.without-results' )\n\t\t\t\t\t\t\t\t.show();\n\n\t\t\t\t\t\t\t// eslint-disable-next-line no-new\n\t\t\t\t\t\t\tnew WatchstarPageList( {\n\t\t\t\t\t\t\t\tapi: api,\n\t\t\t\t\t\t\t\tfunnel: 'search',\n\t\t\t\t\t\t\t\tpages: data.results,\n\t\t\t\t\t\t\t\tel: self.$resultContainer\n\t\t\t\t\t\t\t} );\n\n\t\t\t\t\t\t\tself.$results = self.$resultContainer.find( 'li' );\n\t\t\t\t\t\t}\n\t\t\t\t\t} ).promise( { abort: function () { xhr.abort(); } } );\n\t\t\t\t}, delay );\n\t\t\t} else {\n\t\t\t\tself.resetSearch();\n\t\t\t}\n\n\t\t\tthis.lastQuery = query;\n\t\t}\n\t},\n\t/**\n\t * Clear results\n\t *\n\t * @private\n\t */\n\tresetSearch: function () {\n\t\tthis.$el.find( '.overlay-content' ).children().hide();\n\t}\n} );\n\nmodule.exports = SearchOverlay;\n","const View = require( '../View' ),\n\tIcon = require( '../Icon' ),\n\tAnchor = require( '../Anchor' ),\n\ticons = require( '../icons' ),\n\t$spinner = icons.spinner().$el,\n\tutil = require( '../util' );\n\n/**\n * @class SearchResultsView\n * @extends View\n * @param {Object} options\n * @param {string} options.searchContentLabel actionable label to tell the user they can \"search\n *  within pages rather than doing a full text search\n * @param {string} options.noResultsMsg shows when no results displayed\n * @param {string} options.searchContentNoResultsMsg alternative to options.searchContentLabel that\n * shows when no search results have been displayed.\n */\nclass SearchResultsView extends View {\n\t/** @inheritdoc */\n\tget isTemplateMode() {\n\t\treturn true;\n\t}\n\t/** @inheritdoc */\n\tget template() {\n\t\treturn util.template( `\n<div class=\"search-results-view\">\n\t<div class=\"search-content\">\n\t\t<div class=\"caption\">\n\t\t\t<p class=\"with-results\">{{searchContentLabel}}</p>\n\t\t\t<p class=\"without-results\">{{noResultsMsg}}</p>\n\t\t\t<p class=\"without-results\">{{{searchContentNoResultsMsg}}}</p>\n\t\t</div>\n\t</div>\n\t<div class=\"spinner-container position-fixed\"></div>\n\t<div class=\"results\">\n\t\t<div class=\"results-list-container\"></div>\n\t\t{{#feedback}}\n\t\t\t<div class=\"search-feedback\">\n\t\t\t\t{{prompt}}\n\t\t\t</div>\n\t\t{{/feedback}}\n\t</div>\n</div>`\n\t\t);\n\t}\n\t/** @inheritdoc */\n\tpreRender() {\n\t\tconst feedbackLink = mw.config.get( 'wgCirrusSearchFeedbackLink' );\n\t\tif ( feedbackLink ) {\n\t\t\tthis.options.feedback = {\n\t\t\t\tprompt: mw.msg( 'mobile-frontend-search-feedback-prompt' ) };\n\t\t}\n\t}\n\t/** @inheritdoc */\n\tpostRender( options ) {\n\t\tconst feedbackLink = mw.config.get( 'wgCirrusSearchFeedbackLink' );\n\t\tsuper.postRender( options );\n\t\tthis.$el.find( '.search-content' ).prepend(\n\t\t\tnew Icon( {\n\t\t\t\ttagName: 'a',\n\t\t\t\t// When this icon is clicked we want to reset the hash for subsequent views\n\t\t\t\thref: '#',\n\t\t\t\tname: 'articlesSearch',\n\t\t\t\tadditionalClassNames: 'mw-ui-icon-flush-left',\n\t\t\t\tlabel: mw.msg( 'mobile-frontend-search-content' )\n\t\t\t} ).$el\n\t\t);\n\t\tthis.$el.find( '.spinner-container' ).append( $spinner );\n\t\tif ( feedbackLink ) {\n\t\t\tthis.$el.find( '.search-feedback' ).append(\n\t\t\t\tnew Anchor( {\n\t\t\t\t\tlabel: mw.msg( 'mobile-frontend-search-feedback-link-text' ),\n\t\t\t\t\thref: feedbackLink\n\t\t\t\t} ).$el\n\t\t\t);\n\t\t}\n\t}\n}\n\nmodule.exports = SearchResultsView;\n","const formHeader = require( '../headers' ).formHeader,\n\tSearchHeaderView = require( './SearchHeaderView' ),\n\ticons = require( '../icons' );\n\n/**\n * Generate a search header\n *\n * @param {string} placeholderMsg\n * @param {string} action\n * @param {Function} onInput\n * @param {string} defaultSearchPage\n * @param {string} autocapitalize\n * @return {jQuery.Element}\n */\nfunction searchHeader( placeholderMsg, action, onInput, defaultSearchPage, autocapitalize ) {\n\treturn formHeader(\n\t\tnew SearchHeaderView( {\n\t\t\tplaceholderMsg,\n\t\t\tautocapitalize,\n\t\t\taction,\n\t\t\tonInput,\n\t\t\tdefaultSearchPage\n\t\t} ),\n\t\t[\n\t\t\ticons.cancel()\n\t\t],\n\t\tfalse\n\t);\n}\n\nmodule.exports = searchHeader;\n","var units = [ 'seconds', 'minutes', 'hours', 'days', 'months', 'years' ],\n\tutil = require( './util' ),\n\tlimits = [ 1, 60, 3600, 86400, 2592000, 31536000 ];\n\n/** @class time */\n\n/**\n * Calculate the correct unit of timestamp\n *\n * @memberof time\n * @instance\n * @param {number} timestampDelta\n * @return {{value: number, unit: string}}\n */\nfunction timeAgo( timestampDelta ) {\n\tvar i = 0;\n\twhile ( i < limits.length && timestampDelta > limits[i + 1] ) {\n\t\t++i;\n\t}\n\treturn {\n\t\tvalue: Math.round( timestampDelta / limits[i] ),\n\t\tunit: units[i]\n\t};\n}\n\n/**\n * Calculate the correct unit of timestamp delta\n *\n * @memberof time\n * @instance\n * @param {number} timestamp\n * @return {{value: number, unit: string}}\n */\nfunction getTimeAgoDelta( timestamp ) {\n\tvar currentTimestamp = Math.round( Date.now() / 1000 );\n\n\treturn timeAgo( currentTimestamp - timestamp );\n}\n\n/**\n * Whether timestamp delta is less than a day old\n *\n * @memberof time\n * @instance\n * @param {{value: number, unit: string}} delta Object of timestamp and its label\n * @return {boolean}\n */\nfunction isRecent( delta ) {\n\treturn [ 'seconds', 'minutes', 'hours' ].indexOf( delta.unit ) > -1;\n}\n\n/**\n * Is delta less than 10 seconds?\n *\n * @memberof time\n * @instance\n * @param {{value: number, unit: string}} delta Object of timestamp and its label\n * @return {boolean}\n */\nfunction isNow( delta ) {\n\treturn delta.unit === 'seconds' && delta.value < 10;\n}\n\n/**\n * Return a message relating to the last modified relative time.\n *\n * @memberof time\n * @instance\n * @param {number} ts timestamp\n * @param {string} username of the last user to modify the page\n * @param {string} gender of the last user to modify the page\n * @param {string} historyUrl url to the history page for the message (deprecated)\n * @return {string}\n */\nfunction getLastModifiedMessage( ts, username, gender, historyUrl ) {\n\tvar delta,\n\t\tlastEditedElement, usernameElement,\n\t\tlinkAll = typeof historyUrl === 'undefined',\n\t\tkeys = {\n\t\t\tseconds: 'mobile-frontend-last-modified-with-user-seconds',\n\t\t\tminutes: 'mobile-frontend-last-modified-with-user-minutes',\n\t\t\thours: 'mobile-frontend-last-modified-with-user-hours',\n\t\t\tdays: 'mobile-frontend-last-modified-with-user-days',\n\t\t\tmonths: 'mobile-frontend-last-modified-with-user-months',\n\t\t\tyears: 'mobile-frontend-last-modified-with-user-years'\n\t\t},\n\t\targs = [];\n\n\tgender = gender || 'unknown';\n\n\tdelta = getTimeAgoDelta( ts );\n\tif ( isNow( delta ) ) {\n\t\targs.push( 'mobile-frontend-last-modified-with-user-just-now', gender, username );\n\t} else {\n\t\targs.push( keys[ delta.unit ], gender, username,\n\t\t\tmw.language.convertNumber( delta.value )\n\t\t);\n\t}\n\n\tlastEditedElement = linkAll ?\n\t\tutil.parseHTML( '<strong>' ).attr( 'class', 'last-modified-text-accent' ) :\n\t\tutil.parseHTML( '<a>' ).attr( 'href', historyUrl || '#' );\n\tusernameElement = linkAll ?\n\t\tutil.parseHTML( '<span>' ).attr( 'class', 'last-modified-text-accent' ) :\n\t\tutil.parseHTML( '<a>' ).attr( 'href', mw.util.getUrl( 'User:' + username ) );\n\n\targs.push(\n\t\tlastEditedElement,\n\t\t// Abuse PLURAL support to determine if the user is anonymous or not\n\t\tmw.language.convertNumber( username ? 1 : 0 ),\n\t\t// Our abuse of PLURAL support means we have to pass the relative URL\n\t\t// rather than construct it from a wikilink\n\t\tusername ? usernameElement : ''\n\t);\n\n\treturn mw.message.apply( this, args ).parse();\n}\n\n/**\n * Return a message relating to the registration date of the user\n *\n * @memberof time\n * @instance\n * @param {string} ts timestamp\n * @param {string} [gender] of the last user editing this page\n * @return {string}\n */\nfunction getRegistrationMessage( ts, gender ) {\n\tvar delta, html,\n\t\tkeys = {\n\t\t\tseconds: 'mobile-frontend-joined-seconds',\n\t\t\tminutes: 'mobile-frontend-joined-minutes',\n\t\t\thours: 'mobile-frontend-joined-hours',\n\t\t\tdays: 'mobile-frontend-joined-days',\n\t\t\tmonths: 'mobile-frontend-joined-months',\n\t\t\tyears: 'mobile-frontend-joined-years'\n\t\t},\n\t\targs = [];\n\n\tgender = gender || 'unknown';\n\n\tdelta = getTimeAgoDelta( parseInt( ts, 10 ) );\n\tif ( isNow( delta ) ) {\n\t\targs.push( 'mobile-frontend-joined-just-now', gender );\n\t} else {\n\t\targs.push( keys[ delta.unit ], gender, mw.language.convertNumber( delta.value ) );\n\t}\n\thtml = mw.message.apply( this, args ).parse();\n\treturn html;\n}\n\nmodule.exports = {\n\tgetLastModifiedMessage: getLastModifiedMessage,\n\tgetRegistrationMessage: getRegistrationMessage,\n\ttimeAgo: timeAgo,\n\tgetTimeAgoDelta: getTimeAgoDelta,\n\tisNow: isNow,\n\tisRecent: isRecent\n};\n"],"sourceRoot":""}