author | Ryan VanderMeulen <ryanvm@gmail.com> |
Sat, 25 Aug 2012 11:42:21 -0400 | |
changeset 103411 | e874475efe15461988861e6172417b7b09fd7b62 |
parent 103410 | ead893fc780c8e4c1fa43a4c688d75e725709448 (current diff) |
parent 103381 | 54fdedb218f858cda41f4c45d91dc8ee46d998e5 (diff) |
child 103412 | 36f85f213ee28ce22a753c963d971408674cbfb1 |
child 103466 | bc23ba35391382a3de4dd325ad6baaaa88292ec3 |
push id | 13981 |
push user | ryanvm@gmail.com |
push date | Sat, 25 Aug 2012 19:48:18 +0000 |
treeherder | mozilla-inbound@779bdf71cde5 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 17.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
browser/config/tooltool-manifests/macosx32/clang.manifest | file | annotate | diff | comparison | revisions | |
browser/config/tooltool-manifests/macosx64/clang.manifest | file | annotate | diff | comparison | revisions | |
browser/themes/pinstripe/social/panelarrow-down.png | file | annotate | diff | comparison | revisions | |
browser/themes/pinstripe/social/panelarrow-horiz.png | file | annotate | diff | comparison | revisions | |
browser/themes/pinstripe/social/panelarrow-up.png | file | annotate | diff | comparison | revisions |
--- a/accessible/src/generic/Accessible.cpp +++ b/accessible/src/generic/Accessible.cpp @@ -794,18 +794,17 @@ Accessible::ChildAtPoint(int32_t aX, int NS_ENSURE_TRUE(frame, nullptr); nsPresContext *presContext = frame->PresContext(); nsRect screenRect = frame->GetScreenRectInAppUnits(); nsPoint offset(presContext->DevPixelsToAppUnits(aX) - screenRect.x, presContext->DevPixelsToAppUnits(aY) - screenRect.y); - nsIPresShell* presShell = presContext->PresShell(); - nsIFrame *foundFrame = presShell->GetFrameForPoint(frame, offset); + nsIFrame *foundFrame = nsLayoutUtils::GetFrameForPoint(frame, offset); nsIContent* content = nullptr; if (!foundFrame || !(content = foundFrame->GetContent())) return fallbackAnswer; // Get accessible for the node with the point or the first accessible in // the DOM parent chain. DocAccessible* contentDocAcc = GetAccService()->
--- a/browser/base/content/browser-social.js +++ b/browser/base/content/browser-social.js @@ -36,16 +36,17 @@ let SocialUI = { // Exceptions here sometimes don't get reported properly, report them // manually :( try { this.updateToggleCommand(); SocialShareButton.updateButtonHiddenState(); SocialToolbar.updateButtonHiddenState(); SocialSidebar.updateSidebar(); SocialChatBar.update(); + SocialFlyout.unload(); } catch (e) { Components.utils.reportError(e); throw e; } break; case "social:ambient-notification-changed": SocialToolbar.updateButton(); break; @@ -174,16 +175,126 @@ let SocialChatBar = { this.chatbar.newChat(aProvider, aURL, aCallback); }, update: function() { if (!this.canShow) this.chatbar.removeAll(); } } +function sizeSocialPanelToContent(iframe) { + // FIXME: bug 764787: Maybe we can use nsIDOMWindowUtils.getRootBounds() here? + // Need to handle dynamic sizing + let doc = iframe.contentDocument; + if (!doc) { + return; + } + // "notif" is an implementation detail that we should get rid of + // eventually + let body = doc.getElementById("notif") || doc.body; + if (!body || !body.firstChild) { + return; + } + + let [height, width] = [body.firstChild.offsetHeight || 300, 330]; + iframe.style.width = width + "px"; + iframe.style.height = height + "px"; +} + +let SocialFlyout = { + get panel() { + return document.getElementById("social-flyout-panel"); + }, + + dispatchPanelEvent: function(name) { + let doc = this.panel.firstChild.contentDocument; + let evt = doc.createEvent("CustomEvent"); + evt.initCustomEvent(name, true, true, {}); + doc.documentElement.dispatchEvent(evt); + }, + + _createFrame: function() { + let panel = this.panel; + if (!Social.provider || panel.firstChild) + return; + // create and initialize the panel for this window + let iframe = document.createElement("iframe"); + iframe.setAttribute("type", "content"); + iframe.setAttribute("flex", "1"); + iframe.setAttribute("origin", Social.provider.origin); + panel.appendChild(iframe); + }, + + unload: function() { + let panel = this.panel; + if (!panel.firstChild) + return + panel.removeChild(panel.firstChild); + }, + + onShown: function(aEvent) { + let iframe = this.panel.firstChild; + iframe.docShell.isActive = true; + iframe.docShell.isAppTab = true; + if (iframe.contentDocument.readyState == "complete") { + this.dispatchPanelEvent("socialFrameShow"); + } else { + // first time load, wait for load and dispatch after load + iframe.addEventListener("load", function panelBrowserOnload(e) { + iframe.removeEventListener("load", panelBrowserOnload, true); + setTimeout(function() { + SocialFlyout.dispatchPanelEvent("socialFrameShow"); + }, 0); + }, true); + } + }, + + onHidden: function(aEvent) { + this.panel.firstChild.docShell.isActive = false; + this.dispatchPanelEvent("socialFrameHide"); + }, + + open: function(aURL, yOffset, aCallback) { + if (!Social.provider) + return; + let panel = this.panel; + if (!panel.firstChild) + this._createFrame(); + panel.hidden = false; + let iframe = panel.firstChild; + + let src = iframe.getAttribute("src"); + if (src != aURL) { + iframe.addEventListener("load", function documentLoaded() { + iframe.removeEventListener("load", documentLoaded, true); + sizeSocialPanelToContent(iframe); + if (aCallback) { + try { + aCallback(iframe.contentWindow); + } catch(e) { + Cu.reportError(e); + } + } + }, true); + iframe.setAttribute("src", aURL); + } + else if (aCallback) { + try { + aCallback(iframe.contentWindow); + } catch(e) { + Cu.reportError(e); + } + } + + sizeSocialPanelToContent(iframe); + let anchor = document.getElementById("social-sidebar-browser"); + panel.openPopup(anchor, "start_before", 0, yOffset, false, false); + } +} + let SocialShareButton = { // Called once, after window load, when the Social.provider object is initialized init: function SSB_init() { this.updateButtonHiddenState(); this.updateProfileInfo(); }, updateProfileInfo: function SSB_updateProfileInfo() { @@ -331,16 +442,18 @@ var SocialToolbar = { }, updateButton: function SocialToolbar_updateButton() { this.updateButtonHiddenState(); let provider = Social.provider; let iconNames = Object.keys(provider.ambientNotificationIcons); let iconBox = document.getElementById("social-status-iconbox"); let notifBox = document.getElementById("social-notification-box"); + let panel = document.getElementById("social-notification-panel"); + panel.hidden = false; let notificationFrames = document.createDocumentFragment(); let iconContainers = document.createDocumentFragment(); for each(let name in iconNames) { let icon = provider.ambientNotificationIcons[name]; let notificationFrameId = "social-status-" + icon.name; let notificationFrame = document.getElementById(notificationFrameId); @@ -390,69 +503,50 @@ var SocialToolbar = { }, showAmbientPopup: function SocialToolbar_showAmbientPopup(iconContainer) { let iconImage = iconContainer.firstChild; let panel = document.getElementById("social-notification-panel"); let notifBox = document.getElementById("social-notification-box"); let notificationFrame = document.getElementById(iconImage.getAttribute("notificationFrameId")); - panel.hidden = false; - - function sizePanelToContent() { - // FIXME: bug 764787: Maybe we can use nsIDOMWindowUtils.getRootBounds() here? - // Need to handle dynamic sizing - let doc = notificationFrame.contentDocument; - if (!doc) { - return; - } - // "notif" is an implementation detail that we should get rid of - // eventually - let body = doc.getElementById("notif") || doc.body; - if (!body || !body.firstChild) { - return; - } - - // Clear dimensions on all browsers so the panel size will - // only use the selected browser. - let frameIter = notifBox.firstElementChild; - while (frameIter) { - frameIter.hidden = (frameIter != notificationFrame); - frameIter = frameIter.nextElementSibling; - } - - let [height, width] = [body.firstChild.offsetHeight || 300, 330]; - notificationFrame.style.width = width + "px"; - notificationFrame.style.height = height + "px"; + // Clear dimensions on all browsers so the panel size will + // only use the selected browser. + let frameIter = notifBox.firstElementChild; + while (frameIter) { + frameIter.collapsed = (frameIter != notificationFrame); + frameIter = frameIter.nextElementSibling; } - sizePanelToContent(); - function dispatchPanelEvent(name) { let evt = notificationFrame.contentDocument.createEvent("CustomEvent"); evt.initCustomEvent(name, true, true, {}); notificationFrame.contentDocument.documentElement.dispatchEvent(evt); } - panel.addEventListener("popuphiding", function onpopuphiding() { - panel.removeEventListener("popuphiding", onpopuphiding); + panel.addEventListener("popuphidden", function onpopuphiding() { + panel.removeEventListener("popuphidden", onpopuphiding); SocialToolbar.button.removeAttribute("open"); + notificationFrame.docShell.isActive = false; dispatchPanelEvent("socialFrameHide"); }); panel.addEventListener("popupshown", function onpopupshown() { panel.removeEventListener("popupshown", onpopupshown); SocialToolbar.button.setAttribute("open", "true"); + notificationFrame.docShell.isActive = true; notificationFrame.docShell.isAppTab = true; if (notificationFrame.contentDocument.readyState == "complete") { + sizeSocialPanelToContent(notificationFrame); dispatchPanelEvent("socialFrameShow"); } else { // first time load, wait for load and dispatch after load notificationFrame.addEventListener("load", function panelBrowserOnload(e) { notificationFrame.removeEventListener("load", panelBrowserOnload, true); + sizeSocialPanelToContent(notificationFrame); setTimeout(function() { dispatchPanelEvent("socialFrameShow"); }, 0); }, true); } }); panel.openPopup(iconImage, "bottomcenter topleft", 0, 0, false, false);
--- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -266,16 +266,23 @@ command="Social:UnsharePage"/> #endif </hbox> </panel> <panel id="social-notification-panel" type="arrow" hidden="true" noautofocus="true"> <box id="social-notification-box" flex="1"></box> </panel> + <panel id="social-flyout-panel" + onpopupshown="SocialFlyout.onShown()" + onpopuphidden="SocialFlyout.onHidden()" + type="arrow" + hidden="true" + noautofocus="true" + position="topcenter topright"/> <menupopup id="inspector-node-popup"> <menuitem id="inspectorHTMLCopyInner" label="&inspectorHTMLCopyInner.label;" accesskey="&inspectorHTMLCopyInner.accesskey;" command="Inspector:CopyInner"/> <menuitem id="inspectorHTMLCopyOuter" label="&inspectorHTMLCopyOuter.label;" @@ -1063,16 +1070,17 @@ <splitter id="social-sidebar-splitter" class="chromeclass-extrachrome sidebar-splitter" observes="socialSidebarBroadcaster"/> <vbox id="social-sidebar-box" class="chromeclass-extrachrome" observes="socialSidebarBroadcaster"> <browser id="social-sidebar-browser" type="content" + disableglobalhistory="true" flex="1" style="min-width: 14em; width: 18em; max-width: 36em;"/> </vbox> <vbox id="browser-border-end" hidden="true" layer="true"/> </hbox> <hbox id="full-screen-warning-container" hidden="true" fadeout="true"> <hbox style="width: 100%;" pack="center"> <!-- Inner hbox needed due to bug 579776. -->
--- a/browser/base/content/socialchat.xml +++ b/browser/base/content/socialchat.xml @@ -20,16 +20,43 @@ xbl:inherits="src,origin,collapsed=minimized" type="content"/> </content> <implementation implements="nsIDOMEventListener"> <field name="iframe" readonly="true"> document.getAnonymousElementByAttribute(this, "anonid", "iframe"); </field> + <property name="minimized"> + <getter> + return this.getAttribute("minimized") == "true"; + </getter> + <setter> + this.isActive = !val; + if (val) + this.setAttribute("minimized", "true"); + else + this.removeAttribute("minimized"); + </setter> + </property> + + <property name="isActive"> + <getter> + return this.iframe.docShell.isActive; + </getter> + <setter> + this.iframe.docShell.isActive = !!val; + + // let the chat frame know if it is being shown or hidden + let evt = this.iframe.contentDocument.createEvent("CustomEvent"); + evt.initCustomEvent(val ? "socialFrameHide" : "socialFrameShow", true, true, {}); + this.iframe.contentDocument.documentElement.dispatchEvent(evt); + </setter> + </property> + <method name="init"> <parameter name="aProvider"/> <parameter name="aURL"/> <parameter name="aCallback"/> <body><![CDATA[ this._callback = aCallback; this.setAttribute("origin", aProvider.origin); this.setAttribute("src", aURL); @@ -39,37 +66,29 @@ <method name="close"> <body><![CDATA[ this.parentNode.remove(this); ]]></body> </method> <method name="toggle"> <body><![CDATA[ - let type; - if (this.getAttribute("minimized") == "true") { - this.removeAttribute("minimized"); - type = "socialFrameShow"; - } else { - this.setAttribute("minimized", "true"); - type = "socialFrameHide"; - } - // let the chat frame know if it is being shown or hidden - let evt = this.iframe.contentDocument.createEvent("CustomEvent"); - evt.initCustomEvent(type, true, true, {}); - this.iframe.contentDocument.documentElement.dispatchEvent(evt); + this.minimized = !this.minimized; ]]></body> </method> </implementation> <handlers> <handler event="focus" phase="capturing"> this.parentNode.selectedChat = this; </handler> - <handler event="DOMContentLoaded" action="if (this._callback) this._callback(this.iframe.contentWindow);"/> + <handler event="load"><![CDATA[ + this.isActive = !this.minimized; + if (this._callback) this._callback(this.iframe.contentWindow); + ]]></handler> <handler event="DOMTitleChanged" action="this.setAttribute('label', this.iframe.contentDocument.title);"/> <handler event="DOMLinkAdded"><![CDATA[ // much of this logic is from DOMLinkHandler in browser.js // this sets the presence icon for a chat user, we simply use favicon style updating let link = event.originalTarget; let rel = link.rel && link.rel.toLowerCase(); if (!link || !link.ownerDocument || !rel || !link.href) return; @@ -187,32 +206,34 @@ this.showChat(newChat); ]]></body> </method> <method name="collapseChat"> <parameter name="aChatbox"/> <body><![CDATA[ aChatbox.collapsed = true; + aChatbox.isActive = false; let menu = document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "menuitem"); menu.setAttribute("label", aChatbox.iframe.contentDocument.title); menu.chat = aChatbox; this.menuitemMap.set(aChatbox, menu); this.menupopup.appendChild(menu); this.menupopup.parentNode.collapsed = false; ]]></body> </method> <method name="showChat"> <parameter name="aChatbox"/> <body><![CDATA[ let menuitem = this.menuitemMap.get(aChatbox); this.menuitemMap.delete(aChatbox); this.menupopup.removeChild(menuitem); aChatbox.collapsed = false; + aChatbox.isActive = !aChatbox.minimized; ]]></body> </method> <method name="remove"> <parameter name="aChatbox"/> <body><![CDATA[ if (this.selectedChat == aChatbox) { this.selectedChat = aChatbox.previousSibling ? aChatbox.previousSibling : aChatbox.nextSibling
--- a/browser/base/content/test/Makefile.in +++ b/browser/base/content/test/Makefile.in @@ -59,19 +59,16 @@ endif # 480169) # browser_drag.js is disabled, as it needs to be updated for the new behavior from bug 320638. # browser_bug321000.js is disabled because newline handling is shaky (bug 592528) # browser_pageInfo.js + feed_tab.html is disabled for leaking (bug 767896) -# browser_social_shareButton.js is disabled for not properly -# tearing down the social providers (bug 780010). - _BROWSER_FILES = \ head.js \ browser_typeAheadFind.js \ browser_keywordSearch.js \ browser_allTabsPanel.js \ browser_alltabslistener.js \ browser_bug304198.js \ title_test.svg \ @@ -258,23 +255,26 @@ endif browser_minimize.js \ browser_aboutSyncProgress.js \ browser_middleMouse_inherit.js \ redirect_bug623155.sjs \ browser_tabDrop.js \ browser_lastAccessedTab.js \ browser_bug734076.js \ browser_social_toolbar.js \ + browser_social_shareButton.js \ browser_social_sidebar.js \ + browser_social_flyout.js \ browser_social_mozSocial_API.js \ browser_social_isVisible.js \ browser_social_chatwindow.js \ social_panel.html \ social_sidebar.html \ social_chat.html \ + social_flyout.html \ social_window.html \ social_worker.js \ $(NULL) ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT)) _BROWSER_FILES += \ browser_bug462289.js \ $(NULL)
new file mode 100644 --- /dev/null +++ b/browser/base/content/test/browser_social_flyout.js @@ -0,0 +1,48 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +function test() { + waitForExplicitFinish(); + + let manifest = { // normal provider + name: "provider 1", + origin: "https://example.com", + sidebarURL: "https://example.com/browser/browser/base/content/test/social_sidebar.html", + workerURL: "https://example.com/browser/browser/base/content/test/social_worker.js", + iconURL: "chrome://branding/content/icon48.png" + }; + runSocialTestWithProvider(manifest, function (finishcb) { + runSocialTests(tests, undefined, undefined, finishcb); + }); +} + +var tests = { + testOpenCloseFlyout: function(next) { + let panel = document.getElementById("social-flyout-panel"); + let port = Social.provider.port; + ok(port, "provider has a port"); + port.onmessage = function (e) { + let topic = e.data.topic; + switch (topic) { + case "got-sidebar-message": + port.postMessage({topic: "test-flyout-open"}); + break; + case "got-flyout-visibility": + if (e.data.result == "hidden") { + ok(true, "flyout visibility is 'hidden'"); + next(); + } else if (e.data.result == "shown") { + ok(true, "flyout visibility is 'shown"); + panel.hidePopup(); + } + break; + case "got-flyout-message": + ok(e.data.result == "ok", "got flyout message"); + break; + } + } + port.postMessage({topic: "test-init"}); + } +} +
--- a/browser/base/content/test/browser_social_mozSocial_API.js +++ b/browser/base/content/test/browser_social_mozSocial_API.js @@ -37,16 +37,18 @@ var tests = { let port = Social.provider.port; ok(port, "provider has a port"); port.onmessage = function (e) { let topic = e.data.topic; switch (topic) { case "got-panel-message": ok(true, "got panel message"); + // Check the panel isn't in our history. + ensureSocialUrlNotRemembered(e.data.location); break; case "got-social-panel-visibility": if (e.data.result == "shown") { ok(true, "panel shown"); let panel = document.getElementById("social-notification-panel"); panel.hidePopup(); } else if (e.data.result == "hidden") { ok(true, "panel hidden"); @@ -89,16 +91,18 @@ var tests = { ok(port, "provider has a port"); port.postMessage({topic: "test-service-window"}); port.onmessage = function (e) { let topic = e.data.topic; switch (topic) { case "got-service-window-message": // The sidebar message will always come first, since it loads by default ok(true, "got service window message"); + // the service window URL should not be stored in history. + ensureSocialUrlNotRemembered(e.data.location); port.postMessage({topic: "test-close-service-window"}); break; case "got-service-window-closed-message": ok(true, "got service window closed message"); next(); break; } }
--- a/browser/base/content/test/browser_social_shareButton.js +++ b/browser/base/content/test/browser_social_shareButton.js @@ -1,17 +1,13 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ let prefName = "social.enabled", - shareButton, - sharePopup, - okButton, - undoButton, gFinishCB; function test() { waitForExplicitFinish(); // Need to load a non-empty page for the social share button to appear let tab = gBrowser.selectedTab = gBrowser.addTab("about:", {skipAnimation: true}); tab.linkedBrowser.addEventListener("load", function tabLoad(event) { @@ -41,54 +37,69 @@ function tabLoaded() { }); } function testInitial(finishcb) { ok(Social.provider, "Social provider is active"); ok(Social.provider.enabled, "Social provider is enabled"); ok(Social.provider.port, "Social provider has a port to its FrameWorker"); - shareButton = SocialShareButton.shareButton; - sharePopup = SocialShareButton.sharePopup; + let {shareButton, sharePopup} = SocialShareButton; ok(shareButton, "share button exists"); ok(sharePopup, "share popup exists"); - okButton = document.getElementById("editSharePopupOkButton"); - undoButton = document.getElementById("editSharePopupUndoButton"); - - is(shareButton.hidden, false, "share button should be visible"); + let okButton = document.getElementById("editSharePopupOkButton"); + let undoButton = document.getElementById("editSharePopupUndoButton"); - // Test clicking the share button - shareButton.addEventListener("click", function listener() { - shareButton.removeEventListener("click", listener); - is(shareButton.hasAttribute("shared"), true, "Share button should have 'shared' attribute after share button is clicked"); - executeSoon(testSecondClick.bind(window, testPopupOKButton)); - }); - EventUtils.synthesizeMouseAtCenter(shareButton, {}); + // ensure the worker initialization and handshakes are all done and we + // have a profile. + waitForCondition(function() Social.provider.profile, function() { + is(shareButton.hidden, false, "share button should be visible"); + // check dom values + let profile = Social.provider.profile; + let portrait = document.getElementById("socialUserPortrait").getAttribute("src"); + is(profile.portrait, portrait, "portrait is set"); + let displayName = document.getElementById("socialUserDisplayName"); + is(displayName.label, profile.displayName, "display name is set"); + ok(!document.getElementById("editSharePopupHeader").hidden, "user profile is visible"); + + // Test clicking the share button + shareButton.addEventListener("click", function listener() { + shareButton.removeEventListener("click", listener); + is(shareButton.hasAttribute("shared"), true, "Share button should have 'shared' attribute after share button is clicked"); + executeSoon(testSecondClick.bind(window, testPopupOKButton)); + }); + EventUtils.synthesizeMouseAtCenter(shareButton, {}); + }, "provider didn't provide a profile"); } function testSecondClick(nextTest) { + let {shareButton, sharePopup} = SocialShareButton; sharePopup.addEventListener("popupshown", function listener() { sharePopup.removeEventListener("popupshown", listener); ok(true, "popup was shown after second click"); executeSoon(nextTest); }); EventUtils.synthesizeMouseAtCenter(shareButton, {}); } function testPopupOKButton() { + let {shareButton, sharePopup} = SocialShareButton; + let okButton = document.getElementById("editSharePopupOkButton"); sharePopup.addEventListener("popuphidden", function listener() { sharePopup.removeEventListener("popuphidden", listener); is(shareButton.hasAttribute("shared"), true, "Share button should still have 'shared' attribute after OK button is clicked"); executeSoon(testSecondClick.bind(window, testPopupUndoButton)); }); EventUtils.synthesizeMouseAtCenter(okButton, {}); } function testPopupUndoButton() { + let {shareButton, sharePopup} = SocialShareButton; + let undoButton = document.getElementById("editSharePopupUndoButton"); sharePopup.addEventListener("popuphidden", function listener() { sharePopup.removeEventListener("popuphidden", listener); is(shareButton.hasAttribute("shared"), false, "Share button should not have 'shared' attribute after Undo button is clicked"); executeSoon(testShortcut); }); EventUtils.synthesizeMouseAtCenter(undoButton, {}); } @@ -97,28 +108,31 @@ function testShortcut() { keyTarget.addEventListener("keyup", function listener() { keyTarget.removeEventListener("keyup", listener); executeSoon(checkShortcutWorked.bind(window, keyTarget)); }); EventUtils.synthesizeKey("l", {accelKey: true, shiftKey: true}, keyTarget); } function checkShortcutWorked(keyTarget) { + let {sharePopup, shareButton} = SocialShareButton; is(shareButton.hasAttribute("shared"), true, "Share button should be in the 'shared' state after keyboard shortcut is used"); // Test a second invocation of the shortcut sharePopup.addEventListener("popupshown", function listener() { sharePopup.removeEventListener("popupshown", listener); ok(true, "popup was shown after second use of keyboard shortcut"); executeSoon(checkOKButton); }); EventUtils.synthesizeKey("l", {accelKey: true, shiftKey: true}, keyTarget); } function checkOKButton() { + let okButton = document.getElementById("editSharePopupOkButton"); + let undoButton = document.getElementById("editSharePopupUndoButton"); is(document.activeElement, okButton, "ok button should be focused by default"); // This rest of particular test doesn't really apply on Mac, since buttons // aren't focusable by default. if (navigator.platform.indexOf("Mac") != -1) { executeSoon(testCloseBySpace); return; } @@ -151,22 +165,24 @@ function checkNextInTabOrder(element, ne // Register a cleanup function to remove the listener in case this test fails registerCleanupFunction(function () { element.removeEventListener("focus", listener); }); EventUtils.synthesizeKey("VK_TAB", {}); } function testCloseBySpace() { - is(document.activeElement.id, okButton.id, "testCloseBySpace, the ok button should be focused"); + let sharePopup = SocialShareButton.sharePopup; + is(document.activeElement.id, "editSharePopupOkButton", "testCloseBySpace, the ok button should be focused"); sharePopup.addEventListener("popuphidden", function listener() { sharePopup.removeEventListener("popuphidden", listener); ok(true, "space closed the share popup"); executeSoon(testDisable); }); EventUtils.synthesizeKey("VK_SPACE", {}); } function testDisable() { + let shareButton = SocialShareButton.shareButton; Services.prefs.setBoolPref(prefName, false); is(shareButton.hidden, true, "Share button should be hidden when pref is disabled"); gFinishCB(); }
--- a/browser/base/content/test/head.js +++ b/browser/base/content/test/head.js @@ -83,19 +83,37 @@ function waitForCondition(condition, nex if (condition()) { moveOn(); } tries++; }, 100); var moveOn = function() { clearInterval(interval); nextTest(); }; } +// Check that a specified (string) URL hasn't been "remembered" (ie, is not +// in history, will not appear in about:newtab or auto-complete, etc.) +function ensureSocialUrlNotRemembered(url) { + let gh = Cc["@mozilla.org/browser/global-history;2"] + .getService(Ci.nsIGlobalHistory2); + let uri = Services.io.newURI(url, null, null); + ok(!gh.isVisited(uri), "social URL " + url + " should not be in global history"); +} + function runSocialTestWithProvider(manifest, callback) { let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService; + // Check that none of the provider's content ends up in history. + registerCleanupFunction(function () { + for (let what of ['sidebarURL', 'workerURL', 'iconURL']) { + if (manifest[what]) { + ensureSocialUrlNotRemembered(manifest[what]); + } + } + }); + info("runSocialTestWithProvider: " + manifest.toSource()); let oldProvider; SocialService.addProvider(manifest, function(provider) { info("runSocialTestWithProvider: provider added"); oldProvider = Social.provider; Social.provider = provider;
new file mode 100644 --- /dev/null +++ b/browser/base/content/test/social_flyout.html @@ -0,0 +1,22 @@ +<html> + <head> + <meta charset="utf-8"> + <script> + function pingWorker() { + var port = navigator.mozSocial.getWorker().port; + port.postMessage({topic: "flyout-message", result: "ok"}); + } + window.addEventListener("socialFrameShow", function(e) { + var port = navigator.mozSocial.getWorker().port; + port.postMessage({topic: "flyout-visibility", result: "shown"}); + }, false); + window.addEventListener("socialFrameHide", function(e) { + var port = navigator.mozSocial.getWorker().port; + port.postMessage({topic: "flyout-visibility", result: "hidden"}); + }, false); + </script> + </head> + <body onload="pingWorker();"> + <p>This is a test social flyout panel.</p> + </body> +</html>
--- a/browser/base/content/test/social_panel.html +++ b/browser/base/content/test/social_panel.html @@ -1,15 +1,17 @@ <html> <head> <meta charset="utf-8"> <script> function pingWorker() { var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "panel-message", result: "ok"}); + port.postMessage({topic: "panel-message", + result: "ok", + location: window.location.href}); } window.addEventListener("socialFrameShow", function(e) { var port = navigator.mozSocial.getWorker().port; port.postMessage({topic: "status-panel-visibility", result: "shown"}); }, false); window.addEventListener("socialFrameHide", function(e) { var port = navigator.mozSocial.getWorker().port; port.postMessage({topic: "status-panel-visibility", result: "hidden"});
--- a/browser/base/content/test/social_sidebar.html +++ b/browser/base/content/test/social_sidebar.html @@ -3,16 +3,19 @@ <meta charset="utf-8"> <script> var win; function pingWorker() { var port = navigator.mozSocial.getWorker().port; port.onmessage = function(e) { var topic = e.data.topic; switch (topic) { + case "test-flyout-open": + navigator.mozSocial.openPanel("social_flyout.html"); + break; case "test-chatbox-open": navigator.mozSocial.openChatWindow("social_chat.html", function(chatwin) { port.postMessage({topic: "chatbox-opened", result: chatwin ? "ok" : "failed"}); }); break; case "test-service-window": win = navigator.mozSocial.openServiceWindow("social_window.html", "test-service-window", "width=300,height=300"); break;
--- a/browser/base/content/test/social_window.html +++ b/browser/base/content/test/social_window.html @@ -1,14 +1,17 @@ <html> <head> <meta charset="utf-8"> <script> function pingWorker() { var port = navigator.mozSocial.getWorker().port; - port.postMessage({topic: "service-window-message", result: "ok"}); + port.postMessage({topic: "service-window-message", + location: window.location.href, + result: "ok" + }); } </script> </head> <body onload="pingWorker();"> <p>This is a test social service window.</p> </body> </html>
--- a/browser/base/content/test/social_worker.js +++ b/browser/base/content/test/social_worker.js @@ -13,17 +13,18 @@ onconnect = function(e) { testPort = port; break; case "sidebar-message": sidebarPort = port; if (testPort && event.data.result == "ok") testPort.postMessage({topic:"got-sidebar-message"}); break; case "service-window-message": - testPort.postMessage({topic:"got-service-window-message"}); + testPort.postMessage({topic:"got-service-window-message", + location: event.data.location}); break; case "service-window-closed-message": testPort.postMessage({topic:"got-service-window-closed-message"}); break; case "test-service-window": sidebarPort.postMessage({topic:"test-service-window"}); break; case "test-service-window-twice": @@ -32,35 +33,49 @@ onconnect = function(e) { case "test-service-window-twice-result": testPort.postMessage({topic: "test-service-window-twice-result", result: event.data.result }) break; case "test-close-service-window": sidebarPort.postMessage({topic:"test-close-service-window"}); break; case "panel-message": if (testPort && event.data.result == "ok") - testPort.postMessage({topic:"got-panel-message"}); + testPort.postMessage({topic:"got-panel-message", + location: event.data.location + }); break; case "status-panel-visibility": testPort.postMessage({topic:"got-social-panel-visibility", result: event.data.result }); break; case "test-chatbox-open": sidebarPort.postMessage({topic:"test-chatbox-open"}); break; case "chatbox-message": testPort.postMessage({topic:"got-chatbox-message", result: event.data.result}); break; case "chatbox-visibility": testPort.postMessage({topic:"got-chatbox-visibility", result: event.data.result}); break; + case "test-flyout-open": + sidebarPort.postMessage({topic:"test-flyout-open"}); + break; + case "flyout-message": + testPort.postMessage({topic:"got-flyout-message", result: event.data.result}); + break; + case "flyout-visibility": + testPort.postMessage({topic:"got-flyout-visibility", result: event.data.result}); + break; case "social.initialize": // This is the workerAPI port, respond and set up a notification icon. port.postMessage({topic: "social.initialize-response"}); let profile = { - userName: "foo" + portrait: "https://example.com/portrait.jpg", + userName: "trickster", + displayName: "Kuma Lisa", + profileURL: "http://en.wikipedia.org/wiki/Kuma_Lisa" }; port.postMessage({topic: "social.user-profile", data: profile}); let icon = { name: "testIcon", iconURL: "chrome://branding/content/icon48.png", contentPanel: "https://example.com/browser/browser/base/content/test/social_panel.html", counter: 1 };
--- a/browser/components/thumbnails/PageThumbs.jsm +++ b/browser/components/thumbnails/PageThumbs.jsm @@ -480,17 +480,17 @@ let PageThumbsWorker = { _callbacks: [], /** * Get the worker, spawning it if necessary. * Code of the worker is in companion file PageThumbsWorker.js */ get _worker() { delete this._worker; - this._worker = new ChromeWorker("resource://gre/modules/PageThumbsWorker.js"); + this._worker = new ChromeWorker("resource:///modules/PageThumbsWorker.js"); this._worker.addEventListener("message", this); return this._worker; }, /** * Post a message to the dedicated thread, registering a callback * to be executed once the reply has been received. *
--- a/browser/components/thumbnails/PageThumbsWorker.js +++ b/browser/components/thumbnails/PageThumbsWorker.js @@ -14,16 +14,19 @@ importScripts("resource://gre/modules/osfile.jsm"); let PageThumbsWorker = { handleMessage: function Worker_handleMessage(aEvent) { let msg = aEvent.data; let data = {result: null, data: null}; switch (msg.type) { + case "removeFile": + data.result = this.removeFile(msg); + break; case "removeFiles": data.result = this.removeFiles(msg); break; case "getFilesInDirectory": data.result = this.getFilesInDirectory(msg); break; default: data.result = false; @@ -43,16 +46,25 @@ let PageThumbsWorker = { entries.push(entry.name); } } iter.close(); return entries; }, + removeFile: function Worker_removeFile(msg) { + try { + OS.File.remove(msg.path); + return true; + } catch (e) { + return false; + } + }, + removeFiles: function Worker_removeFiles(msg) { for (let file of msg.paths) { try { OS.File.remove(file); } catch (e) { // We couldn't remove the file for some reason. // Let's just continue with the next one. }
--- a/browser/components/thumbnails/test/browser_thumbnails_storage.js +++ b/browser/components/thumbnails/test/browser_thumbnails_storage.js @@ -14,42 +14,52 @@ XPCOMUtils.defineLazyGetter(this, "Sanit /** * These tests ensure that the thumbnail storage is working as intended. * Newly captured thumbnails should be saved as files and they should as well * be removed when the user sanitizes their history. */ function runTests() { yield clearHistory(); - - // create a thumbnail - yield addTab(URL); - yield whenFileExists(); - gBrowser.removeTab(gBrowser.selectedTab); + yield createThumbnail(); - // clear all browser history - yield clearHistory(); - - // create a thumbnail - yield addTab(URL); - yield whenFileExists(); - gBrowser.removeTab(gBrowser.selectedTab); - - // make sure copy() updates an existing file + // Make sure Storage.copy() updates an existing file. PageThumbsStorage.copy(URL, URL_COPY); let copy = PageThumbsStorage.getFileForURL(URL_COPY); let mtime = copy.lastModifiedTime -= 60; PageThumbsStorage.copy(URL, URL_COPY); isnot(PageThumbsStorage.getFileForURL(URL_COPY).lastModifiedTime, mtime, "thumbnail file was updated"); - // clear last 10 mins of history + let file = PageThumbsStorage.getFileForURL(URL); + let fileCopy = PageThumbsStorage.getFileForURL(URL_COPY); + + // Clear the browser history. Retry until the files are gone because Windows + // locks them sometimes. + while (file.exists() || fileCopy.exists()) { + yield clearHistory(); + } + + yield createThumbnail(); + + // Clear the last 10 minutes of browsing history. yield clearHistory(true); - ok(!copy.exists(), "copy of thumbnail has been removed"); + + // Retry until the file is gone because Windows locks it sometimes. + while (file.exists()) { + // Re-add our URL to the history so that history observer's onDeleteURI() + // is called again. + let time = Date.now() * 1000; + let trans = Ci.nsINavHistoryService.TRANSITION_LINK; + PlacesUtils.history.addVisit(makeURI(URL), time, null, trans, false, 0); + + // Try again... + yield clearHistory(true); + } } function clearHistory(aUseRange) { let s = new Sanitizer(); s.prefDomain = "privacy.cpd."; let prefs = gPrefService.getBranch(s.prefDomain); prefs.setBoolPref("history", true); @@ -60,30 +70,38 @@ function clearHistory(aUseRange) { prefs.setBoolPref("offlineApps", false); prefs.setBoolPref("passwords", false); prefs.setBoolPref("sessions", false); prefs.setBoolPref("siteSettings", false); if (aUseRange) { let usec = Date.now() * 1000; s.range = [usec - 10 * 60 * 1000 * 1000, usec]; + s.ignoreTimespan = false; } s.sanitize(); s.range = null; + s.ignoreTimespan = true; - executeSoon(function () { - if (PageThumbsStorage.getFileForURL(URL).exists()) - clearHistory(aUseRange); - else + executeSoon(next); +} + +function createThumbnail() { + addTab(URL, function () { + whenFileExists(function () { + gBrowser.removeTab(gBrowser.selectedTab); next(); + }); }); } -function whenFileExists() { - let callback = whenFileExists; - +function whenFileExists(aCallback) { + let callback; let file = PageThumbsStorage.getFileForURL(URL); - if (file.exists() && file.fileSize) - callback = next; + if (file.exists() && file.fileSize) { + callback = aCallback; + } else { + callback = function () whenFileExists(aCallback); + } executeSoon(callback); }
--- a/browser/components/thumbnails/test/head.js +++ b/browser/components/thumbnails/test/head.js @@ -52,20 +52,21 @@ let TestRunner = { */ function next() { TestRunner.next(); } /** * Creates a new tab with the given URI. * @param aURI The URI that's loaded in the tab. + * @param aCallback The function to call when the tab has loaded. */ -function addTab(aURI) { +function addTab(aURI, aCallback) { let tab = gBrowser.selectedTab = gBrowser.addTab(aURI); - whenLoaded(tab.linkedBrowser); + whenLoaded(tab.linkedBrowser, aCallback); } /** * Loads a new URI into the currently selected tab. * @param aURI The URI to load. */ function navigateTo(aURI) { let browser = gBrowser.selectedTab.linkedBrowser;
deleted file mode 100644 --- a/browser/config/tooltool-manifests/macosx32/clang.manifest +++ /dev/null @@ -1,17 +0,0 @@ -[ -{ -"clang_version": "r161022" -}, -{ -"size": 47, -"digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa", -"algorithm": "sha512", -"filename": "setup.sh" -}, -{ -"size": 54405078, -"digest": "940f02ee8e4a760f52d6fe9cd1dc8dec01abc61b8086d46b4aa7d7292cf7c353a2cec1c9687491ade756ba2654b9e93986123155cb931bd18431fbbfdef671a9", -"algorithm": "sha512", -"filename": "clang.tar.bz2" -} -]
deleted file mode 100644 --- a/browser/config/tooltool-manifests/macosx64/clang.manifest +++ /dev/null @@ -1,17 +0,0 @@ -[ -{ -"clang_version": "r161022" -}, -{ -"size": 47, -"digest": "2005a41fe97a5e00997063705f39d42b6a43b1cf7ba306cbc7b1513de34cdcd050fc6326efa2107f19ba0cc67914745dbf13154fa748010a93cf072481ef4aaa", -"algorithm": "sha512", -"filename": "setup.sh" -}, -{ -"size": 54405078, -"digest": "940f02ee8e4a760f52d6fe9cd1dc8dec01abc61b8086d46b4aa7d7292cf7c353a2cec1c9687491ade756ba2654b9e93986123155cb931bd18431fbbfdef671a9", -"algorithm": "sha512", -"filename": "clang.tar.bz2" -} -]
--- a/browser/locales/en-US/chrome/browser/browser.properties +++ b/browser/locales/en-US/chrome/browser/browser.properties @@ -378,16 +378,25 @@ social.pageShared.label=Page shared # LOCALIZATION NOTE (social.enable.label): %S = Social networking provider social.enable.label=%S integration social.enable.accesskey=n # LOCALIZATION NOTE (social.enabled.message): %1$S is the name of the social provider, %2$S is brandShortName (e.g. Firefox) social.activated.message=%1$S integration with %2$S has been activated. +# LOCALIZATION NOTE (social.error.message): %1$S is brandShortName (e.g. Firefox), %2$S is the name of the social provider +social.error.message=%1$S is unable to connect with %2$S right now. +social.error.tryAgain.label=Try Again +social.error.tryAgain.accesskey=T +social.error.ok.label=OK +social.error.ok.accesskey=O +social.error.closeSidebar.label=Close This Sidebar +social.error.closeSidebar.accesskey=C + # Identity notifications popups identity.termsOfService = Terms of Service identity.privacyPolicy = Privacy Policy identity.chooseIdentity.description = Sign in to %S identity.chooseIdentity.label = Use an existing email identity.newIdentity.label = Use a different email identity.newIdentity.accessKey = e identity.newIdentity.email.placeholder = Email
--- a/browser/themes/gnomestripe/browser.css +++ b/browser/themes/gnomestripe/browser.css @@ -2736,24 +2736,16 @@ stack[anonid=browserStack][responsivemod cursor: pointer; min-width: 0; margin: 0 6px; } #social-statusarea-username:hover { text-decoration: underline; } -#social-notification-panel { - min-height: 100px; - min-width: 100px; - max-height: 600px; - max-width: 400px; -} - - .chat-status-icon { max-height: 16px; max-width: 16px; padding: 0; } .chat-toolbarbutton { -moz-appearance: none;
--- a/browser/themes/pinstripe/browser.css +++ b/browser/themes/pinstripe/browser.css @@ -3425,58 +3425,16 @@ stack[anonid=browserStack][responsivemod } #social-statusarea-username:hover { text-decoration: underline; } /* === end of social toolbar provider menu === */ -/* === start of social toolbar panels === */ - -#social-notification-panel { - min-height: 100px; - min-width: 240px; - max-height: 600px; - max-width: 400px; -} - -#social-notification-panel .panel-arrowcontent { - margin: -4px 0 0 0; - padding: 0; - border-radius: 0px; - background: white; -} - -#social-notification-panel .panel-arrow[side="top"] { - list-style-image: url("chrome://browser/skin/social/panelarrow-up.png"); - margin-top: -4px; - margin-bottom: 3px; - height: 21px; -} - -#social-notification-panel .panel-arrow[side="bottom"] { - list-style-image: url("chrome://browser/skin/social/panelarrow-down.png"); - margin-top: -5px; -} - -#social-notification-panel .panel-arrow[side="left"] { - list-style-image: url("chrome://browser/skin/social/panelarrow-horiz.png"); - margin-right: -1px; - -moz-transform: scaleX(-1); -} - -#social-notification-panel .panel-arrow[side="right"] { - list-style-image: url("chrome://browser/skin/social/panelarrow-horiz.png"); - margin-left: -1px; -} - -/* === end of social toolbar panels === */ - - .chat-status-icon { max-height: 16px; max-width: 16px; padding: 0; } .chat-toolbarbutton { -moz-appearance: none;
--- a/browser/themes/pinstripe/jar.mn +++ b/browser/themes/pinstripe/jar.mn @@ -105,19 +105,16 @@ browser.jar: skin/classic/browser/preferences/Options-sync.png (preferences/Options-sync.png) #endif skin/classic/browser/preferences/saveFile.png (preferences/saveFile.png) * skin/classic/browser/preferences/preferences.css (preferences/preferences.css) skin/classic/browser/preferences/in-content/preferences.css (preferences/in-content/preferences.css) skin/classic/browser/preferences/applications.css (preferences/applications.css) skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css) skin/classic/browser/social/social.png (social/social.png) - skin/classic/browser/social/panelarrow-down.png (social/panelarrow-down.png) - skin/classic/browser/social/panelarrow-horiz.png (social/panelarrow-horiz.png) - skin/classic/browser/social/panelarrow-up.png (social/panelarrow-up.png) skin/classic/browser/tabbrowser/alltabs-box-bkgnd-icon.png (tabbrowser/alltabs-box-bkgnd-icon.png) skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png) skin/classic/browser/tabbrowser/connecting.png (tabbrowser/connecting.png) skin/classic/browser/tabbrowser/loading.png (tabbrowser/loading.png) skin/classic/browser/tabbrowser/tab-arrow-left.png (tabbrowser/tab-arrow-left.png) skin/classic/browser/tabbrowser/tab-arrow-right.png (tabbrowser/tab-arrow-right.png) skin/classic/browser/tabbrowser/tabbar-bottom-bg-active.png (tabbrowser/tabbar-bottom-bg-active.png) skin/classic/browser/tabbrowser/tabbar-bottom-bg-inactive.png (tabbrowser/tabbar-bottom-bg-inactive.png)
deleted file mode 100644 index 0224ebdf153bec5d7125f88bb9494d6d36dfbeae..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index ed59312c14252fe9c7f37e902285d652cbb09359..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index 451b83b3b9bfde3ffba768feba91566bea92210d..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@<O00001
--- a/browser/themes/winstripe/browser.css +++ b/browser/themes/winstripe/browser.css @@ -3439,24 +3439,16 @@ stack[anonid=browserStack][responsivemod cursor: pointer; min-width: 0; margin: 0 6px; } #social-statusarea-username:hover { text-decoration: underline; } -#social-notification-panel { - min-height: 100px; - min-width: 100px; - max-height: 600px; - max-width: 400px; -} - - .chat-status-icon { max-height: 16px; max-width: 16px; padding: 0; } .chat-toolbarbutton { -moz-appearance: none;
--- a/config/system-headers +++ b/config/system-headers @@ -399,17 +399,16 @@ libgnomevfs/gnome-vfs-file-info.h libgnomevfs/gnome-vfs.h libgnomevfs/gnome-vfs-init.h libgnomevfs/gnome-vfs-mime.h libgnomevfs/gnome-vfs-mime-handlers.h libgnomevfs/gnome-vfs-mime-utils.h libgnomevfs/gnome-vfs-ops.h libgnomevfs/gnome-vfs-standard-callbacks.h lib$routines.h -libnotify/notify.h limits limits.h link.h linux/kernel.h linux/limits.h linux/rtc.h linux/version.h list
--- a/configure.in +++ b/configure.in @@ -69,17 +69,16 @@ WINDRES_VERSION=2.14.90 W32API_VERSION=3.14 GNOMEVFS_VERSION=2.0 GNOMEUI_VERSION=2.2.0 GCONF_VERSION=1.2.1 GIO_VERSION=2.18 STARTUP_NOTIFICATION_VERSION=0.8 DBUS_VERSION=0.60 SQLITE_VERSION=3.7.13 -LIBNOTIFY_VERSION=0.4 MSMANIFEST_TOOL= dnl Set various checks dnl ======================================================== MISSING_X= AC_PROG_AWK @@ -4924,61 +4923,22 @@ then AC_DEFINE(MOZ_ENABLE_LIBPROXY) fi fi AC_SUBST(MOZ_ENABLE_LIBPROXY) AC_SUBST(MOZ_LIBPROXY_CFLAGS) AC_SUBST(MOZ_LIBPROXY_LIBS) dnl ======================================================== -dnl = libnotify support +dnl = GNOME component (mozgnome) dnl ======================================================== if test "$MOZ_ENABLE_GTK2" then - MOZ_ENABLE_LIBNOTIFY=1 - - MOZ_ARG_DISABLE_BOOL(libnotify, - [ --disable-libnotify Disable libnotify support ], - MOZ_ENABLE_LIBNOTIFY=, - MOZ_ENABLE_LIBNOTIFY=1) - - if test "$MOZ_ENABLE_LIBNOTIFY" - then - AC_DEFINE(MOZ_ENABLE_LIBNOTIFY) - fi -fi - -if test -z "$SKIP_LIBRARY_CHECKS" -then - if test "$MOZ_ENABLE_GTK2" - then - if test "$MOZ_ENABLE_LIBNOTIFY" - then - PKG_CHECK_MODULES(MOZ_LIBNOTIFY, libnotify >= $LIBNOTIFY_VERSION) - fi - fi -fi -AC_SUBST(MOZ_ENABLE_LIBNOTIFY) -AC_SUBST(MOZ_LIBNOTIFY_CFLAGS) -AC_SUBST(MOZ_LIBNOTIFY_LIBS) - -dnl ======================================================== -dnl = GNOME component (mozgnome) -dnl ======================================================== - -# The GNOME component is built if one of -# gnome-vfs, gio, gconf or libnotify is available. -if test "$MOZ_ENABLE_GCONF" -o \ - "$MOZ_ENABLE_GNOMEVFS" -o \ - "$MOZ_ENABLE_GIO" -o \ - "$MOZ_ENABLE_LIBNOTIFY"; then MOZ_ENABLE_GNOME_COMPONENT=1 -else - MOZ_ENABLE_GNOME_COMPONENT= fi AC_SUBST(MOZ_ENABLE_GNOME_COMPONENT) dnl ======================================================== dnl = libgnomeui support module dnl ======================================================== if test "$MOZ_ENABLE_GTK2"
--- a/dom/activities/interfaces/nsIActivityProxy.idl +++ b/dom/activities/interfaces/nsIActivityProxy.idl @@ -1,18 +1,21 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsISupports.idl" interface nsIDOMMozActivity; interface nsIDOMMozActivityOptions; +interface nsIDOMWindow; /** * Implemented by @mozilla.org/dom/activities/proxy;1 */ -[scriptable, uuid(2241faf9-6219-4bc0-95f3-18651ac8a18b)] +[scriptable, uuid(3f9e0695-f466-4111-a8fa-ed5c0751c42b)] interface nsIActivityProxy : nsISupports { - void startActivity(in nsIDOMMozActivity activity, in nsIDOMMozActivityOptions options); + void startActivity(in nsIDOMMozActivity activity, + in nsIDOMMozActivityOptions options, + in nsIDOMWindow window); void cleanup(); };
--- a/dom/activities/src/Activity.cpp +++ b/dom/activities/src/Activity.cpp @@ -62,17 +62,17 @@ Activity::Initialize(nsISupports* aOwner } // Instantiate a JS proxy that will do the child <-> parent communication // with the JS implementation of the backend. nsresult rv; mProxy = do_CreateInstance("@mozilla.org/dom/activities/proxy;1", &rv); NS_ENSURE_SUCCESS(rv, rv); - mProxy->StartActivity(this, options); + mProxy->StartActivity(this, options, window); return NS_OK; } Activity::~Activity() { if (mProxy) { mProxy->Cleanup(); }
--- a/dom/activities/src/ActivityProxy.js +++ b/dom/activities/src/ActivityProxy.js @@ -1,46 +1,48 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; - + const Cc = Components.classes; const Ci = Components.interfaces; const Cu = Components.utils; - + Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/ObjectWrapper.jsm"); XPCOMUtils.defineLazyGetter(this, "cpmm", function() { return Cc["@mozilla.org/childprocessmessagemanager;1"] .getService(Ci.nsIFrameMessageManager) .QueryInterface(Ci.nsISyncMessageSender); }); function debug(aMsg) { //dump("-- ActivityProxy " + Date.now() + " : " + aMsg + "\n"); } /** * nsIActivityProxy implementation * We keep a reference to the C++ Activity object, and - * communicate with the Message Manager to know when to + * communicate with the Message Manager to know when to * fire events on it. */ function ActivityProxy() { debug("ActivityProxy"); this.activity = null; } ActivityProxy.prototype = { - startActivity: function actProxy_startActivity(aActivity, aOptions) { + startActivity: function actProxy_startActivity(aActivity, aOptions, aWindow) { debug("startActivity"); + this.window = aWindow; this.activity = aActivity; this.id = Cc["@mozilla.org/uuid-generator;1"] .getService(Ci.nsIUUIDGenerator) .generateUUID().toString(); cpmm.sendAsyncMessage("Activity:Start", { id: this.id, options: aOptions }); cpmm.addMessageListener("Activity:FireSuccess", this); cpmm.addMessageListener("Activity:FireError", this); @@ -51,17 +53,18 @@ ActivityProxy.prototype = { let msg = aMessage.json; if (msg.id != this.id) return; debug("msg=" + JSON.stringify(msg)); switch(aMessage.name) { case "Activity:FireSuccess": debug("FireSuccess"); - Services.DOMRequest.fireSuccess(this.activity, msg.result); + Services.DOMRequest.fireSuccess(this.activity, + ObjectWrapper.wrap(msg.result, this.window)); break; case "Activity:FireError": debug("FireError"); Services.DOMRequest.fireError(this.activity, msg.error); break; } },
--- a/dom/activities/src/ActivityWrapper.js +++ b/dom/activities/src/ActivityWrapper.js @@ -4,40 +4,41 @@ "use strict"; const Cc = Components.classes; const Ci = Components.interfaces; const Cu = Components.utils; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); +Cu.import("resource://gre/modules/ObjectWrapper.jsm"); function debug(aMsg) { //dump("-- ActivityWrapper.js " + Date.now() + " : " + aMsg + "\n"); } /** * nsISystemMessagesWrapper implementation. Will return a * nsIDOMMozActivityRequestHandler */ function ActivityWrapper() { debug("ActivityWrapper"); } ActivityWrapper.prototype = { - wrapMessage: function wrapMessage(aMessage) { + wrapMessage: function wrapMessage(aMessage, aWindow) { debug("Wrapping " + JSON.stringify(aMessage)); let handler = Cc["@mozilla.org/dom/activities/request-handler;1"] .createInstance(Ci.nsIDOMMozActivityRequestHandler); handler.wrappedJSObject._id = aMessage.id; // options is an nsIDOMActivityOptions object. var options = handler.wrappedJSObject._options; options.wrappedJSObject._name = aMessage.payload.name; - options.wrappedJSObject._data = aMessage.payload.data; + options.wrappedJSObject._data = ObjectWrapper.wrap(aMessage.payload.data, aWindow); return handler; }, classID: Components.ID("{5430d6f9-32d6-4924-ba39-6b6d1b093cd6}"), QueryInterface: XPCOMUtils.generateQI([Ci.nsISystemMessagesWrapper]) }
--- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -97,16 +97,17 @@ UnwrapDOMObject(JSObject* obj, DOMObject #ifdef DEBUG if (IsDOMClass(js::GetObjectClass(obj))) { MOZ_ASSERT(slot == eRegularDOMObject); } else { MOZ_ASSERT(js::IsObjectProxyClass(js::GetObjectClass(obj)) || js::IsFunctionProxyClass(js::GetObjectClass(obj))); MOZ_ASSERT(js::GetProxyHandler(obj)->family() == ProxyFamily()); + MOZ_ASSERT(IsNewProxyBinding(js::GetProxyHandler(obj))); MOZ_ASSERT(slot == eProxyDOMObject); } #endif JS::Value val = js::GetReservedSlot(obj, slot); // XXXbz/khuey worker code tries to unwrap interface objects (which have // nothing here). That needs to stop. // XXX We don't null-check UnwrapObject's result; aren't we going to crash @@ -124,31 +125,32 @@ GetDOMClass(JSObject* obj) { js::Class* clasp = js::GetObjectClass(obj); if (IsDOMClass(clasp)) { return &DOMJSClass::FromJSClass(clasp)->mClass; } js::BaseProxyHandler* handler = js::GetProxyHandler(obj); MOZ_ASSERT(handler->family() == ProxyFamily()); + MOZ_ASSERT(IsNewProxyBinding(handler)); return &static_cast<DOMProxyHandler*>(handler)->mClass; } inline DOMObjectSlot GetDOMClass(JSObject* obj, const DOMClass*& result) { js::Class* clasp = js::GetObjectClass(obj); if (IsDOMClass(clasp)) { result = &DOMJSClass::FromJSClass(clasp)->mClass; return eRegularDOMObject; } if (js::IsObjectProxyClass(clasp) || js::IsFunctionProxyClass(clasp)) { js::BaseProxyHandler* handler = js::GetProxyHandler(obj); - if (handler->family() == ProxyFamily()) { + if (handler->family() == ProxyFamily() && IsNewProxyBinding(handler)) { result = &static_cast<DOMProxyHandler*>(handler)->mClass; return eProxyDOMObject; } } return eNonDOMObject; } @@ -166,17 +168,18 @@ UnwrapDOMObjectToISupports(JSObject* obj } inline bool IsDOMObject(JSObject* obj) { js::Class* clasp = js::GetObjectClass(obj); return IsDOMClass(clasp) || ((js::IsObjectProxyClass(clasp) || js::IsFunctionProxyClass(clasp)) && - js::GetProxyHandler(obj)->family() == ProxyFamily()); + (js::GetProxyHandler(obj)->family() == ProxyFamily() && + IsNewProxyBinding(js::GetProxyHandler(obj)))); } // Some callers don't want to set an exception when unwrappin fails // (for example, overload resolution uses unwrapping to tell what sort // of thing it's looking at). // U must be something that a T* can be assigned to (e.g. T* or an nsRefPtr<T>). template <prototypes::ID PrototypeID, class T, typename U> inline nsresult
--- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -77,16 +77,26 @@ DOMInterfaces = { ], 'resultNotAddRefed': [ 'canvas' ], 'binaryNames': { 'mozImageSmoothingEnabled': 'imageSmoothingEnabled', 'mozFillRule': 'fillRule' } }], +'CSS2Properties': { + 'nativeType': 'nsDOMCSSDeclaration', + 'prefable': True, +}, + +'CSSStyleDeclaration': { + 'nativeType': 'nsICSSDeclaration', + 'prefable': True +}, + 'Document': [ { 'nativeType': 'nsIDocument', }, { 'workers': True, 'nativeType': 'JSObject', 'headerFile': 'jsapi.h', @@ -368,16 +378,18 @@ def addExternalHTMLElement(element): addExternalIface(element, nativeType=nativeElement, headerFile=nativeElement + '.h') addExternalHTMLElement('HTMLCanvasElement') addExternalHTMLElement('HTMLImageElement') addExternalHTMLElement('HTMLVideoElement') addExternalIface('CanvasGradient', headerFile='nsIDOMCanvasRenderingContext2D.h') addExternalIface('CanvasPattern', headerFile='nsIDOMCanvasRenderingContext2D.h') +addExternalIface('CSSRule') +addExternalIface('CSSValue') addExternalIface('HitRegionOptions', nativeType='nsISupports') addExternalIface('ImageData', nativeType='mozilla::dom::ImageData') addExternalIface('TextMetrics', headerFile='nsIDOMCanvasRenderingContext2D.h') addExternalIface('WebGLActiveInfo', nativeType='mozilla::WebGLActiveInfo', headerFile='WebGLContext.h') addExternalIface('WebGLBuffer', nativeType='mozilla::WebGLBuffer', headerFile='WebGLContext.h') addExternalIface('WebGLContextAttributes', nativeType='JSObject',
--- a/dom/bindings/DOMJSProxyHandler.cpp +++ b/dom/bindings/DOMJSProxyHandler.cpp @@ -33,16 +33,27 @@ DefineStaticJSVals(JSContext* cx) JSAutoRequest ar(cx); return InternJSString(cx, s_length_id, "length"); } int HandlerFamily; +// Store the information for the specialized ICs. +struct SetListBaseInformation +{ + SetListBaseInformation() { + js::SetListBaseInformation((void*) &HandlerFamily, js::JSSLOT_PROXY_EXTRA + JSPROXYSLOT_EXPANDO); + } +}; + +SetListBaseInformation gSetListBaseInformation; + + bool DefineConstructor(JSContext* cx, JSObject* obj, DefineInterface aDefine, nsresult* aResult) { bool enabled; bool defined = aDefine(cx, obj, &enabled); MOZ_ASSERT(!defined || enabled, "We defined a constructor but the new bindings are disabled?"); *aResult = defined ? NS_OK : NS_ERROR_FAILURE;
--- a/dom/bindings/DOMJSProxyHandler.h +++ b/dom/bindings/DOMJSProxyHandler.h @@ -19,21 +19,21 @@ namespace mozilla { namespace dom { enum { JSPROXYSLOT_EXPANDO = 0 }; template<typename T> struct Prefable; -class DOMProxyHandler : public js::BaseProxyHandler +class DOMProxyHandler : public DOMBaseProxyHandler { public: DOMProxyHandler(const DOMClass& aClass) - : js::BaseProxyHandler(ProxyFamily()), + : DOMBaseProxyHandler(true), mClass(aClass) { } bool getPropertyDescriptor(JSContext* cx, JSObject* proxy, jsid id, bool set, JSPropertyDescriptor* desc); bool defineProperty(JSContext* cx, JSObject* proxy, jsid id, JSPropertyDescriptor* desc);
--- a/dom/bindings/ErrorResult.h +++ b/dom/bindings/ErrorResult.h @@ -7,16 +7,17 @@ /** * A struct for tracking exceptions that need to be thrown to JS. */ #ifndef mozilla_ErrorResult_h #define mozilla_ErrorResult_h #include "nscore.h" +#include "mozilla/Assertions.h" namespace mozilla { class ErrorResult { public: ErrorResult() { mResult = NS_OK; }
new file mode 100644 --- /dev/null +++ b/dom/bindings/GenerateCSS2PropertiesWebIDL.py @@ -0,0 +1,22 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +import sys +import string + +propList = eval(sys.stdin.read()) +props = "" +for [prop, pref] in propList: + pref = '[Pref=%s] ' % pref if pref is not "" else "" + if not prop.startswith("Moz"): + prop = prop[0].lower() + prop[1:] + # Unfortunately, even some of the getters here are fallible + # (e.g. on nsComputedDOMStyle). + props += " %sattribute DOMString %s;\n" % (pref, prop) + +idlFile = open(sys.argv[1], "r"); +idlTemplate = idlFile.read(); +idlFile.close(); + +print string.Template(idlTemplate).substitute({ "props": props })
--- a/dom/bindings/Makefile.in +++ b/dom/bindings/Makefile.in @@ -17,17 +17,17 @@ EXPORT_LIBRARY = 1 include $(topsrcdir)/config/config.mk # Need this to find all our DOM source files. include $(topsrcdir)/dom/dom-config.mk include $(topsrcdir)/dom/webidl/WebIDL.mk binding_include_path := mozilla/dom -all_webidl_files = $(webidl_files) +all_webidl_files = $(webidl_files) $(generated_webidl_files) # Set exported_binding_headers before adding the test IDL to the mix exported_binding_headers := $(subst .webidl,Binding.h,$(all_webidl_files)) # Set linked_binding_cpp_files before adding the test IDL to the mix linked_binding_cpp_files := $(subst .webidl,Binding.cpp,$(all_webidl_files)) all_webidl_files += $(test_webidl_files) binding_header_files := $(subst .webidl,Binding.h,$(all_webidl_files)) @@ -83,16 +83,26 @@ bindinggen_dependencies := \ Bindings.conf \ Configuration.py \ Codegen.py \ parser/WebIDL.py \ ParserResults.pkl \ $(GLOBAL_DEPS) \ $(NULL) +CSS2Properties.webidl: $(topsrcdir)/layout/style/nsCSSPropList.h \ + $(topsrcdir)/layout/style/nsCSSPropAliasList.h \ + $(webidl_base)/CSS2Properties.webidl.in \ + $(webidl_base)/CSS2PropertiesProps.h \ + $(srcdir)/GenerateCSS2PropertiesWebIDL.py \ + $(GLOBAL_DEPS) + $(CPP) -I$(topsrcdir)/layout/style $(webidl_base)/CSS2PropertiesProps.h | \ + PYTHONDONTWRITEBYTECODE=1 $(PYTHON) \ + $(srcdir)/GenerateCSS2PropertiesWebIDL.py $(webidl_base)/CSS2Properties.webidl.in > CSS2Properties.webidl + $(webidl_files): %: $(webidl_base)/% $(INSTALL) $(IFLAGS1) $(webidl_base)/$* . $(test_webidl_files): %: $(srcdir)/test/% $(INSTALL) $(IFLAGS1) $(srcdir)/test/$* . $(binding_header_files): %Binding.h: $(bindinggen_dependencies) \ %.webidl \
--- a/dom/bluetooth/linux/BluetoothDBusService.cpp +++ b/dom/bluetooth/linux/BluetoothDBusService.cpp @@ -1315,17 +1315,18 @@ BluetoothDBusService::SetProperty(Blueto void* val; nsCString str; if (aValue.value().type() == BluetoothValue::Tuint32_t) { tmp_int = aValue.value().get_uint32_t(); val = &tmp_int; type = DBUS_TYPE_UINT32; } else if (aValue.value().type() == BluetoothValue::TnsString) { str = NS_ConvertUTF16toUTF8(aValue.value().get_nsString()); - val = (void*)str.get(); + const char* tempStr = str.get(); + val = &tempStr; type = DBUS_TYPE_STRING; } else if (aValue.value().type() == BluetoothValue::Tbool) { tmp_int = aValue.value().get_bool() ? 1 : 0; val = &(tmp_int); type = DBUS_TYPE_BOOLEAN; } else { NS_WARNING("Property type not handled!"); dbus_message_unref(msg);
--- a/dom/messages/SystemMessageManager.js +++ b/dom/messages/SystemMessageManager.js @@ -55,17 +55,17 @@ SystemMessageManager.prototype = { debug("Dispatching " + JSON.stringify(aMessage) + "\n"); let contractID = "@mozilla.org/dom/system-messages/wrapper/" + aType + ";1"; let wrapped = false; if (contractID in Cc) { debug(contractID + " is registered, creating an instance"); let wrapper = Cc[contractID].createInstance(Ci.nsISystemMessagesWrapper); if (wrapper) { - aMessage = wrapper.wrapMessage(aMessage); + aMessage = wrapper.wrapMessage(aMessage, this._window); wrapped = true; debug("wrapped = " + aMessage); } } aHandler.handleMessage(wrapped ? aMessage : ObjectWrapper.wrap(aMessage, this._window)); },
--- a/dom/messages/interfaces/nsISystemMessagesInternal.idl +++ b/dom/messages/interfaces/nsISystemMessagesInternal.idl @@ -1,15 +1,16 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "domstubs.idl" interface nsIURI; +interface nsIDOMWindow; // Implemented by the contract id @mozilla.org/system-message-internal;1 [scriptable, uuid(3a50fd6b-0263-45c1-b738-a002052ad31b)] interface nsISystemMessagesInternal : nsISupports { /* * Allow any internal user to broadcast a message of a given type. @@ -24,17 +25,17 @@ interface nsISystemMessagesInternal : ns * Registration of a page that wants to be notified of a message type. * @param type The message type. * @param pageURI The URI of the page that will be opened. * @param manifestURI The webapp's manifest URI. */ void registerPage(in DOMString type, in nsIURI pageURI, in nsIURI manifestURI); }; -[scriptable, uuid(b43c74ec-1b64-49fb-b552-aadd9d827eec)] +[scriptable, uuid(002f0e82-91f0-41de-ad43-569a2b9d12df)] interface nsISystemMessagesWrapper: nsISupports { /* * Wrap a message and gives back any kind of object. * @param message The json blob to wrap. */ - jsval wrapMessage(in jsval message); + jsval wrapMessage(in jsval message, in nsIDOMWindow window); };
--- a/dom/tests/mochitest/bugs/test_bug529328.html +++ b/dom/tests/mochitest/bugs/test_bug529328.html @@ -96,41 +96,31 @@ function testMediaList() { is(s.sheet.media.item(0), "a", "Wrong value for in bounds access (MediaList)"); is(s.sheet.media.item(1), "b", "Wrong value for in bounds access (MediaList)"); is(s.sheet.media.item(2), null, "Wrong value for out of bounds access (MediaList) (MediaList)"); } function testCSSStyleDeclaration() { var s = document.createElement("span"); - try { - is(s.style[-1], "", "Wrong value for out of bounds access (CSSStyleDeclaration)"); - todo(true, "Didn't throw"); - } catch (e) { - todo(false, "Shouldn't throw"); - } - is(s.style[0], "", "Wrong value for out of bounds access (CSSStyleDeclaration)"); - is(s.style[1], "", "Wrong value for out of bounds access (CSSStyleDeclaration)"); - is(s.style[2], "", "Wrong value for out of bounds access (CSSStyleDeclaration)"); + is(s.style[-1], undefined, "Wrong value for out of bounds access (CSSStyleDeclaration)"); + is(s.style[0], undefined, "Wrong value for out of bounds access (CSSStyleDeclaration)"); + is(s.style[1], undefined, "Wrong value for out of bounds access (CSSStyleDeclaration)"); + is(s.style[2], undefined, "Wrong value for out of bounds access (CSSStyleDeclaration)"); is(s.style.item(-1), "", "Wrong value for out of bounds access (CSSStyleDeclaration)"); is(s.style.item(0), "", "Wrong value for out of bounds access (CSSStyleDeclaration)"); is(s.style.item(1), "", "Wrong value for out of bounds access (CSSStyleDeclaration)"); is(s.style.item(2), "", "Wrong value for out of bounds access (CSSStyleDeclaration)"); s.setAttribute("style", "color: blue; z-index: 42;"); - try { - is(s.style[-1], "", "Wrong value for out of bounds access (CSSStyleDeclaration)"); - todo(true, "Didn't throw"); - } catch (e) { - todo(false, "Shouldn't throw"); - } + is(s.style[-1], undefined, "Wrong value for out of bounds access (CSSStyleDeclaration)"); is(s.style[0], "color", "Wrong value for in bounds access (CSSStyleDeclaration)"); is(s.style[1], "z-index", "Wrong value for in bounds access (CSSStyleDeclaration)"); - is(s.style[2], "", "Wrong value for out of bounds access (CSSStyleDeclaration)"); + is(s.style[2], undefined, "Wrong value for out of bounds access (CSSStyleDeclaration)"); is(s.style.item(-1), "", "Wrong value for out of bounds access (CSSStyleDeclaration)"); is(s.style.item(0), "color", "Wrong value for in bounds access (CSSStyleDeclaration)"); is(s.style.item(1), "z-index", "Wrong value for in bounds access (CSSStyleDeclaration)"); is(s.style.item(2), "", "Wrong value for out of bounds access (CSSStyleDeclaration)"); } testDOMTokenList(); testDOMStringList();
new file mode 100644 --- /dev/null +++ b/dom/webidl/CSS2Properties.webidl.in @@ -0,0 +1,3 @@ +interface CSS2Properties : CSSStyleDeclaration { +${props} +};
new file mode 100644 --- /dev/null +++ b/dom/webidl/CSS2PropertiesProps.h @@ -0,0 +1,34 @@ +/* A file meant as input to the preprocessor only */ + +/* DO_PROP serves as an extra level of indirection to allow expansion + of CSS_PROP_DOMPROP_PREFIXED */ + +[ + +#define DO_PROP(method, pref) \ + [ #method, pref ], +#define CSS_PROP(name, id, method, flags, pref, parsevariant, kwtable, \ + stylestruct, stylestructofset, animtype) \ + DO_PROP(method, pref) +#define CSS_PROP_SHORTHAND(name, id, method, flags, pref) \ + DO_PROP(method, pref) +#define CSS_PROP_DOMPROP_PREFIXED(val) Moz##val +#define CSS_PROP_LIST_EXCLUDE_INTERNAL + +#include "nsCSSPropList.h" + +#undef CSS_PROP_LIST_EXCLUDE_INTERNAL +#undef CSS_PROP_DOMPROP_PREFIXED +#undef CSS_PROP_SHORTHAND +#undef CSS_PROP + +#define CSS_PROP_ALIAS(name, id, method, pref) \ + DO_PROP(method, pref) + +#include "nsCSSPropAliasList.h" + +#undef CSS_PROP_ALIAS + +#undef DO_PROP + +]
new file mode 100644 --- /dev/null +++ b/dom/webidl/CSSStyleDeclaration.webidl @@ -0,0 +1,34 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * http://dev.w3.org/csswg/cssom/ + */ + +interface CSSRule; +interface CSSValue; + +interface CSSStyleDeclaration { + [GetterInfallible] + attribute DOMString cssText; + + [Infallible] + readonly attribute unsigned long length; + [Infallible] + getter DOMString item(unsigned long index); + + DOMString getPropertyValue(DOMString property); + // Mozilla extension, sort of + CSSValue getPropertyCSSValue(DOMString property); + [Infallible] + DOMString getPropertyPriority(DOMString property); + // This would be nicer if it used a string default value of "". + // See bug 759622. + void setProperty(DOMString property, DOMString value, [TreatNullAs=EmptyString] optional DOMString priority); + DOMString removeProperty(DOMString property); + + [Infallible] + readonly attribute CSSRule parentRule; +};
--- a/dom/webidl/WebIDL.mk +++ b/dom/webidl/WebIDL.mk @@ -1,16 +1,21 @@ # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. webidl_base = $(topsrcdir)/dom/webidl +generated_webidl_files = \ + CSS2Properties.webidl \ + $(NULL) + webidl_files = \ CanvasRenderingContext2D.webidl \ + CSSStyleDeclaration.webidl \ Function.webidl \ EventListener.webidl \ EventTarget.webidl \ Performance.webidl \ PerformanceNavigation.webidl \ PerformanceTiming.webidl \ XMLHttpRequest.webidl \ XMLHttpRequestEventTarget.webidl \
--- a/js/src/config/system-headers +++ b/js/src/config/system-headers @@ -399,17 +399,16 @@ libgnomevfs/gnome-vfs-file-info.h libgnomevfs/gnome-vfs.h libgnomevfs/gnome-vfs-init.h libgnomevfs/gnome-vfs-mime.h libgnomevfs/gnome-vfs-mime-handlers.h libgnomevfs/gnome-vfs-mime-utils.h libgnomevfs/gnome-vfs-ops.h libgnomevfs/gnome-vfs-standard-callbacks.h lib$routines.h -libnotify/notify.h limits limits.h link.h linux/kernel.h linux/limits.h linux/rtc.h linux/version.h list
--- a/js/src/jsreflect.cpp +++ b/js/src/jsreflect.cpp @@ -2667,18 +2667,18 @@ ASTSerializer::expression(ParseNode *pn, { NodeVector elts(cx); if (!elts.reserve(pn->pn_count)) return false; for (ParseNode *next = pn->pn_head; next; next = next->pn_next) { JS_ASSERT(pn->pn_pos.encloses(next->pn_pos)); - if (next->isKind(PNK_COMMA)) { - elts.infallibleAppend(MagicValue(JS_SERIALIZE_NO_NODE)); + if (next->isKind(PNK_COMMA) && next->pn_count == 0) { + elts.infallibleAppend(NullValue()); } else { Value expr; if (!expression(next, &expr)) return false; elts.infallibleAppend(expr); } } @@ -3015,18 +3015,21 @@ ASTSerializer::arrayPattern(ParseNode *p { JS_ASSERT(pn->isKind(PNK_RB)); NodeVector elts(cx); if (!elts.reserve(pn->pn_count)) return false; for (ParseNode *next = pn->pn_head; next; next = next->pn_next) { + /* Comma expressions can't occur inside patterns, so no need to test pn_count. */ + JS_ASSERT_IF(next->isKind(PNK_COMMA), next->pn_count == 0); + if (next->isKind(PNK_COMMA)) { - elts.infallibleAppend(MagicValue(JS_SERIALIZE_NO_NODE)); + elts.infallibleAppend(NullValue()); } else { Value patt; if (!pattern(next, pkind, &patt)) return false; elts.infallibleAppend(patt); } }
--- a/js/src/tests/js1_8_5/extensions/reflect-parse.js +++ b/js/src/tests/js1_8_5/extensions/reflect-parse.js @@ -233,16 +233,19 @@ assertDecl("function f(a) { function a() funDecl(ident("f"), [ident("a")], blockStmt([funDecl(ident("a"), [], blockStmt([]))]))); assertDecl("function f(a,b,c) { function b() { } }", funDecl(ident("f"), [ident("a"),ident("b"),ident("c")], blockStmt([funDecl(ident("b"), [], blockStmt([]))]))); assertDecl("function f(a,[x,y]) { function a() { } }", funDecl(ident("f"), [ident("a"), arrPatt([ident("x"), ident("y")])], blockStmt([funDecl(ident("a"), [], blockStmt([]))]))); +// Bug 632027: array holes should reflect as null +assertExpr("[,]=[,]", aExpr("=", arrPatt([null]), arrExpr([null]))); + // Bug 591450: this test currently crashes because of a bug in jsparse // assertDecl("function f(a,[x,y],b,[w,z],c) { function b() { } }", // funDecl(ident("f"), // [ident("a"), arrPatt([ident("x"), ident("y")]), ident("b"), arrPatt([ident("w"), ident("z")]), ident("c")], // blockStmt([funDecl(ident("b"), [], blockStmt([]))]))); // expressions @@ -315,29 +318,31 @@ assertExpr("(new Object(42))", newExpr(i assertExpr("(new Object(1,2,3))", newExpr(ident("Object"), [lit(1),lit(2),lit(3)])); assertExpr("(String())", callExpr(ident("String"), [])); assertExpr("(String(42))", callExpr(ident("String"), [lit(42)])); assertExpr("(String(1,2,3))", callExpr(ident("String"), [lit(1),lit(2),lit(3)])); assertExpr("[]", arrExpr([])); assertExpr("[1]", arrExpr([lit(1)])); assertExpr("[1,2]", arrExpr([lit(1),lit(2)])); assertExpr("[1,2,3]", arrExpr([lit(1),lit(2),lit(3)])); -assertExpr("[1,,2,3]", arrExpr([lit(1),,lit(2),lit(3)])); -assertExpr("[1,,,2,3]", arrExpr([lit(1),,,lit(2),lit(3)])); -assertExpr("[1,,,2,,3]", arrExpr([lit(1),,,lit(2),,lit(3)])); -assertExpr("[1,,,2,,,3]", arrExpr([lit(1),,,lit(2),,,lit(3)])); -assertExpr("[,1,2,3]", arrExpr([,lit(1),lit(2),lit(3)])); -assertExpr("[,,1,2,3]", arrExpr([,,lit(1),lit(2),lit(3)])); -assertExpr("[,,,1,2,3]", arrExpr([,,,lit(1),lit(2),lit(3)])); -assertExpr("[,,,1,2,3,]", arrExpr([,,,lit(1),lit(2),lit(3),])); -assertExpr("[,,,1,2,3,,]", arrExpr([,,,lit(1),lit(2),lit(3),,])); -assertExpr("[,,,1,2,3,,,]", arrExpr([,,,lit(1),lit(2),lit(3),,,])); -assertExpr("[,,,,,]", arrExpr([,,,,,])); +assertExpr("[1,,2,3]", arrExpr([lit(1),null,lit(2),lit(3)])); +assertExpr("[1,,,2,3]", arrExpr([lit(1),null,null,lit(2),lit(3)])); +assertExpr("[1,,,2,,3]", arrExpr([lit(1),null,null,lit(2),null,lit(3)])); +assertExpr("[1,,,2,,,3]", arrExpr([lit(1),null,null,lit(2),null,null,lit(3)])); +assertExpr("[,1,2,3]", arrExpr([null,lit(1),lit(2),lit(3)])); +assertExpr("[,,1,2,3]", arrExpr([null,null,lit(1),lit(2),lit(3)])); +assertExpr("[,,,1,2,3]", arrExpr([null,null,null,lit(1),lit(2),lit(3)])); +assertExpr("[,,,1,2,3,]", arrExpr([null,null,null,lit(1),lit(2),lit(3)])); +assertExpr("[,,,1,2,3,,]", arrExpr([null,null,null,lit(1),lit(2),lit(3),null])); +assertExpr("[,,,1,2,3,,,]", arrExpr([null,null,null,lit(1),lit(2),lit(3),null,null])); +assertExpr("[,,,,,]", arrExpr([null,null,null,null,null])); assertExpr("[1, ...a, 2]", arrExpr([lit(1), spread(ident("a")), lit(2)])); -assertExpr("[,, ...a,, ...b, 42]", arrExpr([,, spread(ident("a")),, spread(ident("b")), lit(42)])); +assertExpr("[,, ...a,, ...b, 42]", arrExpr([null,null, spread(ident("a")),, spread(ident("b")), lit(42)])); +assertExpr("[1,(2,3)]", arrExpr([lit(1),seqExpr([lit(2),lit(3)])])); +assertExpr("[,(2,3)]", arrExpr([null,seqExpr([lit(2),lit(3)])])); assertExpr("({})", objExpr([])); assertExpr("({x:1})", objExpr([{ key: ident("x"), value: lit(1) }])); assertExpr("({x:1, y:2})", objExpr([{ key: ident("x"), value: lit(1) }, { key: ident("y"), value: lit(2) } ])); assertExpr("({x:1, y:2, z:3})", objExpr([{ key: ident("x"), value: lit(1) }, { key: ident("y"), value: lit(2) }, { key: ident("z"), value: lit(3) } ])); assertExpr("({x:1, 'y':2, z:3})", objExpr([{ key: ident("x"), value: lit(1) },
--- a/js/xpconnect/src/dombindings.cpp +++ b/js/xpconnect/src/dombindings.cpp @@ -60,25 +60,16 @@ DefineStaticJSVals(JSContext *cx) return SET_JSID_TO_STRING(cx, prototype) && SET_JSID_TO_STRING(cx, length) && SET_JSID_TO_STRING(cx, iterator) && DefinePropertyStaticJSVals(cx); } -int HandlerFamily; - -struct SetListBaseInformation -{ - SetListBaseInformation() { - js::SetListBaseInformation((void*) &HandlerFamily, js::JSSLOT_PROXY_EXTRA + JSPROXYSLOT_EXPANDO); - } -} gSetListBaseInformation; - JSBool Throw(JSContext *cx, nsresult rv) { XPCThrower::Throw(rv, cx); return false; } template<class T>
--- a/js/xpconnect/src/dombindings.h +++ b/js/xpconnect/src/dombindings.h @@ -12,19 +12,19 @@ #include "jsproxy.h" #include "xpcpublic.h" #include "nsString.h" namespace mozilla { namespace dom { namespace oldproxybindings { -class ProxyHandler : public js::BaseProxyHandler { +class ProxyHandler : public DOMBaseProxyHandler { protected: - ProxyHandler() : js::BaseProxyHandler(ProxyFamily()) + ProxyHandler() : DOMBaseProxyHandler(false) { } public: virtual bool isInstanceOf(JSObject *prototype) = 0; }; class NoType;
--- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -304,41 +304,59 @@ Throw(JSContext *cx, nsresult rv); nsCycleCollectionParticipant * xpc_JSCompartmentParticipant(); namespace mozilla { namespace dom { extern int HandlerFamily; inline void* ProxyFamily() { return &HandlerFamily; } + +class DOMBaseProxyHandler : public js::BaseProxyHandler { +protected: + DOMBaseProxyHandler(bool aNewDOMProxy) : js::BaseProxyHandler(ProxyFamily()), + mNewDOMProxy(aNewDOMProxy) + { + } + +public: + bool mNewDOMProxy; +}; + +inline bool IsNewProxyBinding(js::BaseProxyHandler* handler) +{ + MOZ_ASSERT(handler->family() == ProxyFamily()); + return static_cast<DOMBaseProxyHandler*>(handler)->mNewDOMProxy; +} + inline bool IsDOMProxy(JSObject *obj) { return js::IsProxy(obj) && - js::GetProxyHandler(obj)->family() == ProxyFamily(); + js::GetProxyHandler(obj)->family() == ProxyFamily() && + IsNewProxyBinding(js::GetProxyHandler(obj)); } typedef bool (*DefineInterface)(JSContext *cx, JSObject *global, bool *enabled); extern bool DefineStaticJSVals(JSContext *cx); void Register(nsScriptNameSpaceManager* aNameSpaceManager); extern bool DefineConstructor(JSContext *cx, JSObject *obj, DefineInterface aDefine, nsresult *aResult); namespace oldproxybindings { -extern int HandlerFamily; -inline void* ProxyFamily() { return &HandlerFamily; } inline bool instanceIsProxy(JSObject *obj) { return js::IsProxy(obj) && - js::GetProxyHandler(obj)->family() == ProxyFamily(); + js::GetProxyHandler(obj)->family() == ProxyFamily() && + !IsNewProxyBinding(js::GetProxyHandler(obj)); } extern bool DefineStaticJSVals(JSContext *cx); void Register(nsScriptNameSpaceManager* aNameSpaceManager); } // namespace oldproxybindings
--- a/js/xpconnect/tests/chrome/test_weakmaps.xul +++ b/js/xpconnect/tests/chrome/test_weakmaps.xul @@ -215,24 +215,16 @@ https://bugzilla.mozilla.org/show_bug.cg let unpreservable_native_key = function () { // We only allow natives that support wrapper preservation to be used as weak // map keys. We should be able to try to add unpreservable natives as keys without // crashing (bug 711616), but we should throw an error (bug 761620). let dummy_test_map = new WeakMap; - let div_fail = false; - try { - dummy_test_map.set(document.createElement("div").style, 1); - } catch (e) { - div_fail = true; - } - ok(div_fail, "Using elem.style as a weak map key should produce an exception because it can't be wrapper preserved."); - let navi_fail = false; try { dummy_test_map.set(window.navigator, 1); } catch (e) { navi_fail = true; } ok(navi_fail, "Using window.navigator as a weak map key should produce an exception because it can't be wrapper preserved.");
--- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -834,24 +834,16 @@ public: /** * Notify that a content node's state has changed */ virtual void ContentStateChanged(nsIDocument* aDocument, nsIContent* aContent, nsEventStates aStateMask) = 0; /** - * Given aFrame, the root frame of a stacking context, find its descendant - * frame under the point aPt that receives a mouse event at that location, - * or nullptr if there is no such frame. - * @param aPt the point, relative to the frame origin - */ - virtual nsIFrame* GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt) = 0; - - /** * See if reflow verification is enabled. To enable reflow verification add * "verifyreflow:1" to your NSPR_LOG_MODULES environment variable * (any non-zero debug level will work). Or, call SetVerifyReflowEnable * with true. */ static bool GetVerifyReflowEnable(); /**
--- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -2363,22 +2363,16 @@ nsIPresShell::GetRootScrollFrameAsScroll nsIPageSequenceFrame* PresShell::GetPageSequenceFrame() const { nsIFrame* frame = mFrameConstructor->GetPageSequenceFrame(); return do_QueryFrame(frame); } -nsIFrame* -PresShell::GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt) -{ - return nsLayoutUtils::GetFrameForPoint(aFrame, aPt); -} - void PresShell::BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType) { #ifdef DEBUG mUpdateCount++; #endif mFrameConstructor->BeginUpdate();
--- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -152,18 +152,16 @@ public: virtual NS_HIDDEN_(already_AddRefed<nsIContent>) GetEventTargetContent(nsEvent* aEvent); virtual nsresult ReconstructFrames(void); virtual void Freeze(); virtual void Thaw(); virtual void FireOrClearDelayedEvents(bool aFireEvents); - virtual nsIFrame* GetFrameForPoint(nsIFrame* aFrame, nsPoint aPt); - virtual NS_HIDDEN_(nsresult) RenderDocument(const nsRect& aRect, uint32_t aFlags, nscolor aBackgroundColor, gfxContext* aThebesContext); virtual already_AddRefed<gfxASurface> RenderNode(nsIDOMNode* aNode, nsIntRegion* aRegion, nsIntPoint& aPoint, nsIntRect* aScreenRect);
--- a/layout/style/Declaration.cpp +++ b/layout/style/Declaration.cpp @@ -982,26 +982,28 @@ Declaration::List(FILE* out, int32_t aIn fputs("{ ", out); nsAutoString s; ToString(s); fputs(NS_ConvertUTF16toUTF8(s).get(), out); fputs("}", out); } #endif -void +bool Declaration::GetNthProperty(uint32_t aIndex, nsAString& aReturn) const { aReturn.Truncate(); if (aIndex < mOrder.Length()) { nsCSSProperty property = OrderValueAt(aIndex); if (0 <= property) { AppendASCIItoUTF16(nsCSSProps::GetStringValue(property), aReturn); + return true; } } + return false; } void Declaration::InitializeEmpty() { NS_ABORT_IF_FALSE(!mData && !mImportantData, "already initialized"); mData = nsCSSCompressedDataBlock::CreateEmptyBlock(); }
--- a/layout/style/Declaration.h +++ b/layout/style/Declaration.h @@ -65,17 +65,19 @@ public: bool HasImportantData() const { return mImportantData != nullptr; } bool GetValueIsImportant(nsCSSProperty aProperty) const; bool GetValueIsImportant(const nsAString& aProperty) const; uint32_t Count() const { return mOrder.Length(); } - void GetNthProperty(uint32_t aIndex, nsAString& aReturn) const; + + // Returns whether we actually had a property at aIndex + bool GetNthProperty(uint32_t aIndex, nsAString& aReturn) const; void ToString(nsAString& aString) const; nsCSSCompressedDataBlock* GetNormalBlock() const { return mData; } nsCSSCompressedDataBlock* GetImportantBlock() const { return mImportantData; } /** * Initialize this declaration as holding no data. Cannot fail.
--- a/layout/style/nsCSSRules.cpp +++ b/layout/style/nsCSSRules.cpp @@ -30,16 +30,17 @@ #include "nsContentUtils.h" #include "nsStyleConsts.h" #include "nsError.h" #include "nsStyleUtil.h" #include "mozilla/css/Declaration.h" #include "nsCSSParser.h" #include "nsPrintfCString.h" #include "nsDOMClassInfoID.h" +#include "mozilla/dom/CSSStyleDeclarationBinding.h" namespace css = mozilla::css; #define IMPL_STYLE_RULE_INHERIT_GET_DOM_RULE_WEAK(class_, super_) \ /* virtual */ nsIDOMCSSRule* class_::GetDOMRule() \ { return this; } #define IMPL_STYLE_RULE_INHERIT_MAP_RULE_INFO_INTO(class_, super_) \ /* virtual */ void class_::MapRuleInfoInto(nsRuleData* aRuleData) \ @@ -1553,33 +1554,44 @@ nsCSSFontFaceStyleDecl::GetLength(uint32 len++; *aLength = len; return NS_OK; } // DOMString item (in unsigned long index); NS_IMETHODIMP -nsCSSFontFaceStyleDecl::Item(uint32_t index, nsAString & aResult) - { +nsCSSFontFaceStyleDecl::Item(uint32_t aIndex, nsAString& aReturn) +{ + bool found; + IndexedGetter(aIndex, found, aReturn); + if (!found) { + aReturn.Truncate(); + } + return NS_OK; +} + +void +nsCSSFontFaceStyleDecl::IndexedGetter(uint32_t index, bool& aFound, nsAString & aResult) +{ int32_t nset = -1; for (nsCSSFontDesc id = nsCSSFontDesc(eCSSFontDesc_UNKNOWN + 1); id < eCSSFontDesc_COUNT; id = nsCSSFontDesc(id + 1)) { if ((this->*nsCSSFontFaceStyleDecl::Fields[id]).GetUnit() != eCSSUnit_Null) { nset++; if (nset == int32_t(index)) { + aFound = true; aResult.AssignASCII(nsCSSProps::GetStringValue(id).get()); - return NS_OK; + return; } } } - aResult.Truncate(); - return NS_OK; + aFound = false; } // readonly attribute nsIDOMCSSRule parentRule; NS_IMETHODIMP nsCSSFontFaceStyleDecl::GetParentRule(nsIDOMCSSRule** aParentRule) { NS_IF_ADDREF(*aParentRule = ContainingRule()->GetDOMRule()); return NS_OK; @@ -1603,16 +1615,24 @@ nsCSSFontFaceStyleDecl::SetPropertyValue } nsINode* nsCSSFontFaceStyleDecl::GetParentObject() { return ContainingRule()->GetDocument(); } +JSObject* +nsCSSFontFaceStyleDecl::WrapObject(JSContext *cx, JSObject *scope, + bool *triedToWrap) +{ + return mozilla::dom::CSSStyleDeclarationBinding::Wrap(cx, scope, this, + triedToWrap); +} + // ------------------------------------------- // nsCSSFontFaceRule // /* virtual */ already_AddRefed<css::Rule> nsCSSFontFaceRule::Clone() const { nsRefPtr<css::Rule> clone = new nsCSSFontFaceRule(*this);
--- a/layout/style/nsCSSRules.h +++ b/layout/style/nsCSSRules.h @@ -159,21 +159,30 @@ protected: class nsCSSFontFaceRule; class nsCSSFontFaceStyleDecl : public nsICSSDeclaration { public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIDOMCSSSTYLEDECLARATION NS_DECL_NSICSSDECLARATION + nsCSSFontFaceStyleDecl() + { + SetIsDOMBinding(); + } + virtual nsINode *GetParentObject(); + virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName); nsresult GetPropertyValue(nsCSSFontDesc aFontDescID, nsAString & aResult) const; + virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, + bool *triedToWrap); + protected: friend class nsCSSFontFaceRule; #define CSS_FONT_DESC(name_, method_) nsCSSValue m##method_; #include "nsCSSFontDescList.h" #undef CSS_FONT_DESC static nsCSSValue nsCSSFontFaceStyleDecl::* const Fields[]; inline nsCSSFontFaceRule* ContainingRule();
--- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -540,28 +540,31 @@ nsComputedDOMStyle::SetProperty(const ns { return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; } NS_IMETHODIMP nsComputedDOMStyle::Item(uint32_t aIndex, nsAString& aReturn) { - aReturn.Truncate(); - + return nsDOMCSSDeclaration::Item(aIndex, aReturn); +} + +void +nsComputedDOMStyle::IndexedGetter(uint32_t aIndex, bool& aFound, + nsAString& aPropName) +{ uint32_t length = 0; const ComputedStyleMapEntry* propMap = GetQueryablePropertyMap(&length); - if (aIndex < length) { + aFound = aIndex < length; + if (aFound) { CopyASCIItoUTF16(nsCSSProps::GetStringValue(propMap[aIndex].mProperty), - aReturn); + aPropName); } - - return NS_OK; -} - +} // Property getters... nsIDOMCSSValue* nsComputedDOMStyle::DoGetBinding() { nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
--- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -20,26 +20,27 @@ #include "nsWeakReference.h" #include "nsAutoPtr.h" #include "nsStyleStruct.h" #include "nsStyleContext.h" class nsIFrame; class nsIPresShell; -class nsComputedDOMStyle : public nsDOMCSSDeclaration +class nsComputedDOMStyle MOZ_FINAL : public nsDOMCSSDeclaration { public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsComputedDOMStyle, nsICSSDeclaration) NS_DECL_NSICSSDECLARATION NS_DECL_NSIDOMCSSSTYLEDECLARATION + virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName); nsComputedDOMStyle(mozilla::dom::Element* aElement, const nsAString& aPseudoElt, nsIPresShell* aPresShell); virtual ~nsComputedDOMStyle(); static void Shutdown();
--- a/layout/style/nsDOMCSSAttrDeclaration.h +++ b/layout/style/nsDOMCSSAttrDeclaration.h @@ -18,17 +18,17 @@ namespace css { class Loader; } namespace dom { class Element; } } -class nsDOMCSSAttributeDeclaration : public nsDOMCSSDeclaration +class nsDOMCSSAttributeDeclaration MOZ_FINAL : public nsDOMCSSDeclaration { public: typedef mozilla::dom::Element Element; nsDOMCSSAttributeDeclaration(Element* aContent, bool aIsSMILOverride); ~nsDOMCSSAttributeDeclaration(); NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsDOMCSSAttributeDeclaration,
--- a/layout/style/nsDOMCSSDeclaration.cpp +++ b/layout/style/nsDOMCSSDeclaration.cpp @@ -139,27 +139,21 @@ nsDOMCSSDeclaration::GetPropertyCSSValue NS_ENSURE_ARG_POINTER(aReturn); // We don't support CSSValue yet so we'll just return null... *aReturn = nullptr; return NS_OK; } -NS_IMETHODIMP -nsDOMCSSDeclaration::Item(uint32_t aIndex, nsAString& aReturn) +void +nsDOMCSSDeclaration::IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName) { css::Declaration* decl = GetCSSDeclaration(false); - - aReturn.SetLength(0); - if (decl) { - decl->GetNthProperty(aIndex, aReturn); - } - - return NS_OK; + aFound = decl && decl->GetNthProperty(aIndex, aPropName); } NS_IMETHODIMP nsDOMCSSDeclaration::GetPropertyValue(const nsAString& aPropertyName, nsAString& aReturn) { const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName, nsCSSProps::eEnabled);
--- a/layout/style/nsDOMCSSDeclaration.h +++ b/layout/style/nsDOMCSSDeclaration.h @@ -6,16 +6,17 @@ /* base class for DOM objects for element.style and cssStyleRule.style */ #ifndef nsDOMCSSDeclaration_h___ #define nsDOMCSSDeclaration_h___ #include "nsICSSDeclaration.h" #include "nsIDOMCSS2Properties.h" #include "nsCOMPtr.h" +#include "mozilla/dom/CSS2PropertiesBinding.h" class nsCSSParser; class nsIURI; class nsIPrincipal; class nsIDocument; namespace mozilla { namespace css { @@ -28,40 +29,86 @@ class Rule; class nsDOMCSSDeclaration : public nsICSSDeclaration, public nsIDOMCSS2Properties { public: // Only implement QueryInterface; subclasses have the responsibility // of implementing AddRef/Release. NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr); + // Declare addref and release so they can be called on us, but don't + // implement them. Our subclasses must handle their own + // refcounting. + NS_IMETHOD_(nsrefcnt) AddRef() = 0; + NS_IMETHOD_(nsrefcnt) Release() = 0; + NS_DECL_NSICSSDECLARATION + using nsICSSDeclaration::GetLength; // Require subclasses to implement |GetParentRule|. //NS_DECL_NSIDOMCSSSTYLEDECLARATION NS_IMETHOD GetCssText(nsAString & aCssText); NS_IMETHOD SetCssText(const nsAString & aCssText); NS_IMETHOD GetPropertyValue(const nsAString & propertyName, nsAString & _retval); NS_IMETHOD GetPropertyCSSValue(const nsAString & propertyName, nsIDOMCSSValue **_retval); NS_IMETHOD RemoveProperty(const nsAString & propertyName, nsAString & _retval); NS_IMETHOD GetPropertyPriority(const nsAString & propertyName, nsAString & _retval); NS_IMETHOD SetProperty(const nsAString & propertyName, const nsAString & value, const nsAString & priority); NS_IMETHOD GetLength(uint32_t *aLength); - NS_IMETHOD Item(uint32_t index, nsAString & _retval); NS_IMETHOD GetParentRule(nsIDOMCSSRule * *aParentRule) = 0; // We implement this as a shim which forwards to GetPropertyValue // and SetPropertyValue; subclasses need not. NS_DECL_NSIDOMCSS2PROPERTIES + // WebIDL interface for CSS2Properties +#define CSS_PROP_DOMPROP_PREFIXED(prop_) Moz ## prop_ +#define CSS_PROP(name_, id_, method_, flags_, pref_, parsevariant_, \ + kwtable_, stylestruct_, stylestructoffset_, animtype_) \ + void \ + Get##method_(nsAString& aValue, mozilla::ErrorResult& rv) \ + { \ + rv = GetPropertyValue(eCSSProperty_##id_, aValue); \ + } \ + \ + void \ + Set##method_(const nsAString& aValue, mozilla::ErrorResult& rv) \ + { \ + rv = SetPropertyValue(eCSSProperty_##id_, aValue); \ + } + +#define CSS_PROP_LIST_EXCLUDE_INTERNAL +#define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, pref_) \ + CSS_PROP(name_, id_, method_, flags_, pref_, X, X, X, X, X) +#include "nsCSSPropList.h" + +#define CSS_PROP_ALIAS(aliasname_, propid_, aliasmethod_, pref_) \ + CSS_PROP(X, propid_, aliasmethod_, X, pref_, X, X, X, X, X) +#include "nsCSSPropAliasList.h" +#undef CSS_PROP_ALIAS + +#undef CSS_PROP_SHORTHAND +#undef CSS_PROP_LIST_EXCLUDE_INTERNAL +#undef CSS_PROP +#undef CSS_PROP_DOMPROP_PREFIXED + + virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName); + + virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, + bool *triedToWrap) + { + return mozilla::dom::CSS2PropertiesBinding::Wrap(cx, scope, this, + triedToWrap); + } + protected: // This method can return null regardless of the value of aAllocate; // however, a null return should only be considered a failure // if aAllocate is true. virtual mozilla::css::Declaration* GetCSSDeclaration(bool aAllocate) = 0; virtual nsresult SetCSSDeclaration(mozilla::css::Declaration* aDecl) = 0; // Document that we must call BeginUpdate/EndUpdate on around the // calls to SetCSSDeclaration and the style rule mutation that leads @@ -97,11 +144,15 @@ protected: bool aIsImportant); // Prop-id based version of RemoveProperty. Note that this does not // return the old value; it just does a straight removal. nsresult RemoveProperty(const nsCSSProperty aPropID); protected: virtual ~nsDOMCSSDeclaration(); + nsDOMCSSDeclaration() + { + SetIsDOMBinding(); + } }; #endif // nsDOMCSSDeclaration_h___
--- a/layout/style/nsICSSDeclaration.h +++ b/layout/style/nsICSSDeclaration.h @@ -17,51 +17,132 @@ * nsCSSProperty enums for the prop names instead of using strings. * This is meant for use in performance-sensitive code only! Most * consumers should continue to use nsIDOMCSSStyleDeclaration. */ #include "nsIDOMCSSStyleDeclaration.h" #include "nsCSSProperty.h" #include "nsWrapperCache.h" +#include "mozilla/dom/BindingUtils.h" +#include "nsString.h" +#include "nsIDOMCSSRule.h" +#include "nsIDOMCSSValue.h" +#include "mozilla/ErrorResult.h" -// 57eb81d1-a607-4429-926b-802519d43aad +// dbeabbfa-6cb3-4f5c-aec2-dd558d9d681f #define NS_ICSSDECLARATION_IID \ - { 0x57eb81d1, 0xa607, 0x4429, \ - {0x92, 0x6b, 0x80, 0x25, 0x19, 0xd4, 0x3a, 0xad } } +{ 0xdbeabbfa, 0x6cb3, 0x4f5c, \ + { 0xae, 0xc2, 0xdd, 0x55, 0x8d, 0x9d, 0x68, 0x1f } } class nsINode; class nsICSSDeclaration : public nsIDOMCSSStyleDeclaration, public nsWrapperCache { public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICSSDECLARATION_IID) /** * Method analogous to nsIDOMCSSStyleDeclaration::GetPropertyValue, * which obeys all the same restrictions. */ NS_IMETHOD GetPropertyValue(const nsCSSProperty aPropID, nsAString& aValue) = 0; - // Also have to declare the nsIDOMCSSStyleDeclaration method, so we - // don't hide it... very sad, but it stole the good method name - NS_IMETHOD GetPropertyValue(const nsAString& aPropName, - nsAString& aValue) = 0; - /** * Method analogous to nsIDOMCSSStyleDeclaration::SetProperty. This * method does NOT allow setting a priority (the priority will * always be set to default priority). */ NS_IMETHOD SetPropertyValue(const nsCSSProperty aPropID, const nsAString& aValue) = 0; virtual nsINode *GetParentObject() = 0; + + // Also have to declare all the nsIDOMCSSStyleDeclaration methods, + // since we want to be able to call them from the WebIDL versions. + NS_IMETHOD GetCssText(nsAString& aCssText) = 0; + NS_IMETHOD SetCssText(const nsAString& aCssText) = 0; + NS_IMETHOD GetPropertyValue(const nsAString& aPropName, + nsAString& aValue) = 0; + NS_IMETHOD GetPropertyCSSValue(const nsAString& aPropertyName, + nsIDOMCSSValue** aReturn) = 0; + NS_IMETHOD RemoveProperty(const nsAString& aPropertyName, + nsAString& aReturn) = 0; + NS_IMETHOD GetPropertyPriority(const nsAString& aPropertyName, + nsAString& aReturn) = 0; + NS_IMETHOD SetProperty(const nsAString& aPropertyName, + const nsAString& aValue, + const nsAString& aPriority) = 0; + NS_IMETHOD GetLength(uint32_t* aLength) = 0; + NS_IMETHOD Item(uint32_t aIndex, nsAString& aReturn) + { + bool found; + IndexedGetter(aIndex, found, aReturn); + if (!found) { + aReturn.Truncate(); + } + return NS_OK; + } + NS_IMETHOD GetParentRule(nsIDOMCSSRule * *aParentRule) = 0; + + // WebIDL interface for CSSStyleDeclaration + void SetCssText(const nsAString& aString, mozilla::ErrorResult& rv) { + rv = SetCssText(aString); + } + void GetCssText(nsString& aString) { + // Cast to nsAString& so we end up calling our virtual + // |GetCssText(nsAString& aCssText)| overload, which does the real work. + GetCssText(static_cast<nsAString&>(aString)); + } + uint32_t GetLength() { + uint32_t length; + GetLength(&length); + return length; + } + void Item(uint32_t aIndex, nsString& aPropName) { + Item(aIndex, static_cast<nsAString&>(aPropName)); + } + + // The actual implementation of the Item method and the WebIDL indexed getter + virtual void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName) = 0; + + void GetPropertyValue(const nsAString& aPropName, nsString& aValue, + mozilla::ErrorResult& rv) { + rv = GetPropertyValue(aPropName, aValue); + } + already_AddRefed<nsIDOMCSSValue> + GetPropertyCSSValue(const nsAString& aPropName, mozilla::ErrorResult& rv) { + nsCOMPtr<nsIDOMCSSValue> val; + rv = GetPropertyCSSValue(aPropName, getter_AddRefs(val)); + return val.forget(); + } + void GetPropertyPriority(const nsAString& aPropName, nsString& aPriority) { + GetPropertyPriority(aPropName, static_cast<nsAString&>(aPriority)); + } + // XXXbz we should nix the Optional thing once bug 759622 is fixed. + void SetProperty(const nsAString& aPropName, const nsAString& aValue, + const mozilla::dom::Optional<nsAString>& aPriority, + mozilla::ErrorResult& rv) { + if (aPriority.WasPassed()) { + rv = SetProperty(aPropName, aValue, aPriority.Value()); + } else { + rv = SetProperty(aPropName, aValue, EmptyString()); + } + } + void RemoveProperty(const nsAString& aPropName, nsString& aRetval, + mozilla::ErrorResult& rv) { + rv = RemoveProperty(aPropName, aRetval); + } + already_AddRefed<nsIDOMCSSRule> GetParentRule() { + nsCOMPtr<nsIDOMCSSRule> rule; + GetParentRule(getter_AddRefs(rule)); + return rule.forget(); + } }; NS_DEFINE_STATIC_IID_ACCESSOR(nsICSSDeclaration, NS_ICSSDECLARATION_IID) #define NS_DECL_NSICSSDECLARATION \ NS_IMETHOD GetPropertyValue(const nsCSSProperty aPropID, \ nsAString& aValue); \ NS_IMETHOD SetPropertyValue(const nsCSSProperty aPropID, \
--- a/layout/style/nsTransitionManager.cpp +++ b/layout/style/nsTransitionManager.cpp @@ -124,17 +124,17 @@ ElementTransitions::HasTransitionOfPrope return false; } bool ElementTransitions::CanPerformOnCompositorThread() const { if (mElementProperty != nsGkAtoms::transitionsProperty) { if (nsLayoutUtils::IsAnimationLoggingEnabled()) { - printf_stderr("Gecko bug: Async animation of pseudoelements not supported. See bug 771367\n"); + printf_stderr("Gecko bug: Async transition of pseudoelements not supported. See bug 771367\n"); } return false; } bool hasGeometricProperty = false; nsIFrame* frame = mElement->GetPrimaryFrame(); TimeStamp now = frame->PresContext()->RefreshDriver()->MostRecentRefresh(); for (uint32_t i = 0, i_end = mPropertyTransitions.Length(); i < i_end; ++i) {
--- a/media/omx-plugin/OmxPlugin.cpp +++ b/media/omx-plugin/OmxPlugin.cpp @@ -12,16 +12,17 @@ #else #include <stagefright/OMXClient.h> #endif #include "mozilla/Types.h" #include "MPAPI.h" #include "android/log.h" +#undef LOG #define LOG(args...) __android_log_print(ANDROID_LOG_INFO, "OmxPlugin" , ## args) using namespace MPAPI; namespace android { // MediaStreamSource is a DataSource that reads from a MPAPI media stream. @@ -243,31 +244,33 @@ bool OmxDecoder::Init() { sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource); if (extractor == NULL) { return false; } ssize_t audioTrackIndex = -1; ssize_t videoTrackIndex = -1; const char *audioMime = NULL; + const char *videoMime = NULL; for (size_t i = 0; i < extractor->countTracks(); ++i) { sp<MetaData> meta = extractor->getTrackMetaData(i); int32_t bitRate; if (!meta->findInt32(kKeyBitRate, &bitRate)) bitRate = 0; const char *mime; if (!meta->findCString(kKeyMIMEType, &mime)) { continue; } if (videoTrackIndex == -1 && !strncasecmp(mime, "video/", 6)) { videoTrackIndex = i; + videoMime = mime; } else if (audioTrackIndex == -1 && !strncasecmp(mime, "audio/", 6)) { audioTrackIndex = i; audioMime = mime; } } if (videoTrackIndex == -1 && audioTrackIndex == -1) { return false; @@ -297,20 +300,23 @@ bool OmxDecoder::Init() { if (videoTrackIndex != -1 && (videoTrack = extractor->getTrack(videoTrackIndex)) != NULL) { videoSource = OMXCodec::Create(omx, videoTrack->getFormat(), false, // decoder videoTrack, NULL, flags); if (videoSource == NULL) { + LOG("OMXCodec failed to initialize video decoder for \"%s\"", videoMime); return false; } - if (videoSource->start() != OK) { + status_t status = videoSource->start(); + if (status != OK) { + LOG("videoSource->start() failed with status %#x", status); return false; } int64_t durationUs; if (videoTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) { if (durationUs > totalDurationUs) totalDurationUs = durationUs; } @@ -323,20 +329,25 @@ bool OmxDecoder::Init() { if (!strcasecmp(audioMime, "audio/raw")) { audioSource = audioTrack; } else { audioSource = OMXCodec::Create(omx, audioTrack->getFormat(), false, // decoder audioTrack); } + if (audioSource == NULL) { + LOG("OMXCodec failed to initialize audio decoder for \"%s\"", audioMime); return false; } - if (audioSource->start() != OK) { + + status_t status = audioSource->start(); + if (status != OK) { + LOG("audioSource->start() failed with status %#x", status); return false; } int64_t durationUs; if (audioTrack->getFormat()->findInt64(kKeyDuration, &durationUs)) { if (durationUs > totalDurationUs) totalDurationUs = durationUs; } @@ -494,17 +505,17 @@ bool OmxDecoder::ToVideoFrame(VideoFrame break; case OMX_QCOM_COLOR_FormatYVU420SemiPlanar: SemiPlanarYVU420Frame(aFrame, aTimeUs, aData, aSize, aKeyFrame); break; case OMX_QCOM_COLOR_FormatYVU420PackedSemiPlanar32m4ka: SemiPlanarYVU420Packed32m4ka(aFrame, aTimeUs, aData, aSize, aKeyFrame); break; default: - LOG("Unknown video color format: %x", mVideoColorFormat); + LOG("Unknown video color format: %#x", mVideoColorFormat); return false; } return true; } bool OmxDecoder::ToAudioFrame(AudioFrame *aFrame, int64_t aTimeUs, void *aData, size_t aDataOffset, size_t aSize, int32_t aAudioChannels, int32_t aAudioSampleRate) { aFrame->Set(aTimeUs, reinterpret_cast<char *>(aData) + aDataOffset, aSize, aAudioChannels, aAudioSampleRate);
--- a/mobile/android/base/Favicons.java +++ b/mobile/android/base/Favicons.java @@ -264,17 +264,17 @@ public class Favicons { } // Runs in background thread private BitmapDrawable downloadFavicon(URL faviconUrl) { Log.d(LOGTAG, "Downloading favicon for URL = " + mPageUrl + " with favicon URL = " + mFaviconUrl); if (mFaviconUrl.startsWith("jar:jar:")) { - return GeckoJarReader.getBitmapDrawable(mFaviconUrl); + return GeckoJarReader.getBitmapDrawable(GeckoApp.mAppContext.getResources(), mFaviconUrl); } URI uri; try { uri = faviconUrl.toURI(); } catch (URISyntaxException e) { Log.d(LOGTAG, "Could not get URI for favicon URL: " + mFaviconUrl); return null;
--- a/mobile/android/base/GeckoInputConnection.java +++ b/mobile/android/base/GeckoInputConnection.java @@ -526,19 +526,19 @@ class GeckoInputConnection if (changedText.length() == 1) { char changedChar = changedText.charAt(0); // Some IMEs (e.g. SwiftKey X) send a string with '\n' when Enter is pressed // Such string cannot be handled by Gecko, so we convert it to a key press instead if (changedChar == '\n') { processKeyDown(KeyEvent.KEYCODE_ENTER, new KeyEvent(KeyEvent.ACTION_DOWN, - KeyEvent.KEYCODE_ENTER), false); + KeyEvent.KEYCODE_ENTER)); processKeyUp(KeyEvent.KEYCODE_ENTER, new KeyEvent(KeyEvent.ACTION_UP, - KeyEvent.KEYCODE_ENTER), false); + KeyEvent.KEYCODE_ENTER)); return; } // If we are committing a single character and didn't have an active composition string, // we can send Gecko keydown/keyup events instead of composition events. if (mCommittingText && !hasCompositionString() && sendKeyEventsToGecko(changedChar)) { // Block this thread until all pending events are processed GeckoAppShell.geckoEventSync(); @@ -850,33 +850,32 @@ class GeckoInputConnection resetCompositionState(); return this; } public boolean onKeyPreIme(int keyCode, KeyEvent event) { switch (event.getAction()) { case KeyEvent.ACTION_DOWN: - return processKeyDown(keyCode, event, true); + return processKeyDown(keyCode, event); case KeyEvent.ACTION_UP: - return processKeyUp(keyCode, event, true); + return processKeyUp(keyCode, event); case KeyEvent.ACTION_MULTIPLE: return onKeyMultiple(keyCode, event.getRepeatCount(), event); } return false; } public boolean onKeyDown(int keyCode, KeyEvent event) { - return processKeyDown(keyCode, event, false); + return processKeyDown(keyCode, event); } - private boolean processKeyDown(int keyCode, KeyEvent event, boolean isPreIme) { + private boolean processKeyDown(int keyCode, KeyEvent event) { if (DEBUG) { - Log.d(LOGTAG, "IME: processKeyDown(keyCode=" + keyCode + ", event=" + event + ", " - + isPreIme + ")"); + Log.d(LOGTAG, "IME: processKeyDown(keyCode=" + keyCode + ", event=" + event + ")"); GeckoApp.assertOnUiThread(); } if (keyCode > KeyEvent.getMaxKeyCode()) return false; switch (keyCode) { case KeyEvent.KEYCODE_MENU: @@ -895,21 +894,16 @@ class GeckoInputConnection if ((event.getFlags() & KeyEvent.FLAG_EDITOR_ACTION) != 0 && mIMEActionHint.equalsIgnoreCase("next")) event = new KeyEvent(event.getAction(), KeyEvent.KEYCODE_TAB); break; default: break; } - if (isPreIme && mIMEState != IME_STATE_DISABLED && - (event.getMetaState() & KeyEvent.META_ALT_ON) != 0) - // Let active IME process pre-IME key events - return false; - View view = getView(); KeyListener keyListener = TextKeyListener.getInstance(); // KeyListener returns true if it handled the event for us. if (mIMEState == IME_STATE_DISABLED || keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_DEL || keyCode == KeyEvent.KEYCODE_TAB || @@ -921,43 +915,37 @@ class GeckoInputConnection selection.start, selection.length)); GeckoAppShell.sendEventToGecko(GeckoEvent.createKeyEvent(event)); } return true; } public boolean onKeyUp(int keyCode, KeyEvent event) { - return processKeyUp(keyCode, event, false); + return processKeyUp(keyCode, event); } - private boolean processKeyUp(int keyCode, KeyEvent event, boolean isPreIme) { + private boolean processKeyUp(int keyCode, KeyEvent event) { if (DEBUG) { - Log.d(LOGTAG, "IME: processKeyUp(keyCode=" + keyCode + ", event=" + event + ", " - + isPreIme + ")"); + Log.d(LOGTAG, "IME: processKeyUp(keyCode=" + keyCode + ", event=" + event + ")"); GeckoApp.assertOnUiThread(); } if (keyCode > KeyEvent.getMaxKeyCode()) return false; switch (keyCode) { case KeyEvent.KEYCODE_BACK: case KeyEvent.KEYCODE_SEARCH: case KeyEvent.KEYCODE_MENU: return false; default: break; } - if (isPreIme && mIMEState != IME_STATE_DISABLED && - (event.getMetaState() & KeyEvent.META_ALT_ON) != 0) - // Let active IME process pre-IME key events - return false; - View view = getView(); KeyListener keyListener = TextKeyListener.getInstance(); if (mIMEState == IME_STATE_DISABLED || keyCode == KeyEvent.KEYCODE_ENTER || keyCode == KeyEvent.KEYCODE_DEL || (event.getFlags() & KeyEvent.FLAG_SOFT_KEYBOARD) != 0 || !keyListener.onKeyUp(view, mEditable, keyCode, event)) {
--- a/mobile/android/base/GeckoJarReader.java +++ b/mobile/android/base/GeckoJarReader.java @@ -1,14 +1,15 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.mozilla.gecko.util; +import android.content.res.Resources; import android.graphics.drawable.BitmapDrawable; import android.util.Log; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.EmptyStackException; @@ -20,28 +21,28 @@ import java.util.zip.ZipInputStream; /* Reads out of a multiple level deep jar file such as * jar:jar:file:///data/app/org.mozilla.fennec.apk!/omni.ja!/chrome/chrome/content/branding/favicon32.png */ public final class GeckoJarReader { private static String LOGTAG = "GeckoJarReader"; private GeckoJarReader() {} - public static BitmapDrawable getBitmapDrawable(String url) { + public static BitmapDrawable getBitmapDrawable(Resources resources, String url) { Stack<String> jarUrls = parseUrl(url); InputStream inputStream = null; BitmapDrawable bitmap = null; ZipFile zip = null; try { // Load the initial jar file as a zip zip = getZipFile(jarUrls.pop()); inputStream = getStream(zip, jarUrls); if (inputStream != null) { - bitmap = new BitmapDrawable(inputStream); + bitmap = new BitmapDrawable(resources, inputStream); } } catch (IOException ex) { Log.e(LOGTAG, "Exception ", ex); } finally { if (inputStream != null) { try { inputStream.close(); } catch(IOException ex) {
--- a/mobile/android/base/locales/en-US/android_strings.dtd +++ b/mobile/android/base/locales/en-US/android_strings.dtd @@ -172,23 +172,23 @@ size. --> <!ENTITY button_clear_data "Clear data"> <!ENTITY abouthome_addons_title "Add-ons for your &brandShortName;"> <!ENTITY abouthome_addons_browse "Browse all &brandShortName; add-ons"> <!ENTITY abouthome_last_tabs_title "Your tabs from last time"> <!ENTITY abouthome_last_tabs_open "Open all tabs from last time"> <!ENTITY abouthome_top_sites_title "Top sites"> <!ENTITY abouthome_top_sites_browse "Browse all your top sites"> -<!-- Localization note (abouthome_about_sync2, abouthome_about_apps): The +<!-- Localization note (abouthome_about_sync3, abouthome_about_apps2): The chevron (ex: "»"; unicode= U+00BB) is used as an arrow to show that clicking this text in the promotions box will perform some action. Note that a non-breaking space (unicode= U+00A0) should be used between this character and the remainder of the string to prevent word wrap. --> -<!ENTITY abouthome_about_sync2 "Set up Firefox Sync to access bookmarks, history and tabs from your other devices »"> -<!ENTITY abouthome_about_apps "Get apps from the Mozilla Marketplace and discover the best the Web has to offer »"> +<!ENTITY abouthome_about_sync3 "Set up Firefox Sync to access bookmarks, history and tabs from your other devices Â»"> +<!ENTITY abouthome_about_apps2 "Get apps from the Mozilla Marketplace and discover the best the Web has to offer Â»"> <!-- Localization note (abouthome_sync_bold_name, abouthome_apps_bold_name): These strings are accentuated as bold text in the "abouthome_about_..." strings above. These strings should be a subset of the strings above and generally be the name of the product the string describes. --> <!ENTITY abouthome_sync_bold_name "Firefox Sync"> <!ENTITY abouthome_apps_bold_name "Mozilla Marketplace"> <!ENTITY filepicker_title "Choose File">
--- a/mobile/android/base/strings.xml.in +++ b/mobile/android/base/strings.xml.in @@ -165,18 +165,18 @@ <string name="button_clear_data">&button_clear_data;</string> <string name="abouthome_addons_title">&abouthome_addons_title;</string> <string name="abouthome_addons_browse">&abouthome_addons_browse;</string> <string name="abouthome_last_tabs_title">&abouthome_last_tabs_title;</string> <string name="abouthome_last_tabs_open">&abouthome_last_tabs_open;</string> <string name="abouthome_top_sites_title">&abouthome_top_sites_title;</string> <string name="abouthome_top_sites_browse">&abouthome_top_sites_browse;</string> - <string name="abouthome_about_sync">&abouthome_about_sync2;</string> - <string name="abouthome_about_apps">&abouthome_about_apps;</string> + <string name="abouthome_about_sync">&abouthome_about_sync3;</string> + <string name="abouthome_about_apps">&abouthome_about_apps2;</string> <string name="abouthome_sync_bold_name">&abouthome_sync_bold_name;</string> <string name="abouthome_apps_bold_name">&abouthome_apps_bold_name;</string> <string name="filepicker_title">&filepicker_title;</string> <string name="filepicker_audio_title">&filepicker_audio_title;</string> <string name="filepicker_image_title">&filepicker_image_title;</string> <string name="filepicker_video_title">&filepicker_video_title;</string>
--- a/mobile/android/base/tests/testHistoryTab.java.in +++ b/mobile/android/base/tests/testHistoryTab.java.in @@ -29,16 +29,17 @@ import java.io.File; public class testHistoryTab extends PixelTest { private static final String ABOUT_HOME_URL = "about:home"; private static final String OPEN_NEW_TAB = "Open in New Tab"; private static final int WAIT_FOR_CHILD_TIMEOUT = 2000; private String[] bookmarks = new String[] { "http://mochi.test:8888/tests/robocop/robocop_blank_01.html" }; + private View mFirstChild; @Override protected int getTestType() { return TEST_MOCHITEST; } public void testHistoryTab() { mActions.expectGeckoEvent("Gecko:Ready").blockForEvent(); @@ -125,75 +126,86 @@ public class testHistoryTab extends Pixe mActions.sendSpecialKey(Actions.SpecialKey.BACK); mSolo.waitForText(url); View child = list.getChildAt(0); mSolo.clickLongOnView(child); mAsserter.is(false, mSolo.waitForText("Open in New Tab"), "Header rows should not show a context menu"); // wait for the history list to be populated - waitForTest(new BooleanTest() { + mFirstChild = null; + boolean success = waitForTest(new BooleanTest() { public boolean test() { - if (list.getChildAt(1) == null) { + mFirstChild = list.getChildAt(1); + if (mFirstChild == null) { return false; } - View firstChild = list.getChildAt(1); - if (firstChild instanceof android.view.ViewGroup) { - ViewGroup group = (ViewGroup)firstChild; + if (mFirstChild instanceof android.view.ViewGroup) { + ViewGroup group = (ViewGroup)mFirstChild; if (group.getChildCount() < 1) { return false; } for (int i = 0; i < group.getChildCount(); i++) { View grandChild = group.getChildAt(i); if (grandChild instanceof android.widget.TextView) { mAsserter.ok(true, "found TextView:", ((android.widget.TextView)grandChild).getText().toString()); } } + } else { + mAsserter.dumpLog("first child not a ViewGroup: "+mFirstChild); + return false; } return true; } }, WAIT_FOR_CHILD_TIMEOUT); - child = list.getChildAt(1); - - mSolo.clickLongOnView(child); + if (success == true && mFirstChild != null) { + mAsserter.dumpLog("clickLongOnView: "+mFirstChild); + mSolo.clickLongOnView(mFirstChild); - // TODO: Test clicking these does the right thing - mAsserter.ok(mSolo.waitForText("Open in New Tab"), "Context menu has New Tab option", "Open in New Tab"); - mAsserter.ok(mSolo.searchText("Share", true), "Context menu has Share option", "Share"); - mAsserter.ok(mSolo.searchText("Remove", true), "Context menu has Remove option", "Remove"); - mAsserter.ok(mSolo.searchText("Add to Home Screen", true), "Context menu has Add to Home Screen option", "Add to Home Screen"); + // TODO: Test clicking these does the right thing + mAsserter.ok(mSolo.waitForText("Open in New Tab"), "Context menu has New Tab option", "Open in New Tab"); + mAsserter.ok(mSolo.searchText("Share", true), "Context menu has Share option", "Share"); + mAsserter.ok(mSolo.searchText("Remove", true), "Context menu has Remove option", "Remove"); + mAsserter.ok(mSolo.searchText("Add to Home Screen", true), "Context menu has Add to Home Screen option", "Add to Home Screen"); - mActions.sendSpecialKey(Actions.SpecialKey.BACK); + mActions.sendSpecialKey(Actions.SpecialKey.BACK); + } else { + mAsserter.ok(false, "waiting for history item", "history item available"); + } mActions.sendSpecialKey(Actions.SpecialKey.BACK); } private void testClick(String url) { list = getHistoryList(); // clear VKB mActions.sendSpecialKey(Actions.SpecialKey.BACK); mSolo.waitForText(url); View child = list.getChildAt(0); mSolo.clickOnView(child); // nothing should happen Actions.EventExpecter contentEventExpecter = mActions.expectGeckoEvent("DOMContentLoaded"); - waitForTest(new BooleanTest() { + mFirstChild = null; + boolean success = waitForTest(new BooleanTest() { public boolean test() { - if (list.getChildAt(1) == null) { + mFirstChild = list.getChildAt(1); + if (mFirstChild == null) { return false; } return true; } }, WAIT_FOR_CHILD_TIMEOUT); - child = list.getChildAt(1); - - mSolo.clickOnView(child); - contentEventExpecter.blockForEvent(); - verifyUrl(url); + if (success == true && mFirstChild != null) { + mSolo.clickOnView(mFirstChild); + contentEventExpecter.blockForEvent(); + verifyUrl(url); + } else { + mAsserter.ok(false, "waiting for history item", "history item available"); + } } private ListView getHistoryList() { Activity awesomeBarActivity = clickOnAwesomeBar(); mSolo.clickOnText("History"); TabHost tabHost = (TabHost)mSolo.getView(TabHost.class, 0); return (ListView)tabHost.getCurrentView();
--- a/toolkit/components/social/MozSocialAPI.jsm +++ b/toolkit/components/social/MozSocialAPI.jsm @@ -8,25 +8,32 @@ Cu.import("resource://gre/modules/Servic Cu.import("resource://gre/modules/XPCOMUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "SocialService", "resource://gre/modules/SocialService.jsm"); const EXPORTED_SYMBOLS = ["MozSocialAPI"]; var MozSocialAPI = { _enabled: false, + _everEnabled: false, set enabled(val) { let enable = !!val; if (enable == this._enabled) { return; } this._enabled = enable; if (enable) { Services.obs.addObserver(injectController, "document-element-inserted", false); + + if (!this._everEnabled) { + this._everEnabled = true; + Services.telemetry.getHistogramById("SOCIAL_ENABLED_ON_SESSION").add(true); + } + } else { Services.obs.removeObserver(injectController, "document-element-inserted", false); } } }; // Called on document-element-inserted, checks that the API should be injected, // and then calls attachToWindow as appropriate @@ -107,16 +114,31 @@ function attachToWindow(provider, target enumerable: true, configurable: true, writable: true, value: function(toURL, callback) { let url = targetWindow.document.documentURIObject.resolve(toURL); openChatWindow(getChromeWindow(targetWindow), provider, url, callback); } }, + openPanel: { + enumerable: true, + configurable: true, + writable: true, + value: function(toURL, offset, callback) { + let chromeWindow = getChromeWindow(targetWindow); + if (!chromeWindow.SocialFlyout) + return; + let url = targetWindow.document.documentURIObject.resolve(toURL); + let fullURL = ensureProviderOrigin(provider, url); + if (!fullURL) + return; + chromeWindow.SocialFlyout.open(fullURL, offset, callback); + } + }, getAttention: { enumerable: true, configurable: true, writable: true, value: function() { getChromeWindow(targetWindow).getAttention(); } }, @@ -214,16 +236,19 @@ function openServiceWindow(provider, con // Get the newly opened window's containing XUL window chromeWindow = getChromeWindow(serviceWindow); // set the window's name and origin attribute on its browser, so that it can // be found via getWindowByName chromeWindow.name = windowName; chromeWindow.gBrowser.selectedBrowser.setAttribute("origin", provider.origin); + // disable global history for the new window. + chromeWindow.gBrowser.docShell.QueryInterface(Components.interfaces.nsIDocShellHistory).useGlobalHistory = false; + // we dont want the default title the browser produces, we'll fixup whenever // it changes. serviceWindow.addEventListener("DOMTitleChanged", function() { let sep = xulWindow.document.documentElement.getAttribute("titlemenuseparator"); xulWindow.document.title = provider.name + sep + serviceWindow.document.title; }); return serviceWindow;
--- a/toolkit/components/social/SocialService.jsm +++ b/toolkit/components/social/SocialService.jsm @@ -92,16 +92,17 @@ const SocialService = { Services.prefs.setBoolPref("social.enabled", enable); this._setEnabled(enable); }, _setEnabled: function _setEnabled(enable) { SocialServiceInternal.providerArray.forEach(function (p) p.enabled = enable); SocialServiceInternal.enabled = enable; MozSocialAPI.enabled = enable; Services.obs.notifyObservers(null, "social:pref-changed", enable ? "enabled" : "disabled"); + Services.telemetry.getHistogramById("SOCIAL_TOGGLED").add(enable); }, // Adds a provider given a manifest, and returns the added provider. addProvider: function addProvider(manifest, onDone) { if (SocialServiceInternal.providers[manifest.origin]) throw new Error("SocialService.addProvider: provider with this origin already exists"); let provider = new SocialProvider(manifest, SocialServiceInternal.enabled);
--- a/toolkit/components/telemetry/Histograms.json +++ b/toolkit/components/telemetry/Histograms.json @@ -2189,10 +2189,18 @@ "kind": "flag", "description": "Killed due to an OOM condition", "cpp_guard": "ANDROID" }, "SECURITY_UI": { "kind": "enumerated", "n_values": 100, "description": "Security UI Telemetry" + }, + "SOCIAL_ENABLED_ON_SESSION": { + "kind": "flag", + "description": "Social has been enabled at least once on the current session" + }, + "SOCIAL_TOGGLED": { + "kind": "boolean", + "description": "Social has been toggled to on or off" } }
--- a/toolkit/mozapps/installer/packager.mk +++ b/toolkit/mozapps/installer/packager.mk @@ -713,17 +713,16 @@ else PKGCP_OS = unix endif # The following target stages files into two directories: one directory for # core files, and one for optional extensions based on the information in # the MOZ_PKG_MANIFEST file and the following vars: # MOZ_NONLOCALIZED_PKG_LIST # MOZ_LOCALIZED_PKG_LIST -# MOZ_OPTIONAL_PKG_LIST PKG_ARG = , "$(pkg)" # Define packager macro to work around make 3.81 backslash issue (bug #339933) # Controls whether missing file warnings should be fatal ifndef MOZ_PKG_FATAL_WARNINGS MOZ_PKG_FATAL_WARNINGS = 0 @@ -744,29 +743,16 @@ endif ifdef MOZ_OMNIJAR @(cd $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH) && $(PACK_OMNIJAR)) ifdef MOZ_WEBAPP_RUNTIME @(cd $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/webapprt && $(PACK_OMNIJAR_WEBAPP_RUNTIME)) endif endif @cp -av $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/. $(DEPTH)/installer-stage/core @(cd $(DEPTH)/installer-stage/core && $(CREATE_PRECOMPLETE_CMD)) -ifdef MOZ_OPTIONAL_PKG_LIST - @$(NSINSTALL) -D $(DEPTH)/installer-stage/optional - $(call PACKAGER_COPY, "$(call core_abspath,$(DIST))",\ - "$(call core_abspath,$(DEPTH)/installer-stage/optional)", \ - "$(MOZ_PKG_MANIFEST)", "$(PKGCP_OS)", 1, 0, 1 \ - $(foreach pkg,$(MOZ_OPTIONAL_PKG_LIST),$(PKG_ARG)) ) - if test -d $(DEPTH)/installer-stage/optional/extensions ; then \ - cd $(DEPTH)/installer-stage/optional/extensions; find -maxdepth 1 -mindepth 1 -exec rm -r ../../core/extensions/{} \; ; \ - fi - if test -d $(DEPTH)/installer-stage/optional/distribution/extensions/ ; then \ - cd $(DEPTH)/installer-stage/optional/distribution/extensions/; find -maxdepth 1 -mindepth 1 -exec rm -r ../../../core/distribution/extensions/{} \; ; \ - fi -endif ifdef MOZ_SIGN_PREPARED_PACKAGE_CMD $(MOZ_SIGN_PREPARED_PACKAGE_CMD) $(DEPTH)/installer-stage endif elfhack: ifdef USE_ELF_HACK @echo === @echo === If you get failures below, please file a bug describing the error
--- a/toolkit/system/gnome/Makefile.in +++ b/toolkit/system/gnome/Makefile.in @@ -10,18 +10,22 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk MODULE = mozgnome LIBRARY_NAME = mozgnome FORCE_SHARED_LIB = 1 IS_COMPONENT = 1 -CPPSRCS = nsGnomeModule.cpp - +CPPSRCS = \ + nsGnomeModule.cpp \ + nsAlertsService.cpp \ + nsAlertsIconListener.cpp \ + $(NULL) + ifdef MOZ_ENABLE_GCONF CPPSRCS += \ nsGConfService.cpp \ $(NULL) endif ifdef MOZ_ENABLE_GNOMEVFS CPPSRCS += \ @@ -31,38 +35,29 @@ endif ifdef MOZ_ENABLE_GIO CPPSRCS += \ nsGIOService.cpp \ nsGSettingsService.cpp \ $(NULL) endif -ifdef MOZ_ENABLE_LIBNOTIFY -CPPSRCS += \ - nsAlertsService.cpp \ - nsAlertsIconListener.cpp \ - $(NULL) -endif - EXTRA_DSO_LDOPTS += \ $(XPCOM_GLUE_LDOPTS) \ $(XPCOM_FROZEN_LDOPTS) \ $(NSPR_LIBS) \ $(MOZ_GCONF_LIBS) \ $(MOZ_GNOMEVFS_LIBS) \ $(GLIB_LIBS) \ - $(MOZ_LIBNOTIFY_LIBS) \ $(MOZ_GIO_LIBS) \ $(NULL) LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/components/build/ include $(topsrcdir)/config/rules.mk CXXFLAGS += \ $(MOZ_GCONF_CFLAGS) \ $(MOZ_GNOMEVFS_CFLAGS) \ $(MOZ_GIO_CFLAGS) \ $(GLIB_CFLAGS) \ - $(MOZ_LIBNOTIFY_CFLAGS) \ $(MOZ_GTK2_CFLAGS) \ $(NULL)
--- a/toolkit/system/gnome/nsAlertsIconListener.cpp +++ b/toolkit/system/gnome/nsAlertsIconListener.cpp @@ -8,26 +8,32 @@ #include "imgILoader.h" #include "imgIRequest.h" #include "nsNetUtil.h" #include "nsIImageToPixbuf.h" #include "nsIStringBundle.h" #include "nsIObserverService.h" #include "nsCRT.h" +#include <dlfcn.h> #include <gdk/gdk.h> -// Compatibility macro for <libnotify-0.7 -#ifndef NOTIFY_CHECK_VERSION -#define NOTIFY_CHECK_VERSION(x,y,z) 0 -#endif - static bool gHasActions = false; static bool gHasCaps = false; +void* nsAlertsIconListener::libNotifyHandle = nullptr; +bool nsAlertsIconListener::libNotifyNotAvail = false; +nsAlertsIconListener::notify_is_initted_t nsAlertsIconListener::notify_is_initted = nullptr; +nsAlertsIconListener::notify_init_t nsAlertsIconListener::notify_init = nullptr; +nsAlertsIconListener::notify_get_server_caps_t nsAlertsIconListener::notify_get_server_caps = nullptr; +nsAlertsIconListener::notify_notification_new_t nsAlertsIconListener::notify_notification_new = nullptr; +nsAlertsIconListener::notify_notification_show_t nsAlertsIconListener::notify_notification_show = nullptr; +nsAlertsIconListener::notify_notification_set_icon_from_pixbuf_t nsAlertsIconListener::notify_notification_set_icon_from_pixbuf = nullptr; +nsAlertsIconListener::notify_notification_add_action_t nsAlertsIconListener::notify_notification_add_action = nullptr; + static void notify_action_cb(NotifyNotification *notification, gchar *action, gpointer user_data) { nsAlertsIconListener* alert = static_cast<nsAlertsIconListener*> (user_data); alert->SendCallback(); } static void notify_closed_marshal(GClosure* closure, @@ -47,22 +53,45 @@ static void notify_closed_marshal(GClosu NS_IMPL_ISUPPORTS4(nsAlertsIconListener, imgIContainerObserver, imgIDecoderObserver, nsIObserver, nsISupportsWeakReference) nsAlertsIconListener::nsAlertsIconListener() : mLoadedFrame(false), mNotification(NULL) { + if (!libNotifyHandle && !libNotifyNotAvail) { + libNotifyHandle = dlopen("libnotify.so.4", RTLD_LAZY); + if (!libNotifyHandle) { + libNotifyHandle = dlopen("libnotify.so.1", RTLD_LAZY); + if (!libNotifyHandle) { + libNotifyNotAvail = true; + return; + } + } + + notify_is_initted = (notify_is_initted_t)dlsym(libNotifyHandle, "notify_is_initted"); + notify_init = (notify_init_t)dlsym(libNotifyHandle, "notify_init"); + notify_get_server_caps = (notify_get_server_caps_t)dlsym(libNotifyHandle, "notify_get_server_caps"); + notify_notification_new = (notify_notification_new_t)dlsym(libNotifyHandle, "notify_notification_new"); + notify_notification_show = (notify_notification_show_t)dlsym(libNotifyHandle, "notify_notification_show"); + notify_notification_set_icon_from_pixbuf = (notify_notification_set_icon_from_pixbuf_t)dlsym(libNotifyHandle, "notify_notification_set_icon_from_pixbuf"); + notify_notification_add_action = (notify_notification_add_action_t)dlsym(libNotifyHandle, "notify_notification_add_action"); + if (!notify_is_initted || !notify_init || !notify_get_server_caps || !notify_notification_new || !notify_notification_show || !notify_notification_set_icon_from_pixbuf || !notify_notification_add_action) { + dlclose(libNotifyHandle); + libNotifyHandle = nullptr; + } + } } nsAlertsIconListener::~nsAlertsIconListener() { if (mIconRequest) mIconRequest->CancelAndForgetObserver(NS_BINDING_ABORTED); + // Don't dlclose libnotify as it uses atexit(). } NS_IMETHODIMP nsAlertsIconListener::OnStartRequest(imgIRequest* aRequest) { return NS_OK; } @@ -180,24 +209,17 @@ nsAlertsIconListener::OnStopFrame(imgIRe mLoadedFrame = true; return NS_OK; } nsresult nsAlertsIconListener::ShowAlert(GdkPixbuf* aPixbuf) { - mNotification = notify_notification_new(mAlertTitle.get(), - mAlertText.get(), - NULL -// >=libnotify-0.7.0 has no support for attaching to widgets -#if !NOTIFY_CHECK_VERSION(0,7,0) - , NULL -#endif - ); + mNotification = notify_notification_new(mAlertTitle.get(), mAlertText.get(), NULL, NULL); if (!mNotification) return NS_ERROR_OUT_OF_MEMORY; if (aPixbuf) notify_notification_set_icon_from_pixbuf(mNotification, aPixbuf); NS_ADDREF(this); @@ -279,16 +301,19 @@ nsAlertsIconListener::Observe(nsISupport nsresult nsAlertsIconListener::InitAlertAsync(const nsAString & aImageUrl, const nsAString & aAlertTitle, const nsAString & aAlertText, bool aAlertTextClickable, const nsAString & aAlertCookie, nsIObserver * aAlertListener) { + if (!libNotifyHandle) + return NS_ERROR_FAILURE; + if (!notify_is_initted()) { // Give the name of this application to libnotify nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID); nsCAutoString appShortName; if (bundleService) { nsCOMPtr<nsIStringBundle> bundle;
--- a/toolkit/system/gnome/nsAlertsIconListener.h +++ b/toolkit/system/gnome/nsAlertsIconListener.h @@ -8,20 +8,21 @@ #include "nsCOMPtr.h" #include "imgIDecoderObserver.h" #include "nsStringAPI.h" #include "nsIObserver.h" #include "nsWeakReference.h" #include <gdk-pixbuf/gdk-pixbuf.h> -#include <libnotify/notify.h> class imgIRequest; +struct NotifyNotification; + class nsAlertsIconListener : public imgIDecoderObserver, public nsIObserver, public nsSupportsWeakReference { public: NS_DECL_ISUPPORTS NS_DECL_IMGICONTAINEROBSERVER NS_DECL_IMGIDECODEROBSERVER @@ -36,26 +37,50 @@ public: bool aAlertTextClickable, const nsAString & aAlertCookie, nsIObserver * aAlertListener); void SendCallback(); void SendClosed(); protected: + /** + * The only difference between libnotify.so.4 and libnotify.so.1 for these symbols + * is that notify_notification_new takes three arguments in libnotify.so.4 and + * four in libnotify.so.1. + * Passing the fourth argument as NULL is binary compatible. + */ + typedef void (*NotifyActionCallback)(NotifyNotification*, char*, gpointer); + typedef bool (*notify_is_initted_t)(void); + typedef bool (*notify_init_t)(const char*); + typedef GList* (*notify_get_server_caps_t)(void); + typedef NotifyNotification* (*notify_notification_new_t)(const char*, const char*, const char*, const char*); + typedef bool (*notify_notification_show_t)(void*, char*); + typedef void (*notify_notification_set_icon_from_pixbuf_t)(void*, GdkPixbuf*); + typedef void (*notify_notification_add_action_t)(void*, const char*, const char*, NotifyActionCallback, gpointer, GFreeFunc); + nsCOMPtr<imgIRequest> mIconRequest; nsCString mAlertTitle; nsCString mAlertText; nsCOMPtr<nsIObserver> mAlertListener; nsString mAlertCookie; bool mLoadedFrame; bool mAlertHasAction; + static void* libNotifyHandle; + static bool libNotifyNotAvail; + static notify_is_initted_t notify_is_initted; + static notify_init_t notify_init; + static notify_get_server_caps_t notify_get_server_caps; + static notify_notification_new_t notify_notification_new; + static notify_notification_show_t notify_notification_show; + static notify_notification_set_icon_from_pixbuf_t notify_notification_set_icon_from_pixbuf; + static notify_notification_add_action_t notify_notification_add_action; NotifyNotification* mNotification; gulong mClosureHandler; nsresult StartRequest(const nsAString & aImageUrl); nsresult ShowAlert(GdkPixbuf* aPixbuf); }; #endif
--- a/toolkit/system/gnome/nsGnomeModule.cpp +++ b/toolkit/system/gnome/nsGnomeModule.cpp @@ -17,67 +17,59 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGC NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGnomeVFSService, Init) #endif #ifdef MOZ_ENABLE_GIO #include "nsGIOService.h" #include "nsGSettingsService.h" NS_GENERIC_FACTORY_CONSTRUCTOR(nsGIOService) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGSettingsService, Init) #endif -#ifdef MOZ_ENABLE_LIBNOTIFY #include "nsAlertsService.h" NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsAlertsService, Init) -#endif #ifdef MOZ_ENABLE_GCONF NS_DEFINE_NAMED_CID(NS_GCONFSERVICE_CID); #endif #ifdef MOZ_ENABLE_GNOMEVFS NS_DEFINE_NAMED_CID(NS_GNOMEVFSSERVICE_CID); #endif #ifdef MOZ_ENABLE_GIO NS_DEFINE_NAMED_CID(NS_GIOSERVICE_CID); NS_DEFINE_NAMED_CID(NS_GSETTINGSSERVICE_CID); #endif -#ifdef MOZ_ENABLE_LIBNOTIFY NS_DEFINE_NAMED_CID(NS_SYSTEMALERTSSERVICE_CID); -#endif static const mozilla::Module::CIDEntry kGnomeCIDs[] = { #ifdef MOZ_ENABLE_GCONF { &kNS_GCONFSERVICE_CID, false, NULL, nsGConfServiceConstructor }, #endif #ifdef MOZ_ENABLE_GNOMEVFS { &kNS_GNOMEVFSSERVICE_CID, false, NULL, nsGnomeVFSServiceConstructor }, #endif #ifdef MOZ_ENABLE_GIO { &kNS_GIOSERVICE_CID, false, NULL, nsGIOServiceConstructor }, { &kNS_GSETTINGSSERVICE_CID, false, NULL, nsGSettingsServiceConstructor }, #endif -#ifdef MOZ_ENABLE_LIBNOTIFY { &kNS_SYSTEMALERTSSERVICE_CID, false, NULL, nsAlertsServiceConstructor }, -#endif { NULL } }; static const mozilla::Module::ContractIDEntry kGnomeContracts[] = { #ifdef MOZ_ENABLE_GCONF { NS_GCONFSERVICE_CONTRACTID, &kNS_GCONFSERVICE_CID }, #endif #ifdef MOZ_ENABLE_GNOMEVFS { NS_GNOMEVFSSERVICE_CONTRACTID, &kNS_GNOMEVFSSERVICE_CID }, #endif #ifdef MOZ_ENABLE_GIO { NS_GIOSERVICE_CONTRACTID, &kNS_GIOSERVICE_CID }, { NS_GSETTINGSSERVICE_CONTRACTID, &kNS_GSETTINGSSERVICE_CID }, #endif -#ifdef MOZ_ENABLE_LIBNOTIFY { NS_SYSTEMALERTSERVICE_CONTRACTID, &kNS_SYSTEMALERTSSERVICE_CID }, -#endif { NULL } }; static nsresult InitGType () { g_type_init(); return NS_OK;