I am trying to make "Highlighter" for epub reader in one my Android project using webview.
I am using Rangy for getting Selected text.
The serialize functions gives me this value after selecting text from the below sample HTML:
2/5/3/5/1/2:0,13/5/3/5/1/2:24
I am storing this in DB. When user returns to this page, i am retrieving the same selection and trying to deserialize but the deserialize function throws the following error:
Error in Rangy Serializer module: deserializePosition failed: node <DIV>[7] has no child with index 13, 0
I am getting why this is happenig??
Even i am trying to do the same thing using XPath but still the same issue.
<html>
<head>
<script></script>
</head>
<body>
<div id="mainpage" class="highlighter-context">
<div> Some text here also....... </div>
<div> Some text here also.........</div>
<div>
<h1 class="heading"></h1>
<div class="left_side">
<ol></ol>
<h1></h1>
<div class="text_bio">
In human beings, height, colour of eyes, complexion, chin, etc. are
some recognisable features. A feature that can be recognised is known as
character or trait. Human beings reproduce through sexual reproduction. In this
process, two individuals one male and another female are involved. Male produces
male gamete or sperm and female produces female gamete or ovum. These gametes fuse
to form zygote which develops into a new young one which resembles to their parent.
During the process of sexual reproduction
</div>
</div>
<div class="righ_side">
Some text here also.........
</div>
<div class="clr">
Some text here also.......
</div>
</div>
</div>
</body>
</html>
Any guesses??
you are probably using the following:
highlighter.highlightSelection();
rangy.serializeSelection();
if you are running highlightSelection before serializing it will not work.
this is because highlighting is actually wrapping text in tags which means that DOM is manipulated.
deserializing on original DOM will obviously won't work.
try change the order of commands so you will serialize first and only then use highlight.
Correct Order:
rangy.serializeSelection();
highlighter.highlightSelection();
Related
I have a JSP page, with some info pulled from Mongo DB. The outcome HTML page has UTF-8 encoding. Occasionally this char is being pulled from the DB: –, the en dash. When the page displayed in browser - this char is being displayed OK. But when in Android Webview - I see a question mark instead of it.
Any ideas how to solve it without touching the Mongo DB?
EDIT
Short HTML outcome:
<head>
<meta charset="utf-8">
....
</head>
...
<div class="photo_description">
<h1>
<span class="text-ellipsis">
NY – The sunrise
</span>
</h1>
<div class="button">
<div class="btn-txt">
View
</div>
</div>
...
</div>
...
Notice the dash in the <span> element.
I found an answer here:
${fn:escapeXml(photoTitle)}
I am creating a very simple WebView application on android. However, I want to edit the html file before displaying it in the WebView.
For example, if the original html source looked like :
<html>
<body>
<h1> abc </h1>
<h2> abc </h2>
......
<h6> abc </h6>
</body>
</html>
And I want to change it to:
<html>
<body>
<h1> cba </h1>
<h2> cba </h2>
......
<h6> cba </h6>
</body>
</html>
(all "abc" become "cba")
And then, I want to display that new code in my WebView. How can I do this? thanks
I am not sure why do you need this and what kind of app it is to need this. But if you have to do it check foll code:
$(function() {
for(var i =0;i<101;i++) {
if(jQuery('h'+i).length)
jQuery('h'+i).html(jQuery('h'+i).html().split("").reverse().join(""));
}
});
First, a note on your header tags: <h100> is a common misconception for newcomers. <h_> tags are simply an organizational item for your page, and only go out to <h6> You can have multiple <h1> tags on the same page, which are just headings for that section of content (with <h2> implying a subsection of <h1>, etc).
From there, when you say "original source", I assume you mean this is your own code, correct? Not a WebView sourced from another site? If this is the case, and you are only looking to change a specific instance of a specific string in your own code, a Find and Replace should be sufficient via any text or code editor you are using.
But if this is the case, you might want to look into first learning HTML and being able to render it in a basic web browser before moving on to also trying to learn Android.
I am trying to develop in an application, which is based on Phonegap and JQuery Mobile framework.
I have created a Page and Sub Page as separate HTML files.
The body part of the index.html file will look like:
<div data-role="page" id="p1" **data-theme="e"**>
<div data-role="header">App Name</div>
<div data-role="content" class="fit-content"><br/>
<ul data-role="listview" data-inset="true" data-filter="true" data-icon="star" data-iconpos="right" data-transition="slide">
<li>Link1</li>
<li>Link2</li>
</ul></div></div>
The body part of page2.html file will look like:
<div data-role="subpage" id="p2" **data-theme="e"**>
<div data-role="header">Places</div>
<div data-role="content" class="fit-content"><br/>
<ul data-role="listview" data-inset="true" data-filter="true" data-icon="star" data-iconpos="right" data-transition="slide">
<li>Go Back</li>
</ul></div></div>
The data-theme="e" is successfully getting applied to index.html, whereas it is not getting applied to page2.html. Can someone please provide me with the reasons, for this behavior..?
I am using JQuery 1.8.3 and JQuery Mobile 1.2.1 version and I am properly calling the CSS and JS versions from local storage in both the HTML files (ex: /android_asset/www/css/jquery.mobile-1.2.1.css, ex: /android_asset/www/js/jquery-1.8.3.js/)
Also, another question lingering in my mind is, I am unable to call
the CLICK event for Link1, when I keep the body content of page2.html
in the same HTML file as index.html, as a SubPage; upon click on Link1, I am not redirected to Page2.html, even though I give href="#p2", instead of href-"page2.html#p2".
Provide data-ajax="false" in list divider of index.html. This tells the framework to do a full page reload to clear out the Ajax hash in the URL. As per this link,
"Providing data-ajax="false" is critical because Ajax pages use the
hash (#) to track the Ajax history, while multiple internal pages use
the hash to indicate internal pages so there will be a conflicts."
Also, rename data-role="subpage" to data-role="page". This is the solution to this problem.
I am creating "Highlighter" for Android in WebView.
I am getting XPath expression for the selected Range in HTML through a function as follows
/HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/text()[5]
Now i am evaluating the above XPath expression through this function in javascript
var resNode = document.evaluate('/HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/text()[5]',document,null,XPathResult.FIRST_ORDERED_NODE_TYPE ,null);
var startNode = resNode.singleNodeValue;
but I am getting the startNode 'null'.
But, here is the interesting point:
if I evaluate this '/HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]' XPath expression using the same function, it gives the proper node i.e. a 'div'.
The difference between the two XPaths is the previous ones contains a textNode and later only div.
But the same thing is working fine on Desktop browsers.
Edited
Sample HTML
<html>
<head>
<script></script>
</head>
<body>
<div id="mainpage" class="highlighter-context">
<div> Some text here also....... </div>
<div> Some text here also.........</div>
<div>
<h1 class="heading"></h1>
<div class="left_side">
<ol></ol>
<h1></h1>
<div class="text_bio">
In human beings, height, colour of eyes, complexion, chin, etc. are
some recognisable features. A feature that can be recognised is known as
character or trait. Human beings reproduce through sexual reproduction. In this
process, two individuals one male and another female are involved. Male produces
male gamete or sperm and female produces female gamete or ovum. These gametes fuse
to form zygote which develops into a new young one which resembles to their parent.
During the process of sexual reproduction
</div>
</div>
<div class="righ_side">
Some text here also.........
</div>
<div class="clr">
Some text here also.......
</div>
</div>
</div>
</body>
</html>
getting XPath:
var selection = window.getSelection();
var range = selection.getRangeAt(0);
var xpJson = '{startXPath :"'+makeXPath(range.startContainer)+
'",startOffset:"'+range.startOffset+
'",endXPath:"'+makeXPath(range.endContainer)+
'",endOffset:"'+range.endOffset+'"}';
function to make XPath:
function makeXPath(node, currentPath) {
currentPath = currentPath || '';
switch (node.nodeType) {
case 3:
case 4:return makeXPath(node.parentNode, 'text()[' + (document.evaluate('preceding-sibling::text()', node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength + 1) + ']');
case 1:return makeXPath(node.parentNode, node.nodeName + '[' + (document.evaluate('preceding-sibling::' + node.nodeName, node, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null).snapshotLength + 1) + ']' + (currentPath ? '/' + currentPath : ''));
case 9:return '/' + currentPath;default:return '';
}
}
I am not working with XML but with HTML in webview.
I tried using Rangy serialize and deserialize but the Rangy "Serialize" works properly but not the "deserialize".
Any ideas guys, whats going wrong?
UPDATE
Finally got the root cause of the problem (not solution yet :( )
`what exactly is happening in android webview. -->> Somehow, the android webview is changing the DOM structure of the loaded HTML page. Even though the DIV doesn't contains any TEXTNODES, while selecting the text from DIV, i am getting TEXTNODE for every single line in that DIV. for example, for the same HTML page in Desktop browser and for the same text selection, the XPath getting from webview is entirely different from that of given in Desktop Browser'
XPath from Desktop Browser:
startXPath /HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/text()[1]
startOffset: 184
endXPath: /HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/text()[1]
endOffset: 342
Xpath from webview:
startXPath :/HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/text()[3]
startOffset:0
endXPath:/HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/text()[4]
endOffset:151
Well in your sample the path /HTML[1]/BODY[1]/DIV[1]/DIV[3]/DIV[1]/DIV[1]/text()[5] selects the fifth text child node of the div element
<div class="text_bio">
In human beings, height, colour of eyes, complexion, chin, etc. are
some recognisable features. A feature that can be recognised is known as
character or trait. Human beings reproduce through sexual reproduction. In this
process, two individuals one male and another female are involved. Male produces
male gamete or sperm and female produces female gamete or ovum. These gametes fuse
to form zygote which develops into a new young one which resembles to their parent.
During the process of sexual reproduction
</div>
That div has a single text child node so I don't see why text()[5] should select anything.
Hi its my first post here I am writing it because I went throught every example google knows about on htmlcleaner... and I cant get my project running ;( Im tryng to make an Android app fetching and displaying data from flash rich webpage. The idea is to get only the most important data so that users wouldnt wast time, money processing power, nerves on atempting to brawse those pages on their smartphones... Its a country specific webpage... therefore country pecific app. On the page i want to parse there is this part
<li class="genre-3 genre-7 genre-9 mi-37 ">
<img src="picture.jpg" alt="altTitle">
<div class="superClass">
<a> aaa </a>
bbb
ccc
ddd
eee
</div>
<h2>title_of_super_product</h2>
<ul class="icons tooltip-enabled">
<li class="before"></li>
<li><img src="15_2.png" alt="15_2"></li>
</ul>
<div> </div>
<span class="material">some_material</span>
<span class="price">0.1USD</span>
<p class="text"> Some description </p>
<a class="button-more" href="http://link_to_more_info"></a>
</li>
The above is a ListItem, there are others similiar on the webpage. I have java class ready to fill it with data from the li lements. One clsss object for one li element. I need to extract the description, price, material, image links, stuff from superClass , meaning aaa,bbb,ccc,ddd, etc... The big question is how to do that? I thought that if i start from making a array that would consist of li elements i would be able to search each of them further for subelements i need... but it doest work ;(
TagNode[] liElements = rootNode.getElementsByName("li", true);
for (int i=0; liElements != null && i < liElements.length; i++) {
if(liElements.getAttributeByName("class").contains("genre"))
Log.d("li",liElements.getAttributeByName("class")); }
Gives only the first li element, then it spams nullPointerExceptions in the console Please please help, Im hopeless ;(;(;(
String classType =liElements.getAttributeByName("class");
if(classType!=null && classType.equals("genre........");
liElements[i]