From 8483cc805eb7d55c9b8a33c6b3a8aedb52c5331d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Fri, 20 Nov 2020 10:33:03 +0100 Subject: [PATCH] [FIX/IMP] export browser object, prevent crash in private mode This commit performs two tasks: 1. it exports the internal browser object (in owl.browser), for ease of testing 2. it makes sure that Owl does not crash inside iframes in incognito mode, because window.localStorage raises an exception in that case closes #791 --- doc/readme.md | 1 + doc/reference/animations.md | 6 ++++-- doc/reference/browser.md | 33 +++++++++++++++++++++++++++++++++ doc/reference/content.md | 1 + doc/reference/environment.md | 15 +-------------- src/browser.ts | 9 ++++++++- src/component/component.ts | 1 + src/index.ts | 1 + 8 files changed, 50 insertions(+), 17 deletions(-) create mode 100644 doc/reference/browser.md diff --git a/doc/readme.md b/doc/readme.md index 4507ac14..cf53639f 100644 --- a/doc/readme.md +++ b/doc/readme.md @@ -17,6 +17,7 @@ You will find here a complete reference of every feature, class or object provided by Owl. - [Animations](reference/animations.md) +- [Browser](reference/browser.md) - [Component](reference/component.md) - [Content](reference/content.md) - [Concurrency Model](reference/concurrency_model.md) diff --git a/doc/reference/animations.md b/doc/reference/animations.md index ba23a586..3a4ff190 100644 --- a/doc/reference/animations.md +++ b/doc/reference/animations.md @@ -52,7 +52,7 @@ sequence of events will happen: At node insertion: - the css classes `name-enter` and `name-enter-active` will be added directly - when the node is inserted into the DOM. + when the node is inserted into the DOM. - on the next animation frame: the css class `name-enter` will be removed and the class `name-enter-to` will be added (so they can be used to trigger css transition effects). @@ -115,11 +115,13 @@ If you use SCSS, you can use mixins to make generic animations. Here is an exemp ``` Usage: + ```scss @include animation-fade(0.5s, "o_notification"); ``` -You can now have in your template: +You can now have in your template: + ```xml ``` diff --git a/doc/reference/browser.md b/doc/reference/browser.md new file mode 100644 index 00000000..fd7b3724 --- /dev/null +++ b/doc/reference/browser.md @@ -0,0 +1,33 @@ +# 🦉 Browser 🦉 + +## Content + +- [Overview](#overview) +- [Browser Content](#browser-content) + +## Overview + +The browser object contains some browser native APIs, such as `setTimeout`, that +are used by Owl and its utility functions. They are exposed with the intent of +making them mockable if necessary. + +```js +owl.browser.setTimeout === window.setTimeout; // return true +``` + +For now, this object contains some functions that are not used by Owl. They +will eventually be removed in Owl 2.0. + +## Browser Content + +More specifically, the `browser` object contains the following methods and objects: + +- `setTimeout` +- `clearTimeout` +- `setInterval` +- `clearInterval` +- `requestAnimationFrame` +- `random` +- `Date` +- `fetch` +- `localStorage` diff --git a/doc/reference/content.md b/doc/reference/content.md index 54d74508..8f272579 100644 --- a/doc/reference/content.md +++ b/doc/reference/content.md @@ -7,6 +7,7 @@ For example, `Component` is available at `owl.Component` and `EventBus` is exported as `owl.core.EventBus`. ``` +browser Component misc Context AsyncRoot QWeb Portal diff --git a/doc/reference/environment.md b/doc/reference/environment.md index 21f62b7d..d3f22307 100644 --- a/doc/reference/environment.md +++ b/doc/reference/environment.md @@ -133,17 +133,4 @@ the `QWeb` instance and a `browser` object: - `qweb` will be set to an empty `QWeb` instance. This is absolutely necessary for Owl to be able to render anything - `browser`: this is an object that contains some common access points to the - browser methods with a side effect. This is particularly useful when one want - to test more advanced components, and be able to mock those methods. - -More specifically, the `browser` object contains the following methods and objects: - -- `setTimeout` -- `clearTimeout` -- `setInterval` -- `clearInterval` -- `requestAnimationFrame` -- `random` -- `Date` -- `fetch` -- `localStorage` + browser methods with a side effect. See [browser](browser.md) for more information. Note that the browser object will be removed from the environment in Owl 2.0. diff --git a/src/browser.ts b/src/browser.ts index f47a6620..b18d44dd 100644 --- a/src/browser.ts +++ b/src/browser.ts @@ -10,6 +10,8 @@ export interface Browser { localStorage: Window["localStorage"]; } +let localStorage: Window["localStorage"] | null = null; + export const browser: Browser = { setTimeout: window.setTimeout.bind(window), clearTimeout: window.clearTimeout.bind(window), @@ -19,5 +21,10 @@ export const browser: Browser = { random: Math.random, Date: window.Date, fetch: (window.fetch || (() => {})).bind(window), - localStorage: window.localStorage, + get localStorage() { + return localStorage || window.localStorage; + }, + set localStorage(newLocalStorage: Window["localStorage"]) { + localStorage = newLocalStorage; + }, }; diff --git a/src/component/component.ts b/src/component/component.ts index faafa16f..ded8cca4 100644 --- a/src/component/component.ts +++ b/src/component/component.ts @@ -159,6 +159,7 @@ export class Component { if (!this.env.qweb) { this.env.qweb = new QWeb(); } + // TODO: remove this in owl 2.0 if (!this.env.browser) { this.env.browser = browser; } diff --git a/src/index.ts b/src/index.ts index f4d6ff1a..e2fada72 100644 --- a/src/index.ts +++ b/src/index.ts @@ -22,6 +22,7 @@ import { Router } from "./router/router"; export { Component, mount } from "./component/component"; export { QWeb }; export { config }; +export { browser } from "./browser"; export const Context = _context.Context; export const useState = _hooks.useState;