i want some code to move the cursor position in an IFrame via Javascript or jquery.
Really it will help me a lot.
Not possible. To answer why that's impossible, imagine:
I include an iframe to some very important business (let's suppose for a moment this business does not have frame-busting code)
When the user reaches my page, it begins manually controlling the cursor's position to highlight the "Delete Account" button, and simulates a click.
User's account is deleted on a completely different site, through none of their input.
Javascript allows you many UI-coding capabilities, but ultimately the user is in control. Even events like the "onpageunload" are very much restricted in what they can do, and browsers will often include 'escape' options even there. Furthermore, even in the instance that you CAN find a way around these chains, it will frustrate and quite possibly even panic many of your users. I try to warn people that any instance in which you're "re-coding the browser" may lead to all sorts of unpredictable issues, and may even prevent handicapped accessibility to your site.
It might help us to know if there's some specific reason you'd like to do this - possibly the solution is not what you think it is. For instance, if you are trying to make an FPS using WebGL, I seem to remember Chrome including some function to allow for mouse control inside of a window (possibly taking a browser confirmation dialog)
You should check out
http://jqueryui.com/draggable/
You "could" put make the content in the iframe draggable, if you host the src for your frame.
If you don't host the src for your Iframe, you "could" put have an inner iframe that is draggable, and an outer iframe that displays the inner frame.
It is a very messy solution, I hope there is something better for you.
Related
I have an iframe, inside which arbitrary content is served. I want to ensure content within the iframe is not accessible to screen readers, and specify what screen readers should read out when the iframe is selected.
My expectation is when tabbing through different elements on the page, myDiv is selected as a single unit, and it reads out Unknown content.
I tried the following
<div id="myDiv" title="Unknown content">
<iframe id="myIframe" aria-hidden="true">
{arbitraryContent}
</html>
</div>
Problems I face with this are
Not all content within the iframe are being ignored. Perhaps that is because aria-hidden does not work with focusable child elements.
Unknown text is not always being read, especially if the child elements are focusable.
I also tried setting tabIndex=-1 on the iframe. This however causes all the elements (including myDiv) to not be selectable by keyboard.
What is the right approach to achieve what I am looking for?
If you prevent the screen reader from reading the entire iframe and if it still has focusable elements, yes, you have a fatal accessibility problem:
you can focus something but the screen reader isn't allowed to tell what is focused. So what to do ? Should it say nothing, or go against what you have defined ?
Technically, it means that there shouldn't be any focusable element inside aria-hidden=true.
You must ensure that it never happens.
However, the good question you have to ask yourself is why do you want to completely hide what is in the iframe or in other words, explicitely make it totally unaccessible.
IF your fear is that contents out of your control could break the accessibility of your page, then
Administratively speaking, certifications based on WCAG complience know this problem and usually accept exceptions, i.e. don't take into account something you haven't control in.
Pratically speaking as a screen reader user, the badly accessible iframe will probably indeed give the impression that the whole accessibility of your site is bad in general, but it's still certainly better to have some partially accessible content rather than nothing at all.
You'd better remove the aria-hidden=true. Even if you know that it isn't very accessible, leave a chance to access a little of it no matter what, instead of blocking it definitely. Perhaps the accessibility of the content will improve over time.
The exception to this is if the content of the iframe is objectionnable, decorative, or doesn't bring any real information in the context of your page. Typical examples include ads and various kinds of widgets (weather, clock, social network share, etc.)
For those, go ahead, leave the aria-hidden=true and remove all focusable elements of the iframe. They are anyway just useless noise, without any regret if they are completely skipped.
Goal
I'm making a Chrome extension to perform some manipulations on my university's website since the layout to select a course is bad. For this I need to access elements to read their inner information and also copy their CSS to add certain information that I will obtain from a different site, in a way that fits the style of the page.
Problem
When I open the source code on the exact page I want to use, it doesn't display the correct HTML. Instead it shows the main page's code under the dev tool. The interesting part is that when I highlight a certain element the code shows up and I'm able to make changes within the tool. But if I try to call a specific element under the console using $(id) or $$(id) it would show either null or [].
This causes some problems to because I'm new to any sort of web-related development and I would like to see the complete source so that I can select the elements I want and manipulate the page the way I would like. Maybe there is something I'm overlooking? that's why I need your help.
Possible reasons
I tried many things and try to research and concluded that it might have to do with frames since the url is not changing. However I'm not able to find any resources to teach me about frames (I know nothing about it) if that's the actual problem.
If the problem is another I would appreciate any assistance in solving it or any work around that I am not aware of.
The reason is definitely the use of frames. There are multiple documents at play here, the top level document and each frame has it's own document. This is important because the JavaScript you are executing is 99.9999% the top level document and not a child frame's document. Due to this, it's not finding the DOM nodes because it doesn't search the frames' documents.
Imagine you have a simple, single-page application - regardless of whether it was written using Backbone, Angular, Ember or anything else.
How can you tell a screen reader that we've changed 'page' when a route is followed?
In a classic application, when I navigate from /index.html to /about.html the screen reader obviously detects the page change, and re-reads as you'd expect.
In my Backbone application though, when I follow a route I cannot work out how to trigger a 're-read'. I've tried triggering a focus event which I'd seen somewhere, but that doesn't seem to work.
Note: I'm currently testing with NVDA/Chrome.
Overall, you should not need to trigger a 're-read', and depending on your UI that might not be a good thing anyway.
My experience has been with angular.js (as an accessibility person rather than the developer), and our overall approach was to manage the focus rather than trigger a re-read. (We do extensive accessibility testing.)
The key thing from a UI point of view (primarily for screen reader users) is that selecting a link (e.g. about.html) should take you somewhere.
In this case the appropriate place to put the focus would be the top of the content area of the about 'page', hopefully an <h1>.
In order for that to work the target element should be focusable via a script, so probably needs tabindex unless it is a link or form control:
<h1 id="test" tabindex="-1">
The -1 means it is not in the default tab order, but is focusable via a script. See more at WAI-ARIA authoring practices.
Then at the end of the function that loads the new content, including the tabindex attribute, add something like:
$('#test').attr('tabindex', '-1').css('outline', 'none');
$('#test').focus();
When adding tabindex dynamically it is best to do so in a line before the focus() function otherwise it may not work (I remember that from testing with JAWS).
To test this I would use either:
NVDA & Firefox, Windows
Jaws & IE, Windows
It is also good to test with VoiceOver on Safari/OSX, but that works differently and may not hit the same issues as a windows based screen reader.
You will hit a lot of issues with Chrome/NVDA as that is not supported very well, and end-users are very unlikely to use that. IE is ok with NVDA, but Firefox is best.
Overall, it is worth getting to know the WAI-ARIA authoring practices, particularly Using ARIA in HTML. Even though you are using a JS app, the browser (and therefore screen reader) is interpreting the resulting HTML so that advice is still relevant.
Lastly, if you are updating page content without the user pressing space/enter to activate something, you might find that JAWS/NVDA do not know about the new content as their 'virtual buffer' has not updated. In that case, you might need to add a JS shim to make them update, but only do that if you run into problems in testing, it should not be a global patch.
Taking the answer from #AlastairC, and the comments below it. I've taken this a bit further now and am going with this as my solution going forward:
My go-forward solution
I found that just reading out the first heading wasn't really that useful. Especially if the last page you were on was a loading sequence. You can hear that there something new has been focused, but it's certainly not clear that this forms the part of a whole now page.
Add some useful, descriptive text to the page
As such I now have a single paragraph at the top of my page layout template. This includes a screen-reader friendly message, along with a very rough overview of what the page.
<p class="screenreader-summary" tabindex="-1">
The <strong>Dashboard</strong> page is now on-screen.
It contains several widgets for summarizing your data.
</p>
Note that the tabindex value allows us to focus this element with JavaScript. You might not want to use a p element for this, you can use anything you like really.
Hide it off-screen (optional, only required if it would break your design/readability)
This is then coupled with CSS to move this element off-screen:
.screenreader-summary {
position: absolute;
left:-10000px;
top:auto;
width:1px;
height:1px;
overflow:hidden;
outline: none; /* Important, don't show an outline on-focus */
}
Focus this element, when a new page is shown on-screen
Finally, in the JavaScript code that shows your page on screen (e.g. in MarionetteJS using onShow or the show event):
$yourViewEl.find('.screenreader-summary').focus();
The result
I'm a sighted person, so take what I say with a pinch of salt - however I found that reading out a short description is so much more useful.
For angular the url changes, If someone REALLY needs to reread everything, (like me because of requirements), what did the trick for us was this:
$(window).on('hashchange', function () {
location.reload();
});
and we just added extra code to handle pages like "success" were no reloads are supposed to happen.
this simulates the actual page loading, and screen readers will read it normally like a page change.
kind of defeats the purpose of angular in a way, but this will help people like me who already have the application, and want a quick fix.
Clickjacking is when people trick users into clicking a button they're not supposed to, making them perform a malicious action.
I'm working on a product which, as an option for merchants, provides an iFrame component that can be embedded into a website to make a payment. Signed in users will see a button in the iframe that they can click to perform an important action. This action should only be called when the click is genuinely theirs.
i use this code to prevent clickjacking :
if (top == self || parent != top || document.location.hostname != document.domain) { top.location.replace("https:\/\/www.mysite.com\/?404");}
can someone break into my code ?
note: i don't want to use x-frame-option
thanks
From an Iframe you cannot really control clicks from the parent, if they click inside the Iframe but another event is watching it, you cannot really prevent it being from a different domain.
But all is not lost, the Iframe itself cannot stop it, but it can be wrapped with something like this. This is assuming jquery, might be best to translate to a native version for your application, in the interest of showing an example I will use jQuery.
<div id="i_wrap"><iframe src="SRC"></iframe></div>
<script>
$('#i_wrap').on('click',function(event){
event.stopPropagation();
});
</script>
Of course this is not a cure-all, there are still ways around this. You could also use a portion of the new HTML 5 cross document messaging read here on it to do some validation and possible warn the user on an unsafe site (if your iframe gets no message, then you show no button).
Though I have no experience in the cross document messaging methods, and I am sure they probably don't allow different domains (though there may be ways around that, to an extent).
Though this question is not totally clear and I may not be understanding it perfectly, if you update your question with more details I will update my answer to suit.
For my current project, I require the facility to be able to remove all functionality from a page, so that it is complete and literal static page. Removing the ability to follow any links, and disabling and javascript listeners allowing content to be changed on the page. Here is my attempt so far:
$("*").unbind().attr("href", "#");
But in the pursuit of a perfect script, and to allow it to work in every eventuality for any possible page (and with the uncertainty of a on liner being effective enough), I thought i'd consult the experts here at stackOverflow.
In summary, my question is, 'Can this be (and has it been) done in a one liner, is there anything this could miss?'. Please break this as best you can.
No. Nothing in this stops meta redirects, or timeouts or intervals already in flight, and it does nothing about same origin iframes (or ones that can become same origin via document.domain) that can reach back into the parent page to redynamize content.
EDIT:
The sheer number of ways scripts can stay submerged to pop up later is large, so unless you control all the code that can run before you want to do this, I would be inclined to say that it's impossible in practice to lock this down unless you have a team including some browser implementors working on this for some time.
Other possible sources of submarine scripts : XMLHttpRequests (and their onreadystatechange handlers), flash objects that canscript, web workers, and embedding code to run in things like Object.prototype.toString.
I did not want to write a lengthy comment so I'm posting this instead.
As #Felix Kling said, I don't think your code will remove the href attributes on every element but rather remove every element and then select their href attributes.
You probably need to write:
$("*").attr("href", "#").detach() ;
to remove the attributes instead of the elements.
Other than that, I doubt that you could remove the event handlers in one line. For one thing you would need to account for DOM level 2 Event registration (only settable with scripting) and DOM level 1 Event registration (via attributes or scripting).
As far as I'm concerned, your best bet is to make a shallow document copy using an XML parser and replace the old document (which you could backup-save to the window).
First: Your code will remove everything from the page, leaving a blank page. I cannot see how it would make the page "static".
$('*').detach();
will remove every element form the DOM. Nothing left. So yes, you remove every functionality in a way, but you also remove all the content.
Update: Even with the change from detach to unbind, the below points are still valid.
Event listeners added in the markup via oneventname="foo()" won't be affected.
javascript: URLs e.g. in images might still be triggered.
Event listeners added to window and document will persist.
See a DEMO.