Skip to content
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

Redesign flow to build a partial. #8

Closed
tomalec opened this issue Mar 25, 2014 · 19 comments
Closed

Redesign flow to build a partial. #8

tomalec opened this issue Mar 25, 2014 · 19 comments

Comments

@tomalec
Copy link
Member

tomalec commented Mar 25, 2014

We are facing more, and more issues that suggest we should reconsider overall design of <x-html>.

I have decided to create this umbrella issue, to track general discussions about new designs, and flows.

Here is the list of issues that, led us here:

@tomalec
Copy link
Member Author

tomalec commented Mar 25, 2014

There were and are many ideas, but for now I'll describe my recent one:

I have already submitted a proposition to change <x-html> to <template is="x-html"> (. It seems to give many benefits:

  1. First, of all, as it is <template> we will get .model out of the box (Model binding does not work in Polymer 0.2.2 #7),
  2. We would not have to wrap every <x-html> with <template bind="{{scope}}"> as we can do it with <template is="x-html" bind="{{scope}}"> (see example ),
  3. It will be absolutely clear now, that scripts and HTML Imports are handled exactly as in any other <template>.(Sometimes <script>'s are being executed before HTML was attached to DOM. #3, External script support #6)
    If we would like to change also this behavior I believe we should do it with other Custom Element (probably by extending this one) (Polyjuice/Launcher#10)
  4. Partial content will naturally appear as element's siblings (Polyjuice/Launcher#12)
  5. It works with current (Polymer#master(23044b02e0)).

I believe, that it will give us fully featured <template> simply extended by safe-HTML support, without messing with/blocking/re-implementing any other stuff

@warpech
Copy link
Contributor

warpech commented Mar 25, 2014

Would it still support two usage scenarios that we have right now?

<template is="x-html" bind content="<b>Some HTML</b>"></template>
<template is="x-html" bind content="./partial.html"></template>

Point 4 seems to be the biggest winner for me.

Points 1-2 are implementation details, that don't matter now.

Point 3 is where we lose the current syntactic sugar. Could we please further investigate if it is possible for scripts to be handled exactly as in an HTML Import? (from my test it looks that they load with blocking, which is what we want). I agree that this can be another Custom Element that extends this one, I would just use it instead.

@tomalec
Copy link
Member Author

tomalec commented Mar 25, 2014

Yes, it will. Please take a look at examples.

Regarding 3., I'm affraid, just HTML Import behavior is not entirely what
we want, as it runs script when loaded, and cannot be imported more than
once.
But still, we can cover subpage scenario and control scripts flow with new
Element.

@Starcounter-Jack
Copy link

I think we can keep support for the simplicity of the old <x-html> tag and still cater for big and complex partials.

In this post, I will use the old name <x/html> although it will probably be renamed.

We need two versions of <x-html>. One to stamp out a singleton and one to enhance a <template> element. Otherwise, they should work the same.

<template is="html-import" src="/test.html"></template>
<x-html src="/test.html"></x-html>

The html-import element

It uses the <link rel="import"> standard. In this way, the user can enjoy things as dependency management (not loading the same stuff many times) and script execution order (the script manipulating the instance will run once for every stamp-out and the other stuff will only run once). The good part is that the behavior is (will be) well documented by the W3C. But to keep the simplicity of the old use-case and to allow the developer not to know about templates and html imports, we also provide a fall back that allows for ill-behaved or simple partials.

Ill-behaved partials

An ill behaved partial will believe it is the only instance in the document. It will use document.getElementById() or $("mything") and risk on addressing other elements than inside its own scope. This will lead to a very unstable system.

Providing protection

There are basically three levels of encapsulation available.

  1. Global DOM
  2. Shadow DOM
  3. <iframe>

The idea is to avoid the <iframe> only when it is safe.

Detecting ill behaved partials

The imported document fragement from test.html will be queried for a <template> and a <title>

  1. If there is a no <title>, we will consider this a well behaved partial
  2. If not, we will consider this an ill behaved partial (there is one exception, see below)

Dealing with ill-behaved partials

If it is an ill behaved partial, we will put it in an <iframe> if it contains a <title>. If not, we can upgrade the fragment to being well behaved. There is no Javascript, so a shadow dom is a better option. In this way, we provide the same functionality as for the old <x-html> tag and also allow for inline html.

Well behaved partials

The well behaved partial will be put it the shadow dom. The well behaved partial will be responsible for not leaking its logic. Shadow DOM should be used for individual parts of the partial to allow mixing while at the same time protecting internal styling.

The x-html element

Same as the template but creates an instance in the DOM.

@tomalec
Copy link
Member Author

tomalec commented Mar 25, 2014

I'm going to start development of <template is="html-import">, but I doubt if html-import is the name we should use, as it could lead to confusion with W3C HTML Imports. Maybe template-import? - it is not so confusing when used alone, however, in code <template is="template-import"> looks a bit weird.

BTW, are we going to keep current <x-html> as it is or are we going to use <template is="x-html"> as I proposed in here which is in my opinion serves exactly same functionality but cleaner and minimized.

@Starcounter-Jack
Copy link

To summarise:

  1. The well behaved partials should be put in the shadow dom.
  2. The ill behaved partials should be put in an <iframe>

We detect the existence of a <title> element to identify who is who.

@Starcounter-Jack
Copy link

Example of a naive but (hopefully) well behaved partial

<div>
I'm well behaved because I have no title. I do not believe I'm on my own.
</div>
<script>
what.is.going.on();
</script>

@Starcounter-Jack
Copy link

Example of an ill-behaved partial

<head>
   <script src="lib/jquery.js"></script>
   <title>I'm my own boss</title>
</head>
<div id="main">
   I will be put in an iframe because I might believe I'm on my own (and I do scripting).
   Please contain me.
</div>
<script>$("main").textContent = "Typical me";</script>

@Starcounter-Jack
Copy link

Example of a performant and well behaved partial

<link rel="import" href="lib/jquery.html"> <!-- well behaved partials can load dependencies as
                                                they are guaranteed not to run multiple times --->
<template>
   <div>I might be cloned in many places in the document</div>
   </template>
   <script>
      console.log("I will run whenever I'm stamped out in by an owner document");
   </script>
</template>
<script>I will run only once</script>

@Starcounter-Jack
Copy link

Simple partials

<link rel="import" href="lib/handsontable.html">
<div>{{FirstName}} {{LastName}}</div>

@Starcounter-Jack
Copy link

Simple partials

<div>hello world</div>

@Starcounter-Jack
Copy link

How do we detect well behaved partials?

@tomalec
Copy link
Member Author

tomalec commented Mar 25, 2014

Difference between x-html and new element, names:

For simple use cases, when we need to put just HTML (either inline or from file), without any additional magic, or scripting solutions, there will be current <x-html>

<template is="x-html" content="./file.html" bind></template>
<template is="x-html" content="<li>{name}</li>" repeat="{{person in people}}"></template>

as a extended <template>. That gives us benefits described above.

To get better control over scripting inside template we need additional extension for <template is="x-html">, that will add with some HTML Imports features, and handle various scenarios of partial's content.

<template is="imported-template" content="./file.html" bind></template>

Partials detection

At first attempt lets try something simple:

Well behaved partial

Partial that is aware that it could be replicated, and delivers <template> to clone, as well as <script>,<link>s, etc. that will be used only once.

  • contain <template> on root level
<link rel="import" href="my/custom/element.html">
<script src="external.js"></script>
<template>
    <my-element><strong>{{Name}}</strong></my-element>
    <script>console.log("my-element stamped");</script>
</template>

Ill behaved (<iframe>)

  • does not contain <template> on root level
  • but does contain at least one <script>, or <link>
<script src="external.js"></script>
<div><h1>My App</h1></div>
<script>console.log("My App rule the world!");</script>

Simple partial

Something that we can simply put as document fragment to <template>.content

  • HTML given as string
  • HTML file (document) that does not contain neither <script>, <link>, nor <template>
<li><strong>{{Name}}</strong></li>

@tomalec
Copy link
Member Author

tomalec commented Mar 26, 2014

I'm afraid there will be a problem with handling ill behaved ones.
We cannot query HTML document to load before, well.. loading it first.
So if we are going to use HTML Imports, scripts from ill behaved partial will be already executed.
If we are going to do XHR as before, then we will need to perform it also for well behaved ones,, and for every single instance of template (unless we will implement some caching magic), and then, we would need to parse entire document.

For sure, it would be way much simpler if ill behaved flag would be given from outside as attribute.
Then someone responsible for providing URL for HTML file, would be responsible also for providing information if it is a ill behaved or well behaved (simple vs. composite partial could be easily distinguished by our Element)
Current examples available in here

@tomalec
Copy link
Member Author

tomalec commented Mar 26, 2014

There is also a problem with putting well behaved ones into ShadowDOM, as it will break partials that were designed to server multiple nodes on root level, for examples merged output from Polujuice/Launcher.
To solve this we will probably need, any of those:

  1. a feature to handle multiple templates in single partial,
  2. put <sortable-list> element into merged partial,
  3. change Launcher's merging flow even more.

@Starcounter-Jack I'm afraid we should reconsider changing design once again.

@Starcounter-Jack
Copy link

Good point. Let's assume they are well behaved for now. We need to work against the demo.

Sent from my iPhone

On 26 Mar 2014, at 18:19, Tomek Wytrębowicz notifications@github.com wrote:

I'm afraid there will be a problem with handling ill behaved ones.
We cannot query HTML document to load before, well.. loading it first.
So if we are going to use HTML Imports, scripts from ill behaved partial will be already executed.
If we are going to do XHR as before, then we will need to perform it also for well behaved ones,, and for every single instance of template (unless we will implement some caching magic), and then, we would need to parse entire document.

For sure, it would be way much simpler if ill behaved flag would be given from outside as attribute.
Then someone responsible for providing URL for HTML file, would be responsible also for providing information if it is a ill behaved or well behaved (simple vs. composite partial could be easily distinguished by our Element)


Reply to this email directly or view it on GitHub.

@Starcounter-Jack
Copy link

Let's do it first thing in the morning (hangout)

On 26 Mar 2014, at 23:23, Tomek Wytrębowicz notifications@github.com wrote:

There is also a problem with putting well behaved ones into ShadowDOM, as it will break partials that were designed to server multiple nodes on root level, for examples merged output from Polujuice/Launcher.

@Starcounter-Jack I'm afraid we should reconsider changing design once again.


Reply to this email directly or view it on GitHub.

@tomalec
Copy link
Member Author

tomalec commented Mar 27, 2014

I have an idea how could we solve ShadowDOM issue, add support for <content></content> syntax in our <imported-template> as it works in native <template>. So we could write:

<template is="imported-template">
  <sortable-list order="{{order}}">
    <content></content>
  </sortable-list>
</template>

But i still do not have any idea how to solve iframe detection on client side.

@warpech
Copy link
Contributor

warpech commented Jun 25, 2014

This issue has been solved back in March/April. In result, 2 options are available:

@warpech warpech closed this as completed Jun 25, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants