dojo.query not working for attribute selector that includes a tilde (~) character - dojo

I need to select a link node given its url. Using an attribute selector works quite well except for a few rare cases when the url has a tilda. I have no control over the link urls. Here is an example:
<script>
dojo.ready(function() {
var node = dojo.query('a[href="http://abc.com/~123"]')[0];
console.debug(node);
node = dojo.query('a[href="http://abc.com/_123"]')[0];
console.debug(node);
});
</script>
...
<body>
<a href="http://abc.com/~123">link 1</a>
<a href="http://abc.com/_123">link 2</a>
</body>
This prints:
undefined
<a href="http://abc.com/_123">
I looked at the level 3 selectors spec and didn't find anything on the tilde character being unsupported for attribute selector values which are just CSS strings.
Help!

This appears to have been fixed in 1.6 http://bugs.dojotoolkit.org/ticket/10651

Related

Use GetElementsByClass to find all <div> elements by class name, nested inside a <p> element

I am creating a parser using Jsoup in Kotlin
I need to get a inner text of a tag with class "ptrack-content" inside the tag with class "titleCard-synopsis"
When I am trying to getElementsByClass in a element objects that created by a former getElementsByClass, I getting 0 elements
Code:
class NetlifxHtmlParser {
val html = """
<div class="titleCardList--metadataWrapper">
<div class="titleCardList-title"><span class="titleCard-title_text">Map Her</span><span><span class="duration ellipsized">50m</span></span></div>
<p class="titleCard-synopsis previewModal--small-text">
<div class="ptrack-content">A hidden map rocks Hartley High as the students' sexcapades are publicly exposed. Caught as the culprit, Amerie becomes an instant social pariah.</div>
</p>
</div>
<div class="titleCardList--metadataWrapper">
<div class="titleCardList-title"><span class="titleCard-title_text">Renaissance Titties</span><span><span class="duration ellipsized">50m</span></span></div>
<p class="titleCard-synopsis previewModal--small-text">
<div class="ptrack-content">Amerie, the new outcast, receives a party invitation that gives her butterflies. But when she manages to show up, a bitter surprise awaits.</div>
</p>
</div>
""".trimIndent()
fun parseEpisode() {
val doc = Jsoup.parseBodyFragment(html)
val titleCards = doc.getElementsByClass("titleCard-synopsis")
println("Episode: count titleCard = > ${titleCards.count()}") // 2
titleCards.forEachIndexed { index, element ->
val ptrack = element.getElementsByClass("ptrack-content")
println("Episode: count ptrack = > ${ptrack.count()}") // 0 !!
println("inner html = > ${ptrack.html()}") // null string !!
}
}
}
In the above code,
First, I am extracting tags with class name titleCard-synopsis.
For that , I using doc.getElementsByClass("titleCard-synopsis") which returns 2 element items.
Then, In the List of titleCard elements, I am extracting the elements that have ptrack-content as Class, by using the same getElementsByClass in each element,
which returns empty list.
Why this is happening ?
My goal is, I need to extract the description text for each title, the stored in the interior tags of p tag with class titleCard-synopsis.
If I try to get directly from "ptrack-content", it's working fine, but this a general class used in many places in the main HTML source. (this is snippet)
I need to get a inner text of a tag with class "ptrack-content" inside the tag with class "titleCard-synopsis"
But in the above method in the code, I am only getting emtpy list.
Why ?
Also note that, if I invoke the HTML() method in a element object of titleCards(ptrack.html()),
I am not getting the inner DIV tag, an empty string!!!
Please guide my to resolve the issue !
TL;DR
I need to get a inner text of a tag with class "ptrack-content" inside the tag with class "titleCard-synopsis"
I'm not really familiar with Kotlin, but this should produce the desired output:
val doc = Jsoup.parseBodyFragment(html)
val result = doc.select(".titleCard-synopsis + .ptrack-content")
result.forEachIndexed {index, element ->
println("${element.html()}")
}
Live example
This is an interesting problem!
You basically have an invalid HTML and jsoup is smart enough to auto-correct it for your. Your HTML structure gets altered and suddenly your query does not work.
This is the error:
<p class="titleCard-synopsis previewModal--small-text">
<div class="ptrack-content">A hidden map rocks Hartley High as the students' sexcapades are publicly exposed. Caught as the culprit, Amerie becomes an instant social pariah.</div>
</p>
You can't nest a <div> element inside a <p> element like that.
Paragraphs are block-level elements, and notably will automatically close if another block-level element is parsed before the closing </p> tag. [Source: <p>: The Paragraph element]
Also, look at Nesting block level elements inside the <p> tag... right or wrong?
This is how jsoup parses your tree:
<html>
<head></head>
<body>
<div class="titleCardList--metadataWrapper">
<div class="titleCardList-title">
<span class="titleCard-title_text">Map Her</span><span><span class="duration ellipsized">50m</span></span>
</div>
<p class="titleCard-synopsis previewModal--small-text"></p>
<div class="ptrack-content">
A hidden map rocks Hartley High as the students' sexcapades are publicly exposed. Caught as the culprit, Amerie becomes an instant social pariah.
</div>
<p></p>
</div>
<div class="titleCardList--metadataWrapper">
<div class="titleCardList-title">
<span class="titleCard-title_text">Renaissance Titties</span><span><span class="duration ellipsized">50m</span></span>
</div>
<p class="titleCard-synopsis previewModal--small-text"></p>
<div class="ptrack-content">
Amerie, the new outcast, receives a party invitation that gives her butterflies. But when she manages to show up, a bitter surprise awaits.
</div>
<p></p>
</div>
</body>
</html>
As you can see, elements with class titleCard-synopsis have no children with class ptrack-content.

