How to register a xul window as listener of another? - xul

I have a keylistener that receives a function and calls it when a key is pressed:
function addKeyListener(functionToCall) {
addKeyEvent("keypress", function() { functionToCall(arguments[0]) }, false);
}
What can I pass to that function to let my window be a keylistener?

I'm not quite sure what your code snippet is trying to achieve, but if you have a reference to another window, and you want to listen to key events on that window, simply use otherWindow.addEventListener("keypress", eventHandler, false);.

OK, so given your clarification, it looks as if you need to do the following:
Locate the focused document in the other window: otherWindow.document.commandDispatcher.focusedWindow.document
Create a key event: otherDocument.createEvent('KeyEvents')
Initialise the event (type, code, modifiers etc.) from your key event
Locate the focused element, if any, in the other window:
otherWindow.document.commandDispatcher.focusedElement
Dispatch the event to the focused element, or document if no element has focus.

Related

Is there a "onExpand" event or similar for dijit.TitlePane?

Is there any way to get an event callback when the dojo-dijit's TitlePane expands?
I can capture onClick on the TitlePane. However, that is not enough for me. I have a button for "Expand All" TitlePanes. When user clicks on that I iterate on all TitlePanes and call it's toggle() method. When that happens, onClick event is not fired (as expected). I was wondering if there is any event fired upon toggle().
Or any other smart ways to address it also will be appreciated.
After looking into documentation in detail, I do not think there is any built in event that is fired during the toggle/expand. I ended up firing a custom event, and that helped me get what I wanted.
This answer helped me - https://stackoverflow.com/a/12852043/3810374
Basically,
First using isOpen() method, ensure the title pane is not already expanded. Then call toggle() method, and fire a custom event like this:
require(["dojo/on"], function(on){
// Send event
on.emit(target, "onExpand", {
bubbles: true,
cancelable: true
});
});
And then handle the event:
require(["dojo/on"], function(on){
// register event handler
on(target, "onExpand", function(e){
// handle event
});
});
You may be wondering, why not just do the work right after toggle(), instead of going through the pain of firing/handling event. I needed to handle the event in a particular closure, where I have access to other objects and variables.

ReactTestUtils.Simulate can't trigger event bind by addEventListener?

Here is the example:
http://jsfiddle.net/hulufei/twr4thuh/7/
It just worked when bind onClick in virtual dom(like line 18), but If I comment line 18 and comment off line 8 to bind click with addEventListener, it failed.
So what's the problem?
TestUtils triggers events within react's synthetic event system, so the native event that addEventListener listens for is never going to be triggered. You will need to use the native click method on the element in your test:
var events = Events();
ReactTestUtils.renderIntoDocument(events);
events.refs.button.getDOMNode().click();
events.state.event.should.equal('click');
Additionally, you've misspelled clickHandler in your addEventListener definition.
jsfiddle
You can also simplify adding your event listener by reusing your prop definition:
componentDidMount: function () {
this.refs.button.getDOMNode().addEventListener('click', this.clickHandler);
},
Note:
Is there a reason why you want to use addEventListener instead of just passing an onClick attribute for your button? Unless there's a specific and good reason otherwise, i'd suggest doing things the react way when handling events for sanity :)
Edit
I originally mentioned that I did not know what TestUtils' SimulateNative.click did not trigger the event. I was wrong in thinking that it ever would since it would be simulating a native click event within the react even system. #thilo pointed me in the right direction :)
I had many problems while testing addEventListener, and I got the following conclusion.
You can create the events listener with pure javascript, jquery, but when running the tests with Jest I always had a problem.
The rendering of ReactTestUtils does not work directly with the document, and when we do:
For example, our events were added in the document, when rendering with ReactTestUtils it creates a div and renders it in the div, This way I could not get Simulate to trigger the call.
My first solution was to use jquery to create the listener and to test I did the render manually by appending the div in document.body, and triggered the events with the dispachEvent of javascript. But I thought the code was dirty, not the best way to work.
I made a sample code by adding the event and testing it with Jest, also have a test teaching to get all the listener that were created.
You can find the code here: https://github.com/LVCarnevalli/create-react-app/tree/master/src/components/datepicker
Component:
componentDidMount() {
ReactDOM.findDOMNode(this.datePicker.refs.input).addEventListener("change", (event) => {
const value = event.target.value;
this.handleChange(Moment(value).toISOString(), value);
});
}
Test:
it('change empty value date picker', () => {
const app = ReactTestUtils.renderIntoDocument(<Datepicker />);
const datePicker = ReactDOM.findDOMNode(app.datePicker.refs.input);
const value = "";
const event = new Event("change");
datePicker.value = value;
datePicker.dispatchEvent(event);
expect(app.state.formattedValue).toEqual(value);
});
Links:
window.addEventListener not triggered by simulated events: https://github.com/airbnb/enzyme/issues/426
Creating and triggering events: https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events

