Since Polymer 1.0 release I start to get a different initialization order between Chrome and other browsers (Firefox, barebone WebKit). Although the 1.0 docs say "there are no guarantees with regard to initialization timing", in version 0.5 I didn't have such issue.
index.html:
<script src="components/webcomponentsjs/webcomponents.js"></script>
<link rel="import" href="name-tag.html">
<body onload="console.log('body onload');">
<name-tag></name-tag>
</body>
name-tag.html:
<link rel="import" href="components/polymer/polymer.html">
<dom-module id="name-tag">
<template></template>
<script>
Polymer({
is: "name-tag",
ready: function() {
console.log("polymer ready");
}
});
</script>
</dom-module>
Chrome 44:
polymer ready
body onload
Firefox 39, QWebView (Qt5.4, WebKit):
body onload
polymer ready
What I have already tried:
window.WebComponents = {flags: {register: true, polyfill: true}}; (register used to be in Polymer)
window.Polymer.Settings = {useNativeShadow: false};
attached callback with this.async()
window.Polymer.dom = 'shadow' forces Polymer to use the shadow DOM by default (either the polyfilled one if you used webcomponents.js or natively if you used webcomponents-lite.js instead).
Related
I want to use trumbowyg.js in my polymer element, it includes jquery.js and trumbowyg.js. It works fine in Firefox but not in chrome.
It gives error, may be because shadow dom lookup/separation in chrome. The error happens where ever trumbowyg.js uses "this".
Whats going wrong here? What should I do differently?
I am using Polymer 2.0
error:
Uncaught TypeError: Cannot read property 'toLowerCase' of undefined
at trumbowyg.js:1544
my-notes.html
<link rel="import" href="../polymer/polymer-element.html">
<link rel="import" href="../bower_components/trumbowyg/trumbowyg.html">
<dom-module id="my-notes">
<template>
<link rel="stylesheet" href="../bower_components/trumbowyg/dist/ui/trumbowyg.min.css">
<firebase-auth user="{{user}}" signed-in="{{signedIn}}"></firebase-auth>
<div class="card">
<div id="trumbowygd">hello</div>
</div>
</template>
<script>
class MyNotes extends Polymer.Element {
static get is() { return 'my-notes'; }
static get properties() {
return {
user: {
type: Object,
observer: '_shownotearea'
},
};
}
_shownotearea(){
var myFineElement = this.$.trumbowygd;
myFineElement.innerHTML="hello nice meeting you";
$(myFineElement).trumbowyg({});
}
</script>
</dom-module>
trumbowyg.html
<script src="../jquery/dist/jquery.min.js"></script>
<script src="dist/trumbowyg.js"></script>
This doesnt seem to be working
jQuery plugins and Polymer elements
The short answer is this plugin probably won't work with native Shadow DOM.
Likely trumbowyg is trying to query the document to look for some element. Shadow DOM creates markup encapsulation so you can't use $() or document.querySelector to look for things inside of shadow roots. In general I recommend not using jQuery plugins inside of Shadow DOM for this reason.
I've created a test polymer element where in I was figuring out how to use use arrays in templates. My code does not work and the documentation for 1.0 doesn't really talk much about how to use repeat in template tags.
my element:
<!-- Imports polymer -->
<link rel="import" href="polymer/polymer.html">
<!-- Defines element markup -->
<dom-module id="my-element" >
<template>
<style>
my-element
</style>
<h2>{{data}}</h2>
<ul>
<template repeat={{column in columns}} bind>
<li>{{column}}</li>
</template>
</ul>
</template>
</dom-module>
<!-- Registers custom element -->
<script>
Polymer({
is: 'my-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(name, type) {
alert("changed");
},
properties:{
data :String,
columns:Array
}
});
</script>
and the index.html page where I'm using the element:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title><my-repo></title>
<!-- Imports polyfill -->
<script src="webcomponents-lite.min.js"></script>
<!-- Imports
custom element -->
<link rel="import" href="my-element.html">
<!-- Runs custom element -->
<my-element users = '{{[1,2,3,4]}}' data="This is a polymer table"></my-element>
Please let me know what's wrong with my code!!
You have to use
<template is="dom-repeat" items="{{users}}">
<li>{{item}}</li>
</template>
And in main file:
<my-element users="[1,2,3,4]" data="This is a polymer table"></my-element>
You can search Youtube for Polycast, a series by Google Developers where they're talking about Polymer for beginners and showing cool tricks.
Polymer 1.0 does not allow expressions in data binding. The problem is in:
<my-element users = '{{[1,2,3,4]}}' ...>
You need to replace {{[1,2,3,4]}} with a property. Something like this:
<template is="dom-bind">
<my-element users = '{{myarray}}' data="This is a polymer table"></my-element>
</template>
<script>
(function() {
var template = document.querySelector('template[is="dom-bind"]');
template.myarray = [1,2,3,4];
})();
</script>
I've been trying to use Polymer for a project I'm working on. And although I enjoyed it quite a lot so far, I ran into a problem I just can't solve.
I dumped it down to a simple example. Basically it's just a list element (item-list) that contains item elements (item-card) and i want to parse the items position to the element via the attribute pos. But for some reason the items attribute is allways undefined! Is this because the attribute is bound to the variable i, which dies after the template repeat? If so, how do I work around it? Is there a different approach I should be using here?
SOLUTION: You can find the solution by reading through all the comments, but to sum it up: apperantly there was a timing issue and the attribute wasn't ready at the ready callback. But I found out about the domReady callback (polymer lifecycle documentation). Using domReady it works just fine! Thanks to Günter Zöchbauer for the help!
This is the item-list.html:
<link rel="import" href="components/polymer/polymer.html">
<link rel="import" href="item-card.html">
<polymer-element name="item-list">
<template>
<style>
</style>
<template repeat="{{values, i in data.data}}">
<item-card pos="{{i}}"></item-card>
</template>
</template>
<script>
Polymer({
created: function()
{
this.num = 123456;
this.data = { "data":
[
{
"value":999
},
{
"value":666
},
{
"value":555
},
{
"value":222
}
]
};
}
});
</script>
</polymer-element>
This is the item-card.html
<link rel="import" href="components/polymer/polymer.html">
<polymer-element name="item-card" attributes="pos">
<template>
<style>
</style>
</template>
<script>
Polymer({
ready: function()
{
console.log("ready: " + this.pos);
}
});
</script>
</polymer-element>
I didn't bother putting the index.html in, since it just containts one item-list element.
Thanks alot!!
I think you need a pos field in <item-card> in addition to the attributes="pos" declaration.
The repeated element also references the bound model which can be accessed like querySelector('item-card').templateInstance.model property.
See https://github.com/PolymerLabs/polymer-selector/blob/master/polymer-selector.html#L286 for an example.
Info:
According to the comments it turned out to be a timing issue. The value wasn't yet assigned when the ready callback was called but using domReady worked.
Sometimes it takes a while for polymer to load, and when using <body unresolved>, the page stays blank until everything is ready. Is there a way to display something between the time that the page is served and the time that polymer is done doing its magic?
The documentation that describes the unresolved attribute clears some of this up.
While it's common to apply unresolved to the <body> element, causing the entirety of your page's content to be hidden until Polymer is ready, it can be applied to any element(s). You can, for instance, use <div unresolved> as a wrapper around the portion of your page that relies on Polymer, and create a loading message that's outside that wrapper which will be visible immediately. (You'd then want to listen to the polymer-ready event and hide your loading message when that's fired.)
Here's an example using a very contrived way of slowing down the time it takes for the Polymer element to complete one of its lifecycle methods (live demo):
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>Polymer Demo</title>
<style>
.hidden {
display: none;
}
</style>
</head>
<body>
<p id="spinner">Loading...</p>
<script src="http://www.polymer-project.org/platform.js"></script>
<link rel="import" href="http://www.polymer-project.org/components/polymer/polymer.html">
<polymer-element name="slow-poke">
<template>
<h1><content></content></h1>
</template>
<script>
Polymer({
// Used to introduce a delay in initializing the Polymer element.
// Don't try this at home!
created: function() {
var start = Date.now();
while (true) {
if (Date.now() - start > 1000) {
break;
}
}
}
});
</script>
</polymer-element>
<div unresolved>
<slow-poke>Here I am... finally!</slow-poke>
<slow-poke>Me too!</slow-poke>
</div>
<script>
window.addEventListener('polymer-ready', function() {
document.querySelector('#spinner').classList.add('hidden');
});
</script>
</body>
</html>
(By the way, what are you finding to be slow-loading? If it's a standard/core element, it might be worth filing a bug against the corresponding project on GitHub.)
I've been happily developing an app in Polymer. All is going well, but some fairly basic stuff isn't working in Chrome Dev and Chrome Canary, is this expected?
Here's a reduction of what I'm seeing [codepen to try it out yourself]:
<script src="http://www.polymer-project.org/platform.js"></script></script>
<link rel="import" href="http://www.polymer-project.org/components/polymer/polymer.html">
<my-app></my-app>
<polymer-element name='my-app'>
<template>
<my-processor input='{{input}}' output='{{output}}'>
<input value='{{input}}'> <br>
Input: {{input}} <br>
Processed: {{output}}
</template>
<script>
Polymer('my-app', { 'input': 'hello world', });
</script>
</polymer-element>
<polymer-element name='my-processor' attributes='input output'>
<script>
Polymer('my-processor', {
inputChanged: function() {
this.output = this.input + ' (processed)';
}
});
</script>
</polymer-element>
In Chrome Dev and Canary the processed output is never displayed. I've used the debugger to see that inputChanged does fire on the my-processor element, but my-app never gets the updated output value.
In Chrome 34, Safari and Firefox everything works as expected and the processed output is displayed as expected.
As per the warning in the console, it's important that the the my-processor definitions comes prior to my-app that uses it. my-processor needs to be registered first for the bindings to be picked up properly.
http://jsbin.com/xovegoga/3/edit