maildev@lists.thunderbird.net

Thunderbird email developers

View all threads

custom elements, models, and views

PM
Paul Morris
Fri, Oct 11, 2019 6:07 PM

Hi all,

I wanted to share some thoughts on custom elements (CEs) and how they
relate to UI patterns that separate model from view -- various themes
and variations on MVC (model, view, controller):

https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

Basically, CEs don't encourage separation of model and view (data/state
and presentation).  One of the main things they offer over plan HTML is
letting you couple JS logic with a particular piece of HTML/CSS UI.  One
of their main use cases was to bundle all of that up into self-contained
units that could be dropped wherever but not de-composed.  (I.e. put a
google maps widget on your website.)  In short, they enable and tend to
encourage keeping state in DOM nodes/local component state, which
couples the model and view together.

Separating model and view is a pretty well established UI approach with
various benefits.  MVC dates from the 1970s, and more recently in the
web dev world we had a broad shift away from jQuery to React/Redux etc.

While CEs make a lot of sense as an upgrade/migration path away from
XBL, I think it's worth considering as we go forward, whether we should
move towards greater separation between model and view in our UI code. 
I think there's a lot of unnecessary complexity and brittleness in our
UI code that could be improved by this kind of separation of concerns. 
Here are a couple of articles on this topic:

UI as an afterthought
Makes the general case really well.
https://medium.com/@mweststrate/ui-as-an-afterthought-26e5d2bb24d6

Choosing a web component Model
A short post I found that makes the comparison between web components
and MVC, etc.
https://medium.com/@daveford/choosing-a-web-component-model-f83bb9a8edae

Consider an example.  Just for sake of argument, say we wanted to offer
two UIs for entering recipients for a message, a plain text one and a
pill-based one, and we wanted to be able to toggle between them on the
fly.  Or maybe an addon wants to offer an alternative UI.

If we have the model separate from the view, then it is just a matter of
switching the view.  If we have our model coupled with one particular
view, then it is not so simple.

Consider addons that want to modify the UI (like "Conversations" or
"CardBook").  It would be much more feasible to see how that could work
if we had more separation between model and view.  It's easier to
imagine where WebExtensions APIs might hook in, in a world with greater
model/view separation.

Or consider making TB more scriptable via command line, etc.

These are just some preliminary thoughts I've had about this as I've
been working with CEs, and now as we move past de-XBL to moving the UI
forward.  Curious to hear what others think.

-Paul

--
Paul Morris
Thunderbird.net

Hi all, I wanted to share some thoughts on custom elements (CEs) and how they relate to UI patterns that separate model from view -- various themes and variations on MVC (model, view, controller): https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller Basically, CEs don't encourage separation of model and view (data/state and presentation).  One of the main things they offer over plan HTML is letting you couple JS logic with a particular piece of HTML/CSS UI.  One of their main use cases was to bundle all of that up into self-contained units that could be dropped wherever but not de-composed.  (I.e. put a google maps widget on your website.)  In short, they enable and tend to encourage keeping state in DOM nodes/local component state, which couples the model and view together. Separating model and view is a pretty well established UI approach with various benefits.  MVC dates from the 1970s, and more recently in the web dev world we had a broad shift away from jQuery to React/Redux etc. While CEs make a lot of sense as an upgrade/migration path away from XBL, I think it's worth considering as we go forward, whether we should move towards greater separation between model and view in our UI code.  I think there's a lot of unnecessary complexity and brittleness in our UI code that could be improved by this kind of separation of concerns.  Here are a couple of articles on this topic: UI as an afterthought Makes the general case really well. https://medium.com/@mweststrate/ui-as-an-afterthought-26e5d2bb24d6 Choosing a web component Model A short post I found that makes the comparison between web components and MVC, etc. https://medium.com/@daveford/choosing-a-web-component-model-f83bb9a8edae Consider an example.  Just for sake of argument, say we wanted to offer two UIs for entering recipients for a message, a plain text one and a pill-based one, and we wanted to be able to toggle between them on the fly.  Or maybe an addon wants to offer an alternative UI. If we have the model separate from the view, then it is just a matter of switching the view.  If we have our model coupled with one particular view, then it is not so simple. Consider addons that want to modify the UI (like "Conversations" or "CardBook").  It would be much more feasible to see how that could work if we had more separation between model and view.  It's easier to imagine where WebExtensions APIs might hook in, in a world with greater model/view separation. Or consider making TB more scriptable via command line, etc. These are just some preliminary thoughts I've had about this as I've been working with CEs, and now as we move past de-XBL to moving the UI forward.  Curious to hear what others think. -Paul -- Paul Morris Thunderbird.net
AC
Alessandro Castellani
Fri, Oct 11, 2019 10:14 PM

