How to get window name from parent window in dart? - dart

I can get parent window name in Javascript, and don't know how to do it in Dart.
I have tried to down cast window.opener to window in Dart, but it throw exception.
According html5.1 nightly, should we expect it implemented as window basic attribute?
//js version:
window.opener.name
//dart version:
(window.opener as ?).name

For a popup window.opener can be used and for an iframe window.parent. Both return a _DOMWindowCrossFrame which do not support name as they implement WindowBase. That's also the reason why you can't cast to window. You should use postMessage to communicate and exchange information.
See also this implementation note: Its fields and methods can only be accessed via JavaScript.

An alternative approach is to use dart-js-interop
import 'dart:js' as js;
print(new js.JsObject.fromBrowserObject(
js.context['window'])['opener']['name']);
There is currently no way in Dart. Access to the windows object is intentionally denied for security reasons. According to comments on related bug reports they consider changing it because it can be worked around using dart-js-interop anyway.

Related

Using Dart classes from JavaScript

I have a Dart class (foo.dart):
class Foo {
void talk() {
print('Hello');
}
}
After compiling foo.dart to JavaScript, I'd like to be able to use Foo like this:
var foo = new Foo(); // from foo.dart.js
foo.talk() // prints "Hello"
My questions:
Is this currently possible?
If so, how?
If not, what plans, if any, are in place to make it possible?
The dart:js library documentation states:
This library does not yet make Dart objects usable from JavaScript, their methods and proeprties [sic] are not accessible, though it does allow Dart functions to be passed into and called from JavaScript.
That word "yet" offers some hope, but I've found very little on this topic anywhere else.
Edit:
I do realize it's possible to call Dart functions from JavaScript using dart2js. However, what I'm trying to do is somewhat different. I'd like to be able to access all of the functionality of a Dart class from JavaScript.
Due to tree-shaking and minification this is normally not possible. If you have a Dart application (with a main() then you can make a Dart function available to be called from JavaScript (see How to call a Dart function from Javascript? for an example).
As far as I know there are plans to support your requirement but I have no idea about progress or when such a feature might be available.
This is the related project https://github.com/dart-lang/js-interop

Accessing hidden private class in Objective-C

How can I access an attribute that's been hidden via:
__attribute__((visibility("hidden")))
I'm trying to access UINavigationItemButtonView, but it seems sometime recent (iOS 7.1?) they've added the above into the header file. Recursively printing the window no longer reveals UINavigationItemButtonView in the view stack either.
So, given a UINavigationBar, how can I access a UINavigationItemButtonView that has been hidden via the above flag?
Printing all the subviews in UINavigationBar doesn't reveal it.
The attribute keyword is simply a message to the compiler, and has nothing to do with the runtime. Using ((visibility("xxx")) only serves to tell the compiler if the given declaration should be "visible" or usable by clients in some other package. visibility("hidden") just means that, despite the public declaration, make this thing invisible to external packages, so that they will not be able to use it. Compiling will fail if you attempt to use this class or method.
If you don't see this class being used in a recursive description, it is likely that this class is no longer used; it certainly isn't because of the attribute statement.
Since it's a private class, you shouldn't. Anything you do to bypass that restriction may result in your application failing the review process. Not to mention that, in general, accessing private and/or hidden API's, classes, instance variables, properties or whatever else it is, is a really good way to make sure your application breaks in the (not too distant) future.

Is there any way to pass Dart variables to another browser window?

I know that I can use local storage, cookies and postMessage but all these methods only accept simple types. I want to pass objects and lists directly to the other window.
I found a similar question but using javascript. I'd like to do something just like Victor pointed in the following link.
Can I pass a JavaScript variable to another browser window?
Trying anything similar in Dart gives me a warining even before running.
var popup = window.open('popup.html', '');
popup.variable = localVariable; //warning here
Passing objects is not possible.
You can serialize to JSON to make it a simple type and pass it using postMessage and then deserialize.
Lists and maps containing only simple types should work with postMessage.

How do I access a non-#observable field via polymer bindings with dart2js in Dart?

Seth Ladd's Polymer.dart examples are awesome and really helpful. The observable_list example appends DateTime instances to an ObservableList timestamps. Although DateTime does not extend Observable, modifying my_element.html to access a field on
{{ts in timestamps}}
works when running in the Dart VM. For example, changing
<li>{{ts}}</li>
to
<li>{{ts.second}}</li>
will access the DateTime.seconds field when on the Dart VM. However, when dart2js compiles the app to javascript, access to fields in the Polymer expression is broken. An exception Uncaught Error: RangeError: value 0 is thrown in this case, or more generally NoSuchMethodError : method not found: 'Symbol(...)' for the fieldname is thrown (see example here)
If a class extends Observable then access to #observable fields works inside of Polymer expressions after compiling to Javascript (changing the class MyRow in this example to extends Observable does not throw an exception in javascript).
What can I do when I am unable to add annotations to external classes like DateTime? Is this just a current bug in dart2js generation, or will the Polymer.dart spec forbid reading fields out of non-observable classes? Previously, web_ui successfully accessed fields from our dart-protobuf generated classes after compiling to javascript, so I'm hoping this use-case will gain support in Polymer.dart too.
In general, dart2js tries to tree-shake and minify code, and it doesn't know that some of the code is used from a polymer expression (which uses mirrors internally to interpret the expressions). Very likely what happened here is that dart2js is either deleting the non-observable fields or minifying them in a way that they are not reflectable.
To fix this, you can indicate that these fields need to be preserved and used via mirrors. In polymer we provide the #reflectable annotation for this purpose. (#observable also implies #reflectable, that's why it works when you have #observable). So you can use that in the MyRow case.
Fields from types in the core libraries can work also if they become reflectable. In this case it is a bit harder to express because you can't modify the original code to add this annotation. Instead you can use the #MirrorsUsed annotation to override the default behavior on these core types, or avoid using these fields inside polymer-expressions by hiding them inside #reflectable getters or in filters that are written directly in Dart code.

custom protocol handlers in bootstrapped firefox addon

I am writing a bootstrap Firefox addon and need to register a new protocol/schema handler (e.g. foo:somthing). I have looked all over and I only see ways to do this using chrome.manifest, which bootstrapped add-ons cannot use.
So, does anyone know a way or is it possible to register a custom protocol handler in a bootstrapped add-on?
Yes, but you'll have to do the work that the add-on/component manager would do for you, in particular calling .registerFactory yourself.
There is already a test demonstrating how to register components in general, and protocol handlers in particular, at runtime yourself.
Although #nmair's answer is a good general thing I'll keep in mind, I was able to find a better solution to my own problem. I noticed that there was an HTML5 method that would try to ask the user to register a handler for a protocol/schema, and after picking around in omni.ja (firefox source code), I found it's definition. After fiddling around, I wrote this:
var handler = Cc["#mozilla.org/uriloader/web-handler-app;1"]
.createInstance(Ci.nsIWebHandlerApp);
handler.name='My Protocol';
handler.uriTemplate='chrome://myprotocol/content/launcher.xul#%s';
var eps=Cc["#mozilla.org/uriloader/external-protocol-service;1"].
getService(Ci.nsIExternalProtocolService);
var handlerInfo=eps.getProtocolHandlerInfo('myprotocol');
handlerInfo.possibleApplicationHandlers.appendElement(handler, false);
handlerInfo.alwaysAskBeforeHandling=false; // don't ask the user
handlerInfo.preferredApplicationHandler=handler; // set my handler as default
hi=handlerInfo;
var hs=Cc["#mozilla.org/uriloader/handler-service;1"].
getService(Ci.nsIHandlerService);
hs.store(handlerInfo);
Registers the protocol, no restart or components required.

Resources