Open jonathanKingston opened 8 years ago
I like the general idea but I'm not sure I fully understand what would be the lifecycle of the 'context'.
Is the plan to throw it away depending on heuristics (like the origin check we currently have)?
Also interested in how this ties in to adding a progress indicator + support for the canGoBack
/ canGoForward
exposed on the mozbrowser iframe.
I'm torn between suggesting that the context could be replaced with
something like hasStaleState = true
which the page could reset after the
first paint and clean up the theme color for example.
Either that or as you say the context could be modified on the way in by
the heuristics on the outside and painted on the initial new Page()
generation.
The idea is to always get a new page object which knows about where it is
in the painting and loading lifecycle etc which could be slightly in front
of the colours of the bars etc because the info hasn't loaded yet.
The stale page objects could also be stored within a WeakSet perhaps to make a API similar to History.
Sorry this doesn't make much sense... I'll try and draw a state diagram soon.
On Thu, Feb 4, 2016 at 3:00 PM Etienne Segonzac notifications@github.com wrote:
I like the general idea but I'm not sure I fully understand what would be the lifecycle of the 'context'. Is the plan to throw it away depending on heuristics (like the origin check we currently have)? Also interested in how this ties in to adding a progress indicator + support for the canGoBack / canGoForward exposed on the mozbrowser iframe.
— Reply to this email directly or view it on GitHub https://github.com/kite-project/hope/issues/43#issuecomment-179884234.
Does canGoBack
get limited by origin much like the History API would be? If not I'm not really sure handling through Objects really makes any change here other than goBack()
giving us the old theme instantly.
This is perhaps a lot simpler were the heuristics are done up front to check if the interface needs to be reset, then on first paint if it still doesn't have a theme it will also default.
The page also isn't responsible for making the UX change here either.
Again this code is rough - there is GC issues etc
const DEFAULT_THEME = '#56565A';
const DEFAULT_URL = 'apps/homescreen/index.html';
window.HopeTab = fxosComponent.register('hope-tab', {
created() {
let url = this.getAttribute('url') || DEFAULT_URL;
this.setPage(url);
// Chrome based
on(iframe, 'mozbrowserlocationchange', e => this.onLocationChange(e));
on(this.els.close, 'click', e => this.onCloseClick(e));
on(this.els.form, 'submit', e => this.onSubmit(e));
on(this.els.refresh, 'click', e => this.refresh(e));
on(this.els.input, 'focus', e => this.onInputFocus(e));
// Page based
on(iframe, 'mozbrowsertitlechange', e => this.currentPage.onTitleChange(e));
on(iframe, 'mozbrowsermetachange', e => this.currentPage.onMetaChange(e));
on(iframe, 'mozbrowsererror', e => this.currentPage.onError(e));
on(iframe, 'mozbrowserloadstart', e => this.currentPage.onLoadStart(e));
on(iframe, 'mozbrowserloadend', e => this.currentPage.onLoadEnd(e));
},
currentPage: null,
sanitizeUrl(url) {
let outputURL = url;
...
return new URL(outputUrl);
},
onSubmit: function (e) {
e.preventDefault();
let url = this.els.input.value;
this.els.input.blur();
let page = this.setPage(url, defaultContext);
page.userSubmittedUrl = true;
},
onLocationChange: function (e) {
this.setPage(e.detail);
},
shouldResetState(currentPage, newPage) {
let output = true;
if (currentPage.origin === newPage.origin) {
ourput = false;
}
return output;
},
setPage: function (url) {
this.url = url;
let urlObject = this.sanitizeUrl(url);
// heuristics on resetting the page
if (this.shouldResetState(urlObject, this.currentPage.url)) {
this.chrome.setTheme(DEFAULT_THEME);
}
this.currentPage = new Page(urlObject, this.chrome);
return this.currentPage;
},
// UI based methods accessible to Pages
chrome: {
setTheme(value) {
scheduler.mutation(() => {
value = value || '';
this.els.bar.style.backgroundColor = value;
this.els.overlay.style.backgroundColor = value;
this.els.tab.style.backgroundColor = value;
this.style.backgroundColor = value;
debug('set theme', value);
});
}
}
});
class Page {
constructor(urlObject, chrome) {
this.userSubmittedUrl = false;
this.url = urlObject;
this.chrome = chrome;
this.hasOverrideTheme();
}
hasOverrideTheme() {
const urls = [
{match: /^https:\/\/mobile[.]twitter[.]com/, color: '#1da1f2'},
{match: /^https:\/\/m[.]facebook[.]com/, color: '#3a5795'}
];
urls.forEach((url) => {
if (url.match.test(this.url.origin)) {
this.theme = url.color;
}
});
return this.theme;
}
onMetaChange() {
var meta = e.detail;
switch (meta.name) {
case 'theme-color': this.theme = meta.content; break;
}
}
set theme(color) {
this._theme = color;
this.showTheme();
}
get theme() {
return this._theme;
}
showTheme() {
let shownColor = this.theme;
if (this.securityState === 'insecure') {
shownColor = 'red';
}
if (this.securityState === 'broken') {
shownColor = DEFAULT_THEME;
}
this.chrome.setTheme(shownColor);
}
firstPaint() {
if (!('theme' in this)) {
this.theme = DEFAULT_THEME;
}
}
error(e) {
if (this.userSubmittedUrl) {
// Handle degrade to http
}
if (e.detail === 'certError') {
// ...
this.showTheme();
}
}
securityChange(e) {
this.securityState = e.details.state;
this.showTheme();
}
}
Consider a change to manage page state with an object that knows it's own history and how the user has interacted with it. This should allow the page:
This would then be thrown away on navigation or passed to a new page object which would could have it's own timers, state etc.
Super rough example code:
@etiennesegonzac and @wilsonpage thoughts?