I kind of completely agree with you.

Coming from lots of years of Angular, Laravel, and VueJS, I love the MVC
approach and it makes monolith applications incredibly easy to maintain
and extend.

Since I'm having this sort of thought process while coding the new
address pills, I was trying to find a decent solution in order to make
the pills easily reusable and adaptable to various locations in the UI.

Maybe creating a basic MozElement as a CE acting as a model that can be
extended freely to create dedicate CEs that act only as views.

Something similar, but not quite identical, is how the new Notification
system is handled in m-c:
https://searchfox.org/mozilla-central/rev/c8933daeb71df02566407eff88904ee981a7bcdd/toolkit/content/widgets/notificationbox.js

There's a MozElements.NotificationBox class that handles all the data
and the various actions and behavior of a notification-box element, but
the actual notification-box UI is a Custom Element defined as
"notification".

So far, this is the closest attempt of separating the model from the
view I've stumbled upon.

I think it's worth exploring this approach.

On 2019-10-11 11:07, Paul Morris wrote:

Hi all,

I wanted to share some thoughts on custom elements (CEs) and how they
relate to UI patterns that separate model from view -- various themes
and variations on MVC (model, view, controller):

https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

Basically, CEs don't encourage separation of model and view
(data/state and presentation).  One of the main things they offer over
plan HTML is letting you couple JS logic with a particular piece of
HTML/CSS UI.  One of their main use cases was to bundle all of that up
into self-contained units that could be dropped wherever but not
de-composed.  (I.e. put a google maps widget on your website.)  In
short, they enable and tend to encourage keeping state in DOM
nodes/local component state, which couples the model and view together.

Separating model and view is a pretty well established UI approach
with various benefits.  MVC dates from the 1970s, and more recently in
the web dev world we had a broad shift away from jQuery to React/Redux
etc.

While CEs make a lot of sense as an upgrade/migration path away from
XBL, I think it's worth considering as we go forward, whether we
should move towards greater separation between model and view in our
UI code.  I think there's a lot of unnecessary complexity and
brittleness in our UI code that could be improved by this kind of
separation of concerns.  Here are a couple of articles on this topic:

UI as an afterthought
Makes the general case really well.
https://medium.com/@mweststrate/ui-as-an-afterthought-26e5d2bb24d6

Choosing a web component Model
A short post I found that makes the comparison between web components
and MVC, etc.
https://medium.com/@daveford/choosing-a-web-component-model-f83bb9a8edae

Consider an example.  Just for sake of argument, say we wanted to
offer two UIs for entering recipients for a message, a plain text one
and a pill-based one, and we wanted to be able to toggle between them
on the fly.  Or maybe an addon wants to offer an alternative UI.

If we have the model separate from the view, then it is just a matter
of switching the view.  If we have our model coupled with one
particular view, then it is not so simple.

Consider addons that want to modify the UI (like "Conversations" or
"CardBook").  It would be much more feasible to see how that could
work if we had more separation between model and view.  It's easier to
imagine where WebExtensions APIs might hook in, in a world with
greater model/view separation.

Or consider making TB more scriptable via command line, etc.

These are just some preliminary thoughts I've had about this as I've
been working with CEs, and now as we move past de-XBL to moving the UI
forward.  Curious to hear what others think.

-Paul

--
Alessandro Castellani
Lead UX Architect
Thunderbird

