Shared Polymer/webcomponents - polymer

I started on a project and wanted to wrap up a component and then share it to another project, however because of company constraints I can't publish it to github as per the documentation suggests.
I managed to share the component through IIS, however I am not sure if this is the best way, as the desired result is having a CDN like way of referencing components into applications.
Here is the code:
This is the component that i want to share: base-element.html
<!-- Imports polymer -->
<link rel="import" href="bower_components/polymer/polymer.html">
<!-- Defines element markup -->
<dom-module id="base-element">
<template>
<h3>Hello</h3>
</template>
<!-- Registers custom element -->
<script>
Polymer({
is: 'base-element',
// Fires when an instance of the element is created
created: function() {},
// Fires when the local DOM has been fully prepared
ready: function() {},
// Fires when the element was inserted into the document
attached: function() {},
// Fires when the element was removed from the document
detached: function() {},
// Fires when an attribute was added, removed, or updated
attributeChanged: function(attr, oldVal, newVal) {}
});
</script>
</dom-module>
Here is the bower.json file:
{
"name": "base-element",
"private": true,
"dependencies": {
"polymer": "Polymer/polymer#^1.2.0"
},
"devDependencies": {
"web-component-tester": "^4.0.0"
},
"ignore": []
}
In IIS i setup this as the main application then I setup a virtual app called client which then references this html file.
In the index.html file of the client app
<script src="bower_components/webcomponentsjs/webcomponents.js"></script>
<!-- endbower -->
<!-- endbuild -->
<link rel="import" href="../base-element.html"/>
Then in the view that I want to display the component:
<base-element></base-element>
This functions however, it would be nice if I could achieve this using grunt serve or something. Any suggestions?

A an idea, see my answer to my own question here How can I replace the server in Web Component Tester
This suggests using a proxy server to forward requests at for your base element to your main running server. (or another instance using a nodejs style server).

See if this helps - Using Bower as the Package Management tool for Internal, Private Libraries
You can share your component via a private repository and this can be included as a bower dependency. Check the documentation.

Related

Polymer Starter Kit adding function equivalent to ready for the main page

I've got a newly created polymer starter kit, 1.3 to be exact.
I would like to created a method like the one below, on the index.html page
ready: function() {
firebase.auth().onAuthStateChanged(function(user) {
if(user) {
// console.log('user is logged in');
} else {
// console.log('user is not logged in');
}
});
}
On the main page, how can I do it? I would like to instantiate a Polymer element for the application template, but the document stays that should be avoided. If anyone could explain why that would be awesome.
Thanks in advance for any feedback!
On the main page, how can I do it?
In index.html, you could use a WebComponentsReady handler to perform any action that's dependent on all elements being registered:
window.addEventListener('WebComponentsReady', function(e) {
// imports are loaded and elements have been registered
...
});
I would like to instantiate a Polymer element for the application template, but the document stays that should be avoided.
Where did you see that? While version 1.3.0 of the Polymer Starter Kit uses an auto-binding template in index.html instead of an app element, I don't see why you'd try to avoid an app element. In fact, there's growing evidence that an app element is recommended:
Version 2 of Polymer Starter Kit replaces the auto-binding template with a custom app element
The dev guide describes the Basic Application Template (generated by polymer-cli) as a custom element:
The application template is the most basic starting point for any app built with Polymer. It starts with a single bare-bones custom element that can serve as the root of your application, from which you can build in any direction with maximum flexibility.

How to use x3dom with polymer?

I have a polymer site where I'd like to use the x3dom library to view an external x3d file, and simply be able to rotate the loaded 3D scene 360 degrees.
Has anyone successfully used x3dom with polymer? I don't see any reason why this wouldn't work. Please assume I have all the polymer stuff correct (which I have) and have loaded the prerequisite x3dom.js script and x3dom.css in the head of the page too. This is just a stripped down code snippet to show key bits:
<x3d width='350px' height='400px'>
<scene>
<inline nameSpaceName="myNS" mapDEFToID="true" url="{{_x3dPath}}"></inline>
</scene>
</x3d>
<script>
Polymer({
properties: {
_x3dPath: {type: String},
},
ready: function() {
this._x3dPath = "/someDynamicPath/threeDfile.x3d";
}
});
</script>
Any suggestions?
You need to create a custom element that serves as a wrapper for the 3rd party library. (e.g x3dom-wrapper.html ).
Inside that file, you must add the script reference to x3dom .js
<script type="text/javascript" src='../bower_components/x3dom/x3dom.js'></script>
Then, you need to import the wrapper custom element like any other polymer component. That way you ensure the x3dom dependency will be available when you need it.
Edit:
Wrapping the library is still a good practice but not the cause of your problem. I did a quick test and found that you must call x3dom.reload() on your "ready" polymer event handler. That way x3dom system reloads properly

Bower Installed Polymer is broken but web hosted libraries work

