-
Notifications
You must be signed in to change notification settings - Fork 349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[IMP] parser: add support for user-space directives #1651
base: master
Are you sure you want to change the base?
Conversation
e0e4d78
to
f2eab03
Compare
If the user directives are defined on the app, doesn't that mean the entire feature is unavailable when precompiling? |
f2eab03
to
53807d8
Compare
tests/app/app.test.ts
Outdated
} | ||
const app = new App(SomeComponent, { | ||
globalValues: { | ||
plop: (string : any) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a fan of the API: calling __globals__.plop()
is not natural.
- Find a way at compile time to destructure that object on demand, a bit like helpers and bdom are.
or - rename every member of the globalValue to
custom[Value]
Find a way to protect the helpers and globals from user alteration: if user's code accesses via __globals__.myfunc()
and myfunc is not an arrow function, then myfunc could access, modify, add to the globals object (via its this
)
Also, it is obviously a side effect of that feature, but it is another door open to memory leaks and errors due to scoping things into arbitrary, unkillable closures
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when:
- A "main" app (let's the one spawning the webclient) defines such globals
- a secondary app (lets say the ones spawned by the htmleditor) doesn't define such globals.
In the secondary app, it is legitimate to want to spawn the same components that the main app would.
Does the globals object gets shared, or do we expect a crash ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is no secondary app, that's why we have owl roots. they all share the same config/templates/translation function/settings and now global and user directives. should be fine
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a fan of the API: calling
__globals__.plop()
is not natural.
imo, it's not a problem, it will be extremely rare, it's only for some specific low level code
- Find a way at compile time to destructure that object on demand, a bit like helpers and bdom are.
- rename every member of the globalValue to
custom[Value]
this is much much harder to do safely
Find a way to protect the helpers and globals from user alteration: if user's code accesses via
__globals__.myfunc()
and myfunc is not an arrow function, then myfunc could access, modify, add to the globals object (via itsthis
) Also, it is obviously a side effect of that feature, but it is another door open to memory leaks and errors due to scoping things into arbitrary, unkillable closures
good point about memory leaks, i am unsure, need to think about it. now, i don't see how to really protect the globals object. maybe we can use Object.seal
. could be a good idea indeed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is another door open to memory leaks and errors due to scoping things into arbitrary, unkillable closures
I for one am just not seeing it, mind expanding on that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was just a general observation. In the history of what we did in odoo, we realized progressively that when passing callbacks everywhere we take the risk to have some objects in a closure that can hold the whole OWL Tree. In this particular case, those closures would be, indeed unkillable. But I don't think they will hold much information......
6a19f9e
to
545cb32
Compare
9a824a6
to
7c17b7f
Compare
987429c
to
3c34085
Compare
This commit adds the support for custom directives. To use the custom directive, an Object of functions needs to be configured on the owl APP: ```js new App(..., { customDirectives: { test_directive: function (el, value) { el.setAttribute("t-on-click", value); return el; } } }); ``` The functions will be called when a custom directive with the name of the function is found. The original element will be replaced with the one returned by the function. This : ```xml <div t-custom-test_directive="click" /> ``` will be replace by : ```xml <div t-on-click="value"/> ``` issue : #1650
This commit, add a new configuration on the App: globalValues. It's a global object of elements available at compilations. For instance: ```js const app = new App(SomeComponent, { globalValues: { plop: (string: any) => { steps.push(string); }, }, }); ``` The plop function will be available at the compilation, so it can be used on the templates : ```xml <div t-on-click="() => __globals__.plop('click')" class="my-div"/> ```
3c34085
to
a96815f
Compare
@@ -42,6 +47,8 @@ export class TemplateSet { | |||
} | |||
} | |||
this.getRawTemplate = config.getTemplate; | |||
this.customDirectives = config.customDirectives || {}; | |||
this.globalValues = config.globalValues || {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this.runtimeUtils = { ...helpers, __globals__: config.globalValues || {}} ;
and remove this.globalValues
@@ -97,7 +104,8 @@ export class TemplateSet { | |||
this.templates[name] = function (context, parent) { | |||
return templates[name].call(this, context, parent); | |||
}; | |||
const template = templateFn(this, bdom, helpers); | |||
const runtimeUtils = { ...helpers, __globals__: this.globalValues }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is done everytime a component is instantiated. it would be cheaper to do it just once in the setup. so, remove this line
@@ -97,7 +104,8 @@ export class TemplateSet { | |||
this.templates[name] = function (context, parent) { | |||
return templates[name].call(this, context, parent); | |||
}; | |||
const template = templateFn(this, bdom, helpers); | |||
const runtimeUtils = { ...helpers, __globals__: this.globalValues }; | |||
const template = templateFn(this, bdom, runtimeUtils); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const template = templateFn(this, bdom, this.runtimeUtils);
This commit adds the support for user-space directives. To use the user-space directive, an Object of functions needs to be configured on the owl APP:
The functions will be called when a user directive with the name of the function is found. The original element will be replaced with the one returned by the function.
This :
will be replace by :
issue : #1650