diff --git a/b2g/config/dolphin/sources.xml b/b2g/config/dolphin/sources.xml index b9d2bf969ef..cdb0d05b10e 100644 --- a/b2g/config/dolphin/sources.xml +++ b/b2g/config/dolphin/sources.xml @@ -15,7 +15,7 @@ - + @@ -35,7 +35,7 @@ - + diff --git a/b2g/config/emulator-ics/sources.xml b/b2g/config/emulator-ics/sources.xml index d9197012c57..a1578fd8057 100644 --- a/b2g/config/emulator-ics/sources.xml +++ b/b2g/config/emulator-ics/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/emulator-jb/sources.xml b/b2g/config/emulator-jb/sources.xml index 9a6c7d319bf..a6ed0c2d65b 100644 --- a/b2g/config/emulator-jb/sources.xml +++ b/b2g/config/emulator-jb/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/emulator-kk/sources.xml b/b2g/config/emulator-kk/sources.xml index 84684c1215e..62c6e52f559 100644 --- a/b2g/config/emulator-kk/sources.xml +++ b/b2g/config/emulator-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/emulator/sources.xml b/b2g/config/emulator/sources.xml index d9197012c57..a1578fd8057 100644 --- a/b2g/config/emulator/sources.xml +++ b/b2g/config/emulator/sources.xml @@ -19,7 +19,7 @@ - + diff --git a/b2g/config/flame-kk/sources.xml b/b2g/config/flame-kk/sources.xml index d55ce8f7482..b88fef48a4c 100644 --- a/b2g/config/flame-kk/sources.xml +++ b/b2g/config/flame-kk/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/flame/sources.xml b/b2g/config/flame/sources.xml index 52ca484c87a..c54a0fefbb6 100644 --- a/b2g/config/flame/sources.xml +++ b/b2g/config/flame/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/gaia.json b/b2g/config/gaia.json index 9664093845c..6744f75759e 100644 --- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -4,6 +4,6 @@ "remote": "", "branch": "" }, - "revision": "934b8c3014a3e20dd5d90ecf95f4b6b704dddb1e", + "revision": "f486771c1a2a76bfea1a5c7eac8debe14f29927b", "repo_path": "/integration/gaia-central" } diff --git a/b2g/config/hamachi/sources.xml b/b2g/config/hamachi/sources.xml index 423b426b54a..cb720acafca 100644 --- a/b2g/config/hamachi/sources.xml +++ b/b2g/config/hamachi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/helix/sources.xml b/b2g/config/helix/sources.xml index 6eb79edcafc..5ef8f9b4670 100644 --- a/b2g/config/helix/sources.xml +++ b/b2g/config/helix/sources.xml @@ -15,7 +15,7 @@ - + diff --git a/b2g/config/nexus-4/sources.xml b/b2g/config/nexus-4/sources.xml index ae02f80fd64..31869b9766a 100644 --- a/b2g/config/nexus-4/sources.xml +++ b/b2g/config/nexus-4/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/b2g/config/wasabi/sources.xml b/b2g/config/wasabi/sources.xml index 70ac3ec4113..34b5b4c036b 100644 --- a/b2g/config/wasabi/sources.xml +++ b/b2g/config/wasabi/sources.xml @@ -17,7 +17,7 @@ - + diff --git a/browser/app/blocklist.xml b/browser/app/blocklist.xml index 7f0e74f5032..ab63950d319 100644 --- a/browser/app/blocklist.xml +++ b/browser/app/blocklist.xml @@ -1,5 +1,5 @@ - + @@ -27,8 +27,8 @@ - - + + @@ -84,7 +84,7 @@ - + @@ -96,10 +96,12 @@ - - + + + browser.startup.homepage + browser.search.defaultenginename @@ -108,8 +110,8 @@ - - + + @@ -294,6 +296,12 @@ + + + + + + @@ -354,7 +362,19 @@ - + + + + + + + + + + + + + @@ -409,6 +429,12 @@ + + + + + + @@ -443,8 +469,8 @@ - - + + @@ -520,6 +546,18 @@ + + + + + + + + + + + + @@ -580,6 +618,12 @@ + + + + + + @@ -592,6 +636,14 @@ + + + + + + browser.startup.homepage + browser.search.defaultenginename + @@ -743,8 +795,12 @@ - - + + + + + + @@ -767,8 +823,8 @@ - - + + @@ -851,10 +907,12 @@ - + + browser.startup.homepage + browser.search.defaultenginename @@ -919,8 +977,10 @@ - - + + + + @@ -987,6 +1047,13 @@ + + + + + + browser.startup.homepage + @@ -1000,7 +1067,7 @@ - + @@ -1194,7 +1261,7 @@ - + @@ -1205,6 +1272,12 @@ + + + + + + @@ -1235,6 +1308,13 @@ + + + + + + browser.startup.homepage + @@ -1278,8 +1358,8 @@ - - + + @@ -1539,6 +1619,12 @@ + + + + + + @@ -1557,6 +1643,12 @@ + + + + + + @@ -1575,6 +1667,12 @@ + + + + + + @@ -1624,8 +1722,8 @@ - - + + @@ -1705,6 +1803,12 @@ + + + + + + @@ -1768,8 +1872,8 @@ - - + + @@ -1779,6 +1883,12 @@ + + + + + + @@ -1805,6 +1915,12 @@ + + + + + + @@ -1824,7 +1940,7 @@ - + @@ -1943,6 +2059,12 @@ + + + + + + @@ -2013,6 +2135,12 @@ + + + + + + diff --git a/browser/base/content/browser-context.inc b/browser/base/content/browser-context.inc index e8a58892b3b..44fb0cf3ef0 100644 --- a/browser/base/content/browser-context.inc +++ b/browser/base/content/browser-context.inc @@ -240,6 +240,11 @@ label="&emailVideoCmd.label;" accesskey="&emailVideoCmd.accesskey;" oncommand="gContextMenu.sendMedia();"/> + + + 0 && + CastingApps.getServicesForVideo(this.target).length > 0; + this.setItemAttr("context-castvideo", "disabled", !shouldShowCast); }, initViewItems: function CM_initViewItems() { @@ -1316,6 +1326,25 @@ nsContextMenu.prototype = { MailIntegration.sendMessage(this.mediaURL, ""); }, + castVideo: function() { + CastingApps.openExternal(this.target, window); + }, + + populateCastVideoMenu: function(popup) { + let videoEl = this.target; + popup.innerHTML = null; + let doc = popup.ownerDocument; + let services = CastingApps.getServicesForVideo(videoEl); + services.forEach(service => { + let item = doc.createElement("menuitem"); + item.setAttribute("label", service.friendlyName); + item.addEventListener("command", event => { + CastingApps.sendVideoToService(videoEl, service); + }); + popup.appendChild(item); + }); + }, + playPlugin: function() { gPluginHandler.contextMenuCommand(this.browser, this.target, "play"); }, diff --git a/browser/base/content/socialchat.xml b/browser/base/content/socialchat.xml index 9979da1901f..63808225ab4 100644 --- a/browser/base/content/socialchat.xml +++ b/browser/base/content/socialchat.xml @@ -707,7 +707,7 @@ canvas.mozOpaque = true; canvas.width = 160 * scale; canvas.height = 90 * scale; - PageThumbs.captureToCanvas(chatbox.contentWindow, canvas); + PageThumbs.captureToCanvas(chatbox, canvas); dt.setDragImage(canvas, -16 * scale, -16 * scale); event.stopPropagation(); diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index f48e358dea7..0b07f56874e 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -4530,7 +4530,7 @@ canvas.height = 90 * scale; if (!gMultiProcessBrowser) { // Bug 863512 - Make page thumbnails work in e10s - PageThumbs.captureToCanvas(browser.contentWindow, canvas); + PageThumbs.captureToCanvas(browser, canvas); } dt.setDragImage(canvas, -16 * scale, -16 * scale); diff --git a/browser/base/content/test/general/test_contextmenu.html b/browser/base/content/test/general/test_contextmenu.html index 20c86b4534a..edb7c705d50 100644 --- a/browser/base/content/test/general/test_contextmenu.html +++ b/browser/base/content/test/general/test_contextmenu.html @@ -174,7 +174,9 @@ function runTest(testNum) { "---", null, "context-savevideo", true, "context-video-saveimage", true, - "context-sendvideo", true + "context-sendvideo", true, + "context-castvideo", null, + [], null ].concat(inspectItems)); closeContextMenu(); openContextMenuFor(audio_in_video); // Invoke context menu for next test. @@ -218,7 +220,9 @@ function runTest(testNum) { "---", null, "context-savevideo", true, "context-video-saveimage", false, - "context-sendvideo", true + "context-sendvideo", true, + "context-castvideo", null, + [], null ].concat(inspectItems)); closeContextMenu(); openContextMenuFor(video_bad2); // Invoke context menu for next test. @@ -242,7 +246,9 @@ function runTest(testNum) { "---", null, "context-savevideo", false, "context-video-saveimage", false, - "context-sendvideo", false + "context-sendvideo", false, + "context-castvideo", null, + [], null ].concat(inspectItems)); closeContextMenu(); openContextMenuFor(iframe); // Invoke context menu for next test. @@ -301,6 +307,8 @@ function runTest(testNum) { "context-savevideo", true, "context-video-saveimage", true, "context-sendvideo", true, + "context-castvideo", null, + [], null, "frame", null, ["context-showonlythisframe", true, "context-openframeintab", true, diff --git a/browser/components/customizableui/CustomizableWidgets.jsm b/browser/components/customizableui/CustomizableWidgets.jsm index f86a42e42dc..08e2f15508b 100644 --- a/browser/components/customizableui/CustomizableWidgets.jsm +++ b/browser/components/customizableui/CustomizableWidgets.jsm @@ -924,7 +924,7 @@ const CustomizableWidgets = [ id: "loop-call-button", type: "custom", label: "loop-call-button3.label", - tooltiptext: "loop-call-button2.tooltiptext", + tooltiptext: "loop-call-button3.tooltiptext", defaultArea: CustomizableUI.AREA_NAVBAR, introducedInVersion: 1, onBuild: function(aDocument) { diff --git a/browser/components/nsBrowserGlue.js b/browser/components/nsBrowserGlue.js index abd2504a910..d54260737b8 100644 --- a/browser/components/nsBrowserGlue.js +++ b/browser/components/nsBrowserGlue.js @@ -99,6 +99,9 @@ XPCOMUtils.defineLazyModuleGetter(this, "AsyncShutdown", XPCOMUtils.defineLazyModuleGetter(this, "LoginManagerParent", "resource://gre/modules/LoginManagerParent.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "SimpleServiceDiscovery", + "resource://gre/modules/SimpleServiceDiscovery.jsm"); + #ifdef NIGHTLY_BUILD XPCOMUtils.defineLazyModuleGetter(this, "SignInToWebsiteUX", "resource:///modules/SignInToWebsite.jsm"); @@ -747,8 +750,30 @@ BrowserGlue.prototype = { FormValidationHandler.uninit(); }, + _initServiceDiscovery: function () { + var rokuDevice = { + id: "roku:ecp", + target: "roku:ecp", + factory: function(aService) { + Cu.import("resource://gre/modules/RokuApp.jsm"); + return new RokuApp(aService); + }, + mirror: false, + types: ["video/mp4"], + extensions: ["mp4"] + }; + + // Register targets + SimpleServiceDiscovery.registerDevice(rokuDevice); + + // Search for devices continuously every 120 seconds + SimpleServiceDiscovery.search(120 * 1000); + }, + // All initial windows have opened. _onWindowsRestored: function BG__onWindowsRestored() { + this._initServiceDiscovery(); + // Show update notification, if needed. if (Services.prefs.prefHasUserValue("app.update.postupdate")) this._showUpdateNotification(); @@ -1344,7 +1369,7 @@ BrowserGlue.prototype = { }, _migrateUI: function BG__migrateUI() { - const UI_VERSION = 23; + const UI_VERSION = 24; const BROWSER_DOCURL = "chrome://browser/content/browser.xul"; let currentUIVersion = 0; try { @@ -1422,15 +1447,6 @@ BrowserGlue.prototype = { } } - if (currentUIVersion < 8) { - // Reset homepage pref for users who have it set to google.com/firefox - let uri = Services.prefs.getComplexValue("browser.startup.homepage", - Ci.nsIPrefLocalizedString).data; - if (uri && /^https?:\/\/(www\.)?google(\.\w{2,3}){1,2}\/firefox\/?$/.test(uri)) { - Services.prefs.clearUserPref("browser.startup.homepage"); - } - } - if (currentUIVersion < 9) { // This code adds the customizable downloads buttons. let currentset = xulStore.getValue(BROWSER_DOCURL, "nav-bar", "currentset"); @@ -1495,10 +1511,6 @@ BrowserGlue.prototype = { } } - if (currentUIVersion < 13) { - /* Obsolete */ - } - if (currentUIVersion < 14) { // DOM Storage doesn't specially handle about: pages anymore. let path = OS.Path.join(OS.Constants.Path.profileDir, @@ -1593,6 +1605,18 @@ BrowserGlue.prototype = { } } + if (currentUIVersion < 24) { + // Reset homepage pref for users who have it set to start.mozilla.org + // or google.com/firefox. + const HOMEPAGE_PREF = "browser.startup.homepage"; + let uri = Services.prefs.getComplexValue(HOMEPAGE_PREF, + Ci.nsIPrefLocalizedString).data; + if (uri && (uri.startsWith("http://start.mozilla.org") || + /^https?:\/\/(www\.)?google\.[a-z.]+\/firefox/i.test(uri))) { + Services.prefs.clearUserPref(HOMEPAGE_PREF); + } + } + // Update the migration version. Services.prefs.setIntPref("browser.migration.version", UI_VERSION); }, diff --git a/browser/components/shell/nsGNOMEShellService.cpp b/browser/components/shell/nsGNOMEShellService.cpp index 2d6be344288..aad82420aee 100644 --- a/browser/components/shell/nsGNOMEShellService.cpp +++ b/browser/components/shell/nsGNOMEShellService.cpp @@ -313,6 +313,11 @@ nsGNOMEShellService::SetDefaultBrowser(bool aClaimAllTypes, } } + nsCOMPtr prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); + if (prefs) { + (void) prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, true); + } + return NS_OK; } @@ -326,29 +331,25 @@ nsGNOMEShellService::GetShouldCheckDefaultBrowser(bool* aResult) return NS_OK; } - nsCOMPtr prefs; - nsCOMPtr pserve(do_GetService(NS_PREFSERVICE_CONTRACTID)); - if (pserve) - pserve->GetBranch("", getter_AddRefs(prefs)); + nsresult rv; + nsCOMPtr prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); + if (NS_FAILED(rv)) { + return rv; + } - if (prefs) - prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult); - - return NS_OK; + return prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult); } NS_IMETHODIMP nsGNOMEShellService::SetShouldCheckDefaultBrowser(bool aShouldCheck) { - nsCOMPtr prefs; - nsCOMPtr pserve(do_GetService(NS_PREFSERVICE_CONTRACTID)); - if (pserve) - pserve->GetBranch("", getter_AddRefs(prefs)); + nsresult rv; + nsCOMPtr prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); + if (NS_FAILED(rv)) { + return rv; + } - if (prefs) - prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck); - - return NS_OK; + return prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck); } NS_IMETHODIMP diff --git a/browser/components/shell/nsMacShellService.cpp b/browser/components/shell/nsMacShellService.cpp index c9351dbbc86..0e3f8cb50ce 100644 --- a/browser/components/shell/nsMacShellService.cpp +++ b/browser/components/shell/nsMacShellService.cpp @@ -90,7 +90,12 @@ nsMacShellService::SetDefaultBrowser(bool aClaimAllTypes, bool aForAllUsers) return NS_ERROR_FAILURE; } } - + + nsCOMPtr prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); + if (prefs) { + (void) prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, true); + } + return NS_OK; } @@ -104,27 +109,25 @@ nsMacShellService::GetShouldCheckDefaultBrowser(bool* aResult) return NS_OK; } - nsCOMPtr prefs; - nsCOMPtr pserve(do_GetService(NS_PREFSERVICE_CONTRACTID)); - if (pserve) - pserve->GetBranch("", getter_AddRefs(prefs)); + nsresult rv; + nsCOMPtr prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); + if (NS_FAILED(rv)) { + return rv; + } - prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult); - - return NS_OK; + return prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult); } NS_IMETHODIMP nsMacShellService::SetShouldCheckDefaultBrowser(bool aShouldCheck) { - nsCOMPtr prefs; - nsCOMPtr pserve(do_GetService(NS_PREFSERVICE_CONTRACTID)); - if (pserve) - pserve->GetBranch("", getter_AddRefs(prefs)); + nsresult rv; + nsCOMPtr prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); + if (NS_FAILED(rv)) { + return rv; + } - prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck); - - return NS_OK; + return prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck); } NS_IMETHODIMP diff --git a/browser/components/shell/nsWindowsShellService.cpp b/browser/components/shell/nsWindowsShellService.cpp index edbba2ddc8f..69dc7872976 100644 --- a/browser/components/shell/nsWindowsShellService.cpp +++ b/browser/components/shell/nsWindowsShellService.cpp @@ -275,20 +275,15 @@ nsWindowsShellService::ShortcutMaintenance() return NS_ERROR_UNEXPECTED; NS_NAMED_LITERAL_CSTRING(prefName, "browser.taskbar.lastgroupid"); - nsCOMPtr prefs = + nsCOMPtr prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); if (!prefs) return NS_ERROR_UNEXPECTED; - nsCOMPtr prefBranch; - prefs->GetBranch(nullptr, getter_AddRefs(prefBranch)); - if (!prefBranch) - return NS_ERROR_UNEXPECTED; - nsCOMPtr prefString; - rv = prefBranch->GetComplexValue(prefName.get(), - NS_GET_IID(nsISupportsString), - getter_AddRefs(prefString)); + rv = prefs->GetComplexValue(prefName.get(), + NS_GET_IID(nsISupportsString), + getter_AddRefs(prefString)); if (NS_SUCCEEDED(rv)) { nsAutoString version; prefString->GetData(version); @@ -304,9 +299,9 @@ nsWindowsShellService::ShortcutMaintenance() return rv; prefString->SetData(appId); - rv = prefBranch->SetComplexValue(prefName.get(), - NS_GET_IID(nsISupportsString), - prefString); + rv = prefs->SetComplexValue(prefName.get(), + NS_GET_IID(nsISupportsString), + prefString); if (NS_FAILED(rv)) { NS_WARNING("Couldn't set last user model id!"); return NS_ERROR_UNEXPECTED; @@ -707,6 +702,11 @@ nsWindowsShellService::SetDefaultBrowser(bool aClaimAllTypes, bool aForAllUsers) } } + nsCOMPtr prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); + if (prefs) { + (void) prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, true); + } + return rv; } @@ -722,13 +722,11 @@ nsWindowsShellService::GetShouldCheckDefaultBrowser(bool* aResult) return NS_OK; } - nsCOMPtr prefs; nsresult rv; - nsCOMPtr pserve(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = pserve->GetBranch("", getter_AddRefs(prefs)); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); + if (NS_FAILED(rv)) { + return rv; + } return prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult); } @@ -736,14 +734,11 @@ nsWindowsShellService::GetShouldCheckDefaultBrowser(bool* aResult) NS_IMETHODIMP nsWindowsShellService::SetShouldCheckDefaultBrowser(bool aShouldCheck) { - nsCOMPtr prefs; nsresult rv; - - nsCOMPtr pserve(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); - NS_ENSURE_SUCCESS(rv, rv); - - rv = pserve->GetBranch("", getter_AddRefs(prefs)); - NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); + if (NS_FAILED(rv)) { + return rv; + } return prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck); } diff --git a/browser/components/tabview/tabitems.js b/browser/components/tabview/tabitems.js index 983fab082a1..1f8263f84d4 100644 --- a/browser/components/tabview/tabitems.js +++ b/browser/components/tabview/tabitems.js @@ -1383,15 +1383,9 @@ TabCanvas.prototype = Utils.extend(new Subscribable(), { if (!w || !h) return; - if (!this.tab.linkedBrowser.contentWindow) { - Utils.log('no tab.linkedBrowser.contentWindow in TabCanvas.paint()'); - return; - } - - let win = this.tab.linkedBrowser.contentWindow; - gPageThumbnails.captureToCanvas(win, this.canvas); - - this._sendToSubscribers("painted"); + gPageThumbnails.captureToCanvas(this.tab.linkedBrowser, this.canvas, () => { + this._sendToSubscribers("painted"); + }); }, // ---------- diff --git a/browser/devtools/timeline/test/browser_timeline_overview-initial-selection-01.js b/browser/devtools/timeline/test/browser_timeline_overview-initial-selection-01.js index abb9fab6560..0c6d04f03b0 100644 --- a/browser/devtools/timeline/test/browser_timeline_overview-initial-selection-01.js +++ b/browser/devtools/timeline/test/browser_timeline_overview-initial-selection-01.js @@ -29,7 +29,7 @@ let test = Task.async(function*() { let selection = TimelineView.overview.getSelection(); is((selection.start) | 0, - (markers[0].start * TimelineView.overview.dataScaleX) | 0, + ((markers[0].start - markers.startTime) * TimelineView.overview.dataScaleX) | 0, "The initial selection start is correct."); is((selection.end - selection.start) | 0, diff --git a/browser/devtools/timeline/timeline.js b/browser/devtools/timeline/timeline.js index bb581bfc01a..e64c5fb304e 100644 --- a/browser/devtools/timeline/timeline.js +++ b/browser/devtools/timeline/timeline.js @@ -107,13 +107,19 @@ let TimelineController = { * Starts the recording, updating the UI as needed. */ _startRecording: function*() { - this._markers = []; - this._markers.startTime = performance.now(); - this._markers.endTime = performance.now(); - this._updateId = setInterval(this._onRecordingTick, OVERVIEW_UPDATE_INTERVAL); - TimelineView.handleRecordingStarted(); - yield gFront.start(); + let startTime = yield gFront.start(); + // Times must come from the actor in order to be self-consistent. + // However, we also want to update the view with the elapsed time + // even when the actor is not generating data. To do this we get + // the local time and use it to compute a reasonable elapsed time. + // See _onRecordingTick. + this._localStartTime = performance.now(); + + this._markers = []; + this._markers.startTime = startTime; + this._markers.endTime = startTime; + this._updateId = setInterval(this._onRecordingTick, OVERVIEW_UPDATE_INTERVAL); }, /** @@ -142,9 +148,12 @@ let TimelineController = { * @param array markers * A list of new markers collected since the last time this * function was invoked. + * @param number endTime + * A time after the last marker in markers was collected. */ - _onMarkers: function(markers) { + _onMarkers: function(markers, endTime) { Array.prototype.push.apply(this._markers, markers); + this._markers.endTime = endTime; }, /** @@ -152,7 +161,13 @@ let TimelineController = { * Updates the markers store with the current time and the timeline overview. */ _onRecordingTick: function() { - this._markers.endTime = performance.now(); + // Compute an approximate ending time for the view. This is + // needed to ensure that the view updates even when new data is + // not being generated. + let fakeTime = this._markers.startTime + (performance.now() - this._localStartTime); + if (fakeTime > this._markers.endTime) { + this._markers.endTime = fakeTime; + } TimelineView.handleMarkersUpdate(this._markers); } }; @@ -214,12 +229,12 @@ let TimelineView = { let markers = TimelineController.getMarkers(); if (markers.length) { - let start = markers[0].start * this.overview.dataScaleX; + let start = (markers[0].start - markers.startTime) * this.overview.dataScaleX; let end = start + this.overview.width * OVERVIEW_INITIAL_SELECTION_RATIO; this.overview.setSelection({ start, end }); } else { let duration = markers.endTime - markers.startTime; - this.waterfall.setData(markers, 0, duration); + this.waterfall.setData(markers, markers.startTime, markers.endTime); } window.emit(EVENTS.RECORDING_ENDED); @@ -251,8 +266,8 @@ let TimelineView = { let end = selection.end / this.overview.dataScaleX; let markers = TimelineController.getMarkers(); - let timeStart = Math.min(start, end); - let timeEnd = Math.max(start, end); + let timeStart = markers.startTime + Math.min(start, end); + let timeEnd = markers.startTime + Math.max(start, end); this.waterfall.setData(markers, timeStart, timeEnd); }, diff --git a/browser/devtools/timeline/widgets/overview.js b/browser/devtools/timeline/widgets/overview.js index 65bb2848bd0..f2ca65db35d 100644 --- a/browser/devtools/timeline/widgets/overview.js +++ b/browser/devtools/timeline/widgets/overview.js @@ -170,6 +170,9 @@ Overview.prototype = Heritage.extend(AbstractCanvasGraph.prototype, { ctx.beginPath(); for (let { start, end } of batch) { + start -= this._data.startTime; + end -= this._data.startTime; + let left = start * dataScale; let duration = Math.max(end - start, OVERVIEW_MARKER_DURATION_MIN); let width = Math.max(duration * dataScale, this._pixelRatio); diff --git a/browser/devtools/timeline/widgets/waterfall.js b/browser/devtools/timeline/widgets/waterfall.js index c5678573d98..f51eab8dc4a 100644 --- a/browser/devtools/timeline/widgets/waterfall.js +++ b/browser/devtools/timeline/widgets/waterfall.js @@ -76,16 +76,17 @@ Waterfall.prototype = { * @param array markers * A list of markers received from the controller. * @param number timeStart - * The delta time (in milliseconds) to start drawing from. + * The time (in milliseconds) to start drawing from. * @param number timeEnd - * The delta time (in milliseconds) to end drawing at. + * The time (in milliseconds) to end drawing at. */ setData: function(markers, timeStart, timeEnd) { this.clearView(); let dataScale = this._waterfallWidth / (timeEnd - timeStart); this._drawWaterfallBackground(dataScale); - this._buildHeader(this._headerContents, timeStart, dataScale); + // Label the header as if the first possible marker was at T=0. + this._buildHeader(this._headerContents, timeStart - markers.startTime, dataScale); this._buildMarkers(this._listContents, markers, timeStart, timeEnd, dataScale); }, diff --git a/browser/devtools/webaudioeditor/test/browser.ini b/browser/devtools/webaudioeditor/test/browser.ini index 438accdc9db..503e6f01fb6 100644 --- a/browser/devtools/webaudioeditor/test/browser.ini +++ b/browser/devtools/webaudioeditor/test/browser.ini @@ -23,6 +23,7 @@ support-files = [browser_audionode-actor-is-source.js] [browser_audionode-actor-bypass.js] [browser_audionode-actor-connectnode-disconnect.js] +[browser_audionode-actor-connectparam.js] [browser_webaudio-actor-simple.js] [browser_webaudio-actor-destroy-node.js] [browser_webaudio-actor-connect-param.js] diff --git a/browser/devtools/webaudioeditor/test/browser_audionode-actor-connectparam.js b/browser/devtools/webaudioeditor/test/browser_audionode-actor-connectparam.js new file mode 100644 index 00000000000..2603299d17b --- /dev/null +++ b/browser/devtools/webaudioeditor/test/browser_audionode-actor-connectparam.js @@ -0,0 +1,35 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Tests that AudioNodeActor#connectParam() work. + * Uses the editor front as the actors do not retain connect state. + */ + +function spawnTest() { + let { target, panel } = yield initWebAudioEditor(SIMPLE_CONTEXT_URL); + let { panelWin } = panel; + let { gFront, $, $$, EVENTS, gAudioNodes } = panelWin; + + reload(target); + + let [actors] = yield Promise.all([ + get3(gFront, "create-node"), + waitForGraphRendered(panelWin, 3, 2) + ]); + + let [dest, osc, gain] = actors; + + yield osc.disconnect(); + + osc.connectParam(gain, "gain"); + yield Promise.all([ + waitForGraphRendered(panelWin, 3, 1, 1), + once(gAudioNodes, "connect") + ]); + ok(true, "Oscillator connect to Gain's Gain AudioParam, event emitted."); + + yield teardown(panel); + finish(); +} + diff --git a/browser/devtools/webide/content/addons.js b/browser/devtools/webide/content/addons.js index a533969c1a8..f3e2d24f804 100644 --- a/browser/devtools/webide/content/addons.js +++ b/browser/devtools/webide/content/addons.js @@ -30,13 +30,14 @@ function CloseUI() { } function BuildUI(addons) { - BuildItem(addons.adb, true /* is adb */); + BuildItem(addons.adb, "adb"); + BuildItem(addons.adapters, "adapters"); for (let addon of addons.simulators) { - BuildItem(addon, false /* is adb */); + BuildItem(addon, "simulator"); } } -function BuildItem(addon, isADB) { +function BuildItem(addon, type) { function onAddonUpdate(event, arg) { switch (event) { @@ -73,20 +74,29 @@ function BuildItem(addon, isADB) { let li = document.createElement("li"); li.setAttribute("status", addon.status); - // Used in tests - if (isADB) { - li.setAttribute("addon", "adb"); - } else { - li.setAttribute("addon", "simulator-" + addon.version); - } - let name = document.createElement("span"); name.className = "name"; - if (isADB) { - name.textContent = Strings.GetStringFromName("addons_adb_label"); - } else { - let stability = Strings.GetStringFromName("addons_" + addon.stability); - name.textContent = Strings.formatStringFromName("addons_simulator_label", [addon.version, stability], 2); + + switch (type) { + case "adb": + li.setAttribute("addon", type); + name.textContent = Strings.GetStringFromName("addons_adb_label"); + break; + case "adapters": + li.setAttribute("addon", type); + try { + name.textContent = Strings.GetStringFromName("addons_adapters_label"); + } catch(e) { + // This code (bug 1081093) will be backported to Aurora, which doesn't + // contain this string. + name.textContent = "Tools Adapters Add-on"; + } + break; + case "simulator": + li.setAttribute("addon", "simulator-" + addon.version); + let stability = Strings.GetStringFromName("addons_" + addon.stability); + name.textContent = Strings.formatStringFromName("addons_simulator_label", [addon.version, stability], 2); + break; } li.appendChild(name); @@ -111,7 +121,7 @@ function BuildItem(addon, isADB) { let progress = document.createElement("progress"); li.appendChild(progress); - if (isADB) { + if (type == "adb") { let warning = document.createElement("p"); warning.textContent = Strings.GetStringFromName("addons_adb_warning"); warning.className = "warning"; diff --git a/browser/devtools/webide/content/webide.js b/browser/devtools/webide/content/webide.js index 051455b279f..e79d8724963 100644 --- a/browser/devtools/webide/content/webide.js +++ b/browser/devtools/webide/content/webide.js @@ -69,15 +69,22 @@ let UI = { this.autoSelectProject(); }); - // Auto install the ADB Addon Helper. Only once. - // If the user decides to uninstall the addon, we won't install it again. - let autoInstallADBHelper = Services.prefs.getBoolPref("devtools.webide.autoinstallADBHelper"); - if (autoInstallADBHelper && !Devices.helperAddonInstalled) { + // Auto install the ADB Addon Helper and Tools Adapters. Only once. + // If the user decides to uninstall any of this addon, we won't install it again. + let autoinstallADBHelper = Services.prefs.getBoolPref("devtools.webide.autoinstallADBHelper"); + let autoinstallFxdtAdapters = Services.prefs.getBoolPref("devtools.webide.autoinstallFxdtAdapters"); + if (autoinstallADBHelper) { GetAvailableAddons().then(addons => { addons.adb.install(); }, console.error); } + if (autoinstallFxdtAdapters) { + GetAvailableAddons().then(addons => { + addons.adapters.install(); + }, console.error); + } Services.prefs.setBoolPref("devtools.webide.autoinstallADBHelper", false); + Services.prefs.setBoolPref("devtools.webide.autoinstallFxdtAdapters", false); this.lastConnectedRuntime = Services.prefs.getCharPref("devtools.webide.lastConnectedRuntime"); diff --git a/browser/devtools/webide/modules/addons.js b/browser/devtools/webide/modules/addons.js index 61df4c7167a..6f8f1684098 100644 --- a/browser/devtools/webide/modules/addons.js +++ b/browser/devtools/webide/modules/addons.js @@ -13,8 +13,10 @@ const {GetAddonsJSON} = require("devtools/webide/remote-resources"); let SIMULATOR_LINK = Services.prefs.getCharPref("devtools.webide.simulatorAddonsURL"); let ADB_LINK = Services.prefs.getCharPref("devtools.webide.adbAddonURL"); +let ADAPTERS_LINK = Services.prefs.getCharPref("devtools.webide.adaptersAddonURL"); let SIMULATOR_ADDON_ID = Services.prefs.getCharPref("devtools.webide.simulatorAddonID"); let ADB_ADDON_ID = Services.prefs.getCharPref("devtools.webide.adbAddonID"); +let ADAPTERS_ADDON_ID = Services.prefs.getCharPref("devtools.webide.adaptersAddonID"); let platform = Services.appShell.hiddenDOMWindow.navigator.platform; let OS = ""; @@ -26,36 +28,24 @@ if (platform.indexOf("Win") != -1) { if (platform.indexOf("x86_64") != -1) { OS = "linux64"; } else { - OS = "linux"; + OS = "linux32"; } } -Simulator.on("unregister", updateSimulatorAddons); -Simulator.on("register", updateSimulatorAddons); -Devices.on("addon-status-updated", updateAdbAddon); - -function updateSimulatorAddons(event, version) { +let addonsListener = {}; +addonsListener.onEnabled = +addonsListener.onDisabled = +addonsListener.onInstalled = +addonsListener.onUninstalled = (updatedAddon) => { GetAvailableAddons().then(addons => { - let foundAddon = null; - for (let addon of addons.simulators) { - if (addon.version == version) { - foundAddon = addon; - break; + for (let a of [...addons.simulators, addons.adb, addons.adapters]) { + if (a.addonID == updatedAddon.id) { + a.updateInstallStatus(); } } - if (!foundAddon) { - console.warn("An unknown simulator (un)registered", version); - return; - } - foundAddon.updateInstallStatus(); - }); -} - -function updateAdbAddon() { - GetAvailableAddons().then(addons => { - addons.adb.updateInstallStatus(); }); } +AddonManager.addAddonListener(addonsListener); let GetAvailableAddons_promise = null; let GetAvailableAddons = exports.GetAvailableAddons = function() { @@ -73,6 +63,7 @@ let GetAvailableAddons = exports.GetAvailableAddons = function() { } } addons.adb = new ADBAddon(); + addons.adapters = new AdaptersAddon(); deferred.resolve(addons); }, e => { GetAvailableAddons_promise = null; @@ -99,13 +90,23 @@ Addon.prototype = { return this._status; }, - install: function() { - if (this.status != "uninstalled") { - throw new Error("Not uninstalled"); - } - this.status = "preparing"; - + updateInstallStatus: function() { AddonManager.getAddonByID(this.addonID, (addon) => { + if (addon && !addon.userDisabled) { + this.status = "installed"; + } else { + this.status = "uninstalled"; + } + }); + }, + + install: function() { + AddonManager.getAddonByID(this.addonID, (addon) => { + if (addon && !addon.userDisabled) { + this.status = "installed"; + return; + } + this.status = "preparing"; if (addon && addon.userDisabled) { addon.userDisabled = false; } else { @@ -115,7 +116,6 @@ Addon.prototype = { }, "application/x-xpinstall"); } }); - }, uninstall: function() { @@ -167,44 +167,30 @@ function SimulatorAddon(stability, version) { EventEmitter.decorate(this); this.stability = stability; this.version = version; - this.xpiLink = SIMULATOR_LINK.replace(/#OS#/g, OS) + // This addon uses the string "linux" for "linux32" + let fixedOS = OS == "linux32" ? "linux" : OS; + this.xpiLink = SIMULATOR_LINK.replace(/#OS#/g, fixedOS) .replace(/#VERSION#/g, version) .replace(/#SLASHED_VERSION#/g, version.replace(/\./g, "_")); this.addonID = SIMULATOR_ADDON_ID.replace(/#SLASHED_VERSION#/g, version.replace(/\./g, "_")); this.updateInstallStatus(); } - -SimulatorAddon.prototype = Object.create(Addon.prototype, { - updateInstallStatus: { - enumerable: true, - value: function() { - let sim = Simulator.getByVersion(this.version); - if (sim) { - this.status = "installed"; - } else { - this.status = "uninstalled"; - } - } - }, -}); +SimulatorAddon.prototype = Object.create(Addon.prototype); function ADBAddon() { EventEmitter.decorate(this); - this.xpiLink = ADB_LINK.replace(/#OS#/g, OS); + // This addon uses the string "linux" for "linux32" + let fixedOS = OS == "linux32" ? "linux" : OS; + this.xpiLink = ADB_LINK.replace(/#OS#/g, fixedOS); this.addonID = ADB_ADDON_ID; this.updateInstallStatus(); } +ADBAddon.prototype = Object.create(Addon.prototype); -ADBAddon.prototype = Object.create(Addon.prototype, { - updateInstallStatus: { - enumerable: true, - value: function() { - if (Devices.helperAddonInstalled) { - this.status = "installed"; - } else { - this.status = "uninstalled"; - } - } - }, -}); - +function AdaptersAddon() { + EventEmitter.decorate(this); + this.xpiLink = ADAPTERS_LINK.replace(/#OS#/g, OS); + this.addonID = ADAPTERS_ADDON_ID; + this.updateInstallStatus(); +} +AdaptersAddon.prototype = Object.create(Addon.prototype); diff --git a/browser/devtools/webide/test/addons/fxdt-adapters-linux32.xpi b/browser/devtools/webide/test/addons/fxdt-adapters-linux32.xpi new file mode 100644 index 00000000000..5a512ae3d19 Binary files /dev/null and b/browser/devtools/webide/test/addons/fxdt-adapters-linux32.xpi differ diff --git a/browser/devtools/webide/test/addons/fxdt-adapters-linux64.xpi b/browser/devtools/webide/test/addons/fxdt-adapters-linux64.xpi new file mode 100644 index 00000000000..5a512ae3d19 Binary files /dev/null and b/browser/devtools/webide/test/addons/fxdt-adapters-linux64.xpi differ diff --git a/browser/devtools/webide/test/addons/fxdt-adapters-mac64.xpi b/browser/devtools/webide/test/addons/fxdt-adapters-mac64.xpi new file mode 100644 index 00000000000..5a512ae3d19 Binary files /dev/null and b/browser/devtools/webide/test/addons/fxdt-adapters-mac64.xpi differ diff --git a/browser/devtools/webide/test/addons/fxdt-adapters-win32.xpi b/browser/devtools/webide/test/addons/fxdt-adapters-win32.xpi new file mode 100644 index 00000000000..5a512ae3d19 Binary files /dev/null and b/browser/devtools/webide/test/addons/fxdt-adapters-win32.xpi differ diff --git a/browser/devtools/webide/test/chrome.ini b/browser/devtools/webide/test/chrome.ini index 27219e29a11..4ec6c3f3b01 100644 --- a/browser/devtools/webide/test/chrome.ini +++ b/browser/devtools/webide/test/chrome.ini @@ -20,6 +20,10 @@ support-files = addons/adbhelper-linux64.xpi addons/adbhelper-win32.xpi addons/adbhelper-mac64.xpi + addons/fxdt-adapters-linux32.xpi + addons/fxdt-adapters-linux64.xpi + addons/fxdt-adapters-win32.xpi + addons/fxdt-adapters-mac64.xpi head.js hosted_app.manifest templates.json diff --git a/browser/devtools/webide/test/head.js b/browser/devtools/webide/test/head.js index f7a63521f70..6047dfc60e7 100644 --- a/browser/devtools/webide/test/head.js +++ b/browser/devtools/webide/test/head.js @@ -27,25 +27,22 @@ Services.prefs.setBoolPref("devtools.webide.enableLocalRuntime", true); Services.prefs.setCharPref("devtools.webide.addonsURL", TEST_BASE + "addons/simulators.json"); Services.prefs.setCharPref("devtools.webide.simulatorAddonsURL", TEST_BASE + "addons/fxos_#SLASHED_VERSION#_simulator-#OS#.xpi"); Services.prefs.setCharPref("devtools.webide.adbAddonURL", TEST_BASE + "addons/adbhelper-#OS#.xpi"); +Services.prefs.setCharPref("devtools.webide.adaptersAddonURL", TEST_BASE + "addons/fxdt-adapters-#OS#.xpi"); Services.prefs.setCharPref("devtools.webide.templatesURL", TEST_BASE + "templates.json"); SimpleTest.registerCleanupFunction(() => { - Services.prefs.clearUserPref("devtools.webide.templatesURL"); Services.prefs.clearUserPref("devtools.webide.enabled"); Services.prefs.clearUserPref("devtools.webide.enableLocalRuntime"); - Services.prefs.clearUserPref("devtools.webide.addonsURL"); - Services.prefs.clearUserPref("devtools.webide.simulatorAddonsURL"); - Services.prefs.clearUserPref("devtools.webide.adbAddonURL"); - Services.prefs.clearUserPref("devtools.webide.autoInstallADBHelper", false); + Services.prefs.clearUserPref("devtools.webide.autoinstallADBHelper"); + Services.prefs.clearUserPref("devtools.webide.autoinstallFxdtAdapters"); }); -function openWebIDE(autoInstallADBHelper) { +function openWebIDE(autoInstallAddons) { info("opening WebIDE"); - if (!autoInstallADBHelper) { - Services.prefs.setBoolPref("devtools.webide.autoinstallADBHelper", false); - } + Services.prefs.setBoolPref("devtools.webide.autoinstallADBHelper", !!autoInstallAddons); + Services.prefs.setBoolPref("devtools.webide.autoinstallFxdtAdapters", !!autoInstallAddons); let deferred = promise.defer(); diff --git a/browser/devtools/webide/test/test_addons.html b/browser/devtools/webide/test/test_addons.html index 24ec846c97c..5af951998dd 100644 --- a/browser/devtools/webide/test/test_addons.html +++ b/browser/devtools/webide/test/test_addons.html @@ -109,10 +109,10 @@ let lis; lis = addonDoc.querySelectorAll("li"); - is(lis.length, 4, "4 addons listed"); + is(lis.length, 5, "5 addons listed"); lis = addonDoc.querySelectorAll('li[status="installed"]'); - is(lis.length, 2, "2 addons installed"); + is(lis.length, 3, "3 addons installed"); lis = addonDoc.querySelectorAll('li[status="uninstalled"]'); is(lis.length, 2, "2 addons uninstalled"); diff --git a/browser/devtools/webide/webide-prefs.js b/browser/devtools/webide/webide-prefs.js index 0d7c1b1e392..47bd60ca433 100644 --- a/browser/devtools/webide/webide-prefs.js +++ b/browser/devtools/webide/webide-prefs.js @@ -6,6 +6,7 @@ pref("devtools.webide.showProjectEditor", true); pref("devtools.webide.templatesURL", "https://code.cdn.mozilla.net/templates/list.json"); pref("devtools.webide.autoinstallADBHelper", true); +pref("devtools.webide.autoinstallFxdtAdapters", false); pref("devtools.webide.restoreLastProject", true); pref("devtools.webide.enableLocalRuntime", true); pref("devtools.webide.addonsURL", "https://ftp.mozilla.org/pub/mozilla.org/labs/fxos-simulator/index.json"); @@ -13,6 +14,8 @@ pref("devtools.webide.simulatorAddonsURL", "https://ftp.mozilla.org/pub/mozilla. pref("devtools.webide.simulatorAddonID", "fxos_#SLASHED_VERSION#_simulator@mozilla.org"); pref("devtools.webide.adbAddonURL", "https://ftp.mozilla.org/pub/mozilla.org/labs/fxos-simulator/adb-helper/#OS#/adbhelper-#OS#-latest.xpi"); pref("devtools.webide.adbAddonID", "adbhelper@mozilla.org"); +pref("devtools.webide.adaptersAddonURL", "https://ftp.mozilla.org/pub/mozilla.org/labs/fxdt-adapters/#OS#/fxdt-adapters-#OS#-latest.xpi"); +pref("devtools.webide.adaptersAddonID", "fxdevtools-adapters@mozilla.org"); pref("devtools.webide.monitorWebSocketURL", "ws://localhost:9000"); pref("devtools.webide.lastConnectedRuntime", ""); pref("devtools.webide.lastSelectedProject", ""); diff --git a/browser/fuel/test/browser_ApplicationPrefs.js b/browser/fuel/test/browser_ApplicationPrefs.js index 23ac5dc48ba..6c84b5dbcc4 100644 --- a/browser/fuel/test/browser_ApplicationPrefs.js +++ b/browser/fuel/test/browser_ApplicationPrefs.js @@ -127,7 +127,7 @@ function test() { is(Application.prefs.root, "", "Check the Application preference root"); // test for user changed preferences - ok(Application.prefs.get("browser.shell.checkDefaultBrowser").modified, "A single preference is marked as modified."); + ok(Application.prefs.get("browser.dom.window.dump.enabled").modified, "A single preference is marked as modified."); ok(!Application.prefs.get(testdata.string).modified, "A single preference is marked as not modified."); // test for a locked preference diff --git a/browser/locales/en-US/chrome/browser/browser.dtd b/browser/locales/en-US/chrome/browser/browser.dtd index 29f515d814c..5037eb8e478 100644 --- a/browser/locales/en-US/chrome/browser/browser.dtd +++ b/browser/locales/en-US/chrome/browser/browser.dtd @@ -484,6 +484,8 @@ These should match what Safari and other Apple applications use on OS X Lion. -- + + diff --git a/browser/locales/en-US/chrome/browser/customizableui/customizableWidgets.properties b/browser/locales/en-US/chrome/browser/customizableui/customizableWidgets.properties index 9d84c904302..187412020a8 100644 --- a/browser/locales/en-US/chrome/browser/customizableui/customizableWidgets.properties +++ b/browser/locales/en-US/chrome/browser/customizableui/customizableWidgets.properties @@ -100,7 +100,7 @@ quit-button.tooltiptext.mac = Quit %1$S (%2$S) # LOCALIZATION NOTE(loop-call-button3.label): This is a brand name, request # approval before you change it. loop-call-button3.label = Hello -loop-call-button2.tooltiptext = Start a conversation +loop-call-button3.tooltiptext = Start a conversation social-share-button.label = Share This Page social-share-button.tooltiptext = Share This Page diff --git a/browser/locales/en-US/chrome/browser/devtools/webide.properties b/browser/locales/en-US/chrome/browser/devtools/webide.properties index 23f15b93be3..a9eed38171c 100644 --- a/browser/locales/en-US/chrome/browser/devtools/webide.properties +++ b/browser/locales/en-US/chrome/browser/devtools/webide.properties @@ -52,6 +52,7 @@ addons_simulator_label=Firefox OS %1$S Simulator (%2$S) addons_install_button=install addons_uninstall_button=uninstall addons_adb_label=ADB Helper Add-on +addons_adapters_label=Tools Adapters Add-on addons_adb_warning=USB devices won't be detected without this add-on addons_status_unknown=? addons_status_installed=Installed diff --git a/browser/modules/CastingApps.jsm b/browser/modules/CastingApps.jsm new file mode 100644 index 00000000000..df974f04f60 --- /dev/null +++ b/browser/modules/CastingApps.jsm @@ -0,0 +1,160 @@ +// -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*- +/* 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"; +this.EXPORTED_SYMBOLS = ["CastingApps"]; + +const { classes: Cc, interfaces: Ci, utils: Cu } = Components; + +Cu.import("resource://gre/modules/Services.jsm"); +Cu.import("resource://gre/modules/SimpleServiceDiscovery.jsm"); + + +var CastingApps = { + _sendEventToVideo: function (element, data) { + let event = element.ownerDocument.createEvent("CustomEvent"); + event.initCustomEvent("media-videoCasting", false, true, JSON.stringify(data)); + element.dispatchEvent(event); + }, + + makeURI: function (url, charset, baseURI) { + return Services.io.newURI(url, charset, baseURI); + }, + + getVideo: function (element) { + if (!element) { + return null; + } + + let extensions = SimpleServiceDiscovery.getSupportedExtensions(); + let types = SimpleServiceDiscovery.getSupportedMimeTypes(); + + // Grab the poster attribute from the