зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to inbound, a=merge
This commit is contained in:
Коммит
ae855cdb28
|
@ -128,6 +128,7 @@ devtools/shared/*.js
|
||||||
!devtools/shared/css-lexer.js
|
!devtools/shared/css-lexer.js
|
||||||
!devtools/shared/defer.js
|
!devtools/shared/defer.js
|
||||||
!devtools/shared/event-emitter.js
|
!devtools/shared/event-emitter.js
|
||||||
|
!devtools/shared/loader-plugin-raw.jsm
|
||||||
!devtools/shared/task.js
|
!devtools/shared/task.js
|
||||||
devtools/shared/*.jsm
|
devtools/shared/*.jsm
|
||||||
!devtools/shared/Loader.jsm
|
!devtools/shared/Loader.jsm
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
<em:version>1.0</em:version>
|
<em:version>1.0</em:version>
|
||||||
<em:type>2</em:type>
|
<em:type>2</em:type>
|
||||||
<em:bootstrap>true</em:bootstrap>
|
<em:bootstrap>true</em:bootstrap>
|
||||||
|
<em:multiprocessCompatible>true</em:multiprocessCompatible>
|
||||||
|
|
||||||
<!-- Target Application this theme can install into,
|
<!-- Target Application this theme can install into,
|
||||||
with minimum and maximum supported versions. -->
|
with minimum and maximum supported versions. -->
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
<em:version>1.0</em:version>
|
<em:version>1.0</em:version>
|
||||||
<em:type>2</em:type>
|
<em:type>2</em:type>
|
||||||
<em:bootstrap>true</em:bootstrap>
|
<em:bootstrap>true</em:bootstrap>
|
||||||
|
<em:multiprocessCompatible>true</em:multiprocessCompatible>
|
||||||
|
|
||||||
<!-- Target Application this theme can install into,
|
<!-- Target Application this theme can install into,
|
||||||
with minimum and maximum supported versions. -->
|
with minimum and maximum supported versions. -->
|
||||||
|
|
|
@ -101,6 +101,12 @@ function BrowserLoaderBuilder({ baseURI, window, useOnlyShared }) {
|
||||||
paths: Object.assign({}, dynamicPaths, loaderOptions.paths),
|
paths: Object.assign({}, dynamicPaths, loaderOptions.paths),
|
||||||
invisibleToDebugger: loaderOptions.invisibleToDebugger,
|
invisibleToDebugger: loaderOptions.invisibleToDebugger,
|
||||||
requireHook: (id, require) => {
|
requireHook: (id, require) => {
|
||||||
|
// If |id| requires special handling, simply defer to devtools
|
||||||
|
// immediately.
|
||||||
|
if (devtools.isLoaderPluginId(id)) {
|
||||||
|
return devtools.require(id);
|
||||||
|
}
|
||||||
|
|
||||||
const uri = require.resolve(id);
|
const uri = require.resolve(id);
|
||||||
let isBrowserDir = BROWSER_BASED_DIRS.filter(dir => {
|
let isBrowserDir = BROWSER_BASED_DIRS.filter(dir => {
|
||||||
return uri.startsWith(dir);
|
return uri.startsWith(dir);
|
||||||
|
|
|
@ -147,6 +147,7 @@ skip-if = e10s # Test intermittently fails with e10s. Bug 1124162.
|
||||||
[browser_poller.js]
|
[browser_poller.js]
|
||||||
[browser_prefs-01.js]
|
[browser_prefs-01.js]
|
||||||
[browser_prefs-02.js]
|
[browser_prefs-02.js]
|
||||||
|
[browser_require_raw.js]
|
||||||
[browser_spectrum.js]
|
[browser_spectrum.js]
|
||||||
[browser_theme.js]
|
[browser_theme.js]
|
||||||
[browser_tableWidget_basic.js]
|
[browser_tableWidget_basic.js]
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const { BrowserLoader } = Cu.import("resource://devtools/client/shared/browser-loader.js", {});
|
||||||
|
|
||||||
|
const { require: browserRequire } = BrowserLoader({
|
||||||
|
baseURI: "resource://devtools/client/shared/",
|
||||||
|
window: this
|
||||||
|
});
|
||||||
|
|
||||||
|
const variableFileContents = browserRequire("raw!devtools/client/themes/variables.css");
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
ok(variableFileContents.length > 0, "raw browserRequire worked");
|
||||||
|
finish();
|
||||||
|
}
|
|
@ -9,45 +9,21 @@
|
||||||
* https://developer.mozilla.org/en-US/docs/Tools/DevToolsColors
|
* https://developer.mozilla.org/en-US/docs/Tools/DevToolsColors
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const { Cu } = require("chrome");
|
|
||||||
const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
|
|
||||||
const Services = require("Services");
|
const Services = require("Services");
|
||||||
const { gDevTools } = require("devtools/client/framework/devtools");
|
const { gDevTools } = require("devtools/client/framework/devtools");
|
||||||
|
|
||||||
const VARIABLES_URI = "chrome://devtools/skin/variables.css";
|
const variableFileContents = require("raw!devtools/client/themes/variables.css");
|
||||||
|
|
||||||
const THEME_SELECTOR_STRINGS = {
|
const THEME_SELECTOR_STRINGS = {
|
||||||
light: ":root.theme-light {",
|
light: ":root.theme-light {",
|
||||||
dark: ":root.theme-dark {"
|
dark: ":root.theme-dark {"
|
||||||
};
|
};
|
||||||
|
|
||||||
let variableFileContents;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a string of the file found at URI
|
|
||||||
*/
|
|
||||||
function readURI(uri) {
|
|
||||||
let stream = NetUtil.newChannel({
|
|
||||||
uri: NetUtil.newURI(uri, "UTF-8"),
|
|
||||||
loadUsingSystemPrincipal: true}
|
|
||||||
).open2();
|
|
||||||
|
|
||||||
let count = stream.available();
|
|
||||||
let data = NetUtil.readInputStreamToString(stream, count, {
|
|
||||||
charset: "UTF-8"
|
|
||||||
});
|
|
||||||
stream.close();
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a theme name and returns the contents of its variable rule block.
|
* Takes a theme name and returns the contents of its variable rule block.
|
||||||
* The first time this runs fetches the variables CSS file and caches it.
|
* The first time this runs fetches the variables CSS file and caches it.
|
||||||
*/
|
*/
|
||||||
function getThemeFile(name) {
|
function getThemeFile(name) {
|
||||||
if (!variableFileContents) {
|
|
||||||
variableFileContents = readURI(VARIABLES_URI);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If there's no theme expected for this name, use `light` as default.
|
// If there's no theme expected for this name, use `light` as default.
|
||||||
let selector = THEME_SELECTOR_STRINGS[name] ||
|
let selector = THEME_SELECTOR_STRINGS[name] ||
|
||||||
THEME_SELECTOR_STRINGS.light;
|
THEME_SELECTOR_STRINGS.light;
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
var { utils: Cu } = Components;
|
var { utils: Cu } = Components;
|
||||||
var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
|
var { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||||
var { Loader, descriptor, resolveURI } = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {});
|
var { Loader, descriptor, resolveURI } = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {});
|
||||||
|
var { requireRawId } = Cu.import("resource://devtools/shared/loader-plugin-raw.jsm", {});
|
||||||
|
|
||||||
this.EXPORTED_SYMBOLS = ["DevToolsLoader", "devtools", "BuiltinProvider",
|
this.EXPORTED_SYMBOLS = ["DevToolsLoader", "devtools", "BuiltinProvider",
|
||||||
"require", "loader"];
|
"require", "loader"];
|
||||||
|
@ -59,6 +60,12 @@ BuiltinProvider.prototype = {
|
||||||
invisibleToDebugger: this.invisibleToDebugger,
|
invisibleToDebugger: this.invisibleToDebugger,
|
||||||
sharedGlobal: true,
|
sharedGlobal: true,
|
||||||
sharedGlobalBlocklist,
|
sharedGlobalBlocklist,
|
||||||
|
requireHook: (id, require) => {
|
||||||
|
if (id.startsWith("raw!")) {
|
||||||
|
return requireRawId(id, require);
|
||||||
|
}
|
||||||
|
return require(id);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -120,6 +127,14 @@ DevToolsLoader.prototype = {
|
||||||
return this.require.apply(this, arguments);
|
return this.require.apply(this, arguments);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if |id| refers to something requiring help from a
|
||||||
|
* loader plugin.
|
||||||
|
*/
|
||||||
|
isLoaderPluginId: function (id) {
|
||||||
|
return id.startsWith("raw!");
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Override the provider used to load the tools.
|
* Override the provider used to load the tools.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const { utils: Cu } = Components;
|
||||||
|
const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm", {});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function that can be used as part of a require hook for a
|
||||||
|
* loader.js Loader. This function only handles webpack-style "raw!"
|
||||||
|
* requires; other requires should not be passed to this. See
|
||||||
|
* https://github.com/webpack/raw-loader.
|
||||||
|
*/
|
||||||
|
function requireRawId(id, require) {
|
||||||
|
let uri = require.resolve(id.slice(4));
|
||||||
|
// If the original string did not end with ".js", then
|
||||||
|
// require.resolve might have added the suffix. We don't want to
|
||||||
|
// add a suffix for a raw load (if needed the caller can specify it
|
||||||
|
// manually), so remove it here.
|
||||||
|
if (!id.endsWith(".js") && uri.endsWith(".js")) {
|
||||||
|
uri = uri.slice(0, -3);
|
||||||
|
}
|
||||||
|
let stream = NetUtil.newChannel({
|
||||||
|
uri: NetUtil.newURI(uri, "UTF-8"),
|
||||||
|
loadUsingSystemPrincipal: true
|
||||||
|
}).open2();
|
||||||
|
|
||||||
|
let count = stream.available();
|
||||||
|
let data = NetUtil.readInputStreamToString(stream, count, {
|
||||||
|
charset: "UTF-8"
|
||||||
|
});
|
||||||
|
stream.close();
|
||||||
|
|
||||||
|
// For the time being it doesn't seem worthwhile to cache the
|
||||||
|
// result here.
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.EXPORTED_SYMBOLS = ["requireRawId"];
|
|
@ -54,6 +54,7 @@ DevToolsModules(
|
||||||
'dom-node-filter-constants.js',
|
'dom-node-filter-constants.js',
|
||||||
'event-emitter.js',
|
'event-emitter.js',
|
||||||
'indentation.js',
|
'indentation.js',
|
||||||
|
'loader-plugin-raw.jsm',
|
||||||
'Loader.jsm',
|
'Loader.jsm',
|
||||||
'Parser.jsm',
|
'Parser.jsm',
|
||||||
'path.js',
|
'path.js',
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Test require using "raw!".
|
||||||
|
|
||||||
|
function run_test() {
|
||||||
|
let loader = new DevToolsLoader();
|
||||||
|
let require = loader.require;
|
||||||
|
|
||||||
|
let variableFileContents = require("raw!devtools/client/themes/variables.css");
|
||||||
|
ok(variableFileContents.length > 0, "raw browserRequire worked");
|
||||||
|
}
|
|
@ -25,6 +25,7 @@ support-files =
|
||||||
[test_console_filtering.js]
|
[test_console_filtering.js]
|
||||||
[test_prettifyCSS.js]
|
[test_prettifyCSS.js]
|
||||||
[test_require_lazy.js]
|
[test_require_lazy.js]
|
||||||
|
[test_require_raw.js]
|
||||||
[test_require.js]
|
[test_require.js]
|
||||||
[test_stack.js]
|
[test_stack.js]
|
||||||
[test_defer.js]
|
[test_defer.js]
|
||||||
|
|
|
@ -764,11 +764,12 @@ nsDOMWindowUtils::SendPointerEventCommon(const nsAString& aType,
|
||||||
event.pressure = aPressure;
|
event.pressure = aPressure;
|
||||||
event.inputSource = aInputSourceArg;
|
event.inputSource = aInputSourceArg;
|
||||||
event.pointerId = aPointerId;
|
event.pointerId = aPointerId;
|
||||||
event.width = aWidth;
|
event.mWidth = aWidth;
|
||||||
event.height = aHeight;
|
event.mHeight = aHeight;
|
||||||
event.tiltX = aTiltX;
|
event.tiltX = aTiltX;
|
||||||
event.tiltY = aTiltY;
|
event.tiltY = aTiltY;
|
||||||
event.isPrimary = (nsIDOMMouseEvent::MOZ_SOURCE_MOUSE == aInputSourceArg) ? true : aIsPrimary;
|
event.mIsPrimary =
|
||||||
|
(nsIDOMMouseEvent::MOZ_SOURCE_MOUSE == aInputSourceArg) ? true : aIsPrimary;
|
||||||
event.mClickCount = aClickCount;
|
event.mClickCount = aClickCount;
|
||||||
event.mTime = PR_IntervalNow();
|
event.mTime = PR_IntervalNow();
|
||||||
event.mFlags.mIsSynthesizedForTests = aOptionalArgCount >= 10 ? aIsSynthesized : true;
|
event.mFlags.mIsSynthesizedForTests = aOptionalArgCount >= 10 ? aIsSynthesized : true;
|
||||||
|
|
|
@ -3834,10 +3834,10 @@ CreateMouseOrPointerWidgetEvent(WidgetMouseEvent* aMouseEvent,
|
||||||
newPointerEvent =
|
newPointerEvent =
|
||||||
new WidgetPointerEvent(aMouseEvent->IsTrusted(), aMessage,
|
new WidgetPointerEvent(aMouseEvent->IsTrusted(), aMessage,
|
||||||
aMouseEvent->mWidget);
|
aMouseEvent->mWidget);
|
||||||
newPointerEvent->isPrimary = sourcePointer->isPrimary;
|
newPointerEvent->mIsPrimary = sourcePointer->mIsPrimary;
|
||||||
newPointerEvent->pointerId = sourcePointer->pointerId;
|
newPointerEvent->pointerId = sourcePointer->pointerId;
|
||||||
newPointerEvent->width = sourcePointer->width;
|
newPointerEvent->mWidth = sourcePointer->mWidth;
|
||||||
newPointerEvent->height = sourcePointer->height;
|
newPointerEvent->mHeight = sourcePointer->mHeight;
|
||||||
newPointerEvent->inputSource = sourcePointer->inputSource;
|
newPointerEvent->inputSource = sourcePointer->inputSource;
|
||||||
newPointerEvent->relatedTarget =
|
newPointerEvent->relatedTarget =
|
||||||
nsIPresShell::GetPointerCapturingContent(sourcePointer->pointerId)
|
nsIPresShell::GetPointerCapturingContent(sourcePointer->pointerId)
|
||||||
|
|
|
@ -87,13 +87,13 @@ PointerEvent::Constructor(EventTarget* aOwner,
|
||||||
|
|
||||||
WidgetPointerEvent* widgetEvent = e->mEvent->AsPointerEvent();
|
WidgetPointerEvent* widgetEvent = e->mEvent->AsPointerEvent();
|
||||||
widgetEvent->pointerId = aParam.mPointerId;
|
widgetEvent->pointerId = aParam.mPointerId;
|
||||||
widgetEvent->width = aParam.mWidth;
|
widgetEvent->mWidth = aParam.mWidth;
|
||||||
widgetEvent->height = aParam.mHeight;
|
widgetEvent->mHeight = aParam.mHeight;
|
||||||
widgetEvent->pressure = aParam.mPressure;
|
widgetEvent->pressure = aParam.mPressure;
|
||||||
widgetEvent->tiltX = aParam.mTiltX;
|
widgetEvent->tiltX = aParam.mTiltX;
|
||||||
widgetEvent->tiltY = aParam.mTiltY;
|
widgetEvent->tiltY = aParam.mTiltY;
|
||||||
widgetEvent->inputSource = ConvertStringToPointerType(aParam.mPointerType);
|
widgetEvent->inputSource = ConvertStringToPointerType(aParam.mPointerType);
|
||||||
widgetEvent->isPrimary = aParam.mIsPrimary;
|
widgetEvent->mIsPrimary = aParam.mIsPrimary;
|
||||||
widgetEvent->buttons = aParam.mButtons;
|
widgetEvent->buttons = aParam.mButtons;
|
||||||
|
|
||||||
e->SetTrusted(trusted);
|
e->SetTrusted(trusted);
|
||||||
|
@ -126,13 +126,13 @@ PointerEvent::PointerId()
|
||||||
int32_t
|
int32_t
|
||||||
PointerEvent::Width()
|
PointerEvent::Width()
|
||||||
{
|
{
|
||||||
return mEvent->AsPointerEvent()->width;
|
return mEvent->AsPointerEvent()->mWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
PointerEvent::Height()
|
PointerEvent::Height()
|
||||||
{
|
{
|
||||||
return mEvent->AsPointerEvent()->height;
|
return mEvent->AsPointerEvent()->mHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
|
@ -156,7 +156,7 @@ PointerEvent::TiltY()
|
||||||
bool
|
bool
|
||||||
PointerEvent::IsPrimary()
|
PointerEvent::IsPrimary()
|
||||||
{
|
{
|
||||||
return mEvent->AsPointerEvent()->isPrimary;
|
return mEvent->AsPointerEvent()->mIsPrimary;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
@ -369,7 +369,7 @@ HTMLButtonElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
||||||
mType == NS_FORM_BUTTON_RESET)) {
|
mType == NS_FORM_BUTTON_RESET)) {
|
||||||
InternalFormEvent event(true,
|
InternalFormEvent event(true,
|
||||||
(mType == NS_FORM_BUTTON_RESET) ? eFormReset : eFormSubmit);
|
(mType == NS_FORM_BUTTON_RESET) ? eFormReset : eFormSubmit);
|
||||||
event.originator = this;
|
event.mOriginator = this;
|
||||||
nsEventStatus status = nsEventStatus_eIgnore;
|
nsEventStatus status = nsEventStatus_eIgnore;
|
||||||
|
|
||||||
nsCOMPtr<nsIPresShell> presShell =
|
nsCOMPtr<nsIPresShell> presShell =
|
||||||
|
|
|
@ -687,7 +687,7 @@ HTMLFormElement::BuildSubmission(HTMLFormSubmission** aFormSubmission,
|
||||||
if (aEvent) {
|
if (aEvent) {
|
||||||
InternalFormEvent* formEvent = aEvent->AsFormEvent();
|
InternalFormEvent* formEvent = aEvent->AsFormEvent();
|
||||||
if (formEvent) {
|
if (formEvent) {
|
||||||
nsIContent* originator = formEvent->originator;
|
nsIContent* originator = formEvent->mOriginator;
|
||||||
if (originator) {
|
if (originator) {
|
||||||
if (!originator->IsHTMLElement()) {
|
if (!originator->IsHTMLElement()) {
|
||||||
return NS_ERROR_UNEXPECTED;
|
return NS_ERROR_UNEXPECTED;
|
||||||
|
|
|
@ -4556,7 +4556,7 @@ HTMLInputElement::PostHandleEvent(EventChainPostVisitor& aVisitor)
|
||||||
if (mForm) {
|
if (mForm) {
|
||||||
InternalFormEvent event(true,
|
InternalFormEvent event(true,
|
||||||
(mType == NS_FORM_INPUT_RESET) ? eFormReset : eFormSubmit);
|
(mType == NS_FORM_INPUT_RESET) ? eFormReset : eFormSubmit);
|
||||||
event.originator = this;
|
event.mOriginator = this;
|
||||||
nsEventStatus status = nsEventStatus_eIgnore;
|
nsEventStatus status = nsEventStatus_eIgnore;
|
||||||
|
|
||||||
nsCOMPtr<nsIPresShell> presShell =
|
nsCOMPtr<nsIPresShell> presShell =
|
||||||
|
|
|
@ -114,13 +114,10 @@ ProcessHandle GetCurrentProcessHandle();
|
||||||
bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle);
|
bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle);
|
||||||
|
|
||||||
// Converts a PID to a process handle. On Windows the handle is opened
|
// Converts a PID to a process handle. On Windows the handle is opened
|
||||||
// with more access rights and must only be used by trusted code. Parameter
|
// with more access rights and must only be used by trusted code.
|
||||||
// error can be used to get the error code in opening the process handle.
|
|
||||||
// You have to close returned handle using CloseProcessHandle. Returns true
|
// You have to close returned handle using CloseProcessHandle. Returns true
|
||||||
// on success.
|
// on success.
|
||||||
bool OpenPrivilegedProcessHandle(ProcessId pid,
|
bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle);
|
||||||
ProcessHandle* handle,
|
|
||||||
int64_t* error = nullptr);
|
|
||||||
|
|
||||||
// Closes the process handle opened by OpenProcessHandle.
|
// Closes the process handle opened by OpenProcessHandle.
|
||||||
void CloseProcessHandle(ProcessHandle process);
|
void CloseProcessHandle(ProcessHandle process);
|
||||||
|
|
|
@ -49,14 +49,9 @@ bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenPrivilegedProcessHandle(ProcessId pid,
|
bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle) {
|
||||||
ProcessHandle* handle,
|
|
||||||
int64_t* error) {
|
|
||||||
// On POSIX permissions are checked for each operation on process,
|
// On POSIX permissions are checked for each operation on process,
|
||||||
// not when opening a "handle".
|
// not when opening a "handle".
|
||||||
if (error) {
|
|
||||||
*error = 0;
|
|
||||||
}
|
|
||||||
return OpenProcessHandle(pid, handle);
|
return OpenProcessHandle(pid, handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,9 +86,7 @@ bool OpenProcessHandle(ProcessId pid, ProcessHandle* handle) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenPrivilegedProcessHandle(ProcessId pid,
|
bool OpenPrivilegedProcessHandle(ProcessId pid, ProcessHandle* handle) {
|
||||||
ProcessHandle* handle,
|
|
||||||
int64_t* error) {
|
|
||||||
ProcessHandle result = OpenProcess(PROCESS_DUP_HANDLE |
|
ProcessHandle result = OpenProcess(PROCESS_DUP_HANDLE |
|
||||||
PROCESS_TERMINATE |
|
PROCESS_TERMINATE |
|
||||||
PROCESS_QUERY_INFORMATION |
|
PROCESS_QUERY_INFORMATION |
|
||||||
|
@ -97,9 +95,6 @@ bool OpenPrivilegedProcessHandle(ProcessId pid,
|
||||||
FALSE, pid);
|
FALSE, pid);
|
||||||
|
|
||||||
if (result == NULL) {
|
if (result == NULL) {
|
||||||
if (error) {
|
|
||||||
*error = GetLastError();
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1151,43 +1151,47 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector<std::string>& aExt
|
||||||
mChildTask = child_task;
|
mChildTask = child_task;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
OpenPrivilegedHandle(base::GetProcId(process));
|
if (!OpenPrivilegedHandle(base::GetProcId(process))
|
||||||
{
|
#ifdef XP_WIN
|
||||||
MonitorAutoLock lock(mMonitor);
|
// If we failed in opening the process handle, try harder by duplicating
|
||||||
mProcessState = PROCESS_CREATED;
|
// one.
|
||||||
lock.Notify();
|
&& !::DuplicateHandle(::GetCurrentProcess(), process,
|
||||||
|
::GetCurrentProcess(), &mChildProcessHandle,
|
||||||
|
PROCESS_DUP_HANDLE | PROCESS_TERMINATE |
|
||||||
|
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ |
|
||||||
|
SYNCHRONIZE,
|
||||||
|
FALSE, 0)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
NS_RUNTIMEABORT("cannot open handle to child process");
|
||||||
}
|
}
|
||||||
|
MonitorAutoLock lock(mMonitor);
|
||||||
|
mProcessState = PROCESS_CREATED;
|
||||||
|
lock.Notify();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
GeckoChildProcessHost::OpenPrivilegedHandle(base::ProcessId aPid)
|
GeckoChildProcessHost::OpenPrivilegedHandle(base::ProcessId aPid)
|
||||||
{
|
{
|
||||||
if (mChildProcessHandle) {
|
if (mChildProcessHandle) {
|
||||||
MOZ_ASSERT(aPid == base::GetProcId(mChildProcessHandle));
|
MOZ_ASSERT(aPid == base::GetProcId(mChildProcessHandle));
|
||||||
return;
|
return true;
|
||||||
}
|
|
||||||
int64_t error = 0;
|
|
||||||
if (!base::OpenPrivilegedProcessHandle(aPid, &mChildProcessHandle, &error)) {
|
|
||||||
#ifdef MOZ_CRASHREPORTER
|
|
||||||
CrashReporter::
|
|
||||||
AnnotateCrashReport(NS_LITERAL_CSTRING("LastError"),
|
|
||||||
nsPrintfCString ("%lld", error));
|
|
||||||
#endif
|
|
||||||
NS_RUNTIMEABORT("can't open handle to child process");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return base::OpenPrivilegedProcessHandle(aPid, &mChildProcessHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
GeckoChildProcessHost::OnChannelConnected(int32_t peer_pid)
|
GeckoChildProcessHost::OnChannelConnected(int32_t peer_pid)
|
||||||
{
|
{
|
||||||
OpenPrivilegedHandle(peer_pid);
|
if (!OpenPrivilegedHandle(peer_pid)) {
|
||||||
{
|
NS_RUNTIMEABORT("can't open handle to child process");
|
||||||
MonitorAutoLock lock(mMonitor);
|
|
||||||
mProcessState = PROCESS_CONNECTED;
|
|
||||||
lock.Notify();
|
|
||||||
}
|
}
|
||||||
|
MonitorAutoLock lock(mMonitor);
|
||||||
|
mProcessState = PROCESS_CONNECTED;
|
||||||
|
lock.Notify();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1254,7 +1258,9 @@ bool
|
||||||
GeckoExistingProcessHost::PerformAsyncLaunch(StringVector aExtraOpts,
|
GeckoExistingProcessHost::PerformAsyncLaunch(StringVector aExtraOpts,
|
||||||
base::ProcessArchitecture aArch)
|
base::ProcessArchitecture aArch)
|
||||||
{
|
{
|
||||||
OpenPrivilegedHandle(base::GetProcId(mExistingProcessHandle));
|
if (!OpenPrivilegedHandle(base::GetProcId(mExistingProcessHandle))) {
|
||||||
|
NS_RUNTIMEABORT("can't open handle to child process");
|
||||||
|
}
|
||||||
|
|
||||||
MonitorAutoLock lock(mMonitor);
|
MonitorAutoLock lock(mMonitor);
|
||||||
mProcessState = PROCESS_CREATED;
|
mProcessState = PROCESS_CREATED;
|
||||||
|
|
|
@ -173,7 +173,7 @@ protected:
|
||||||
task_t mChildTask;
|
task_t mChildTask;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void OpenPrivilegedHandle(base::ProcessId aPid);
|
bool OpenPrivilegedHandle(base::ProcessId aPid);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DISALLOW_EVIL_CONSTRUCTORS(GeckoChildProcessHost);
|
DISALLOW_EVIL_CONSTRUCTORS(GeckoChildProcessHost);
|
||||||
|
|
|
@ -6839,14 +6839,16 @@ PresShell::UpdateActivePointerState(WidgetGUIEvent* aEvent)
|
||||||
// In this case we have to know information about available mouse pointers
|
// In this case we have to know information about available mouse pointers
|
||||||
if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
|
if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
|
||||||
gActivePointersIds->Put(mouseEvent->pointerId,
|
gActivePointersIds->Put(mouseEvent->pointerId,
|
||||||
new PointerInfo(false, mouseEvent->inputSource, true));
|
new PointerInfo(false, mouseEvent->inputSource,
|
||||||
|
true));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ePointerDown:
|
case ePointerDown:
|
||||||
// In this case we switch pointer to active state
|
// In this case we switch pointer to active state
|
||||||
if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) {
|
if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) {
|
||||||
gActivePointersIds->Put(pointerEvent->pointerId,
|
gActivePointersIds->Put(pointerEvent->pointerId,
|
||||||
new PointerInfo(true, pointerEvent->inputSource, pointerEvent->isPrimary));
|
new PointerInfo(true, pointerEvent->inputSource,
|
||||||
|
pointerEvent->mIsPrimary));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ePointerUp:
|
case ePointerUp:
|
||||||
|
@ -6854,14 +6856,17 @@ PresShell::UpdateActivePointerState(WidgetGUIEvent* aEvent)
|
||||||
if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) {
|
if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) {
|
||||||
if(pointerEvent->inputSource != nsIDOMMouseEvent::MOZ_SOURCE_TOUCH) {
|
if(pointerEvent->inputSource != nsIDOMMouseEvent::MOZ_SOURCE_TOUCH) {
|
||||||
gActivePointersIds->Put(pointerEvent->pointerId,
|
gActivePointersIds->Put(pointerEvent->pointerId,
|
||||||
new PointerInfo(false, pointerEvent->inputSource, pointerEvent->isPrimary));
|
new PointerInfo(false,
|
||||||
|
pointerEvent->inputSource,
|
||||||
|
pointerEvent->mIsPrimary));
|
||||||
} else {
|
} else {
|
||||||
gActivePointersIds->Remove(pointerEvent->pointerId);
|
gActivePointersIds->Remove(pointerEvent->pointerId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case eMouseExitFromWidget:
|
case eMouseExitFromWidget:
|
||||||
// In this case we have to remove information about disappeared mouse pointers
|
// In this case we have to remove information about disappeared mouse
|
||||||
|
// pointers
|
||||||
if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
|
if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
|
||||||
gActivePointersIds->Remove(mouseEvent->pointerId);
|
gActivePointersIds->Remove(mouseEvent->pointerId);
|
||||||
}
|
}
|
||||||
|
@ -7205,12 +7210,12 @@ DispatchPointerFromMouseOrTouch(PresShell* aShell,
|
||||||
|
|
||||||
WidgetPointerEvent event(touchEvent->IsTrusted(), pointerMessage,
|
WidgetPointerEvent event(touchEvent->IsTrusted(), pointerMessage,
|
||||||
touchEvent->mWidget);
|
touchEvent->mWidget);
|
||||||
event.isPrimary = i == 0;
|
event.mIsPrimary = i == 0;
|
||||||
event.pointerId = touch->Identifier();
|
event.pointerId = touch->Identifier();
|
||||||
event.mRefPoint = touch->mRefPoint;
|
event.mRefPoint = touch->mRefPoint;
|
||||||
event.mModifiers = touchEvent->mModifiers;
|
event.mModifiers = touchEvent->mModifiers;
|
||||||
event.width = touch->RadiusX();
|
event.mWidth = touch->RadiusX();
|
||||||
event.height = touch->RadiusY();
|
event.mHeight = touch->RadiusY();
|
||||||
event.tiltX = touch->tiltX;
|
event.tiltX = touch->tiltX;
|
||||||
event.tiltY = touch->tiltY;
|
event.tiltY = touch->tiltY;
|
||||||
event.mTime = touchEvent->mTime;
|
event.mTime = touchEvent->mTime;
|
||||||
|
|
|
@ -563,6 +563,9 @@ MediaPipeline::AttachTransport_s()
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transport_->Attach(this);
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,6 +166,7 @@ class MediaPipeline : public sigslot::has_slots<> {
|
||||||
: pipeline_(pipeline),
|
: pipeline_(pipeline),
|
||||||
sts_thread_(pipeline->sts_thread_) {}
|
sts_thread_(pipeline->sts_thread_) {}
|
||||||
|
|
||||||
|
void Attach(MediaPipeline *pipeline) { pipeline_ = pipeline; }
|
||||||
void Detach() { pipeline_ = nullptr; }
|
void Detach() { pipeline_ = nullptr; }
|
||||||
MediaPipeline *pipeline() const { return pipeline_; }
|
MediaPipeline *pipeline() const { return pipeline_; }
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ firefox-ui-functional-local:
|
||||||
treeherder-symbol: tc-Fxfn-l(en-US)
|
treeherder-symbol: tc-Fxfn-l(en-US)
|
||||||
max-run-time: 5400
|
max-run-time: 5400
|
||||||
tier: 1
|
tier: 1
|
||||||
|
docker-image: {"in-tree": "desktop1604-test"}
|
||||||
mozharness:
|
mozharness:
|
||||||
script: mozharness/scripts/firefox_ui_tests/functional.py
|
script: mozharness/scripts/firefox_ui_tests/functional.py
|
||||||
config:
|
config:
|
||||||
|
@ -67,6 +68,7 @@ firefox-ui-functional-remote:
|
||||||
treeherder-symbol: tc-Fxfn-r(en-US)
|
treeherder-symbol: tc-Fxfn-r(en-US)
|
||||||
max-run-time: 5400
|
max-run-time: 5400
|
||||||
tier: 2
|
tier: 2
|
||||||
|
docker-image: {"in-tree": "desktop1604-test"}
|
||||||
mozharness:
|
mozharness:
|
||||||
script: mozharness/scripts/firefox_ui_tests/functional.py
|
script: mozharness/scripts/firefox_ui_tests/functional.py
|
||||||
config:
|
config:
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# 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/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
from errors import MarionetteException, TimeoutException
|
from errors import MarionetteException
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
|
@ -40,13 +40,16 @@ def do_process_check(func, always=False):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
except (MarionetteException, socket.error, IOError) as e:
|
except (MarionetteException, IOError) as e:
|
||||||
exc, val, tb = sys.exc_info()
|
exc, val, tb = sys.exc_info()
|
||||||
|
|
||||||
|
# In case of socket failures force a shutdown of the application
|
||||||
|
if type(e) in (socket.error, socket.timeout):
|
||||||
|
m.force_shutdown()
|
||||||
|
|
||||||
if not isinstance(e, MarionetteException) or type(e) is MarionetteException:
|
if not isinstance(e, MarionetteException) or type(e) is MarionetteException:
|
||||||
if not always:
|
if not always:
|
||||||
check_for_crash()
|
check_for_crash()
|
||||||
if not isinstance(e, MarionetteException) or type(e) is TimeoutException:
|
|
||||||
m.force_shutdown()
|
|
||||||
raise exc, val, tb
|
raise exc, val, tb
|
||||||
finally:
|
finally:
|
||||||
if always:
|
if always:
|
||||||
|
|
|
@ -49,7 +49,10 @@ class MarionetteException(Exception):
|
||||||
st = "".join(["\t%s\n" % x for x in self.stacktrace.splitlines()])
|
st = "".join(["\t%s\n" % x for x in self.stacktrace.splitlines()])
|
||||||
msg += "\nstacktrace:\n%s" % st
|
msg += "\nstacktrace:\n%s" % st
|
||||||
|
|
||||||
return "".join(traceback.format_exception(self.__class__, msg, tb)).strip()
|
if tb:
|
||||||
|
msg += ': ' + "".join(traceback.format_tb(tb))
|
||||||
|
|
||||||
|
return msg
|
||||||
|
|
||||||
|
|
||||||
class ElementNotSelectableException(MarionetteException):
|
class ElementNotSelectableException(MarionetteException):
|
||||||
|
|
|
@ -173,7 +173,7 @@ class GeckoInstance(object):
|
||||||
def restart(self, prefs=None, clean=True):
|
def restart(self, prefs=None, clean=True):
|
||||||
self.close(restart=True)
|
self.close(restart=True)
|
||||||
|
|
||||||
if clean:
|
if clean and self.profile:
|
||||||
self.profile.cleanup()
|
self.profile.cleanup()
|
||||||
self.profile = None
|
self.profile = None
|
||||||
|
|
||||||
|
@ -221,11 +221,9 @@ class FennecInstance(GeckoInstance):
|
||||||
self.runner.device.connect()
|
self.runner.device.connect()
|
||||||
self.runner.start()
|
self.runner.start()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
message = 'Error possibly due to runner or device args.'
|
exc, val, tb = sys.exc_info()
|
||||||
e.args += (message,)
|
message = 'Error possibly due to runner or device args: {}'
|
||||||
if hasattr(e, 'strerror') and e.strerror:
|
raise exc, message.format(e.message), tb
|
||||||
e.strerror = ', '.join([e.strerror, message])
|
|
||||||
raise e
|
|
||||||
# gecko_log comes from logcat when running with device/emulator
|
# gecko_log comes from logcat when running with device/emulator
|
||||||
logcat_args = {
|
logcat_args = {
|
||||||
'filterspec': 'Gecko',
|
'filterspec': 'Gecko',
|
||||||
|
|
|
@ -543,6 +543,7 @@ class Marionette(object):
|
||||||
TIMEOUT_PAGE = 'page load'
|
TIMEOUT_PAGE = 'page load'
|
||||||
DEFAULT_SOCKET_TIMEOUT = 360
|
DEFAULT_SOCKET_TIMEOUT = 360
|
||||||
DEFAULT_STARTUP_TIMEOUT = 120
|
DEFAULT_STARTUP_TIMEOUT = 120
|
||||||
|
DEFAULT_SHUTDOWN_TIMEOUT = 65 # Firefox will kill hanging threads after 60s
|
||||||
|
|
||||||
def __init__(self, host='localhost', port=2828, app=None, bin=None,
|
def __init__(self, host='localhost', port=2828, app=None, bin=None,
|
||||||
baseurl=None, timeout=None, socket_timeout=DEFAULT_SOCKET_TIMEOUT,
|
baseurl=None, timeout=None, socket_timeout=DEFAULT_SOCKET_TIMEOUT,
|
||||||
|
@ -616,7 +617,7 @@ class Marionette(object):
|
||||||
if self.session:
|
if self.session:
|
||||||
try:
|
try:
|
||||||
self.delete_session()
|
self.delete_session()
|
||||||
except (errors.MarionetteException, socket.error, IOError):
|
except (errors.MarionetteException, IOError):
|
||||||
# These exceptions get thrown if the Marionette server
|
# These exceptions get thrown if the Marionette server
|
||||||
# hit an exception/died or the connection died. We can
|
# hit an exception/died or the connection died. We can
|
||||||
# do no further server-side cleanup in this case.
|
# do no further server-side cleanup in this case.
|
||||||
|
@ -648,7 +649,7 @@ class Marionette(object):
|
||||||
@do_process_check
|
@do_process_check
|
||||||
def raise_for_port(self, port_obtained):
|
def raise_for_port(self, port_obtained):
|
||||||
if not port_obtained:
|
if not port_obtained:
|
||||||
raise IOError("Timed out waiting for port!")
|
raise socket.timeout("Timed out waiting for port {}!".format(self.port))
|
||||||
|
|
||||||
@do_process_check
|
@do_process_check
|
||||||
def _send_message(self, name, params=None, key=None):
|
def _send_message(self, name, params=None, key=None):
|
||||||
|
@ -684,7 +685,8 @@ class Marionette(object):
|
||||||
self.session = None
|
self.session = None
|
||||||
self.window = None
|
self.window = None
|
||||||
self.client.close()
|
self.client.close()
|
||||||
raise errors.TimeoutException("Connection timed out")
|
|
||||||
|
raise
|
||||||
|
|
||||||
res, err = msg.result, msg.error
|
res, err = msg.result, msg.error
|
||||||
if err:
|
if err:
|
||||||
|
@ -754,17 +756,19 @@ class Marionette(object):
|
||||||
if self.instance:
|
if self.instance:
|
||||||
exc, val, tb = sys.exc_info()
|
exc, val, tb = sys.exc_info()
|
||||||
|
|
||||||
returncode = self.instance.runner.returncode
|
# Give the application some time to shutdown
|
||||||
|
returncode = self.instance.runner.wait(timeout=self.DEFAULT_STARTUP_TIMEOUT)
|
||||||
if returncode is None:
|
if returncode is None:
|
||||||
self.instance.runner.stop()
|
self.cleanup()
|
||||||
message = 'Process killed because the connection was lost'
|
message = ('Process killed because the connection to Marionette server is lost.'
|
||||||
|
' Check gecko.log for errors')
|
||||||
else:
|
else:
|
||||||
message = 'Process died with returncode "{returncode}"'
|
message = 'Process has been closed (Exit code: {returncode})'
|
||||||
|
|
||||||
if exc:
|
if exc:
|
||||||
message += ' (Reason: {reason})'
|
message += ' (Reason: {reason})'
|
||||||
|
|
||||||
raise exc, message.format(returncode=returncode, reason=val), tb
|
raise IOError, message.format(returncode=returncode, reason=val), tb
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def convert_keys(*string):
|
def convert_keys(*string):
|
||||||
|
@ -993,8 +997,8 @@ class Marionette(object):
|
||||||
: param prefs: A dictionary whose keys are preference names.
|
: param prefs: A dictionary whose keys are preference names.
|
||||||
"""
|
"""
|
||||||
if not self.instance:
|
if not self.instance:
|
||||||
raise errors.MarionetteException("enforce_gecko_prefs can only be called "
|
raise errors.MarionetteException("enforce_gecko_prefs() can only be called "
|
||||||
"on gecko instances launched by Marionette")
|
"on Gecko instances launched by Marionette")
|
||||||
pref_exists = True
|
pref_exists = True
|
||||||
self.set_context(self.CONTEXT_CHROME)
|
self.set_context(self.CONTEXT_CHROME)
|
||||||
for pref, value in prefs.iteritems():
|
for pref, value in prefs.iteritems():
|
||||||
|
@ -1027,13 +1031,14 @@ class Marionette(object):
|
||||||
self.start_session()
|
self.start_session()
|
||||||
self.reset_timeouts()
|
self.reset_timeouts()
|
||||||
|
|
||||||
|
@do_process_check
|
||||||
def quit_in_app(self):
|
def quit_in_app(self):
|
||||||
"""
|
"""
|
||||||
This will terminate the currently running instance.
|
This will terminate the currently running instance.
|
||||||
"""
|
"""
|
||||||
if not self.instance:
|
if not self.instance:
|
||||||
raise errors.MarionetteException("quit_in_app can only be called "
|
raise errors.MarionetteException("quit_in_app() can only be called "
|
||||||
"on gecko instances launched by Marionette")
|
"on Gecko instances launched by Marionette")
|
||||||
# Values here correspond to constants in nsIAppStartup.
|
# Values here correspond to constants in nsIAppStartup.
|
||||||
# See http://mzl.la/1X0JZsC
|
# See http://mzl.la/1X0JZsC
|
||||||
restart_flags = [
|
restart_flags = [
|
||||||
|
@ -1042,7 +1047,14 @@ class Marionette(object):
|
||||||
]
|
]
|
||||||
self._send_message("quitApplication", {"flags": restart_flags})
|
self._send_message("quitApplication", {"flags": restart_flags})
|
||||||
self.client.close()
|
self.client.close()
|
||||||
self.raise_for_port(self.wait_for_port())
|
|
||||||
|
try:
|
||||||
|
self.raise_for_port(self.wait_for_port())
|
||||||
|
except socket.timeout:
|
||||||
|
if self.instance.runner.returncode is not None:
|
||||||
|
exc, val, tb = sys.exc_info()
|
||||||
|
self.cleanup()
|
||||||
|
raise exc, 'Requested restart of the application was aborted', tb
|
||||||
|
|
||||||
def restart(self, clean=False, in_app=False):
|
def restart(self, clean=False, in_app=False):
|
||||||
"""
|
"""
|
||||||
|
@ -1057,11 +1069,11 @@ class Marionette(object):
|
||||||
by killing the process.
|
by killing the process.
|
||||||
"""
|
"""
|
||||||
if not self.instance:
|
if not self.instance:
|
||||||
raise errors.MarionetteException("restart can only be called "
|
raise errors.MarionetteException("restart() can only be called "
|
||||||
"on gecko instances launched by Marionette")
|
"on Gecko instances launched by Marionette")
|
||||||
if in_app:
|
if in_app:
|
||||||
if clean:
|
if clean:
|
||||||
raise ValueError
|
raise ValueError("An in_app restart cannot be triggered with the clean flag set")
|
||||||
self.quit_in_app()
|
self.quit_in_app()
|
||||||
else:
|
else:
|
||||||
self.delete_session()
|
self.delete_session()
|
||||||
|
@ -1463,8 +1475,13 @@ class Marionette(object):
|
||||||
:param ms: A number value specifying the timeout length in
|
:param ms: A number value specifying the timeout length in
|
||||||
milliseconds (ms)
|
milliseconds (ms)
|
||||||
"""
|
"""
|
||||||
if timeout_type not in [self.TIMEOUT_SEARCH, self.TIMEOUT_SCRIPT, self.TIMEOUT_PAGE]:
|
timeout_types = (self.TIMEOUT_PAGE,
|
||||||
raise ValueError("Unknown timeout type: %s" % timeout_type)
|
self.TIMEOUT_SCRIPT,
|
||||||
|
self.TIMEOUT_SEARCH,
|
||||||
|
)
|
||||||
|
if timeout_type not in timeout_types:
|
||||||
|
raise ValueError("Unknown timeout type: {0} (should be one "
|
||||||
|
"of {1})".format(timeout_type, timeout_types))
|
||||||
body = {"type": timeout_type, "ms": ms}
|
body = {"type": timeout_type, "ms": ms}
|
||||||
self._send_message("timeouts", body)
|
self._send_message("timeouts", body)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import errno
|
|
||||||
import json
|
import json
|
||||||
import socket
|
import socket
|
||||||
import time
|
import time
|
||||||
|
@ -119,7 +118,6 @@ class TcpTransport(object):
|
||||||
Supported protocol levels are 1 and above.
|
Supported protocol levels are 1 and above.
|
||||||
"""
|
"""
|
||||||
max_packet_length = 4096
|
max_packet_length = 4096
|
||||||
connection_lost_msg = "Connection to Marionette server is lost. Check gecko.log for errors."
|
|
||||||
|
|
||||||
def __init__(self, addr, port, socket_timeout=360.0):
|
def __init__(self, addr, port, socket_timeout=360.0):
|
||||||
"""If `socket_timeout` is `0` or `0.0`, non-blocking socket mode
|
"""If `socket_timeout` is `0` or `0.0`, non-blocking socket mode
|
||||||
|
@ -176,7 +174,7 @@ class TcpTransport(object):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if not chunk:
|
if not chunk:
|
||||||
raise IOError(self.connection_lost_msg)
|
raise socket.error("No data received over socket")
|
||||||
|
|
||||||
sep = data.find(":")
|
sep = data.find(":")
|
||||||
if sep > -1:
|
if sep > -1:
|
||||||
|
@ -203,7 +201,7 @@ class TcpTransport(object):
|
||||||
|
|
||||||
bytes_to_recv = int(length) - len(remaining)
|
bytes_to_recv = int(length) - len(remaining)
|
||||||
|
|
||||||
raise socket.timeout("connection timed out after %ds" % self.socket_timeout)
|
raise socket.timeout("Connection timed out after %ds" % self.socket_timeout)
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
"""Connect to the server and process the hello message we expect
|
"""Connect to the server and process the hello message we expect
|
||||||
|
@ -246,19 +244,12 @@ class TcpTransport(object):
|
||||||
|
|
||||||
totalsent = 0
|
totalsent = 0
|
||||||
while totalsent < len(payload):
|
while totalsent < len(payload):
|
||||||
try:
|
sent = self.sock.send(payload[totalsent:])
|
||||||
sent = self.sock.send(payload[totalsent:])
|
if sent == 0:
|
||||||
if sent == 0:
|
raise IOError("Socket error after sending %d of %d bytes" %
|
||||||
raise IOError("socket error after sending %d of %d bytes" %
|
(totalsent, len(payload)))
|
||||||
(totalsent, len(payload)))
|
else:
|
||||||
else:
|
totalsent += sent
|
||||||
totalsent += sent
|
|
||||||
|
|
||||||
except IOError as e:
|
|
||||||
if e.errno == errno.EPIPE:
|
|
||||||
raise IOError("%s: %s" % (str(e), self.connection_lost_msg))
|
|
||||||
else:
|
|
||||||
raise e
|
|
||||||
|
|
||||||
def respond(self, obj):
|
def respond(self, obj):
|
||||||
"""Send a response to a command. This can be an arbitrary JSON
|
"""Send a response to a command. This can be an arbitrary JSON
|
||||||
|
|
|
@ -121,9 +121,9 @@ class Wait(object):
|
||||||
while not until(self.clock, self.end):
|
while not until(self.clock, self.end):
|
||||||
try:
|
try:
|
||||||
rv = condition(self.marionette)
|
rv = condition(self.marionette)
|
||||||
except (KeyboardInterrupt, SystemExit) as e:
|
except (KeyboardInterrupt, SystemExit):
|
||||||
raise e
|
raise
|
||||||
except self.exceptions as e:
|
except self.exceptions:
|
||||||
last_exc = sys.exc_info()
|
last_exc = sys.exc_info()
|
||||||
|
|
||||||
if not rv:
|
if not rv:
|
||||||
|
|
|
@ -128,9 +128,9 @@ this.GeckoDriver = function(appName, stopSignal) {
|
||||||
|
|
||||||
this.sessionCapabilities = {
|
this.sessionCapabilities = {
|
||||||
// mandated capabilities
|
// mandated capabilities
|
||||||
"browserName": Services.appinfo.name,
|
"browserName": Services.appinfo.name.toLowerCase(),
|
||||||
"browserVersion": Services.appinfo.version,
|
"browserVersion": Services.appinfo.version,
|
||||||
"platformName": Services.sysinfo.getProperty("name"),
|
"platformName": Services.sysinfo.getProperty("name").toLowerCase(),
|
||||||
"platformVersion": Services.sysinfo.getProperty("version"),
|
"platformVersion": Services.sysinfo.getProperty("version"),
|
||||||
"specificationLevel": 0,
|
"specificationLevel": 0,
|
||||||
|
|
||||||
|
|
|
@ -616,9 +616,9 @@ class BaseMarionetteTestRunner(object):
|
||||||
with open(path) as f:
|
with open(path) as f:
|
||||||
data.append(json.loads(f.read()))
|
data.append(json.loads(f.read()))
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise Exception("JSON file (%s) is not properly "
|
exc, val, tb = sys.exc_info()
|
||||||
"formatted: %s" % (os.path.abspath(path),
|
msg = "JSON file ({0}) is not properly formatted: {1}"
|
||||||
e.message))
|
raise exc, msg.format(os.path.abspath(path), e.message), tb
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -669,11 +669,7 @@ class BaseMarionetteTestRunner(object):
|
||||||
"""
|
"""
|
||||||
self._bin = path
|
self._bin = path
|
||||||
self.tests = []
|
self.tests = []
|
||||||
if hasattr(self, 'marionette') and self.marionette:
|
self.cleanup()
|
||||||
self.marionette.cleanup()
|
|
||||||
if self.marionette.instance:
|
|
||||||
self.marionette.instance = None
|
|
||||||
self.marionette = None
|
|
||||||
|
|
||||||
def reset_test_stats(self):
|
def reset_test_stats(self):
|
||||||
self.passed = 0
|
self.passed = 0
|
||||||
|
@ -737,8 +733,10 @@ class BaseMarionetteTestRunner(object):
|
||||||
connection = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
|
connection = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
|
||||||
connection.connect((host,int(port)))
|
connection.connect((host,int(port)))
|
||||||
connection.close()
|
connection.close()
|
||||||
except Exception, e:
|
except Exception as e:
|
||||||
raise Exception("Connection attempt to %s:%s failed with error: %s" %(host,port,e))
|
exc, val, tb = sys.exc_info()
|
||||||
|
msg = "Connection attempt to {0}:{1} failed with error: {2}"
|
||||||
|
raise exc, msg.format(host, port, e), tb
|
||||||
if self.workspace:
|
if self.workspace:
|
||||||
kwargs['workspace'] = self.workspace_path
|
kwargs['workspace'] = self.workspace_path
|
||||||
return kwargs
|
return kwargs
|
||||||
|
@ -896,16 +894,17 @@ setReq.onerror = function() {
|
||||||
# we want to display current test results.
|
# we want to display current test results.
|
||||||
# so we keep the exception to raise it later.
|
# so we keep the exception to raise it later.
|
||||||
interrupted = sys.exc_info()
|
interrupted = sys.exc_info()
|
||||||
|
except:
|
||||||
|
# For any other exception we return immediately and have to
|
||||||
|
# cleanup running processes
|
||||||
|
self.cleanup()
|
||||||
|
raise
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._print_summary(tests)
|
self._print_summary(tests)
|
||||||
self.record_crash()
|
self.record_crash()
|
||||||
self.elapsedtime = time.time() - start_time
|
self.elapsedtime = time.time() - start_time
|
||||||
|
|
||||||
if self.marionette.instance:
|
|
||||||
self.marionette.instance.close()
|
|
||||||
self.marionette.instance = None
|
|
||||||
self.marionette.cleanup()
|
|
||||||
|
|
||||||
for run_tests in self.mixin_run_tests:
|
for run_tests in self.mixin_run_tests:
|
||||||
run_tests(tests)
|
run_tests(tests)
|
||||||
if self.shuffle:
|
if self.shuffle:
|
||||||
|
@ -918,6 +917,8 @@ setReq.onerror = function() {
|
||||||
if not interrupted:
|
if not interrupted:
|
||||||
raise
|
raise
|
||||||
finally:
|
finally:
|
||||||
|
self.cleanup()
|
||||||
|
|
||||||
# reraise previous interruption now
|
# reraise previous interruption now
|
||||||
if interrupted:
|
if interrupted:
|
||||||
raise interrupted[0], interrupted[1], interrupted[2]
|
raise interrupted[0], interrupted[1], interrupted[2]
|
||||||
|
@ -1090,10 +1091,16 @@ setReq.onerror = function() {
|
||||||
self.run_test_set(self.tests)
|
self.run_test_set(self.tests)
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
if self.httpd:
|
if hasattr(self, 'httpd') and self.httpd:
|
||||||
self.httpd.stop()
|
self.httpd.stop()
|
||||||
|
self.httpd = None
|
||||||
|
|
||||||
|
if hasattr(self, 'marionette') and self.marionette:
|
||||||
|
if self.marionette.instance:
|
||||||
|
self.marionette.instance.close()
|
||||||
|
self.marionette.instance = None
|
||||||
|
|
||||||
if self.marionette:
|
|
||||||
self.marionette.cleanup()
|
self.marionette.cleanup()
|
||||||
|
self.marionette = None
|
||||||
|
|
||||||
__del__ = cleanup
|
__del__ = cleanup
|
||||||
|
|
|
@ -11,7 +11,7 @@ class FixtureServer(object):
|
||||||
|
|
||||||
def __init__(self, root, host="127.0.0.1", port=0):
|
def __init__(self, root, host="127.0.0.1", port=0):
|
||||||
if not os.path.isdir(root):
|
if not os.path.isdir(root):
|
||||||
raise Exception("Server root is not a valid path: %s" % root)
|
raise IOError("Server root is not a valid path: %s" % root)
|
||||||
self.root = root
|
self.root = root
|
||||||
self.host = host
|
self.host = host
|
||||||
self.port = port
|
self.port = port
|
||||||
|
@ -44,7 +44,7 @@ class FixtureServer(object):
|
||||||
|
|
||||||
def get_url(self, path="/"):
|
def get_url(self, path="/"):
|
||||||
if not self.alive:
|
if not self.alive:
|
||||||
raise "Server not started"
|
raise Exception("Server not started")
|
||||||
return self._server.get_url(path)
|
return self._server.get_url(path)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|
|
@ -31,8 +31,8 @@ class Server(object):
|
||||||
break
|
break
|
||||||
|
|
||||||
if not os.path.isfile(path) and exec_not_on_path:
|
if not os.path.isfile(path) and exec_not_on_path:
|
||||||
raise Exception("Browsermob-Proxy binary couldn't be found in path"
|
raise IOError("Browsermob-Proxy binary couldn't be found in path"
|
||||||
" provided: %s" % path)
|
" provided: %s" % path)
|
||||||
|
|
||||||
self.path = path
|
self.path = path
|
||||||
self.port = options.get('port', 8080)
|
self.port = options.get('port', 8080)
|
||||||
|
|
|
@ -12,7 +12,7 @@ class TestAboutPages(MarionetteTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
MarionetteTestCase.setUp(self)
|
MarionetteTestCase.setUp(self)
|
||||||
if self.marionette.session_capabilities['platformName'] == 'Darwin':
|
if self.marionette.session_capabilities['platformName'] == 'darwin':
|
||||||
self.mod_key = Keys.META
|
self.mod_key = Keys.META
|
||||||
else:
|
else:
|
||||||
self.mod_key = Keys.CONTROL
|
self.mod_key = Keys.CONTROL
|
||||||
|
|
|
@ -15,7 +15,7 @@ class TestCapabilities(MarionetteTestCase):
|
||||||
self.appinfo = self.marionette.execute_script(
|
self.appinfo = self.marionette.execute_script(
|
||||||
"return Services.appinfo")
|
"return Services.appinfo")
|
||||||
self.os_name = self.marionette.execute_script(
|
self.os_name = self.marionette.execute_script(
|
||||||
"return Services.sysinfo.getProperty('name')")
|
"return Services.sysinfo.getProperty('name')").lower()
|
||||||
self.os_version = self.marionette.execute_script(
|
self.os_version = self.marionette.execute_script(
|
||||||
"return Services.sysinfo.getProperty('version')")
|
"return Services.sysinfo.getProperty('version')")
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ class TestCapabilities(MarionetteTestCase):
|
||||||
self.assertIn("platformVersion", self.caps)
|
self.assertIn("platformVersion", self.caps)
|
||||||
self.assertIn("specificationLevel", self.caps)
|
self.assertIn("specificationLevel", self.caps)
|
||||||
|
|
||||||
self.assertEqual(self.caps["browserName"], self.appinfo["name"])
|
self.assertEqual(self.caps["browserName"], self.appinfo["name"].lower())
|
||||||
self.assertEqual(self.caps["browserVersion"], self.appinfo["version"])
|
self.assertEqual(self.caps["browserVersion"], self.appinfo["version"])
|
||||||
self.assertEqual(self.caps["platformName"], self.os_name)
|
self.assertEqual(self.caps["platformName"], self.os_name)
|
||||||
self.assertEqual(self.caps["platformVersion"], self.os_version)
|
self.assertEqual(self.caps["platformVersion"], self.os_version)
|
||||||
|
@ -78,12 +78,12 @@ class TestCapabilities(MarionetteTestCase):
|
||||||
capabilities = {"desiredCapabilities": {"browserName": "ChocolateCake"}}
|
capabilities = {"desiredCapabilities": {"browserName": "ChocolateCake"}}
|
||||||
self.marionette.start_session(capabilities)
|
self.marionette.start_session(capabilities)
|
||||||
caps = self.marionette.session_capabilities
|
caps = self.marionette.session_capabilities
|
||||||
self.assertEqual(caps["browserName"], self.appinfo["name"],
|
self.assertEqual(caps["browserName"], self.appinfo["name"].lower(),
|
||||||
"This should have appname not ChocolateCake")
|
"This should have appname not ChocolateCake.")
|
||||||
|
|
||||||
def test_we_can_pass_in_required_capabilities_on_session_start(self):
|
def test_we_can_pass_in_required_capabilities_on_session_start(self):
|
||||||
self.marionette.delete_session()
|
self.marionette.delete_session()
|
||||||
capabilities = {"requiredCapabilities": {"browserName": self.appinfo["name"]}}
|
capabilities = {"requiredCapabilities": {"browserName": self.appinfo["name"].lower()}}
|
||||||
self.marionette.start_session(capabilities)
|
self.marionette.start_session(capabilities)
|
||||||
caps = self.marionette.session_capabilities
|
caps = self.marionette.session_capabilities
|
||||||
self.assertIn("browserName", caps)
|
self.assertIn("browserName", caps)
|
||||||
|
|
|
@ -38,7 +38,6 @@ class TestErrors(marionette_test.MarionetteTestCase):
|
||||||
self.assertIn(message, r)
|
self.assertIn(message, r)
|
||||||
self.assertIn(", caused by %r" % cause[0], r)
|
self.assertIn(", caused by %r" % cause[0], r)
|
||||||
self.assertIn("\nstacktrace:\n\tfirst\n\tsecond", r)
|
self.assertIn("\nstacktrace:\n\tfirst\n\tsecond", r)
|
||||||
self.assertIn("MarionetteException:", r)
|
|
||||||
|
|
||||||
def test_cause_string(self):
|
def test_cause_string(self):
|
||||||
exc = errors.MarionetteException(cause="foo")
|
exc = errors.MarionetteException(cause="foo")
|
||||||
|
|
|
@ -11,7 +11,7 @@ from marionette_driver.by import By
|
||||||
class TestKeyActions(MarionetteTestCase):
|
class TestKeyActions(MarionetteTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
MarionetteTestCase.setUp(self)
|
MarionetteTestCase.setUp(self)
|
||||||
if self.marionette.session_capabilities["platformName"] == "Darwin":
|
if self.marionette.session_capabilities["platformName"] == "darwin":
|
||||||
self.mod_key = Keys.META
|
self.mod_key = Keys.META
|
||||||
else:
|
else:
|
||||||
self.mod_key = Keys.CONTROL
|
self.mod_key = Keys.CONTROL
|
||||||
|
|
|
@ -11,7 +11,7 @@ from marionette_driver.by import By
|
||||||
class TestMouseAction(MarionetteTestCase):
|
class TestMouseAction(MarionetteTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
MarionetteTestCase.setUp(self)
|
MarionetteTestCase.setUp(self)
|
||||||
if self.marionette.session_capabilities["platformName"] == "Darwin":
|
if self.marionette.session_capabilities["platformName"] == "darwin":
|
||||||
self.mod_key = Keys.META
|
self.mod_key = Keys.META
|
||||||
else:
|
else:
|
||||||
self.mod_key = Keys.CONTROL
|
self.mod_key = Keys.CONTROL
|
||||||
|
|
|
@ -11,6 +11,12 @@ from marionette_driver.by import By
|
||||||
|
|
||||||
|
|
||||||
class TestTimeouts(MarionetteTestCase):
|
class TestTimeouts(MarionetteTestCase):
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.marionette.reset_timeouts()
|
||||||
|
|
||||||
|
MarionetteTestCase.tearDown(self)
|
||||||
|
|
||||||
def test_pagetimeout_notdefinetimeout_pass(self):
|
def test_pagetimeout_notdefinetimeout_pass(self):
|
||||||
test_html = self.marionette.absolute_url("test.html")
|
test_html = self.marionette.absolute_url("test.html")
|
||||||
self.marionette.navigate(test_html)
|
self.marionette.navigate(test_html)
|
||||||
|
@ -62,3 +68,8 @@ class TestTimeouts(MarionetteTestCase):
|
||||||
var callback = arguments[arguments.length - 1];
|
var callback = arguments[arguments.length - 1];
|
||||||
setTimeout(function() { callback(true); }, 500);
|
setTimeout(function() { callback(true); }, 500);
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
|
def test_invalid_timeout_type(self):
|
||||||
|
self.assertRaises(ValueError, self.marionette.timeouts, "foobar", 1000)
|
||||||
|
self.assertRaises(ValueError, self.marionette.timeouts, 42, 1000)
|
||||||
|
self.assertRaises(MarionetteException, self.marionette.timeouts, "page load", "foobar")
|
||||||
|
|
|
@ -58,7 +58,7 @@ class TestTyping(MarionetteTestCase):
|
||||||
|
|
||||||
def testCutAndPasteShortcuts(self):
|
def testCutAndPasteShortcuts(self):
|
||||||
# test that modifier keys work via copy/paste shortcuts
|
# test that modifier keys work via copy/paste shortcuts
|
||||||
if self.marionette.session_capabilities["platformName"] == "Darwin":
|
if self.marionette.session_capabilities["platformName"] == "darwin":
|
||||||
mod_key = Keys.META
|
mod_key = Keys.META
|
||||||
else:
|
else:
|
||||||
mod_key = Keys.CONTROL
|
mod_key = Keys.CONTROL
|
||||||
|
|
|
@ -12,7 +12,7 @@ class TestWindowHandles(MarionetteTestCase):
|
||||||
def test_new_tab_window_handles(self):
|
def test_new_tab_window_handles(self):
|
||||||
|
|
||||||
keys = []
|
keys = []
|
||||||
if self.marionette.session_capabilities['platformName'] == 'Darwin':
|
if self.marionette.session_capabilities['platformName'] == 'darwin':
|
||||||
keys.append(Keys.META)
|
keys.append(Keys.META)
|
||||||
else:
|
else:
|
||||||
keys.append(Keys.CONTROL)
|
keys.append(Keys.CONTROL)
|
||||||
|
|
|
@ -126,7 +126,7 @@ function registerSelf() {
|
||||||
if (register[0]) {
|
if (register[0]) {
|
||||||
let {id, remotenessChange} = register[0][0];
|
let {id, remotenessChange} = register[0][0];
|
||||||
capabilities = register[0][2];
|
capabilities = register[0][2];
|
||||||
isB2G = capabilities.platformName == "B2G";
|
isB2G = capabilities.platformName == "b2g";
|
||||||
listenerId = id;
|
listenerId = id;
|
||||||
if (typeof id != "undefined") {
|
if (typeof id != "undefined") {
|
||||||
// check if we're the main process
|
// check if we're the main process
|
||||||
|
|
|
@ -66,7 +66,7 @@ class Puppeteer(object):
|
||||||
|
|
||||||
:returns: Platform name
|
:returns: Platform name
|
||||||
"""
|
"""
|
||||||
return self.marionette.session_capabilities['platformName'].lower()
|
return self.marionette.session_capabilities['platformName']
|
||||||
|
|
||||||
@use_class_as_property('api.prefs.Preferences')
|
@use_class_as_property('api.prefs.Preferences')
|
||||||
def prefs(self):
|
def prefs(self):
|
||||||
|
|
|
@ -13,7 +13,7 @@ class Keys(marionette_driver.keys.Keys):
|
||||||
self.marionette_getter = marionette_getter
|
self.marionette_getter = marionette_getter
|
||||||
|
|
||||||
caps = self.marionette_getter().session_capabilities
|
caps = self.marionette_getter().session_capabilities
|
||||||
self.isDarwin = caps['platformName'] == 'DARWIN'
|
self.isDarwin = caps['platformName'] == 'darwin'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ACCEL(self):
|
def ACCEL(self):
|
||||||
|
|
|
@ -398,7 +398,7 @@ class BaseWindow(BaseLib):
|
||||||
Defaults to `False`.
|
Defaults to `False`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
platform = self.marionette.session_capabilities['platformName'].lower()
|
platform = self.marionette.session_capabilities['platformName']
|
||||||
|
|
||||||
keymap = {
|
keymap = {
|
||||||
'accel': Keys.META if platform == 'darwin' else Keys.CONTROL,
|
'accel': Keys.META if platform == 'darwin' else Keys.CONTROL,
|
||||||
|
|
|
@ -283,8 +283,14 @@ FinderHighlighter.prototype = {
|
||||||
* Optional, defaults to the finder window.
|
* Optional, defaults to the finder window.
|
||||||
* @param {nsIDOMRange} skipRange A range that should not be removed from the
|
* @param {nsIDOMRange} skipRange A range that should not be removed from the
|
||||||
* find selection.
|
* find selection.
|
||||||
|
* @param {nsIDOMEvent} event When called from an event handler, this will
|
||||||
|
* be the triggering event.
|
||||||
*/
|
*/
|
||||||
hide(window = null, skipRange = null) {
|
hide(window = null, skipRange = null, event = null) {
|
||||||
|
// Do not hide on anything but a left-click.
|
||||||
|
if (event && event.type == "click" && event.button !== 0)
|
||||||
|
return;
|
||||||
|
|
||||||
window = window || this.finder._getWindow();
|
window = window || this.finder._getWindow();
|
||||||
|
|
||||||
let doc = window.document;
|
let doc = window.document;
|
||||||
|
@ -836,12 +842,11 @@ FinderHighlighter.prototype = {
|
||||||
|
|
||||||
this._highlightListeners = [
|
this._highlightListeners = [
|
||||||
this._scheduleRepaintOfMask.bind(this, window),
|
this._scheduleRepaintOfMask.bind(this, window),
|
||||||
this.hide.bind(this, window)
|
this.hide.bind(this, window, null)
|
||||||
];
|
];
|
||||||
window.addEventListener("DOMContentLoaded", this._highlightListeners[0]);
|
window.addEventListener("DOMContentLoaded", this._highlightListeners[0]);
|
||||||
window.addEventListener("mousedown", this._highlightListeners[1]);
|
window.addEventListener("click", this._highlightListeners[1]);
|
||||||
window.addEventListener("resize", this._highlightListeners[1]);
|
window.addEventListener("resize", this._highlightListeners[1]);
|
||||||
window.addEventListener("touchstart", this._highlightListeners[1]);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -854,9 +859,8 @@ FinderHighlighter.prototype = {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
window.removeEventListener("DOMContentLoaded", this._highlightListeners[0]);
|
window.removeEventListener("DOMContentLoaded", this._highlightListeners[0]);
|
||||||
window.removeEventListener("mousedown", this._highlightListeners[1]);
|
window.removeEventListener("click", this._highlightListeners[1]);
|
||||||
window.removeEventListener("resize", this._highlightListeners[1]);
|
window.removeEventListener("resize", this._highlightListeners[1]);
|
||||||
window.removeEventListener("touchstart", this._highlightListeners[1]);
|
|
||||||
|
|
||||||
this._highlightListeners = null;
|
this._highlightListeners = null;
|
||||||
},
|
},
|
||||||
|
|
|
@ -113,7 +113,7 @@ public:
|
||||||
* mozilla::InternalFormEvent
|
* mozilla::InternalFormEvent
|
||||||
*
|
*
|
||||||
* We hold the originating form control for form submit and reset events.
|
* We hold the originating form control for form submit and reset events.
|
||||||
* originator is a weak pointer (does not hold a strong reference).
|
* mOriginator is a weak pointer (does not hold a strong reference).
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
class InternalFormEvent : public WidgetEvent
|
class InternalFormEvent : public WidgetEvent
|
||||||
|
@ -123,7 +123,7 @@ public:
|
||||||
|
|
||||||
InternalFormEvent(bool aIsTrusted, EventMessage aMessage)
|
InternalFormEvent(bool aIsTrusted, EventMessage aMessage)
|
||||||
: WidgetEvent(aIsTrusted, aMessage, eFormEventClass)
|
: WidgetEvent(aIsTrusted, aMessage, eFormEventClass)
|
||||||
, originator(nullptr)
|
, mOriginator(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,13 +137,13 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIContent *originator;
|
nsIContent* mOriginator;
|
||||||
|
|
||||||
void AssignFormEventData(const InternalFormEvent& aEvent, bool aCopyTargets)
|
void AssignFormEventData(const InternalFormEvent& aEvent, bool aCopyTargets)
|
||||||
{
|
{
|
||||||
AssignEventData(aEvent, aCopyTargets);
|
AssignEventData(aEvent, aCopyTargets);
|
||||||
|
|
||||||
// Don't copy originator due to a weak pointer.
|
// Don't copy mOriginator due to a weak pointer.
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -666,9 +666,9 @@ class WidgetPointerEvent : public WidgetMouseEvent
|
||||||
friend class mozilla::dom::PBrowserChild;
|
friend class mozilla::dom::PBrowserChild;
|
||||||
|
|
||||||
WidgetPointerEvent()
|
WidgetPointerEvent()
|
||||||
: width(0)
|
: mWidth(0)
|
||||||
, height(0)
|
, mHeight(0)
|
||||||
, isPrimary(true)
|
, mIsPrimary(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -677,17 +677,17 @@ public:
|
||||||
|
|
||||||
WidgetPointerEvent(bool aIsTrusted, EventMessage aMsg, nsIWidget* w)
|
WidgetPointerEvent(bool aIsTrusted, EventMessage aMsg, nsIWidget* w)
|
||||||
: WidgetMouseEvent(aIsTrusted, aMsg, w, ePointerEventClass, eReal)
|
: WidgetMouseEvent(aIsTrusted, aMsg, w, ePointerEventClass, eReal)
|
||||||
, width(0)
|
, mWidth(0)
|
||||||
, height(0)
|
, mHeight(0)
|
||||||
, isPrimary(true)
|
, mIsPrimary(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit WidgetPointerEvent(const WidgetMouseEvent& aEvent)
|
explicit WidgetPointerEvent(const WidgetMouseEvent& aEvent)
|
||||||
: WidgetMouseEvent(aEvent)
|
: WidgetMouseEvent(aEvent)
|
||||||
, width(0)
|
, mWidth(0)
|
||||||
, height(0)
|
, mHeight(0)
|
||||||
, isPrimary(true)
|
, mIsPrimary(true)
|
||||||
{
|
{
|
||||||
mClass = ePointerEventClass;
|
mClass = ePointerEventClass;
|
||||||
}
|
}
|
||||||
|
@ -704,9 +704,9 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t width;
|
uint32_t mWidth;
|
||||||
uint32_t height;
|
uint32_t mHeight;
|
||||||
bool isPrimary;
|
bool mIsPrimary;
|
||||||
|
|
||||||
// XXX Not tested by test_assign_event_data.html
|
// XXX Not tested by test_assign_event_data.html
|
||||||
void AssignPointerEventData(const WidgetPointerEvent& aEvent,
|
void AssignPointerEventData(const WidgetPointerEvent& aEvent,
|
||||||
|
@ -714,9 +714,9 @@ public:
|
||||||
{
|
{
|
||||||
AssignMouseEventData(aEvent, aCopyTargets);
|
AssignMouseEventData(aEvent, aCopyTargets);
|
||||||
|
|
||||||
width = aEvent.width;
|
mWidth = aEvent.mWidth;
|
||||||
height = aEvent.height;
|
mHeight = aEvent.mHeight;
|
||||||
isPrimary = aEvent.isPrimary;
|
mIsPrimary = aEvent.mIsPrimary;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -287,11 +287,11 @@ struct ParamTraits<mozilla::WidgetPointerEvent>
|
||||||
{
|
{
|
||||||
WriteParam(aMsg, static_cast<mozilla::WidgetMouseEvent>(aParam));
|
WriteParam(aMsg, static_cast<mozilla::WidgetMouseEvent>(aParam));
|
||||||
WriteParam(aMsg, aParam.pointerId);
|
WriteParam(aMsg, aParam.pointerId);
|
||||||
WriteParam(aMsg, aParam.width);
|
WriteParam(aMsg, aParam.mWidth);
|
||||||
WriteParam(aMsg, aParam.height);
|
WriteParam(aMsg, aParam.mHeight);
|
||||||
WriteParam(aMsg, aParam.tiltX);
|
WriteParam(aMsg, aParam.tiltX);
|
||||||
WriteParam(aMsg, aParam.tiltY);
|
WriteParam(aMsg, aParam.tiltY);
|
||||||
WriteParam(aMsg, aParam.isPrimary);
|
WriteParam(aMsg, aParam.mIsPrimary);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||||
|
@ -299,11 +299,11 @@ struct ParamTraits<mozilla::WidgetPointerEvent>
|
||||||
bool rv =
|
bool rv =
|
||||||
ReadParam(aMsg, aIter, static_cast<mozilla::WidgetMouseEvent*>(aResult)) &&
|
ReadParam(aMsg, aIter, static_cast<mozilla::WidgetMouseEvent*>(aResult)) &&
|
||||||
ReadParam(aMsg, aIter, &aResult->pointerId) &&
|
ReadParam(aMsg, aIter, &aResult->pointerId) &&
|
||||||
ReadParam(aMsg, aIter, &aResult->width) &&
|
ReadParam(aMsg, aIter, &aResult->mWidth) &&
|
||||||
ReadParam(aMsg, aIter, &aResult->height) &&
|
ReadParam(aMsg, aIter, &aResult->mHeight) &&
|
||||||
ReadParam(aMsg, aIter, &aResult->tiltX) &&
|
ReadParam(aMsg, aIter, &aResult->tiltX) &&
|
||||||
ReadParam(aMsg, aIter, &aResult->tiltY) &&
|
ReadParam(aMsg, aIter, &aResult->tiltY) &&
|
||||||
ReadParam(aMsg, aIter, &aResult->isPrimary);
|
ReadParam(aMsg, aIter, &aResult->mIsPrimary);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Загрузка…
Ссылка в новой задаче