зеркало из https://github.com/mozilla/gecko-dev.git
Bug 548763 - Show download progress in OS X app dock icon. r=dao r=josh
--HG-- rename : widget/tests/taskbar_progress.xul => widget/tests/test_taskbar_progress.xul
This commit is contained in:
Родитель
092affd5c4
Коммит
107c52d281
|
@ -1486,14 +1486,9 @@ var gBrowserInit = {
|
|||
// downloads will start right away, and getting the service again won't hurt.
|
||||
setTimeout(function() {
|
||||
Services.downloads;
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (Win7Features) {
|
||||
let DownloadTaskbarProgress =
|
||||
Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm", {}).DownloadTaskbarProgress;
|
||||
DownloadTaskbarProgress.onBrowserWindowLoad(window);
|
||||
}
|
||||
#endif
|
||||
}, 10000);
|
||||
|
||||
// The object handling the downloads indicator is also initialized here in the
|
||||
|
|
|
@ -14,13 +14,21 @@ this.EXPORTED_SYMBOLS = [
|
|||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
const kTaskbarID = "@mozilla.org/windows-taskbar;1";
|
||||
const kTaskbarIDWin = "@mozilla.org/windows-taskbar;1";
|
||||
const kTaskbarIDMac = "@mozilla.org/widget/macdocksupport;1";
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// DownloadTaskbarProgress Object
|
||||
|
||||
this.DownloadTaskbarProgress =
|
||||
{
|
||||
init: function DTP_init()
|
||||
{
|
||||
if (DownloadTaskbarProgressUpdater) {
|
||||
DownloadTaskbarProgressUpdater._init();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when a browser window appears. This has an effect only when we
|
||||
* don't already have an active window.
|
||||
|
@ -31,6 +39,7 @@ this.DownloadTaskbarProgress =
|
|||
*/
|
||||
onBrowserWindowLoad: function DTP_onBrowserWindowLoad(aWindow)
|
||||
{
|
||||
this.init();
|
||||
if (!DownloadTaskbarProgressUpdater) {
|
||||
return;
|
||||
}
|
||||
|
@ -83,6 +92,9 @@ this.DownloadTaskbarProgress =
|
|||
|
||||
var DownloadTaskbarProgressUpdater =
|
||||
{
|
||||
/// Whether the taskbar is initialized.
|
||||
_initialized: false,
|
||||
|
||||
/// Reference to the taskbar.
|
||||
_taskbar: null,
|
||||
|
||||
|
@ -94,18 +106,27 @@ var DownloadTaskbarProgressUpdater =
|
|||
*/
|
||||
_init: function DTPU_init()
|
||||
{
|
||||
if (!(kTaskbarID in Cc)) {
|
||||
// This means that the component isn't available
|
||||
DownloadTaskbarProgressUpdater = null;
|
||||
return;
|
||||
if (this._initialized) {
|
||||
return; // Already initialized
|
||||
}
|
||||
this._initialized = true;
|
||||
|
||||
this._taskbar = Cc[kTaskbarID].getService(Ci.nsIWinTaskbar);
|
||||
if (kTaskbarIDWin in Cc) {
|
||||
this._taskbar = Cc[kTaskbarIDWin].getService(Ci.nsIWinTaskbar);
|
||||
if (!this._taskbar.available) {
|
||||
// The Windows version is probably too old
|
||||
DownloadTaskbarProgressUpdater = null;
|
||||
return;
|
||||
}
|
||||
} else if (kTaskbarIDMac in Cc) {
|
||||
this._activeTaskbarProgress = Cc[kTaskbarIDMac].
|
||||
getService(Ci.nsITaskbarProgress);
|
||||
} else {
|
||||
DownloadTaskbarProgressUpdater = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this._taskbarState = Ci.nsITaskbarProgress.STATE_NO_PROGRESS;
|
||||
|
||||
this._dm = Cc["@mozilla.org/download-manager;1"].
|
||||
getService(Ci.nsIDownloadManager);
|
||||
|
@ -126,6 +147,8 @@ var DownloadTaskbarProgressUpdater =
|
|||
_uninit: function DTPU_uninit() {
|
||||
this._dm.removeListener(this);
|
||||
this._os.removeObserver(this, "quit-application-granted");
|
||||
this._activeTaskbarProgress = null;
|
||||
this._initialized = false;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -150,6 +173,7 @@ var DownloadTaskbarProgressUpdater =
|
|||
*/
|
||||
_setActiveWindow: function DTPU_setActiveWindow(aWindow, aIsDownloadWindow)
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
// Clear out the taskbar for the old active window. (If there was no active
|
||||
// window, this is a no-op.)
|
||||
this._clearTaskbar();
|
||||
|
@ -175,13 +199,27 @@ var DownloadTaskbarProgressUpdater =
|
|||
else {
|
||||
this._activeTaskbarProgress = null;
|
||||
}
|
||||
#endif
|
||||
},
|
||||
|
||||
/// Current state displayed on the active window's taskbar item
|
||||
_taskbarState: Ci.nsITaskbarProgress.STATE_NO_PROGRESS,
|
||||
_taskbarState: null,
|
||||
_totalSize: 0,
|
||||
_totalTransferred: 0,
|
||||
|
||||
// If the active window is not the download manager window, set the state
|
||||
// only if it is normal or indeterminate.
|
||||
_shouldSetState: function DTPU_shouldSetState()
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
return this._activeWindowIsDownloadWindow ||
|
||||
(this._taskbarState == Ci.nsITaskbarProgress.STATE_NORMAL ||
|
||||
this._taskbarState == Ci.nsITaskbarProgress.STATE_INDETERMINATE);
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the active window's taskbar indicator with the current state. There
|
||||
* are two cases here:
|
||||
|
@ -198,11 +236,7 @@ var DownloadTaskbarProgressUpdater =
|
|||
return;
|
||||
}
|
||||
|
||||
// If the active window is not the download manager window, set the state
|
||||
// only if it is normal or indeterminate.
|
||||
if (this._activeWindowIsDownloadWindow ||
|
||||
(this._taskbarState == Ci.nsITaskbarProgress.STATE_NORMAL ||
|
||||
this._taskbarState == Ci.nsITaskbarProgress.STATE_INDETERMINATE)) {
|
||||
if (this._shouldSetState()) {
|
||||
this._activeTaskbarProgress.setProgressState(this._taskbarState,
|
||||
this._totalTransferred,
|
||||
this._totalSize);
|
||||
|
@ -361,8 +395,3 @@ var DownloadTaskbarProgressUpdater =
|
|||
}
|
||||
}
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//// Initialization
|
||||
|
||||
DownloadTaskbarProgressUpdater._init();
|
||||
|
|
|
@ -21,10 +21,6 @@ EXTRA_JS_MODULES = \
|
|||
DownloadUtils.jsm \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
EXTRA_JS_MODULES += \
|
||||
DownloadTaskbarProgress.jsm \
|
||||
$(NULL)
|
||||
endif
|
||||
EXTRA_PP_JS_MODULES = DownloadTaskbarProgress.jsm
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -447,11 +447,9 @@ function Startup()
|
|||
}
|
||||
}, false);
|
||||
|
||||
#ifdef XP_WIN
|
||||
let tempScope = {};
|
||||
Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm", tempScope);
|
||||
tempScope.DownloadTaskbarProgress.onDownloadWindowLoad(window);
|
||||
#endif
|
||||
let DownloadTaskbarProgress =
|
||||
Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm", {}).DownloadTaskbarProgress;
|
||||
DownloadTaskbarProgress.onDownloadWindowLoad(window);
|
||||
}
|
||||
|
||||
function Shutdown()
|
||||
|
|
|
@ -48,9 +48,13 @@ MOCHITEST_CHROME_FILES += \
|
|||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
ifneq (,$(filter WINNT, $(OS_ARCH))$(filter cocoa, $(MOZ_WIDGET_TOOLKIT)))
|
||||
MOCHITEST_CHROME_FILES += \
|
||||
test_taskbarprogress_downloadstates.xul \
|
||||
$(NULL)
|
||||
endif
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
MOCHITEST_CHROME_FILES += \
|
||||
$(filter disabled-for-very-frequent-orange--bug-630567, test_taskbarprogress_service.xul) \
|
||||
$(NULL)
|
||||
endif
|
||||
|
|
|
@ -166,6 +166,8 @@ function testSetup()
|
|||
return;
|
||||
}
|
||||
|
||||
let isWin = /Win/.test(navigator.platform);
|
||||
if (isWin) {
|
||||
let isWin7OrHigher = false;
|
||||
try {
|
||||
let version = Cc["@mozilla.org/system-info;1"]
|
||||
|
@ -178,16 +180,20 @@ function testSetup()
|
|||
ok(true, "This test only runs on Windows 7 or higher");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let tempScope = {};
|
||||
Cu.import("resource://gre/modules/DownloadTaskbarProgress.jsm", tempScope);
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
DownloadTaskbarProgress = tempScope.DownloadTaskbarProgress;
|
||||
let TaskbarService = Cc[kTaskbarID].getService(Ci.nsIWinTaskbar);
|
||||
|
||||
isnot(DownloadTaskbarProgress, null, "Download taskbar progress service exists");
|
||||
DownloadTaskbarProgress.init();
|
||||
|
||||
if (isWin) {
|
||||
let TaskbarService = Cc[kTaskbarID].getService(Ci.nsIWinTaskbar);
|
||||
is(TaskbarService.available, true, "Taskbar Service is available");
|
||||
}
|
||||
|
||||
dm = Cc["@mozilla.org/download-manager;1"].
|
||||
getService(Ci.nsIDownloadManager);
|
||||
|
|
|
@ -122,6 +122,7 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)
|
|||
XPIDLSRCS += nsIMacDockSupport.idl \
|
||||
nsIStandaloneNativeMenu.idl \
|
||||
nsIMacWebAppUtils.idl \
|
||||
nsITaskbarProgress.idl \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
|
|
@ -3,21 +3,38 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#import <Carbon/Carbon.h>
|
||||
|
||||
#include "nsIMacDockSupport.h"
|
||||
#include "nsIStandaloneNativeMenu.h"
|
||||
#include "nsITaskbarProgress.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
|
||||
class nsMacDockSupport : public nsIMacDockSupport
|
||||
class nsMacDockSupport : public nsIMacDockSupport, public nsITaskbarProgress
|
||||
{
|
||||
public:
|
||||
nsMacDockSupport() {}
|
||||
virtual ~nsMacDockSupport() {}
|
||||
nsMacDockSupport();
|
||||
virtual ~nsMacDockSupport();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMACDOCKSUPPORT
|
||||
NS_DECL_NSITASKBARPROGRESS
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsIStandaloneNativeMenu> mDockMenu;
|
||||
nsString mBadgeText;
|
||||
|
||||
NSImage *mAppIcon, *mProgressBackground;
|
||||
HIThemeTrackDrawInfo mProgressDrawInfo;
|
||||
|
||||
nsTaskbarProgressState mProgressState;
|
||||
double mProgressFraction;
|
||||
nsCOMPtr<nsITimer> mProgressTimer;
|
||||
|
||||
static void RedrawIconCallback(nsITimer* aTimer, void* aClosure);
|
||||
|
||||
bool InitProgress();
|
||||
nsresult RedrawIcon();
|
||||
};
|
||||
|
|
|
@ -3,12 +3,38 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#import <Carbon/Carbon.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "nsMacDockSupport.h"
|
||||
#include "nsObjCExceptions.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsMacDockSupport, nsIMacDockSupport)
|
||||
NS_IMPL_ISUPPORTS2(nsMacDockSupport, nsIMacDockSupport, nsITaskbarProgress)
|
||||
|
||||
nsMacDockSupport::nsMacDockSupport()
|
||||
: mAppIcon(nil)
|
||||
, mProgressBackground(nil)
|
||||
, mProgressState(STATE_NO_PROGRESS)
|
||||
, mProgressFraction(0.0)
|
||||
{
|
||||
mProgressTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
}
|
||||
|
||||
nsMacDockSupport::~nsMacDockSupport()
|
||||
{
|
||||
if (mAppIcon) {
|
||||
[mAppIcon release];
|
||||
mAppIcon = nil;
|
||||
}
|
||||
if (mProgressBackground) {
|
||||
[mProgressBackground release];
|
||||
mProgressBackground = nil;
|
||||
}
|
||||
if (mProgressTimer) {
|
||||
mProgressTimer->Cancel();
|
||||
mProgressTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacDockSupport::GetDockMenu(nsIStandaloneNativeMenu ** aDockMenu)
|
||||
|
@ -62,3 +88,116 @@ nsMacDockSupport::GetBadgeText(nsAString& aBadgeText)
|
|||
aBadgeText = mBadgeText;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacDockSupport::SetProgressState(nsTaskbarProgressState aState,
|
||||
PRUint64 aCurrentValue,
|
||||
PRUint64 aMaxValue)
|
||||
{
|
||||
NS_ENSURE_ARG_RANGE(aState, 0, STATE_PAUSED);
|
||||
if (aState == STATE_NO_PROGRESS || aState == STATE_INDETERMINATE) {
|
||||
NS_ENSURE_TRUE(aCurrentValue == 0, NS_ERROR_INVALID_ARG);
|
||||
NS_ENSURE_TRUE(aMaxValue == 0, NS_ERROR_INVALID_ARG);
|
||||
}
|
||||
if (aCurrentValue > aMaxValue) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
mProgressState = aState;
|
||||
if (aMaxValue == 0) {
|
||||
mProgressFraction = 0;
|
||||
} else {
|
||||
mProgressFraction = (double)aCurrentValue / aMaxValue;
|
||||
}
|
||||
|
||||
if (mProgressState == STATE_NORMAL || mProgressState == STATE_INDETERMINATE) {
|
||||
int perSecond = 30;
|
||||
mProgressTimer->InitWithFuncCallback(RedrawIconCallback, this, 1000 / perSecond,
|
||||
nsITimer::TYPE_REPEATING_SLACK);
|
||||
return NS_OK;
|
||||
} else {
|
||||
mProgressTimer->Cancel();
|
||||
return RedrawIcon();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void nsMacDockSupport::RedrawIconCallback(nsITimer* aTimer, void* aClosure)
|
||||
{
|
||||
static_cast<nsMacDockSupport*>(aClosure)->RedrawIcon();
|
||||
}
|
||||
|
||||
// Return whether to draw progress
|
||||
bool nsMacDockSupport::InitProgress()
|
||||
{
|
||||
if (mProgressState != STATE_NORMAL && mProgressState != STATE_INDETERMINATE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mAppIcon) {
|
||||
mProgressTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
mAppIcon = [[NSImage imageNamed:@"NSApplicationIcon"] retain];
|
||||
mProgressBackground = [mAppIcon copyWithZone:nil];
|
||||
|
||||
NSSize sz = [mProgressBackground size];
|
||||
mProgressDrawInfo.version = 0;
|
||||
mProgressDrawInfo.min = 0;
|
||||
mProgressDrawInfo.value = 0;
|
||||
mProgressDrawInfo.max = PR_INT32_MAX;
|
||||
mProgressDrawInfo.bounds = CGRectMake(sz.width * 1/32, sz.height * 3/32,
|
||||
sz.width * 30/32, sz.height * 2/32);
|
||||
mProgressDrawInfo.attributes = kThemeTrackHorizontal;
|
||||
mProgressDrawInfo.enableState = kThemeTrackActive;
|
||||
mProgressDrawInfo.kind = kThemeLargeProgressBar;
|
||||
mProgressDrawInfo.trackInfo.progress.phase = 0;
|
||||
|
||||
// Draw a light background, to visually distinguish the progress.
|
||||
HIRect bounds;
|
||||
HIThemeGetTrackBounds(&mProgressDrawInfo, &bounds);
|
||||
// Margins within track, empirically. FIXME: Don't hardcode?
|
||||
int mleft = 3, mtop = 3, mright = 3, mbot = 1;
|
||||
bounds.origin.x += mleft;
|
||||
bounds.origin.y += mbot;
|
||||
bounds.size.width -= mleft + mright;
|
||||
bounds.size.height -= mtop + mbot;
|
||||
|
||||
[mProgressBackground lockFocus];
|
||||
[[NSColor whiteColor] set];
|
||||
NSRectFill(NSRectFromCGRect(bounds));
|
||||
[mProgressBackground unlockFocus];
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMacDockSupport::RedrawIcon()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
|
||||
|
||||
if (InitProgress()) {
|
||||
// TODO: - Share code with nsNativeThemeCocoa?
|
||||
// - Implement ERROR and PAUSED states?
|
||||
NSImage *icon = [mProgressBackground copyWithZone:nil];
|
||||
|
||||
bool isIndeterminate = (mProgressState != STATE_NORMAL);
|
||||
mProgressDrawInfo.value = PR_INT32_MAX * mProgressFraction;
|
||||
mProgressDrawInfo.kind = isIndeterminate ? kThemeLargeIndeterminateBar
|
||||
: kThemeLargeProgressBar;
|
||||
|
||||
int stepsPerSecond = isIndeterminate ? 60 : 30;
|
||||
mProgressDrawInfo.trackInfo.progress.phase =
|
||||
PR_IntervalToMilliseconds(PR_IntervalNow()) * stepsPerSecond / 1000 % 32;
|
||||
|
||||
[icon lockFocus];
|
||||
CGContextRef ctx = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
|
||||
HIThemeDrawTrack(&mProgressDrawInfo, NULL, ctx, kHIThemeOrientationNormal);
|
||||
[icon unlockFocus];
|
||||
[NSApp setApplicationIconImage:icon];
|
||||
[icon release];
|
||||
} else {
|
||||
[NSApp setApplicationIconImage:mAppIcon];
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@ interface nsIStandaloneNativeMenu;
|
|||
|
||||
/**
|
||||
* Allow applications to interface with the Mac OS X Dock.
|
||||
*
|
||||
* Applications may indicate progress on their Dock icon. Only one such
|
||||
* progress indicator is available to the entire application.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(8BE66B0C-5F71-4B74-98CF-6C2551B999B1)]
|
||||
|
|
|
@ -80,13 +80,14 @@ MOCHITEST_CHROME_FILES += native_menus_window.xul \
|
|||
test_key_event_counts.xul \
|
||||
test_bug596600.xul \
|
||||
test_bug673301.xul \
|
||||
test_taskbar_progress.xul \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
|
||||
MOCHITEST_CHROME_FILES += taskbar_previews.xul \
|
||||
window_state_windows.xul \
|
||||
taskbar_progress.xul \
|
||||
$(warning test_taskbar_progress.xul disabled due to regression, see bug 605813) \
|
||||
test_chrome_context_menus_win.xul \
|
||||
test_plugin_input_event.html \
|
||||
chrome_context_menus_win.xul \
|
||||
|
|
|
@ -17,33 +17,21 @@
|
|||
let Cu = Components.utils;
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
let taskbar = Cc["@mozilla.org/windows-taskbar;1"].getService(Ci.nsIWinTaskbar);
|
||||
let TP = Ci.nsITaskbarProgress;
|
||||
|
||||
function IsWin7OrHigher() {
|
||||
try {
|
||||
var sysInfo = Cc["@mozilla.org/system-info;1"].
|
||||
getService(Ci.nsIPropertyBag2);
|
||||
var ver = parseFloat(sysInfo.getProperty("version"));
|
||||
if (ver >= 6.1)
|
||||
return true;
|
||||
} catch (ex) { }
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function loaded()
|
||||
{
|
||||
function winProgress() {
|
||||
let taskbar = Cc["@mozilla.org/windows-taskbar;1"];
|
||||
if (!taskbar)
|
||||
return null;
|
||||
taskbar = taskbar.getService(Ci.nsIWinTaskbar);
|
||||
if (!taskbar.available)
|
||||
SimpleTest.finish();
|
||||
return null;
|
||||
|
||||
// HACK from mconnor:
|
||||
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
|
||||
let win = wm.getMostRecentWindow("navigator:browser");
|
||||
let docShell = win.gBrowser.docShell;
|
||||
|
||||
let TP = Ci.nsITaskbarProgress;
|
||||
|
||||
let progress = taskbar.getTaskbarProgress(docShell);
|
||||
isnot(progress, null, "Progress is not null");
|
||||
|
||||
|
@ -54,6 +42,24 @@
|
|||
ok(true, "Cannot get progress for null docshell");
|
||||
}
|
||||
|
||||
return progress;
|
||||
}
|
||||
|
||||
function macProgress() {
|
||||
let progress = Cc["@mozilla.org/widget/macdocksupport;1"];
|
||||
if (!progress)
|
||||
return null;
|
||||
return progress.getService(TP);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function loaded()
|
||||
{
|
||||
let progress = winProgress() || macProgress();
|
||||
if (!TP)
|
||||
SimpleTest.finish();
|
||||
|
||||
function shouldThrow(s,c,m) {
|
||||
try {
|
||||
progress.setProgressState(s,c,m);
|
Загрузка…
Ссылка в новой задаче