cubbles / cubx.core.rte

Contains the artifacts for the in-browser runtime-environment.
https://cubbles.atlassian.net/wiki/display/RTE
1 stars 1 forks source link

POC: Make <cubx-core-slot-init> extend HTMLScriptElement #27

Closed pwrinc closed 5 years ago

pwrinc commented 6 years ago

To enable page editors set HTML markup as slot init values we need to enable <cubx-core-slot-init> tag to handle HTML markup without making the browser interpret it as HTML markup.

Idea: Make <cubx-core-slot-init> cutoms element extend the HTMLScriptElement to prevent browsers from interpreting <cubx-core-slot-init> tags content as HTML.

Scenarios to test:

edwingamboa commented 6 years ago

A demo in which the <cubx-core-slot-init> extends from HTMLScriptElement is available online.

However, extending from HTMLScriptElement does not allow having HTML markup code as slot values because the <cubx-core-slot-init> is not rendered in the same way as a <script> element.

edwingamboa commented 6 years ago

A possibility would be to set the slot value as the value of an attribute and not as innerHTML.; e.g.,

<cubx-core-slot-init slot="htmlCode" value="<b>Hi</b>"></cubx-core-slot-init>

Or extending the <script> element directly as explained here or here (old way to create custom elements). In that case, the code would look as follows:

var SlotInit = document.registerElement('cubx-core-slot-init', {
  prototype: Object.create(HTMLScriptElement.prototype),
  extends: 'script'
});
<script is="cubx-core-slot-init" slot="htmlCode">"<p>a</p>"</script>

Note that the tag name is script. The additional behaviour should be programmed in SlotInit class

hrbu commented 6 years ago

https://stackoverflow.com/questions/25007568/custom-html-element-extending-the-script-element

edwingamboa commented 6 years ago

@HD I had already check that thread in StackOverflow. Actually, the implementation in the demo that I created is the one suggested there. The problem is that it allows implementing the HTMLScriptElement interface, but not the script element itself. Therefore, when the extended element is displayed in the browser, its innerHTML is displayed as a normal HTML element.

The correct way to extend the script element itself is, as a I have mentioned previously, using the script tag with attribute "is":

var SlotInit = document.registerElement('cubx-core-slot-init', {
  prototype: Object.create(HTMLScriptElement.prototype),
  extends: 'script'
});
<script is="cubx-core-slot-init" slot="htmlCode">"<p>a</p>"</script>
hrbu commented 6 years ago

... i just mentioned to underline you are right 😉.

Maybe we go for the property (value="...") approach. What do you think?

edwingamboa commented 6 years ago

Okay :). And, I agree that the best approach would be using a value attribute.

jtrs commented 6 years ago

Consider this implementation of steel-module: https://jsbin.com/gukanujuku/edit?html,js,output Attention: @edwingamboa used the outdated v1 version of custom-elements. But like this diskussion https://github.com/stealjs/steal/issues/1308, is not possible extend HTMLScriptElement.

Hmm... Look at https://bugs.chromium.org/p/chromium/issues/detail?id=808311. Is this Bug already fixed in chromium?

edwingamboa commented 6 years ago

@hrbu @jtrs @pwrinc I tried something similar the steal-component mentioned by @jtrs.

I have implemented two versions, with and without using the shadow root. I have also override the getter of innerHTML to return innerHTML of the inner script containing the slotValue.

The demo can be checked here.

However, I noticed that the script containing the new element definition should be imported after the <cubx-core-slot-init> tag in the HTML document. Otherwise, accessing the innerHTML property of the <cubx-core-slot-init> in the connectedCallback(). But waiting until DOMContentLoaded event to define the element solves the issue.

It should be tested in CIF.

pwrinc commented 6 years ago

Problem: When providing valid JS expression as init value it will get executed:

<cubx-core-slot-init slot="htmlCode">alert('hello 2');</cubx-core-slot-init>

Desired behaviour: Script should net get executed. Solution: https://jsfiddle.net/oxr4hkzf/ Decision: We will not use shadow DOM.

edwingamboa commented 6 years ago

The demo was tested locally. I updated it showing different types of JSON values. Also, before showing values and the textarea, I perform a JSON.parse as in CIF initialiser L#234. Is presented the user uses non-valid JSON values, it would be recognised. The demo is available in: https://jsfiddle.net/edwingamboa/oxr4hkzf/25/

frank-dspeed commented 4 years ago

Only to make the issue here correct stealjs/steal#1308 shows that this is possible i had a working poc at end of that issue :D