Can't parse html correctly / empty body after parsing - xpath

I am facing an odd problem. I im trying to parse the following html:
The problem is that when I do
response.xpath('//div//section//div[#id="hiring-candidate-app"]')[0].extract()
I only get
'<div id="hiring-candidate-app"></div>'
instead of all the content under hiring-candidate-app.
I would like to get, for instance, inside-content, but it looks like I am not even getting that in the response. This webpage requires to be logged in, which I am.
Thanks in advance!

It looks like your Xpath is grabbing the right thing. But your issue might have to do with the '[0]' part of the call. I would remove that to get the full content of the div.

It looks like the elements in question sit on an <iframe>, and therefore live in a different context. You need to activate or switch to the context of the iframe, eg. using JavaScript to interact with an iframe and the document inside of it, e.g.
//Note: Assigning document.domain is forbidden for sandboxed iframes, i.e. on stacksnippets
//document.domain = "https://stacksnippets.net";
var ifrm = document.getElementById("myFrame");
// reference to iframe's window
//var win = ifrm.contentWindow;
// reference to document in iframe
var doc = ifrm.contentDocument ? ifrm.contentDocument : ifrm.contentWindow.document;
// reference an element via css selector in iframe
//var form = doc.getElementById('body > div > div.message');
// reference an element via xpat in iframe
var xpathResult = doc.evaluate("/html/body/div/div[1]", doc, null, XPathResult.ANY_TYPE, null);
<iframe id="myFrame" src="https://stacksnippets.net" style="height:380px;width:100%"></iframe>
However, as you can see when you run the snipped, cross-document interactions are only possible if the documents have the same origin. There are other, more involved methods like the postMessage method that provide the means of interacting cross-domain.

Related

Single page application with Rails 4 and AngularJS

Ok, this idea might seem quite a bit crazy and it kindo' is (at least for me at my level).
I have a fairly standarad rails app (some content pages, a blog, a news block, some authentication). And I want to make it into a single page app.
What I want to accomplish is:
All the pages are fetched through AJAX like when using turbolinks, except that the AJAX returns only the view part (the yield part in the layout) withought the layout itself, which stays the same (less data in the responces, quicker render and load time).
The pages are mostly just static html with AngularJS markup so not much to process.
All the actual data is loaded separately through JSON and populated in the view.
Also the url and the page title get changed accordingly.
I've been thinking about this concept for quite a while and I just can't seem to come up with a solution. At this point I've got to some ideas on how this actualy might be done along with some problems I can't pass. Any ideas or solutions are greatly appreciated. Or might be I've just gone crazy and 3 small requests to load a page are worse then I big that needs all the rendering done on server side.
So, here's my idea and known problems.
When user first visits the app, the view template with angular markup is rendered regularly and the second request comes from the Angular Resource.
Then on ngClick on any link that adress is sent to ngInclude of the content wrapper.
How do I bind that onClick on any link and how can I exclude certain links from that bind (e.g. links to external authentication services)?
How do I tell the server not to render the layout if the request is comming from Angular? I though about adding a parameter to the request, but there might be a better idea.
When ngInclude gets the requested template, it fires the ngInit functions of the controllers (usually a single one) in that template and gets the data from the server as JSON (along with the proper page title).
Angular populates the template with the received data, sets the browser url to the url of the link and sets the page title to what it just got.
How do I change the page title and the page url? The title can be changed using jQuery, but is there a way through Angular itself?
Again, I keep thinking about some kind of animation to make this change more fancy.
Profit!
So. What do you guys think?
OK, in case enyone ever finds this idea worth thinking about.
The key can be solved as follows.
Server-side decision of whether to render the view or not.
Use a param in the ngInclude and set the layout: false in the controller if that param is present.
Have not found an easier way.
Client-side binding all links except those that have a particular class no-ajax
Here's a directive that does it.
App.directive('allClicks', function($parse) {
return {
restrict: 'A',
transclude: true,
replace: true,
link: function(scope, element, attrs) {
var $a = element.find('a').not($('a.no-ajax')),
fn = $parse(attrs['allLinks']);
$a.on('click', function(event) {
event.preventDefault();
scope.$apply(function() {
var $this = angular.element(event.target);
fn(scope, {
$event: event,
$href: $this.attr('href'),
$link: $this
});
});
});
}
};
})
And then use it on some wrapper div or body tag like <body ng-controller="WrapperCtrl" all-links="ajaxLink($href)"> and then in your content div do <div id="content" ng-include="current_page_template">
In your angular controller set the current_page template to the document.URL and implement that ajaxLink function.
$scope.ajaxLink = function(path) {
$scope.current_page_template = path+"?nolayout=true";
}
And then when you get your JSON with your data from the server don't forget to use history.pushState to set the url line and document.title = to setr the title.

canvas.drawImage(canvas, 0,0) getting Type Error

I am trying to copy the image from one canvas to another canvas. I have seen an answer saying that an easy way to do it is:
var Scanvas = $("#sourceCanvas");
var Scontext = Scanvas.get(0).getContext("2d");
var Dcanvas = $("#destinationCanvas");
var Dcontext = Scanvas.get(0).getContext("2d");
//draw something in Scanvas
Dcontext.drawImage(Scanvas, 0 ,0);
However, whenever I try this I keep getting a Type Error.
The browser I am using is an up-to-date version of Google Chrome, so I don't think that is the problem.
You are using a jQuery object as the first parameter of drawImage().
It needs to be a pure DOM object.
You can access the underlying DOM objects in jQuery by calling get() and specifically get(0) if there is only one object in jQuery selection, as mentioned in the comments.
DContext.drawImage(Scanvas.get(0),....)