Prevent vue render newline between elements

<template>
<div>
<span>foo</span> <!-- unwanted space here -->
<span>bar</span>
<span>foo</span>
</div>
</template>
// But I don't want to do this
<template>
<div>
<span>
foo
</span><span> <!-- bad coding style -->
bar
</span><span>
baz
</span>
</div>
</template>
In html, newlines between elements are rendered as spaces, and Vue followed that behavior. If I want no spaces between the elements, the obvious way is to put no space there, as shown in the code sample. But it is ugly, I don't want that. How can I do otherwise such that there is no space between the elements?
You can change the compiler options.
compilerOptions
type: Object
default: {}
Options for the template compiler. When using the default vue-template-compiler, you can use this option to add custom compiler directives, modules, or discard whitespaces between template tags with { preserveWhitespace: false }.
However the documentation states this only applies to single file components and template tags. I don't think there is currently any option for native tags and related issue has been closed. But maybe it gives you the desired result.

Using ng-repeat variable inside src attribute in angularjs?

I have the following:
div.container
script(src='/js/bootstrap/holder.js')
p.text-info(ng-pluralize,
count="devices.length",
when="{ '0': 'There are no fragments.', 'one': 'There is 1 fragment.', 'other': 'There are {} fragments.'}")
ul.unstyled(ng-repeat='fragment in devices')
ul.thumbnails
li.span
div.thumbnail
img(src="holder.js/{{fragment.dimension.width}}x{{fragment.dimension.height}}")
div.caption
h3 {{fragment.name}}
p {{fragment.dimension}}
ul.unstyled(ng-repeat='component in fragment.components')
li {{ component.name }}
The problem is in src="holder.js/{{fragment.dimension.width}}x{{fragment.dimension.height}}", i.e. even if looking at the resulting html I see a correct src (src="holder.js/300x200") it does not show the image. My guess is this is not how one uses angular variables inside attributes..
How can I make it work?
EDIT:
it seems it does not execute holder.js..
here is the source: in the first call I used angular {{hash}} in the second I manually put holder.js/300x200
<div class="thumbnail">
<img src="holder.js/1678x638">
<img src="data:image/png;base64,iVBORw0KG...ElFTkSuQmCC" data-src="holder.js/300x200" alt="300x200" style="width: 300px; height: 200px;">
</div>
The documentation explains that quite clearly:
Using Angular markup like {{hash}} in a src attribute doesn't work right: The browser will fetch from the URL with the literal text {{hash}} until Angular replaces the expression inside {{hash}}. The ngSrc directive solves this problem.
So you must use:
<img ng-src="holder.js/{{fragment.dimension.width}}x{{fragment.dimension.height}}" />

Difference between innerhtml and outerhtml in cocoa WebView