I followed The Bower installation method to install the Polymer library as recommended on the Polymer Project website. Specifically, I ran these commands from the root of my project's live web folder. The OS is Amazon Linux:
bower init
bower install --save Polymer/polymer#^1.2.0
bower update
This generated the following files/folders:
/bower.json
/bower_components/*
/bower_components/polymer/*
/bower_components/webcomponentsjs/*
To test whether the libraries were successfully installed, I went ahead and grabbed one of the examples from the tutorial and tried it out. Only the first line of this code comes into question, but I'm including all of it to dispel concerns that the code here is at fault:
elements/proto-element.html
// THIS is the line that doesn't work. The file exists, it was
// installed in the correct location. However, the polymer.html file
// itself appears to be broken
<link rel="import" href="../bower_components/polymer/polymer.html">
// HOWEVER, if I change it to link the library in from the web, everything
// works perfectly. As in this example:
<!--<link rel="import" href="http://www.polymer-project.org/1.0/components/polymer/polymer.html">-->
<polymer-element name="proto-element">
<template>
<span>Hello World.</span>
</template>
<script>
Polymer({
ready: function() {
}
});
</script>
</polymer-element>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="bower_components/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="elements/proto-element.html">
</head>
<body>
<proto-element></proto-element>
</body>
</html>
I examined the polymer.html file in question. The file that bower installed is completely different from the one available on the web. I guess my question is - is the bower install of Polymer just broken? Why is Bower installing a version other than the active stable release? Am I missing something?
If you open the web version's code, it is clearly marked as version 0.5.5, even though it is being pulled from the /1.0/ pool.
The bower version has no version markers in the code so I'm not sure which one it is, though I have to assume it is the latest 1.2.x stable release because that was specified in the install command. I'll note that I did try it without specifying any version as well (supposed to just install the very latest then) but that still didn't work.
Conclusion
The libraries Bower installed were working files after all. The problem was that the examples I had pulled from the "Getting Started" tutorial on the Polymer-Project.org website were outdated. Be very careful to select v. 1.0 from the top right hand corner.
It's not going to work as you're using the old way of declaring elements (pre v0.8).
Here's how you declare new elements:
<dom-module id="my-element"> <!-- ID must be the same as that of the name of the element you declared. -->
<template> <!-- Styles used to be declared outside the template v0.8 to v1.0. At v1.1 it is now declared inside the template (the outside declaration still works, it's just slow and discouraged). -->
<style>
:host {
display: block;
}
</style>
<div>Hello {{name}}.</div>
</template>
</dom-module>
<script>
Polymer({
is: 'my-element', // you must declare the name of your element
properties: { // declare your element's properties here
name: {
type: String,
value: 'Neil'
}
}
});
</script>
Also, the official hub/CDN for the library is at http://polygit.org, not at the official website.

How to structure a Polymer SPA?

I'm new to Polymer 1.0.
I get the whole "everything is an element" philosophy but, to what extent?
How to structure all theses elements together?
TL;DR: Is there an equivalent to the main() function with Polymer and WebComponents in general ? If so , where should it be and what should it do ?
I usually look at examples, demos and projects to see how it should work, but because Polymer is so new (especially v1.0), I have a hard time finding non-trivial examples.
Long version
I get how to use Polymer to create elements.
But I'm hitting a roadbloack when I want to interface them. What structure shoud I use to make components talk between them.
Coming from an Angular background I have a relatively precise view of what should go where.
For example: the data is contained within scopes which are accessible from controllers, directives and html elements and you can use services to pull data from different part of the app.
In Polymer I don't get where are the boundaries of the data.
Not in the component itself but outside of it, where it lives and if another component can access it.
A simple drawing could help me a lot. There is no such thing explained in the polymer docs, probably because it's broader than Polymer.
To give you insights on my problem this is what I came across:
I set up a SPA based on Polymer Starter Kit
I wanted to wire it to firebase with the firebase-element
I created my own element which itself use <firebase-auth>:
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../../bower_components/firebase-element/firebase-auth.html">
<dom-module id="my-login">
<template>
<firebase-auth id="firebaseLogin"
user="{{user}}"
location="https://my-project.firebaseio.com"
provider="facebook"
on-error="_errorHandler"
on-login="_loginHandler"></firebase-auth>
<button on-tap="login">Login with facebook</button>
<button on-tap="logout">Logout</button>
</template>
</dom-module>
<script>
Polymer({
is: 'my-login',
properties: {
successRedirect: String
},
_errorHandler: function(e){
console.log(e.detail);
},
_loginHandler: function(e){
if(this.successRedirect){
// How can I tell pagejs to redirect me ?
app.route = this.successRedirect;
}
}
});
</script>
Basically How do I tell pagejs (my routing library) to redirect the app to a page after a successful login ? My pagejs config lives in it's own routing.html file and I don't understand how to piece together all of this.
I hope someone will be abe to understand this broad question and hopefully help me.
Thanks
Short answer: Event Listeners. Place an event listener on your router. Have the login handler fire the event on the router. The router will pick up that event and then redirect.
...
_loginHandler: function(e){
if(this.successRedirect){
// How can I tell pagejs to redirect me ?
var router = document.querySelector('router');
router.dispatchEvent(new Event('redirect', {redirectURL: this.successRedirect});
app.route = this.successRedirect;
}
}
...
Then in your router:
connectedCallback() {
this.addEventListener('redirect', function(event) {
var url = event.redirectURL;
// Redirect using the router's API.
});
}

Polymer: Registering Elements in External Scripts

In most of the examples I've seen for creating elements the script that registers the element is defined in the component's HTML file, e.g.
<link rel="import" href="/components/polymer/polymer.html">
<polymer-element name="my-element">
<template>
...
</template>
<script>
// convenience wrapper for document.registerElement
Polymer('my-element', {
...
});
</script>
</polymer-element>
It's possible to do that registration in an external script instead, e.g.
<script src="my-element.js"></script>
That seems like an attractive option because the script then becomes visible to tools like JSHint, but then you lose the automatically generated documentation of attributes, etc.
Is there a workflow or set of tools that help you get the best of both worlds?
e.g. combine a raw template and script into a single HTML file in a similar way to preprocessing CSS with Sass?
Yes. Polymer supports registering an element with by referencing an external script. See http://www.polymer-project.org/docs/polymer/polymer.html#separatescript. An original reason the element is in the call to Polymer() is to support this. It associates the definition with the script.