I kind of completely agree with you. Coming from lots of years of Angular, Laravel, and VueJS, I love the MVC approach and it makes monolith applications incredibly easy to maintain and extend. Since I'm having this sort of thought process while coding the new address pills, I was trying to find a decent solution in order to make the pills easily reusable and adaptable to various locations in the UI. Maybe creating a basic MozElement as a CE acting as a model that can be extended freely to create dedicate CEs that act only as views. Something similar, but not quite identical, is how the new Notification system is handled in m-c: https://searchfox.org/mozilla-central/rev/c8933daeb71df02566407eff88904ee981a7bcdd/toolkit/content/widgets/notificationbox.js There's a `MozElements.NotificationBox` class that handles all the data and the various actions and behavior of a notification-box element, but the actual notification-box UI is a Custom Element defined as "notification". So far, this is the closest attempt of separating the model from the view I've stumbled upon. I think it's worth exploring this approach. On 2019-10-11 11:07, Paul Morris wrote: > Hi all, > > I wanted to share some thoughts on custom elements (CEs) and how they > relate to UI patterns that separate model from view -- various themes > and variations on MVC (model, view, controller): > > https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller > > Basically, CEs don't encourage separation of model and view > (data/state and presentation).  One of the main things they offer over > plan HTML is letting you couple JS logic with a particular piece of > HTML/CSS UI.  One of their main use cases was to bundle all of that up > into self-contained units that could be dropped wherever but not > de-composed.  (I.e. put a google maps widget on your website.)  In > short, they enable and tend to encourage keeping state in DOM > nodes/local component state, which couples the model and view together. > > Separating model and view is a pretty well established UI approach > with various benefits.  MVC dates from the 1970s, and more recently in > the web dev world we had a broad shift away from jQuery to React/Redux > etc. > > While CEs make a lot of sense as an upgrade/migration path away from > XBL, I think it's worth considering as we go forward, whether we > should move towards greater separation between model and view in our > UI code.  I think there's a lot of unnecessary complexity and > brittleness in our UI code that could be improved by this kind of > separation of concerns.  Here are a couple of articles on this topic: > > UI as an afterthought > Makes the general case really well. > https://medium.com/@mweststrate/ui-as-an-afterthought-26e5d2bb24d6 > > Choosing a web component Model > A short post I found that makes the comparison between web components > and MVC, etc. > https://medium.com/@daveford/choosing-a-web-component-model-f83bb9a8edae > > Consider an example.  Just for sake of argument, say we wanted to > offer two UIs for entering recipients for a message, a plain text one > and a pill-based one, and we wanted to be able to toggle between them > on the fly.  Or maybe an addon wants to offer an alternative UI. > > If we have the model separate from the view, then it is just a matter > of switching the view.  If we have our model coupled with one > particular view, then it is not so simple. > > Consider addons that want to modify the UI (like "Conversations" or > "CardBook").  It would be much more feasible to see how that could > work if we had more separation between model and view.  It's easier to > imagine where WebExtensions APIs might hook in, in a world with > greater model/view separation. > > Or consider making TB more scriptable via command line, etc. > > These are just some preliminary thoughts I've had about this as I've > been working with CEs, and now as we move past de-XBL to moving the UI > forward.  Curious to hear what others think. > > -Paul > -- *Alessandro Castellani* Lead UX Architect Thunderbird
PK
Philipp Kewisch
Sat, Oct 12, 2019 12:07 PM

Hi Paul,

this is definitely an interesting topic. To me there are two areas to
this, one being separating the HTML from Javascript (view from
controller), and the other being separating the view/controller from the
model.

The latter point, to my mind, is pretty clear. Web Components should not
have any model code. They should be re-usable widgets that are
self-contained. The way they get their model data is setters, which will
re-render as appropriate. This means the controller that drives the
window those elements are in will need to update those custom elements
by getting from the model and setting on the custom element.

The former point is a complaint I've had with react as well, and
especially coming from XBL something I am unhappy about with custom
elements. Having to either create dom nodes with javascript or using
some form of templating system kills the great separation I am used to
with XBL. Similarly, styling information needs to be within the node
somehow, so it ends up being within the javascript. I think currently
there aren't a lot of ways go resolve this, as long as web components
are defined in js. You can have separate files and load them using
DOMParser and friends. You can use template strings as well.

What I've been doing for now is to make the style and content static
getters on the element. This at least allows some degree of separation
and avoids manual dom node creation. There are certainly some things
that could be generalized into a super class. See here for example:
https://github.com/kewisch/quickmove-extension/blob/webextension/popup/folderlist.js
. When these components are being re-used you could also do the parsing
into a document fragment once in a static method and then re-use that on
each instance.

For your example, the model would be separate from any custom element. A
controller for the window would be responsible for retrieving that data,
and feeding it to the custom element. Maybe both the pill based and
plain UIs would have the same setters, so switching would just be a
matter of the controller determining the preference and then swapping
out the elements. The add-ons argument is a whole other can of worms,
though of course a good architecture would indeed make it easier to
integrate.

