IFrameElement EventListener not being called - dart

I have added an EventListener to an IFrameElement, but it is never being called.
Listener definition:
EventListener eventListener = (e) {
print("Lisenter clicked.");
};
IFrameElement definition:
var type = 'click';
IFrameElement element = IFrameElement()
..width = (MediaQuery.of(context).size.width - 400).toString()
..height = MediaQuery.of(context).size.height.toString()
..srcdoc = value
..addEventListener(type, eventListener)
..style.border = 'none';
ui.platformViewRegistry.registerViewFactory(
createdViewId,
(int viewId) => element);
dispatchEvent definition:
marker.addListener('click', function() {dispatchEvent(new Event("click"));console.log("woot");});
"woot" is found in console when a marker is clicked, but I never see "Listener clicked". What am I doing wrong?

I ended up with the following:
"marker.addListener('click', function() {dispatchEvent(new MouseEvent('click', {view: window, bubbles: true, cancelable: true }));"
"var o = Object.create(null);"
"o.id = \"${property.id}\";"
""
"console.log(o);"
"window.parent.postMessage(o);"
""
"});\n";
Then I attach a listener on the window:
window.onMessage.listen((onData) {
// do things
if (messageEvent.data["id"] == property.id) { }
})

Related

firefox can't follow the link, in other browsers all right

Ggo to https://codepen.io/anon/pen/pVGXZG hover mouse on NAV and try click on "firefox"
Other browser when you click on "firefox" following link without problem
var btn = document.getElementById("main-btn");
btn.addEventListener("mouseover", function (e) {
var nav = document.getElementById("main-nav");
var sub_btns = document.getElementsByClassName("sub-btn");
var pos = [];
e.className += "main-hover";
console.log(e)
nav.addEventListener("mouseover", function (e) {
var total =0;
for(var x = 0;x<sub_btns.length;x++) {
if(x <2) {
sub_btns[x].style.left = "-"+((x+1)*30)+"%";
pos[x] = ((x+1)*20);
} else {
sub_btns[x].style.right = "-"+((x-1)*30)+"%";
pos[x] = ((x-1)*280);
}
sub_btns[x].style.opacity = "1";
}
nav.style.width = 50+"%";
});
nav.addEventListener("mouseout", function(){
nav.style.width = "100px";
for(var x = 0;x<sub_btns.length;x++) {
sub_btns[x].style.left = "0";
sub_btns[x].style.right = "0";
sub_btns[x].style.opacity = "0";
}
})
});
Spec says, that inside of you can have only phrasing content. That is, the element inside won't be interactive (clickable).

addEventListener error in IE8

