How to register keypress event listener on non-root element? - svg

I've been developing a text editor based on SVG, and I'm now trying to
make it so that multiple instances can be instantiated in a single SVG
document. The way I've been trying to achieve this is to wrap the DOM
representation of each text editor instance with a single parent
element (either or ), and then to attach a keypress event
listener to that parent element. The problem I'm running into, though,
is it seems that keypress events are only received by the document
root. Furthermore, for all browser SVG implementations I've tried, the
target, originalTarget, and explicitOriginalTarget event properties,
when they exist, are also set to the document root, so it doesn't
event seem like it's possible to hack a solution by attaching a single
event listener on the document root, and then manually dispatching
events by reading the event's originalTarget property.
So far, I've tested Firefox 3.6, Chromium 9, Opera 11, and Batik
Squiggle 1.7, with the following test case:
http://stuff.echo-flow.com/svg-developers/testEventListener.svg
Only Batik works as expected, with the rect element receiving the
keypress event. In Firefox, target, originalTarget, and
explicitOriginalTarget are all equal to the root element. In Chromium
and Opera, target is set to the root element, and originalTarget and
explicitOriginalTarget are undefined.
Basically, what I'm trying to do is relate a keypress event back to
the element that originally fired it. I think I could probably get
this to work if I used an HTML context and embedded iframes; or, if I
used iframes inside of a foreignObject. But I'm wondering if there's a
cleaner workaround that does not require the use of iframes.
Furthermore, I guess as a worst-case scenario, I could do my own hit
testing by inspecting the clientX/clientY properties of the keypress
event, and comparing that to the bboxes of all text editor group
elements. But once again, this seems very hacky, and I wonder if
there's a better approach.

First, it's better to specify the SVG version and baseProfile you're using in your SVG document.
So far, SVG only support (in the specifications) those events, no key press event. Browsers are a bit ahead the specs, so, lets just assume it's supported.
So, you're using the DOM 3 Event keypress since it doesn't exist in DOM 2 Events.
Looking at keypress event context infos :
Event.target: focused element processing the key event, root element if no suitable input element focused
Focus is not mouse position. In the SVG 1.1 specs, no "focusable" attribute exists, but you can find it in the SVG 2.0 draft.
So Batik use a wrong "keypress event" implementation. You could use the "mouseover event" to know what element you're hovering, or try if the "focusable" attribute is already working on some browsers.
Also, originalTarget and explicitOriginalTarget are Mozilla specific, non standard, that explain your results with other browsers.

Related

Make WebdriverIO wait for a specific component to reload

I am testing an Electron/React app using Spectron, which uses the WebdriverIO commands API. I would like to test the attributes on some components, but I want to be sure I am testing them only after the component has reloaded.
The normal WebDriverIO wait commands like waitForText() or waitForExist(), wait for some change, but I need to wait until a component redraw has occurred. For example the component will already exist or will already have some text before it is redrawn. This means any test on the text will occur before the redraw, and I won't be testing the new text. Is there a general way to wait for a redraw?
You can use the custom 'waitUntil' command to wait for just about anything. You'd need to figure out what you're waiting for, or how to tell that the component has been redrawn, but it should be possible.
Is there a class name you can tag in to?
Also, the 'waitFor' commands do take negation flags, allowing you to wait for an element to stop existing or stop having text. That might be useful.
Another solution, to this specific question on waiting for changing text, is to use an XPath selector. The XPath language treats an HTML page like a tree, but text, amongst other things, is also a separate node in that tree. Unlike a CSS selector, you can easily select an element based on it's inner text. See this article.
So if my XPath selector uses a text 'predicate', then I can use a standard waitForExist command from the webdriver API.
For example, say my p element, after the redraw, should have the text 'Burgers'. It did exist before the redraw but it had some other text. To only select it when it has the new next:
const selector = '//*p[text()="Burgers"]';
browser.waitForExist(selector);

IE11 full screen on element

IE 11 has been out just one day as of this posting.
I cannot get an element to go full screen (div or document)
http://msdn.microsoft.com/en-us/library/ie/dn265028
msRequestFullscreen will error 'object does not support this...)
However, the above msdn example will work on passing a target - makeFullScreen(evt.target).
Can I get an div to go fullscreen as in following jquery code?:
var xxx = $('#container');
xxx.msRequestFullscreen();
Or better still: click a button then have a div or the entire document to go fullscreen?
As it stands now, when a click a button, it's the button that goes full screen.
I think this is actually a small misconception of JQuery. JQuery-ing an ID doesn't actually return the element found - it returns a "JQuery object" which allows many actions on that element (or, on a series of elements if you used a class selector)
I don't have IE11 available so I can't test for you, but try this. The [0] should retrieve the element itself.
var xxx = $('#container')[0]; xxx.msRequestFullscreen();
Your code:
var xxx = $('#container');
xxx.msRequestFullscreen();
This is wrong, because you're trying to call a DOM method on a jQuery object.
jQuery calls like $('#container') return jQuery objects. You can do lots of things with these objects, but one thing you can't do is call standard DOM methods. For that, you need an actual DOM object.
jQuery objects contain an array of matching DOM objects, which you can access via [0] for the first one, and [1], etc if there was more than one matching element. So you can do your call by changing your second line as follows:
xxx[0].msRequestFullscreen();
This will call the msRequestFullscreen() on the DOM element rather than the jQuery element, and that should work for you.
In this case, you don't even need jQuery at all, since you're not using any of the jQuery functionality. You could simply use document.getElementById('container') to get the DOM object in the first place rather than the jQuery method. Then you don't need the [0] syntax on the second line because you've already got the DOM object.
Finally, you might want to be careful of course, because this is an IE-specific method; the ms at the front of the name tells you that, which means that your code won't work in other browsers, even if they support the same feature. You need to do it in a cross-browser way. There are some tips on how to do this here: How to make the window full screen with Javascript (stretching all over the screen)