I think this might be a good topic to explore further and maybe even
blog about. Thanks Paul for venturing into this, I'm glad we are
spending time on the architecture of Thunderbird and not only patching
holes.

Philipp

On 10/11/19 8:07 PM, Paul Morris wrote:

Hi all,

I wanted to share some thoughts on custom elements (CEs) and how they
relate to UI patterns that separate model from view -- various themes
and variations on MVC (model, view, controller):

https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

Basically, CEs don't encourage separation of model and view
(data/state and presentation).  One of the main things they offer over
plan HTML is letting you couple JS logic with a particular piece of
HTML/CSS UI.  One of their main use cases was to bundle all of that up
into self-contained units that could be dropped wherever but not
de-composed.  (I.e. put a google maps widget on your website.)  In
short, they enable and tend to encourage keeping state in DOM
nodes/local component state, which couples the model and view together.

Separating model and view is a pretty well established UI approach
with various benefits.  MVC dates from the 1970s, and more recently in
the web dev world we had a broad shift away from jQuery to React/Redux
etc.

While CEs make a lot of sense as an upgrade/migration path away from
XBL, I think it's worth considering as we go forward, whether we
should move towards greater separation between model and view in our
UI code.  I think there's a lot of unnecessary complexity and
brittleness in our UI code that could be improved by this kind of
separation of concerns.  Here are a couple of articles on this topic:

UI as an afterthought
Makes the general case really well.
https://medium.com/@mweststrate/ui-as-an-afterthought-26e5d2bb24d6

Choosing a web component Model
A short post I found that makes the comparison between web components
and MVC, etc.
https://medium.com/@daveford/choosing-a-web-component-model-f83bb9a8edae

Consider an example.  Just for sake of argument, say we wanted to
offer two UIs for entering recipients for a message, a plain text one
and a pill-based one, and we wanted to be able to toggle between them
on the fly.  Or maybe an addon wants to offer an alternative UI.

If we have the model separate from the view, then it is just a matter
of switching the view.  If we have our model coupled with one
particular view, then it is not so simple.

Consider addons that want to modify the UI (like "Conversations" or
"CardBook").  It would be much more feasible to see how that could
work if we had more separation between model and view.  It's easier to
imagine where WebExtensions APIs might hook in, in a world with
greater model/view separation.

Or consider making TB more scriptable via command line, etc.

These are just some preliminary thoughts I've had about this as I've
been working with CEs, and now as we move past de-XBL to moving the UI
forward.  Curious to hear what others think.

-Paul

