How would one abstract away the usage of browser's window object when using the Aurelia framework? I would like to avoid direct dependency on the browser when using functionality such as setInterval or addEventListener for example.
Aurelia has something called Platform Abstraction Library which in theory should provide the functionality I am looking for. However, I could not find any documentation about it at the time of writing this question.
Few examples:
import {DOM, PLATFORM, FEATURE} from 'aurelia-pal';
PLATFORM.addEventListener('click', e => ...);
PLATFORM.requestAnimationFrame(() => ...);
let event = DOM.createCustomEvent('foo', { bubbles: true });
DOM.dispatchEvent(event);
let element = DOM.createElement('div');
if (FEATURE.shadowDOM && FEATURE.scopedCSS && FEATURE.htmlTemplateElement) {
...
}
There's no setTimeout / setInterval in the PAL- I think because aurelia doesn't use setTimeout. I've added an issue to get these added.
Related
I'm trying to write Robot Framework tests to cover certain use cases for a third party AngularJS app.
I have the requirement that I need to use Python 3.5+ and SeleniumLibrary (rather than the old Selenium2Library).
I've attempted to adapt the wait_until_angular_ready keyword from https://github.com/rickypc/robotframework-extendedselenium2library to work outside of the context of this library, updating it to work with Python 3.5+ and SeleniumLibrary.
The keyword executes the following JavaScript to check when Angular is Ready, but it seems to always return true immediately
var cb = arguments[arguments.length-1];
if(window.angular){
var $inj;
try {
$inj = angular.element(document.querySelector('[data-ng-app],[ng-app],.ng-scope')
||document).injector()
||angular.injector(['ng'])
} catch(ex) {
$inj = angular.injector(['ng'])
};
$inj.get = $inj.get||$inj;
$inj.get('$browser').notifyWhenNoOutstandingRequests(function() {
cb(true) // it's always returning here
})
} else {
cb(true)
}
This is called from within my version of the wait_until_angular_ready keyword which is located in a class which subclasses the SeleniumLibrary WaitingKeywords class.
The code which executes the Js looks like
WebDriverWait(self.driver, 100, 0.1). \
until(lambda driver: driver.execute_async_script(script), error)
Have I made a mistake here or is this not the correct way to check when angular has finished rendering the page? I will admit that I am not very familiar with AngularJS
Probably you resolved this issue, but if anyone in the future have the same inconvenience can use this library for Angular in Robot framework: https://github.com/Selenium2Library/robotframework-angularjs
you can use document.readyState , it will return "complete" as a response if the page is rendered completly.
Basically I'm wondering whether it is possible to redefine a method at class level, not instance level, as sought here.
Just to make clear, also, I want to be able to call the original method (on this) from within the enhanced/replacement method.
I tried implementing the chosen answer, "decorating the constructor", but it doesn't appear to work in FF55's "SpiderMonkey" version of ES2017: I get a message saying the class "requires new".
Doing a bit of googling I found this article. This man talks about a whole bunch of concepts which I wasn't even aware existed in Javascript! My knowledge of JS hasn't gone much beyond the Javascript Definitive Guide 6th Edition, although I do use Promises and async/await a lot (I'm hoping a new edition of the JS Def Guide will come out one day...).
So are there any experts out there who know of a way to, essentially, "enhance" (i.e. re-engineer, not extend) existing JS classes in ES2017?
Let say you have a class named Original, which has a render method, which you want to update.
class Original {
render() {
return 'Original';
}
}
You can update it by changing the render method of the prototype of the Original function like so:
Original.prototype.render = function() {
return 'Changed';
}
If you want to add a new method to your class this is how you do it:
Original.prototype.print = function() {
return 'Printing...';
}
Then you can use these methods as usual.
const changed = new Original().render();
const printed = new Original().print();
Whoops... thanks to Dovydas for this. I was obviously having a mental block!
const superObserve = MutationObserver.prototype.observe;
MutationObserver.prototype.observe = function( target, config ){
console.log( 'blip');
superObserve.call( this, target, config );
}
I want to implement a custom event that can be "broadcast", rather than sent to specific targets. Only those elements that have registered themselves as listeners for such events will receive them.
What I have in mind would look as follows.
First, in various places of the code, there would be statements of the form
some_subscriber.on_signal( 'some_signal', some_handler );
I'm using the term signal as shorthand for "broadcast event". In the expression above, some_subscriber registers itself as a listener of one type (called 'some_signal') of such signals, by providing a handler for it.
Elsewhere in the code, there would be statements of the form
publisher.signal_types[ 'some_signal' ].broadcast( event_data );
When statements like these get executed, a new event is generated and "broadcast". By this I mean that the code that calls the broadcast method has no direct information about the listeners for the signal it is issuing.
I have implemented a sketch of this idea in this jsFiddle, mostly in order to illustrate what I described in words above1. (It's certainly not production-grade, and I'm not particularly confident that it could be made so.)
The key elements of this implementation are the following. First, publisher objects do not keep track of their subscribers, as can be seen in the implementation of a factory method for such a publisher, shown below:
function make_publisher ( signal_types ) {
// ...
var _
, signal = {}
, ping = function ( type ) {
signal[ type ].broadcast( ... );
}
;
signal_types.forEach( function ( type ) {
signal[ type ] = $.register_signal_type( type );
} );
return { signal_types: signal_types, ping: ping };
}
This publisher object exposes only two items: the types of signals it broadcasts (in signal_types), and a ping method. When its ping method is invoked, the publisher responds by broadcasting a signal:
signal[ type ].broadcast( ... )
The ultimate recipients of this broadcast are nowhere to be seen in this code.
Second, elsewhere in the code, subscribers register themselves as listeners of these broadcast signals, like so
$( some_selector ).on_signal( signal_type, some_handler );
Note: It is basically impossible to illustrate the rationale for this scheme using an example that is both small and realistic. The reason for this is that the strength of this scheme is that it supports very loose coupling between the publisher code and subscriber code, and this is a feature that is never necessary in a small example. On the contrary, in a small example, code that implements such loose coupling invariably comes across as unnecessarily complex. It is therefore important to keep in mind that this apparent excess complexity is an artifact of the context. Loose coupling is very useful in larger projects. In particular, loose coupling via a publisher/subscriber-type pattern is one of the essential features of MVC.
My question is: is there a better (or at least more standard) way to achieve this effect of "broadcasting" custom events?
(I'm interested in both jQuery-based answers as well as "pure JS" ones.)
1An earlier, ill-fated version of this post was met with almost universal incomprehension, and (of course) the all-too-typical down-voting. With one exception, all the comments I got challenged the very premises of the post, and one directly questioned my grasp of the basics of event-driven programming, etc. I'm hoping that by presenting a working example of what I mean at least it won't come across as utterly inconceivable as it did when I described it in words alone. Luckily, the one helpful comment I did get on that earlier post informed me of the function jQuery.Callbacks. This was indeed a useful tip; the sketch implementation mentioned in the post is based on jQuery.Callbacks.
All right.
So I think what you can do is use the native dispatchEvent and addEventListener methods and use document as the only element for both publishing and subscribing to those events. Something like:
var myCustomEvent = new Event('someEvent');
document.dispatchEvent(myCustomEvent);
...
document.addEventListener('someEvent', doSomething, false);
And to make cross-browser, you could:
var myCustomEvent = new Event('someEvent');
document.dispatchEvent(myCustomEvent);
...
if (document.addEventListener) {
document.addEventListener('someEvent', doSomething, false);
} else {
document.attachEvent('someEvent', doSomething);
}
You can read more on the subject here and here. Hope this helps.
My question is: is there a better (or at least more standard) way to
achieve this effect of "broadcasting" custom events?
No, there is not a more standard way of doing publish/subscribe in Javascript. It is not directly built into the language or the browser and there are no platform standards for it that I'm aware of.
You have several options (most of which you seem aware of) to put your own system together.
You could pick a specific object such as the document object or the window object or a new object you create and use jQuery's .on() and .trigger() with that object as a central clearing house to cobble together a publish/subscribe-like model. You could even hide the existence of that object from your actual use by just coding it into a few utility functions if you want.
Or, as you seem to already know, you could use the jQuery.Callbacks functionality. There's even publish/subscribe sample code in the jQuery doc.
Or, you can find a third party library that offers a somewhat traditional publish/subscribe model.
Or, you can build your own from scratch which really just involves keeping a list of callback functions that are associated with a specific event so when that event is triggered, you can call each callback function.
If you came here looking for the jQuery way of doing this, here you go:
Add the event broadcast/dispatch code:
Syntax:
$(<element-name>).trigger(<event-name>);.
Example:
$.ajax({
...
complete: function () {
// signal to registered listeners that event has occured
$(document).trigger("build_complete");
...
}
});
Register a listener for the event:
Syntax:
$(<element-name>).on(<event-name>, function() {...});
Example:
$(document).on("build_complete", function () {
NextTask.Init();
});
Note:
Doing it this way: $(document).build_complete(function() {...}); leads to an error: Uncaught TypeError: $(...).build_complete is not a function.
I know this has been marked as answered back in 2015 -- but a solution that is also elegant and simple could be to use Redux
I'm working on implementing correct memory management for a native Node.js module. I've ran into the problem described in this question:
node.js native addon - destructor of wrapped class doesn't run
The suggested solution is to bind the destructors of native objects to process.on('exit'), however the answer does not contain how to do that in a native module.
I've taken a brief look at the libuv docs as well, but they didn't contain anything useful in this regard, either.
NOTE: I'm not particularly interested in getting the process object, but I tried it that way:
auto globalObj = NanGetCurrentContext()->Global();
auto processObj = ::v8::Handle<::v8::Object>::Cast(globalObj->Get(NanNew<String>("process")));
auto processOnFunc = ::v8::Handle<::v8::Function>::Cast(processObj->Get(NanNew<String>("on")));
Handle<Value> processOnExitArgv[2] = { NanNew<String>("exit"), NanNew<FunctionTemplate>(onProcessExit)->GetFunction() };
processOnFunc->Call(processObj, 2, processOnExitArgv);
The problem then is that I get this message when trying to delete my object:
Assertion `persistent().IsNearDeath()' failed.
I also tried to use std::atexit and got the same assertion error.
So far, the best I could do is collecting stray ObjectWrap instances in an std::set and cleaning up the wrapped objects, but because of the above error, I was unable to clean up the wrappers themselves.
So, how can I do this properly?
I was also getting the "Assertion persistent().IsNearDeath()' failed" message.
There is a node::AtExit() function that runs just before Node.js shuts down - the equivalent of process.on('exit').
Pass a callback function to node::AtExit from within your add-on's init function (or where ever is appropriate).
The function is documented here:
https://nodejs.org/api/addons.html#addons_atexit_hooks
For example:
NAN_MODULE_INIT(my_exports)
{
// other exported stuff here
node::AtExit(my_cleanup);
}
NODE_MODULE(my_module, my_exports) //add-on exports
//call C++ dtors:
void my_cleanup()
{
delete my_object_ptr; //call object dtor, or other stuff that needs to be cleaned up here
}
I would like to ask if there is a liveconnect equivalent for ActionScript 3. I understand that there is the ExternalInterface class inside AS3 but it only supports calling a method by name. The really cool thing about Java and LiveConnect is that you can do something like
function jsFunc(name) = {
this.name = name;
this.talk = function(){
alert('hello world my name is ' + this.name);
}
}
javaapplet.function(new jsFunc("bob"));
The above approaches pseudo code since I never tested it but I've seen it in action. In AS3, while I am able to pass in an instance of JavaScript "object" into AS, it is often converted into an ActionScript Object instance which does away with all the functions as far as I'm aware.
I saw an implementation of JSInterface but I don't think it does specifically that. Is there any way to make OO like javascript work with ActionScript 3?
Try this library on Google code:
http://code.google.com/p/jsobject/
ExternalInterface.call("f = function() { alert('Is this like live connect?'); }");
Actually the main usage scenario is to have JS "objects" interacting with the Flex SWF application. Therefore when the JS "object" wants to say wait for something happening in the SWF object, it will put in a "this" with a callback.
After researching, the way I used to accomplish this is via the Flex Ajax bridge. It may not be a direct answer to the way I phrased the question but it was sufficient for my needs.
Basically what I do is via FABridge, after initializing, I'll attach event listeners to the object.
// JS
FlexApp.addEventListeners('flexDidSomething', this.doSomething().bind(this)); //using mootools;
and in Flex, the main application itself
// AS
dispatchEvent(new CustomCreatedEvent(param1, param2));
And inside the JS function I'll access the get methods of the event object to retrieve the params.
There's tight coupling in that sense but it works at least for what I need.
Hope this is helpful!
JSInterface designed exactly for such things.