Extension:CentralNotice/Banner loading

This page details the process of loading and rendering a banner.

Skin load
The user's browser fetches a MediaWiki page. The HTML causes three more requests to be initiated,
 * A head script request to GeoIP javascript at bits.wikimedia.org.
 * A DNS-prefetch link rel caches meta.wikimedia.org's IP address.
 * ResourceLoader is instructed to load the ext.centralNotice.bannerController module.

Banner controller initialization
The bannerController javascript sets an onload handler to call mw.centralNotice.initialize.

The onload initialization gathers the following information,
 * Query string parameters on the main page URL may be used to override default functionality: country, device, banner, debug
 * Bucketing is determined by reading the centralnotice_bucket cookie, or a new bucket is randomly chosen.
 * The GeoIP response is used to set the country variable.
 * Address family is determined, either IPv4 or IPv6.
 * Device is determined from the wgMobileDeviceName config variable.

A #centralNotice div is injected into the #siteNotice div. This is where ordinary banners are rendered.

We call mw.centralNotice.loadBanner.

Load banner
The banner controller generates an URL with all the campaign and banner selection criteria, plus a random integer between 1 and 30. This URL looks like, http://meta.wikimedia.org/wiki/Special:BannerRandom ?uselang=fr &sitename=enwiki &project=wikipedia &anonymous=true &bucket=1 &country=BE &device=desktop &slot=29 &debug=false

This request is made using the jQuery ajax helper, set to the "script" type, which evaluates the response body as javascript if successful.

Banner response
Note that any BannerRandom response must be deterministic, because we rely on caching. For every set of query parameters, there is exactly one response. As different campaigns and tests become active, the response may change, but there is a roughly 15-minute lag until the caches will be refreshed with the new banner contents.

Banner selection is performed by the BannerChooser class, and is covered in its own article. Here it's enough to mention that each "slot" number corresponds to a banner, or to an empty response.

A BannerRandom response is essentially a JSONP payload, plus a few extra function calls. This is generated by the BannerRenderer class, The order of calls made by a typical banner payload is,
 * If the banner uses a preload mixin module, the mw.centralNotice.bannerData.preload function is set to a callback that will return a boolean.
 * mw.centralNotice.insertBanner is called with the banner's html and some metadata as its arguments.

Insert banner
When the banner payload is received by the client, it is executed as a script. The banner will call window.insertBanner and pass in a JSON representation of its contents and metadata. The insertBanner function runs any preload logic to determine whether to display the banner. If the banner wants to be displayed, the bannerJson.banerHtml contents are inserted into the page DOM at div#centralNotice, which will be present at the top of the page contents unless it has been removed by code such as the Wikipedia Zero hooks.

Record impression
The banner selection criteria, show/hide result, and any applicable hide reason, are sent to the Special:RecordImpression endpoint, which does nothing. The log of this web request is used to determine how many banner impressions we received.