Hi Paul, this is definitely an interesting topic. To me there are two areas to this, one being separating the HTML from Javascript (view from controller), and the other being separating the view/controller from the model. The latter point, to my mind, is pretty clear. Web Components should not have any model code. They should be re-usable widgets that are self-contained. The way they get their model data is setters, which will re-render as appropriate. This means the controller that drives the window those elements are in will need to update those custom elements by getting from the model and setting on the custom element. The former point is a complaint I've had with react as well, and especially coming from XBL something I am unhappy about with custom elements. Having to either create dom nodes with javascript or using some form of templating system kills the great separation I am used to with XBL. Similarly, styling information needs to be within the node somehow, so it ends up being within the javascript. I think currently there aren't a lot of ways go resolve this, as long as web components are defined in js. You can have separate files and load them using DOMParser and friends. You can use template strings as well. What I've been doing for now is to make the style and content static getters on the element. This at least allows some degree of separation and avoids manual dom node creation. There are certainly some things that could be generalized into a super class. See here for example: https://github.com/kewisch/quickmove-extension/blob/webextension/popup/folderlist.js . When these components are being re-used you could also do the parsing into a document fragment once in a static method and then re-use that on each instance. For your example, the model would be separate from any custom element. A controller for the window would be responsible for retrieving that data, and feeding it to the custom element. Maybe both the pill based and plain UIs would have the same setters, so switching would just be a matter of the controller determining the preference and then swapping out the elements. The add-ons argument is a whole other can of worms, though of course a good architecture would indeed make it easier to integrate. I think this might be a good topic to explore further and maybe even blog about. Thanks Paul for venturing into this, I'm glad we are spending time on the architecture of Thunderbird and not only patching holes. Philipp On 10/11/19 8:07 PM, Paul Morris wrote: > Hi all, > > I wanted to share some thoughts on custom elements (CEs) and how they > relate to UI patterns that separate model from view -- various themes > and variations on MVC (model, view, controller): > > https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller > > Basically, CEs don't encourage separation of model and view > (data/state and presentation).  One of the main things they offer over > plan HTML is letting you couple JS logic with a particular piece of > HTML/CSS UI.  One of their main use cases was to bundle all of that up > into self-contained units that could be dropped wherever but not > de-composed.  (I.e. put a google maps widget on your website.)  In > short, they enable and tend to encourage keeping state in DOM > nodes/local component state, which couples the model and view together. > > Separating model and view is a pretty well established UI approach > with various benefits.  MVC dates from the 1970s, and more recently in > the web dev world we had a broad shift away from jQuery to React/Redux > etc. > > While CEs make a lot of sense as an upgrade/migration path away from > XBL, I think it's worth considering as we go forward, whether we > should move towards greater separation between model and view in our > UI code.  I think there's a lot of unnecessary complexity and > brittleness in our UI code that could be improved by this kind of > separation of concerns.  Here are a couple of articles on this topic: > > UI as an afterthought > Makes the general case really well. > https://medium.com/@mweststrate/ui-as-an-afterthought-26e5d2bb24d6 > > Choosing a web component Model > A short post I found that makes the comparison between web components > and MVC, etc. > https://medium.com/@daveford/choosing-a-web-component-model-f83bb9a8edae > > Consider an example.  Just for sake of argument, say we wanted to > offer two UIs for entering recipients for a message, a plain text one > and a pill-based one, and we wanted to be able to toggle between them > on the fly.  Or maybe an addon wants to offer an alternative UI. > > If we have the model separate from the view, then it is just a matter > of switching the view.  If we have our model coupled with one > particular view, then it is not so simple. > > Consider addons that want to modify the UI (like "Conversations" or > "CardBook").  It would be much more feasible to see how that could > work if we had more separation between model and view.  It's easier to > imagine where WebExtensions APIs might hook in, in a world with > greater model/view separation. > > Or consider making TB more scriptable via command line, etc. > > These are just some preliminary thoughts I've had about this as I've > been working with CEs, and now as we move past de-XBL to moving the UI > forward.  Curious to hear what others think. > > -Paul >
PM
Paul Morris
Thu, Oct 31, 2019 7:57 PM

Hi Philipp and Alessandro,

I like the approach Philipp laid out below, especially concerning
separation between models and views.

I don't have as strong a feel for the need for separation between
controller and view (e.g. JS and HTML).  That probably shows how I've
been influenced by React, and the uni-directional data flow
approach[0][1].  In any case our options there seem more limited, and
Philipp's approach/example of making "the style and content static
getters on the element" makes sense to me.

So there would be one controller object for any given window. I'm less
clear on what the model part might look like.  Would it be one model
object per component/custom element, one model per window, or something
else?

Custom elements would have event listeners on them for user input, but
(for separation between view and controller) they would respond to user
input events by say calling functions in the controller code, passing
along the relevant data, and letting the controller code handle them. 
So that's another piece of how this could work.

-Paul

[0]
https://www.exclamationlabs.com/blog/the-case-for-unidirectional-data-flow/
[1]
https://vaibhavgupta.me/2018/01/07/bidirectional-vs-unidirectional-data-flow-architecture/

On 10/12/19 8:07 AM, Philipp Kewisch wrote:

Hi Paul,

this is definitely an interesting topic. To me there are two areas to
this, one being separating the HTML from Javascript (view from
controller), and the other being separating the view/controller from
the model.

The latter point, to my mind, is pretty clear. Web Components should
not have any model code. They should be re-usable widgets that are
self-contained. The way they get their model data is setters, which
will re-render as appropriate. This means the controller that drives
the window those elements are in will need to update those custom
elements by getting from the model and setting on the custom element.

The former point is a complaint I've had with react as well, and
especially coming from XBL something I am unhappy about with custom
elements. Having to either create dom nodes with javascript or using
some form of templating system kills the great separation I am used to
with XBL. Similarly, styling information needs to be within the node
somehow, so it ends up being within the javascript. I think currently
there aren't a lot of ways go resolve this, as long as web components
are defined in js. You can have separate files and load them using
DOMParser and friends. You can use template strings as well.

