Defining Polymer web components without importing them - polymer

Is there a way to define Polymer web components directly in the HTML file for the page where they're used instead of importing them through link tags?
This seems like it would be faster vs having to request a page and then send requests for the web component html files as well. So far all the guides I've seen only reference importing via <link rel="import" href="/my_component.html" />.

You can use Polymer Bundler to reduce the number of network requests concatenating web components and dependencies in one file. You can find more info here.

As suggested in the other answer, it seems like a better approach to worry more about having a clear structure of your files/elements while you're developing, and to let a build script worry about stuff like that.
But since a bundler would basically do the same thing, define all the elements in a file, it's obviously possible. So only to answer the initial question, you can see a sample here.
So you just have to use multiple dom-module tags like:
<dom-module id="my-element">
...
</dom-module>
<dom-module id="my-inner-element">
...
</dom-module>
And multiple calls to customElements.define:
customElements.define(MyElement.is, MyElement);
customElements.define(MyInnerElement.is, MyInnerElement);
But I would most certainly recommend against writing your entire application in a single file.

Related

Move 2sxc <script> to external file when it has razor content

I'm trying to make my CSP without unsafe inline.
Since I have to manually check every file from every app, I may as well move the scripts to external files instead of creating a million word CSP entry in the web.config by adding hashes or nounces.
This seems easy enough for client side content, but many templates have razor code in then such as:
<script>
alert(#myVar);
</script>
How can I move this to external?
So in general if you JS needs some input parameters you must of course put them somewhere, and only the razor will know what they are.
The simplest way is still to just have the initial call use the variables - like in your example above. If you have security concerns, doing type-checking in razor should eliminate that for you.
For example, if you do #((int)thing.property) than it simply cannot inject any unexpected payload.
If for some reason you really, really don't want this you can use a attribute-json convention, like
<div class="myGallery" init='{"files": 17}'> gallery contents </div>
and pick it up from the js you created. but this is quite a bit of work, so I would recommend the simpler way.

What is an HTML Module?

What exactly is HTML Modules? I understand that it might allow a developer to create HTML as a module like how ES6 Modules are to JavaScript.
But, are these modules basically templates like Mustache, Handlebars and Pug? Or is it like a wrapper around a similar templating system that will allow us to import an HTML file easily into another HTML file?
Will it pave a way to avoid using templating libraries utilizing the Web Components?
[Update]
Here is the link to where I found this - https://github.com/w3c/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md
HTML Modules are the new proposal for importing HTML files into a document.
HTML import supported a similar feature and permitted to import an HTML file (eventually containing itself JS and CSS) but it has been deprecated and JS module import has partially substituted that feature.
The point of HTML imports are to complete that part and make possible to import HTML files again instead of JavaScript files only.
Today you just can't import files that contain HTML (again, you could do that when meta rel=import href=myfile.html> which is not supported anymore).
If you want to do that, you have to write HTML in JavaScript string prior to process it.
The proposal also introduces notions such as import.meta.document that refer to the internal document to be imported.
Note that is it a proposal, even though it could be inserted into the spec, it should then be implemented by browsers, and finally adopted by the community in order to remain and become a stable feature.
Currently the closest you can use is the Lego Web-Component library that allows to include HTML as a module and extends native HTML functionality:
<template>
<p>Hello World!</p>
</template>
Used as:
<script src="./dist/index.js" type="module"></script>
<hello-world />
Example taken from https://github.com/polight/lego#hello-world
Let's see how the spec is going to evolve for HTML Modules in the futureā€¦

Modules in Polymer

In my react projects I have been using ES6 modules for some time. In my react component I would use import:
import {f1,f2} from "./myLib";
In my polymer component I use a script tag:
<script src="./myLib.js"></script>
If I'm not mistaken, these are doing two totally different things. The script tag is polluting my global namespace for the whole app. The import isn't.
Question #1: Am I correct in my understanding of this?
Question #2: Is there a way to get something similar in polymer?
I have dozens of different polymer components. Some import conflicting libraries. Then, if I have a page that uses multiple components it seems like a crap shoot as to which version of the JS script I will get.
It is certainly possible to use ES6 modules with Polymer. First thing you will have to do is split the template and script. You can then go both ways
Add a script tag containing transpiled ES6 code to the element's html:
<dom-module id="my-elem"></dom-module>
<script src="my-elem.js"></script>
Use some kind of plugin to import HTML from ES6 code. This is, for example, possible with this plugin for SystemJS
import './my-elem.html!';
class MyElem extends HTMLElement {}
document.registerElement('my-elem', MyElem);
Then the difficult part is then transpiling. I'm not sure about other module loaders, but with JSPM+SystemJS it is easy to bundle as an Universal module. This way your element will be usable both by <link rel="import" href="bower_components/my-elem/my-elem.html"> and for importing from other ES6 code. In the former case any dependencies not bundled will have to live in the global scope. You could, however, place any such dependencies in your main html file. Just like many other elements are published.
If you're willing to give JSPM+SystemJS a try, please have a look at a blog post on my blog. I'm using TypeScript but for ES6 the general solution should be roughly the same.

Polymer HTML Import caching

I want to make sure that the browser gets the latest version of my custom elements via HMLT import. Right now, I am attaching a version query string:
e.g.
<link rel="import" href="/dist/elements/my-element.html?v=12345">
This is a common practice for JS and CSS files, and I am wondering if this is valid approach for HTML Imports as well?
Yes, the same principles apply.
As an example, take a look at the source of http://www.polymer-project.org/. At the time of this writing, it contains <link rel="import" href="http://www.polymer-project.org/elements/homepage_elements.vulcanized.html?20140828">.
P.S. Described query parameter is not used at http://www.polymer-project.org/ anymore.

Reusable view components in HTML

Can you create reusable components in html? Let's say I want to encapsulate some css / html and js into a tidy reusable component. How do web developers do this? I'm coming from the Flex, C# side of the planet.
2017 update
This question is 7 years old and a lot has changed since. Web components and are now implemented or can be used with polyfills in every major browser. Which means you can use Polymer by Google or X-Tag supported by Microsoft made exactly for this.
Sample approach using Polymer:
custom tag declaration in custom-tag.html:
<dom-module id="custom-tag">
<template>
<style>
h1 {
color: red;
}
</style>
<div class="text-holder">
<h1>[[name]]</h1>
<p>[[description]]</p>
</div>
</template>
</dom-module>
<script>
Polymer({
is: "custom-tag",
properties: {
name: String,
description: String
}
});
</script>
how to use custom tag in your page:
include tag in head:
<link rel="import" href="path/to/custom-tag.html"/>
and then:
<custom-tag
name="Lorem"
description="Lorem ipsum dolor sit amet.">
</custom-tag>
You'll need a simple http server because of the html import. Encapsulation you talked about is backed by Shadow DOM - javascript and css packed inside of custom tag won't "bleed out" and change anything outside of the element and vice versa (unless you force it). Polymer comes out with quite large asset of elements, you can find it here.
Everything about using elements and creating your own is covered here.
You can use Server-Side Includes to directly import pieces of HTML (e.g. a header), but most frameworks these days tend to approach things at a higher level, e.g. Apache Taglibs or Django templates.
It depends on your environment. HTML is (in a simple environ) often included with a server-side include (the syntax of which will depend on your server).
That way you could have:
<!-- #include header.html -->
<h1>Blog Page</h1>
<p>content...</p>
<!-- #include footer.html -->
Javascript is included externally so can be called from anywhere. If you're in a "simple" environment (no server-side code, CMS, etc) you might call module.js which in turn loads specific CSS styles and injects into the DOM the HTML you require.
If you're using a CMS of any sort, they will often have a module idea or plug-ins that wrap this up for you. What are you working with here?
Generally you can put snippets into a separate file that you can add in with a server side include:
<!--#include FILE="you_snippet.html" -->
If you have the option, you might want to have a look at some template languages like Apache Velocity. In Velocity, not only can you include different files, you can define macros that will generate the html for you.
You can try out the templating engines, like google closure template tools.
What you do here is basically create html layouts in a special file called soy files for which you are going to feed the data passed in as parameters and these data are going to be interpreted dynamically with javascript/java. Check out their tutorials, its pretty good. Closures are widely used in Gmail, Youtube and mostly all of Google's products.