diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index ac876fc74cbf..32ce9d962dfd 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -5944,30 +5944,72 @@ var gMissingPluginInstaller = { return this.crashReportHelpURL; }, + addLinkClickCallback: function (linkNode, callbackName, callbackArg) { + // XXX just doing (callback)(arg) was giving a same-origin error. bug? + let self = this; + linkNode.addEventListener("click", + function(evt) { + if (!evt.isTrusted) + return; + evt.preventDefault(); + if (callbackArg == undefined) + callbackArg = evt; + (self[callbackName])(callbackArg); + }, + true); + + linkNode.addEventListener("keydown", + function(evt) { + if (!evt.isTrusted) + return; + if (evt.keyCode == evt.DOM_VK_RETURN) { + evt.preventDefault(); + if (callbackArg == undefined) + callbackArg = evt; + evt.preventDefault(); + (self[callbackName])(callbackArg); + } + }, + true); + }, + + // Callback for user clicking on a missing (unsupported) plugin. installSinglePlugin: function (aEvent) { - if (!aEvent.isTrusted) - return; var missingPluginsArray = {}; var pluginInfo = getPluginInfo(aEvent.target); missingPluginsArray[pluginInfo.mimetype] = pluginInfo; - if (missingPluginsArray) { - openDialog("chrome://mozapps/content/plugins/pluginInstallerWizard.xul", - "PFSWindow", "chrome,centerscreen,resizable=yes", - {plugins: missingPluginsArray, browser: gBrowser.selectedBrowser}); - } - - aEvent.stopPropagation(); + openDialog("chrome://mozapps/content/plugins/pluginInstallerWizard.xul", + "PFSWindow", "chrome,centerscreen,resizable=yes", + {plugins: missingPluginsArray, browser: gBrowser.selectedBrowser}); }, + // Callback for user clicking on a disabled plugin managePlugins: function (aEvent) { - if (!aEvent.isTrusted) - return; BrowserOpenAddonsMgr("plugins"); - aEvent.stopPropagation(); }, + // Callback for user clicking "submit a report" link + submitReport : function(minidumpID) { + // The crash reporter wants a DOM element it can append an IFRAME to, + // which it uses to submit a form. Let's just give it gBrowser. + this.CrashSubmit.submit(minidumpID, gBrowser, null, null); + }, + + // Callback for user clicking a "reload page" link + reloadPage: function (browser) { + browser.reload(); + }, + + // Callback for user clicking the help icon + openHelpPage: function () { + openHelpLink("plugin-crashed", false); + }, + + + + // event listener for missing/blocklisted/outdated plugins. newMissingPlugin: function (aEvent) { // Since we are expecting also untrusted events, make sure // that the target is a plugin @@ -5982,14 +6024,7 @@ var gMissingPluginInstaller = { if (aEvent.type != "PluginBlocklisted" && aEvent.type != "PluginOutdated" && !(aEvent.target instanceof HTMLObjectElement)) { - aEvent.target.addEventListener("click", - gMissingPluginInstaller.installSinglePlugin, - true); - aEvent.target.addEventListener("keydown", - function(evt) { if (evt.keyCode == evt.DOM_VK_RETURN) - gMissingPluginInstaller.installSinglePlugin(evt) }, - true); - + gMissingPluginInstaller.addLinkClickCallback(aEvent.target, "installSinglePlugin"); } let hideBarPrefName = aEvent.type == "PluginOutdated" ? @@ -6110,13 +6145,7 @@ var gMissingPluginInstaller = { if (!(aEvent.target instanceof Ci.nsIObjectLoadingContent)) return; - aEvent.target.addEventListener("click", - gMissingPluginInstaller.managePlugins, - true); - aEvent.target.addEventListener("keydown", - function(evt) { if (evt.keyCode == evt.DOM_VK_RETURN) - gMissingPluginInstaller.managePlugins(evt) }, - true); + gMissingPluginInstaller.addLinkClickCallback(aEvent.target, "managePlugins"); }, // Crashed-plugin observer. Notified once per plugin crash, before events @@ -6128,17 +6157,24 @@ var gMissingPluginInstaller = { return; #ifdef MOZ_CRASHREPORTER - let minidumpID = subject.getPropertyAsAString("minidumpID"); - let submitted = gCrashReporter.submitReports && minidumpID.length; - // The crash reporter wants a DOM element it can append an IFRAME to, - // which it uses to submit a form. Let's just give it gBrowser. - if (submitted) - submitted = gMissingPluginInstaller.CrashSubmit.submit(minidumpID, gBrowser, null, null); - propertyBag.setPropertyAsBool("submittedCrashReport", submitted); + let minidumpID = propertyBag.getPropertyAsAString("minidumpID"); + let shouldSubmit = gCrashReporter.submitReports; + let doPrompt = true; // XXX followup to get via gCrashReporter + + // Submit automatically when appropriate. + if (minidumpID && shouldSubmit && !doPrompt) { + this.submitReport(minidumpID); + // Submission is async, so we can't easily show failure UI. + propertyBag.setPropertyAsBool("submittedCrashReport", true); + } #endif }, + // Crashed-plugin event listener. Called for every instance of a + // plugin in content. pluginInstanceCrashed: function (aEvent) { + let self = gMissingPluginInstaller; + // Evil content could fire a fake event at us, ignore them. if (!aEvent.isTrusted) return; @@ -6147,7 +6183,10 @@ var gMissingPluginInstaller = { return; let submittedReport = aEvent.getData("submittedCrashReport"); + let doPrompt = true; // XXX followup for .getData("doPrompt"); + let submitReports = true; // XXX followup for .getData("submitReports"); let pluginName = aEvent.getData("pluginName"); + let minidumpID = aEvent.getData("minidumpID"); // We're expecting this to be a plugin. let plugin = aEvent.target; @@ -6171,36 +6210,77 @@ var gMissingPluginInstaller = { overlay.removeAttribute("role"); #ifdef MOZ_CRASHREPORTER + // Determine which message to show regarding crash reports. let helpClass, showClass; - - // If we didn't submit a report but don't have submission disabled, - // we probably just didn't collect a crash report; don't put up any - // special crashing text. - if (submittedReport) { - helpClass = "submitLink"; + if (submittedReport) { // submitReports && !doPrompt, handled in observer showClass = "msg msgSubmitted"; } - else if (!gCrashReporter.submitReports) { - helpClass = "notSubmitLink"; + else if (!submitReports && !doPrompt) { showClass = "msg msgNotSubmitted"; } + else { // doPrompt + showClass = "msg msgPleaseSubmit"; + // XXX can we make the link target actually be blank? + let pleaseLink = doc.getAnonymousElementByAttribute( + plugin, "class", "pleaseSubmitLink"); + self.addLinkClickCallback(pleaseLink, "submitReport", minidumpID); + } - if (helpClass) { - let helpLink = doc.getAnonymousElementByAttribute(plugin, "class", helpClass); - helpLink.href = gMissingPluginInstaller.crashReportHelpURL; - let textToShow = doc.getAnonymousElementByAttribute(plugin, "class", showClass); - textToShow.style.display = "block"; + // If we don't have a minidumpID, we can't (or didn't) submit anything. + // This can happen if the plugin is killed from the task manager. + if (!minidumpID) { + showClass = "msg msgNoCrashReport"; + } + + let textToShow = doc.getAnonymousElementByAttribute(plugin, "class", showClass); + textToShow.style.display = "block"; + + let bottomLinks = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgBottomLinks"); + bottomLinks.style.display = "block"; + let helpIcon = doc.getAnonymousElementByAttribute(plugin, "class", "helpIcon"); + self.addLinkClickCallback(helpIcon, "openHelpPage"); + + // If we're showing the link to manually trigger report submission, we'll + // want to be able to update all the instances of the UI for this crash to + // show an updated message when a report is submitted. + if (doPrompt) { + let observer = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, + Ci.nsISupportsWeakReference]), + observe : function(subject, topic, data) { + let propertyBag = subject; + if (!(propertyBag instanceof Ci.nsIPropertyBag2)) + return; + // Ignore notifications for other crashes. + if (propertyBag.get("minidumpID") != minidumpID) + return; + self.updateSubmissionStatus(plugin, propertyBag, data); + }, + + handleEvent : function(event) { + // Not expected to be called, just here for the closure. + } + } + + // Use a weak reference, so we don't have to remove it... + Services.obs.addObserver(observer, "crash-report-status", true); + // ...alas, now we need something to hold a strong reference to prevent + // it from being GC. But I don't want to manually manage the reference's + // lifetime (which should be no greater than the page). + // Clever solution? Use a closue with an event listener on the document. + // When the doc goes away, so do the listener references and the closure. + doc.addEventListener("mozCleverClosureHack", observer, false); } #endif let crashText = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgCrashed"); crashText.textContent = messageString; - let link = doc.getAnonymousElementByAttribute(plugin, "class", "reloadLink"); - link.addEventListener("click", function(e) { if (e.isTrusted) browser.reload(); }, true); + let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document); + + let link = doc.getAnonymousElementByAttribute(plugin, "class", "reloadLink"); + self.addLinkClickCallback(link, "reloadPage", browser); - let browser = gBrowser.getBrowserForDocument(plugin.ownerDocument - .defaultView.top.document); let notificationBox = gBrowser.getNotificationBox(browser); // Is the 's size too small to hold what we want to show? @@ -6216,7 +6296,7 @@ var gMissingPluginInstaller = { // If another plugin on the page was large enough to show our UI, we // don't want to show a notification bar. if (!doc.mozNoPluginCrashedNotification) - showNotificationBar(); + showNotificationBar(minidumpID); } else { // If a previous plugin on the page was too small and resulted in // adding a notification bar, then remove it because this plugin @@ -6231,7 +6311,7 @@ var gMissingPluginInstaller = { notificationBox.removeNotification(notification, true); } - function showNotificationBar() { + function showNotificationBar(minidumpID) { // If there's already an existing notification bar, don't do anything. let notification = notificationBox.getNotificationWithValue("plugin-crashed"); if (notification) @@ -6240,22 +6320,68 @@ var gMissingPluginInstaller = { // Configure the notification bar let priority = notificationBox.PRIORITY_WARNING_MEDIUM; let iconURL = "chrome://mozapps/skin/plugins/pluginGeneric-16.png"; - let label = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.label"); - let accessKey = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.accesskey"); + let reloadLabel = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.label"); + let reloadKey = gNavigatorBundle.getString("crashedpluginsMessage.reloadButton.accesskey"); + let submitLabel = gNavigatorBundle.getString("crashedpluginsMessage.submitButton.label"); + let submitKey = gNavigatorBundle.getString("crashedpluginsMessage.submitButton.accesskey"); - let buttons = [{ - label: label, - accessKey: accessKey, - popup: null, - callback: function() { browser.reload(); }, - }]; + let buttons = [ +#ifdef MOZ_CRASHREPORTER + { + label: submitLabel, + accessKey: submitKey, + popup: null, + callback: function() { gMissingPluginInstaller.submitReport(minidumpID); }, + }, +#endif + { + label: reloadLabel, + accessKey: reloadKey, + popup: null, + callback: function() { browser.reload(); }, + }]; let notification = notificationBox.appendNotification(messageString, "plugin-crashed", iconURL, priority, buttons); + + // Add the "learn more" link. + let XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; + let link = notification.ownerDocument.createElementNS(XULNS, "label"); + link.className = "text-link"; + link.setAttribute("value", gNavigatorBundle.getString("crashedpluginsMessage.learnMore")); + link.href = gMissingPluginInstaller.crashReportHelpURL; + let description = notification.ownerDocument.getAnonymousElementByAttribute(notification, "anonid", "messageText"); + description.appendChild(link); } }, + updateSubmissionStatus : function (plugin, propBag, status) { + let doc = plugin.ownerDocument; + + // One of these two may already be visible, reset them to be hidden. + let pleaseText = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgPleaseSubmit"); + let submittingText = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgSubmitting"); + pleaseText.style.display = ""; + submittingText.style.display = ""; + + let msgClass; + switch (status) { + case "submitting": + msgClass = "msg msgSubmitting"; + break; + case "success": + msgClass = "msg msgSubmitted"; + break; + case "failed": + msgClass = "msg msgSubmitFailed"; + break; + } + + let textToShow = doc.getAnonymousElementByAttribute(plugin, "class", msgClass); + textToShow.style.display = "block"; + }, + refreshBrowser: function (aEvent) { // browser elements are anonymous so we can't just use target. var browser = aEvent.originalTarget; diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties index a814803c926a..ea332d1c7ba1 100644 --- a/browser/locales/en-US/chrome/browser/browser.properties +++ b/browser/locales/en-US/chrome/browser/browser.properties @@ -77,6 +77,9 @@ blockedpluginsMessage.searchButton.accesskey=U crashedpluginsMessage.title=The %S plugin has crashed. crashedpluginsMessage.reloadButton.label=Reload page crashedpluginsMessage.reloadButton.accesskey=R +crashedpluginsMessage.submitButton.label=Submit a crash report +crashedpluginsMessage.submitButton.accesskey=S +crashedpluginsMessage.learnMore=Learn More… # Sanitize # LOCALIZATION NOTE (sanitizeDialog2.everything.title): When "Time range to diff --git a/content/base/public/nsIObjectLoadingContent.idl b/content/base/public/nsIObjectLoadingContent.idl index 30234fd64084..c573cf408c01 100644 --- a/content/base/public/nsIObjectLoadingContent.idl +++ b/content/base/public/nsIObjectLoadingContent.idl @@ -40,6 +40,7 @@ interface nsIFrame; interface nsIObjectFrame; interface nsIPluginInstance; +interface nsIPluginTag; interface nsIDOMElement; interface nsIDOMClientRect; @@ -124,6 +125,7 @@ interface nsIObjectLoadingContent : nsISupports */ [noscript] nsIFrame getPrintFrame(); - [noscript] void pluginCrashed(in AString pluginName, + [noscript] void pluginCrashed(in nsIPluginTag pluginTag, + in AString minidumpID, in boolean submittedCrashReport); }; diff --git a/content/base/src/nsObjectLoadingContent.cpp b/content/base/src/nsObjectLoadingContent.cpp index df5fd3a78a83..ae32c513078b 100644 --- a/content/base/src/nsObjectLoadingContent.cpp +++ b/content/base/src/nsObjectLoadingContent.cpp @@ -221,13 +221,16 @@ nsPluginErrorEvent::Run() class nsPluginCrashedEvent : public nsRunnable { public: nsCOMPtr mContent; + nsString mMinidumpID; nsString mPluginName; PRBool mSubmittedCrashReport; nsPluginCrashedEvent(nsIContent* aContent, + const nsAString& aMinidumpID, const nsAString& aPluginName, PRBool submittedCrashReport) : mContent(aContent), + mMinidumpID(aMinidumpID), mPluginName(aPluginName), mSubmittedCrashReport(submittedCrashReport) {} @@ -266,6 +269,15 @@ nsPluginCrashedEvent::Run() nsCOMPtr variant; + // add a "minidumpID" property to this event + variant = do_CreateInstance("@mozilla.org/variant;1"); + if (!variant) { + NS_WARNING("Couldn't create minidumpID variant for PluginCrashed event!"); + return NS_OK; + } + variant->SetAsAString(mMinidumpID); + containerEvent->SetData(NS_LITERAL_STRING("minidumpID"), variant); + // add a "pluginName" property to this event variant = do_CreateInstance("@mozilla.org/variant;1"); if (!variant) { @@ -2008,15 +2020,23 @@ nsObjectLoadingContent::SetAbsoluteScreenPosition(nsIDOMElement* element, } NS_IMETHODIMP -nsObjectLoadingContent::PluginCrashed(const nsAString& pluginName, +nsObjectLoadingContent::PluginCrashed(nsIPluginTag* aPluginTag, + const nsAString& minidumpID, PRBool submittedCrashReport) { AutoNotifier notifier(this, PR_TRUE); UnloadContent(); mFallbackReason = ePluginCrashed; nsCOMPtr thisContent = do_QueryInterface(static_cast(this)); + + // Note that aPluginTag in invalidated after we're called, so copy + // out any data we need now. + nsCAutoString pluginName; + aPluginTag->GetName(pluginName); + nsCOMPtr ev = new nsPluginCrashedEvent(thisContent, - pluginName, + minidumpID, + NS_ConvertUTF8toUTF16(pluginName), submittedCrashReport); nsresult rv = NS_DispatchToCurrentThread(ev); if (NS_FAILED(rv)) { diff --git a/modules/plugin/base/src/nsPluginHost.cpp b/modules/plugin/base/src/nsPluginHost.cpp index b182459ca526..649720c58272 100644 --- a/modules/plugin/base/src/nsPluginHost.cpp +++ b/modules/plugin/base/src/nsPluginHost.cpp @@ -5035,6 +5035,7 @@ nsPluginHost::PluginCrashed(nsNPAPIPlugin* aPlugin, const nsAString& dumpID) nsCOMPtr propbag = do_CreateInstance("@mozilla.org/hash-property-bag;1"); if (obsService && propbag) { propbag->SetPropertyAsAString(NS_LITERAL_STRING("minidumpID"), dumpID); + propbag->SetPropertyAsBool(NS_LITERAL_STRING("submittedCrashReport"), submittedCrashReport); obsService->NotifyObservers(propbag, "plugin-crashed", nsnull); // see if an observer submitted a crash report. propbag->GetPropertyAsBool(NS_LITERAL_STRING("submittedCrashReport"), &submittedCrashReport); @@ -5050,8 +5051,7 @@ nsPluginHost::PluginCrashed(nsNPAPIPlugin* aPlugin, const nsAString& dumpID) instanceTag->mInstance->GetDOMElement(getter_AddRefs(domElement)); nsCOMPtr objectContent(do_QueryInterface(domElement)); if (objectContent) { - objectContent->PluginCrashed(NS_ConvertUTF8toUTF16(pluginTag->mName), - submittedCrashReport); + objectContent->PluginCrashed(pluginTag, dumpID, submittedCrashReport); } instanceTag->mInstance->Stop(); diff --git a/toolkit/crashreporter/CrashSubmit.jsm b/toolkit/crashreporter/CrashSubmit.jsm index 22633e8eb556..94e4e08f5197 100644 --- a/toolkit/crashreporter/CrashSubmit.jsm +++ b/toolkit/crashreporter/CrashSubmit.jsm @@ -35,6 +35,8 @@ * * ***** END LICENSE BLOCK ***** */ +Components.utils.import("resource://gre/modules/Services.jsm"); + let EXPORTED_SYMBOLS = [ "CrashSubmit" ]; @@ -44,6 +46,10 @@ const Ci = Components.interfaces; const STATE_START = Ci.nsIWebProgressListener.STATE_START; const STATE_STOP = Ci.nsIWebProgressListener.STATE_STOP; +const SUCCESS = "success"; +const FAILED = "failed"; +const SUBMITTING = "submitting"; + let reportURL = null; let strings = null; let myListener = null; @@ -191,6 +197,7 @@ Submitter.prototype = { submitSuccess: function Submitter_submitSuccess(ret) { if (!ret.CrashID) { + this.notifyStatus(FAILED); this.cleanup(); return; } @@ -207,8 +214,7 @@ Submitter.prototype = { // report an error? not much the user can do here. } - if (this.successCallback) - this.successCallback(this.id, ret); + this.notifyStatus(SUCCESS, ret); this.cleanup(); }, @@ -272,9 +278,7 @@ Submitter.prototype = { // check general request status first if (!Components.isSuccessCode(aStatus)) { this.element.removeChild(this.iframe); - if (this.errorCallback) { - this.errorCallback(this.id); - } + this.notifyStatus(FAILED); this.cleanup(); return 0; } @@ -282,9 +286,7 @@ Submitter.prototype = { if (aRequest instanceof Ci.nsIHttpChannel && aRequest.responseStatus != 200) { this.element.removeChild(this.iframe); - if (this.errorCallback) { - this.errorCallback(this.id); - } + this.notifyStatus(FAILED); this.cleanup(); return 0; } @@ -301,13 +303,39 @@ Submitter.prototype = { onStatusChange: function() {return 0;}, onSecurityChange: function() {return 0;}, + notifyStatus: function Submitter_notify(status, ret) + { + let propBag = Cc["@mozilla.org/hash-property-bag;1"]. + createInstance(Ci.nsIWritablePropertyBag2); + propBag.setPropertyAsAString("minidumpID", this.id); + + Services.obs.notifyObservers(propBag, "crash-report-status", status); + + switch (status) { + case SUCCESS: + if (this.successCallback) + this.successCallback(this.id, ret); + break; + case FAILED: + if (this.errorCallback) + this.errorCallback(this.id); + break; + default: + // no callbacks invoked. + } + }, + submit: function Submitter_submit() { let [dump, extra] = getPendingMinidump(this.id); if (!dump.exists() || !extra.exists()) { + this.notifyStatus(FAILED); this.cleanup(); return false; } + + this.notifyStatus(SUBMITTING); + this.dump = dump; this.extra = extra; let iframe = this.document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "iframe"); @@ -320,8 +348,10 @@ Submitter.prototype = { if (iframe.contentWindow.location == "about:blank") return; iframe.removeEventListener("load", loadHandler, true); - if (!self.submitForm()) + if (!self.submitForm()) { + this.notifyStatus(FAILED); self.cleanup(); + } } iframe.addEventListener("load", loadHandler, true); diff --git a/toolkit/locales/en-US/chrome/mozapps/plugins/plugins.dtd b/toolkit/locales/en-US/chrome/mozapps/plugins/plugins.dtd index ff95102e48cc..e86c18e60f98 100644 --- a/toolkit/locales/en-US/chrome/mozapps/plugins/plugins.dtd +++ b/toolkit/locales/en-US/chrome/mozapps/plugins/plugins.dtd @@ -29,15 +29,10 @@ - - - - - - - - - - - - + + + + + + + diff --git a/toolkit/mozapps/plugins/content/pluginProblem.xml b/toolkit/mozapps/plugins/content/pluginProblem.xml index 3f24310c673d..b221fefce97e 100644 --- a/toolkit/mozapps/plugins/content/pluginProblem.xml +++ b/toolkit/mozapps/plugins/content/pluginProblem.xml @@ -58,9 +58,17 @@ &reloadPlugin.pre;&reloadPlugin.middle;&reloadPlugin.post; - - &submittedCrashReport.pre;&submittedCrashReport.middle;&submittedCrashReport.post; - ¬SubmittedCrashReport.pre;¬SubmittedCrashReport.middle;¬SubmittedCrashReport.post; + + + &report.please; + &report.submitting; + &report.submitted; + &report.disabled; + &report.failed; + &report.unavailable; + + + diff --git a/toolkit/mozapps/plugins/content/pluginProblemContent.css b/toolkit/mozapps/plugins/content/pluginProblemContent.css index 74dbbcf60aad..20c8dd2c4750 100644 --- a/toolkit/mozapps/plugins/content/pluginProblemContent.css +++ b/toolkit/mozapps/plugins/content/pluginProblemContent.css @@ -12,6 +12,10 @@ html|applet:not([height]), html|applet[height=""] { height: 200px; } +:-moz-type-unsupported .mainBox { + cursor: pointer; +} + :-moz-type-unsupported .mainBox, :-moz-handler-disabled .mainBox, :-moz-handler-blocked .mainBox { @@ -40,3 +44,7 @@ html|applet:not([height]), html|applet[height=""] { :-moz-handler-crashed .msgReload { display: block; } + +.helpIcon { + cursor: pointer; +} diff --git a/toolkit/themes/pinstripe/mozapps/jar.mn b/toolkit/themes/pinstripe/mozapps/jar.mn index fa68806809cb..8b102f7c2f29 100644 --- a/toolkit/themes/pinstripe/mozapps/jar.mn +++ b/toolkit/themes/pinstripe/mozapps/jar.mn @@ -27,6 +27,7 @@ toolkit.jar: skin/classic/mozapps/plugins/pluginGeneric-16.png (plugins/pluginGeneric-16.png) skin/classic/mozapps/plugins/pluginBlocked-16.png (plugins/pluginBlocked-16.png) skin/classic/mozapps/plugins/pluginOutdated-16.png (plugins/pluginOutdated-16.png) + skin/classic/mozapps/plugins/pluginHelp-16.png (plugins/pluginHelp-16.png) skin/classic/mozapps/profile/profileicon.png (profile/profileicon.png) skin/classic/mozapps/profile/profileicon-selected.png (profile/profileicon-selected.png) skin/classic/mozapps/profile/profileSelection.css (profile/profileSelection.css) diff --git a/toolkit/themes/pinstripe/mozapps/plugins/pluginHelp-16.png b/toolkit/themes/pinstripe/mozapps/plugins/pluginHelp-16.png new file mode 100644 index 000000000000..9a577c08f2dc Binary files /dev/null and b/toolkit/themes/pinstripe/mozapps/plugins/pluginHelp-16.png differ diff --git a/toolkit/themes/pinstripe/mozapps/plugins/pluginProblem.css b/toolkit/themes/pinstripe/mozapps/plugins/pluginProblem.css index d2df19348e1d..b69c077c5d03 100644 --- a/toolkit/themes/pinstripe/mozapps/plugins/pluginProblem.css +++ b/toolkit/themes/pinstripe/mozapps/plugins/pluginProblem.css @@ -41,9 +41,35 @@ html|a { background-image: url(chrome://mozapps/skin/plugins/pluginCrashed.png); } +.throbber { + padding-left: 16px; /* width of the background image */ + background: url(chrome://global/skin/icons/loading_16.png) no-repeat; + margin-left: 5px; +} + .msg { - font: 12px sans-serif; - font-weight: bold; + font: message-box; + font-size: 12px; cursor: default; text-shadow: rgba(0,0,0,0.8) 0 0 5px; } + +.msgBottomLinks { + padding-left: 2px; + padding-right: 2px; +} + +.msgBottomLinks div { + text-align: right; + margin-right: 4px; + margin-bottom: -19px; + min-height: 19px; /* height of biggest line (with throbber) */ +} + +.helpIcon { + float: left; + display: inline-block; + min-width: 16px; + min-height: 16px; + background: url(chrome://mozapps/skin/plugins/pluginHelp-16.png) no-repeat; +} diff --git a/toolkit/themes/winstripe/mozapps/jar.mn b/toolkit/themes/winstripe/mozapps/jar.mn index 449c1b8786e6..0780a58b1bf7 100644 --- a/toolkit/themes/winstripe/mozapps/jar.mn +++ b/toolkit/themes/winstripe/mozapps/jar.mn @@ -33,6 +33,7 @@ toolkit.jar: skin/classic/mozapps/plugins/pluginGeneric-16.png (plugins/pluginGeneric-16.png) skin/classic/mozapps/plugins/pluginBlocked-16.png (plugins/pluginBlocked-16.png) skin/classic/mozapps/plugins/pluginOutdated-16.png (plugins/pluginOutdated-16.png) + skin/classic/mozapps/plugins/pluginHelp-16.png (plugins/pluginHelp-16.png) skin/classic/mozapps/plugins/pluginInstallerWizard.css (plugins/pluginInstallerWizard.css) skin/classic/mozapps/profile/profileicon.png (profile/profileicon.png) skin/classic/mozapps/profile/profileSelection.css (profile/profileSelection.css) @@ -75,6 +76,7 @@ toolkit.jar: skin/classic/aero/mozapps/plugins/pluginGeneric-16.png (plugins/pluginGeneric-16-aero.png) skin/classic/aero/mozapps/plugins/pluginBlocked-16.png (plugins/pluginBlocked-16-aero.png) skin/classic/aero/mozapps/plugins/pluginOutdated-16.png (plugins/pluginOutdated-16-aero.png) + skin/classic/aero/mozapps/plugins/pluginHelp-16.png (plugins/pluginHelp-16-aero.png) skin/classic/aero/mozapps/plugins/pluginInstallerWizard.css (plugins/pluginInstallerWizard.css) skin/classic/aero/mozapps/profile/profileicon.png (profile/profileicon-aero.png) skin/classic/aero/mozapps/profile/profileSelection.css (profile/profileSelection.css) diff --git a/toolkit/themes/winstripe/mozapps/plugins/pluginHelp-16-aero.png b/toolkit/themes/winstripe/mozapps/plugins/pluginHelp-16-aero.png new file mode 100644 index 000000000000..9a577c08f2dc Binary files /dev/null and b/toolkit/themes/winstripe/mozapps/plugins/pluginHelp-16-aero.png differ diff --git a/toolkit/themes/winstripe/mozapps/plugins/pluginHelp-16.png b/toolkit/themes/winstripe/mozapps/plugins/pluginHelp-16.png new file mode 100644 index 000000000000..9a577c08f2dc Binary files /dev/null and b/toolkit/themes/winstripe/mozapps/plugins/pluginHelp-16.png differ diff --git a/toolkit/themes/winstripe/mozapps/plugins/pluginProblem.css b/toolkit/themes/winstripe/mozapps/plugins/pluginProblem.css index d2df19348e1d..b69c077c5d03 100644 --- a/toolkit/themes/winstripe/mozapps/plugins/pluginProblem.css +++ b/toolkit/themes/winstripe/mozapps/plugins/pluginProblem.css @@ -41,9 +41,35 @@ html|a { background-image: url(chrome://mozapps/skin/plugins/pluginCrashed.png); } +.throbber { + padding-left: 16px; /* width of the background image */ + background: url(chrome://global/skin/icons/loading_16.png) no-repeat; + margin-left: 5px; +} + .msg { - font: 12px sans-serif; - font-weight: bold; + font: message-box; + font-size: 12px; cursor: default; text-shadow: rgba(0,0,0,0.8) 0 0 5px; } + +.msgBottomLinks { + padding-left: 2px; + padding-right: 2px; +} + +.msgBottomLinks div { + text-align: right; + margin-right: 4px; + margin-bottom: -19px; + min-height: 19px; /* height of biggest line (with throbber) */ +} + +.helpIcon { + float: left; + display: inline-block; + min-width: 16px; + min-height: 16px; + background: url(chrome://mozapps/skin/plugins/pluginHelp-16.png) no-repeat; +}