This commit is contained in:
Wes Kocher 2016-05-23 17:14:42 -07:00
Родитель 5cbce51a75 c5967c0388
Коммит 865c827ac1
93 изменённых файлов: 1670 добавлений и 1279 удалений

Просмотреть файл

@ -99,16 +99,12 @@ devtools/client/promisedebugger/**
devtools/client/responsivedesign/**
devtools/client/scratchpad/**
devtools/client/shadereditor/**
devtools/client/shared/*.js
devtools/client/shared/*.jsm
!devtools/client/shared/css-angle.js
!devtools/client/shared/css-color.js
!devtools/client/shared/css-color-db.js
!devtools/client/shared/css-parsing-utils.js
devtools/client/shared/developer-toolbar.js
devtools/client/shared/components/test/**
devtools/client/shared/redux/middleware/test/**
devtools/client/shared/test/**
devtools/client/shared/widgets/**
devtools/client/shared/widgets/*.jsm
devtools/client/sourceeditor/**
devtools/client/webaudioeditor/**
devtools/client/webconsole/**

Просмотреть файл

@ -166,14 +166,6 @@
label="&mediaHideControls.label;"
accesskey="&mediaHideControls.accesskey;"
oncommand="gContextMenu.mediaCommand('hidecontrols');"/>
<menuitem id="context-video-showstats"
accesskey="&videoShowStats.accesskey;"
label="&videoShowStats.label;"
oncommand="gContextMenu.mediaCommand('showstats');"/>
<menuitem id="context-video-hidestats"
accesskey="&videoHideStats.accesskey;"
label="&videoHideStats.label;"
oncommand="gContextMenu.mediaCommand('hidestats');"/>
<menuitem id="context-video-fullscreen"
accesskey="&videoFullScreen.accesskey;"
label="&videoFullScreen.label;"

Просмотреть файл

@ -755,13 +755,6 @@ addMessageListener("ContextMenu:MediaCommand", (message) => {
case "showcontrols":
media.setAttribute("controls", "true");
break;
case "hidestats":
case "showstats":
let event = media.ownerDocument.createEvent("CustomEvent");
event.initCustomEvent("media-showStatistics", false, true,
message.data.command == "showstats");
media.dispatchEvent(event);
break;
case "fullscreen":
if (content.document.fullscreenEnabled)
media.requestFullscreen();

Просмотреть файл

@ -474,9 +474,6 @@ nsContextMenu.prototype = {
this.showItem("context-media-showcontrols", onMedia && !this.target.controls);
this.showItem("context-media-hidecontrols", this.target.controls && (this.onVideo || (this.onAudio && !this.inSyntheticDoc)));
this.showItem("context-video-fullscreen", this.onVideo && this.target.ownerDocument.fullscreenElement == null);
var statsShowing = this.onVideo && this.target.mozMediaStatisticsShowing;
this.showItem("context-video-showstats", this.onVideo && this.target.controls && !statsShowing);
this.showItem("context-video-hidestats", this.onVideo && this.target.controls && statsShowing);
this.showItem("context-media-eme-learnmore", this.onDRMMedia);
this.showItem("context-media-eme-separator", this.onDRMMedia);
@ -506,8 +503,6 @@ nsContextMenu.prototype = {
let canSaveSnapshot = !this.onDRMMedia && this.target.readyState >= this.target.HAVE_CURRENT_DATA;
this.setItemAttr("context-video-saveimage", "disabled", !canSaveSnapshot);
this.setItemAttr("context-video-fullscreen", "disabled", hasError);
this.setItemAttr("context-video-showstats", "disabled", hasError);
this.setItemAttr("context-video-hidestats", "disabled", hasError);
}
}
this.showItem("context-media-sep-commands", onMedia);

Просмотреть файл

@ -63,17 +63,10 @@
Components.classes["@mozilla.org/docshell/urifixup;1"]
.getService(Components.interfaces.nsIURIFixup);
</field>
<field name="mFaviconService" readonly="true">
Components.classes["@mozilla.org/browser/favicon-service;1"]
.getService(Components.interfaces.nsIFaviconService);
</field>
<field name="_unifiedComplete" readonly="true">
Components.classes["@mozilla.org/autocomplete/search;1?name=unifiedcomplete"]
.getService(Components.interfaces.mozIPlacesAutoComplete);
</field>
<field name="PlacesUtils" readonly="true">
(Components.utils.import("resource://gre/modules/PlacesUtils.jsm", {})).PlacesUtils;
</field>
<field name="AppConstants" readonly="true">
(Components.utils.import("resource://gre/modules/AppConstants.jsm", {})).AppConstants;
</field>
@ -862,7 +855,7 @@
let browser = this.getBrowserForTab(aTab);
browser.mIconURL = aURI instanceof Ci.nsIURI ? aURI.spec : aURI;
if (aURI && this.mFaviconService) {
if (aURI) {
if (!(aURI instanceof Ci.nsIURI)) {
aURI = makeURI(aURI);
}
@ -872,12 +865,7 @@
let loadingPrincipal = aLoadingPrincipal
? aLoadingPrincipal
: Services.scriptSecurityManager.getSystemPrincipal();
let loadType = PrivateBrowsingUtils.isWindowPrivate(window)
? this.mFaviconService.FAVICON_LOAD_PRIVATE
: this.mFaviconService.FAVICON_LOAD_NON_PRIVATE;
this.mFaviconService.setAndFetchFaviconForPage(
browser.currentURI, aURI, false, loadType, null, loadingPrincipal);
PlacesUIUtils.loadFavicon(browser, loadingPrincipal, aURI);
}
let sizedIconUrl = browser.mIconURL || "";
@ -950,12 +938,9 @@
<parameter name="aURI"/>
<body>
<![CDATA[
if (this.mFaviconService) {
if (!(aURI instanceof Ci.nsIURI))
aURI = makeURI(aURI);
return this.mFaviconService.isFailedFavicon(aURI);
}
return null;
if (!(aURI instanceof Ci.nsIURI))
aURI = makeURI(aURI);
return PlacesUtils.favicons.isFailedFavicon(aURI);
]]>
</body>
</method>

Просмотреть файл

@ -117,7 +117,6 @@ add_task(function* test_video_ok() {
"context-media-playbackrate-200x", true], null,
"context-media-loop", true,
"context-media-hidecontrols", true,
"context-video-showstats", true,
"context-video-fullscreen", true,
"---", null,
"context-viewvideo", true,
@ -165,7 +164,6 @@ add_task(function* test_video_bad() {
"context-media-playbackrate-200x", false], null,
"context-media-loop", true,
"context-media-hidecontrols", false,
"context-video-showstats", false,
"context-video-fullscreen", false,
"---", null,
"context-viewvideo", true,
@ -192,7 +190,6 @@ add_task(function* test_video_bad2() {
"context-media-playbackrate-200x", false], null,
"context-media-loop", true,
"context-media-hidecontrols", false,
"context-video-showstats", false,
"context-video-fullscreen", false,
"---", null,
"context-viewvideo", false,
@ -253,7 +250,6 @@ add_task(function* test_video_in_iframe() {
"context-media-playbackrate-200x", true], null,
"context-media-loop", true,
"context-media-hidecontrols", true,
"context-video-showstats", true,
"context-video-fullscreen", true,
"---", null,
"context-viewvideo", true,

Просмотреть файл

@ -214,15 +214,6 @@ FeedWriter.prototype = {
element.setAttribute(attribute, uri);
},
__faviconService: null,
get _faviconService() {
if (!this.__faviconService)
this.__faviconService = Cc["@mozilla.org/browser/favicon-service;1"].
getService(Ci.nsIFaviconService);
return this.__faviconService;
},
__bundle: null,
get _bundle() {
if (!this.__bundle) {
@ -1027,7 +1018,6 @@ FeedWriter.prototype = {
prefs.removeObserver(PREF_AUDIO_SELECTED_APP, this);
this._removeFeedFromCache();
this.__faviconService = null;
this.__bundle = null;
this._feedURI = null;
@ -1168,52 +1158,6 @@ FeedWriter.prototype = {
}
},
/**
* Sets the icon for the given web-reader item in the readers menu.
* The icon is fetched and stored through the favicon service.
*
* @param aReaderUrl
* the reader url.
* @param aMenuItem
* the reader item in the readers menulist.
*
* @note For privacy reasons we cannot set the image attribute directly
* to the icon url. See Bug 358878 for details.
*/
_setFaviconForWebReader:
function FW__setFaviconForWebReader(aReaderUrl, aMenuItem) {
let readerURI = makeURI(aReaderUrl);
if (!/^https?$/.test(readerURI.scheme)) {
// Don't try to get a favicon for non http(s) URIs.
return;
}
let faviconURI = makeURI(readerURI.prePath + "/favicon.ico");
let self = this;
let docShell = this._window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
let usePrivateBrowsing = docShell.QueryInterface(Ci.nsILoadContext)
.usePrivateBrowsing;
// We probably need to call InheritFromDocShellToDoc for this, but right now
// we can't call it from JS.
let attrs = docShell.getOriginAttributes();
let ssm = Services.scriptSecurityManager;
let nullPrincipal = ssm.createNullPrincipal(attrs);
this._faviconService.setAndFetchFaviconForPage(readerURI, faviconURI, false,
usePrivateBrowsing ? this._faviconService.FAVICON_LOAD_PRIVATE
: this._faviconService.FAVICON_LOAD_NON_PRIVATE,
function (aURI, aDataLen, aData, aMimeType) {
if (aDataLen > 0) {
let dataURL = "data:" + aMimeType + ";base64," +
btoa(String.fromCharCode.apply(null, aData));
aMenuItem.setAttribute('image', dataURL);
}
}, nullPrincipal);
},
get _mm() {
let mm = this._window.QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDocShell).

Просмотреть файл

