how to disable polymer 1.0. paper-tooltip animation - polymer

I have a paper tooltip, working correctly. I'm trying to disable the fade-in / out animation, to resemble Polymer 0.5 behavior. THe animationconfig seems to be ignored. Any ideas ?
<paper-tooltip for="addid" position="left" animationConfig="{{tooltipAnimation}}">Tooltip text</paper-tooltip>
In the polymer code:
ready: function() {
this.tooltipAnimation =
{"entry": [{"name": "fade-in-animation", "timing": {"delay": 1000}}],
"exit": [{"name": "fade-out-animation"}]};

It should write as -
animation-config="{{tooltipAnimation}}"
Attribute names with dashes are converted to camelCase property names
by capitalizing the character following each dash, then removing the
dashes. For example, the attribute first-name maps to firstName.
Read Property name to attribute name mapping.

Related

Polymer 1.x: How to print all the properties of a Polymer element?

How do I print to the console all the properties of an element I have imported into a custom element.
For example, I have a custom element my-el and in that element, I have imported a firebase-document element. I want to know the current state of the model for the firebase-document element by observing the value of all the properties of the firebase-document at a particular point in time.
my-el.html
<firebase-document id="document"
app-name="my-app"
data="{{data}}">
</firebase-document>
...
foo: function() {
...
var doc = this.$.document;
// Neither of the following "works" (see below for definition)
console.log('doc', doc);
console.log('doc.properties', doc.properties);
}
By works, I mean it does not produce the desired behavior of printing an object to the console. The object being all the properties of the doc object.
You can use console.dir(), but you can also use the %o substitution string in a standard console.log() call:
console.log( 'doc=%o', doc );
The list of substition strings is avaiable on MDN's website.
Summary from comments:
Use
console.dir( doc );

Polymer style google-map

How can styles be applied to the Polymer 1 google-map tag?
The documentation suggests that an object of styles can be passed in via a 'styles' property on the tag.
However, when using something like this which previously worked without issue, the style is not being loaded in.
I've tried replacing the code from snazzymaps with an object (as opposed to an array), but that doesn't work.
It should work. Are you sure you are passing your styles object in correctly?
This gives you a styled map:
<google-map latitude="37.779" longitude="-122.3892"
min-zoom="9" max-zoom="11" language="en"
styles='[{"featureType":"landscape","stylers":[{"hue":"#FFBB00"},{"saturation":43.400000000000006},{"lightness":37.599999999999994},{"gamma":1}]},{"featureType":"road.highway","stylers":[{"hue":"#FFC200"},{"saturation":-61.8},{"lightness":45.599999999999994},{"gamma":1}]},{"featureType":"road.arterial","stylers":[{"hue":"#FF0300"},{"saturation":-100},{"lightness":51.19999999999999},{"gamma":1}]},{"featureType":"road.local","stylers":[{"hue":"#FF0300"},{"saturation":-100},{"lightness":52},{"gamma":1}]},{"featureType":"water","stylers":[{"hue":"#0078FF"},{"saturation":-13.200000000000003},{"lightness":2.4000000000000057},{"gamma":1}]},{"featureType":"poi","stylers":[{"hue":"#00FF6A"},{"saturation":-1.0989010989011234},{"lightness":11.200000000000017},{"gamma":1}]}]'>
</google-map>
Are you using single quotes for the styles property? I.e. styles='' rather than styles=""
That's what worked for me.
I could not find any answers on how to pass this object inside the value of the style tag, but I was able to apply the styles by reading the comments in the file" google-map.html":
<script>
var map = document.querySelector('google-map');
map.styles = [
{
stylers: [
{saturation: -100}
]
},
{
featureType: 'water',
stylers: [
{color: '#1d5068'}
]
}
];
Expanding on my previous comment / answer to Dian Carlos, here is code I finally used
Assuming that styledMapDef holds the map styles definitions object
var styledMapType = new google.maps.StyledMapType(styledMapDef, {name: 'Styled'});
this.map.setOptions( {"mapTypeControl":"true","mapTypeControlOptions":{"position":"3", "mapTypeIds": ["roadmap", "satellite", "hybrid", "terrain", "styled"]}, "scaleControl": "true"} );
this.map.mapTypes.set('styled', styledMapType);
this.map.setMapTypeId('styled');

In what contexts is interpolation legal in Angular, and why?

I know that Angular's string interpolation normally operates on expressions inside Handlebars-style {{ double curly braces }}, and by observation I know that I can use it in contexts like
text outside HTML tags: <span>{{ 'string literal expression ' }}</span>
attribute values inside HTML tags: link
and not to generate attributes themselves, i.e.
<a {{ 'href="/link/to/elsewhere"' }}>link</a>
does not get interpolated.
What I'm curious about is why: what are the rules on where interpolation does and doesn't happen, where this is documented, and what the design considerations or constraints are that led to this.
I guess this is because the document is parsed as HTML by the browser before Angular sees it, so the structure is dictated by HTML and the {{ stuff }} has to appear in places that are well-formed according to HTML even before interpolation happens. But I'd appreciate knowing the whole story.
What are the rules on where interpolation does and doesn't happen ?
Angular.js uses $compile service to compile a piece of DOM. The docs says:
The compilation is a process of walking the DOM tree and matching DOM elements to directives.
In the source code of compile.js there is a function collectDirectives, I trimmed it to show only the relevant code:
function collectDirectives(node, directives, attrs, maxPriority, ignoreDirective) {
var nodeType = node.nodeType;
// ....
switch(nodeType) {
case 1: /* Element */
// ....
// iterate over the attributes
for (var attr, name, nName, ngAttrName, value, nAttrs = node.attributes,
j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {
// ....
addAttrInterpolateDirective(node, directives, value, nName);
// ....
}
// ....
break;
case 3: /* Text Node */
addTextInterpolateDirective(directives, node.nodeValue);
break;
case 8: /* Comment */
// ....
break;
}
directives.sort(byPriority);
return directives;
}
As you can see, $compile search for interpolated content only inside attributes and text nodes when it iterates a piece of DOM.
Those functions, addTextInterpolateDirective and addAttrInterpolateDirective "translate" the interpolated expression into directives that $watch interpolated expressions and update the DOM element.
Where this is documented?
The compilation phase is documented here: http://docs.angularjs.org/guide/compiler
It's getting better every day but still some in-depth stuff are not clear until you read the source code itself. I guess some things are just too compilcated to explain without showing the code.
What the design considerations or constraints are that led to this?
I guess there are two reasons:
Angular operates on DOM nodes rather than strings, If angular needed to interpolate attributes or elements then It should operate on html strings which is probably bad for performance.
There is no major use case for such things.
If you still want to interpolate everything, do that kind of magic inside a directive:
An example:
app.directive('myAnchor',function(){
return {
restrict: "E",
transclude: true,
link: function(scope,element,attrs,ctrl,$transclude) {
attrs.$observe('interpolate', function(val){
var e = angular.element("<a " + val + "></a>");
$transclude(scope,function(clone){
e.append(clone);
});
element.replaceWith(e);
});
}
};
});
Be sure to read this:
What is the difference between the $parse, $interpolate and $compile services?

How to build Regular Expression for more strict Anchor tag

I am trying to restrict some of the attributes that can go with anchor tag in HTML for Markdown editor. This is what I have right now:
/^(<a\shref="((https?|ftp):\/\/|\/)[-A-Za-z0-9+&##\/%?=~_|!:,.;\(\)]+"(\stitle="[^"<>]+")?\s?>|<\/a>)$/i
This allows an anchor tag with title and href attributes but nothing else. I also wanted to add target but whatever I tried didn't work.
The link must contain an href attribute.
It can contain title attribute but doens't have to.
It can contain target attribute but doesn't have to too.
How can I modify the Regex above which satisfies all the conditions above.
Usually regexes aren't the best tool for parsing some languages. On the other hand, if you just want to match an isolated anchor tag, then a parser could be a little too much, and regexes can do a decent job.
To match an anchor tag to your requirements, you can use the regex below. It uses backreferencing to keep track of at most one title and one target (duplicated attributes), also at least/most one href:
^(<a(?=[^>]*?(\s+href="((https?|ftp):\/\/|\/)[-A-Za-z0-9+&##\/%?=~_|!:,.;\(\)]+")[^>]*>)(?=([^>]*?(\s+title="[^"<>]+"))?[^>]*>)(?=([^>]*?(\s+target="[^"<>]+"))?[^>]*>)(\2(\6\8?)?|\2\8\6?|\6\2\8?|\8\2\6?|\6\8\2|\8\6\2)\s*>[^<]*</a>)$
Check the demo here, along with dozens of test cases which you can proof test the solution.
Observe this regex is not so complicated (the "ugly" part is the URL, really), but it is very comprehensive and takes care of:
a mandatory href attribute
an optional title attribute
an optional target attribute
no other type of attribute is allowed (altought it would be easy to customize and add support)
any number of spaces between them
they can come in any order
there can be at most one href, one title and one target.
RegEx-en by themselves aren't really good at this kind of thing.
I'd do something like:
function validateAnchor(anchor){
var match,
name,
value,
test,
attrRE=/\s([a-z]+)(?:\s*=\s*"([^"]+))?"/gi, // matches one tag attribute
allowedAttrs={ // attributes must appear here to be considered legal
href:{
isValid:function(val){
return isValidURL(val);
}
},
title:{
isValid:function(val){
return true;
}
},
target:{
isValid:function(val){
return true;
}
}
},
result=true;
while(match=attrRE.exec(anchor)){
name=match[1].toLowerCase(); // lowerCase to match our allowedAttrs keys
value=match[2]||''; // optional
// must have a name
if(!name){
console.log('no name for this attr - should not happen!');
result=false;
break;
}
// and must exist in allowedAttrs
if(test=allowedAttrs[name]) {
console.log('unknown attr');
result=false;
break;
}
// if it has a value and there is am isValid function.
if(value && 'function'==typeof(attr.isValid)){
if(!attr.isValid(value)){ // which fails!
result=false;
break;
}
}
}
return result;
}
So, that given:
var anchor='<a href=\"...\" target = \"...\" foo >';
validateAnchor(anchor) will fail since 'foo' is a disallowed attribute (not defined in allowedAttrs).
The benefits of this approach are that you
don't need to modify your RE each time you need to accept a new attribute,
can have value-less attributes
I leave isValidURL() for you to define.
Let's make it easier:
/<a(?=.*href="((ht|f)tps?:\/)?\/.*")\s*((href|title|target)="[^"]*"\s*)*>[^<]*</a>/

Using attr binding in knockout with a boolean attribute 'autofocus'

For some attributes, it is the presence of the attribute that has an effect - the value that is assigned to it is irrelevant. For example, the autofocus attribute can be set to 'false' or 'true, or 'banana' and the element is still gets automatically focused. IE, the following are all equivalent and cause the div to get focus :
<div autofocus="false" contenteditable="true"></div>
<div autofocus="true" contenteditable="true"></div>
<div autofocus="banana" contenteditable="true"></div>
Knockout has an 'attr' binding, but it seems to be only useful for assigning values to attributes, not for adding/removing attributes.
Is there another way to do it in knockout, or am I forced to set it from javascript?
NB Using chrome on ubuntu.
Use a boolean false value to remove the attribute, use a string 'false' to set the attribute. What more do you need?
eg:
// Set as boolean, removes the attribute
autofocus(false);
// Set as boolean, adds the attribute
autofocus(true);
// Set as string, adds the attribute
autofocus('false');
// Set as string, adds the attribute
autofocus('true');
See here for an example: http://jsfiddle.net/badsyntax/XMDFh/
You can use hasfocus knockout binding:
<input data-bind="hasfocus: isSelected" />
Read more here: http://knockoutjs.com/documentation/hasfocus-binding.html
You can write a kohandler that removes attributes using jquery.
There is not a native binding in Knockout to add or remove an attribute, only to set an attribute.
The reason why the hasFocus binding exhibits the behavior it does is because it uses an element's native .focus() and .blur() methods to add or remove focus.
Knockout having difficulty managing non-boolean attributes has been reported before, here's one example where Michael Best mentioned it would not be addressed:
https://github.com/SteveSanderson/knockout/issues/391
Update:
You could create a binding handler along these lines:
ko.bindingHandlers.toggleAttr = {
update: function (element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor());
var attr = ko.utils.unwrapObservable(options.attr);
var param = ko.utils.unwrapObservable(options.param);
param ? element.setAttribute(attr, true) : element.removeAttribute(attr);
}
};
Which would allow you to do this:
<input data-bind="toggleAttr: { attr: 'autofocus', param: focusMe }" />
Here's a fiddle: http://jsfiddle.net/nathanjones/9EzBD/