What I've been doing for now is to make the style and content static
getters on the element. This at least allows some degree of separation
and avoids manual dom node creation. There are certainly some things
that could be generalized into a super class. See here for example:
https://github.com/kewisch/quickmove-extension/blob/webextension/popup/folderlist.js
. When these components are being re-used you could also do the
parsing into a document fragment once in a static method and then
re-use that on each instance.

For your example, the model would be separate from any custom element.
A controller for the window would be responsible for retrieving that
data, and feeding it to the custom element. Maybe both the pill based
and plain UIs would have the same setters, so switching would just be
a matter of the controller determining the preference and then
swapping out the elements. The add-ons argument is a whole other can
of worms, though of course a good architecture would indeed make it
easier to integrate.

I think this might be a good topic to explore further and maybe even
blog about. Thanks Paul for venturing into this, I'm glad we are
spending time on the architecture of Thunderbird and not only patching
holes.

Philipp

On 10/11/19 8:07 PM, Paul Morris wrote:

Hi all,

I wanted to share some thoughts on custom elements (CEs) and how they
relate to UI patterns that separate model from view -- various themes
and variations on MVC (model, view, controller):

https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

Basically, CEs don't encourage separation of model and view
(data/state and presentation).  One of the main things they offer
over plan HTML is letting you couple JS logic with a particular piece
of HTML/CSS UI.  One of their main use cases was to bundle all of
that up into self-contained units that could be dropped wherever but
not de-composed.  (I.e. put a google maps widget on your website.) 
In short, they enable and tend to encourage keeping state in DOM
nodes/local component state, which couples the model and view together.

Separating model and view is a pretty well established UI approach
with various benefits.  MVC dates from the 1970s, and more recently
in the web dev world we had a broad shift away from jQuery to
React/Redux etc.

While CEs make a lot of sense as an upgrade/migration path away from
XBL, I think it's worth considering as we go forward, whether we
should move towards greater separation between model and view in our
UI code.  I think there's a lot of unnecessary complexity and
brittleness in our UI code that could be improved by this kind of
separation of concerns.  Here are a couple of articles on this topic:

UI as an afterthought
Makes the general case really well.
https://medium.com/@mweststrate/ui-as-an-afterthought-26e5d2bb24d6

Choosing a web component Model
A short post I found that makes the comparison between web components
and MVC, etc.
https://medium.com/@daveford/choosing-a-web-component-model-f83bb9a8edae

Consider an example.  Just for sake of argument, say we wanted to
offer two UIs for entering recipients for a message, a plain text one
and a pill-based one, and we wanted to be able to toggle between them
on the fly.  Or maybe an addon wants to offer an alternative UI.

If we have the model separate from the view, then it is just a matter
of switching the view.  If we have our model coupled with one
particular view, then it is not so simple.

Consider addons that want to modify the UI (like "Conversations" or
"CardBook").  It would be much more feasible to see how that could
work if we had more separation between model and view. It's easier to
imagine where WebExtensions APIs might hook in, in a world with
greater model/view separation.

Or consider making TB more scriptable via command line, etc.

These are just some preliminary thoughts I've had about this as I've
been working with CEs, and now as we move past de-XBL to moving the
UI forward.  Curious to hear what others think.

-Paul

--
Paul Morris
Thunderbird.net

