Permalink
Browse files

prior to removing dynamic anchor creation

  • Loading branch information...
1 parent 9daeb07 commit e28281f9cc0b4368c2aa9b5d281430aa676428c8 @asutherland asutherland committed Apr 2, 2012
View
@@ -39,14 +39,13 @@ <h3>Log: (newest to oldest)</h3>
var resultsNode = document.getElementById("results");
function logResult(styleClass, msg) {
- var node = document.createElement("span");
+ var node = document.createElement("div");
node.class = styleClass;
node.textContent = msg;
resultsNode.insertBefore(node, resultsNode.firstChild);
}
function checkImapServer(host, port, crypto) {
-console.log("TCPSocket:", TCPSocket);
var socket = TCPSocket();
socket.onopen = function(evt) {
logResult("status", "Connection opened!");
View
@@ -95,7 +95,6 @@ exports.main = function() {
}
}
-
let ownerInfo = {
// For aliased things like about: URLs, this will be the about: URL
uri: Services.io.newURI(domWindow.location, null, null),
@@ -139,31 +138,34 @@ console.log("trying to create a socket!");
};
console.log("Exposed!");
- function killSocketsForWindow() {
- if (!weakrefs)
- return;
-console.log("killing weakrefs!", windowID);
- for (let i = 0; i < weakrefs.length; i++) {
- let socket = weakrefs[i].get();
- if (socket) {
- // kill off the socket and ignore any complaints.
- try {
- socket.close();
- }
- catch (ex) {
+ let unloadHelper = {
+ unload: function killSocketsForWindow() {
+ if (!weakrefs)
+ return;
+ for (let i = 0; i < weakrefs.length; i++) {
+ let socket = weakrefs[i].get();
+ if (socket) {
+ // kill off the socket and ignore any complaints.
+ try {
+ socket.close();
+ }
+ catch (ex) {
+ }
}
}
+ weakrefs = null;
+ $observe.remove('inner-window-destroyed', observeWindowDeath);
}
- weakrefs = null;
- $observe.remove('inner-window-destroyed', observeWindowDeath);
};
function observeWindowDeath(subject, topic, data) {
let innerWindowID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (innerWindowID === windowID)
- killSocketsForWindow();
+ unloadHelper.unload();
}
$observe.add('inner-window-destroyed', observeWindowDeath);
- $unload.when(killSocketsForWindow);
+ // Use ensure so that our unload helpers get removed when invoked so we
+ // don't end up with an ever-growing list of moot unload closures.
+ $unload.ensure(unloadHelper);
}
$observe.add(CONTENT_GLOBAL_CREATED, contentGlobalCreated);
$unload.when(function() {
View
@@ -4,14 +4,11 @@
/**
* Provides the UI and persistence for WebAPI TCP connections.
- *
- * While we currently hard-code our string bundle for prototyping, we do,
- * however depend on a chrome.manifest-driven overlay (xul, css) to include our
- * icon in the address bar for our door-hanger.
**/
"use strict";
-const {Cc,Ci,Cu} = require("chrome");
+const {Cc,Ci,Cu} = require("chrome"),
+ $unload = require("unload");
let importNS = {};
Cu.import("resource://gre/modules/Services.jsm", importNS);
@@ -74,6 +71,105 @@ const gStringBundle = {
}
};
+let PERMISSION_ANCHOR_ID = "webapi-tcp-notification-icon",
+ PERMISSION_ANCHOR_ICON_URL = "chrome://global/skin/icons/question-16.png",
+ PERMISSION_POPUP_ICON_URL = "chrome://global/skin/icons/question-64.png",
+ CERTIFICATE_ANCHOR_ID = "webapi-tcp-exception-icon",
+ CERTIFICATE_ANCHOR_ICON_URL = "chrome://global/skin/icons/question-16.png",
+ CERTIFICATE_POPUP_ICON_URL = "chrome://global/skin/icons/question-64.png";
+
+// NB: We tried to dynamically create an anchor-id so that we could give it
+// its own icon and have a persistent location for our notifications. This
+// unfortunately runs afoul of the means by which the icons are shown. The
+// iconbox sets an "anchorid" attribute and there exist specific CSS rules to
+// set each element's display to -moz-box. Because dynamically creating CSS
+// rules in XUL tends to break everything, we hit a wall. (And just manually
+// updating the display style ourself is problematic without aggressive
+// monkeypatching, as if we use the callback we are too late for the panel
+// positioning. We could probably fix-up the panel afterwards, but that's
+// also ugly.
+
+/**
+ * Dynamically create the anchor element (since we can't use an overlay) and
+ * provide a function that will clean it up.
+ */
+function makeAnchorElementAndCleanupLogic(document, elemId, iconUrl) {
+console.log("creating element...");
+ let box = document.getElementById("notification-popup-box"),
+ // we may already exist in this window...
+ img = document.getElementById(elemId);
+ if (img) {
+ img.refCount++;
+ }
+ else {
+ img = document.createElement("image");
+ img.setAttribute("id", elemId);
+ img.setAttribute("class", "notification-anchor-icon");
+ img.setAttribute("role", "button");
+ // We have to force the icon to visible because of a CSS snafu. All the
+ //
+ img.setAttribute(
+ "style", "list-style-image: url(" + iconUrl + "); display: -moz-box;");
+ img.style.display = "-moz-box;";
+ img.refCount = 1;
+ box.appendChild(img);
+ }
+
+ // super-frown... we need to create a CSS rule for the dude.
+
+ return function cleanupFunc() {
+ if (!img)
+ return;
+ if (--img.refCount) {
+ img = null;
+ return;
+ }
+ img.parentNode.removeChild(img);
+ imgStyle.parentNode.removeChild(imgStyle);
+ };
+}
+
+function showPopup(contentWin,
+ anchorId, anchorIconUrl, popupIconUrl,
+ message, primaryAction, secondaryActions) {
+ let browserWin = contentWin.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem)
+ .rootTreeItem
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow),
+ browserNode = browserWin.gBrowser.getBrowserForDocument(
+ contentWin.document),
+ PopupNotifications = browserWin.PopupNotifications;
+
+ let anchorCleanup = makeAnchorElementAndCleanupLogic(
+ browserWin.document, anchorId, anchorIconUrl);
+
+ let unloadHelper = {
+ unload: function() {
+ anchorCleanup();
+ if (notification) {
+ PopupNotifications.remove(notification);
+ notification = null;
+ }
+ },
+ };
+
+ let notification = PopupNotifications.show(
+ browserNode, anchorId, message, anchorId,
+ primaryAction, secondaryActions,
+ {
+ popupIconURL: popupIconUrl,
+ eventCallback: function(state) {
+ if (state === "removed") {
+ notification = null;
+ unloadHelper.unload();
+ }
+ }
+ });
+ $unload.ensure(unloadHelper);
+}
+
/**
* Permission checks.
* - Is this webapp authorized to attempt to try establish TCP connections?
@@ -115,17 +211,6 @@ console.log("checkTCPConnectionAllowed", ownerInfo, host, port, useSSL);
return;
// - Ask for Permission
- let browserWin = ownerInfo.contentWin
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem)
- .rootTreeItem
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow),
- browserNode = browserWin.gBrowser.getBrowserForDocument(
- ownerInfo.contentWin.document),
- PopupNotifications = browserWin.PopupNotifications;
-
let allowAction = {
label: gStringBundle.getString("webapi.permission.allow"),
accessKey: gStringBundle.getString("webapi.permission.allowAccessKey"),
@@ -161,16 +246,16 @@ console.log("checkTCPConnectionAllowed", ownerInfo, host, port, useSSL);
// This UI choice is a no-op.
},
};
- PopupNotifications.show(
- browserNode,
- "webapi-tcp-permission-prompt",
+
+ showPopup(
+ ownerInfo.contentWin,
+ PERMISSION_ANCHOR_ID, PERMISSION_ANCHOR_ICON_URL,
+ PERMISSION_POPUP_ICON_URL,
gStringBundle.getFormattedString(
"webapi.permission." + (useSSL ? "tcps" : "tcp") + ".prompt",
[ownerInfo.host, host, port]),
- "webapi-tcp-notification-icon",
allowAction,
- [neverThisAction, neverAnyAction, notNowAction],
- {});
+ [neverThisAction, neverAnyAction, notNowAction]);
},
/**
@@ -231,13 +316,12 @@ console.log("checkTCPConnectionAllowed", ownerInfo, host, port, useSSL);
},
};
- PopupNotifications.show(
- browserNode,
- "webapi-tcp-exception-prompt",
+ showPopup(
+ ownerInfo.contentWin,
+ CERTIFICATE_ANCHOR_ID, CERTIFICATE_ANCHOR_ICON_URL,
+ CERTIFICATE_POPUP_ICON_URL,
promptString,
- "webapi-tcp-notification-icon",
seeAction,
- [notNowAction],
- {});
+ [notNowAction]);
},
};
Oops, something went wrong.

0 comments on commit e28281f

Please sign in to comment.