@ -12,6 +12,7 @@ var Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Timer.jsm");
Cu.import("resource://gre/modules/PlacesUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PluralForm",
@ -37,6 +38,11 @@ XPCOMUtils.defineLazyModuleGetter(this, "CloudSync",
XPCOMUtils.defineLazyModuleGetter(this, "Weave",
"resource://services-sync/main.js");
const gInContentProcess = Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT;
const FAVICON_REQUEST_TIMEOUT = 60 * 1000;
// Map from windows to arrays of data about pending favicon loads.
let gFaviconLoadDataMap = new Map();
// copied from utilityOverlay.js
const TAB_DROP_TYPE = "application/x-moz-tabbrowser-tab";
@ -77,6 +83,149 @@ function IsLivemark(aItemId) {
return self.ids.has(aItemId);
}
let InternalFaviconLoader = {
/**
* This gets called for every inner window that is destroyed.
* In the parent process, we process the destruction ourselves. In the child process,
* we notify the parent which will then process it based on that message.
*/
observe(subject, topic, data) {
let innerWindowID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
this.onInnerDestroyed(innerWindowID);
},
/**
* Actually cancel the request, and clear the timeout for cancelling it.
*/
_cancelRequest({uri, innerWindowID, timerID, callback}, reason) {
// Break cycle
let request = callback.request;
delete callback.request;
// Ensure we don't time out.
clearTimeout(timerID);
try {
request.cancel();
} catch (ex) {
Cu.reportError("When cancelling a request for " + uri.spec + " because " + reason + ", it was already canceled!");
}
},
/**
* Called for every inner that gets destroyed, only in the parent process.
*/
onInnerDestroyed(innerID) {
for (let [window, loadDataForWindow] of gFaviconLoadDataMap) {
let newLoadDataForWindow = loadDataForWindow.filter(loadData => {
let innerWasDestroyed = loadData.innerWindowID == innerID;
if (innerWasDestroyed) {
this._cancelRequest(loadData, "the inner window was destroyed");
}
// Keep the items whose inner is still alive.
return !innerWasDestroyed;
});
// Map iteration with for...of is safe against modification, so
// now just replace the old value:
gFaviconLoadDataMap.set(window, newLoadDataForWindow);
}
},
/**
* Called when a toplevel chrome window unloads. We use this to tidy up after ourselves,
* avoid leaks, and cancel any remaining requests. The last part should in theory be
* handled by the inner-window-destroyed handlers. We clean up just to be on the safe side.
*/
onUnload(win) {
let loadDataForWindow = gFaviconLoadDataMap.get(win);
if (loadDataForWindow) {
for (let loadData of loadDataForWindow) {
this._cancelRequest(loadData, "the chrome window went away");
}
}
gFaviconLoadDataMap.delete(win);
},
/**
* Create a function to use as a nsIFaviconDataCallback, so we can remove cancelling
* information when the request succeeds. Note that right now there are some edge-cases,
* such as about: URIs with chrome:// favicons where the success callback is not invoked.
* This is OK: we will 'cancel' the request after the timeout (or when the window goes
* away) but that will be a no-op in such cases.
*/
_makeCompletionCallback(win, id) {
return {
onComplete(uri) {
let loadDataForWindow = gFaviconLoadDataMap.get(win);
if (loadDataForWindow) {
let itemIndex = loadDataForWindow.findIndex(loadData => {
return loadData.innerWindowID == id &&
loadData.uri.equals(uri) &&
loadData.callback.request == this.request;
});
if (itemIndex != -1) {
let loadData = loadDataForWindow[itemIndex];
clearTimeout(loadData.timerID);
loadDataForWindow.splice(itemIndex, 1);
}
}
delete this.request;
},
};
},
ensureInitialized() {
if (this._initialized) {
return;
}
this._initialized = true;
Services.obs.addObserver(this, "inner-window-destroyed", false);
Services.ppmm.addMessageListener("Toolkit:inner-window-destroyed", msg => {
this.onInnerDestroyed(msg.data);
});
},
loadFavicon(browser, principal, uri) {
this.ensureInitialized();
let win = browser.ownerDocument.defaultView;
if (!gFaviconLoadDataMap.has(win)) {
gFaviconLoadDataMap.set(win, []);
let unloadHandler = event => {
let doc = event.target;
let eventWin = doc.defaultview;
if (win == win.top && doc.documentURI != "about:blank") {
win.removeEventListener("unload", unloadHandler);
this.onUnload(win);
}
};
win.addEventListener("unload", unloadHandler, true);
}
// First we do the actual setAndFetch call:
let {innerWindowID, currentURI} = browser;
let loadType = PrivateBrowsingUtils.isWindowPrivate(win)
? PlacesUtils.favicons.FAVICON_LOAD_PRIVATE
: PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE;
let callback = this._makeCompletionCallback(win, innerWindowID);
let request = PlacesUtils.favicons.setAndFetchFaviconForPage(currentURI, uri, false,
loadType, callback, principal);
// Now register the result so we can cancel it if/when necessary.
if (!request) {
// The favicon service can return with success but no-op (and leave request
// as null) if the icon is the same as the page (e.g. for images) or if it is
// the favicon for an error page. In this case, we do not need to do anything else.
return;
}
callback.request = request;
let loadData = {innerWindowID, uri, callback};
loadData.timerID = setTimeout(() => {
this._cancelRequest(loadData, "it timed out");
}, FAVICON_REQUEST_TIMEOUT);
let loadDataForWindow = gFaviconLoadDataMap.get(win);
loadDataForWindow.push(loadData);
},
};
this.PlacesUIUtils = {
ORGANIZER_LEFTPANE_VERSION: 7,
ORGANIZER_FOLDER_ANNO: "PlacesOrganizer/OrganizerFolder",
@ -481,6 +630,19 @@ this.PlacesUIUtils = {
return RecentWindow.getMostRecentBrowserWindow();
},
/**
* set and fetch a favicon. Can only be used from the parent process.
* @param browser {Browser} The XUL browser element for which we're fetching a favicon.
* @param principal {Principal} The loading principal to use for the fetch.
* @param uri {URI} The URI to fetch.
*/
loadFavicon(browser, principal, uri) {
if (gInContentProcess) {
throw new Error("Can't track loads from within the child process!");
}
InternalFaviconLoader.loadFavicon(browser, principal, uri);
},
/**
* Returns the closet ancestor places view for the given DOM node
* @param aNode

Просмотреть файл

@ -107,6 +107,7 @@ Var DownloadedBytes
Var DownloadRetryCount
Var OpenedDownloadPage
Var DownloadServerIP
Var PostSigningData
Var ControlHeightPX
Var ControlRightPX
@ -115,7 +116,7 @@ Var ControlRightPX
; the stub installer
;!define STUB_DEBUG
!define StubURLVersion "v6"
!define StubURLVersion "v7"
; Successful install exit code
!define ERR_SUCCESS 0
@ -220,11 +221,13 @@ Var ControlRightPX
!include "nsDialogs.nsh"
!include "LogicLib.nsh"
!include "FileFunc.nsh"
!include "TextFunc.nsh"
!include "WinVer.nsh"
!include "WordFunc.nsh"
!insertmacro GetParameters
!insertmacro GetOptions
!insertmacro LineFind
!insertmacro StrFilter
!include "locales.nsi"
@ -745,14 +748,15 @@ Function SendPing
$\nHas Admin = $R8 \
$\nDefault Status = $R2 \
$\nSet As Sefault Status = $R3 \
$\nDownload Server IP = $DownloadServerIP"
$\nDownload Server IP = $DownloadServerIP \
$\nPost-Signing Data = $PostSigningData"
; The following will exit the installer
SetAutoClose true
StrCpy $R9 "2"
Call RelativeGotoPage
!else
${NSD_CreateTimer} OnPing ${DownloadIntervalMS}
InetBgDL::Get "${BaseURLStubPing}/${StubURLVersion}${StubURLVersionAppend}/${Channel}/${UpdateChannel}/${AB_CD}/$R0/$R1/$5/$6/$7/$8/$9/$ExitCode/$FirefoxLaunchCode/$DownloadRetryCount/$DownloadedBytes/$DownloadSizeBytes/$IntroPhaseSeconds/$OptionsPhaseSeconds/$0/$1/$DownloadFirstTransferSeconds/$2/$3/$4/$InitialInstallRequirementsCode/$OpenedDownloadPage/$ExistingProfile/$ExistingVersion/$ExistingBuildID/$R5/$R6/$R7/$R8/$R2/$R3/$DownloadServerIP" \
InetBgDL::Get "${BaseURLStubPing}/${StubURLVersion}${StubURLVersionAppend}/${Channel}/${UpdateChannel}/${AB_CD}/$R0/$R1/$5/$6/$7/$8/$9/$ExitCode/$FirefoxLaunchCode/$DownloadRetryCount/$DownloadedBytes/$DownloadSizeBytes/$IntroPhaseSeconds/$OptionsPhaseSeconds/$0/$1/$DownloadFirstTransferSeconds/$2/$3/$4/$InitialInstallRequirementsCode/$OpenedDownloadPage/$ExistingProfile/$ExistingVersion/$ExistingBuildID/$R5/$R6/$R7/$R8/$R2/$R3/$DownloadServerIP/$PostSigningData" \
"$PLUGINSDIR\_temp" /END
!endif
${Else}
@ -1045,7 +1049,7 @@ Function createOptions
; We can only install the maintenance service if the user is an admin.
Call IsUserAdmin
Pop $0
; Only show the maintenance service checkbox if we're on XP SP3 or higher;
; we don't ever want to install it on XP without at least SP3 installed.
${If} $0 == "true"
@ -1053,7 +1057,7 @@ Function createOptions
${AndIf} ${AtMostServicePack} 2
StrCpy $0 "false"
${EndIf}
; Only show the maintenance service checkbox if we have write access to HKLM
ClearErrors
WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" \
@ -1767,8 +1771,8 @@ Function FinishProgressBar
${NSD_KillTimer} FinishProgressBar
Call CopyPostSigningData
Call LaunchApp
Call SendPing
FunctionEnd
@ -1997,6 +2001,17 @@ Function LaunchAppFromElevatedProcess
Exec "$\"$0$\""
FunctionEnd
Function CopyPostSigningData
${LineRead} "$EXEDIR\postSigningData" "1" $PostSigningData
${If} ${Errors}
ClearErrors
StrCpy $PostSigningData "0"
${Else}
CreateDirectory "$LOCALAPPDATA\Mozilla\Firefox"
CopyFiles /SILENT "$EXEDIR\postSigningData" "$LOCALAPPDATA\Mozilla\Firefox"
${Endif}
FunctionEnd
Function DisplayDownloadError
${NSD_KillTimer} DisplayDownloadError
; To better display the error state on the taskbar set the progress completed

Просмотреть файл

@ -699,8 +699,8 @@ this.BrowserUITelemetry = {
"media-mute", "media-unmute", "media-playbackrate",
"media-playbackrate-050x", "media-playbackrate-100x",
"media-playbackrate-125x", "media-playbackrate-150x", "media-playbackrate-200x",
"media-showcontrols", "media-hidecontrols", "video-showstats",
"video-hidestats", "video-fullscreen", "leave-dom-fullscreen",
"media-showcontrols", "media-hidecontrols",
"video-fullscreen", "leave-dom-fullscreen",
"reloadimage", "viewimage", "viewvideo", "copyimage-contents", "copyimage",
"copyvideourl", "copyaudiourl", "saveimage", "shareimage", "sendimage",
"setDesktopBackground", "viewimageinfo", "viewimagedesc", "savevideo",

Просмотреть файл

@ -1156,6 +1156,12 @@ html|span.ac-tag {
color: Highlight;
}
html|span.ac-emphasize-text-title,
html|span.ac-emphasize-text-tag,
html|span.ac-emphasize-text-url {
font-weight: 600;
}
.ac-type-icon[type=bookmark] {
list-style-image: url("chrome://browser/skin/urlbar-star.svg#star");
}

Просмотреть файл

@ -1750,10 +1750,6 @@ toolbar .toolbarbutton-1 > .toolbarbutton-menubutton-button {
color: hsl(0, 0%, 0%);
}
html|span.ac-emphasize-text-title {
color: hsl(0, 0%, 50%);
}
.ac-tags {
font-size: 12px;
}
@ -1766,10 +1762,6 @@ html|span.ac-tag {
padding: 0 1px;
}
html|span.ac-emphasize-text-tag {
color: hsl(0, 0%, 50%);
}
.ac-separator,
.ac-url,
.ac-action {
@ -1784,10 +1776,6 @@ html|span.ac-emphasize-text-tag {
color: hsl(210, 77%, 47%);
}
html|span.ac-emphasize-text-url {
color: hsl(210, 86%, 64%);
}
.ac-action {
color: hsl(178, 100%, 28%);
}
@ -1795,10 +1783,7 @@ html|span.ac-emphasize-text-url {
.ac-title[selected],
.ac-separator[selected],
.ac-url[selected],
.ac-action[selected],
.ac-title-text[selected] > html|span.ac-emphasize-text,
.ac-url-text[selected] > html|span.ac-emphasize-text,
.ac-action-text[selected] > html|span.ac-emphasize-text {
.ac-action[selected] {
color: hsl(0, 0%, 100%);
}
@ -1807,8 +1792,10 @@ html|span.ac-emphasize-text-url {
color: hsl(210, 80%, 40%);
}
.ac-tags-text[selected] > html|span.ac-tag > html|span.ac-emphasize-text-tag {
color: hsl(210, 80%, 52%);
html|span.ac-emphasize-text-title,
html|span.ac-emphasize-text-tag,
html|span.ac-emphasize-text-url {
font-weight: 600;
}
.ac-type-icon[type=bookmark] {

Просмотреть файл

@ -1424,10 +1424,6 @@ html|*.urlbar-input:-moz-lwtheme::-moz-placeholder,
color: hsl(0, 0%, 0%);
}
html|span.ac-emphasize-text-title {
color: hsl(0, 0%, 50%);
}
.ac-tags {
font-size: 12px;
}
@ -1440,10 +1436,6 @@ html|span.ac-tag {
padding: 0 1px;
}
html|span.ac-emphasize-text-tag {
color: hsl(0, 0%, 50%);
}
.ac-separator,
.ac-url,
.ac-action {
@ -1458,10 +1450,6 @@ html|span.ac-emphasize-text-tag {
color: hsl(210, 77%, 47%);
}
html|span.ac-emphasize-text-url {
color: hsl(210, 86%, 64%);
}
.ac-action {
color: hsl(178, 100%, 28%);
}
@ -1469,10 +1457,7 @@ html|span.ac-emphasize-text-url {
.ac-title[selected=true],
.ac-separator[selected],
.ac-url[selected=true],
.ac-action[selected=true],
.ac-title-text[selected=true] > html|span.ac-emphasize-text,
.ac-url-text[selected=true] > html|span.ac-emphasize-text,
.ac-action-text[selected=true] > html|span.ac-emphasize-text {
.ac-action[selected=true] {
color: hsl(0, 0%, 100%);
}
@ -1481,8 +1466,10 @@ html|span.ac-emphasize-text-url {
color: hsl(210, 80%, 40%);
}
.ac-tags-text[selected] > html|span.ac-tag > html|span.ac-emphasize-text-tag {
color: hsl(210, 80%, 52%);
html|span.ac-emphasize-text-title,
html|span.ac-emphasize-text-tag,
html|span.ac-emphasize-text-url {
font-weight: 600;
}
@media not all and (-moz-windows-default-theme) {
@ -1490,26 +1477,22 @@ html|span.ac-emphasize-text-url {
background-color: Highlight;
}
.ac-title,
html|span.ac-emphasize-text-title {
.ac-title {
color: inherit;
}
html|span.ac-tag,
html|span.ac-emphasize-text-tag {
html|span.ac-tag {
background-color: -moz-FieldText;
color: -moz-Field;
}
.ac-separator,
.ac-url,
.ac-action,
html|span.ac-emphasize-text-url {
.ac-action {
color: -moz-nativehyperlinktext;
}
.ac-tags-text[selected] > html|span.ac-tag,
.ac-tags-text[selected] > html|span.ac-tag > html|span.ac-emphasize-text-tag {
.ac-tags-text[selected] > html|span.ac-tag {
background-color: HighlightText;
color: Highlight;
}

Просмотреть файл

@ -68,9 +68,9 @@ function testEventListeners(aThreadClient) {
return;
}
// There are 4 event listeners in the page: button.onclick, window.onload
// and two more from the video element controls.
is(aPacket.listeners.length, 4, "Found all event listeners.");
// There are 3 event listeners in the page: button.onclick, window.onload
// and one more from the video element controls.
is(aPacket.listeners.length, 3, "Found all event listeners.");
aThreadClient.resume(deferred.resolve);
});

Просмотреть файл

@ -20,6 +20,9 @@ const TEST_URI = `
<p>Empty<p>
<h1 class="asd@@@@a!!!!:::@asd">Invalid characters in class</h1>
<h2 id="asd@@@a!!2a">Invalid characters in id</h2>
<svg viewBox="0 0 10 10">
<circle cx="5" cy="5" r="5" fill="blue"></circle>
</svg>
`;
const TEST_DATA = [
@ -29,7 +32,8 @@ const TEST_DATA = [
{ node: ".class3.class4", expected: ".class3.class4" },
{ node: "p", expected: "p" },
{ node: "h1", expected: ".asd\\@\\@\\@\\@a\\!\\!\\!\\!\\:\\:\\:\\@asd" },
{ node: "h2", expected: "#asd\\@\\@\\@a\\!\\!2a" }
{ node: "h2", expected: "#asd\\@\\@\\@a\\!\\!2a" },
{ node: "circle", expected: "circle" }
];
add_task(function* () {

Просмотреть файл

@ -147,8 +147,7 @@ function BrowserLoaderBuilder({ baseURI, window, useOnlyShared }) {
const proxy = createProxy(exports);
componentProxies.set(uri, proxy);
module.exports = proxy.get();
}
else {
} else {
const proxy = componentProxies.get(uri);
const instances = proxy.update(exports);
instances.forEach(getForceUpdate(React));

Просмотреть файл

@ -4,7 +4,6 @@
"use strict";
const { Ci, Cc } = require("chrome");
const { getJSON } = require("devtools/client/shared/getjson");
const Services = require("Services");
const promise = require("promise");

Просмотреть файл

@ -28,9 +28,8 @@ function findSourceDir(path) {
).then(exists => {
if (exists) {
return path;
} else {
return findSourceDir(OS.Path.dirname(path));
}
return findSourceDir(OS.Path.dirname(path));
});
}
@ -56,7 +55,8 @@ const onPrefChange = function () {
const searchPoint = OS.Path.dirname(OS.Path.dirname(devtoolsPath));
findSourceDir(searchPoint)
.then(srcPath => {
const rootPath = srcPath ? OS.Path.join(srcPath, "devtools") : devtoolsPath;
const rootPath = srcPath ? OS.Path.join(srcPath, "devtools")
: devtoolsPath;
const watchPath = OS.Path.join(rootPath, "client");
const { watchFiles } = require("devtools/client/shared/file-watcher");
worker = watchFiles(watchPath, path => {
@ -69,6 +69,7 @@ const onPrefChange = function () {
worker = null;
}
};
Services.prefs.addObserver(HOTRELOAD_PREF, {
observe: onPrefChange
}, false);

Просмотреть файл

@ -37,7 +37,9 @@ var TYPES = {
// in Beta releases. Only displayed once per profile.
deveditionpromo: {
predicate: shouldDevEditionPromoShow,
success: () => Services.prefs.setBoolPref(DEV_EDITION_PROMO_SHOWN_PREF, true),
success: () => {
return Services.prefs.setBoolPref(DEV_EDITION_PROMO_SHOWN_PREF, true);
},
action: () => {
let url = Services.prefs.getCharPref(DEV_EDITION_PROMO_URL_PREF);
getGBrowser().selectedTab = getGBrowser().addTab(url);
@ -63,10 +65,11 @@ var panelAttrs = {
* @param {XULWindow} window
* The window that should house the doorhanger.
* @param {String} type
* The type of doorhanger to be displayed is, using the `TYPES` definition.
* The type of doorhanger to be displayed is, using the `TYPES`
* definition.
* @param {String} selector
* The selector that the doorhanger should be appended to within `window`.
* Defaults to a XUL Document's `window` element.
* The selector that the doorhanger should be appended to within
* `window`. Defaults to a XUL Document's `window` element.
*/
exports.showDoorhanger = Task.async(function* ({ window, type, anchor }) {
let { predicate, success, url, action } = TYPES[type];
@ -118,7 +121,9 @@ exports.showDoorhanger = Task.async(function* ({ window, type, anchor }) {
});
function setDoorhangerStyle(panel, frame) {
Object.keys(panelAttrs).forEach(prop => panel.setAttribute(prop, panelAttrs[prop]));
Object.keys(panelAttrs).forEach(prop => {
return panel.setAttribute(prop, panelAttrs[prop]);
});
panel.style.margin = "20px";
panel.style.borderRadius = "5px";
panel.style.border = "none";

Просмотреть файл

@ -79,4 +79,3 @@ onmessage = function (event) {
});
}, 1000);
};

Просмотреть файл

@ -3,8 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Ci, ChromeWorker } = require("chrome");
const Services = require("Services");
const { ChromeWorker } = require("chrome");
function watchFiles(path, onFileChanged) {
const watchWorker = new ChromeWorker(
@ -16,8 +15,8 @@ function watchFiles(path, onFileChanged) {
// chrome). This means that this system will only work when built
// files are symlinked, so that these URIs actually read from
// local sources. There might be a better way to do this.
const { path } = event.data;
onFileChanged(path);
const { newPath } = event.data;
onFileChanged(newPath);
};
watchWorker.postMessage({

Просмотреть файл

@ -2,6 +2,8 @@
* 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/. */
/* eslint-env browser */
/* global addMessageListener, sendAsyncMessage, content */
"use strict";
var {classes: Cc, interfaces: Ci, utils: Cu} = Components;
const {require, loader} = Cu.import("resource://devtools/shared/Loader.jsm", {});
@ -25,7 +27,8 @@ addMessageListener("devtools:test:reload", function ({ data }) {
content.location.reload(data.forceget);
});
addMessageListener("devtools:test:console", function ({ data: { method, args, id } }) {
addMessageListener("devtools:test:console", function ({ data }) {
let { method, args, id } = data;
content.console[method].apply(content.console, args);
sendAsyncMessage("devtools:test:console:response", { id });
});
@ -79,8 +82,9 @@ function promiseXHR(data) {
/**
* Performs XMLHttpRequest request(s) in the context of the page. The data
* parameter can be either a single object or an array of objects described below.
* The requests will be performed one at a time in the order they appear in the data.
* parameter can be either a single object or an array of objects described
* below. The requests will be performed one at a time in the order they appear
* in the data.
*
* The objects should have following form (any of them can be omitted; defaults
* shown below):
@ -115,7 +119,8 @@ addMessageListener("devtools:test:xhr", Task.async(function* ({ data }) {
sendAsyncMessage("devtools:test:xhr", responses);
}));
addMessageListener("devtools:test:profiler", function ({ data: { method, args, id }}) {
addMessageListener("devtools:test:profiler", function ({ data }) {
let { method, args, id } = data;
let result = nsIProfilerModule[method](...args);
sendAsyncMessage("devtools:test:profiler:response", {
data: result,
@ -123,7 +128,6 @@ addMessageListener("devtools:test:profiler", function ({ data: { method, args, i
});
});
// To eval in content, look at `evalInDebuggee` in the shared-head.js.
addMessageListener("devtools:test:eval", function ({ data }) {
sendAsyncMessage("devtools:test:eval:response", {
@ -190,14 +194,13 @@ function superQuerySelector(superSelector, root = content.document) {
let frameIndex = superSelector.indexOf("||");
if (frameIndex === -1) {
return root.querySelector(superSelector);
} else {
let rootSelector = superSelector.substring(0, frameIndex).trim();
let childSelector = superSelector.substring(frameIndex + 2).trim();
root = root.querySelector(rootSelector);
if (!root || !root.contentWindow) {
return null;
}
return superQuerySelector(childSelector, root.contentWindow.document);
}
let rootSelector = superSelector.substring(0, frameIndex).trim();
let childSelector = superSelector.substring(frameIndex + 2).trim();
root = root.querySelector(rootSelector);
if (!root || !root.contentWindow) {
return null;
}
return superQuerySelector(childSelector, root.contentWindow.document);
}

Просмотреть файл

@ -2,7 +2,9 @@
* 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/. */
const {Cu, CC} = require("chrome");
"use strict";
const {CC} = require("chrome");
const promise = require("promise");
const Services = require("Services");
@ -15,7 +17,9 @@ exports.getJSON = function (prefName, bypassCache) {
let str = Services.prefs.getCharPref(prefName + "_cache");
let json = JSON.parse(str);
return promise.resolve(json);
} catch (e) {/* no pref or invalid json. Let's continue */}
} catch (e) {
// no pref or invalid json. Let's continue
}
}
let deferred = promise.defer();
@ -29,7 +33,7 @@ exports.getJSON = function (prefName, bypassCache) {
return deferred.reject("Invalid JSON");
}
Services.prefs.setCharPref(prefName + "_cache", xhr.responseText);
deferred.resolve(json);
return deferred.resolve(json);
};
xhr.onerror = (e) => {

Просмотреть файл

@ -43,7 +43,7 @@ const FOCUS_FORWARD = Ci.nsIFocusManager.MOVEFOCUS_FORWARD;
const FOCUS_BACKWARD = Ci.nsIFocusManager.MOVEFOCUS_BACKWARD;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://devtools/shared/event-emitter.js");
const EventEmitter = require("devtools/shared/event-emitter");
const { findMostRelevantCssPropertyIndex } = require("./suggestion-picker");
/**
@ -628,7 +628,9 @@ InplaceEditor.prototype = {
* 'type'.
*/
_parseCSSValue: function (value, offset) {
/* eslint-disable max-len */
const reSplitCSS = /(url\("?[^"\)]+"?\)?)|(rgba?\([^)]*\)?)|(hsla?\([^)]*\)?)|(#[\dA-Fa-f]+)|(-?\d*\.?\d+(%|[a-z]{1,4})?)|"([^"]*)"?|'([^']*)'?|([^,\s\/!\(\)]+)|(!(.*)?)/;
/* eslint-enable */
let start = 0;
let m;

Просмотреть файл

@ -174,7 +174,8 @@ KeyShortcuts.prototype = {
on(key, listener) {
if (typeof listener !== "function") {
throw new Error("KeyShortcuts.on() expects a function as second argument");
throw new Error("KeyShortcuts.on() expects a function as " +
"second argument");
}
if (!this.keys.has(key)) {
let shortcut = KeyShortcuts.parseElectronKey(this.window, key);

Просмотреть файл

@ -16,7 +16,8 @@ function LocalizationHelper(stringBundleName) {
loader.lazyGetter(this, "stringBundle", () =>
Services.strings.createBundle(stringBundleName));
loader.lazyGetter(this, "ellipsis", () =>
Services.prefs.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString).data);
Services.prefs.getComplexValue("intl.ellipsis", Ci.nsIPrefLocalizedString)
.data);
}
LocalizationHelper.prototype = {
@ -51,8 +52,12 @@ LocalizationHelper.prototype = {
* @return string
*/
getFormatStrWithNumbers: function (name, ...args) {
let newArgs = args.map(x => typeof x == "number" ? this.numberWithDecimals(x, 2) : x);
return this.stringBundle.formatStringFromName(name, newArgs, newArgs.length);
let newArgs = args.map(x => {
return typeof x == "number" ? this.numberWithDecimals(x, 2) : x;
});
return this.stringBundle.formatStringFromName(name,
newArgs,
newArgs.length);
},
/**
@ -92,19 +97,22 @@ LocalizationHelper.prototype = {
};
/**
* A helper for having the same interface as LocalizationHelper, but for more than
* one file. Useful for abstracting l10n string locations.
* A helper for having the same interface as LocalizationHelper, but for more
* than one file. Useful for abstracting l10n string locations.
*/
function MultiLocalizationHelper(...stringBundleNames) {
let instances = stringBundleNames.map(bundle => new LocalizationHelper(bundle));
let instances = stringBundleNames.map(bundle => {
return new LocalizationHelper(bundle);
});
// Get all function members of the LocalizationHelper class, making sure we're not
// executing any potential getters while doing so, and wrap all the
// Get all function members of the LocalizationHelper class, making sure we're
// not executing any potential getters while doing so, and wrap all the
// methods we've found to work on all given string bundles.
Object.getOwnPropertyNames(LocalizationHelper.prototype)
.map(name => ({
name: name,
descriptor: Object.getOwnPropertyDescriptor(LocalizationHelper.prototype, name)
descriptor: Object.getOwnPropertyDescriptor(LocalizationHelper.prototype,
name)
}))
.filter(({ descriptor }) => descriptor.value instanceof Function)
.forEach(method => {
@ -112,8 +120,11 @@ function MultiLocalizationHelper(...stringBundleNames) {
for (let l10n of instances) {
try {
return method.descriptor.value.apply(l10n, args);
} catch (e) {}
} catch (e) {
// Do nothing
}
}
return null;
};
});
}

Просмотреть файл

@ -34,10 +34,10 @@ const TYPE_IDREF_LIST = "idrefList";
const TYPE_JS_RESOURCE_URI = "jsresource";
const TYPE_CSS_RESOURCE_URI = "cssresource";
const SVG_NS = "http://www.w3.org/2000/svg";
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const HTML_NS = "http://www.w3.org/1999/xhtml";
/* eslint-disable max-len */
const ATTRIBUTE_TYPES = [
{namespaceURI: HTML_NS, attributeName: "action", tagName: "form", type: TYPE_URI},
{namespaceURI: HTML_NS, attributeName: "background", tagName: "body", type: TYPE_URI},
@ -69,9 +69,11 @@ const ATTRIBUTE_TYPES = [
{namespaceURI: HTML_NS, attributeName: "href", tagName: "a", type: TYPE_URI},
{namespaceURI: HTML_NS, attributeName: "href", tagName: "area", type: TYPE_URI},
{namespaceURI: "*", attributeName: "href", tagName: "link", type: TYPE_CSS_RESOURCE_URI,
isValid: (namespaceURI, tagName, attributes) => {
return getAttribute(attributes, "rel") === "stylesheet";
}},
/* eslint-enable */
isValid: (namespaceURI, tagName, attributes) => {
return getAttribute(attributes, "rel") === "stylesheet";
}},
/* eslint-disable max-len */
{namespaceURI: "*", attributeName: "href", tagName: "link", type: TYPE_URI},
{namespaceURI: HTML_NS, attributeName: "href", tagName: "base", type: TYPE_URI},
{namespaceURI: HTML_NS, attributeName: "icon", tagName: "menuitem", type: TYPE_URI},
@ -115,6 +117,7 @@ const ATTRIBUTE_TYPES = [
{namespaceURI: XUL_NS, attributeName: "src", tagName: "stringbundle", type: TYPE_URI},
{namespaceURI: XUL_NS, attributeName: "template", tagName: "*", type: TYPE_IDREF},
{namespaceURI: XUL_NS, attributeName: "tooltip", tagName: "*", type: TYPE_IDREF},
/* eslint-enable */
// SVG links aren't handled yet, see bug 1158831.
// {namespaceURI: SVG_NS, attributeName: "fill", tagName: "*", type: },
// {namespaceURI: SVG_NS, attributeName: "stroke", tagName: "*", type: },
@ -188,7 +191,8 @@ var parsers = {
*/
function parseAttribute(namespaceURI, tagName, attributes, attributeName) {
if (!hasAttribute(attributes, attributeName)) {
throw new Error(`Attribute ${attributeName} isn't part of the provided attributes`);
throw new Error(`Attribute ${attributeName} isn't part of the ` +
"provided attributes");
}
let type = getType(namespaceURI, tagName, attributes, attributeName);
@ -214,17 +218,20 @@ function parseAttribute(namespaceURI, tagName, attributes, attributeName) {
*/
function getType(namespaceURI, tagName, attributes, attributeName) {
for (let typeData of ATTRIBUTE_TYPES) {
let hasAttribute = attributeName === typeData.attributeName ||
typeData.attributeName === "*";
let containsAttribute = attributeName === typeData.attributeName ||
typeData.attributeName === "*";
let hasNamespace = namespaceURI === typeData.namespaceURI ||
typeData.namespaceURI === "*";
let hasTagName = tagName.toLowerCase() === typeData.tagName ||
typeData.tagName === "*";
let isValid = typeData.isValid
? typeData.isValid(namespaceURI, tagName, attributes, attributeName)
? typeData.isValid(namespaceURI,
tagName,
attributes,
attributeName)
: true;
if (hasAttribute && hasNamespace && hasTagName && isValid) {
if (containsAttribute && hasNamespace && hasTagName && isValid) {
return typeData.type;
}
}
@ -242,7 +249,7 @@ function getAttribute(attributes, attributeName) {
}
function hasAttribute(attributes, attributeName) {
for (let {name, value} of attributes) {
for (let {name} of attributes) {
if (name === attributeName) {
return true;
}

Просмотреть файл

@ -1,3 +1,5 @@
"use strict";
const EventEmitter = require("devtools/shared/event-emitter");
const Services = require("Services");
const { Preferences } = require("resource://gre/modules/Preferences.jsm");
@ -10,9 +12,10 @@ const PREF_CHANGE_EVENT = "pref-changed";
* - branchName: The name of the prefs branch, like "devtools.debugger."
* - menupopup: The XUL `menupopup` item that contains the pref buttons.
*
* Fires an event, PREF_CHANGE_EVENT, with the preference name that changed as the second
* argument. Fires events on opening/closing the XUL panel (OPTIONS_SHOW_EVENT, OPTIONS_HIDDEN_EVENT)
* as the second argument in the listener, used for tests mostly.
* Fires an event, PREF_CHANGE_EVENT, with the preference name that changed as
* the second argument. Fires events on opening/closing the XUL panel
* (OPTIONS_SHOW_EVENT, OPTIONS_HIDDEN_EVENT) as the second argument in the
* listener, used for tests mostly.
*/
const OptionsView = function (options = {}) {
this.branchName = options.branchName;
@ -43,8 +46,8 @@ OptionsView.prototype = {
this._onPopupHidden = this._onPopupHidden.bind(this);
// We use a mutation observer instead of a click handler
// because the click handler is fired before the XUL menuitem updates
// it's checked status, which cascades incorrectly with the Preference observer.
// because the click handler is fired before the XUL menuitem updates its
// checked status, which cascades incorrectly with the Preference observer.
this.mutationObserver = new MutationObserver(this._onOptionChange);
let observerConfig = { attributes: true, attributeFilter: ["checked"]};

Просмотреть файл

@ -4,7 +4,7 @@
"use strict";
const {Cc, Ci, Cu} = require("chrome");
const {Cc, Ci} = require("chrome");
const {angleUtils} = require("devtools/client/shared/css-angle");
const {colorUtils} = require("devtools/client/shared/css-color");
const {getCSSLexer} = require("devtools/shared/css-lexer");
@ -398,7 +398,8 @@ OutputParser.prototype = {
style: "background-color:" + color
});
this.colorSwatches.set(swatch, colorObj);
swatch.addEventListener("mousedown", this._onColorSwatchMouseDown, false);
swatch.addEventListener("mousedown", this._onColorSwatchMouseDown,
false);
EventEmitter.decorate(swatch);
container.appendChild(swatch);
}

Просмотреть файл

@ -81,7 +81,8 @@ Poller.prototype.off = function pollerOff() {
/**
* Turns off polling and removes the reference to the poller function.
* Resolves when the last outstanding `fn` call finishes if it's an async function.
* Resolves when the last outstanding `fn` call finishes if it's an async
* function.
*/
Poller.prototype.destroy = function pollerDestroy() {
return this.off().then(() => {

Просмотреть файл

@ -61,7 +61,9 @@ function get(cache, prefType, prefsRoot, prefName) {
if (cachedPref !== undefined) {
return cachedPref;
}
let value = Services.prefs["get" + prefType + "Pref"]([prefsRoot, prefName].join("."));
let value = Services.prefs["get" + prefType + "Pref"](
[prefsRoot, prefName].join(".")
);
cache.set(prefName, value);
return value;
}
@ -76,7 +78,10 @@ function get(cache, prefType, prefsRoot, prefName) {
* @param any value
*/
function set(cache, prefType, prefsRoot, prefName, value) {
Services.prefs["set" + prefType + "Pref"]([prefsRoot, prefName].join("."), value);
Services.prefs["set" + prefType + "Pref"](
[prefsRoot, prefName].join("."),
value
);
cache.set(prefName, value);
}
@ -94,16 +99,24 @@ function set(cache, prefType, prefsRoot, prefName, value) {
* @param string prefName
* @param array serializer [optional]
*/
function map(self, cache, accessorName, prefType, prefsRoot, prefName, serializer = { in: e => e, out: e => e }) {
function map(self, cache, accessorName, prefType, prefsRoot, prefName,
serializer = { in: e => e, out: e => e }) {
if (prefName in self) {
throw new Error(`Can't use ${prefName} because it overrides a property on the instance.`);
throw new Error(`Can't use ${prefName} because it overrides a property` +
"on the instance.");
}
if (prefType == "Json") {
map(self, cache, accessorName, "Char", prefsRoot, prefName, { in: JSON.parse, out: JSON.stringify });
map(self, cache, accessorName, "Char", prefsRoot, prefName, {
in: JSON.parse,
out: JSON.stringify
});
return;
}
if (prefType == "Float") {
map(self, cache, accessorName, "Char", prefsRoot, prefName, { in: Number.parseFloat, out: (n) => n + ""});
map(self, cache, accessorName, "Char", prefsRoot, prefName, {
in: Number.parseFloat,
out: (n) => n + ""
});
return;
}

Просмотреть файл

@ -64,21 +64,24 @@ function parseURL(location) {
// `host`: "foo.com:8888"
//
// sdk/url does not match several definitions.: both `host` and `hostname`
// are actually the `hostname` (even though this is the `host` property on the
// original nsIURL, with `hostPort` representing the actual `host` name, AH!!!)
// So normalize all that garbage here.
// are actually the `hostname` (even though this is the `host` property on
// the original nsIURL, with `hostPort` representing the actual `host` name,
// AH!!!). So normalize all that garbage here.
let isChrome = isChromeScheme(location);
let fileName = url.fileName || "/";
let hostname = isChrome ? null : url.hostname;
let host = isChrome ? null :
url.port ? `${url.host}:${url.port}` :
url.host;
let hostname, host;
if (isChrome) {
hostname = null;
host = null;
} else {
hostname = url.hostname;
host = url.port ? `${url.host}:${url.port}` : url.host;
}
let parsed = Object.assign({}, url, { host, fileName, hostname });
gURLStore.set(location, parsed);
return parsed;
}
catch (e) {
} catch (e) {
gURLStore.set(location, null);
return null;
}
@ -88,12 +91,14 @@ function parseURL(location) {
* Parse a source into a short and long name as well as a host name.
*
* @param {String} source
* The source to parse. Can be a URI or names like "(eval)" or "self-hosted".
* The source to parse. Can be a URI or names like "(eval)" or
* "self-hosted".
* @return {Object}
* An object with the following properties:
* - {String} short: A short name for the source.
* - "http://page.com/test.js#go?q=query" -> "test.js"
* - {String} long: The full, long name for the source, with hash/query stripped.
* - {String} long: The full, long name for the source, with
hash/query stripped.
* - "http://page.com/test.js#go?q=query" -> "http://page.com/test.js"
* - {String?} host: If available, the host name for the source.
* - "http://page.com/test.js#go?q=query" -> "page.com"
@ -114,7 +119,7 @@ function getSourceNames(source) {
if (commaIndex > -1) {
// The `short` name for a data URI becomes `data:` followed by the actual
// encoded content, omitting the MIME type, and charset.
let short = `data:${sourceStr.substring(commaIndex + 1)}`.slice(0, 100);
short = `data:${sourceStr.substring(commaIndex + 1)}`.slice(0, 100);
let result = { short, long: sourceStr };
gSourceNamesStore.set(source, result);
return result;
@ -208,10 +213,11 @@ function isContentScheme(location, i = 0) {
let firstChar = location.charCodeAt(i);
switch (firstChar) {
case CHAR_CODE_H: // "http://" or "https://"
// "http://" or "https://"
case CHAR_CODE_H:
if (location.charCodeAt(++i) === CHAR_CODE_T &&
location.charCodeAt(++i) === CHAR_CODE_T &&
location.charCodeAt(++i) === CHAR_CODE_P) {
location.charCodeAt(++i) === CHAR_CODE_T &&
location.charCodeAt(++i) === CHAR_CODE_P) {
if (location.charCodeAt(i + 1) === CHAR_CODE_S) {
++i;
}
@ -219,17 +225,19 @@ function isContentScheme(location, i = 0) {
}
return false;
case CHAR_CODE_F: // "file://"
// "file://"
case CHAR_CODE_F:
if (location.charCodeAt(++i) === CHAR_CODE_I &&
location.charCodeAt(++i) === CHAR_CODE_L &&
location.charCodeAt(++i) === CHAR_CODE_E) {
location.charCodeAt(++i) === CHAR_CODE_L &&
location.charCodeAt(++i) === CHAR_CODE_E) {
return isColonSlashSlash(location, i);
}
return false;
case CHAR_CODE_A: // "app://"
// "app://"
case CHAR_CODE_A:
if (location.charCodeAt(++i) == CHAR_CODE_P &&
location.charCodeAt(++i) == CHAR_CODE_P) {
location.charCodeAt(++i) == CHAR_CODE_P) {
return isColonSlashSlash(location, i);
}
return false;
@ -243,36 +251,39 @@ function isChromeScheme(location, i = 0) {
let firstChar = location.charCodeAt(i);
switch (firstChar) {
case CHAR_CODE_C: // "chrome://"
// "chrome://"
case CHAR_CODE_C:
if (location.charCodeAt(++i) === CHAR_CODE_H &&
location.charCodeAt(++i) === CHAR_CODE_R &&
location.charCodeAt(++i) === CHAR_CODE_O &&
location.charCodeAt(++i) === CHAR_CODE_M &&
location.charCodeAt(++i) === CHAR_CODE_E) {
location.charCodeAt(++i) === CHAR_CODE_R &&
location.charCodeAt(++i) === CHAR_CODE_O &&
location.charCodeAt(++i) === CHAR_CODE_M &&
location.charCodeAt(++i) === CHAR_CODE_E) {
return isColonSlashSlash(location, i);
}
return false;
case CHAR_CODE_R: // "resource://"
// "resource://"
case CHAR_CODE_R:
if (location.charCodeAt(++i) === CHAR_CODE_E &&
location.charCodeAt(++i) === CHAR_CODE_S &&
location.charCodeAt(++i) === CHAR_CODE_O &&
location.charCodeAt(++i) === CHAR_CODE_U &&
location.charCodeAt(++i) === CHAR_CODE_R &&
location.charCodeAt(++i) === CHAR_CODE_C &&
location.charCodeAt(++i) === CHAR_CODE_E) {
location.charCodeAt(++i) === CHAR_CODE_S &&
location.charCodeAt(++i) === CHAR_CODE_O &&
location.charCodeAt(++i) === CHAR_CODE_U &&
location.charCodeAt(++i) === CHAR_CODE_R &&
location.charCodeAt(++i) === CHAR_CODE_C &&
location.charCodeAt(++i) === CHAR_CODE_E) {
return isColonSlashSlash(location, i);
}
return false;
case CHAR_CODE_J: // "jar:file://"
// "jar:file://"
case CHAR_CODE_J:
if (location.charCodeAt(++i) === CHAR_CODE_A &&
location.charCodeAt(++i) === CHAR_CODE_R &&
location.charCodeAt(++i) === CHAR_CODE_COLON &&
location.charCodeAt(++i) === CHAR_CODE_F &&
location.charCodeAt(++i) === CHAR_CODE_I &&
location.charCodeAt(++i) === CHAR_CODE_L &&
location.charCodeAt(++i) === CHAR_CODE_E) {
location.charCodeAt(++i) === CHAR_CODE_R &&
location.charCodeAt(++i) === CHAR_CODE_COLON &&
location.charCodeAt(++i) === CHAR_CODE_F &&
location.charCodeAt(++i) === CHAR_CODE_I &&
location.charCodeAt(++i) === CHAR_CODE_L &&
location.charCodeAt(++i) === CHAR_CODE_E) {
return isColonSlashSlash(location, i);
}
return false;

Просмотреть файл

@ -39,6 +39,8 @@
* telemetry.mozilla.org.
*/
"use strict";
const TOOLS_OPENED_PREF = "devtools.telemetry.tools.opened.version";
this.Telemetry = function () {

Просмотреть файл

@ -2,6 +2,8 @@
* 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/. */
/* eslint-env browser */
"use strict";
(function () {
const SCROLLBARS_URL = "chrome://devtools/skin/floating-scrollbars-dark-theme.css";
let documentElement = document.documentElement;
@ -33,10 +35,13 @@
// required then as scrollbars would be in their state without flushing.
return;
}
let display = computedStyle.display; // Save display value
// Save display value
let display = computedStyle.display;
documentElement.style.display = "none";
window.getComputedStyle(documentElement).display; // Flush
documentElement.style.display = display; // Restore
// Flush
window.getComputedStyle(documentElement).display;
// Restore
documentElement.style.display = display;
}
/*

Просмотреть файл

@ -9,7 +9,7 @@
* https://developer.mozilla.org/en-US/docs/Tools/DevToolsColors
*/
const { Ci, Cu } = require("chrome");
const { Cu } = require("chrome");
const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
const Services = require("Services");
const { gDevTools } = require("devtools/client/framework/devtools");
@ -32,7 +32,9 @@ function readURI(uri) {
).open();
let count = stream.available();
let data = NetUtil.readInputStreamToString(stream, count, { charset: "UTF-8" });
let data = NetUtil.readInputStreamToString(stream, count, {
charset: "UTF-8"
});
stream.close();
return data;
}
@ -48,7 +50,7 @@ function getThemeFile(name) {
// If there's no theme expected for this name, use `light` as default.
let selector = THEME_SELECTOR_STRINGS[name] ||
THEME_SELECTOR_STRINGS["light"];
THEME_SELECTOR_STRINGS.light;
// This is a pretty naive way to find the contents between:
// selector {
@ -67,14 +69,17 @@ function getThemeFile(name) {
* Returns the string value of the current theme,
* like "dark" or "light".
*/
const getTheme = exports.getTheme = () => Services.prefs.getCharPref("devtools.theme");
const getTheme = exports.getTheme = () => {
return Services.prefs.getCharPref("devtools.theme");
};
/**
* Returns a color indicated by `type` (like "toolbar-background", or "highlight-red"),
* with the ability to specify a theme, or use whatever the current theme is
* if left unset. If theme not found, falls back to "light" theme. Returns null
* if the type cannot be found for the theme given.
* Returns a color indicated by `type` (like "toolbar-background", or
* "highlight-red"), with the ability to specify a theme, or use whatever the
* current theme is if left unset. If theme not found, falls back to "light"
* theme. Returns null if the type cannot be found for the theme given.
*/
/* eslint-disable no-unused-vars */
const getColor = exports.getColor = (type, theme) => {
let themeName = theme || getTheme();
let themeFile = getThemeFile(themeName);
@ -99,3 +104,4 @@ const setTheme = exports.setTheme = (newTheme) => {
oldValue: oldTheme
});
};
/* eslint-enable */

Просмотреть файл

@ -4,21 +4,19 @@
* 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";
/**
* A simple undo stack manager.
*
* Actions are added along with the necessary code to
* reverse the action.
*
* @param function aChange Called whenever the size or position
* of the undo stack changes, to use for updating undo-related
* UI.
* @param integer aMaxUndo Maximum number of undo steps.
* @param integer maxUndo Maximum number of undo steps.
* defaults to 50.
*/
function UndoStack(aMaxUndo)
{
this.maxUndo = aMaxUndo || 50;
function UndoStack(maxUndo) {
this.maxUndo = maxUndo || 50;
this._stack = [];
}
@ -32,8 +30,7 @@ UndoStack.prototype = {
// The current batch depth (see startBatch() for details)
_batchDepth: 0,
destroy: function Undo_destroy()
{
destroy: function () {
this.uninstallController();
delete this._stack;
},
@ -47,8 +44,7 @@ UndoStack.prototype = {
* actions made up of a collection of smaller actions to be
* undone as a single action.
*/
startBatch: function Undo_startBatch()
{
startBatch: function () {
if (this._batchDepth++ === 0) {
this._batch = [];
}
@ -58,8 +54,7 @@ UndoStack.prototype = {
* End a batch of related changes, performing its action and adding
* it to the undo stack.
*/
endBatch: function Undo_endBatch()
{
endBatch: function () {
if (--this._batchDepth > 0) {
return;
}
@ -92,20 +87,19 @@ UndoStack.prototype = {
/**
* Perform an action, adding it to the undo stack.
*
* @param function aDo Called to perform the action.
* @param function aUndo Called to reverse the action.
* @param function toDo Called to perform the action.
* @param function undo Called to reverse the action.
*/
do: function Undo_do(aDo, aUndo) {
do: function (toDo, undo) {
this.startBatch();
this._batch.push({ do: aDo, undo: aUndo });
this._batch.push({ do: toDo, undo });
this.endBatch();
},
/*
* Returns true if undo() will do anything.
*/
canUndo: function Undo_canUndo()
{
canUndo: function () {
return this._index > 0;
},
@ -114,8 +108,7 @@ UndoStack.prototype = {
*
* @return true if an action was undone.
*/
undo: function Undo_canUndo()
{
undo: function () {
if (!this.canUndo()) {
return false;
}
@ -127,8 +120,7 @@ UndoStack.prototype = {
/**
* Returns true if redo() will do anything.
*/
canRedo: function Undo_canRedo()
{
canRedo: function () {
return this._stack.length > this._index;
},
@ -137,8 +129,7 @@ UndoStack.prototype = {
*
* @return true if an action was redone.
*/
redo: function Undo_canRedo()
{
redo: function () {
if (!this.canRedo()) {
return false;
}
@ -147,8 +138,7 @@ UndoStack.prototype = {
return true;
},
_change: function Undo__change()
{
_change: function () {
if (this._controllerWindow) {
this._controllerWindow.goUpdateCommand("cmd_undo");
this._controllerWindow.goUpdateCommand("cmd_redo");
@ -162,45 +152,41 @@ UndoStack.prototype = {
/**
* Install this object as a command controller.
*/
installController: function Undo_installController(aControllerWindow)
{
this._controllerWindow = aControllerWindow;
aControllerWindow.controllers.appendController(this);
installController: function (controllerWindow) {
this._controllerWindow = controllerWindow;
controllerWindow.controllers.appendController(this);
},
/**
* Uninstall this object from the command controller.
*/
uninstallController: function Undo_uninstallController()
{
uninstallController: function () {
if (!this._controllerWindow) {
return;
}
this._controllerWindow.controllers.removeController(this);
},
supportsCommand: function Undo_supportsCommand(aCommand)
{
return (aCommand == "cmd_undo" ||
aCommand == "cmd_redo");
supportsCommand: function (command) {
return (command == "cmd_undo" ||
command == "cmd_redo");
},
isCommandEnabled: function Undo_isCommandEnabled(aCommand)
{
switch (aCommand) {
isCommandEnabled: function (command) {
switch (command) {
case "cmd_undo": return this.canUndo();
case "cmd_redo": return this.canRedo();
}
return false;
},
doCommand: function Undo_doCommand(aCommand)
{
switch (aCommand) {
doCommand: function (command) {
switch (command) {
case "cmd_undo": return this.undo();
case "cmd_redo": return this.redo();
default: return null;
}
},
onEvent: function Undo_onEvent(aEvent) {},
onEvent: function (event) {},
};

Просмотреть файл

@ -8,14 +8,13 @@ var { Task } = require("devtools/shared/task");
var Services = require("Services");
var {gDevTools} = require("devtools/client/framework/devtools");
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
/**
* Tries to open a Stylesheet file in the Style Editor. If the file is not found,
* it is opened in source view instead.
* Tries to open a Stylesheet file in the Style Editor. If the file is not
* found, it is opened in source view instead.
* Returns a promise resolving to a boolean indicating whether or not
* the source was able to be displayed in the StyleEditor, as the built-in Firefox
* View Source is the fallback.
* the source was able to be displayed in the StyleEditor, as the built-in
* Firefox View Source is the fallback.
*
* @param {Toolbox} toolbox
* @param {string} sourceURL
@ -23,7 +22,8 @@ var DevToolsUtils = require("devtools/shared/DevToolsUtils");
*
* @return {Promise<boolean>}
*/
exports.viewSourceInStyleEditor = Task.async(function* (toolbox, sourceURL, sourceLine) {
exports.viewSourceInStyleEditor = Task.async(function* (toolbox, sourceURL,
sourceLine) {
let panel = yield toolbox.loadTool("styleeditor");
try {
@ -49,7 +49,8 @@ exports.viewSourceInStyleEditor = Task.async(function* (toolbox, sourceURL, sour
*
* @return {Promise<boolean>}
*/
exports.viewSourceInDebugger = Task.async(function* (toolbox, sourceURL, sourceLine) {
exports.viewSourceInDebugger = Task.async(function* (toolbox, sourceURL,
sourceLine) {
// If the Debugger was already open, switch to it and try to show the
// source immediately. Otherwise, initialize it and wait for the sources
// to be added first.
@ -66,8 +67,11 @@ exports.viewSourceInDebugger = Task.async(function* (toolbox, sourceURL, sourceL
let item = Sources.getItemForAttachment(a => a.source.url === sourceURL);
if (item) {
yield toolbox.selectTool("jsdebugger");
const isLoading = dbg.DebuggerController.getState().sources.selectedSource !== item.attachment.source.actor;
DebuggerView.setEditorLocation(item.attachment.source.actor, sourceLine, { noDebug: true });
const isLoading = dbg.DebuggerController.getState().sources.selectedSource
!== item.attachment.source.actor;
DebuggerView.setEditorLocation(item.attachment.source.actor, sourceLine, {
noDebug: true
});
if (isLoading) {
yield dbg.DebuggerController.waitForSourceShown(sourceURL);
}
@ -138,4 +142,5 @@ exports.viewSource = Task.async(function* (toolbox, sourceURL, sourceLine) {
}
let utils = toolbox.gViewSourceUtils;
utils.viewSource(sourceURL, null, toolbox.doc, sourceLine || 0);
return null;
});

Просмотреть файл

@ -8,13 +8,11 @@ const Services = require("Services");
const WEBGL_CONTEXT_NAME = "experimental-webgl";
function isWebGLForceEnabled()
{
function isWebGLForceEnabled() {
return Services.prefs.getBoolPref("webgl.force-enabled");
}
function isWebGLSupportedByGFX()
{
function isWebGLSupportedByGFX() {
let supported = false;
try {
@ -31,12 +29,11 @@ function isWebGLSupportedByGFX()
return supported;
}
function create3DContext(aCanvas)
{
function create3DContext(canvas) {
// try to get a valid context from an existing canvas
let context = null;
try {
context = aCanvas.getContext(WEBGL_CONTEXT_NAME, aFlags);
context = canvas.getContext(WEBGL_CONTEXT_NAME, {});
} catch (e) {
return null;
}

Просмотреть файл

@ -1,7 +1,5 @@
"use strict";
const { Cc, Ci, Cu, Cr } = require("chrome");
const { Heritage, setNamedTimeout, clearNamedTimeout } = require("devtools/client/shared/widgets/view-helpers");
const { AbstractCanvasGraph, CanvasGraphUtils } = require("devtools/client/shared/widgets/Graphs");
@ -10,10 +8,12 @@ const HTML_NS = "http://www.w3.org/1999/xhtml";
// Bar graph constants.
const GRAPH_DAMPEN_VALUES_FACTOR = 0.75;
const GRAPH_BARS_MARGIN_TOP = 1; // px
const GRAPH_BARS_MARGIN_END = 1; // px
const GRAPH_MIN_BARS_WIDTH = 5; // px
const GRAPH_MIN_BLOCKS_HEIGHT = 1; // px
// The following are in pixels
const GRAPH_BARS_MARGIN_TOP = 1;
const GRAPH_BARS_MARGIN_END = 1;
const GRAPH_MIN_BARS_WIDTH = 5;
const GRAPH_MIN_BLOCKS_HEIGHT = 1;
const GRAPH_BACKGROUND_GRADIENT_START = "rgba(0,136,204,0.0)";
const GRAPH_BACKGROUND_GRADIENT_END = "rgba(255,255,255,0.25)";
@ -28,7 +28,8 @@ const GRAPH_REGION_STRIPES_COLOR = "rgba(237,38,85,0.2)";
const GRAPH_HIGHLIGHTS_MASK_BACKGROUND = "rgba(255,255,255,0.75)";
const GRAPH_HIGHLIGHTS_MASK_STRIPES = "rgba(255,255,255,0.5)";
const GRAPH_LEGEND_MOUSEOVER_DEBOUNCE = 50; // ms
// in ms
const GRAPH_LEGEND_MOUSEOVER_DEBOUNCE = 50;
/**
* A bar graph, plotting tuples of values as rectangles.
@ -144,7 +145,8 @@ BarGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
*/
buildGraphImage: function () {
if (!this.format || !this.format.length) {
throw "The graph format traits are mandatory to style the data source.";
throw new Error("The graph format traits are mandatory to style " +
"the data source.");
}
let { canvas, ctx } = this._getNamedCanvas("bar-graph-data");
let width = this._width;
@ -260,7 +262,8 @@ BarGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
* @param function unpack [optional]
* @see AbstractCanvasGraph.prototype.getMappedSelection
*/
buildMaskImage: function (highlights, inPixels = false, unpack = e => e.delta) {
buildMaskImage: function (highlights, inPixels = false,
unpack = e => e.delta) {
// A null `highlights` array is used to clear the mask. An empty array
// will mask the entire graph.
if (!highlights) {
@ -295,11 +298,19 @@ BarGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
start = CanvasGraphUtils.map(start, firstTick, lastTick, 0, width);
end = CanvasGraphUtils.map(end, firstTick, lastTick, 0, width);
}
let firstSnap = findFirst(this._blocksBoundingRects, e => e.start >= start);
let lastSnap = findLast(this._blocksBoundingRects, e => e.start >= start && e.end <= end);
let firstSnap = findFirst(this._blocksBoundingRects,
e => e.start >= start);
let lastSnap = findLast(this._blocksBoundingRects,
e => e.start >= start && e.end <= end);
let x1 = firstSnap ? firstSnap.start : start;
let x2 = lastSnap ? lastSnap.end : firstSnap ? firstSnap.end : end;
let x2;
if (lastSnap) {
x2 = lastSnap.end;
} else {
x2 = firstSnap ? firstSnap.end : end;
}
let y1 = top || 0;
let y2 = bottom || height;
ctx.clearRect(x1, y1, x2 - x1, y2 - y1);
@ -357,7 +368,8 @@ BarGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
* Creates the legend container when constructing this graph.
*/
_createLegend: function () {
let legendNode = this._legendNode = this._document.createElementNS(HTML_NS, "div");
let legendNode = this._legendNode = this._document.createElementNS(HTML_NS,
"div");
legendNode.className = "bar-graph-widget-legend";
this._container.appendChild(legendNode);
},
@ -390,17 +402,21 @@ BarGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
/**
* Invoked whenever a color node in the legend is hovered.
*/
_onLegendMouseOver: function (e) {
setNamedTimeout("bar-graph-debounce", GRAPH_LEGEND_MOUSEOVER_DEBOUNCE, () => {
let type = e.target.dataset.index;
let rects = this._blocksBoundingRects.filter(e => e.type == type);
_onLegendMouseOver: function (ev) {
setNamedTimeout(
"bar-graph-debounce",
GRAPH_LEGEND_MOUSEOVER_DEBOUNCE,
() => {
let type = ev.target.dataset.index;
let rects = this._blocksBoundingRects.filter(e => e.type == type);
this._originalHighlights = this._mask;
this._hasCustomHighlights = true;
this.setMask(rects, true);
this._originalHighlights = this._mask;
this._hasCustomHighlights = true;
this.setMask(rects, true);
this.emit("legend-hover", [type, rects]);
});
this.emit("legend-hover", [type, rects]);
}
);
},
/**
@ -421,11 +437,11 @@ BarGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
/**
* Invoked whenever a color node in the legend is pressed.
*/
_onLegendMouseDown: function (e) {
e.preventDefault();
e.stopPropagation();
_onLegendMouseDown: function (ev) {
ev.preventDefault();
ev.stopPropagation();
let type = e.target.dataset.index;
let type = ev.target.dataset.index;
let rects = this._blocksBoundingRects.filter(e => e.type == type);
let leftmost = rects[0];
let rightmost = rects[rects.length - 1];
@ -456,8 +472,11 @@ BarGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
function findFirst(array, predicate) {
for (let i = 0, len = array.length; i < len; i++) {
let element = array[i];
if (predicate(element)) return element;
if (predicate(element)) {
return element;
}
}
return null;
}
/**
@ -469,8 +488,11 @@ function findFirst(array, predicate) {
function findLast(array, predicate) {
for (let i = array.length - 1; i >= 0; i--) {
let element = array[i];
if (predicate(element)) return element;
if (predicate(element)) {
return element;
}
}
return null;
}
module.exports = BarGraphWidget;

Просмотреть файл

@ -32,7 +32,6 @@ const {
DEFAULT_PRESET_CATEGORY
} = require("devtools/client/shared/widgets/CubicBezierPresets");
const {getCSSLexer} = require("devtools/shared/css-lexer");
const {Cc, Ci} = require("chrome");
/**
* CubicBezier data structure helper
@ -114,10 +113,12 @@ BezierCanvas.prototype = {
return [{
left: w * (this.bezier.coordinates[0] * (1 - p[3] - p[1]) - p[3]) + "px",
top: h * (1 - this.bezier.coordinates[1] * (1 - p[0] - p[2]) - p[0]) + "px"
top: h * (1 - this.bezier.coordinates[1] * (1 - p[0] - p[2]) - p[0])
+ "px"
}, {
left: w * (this.bezier.coordinates[2] * (1 - p[3] - p[1]) - p[3]) + "px",
top: h * (1 - this.bezier.coordinates[3] * (1 - p[0] - p[2]) - p[0]) + "px"
top: h * (1 - this.bezier.coordinates[3] * (1 - p[0] - p[2]) - p[0])
+ "px"
}];
},
@ -400,7 +401,9 @@ CubicBezierWidget.prototype = {
_updateFromPoints: function () {
// Get the new coordinates from the point's offsets
let coordinates = this.bezierCanvas.offsetsToCoordinates(this.p1);
coordinates = coordinates.concat(this.bezierCanvas.offsetsToCoordinates(this.p2));
coordinates = coordinates.concat(
this.bezierCanvas.offsetsToCoordinates(this.p2)
);
this.presets.refreshMenu(coordinates);
this._redraw(coordinates);
@ -602,7 +605,8 @@ CubicBezierPresetWidget.prototype = {
// Create preset label
let presetLabelElem = doc.createElement("p");
let presetDisplayLabel = this._normalizePresetLabel(categoryLabel, presetLabel);
let presetDisplayLabel = this._normalizePresetLabel(categoryLabel,
presetLabel);
presetLabelElem.textContent = presetDisplayLabel;
preset.appendChild(presetLabelElem);
preset.setAttribute("title", presetDisplayLabel);
@ -759,7 +763,7 @@ TimingFunctionPreviewWidget.prototype = {
preview: function (value) {
// Don't restart the preview animation if the value is the same
if (value === this.previousValue) {
return false;
return;
}
clearTimeout(this.autoRestartAnimation);
@ -781,7 +785,6 @@ TimingFunctionPreviewWidget.prototype = {
// Just toggling the class won't do it unless there's a sync reflow
this.dot.classList.remove("animate");
let w = this.dot.offsetWidth;
this.dot.classList.add("animate");
// Restart it again after a while

Просмотреть файл

@ -6,7 +6,6 @@
"use strict";
const EventEmitter = require("devtools/shared/event-emitter");
const { Cu, Ci } = require("chrome");
const { ViewHelpers } = require("devtools/client/shared/widgets/view-helpers");
/**
@ -18,10 +17,10 @@ const { ViewHelpers } = require("devtools/client/shared/widgets/view-helpers");
* @param nsIDOMNode aNode
* The element associated with the widget.
*/
const FastListWidget = module.exports = function FastListWidget(aNode) {
this.document = aNode.ownerDocument;
const FastListWidget = module.exports = function FastListWidget(node) {
this.document = node.ownerDocument;
this.window = this.document.defaultView;
this._parent = aNode;
this._parent = node;
this._fragment = this.document.createDocumentFragment();
// This is a prototype element that each item added to the list clones.
@ -34,7 +33,8 @@ const FastListWidget = module.exports = function FastListWidget(aNode) {
this._list.setAttribute("orient", "vertical");
this._list.setAttribute("tabindex", "0");
this._list.addEventListener("keypress", e => this.emit("keyPress", e), false);
this._list.addEventListener("mousedown", e => this.emit("mousePress", e), false);
this._list.addEventListener("mousedown", e => this.emit("mousePress", e),
false);
this._parent.appendChild(this._list);
this._orderedMenuElementsArray = [];
@ -45,8 +45,8 @@ const FastListWidget = module.exports = function FastListWidget(aNode) {
// Delegate some of the associated node's methods to satisfy the interface
// required by MenuContainer instances.
ViewHelpers.delegateWidgetAttributeMethods(this, aNode);
ViewHelpers.delegateWidgetEventMethods(this, aNode);
ViewHelpers.delegateWidgetAttributeMethods(this, node);
ViewHelpers.delegateWidgetEventMethods(this, node);
};
FastListWidget.prototype = {
@ -63,11 +63,11 @@ FastListWidget.prototype = {
* @return nsIDOMNode
* The element associated with the displayed item.
*/
insertItemAt: function (aIndex, aContents, aAttachment = {}) {
insertItemAt: function (index, contents, attachment = {}) {
let element = this._templateElement.cloneNode();
element.appendChild(aContents);
element.appendChild(contents);
if (aIndex >= 0) {
if (index >= 0) {
throw new Error("FastListWidget only supports appending items.");
}
@ -91,7 +91,6 @@ FastListWidget.prototype = {
* Removes all of the child nodes from this container.
*/
removeAllItems: function () {
let parent = this._parent;
let list = this._list;
while (list.hasChildNodes()) {
@ -204,11 +203,11 @@ FastListWidget.prototype = {
* Sets the text displayed in this container when empty.
* @param string aValue
*/
set _textWhenEmpty(aValue) {
set _textWhenEmpty(value) {
if (this._emptyTextNode) {
this._emptyTextNode.setAttribute("value", aValue);
this._emptyTextNode.setAttribute("value", value);
}
this._emptyTextValue = aValue;
this._emptyTextValue = value;
this._showEmptyText();
},

Просмотреть файл

@ -10,8 +10,7 @@
*/
const EventEmitter = require("devtools/shared/event-emitter");
const { Cu, Cc, Ci } = require("chrome");
const { ViewHelpers } = require("devtools/client/shared/widgets/view-helpers");
const { Cc, Ci } = require("chrome");
const { LocalizationHelper } = require("devtools/client/shared/l10n");
const STRINGS_URI = "chrome://devtools/locale/filterwidget.properties";
@ -539,7 +538,8 @@ CSSFilterEditorWidget.prototype = {
if (el.classList.contains("remove-button")) {
// If the click happened on the remove button.
presets.splice(id, 1);
this.setPresets(presets).then(this.renderPresets, e => console.error(e));
this.setPresets(presets).then(this.renderPresets,
ex => console.error(ex));
} else {
// Or if the click happened on a preset.
let p = presets[id];
@ -547,7 +547,7 @@ CSSFilterEditorWidget.prototype = {
this.setCssValue(p.value);
this.addPresetInput.value = p.name;
}
}, e => console.error(e));
}, ex => console.error(ex));
},
_togglePresets: function () {
@ -575,8 +575,9 @@ CSSFilterEditorWidget.prototype = {
presets.push({name, value});
}
this.setPresets(presets).then(this.renderPresets, e => console.error(e));
}, e => console.error(e));
this.setPresets(presets).then(this.renderPresets,
ex => console.error(ex));
}, ex => console.error(ex));
},
/**
@ -840,7 +841,7 @@ CSSFilterEditorWidget.prototype = {
removeAt: function (index) {
if (!this.filters[index]) {
return null;
return;
}
this.filters.splice(index, 1);

Просмотреть файл

@ -4,7 +4,7 @@
"use strict";
const { Task } = require("devtools/shared/task");
const { ViewHelpers, setNamedTimeout, clearNamedTimeout } = require("devtools/client/shared/widgets/view-helpers");
const { ViewHelpers, setNamedTimeout } = require("devtools/client/shared/widgets/view-helpers");
const { LocalizationHelper } = require("devtools/client/shared/l10n");
loader.lazyRequireGetter(this, "promise");
@ -28,12 +28,12 @@ loader.lazyRequireGetter(this, "GraphArea",
loader.lazyRequireGetter(this, "GraphAreaDragger",
"devtools/client/shared/widgets/Graphs", true);
const HTML_NS = "http://www.w3.org/1999/xhtml";
const GRAPH_SRC = "chrome://devtools/content/shared/widgets/graphs-frame.xhtml";
const L10N = new LocalizationHelper();
const GRAPH_RESIZE_EVENTS_DRAIN = 100; // ms
// ms
const GRAPH_RESIZE_EVENTS_DRAIN = 100;
const GRAPH_WHEEL_ZOOM_SENSITIVITY = 0.00035;
const GRAPH_WHEEL_SCROLL_SENSITIVITY = 0.5;
@ -41,31 +41,43 @@ const GRAPH_KEYBOARD_ZOOM_SENSITIVITY = 20;
const GRAPH_KEYBOARD_PAN_SENSITIVITY = 20;
const GRAPH_KEYBOARD_ACCELERATION = 1.05;
const GRAPH_KEYBOARD_TRANSLATION_MAX = 150;
const GRAPH_MIN_SELECTION_WIDTH = 0.001; // ms
const GRAPH_HORIZONTAL_PAN_THRESHOLD = 10; // px
const GRAPH_VERTICAL_PAN_THRESHOLD = 30; // px
// ms
const GRAPH_MIN_SELECTION_WIDTH = 0.001;
// px
const GRAPH_HORIZONTAL_PAN_THRESHOLD = 10;
const GRAPH_VERTICAL_PAN_THRESHOLD = 30;
const FIND_OPTIMAL_TICK_INTERVAL_MAX_ITERS = 100;
const TIMELINE_TICKS_MULTIPLE = 5; // ms
const TIMELINE_TICKS_SPACING_MIN = 75; // px
const OVERVIEW_HEADER_HEIGHT = 16; // px
const OVERVIEW_HEADER_TEXT_FONT_SIZE = 9; // px
// ms
const TIMELINE_TICKS_MULTIPLE = 5;
// px
const TIMELINE_TICKS_SPACING_MIN = 75;
// px
const OVERVIEW_HEADER_HEIGHT = 16;
const OVERVIEW_HEADER_TEXT_FONT_SIZE = 9;
const OVERVIEW_HEADER_TEXT_FONT_FAMILY = "sans-serif";
const OVERVIEW_HEADER_TEXT_PADDING_LEFT = 6; // px
const OVERVIEW_HEADER_TEXT_PADDING_TOP = 5; // px
// px
const OVERVIEW_HEADER_TEXT_PADDING_LEFT = 6;
const OVERVIEW_HEADER_TEXT_PADDING_TOP = 5;
const OVERVIEW_HEADER_TIMELINE_STROKE_COLOR = "rgba(128, 128, 128, 0.5)";
const FLAME_GRAPH_BLOCK_HEIGHT = 15; // px
const FLAME_GRAPH_BLOCK_BORDER = 1; // px
const FLAME_GRAPH_BLOCK_TEXT_FONT_SIZE = 10; // px
const FLAME_GRAPH_BLOCK_TEXT_FONT_FAMILY = "message-box, Helvetica Neue, Helvetica, sans-serif";
const FLAME_GRAPH_BLOCK_TEXT_PADDING_TOP = 0; // px
const FLAME_GRAPH_BLOCK_TEXT_PADDING_LEFT = 3; // px
const FLAME_GRAPH_BLOCK_TEXT_PADDING_RIGHT = 3; // px
// px
const FLAME_GRAPH_BLOCK_HEIGHT = 15;
const FLAME_GRAPH_BLOCK_BORDER = 1;
const FLAME_GRAPH_BLOCK_TEXT_FONT_SIZE = 10;
const FLAME_GRAPH_BLOCK_TEXT_FONT_FAMILY = "message-box, Helvetica Neue," +
"Helvetica, sans-serif";
// px
const FLAME_GRAPH_BLOCK_TEXT_PADDING_TOP = 0;
const FLAME_GRAPH_BLOCK_TEXT_PADDING_LEFT = 3;
const FLAME_GRAPH_BLOCK_TEXT_PADDING_RIGHT = 3;
const PALLETTE_SIZE = 20; // Large enough number for a diverse pallette.
// Large enough number for a diverse pallette.
const PALLETTE_SIZE = 20;
const PALLETTE_HUE_OFFSET = Math.random() * 90;
const PALLETTE_HUE_RANGE = 270;
const PALLETTE_SATURATION = 100;
@ -73,7 +85,8 @@ const PALLETTE_BRIGHTNESS = 55;
const PALLETTE_OPACITY = 0.35;
const COLOR_PALLETTE = Array.from(Array(PALLETTE_SIZE)).map((_, i) => "hsla" +
"(" + ((PALLETTE_HUE_OFFSET + (i / PALLETTE_SIZE * PALLETTE_HUE_RANGE)) | 0 % 360) +
"(" +
((PALLETTE_HUE_OFFSET + (i / PALLETTE_SIZE * PALLETTE_HUE_RANGE)) | 0 % 360) +
"," + PALLETTE_SATURATION + "%" +
"," + PALLETTE_BRIGHTNESS + "%" +
"," + PALLETTE_OPACITY +
@ -141,7 +154,8 @@ function FlameGraph(parent, sharpness) {
this._document = iframe.contentDocument;
this._pixelRatio = sharpness || this._window.devicePixelRatio;
let container = this._container = this._document.getElementById("graph-container");
let container =
this._container = this._document.getElementById("graph-container");
container.className = "flame-graph-widget-container graph-widget-container";
let canvas = this._canvas = this._document.getElementById("graph-canvas");
@ -201,7 +215,8 @@ function FlameGraph(parent, sharpness) {
let ownerWindow = this._parent.ownerDocument.defaultView;
ownerWindow.addEventListener("resize", this._onResize);
this._animationId = this._window.requestAnimationFrame(this._onAnimationFrame);
this._animationId =
this._window.requestAnimationFrame(this._onAnimationFrame);
this._ready.resolve(this);
this.emit("ready", this);
@ -415,8 +430,10 @@ FlameGraph.prototype = {
theme = theme || "light";
this.overviewHeaderBackgroundColor = getColor("body-background", theme);
this.overviewHeaderTextColor = getColor("body-color", theme);
// Hard to get a color that is readable across both themes for the text on the flames
this.blockTextColor = getColor(theme === "dark" ? "selection-color" : "body-color", theme);
// Hard to get a color that is readable across both themes for the text
// on the flames
this.blockTextColor = getColor(theme === "dark" ? "selection-color"
: "body-color", theme);
},
/**
@ -430,7 +447,8 @@ FlameGraph.prototype = {
* Animation frame callback, invoked on each tick of the refresh driver.
*/
_onAnimationFrame: function () {
this._animationId = this._window.requestAnimationFrame(this._onAnimationFrame);
this._animationId =
this._window.requestAnimationFrame(this._onAnimationFrame);
this._drawWidget();
},
@ -459,7 +477,8 @@ FlameGraph.prototype = {
let selectionWidth = selection.end - selection.start;
let selectionScale = canvasWidth / selectionWidth;
this._drawTicks(selection.start, selectionScale);
this._drawPyramid(this._data, this._verticalOffset, selection.start, selectionScale);
this._drawPyramid(this._data, this._verticalOffset,
selection.start, selectionScale);
this._drawHeader(selection.start, selectionScale);
// If the user isn't doing anything anymore, it's safe to stop drawing.
@ -467,7 +486,8 @@ FlameGraph.prototype = {
// if any input stops (e.g. smooth panning transitions after the user
// finishes input). We don't care about that right now.
if (this._userInputStack == 0) {
return void (this._shouldRedraw = false);
this._shouldRedraw = false;
return;
}
if (this._userInputStack < 0) {
throw new Error("The user went back in time from a pyramid.");
@ -489,7 +509,6 @@ FlameGraph.prototype = {
const KEY_CODE_D = 68;
let canvasWidth = this._width;
let canvasHeight = this._height;
let pressed = this._keysPressed;
let selection = this._selection;
@ -573,7 +592,11 @@ FlameGraph.prototype = {
ctx.fillStyle = this.overviewHeaderBackgroundColor;
ctx.fillRect(0, 0, canvasWidth, headerHeight);
this._drawTicks(dataOffset, dataScale, { from: 0, to: headerHeight, renderText: true });
this._drawTicks(dataOffset, dataScale, {
from: 0,
to: headerHeight,
renderText: true
});
},
/**
@ -604,7 +627,8 @@ FlameGraph.prototype = {
ctx.strokeStyle = OVERVIEW_HEADER_TIMELINE_STROKE_COLOR;
ctx.beginPath();
for (let x = -scaledOffset % tickInterval; x < canvasWidth; x += tickInterval) {
for (let x = -scaledOffset % tickInterval; x < canvasWidth;
x += tickInterval) {
let lineLeft = x;
let textLeft = lineLeft + textPaddingLeft;
let time = Math.round((x / dataScale + dataOffset) / this._pixelRatio);
@ -635,20 +659,23 @@ FlameGraph.prototype = {
let fontSize = FLAME_GRAPH_BLOCK_TEXT_FONT_SIZE * this._pixelRatio;
let fontFamily = FLAME_GRAPH_BLOCK_TEXT_FONT_FAMILY;
let visibleBlocksInfo = this._drawPyramidFill(dataSource, verticalOffset, dataOffset, dataScale);
let visibleBlocksInfo = this._drawPyramidFill(dataSource, verticalOffset,
dataOffset, dataScale);
ctx.textBaseline = "middle";
ctx.font = fontSize + "px " + fontFamily;
ctx.fillStyle = this.blockTextColor;
this._drawPyramidText(visibleBlocksInfo, verticalOffset, dataOffset, dataScale);
this._drawPyramidText(visibleBlocksInfo, verticalOffset,
dataOffset, dataScale);
},
/**
* Fills all block inside this graph's pyramid.
* @see FlameGraph.prototype._drawPyramid
*/
_drawPyramidFill: function (dataSource, verticalOffset, dataOffset, dataScale) {
_drawPyramidFill: function (dataSource, verticalOffset, dataOffset,
dataScale) {
let visibleBlocksInfoStore = [];
let minVisibleBlockWidth = this._overflowCharWidth;
@ -665,7 +692,8 @@ FlameGraph.prototype = {
* Adds the text for all block inside this graph's pyramid.
* @see FlameGraph.prototype._drawPyramid
*/
_drawPyramidText: function (blocksInfo, verticalOffset, dataOffset, dataScale) {
_drawPyramidText: function (blocksInfo, verticalOffset, dataOffset,
dataScale) {
for (let { block, rect } of blocksInfo) {
this._drawBlockText(block, rect, verticalOffset, dataOffset, dataScale);
}
@ -694,8 +722,7 @@ FlameGraph.prototype = {
*/
_drawBlocksFill: function (
color, blocks, verticalOffset, dataOffset, dataScale,
visibleBlocksInfoStore, minVisibleBlockWidth)
{
visibleBlocksInfoStore, minVisibleBlockWidth) {
let ctx = this._ctx;
let canvasWidth = this._width;
let canvasHeight = this._height;
@ -707,14 +734,16 @@ FlameGraph.prototype = {
for (let block of blocks) {
let { x, y, width, height } = block;
let rectLeft = x * this._pixelRatio * dataScale - scaledOffset;
let rectTop = (y - verticalOffset + OVERVIEW_HEADER_HEIGHT) * this._pixelRatio;
let rectTop = (y - verticalOffset + OVERVIEW_HEADER_HEIGHT)
* this._pixelRatio;
let rectWidth = width * this._pixelRatio * dataScale;
let rectHeight = height * this._pixelRatio;
if (rectLeft > canvasWidth || // Too far right.
rectLeft < -rectWidth || // Too far left.
rectTop > canvasHeight || // Too far bottom.
rectTop < -rectHeight) { // Too far top.
// Too far respectively right/left/bottom/top
if (rectLeft > canvasWidth ||
rectLeft < -rectWidth ||
rectTop > canvasHeight ||
rectTop < -rectHeight) {
continue;
}
@ -766,11 +795,11 @@ FlameGraph.prototype = {
* Offsets and scales the data source by the specified amount.
* This is used for scrolling the visualization.
*/
_drawBlockText: function (block, rect, verticalOffset, dataOffset, dataScale) {
_drawBlockText: function (block, rect, verticalOffset, dataOffset,
dataScale) {
let ctx = this._ctx;
let scaledOffset = dataOffset * dataScale;
let { x, y, width, height, text } = block;
let { text } = block;
let { rectLeft, rectTop, rectWidth, rectHeight } = rect;
let paddingTop = FLAME_GRAPH_BLOCK_TEXT_PADDING_TOP * this._pixelRatio;
@ -849,8 +878,10 @@ FlameGraph.prototype = {
*/
_calcAverageCharWidth: function () {
let letterWidthsSum = 0;
let start = 32; // space
let end = 123; // "z"
// space
let start = 32;
// "z"
let end = 123;
for (let i = start; i < end; i++) {
let char = String.fromCharCode(i);
@ -881,7 +912,8 @@ FlameGraph.prototype = {
}
for (let i = 1, len = text.length; i <= len; i++) {
let trimmedText = text.substring(0, len - i);
let trimmedWidth = this._getTextWidthApprox(trimmedText) + this._overflowCharWidth;
let trimmedWidth = this._getTextWidthApprox(trimmedText)
+ this._overflowCharWidth;
if (trimmedWidth < maxWidth) {
return trimmedText + this.overflowChar;
}
@ -929,7 +961,6 @@ FlameGraph.prototype = {
let {mouseX, mouseY} = this._getRelativeEventCoordinates(e);
let canvasWidth = this._width;
let canvasHeight = this._height;
let selection = this._selection;
let selectionWidth = selection.end - selection.start;
@ -955,17 +986,22 @@ FlameGraph.prototype = {
}
if (horizDrag.origin != null && this._horizontalDragEnabled) {
let relativeX = mouseX + this._horizontalDragDirection * this.horizontalPanThreshold;
selection.start = horizDrag.anchor.start + (horizDrag.origin - relativeX) / selectionScale;
selection.end = horizDrag.anchor.end + (horizDrag.origin - relativeX) / selectionScale;
let relativeX = mouseX + this._horizontalDragDirection *
this.horizontalPanThreshold;
selection.start = horizDrag.anchor.start +
(horizDrag.origin - relativeX) / selectionScale;
selection.end = horizDrag.anchor.end +
(horizDrag.origin - relativeX) / selectionScale;
this._normalizeSelectionBounds();
this._shouldRedraw = true;
this.emit("selecting");
}
if (vertDrag.origin != null && this._verticalDragEnabled) {
let relativeY = mouseY + this._verticalDragDirection * this.verticalPanThreshold;
this._verticalOffset = vertDrag.anchor + (vertDrag.origin - relativeY) / this._pixelRatio;
let relativeY = mouseY +
this._verticalDragDirection * this.verticalPanThreshold;
this._verticalOffset = vertDrag.anchor +
(vertDrag.origin - relativeY) / this._pixelRatio;
this._normalizeVerticalOffset();
this._shouldRedraw = true;
this.emit("panning-vertically");
@ -1011,7 +1047,6 @@ FlameGraph.prototype = {
let {mouseX} = this._getRelativeEventCoordinates(e);
let canvasWidth = this._width;
let canvasHeight = this._height;
let selection = this._selection;
let selectionWidth = selection.end - selection.start;
@ -1226,7 +1261,8 @@ var FlameGraphUtils = {
// Take the timestamp of the first sample as prevTime. 0 is incorrect due
// to circular buffer wraparound. If wraparound happens, then the first
// sample will have an incorrect, large duration.
let prevTime = samplesData.length > 0 ? samplesData[0][SAMPLE_TIME_SLOT] : 0;
let prevTime = samplesData.length > 0 ? samplesData[0][SAMPLE_TIME_SLOT]
: 0;
let prevFrames = [];
let sampleFrames = [];
let sampleFrameKeys = [];
@ -1263,8 +1299,9 @@ var FlameGraphUtils = {
stackIndex = stackEntry[STACK_PREFIX_SLOT];
// Inflate the frame.
let inflatedFrame = getOrAddInflatedFrame(inflatedFrameCache, frameIndex,
frameTable, stringTable);
let inflatedFrame = getOrAddInflatedFrame(inflatedFrameCache,
frameIndex, frameTable,
stringTable);
mutableFrameKeyOptions.isRoot = stackIndex === null;
mutableFrameKeyOptions.isLeaf = stackDepth === 0;
@ -1317,10 +1354,9 @@ var FlameGraphUtils = {
// If there is a block already created, change its width.
if (prevFrame && prevFrame.frameKey === key) {
prevFrame.width = (time - prevFrame.startTime);
}
// Otherwise, create a new block for this frame at this depth,
// using a simple location based salt for picking a color.
else {
} else {
// Otherwise, create a new block for this frame at this depth,
// using a simple location based salt for picking a color.
let hash = this._getStringHash(key);
let bucket = buckets[hash % PALLETTE_SIZE];
@ -1330,7 +1366,8 @@ var FlameGraphUtils = {
} else {
label = labelCache[key];
if (!label) {
label = labelCache[key] = this._formatLabel(key, sampleFrames[frameIndex]);
label = labelCache[key] =
this._formatLabel(key, sampleFrames[frameIndex]);
}
}
@ -1404,8 +1441,10 @@ var FlameGraphUtils = {
* @return string
*/
_formatLabel: function (key, frame) {
let { functionName, fileName, line } = FrameUtils.parseLocation(key, frame.line);
let label = FrameUtils.shouldDemangle(functionName) ? demangle(functionName) : functionName;
let { functionName, fileName, line } =
FrameUtils.parseLocation(key, frame.line);
let label = FrameUtils.shouldDemangle(functionName) ? demangle(functionName)
: functionName;
if (fileName) {
label += ` (${fileName}${line != null ? (":" + line) : ""})`;

Просмотреть файл

@ -3,10 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const { Cc, Ci, Cu, Cr } = require("chrome");
const { Task } = require("devtools/shared/task");
const { Heritage, setNamedTimeout, clearNamedTimeout } = require("devtools/client/shared/widgets/view-helpers");
const { setNamedTimeout } = require("devtools/client/shared/widgets/view-helpers");
const { getCurrentZoom } = require("devtools/shared/layout/utils");
loader.lazyRequireGetter(this, "promise");
@ -23,23 +21,28 @@ const WORKER_URL =
// Generic constants.
const GRAPH_RESIZE_EVENTS_DRAIN = 100; // ms
// ms
const GRAPH_RESIZE_EVENTS_DRAIN = 100;
const GRAPH_WHEEL_ZOOM_SENSITIVITY = 0.00075;
const GRAPH_WHEEL_SCROLL_SENSITIVITY = 0.1;
const GRAPH_WHEEL_MIN_SELECTION_WIDTH = 10; // px
// px
const GRAPH_WHEEL_MIN_SELECTION_WIDTH = 10;
const GRAPH_SELECTION_BOUNDARY_HOVER_LINE_WIDTH = 4; // px
const GRAPH_SELECTION_BOUNDARY_HOVER_THRESHOLD = 10; // px
// px
const GRAPH_SELECTION_BOUNDARY_HOVER_LINE_WIDTH = 4;
const GRAPH_SELECTION_BOUNDARY_HOVER_THRESHOLD = 10;
const GRAPH_MAX_SELECTION_LEFT_PADDING = 1;
const GRAPH_MAX_SELECTION_RIGHT_PADDING = 1;
const GRAPH_REGION_LINE_WIDTH = 1; // px
// px
const GRAPH_REGION_LINE_WIDTH = 1;
const GRAPH_REGION_LINE_COLOR = "rgba(237,38,85,0.8)";
const GRAPH_STRIPE_PATTERN_WIDTH = 16; // px
const GRAPH_STRIPE_PATTERN_HEIGHT = 16; // px
const GRAPH_STRIPE_PATTERN_LINE_WIDTH = 2; // px
const GRAPH_STRIPE_PATTERN_LINE_SPACING = 4; // px
// px
const GRAPH_STRIPE_PATTERN_WIDTH = 16;
const GRAPH_STRIPE_PATTERN_HEIGHT = 16;
const GRAPH_STRIPE_PATTERN_LINE_WIDTH = 2;
const GRAPH_STRIPE_PATTERN_LINE_SPACING = 4;
/**
* Small data primitives for all graphs.
@ -109,7 +112,8 @@ this.AbstractCanvasGraph = function (parent, name, sharpness) {
this._document = iframe.contentDocument;
this._pixelRatio = sharpness || this._window.devicePixelRatio;
let container = this._container = this._document.getElementById("graph-container");
let container =
this._container = this._document.getElementById("graph-container");
container.className = name + "-widget-container graph-widget-container";
let canvas = this._canvas = this._document.getElementById("graph-canvas");
@ -149,7 +153,8 @@ this.AbstractCanvasGraph = function (parent, name, sharpness) {
let ownerWindow = this._parent.ownerDocument.defaultView;
ownerWindow.addEventListener("resize", this._onResize);
this._animationId = this._window.requestAnimationFrame(this._onAnimationFrame);
this._animationId =
this._window.requestAnimationFrame(this._onAnimationFrame);
this._ready.resolve(this);
this.emit("ready", this);
@ -256,7 +261,8 @@ AbstractCanvasGraph.prototype = {
* only when the data source changes.
*/
buildGraphImage: function () {
throw "This method needs to be implemented by inheriting classes.";
let error = "This method needs to be implemented by inheriting classes.";
throw new Error(error);
},
/**
@ -325,10 +331,11 @@ AbstractCanvasGraph.prototype = {
*/
setRegions: function (regions) {
if (!this._cachedGraphImage) {
throw "Can't highlight regions on a graph with no data displayed.";
throw new Error("Can't highlight regions on a graph with " +
"no data displayed.");
}
if (this._regions) {
throw "Regions were already highlighted on the graph.";
throw new Error("Regions were already highlighted on the graph.");
}
this._regions = regions.map(e => ({
start: e.start * this.dataScaleX,
@ -376,7 +383,7 @@ AbstractCanvasGraph.prototype = {
*/
setSelection: function (selection) {
if (!selection || selection.start == null || selection.end == null) {
throw "Invalid selection coordinates";
throw new Error("Invalid selection coordinates");
}
if (!this.isSelectionDifferent(selection)) {
return;
@ -416,10 +423,11 @@ AbstractCanvasGraph.prototype = {
*/
setMappedSelection: function (selection, mapping = {}) {
if (!this.hasData()) {
throw "A data source is necessary for retrieving a mapped selection.";
throw new Error("A data source is necessary for retrieving " +
"a mapped selection.");
}
if (!selection || selection.start == null || selection.end == null) {
throw "Invalid selection coordinates";
throw new Error("Invalid selection coordinates");
}
let { mapStart, mapEnd } = mapping;
@ -448,7 +456,8 @@ AbstractCanvasGraph.prototype = {
*/
getMappedSelection: function (mapping = {}) {
if (!this.hasData()) {
throw "A data source is necessary for retrieving a mapped selection.";
throw new Error("A data source is necessary for retrieving a " +
"mapped selection.");
}
if (!this.hasSelection() && !this.hasSelectionInProgress()) {
return { min: null, max: null };
@ -517,7 +526,7 @@ AbstractCanvasGraph.prototype = {
*/
setCursor: function (cursor) {
if (!cursor || cursor.x == null || cursor.y == null) {
throw "Invalid cursor coordinates";
throw new Error("Invalid cursor coordinates");
}
if (!this.isCursorDifferent(cursor)) {
return;
@ -565,7 +574,9 @@ AbstractCanvasGraph.prototype = {
* The other graph's selection, as { start, end } values.
*/
isSelectionDifferent: function (other) {
if (!other) return true;
if (!other) {
return true;
}
let current = this.getSelection();
return current.start != other.start || current.end != other.end;
},
@ -577,7 +588,9 @@ AbstractCanvasGraph.prototype = {
* The other graph's position, as { x, y } values.
*/
isCursorDifferent: function (other) {
if (!other) return true;
if (!other) {
return true;
}
let current = this.getCursor();
return current.x != other.x || current.y != other.y;
},
@ -703,7 +716,8 @@ AbstractCanvasGraph.prototype = {
* Animation frame callback, invoked on each tick of the refresh driver.
*/
_onAnimationFrame: function () {
this._animationId = this._window.requestAnimationFrame(this._onAnimationFrame);
this._animationId =
this._window.requestAnimationFrame(this._onAnimationFrame);
this._drawWidget();
},
@ -727,7 +741,8 @@ AbstractCanvasGraph.prototype = {
}
if (this._cachedBackgroundImage) {
ctx.globalCompositeOperation = "destination-over";
ctx.drawImage(this._cachedBackgroundImage, 0, 0, this._width, this._height);
ctx.drawImage(this._cachedBackgroundImage, 0, 0,
this._width, this._height);
}
// Revert to the original global composition operation.
@ -749,7 +764,8 @@ AbstractCanvasGraph.prototype = {
* Draws the cliphead, if available and necessary.
*/
_drawCliphead: function () {
if (this._isHoveringSelectionContentsOrBoundaries() || this._isHoveringRegion()) {
if (this._isHoveringSelectionContentsOrBoundaries() ||
this._isHoveringRegion()) {
return;
}
@ -842,7 +858,7 @@ AbstractCanvasGraph.prototype = {
*/
_isHoveringStartBoundary: function () {
if (!this.hasSelection() || !this.hasCursor()) {
return;
return false;
}
let { x } = this._cursor;
let { start } = this._selection;
@ -856,7 +872,7 @@ AbstractCanvasGraph.prototype = {
*/
_isHoveringEndBoundary: function () {
if (!this.hasSelection() || !this.hasCursor()) {
return;
return false;
}
let { x } = this._cursor;
let { end } = this._selection;
@ -870,7 +886,7 @@ AbstractCanvasGraph.prototype = {
*/
_isHoveringSelectionContents: function () {
if (!this.hasSelection() || !this.hasCursor()) {
return;
return false;
}
let { x } = this._cursor;
let { start, end } = this._selection;
@ -938,7 +954,7 @@ AbstractCanvasGraph.prototype = {
let maxX = bb.p2.x - bb.p1.x;
let maxY = bb.p3.y - bb.p1.y;
let mouseX = Math.max(0, Math.min(x, maxX)) * this._pixelRatio;
let mouseY = Math.max(0, Math.min(x, maxY)) * this._pixelRatio;
let mouseY = Math.max(0, Math.min(y, maxY)) * this._pixelRatio;
// The coordinates need to be modified with the current zoom level
// to prevent them from being wrong.
@ -969,7 +985,8 @@ AbstractCanvasGraph.prototype = {
if (e.buttons == 0 && (this.hasSelectionInProgress() ||
resizer.margin != null ||
dragger.origin != null)) {
return this._onMouseUp();
this._onMouseUp();
return;
}
let {mouseX, mouseY} = this._getRelativeEventCoordinates(e);
@ -1137,9 +1154,8 @@ AbstractCanvasGraph.prototype = {
vector = e.detail * GRAPH_WHEEL_ZOOM_SENSITIVITY;
selection.start = selection.start + distStart * vector;
selection.end = selection.end + distEnd * vector;
}
// Otherwise, simply pan the selection towards the left or right.
else {
} else {
// Otherwise, simply pan the selection towards the left or right.
let direction = 0;
if (focusX > selection.end) {
direction = Math.sign(focusX - selection.end);
@ -1389,8 +1405,12 @@ function map(value, istart, istop, ostart, ostop) {
* @return number
*/
function clamp(value, min, max) {
if (value < min) return min;
if (value > max) return max;
if (value < min) {
return min;
}
if (value > max) {
return max;
}
return value;
}

Просмотреть файл

@ -3,6 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/* eslint-env worker */
/**
* Import `createTask` to communicate with `devtools/shared/worker`.
*/
@ -16,14 +18,14 @@ const { createTask } = require("resource://devtools/shared/worker/helper.js");
* @param number interval
* @param number duration
*/
createTask(self, "plotTimestampsGraph", function ({ timestamps, interval, duration }) {
createTask(self, "plotTimestampsGraph", function ({ timestamps,
interval, duration }) {
let plottedData = plotTimestamps(timestamps, interval);
let plottedMinMaxSum = getMinMaxAvg(plottedData, timestamps, duration);
return { plottedData, plottedMinMaxSum };
});
/**
* Gets the min, max and average of the values in an array.
* @param array source
@ -32,14 +34,13 @@ createTask(self, "plotTimestampsGraph", function ({ timestamps, interval, durati
* @return object
*/
function getMinMaxAvg(source, timestamps, duration) {
let totalTicks = source.length;
let totalFrames = timestamps.length;
let maxValue = Number.MIN_SAFE_INTEGER;
let minValue = Number.MAX_SAFE_INTEGER;
// Calculate the average by counting how many frames occurred
// in the duration of the recording, rather than average the frame points
// we have, as that weights higher FPS, as there'll be more timestamps for those
// values
// we have, as that weights higher FPS, as there'll be more timestamps for
// those values
let avgValue = totalFrames / (duration / 1000);
for (let { value } of source) {

Просмотреть файл

@ -1,9 +1,7 @@
"use strict";
const { Cc, Ci, Cu, Cr } = require("chrome");
const { Task } = require("devtools/shared/task");
const { ViewHelpers, Heritage } = require("devtools/client/shared/widgets/view-helpers");
const { Heritage } = require("devtools/client/shared/widgets/view-helpers");
const { AbstractCanvasGraph, CanvasGraphUtils } = require("devtools/client/shared/widgets/Graphs");
const { LocalizationHelper } = require("devtools/client/shared/l10n");
@ -13,14 +11,17 @@ const L10N = new LocalizationHelper("chrome://devtools/locale/graphs.properties"
// Line graph constants.
const GRAPH_DAMPEN_VALUES_FACTOR = 0.85;
const GRAPH_TOOLTIP_SAFE_BOUNDS = 8; // px
const GRAPH_MIN_MAX_TOOLTIP_DISTANCE = 14; // px
// px
const GRAPH_TOOLTIP_SAFE_BOUNDS = 8;
const GRAPH_MIN_MAX_TOOLTIP_DISTANCE = 14;
const GRAPH_BACKGROUND_COLOR = "#0088cc";
const GRAPH_STROKE_WIDTH = 1; // px
// px
const GRAPH_STROKE_WIDTH = 1;
const GRAPH_STROKE_COLOR = "rgba(255,255,255,0.9)";
const GRAPH_HELPER_LINES_DASH = [5]; // px
const GRAPH_HELPER_LINES_WIDTH = 1; // px
// px
const GRAPH_HELPER_LINES_DASH = [5];
const GRAPH_HELPER_LINES_WIDTH = 1;
const GRAPH_MAXIMUM_LINE_COLOR = "rgba(255,255,255,0.4)";
const GRAPH_AVERAGE_LINE_COLOR = "rgba(255,255,255,0.7)";
const GRAPH_MINIMUM_LINE_COLOR = "rgba(255,255,255,0.9)";
@ -58,10 +59,10 @@ const GRAPH_REGION_STRIPES_COLOR = "rgba(237,38,85,0.2)";
* @param nsIDOMNode parent
* The parent node holding the graph.
* @param object options [optional]
* `metric`: The metric displayed in the graph, e.g. "fps" or "bananas".
* `min`: Boolean whether to show the min tooltip/gutter/line (default: true)
* `max`: Boolean whether to show the max tooltip/gutter/line (default: true)
* `avg`: Boolean whether to show the avg tooltip/gutter/line (default: true)
* `metric`: The metric displayed in the graph, e.g. "fps" or "bananas".
* `min`: Boolean whether to show the min tooltip/gutter/line (default: true)
* `max`: Boolean whether to show the max tooltip/gutter/line (default: true)
* `avg`: Boolean whether to show the avg tooltip/gutter/line (default: true)
*/
this.LineGraphWidget = function (parent, options = {}, ...args) {
let { metric, min, max, avg } = options;
@ -77,11 +78,17 @@ this.LineGraphWidget = function (parent, options = {}, ...args) {
// are changed later
this._gutter = this._createGutter();
this._maxGutterLine = this._createGutterLine("maximum");
this._maxTooltip = this._createTooltip("maximum", "start", L10N.getStr("graphs.label.maximum"), metric);
this._maxTooltip = this._createTooltip(
"maximum", "start", L10N.getStr("graphs.label.maximum"), metric
);
this._minGutterLine = this._createGutterLine("minimum");
this._minTooltip = this._createTooltip("minimum", "start", L10N.getStr("graphs.label.minimum"), metric);
this._minTooltip = this._createTooltip(
"minimum", "start", L10N.getStr("graphs.label.minimum"), metric
);
this._avgGutterLine = this._createGutterLine("average");
this._avgTooltip = this._createTooltip("average", "end", L10N.getStr("graphs.label.average"), metric);
this._avgTooltip = this._createTooltip(
"average", "end", L10N.getStr("graphs.label.average"), metric
);
});
};
@ -176,7 +183,7 @@ LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
avgValue = this._tempMinMaxSum.avgValue;
} else {
let sumValues = 0;
for (let { delta, value } of this._data) {
for (let { value } of this._data) {
maxValue = Math.max(value, maxValue);
minValue = Math.min(value, minValue);
sumValues += value;
@ -186,7 +193,8 @@ LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
let duration = this.dataDuration || lastTick;
let dataScaleX = this.dataScaleX = width / (duration - this.dataOffsetX);
let dataScaleY = this.dataScaleY = height / maxValue * this.dampenValuesFactor;
let dataScaleY =
this.dataScaleY = height / maxValue * this.dampenValuesFactor;
// Draw the background.
@ -289,9 +297,12 @@ LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
L10N.numberWithDecimals(minValue, 2);
let bottom = height / this._pixelRatio;
let maxPosY = CanvasGraphUtils.map(maxValue * this.dampenValuesFactor, 0, maxValue, bottom, 0);
let avgPosY = CanvasGraphUtils.map(avgValue * this.dampenValuesFactor, 0, maxValue, bottom, 0);
let minPosY = CanvasGraphUtils.map(minValue * this.dampenValuesFactor, 0, maxValue, bottom, 0);
let maxPosY = CanvasGraphUtils.map(maxValue * this.dampenValuesFactor, 0,
maxValue, bottom, 0);
let avgPosY = CanvasGraphUtils.map(avgValue * this.dampenValuesFactor, 0,
maxValue, bottom, 0);
let minPosY = CanvasGraphUtils.map(minValue * this.dampenValuesFactor, 0,
maxValue, bottom, 0);
let safeTop = GRAPH_TOOLTIP_SAFE_BOUNDS;
let safeBottom = bottom - GRAPH_TOOLTIP_SAFE_BOUNDS;
@ -316,10 +327,14 @@ LineGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
this._minTooltip.setAttribute("with-arrows", this.withTooltipArrows);
let distanceMinMax = Math.abs(maxTooltipTop - minTooltipTop);
this._maxTooltip.hidden = this._showMax === false || !totalTicks || distanceMinMax < GRAPH_MIN_MAX_TOOLTIP_DISTANCE;
this._maxTooltip.hidden = this._showMax === false
|| !totalTicks
|| distanceMinMax < GRAPH_MIN_MAX_TOOLTIP_DISTANCE;
this._avgTooltip.hidden = this._showAvg === false || !totalTicks;
this._minTooltip.hidden = this._showMin === false || !totalTicks;
this._gutter.hidden = (this._showMin === false && this._showAvg === false && this._showMax === false) || !totalTicks;
this._gutter.hidden = (this._showMin === false &&
this._showAvg === false &&
this._showMax === false) || !totalTicks;
this._maxGutterLine.hidden = this._showMax === false;
this._avgGutterLine.hidden = this._showAvg === false;

Просмотреть файл

@ -24,7 +24,6 @@
"use strict";
const {Cc, Cu, Ci} = require("chrome");
const Services = require("Services");
const Promise = require("promise");
const {getCSSLexer} = require("devtools/shared/css-lexer");
@ -37,7 +36,8 @@ var XHR_CSS_URL = "https://developer.mozilla.org/en-US/docs/Web/CSS/";
// Parameters for the link to MDN in the tooltip, so
// so we know which MDN visits come from this feature
const PAGE_LINK_PARAMS = "?utm_source=mozilla&utm_medium=firefox-inspector&utm_campaign=default";
const PAGE_LINK_PARAMS =
"?utm_source=mozilla&utm_medium=firefox-inspector&utm_campaign=default";
// URL for the page link omits locale, so a locale-specific page will be loaded
var PAGE_LINK_URL = "https://developer.mozilla.org/docs/Web/CSS/";
exports.PAGE_LINK_URL = PAGE_LINK_URL;
@ -104,11 +104,8 @@ function appendSyntaxHighlightedCSS(cssText, parentElement) {
function updateIdentClass(tokenText) {
if (tokenText === ":") {
identClass = PROPERTY_VALUE_COLOR;
}
else {
if (tokenText === ";") {
identClass = PROPERTY_NAME_COLOR;
}
} else if (tokenText === ";") {
identClass = PROPERTY_NAME_COLOR;
}
}
@ -172,8 +169,7 @@ function getMdnPage(pageUrl) {
function onLoaded(e) {
if (xhr.status != 200) {
deferred.reject({page: pageUrl, status: xhr.status});
}
else {
} else {
deferred.resolve(xhr.responseXML);
}
}
@ -202,7 +198,6 @@ function getMdnPage(pageUrl) {
* we could not load the page.
*/
function getCssDocs(cssProperty) {
let deferred = Promise.defer();
let pageUrl = XHR_CSS_URL + cssProperty + XHR_PARAMS;
@ -214,8 +209,7 @@ function getCssDocs(cssProperty) {
theDocs.syntax = getSyntax(responseDocument);
if (theDocs.summary || theDocs.syntax) {
deferred.resolve(theDocs);
}
else {
} else {
deferred.reject("Couldn't find the docs in the page.");
}
}
@ -246,7 +240,6 @@ exports.getCssDocs = getCssDocs;
* structure.
*/
function MdnDocsWidget(tooltipDocument) {
// fetch all the bits of the document that we will manipulate later
this.elements = {
heading: tooltipDocument.getElementById("property-name"),
@ -296,20 +289,18 @@ MdnDocsWidget.prototype = {
* The name of the CSS property for which we need to display help.
*/
loadCssDocs: function (propertyName) {
/**
* Do all the setup we can do synchronously, and get the document in
* a state where it can be displayed while we are waiting for the
* MDN docs content to be retrieved.
*/
function initializeDocument(propertyName) {
function initializeDocument(propName) {
// set property name heading
elements.heading.textContent = propertyName;
elements.heading.textContent = propName;
// set link target
elements.linkToMdn.setAttribute("href",
PAGE_LINK_URL + propertyName + PAGE_LINK_PARAMS);
PAGE_LINK_URL + propName + PAGE_LINK_PARAMS);
// clear docs summary and syntax
elements.summary.textContent = "";
@ -346,7 +337,8 @@ MdnDocsWidget.prototype = {
*/
function gotError(error) {
// show error message
elements.summary.textContent = l10n.strings.GetStringFromName("docsTooltip.loadDocsError");
elements.summary.textContent =
l10n.strings.GetStringFromName("docsTooltip.loadDocsError");
// hide the throbber
elements.info.classList.remove("devtools-throbber");
@ -358,7 +350,6 @@ MdnDocsWidget.prototype = {
let deferred = Promise.defer();
let elements = this.elements;
let doc = this.doc;
initializeDocument(propertyName);
getCssDocs(propertyName).then(finalizeDocument, gotError);
@ -402,8 +393,9 @@ function isAllWhitespace(node) {
* True if the node is a comment node or is all whitespace, otherwise false.
*/
function isIgnorable(node) {
return (node.nodeType == 8) || // A comment node
((node.nodeType == 3) && isAllWhitespace(node)); // text node, all ws
// Comment nodes (8), text nodes (3) or whitespace
return (node.nodeType == 8) ||
((node.nodeType == 3) && isAllWhitespace(node));
}
/**
@ -415,7 +407,9 @@ function isIgnorable(node) {
*/
function nodeAfter(sib) {
while ((sib = sib.nextSibling)) {
if (!isIgnorable(sib)) return sib;
if (!isIgnorable(sib)) {
return sib;
}
}
return null;
}
@ -487,7 +481,6 @@ function getSummary(mdnDocument) {
* The syntax section as a string, or null if it could not be found.
*/
function getSyntax(mdnDocument) {
let syntax = mdnDocument.getElementById("Syntax");
if (!hasTagName(syntax, "H2")) {
return null;
@ -502,9 +495,7 @@ function getSyntax(mdnDocument) {
if (hasTagName(secondParagraph, "PRE")) {
return secondParagraph.textContent;
}
else {
return firstParagraph.textContent;
}
return firstParagraph.textContent;
}
/**

Просмотреть файл

@ -1,21 +1,19 @@
"use strict";
const { Cc, Ci, Cu, Cr } = require("chrome");
const { Heritage } = require("devtools/client/shared/widgets/view-helpers");
const { AbstractCanvasGraph, CanvasGraphUtils } = require("devtools/client/shared/widgets/Graphs");
const HTML_NS = "http://www.w3.org/1999/xhtml";
const { AbstractCanvasGraph } = require("devtools/client/shared/widgets/Graphs");
// Bar graph constants.
const GRAPH_DAMPEN_VALUES_FACTOR = 0.9;
const GRAPH_BACKGROUND_COLOR = "#ddd";
const GRAPH_STROKE_WIDTH = 1; // px
// px
const GRAPH_STROKE_WIDTH = 1;
const GRAPH_STROKE_COLOR = "rgba(255,255,255,0.9)";
const GRAPH_HELPER_LINES_DASH = [5]; // px
const GRAPH_HELPER_LINES_WIDTH = 1; // px
// px
const GRAPH_HELPER_LINES_DASH = [5];
const GRAPH_HELPER_LINES_WIDTH = 1;
const GRAPH_CLIPHEAD_LINE_COLOR = "#fff";
const GRAPH_SELECTION_LINE_COLOR = "#fff";
@ -117,7 +115,8 @@ MountainGraphWidget.prototype = Heritage.extend(AbstractCanvasGraph.prototype, {
*/
buildGraphImage: function () {
if (!this.format || !this.format.length) {
throw "The graph format traits are mandatory to style the data source.";
throw new Error("The graph format traits are mandatory to style " +
"the data source.");
}
let { canvas, ctx } = this._getNamedCanvas("mountain-graph-data");
let width = this._width;

Просмотреть файл

@ -166,7 +166,8 @@ Spectrum.draggable = function (element, onmove, onstart, onstop) {
if (dragging) {
if (e.buttons === 0) {
// The button is no longer pressed but we did not get a mouseup event.
return stop();
stop();
return;
}
let pageX = e.pageX;
let pageY = e.pageY;

Просмотреть файл

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const {Ci, Cu} = require("chrome");
const {Ci} = require("chrome");
const EventEmitter = require("devtools/shared/event-emitter");
loader.lazyRequireGetter(this, "setNamedTimeout",
"devtools/client/shared/widgets/view-helpers", true);

Просмотреть файл

@ -493,7 +493,9 @@ Tooltip.prototype = {
// Analyzing state history isn't useful with transient object inspectors.
widget.commitHierarchy = () => {};
for (let e in relayEvents) widget.on(e, relayEvents[e]);
for (let e in relayEvents) {
widget.on(e, relayEvents[e]);
}
VariablesViewController.attach(widget, controllerOptions);
// Some of the view options are allowed to change between uses.
@ -517,7 +519,7 @@ Tooltip.prototype = {
* resolves when the broken image tooltip content is ready, but never rejects.
*/
setRelativeImageContent: Task.async(function* (imageUrl, inspectorFront,
maxDim) {
maxDim) {
if (imageUrl.startsWith("data:")) {
// If the imageUrl already is a data-url, save ourselves a round-trip
this.setImageContent(imageUrl, {maxDim: maxDim});
@ -539,7 +541,9 @@ Tooltip.prototype = {
*/
setBrokenImageContent: function () {
this.setTextContent({
messages: [l10n.strings.GetStringFromName("previewTooltip.image.brokenImage")]
messages: [
l10n.strings.GetStringFromName("previewTooltip.image.brokenImage")
]
});
},
@ -738,7 +742,6 @@ Tooltip.prototype = {
function onLoaded(iframe) {
let win = iframe.contentWindow.wrappedJSObject;
let doc = win.document.documentElement;
let def = promise.defer();
let container = win.document.getElementById("container");
let widget = new CSSFilterEditorWidget(container, filter);
@ -1008,7 +1011,8 @@ function SwatchColorPickerTooltip(doc) {
module.exports.SwatchColorPickerTooltip = SwatchColorPickerTooltip;
SwatchColorPickerTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.prototype, {
SwatchColorPickerTooltip.prototype =
Heritage.extend(SwatchBasedEditorTooltip.prototype, {
/**
* Overriding the SwatchBasedEditorTooltip.show function to set spectrum's
* color.
@ -1287,8 +1291,9 @@ EventTooltip.prototype = {
iframe.setAttribute("style", "width:100%;");
editor.appendTo(content, iframe).then(() => {
/* eslint-disable camelcase */
let tidied = beautify.js(handler, { indent_size: 2 });
/* eslint-enable */
editor.setText(tidied);
eventEditors.appended = true;
@ -1335,7 +1340,9 @@ EventTooltip.prototype = {
);
if (item) {
let actor = item.attachment.source.actor;
DebuggerView.setEditorLocation(actor, line, {noDebug: true}).then(() => {
DebuggerView.setEditorLocation(
actor, line, {noDebug: true}
).then(() => {
if (dom0) {
let text = DebuggerView.editor.getText();
let index = text.indexOf(searchString);
@ -1420,7 +1427,8 @@ function SwatchCubicBezierTooltip(doc) {
module.exports.SwatchCubicBezierTooltip = SwatchCubicBezierTooltip;
SwatchCubicBezierTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.prototype, {
SwatchCubicBezierTooltip.prototype =
Heritage.extend(SwatchBasedEditorTooltip.prototype, {
/**
* Overriding the SwatchBasedEditorTooltip.show function to set the cubic
* bezier curve in the widget
@ -1517,7 +1525,8 @@ function SwatchFilterTooltip(doc) {
exports.SwatchFilterTooltip = SwatchFilterTooltip;
SwatchFilterTooltip.prototype = Heritage.extend(SwatchBasedEditorTooltip.prototype, {
SwatchFilterTooltip.prototype =
Heritage.extend(SwatchBasedEditorTooltip.prototype, {
show: function () {
// Call the parent class' show function
SwatchBasedEditorTooltip.prototype.show.call(this);

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -3,11 +3,13 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Check that Dead Objects do not break the Web/Browser Consoles. See bug 883649.
// Check that Dead Objects do not break the Web/Browser Consoles.
// See bug 883649.
// This test does:
// - opens a new tab,
// - opens the Browser Console,
// - stores a reference to the content document of the tab on the chrome window object,
// - stores a reference to the content document of the tab on the chrome
// window object,
// - closes the tab,
// - tries to use the object that was pointing to the now-defunct content
// document. This is the dead object.

Просмотреть файл

@ -53,7 +53,8 @@ add_task(function* () {
info("try ctrl-l to clear output");
executeSoon(() => {
let clearKey = hud.ui.window.document.querySelector("key[command=consoleCmd_clearOutput]:not([disabled])");
let selector = "key[command=consoleCmd_clearOutput]:not([disabled])";
let clearKey = hud.ui.window.document.querySelector(selector);
synthesizeKeyFromKeyTag(clearKey);
});
yield hud.jsterm.once("messages-cleared");

Просмотреть файл

@ -39,7 +39,11 @@ function consoleOpened() {
ok(hud, "Web Console opened");
hud.jsterm.clearOutput();
content.console.log("foobarz1");
ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
content.console.log("foobarz1");
});
return waitForMessages({
webconsole: hud,
messages: [{
@ -51,7 +55,9 @@ function consoleOpened() {
}
function onReload() {
content.console.log("foobarz2");
ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
content.console.log("foobarz2");
});
return waitForMessages({
webconsole: hud,

Просмотреть файл

@ -38,7 +38,9 @@ function test() {
ConsoleAPIStorage.clearEvents();
// Add a non-private message to the browser console.
content.console.log("bug874061-not-private");
ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
content.console.log("bug874061-not-private");
});
nonPrivateMessage = {
name: "console message from a non-private window",
@ -49,7 +51,7 @@ function test() {
privateWindow = OpenBrowserWindow({ private: true });
ok(privateWindow, "new private window");
ok(PrivateBrowsingUtils.isWindowPrivate(privateWindow), "window is private");
ok(PrivateBrowsingUtils.isWindowPrivate(privateWindow), "window's private");
whenDelayedStartupFinished(privateWindow, onPrivateWindowReady);
}
@ -75,8 +77,8 @@ function test() {
EventUtils.synthesizeMouse(button, 2, 2, {}, privateContent);
}
function consoleOpened(aHud) {
hud = aHud;
function consoleOpened(injectedHud) {
hud = injectedHud;
ok(hud, "web console opened");
addMessages();
@ -111,8 +113,8 @@ function test() {
});
}
function consoleReopened(aHud) {
hud = aHud;
function consoleReopened(injectedHud) {
hud = injectedHud;
ok(hud, "web console reopened");
// Make sure that cached messages are displayed in the web console, even
@ -139,8 +141,8 @@ function test() {
is(text.indexOf("bug 874061"), -1, "no console message displayed");
}
function onBrowserConsoleOpen(aHud) {
hud = aHud;
function onBrowserConsoleOpen(injectedHud) {
hud = injectedHud;
ok(hud, "browser console opened");
checkNoPrivateMessages();
@ -156,7 +158,7 @@ function test() {
}
function testPrivateWindowClose() {
info("close the private window and check if the private messages are removed");
info("close the private window and check if private messages are removed");
hud.jsterm.once("private-messages-cleared", () => {
isnot(hud.outputNode.textContent.indexOf("bug874061-not-private"), -1,
"non-private messages are still shown after private window closed");
@ -172,8 +174,8 @@ function test() {
privateWindow.BrowserTryToCloseWindow();
}
function onBrowserConsoleReopen(aHud) {
hud = aHud;
function onBrowserConsoleReopen(injectedHud) {
hud = injectedHud;
ok(hud, "browser console reopened");
// Make sure that the non-private message is still shown after reopen.

Просмотреть файл

@ -35,21 +35,24 @@ add_task(function* () {
let variablesView = view._variablesView;
let searchbox = variablesView._searchboxNode;
assertAttrs(view, "foo,__proto__", "To start with, we just see the top level foo attr");
assertAttrs(view, "foo,__proto__",
"To start with, we just see the top level foo attr");
fetched = jsterm.once("variablesview-fetched");
searchbox.value = "bar";
searchbox.doCommand();
view = yield fetched;
assertAttrs(view, "", "If we don't manually expand nested attr, we don't see them in search");
assertAttrs(view, "",
"If we don't manually expand nested attr, we don't see them");
fetched = jsterm.once("variablesview-fetched");
searchbox.value = "";
searchbox.doCommand();
view = yield fetched;
assertAttrs(view, "foo", "If we reset the search, we get back to original state");
assertAttrs(view, "foo",
"If we reset the search, we get back to original state");
yield [...view][0][1].expand();
@ -72,5 +75,6 @@ add_task(function* () {
searchbox.doCommand();
view = yield fetched;
assertAttrs(view, "foo", "If we reset again, we get back to original state again");
assertAttrs(view, "foo",
"If we reset again, we get back to original state again");
});

Просмотреть файл

@ -57,10 +57,12 @@ add_task(function* () {
function pushPrefEnv() {
let deferred = promise.defer();
let options = {"set": [
["security.mixed_content.block_active_content", true],
["security.mixed_content.block_display_content", true]
]};
let options = {
"set": [
["security.mixed_content.block_active_content", true],
["security.mixed_content.block_display_content", true]
]
};
SpecialPowers.pushPrefEnv(options, deferred.resolve);
return deferred.promise;
}

Просмотреть файл

@ -1,3 +1,7 @@
/* eslint-disable no-unused-vars */
"use strict";
function counterExternalFile() {
console.count("console.count() testcounter");
}

Просмотреть файл

@ -1 +1,2 @@
"use strict";
console.log("running network console logging tests");

Просмотреть файл

@ -884,12 +884,13 @@ var PageStyleActor = protocol.ActorClassWithSpec(pageStyleSpec, {
let sheet = style.sheet;
let cssRules = sheet.cssRules;
let rawNode = node.rawNode;
let classes = [...rawNode.classList];
let selector;
if (rawNode.id) {
selector = "#" + CSS.escape(rawNode.id);
} else if (rawNode.className) {
selector = "." + [...rawNode.classList].map(c => CSS.escape(c)).join(".");
} else if (classes.length > 0) {
selector = "." + classes.map(c => CSS.escape(c)).join(".");
} else {
selector = rawNode.localName;
}

Просмотреть файл

@ -580,16 +580,6 @@ public:
SetHTMLBoolAttr(nsGkAtoms::muted, aMuted, aRv);
}
bool MozMediaStatisticsShowing() const
{
return mStatsShowing;
}
void SetMozMediaStatisticsShowing(bool aShow)
{
mStatsShowing = aShow;
}
bool MozAllowCasting() const
{
return mAllowCasting;

Просмотреть файл

@ -118,7 +118,6 @@ partial interface HTMLMediaElement {
readonly attribute boolean mozAutoplayEnabled;
// NB: for internal use with the video controls:
[Func="IsChromeOrXBL"] attribute boolean mozMediaStatisticsShowing;
[Func="IsChromeOrXBL"] attribute boolean mozAllowCasting;
[Func="IsChromeOrXBL"] attribute boolean mozIsCasting;

Просмотреть файл

@ -1076,7 +1076,7 @@ void
CountHistogram::Accumulate(Sample value, Count count, size_t index)
{
size_t zero_index = BucketIndex(0);
LinearHistogram::Accumulate(1, 1, zero_index);
LinearHistogram::Accumulate(value, 1, zero_index);
}
void

Просмотреть файл

@ -179,6 +179,8 @@ public class GeckoNetworkManager extends BroadcastReceiver implements NativeEven
return ManagerState.OffNoListeners;
case enableNotifications:
return ManagerState.OnWithListeners;
case receivedUpdate:
return ManagerState.OnNoListeners;
default:
return null;
}
@ -224,16 +226,24 @@ public class GeckoNetworkManager extends BroadcastReceiver implements NativeEven
case OffNoListeners:
if (event == ManagerEvent.start) {
updateNetworkStateAndConnectionType();
registerBroadcastReceiver();
}
if (event == ManagerEvent.enableNotifications) {
updateNetworkStateAndConnectionType();
}
break;
case OnNoListeners:
if (event == ManagerEvent.receivedUpdate) {
updateNetworkStateAndConnectionType();
sendNetworkStateToListeners();
}
if (event == ManagerEvent.enableNotifications) {
updateNetworkStateAndConnectionType();
registerBroadcastReceiver();
}
if (event == ManagerEvent.stop) {
unregisterBroadcastReceiver();
}
break;
case OnWithListeners:
if (event == ManagerEvent.receivedUpdate) {
@ -243,14 +253,13 @@ public class GeckoNetworkManager extends BroadcastReceiver implements NativeEven
if (event == ManagerEvent.stop) {
unregisterBroadcastReceiver();
}
if (event == ManagerEvent.disableNotifications) {
unregisterBroadcastReceiver();
}
/* no-op event: ManagerEvent.disableNotifications */
break;
case OffWithListeners:
if (event == ManagerEvent.start) {
registerBroadcastReceiver();
}
/* no-op event: ManagerEvent.disableNotifications */
break;
default:
throw new IllegalStateException("Unknown current state: " + currentState.name());

Просмотреть файл

@ -13,21 +13,24 @@ import com.adjust.sdk.AdjustConfig;
import com.adjust.sdk.AdjustReferrerReceiver;
import com.adjust.sdk.LogLevel;
import org.mozilla.gecko.AppConstants;
public class AdjustHelper implements AdjustHelperInterface {
public void onCreate(final Context context, final String maybeAppToken) {
final String environment;
final String appToken;
final LogLevel logLevel;
if (maybeAppToken != null) {
if (AppConstants.MOZILLA_OFFICIAL) {
environment = AdjustConfig.ENVIRONMENT_PRODUCTION;
appToken = maybeAppToken;
logLevel = LogLevel.WARN;
} else {
environment = AdjustConfig.ENVIRONMENT_SANDBOX;
appToken = "ABCDEFGHIJKL";
logLevel = LogLevel.VERBOSE;
}
AdjustConfig config = new AdjustConfig(context, appToken, environment);
if (maybeAppToken == null) {
// We've got install tracking turned on -- we better have a token!
throw new IllegalArgumentException("maybeAppToken must not be null");
}
AdjustConfig config = new AdjustConfig(context, maybeAppToken, environment);
config.setLogLevel(logLevel);
Adjust.onCreate(config);
}

Просмотреть файл

@ -832,7 +832,9 @@ public class LocalBrowserDB implements BrowserDB {
// bookmarks exist, so that the user can still access non-mobile bookmarks.
addDesktopFolder = desktopBookmarksExist(cr);
addScreenshotsFolder = AppConstants.SCREENSHOTS_IN_BOOKMARKS_ENABLED;
addReadingListFolder = true;
final int readingListItemCount = getBookmarkCountForFolder(cr, Bookmarks.FAKE_READINGLIST_SMARTFOLDER_ID);
addReadingListFolder = (readingListItemCount > 0);
} else {
addDesktopFolder = false;
addScreenshotsFolder = false;

Просмотреть файл

@ -39,7 +39,7 @@ public class DownloadAction extends BaseAction {
private static final String CACHE_DIRECTORY = "downloadContent";
private static final String CDN_BASE_URL = "https://mobile.cdn.mozilla.net/";
private static final String CDN_BASE_URL = "https://fennec-catalog.cdn.mozilla.net/";
public interface Callback {
void onContentDownloaded(DownloadContent content);

Просмотреть файл

@ -44,7 +44,7 @@ public class SyncAction extends BaseAction {
* Dev instance:
* https://kinto-ota.dev.mozaws.net/v1/buckets/dlc/collections/catalog/records
*/
private static final String CATALOG_ENDPOINT = "https://firefox.settings.services.mozilla.com/v1/buckets/fennec-dlc/collections/catalog/records";
private static final String CATALOG_ENDPOINT = "https://firefox.settings.services.mozilla.com/v1/buckets/fennec/collections/catalog/records";
@Override
public void perform(Context context, DownloadContentCatalog catalog) {

Просмотреть файл

@ -22,10 +22,10 @@ import java.util.List;
List<DownloadContent> initialList = Arrays.asList(
new DownloadContentBuilder()
.setId("c40929cf-7f4c-fa72-3dc9-12cadf56905d")
.setLocation("fonts/ff7ecae7669a51d5fa6a5f8e703278ebda3a68f51bc49c4321bde4438020d639.gz")
.setLocation("fennec/catalog/f63e5f92-793c-4574-a2d7-fbc50242b8cb.gz")
.setFilename("CharisSILCompact-B.ttf")
.setChecksum("699d958b492eda0cc2823535f8567d0393090e3842f6df3c36dbe7239cb80b6d")
.setDownloadChecksum("ff7ecae7669a51d5fa6a5f8e703278ebda3a68f51bc49c4321bde4438020d639")
.setDownloadChecksum("a9f9b34fed353169a88cc159b8f298cb285cce0b8b0f979c22a7d85de46f0532")
.setSize(1676072)
.setKind("font")
.setType("asset-archive")
@ -33,10 +33,10 @@ import java.util.List;
new DownloadContentBuilder()
.setId("6d265876-85ed-0917-fdc8-baf583ca2cba")
.setLocation("fonts/dfb6d583edd27d5e6d91d479e6c8a5706275662c940c65b70911493bb279904a.gz")
.setLocation("fennec/catalog/19af6c88-09d9-4d6c-805e-cfebb8699a6c.gz")
.setFilename("CharisSILCompact-BI.ttf")
.setChecksum("82465e747b4f41471dbfd942842b2ee810749217d44b55dbc43623b89f9c7d9b")
.setDownloadChecksum("dfb6d583edd27d5e6d91d479e6c8a5706275662c940c65b70911493bb279904a")
.setDownloadChecksum("2be26671039a5e2e4d0360a948b4fa42048171133076a3bb6173d93d4b9cd55b")
.setSize(1667812)
.setKind("font")
.setType("asset-archive")
@ -44,10 +44,10 @@ import java.util.List;
new DownloadContentBuilder()
.setId("8460dc6d-d129-fd1a-24b6-343dbf6531dd")
.setLocation("fonts/5a257ec3c5226e7be0be65e463f5b22eff108da853b9ff7bc47f1733b1ddacf2.gz")
.setLocation("fennec/catalog/f35a384a-90ea-41c6-a957-bb1845de97eb.gz")
.setFilename("CharisSILCompact-I.ttf")
.setChecksum("ab3ed6f2a4d4c2095b78227bd33155d7ccd05a879c107a291912640d4d64f767")
.setDownloadChecksum("5a257ec3c5226e7be0be65e463f5b22eff108da853b9ff7bc47f1733b1ddacf2")
.setDownloadChecksum("38a6469041c02624d43dfd41d2dd745e3e3211655e616188f65789a90952a1e9")
.setSize(1693988)
.setKind("font")
.setType("asset-archive")
@ -55,10 +55,10 @@ import java.util.List;
new DownloadContentBuilder()
.setId("c906275c-3747-fe27-426f-6187526a6f06")
.setLocation("fonts/cab284228b8dfe8ef46c3f1af70b5b6f9e92878f05e741ecc611e5e750a4a3b3.gz")
.setLocation("fennec/catalog/8c3bec92-d2df-4789-8c4a-0f523f026d96.gz")
.setFilename("CharisSILCompact-R.ttf")
.setChecksum("4ed509317f1bb441b185ea13bf1c9d19d1a0b396962efa3b5dc3190ad88f2067")
.setDownloadChecksum("cab284228b8dfe8ef46c3f1af70b5b6f9e92878f05e741ecc611e5e750a4a3b3")
.setDownloadChecksum("7c2ec1f550c2005b75383b878f737266b5f0b1c82679dd886c8bbe30c82e340e")
.setSize(1727656)
.setKind("font")
.setType("asset-archive")
@ -66,10 +66,10 @@ import java.util.List;
new DownloadContentBuilder()
.setId("ff5deecc-6ecc-d816-bb51-65face460119")
.setLocation("fonts/d95168996dc932e6504cb5448fcb759e0ee6e66c5c8603293b046d28ab589cce.gz")
.setLocation("fennec/catalog/ea115d71-e2ac-4609-853e-c978780776b1.gz")
.setFilename("ClearSans-Bold.ttf")
.setChecksum("385d0a293c1714770e198f7c762ab32f7905a0ed9d2993f69d640bd7232b4b70")
.setDownloadChecksum("d95168996dc932e6504cb5448fcb759e0ee6e66c5c8603293b046d28ab589cce")
.setDownloadChecksum("0d3c22bef90e7096f75b331bb7391de3aa43017e10d61041cd3085816db4919a")
.setSize(140136)
.setKind("font")
.setType("asset-archive")
@ -77,10 +77,10 @@ import java.util.List;
new DownloadContentBuilder()
.setId("a173d1db-373b-ce42-1335-6b3285cfdebd")
.setLocation("fonts/f5e18f4acc4ceaeca9e081b1be79cd6034e0dc7ad683fa240195fd6c838452e0.gz")
.setLocation("fennec/catalog/0838e513-2d99-4e53-b58f-6b970f6548c6.gz")
.setFilename("ClearSans-BoldItalic.ttf")
.setChecksum("7bce66864e38eecd7c94b6657b9b38c35ebfacf8046bfb1247e08f07fe933198")
.setDownloadChecksum("f5e18f4acc4ceaeca9e081b1be79cd6034e0dc7ad683fa240195fd6c838452e0")
.setDownloadChecksum("de0903164dde1ad3768d0bd6dec949871d6ab7be08f573d9d70f38c138a22e37")
.setSize(156124)
.setKind("font")
.setType("asset-archive")
@ -88,10 +88,10 @@ import java.util.List;
new DownloadContentBuilder()
.setId("e65c66df-0088-940d-ca5c-207c22118c0e")
.setLocation("fonts/56d12114ac15d913d7d9876c698889cd25f26e14966a8bd7424aeb0f61ffaf87.gz")
.setLocation("fennec/catalog/7550fa42-0947-478c-a5f0-5ea1bbb6ba27.gz")
.setFilename("ClearSans-Italic.ttf")
.setChecksum("87c13c5fbae832e4f85c3bd46fcbc175978234f39be5fe51c4937be4cbff3b68")
.setDownloadChecksum("56d12114ac15d913d7d9876c698889cd25f26e14966a8bd7424aeb0f61ffaf87")
.setDownloadChecksum("6e323db3115005dd0e96d2422db87a520f9ae426de28a342cd6cc87b55601d87")
.setSize(155672)
.setKind("font")
.setType("asset-archive")
@ -99,10 +99,10 @@ import java.util.List;
new DownloadContentBuilder()
.setId("25610abb-5dc8-fd75-40e7-990507f010c4")
.setLocation("fonts/1fc716662866b9c01e32dda3fc9c54ca3e57de8c6ac523f46305d8ae6c0a9cf4.gz")
.setLocation("fennec/catalog/dd9bee7d-d784-476b-a3dd-69af8e516487.gz")
.setFilename("ClearSans-Light.ttf")
.setChecksum("e4885f6188e7a8587f5621c077c6c1f5e8d3739dffc8f4d055c2ba87568c750a")
.setDownloadChecksum("1fc716662866b9c01e32dda3fc9c54ca3e57de8c6ac523f46305d8ae6c0a9cf4")
.setDownloadChecksum("19d4f7c67176e9e254c61420da9c7363d9fe5e6b4bb9d61afa4b3b574280714f")
.setSize(145976)
.setKind("font")
.setType("asset-archive")
@ -110,10 +110,10 @@ import java.util.List;
new DownloadContentBuilder()
.setId("ffe40339-a096-2262-c3f8-54af75c81fe6")
.setLocation("fonts/a29184ec6621dbd3bc6ae1e30bba70c479d1001bca647ea4a205ecb64d5a00a0.gz")
.setLocation("fennec/catalog/bc5ada8c-8cfc-443d-93d7-dc5f98138a07.gz")
.setFilename("ClearSans-Medium.ttf")
.setChecksum("5d0e0115f3a3ed4be3eda6d7eabb899bb9a361292802e763d53c72e00f629da1")
.setDownloadChecksum("a29184ec6621dbd3bc6ae1e30bba70c479d1001bca647ea4a205ecb64d5a00a0")
.setDownloadChecksum("edec86dab3ad2a97561cb41b584670262a48bed008c57bb587ee05ca47fb067f")
.setSize(148892)
.setKind("font")
.setType("asset-archive")
@ -121,10 +121,10 @@ import java.util.List;
new DownloadContentBuilder()
.setId("139a94be-ac69-0264-c9cc-8f2d071fd29d")
.setLocation("fonts/a381a3d4060e993af440a7b72fed29fa3a488536cc451d7c435d5fae1256318b.gz")
.setLocation("fennec/catalog/0490c768-6178-49c2-af88-9f8769ff3167.gz")
.setFilename("ClearSans-MediumItalic.ttf")
.setChecksum("937dda88b26469306258527d38e42c95e27e7ebb9f05bd1d7c5d706a3c9541d7")
.setDownloadChecksum("a381a3d4060e993af440a7b72fed29fa3a488536cc451d7c435d5fae1256318b")
.setDownloadChecksum("34edbd1b325dbffe7791fba8dd2d19852eb3c2fe00cff517ea2161ddc424ee22")
.setSize(155228)
.setKind("font")
.setType("asset-archive")
@ -132,10 +132,10 @@ import java.util.List;
new DownloadContentBuilder()
.setId("b887012a-01e1-7c94-fdcb-ca44d5b974a2")
.setLocation("fonts/87dec7f0331e19b293fc510f2764b9bd1b94595ac279cf9414f8d03c5bf34dca.gz")
.setLocation("fennec/catalog/78205bf8-c668-41b1-b68f-afd54f98713b.gz")
.setFilename("ClearSans-Regular.ttf")
.setChecksum("9b91bbdb95ffa6663da24fdaa8ee06060cd0a4d2dceaf1ffbdda00e04915ee5b")
.setDownloadChecksum("87dec7f0331e19b293fc510f2764b9bd1b94595ac279cf9414f8d03c5bf34dca")
.setDownloadChecksum("a72f1420b4da1ba9e6797adac34f08e72f94128a85e56542d5e6a8080af5f08a")
.setSize(142572)
.setKind("font")
.setType("asset-archive")
@ -143,10 +143,10 @@ import java.util.List;
new DownloadContentBuilder()
.setId("c8703652-d317-0356-0bf8-95441a5b2c9b")
.setLocation("fonts/64300b48b2867e5642212690f0ff9ea3988f47790311c444a81d25213b4102aa.gz")
.setLocation("fennec/catalog/3570f44f-9440-4aa0-abd0-642eaf2a1aa0.gz")
.setFilename("ClearSans-Thin.ttf")
.setChecksum("07b0db85a3ad99afeb803f0f35631436a7b4c67ac66d0c7f77d26a47357c592a")
.setDownloadChecksum("64300b48b2867e5642212690f0ff9ea3988f47790311c444a81d25213b4102aa")
.setDownloadChecksum("d9f23fd8687d6743f5c281c33539fb16f163304795039959b8caf159e6d62822")
.setSize(147004)
.setKind("font")
.setType("asset-archive")

Просмотреть файл

@ -104,8 +104,6 @@ public class FloatingToolbarTextSelection implements TextSelection, GeckoEventLi
@Override
public void handleMessage(final String event, final JSONObject message) {
Log.w("SKDBG", "Received event " + event + " with message: " + message.toString());
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {

Просмотреть файл

@ -268,11 +268,12 @@ public class ToolbarDisplayLayout extends ThemedLinearLayout {
return;
}
final boolean isHttpOrHttps = StringUtils.isHttpOrHttps(url);
final String baseDomain = tab.getBaseDomain();
String strippedURL = stripAboutReaderURL(url);
final boolean isHttpOrHttps = StringUtils.isHttpOrHttps(strippedURL);
if (mPrefs.shouldTrimUrls()) {
strippedURL = StringUtils.stripCommonSubdomains(StringUtils.stripScheme(strippedURL));
}
@ -290,12 +291,9 @@ public class ToolbarDisplayLayout extends ThemedLinearLayout {
&& SwitchBoard.isInExperiment(mActivity, Experiments.URLBAR_SHOW_ORIGIN_ONLY)) {
// Show just the base domain as title
setTitle(baseDomain);
} else if (isHttpOrHttps) {
} else {
// Display full URL with base domain highlighted as title
updateAndColorTitleFromFullURL(strippedURL, baseDomain, tab.isPrivate());
} else {
// Not http(s): Just show the full URL as title
setTitle(url);
}
}

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 494 B

После

Ширина:  |  Высота:  |  Размер: 494 B

Просмотреть файл

@ -1,3 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_menu_share_icon"/>

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 713 B

После

Ширина:  |  Высота:  |  Размер: 713 B

Просмотреть файл

До

Ширина:  |  Высота:  |  Размер: 832 B

После

Ширина:  |  Высота:  |  Размер: 832 B

Просмотреть файл

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_menu_share_icon"
android:insetTop="3dp"
android:insetRight="3dp"
android:insetBottom="3dp"
android:insetLeft="3dp"/>

Просмотреть файл

@ -30,9 +30,9 @@ public class GeckoNetworkManagerTest {
testingState = ManagerState.OnNoListeners;
assertNull(GeckoNetworkManager.getNextState(testingState, ManagerEvent.start));
assertNull(GeckoNetworkManager.getNextState(testingState, ManagerEvent.disableNotifications));
assertNull(GeckoNetworkManager.getNextState(testingState, ManagerEvent.receivedUpdate));
assertEquals(ManagerState.OnWithListeners, GeckoNetworkManager.getNextState(testingState, ManagerEvent.enableNotifications));
assertEquals(ManagerState.OffNoListeners, GeckoNetworkManager.getNextState(testingState, ManagerEvent.stop));
assertEquals(ManagerState.OnNoListeners, GeckoNetworkManager.getNextState(testingState, ManagerEvent.receivedUpdate));
testingState = ManagerState.OnWithListeners;
assertNull(GeckoNetworkManager.getNextState(testingState, ManagerEvent.start));

Просмотреть файл

@ -3481,7 +3481,9 @@ dnl ========================================================
dnl = Include install tracking on Android
dnl ========================================================
if test -n "$MOZ_INSTALL_TRACKING"; then
AC_DEFINE(MOZ_INSTALL_TRACKING)
if test -z "$MOZ_INSTALL_TRACKING_ADJUST_SDK_APP_TOKEN"; then
AC_MSG_ERROR([Must specify --with-adjust-sdk-keyfile when MOZ_INSTALL_TRACKING is defined!])
fi
fi
dnl ========================================================

Двоичные данные
other-licenses/7zstub/firefox/7zSD.sfx

Двоичный файл не отображается.

Просмотреть файл

@ -35,6 +35,101 @@ static LPCTSTR kTempDirPrefix = TEXT("7zS");
#define _SHELL_EXECUTE
/* BEGIN Mozilla customizations */
static char const *
FindStrInBuf(char const * buf, size_t bufLen, char const * str)
{
size_t index = 0;
while (index < bufLen) {
char const * result = strstr(buf + index, str);
if (result) {
return result;
}
while ((buf[index] != '\0') && (index < bufLen)) {
index++;
}
index++;
}
return NULL;
}
static bool
ReadPostSigningDataFromView(char const * view, DWORD size, AString& data)
{
// Find the offset and length of the certificate table,
// so we know the valid range to look for the token.
if (size < (0x3c + sizeof(UInt32))) {
return false;
}
UInt32 PEHeaderOffset = *(UInt32*)(view + 0x3c);
UInt32 optionalHeaderOffset = PEHeaderOffset + 24;
UInt32 certDirEntryOffset = 0;
if (size < (optionalHeaderOffset + sizeof(UInt16))) {
return false;
}
UInt16 magic = *(UInt16*)(view + optionalHeaderOffset);
if (magic == 0x010b) {
// 32-bit executable
certDirEntryOffset = optionalHeaderOffset + 128;
} else if (magic == 0x020b) {
// 64-bit executable; certain header fields are wider
certDirEntryOffset = optionalHeaderOffset + 144;
} else {
// Unknown executable
return false;
}
if (size < certDirEntryOffset + 8) {
return false;
}
UInt32 certTableOffset = *(UInt32*)(view + certDirEntryOffset);
UInt32 certTableLen = *(UInt32*)(view + certDirEntryOffset + sizeof(UInt32));
if (certTableOffset == 0 || certTableLen == 0 ||
size < (certTableOffset + certTableLen)) {
return false;
}
char const token[] = "__MOZCUSTOM__:";
// We're searching for a string inside a binary blob,
// so a normal strstr that bails on the first NUL won't work.
char const * tokenPos = FindStrInBuf(view + certTableOffset,
certTableLen, token);
if (tokenPos) {
size_t tokenLen = (sizeof(token) / sizeof(token[0])) - 1;
data = AString(tokenPos + tokenLen);
return true;
}
return false;
}
static bool
ReadPostSigningData(UString exePath, AString& data)
{
bool retval = false;
HANDLE exeFile = CreateFileW(exePath, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (exeFile != INVALID_HANDLE_VALUE) {
HANDLE mapping = CreateFileMapping(exeFile, NULL, PAGE_READONLY, 0, 0, NULL);
if (mapping != INVALID_HANDLE_VALUE) {
// MSDN claims the return value on failure is NULL,
// but I've also seen it returned on success, so double-check.
if (mapping || GetLastError() == ERROR_SUCCESS) {
char * view = (char*)MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
if (view) {
DWORD fileSize = GetFileSize(exeFile, NULL);
retval = ReadPostSigningDataFromView(view, fileSize, data);
}
CloseHandle(mapping);
}
}
CloseHandle(exeFile);
}
return retval;
}
/* END Mozilla customizations */
static bool ReadDataString(LPCWSTR fileName, LPCSTR startID,
LPCSTR endID, AString &stringResult)
{
@ -331,7 +426,22 @@ int APIENTRY WinMain(
}
/* BEGIN Mozilla customizations */
// The code immediately above handles the error case for extraction.
// Retrieve and store any data added to this file after signing.
{
AString postSigningData;
if (ReadPostSigningData(fullPath, postSigningData)) {
NFile::NName::CParsedPath postSigningDataFilePath;
postSigningDataFilePath.ParsePath(tempDirPath);
postSigningDataFilePath.PathParts.Add(L"postSigningData");
NFile::NIO::COutFile postSigningDataFile;
postSigningDataFile.Create(postSigningDataFilePath.MergePath(), true);
UInt32 written = 0;
postSigningDataFile.Write(postSigningData, postSigningData.Length(), written);
}
}
if (extractOnly) {
return 0;
}

Просмотреть файл

@ -511,7 +511,9 @@ AsyncFetchAndSetIconForPage::AsyncOnChannelRedirect(
, nsIAsyncVerifyRedirectCallback *cb
)
{
(void)cb->OnRedirectVerifyCallback(NS_OK);
// If we've been canceled, stop the redirect with NS_BINDING_ABORTED, and
// handle the cancel on the original channel.
(void)cb->OnRedirectVerifyCallback(mCanceled ? NS_BINDING_ABORTED : NS_OK);
return NS_OK;
}

Просмотреть файл

@ -996,9 +996,12 @@ JSHistogram_Add(JSContext *cx, unsigned argc, JS::Value *vp)
MOZ_ASSERT(h);
Histogram::ClassType type = h->histogram_type();
JS::CallArgs args = CallArgsFromVp(argc, vp);
// If we don't have an argument for the count histogram, assume an increment of 1.
// Otherwise, make sure to run some sanity checks on the argument.
int32_t value = 1;
if (type != base::CountHistogram::COUNT_HISTOGRAM) {
JS::CallArgs args = CallArgsFromVp(argc, vp);
if ((type != base::CountHistogram::COUNT_HISTOGRAM) || args.length()) {
if (!args.length()) {
JS_ReportError(cx, "Expected one argument");
return false;
@ -1222,9 +1225,11 @@ JSKeyedHistogram_Add(JSContext *cx, unsigned argc, JS::Value *vp)
}
const uint32_t type = keyed->GetHistogramType();
int32_t value = 1;
if (type != base::CountHistogram::COUNT_HISTOGRAM) {
// If we don't have an argument for the count histogram, assume an increment of 1.
// Otherwise, make sure to run some sanity checks on the argument.
int32_t value = 1;
if ((type != base::CountHistogram::COUNT_HISTOGRAM) || (args.length() == 2)) {
if (args.length() < 2) {
JS_ReportError(cx, "Expected two arguments for this histogram type");
return false;

Просмотреть файл

@ -126,12 +126,6 @@ function savePing(aPing) {
}
}
function tomorrow(date) {
let d = new Date(date);
d.setDate(d.getDate() + 1);
return d;
}
/**
* @return {String} This returns a string with the gzip compressed data.
*/

Просмотреть файл

@ -105,12 +105,6 @@ var gLastMemoryPoll = null;
var gWasDebuggerAttached = false;
function getLocale() {
return Cc["@mozilla.org/chrome/chrome-registry;1"].
getService(Ci.nsIXULChromeRegistry).
getSelectedLocale('global');
}
XPCOMUtils.defineLazyServiceGetter(this, "Telemetry",
"@mozilla.org/base/telemetry;1",
"nsITelemetry");
@ -189,35 +183,6 @@ function getPingType(aPayload) {
return PING_TYPE_MAIN;
}
/**
* Date.toISOString() gives us UTC times, this gives us local times in the ISO date format.
* http://www.w3.org/TR/NOTE-datetime
*/
function toLocalTimeISOString(date) {
function padNumber(number, places) {
number = number.toString();
while (number.length < places) {
number = "0" + number;
}
return number;
}
let sign = (n) => n >= 0 ? "+" : "-";
// getTimezoneOffset counter-intuitively returns -60 for UTC+1.
let tzOffset = - date.getTimezoneOffset();
// YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
return padNumber(date.getFullYear(), 4)
+ "-" + padNumber(date.getMonth() + 1, 2)
+ "-" + padNumber(date.getDate(), 2)
+ "T" + padNumber(date.getHours(), 2)
+ ":" + padNumber(date.getMinutes(), 2)
+ ":" + padNumber(date.getSeconds(), 2)
+ "." + date.getMilliseconds()
+ sign(tzOffset) + padNumber(Math.floor(Math.abs(tzOffset / 60)), 2)
+ ":" + padNumber(Math.abs(tzOffset % 60), 2);
}
/**
* Annotate the current session ID with the crash reporter to map potential
* crash pings with the related main ping.
@ -1022,8 +987,8 @@ var Impl = {
getMetadata: function getMetadata(reason) {
this._log.trace("getMetadata - Reason " + reason);
const sessionStartDate = toLocalTimeISOString(Utils.truncateToDays(this._sessionStartDate));
const subsessionStartDate = toLocalTimeISOString(Utils.truncateToDays(this._subsessionStartDate));
const sessionStartDate = Utils.toLocalTimeISOString(Utils.truncateToDays(this._sessionStartDate));
const subsessionStartDate = Utils.toLocalTimeISOString(Utils.truncateToDays(this._subsessionStartDate));
const monotonicNow = Policy.monotonicNow();
let ret = {

Просмотреть файл

@ -118,4 +118,35 @@ this.TelemetryUtils = {
return (aEndDate.getMonth() - aStartDate.getMonth())
+ 12 * (aEndDate.getFullYear() - aStartDate.getFullYear());
},
/**
* Date.toISOString() gives us UTC times, this gives us local times in
* the ISO date format. See http://www.w3.org/TR/NOTE-datetime
* @param {Object} date The input date.
* @return {String} The local time ISO string.
*/
toLocalTimeISOString: function(date) {
function padNumber(number, places) {
number = number.toString();
while (number.length < places) {
number = "0" + number;
}
return number;
}
let sign = (n) => n >= 0 ? "+" : "-";
// getTimezoneOffset counter-intuitively returns -60 for UTC+1.
let tzOffset = - date.getTimezoneOffset();
// YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)
return padNumber(date.getFullYear(), 4)
+ "-" + padNumber(date.getMonth() + 1, 2)
+ "-" + padNumber(date.getDate(), 2)
+ "T" + padNumber(date.getHours(), 2)
+ ":" + padNumber(date.getMinutes(), 2)
+ ":" + padNumber(date.getSeconds(), 2)
+ "." + date.getMilliseconds()
+ sign(tzOffset) + padNumber(Math.floor(Math.abs(tzOffset / 60)), 2)
+ ":" + padNumber(Math.abs(tzOffset % 60), 2);
},
};

Просмотреть файл

@ -42,7 +42,7 @@ function test_histogram(histogram_type, name, min, max, bucket_count) {
do_check_eq(i, 1);
}
var hgrams = Telemetry.histogramSnapshots
gh = hgrams[name]
let gh = hgrams[name]
do_check_eq(gh.histogram_type, histogram_type);
do_check_eq(gh.min, min)
@ -602,6 +602,11 @@ function test_histogram_recording_enabled() {
Assert.equal(orig.sum + 2, h.snapshot().sum,
"When recording is re-enabled add should record.");
// Check that we're correctly accumulating values other than 1.
h.clear();
h.add(3);
Assert.equal(3, h.snapshot().sum, "Recording counts greater than 1 should work.");
// Check that a histogram with recording disabled by default behaves correctly
h = Telemetry.getHistogramById("TELEMETRY_TEST_COUNT_INIT_NO_RECORD");
orig = h.snapshot();
@ -629,7 +634,7 @@ function test_keyed_histogram_recording_enabled() {
// Check RecordingEnabled for keyed histograms which are recording by default
const TEST_KEY = "record_foo";
h = Telemetry.getKeyedHistogramById("TELEMETRY_TEST_KEYED_RELEASE_OPTOUT");
let h = Telemetry.getKeyedHistogramById("TELEMETRY_TEST_KEYED_RELEASE_OPTOUT");
h.clear();
h.add(TEST_KEY, 1);

Просмотреть файл

@ -12,9 +12,21 @@ var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
Cu.import("resource://gre/modules/RemotePageManager.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const gInContentProcess = Services.appinfo.processType == Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT;
Services.cpmm.addMessageListener("gmp-plugin-crash", msg => {
let gmpservice = Cc["@mozilla.org/gecko-media-plugin-service;1"]
.getService(Ci.mozIGeckoMediaPluginService);
gmpservice.RunPluginCrashCallbacks(msg.data.pluginID, msg.data.pluginName);
});
// Forward inner-window-destroyed notifications with the inner window ID,
// so that code in the parent that should do something when content
// windows go away can do it
if (gInContentProcess) {
Services.obs.addObserver((subject, topic, data) => {
let innerWindowID = subject.QueryInterface(Ci.nsISupportsPRUint64).data;
Services.cpmm.sendAsyncMessage("Toolkit:inner-window-destroyed", innerWindowID);
}, "inner-window-destroyed", false);
}

Просмотреть файл

@ -19,3 +19,4 @@ skip-if = os == 'android'
[test_tree_column_reorder.xul]
skip-if = toolkit == 'android'
[test_videocontrols.html]
[test_videocontrols_onclickplay.html]

Просмотреть файл

@ -0,0 +1,74 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Video controls test</title>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="text/javascript" src="head.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
<video id="video" controls mozNoDynamicControls preload="auto"></video>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
var video = document.getElementById("video");
function startMediaLoad() {
// Kick off test once video has loaded, in its canplaythrough event handler.
video.src = "seek_with_sound.ogg";
video.addEventListener("canplaythrough", runTest, false);
}
function loadevent(event) {
SpecialPowers.pushPrefEnv({"set": [["media.cache_size", 40000]]}, startMediaLoad);
}
window.addEventListener("load", loadevent, false);
function runTest() {
video.addEventListener("click", function() {
this.play();
});
ok(video.paused, "video should be paused initially");
new Promise(resolve => {
let timeupdates = 0;
video.addEventListener("timeupdate", function timeupdate() {
ok(!video.paused, "video should not get paused after clicking in middle");
if (++timeupdates == 3) {
video.removeEventListener("timeupdate", timeupdate);
resolve();
}
});
synthesizeMouseAtCenter(video, {}, window);
}).then(function() {
new Promise(resolve => {
video.addEventListener("pause", function onpause() {
setTimeout(() => {
ok(video.paused, "video should still be paused 200ms after pause request");
// When the video reaches the end of playback it is automatically paused.
// Check during the pause event that the video has not reachd the end
// of playback.
ok(!video.ended, "video should not have paused due to playback ending");
resolve();
}, 200);
});
synthesizeMouse(video, 10, video.clientHeight - 10, {}, window);
}).then(SimpleTest.finish);
});
}
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -211,63 +211,6 @@
<label class="errorLabel" anonid="errorGeneric">&error.generic;</label>
</vbox>
<vbox class="statsOverlay" hidden="true">
<html:div class="statsDiv" xmlns="http://www.w3.org/1999/xhtml">
<table class="statsTable">
<tr>
<td class="statLabel">&stats.media;</td>
<td class="statValue filename"><span class="statFilename"/></td>
</tr>
<tr>
<td class="statLabel">&stats.size;</td>
<td class="statValue size"><span class="statSize"/></td>
</tr>
<tr style="height: 1em;"/>
<tr>
<td class="statLabel">&stats.activity;</td>
<td class="statValue activity">
<span class="statActivity">
<span class="statActivityPaused">&stats.activityPaused;</span>
<span class="statActivityPlaying">&stats.activityPlaying;</span>
<span class="statActivityEnded">&stats.activityEnded;</span>
<span class="statActivitySeeking">&stats.activitySeeking;</span>
</span>
</td>
</tr>
<tr>
<td class="statLabel">&stats.volume;</td> <td class="statValue"><span class="statVolume"/></td>
</tr>
<tr>
<!-- Localization note: readyState is a HTML5 API MediaElement-specific attribute and should not be localized. -->
<td class="statLabel">readyState</td> <td class="statValue"><span class="statReadyState"/></td>
</tr>
<tr>
<!-- Localization note: networkState is a HTML5 API MediaElement-specific attribute and should not be localized. -->
<td class="statLabel">networkState</td> <td class="statValue"><span class="statNetState"/></td>
</tr>
<tr style="height: 1em;"/>
<tr>
<td class="statLabel">&stats.framesParsed;</td>
<td class="statValue"><span class="statFramesParsed"/></td>
</tr>
<tr>
<td class="statLabel">&stats.framesDecoded;</td>
<td class="statValue"><span class="statFramesDecoded"/></td>
</tr>
<tr>
<td class="statLabel">&stats.framesPresented;</td>
<td class="statValue"><span class="statFramesPresented"/></td>
</tr>
<tr>
<td class="statLabel">&stats.framesPainted;</td>
<td class="statValue"><span class="statFramesPainted"/></td>
</tr>
</table>
</html:div>
</vbox>
<vbox class="controlsOverlay">
<stack flex="1">
<spacer class="controlsSpacer" flex="1"/>
@ -327,7 +270,6 @@
statusOverlay : null,
controlsSpacer : null,
clickToPlay : null,
stats : {},
controlsOverlay : null,
fullscreenButton : null,
@ -474,13 +416,6 @@
// _volumeControlWidth, since the volume slider implementation
// depends on it.
this.updateVolumeControls();
// Preserve Statistics when toggling fullscreen mode due to bug 714071.
if (this.video.mozMediaStatisticsShowing)
this.showStatistics(true);
this._handleCustomEventsBound = this.handleCustomEvents.bind(this);
this.video.addEventListener("media-showStatistics", this._handleCustomEventsBound, false, true);
},
setupNewLoadState : function() {
@ -503,12 +438,6 @@
this.startFade(this.controlBar, shouldShow, true);
},
handleCustomEvents : function (e) {
if (!e.isTrusted)
return;
this.showStatistics(e.detail);
},
get dynamicControls() {
// Don't fade controls for <audio> elements.
var enabled = !this.isAudioOnly;
@ -702,10 +631,6 @@
},
terminateEventListeners : function () {
if (this.statsInterval) {
clearInterval(this.statsInterval);
this.statsInterval = null;
}
for (let event of this.videoEvents)
this.video.removeEventListener(event, this, false);
@ -714,9 +639,6 @@
delete this.controlListeners;
this.video.removeEventListener("media-showStatistics", this._handleCustomEventsBound, false);
delete this._handleCustomEventsBound;
this.log("--- videocontrols terminated ---");
},
@ -1112,13 +1034,19 @@
return;
}
// Read defaultPrevented asynchronously, since Web content
// may want to consume the "click" event but will only
// receive it after us.
let self = this;
setTimeout(function clickToPlayCallback() {
if (!e.defaultPrevented)
self.togglePause();
// Read defaultPrevented and the playback state asynchronously,
// since Web content may want to consume the "click" event
// but will only receive it after us. If web content
// doesn't use preventDefault but still toggles playback,
// we will treat that act the same as a call to preventDefault()
// so the web content-initiated toggle is not reverted.
let previousState = this.video.paused;
setTimeout(() => {
if (e.defaultPrevented ||
this.video.paused != previousState) {
return;
}
this.togglePause();
}, 0);
},
hideClickToPlay : function () {
@ -1172,91 +1100,6 @@
return parseInt(value, 10);
},
STATS_INTERVAL_MS : 500,
statsInterval : null,
showStatistics : function(shouldShow) {
if (this.statsInterval) {
clearInterval(this.statsInterval);
this.statsInterval = null;
}
if (shouldShow) {
this.video.mozMediaStatisticsShowing = true;
this.statsOverlay.hidden = false;
this.statsInterval = setInterval(this.updateStats.bind(this), this.STATS_INTERVAL_MS);
this.updateStats();
} else {
this.video.mozMediaStatisticsShowing = false;
this.statsOverlay.hidden = true;
}
},
updateStats : function() {
if (this.videocontrols.randomID != this.randomID) {
this.terminateEventListeners();
return;
}
let v = this.video;
let s = this.stats;
let src = v.currentSrc || v.src || "(no source found)";
let srcParts = src.split('/');
let srcIdx = srcParts.length - 1;
if (src.lastIndexOf('/') == src.length - 1)
srcIdx--;
s.filename.textContent = decodeURI(srcParts[srcIdx]);
let size = v.videoWidth + "x" + v.videoHeight;
if (this._getComputedPropertyValueAsInt(this.video, "width") != v.videoWidth || this._getComputedPropertyValueAsInt(this.video, "height") != v.videoHeight)
size += " scaled to " + this._getComputedPropertyValueAsInt(this.video, "width") + "x" + this._getComputedPropertyValueAsInt(this.video, "height");
s.size.textContent = size;
let activity;
if (v.paused)
activity = "paused";
else
activity = "playing";
if (v.ended)
activity = "ended";
if (s.activity.getAttribute("activity") != activity)
s.activity.setAttribute("activity", activity);
if (v.seeking && !s.activity.hasAttribute("seeking"))
s.activity.setAttribute("seeking", true);
else if (s.activity.hasAttribute("seeking"))
s.activity.removeAttribute("seeking");
let readyState = v.readyState;
switch (readyState) {
case v.HAVE_NOTHING: readyState = "HAVE_NOTHING"; break;
case v.HAVE_METADATA: readyState = "HAVE_METADATA"; break;
case v.HAVE_CURRENT_DATA: readyState = "HAVE_CURRENT_DATA"; break;
case v.HAVE_FUTURE_DATA: readyState = "HAVE_FUTURE_DATA"; break;
case v.HAVE_ENOUGH_DATA: readyState = "HAVE_ENOUGH_DATA"; break;
}
s.readyState.textContent = readyState;
let networkState = v.networkState;
switch (networkState) {
case v.NETWORK_EMPTY: networkState = "NETWORK_EMPTY"; break;
case v.NETWORK_IDLE: networkState = "NETWORK_IDLE"; break;
case v.NETWORK_LOADING: networkState = "NETWORK_LOADING"; break;
case v.NETWORK_NO_SOURCE: networkState = "NETWORK_NO_SOURCE"; break;
}
s.netState.textContent = networkState;
s.framesParsed.textContent = v.mozParsedFrames;
s.framesDecoded.textContent = v.mozDecodedFrames;
s.framesPresented.textContent = v.mozPresentedFrames;
s.framesPainted.textContent = v.mozPaintedFrames;
let volume = Math.round(v.volume * 100) + "%";
if (v.muted)
volume += " (muted)";
s.volume.textContent = volume;
},
keyHandler : function(event) {
// Ignore keys when content might be providing its own.
if (!this.video.hasAttribute("controls"))
@ -1375,7 +1218,7 @@
log : function (msg) {
if (this.debug)
dump("videoctl: " + msg + "\n");
console.log("videoctl: " + msg + "\n");
},
get isTopLevelSyntheticDocument() {
@ -1476,25 +1319,12 @@
this.durationLabel = document.getAnonymousElementByAttribute(binding, "class", "durationLabel");
this.positionLabel = document.getAnonymousElementByAttribute(binding, "class", "positionLabel");
this.statusOverlay = document.getAnonymousElementByAttribute(binding, "class", "statusOverlay");
this.statsOverlay = document.getAnonymousElementByAttribute(binding, "class", "statsOverlay");
this.controlsOverlay = document.getAnonymousElementByAttribute(binding, "class", "controlsOverlay");
this.controlsSpacer = document.getAnonymousElementByAttribute(binding, "class", "controlsSpacer");
this.clickToPlay = document.getAnonymousElementByAttribute(binding, "class", "clickToPlay");
this.fullscreenButton = document.getAnonymousElementByAttribute(binding, "class", "fullscreenButton");
this.volumeForeground = document.getAnonymousElementByAttribute(binding, "anonid", "volumeForeground");
this.statsTable = document.getAnonymousElementByAttribute(binding, "class", "statsTable");
this.stats.filename = document.getAnonymousElementByAttribute(binding, "class", "statFilename");
this.stats.size = document.getAnonymousElementByAttribute(binding, "class", "statSize");
this.stats.activity = document.getAnonymousElementByAttribute(binding, "class", "statActivity");
this.stats.volume = document.getAnonymousElementByAttribute(binding, "class", "statVolume");
this.stats.readyState = document.getAnonymousElementByAttribute(binding, "class", "statReadyState");
this.stats.netState = document.getAnonymousElementByAttribute(binding, "class", "statNetState");
this.stats.framesParsed = document.getAnonymousElementByAttribute(binding, "class", "statFramesParsed");
this.stats.framesDecoded = document.getAnonymousElementByAttribute(binding, "class", "statFramesDecoded");
this.stats.framesPresented = document.getAnonymousElementByAttribute(binding, "class", "statFramesPresented");
this.stats.framesPainted = document.getAnonymousElementByAttribute(binding, "class", "statFramesPainted");
this.isAudioOnly = (this.video instanceof HTMLAudioElement);
this.setupInitialState();
this.setupNewLoadState();
@ -1517,7 +1347,7 @@
}
addListener(this.muteButton, "command", this.toggleMute);
addListener(this.playButton, "command", this.togglePause);
addListener(this.playButton, "click", this.clickToPlayClickHandler);
addListener(this.fullscreenButton, "command", this.toggleFullscreen);
addListener(this.clickToPlay, "click", this.clickToPlayClickHandler);
addListener(this.controlsSpacer, "click", this.clickToPlayClickHandler);

Просмотреть файл

@ -74,6 +74,7 @@ this.UpdateUtils = {
url = url.replace(/%BUILD_ID%/g, Services.appinfo.appBuildID);
url = url.replace(/%BUILD_TARGET%/g, Services.appinfo.OS + "_" + this.ABI);
url = url.replace(/%OS_VERSION%/g, this.OSVersion);
url = url.replace(/%SYSTEM_CAPABILITIES%/g, gSystemCapabilities);
if (/%LOCALE%/.test(url)) {
url = url.replace(/%LOCALE%/g, this.Locale);
}
@ -150,6 +151,45 @@ XPCOMUtils.defineLazyGetter(UpdateUtils, "Locale", function() {
return null;
});
/**
* Provides adhoc system capability information for application update.
*/
XPCOMUtils.defineLazyGetter(this, "gSystemCapabilities", function aus_gSC() {
if (AppConstants.platform == "win") {
const PF_MMX_INSTRUCTIONS_AVAILABLE = 3; // MMX
const PF_XMMI_INSTRUCTIONS_AVAILABLE = 6; // SSE
const PF_XMMI64_INSTRUCTIONS_AVAILABLE = 10; // SSE2
const PF_SSE3_INSTRUCTIONS_AVAILABLE = 13; // SSE3
let lib = ctypes.open("kernel32.dll");
let IsProcessorFeaturePresent = lib.declare("IsProcessorFeaturePresent",
ctypes.winapi_abi,
ctypes.int32_t, /* success */
ctypes.uint32_t); /* DWORD */
let instructionSet = "unknown";
try {
if (IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE)) {
instructionSet = "SSE3";
} else if (IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE)) {
instructionSet = "SSE2";
} else if (IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE)) {
instructionSet = "SSE";
} else if (IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE)) {
instructionSet = "MMX";
}
} catch (e) {
instructionSet = "error";
Cu.reportError("Error getting processor instruction set. " +
"Exception: " + e);
}
lib.close();
return instructionSet;
}
return "NA"
});
/* Windows only getter that returns the processor architecture. */
XPCOMUtils.defineLazyGetter(this, "gWinCPUArch", function aus_gWinCPUArch() {
// Get processor architecture

Просмотреть файл

@ -349,9 +349,68 @@ function check_test_pt9() {
run_test_pt10();
}
// url constructed with %DISTRIBUTION%
// url constructed with %SYSTEM_CAPABILITIES%
function run_test_pt10() {
gCheckFunc = check_test_pt10;
let url = URL_PREFIX + "%SYSTEM_CAPABILITIES%/";
debugDump("testing url constructed with %SYSTEM_CAPABILITIES% - " + url);
setUpdateURLOverride(url);
gUpdateChecker.checkForUpdates(updateCheckListener, true);
}
/**
* Provides system capability information for application update though it may
* be used by other consumers.
*/
function getSystemCapabilities() {
if (IS_WIN) {
const PF_MMX_INSTRUCTIONS_AVAILABLE = 3; // MMX
const PF_XMMI_INSTRUCTIONS_AVAILABLE = 6; // SSE
const PF_XMMI64_INSTRUCTIONS_AVAILABLE = 10; // SSE2
const PF_SSE3_INSTRUCTIONS_AVAILABLE = 13; // SSE3
let lib = ctypes.open("kernel32.dll");
let IsProcessorFeaturePresent = lib.declare("IsProcessorFeaturePresent",
ctypes.winapi_abi,
ctypes.int32_t, /* success */
ctypes.uint32_t); /* DWORD */
let instructionSet = "unknown";
try {
if (IsProcessorFeaturePresent(PF_SSE3_INSTRUCTIONS_AVAILABLE)) {
instructionSet = "SSE3";
} else if (IsProcessorFeaturePresent(PF_XMMI64_INSTRUCTIONS_AVAILABLE)) {
instructionSet = "SSE2";
} else if (IsProcessorFeaturePresent(PF_XMMI_INSTRUCTIONS_AVAILABLE)) {
instructionSet = "SSE";
} else if (IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE)) {
instructionSet = "MMX";
}
} catch (e) {
Cu.reportError("Error getting processor instruction set. " +
"Exception: " + e);
}
lib.close();
return instructionSet;
}
return "NA"
}
function check_test_pt10() {
let systemCapabilities = "NA";
if (IS_WIN) {
systemCapabilities = getSystemCapabilities();
}
Assert.equal(getResult(gRequestURL), systemCapabilities,
"the url param for %SYSTEM_CAPABILITIES%" + MSG_SHOULD_EQUAL);
run_test_pt11();
}
// url constructed with %DISTRIBUTION%
function run_test_pt11() {
gCheckFunc = check_test_pt11;
let url = URL_PREFIX + "%DISTRIBUTION%/";
debugDump("testing url constructed with %DISTRIBUTION% - " + url);
setUpdateURLOverride(url);
@ -359,15 +418,15 @@ function run_test_pt10() {
gUpdateChecker.checkForUpdates(updateCheckListener, true);
}
function check_test_pt10() {
function check_test_pt11() {
Assert.equal(getResult(gRequestURL), "test_distro",
"the url param for %DISTRIBUTION%" + MSG_SHOULD_EQUAL);
run_test_pt11();
run_test_pt12();
}
// url constructed with %DISTRIBUTION_VERSION%
function run_test_pt11() {
gCheckFunc = check_test_pt11;
function run_test_pt12() {
gCheckFunc = check_test_pt12;
let url = URL_PREFIX + "%DISTRIBUTION_VERSION%/";
debugDump("testing url constructed with %DISTRIBUTION_VERSION% - " + url);
setUpdateURLOverride(url);
@ -375,15 +434,15 @@ function run_test_pt11() {
gUpdateChecker.checkForUpdates(updateCheckListener, true);
}
function check_test_pt11() {
function check_test_pt12() {
Assert.equal(getResult(gRequestURL), "test_distro_version",
"the url param for %DISTRIBUTION_VERSION%" + MSG_SHOULD_EQUAL);
run_test_pt12();
run_test_pt13();
}
// url with force param that doesn't already have a param - bug 454357
function run_test_pt12() {
gCheckFunc = check_test_pt12;
function run_test_pt13() {
gCheckFunc = check_test_pt13;
let url = URL_PREFIX;
debugDump("testing url with force param that doesn't already have a " +
"param - " + url);
@ -391,38 +450,38 @@ function run_test_pt12() {
gUpdateChecker.checkForUpdates(updateCheckListener, true);
}
function check_test_pt12() {
function check_test_pt13() {
Assert.equal(getResult(gRequestURL), "?force=1",
"the url query string for force" + MSG_SHOULD_EQUAL);
run_test_pt13();
run_test_pt14();
}
// url with force param that already has a param - bug 454357
function run_test_pt13() {
gCheckFunc = check_test_pt13;
function run_test_pt14() {
gCheckFunc = check_test_pt14;
let url = URL_PREFIX + "?extra=param";
debugDump("testing url with force param that already has a param - " + url);
setUpdateURLOverride(url);
gUpdateChecker.checkForUpdates(updateCheckListener, true);
}
function check_test_pt13() {
function check_test_pt14() {
Assert.equal(getResult(gRequestURL), "?extra=param&force=1",
"the url query string for force with an extra string" +
MSG_SHOULD_EQUAL);
run_test_pt14();
run_test_pt15();
}
function run_test_pt14() {
function run_test_pt15() {
Services.prefs.setCharPref("app.update.custom", "custom");
gCheckFunc = check_test_pt14;
gCheckFunc = check_test_pt15;
let url = URL_PREFIX + "?custom=%CUSTOM%";
debugDump("testing url constructed with %CUSTOM% - " + url);
setUpdateURLOverride(url);
gUpdateChecker.checkForUpdates(updateCheckListener, true);
}
function check_test_pt14() {
function check_test_pt15() {
Assert.equal(getResult(gRequestURL), "?custom=custom&force=1",
"the url query string for force with a custom string" +
MSG_SHOULD_EQUAL);