Hi Philipp and Alessandro, I like the approach Philipp laid out below, especially concerning separation between models and views. I don't have as strong a feel for the need for separation between controller and view (e.g. JS and HTML).  That probably shows how I've been influenced by React, and the uni-directional data flow approach[0][1].  In any case our options there seem more limited, and Philipp's approach/example of making "the style and content static getters on the element" makes sense to me. So there would be one controller object for any given window. I'm less clear on what the model part might look like.  Would it be one model object per component/custom element, one model per window, or something else? Custom elements would have event listeners on them for user input, but (for separation between view and controller) they would respond to user input events by say calling functions in the controller code, passing along the relevant data, and letting the controller code handle them.  So that's another piece of how this could work. -Paul [0] https://www.exclamationlabs.com/blog/the-case-for-unidirectional-data-flow/ [1] https://vaibhavgupta.me/2018/01/07/bidirectional-vs-unidirectional-data-flow-architecture/ On 10/12/19 8:07 AM, Philipp Kewisch wrote: > Hi Paul, > > this is definitely an interesting topic. To me there are two areas to > this, one being separating the HTML from Javascript (view from > controller), and the other being separating the view/controller from > the model. > > The latter point, to my mind, is pretty clear. Web Components should > not have any model code. They should be re-usable widgets that are > self-contained. The way they get their model data is setters, which > will re-render as appropriate. This means the controller that drives > the window those elements are in will need to update those custom > elements by getting from the model and setting on the custom element. > > The former point is a complaint I've had with react as well, and > especially coming from XBL something I am unhappy about with custom > elements. Having to either create dom nodes with javascript or using > some form of templating system kills the great separation I am used to > with XBL. Similarly, styling information needs to be within the node > somehow, so it ends up being within the javascript. I think currently > there aren't a lot of ways go resolve this, as long as web components > are defined in js. You can have separate files and load them using > DOMParser and friends. You can use template strings as well. > > What I've been doing for now is to make the style and content static > getters on the element. This at least allows some degree of separation > and avoids manual dom node creation. There are certainly some things > that could be generalized into a super class. See here for example: > https://github.com/kewisch/quickmove-extension/blob/webextension/popup/folderlist.js > . When these components are being re-used you could also do the > parsing into a document fragment once in a static method and then > re-use that on each instance. > > For your example, the model would be separate from any custom element. > A controller for the window would be responsible for retrieving that > data, and feeding it to the custom element. Maybe both the pill based > and plain UIs would have the same setters, so switching would just be > a matter of the controller determining the preference and then > swapping out the elements. The add-ons argument is a whole other can > of worms, though of course a good architecture would indeed make it > easier to integrate. > > I think this might be a good topic to explore further and maybe even > blog about. Thanks Paul for venturing into this, I'm glad we are > spending time on the architecture of Thunderbird and not only patching > holes. > > Philipp > > > > > On 10/11/19 8:07 PM, Paul Morris wrote: >> Hi all, >> >> I wanted to share some thoughts on custom elements (CEs) and how they >> relate to UI patterns that separate model from view -- various themes >> and variations on MVC (model, view, controller): >> >> https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller >> >> Basically, CEs don't encourage separation of model and view >> (data/state and presentation).  One of the main things they offer >> over plan HTML is letting you couple JS logic with a particular piece >> of HTML/CSS UI.  One of their main use cases was to bundle all of >> that up into self-contained units that could be dropped wherever but >> not de-composed.  (I.e. put a google maps widget on your website.)  >> In short, they enable and tend to encourage keeping state in DOM >> nodes/local component state, which couples the model and view together. >> >> Separating model and view is a pretty well established UI approach >> with various benefits.  MVC dates from the 1970s, and more recently >> in the web dev world we had a broad shift away from jQuery to >> React/Redux etc. >> >> While CEs make a lot of sense as an upgrade/migration path away from >> XBL, I think it's worth considering as we go forward, whether we >> should move towards greater separation between model and view in our >> UI code.  I think there's a lot of unnecessary complexity and >> brittleness in our UI code that could be improved by this kind of >> separation of concerns.  Here are a couple of articles on this topic: >> >> UI as an afterthought >> Makes the general case really well. >> https://medium.com/@mweststrate/ui-as-an-afterthought-26e5d2bb24d6 >> >> Choosing a web component Model >> A short post I found that makes the comparison between web components >> and MVC, etc. >> https://medium.com/@daveford/choosing-a-web-component-model-f83bb9a8edae >> >> Consider an example.  Just for sake of argument, say we wanted to >> offer two UIs for entering recipients for a message, a plain text one >> and a pill-based one, and we wanted to be able to toggle between them >> on the fly.  Or maybe an addon wants to offer an alternative UI. >> >> If we have the model separate from the view, then it is just a matter >> of switching the view.  If we have our model coupled with one >> particular view, then it is not so simple. >> >> Consider addons that want to modify the UI (like "Conversations" or >> "CardBook").  It would be much more feasible to see how that could >> work if we had more separation between model and view. It's easier to >> imagine where WebExtensions APIs might hook in, in a world with >> greater model/view separation. >> >> Or consider making TB more scriptable via command line, etc. >> >> These are just some preliminary thoughts I've had about this as I've >> been working with CEs, and now as we move past de-XBL to moving the >> UI forward.  Curious to hear what others think. >> >> -Paul >> > -- Paul Morris Thunderbird.net