[Step 1A, Step 1B] => Step 2 => Step 3 => Step 4
- Step 1A: create dev branch, add
owl_3_with_some_of_owl2, compatibility layer - Step 1B: prepare master by adding
owl2_with_some_owl3build, and replacing/rewriting unpatchable code - Step 2: merge dev branch with
owl_3_with_some_of_owl2version in master - Step 3: progressively remove owl2 specific code and uses of compatibility layer
- Step 4: replace
owl_3_with_some_of_owl2byowl_3, celebrate
| # | Change | Additional info |
|---|---|---|
| 1 | useState removed |
|
| 2 | reactive removed |
240 calls |
| 3 | useEffect semantics changed |
596 calls |
| 4 | this.props removed |
|
| 5 | static props / defaultprops ignored (use the props function) |
281 default props |
| 6 | this.env removed |
161 useSubEnv |
| 7 | rendering context changes (reading from component through this) |
|
| 8 | onWillUpdateProps removed |
183 calls |
| 9 | t-esc removed |
|
| 10 | t-ref changes: takes a signal (or resource) |
1022 calls |
| 11 | t-model changes: takes a signal |
197 calls |
| 12 | onWillRender removed |
70 calls |
| 13 | onRendered removed |
20 calls |
| 14 | this.render removed |
130 calls |
| 15 | t-portal removed |
18 calls |
| 16 | useExternalListener renamed to useListener (and changed) |
210 calls |
| 17 | status changed |
64 calls |
| 18 | App has only sub roots |
20 new App calls |
| 19 | loadFile removed |
|
| 20 | t-call not allowed on tags !== t |
|
| 21 | t-call body evaluated lazily, variables passed as parameters |
|
| 22 | useComponent removed |
93 calls |
- create dev branch
master-owl3: - add owl3.js to web/static/libs/owl
- create owl3_compatibility.js in web/static/libs/owl <-- need to be executed before owl code
owl_3_with_some_of_owl2build is: owl 3 with additional temporary code:t-portalsupport is not removed yet- this build should have a ComponentNode.prototype.beforeSetup method that is called before the setup, to make it patchable
- keep
onWillUpdateProps - change
t-custom-refandt-custom-modeldirective to wrap content oft-refandt-modelin a signal-like function
In compatibility layer:
// useState
owl.useState = proxy;
// reactive
owl.reactive = function(value, cb) {
if (cb) {
// depreciation warning => probably require manual code update
console.warn("reactive is deprecated");
useEffect(cb());
}
return proxy(value);
}
class EnvPlugin extends Plugin {
env = {};
}
const useEnv = () => plugin(EnvPlugin).env;
owl.useEnv = useEnv;
owl.useSubEnv = function (extension) {
const env = useEnv();
const subEnv = Object.assign(Object.create(env), extension);
class SubEnvPlugin extends Plugin {
static id = "EnvPlugin";
env = subEnv;
}
providePlugins([SubEnvPlugin]);
}
owl.onWillRender = (cb) => {
// find a way to make it work
}
owl.onRendered = (cb) => {
// find a way to make it work
}
owl.useComponent = () => {
...
}
owl.useExternalListener = ... // duplicate current code from owl
owl.Component.ComponentNode.beforeSetup = function() {
if (!this.component.props) {
// only patch it if component does not define it before
this.component.props = props();
}
if (!this.component.env) {
this.component.env = useEnv();
}
}
- adapt all codes that instantiat new App and roots
Build owl2_with_some_owl3, add it in master:
-
export
renderfunction -
useEffect:- duplicate current owl2
useEffectcode in odoouseLayoutEffect(@web/owl2_utils?) - adapt all
useEffectimports from@odoo/owlto@web/owl2_utils
- duplicate current owl2
-
rendering context: add
this.on all free variables in all templates (NEED SCRIPT) -
try to remove all uses of onWillUpdateProps
- (need useAsyncEffect in odoo)
- if successfull => remove onwillUpdateProps from owl3_with2 build
-
rename all
t-esc=>t-out(NEED SCRIPT) -
t-ref:- rename them all
t-custom-ref(NEED SCRIPT?), add directive to remap them tot-ref
- rename them all
-
t-model:- rename them all
t-custom-model(with script?), add directive to remap them tot-modelfor now
- rename them all
-
this.render: update all uses to import render from owl and uses it -
implement
useExternalListenerin owl2_utils -
adapt code to use it instead of owl useListener (script?)
-
t-call: prevent t-call on tag !== t (need script)
Not much to say. Just do it as soon as it is green
- replace
useStatebyproxy(NEED A SCRIPT) - replace
reactivebyproxy(NEED A SCRIPT)- all reactive uses of 2nd argument => manual code update to use useEffect
- go trough all useEffect, and see if they can be replaced by owl useEffect
- if yes => do it
- if at the end, some useEffects cannot be converted => see if we need some notion of useLayoutEffect in owl3
- props:
- add
props = props()in all components (NEED SCRIPT) - if possible, try to convert in script static props/defaultprops => props({ ...}, {...})
- as soon as possible: remove this.props override in compatibility layer
- check that we have no remaining static props/defaultprops, maybe add a linter to prevent readding them in forward ports
- add
- env
- go through all uses of env
- replace them by plugins/provideplugins/...
- t-ref: go through all uses of
t-custom-ref, and rewrite code to use a signal - remove all uses of onWillRender: manual work
- remove all uses of onRendered: manual work
- remove all uses of the exported render function: manual work
- remove all uses of t-portal (manual work)
- check all uses of useExternalListener in owl2_utils => replace them by useListener in owl3
- remove all uses of useComponent
- Remove compatibility layer
- replace owl3_with_some_of_owl2 by owl3
- Take a break...
- replace all
t-refwitht-custom-ref - add
this.before all free variables in owl templates - rename t-esc => t-out (simple)
- replace useState => proxy in all js code
- replace reactive => proxy (except if second argument)
- add
props = props()orprops = props(type, defaultprops)in all components