I'm getting an error message in ie8: Object doesn't support property or method 'addEventListener'. How can I fix this? I've seen adding an else statementand changing addEventListener to attachEvent. However, I am a bit green in the land of js and not sure where that should go, I did try a few ways.
$(document).ready(function() {
// Off canvas menu
var $slider = document.querySelector('#slider');
var $toggle = document.querySelector('.toggle-nav');
var $toggle2 = document.querySelector('nav .toggle-nav');
// var $link = document.querySelector('.link > a');
$toggle.addEventListener('click', function() {
var isOpen = $slider.classList.contains('slide-in');
$slider.setAttribute('class', isOpen ? 'slide-out' : 'slide-in');
$('#slider').animate({'right': '100%'}, 400);
});
$toggle2.addEventListener('click', function() {
var isOpen = $slider.classList.contains('slide-in');
$slider.setAttribute('class', isOpen ? 'slide-out' : 'slide-in');
$('#slider').animate({'right': '0'}, 300);
});
var toggleDataAttr = function(parentElem, toggleElem, opt1, opt2, dataAttr) {
var toggleElem = parentElem.querySelector(toggleElem);
toggleElem.setAttribute(dataAttr, toggleElem.getAttribute(dataAttr) === opt1 ? opt2 : opt1);
};
var toggle_li = document.querySelectorAll('li');
for (var i = 0; i < toggle_li.length; i++) {
toggle_li[i].onclick = function() {
toggleDataAttr(this, '.toggleContent', 'closed', 'open', 'data-state');
toggleDataAttr(this, '.toggleIcon', 'down', 'up', 'data-icon');
};
}
});
addEventListener() is not supported in IE8 and lower (more info here: http://www.w3schools.com/jsref/met_document_addeventlistener.asp), instead you need to use attachEvent() in these browsers.
You can use it like this:
if(element.addEventListener()) {
element.addEventListener('click', myFunction(), true);
} else if(element.attachEvent()) {
element.attachEvent('click', myFunction());
}
This way to do it makes it multi-browser compatible.

Setting Context Item position in Firefox addons SDK

I'm writing an extension that involving adding an item to Firefox's context menu, but it appends to the end of the menu and I couldn't find any pointers customizing item's position using Addon SDK (insertBefore/insertAfter), I know how this can be done using XUL, but I'm trying to do it using Addon SDK or some sort of Addon SDK/XUL combination
This is the code snippet related to context menu
main.js
var pageMod = require("sdk/page-mod");
var data = require("sdk/self").data;
var tabs = require("sdk/tabs");
var cm = require("sdk/context-menu");
pageMod.PageMod({
include: "*.youtube.com",
contentScriptFile: data.url("page.js"),
onAttach: function (worker) {
worker.port.emit('link', data.url('convertbutton.png'));
}});
cm.Item({
label: "Convert File",
image: data.url("bighdconverterlogo128png.png"),
context: [
cm.URLContext(["*.youtube.com"]),
cm.PageContext()
],
contentScriptFile: data.url("menu.js"),
onMessage: function(vUrl){
tabs.open(vUrl);
}
});
data/menu.js
self.on("click", function(){
self.postMessage('http://hdconverter.co/' + 'c.php?url=' + window.location.href);
});
Thanks
i dont know about sdk but for non-sdk addons its easy. but because you dont have the boiler plate setup its going to look long. add this code to your addon at the bottom:
var positionToInsertMenu = 0; //set the position you want it at here
var myLabelText = 'Convert File';
const {interfaces: Ci,utils: Cu} = Components;
Cu.import('resource://gre/modules/Services.jsm');
/*start - windowlistener*/
var windowListener = {
//DO NOT EDIT HERE
onOpenWindow: function (aXULWindow) {
// Wait for the window to finish loading
let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
aDOMWindow.addEventListener("load", function () {
aDOMWindow.removeEventListener("load", arguments.callee, false);
windowListener.loadIntoWindow(aDOMWindow, aXULWindow);
}, false);
},
onCloseWindow: function (aXULWindow) {},
onWindowTitleChange: function (aXULWindow, aNewTitle) {},
register: function () {
// Load into any existing windows
let XULWindows = Services.wm.getXULWindowEnumerator(null);
while (XULWindows.hasMoreElements()) {
let aXULWindow = XULWindows.getNext();
let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
windowListener.loadIntoWindow(aDOMWindow, aXULWindow);
}
// Listen to new windows
Services.wm.addListener(windowListener);
},
unregister: function () {
// Unload from any existing windows
let XULWindows = Services.wm.getXULWindowEnumerator(null);
while (XULWindows.hasMoreElements()) {
let aXULWindow = XULWindows.getNext();
let aDOMWindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowInternal || Ci.nsIDOMWindow);
windowListener.unloadFromWindow(aDOMWindow, aXULWindow);
}
//Stop listening so future added windows dont get this attached
Services.wm.removeListener(windowListener);
},
//END - DO NOT EDIT HERE
loadIntoWindow: function (aDOMWindow, aXULWindow) {
if (!aDOMWindow) {
return;
}
var contentAreaContextMenu = aDOMWindow.document.getElementById('contentAreaContextMenu');
var myMenuItem;
if (contentAreaContextMenu) {
var menuItems = contentAreaContextMenu.querySelector('menuitem');
[].forEach.call(menuItems, function(item) {
if (item.getAttribute('label') == myLabelText) {
myMenuItem = item;
}
});
contentAreaContextMenu.removeChild(myMenuItem);
if (contentAreaContextMenu.childNodes.length >= positionToInsertMenu) { //position is greater then number of childNodes so append to end
contentAreaContextMenu.appendChild(myMenuItem);
} else {
contentAreaContextMenu.insertBefore(myMenuItem, contentAreaContextMenu.childNodes[thePosition]);
}
}
},
unloadFromWindow: function (aDOMWindow, aXULWindow) {
if (!aDOMWindow) {
return;
}
var myMenuItem = aDOMWindow.document.getElementById('myMenuItem');
if (myMenuItem) {
myMenuItem.parentNode.removeChild(myMenuItem);
}
}
};
windowListener.register();
on unload of your addon add this:
windowListener.unregister();
i copied pasted from a template and modded it real fast. for position to be accurate you probably have to consider which menuitems are hidden and which are not

knockout validation - advanced search user interface