How to retrieve images (decoded if possible) present in a wepage using XPCOM

How to get all the images, after decoding if possible, on a webpage through XPCOM ?
The image might be specified in HTML as a background url in some CSS property, inside img tag, or in any form that a web developer might have included.
I tried looking into imgIContainer, imgIDecodeObserver and many other interfaces. Although there is a way through which we can provide image URI to Mozilla so that it loads the image, decodes it and returns imgIContainer. But I couldn't find anyway to get all images in current webpage.
This has to be done in either Java or Javascript.
Any suggestions?
#Wladimir - Thanks for your help.
I want all the images including CSS constructs (background images). So now I am listening to events from nsIWebProgressListener.
onStateChange: function(webProgress, request, stateFlags, status) {
if ((~stateFlags & (nsIWebProgressListener.STATE_IS_REQUEST | nsIWebProgressListener.STATE_STOP)) == 0) {
var imgReq = request.QueryInterface(CI.imgIRequest);
if (imgReq)
var img = imgReq.image;
}
}
The problem is that request.QueryInterface(CI.imgIRequest) throws exception for all NON-image requests. Although those exceptions can be ignored by putting code inside try-catch block, but I'd prefer to do things cleanly.
Is there any condition that can be checked to know whether request is for image or not?
There is existing code that you can look at. The Page Info dialog has a Media tab that successfully shows most images on the page. The important function is grabAll() in pageInfo.js, it is called for each element (via a TreeWalker). As you can see, there is no generic way to get the image, this function rather uses window.getComputedStyle() to extract the values of a bunch of the CSS properties for this element: background-image, border-image, list-style-image, cursor. It will also look for <img>, <svg:image>, <link> (favicon), <input>, <button>, <object> and <embed> tags. It doesn't manage to recognize everything however, e.g. these CSS constructs will not be recognized:
.foo:before
{
content: url(image.png);
}
.foo:hover
{
background-image: url(image.png);
}
Still, this is probably as far as you can get - unless you want to look at the requests made by the web page as it loads.
Edit: If you look at the requests as they are performed (via a web progress listener), you can do the following:
if (request instanceof CI.imgIRequest)
var img = request.URI.spec;
Note that request.image won't help you much, almost all methods of imgIContainer are only accessible from native code.

Selecting a div from prototype response Magento

Hello i am using Prototype javascript library in Magento.
I am getting an ajax response and everything is working fine.
The response is saved in the response variable.
var response = transport.responseText || "no response text";
What i want is to fetch a div and its content from the response variable. I am totally confused on how to do it.
I want to get the div and its content and replace it with the current div and its content.
I know how to do it by $('div').update('content') but i am not able to fetch the exact div the content within the div.
You could try something like this:
var container = new Element("div", {}).update(responseText); // this way you get a valid Prototype Element that you can easily query
// performs your query on the Prototype Element
// NOTE: remember to not include the root "div" when attaching your response to the html page
Hopefully I answered your question. If not, please add a sample of code of what you are trying to accomplish!

Dynamic Elements are not appearing in IE8 until there is a mouse click

I have an Ajax request that returns search results, and I am dynamically creating DOM elements to display those results. This is working as expected in all the browsers I've tested except for IE8.
The request is returning fine, the JavaScript is running successfully, and the elements are being created, but the elements are not being displayed in the page. They only appear after a mouse-click somewhere on the page.
I ran a quick test that ran the callback code without the Ajax request, and it behaved as expected there. So I'm wondering if this has something to do with the way IE8 is managing the callback thread. Has anyone else seen behavior like this, or have insight on it?
The callback is fundamentally very simple. I have reproduced with this:
function catchResults(response) {
var contentBlock = document.getElementById('divResults');
var divResults = document.createElement('div');
var txt = document.createTextNode("Results");
divResults.appendChild(txt);
contentBlock.appendChild(divResults);
}
I am using JQuery.ajax to make the call.
I have seen the proper behavior in FireFox and Chrome.
Thanks for the help!
I ran into this problem not so long ago on IE8.
I think this might be a problem with IE8 not re-rendering the elements in question.
An easy way to confirm this is to add a class to the parent element and then remove it. This should trigger IE8 to re-render the element.
If contentBlock is the parent element then you could test with the following:
Javascript version:
// Variable storing the test class name
var testClass = "testClass";
// Add test class to element
contentBlock.className += " "+testClass;
// Remove test class from element
var reg = new RegExp('(\\s|^)'+testClass+'(\\s|$)');
contentBlock.className=contentBlock.className.replace(reg,' ');
jQuery version:
// Variable storing the test class name
var testClass = "testClass";
// Add test class to element and then remove it
$('#divResults').addClass(testClass).removeClass(testClass);
Just put it at end of the function after you appendChild. Hopefully this should fix your issue.
Reference: http://www.openjs.com/scripts/dom/class_manipulation.php

Resources