Jquery .off vs dojo?

What is equivalent of jquery $.off(event) to remove event on element by passing event name in Dojo?
I tried :
dojo.disconnect(handle) // but I dont have an handle to event
How to get the handle or is there any better way to to it?
There is no out of the box solution as far as I know of, so you would have to implement one by yourself. However, this could be a dangerous feature, if you suddenly disconnect all event handlers of a specific type.
However, you could use the dojo/aspect module to intercept calls to the dojo/on module, for example:
aspect.around(arguments, 0, function(original) {
on.signals = [ ];
return function(dom, name, handler) {
console.log(arguments);
on.signals.push({
signal: original.apply(this, arguments),
name: name
});
};
}, true);
I didn't find a proper way to put an aspect around a function itself, rather than a function wrapped inside an object. So I used a dirty trick and used the arguments array and because the on module is my first argument, this will put an aspect around the dojo/on reference.
What happens is that when you bind an event handler using dojo/on, it will save it inside an array. Now you could write your own dojo/on::off() function, for example:
on.off = function(eventName) {
arrayUtils.forEach(on.signals, function(signal) {
if (signal.name === eventName) {
signal.signal.remove();
}
});
};
Now you can use:
on.off("click");
To disconnect all click event handlers.
A full example can be found on JSFiddle: http://jsfiddle.net/Lj5yG/ but this could probably be improved.

accessing dojo attach point outside templated widget

I have a dojo attach point for list item which is inside a templated widget.I need to access the dojo attach point outside the widget in order to assign onclick to the list item created by the template.How do I do it?
Well, if you want to attach an event handler to it, you have to provide a function. You can override functions/properties from outside using getters and setters.
I also suggest using data-dojo-attach-event if you only need the node for attaching event handlers. For example by using: data-dojo-attach-event="onclick: myFunction". By doing this, it needs a function called myFunction in your templated widget, provide a default function (in your widget) for example:
myFunction: function() {
/** Stub */
},
And then you can do something like this from outside:
myWidget.set("myFunction", function(evt) {
console.log("Someone clicked on the list item");
});
Because the myFunction event handler is overriden, it will execute the function provided in the setter.
You could also directly access the attach points from outside using:
myWidget.listItemNode
When you have a data-dojo-attach-point="listItemNode". However, I don't think it's recommended to use it this way because now your widget is tightly coupled (you use the internal functionality of the widget).
HTML template:-
<div data-dojo-attach-point="infoDialog" >
</div>
Save this as "Template.html"
---------------------------------------------
load this html file using "dojo\text" plugin in your widget i.e.
"dojo/text!./templates/Template.html",
and store as template in widget main function
-----------------------------------------------
assign it as template string to the widget.
templateString: template,
now this template attachpoint(infoDialog) will be the part of your current widget scope.
-----------------------------------------------
attach event:-
this.infoDialog.onclick=function(){
alert("hello world")
};

Onclick event handler by window.onload doesn't trigger

I want to call the function "details" when an element with the class "link" is clicked. This code doesn't work:
window.onload = function () {
document.getElementById("link").onclick = details;
}
How can I do this?
document.getElementById("link") will select an element with an id of "link", not an element with a class of "link".
Depending on what browsers you need to support, you might use document.getElementsByClassName() instead. (Won't work in IE8 or below, but works in all other browsers you are likely to care about.) You'll have to assign the click handler to each element that is returned.