I use this code to intercept a dialog from a webview but I can not see the content or interact with it:
Element webview= querySelector("#webview");
Map<String,String> map=new Map();
map["src"]=urlWebView+user;
webview.attributes.addAll(map);
querySelector("#webview_cont").style.visibility="visible";
window.addEventListener("dialog",(Event e){ //Use window or webview returns the same result
e.preventDefault();
... //What should I do here ??
} );
Any solution?
Thanks
Edit
Debug:
Open issue: https://code.google.com/p/dart/issues/detail?id=23556
The problem definitely lies with your usage of Dart's Event class.
It simply does not support the extra properties that Chrome is adding to the event: e.dialog, e.messageText, e.messageType.
It does not seem like there is a ready solution for that, at least not in chrome.dart.
Sadly, I don't know Dart well enough to give you a solution. You need to somehow extend that event class, possibly dropping to JS level.
This library, even if abandoned, should give you ideas on how to do that (by catching the JS-level event and stuffing the extra properties in CustomEvent's detail property), though implementing DialogController (which is not JSON-serializable) would be a bit trickier, I guess.
Related
after several rounds of research, I found there is no clear answer about the situation like below:
I have a js file called 'AAA.js', and there is simple code in side like this:
var AAA = {
listenForMenuLayer: function () {
console.log("menu initiated");
$('.nav-menu').on('click', function() { console.log("menu clicked")});
}
init: function(){
this.listenForMenuLayer();
}
};
And in the dart, I wrote like below (using 'dart:js'):
js.context['AAA'].callMethod('init');
Then, when I run it, everything looks fine, the "menu initiated" shows properly, which means the 'listenForMenuLayer' is initiated, but when click on the '.nav-menu', there is nothing happened. (I check many times, there is no spelling error or else)
My question is: Can Dart accept this kind of initiating of external JS event? or we should re-write those JS events at all, please advise, many thanks.
Updates:
I found that if we write the js code like above, the jquery will not be initiated properly, which means all the features begin with '$' will not be functional.
guys, I update it to using 'package:js/js.dart';
#JS('AAA.init')
external void aInit();
then some where, just simply call after including:
aInit();
I have been scouring the web for a clear answer on how to query for an element generated by a dom-repeat element from Dart code.
sample.html
<dom-module id="so-sample>
<style>...</style>
<template>
<template is="dom-repeat" items="[[cars]] as="car>
...
<paper-button on-click="buttonClicked">Button</paper-button>
<paper-dialog id="dialog">
<h2>Title</h2>
</paper-dialog>
</template>
</template>
sample.dart
I'll omit the boilerplate code here, such as imports or the query to my database to fill the cars property ; everything works fine.
...
#reflectable
void buttonClicked(e, [_])
{
PaperDialog infos = this.shadowRoot.querySelector("#dialog");
infos.open();
}
This generates the following error :
Uncaught TypeError: Cannot read property 'querySelector' of undefined
I have tried several 'solutions', which are not, since nothing works.
The only thing I saw on quite a lot of threads is to use Timer.run() and write my code in the callback, but that seems like a hack. Why would I need a timer ?
I understand my problem may be that the content of the dom-repeat is generated lazily, and I query the items 'before' they are added to the local DOM.
Another advice I didn't follow is to use Mutation Observers. I read in the polymer API documentation that the observeNodes method should be used instead, as it internally uses MO to handle indexing the elements, but it again seems a bit complicated just to open a dialog.
My final objective is to bind the button of each generated model to a dedicated paper-dialog to display additional information on the item.
Has anyone ever done that ? (I should hope so :p)
Thanks for your time !
Update 1:
After reading Gunter's advices, although none of them actually worked by themselves, the fact that the IDs aren't mangled inside a dom-repeat made me think and query paper-dialog instead of the id itself, and now my dialog pops up !
sample.dart:
PaperDialog infos = Polymer.dom(root).querySelector("paper-dialog");
infos.open();
I now hope that each button will call the associated dialog, since I'll bind data inside the dialog relative to the item I clicked ~
Update 2:
So, nope, the data binding didn't work as expected: All buttons were bound to the item at index 0, just as I feared. I tried several ways to query the correct paper-dialog but nothing worked. The only 'workaround' I found is to query all the paper-dialog into a list and then get the 'index-th' element from that list.
#reflectable
void buttonClicked(e, [_])
{
var model = new DomRepeatModel.fromEvent(e);
List<PaperDialog> dialogs = Polymer.dom(this.root).querySelectorAll("paper-dialog");
dialogs[model.index].open();
}
This code definitely works, but it feels kind of a waste of resources to get all the elements when you really only need one and you already know which one.
So yeah, my initial problem is solved, but I still wonder why I couldn't query the dialogs from their id:
...
<paper-dialog id="dialog-[[index]]">
...
</paper-dialog>
#reflectable
void buttonClicked(e, [_])
{
var model = new DomRepeatModel.fromEvent(e);
PaperDialog dialog = Polymer.dom(this.root).querySelector("dialog-${model.index}");
dialog.open();
}
With this code, dialog is always null, although I can find those dialogs, correctly id-ied, in the DOM tree.
You need to use Polymers DOM API with shady DOM (default). If you enable shadow DOM your code would probably work as well.
PaperDialog infos = new Polymer.dom(this).querySelector("#dialog")
I am learning Dart and suddenly had an epiphany (or possibly, an epiphany):
Can I write a Dart web app where the "view" is done 100% in Dart?
I'm talking: absolutely no (none/zero/nadda) HTML files (.html). 100% Dart code. Something like:
class SigninView {
LabelElement signinLabel;
InputElement emailTextField;
InputElement passwordTextField;
ButtonElement signinButton;
// constructors, getters, setters, etc.
// Perhaps called from inside constructor...
void initUI() {
signinLabel = new LabelElement();
signinLabel.innerHTML = "<span class=\"blah\">Please sign in</span>";
emailTextField = new InputElement();
emailTextField.innerHTML = "<input type=\"text\" name=\"fizz\" placeholder=\"Email\"/>";
// ...etc.
// htmlFactory would be something I'd need to write myself (?)
String html = htmlFactory.newHTML(signinLabel, emailTextField, ...);
querySelector("#someDivTag").innerHTML = html;
}
}
In theory (that is, my intentions with the above code), as soon as the SigninView is created, it initializes a bunch of DOM elements and populates someDivTag with them.
Is this possible? If so am I "doing it right", or is there a different/preferred/standardized approach to this?
Does this introduce any additional/potential caveats (memory leaks), performance or security issues that I should be aware of?
If I were to adopt this strategy throughout my whole app, can I assume the app would be quicker to download (less HTML text), but slower to execute (dynamic DOM element creation)? If so, is there a way to somehow instantiate all the DOM elements my app will need up front (slowing down initial download time), and then only make certain elements visible as I wish to render different views/screens (thus speeding up execution time)?
You need an HTML file with the script tags for the Dart startup.
Anything else can be done in Dart.
I'm trying to attach an event handler to the keyDown event in a canvas element. Here is a simplified version of my code.
class CanvasFun{
CanvasElement canvas;
CanvasFun(this.canvas){
print("Game is loading!");
this.canvas.onKeyDown.listen(handleInput);
}
void handleInput(e)
{
//breakpoint is never hit
print(e.keyCode);
}
}
I've removed some of the drawing code. In my main function I simply query the canvas element and pass it to my CanvasFun constructor.
I've also tried doing it this way:
void main() {
var canvas = query("#Game");
canvas.onKeyDown.listen(handleInput);
var canvasFun = new CanvasFun(canvas);
}
void handleInput(e)
{
print(e.keyCode);
}
The reason why the event is not firing is because the focus is on the document (or some other element like an input, for example). And in fact, canvas element even when focused does not fire an event. Some elements do, like input elements.
The solution is to listen to key down events from the document or window:
window.onKeyDown.listen(handleInput);
document.onKeyDown.listen(handleInput); // You already noticed this worked.
John McCutchan has written a nice Dart package to help handle keyboard input. You can read more about it here: http://dartgamedevs.org/blog/2012/12/11/keyboard-input/
Note that this library helps you handle input "correctly". You do not want to do any "work" in the input handling, instead you simply want to register that a key was pressed. You can check the state of any key presses inside of your requestAnimationFrame callback.
Hope that helps!
There exists a workaround to get the canvas-element accept KeyboardEvents:
Problems handling KeyboardEvents on DartFlash
Once you add the tabindex-attribute to your canvas-element, it can get the focus and then it will receive KeyboardEvents.
It looks like I can get it to work if I register the event on the document rather than the canvas element.
document.onKeyDown.listen(handleInput);
Does anyone know what might have changed since v3.0.5 that would enable extensions to work? Or, maybe I'm missing a setting somewhere? I wrote this add-on that works fine with newer versions, but I can't get it to launch in older ones. Specifically, I can't even get this part to work (this is in my browser overlay.xul):
<html:script>
<![CDATA[
var Cc = Components.classes;
var Ci = Components.interfaces;
var obSvc = Cc["#mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
gBrowser.consoleService = Cc["#mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
gBrowser.log = function(msg){
this.consoleService.logStringMessage(msg);
}
gBrowser.newObj= new MyAddOn();
gBrowser.log("initializing...");
function regListener()
{
obSvc.addObserver(gBrowser.newObj, "http-on-modify-request", false);
}
function unregListener()
{
obSvc.removeObserver(gBrowser.newObj, "http-on-modify-request");
}
window.addEventListener("load", regListener, false);
window.addEventListener("unload", unregListener, false);
]]>
This should attach listeners to the new obj (defined by a linked .js) However, I'm not even getting the "initializing..." message in the console. Any ideas?
Don't use <html:script>, use <script> (assuming you have xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" on your root <overlay> element).
Don't register an application-global listener (http-on-modify-request) from a window overlay. Doing so will make your code run one time in each window the user may have open. Use an XPCOM component instead - https://developer.mozilla.org/en/Setting_HTTP_request_headers
Don't pollute common objects (like gBrowser or the global object (with var Cc)) with your own properties. If everyone did that, no two extensions would work together. Put all your code properties on your own object with a unique name.
accessing gBrowser before the load event is probably what's causing your specific problem.
Set up your environment and check the Error Console to debug problems.
Don't waste time trying to support Firefox 3. It's not supported by Mozilla itself for over a year and shouldn't be used to access the web.
It looks like gBrowser.log is not defined, or at least is not a function, as the error console will probably tell you. I've never heard of it either. Maybe it was added in Fx 3.5?