The concept of a "page model" is a common subject in MobileFrontend. It may be its most significant model. It should be easy to create, reason about, and manipulate such an important model. To that end, this task covers splitting the model functionality of the Page which actually extends View. The concerns should be separated into PageView and Page, the former accepting the latter. Additionally, the new Page model should not hold a reference or modify the passed options object.
=== Acceptance Criteria
[] Page / Page.test.js is a plain model. No or very minimal work in its constructor except assignment. No inheritance. There will no decrease in the amount of existing code or major API refactors so any model methods that existed previously will still be there.
[] PageView or PageComponent is created. If any inheritance, only View. Just an encapsulation of view-only responsibilities.
[] PageJSONParser / PageJSONParser.test.js: encompasses at least the current Page.newFromJSON which parses JSON and returns a Page model. It clarifies in the comments what gateways or response formats it works with given the flexibility of the MW API. It exists in a distinct file.
[] PageView accepts a Page and exists in distinct file.
[] PageHTMLParser / PageHTMLParser.test.js: this may have some overlap with PageView. For example, the current Page.getThumbnails parses the DOM to construct a model. Ideally, this code will accept HTML and return a Page model.
[] PageView and Page do not modify their parameters and Page is _the_ model with its own fields instead of holding a reference to the passed in options object.
[] All construction parameters including those passed via "options.prop" are well documented with JSDocs including typing and whether parameters are optional.
[] Usages of Page that only needed the model use Page. Those that need the View are updated to PageView.
[] There are no regressions.
= Bonus acceptance criteria
[] If the code is worth keeping, some tests that look nice and set a good precedent that future tests can be patterned off of.
PageJSONParser looks like the easiest to tackle and may be a good place to start. PageView should probably come next so that it's easy to test the Page model without a DOM. Due to overlap with PageView, PageHTMLParser should probably be done last and live with or near PageView.
The Page object is used in various places, so breaking changes to its API are going to be tricky and risky. I thus propose we make any changes here backwards compatibility. For example:
```
// if the new api is
new PageView( { page } )
// but the old id was:
new PageView( { title } )
// then we should
function PageView( options ) {
if ( !options.page ) {
options.page = new Page( { title: options.title } )
// message should be more friendly ;-)
mw.log.warn( "hey you! Pass the PageView a page rather than a title. Don't be lazy!" );
}
}
```