I am using cocoa webview for rich text editing in my application. Just confused with innerHtml and outerHtml method avaiable in webkit.
Can anyone explain what is the difference between
[(DOMHTMLElement *)[[[webView mainFrame] DOMDocument] documentElement] outerHTML];
AND
[(DOMHTMLElement *)[[[webView mainFrame] DOMDocument] documentElement] outerText];
innerHTML is a property of a DOM element that represents the HTML
inside the element, i.e. between the opening and closing tags. It has
been widely copied, however implementations vary (probably because it
has no published standard[1]) particularly in how they treat element
attributes.
outerHTML is similar to innerHTML, it is an element property that
includes the opening an closing tags as well as the content. It
hasn't been as widely copied as innerHTML so it remains more-or-less
IE only.
<p id="pid">welcome</p>
innerHTML of element "pid" == welcome
outerHTML of element "pid" == <p id="pid">welcome</p>
and whereAs
innerText The textual content of the container.
outerText Same as innerText when accessed for read; replaces the whole element when assigned a new value.
<p id="pid">welcome</p>
innerText of element "pid" == welcome
outerText of element "pid" == welcome
Suppose we have a page loaded to webview with html
<html>
<head><title>Your Title</title></head>
<body>
<h1>Heading</h1>
<p id="para" >hi <b>Your_Name</b></p>
</body>
<html>
NOW.
[(DOMHTMLElement *)[[webView mainFrame] DOMDocument] documentElement]
will returen the DOMHTMLElement "html" and
outerHTML will return the complete html as
<html>
<head><title>Your Title</title></head>
<body>
<h1>Heading</hi>
<p id="para">hi <b>Your_Name</b></p>
</body>
<html>
outerText will return html as
Heading
hi Your_Name
for example if we take example of p tag in this case
outerHTML will return - <p id="para">hi <b>Your_Name</b></p>
outerText will return - hi Your_Name
innerHTML will return - hi <b>Your_Name</b>
innerText will return - hi Your_Name
i have explained it with the help of example where definition for these 4 terms already explained in the answer below.
<!DOCTYPE html>
<html>
<head>
<title>innerHTML and outerHTML | Javascript Usages</title>
</head>
<body>
<div id="replace">REPLACE By inner or outer HTML</div>
<script>
userwant = "inner";
userwant = "outer";
if (userwant = "inner") {
document.querySelector("#replace").innerHTML;
// this will remove just message: 'REPLACE By inner or outer HTML' //
} else if (userwant = "outer") {
document.querySelector("#replace").outerHTML;
// this will remove all element <div> ~ </div> by the message: 'REPLACE By inner or outer HTML' //
};
</script>
</body>
</html>

How to add id using dojo.query to search element

I'm trying to add id to a element using dojo.query. I'm not sure if it's possible though. I trying to use the code below to add the id but it's not working.
dojo.query('div[style=""]').attr("id","main-body");
<div style="">
content
</div>
If this is not possible, is there another way to do it? Using javascript or jquery? Thanks.
Your way of adding an id to an element is correct.
The code runs fine for me in Firefox 17 and Chrome 23 but I have an issue in IE9. I suspect you may have the same issue.
In IE9 the query div[style=""] returns no results. The funny thing is,it works fine in compatibility mode!
t seems that in IE9 in normal mode if an HTML element has an inline empty style attribute, that attribute is not being preserved when the element is added to the DOM.
So a solution would be to use a different query to find the divs you want.
You could try to find the divs with an empty style attributes OR with no style attribute at all.
A query like this should work:
div[style=""], div:not([style])
Take a look at the following example:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test Page</title>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/dojo/1.8.2/dojo/dojo.js"></script>
<script type="text/javascript">
dojo.require("dojo.NodeList-manipulate");//just for the innerHTML() function
dojo.addOnLoad(function () {
var nodeListByAttr = dojo.query('div[style=""], div:not([style])');
alert('Search by attribute nodeList length:' + nodeListByAttr.length);
nodeListByAttr.attr("id", "main-body");
var nodeListByID = dojo.query('#main-body');
alert('Search by id nodeList length:' + nodeListByID.length);
nodeListByID.innerHTML('Content set after finding the element by ID');
});
</script>
</head>
<body>
<div style="">
</div>
</body>
</html>
Hope this helps
#Nikanos' answer covers the query issue, I would like to add, that any query returns an array of elements, in case of Dojo it is dojo/NodeList.
The problem is you are about to assign the same id to multiple DOM nodes, especially with query containing div:not([style]). I recommend to use more specific query like first div child of body:
var nodes = dojo.query('body > div:first-child');
nodes.attr("id", "main-body");
To make it more robust, do not manipulate all the nodes, just the first node (even through there should be just one):
dojo.query('body > div:first-child')[0].id = "main-body";
This work also in IE9, see it in action: http://jsfiddle.net/phusick/JN4cz/
The same example written in Modern Dojo: http://jsfiddle.net/phusick/BReda/