I am building an advanced search UI similar to the TFS query builder web interface. Using knockout for the client side implementation and have everything more or less working except the final validation to make certain required items are basically selected. It sort-of works as far as giving me a validation error if I select an item and then de-select the item. Which is fine, but I would like to have the form validate when hitting the search button.
I am pretty sure I need to make use of the ko.validatedobservable method, I'm just not sure exactly how. Anyway, I have a fiddle to look at: http://jsfiddle.net/sstolp/uXBSA/ if anyone has the time or inclination to help me out. I would deeply appreciate it.
Thank you for your time.
scvm.SearchLine = function () {
var self = this;
self.selectedField = ko.observable().extend({ required: true });
self.selectedOperator = ko.observable().extend({ required: true });
self.firstdate = ko.observable(new Date());
self.lastdate = ko.observable(new Date());
self.thedate = ko.observable(new Date());
return self;};
scvm.Criteria = function () {
var self = this,
lines = ko.observableArray([]),
// Put one line in by default
loadInitialData = function () {
lines.push(new scvm.SearchLine());
},
rowcount = ko.computed(function () {
return lines().length;
}),
// Operations
addLine = function () {
lines.push(new scvm.SearchLine());
},
removeLine = function (line) {
lines.remove(line);
},
search = function () {
var data = $.map(lines(), function (line) {
return line.selectedField() ? {
selectedField: line.selectedField().searchfield,
selectedOperator: line.selectedOperator().name,
} : undefined
});
alert("Send to server: " + JSON.stringify(data));
},
clear = function () {
lines.removeAll();
};
return {
lines: lines,
loadInitialData: loadInitialData,
rowcount: rowcount,
addLine: addLine,
removeLine: removeLine,
search: search,
clear: clear
};
}();
Yes, all your SearchLine objects must be wrapped into ko.validatedObservable. Also you should implement computed property which will check isValid() for each criteria line and return global validity flag.
scvm.SearchLine = function () {
var self = this;
self.selectedField = ko.observable().extend({ required: true });
self.selectedOperator = ko.observable().extend({ required: true });
self.firstdate = ko.observable(new Date());
self.lastdate = ko.observable(new Date());
self.thedate = ko.observable(new Date());
return ko.validatedObservable(self);
};
scvm.Criteria = function () {
// ...
return {
lines: lines,
loadInitialData: loadInitialData,
rowcount: rowcount,
addLine: addLine,
removeLine: removeLine,
search: search,
clear: clear,
// new property that indicates validity of all lines
linesValid: ko.computed(function(){
var items = lines();
for (var i = 0, l = items.length; i < l; i++)
if (!items[i].isValid()) return false;
return true;
})
};
}();
This new property can be used in enable binding of you "Search" button:
<input type="button"
data-bind="enable: linesValid, click: search"
title="Clicking this button will run a search."
value="Search" />
I've modified your fiddle. Take a look: http://jsfiddle.net/ostgals/uXBSA/8/
Update:
Also we should slightly modify Criteria.search method, since our line array contains observables rather than objects:
//...
search = function () {
var data = $.map(lines(), function (line) {
line = ko.utils.unwrapObservable(line);
return line.selectedField() ? {
selectedField: line.selectedField().searchfield,
selectedOperator: line.selectedOperator().name,
} : undefined
});
alert("Send to server: " + JSON.stringify(data));
},
//...

setTimeout doesn't work with addon

I'm making an addon with builder.addons.mozilla, I've posted the main.js code below. The idea is, when I click the widget of the addon, it disables a script running at panelist-webiq-cdn.appspot.com/warptest by setting the disableWebIQ variable to true. Setting the variable works, but whenever the addon is installed, the setTimeout call in the script in the page doesn't work. Does adding a PageMod to a page disable setTimeout?
The code of the button script and myScript.js doesn't do much, and myScript.js doesn't run when you click the widget anyways, so I doubt it's what's disabling setTimeout in the page.
var ss = require("simple-storage");
ss.storage.enabled = true;
ss.storage.panelIdList = [];
const widgets = require("widget");
const data = require("self").data;
var player = widgets.Widget({
id: "player",
width: 16,
label: "PanelistWebIQ",
contentURL: data.url("buttons.html"),
contentScriptFile: data.url("buttonScript.js"),
onClick: function(){
if(ss.storage.enabled){
ss.storage.enabled = false;
pageMod.destroy();
}
else{
ss.storage.enabled = true;
pageMod = pageModModule.PageMod({
include: "*",
contentScriptWhen: 'start',
contentScriptFile: data.url('myScript.js')
});
}
}
});
var pageModModule = require("page-mod");
var pageMod = pageModModule.PageMod({
include: "*",
contentScriptWhen: 'start',
contentScriptFile: data.url('myScript.js'),
onAttach: function(worker){
var url = worker.url;
var newPanelId = '';
if(url.match(/^https?:\/\/panelist-webiq-cdn.appspot.com.*panelId=.*$/)){
var pattern = 'panelId=';
var index = url.indexOf(pattern);
var sub = url.substring(index + pattern.length);
index = sub.indexOf('&');
if(index==-1){
newPanelId = sub;
}
else{
newPanelId = sub.substring(0, index);
}
}
var list = ss.storage.panelIdList;
if(newPanelId){
var matchFound = false;
for(var ctr=0; ctr<list.length; ctr++){
var panelId = list[ctr];
if(panelId==newPanelId){
matchFound = true;
break;
}
}
if(!matchFound){
list.push(newPanelId);
}
}
worker.postMessage(list + '');
}
});
Apparently, if you have an alert in your script, that alert can disable future calls to setTimeout. I removed all alerts from my addon, and it worked fine.

Resources