Pre-loading browser clipboard for testing pasting into fields with watir-webdriver

Our web application has some event code to "format" any text with pasted into a field so that any HTML styles do not break our data.
What would be a good way to pre-load the browser clipboard so that I can test pasting into the input field?
Is there any way to do it programmatic-ally or would I have the test script visit "a source page" and copy text before moving onto our application?
Any ideas or code snippets would be welcome.
Working with the clipboard will depend on your platform. E.g. on OS X, you can use pbcopy and Command-V:
open('|pbcopy', 'w') { |io| io << 'some text' }
browser.text_field(:name => 'q').send_keys([:command, 'v'])
I know there are equivalents on Linux (xclip?). Not sure about Windows.
I would consider using the .value= method to set the value. If it's been implemented the same as in watir, then it causes no events to be fired and sets the value directly, and then follow that up by sending an appropriate event (depending on what if any events are being monitored) such as onKeypress. I tried to figure out from the Watir-webdriver rdoc for textfield, if this distinction between .set and .value= has been maintained, but the way the doc describes them (at least there) makes them seem interchangable.. (Jarib can you clarify???)
Potentially you might need to first fire something like onFocus depending on the controls you are using. For example, as described in this SO case Setting a text field that has a JQuery mask on it for a jquery mask, they had to end up firing an unmask event to be able to even set the field.
This is a good case for utilizing the techniques described here How to find out which JavaScript events fired? and in the SO item linked in the comments for that question, to figure out just what events are fired when you manually paste something into a field. (note I would slueth it with both using the mouse, but also using something like tab to move between fields and set the focus, events common to those two methods are the ones most likely to be implemented by the controls.
I presume you have some kind of client side javascript that needs to check what was pasted into the field, and thus the reason for this test. If you are using standard HTML fields, with no javascript stuff, then I would consider this particular test case to be effectively the same as 'testing the browser' since supporting cut and paste in input fields is a standard browser function. In that case, you are sort of 'off the reservation' and I'd not bother with such a test case.

Core data dirty flag not being set

I have a core data document based cocoa app that is working well except for one slightly odd problem.
For some reason, if I make a change to any of my fields the menu/window don't seem to recognize it - ie. the red close button doesn't get the black 'dirty' indicator and the File/Save menu item isn't enabled. However, if I attempt to close the application (via command-Q), I do get the popup asking me if I want to save my changes.
It seems that the document's dirty flag is being set, but the window/menu items aren't reacting to it. I am curious as to where I might look to see why this might be the case. I suspect that it may have something to do with my window not knowing about my ManagedObjectContext...
The only slightly atypical behaviour is that my document's makeWindowControllers method has been overridden and I am adding my window controllers using a call to my document's [self addWindowController:xxx] method. My window controllers subclass from NSWindowController so I had to add my own instance variable to each window controller to hold the ManagedObjectContext, but I suspect that this isn't getting passed to the window/menu. Not sure what the normal pattern is here...
Anyway, any thoughts would be much appreciated. Thanks
From the description it sounds like your UI elements are not actually bound to the document itself. If so, then the UI elements are not observing the document and are not reacting to changes in the document. Check the bindings.
Thanks in part to TechZen, and also re-reading my own question (in particular, where I said "I suspect that it may have something to do with my window not knowing about my ManagedObjectContext") I started to look at the bindings for my WindowController subclass.
As it turned out, I hadn't bound the window outlet for the File's Owner to my actual NSWindow. As soon as I did that, the black dirty dot and the window's menus started behaving correctly.

What's the purpose of the GtkWidget.events property for (like) GtkTreeView widgets?

I have a Glade GUI description file with a GtkTreeView in a GtkHBox in a window; and there's a handler for the row_activated signal. Now, Glade has automatically set the "events" property (inherited from GtkWidget) of that treeview to some value (GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK). And there are two strange things with this:
removing the pre-set value (so that the property is empty) doesn't seem to break the application (at least not with the old GTK 2.10 I have atm).
in fact, an annoying bug I has seen before (where the treeview items would not correctly react to expand or collapse clicks) is now gone!
I have yet to test this with a newer GTK version, but the question is already there: exactly what is the purpose for this events property? And why does Glade automatically and unnecessarily set it to some value? Does this have some side effects I'm not aware of?
It's a bug in glade, it always sets the event property of widgets it create. It has no notion of the default value of a property so it always sets it.
Doesn't this mask indicate the events you're willing to receive? In this case, you'll probably want to receive notification that the user has clicked or double-clicked an item in the GtkTreeView, and you'll want to register callbacks to handle these events.
me.yahoo.com/a/kUQ7zeQ: but even if I set the property to an empty string as mentioned, the row_activated handler is still called when I double-click on a row (or press Enter or Space). So the treeview still gets events...

Resources