I have been following along the Polymer 1.0 Developer guide and I stumbled when getting up to the specific part about hostAttributes.
When I take the example code from the docs:
hostAttributes: {
string-attribute: 'Value',
boolean-attribute: true
tabindex: 0
}
and add it to my prototype, the browser keeps throwing the error:
Uncaught SyntaxError: Unexpected token -
on the lines where there are dashes. Strangely, when I put quotes around string-attribute and boolean-attribute, it renders fine.
Is this an error on my part or is it an error in the docs somehow?
In The way that this example represented string-attribute, string-attribute refers to a string as an attribute that should be set on the label of your element declaration. Also, as you may have noticed by the way you are declaring string-attribute in the example, Javascript assumes that string-attribute is a variable, and variables can not be declared as "my-variable" are declared "myvariable", all strings together.
I think that's the reason why you should declared as follows:
hostAttributes: {
"my-var": 'Value',// Javascript assumes that my-bar is an string
my-var-two: 'value'// Javascript assumes that my-bar-two is a variable (this will fail)
tabindex: 0
}
I hope you have understood me, my English is very bad.
Edit
If a custom elements needs HTML attributes set on it at create-time, these may be declared in a hostAttributes property on the prototype, where keys are the attribute name and values are the values to be assigned. Values should typically be provided as strings, as HTML attributes can only be strings;
hostAttributes: {
string-attribute: 'Value', //string-attribute is a key, should be inside "" because javascript's keys doesn't accepts "-"
boolean-attribute: true//will fail because is not a key
tabindex: 0//this works because for javascript this is a correct key
}
...however, the standard serialize method is used to convert values to
strings, so true will serialize to an empty attribute, and false will
result in no attribute set, and so forth
As you can realize, only serialized string values, never mentioned that the keys are serialized as string as well. As I mentioned before, my English is bad and I understood that.
Related
I'm using libxml2 to parse/read an HTML page. The following code is used to read the value of an attribute:
char *value = (char*)xmlGetProp(node, attr->name);
But xmlGetProp substitutes character entity references when it reads the attribute content. E.g.
<p onload="readId="blahString"; myFun();"> Event handler in P HTML TAG</p>
In the above case, it returns the following string as "onload" attribute value:
readId="blahString";myFun();
The character entity reference is substituted in the above reading process. Is there any way to read the attribute value keeping the original HTML content using libxml2?
What you call "HTML encoding" is actually called character entity reference. To answer your question: No, the HTML parser of libxml2 has no option to turn off substitution of character references.
The XML parser keeps character entity references by default, but it can't be used for typical HTML documents.
Can I have multiple values in one HTML "data-" element? Similar to how a class can have multiple class names.
If possible, I would like to create a CSS/JS library that makes use of one "data-" element to house all of the library styles. For example:
<div data-library-name="xs-hidden col-md-10 col-xl-8 big-hero"></div>
That way, any of the programmers custom style rules can go into the elements class. My reasoning for this is to make readability easier, so together it would look like:
<div class="custom-style another-style" data-library-name="xs-hidden col-md-10 col-xl-8 big-hero"></div>
Can I have multiple values in one HTML "data-" element?
You can have a string. The spec doesn't define any particular format for the data in the attribute, which is designed to be processed by site specific JavaScript.
Similar to how a class can have multiple class names.
The class attribute takes a space separated list of classes.
Your JavaScript can your_data_attribute_value.split(" "); if you like.
Handling this with CSS would use the ~= attribute selector.
[att~=val]
Represents an element with the att attribute whose value is a whitespace-separated list of words, one of which is exactly "val". If "val" contains whitespace, it will never represent anything (since the words are separated by spaces). Also if "val" is the empty string, it will never represent anything.
AFAIK, I don't think data- attributes can convert that to an array. Instead, I think it'll interpret it as one value, but it is allowed.
If you want to do that, you'll probably have to split() it later in JavaScript into an array of usable values.
See this example on JSFiddle.net.
CSS has the shortcut .class selector but it actually is parsing the attribute named "class" as a list for space separated values. This is supported in the non-shortcut form by the following attribute selector:
[att~=val]
Represents an element with the att attribute whose value is a white space-separated list of words, one of which is exactly "val". If "val" contains white space, it will never represent anything (since the words are separated by spaces). If "val" is the empty string, it will never represent anything either.
Ref: http://www.w3.org/TR/CSS2/selector.html#class-html
As your question is tagged CSS you're perhaps looking for that. The rules how the parsing of attribute values is done is given in that document as well, so in case the javascript library you're trying to use on this (if any) won't cover that, it should be easy to add:
var list = $("div").data("library-name").split(/\s+/);
^^^^^^^^^^^^
This split with the white-space regular expression parses the string attribute value into an array with javascript and the Jquery library (for accessing the DOM and the data attribute).
I have data attribute in html element as <button data-verified=false>Update</button>. It have boolean value for data attribute.
Is there any difference with following element <button data-verified="false">Update</button> as the data-attribute is wrapped with double quotes.
Is boolean values are supported in html?
Boolean attributes are supported in HTML, but data-verified isn't one of them, no matter how it appears in the markup. data-verified=false and data-verified="false" both create an attribute of the type string and value "false", which if tested in JS as a boolean will be treated as true
This is only the case because false doesn't contain spaces. As a contrary example, data-verified=not true is invalid and not at all the same as data-verified="not true"
There are no differences in the values - however, always prefer to quote around attribute values, because:
Looks cleaner
Easier to maintain
Every editor can deal with it easily
It's a standard, nearly all HTML code examples you'll see use the value quoted
My answer corroborates from Do you quote HTML5 attributes?
I think it is just a convention that attributes always have double quotes.
However. In jQuery, you can use the .data() method. It is smart enough to recognize booleans and numeric values.
The only difference is that only the latter is allowed in XHTML. In HTML syntax, they both are allowed, and they are equivalent: the difference is lost when the HTML markup is parsed, and the DOM contains in both cases only the string false.
This follows from general principles in HTML and does not depend on the name of the attribute in any way.
“Boolean value” is a vague term. In HTML5, some attributes are called “boolean attributes”, but this is strongly misleading – especially since values true and false, far from being the only values allowed, aren’t allowed at all for such values. You need to read the specification of “boolean attributes” to see what they really are.
When you use data-* attributes, it is completely up to you what you use as values and how you process them.
I was reading something about boolean attribute here, which says that for a boolean attribute (in this particular example, loop attribute of <audio>), whatever value you set, it is going to be recognized as "true". In order to really set to falsy, you cannot set it like loop=false or with javascript as ['loop']=false, but have to remove the attribute such as by doing removeAttribute('loop'). Is this true?
I first believed it, but as far as checked it with Chrome, it seems that setting to ['loop']=false will actually do make it be recognized as falsy. I am not sure how robust this fact is when considered cross-browserly. Is there any difference among browsers?
Boolean attributes are explained here:
http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.3.4.2
Some attributes play the role of boolean variables (e.g., the selected
attribute for the OPTION element). Their appearance in the start tag
of an element implies that the value of the attribute is "true". Their
absence implies a value of "false".
Boolean attributes may legally take a single value: the name of the
attribute itself (e.g., selected="selected").
So, while some browsers may interpret the string "false" as if the value was not set, others may not decide to (which is the correct behavior). Actually, as far as I know (or thought), any non-empty string usually sets the value to on/true (regardless of what the spec says is a legal value). I believe this is also undefined behavior, so this may change as well or be different from browser to browser (don't rely on it).
The bottom line is, just because a browser or two may deviate from the spec doesn't mean that you should. Removing the attribute entirely is the way to go.
Addendum: Looking at your comments and question a little closer, I think you may be confused about attribute values in general. In HTML, attr=false and attr="false" are exactly the same. Quotes are not required in any version of HTML (unless they are needed to remove ambiguity when the value contains spaces). For instance:
<input class=required>
<!-- This is fine -->
<input class=title required>
<!-- this is fine too, but "required" will be parsed as an attribute -->
<input class="title required">
<!-- To have two classes, we need the quotes -->
All attribute values (on elements that have them) are treated as strings. In other words, there is no such thing as a true boolean value (or NULL value) in HTML like there is in javascript.
Just so anyone who needs this in the future:
loop=false remains true unless the entire loop attribute is removed. Basically, the presence of just loop is what a tag needs to do something else. You need to use something like jQuery to remove the entier loop attribute (or at least that's what I would do). Now, if you set a different undefined attribute to false, then you are able to recognize it as false.
The audio element is an HTML5 element, so regarding its meaning, you should consult the HTML5 drafts. In this case, see the definition of boolean attributes in the developer version of the WHATWG draft. It says, in effect, a) that the presence or absence of the attribute determines whether the DOM attribute value is true or false, and b) as a requirement on documents, the value must be empty or (case-insensitively) the attribute name, in this case loop='' or loop="loop". The use of quotation marks around the value are defined elsewhere.
Thus, browsers are required to recognize loop=false to mean the same as loop=loop or loop=true, but authors must not use such constructs, and HTML5 checkers issue error messages about them.
(Basically, you’re supposed to use just loop in HTML serialization of HTML5 and loop="loop" in XHTML serialization.)
Thus, if you have a variable x in JavaScript with an audio element object as its value, x.loop has the value true or false whereas x.attributes['loop'].value indicates the value used in HTML markup (which is usually not interesting as such).
There’s a further complication as regards to Firefox: it still does not seem to support the loop attribute (see the question HTML5 Audio Looping). This means that if you set e.g. loop="loop", x.attributes['loop'].value will be loop but Firefox does not even set x.loop (i.e., it is undefined), still less implement the functionality.
You're confusing strings and real Boolean types. Javascript has a Boolean datatype with two possible values of true and false (without quotes). Strings can contain any text, so can they contain "true" and "false" with quotes. Setting a property to non-null and non-false yields true, so the following will accour:
var a = true; // true
var b = false; // false
var c = "true"; // true
var d = "false" // true
var e = null; // false;
var f = 0; // false
var g = 1; // true
Note the similarities with C.
I found this useful regex code here while looking to parse HTML tag attributes:
(\S+)=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?
It works great, but it's missing one key element that I need. Some attributes are event triggers that have inline Javascript code in them like this:
onclick="doSomething(this, 'foo', 'bar');return false;"
Or:
onclick='doSomething(this, "foo", "bar");return false;'
I can't figure out how to get the original expression to not count the quotes from the JS (single or double) while it's nested inside the set of quotes that contain the attribute's value.
I SHOULD add that this is not being used to parse an entire HTML document. It's used as an argument in an older "array to select menu" function that I've updated. One of the arguments is a tag that can append extra HTML attributes to the form element.
I've made an improved function and am deprecating the old... but in case somewhere in the code is a call to the old function, I need it to parse these into the new array format. Example:
// Old Function
function create_form_element($array, $type, $selected="", $append_att="") { ... }
// Old Call
create_form_element($array, SELECT, $selected_value, "onchange=\"something(this, '444');\"");
The new version takes an array of attr => value pairs to create extra tags.
create_select($array, $selected_value, array('style' => 'width:250px;', 'onchange' => "doSomething('foo', 'bar')"));
This is merely a backwards compatibility issue where all calls to the OLD function are routed to the new one, but the $append_att argument in the old function needs to be made into an array for the new one, hence my need to use regex to parse small HTML snippets. If there is a better, light-weight way to accomplish this, I'm open to suggestions.
The problem with your regular expression is that it tries to handle both single and double quotes at the same time. It doesn't support attribute values that contain the other quote. This regex will work better:
(\w+)=("[^<>"]*"|'[^<>']*'|\w+)
following regex will work as per HTML syntax specs available here
http://www.w3.org/TR/html-markup/syntax.html
regex patterns
// valid tag names
$tagname = '[0-9a-zA-Z]+';
// valid attribute names
$attr = "[^\s\\x00\"'>/=\pC]+";
// valid unquoted attribute values
$uqval = "[^\s\"'=><`]*";
// valid single-quoted attribute values
$sqval = "[^'\\x00\pC]*";
// valid double-quoted attribute values
$dqval = "[^\"\\x00\pC]*";
// valid attribute-value pairs
$attrval = "(?:\s+$attr\s*=\s*\"$dqval\")|(?:\s+$attr\s*=\s*'$sqval')|(?:\s+$attr\s*=\s*$uqval)|(?:\s+$attr)";
and the final regex query will be
// start tags + all attr formats
$patt[] = "<(?'starttags'$tagname)(?'tagattrs'($attrval)*)\s*(?'voidtags'[/]?)>";
// end tags
$patt[] = "</(?'endtags'$tagname)\s*>"; // end tag
// full regex pcre pattern
$patt = implode("|", $patt);
// search and match
preg_match_all("#$patt#imuUs",$data,$matches);
hope this helps.
Even better would be to use backreferences, in PHP the regular expression would be:
([a-zA-Z_:][-a-zA-Z0-9_:.]+)=(["'])(.*?)\\2
Where \\2 is a reference to (["'])
Also this regular expression will match attributes containing _, - and :, which are allowed according to W3C, however, this expression wont match attributes which values are not contained in quotes.