зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to autoland a=merge on a CLOSED TREE
This commit is contained in:
Коммит
220232e2f4
|
@ -43,6 +43,9 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(AccessibleNode)
|
|||
NS_IMPL_CYCLE_COLLECTING_RELEASE(AccessibleNode)
|
||||
|
||||
AccessibleNode::AccessibleNode(nsINode* aNode) :
|
||||
mDoubleProperties(3),
|
||||
mIntProperties(3),
|
||||
mUIntProperties(6),
|
||||
mBooleanProperties(0),
|
||||
mDOMNode(aNode)
|
||||
{
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#ifndef A11Y_AOM_ACCESSIBLENODE_H
|
||||
#define A11Y_AOM_ACCESSIBLENODE_H
|
||||
|
||||
#include "nsDataHashtable.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "mozilla/ErrorResult.h"
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
|
@ -45,6 +46,28 @@ struct ParentObject;
|
|||
}; \
|
||||
MOZ_FOR_EACH(ANODE_FUNC, (typeName, type,), (__VA_ARGS__)) \
|
||||
|
||||
#define ANODE_ACCESSOR_MUTATOR(typeName, type, defVal) \
|
||||
nsDataHashtable<nsUint32HashKey, type> m##typeName##Properties; \
|
||||
\
|
||||
dom::Nullable<type> GetProperty(AOM##typeName##Property aProperty) \
|
||||
{ \
|
||||
type value = defVal; \
|
||||
if (m##typeName##Properties.Get(static_cast<int>(aProperty), &value)) { \
|
||||
return dom::Nullable<type>(value); \
|
||||
} \
|
||||
return dom::Nullable<type>(); \
|
||||
} \
|
||||
\
|
||||
void SetProperty(AOM##typeName##Property aProperty, \
|
||||
const dom::Nullable<type>& aValue) \
|
||||
{ \
|
||||
if (aValue.IsNull()) { \
|
||||
m##typeName##Properties.Remove(static_cast<int>(aProperty)); \
|
||||
} else { \
|
||||
m##typeName##Properties.Put(static_cast<int>(aProperty), aValue.Value()); \
|
||||
} \
|
||||
} \
|
||||
|
||||
class AccessibleNode : public nsISupports,
|
||||
public nsWrapperCache
|
||||
{
|
||||
|
@ -84,6 +107,27 @@ public:
|
|||
Selected
|
||||
)
|
||||
|
||||
ANODE_PROPS(UInt, uint32_t,
|
||||
ColIndex,
|
||||
ColSpan,
|
||||
Level,
|
||||
PosInSet,
|
||||
RowIndex,
|
||||
RowSpan
|
||||
)
|
||||
|
||||
ANODE_PROPS(Int, int32_t,
|
||||
ColCount,
|
||||
RowCount,
|
||||
SetSize
|
||||
)
|
||||
|
||||
ANODE_PROPS(Double, double,
|
||||
ValueMax,
|
||||
ValueMin,
|
||||
ValueNow
|
||||
)
|
||||
|
||||
protected:
|
||||
AccessibleNode(const AccessibleNode& aCopy) = delete;
|
||||
AccessibleNode& operator=(const AccessibleNode& aCopy) = delete;
|
||||
|
@ -112,6 +156,10 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
ANODE_ACCESSOR_MUTATOR(Double, double, 0.0)
|
||||
ANODE_ACCESSOR_MUTATOR(Int, int32_t, 0)
|
||||
ANODE_ACCESSOR_MUTATOR(UInt, uint32_t, 0)
|
||||
|
||||
// The 2k'th bit indicates whether the k'th boolean property is used(1) or not(0)
|
||||
// and 2k+1'th bit contains the property's value(1:true, 0:false)
|
||||
uint32_t mBooleanProperties;
|
||||
|
|
|
@ -408,12 +408,9 @@ var Input = {
|
|||
mm.sendAsyncMessage("AccessFu:Clipboard", aDetails);
|
||||
},
|
||||
|
||||
activateCurrent: function activateCurrent(aData, aActivateIfKey = false) {
|
||||
activateCurrent: function activateCurrent(aData) {
|
||||
let mm = Utils.getMessageManager();
|
||||
let offset = 0;
|
||||
|
||||
mm.sendAsyncMessage("AccessFu:Activate",
|
||||
{offset, activateIfKey: aActivateIfKey});
|
||||
mm.sendAsyncMessage("AccessFu:Activate", { offset: 0 });
|
||||
},
|
||||
|
||||
// XXX: This is here for backwards compatability with screen reader simulator
|
||||
|
|
|
@ -186,16 +186,6 @@ this.ContentControl.prototype = {
|
|||
Logger.debug(() => {
|
||||
return ["activateAccessible", Logger.accessibleToString(aAccessible)];
|
||||
});
|
||||
try {
|
||||
if (aMessage.json.activateIfKey &&
|
||||
!Utils.isActivatableOnFingerUp(aAccessible)) {
|
||||
// Only activate keys, don't do anything on other objects.
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
// accessible is invalid. Silently fail.
|
||||
return;
|
||||
}
|
||||
|
||||
if (aAccessible.actionCount > 0) {
|
||||
aAccessible.doAction(0);
|
||||
|
@ -229,8 +219,9 @@ this.ContentControl.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
if (!Utils.isActivatableOnFingerUp(aAccessible)) {
|
||||
// Keys will typically have a sound of their own.
|
||||
// Action invoked will be presented on checked/selected state change.
|
||||
if (!Utils.getState(aAccessible).contains(States.CHECKABLE) &&
|
||||
!Utils.getState(aAccessible).contains(States.SELECTABLE)) {
|
||||
this._contentScope.get().sendAsyncMessage("AccessFu:Present",
|
||||
Presentation.actionInvoked(aAccessible, "click"));
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ this.EventManager.prototype = {
|
|||
}
|
||||
|
||||
// Blur to document if new position is not explicitly focused.
|
||||
if (!Utils.getState(position).contains(States.FOCUSED)) {
|
||||
if (!position || !Utils.getState(position).contains(States.FOCUSED)) {
|
||||
aEvent.accessibleDocument.takeFocus();
|
||||
}
|
||||
|
||||
|
@ -163,25 +163,12 @@ this.EventManager.prototype = {
|
|||
}
|
||||
case Events.STATE_CHANGE:
|
||||
{
|
||||
let event = aEvent.QueryInterface(Ci.nsIAccessibleStateChangeEvent);
|
||||
let state = Utils.getState(event);
|
||||
const event = aEvent.QueryInterface(Ci.nsIAccessibleStateChangeEvent);
|
||||
const state = Utils.getState(event);
|
||||
if (state.contains(States.CHECKED)) {
|
||||
if (aEvent.accessible.role === Roles.SWITCH) {
|
||||
this.present(
|
||||
Presentation.
|
||||
actionInvoked(aEvent.accessible,
|
||||
event.isEnabled ? "on" : "off"));
|
||||
} else {
|
||||
this.present(
|
||||
Presentation.
|
||||
actionInvoked(aEvent.accessible,
|
||||
event.isEnabled ? "check" : "uncheck"));
|
||||
}
|
||||
this.present(Presentation.checked(aEvent.accessible));
|
||||
} else if (state.contains(States.SELECTED)) {
|
||||
this.present(
|
||||
Presentation.
|
||||
actionInvoked(aEvent.accessible,
|
||||
event.isEnabled ? "select" : "unselect"));
|
||||
this.present(Presentation.selected(aEvent.accessible));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -770,8 +770,12 @@ var UtteranceGenerator = { // jshint ignore:line
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add localized state information to output data.
|
||||
* Note: We do not expose checked and selected states, we let TalkBack do it for us
|
||||
* there. This is because we expose the checked information on the node info itself.
|
||||
*/
|
||||
_addState: function _addState(aOutput, aState, aRoleStr) {
|
||||
|
||||
if (aState.contains(States.UNAVAILABLE)) {
|
||||
aOutput.push({string: "stateUnavailable"});
|
||||
}
|
||||
|
@ -780,22 +784,6 @@ var UtteranceGenerator = { // jshint ignore:line
|
|||
aOutput.push({string: "stateReadonly"});
|
||||
}
|
||||
|
||||
// Don't utter this in Jelly Bean, we let TalkBack do it for us there.
|
||||
// This is because we expose the checked information on the node itself.
|
||||
// XXX: this means the checked state is always appended to the end,
|
||||
// regardless of the utterance ordering preference.
|
||||
if ((Utils.AndroidSdkVersion < 16 || Utils.MozBuildApp === "browser") &&
|
||||
aState.contains(States.CHECKABLE)) {
|
||||
let checked = aState.contains(States.CHECKED);
|
||||
let statetr;
|
||||
if (aRoleStr === "switch") {
|
||||
statetr = checked ? "stateOn" : "stateOff";
|
||||
} else {
|
||||
statetr = checked ? "stateChecked" : "stateNotChecked";
|
||||
}
|
||||
aOutput.push({string: statetr});
|
||||
}
|
||||
|
||||
if (aState.contains(States.PRESSED)) {
|
||||
aOutput.push({string: "statePressed"});
|
||||
}
|
||||
|
@ -817,10 +805,6 @@ var UtteranceGenerator = { // jshint ignore:line
|
|||
if (aState.contains(States.HASPOPUP)) {
|
||||
aOutput.push({string: "stateHasPopup"});
|
||||
}
|
||||
|
||||
if (aState.contains(States.SELECTED)) {
|
||||
aOutput.push({string: "stateSelected"});
|
||||
}
|
||||
},
|
||||
|
||||
_getListUtterance:
|
||||
|
|
|
@ -98,25 +98,38 @@ class AndroidPresentor {
|
|||
}
|
||||
|
||||
/**
|
||||
* An object's action has been invoked.
|
||||
* @param {nsIAccessible} aObject the object that has been invoked.
|
||||
* @param {string} aActionName the name of the action.
|
||||
* An object's check action has been invoked.
|
||||
* Note: Checkable objects use TalkBack's text derived from the event state, so we don't
|
||||
* populate the text here.
|
||||
* @param {nsIAccessible} aAccessible the object that has been invoked.
|
||||
*/
|
||||
actionInvoked(aObject, aActionName) {
|
||||
let state = Utils.getState(aObject);
|
||||
|
||||
// Checkable objects use TalkBack's text derived from the event state,
|
||||
// so we don't populate the text here.
|
||||
let text = null;
|
||||
if (!state.contains(States.CHECKABLE)) {
|
||||
text = Utils.localize(UtteranceGenerator.genForAction(aObject,
|
||||
aActionName));
|
||||
}
|
||||
|
||||
checked(aAccessible) {
|
||||
return [{
|
||||
eventType: AndroidEvents.VIEW_CLICKED,
|
||||
text,
|
||||
checked: state.contains(States.CHECKED)
|
||||
checked: Utils.getState(aAccessible).contains(States.CHECKED)
|
||||
}];
|
||||
}
|
||||
|
||||
/**
|
||||
* An object's select action has been invoked.
|
||||
* @param {nsIAccessible} aAccessible the object that has been invoked.
|
||||
*/
|
||||
selected(aAccessible) {
|
||||
return [{
|
||||
eventType: AndroidEvents.VIEW_CLICKED,
|
||||
selected: Utils.getState(aAccessible).contains(States.SELECTED)
|
||||
}];
|
||||
}
|
||||
|
||||
/**
|
||||
* An object's action has been invoked.
|
||||
* @param {nsIAccessible} aAccessible the object that has been invoked.
|
||||
* @param {string} aActionName the name of the action.
|
||||
*/
|
||||
actionInvoked(aAccessible, aActionName) {
|
||||
return [{
|
||||
eventType: AndroidEvents.VIEW_CLICKED,
|
||||
text: Utils.localize(UtteranceGenerator.genForAction(aAccessible, aActionName))
|
||||
}];
|
||||
}
|
||||
|
||||
|
@ -292,6 +305,7 @@ class AndroidPresentor {
|
|||
checkable: state.contains(States.CHECKABLE),
|
||||
checked: state.contains(States.CHECKED),
|
||||
editable: state.contains(States.EDITABLE),
|
||||
selected: state.contains(States.SELECTED)
|
||||
};
|
||||
|
||||
if (EDIT_TEXT_ROLES.has(aContext.accessible.role)) {
|
||||
|
|
|
@ -385,14 +385,6 @@ var Utils = { // jshint ignore:line
|
|||
|
||||
return parent.role === Roles.LISTITEM && parent.childCount > 1 &&
|
||||
aStaticText.indexInParent === 0;
|
||||
},
|
||||
|
||||
isActivatableOnFingerUp: function isActivatableOnFingerUp(aAccessible) {
|
||||
if (aAccessible.role === Roles.KEY) {
|
||||
return true;
|
||||
}
|
||||
let quick_activate = this.getAttributes(aAccessible)["moz-quick-activate"];
|
||||
return quick_activate && JSON.parse(quick_activate);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -51,6 +51,30 @@
|
|||
is(anode[prop], null, `anode.${prop} was assigned null`);
|
||||
}
|
||||
|
||||
function testDoubleProp(anode, prop) {
|
||||
is(anode[prop], null, `anode.${prop} should be null`);
|
||||
anode[prop] = Number.MAX_VALUE;
|
||||
is(anode[prop], Number.MAX_VALUE, `anode.${prop} was assigned ${Number.MAX_VALUE}`);
|
||||
anode[prop] = null;
|
||||
is(anode[prop], null, `anode.${prop} was assigned null`);
|
||||
}
|
||||
|
||||
function testIntProp(anode, prop) {
|
||||
is(anode[prop], null, `anode.${prop} should be null`);
|
||||
anode[prop] = -1;
|
||||
is(anode[prop], -1, `anode.${prop} was assigned -1`);
|
||||
anode[prop] = null;
|
||||
is(anode[prop], null, `anode.${prop} was assigned null`);
|
||||
}
|
||||
|
||||
function testUIntProp(anode, prop) {
|
||||
is(anode[prop], null, `anode.${prop} should be null`);
|
||||
anode[prop] = 4294967295;
|
||||
is(anode[prop], 4294967295, `anode.${prop} was assigned 4294967295`);
|
||||
anode[prop] = null;
|
||||
is(anode[prop], null, `anode.${prop} was assigned null`);
|
||||
}
|
||||
|
||||
// Check that the WebIDL is as expected.
|
||||
function checkImplementation(ifrDoc) {
|
||||
let anode = ifrDoc.accessibleNode;
|
||||
|
@ -118,6 +142,24 @@
|
|||
testBoolProp(anode, boolProp);
|
||||
}
|
||||
|
||||
const doubleProps = ["valueMax", "valueMin", "valueNow"];
|
||||
|
||||
for (const doubleProp of doubleProps) {
|
||||
testDoubleProp(anode, doubleProp);
|
||||
}
|
||||
|
||||
const intProps = ["colCount", "rowCount", "setSize"];
|
||||
|
||||
for (const intProp of intProps) {
|
||||
testIntProp(anode, intProp);
|
||||
}
|
||||
|
||||
const uintProps = ["colIndex", "colSpan", "level", "posInSet", "rowIndex", "rowSpan"];
|
||||
|
||||
for (const uintProp of uintProps) {
|
||||
testUIntProp(anode, uintProp);
|
||||
}
|
||||
|
||||
// Check if an AccessibleNode is properly cached.
|
||||
let node = ifrDoc.createElement("div");
|
||||
anode = node.accessibleNode;
|
||||
|
|
|
@ -368,6 +368,13 @@ class AccessFuContentTestRunner {
|
|||
`Got ${JSON.stringify(aEvent.text)}, expected ${JSON.stringify(aExpected)}.`);
|
||||
}
|
||||
|
||||
eventInfoMatches(aEvent, aExpected) {
|
||||
for (let key in aExpected) {
|
||||
is(aEvent[key], aExpected[key], `Event info matches for ${key}. ` +
|
||||
`Got ${aEvent[key]}, expected ${aExpected[key]}.`);
|
||||
}
|
||||
}
|
||||
|
||||
androidScrollForward() {
|
||||
this.sendMessage({
|
||||
name: "AccessFu:AndroidScroll",
|
||||
|
|
|
@ -44,12 +44,12 @@
|
|||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["many option", "not checked", "check button", "First item", "list", "1 item"]);
|
||||
runner.eventInfoMatches(evt, { checked: false });
|
||||
runner.eventTextMatches(evt, ["many option", "check button", "First item", "list", "1 item"]);
|
||||
|
||||
evt = await runner.activateCurrent(0,
|
||||
AndroidEvents.VIEW_CLICKED,
|
||||
AndroidEvents.VIEW_CLICKED);
|
||||
is(evt[1].checked, true, "checkbox is checked");
|
||||
is(evt.checked, true, "checkbox is checked");
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
|
@ -77,12 +77,12 @@
|
|||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Light", "off", "switch"]);
|
||||
runner.eventInfoMatches(evt, { checked: false });
|
||||
runner.eventTextMatches(evt, ["Light", "switch"]);
|
||||
|
||||
evt = await runner.activateCurrent(0,
|
||||
AndroidEvents.VIEW_CLICKED,
|
||||
AndroidEvents.VIEW_CLICKED);
|
||||
is(evt[1].checked, true, "checkbox is checked");
|
||||
is(evt.checked, true, "checkbox is checked");
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
|
@ -90,12 +90,12 @@
|
|||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Light", "on", "switch"]);
|
||||
runner.eventInfoMatches(evt, { checked: true });
|
||||
runner.eventTextMatches(evt, ["Light", "switch"]);
|
||||
|
||||
evt = await runner.activateCurrent(0,
|
||||
AndroidEvents.VIEW_CLICKED,
|
||||
AndroidEvents.VIEW_CLICKED);
|
||||
is(evt[1].checked, false, "checkbox is checked");
|
||||
is(evt.checked, false, "checkbox is checked");
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
|
@ -127,12 +127,12 @@
|
|||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["many option", "checked", "check button"]);
|
||||
runner.eventInfoMatches(evt, { checked: true });
|
||||
runner.eventTextMatches(evt, ["many option", "check button"]);
|
||||
|
||||
evt = await runner.activateCurrent(0,
|
||||
AndroidEvents.VIEW_CLICKED,
|
||||
AndroidEvents.VIEW_CLICKED);
|
||||
is(evt[1].checked, false, "checkbox is checked");
|
||||
is(evt.checked, false, "checkbox is checked");
|
||||
|
||||
evt = await runner.movePrevious("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
|
@ -180,7 +180,8 @@
|
|||
|
||||
evt = await runner.moveNext("FormElement",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["such app", "many option", "not checked", "check button", "First item", "list", "1 item"]);
|
||||
runner.eventInfoMatches(evt, { checked: false });
|
||||
runner.eventTextMatches(evt, ["such app", "many option", "check button", "First item", "list", "1 item"]);
|
||||
|
||||
evt = await runner.moveNext("FormElement",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
|
@ -192,7 +193,8 @@
|
|||
|
||||
evt = await runner.movePrevious("FormElement",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["many option", "not checked", "check button", "First item", "list", "1 item"]);
|
||||
runner.eventInfoMatches(evt, { checked: false });
|
||||
runner.eventTextMatches(evt, ["many option", "check button", "First item", "list", "1 item"]);
|
||||
|
||||
evt = await runner.movePrevious("FormElement",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
|
@ -214,7 +216,8 @@
|
|||
runner.eventTextMatches(evt, ["such app", "wow", "heading level 1"]);
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["many option", "not checked", "check button", "First item", "list", "1 item"]);
|
||||
runner.eventInfoMatches(evt, { checked: false });
|
||||
runner.eventTextMatches(evt, ["many option", "check button", "First item", "list", "1 item"]);
|
||||
|
||||
evt = await runner.moveFirst("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
|
@ -415,7 +418,8 @@
|
|||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
runner.eventTextMatches(evt, ["Light", "off", "switch"]);
|
||||
runner.eventInfoMatches(evt, { checked: false });
|
||||
runner.eventTextMatches(evt, ["Light", "switch"]);
|
||||
|
||||
evt = await runner.moveNext("Simple",
|
||||
AndroidEvents.VIEW_ACCESSIBILITY_FOCUSED);
|
||||
|
|
|
@ -253,11 +253,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
|
|||
}, {
|
||||
// Test selected tab
|
||||
accOrElmOrID: "tab1",
|
||||
expectedUtterance: [[{"string": "pagetablist"},
|
||||
{"string": "stateSelected"}, {"string": "pagetab"},
|
||||
expectedUtterance: [[{"string": "pagetablist"}, {"string": "pagetab"},
|
||||
{"string": "objItemOfN", "args": [1, 2]}, "Account"], ["Account",
|
||||
{"string": "stateSelected"}, {"string": "pagetab"},
|
||||
{"string": "objItemOfN", "args": [1, 2]}, {"string": "pagetablist"}]
|
||||
{"string": "pagetab"}, {"string": "objItemOfN", "args": [1, 2]},
|
||||
{"string": "pagetablist"}]
|
||||
],
|
||||
expectedBraille: [[{"string": "pagetabAbbr"},
|
||||
{"string": "objItemOfN", "args": [1, 2]}, "Account"], ["Account",
|
||||
|
@ -277,27 +276,19 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
|
|||
}, {
|
||||
// Landing on this label should mimic landing on the checkbox.
|
||||
accOrElmOrID: "label1",
|
||||
expectedUtterance: [[{"string": "stateNotChecked"},
|
||||
{"string": "checkbutton"}, "Orange"], ["Orange",
|
||||
{"string": "stateNotChecked"}, {"string": "checkbutton"}]],
|
||||
expectedBraille: [[{"string": "stateUncheckedAbbr"}, "Orange"],
|
||||
["Orange", {"string": "stateUncheckedAbbr"}]]
|
||||
expectedUtterance: [[{"string": "checkbutton"}, "Orange"], ["Orange",
|
||||
{"string": "checkbutton"}]],
|
||||
expectedBraille: [["Orange"], ["Orange"]]
|
||||
}, {
|
||||
// Here we get a top-level view of the form.
|
||||
accOrElmOrID: "form1",
|
||||
expectedUtterance: [[{"string": "label"},
|
||||
{"string": "stateNotChecked"}, {"string": "checkbutton"}, "Orange",
|
||||
"Orange", {"string": "stateNotChecked"}, {"string": "checkbutton"},
|
||||
"Blue", {"string": "label"}, "Blue"], ["Orange",
|
||||
{"string": "stateNotChecked"}, {"string": "checkbutton"}, "Orange",
|
||||
{"string": "label"}, "Blue", {"string": "stateNotChecked"},
|
||||
expectedUtterance: [[{"string": "label"}, {"string": "checkbutton"}, "Orange",
|
||||
"Orange", {"string": "checkbutton"}, "Blue", {"string": "label"}, "Blue"],
|
||||
["Orange", {"string": "checkbutton"}, "Orange", {"string": "label"}, "Blue",
|
||||
{"string": "checkbutton"}, "Blue", {"string": "label"}]],
|
||||
expectedBraille: [[{"string": "labelAbbr"},
|
||||
{"string": "stateUncheckedAbbr"}, "Orange", "Orange",
|
||||
{"string": "stateUncheckedAbbr"}, "Blue", {"string": "labelAbbr"},
|
||||
"Blue"], ["Orange", {"string": "stateUncheckedAbbr"}, "Orange",
|
||||
{"string": "labelAbbr"}, "Blue", {"string": "stateUncheckedAbbr"},
|
||||
"Blue", {"string": "labelAbbr"}]]
|
||||
expectedBraille: [[{"string": "labelAbbr"}, "Orange", "Orange", "Blue",
|
||||
{"string": "labelAbbr"}, "Blue"], ["Orange", "Orange",
|
||||
{"string": "labelAbbr"}, "Blue", "Blue", {"string": "labelAbbr"}]]
|
||||
}, {
|
||||
// This is a non-nesting label.
|
||||
accOrElmOrID: "label2",
|
||||
|
@ -308,19 +299,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
|
|||
}, {
|
||||
// This is a distinct control.
|
||||
accOrElmOrID: "input2",
|
||||
expectedUtterance: [[{"string": "stateNotChecked"},
|
||||
{"string": "checkbutton"}, "Blue"], ["Blue",
|
||||
{"string": "stateNotChecked"}, {"string": "checkbutton"}]],
|
||||
expectedBraille: [[{"string": "stateUncheckedAbbr"}, "Blue"], ["Blue",
|
||||
{"string": "stateUncheckedAbbr"}]]
|
||||
expectedUtterance: [[ {"string": "checkbutton"}, "Blue"],
|
||||
["Blue", {"string": "checkbutton"}]],
|
||||
expectedBraille: [["Blue"], ["Blue"]]
|
||||
}, {
|
||||
// This is a nested control.
|
||||
accOrElmOrID: "input1",
|
||||
expectedUtterance: [[{"string": "stateNotChecked"},
|
||||
{"string": "checkbutton"}, "Orange"], ["Orange",
|
||||
{"string": "stateNotChecked"}, {"string": "checkbutton"}]],
|
||||
expectedBraille: [[{"string": "stateUncheckedAbbr"}, "Orange"],
|
||||
["Orange", {"string": "stateUncheckedAbbr"}]]
|
||||
expectedUtterance: [[ {"string": "checkbutton"}, "Orange"], ["Orange",
|
||||
{"string": "checkbutton"}]],
|
||||
expectedBraille: [["Orange"], ["Orange"]]
|
||||
}, {
|
||||
// Landing on this label should mimic landing on the entry.
|
||||
accOrElmOrID: "label3",
|
||||
|
@ -350,30 +337,20 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
|
|||
["Secret Password", {"string": "passwordtextAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "input5",
|
||||
expectedUtterance: [[{"string": "stateChecked"},
|
||||
{"string": "checkbutton"}, "Boring label"], ["Boring label",
|
||||
{"string": "stateChecked"}, {"string": "checkbutton"}]],
|
||||
expectedBraille: [[{"string": "stateCheckedAbbr"}, "Boring label"],
|
||||
["Boring label", {"string": "stateCheckedAbbr"}]]
|
||||
expectedUtterance: [[{"string": "checkbutton"}, "Boring label"],
|
||||
["Boring label", {"string": "checkbutton"}]],
|
||||
expectedBraille: [["Boring label"], ["Boring label"]]
|
||||
}, {
|
||||
accOrElmOrID: "radio_unselected",
|
||||
expectedUtterance: [[{"string": "stateNotChecked"},
|
||||
{"string": "radiobutton"}, "any old radio button"],
|
||||
["any old radio button", {"string": "stateNotChecked"},
|
||||
{"string": "radiobutton"}]
|
||||
expectedUtterance: [[{"string": "radiobutton"}, "any old radio button"],
|
||||
["any old radio button", {"string": "radiobutton"}]
|
||||
],
|
||||
expectedBraille: [
|
||||
[{"string": "stateUncheckedAbbr"}, "any old radio button"],
|
||||
["any old radio button", {"string": "stateUncheckedAbbr"}]]
|
||||
expectedBraille: [["any old radio button"], ["any old radio button"]]
|
||||
}, {
|
||||
accOrElmOrID: "radio_selected",
|
||||
expectedUtterance: [[{"string": "stateChecked"},
|
||||
{"string": "radiobutton"}, "a unique radio button"],
|
||||
["a unique radio button", {"string": "stateChecked"},
|
||||
{"string": "radiobutton"}]],
|
||||
expectedBraille: [
|
||||
[{"string": "stateCheckedAbbr"}, "a unique radio button"],
|
||||
["a unique radio button", {"string": "stateCheckedAbbr"}]]
|
||||
expectedUtterance: [[{"string": "radiobutton"}, "a unique radio button"],
|
||||
["a unique radio button", {"string": "radiobutton"}]],
|
||||
expectedBraille: [["a unique radio button"], ["a unique radio button"]]
|
||||
}, {
|
||||
accOrElmOrID: "togglebutton_notpressed",
|
||||
expectedUtterance: [[{"string": "togglebutton"}, "I am not pressed"],
|
||||
|
@ -437,8 +414,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
|
|||
}, {
|
||||
accOrElmOrID: "gridcell3",
|
||||
oldAccOrElmOrID: "grid",
|
||||
expectedUtterance: [[{"string": "stateSelected"}, "5"],
|
||||
["5", {"string": "stateSelected"}]],
|
||||
expectedUtterance: [["5"], ["5"]],
|
||||
expectedBraille: [["5"], ["5"]],
|
||||
}, {
|
||||
accOrElmOrID: "frequency",
|
||||
|
@ -451,9 +427,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
|
|||
}, {
|
||||
accOrElmOrID: "selected-combobox-option",
|
||||
oldAccOrElmOrID: "frequency",
|
||||
expectedUtterance: [[{"string": "stateSelected"},
|
||||
{"string": "comboboxoption"}, "15 min"], ["15 min",
|
||||
{"string": "stateSelected"}, {"string": "comboboxoption"}]],
|
||||
expectedUtterance: [[{"string": "comboboxoption"}, "15 min"],
|
||||
["15 min", {"string": "comboboxoption"}]],
|
||||
expectedBraille: [[{"string": "comboboxoptionAbbr"}, "15 min"], [
|
||||
"15 min", {"string": "comboboxoptionAbbr"}]]
|
||||
}, {
|
||||
|
@ -484,19 +459,14 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
|
|||
expectedBraille: [["Last sync: 30min ago"], ["Last sync: 30min ago"]]
|
||||
}, {
|
||||
accOrElmOrID: "switch-1",
|
||||
expectedUtterance: [[{"string": "stateOn"}, {"string": "switch"},
|
||||
"Simple switch"], ["Simple switch", {"string": "stateOn"},
|
||||
{"string": "switch"}]],
|
||||
expectedBraille: [[{"string": "stateCheckedAbbr"}, "Simple switch"],
|
||||
["Simple switch", {"string": "stateCheckedAbbr"}]]
|
||||
expectedUtterance: [[{"string": "switch"}, "Simple switch"],
|
||||
["Simple switch", {"string": "switch"}]],
|
||||
expectedBraille: [["Simple switch"], ["Simple switch"]]
|
||||
}, {
|
||||
accOrElmOrID: "switch-2",
|
||||
expectedUtterance: [[{"string": "stateOff"},
|
||||
{"string": "switch"}, "Another switch"], ["Another switch",
|
||||
{"string": "stateOff"}, {"string": "switch"}]],
|
||||
expectedBraille: [
|
||||
[{"string": "stateUncheckedAbbr"}, "Another switch"],
|
||||
["Another switch", {"string": "stateUncheckedAbbr"}]]
|
||||
expectedUtterance: [[{"string": "switch"}, "Another switch"],
|
||||
["Another switch", {"string": "switch"}]],
|
||||
expectedBraille: [["Another switch"], ["Another switch"]]
|
||||
}];
|
||||
|
||||
// Test all possible utterance order preference values.
|
||||
|
|
|
@ -81,32 +81,6 @@ ShowError(DWORD aError = ::GetLastError())
|
|||
::LocalFree(rawMsgBuf);
|
||||
}
|
||||
|
||||
static bool
|
||||
SetArgv0ToFullBinaryPath(wchar_t* aArgv[])
|
||||
{
|
||||
DWORD bufLen = MAX_PATH;
|
||||
mozilla::UniquePtr<wchar_t[]> buf;
|
||||
|
||||
while (true) {
|
||||
buf = mozilla::MakeUnique<wchar_t[]>(bufLen);
|
||||
DWORD retLen = ::GetModuleFileNameW(nullptr, buf.get(), bufLen);
|
||||
if (!retLen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (retLen == bufLen && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||||
bufLen *= 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// We intentionally leak buf into argv[0]
|
||||
aArgv[0] = buf.release();
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
// Eventually we want to be able to set a build config flag such that, when set,
|
||||
|
|
|
@ -132,7 +132,6 @@ var whitelist = [
|
|||
{file: "chrome://marionette/content/test_anonymous_content.xul"},
|
||||
{file: "chrome://marionette/content/test_dialog.properties"},
|
||||
{file: "chrome://marionette/content/test_dialog.xul"},
|
||||
{file: "chrome://marionette/content/PerTestCoverageUtils.jsm"},
|
||||
// Bug 1348533
|
||||
{file: "chrome://mozapps/skin/downloads/buttons.png", platforms: ["macosx"]},
|
||||
{file: "chrome://mozapps/skin/downloads/downloadButtons.png", platforms: ["linux", "win"]},
|
||||
|
@ -203,6 +202,10 @@ if (!isDevtools) {
|
|||
|
||||
}
|
||||
|
||||
if (AppConstants.MOZ_CODE_COVERAGE) {
|
||||
whitelist.add("chrome://marionette/content/PerTestCoverageUtils.jsm");
|
||||
}
|
||||
|
||||
const gInterestingCategories = new Set([
|
||||
"agent-style-sheets", "addon-provider-module", "webextension-modules",
|
||||
"webextension-scripts", "webextension-schemas", "webextension-scripts-addon",
|
||||
|
|
|
@ -67,6 +67,15 @@ let whitelist = [
|
|||
isFromDevTools: true},
|
||||
];
|
||||
|
||||
if (!Services.prefs.getBoolPref("layout.css.xul-box-display-values.content.enabled")) {
|
||||
// These are UA sheets which use non-content-exposed `display` values.
|
||||
whitelist.push({
|
||||
sourceName: /(skin\/shared\/Heartbeat|((?:res|gre-resources)\/(ua|html)))\.css$/i,
|
||||
errorMessage: /Error in parsing value for .*\bdisplay\b/i,
|
||||
isFromDevTools: false
|
||||
});
|
||||
}
|
||||
|
||||
if (!Services.prefs.getBoolPref("full-screen-api.unprefix.enabled")) {
|
||||
whitelist.push({
|
||||
sourceName: /(?:res|gre-resources)\/(ua|html)\.css$/i,
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
</columns>
|
||||
<rows>
|
||||
<row flex="1">
|
||||
<richlistbox id="activeLanguages" flex="1" height="200"
|
||||
<richlistbox id="activeLanguages" flex="1"
|
||||
seltype="multiple"
|
||||
onselect="gLanguagesDialog.onLanguageSelect();"/>
|
||||
<vbox>
|
||||
|
|
|
@ -209,6 +209,10 @@ button > hbox > label {
|
|||
font-size: 90%;
|
||||
}
|
||||
|
||||
#activeLanguages {
|
||||
height: 16em;
|
||||
}
|
||||
|
||||
#activeLanguages > richlistitem {
|
||||
padding: 0.3em;
|
||||
}
|
||||
|
|
|
@ -662,7 +662,7 @@ private:
|
|||
MediaRawData* mTarget;
|
||||
};
|
||||
|
||||
class MediaRawData : public MediaData
|
||||
class MediaRawData final : public MediaData
|
||||
{
|
||||
public:
|
||||
MediaRawData();
|
||||
|
@ -700,11 +700,11 @@ public:
|
|||
RefPtr<TrackInfoSharedPtr> mTrackInfo;
|
||||
|
||||
// Return a deep copy or nullptr if out of memory.
|
||||
virtual already_AddRefed<MediaRawData> Clone() const;
|
||||
already_AddRefed<MediaRawData> Clone() const;
|
||||
// Create a MediaRawDataWriter for this MediaRawData. The writer is not
|
||||
// thread-safe.
|
||||
virtual UniquePtr<MediaRawDataWriter> CreateWriter();
|
||||
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
|
||||
UniquePtr<MediaRawDataWriter> CreateWriter();
|
||||
size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
protected:
|
||||
~MediaRawData();
|
||||
|
|
|
@ -715,6 +715,12 @@ IsVP9CodecString(const nsAString& aCodec)
|
|||
ExtractVPXCodecDetails(aCodec, profile, level, bitDepth));
|
||||
}
|
||||
|
||||
bool
|
||||
IsAV1CodecString(const nsAString& aCodec)
|
||||
{
|
||||
return aCodec.EqualsLiteral("av1"); // AV1
|
||||
}
|
||||
|
||||
UniquePtr<TrackInfo>
|
||||
CreateTrackInfoWithMIMEType(const nsACString& aCodecMIMEType)
|
||||
{
|
||||
|
|
|
@ -361,6 +361,9 @@ IsVP8CodecString(const nsAString& aCodec);
|
|||
bool
|
||||
IsVP9CodecString(const nsAString& aCodec);
|
||||
|
||||
bool
|
||||
IsAV1CodecString(const nsAString& aCodec);
|
||||
|
||||
// Try and create a TrackInfo with a given codec MIME type.
|
||||
UniquePtr<TrackInfo>
|
||||
CreateTrackInfoWithMIMEType(const nsACString& aCodecMIMEType);
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
|
||||
#include "MediaSource.h"
|
||||
|
||||
#if MOZ_AV1
|
||||
#include "AOMDecoder.h"
|
||||
#endif
|
||||
#include "AsyncEventRunner.h"
|
||||
#include "DecoderTraits.h"
|
||||
#include "Benchmark.h"
|
||||
|
@ -135,9 +132,9 @@ MediaSource::IsTypeSupported(const nsAString& aType, DecoderDoctorDiagnostics* a
|
|||
containerType->ExtendedType().Codecs().Contains(
|
||||
NS_LITERAL_STRING("vp8")) ||
|
||||
#ifdef MOZ_AV1
|
||||
// FIXME: Temporary comparison with the full codecs attribute.
|
||||
// See bug 1377015.
|
||||
AOMDecoder::IsSupportedCodec(containerType->ExtendedType().Codecs().AsString()) ||
|
||||
(StaticPrefs::MediaAv1Enabled() &&
|
||||
IsAV1CodecString(
|
||||
containerType->ExtendedType().Codecs().AsString())) ||
|
||||
#endif
|
||||
IsWebMForced(aDiagnostics))) {
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
|
|
|
@ -340,13 +340,6 @@ AOMDecoder::IsAV1(const nsACString& aMimeType)
|
|||
return aMimeType.EqualsLiteral("video/av1");
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
AOMDecoder::IsSupportedCodec(const nsAString& aCodecType)
|
||||
{
|
||||
return aCodecType.EqualsLiteral("av1");
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
AOMDecoder::IsKeyframe(Span<const uint8_t> aBuffer) {
|
||||
|
|
|
@ -37,9 +37,6 @@ public:
|
|||
// by our demuxers to identify AV1 streams.
|
||||
static bool IsAV1(const nsACString& aMimeType);
|
||||
|
||||
// Return true if aCodecType is a supported codec description.
|
||||
static bool IsSupportedCodec(const nsAString& aCodecType);
|
||||
|
||||
// Return true if a sample is a keyframe.
|
||||
static bool IsKeyframe(Span<const uint8_t> aBuffer);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
function check_webm(v, enabled) {
|
||||
async function check_webm(v, enabled) {
|
||||
function check(type, expected) {
|
||||
is(v.canPlayType(type), enabled ? expected : "", type);
|
||||
is(v.canPlayType(type), enabled ? expected : "", type + "='" + expected + "'");
|
||||
}
|
||||
|
||||
// WebM types
|
||||
|
@ -26,4 +26,31 @@ function check_webm(v, enabled) {
|
|||
check("video/webm; codecs=xyz", "");
|
||||
check("video/webm; codecs=xyz,vorbis", "");
|
||||
check("video/webm; codecs=vorbis,xyz", "");
|
||||
|
||||
function getPref(name) {
|
||||
var pref = false;
|
||||
try {
|
||||
pref = SpecialPowers.getBoolPref(name);
|
||||
} catch(ex) { }
|
||||
return pref;
|
||||
}
|
||||
|
||||
function isWindows32() {
|
||||
return navigator.userAgent.includes("Windows") &&
|
||||
!navigator.userAgent.includes("Win64");
|
||||
}
|
||||
|
||||
function isAndroid() {
|
||||
return navigator.userAgent.includes("Android");
|
||||
}
|
||||
|
||||
const haveAv1 = getPref("media.av1.enabled");
|
||||
check("video/webm; codecs=\"av1\"", haveAv1 ? "probably" : "");
|
||||
|
||||
await SpecialPowers.pushPrefEnv({"set": [["media.av1.enabled", true]]});
|
||||
// AV1 is disabled on Windows 32 bits (bug 1475564) and Android (bug 1368843)
|
||||
check("video/webm; codecs=\"av1\"", (isWindows32() || isAndroid()) ? "" : "probably");
|
||||
|
||||
await SpecialPowers.pushPrefEnv({"set": [["media.av1.enabled", false]]});
|
||||
check("video/webm; codecs=\"av1\"", "");
|
||||
}
|
||||
|
|
|
@ -96,6 +96,9 @@ function check_mp4(v, enabled) {
|
|||
check(codec, "probably");
|
||||
ok(MediaSource.isTypeSupported(codec), "VP9 in MP4 should be supported in MSE");
|
||||
});
|
||||
|
||||
// AV1 (disabled until bug 1417050 is fixed)
|
||||
check("video/mp4; codecs=\"av1\"", "");
|
||||
}
|
||||
|
||||
function check_mp3(v, enabled) {
|
||||
|
|
|
@ -21,8 +21,18 @@ a Bug 566245</a>
|
|||
<pre id="test">
|
||||
<script src="can_play_type_webm.js"></script>
|
||||
<script>
|
||||
check_webm(document.getElementById('v'), true);
|
||||
mediaTestCleanup();
|
||||
async function runTest() {
|
||||
try {
|
||||
await check_webm(document.getElementById('v'), true);
|
||||
mediaTestCleanup();
|
||||
} catch (e) {
|
||||
info("Exception " + e.message);
|
||||
ok(false, "Threw exception " + e.message);
|
||||
}
|
||||
SimpleTest.finish();
|
||||
}
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(runTest);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
|
|
@ -65,7 +65,7 @@ WebMDecoder::GetTracksInfo(const MediaContainerType& aType, MediaResult& aError)
|
|||
}
|
||||
}
|
||||
#ifdef MOZ_AV1
|
||||
if (AOMDecoder::IsSupportedCodec(codec)) {
|
||||
if (StaticPrefs::MediaAv1Enabled() && IsAV1CodecString(codec)) {
|
||||
tracks.AppendElement(
|
||||
CreateTrackInfoWithMIMETypeAndContainerTypeExtraParameters(
|
||||
NS_LITERAL_CSTRING("video/av1"), aType));
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
function doXHR(uri) {
|
||||
try {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", uri);
|
||||
xhr.send();
|
||||
} catch(ex) {}
|
||||
}
|
||||
|
||||
var sameBase = "http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=";
|
||||
var crossBase = "http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=";
|
||||
|
||||
onmessage = (e) => {
|
||||
for (base of [sameBase, crossBase]) {
|
||||
var prefix;
|
||||
var suffix;
|
||||
if (e.data.inherited == "parent") {
|
||||
//Worker inherits CSP from parent worker
|
||||
prefix = base + "worker_child_inherited_parent_";
|
||||
suffix = base == sameBase ? "_good" : "_bad";
|
||||
} else if (e.data.inherited == "document") {
|
||||
//Worker inherits CSP from owner document -> parent worker -> subworker
|
||||
prefix = base + "worker_child_inherited_document_";
|
||||
suffix = base == sameBase ? "_good" : "_bad";
|
||||
} else {
|
||||
// Worker delivers CSP from HTTP header
|
||||
prefix = base + "worker_child_";
|
||||
suffix = base == sameBase ? "_same_bad" : "_cross_bad";
|
||||
}
|
||||
|
||||
doXHR(prefix + "xhr" + suffix);
|
||||
// Fetch is likely failed in subworker
|
||||
// See Bug 1273070 - Failed to fetch in subworker
|
||||
// Enable fetch test after the bug is fixed
|
||||
// fetch(prefix + "xhr" + suffix);
|
||||
try {
|
||||
importScripts(prefix + "script" + suffix);
|
||||
} catch(ex) {}
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
Content-Security-Policy: default-src 'none'
|
|
@ -1,12 +1,8 @@
|
|||
function doXHR(uri, callback) {
|
||||
function doXHR(uri) {
|
||||
try {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", uri);
|
||||
xhr.responseType = "blob";
|
||||
xhr.send();
|
||||
xhr.onload = function () {
|
||||
if (callback) callback(xhr.response);
|
||||
}
|
||||
} catch(ex) {}
|
||||
}
|
||||
|
||||
|
@ -16,36 +12,3 @@ fetch("http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=fe
|
|||
fetch("http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=fetch_bad");
|
||||
navigator.sendBeacon("http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=beacon_good");
|
||||
navigator.sendBeacon("http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=beacon_bad");
|
||||
|
||||
var topWorkerBlob;
|
||||
var nestedWorkerBlob;
|
||||
|
||||
doXHR("file_main_worker.js", function (topResponse) {
|
||||
topWorkerBlob = URL.createObjectURL(topResponse);
|
||||
doXHR("file_child_worker.js", function (response) {
|
||||
nestedWorkerBlob = URL.createObjectURL(response);
|
||||
runWorker();
|
||||
});
|
||||
});
|
||||
|
||||
function runWorker() {
|
||||
// Top level worker, no subworker
|
||||
// Worker does not inherit CSP from owner document
|
||||
new Worker("file_main_worker.js").postMessage({inherited : "none"});
|
||||
|
||||
// Top level worker, no subworker
|
||||
// Worker inherits CSP from owner document
|
||||
new Worker(topWorkerBlob).postMessage({inherited : "document"});
|
||||
|
||||
// Subworker
|
||||
// Worker does not inherit CSP from parent worker
|
||||
new Worker("file_main_worker.js").postMessage({inherited : "none", nested : nestedWorkerBlob});
|
||||
|
||||
// Subworker
|
||||
// Worker inherits CSP from parent worker
|
||||
new Worker("file_main_worker.js").postMessage({inherited : "parent", nested : nestedWorkerBlob});
|
||||
|
||||
// Subworker
|
||||
// Worker inherits CSP from owner document -> parent worker -> subworker
|
||||
new Worker(topWorkerBlob).postMessage({inherited : "document", nested : nestedWorkerBlob});
|
||||
}
|
||||
|
|
|
@ -1,48 +0,0 @@
|
|||
function doXHR(uri) {
|
||||
try {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", uri);
|
||||
xhr.send();
|
||||
} catch(ex) {}
|
||||
}
|
||||
|
||||
var sameBase = "http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs?testid=";
|
||||
var crossBase = "http://example.com/tests/dom/security/test/csp/file_CSP.sjs?testid=";
|
||||
|
||||
onmessage = (e) => {
|
||||
// Tests of nested worker
|
||||
if (e.data.nested) {
|
||||
if (e.data.inherited != "none") {
|
||||
// Worker inherits CSP
|
||||
new Worker(e.data.nested).postMessage({inherited : e.data.inherited});
|
||||
}
|
||||
else {
|
||||
// Worker does not inherit CSP
|
||||
new Worker("file_child_worker.js").postMessage({inherited : e.data.inherited});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//Tests of top level worker
|
||||
for (base of [sameBase, crossBase]) {
|
||||
var prefix;
|
||||
var suffix;
|
||||
if (e.data.inherited != "none") {
|
||||
// Top worker inherits CSP from owner document
|
||||
prefix = base + "worker_inherited_";
|
||||
suffix = base == sameBase ? "_good" : "_bad";
|
||||
}
|
||||
else {
|
||||
// Top worker delivers CSP from HTTP header
|
||||
prefix = base + "worker_";
|
||||
suffix = base == sameBase ? "_same_bad" : "_cross_good";
|
||||
}
|
||||
|
||||
doXHR(prefix + "xhr" + suffix);
|
||||
fetch(prefix + "fetch" + suffix);
|
||||
try {
|
||||
if (e.data.inherited == "none") suffix = base == sameBase ? "_same_good" : "_cross_bad";
|
||||
importScripts(prefix + "script" + suffix);
|
||||
} catch(ex) {}
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
Content-Security-Policy: default-src 'self' blob: ; connect-src http://example.com
|
|
@ -0,0 +1,439 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1475849: Test CSP worker inheritance</title>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="worker_helper.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript">
|
||||
const SJS = "worker.sjs";
|
||||
const SAME_BASE = "http://mochi.test:8888/tests/dom/security/test/csp/file_CSP.sjs";
|
||||
const CROSS_BASE = "http://example.com/tests/dom/security/test/csp/file_CSP.sjs";
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
/* test data format :
|
||||
{
|
||||
id: test id, short description of test,
|
||||
base: URL of the request in worker,
|
||||
action: type of request in worker (fetch, xhr, importscript)
|
||||
type: how do we create the worker, from URL or Blob,
|
||||
csp: csp of worker,
|
||||
child: how do we create the child worker, from URL or Blob,
|
||||
childCsp: csp of child worker
|
||||
expectedBlock: result when CSP policy, true or false
|
||||
}
|
||||
*/
|
||||
|
||||
// Document's CSP is defined in main_csp_worker.html^headers^
|
||||
// Content-Security-Policy: default-src 'self' blob: 'unsafe-inline'
|
||||
var tests = [
|
||||
// create new Worker(url), worker's csp should be deliveried from header.
|
||||
// csp should be: default-src 'self' blob: ; connect-src CROSS_BASE
|
||||
{
|
||||
id: "worker_url_fetch_same_bad",
|
||||
base: SAME_BASE,
|
||||
action: "fetch",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob: ; connect-src http://example.com",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_url_importScripts_same_good",
|
||||
base: SAME_BASE,
|
||||
action: "importScripts",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob: ; connect-src http://example.com",
|
||||
expectBlocked: false
|
||||
},
|
||||
{
|
||||
id: "worker_url_xhr_same_bad",
|
||||
base: SAME_BASE,
|
||||
action: "xhr",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob: ; connect-src http://example.com",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_url_fetch_cross_good",
|
||||
base: CROSS_BASE,
|
||||
action: "fetch",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob: ; connect-src http://example.com",
|
||||
expectBlocked: false
|
||||
},
|
||||
{
|
||||
id: "worker_url_importScripts_cross_bad",
|
||||
base: CROSS_BASE,
|
||||
action: "importScripts",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob: ; connect-src http://example.com",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_url_xhr_cross_good",
|
||||
base: CROSS_BASE,
|
||||
action: "xhr",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob: ; connect-src http://example.com",
|
||||
expectBlocked: false
|
||||
},
|
||||
|
||||
// create new Worker(blob:), worker's csp should be inherited from
|
||||
// document.
|
||||
// csp should be : default-src 'self' blob: 'unsafe-inline'
|
||||
{
|
||||
id: "worker_blob_fetch_same_good",
|
||||
base: SAME_BASE,
|
||||
action: "fetch",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob: ; connect-src http://example.com",
|
||||
expectBlocked: false
|
||||
},
|
||||
{
|
||||
id: "worker_blob_xhr_same_good",
|
||||
base: SAME_BASE,
|
||||
action: "xhr",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob: ; connect-src http://example.com",
|
||||
expectBlocked: false
|
||||
},
|
||||
{
|
||||
id: "worker_blob_importScripts_same_good",
|
||||
base: SAME_BASE,
|
||||
action: "importScripts",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob: ; connect-src http://example.com",
|
||||
expectBlocked: false
|
||||
},
|
||||
{
|
||||
id: "worker_blob_fetch_cross_bad",
|
||||
base: CROSS_BASE,
|
||||
action: "fetch",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob: ; connect-src http://example.com",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_blob_xhr_cross_bad",
|
||||
base: CROSS_BASE,
|
||||
action: "xhr",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob: ; connect-src http://example.com",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_blob_importScripts_cross_bad",
|
||||
base: CROSS_BASE,
|
||||
action: "importScripts",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob: ; connect-src http://example.com",
|
||||
expectBlocked: true
|
||||
},
|
||||
|
||||
// create parent worker from url, child worker from blob,
|
||||
// Parent delivery csp then propagate to child
|
||||
// csp should be: "default-src 'self' blob: ; connect-src 'self' http://example.com",
|
||||
{
|
||||
id: "worker_url_child_blob_fetch_same_good",
|
||||
base: SAME_BASE,
|
||||
action: "fetch",
|
||||
child: "blob",
|
||||
childCsp: "default-src 'none'",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob: ; connect-src 'self' http://example.com",
|
||||
expectBlocked: false
|
||||
},
|
||||
{
|
||||
id: "worker_url_child_blob_importScripts_same_good",
|
||||
base: SAME_BASE,
|
||||
action: "importScripts",
|
||||
child: "blob",
|
||||
childCsp: "default-src 'none'",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob: ; connect-src 'self' http://example.com",
|
||||
expectBlocked: false
|
||||
},
|
||||
{
|
||||
id: "worker_url_child_blob_xhr_same_good",
|
||||
base: SAME_BASE,
|
||||
child: "blob",
|
||||
childCsp: "default-src 'none'",
|
||||
action: "xhr",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob: ; connect-src 'self' http://example.com",
|
||||
expectBlocked: false
|
||||
},
|
||||
{
|
||||
id: "worker_url_child_blob_fetch_cross_good",
|
||||
base: CROSS_BASE,
|
||||
action: "fetch",
|
||||
child: "blob",
|
||||
childCsp: "default-src 'none'",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob: ; connect-src 'self' http://example.com",
|
||||
expectBlocked: false
|
||||
},
|
||||
{
|
||||
id: "worker_url_child_blob_importScripts_cross_bad",
|
||||
base: CROSS_BASE,
|
||||
action: "importScripts",
|
||||
child: "blob",
|
||||
childCsp: "default-src 'none'",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob: ; connect-src 'self' http://example.com",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_url_child_blob_xhr_cross_godd",
|
||||
base: CROSS_BASE,
|
||||
child: "blob",
|
||||
childCsp: "default-src 'none'",
|
||||
action: "xhr",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob: ; connect-src 'self' http://example.com",
|
||||
expectBlocked: false
|
||||
},
|
||||
|
||||
|
||||
// create parent worker from blob, child worker from blob,
|
||||
// Csp: document->parent->child
|
||||
// csp should be : default-src 'self' blob: 'unsafe-inline'
|
||||
{
|
||||
id: "worker_blob_child_blob_fetch_same_good",
|
||||
base: SAME_BASE,
|
||||
child: "blob",
|
||||
childCsp: "default-src 'none'",
|
||||
action: "fetch",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: false
|
||||
},
|
||||
{
|
||||
id: "worker_blob_child_blob_xhr_same_good",
|
||||
base: SAME_BASE,
|
||||
child: "blob",
|
||||
childCsp: "default-src 'none'",
|
||||
action: "xhr",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: false
|
||||
},
|
||||
{
|
||||
id: "worker_blob_child_blob_importScripts_same_good",
|
||||
base: SAME_BASE,
|
||||
action: "importScripts",
|
||||
child: "blob",
|
||||
childCsp: "default-src 'none'",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: false
|
||||
},
|
||||
{
|
||||
id: "worker_blob_child_blob_fetch_cross_bad",
|
||||
base: CROSS_BASE,
|
||||
child: "blob",
|
||||
childCsp: "default-src 'none'",
|
||||
action: "fetch",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_blob_child_blob_xhr_cross_bad",
|
||||
base: CROSS_BASE,
|
||||
child: "blob",
|
||||
childCsp: "default-src 'none'",
|
||||
action: "xhr",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_blob_child_blob_importScripts_cross_bad",
|
||||
base: CROSS_BASE,
|
||||
action: "importScripts",
|
||||
child: "blob",
|
||||
childCsp: "default-src 'none'",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
|
||||
// create parent worker from url, child worker from url,
|
||||
// child delivery csp from header
|
||||
// csp should be : default-src 'none'
|
||||
{
|
||||
id: "worker_url_child_url_fetch_cross_bad",
|
||||
base: CROSS_BASE,
|
||||
action: "fetch",
|
||||
child: "url",
|
||||
childCsp: "default-src 'none'",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_url_child_url_xhr_cross_bad",
|
||||
base: CROSS_BASE,
|
||||
child: "url",
|
||||
childCsp: "default-src 'none'",
|
||||
action: "xhr",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_url_child_url_importScripts_cross_bad",
|
||||
base: CROSS_BASE,
|
||||
action: "importScripts",
|
||||
child: "url",
|
||||
childCsp: "default-src 'none'",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_url_child_url_fetch_same_bad",
|
||||
base: SAME_BASE,
|
||||
action: "fetch",
|
||||
child: "url",
|
||||
childCsp: "default-src 'none'",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_url_child_url_xhr_same_bad",
|
||||
base: SAME_BASE,
|
||||
child: "url",
|
||||
childCsp: "default-src 'none'",
|
||||
action: "xhr",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_url_child_url_importScripts_same_bad",
|
||||
base: SAME_BASE,
|
||||
action: "importScripts",
|
||||
child: "url",
|
||||
childCsp: "default-src 'none'",
|
||||
type: "url",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
|
||||
// create parent worker from blob, child worker from url,
|
||||
// child delivery csp from header
|
||||
// csp should be : default-src 'none'
|
||||
{
|
||||
id: "worker_blob_child_url_fetch_cross_bad",
|
||||
base: CROSS_BASE,
|
||||
child: "url",
|
||||
childCsp: "default-src 'none'",
|
||||
action: "fetch",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_blob_child_url_xhr_cross_bad",
|
||||
base: CROSS_BASE,
|
||||
child: "url",
|
||||
childCsp: "default-src 'none'",
|
||||
action: "xhr",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_blob_child_url_importScripts_cross_bad",
|
||||
base: CROSS_BASE,
|
||||
action: "importScripts",
|
||||
child: "url",
|
||||
childCsp: "default-src 'none'",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_blob_child_url_fetch_same_bad",
|
||||
base: SAME_BASE,
|
||||
child: "url",
|
||||
childCsp: "default-src 'none'",
|
||||
action: "fetch",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_blob_child_url_xhr_same_bad",
|
||||
base: SAME_BASE,
|
||||
child: "url",
|
||||
childCsp: "default-src 'none'",
|
||||
action: "xhr",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
{
|
||||
id: "worker_blob_child_url_importScripts_same_bad",
|
||||
base: SAME_BASE,
|
||||
action: "importScripts",
|
||||
child: "url",
|
||||
childCsp: "default-src 'none'",
|
||||
type: "blob",
|
||||
csp: "default-src 'self' blob:",
|
||||
expectBlocked: true
|
||||
},
|
||||
|
||||
|
||||
];
|
||||
|
||||
async function runWorkerTest(data) {
|
||||
let src = SJS;
|
||||
src += "?base=" + escape(data.base);
|
||||
src += "&action=" + escape(data.action);
|
||||
src += "&csp=" + escape(data.csp);
|
||||
src += "&id=" + escape(data.id);
|
||||
|
||||
if (data.child) {
|
||||
src += "&child=" + escape(data.child);
|
||||
}
|
||||
|
||||
if (data.childCsp) {
|
||||
src += "&childCsp=" + escape(data.childCsp);
|
||||
}
|
||||
|
||||
switch (data.type) {
|
||||
case "url":
|
||||
new Worker(src);
|
||||
break;
|
||||
|
||||
case "blob":
|
||||
new Worker(URL.createObjectURL(await doXHRGetBlob(src)));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw "Unsupport type";
|
||||
}
|
||||
|
||||
let checkUri = data.base + "?id=" + data.id;
|
||||
await assertCSPBlock(checkUri, data.expectBlocked);
|
||||
runNextTest();
|
||||
};
|
||||
|
||||
tests.forEach(function(test) {
|
||||
addAsyncTest(async function() {
|
||||
runWorkerTest(test);
|
||||
});
|
||||
});
|
||||
|
||||
runNextTest();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
Content-Security-Policy: default-src 'self' blob: 'unsafe-inline'
|
|
@ -47,10 +47,6 @@ support-files =
|
|||
file_main.html
|
||||
file_main.html^headers^
|
||||
file_main.js
|
||||
file_main_worker.js
|
||||
file_main_worker.js^headers^
|
||||
file_child_worker.js
|
||||
file_child_worker.js^headers^
|
||||
file_web_manifest.html
|
||||
file_web_manifest_remote.html
|
||||
file_web_manifest_https.html
|
||||
|
@ -363,3 +359,9 @@ support-files =
|
|||
file_frame_src.js
|
||||
file_frame_src_inner.html
|
||||
[test_security_policy_violation_event.html]
|
||||
[test_csp_worker_inheritance.html]
|
||||
support-files =
|
||||
worker.sjs
|
||||
worker_helper.js
|
||||
main_csp_worker.html
|
||||
main_csp_worker.html^headers^
|
||||
|
|
|
@ -29,30 +29,6 @@ window.tests = {
|
|||
fetch_bad: -1,
|
||||
beacon_good: -1,
|
||||
beacon_bad: -1,
|
||||
worker_xhr_same_bad: -1,
|
||||
worker_xhr_cross_good: -1,
|
||||
worker_fetch_same_bad: -1,
|
||||
worker_fetch_cross_good: -1,
|
||||
worker_script_same_good: -1,
|
||||
worker_script_cross_bad: -1,
|
||||
worker_inherited_xhr_good: -1,
|
||||
worker_inherited_xhr_bad: -1,
|
||||
worker_inherited_fetch_good: -1,
|
||||
worker_inherited_fetch_bad: -1,
|
||||
worker_inherited_script_good: -1,
|
||||
worker_inherited_script_bad: -1,
|
||||
worker_child_xhr_same_bad: -1,
|
||||
worker_child_xhr_cross_bad: -1,
|
||||
worker_child_script_same_bad: -1,
|
||||
worker_child_script_cross_bad: -1,
|
||||
worker_child_inherited_parent_xhr_bad: -1,
|
||||
worker_child_inherited_parent_xhr_good: -1,
|
||||
worker_child_inherited_parent_script_good: -1,
|
||||
worker_child_inherited_parent_script_bad: -1,
|
||||
worker_child_inherited_document_xhr_good: -1,
|
||||
worker_child_inherited_document_xhr_bad: -1,
|
||||
worker_child_inherited_document_script_good: -1,
|
||||
worker_child_inherited_document_script_bad: -1,
|
||||
media_good: -1,
|
||||
media_bad: -1,
|
||||
font_good: -1,
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 1475849</title>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<iframe style="width:200px;height:200px;" id='cspframe'></iframe>
|
||||
<script class="testbody" type="text/javascript">
|
||||
document.getElementById('cspframe').src = 'main_csp_worker.html';
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,116 @@
|
|||
Components.utils.importGlobalProperties(["URLSearchParams"]);
|
||||
|
||||
const SJS = "http://mochi.test:8888/tests/dom/security/test/csp/worker.sjs";
|
||||
|
||||
function createFetchWorker(url)
|
||||
{
|
||||
return `fetch("${url}");`;
|
||||
}
|
||||
|
||||
function createXHRWorker(url)
|
||||
{
|
||||
return `
|
||||
try {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "${url}");
|
||||
xhr.send();
|
||||
} catch(ex) {}
|
||||
`;
|
||||
}
|
||||
|
||||
function createImportScriptsWorker(url)
|
||||
{
|
||||
return `
|
||||
try {
|
||||
importScripts("${url}");
|
||||
} catch(ex) {}
|
||||
`;
|
||||
}
|
||||
|
||||
function createChildWorkerURL(params)
|
||||
{
|
||||
let url = SJS + "?" + params.toString();
|
||||
return `new Worker("${url}");`;
|
||||
}
|
||||
|
||||
function createChildWorkerBlob(params)
|
||||
{
|
||||
let url = SJS + "?" + params.toString();
|
||||
return `
|
||||
try {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "${url}");
|
||||
xhr.responseType = "blob";
|
||||
xhr.send();
|
||||
xhr.onload = () => {
|
||||
new Worker(URL.createObjectURL(xhr.response));};
|
||||
} catch(ex) {}
|
||||
`;
|
||||
}
|
||||
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
let params = new URLSearchParams(request.queryString);
|
||||
|
||||
let id = params.get("id");
|
||||
let base = unescape(params.get("base"));
|
||||
let child = params.has("child") ? params.get("child") : "";
|
||||
|
||||
//avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "application/javascript");
|
||||
|
||||
// Deliver the CSP policy encoded in the URL
|
||||
if(params.has("csp")) {
|
||||
response.setHeader("Content-Security-Policy", unescape(params.get("csp")), false);
|
||||
}
|
||||
|
||||
if (child) {
|
||||
let childCsp = params.has("childCsp") ? params.get("childCsp") : "";
|
||||
params.delete("csp");
|
||||
params.delete("child");
|
||||
params.delete("childCsp");
|
||||
params.append("csp", childCsp);
|
||||
|
||||
switch (child) {
|
||||
case "blob":
|
||||
response.write(createChildWorkerBlob(params));
|
||||
break;
|
||||
|
||||
case "url":
|
||||
response.write(createChildWorkerURL(params));
|
||||
break;
|
||||
|
||||
default:
|
||||
response.setStatusLine(request.httpVersion, 400, "Bad request");
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.has("action")) {
|
||||
switch (params.get("action")) {
|
||||
case "fetch":
|
||||
response.write(createFetchWorker(base + "?id=" + id));
|
||||
break;
|
||||
|
||||
case "xhr":
|
||||
response.write(createXHRWorker(base + "?id=" + id));
|
||||
break;
|
||||
|
||||
case "importScripts":
|
||||
response.write(createImportScriptsWorker(base + "?id=" + id));
|
||||
break;
|
||||
|
||||
default:
|
||||
response.setStatusLine(request.httpVersion, 400, "Bad request");
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
response.write("I don't know action ");
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
var _tests = [];
|
||||
function addTest(test) {
|
||||
_tests.push(test);
|
||||
}
|
||||
|
||||
function addAsyncTest(fn) {
|
||||
_tests.push(() => (fn)().catch(ok.bind(null, false)));
|
||||
}
|
||||
|
||||
function runNextTest() {
|
||||
if (_tests.length == 0) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
const fn = _tests.shift();
|
||||
try {
|
||||
fn();
|
||||
} catch (ex) {
|
||||
info("Test function " + (fn.name ? "'" + fn.name + "' " : "") +
|
||||
"threw an exception: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to perform an XHR then blob response to create worker
|
||||
*/
|
||||
function doXHRGetBlob(uri) {
|
||||
return new Promise(resolve => {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", uri);
|
||||
xhr.responseType = "blob";
|
||||
xhr.addEventListener("load", function() {
|
||||
is(xhr.status, 200, "doXHRGetBlob load uri='" + uri + "' status=" + xhr.status);
|
||||
resolve(xhr.response);
|
||||
});
|
||||
xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
function removeObserver(observer) {
|
||||
SpecialPowers.removeObserver(observer, "specialpowers-http-notify-request");
|
||||
SpecialPowers.removeObserver(observer, "csp-on-violate-policy");
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to perform an assert to check if the request should be blocked or
|
||||
* allowed by CSP
|
||||
*/
|
||||
function assertCSPBlock(url, shouldBlock) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let observer = {
|
||||
observe(subject, topic, data) {
|
||||
if (topic === "specialpowers-http-notify-request") {
|
||||
if (data == url) {
|
||||
is(shouldBlock, false, "Should allow request uri='" + url);
|
||||
removeObserver(observer);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
|
||||
if (topic === "csp-on-violate-policy") {
|
||||
let asciiSpec = SpecialPowers.getPrivilegedProps(
|
||||
SpecialPowers.do_QueryInterface(subject, "nsIURI"), "asciiSpec");
|
||||
if (asciiSpec == url) {
|
||||
is(shouldBlock, true, "Should block request uri='" + url);
|
||||
removeObserver(observer);
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
SpecialPowers.addObserver(observer, "csp-on-violate-policy");
|
||||
SpecialPowers.addObserver(observer, "specialpowers-http-notify-request");
|
||||
});
|
||||
}
|
|
@ -45,6 +45,7 @@ support-files =
|
|||
[test_getCTM.html]
|
||||
[test_getElementById.xhtml]
|
||||
[test_getSubStringLength.xhtml]
|
||||
[test_getTotalLength.xhtml]
|
||||
[test_lang.xhtml]
|
||||
skip-if = true # disabled-for-intermittent-failures--bug-701060
|
||||
[test_length.xhtml]
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=1474284
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 1474284</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1474284">Mozilla Bug 1474284</a>
|
||||
<p id="display"></p>
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<path id="path1" stroke="#000" fill="none"
|
||||
d="M 50,40
|
||||
C 50,40 0,60 30,20"/>
|
||||
</svg>
|
||||
|
||||
<pre id="test">
|
||||
<script class="testbody" type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function expectValue(id, expected)
|
||||
{
|
||||
isfuzzy(document.getElementById(id).getTotalLength(),
|
||||
expected, expected * 0.02,
|
||||
`getTotalLength() on element id="${id}" returned the wrong value`);
|
||||
}
|
||||
|
||||
function run()
|
||||
{
|
||||
expectValue("path1", 55.19);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
window.addEventListener("load", run, false);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -25,6 +25,11 @@ interface AccessibleNode {
|
|||
attribute boolean? readOnly;
|
||||
attribute boolean? required;
|
||||
|
||||
// Range values
|
||||
attribute double? valueMax;
|
||||
attribute double? valueMin;
|
||||
attribute double? valueNow;
|
||||
|
||||
// Accessible states
|
||||
attribute boolean? disabled;
|
||||
attribute boolean? expanded;
|
||||
|
@ -34,4 +39,15 @@ interface AccessibleNode {
|
|||
// Live regions
|
||||
attribute boolean? atomic;
|
||||
attribute boolean? busy;
|
||||
|
||||
// Collections.
|
||||
attribute long? colCount;
|
||||
attribute unsigned long? colIndex;
|
||||
attribute unsigned long? colSpan;
|
||||
attribute unsigned long? level;
|
||||
attribute unsigned long? posInSet;
|
||||
attribute long? rowCount;
|
||||
attribute unsigned long? rowIndex;
|
||||
attribute unsigned long? rowSpan;
|
||||
attribute long? setSize;
|
||||
};
|
||||
|
|
|
@ -305,6 +305,10 @@ FindInflectionApproximationRange(BezierControlPoints aControlPoints,
|
|||
PointD cp21 = aControlPoints.mCP2 - aControlPoints.mCP1;
|
||||
PointD cp41 = aControlPoints.mCP4 - aControlPoints.mCP1;
|
||||
|
||||
if (cp21.x == 0. && cp21.y == 0.) {
|
||||
cp21 = aControlPoints.mCP3 - aControlPoints.mCP1;
|
||||
}
|
||||
|
||||
if (cp21.x == 0. && cp21.y == 0.) {
|
||||
// In this case s3 becomes lim[n->0] (cp41.x * n) / n - (cp41.y * n) / n = cp41.x - cp41.y.
|
||||
|
||||
|
|
|
@ -224,7 +224,7 @@ class BumpChunk : public SingleLinkedListElement<BumpChunk>
|
|||
static constexpr uintptr_t magicNumber = uintptr_t(0x4c6966);
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG) || defined(MOZ_DIAGNOSTIC_ASSERT_ENABLED)
|
||||
#if defined(DEBUG) || defined(MOZ_ASAN)
|
||||
# define LIFO_CHUNK_PROTECT 1
|
||||
#endif
|
||||
|
||||
|
|
|
@ -652,8 +652,8 @@ load 1233607.html
|
|||
load 1234701-1.html
|
||||
load 1234701-2.html
|
||||
load 1271765.html
|
||||
asserts(2) asserts-if(Android,1) load 1272983-1.html # bug 586628
|
||||
asserts(2) asserts-if(Android,1) load 1272983-2.html # bug 586628
|
||||
pref(layout.css.xul-box-display-values.content.enabled,true) asserts(2) asserts-if(Android,1) load 1272983-1.html # bug 586628
|
||||
pref(layout.css.xul-box-display-values.content.enabled,true) asserts(2) asserts-if(Android,1) load 1272983-2.html # bug 586628
|
||||
load 1275059.html
|
||||
load 1278007.html
|
||||
load 1278080.html
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
== box-ordinal-with-out-of-flow-1.html box-ordinal-with-out-of-flow-1-ref.html
|
||||
pref(layout.css.xul-box-display-values.content.enabled,true) == box-ordinal-with-out-of-flow-1.html box-ordinal-with-out-of-flow-1-ref.html
|
||||
== dynamic-1-remove-to-none-grouped.xul dynamic-1-ref.xul
|
||||
== dynamic-1-add-to-one-grouped.xul dynamic-1-ref.xul
|
||||
== dynamic-1-remove-to-one-grouped-1.xul dynamic-1-ref.xul
|
||||
|
|
|
@ -417,7 +417,7 @@ fuzzy-if(webrender&&winWidget,35-35,1-1) == 321402-3.xul 321402-3-ref.xul
|
|||
== 321402-5.xul 321402-5-ref.xul
|
||||
== 321402-6.xul 321402-6-ref.xul
|
||||
== 321738-1.html 321738-1-ref.html
|
||||
== 322436-1.html 322436-1-ref.html
|
||||
pref(layout.css.xul-box-display-values.content.enabled,true) == 322436-1.html 322436-1-ref.html
|
||||
== 322461-1.xml 322461-1-ref.html
|
||||
== 323656-1.html 323656-1-ref.html
|
||||
== 323656-2.html 323656-2-ref.html
|
||||
|
@ -956,7 +956,7 @@ fails == 411585-3.html 411585-3-ref.html # bug 426909
|
|||
== 412607-1b.html 412607-1-ref.html
|
||||
random-if(Android) == 412679-1.html 412679-1-ref.html
|
||||
fuzzy-if(skiaContent,1,17) == 412679-2.html 412679-2-ref.html
|
||||
== 413027-1.html 413027-1-ref.html
|
||||
pref(layout.css.xul-box-display-values.content.enabled,true) == 413027-1.html 413027-1-ref.html
|
||||
fails == 413027-2.html 413027-2-ref.html
|
||||
fails == 413027-3.html 413027-3-ref.html
|
||||
== 413286-1a.html 413286-1-ref.html
|
||||
|
@ -1409,7 +1409,7 @@ fuzzy-if(Android,5,2800) == 506481-1.html 506481-1-ref.html
|
|||
== 507762-3.html 507762-1-ref.html
|
||||
== 507762-4.html 507762-2-ref.html
|
||||
random == 508816-1.xul 508816-1-ref.xul # Bug 1375012
|
||||
== 508816-2.html 508816-2-ref.html
|
||||
pref(layout.css.xul-box-display-values.content.enabled,true) == 508816-2.html 508816-2-ref.html
|
||||
skip-if(isDebugBuild) == 508908-1.xul 508908-1-ref.xul
|
||||
== 508919-1.xhtml 508919-1-ref.xhtml
|
||||
== 509155-1.xhtml 509155-1-ref.xhtml
|
||||
|
@ -1449,7 +1449,7 @@ fuzzy-if(skiaContent,5,50) == 526463-1.html 526463-1-ref.html
|
|||
== 528038-2.html 528038-2-ref.html
|
||||
== 528096-1.html 528096-1-ref.html
|
||||
== 530686-1.html 530686-1-ref.html
|
||||
== 531098-1.html 531098-1-ref.html
|
||||
pref(layout.css.xul-box-display-values.content.enabled,true) == 531098-1.html 531098-1-ref.html
|
||||
fuzzy-if(Android,2,48) == 531200-1.html 531200-1-ref.html
|
||||
== 531371-1.html 531371-1-ref.html
|
||||
== 534526-1a.html 534526-1-ref.html
|
||||
|
@ -1564,7 +1564,7 @@ random-if(!winWidget) random-if(/^Windows\x20NT\x2010\.0/.test(http.oscpu)) == 5
|
|||
random-if(!winWidget) fails-if(winWidget&&!dwrite) random-if(winWidget&&dwrite) != 574907-3.html 574907-3-notref.html
|
||||
== 577838-1.html 577838-1-ref.html
|
||||
== 577838-2.html 577838-2-ref.html
|
||||
== 579323-1.html 579323-1-ref.html
|
||||
pref(layout.css.xul-box-display-values.content.enabled,true) == 579323-1.html 579323-1-ref.html
|
||||
== 579349-1.html 579349-1-ref.html
|
||||
== 579655-1.html 579655-1-ref.html
|
||||
skip-if(!haveTestPlugin) fails-if(Android) HTTP == 579808-1.html 579808-1-ref.html
|
||||
|
|
|
@ -22,7 +22,7 @@ skip-if(Android) fuzzy-if(skiaContent,1,5) == clipped-elements.html clipped-elem
|
|||
fuzzy-if(gtkWidget,10,32) fuzzy-if(webrender,47,18) == two-value-syntax.html two-value-syntax-ref.html
|
||||
== single-value.html single-value-ref.html
|
||||
fuzzy-if(gtkWidget,10,2) == atomic-under-marker.html atomic-under-marker-ref.html
|
||||
fuzzy(1,2616) skip-if(Android) fuzzy-if(asyncPan&&!layersGPUAccelerated,102,12352) fails-if(gtkWidget) == xulscroll.html xulscroll-ref.html # gtkWidget:bug 1309107, bug 1328771
|
||||
pref(layout.css.xul-box-display-values.content.enabled,true) fuzzy(1,2616) skip-if(Android) fuzzy-if(asyncPan&&!layersGPUAccelerated,102,12352) fails-if(gtkWidget) == xulscroll.html xulscroll-ref.html # gtkWidget:bug 1309107, bug 1328771
|
||||
== combobox-zoom.html combobox-zoom-ref.html
|
||||
== dynamic-change-1.html dynamic-change-1-ref.html
|
||||
== float-edges-1.html float-edges-1-ref.html
|
||||
|
|
|
@ -139,8 +139,6 @@ function main() {
|
|||
var dispValsThatComputeToBlockInAFlexContainer = [
|
||||
"inline",
|
||||
"inline-block",
|
||||
"-moz-box",
|
||||
"-moz-inline-box",
|
||||
];
|
||||
|
||||
dispValsThatComputeToBlockInAFlexContainer.forEach(
|
||||
|
|
|
@ -18,7 +18,10 @@ const VALUES = [
|
|||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv(
|
||||
{"set": [["layout.css.xul-display-values.content.enabled", true]]}
|
||||
{"set": [
|
||||
["layout.css.xul-display-values.content.enabled", true],
|
||||
["layout.css.xul-box-display-values.content.enabled", true],
|
||||
]}
|
||||
).then(runTest);
|
||||
|
||||
function runTest() {
|
||||
|
|
|
@ -6,9 +6,8 @@
|
|||
<script>
|
||||
const NON_CONTENT_ACCESSIBLE_VALUES = {
|
||||
"display": [
|
||||
// FIXME(emilio, bug TBD): Remove from content these two too.
|
||||
// "-moz-box",
|
||||
// "-moz-inline-box",
|
||||
"-moz-box",
|
||||
"-moz-inline-box",
|
||||
"-moz-grid",
|
||||
"-moz-inline-grid",
|
||||
"-moz-grid-group",
|
||||
|
|
|
@ -62,6 +62,7 @@ class AccessibilityTest : BaseSessionTest() {
|
|||
|
||||
private interface EventDelegate {
|
||||
fun onAccessibilityFocused(event: AccessibilityEvent) { }
|
||||
fun onClicked(event: AccessibilityEvent) { }
|
||||
fun onFocused(event: AccessibilityEvent) { }
|
||||
fun onTextSelectionChanged(event: AccessibilityEvent) { }
|
||||
fun onTextChanged(event: AccessibilityEvent) { }
|
||||
|
@ -87,6 +88,7 @@ class AccessibilityTest : BaseSessionTest() {
|
|||
override fun onRequestSendAccessibilityEvent(host: ViewGroup, child: View, event: AccessibilityEvent): Boolean {
|
||||
when (event.eventType) {
|
||||
AccessibilityEvent.TYPE_VIEW_FOCUSED -> newDelegate.onFocused(event)
|
||||
AccessibilityEvent.TYPE_VIEW_CLICKED -> newDelegate.onClicked(event)
|
||||
AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED -> newDelegate.onAccessibilityFocused(event)
|
||||
AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED -> newDelegate.onTextSelectionChanged(event)
|
||||
AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED -> newDelegate.onTextChanged(event)
|
||||
|
@ -195,6 +197,25 @@ class AccessibilityTest : BaseSessionTest() {
|
|||
})
|
||||
}
|
||||
|
||||
private fun waitUntilClick(checked: Boolean? = null, selected: Boolean? = null) {
|
||||
sessionRule.waitUntilCalled(object : EventDelegate {
|
||||
@AssertCalled(count = 1)
|
||||
override fun onClicked(event: AccessibilityEvent) {
|
||||
var nodeId = getSourceId(event)
|
||||
var node = provider.createAccessibilityNodeInfo(nodeId)
|
||||
|
||||
if (checked != null) {
|
||||
assertThat("Event's checked state matches", event.isChecked, equalTo(checked))
|
||||
assertThat("Checkbox node has correct checked state", node.isChecked, equalTo(checked))
|
||||
}
|
||||
|
||||
if (selected != null) {
|
||||
assertThat("Selectable node has correct selected state", node.isSelected, equalTo(selected))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun setSelectionArguments(start: Int, end: Int): Bundle {
|
||||
val arguments = Bundle(2)
|
||||
arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_SELECTION_START_INT, start)
|
||||
|
@ -358,4 +379,58 @@ class AccessibilityTest : BaseSessionTest() {
|
|||
moveByGranularityArguments(AccessibilityNodeInfo.MOVEMENT_GRANULARITY_LINE))
|
||||
waitUntilTextTraversed(0, 18) // "Lorem ipsum dolor "
|
||||
}
|
||||
|
||||
@Test fun testCheckbox() {
|
||||
var nodeId = AccessibilityNodeProvider.HOST_VIEW_ID;
|
||||
sessionRule.session.loadString("<label><input id='checkbox' type='checkbox'>many option</label>", "text/html")
|
||||
sessionRule.waitForPageStop()
|
||||
|
||||
mainSession.evaluateJS("$('#checkbox').focus()")
|
||||
sessionRule.waitUntilCalled(object : EventDelegate {
|
||||
@AssertCalled(count = 1)
|
||||
override fun onAccessibilityFocused(event: AccessibilityEvent) {
|
||||
nodeId = getSourceId(event)
|
||||
var node = provider.createAccessibilityNodeInfo(nodeId)
|
||||
assertThat("Checkbox node is checkable", node.isCheckable, equalTo(true))
|
||||
assertThat("Checkbox node is clickable", node.isClickable, equalTo(true))
|
||||
assertThat("Checkbox node is focusable", node.isFocusable, equalTo(true))
|
||||
assertThat("Checkbox node is not checked", node.isChecked, equalTo(false))
|
||||
assertThat("Checkbox node has correct role", node.text.toString(), equalTo("many option check button"))
|
||||
}
|
||||
})
|
||||
|
||||
provider.performAction(nodeId, AccessibilityNodeInfo.ACTION_CLICK, null)
|
||||
waitUntilClick(checked = true)
|
||||
|
||||
provider.performAction(nodeId, AccessibilityNodeInfo.ACTION_CLICK, null)
|
||||
waitUntilClick(checked = false)
|
||||
}
|
||||
|
||||
@Test fun testSelectable() {
|
||||
var nodeId = View.NO_ID
|
||||
sessionRule.session.loadString(
|
||||
"""<ul style="list-style-type: none;" role="listbox">
|
||||
<li id="li" role="option" onclick="this.setAttribute('aria-selected',
|
||||
this.getAttribute('aria-selected') == 'true' ? 'false' : 'true')">1</li>
|
||||
</ul>""","text/html")
|
||||
sessionRule.waitForPageStop()
|
||||
|
||||
provider.performAction(nodeId, AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null)
|
||||
sessionRule.waitUntilCalled(object : EventDelegate {
|
||||
@AssertCalled(count = 1)
|
||||
override fun onAccessibilityFocused(event: AccessibilityEvent) {
|
||||
nodeId = getSourceId(event)
|
||||
var node = provider.createAccessibilityNodeInfo(nodeId)
|
||||
assertThat("Selectable node is clickable", node.isClickable, equalTo(true))
|
||||
assertThat("Selectable node is not selected", node.isSelected, equalTo(false))
|
||||
assertThat("Selectable node has correct role", node.text.toString(), equalTo("1 option list box"))
|
||||
}
|
||||
})
|
||||
|
||||
provider.performAction(nodeId, AccessibilityNodeInfo.ACTION_CLICK, null)
|
||||
waitUntilClick(selected = true)
|
||||
|
||||
provider.performAction(nodeId, AccessibilityNodeInfo.ACTION_CLICK, null)
|
||||
waitUntilClick(selected = false)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -379,6 +379,7 @@ public class SessionAccessibility {
|
|||
node.setPassword(message.getBoolean("password"));
|
||||
node.setFocusable(message.getBoolean("focusable"));
|
||||
node.setFocused(message.getBoolean("focused"));
|
||||
node.setSelected(message.getBoolean("selected"));
|
||||
|
||||
node.setClassName(message.getString("className", "android.view.View"));
|
||||
|
||||
|
@ -431,6 +432,15 @@ public class SessionAccessibility {
|
|||
node.setBoundsInParent(screenBounds);
|
||||
}
|
||||
|
||||
private void updateState(final AccessibilityNodeInfo node, final GeckoBundle message) {
|
||||
if (message.containsKey("checked")) {
|
||||
node.setChecked(message.getBoolean("checked"));
|
||||
}
|
||||
if (message.containsKey("selected")) {
|
||||
node.setSelected(message.getBoolean("selected"));
|
||||
}
|
||||
}
|
||||
|
||||
private void sendAccessibilityEvent(final GeckoBundle message) {
|
||||
if (mView == null || !Settings.isEnabled())
|
||||
return;
|
||||
|
@ -472,6 +482,11 @@ public class SessionAccessibility {
|
|||
if (mVirtualContentNode != null) {
|
||||
// Bounds for the virtual content can be updated from any event.
|
||||
updateBounds(mVirtualContentNode, message);
|
||||
|
||||
// State for the virtual content can be updated when view is clicked.
|
||||
if (eventType == AccessibilityEvent.TYPE_VIEW_CLICKED) {
|
||||
updateState(mVirtualContentNode, message);
|
||||
}
|
||||
}
|
||||
|
||||
final AccessibilityEvent accessibilityEvent = obtainEvent(eventType, eventSource);
|
||||
|
|
|
@ -361,6 +361,20 @@ VARCACHE_PREF(
|
|||
bool, false
|
||||
)
|
||||
|
||||
// Pref to control whether display: -moz-box and display: -moz-inline-box are
|
||||
// parsed in content pages.
|
||||
#ifdef EARLY_BETA_OR_EARLIER
|
||||
#define PREF_VALUE false
|
||||
#else
|
||||
#define PREF_VALUE true
|
||||
#endif
|
||||
VARCACHE_PREF(
|
||||
"layout.css.xul-box-display-values.content.enabled",
|
||||
layout_css_xul_box_display_values_content_enabled,
|
||||
bool, PREF_VALUE
|
||||
)
|
||||
#undef PREF_VALUE
|
||||
|
||||
// Is support for CSS "grid-template-{columns,rows}: subgrid X" enabled?
|
||||
VARCACHE_PREF(
|
||||
"layout.css.grid-template-subgrid-value.enabled",
|
||||
|
|
|
@ -606,6 +606,10 @@ pref("media.audioipc.stack_size", 262144);
|
|||
pref("media.cubeb.sandbox", false);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_AV1
|
||||
pref("media.av1.enabled", false);
|
||||
#endif
|
||||
|
||||
pref("media.webaudio.audiocontextoptions-samplerate.enabled", true);
|
||||
|
||||
// setSinkId expected to be unconditionally enabled in 63. Till then the
|
||||
|
|
|
@ -399,7 +399,8 @@ bool ShouldTestTipTsf()
|
|||
return true;
|
||||
}
|
||||
|
||||
int main()
|
||||
extern "C"
|
||||
int wmain(int argc, wchar_t* argv[])
|
||||
{
|
||||
LARGE_INTEGER start;
|
||||
QueryPerformanceCounter(&start);
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/CmdLineAndEnvUtils.h"
|
||||
#include "nsWindowsDllInterceptor.h"
|
||||
#include "nsWindowsHelpers.h"
|
||||
|
||||
|
@ -30,8 +33,10 @@ ReturnResultHook()
|
|||
return 0;
|
||||
}
|
||||
|
||||
int ParentMain()
|
||||
int ParentMain(int argc, wchar_t* argv[])
|
||||
{
|
||||
mozilla::SetArgv0ToFullBinaryPath(argv);
|
||||
|
||||
// We'll add the child process to a job so that, in the event of a failure in
|
||||
// this parent process, the child process will be automatically terminated.
|
||||
nsAutoHandle job(::CreateJobObject(nullptr, nullptr));
|
||||
|
@ -40,7 +45,7 @@ int ParentMain()
|
|||
return 1;
|
||||
}
|
||||
|
||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo{};
|
||||
JOBOBJECT_EXTENDED_LIMIT_INFORMATION jobInfo = {};
|
||||
jobInfo.BasicLimitInformation.LimitFlags = JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE;
|
||||
|
||||
if (!::SetInformationJobObject(job.get(), JobObjectExtendedLimitInformation,
|
||||
|
@ -49,14 +54,20 @@ int ParentMain()
|
|||
return 1;
|
||||
}
|
||||
|
||||
wstring cmdLine(::GetCommandLineW());
|
||||
cmdLine += L" -child";
|
||||
wchar_t childArgv_1[] = L"-child";
|
||||
|
||||
wchar_t* childArgv[] = {
|
||||
argv[0],
|
||||
childArgv_1
|
||||
};
|
||||
|
||||
mozilla::UniquePtr<wchar_t[]>
|
||||
cmdLine(mozilla::MakeCommandLine(mozilla::ArrayLength(childArgv), childArgv));
|
||||
|
||||
STARTUPINFOW si = { sizeof(si) };
|
||||
PROCESS_INFORMATION pi;
|
||||
if (!::CreateProcessW(nullptr, const_cast<LPWSTR>(cmdLine.c_str()), nullptr,
|
||||
nullptr, FALSE, CREATE_SUSPENDED, nullptr, nullptr, &si,
|
||||
&pi)) {
|
||||
if (!::CreateProcessW(argv[0], cmdLine.get(), nullptr, nullptr, FALSE,
|
||||
CREATE_SUSPENDED, nullptr, nullptr, &si, &pi)) {
|
||||
printf("TEST-UNEXPECTED-FAIL | DllInterceptorCrossProcess | Failed to spawn child process\n");
|
||||
return 1;
|
||||
}
|
||||
|
@ -114,12 +125,18 @@ int ParentMain()
|
|||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
extern "C"
|
||||
int wmain(int argc, wchar_t* argv[])
|
||||
{
|
||||
if (argc > 1) {
|
||||
return ReturnResult();
|
||||
// clang keeps inlining this call despite every attempt to force it to do
|
||||
// otherwise. We'll use GetProcAddress and call its function pointer instead.
|
||||
auto pReturnResult =
|
||||
reinterpret_cast<decltype(&ReturnResult)>(
|
||||
::GetProcAddress(::GetModuleHandleW(nullptr), "ReturnResult"));
|
||||
return pReturnResult();
|
||||
}
|
||||
|
||||
return ParentMain();
|
||||
return ParentMain(argc, argv);
|
||||
}
|
||||
|
||||
|
|
|
@ -15,3 +15,9 @@ GeckoCppUnitTests(
|
|||
OS_LIBS += [
|
||||
'ole32',
|
||||
]
|
||||
|
||||
if CONFIG['OS_TARGET'] == 'WINNT' and CONFIG['CC_TYPE'] == 'gcc':
|
||||
# This allows us to use wmain as the entry point on mingw
|
||||
LDFLAGS += [
|
||||
'-municode',
|
||||
]
|
||||
|
|
|
@ -1 +1 @@
|
|||
NSPR_4_19_RTM
|
||||
607196c7ef66
|
||||
|
|
|
@ -10,4 +10,3 @@
|
|||
*/
|
||||
|
||||
#error "Do not include this header file."
|
||||
|
||||
|
|
|
@ -2488,7 +2488,7 @@ test -n "$target_alias" &&
|
|||
program_prefix=${target_alias}-
|
||||
|
||||
MOD_MAJOR_VERSION=4
|
||||
MOD_MINOR_VERSION=19
|
||||
MOD_MINOR_VERSION=20
|
||||
MOD_PATCH_VERSION=0
|
||||
NSPR_MODNAME=nspr20
|
||||
_HAVE_PTHREADS=
|
||||
|
|
|
@ -15,7 +15,7 @@ dnl ========================================================
|
|||
dnl = Defaults
|
||||
dnl ========================================================
|
||||
MOD_MAJOR_VERSION=4
|
||||
MOD_MINOR_VERSION=19
|
||||
MOD_MINOR_VERSION=20
|
||||
MOD_PATCH_VERSION=0
|
||||
NSPR_MODNAME=nspr20
|
||||
_HAVE_PTHREADS=
|
||||
|
|
|
@ -1020,6 +1020,98 @@
|
|||
#define PR_BYTES_PER_WORD_LOG2 2
|
||||
#define PR_BYTES_PER_DWORD_LOG2 3
|
||||
|
||||
#elif defined(__riscv) && (__riscv_xlen == 32)
|
||||
|
||||
#undef IS_BIG_ENDIAN
|
||||
#define IS_LITTLE_ENDIAN 1
|
||||
#undef IS_64
|
||||
|
||||
#define PR_BYTES_PER_BYTE 1
|
||||
#define PR_BYTES_PER_SHORT 2
|
||||
#define PR_BYTES_PER_INT 4
|
||||
#define PR_BYTES_PER_INT64 8
|
||||
#define PR_BYTES_PER_LONG 4
|
||||
#define PR_BYTES_PER_FLOAT 4
|
||||
#define PR_BYTES_PER_DOUBLE 8
|
||||
#define PR_BYTES_PER_WORD 4
|
||||
#define PR_BYTES_PER_DWORD 8
|
||||
|
||||
#define PR_BITS_PER_BYTE 8
|
||||
#define PR_BITS_PER_SHORT 16
|
||||
#define PR_BITS_PER_INT 32
|
||||
#define PR_BITS_PER_INT64 64
|
||||
#define PR_BITS_PER_LONG 32
|
||||
#define PR_BITS_PER_FLOAT 32
|
||||
#define PR_BITS_PER_DOUBLE 64
|
||||
#define PR_BITS_PER_WORD 32
|
||||
|
||||
#define PR_BITS_PER_BYTE_LOG2 3
|
||||
#define PR_BITS_PER_SHORT_LOG2 4
|
||||
#define PR_BITS_PER_INT_LOG2 5
|
||||
#define PR_BITS_PER_INT64_LOG2 6
|
||||
#define PR_BITS_PER_LONG_LOG2 5
|
||||
#define PR_BITS_PER_FLOAT_LOG2 5
|
||||
#define PR_BITS_PER_DOUBLE_LOG2 6
|
||||
#define PR_BITS_PER_WORD_LOG2 5
|
||||
|
||||
#define PR_ALIGN_OF_SHORT 2
|
||||
#define PR_ALIGN_OF_INT 4
|
||||
#define PR_ALIGN_OF_LONG 4
|
||||
#define PR_ALIGN_OF_INT64 8
|
||||
#define PR_ALIGN_OF_FLOAT 4
|
||||
#define PR_ALIGN_OF_DOUBLE 8
|
||||
#define PR_ALIGN_OF_POINTER 4
|
||||
#define PR_ALIGN_OF_WORD 4
|
||||
|
||||
#define PR_BYTES_PER_WORD_LOG2 2
|
||||
#define PR_BYTES_PER_DWORD_LOG2 3
|
||||
|
||||
#elif defined(__riscv) && (__riscv_xlen == 64)
|
||||
|
||||
#undef IS_BIG_ENDIAN
|
||||
#define IS_LITTLE_ENDIAN 1
|
||||
#define IS_64
|
||||
|
||||
#define PR_BYTES_PER_BYTE 1
|
||||
#define PR_BYTES_PER_SHORT 2
|
||||
#define PR_BYTES_PER_INT 4
|
||||
#define PR_BYTES_PER_INT64 8
|
||||
#define PR_BYTES_PER_LONG 8
|
||||
#define PR_BYTES_PER_FLOAT 4
|
||||
#define PR_BYTES_PER_DOUBLE 8
|
||||
#define PR_BYTES_PER_WORD 8
|
||||
#define PR_BYTES_PER_DWORD 8
|
||||
|
||||
#define PR_BITS_PER_BYTE 8
|
||||
#define PR_BITS_PER_SHORT 16
|
||||
#define PR_BITS_PER_INT 32
|
||||
#define PR_BITS_PER_INT64 64
|
||||
#define PR_BITS_PER_LONG 64
|
||||
#define PR_BITS_PER_FLOAT 32
|
||||
#define PR_BITS_PER_DOUBLE 64
|
||||
#define PR_BITS_PER_WORD 64
|
||||
|
||||
#define PR_BITS_PER_BYTE_LOG2 3
|
||||
#define PR_BITS_PER_SHORT_LOG2 4
|
||||
#define PR_BITS_PER_INT_LOG2 5
|
||||
#define PR_BITS_PER_INT64_LOG2 6
|
||||
#define PR_BITS_PER_LONG_LOG2 6
|
||||
#define PR_BITS_PER_FLOAT_LOG2 5
|
||||
#define PR_BITS_PER_DOUBLE_LOG2 6
|
||||
#define PR_BITS_PER_WORD_LOG2 6
|
||||
|
||||
#define PR_ALIGN_OF_SHORT 2
|
||||
#define PR_ALIGN_OF_INT 4
|
||||
#define PR_ALIGN_OF_LONG 8
|
||||
#define PR_ALIGN_OF_INT64 8
|
||||
#define PR_ALIGN_OF_FLOAT 4
|
||||
#define PR_ALIGN_OF_DOUBLE 8
|
||||
#define PR_ALIGN_OF_POINTER 8
|
||||
#define PR_ALIGN_OF_WORD 8
|
||||
|
||||
#define PR_BYTES_PER_WORD_LOG2 3
|
||||
#define PR_BYTES_PER_DWORD_LOG2 3
|
||||
|
||||
#else
|
||||
|
||||
#error "Unknown CPU architecture"
|
||||
|
|
|
@ -57,6 +57,10 @@
|
|||
#define _PR_SI_ARCHITECTURE "m32r"
|
||||
#elif defined(__or1k__)
|
||||
#define _PR_SI_ARCHITECTURE "or1k"
|
||||
#elif defined(__riscv) && (__riscv_xlen == 32)
|
||||
#define _PR_SI_ARCHITECTURE "riscv32"
|
||||
#elif defined(__riscv) && (__riscv_xlen == 64)
|
||||
#define _PR_SI_ARCHITECTURE "riscv64"
|
||||
#else
|
||||
#error "Unknown CPU architecture"
|
||||
#endif
|
||||
|
|
|
@ -31,11 +31,11 @@ PR_BEGIN_EXTERN_C
|
|||
** The format of the version string is
|
||||
** "<major version>.<minor version>[.<patch level>] [<Beta>]"
|
||||
*/
|
||||
#define PR_VERSION "4.19"
|
||||
#define PR_VERSION "4.20 Beta"
|
||||
#define PR_VMAJOR 4
|
||||
#define PR_VMINOR 19
|
||||
#define PR_VMINOR 20
|
||||
#define PR_VPATCH 0
|
||||
#define PR_BETA PR_FALSE
|
||||
#define PR_BETA PR_TRUE
|
||||
|
||||
/*
|
||||
** PRVersionCheck
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#if defined(LINUX)
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On Unix, the error code for gethostbyname() and gethostbyaddr()
|
||||
* is returned in the global variable h_errno, instead of the usual
|
||||
|
@ -1366,7 +1370,17 @@ PRUintn _PR_NetAddrSize(const PRNetAddr* addr)
|
|||
#endif
|
||||
#if defined(XP_UNIX) || defined(XP_OS2)
|
||||
else if (AF_UNIX == addr->raw.family)
|
||||
addrsize = sizeof(addr->local);
|
||||
{
|
||||
#if defined(LINUX)
|
||||
if (addr->local.path[0] == 0)
|
||||
/* abstract socket address is supported on Linux only */
|
||||
addrsize = strnlen(addr->local.path + 1,
|
||||
sizeof(addr->local.path)) +
|
||||
offsetof(struct sockaddr_un, sun_path) + 1;
|
||||
else
|
||||
#endif
|
||||
addrsize = sizeof(addr->local);
|
||||
}
|
||||
#endif
|
||||
else addrsize = 0;
|
||||
|
||||
|
|
|
@ -1750,7 +1750,12 @@ static PRStatus pt_Bind(PRFileDesc *fd, const PRNetAddr *addr)
|
|||
if (addr->raw.family == AF_UNIX)
|
||||
{
|
||||
/* Disallow relative pathnames */
|
||||
if (addr->local.path[0] != '/')
|
||||
if (addr->local.path[0] != '/'
|
||||
#if defined(LINUX)
|
||||
/* Linux has abstract socket address support */
|
||||
&& addr->local.path[0] != 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
|
||||
return PR_FAILURE;
|
||||
|
|
|
@ -911,7 +911,8 @@ PR_IMPLEMENT(PRStatus) PR_DeleteSemaphore(const char *name)
|
|||
* From the semctl(2) man page in glibc 2.0
|
||||
*/
|
||||
#if (defined(__GNU_LIBRARY__) && !defined(_SEM_SEMUN_UNDEFINED)) \
|
||||
|| defined(FREEBSD) || defined(OPENBSD) || defined(BSDI) \
|
||||
|| (defined(FREEBSD) && __FreeBSD_version < 1200059) \
|
||||
|| defined(OPENBSD) || defined(BSDI) \
|
||||
|| defined(DARWIN) || defined(SYMBIAN)
|
||||
/* union semun is defined by including <sys/sem.h> */
|
||||
#else
|
||||
|
|
|
@ -18,6 +18,7 @@ include $(topsrcdir)/config/config.mk
|
|||
DIRS = dll
|
||||
|
||||
CSRCS = \
|
||||
abstract.c \
|
||||
accept.c \
|
||||
acceptread.c \
|
||||
acceptreademu.c \
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(LINUX)
|
||||
|
||||
#include <string.h>
|
||||
#include "nspr.h"
|
||||
|
||||
static const char abstractSocketName[] = "\0testsocket";
|
||||
|
||||
static void
|
||||
ClientThread(void* aArg)
|
||||
{
|
||||
PRFileDesc* socket;
|
||||
PRNetAddr addr;
|
||||
PRUint8 buf[1024];
|
||||
PRInt32 len;
|
||||
PRInt32 total;
|
||||
|
||||
addr.local.family = PR_AF_LOCAL;
|
||||
memcpy(addr.local.path, abstractSocketName, sizeof(abstractSocketName));
|
||||
|
||||
socket = PR_OpenTCPSocket(addr.raw.family);
|
||||
if (!socket) {
|
||||
fprintf(stderr, "PR_OpenTCPSokcet failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (PR_Connect(socket, &addr, PR_INTERVAL_NO_TIMEOUT) == PR_FAILURE) {
|
||||
fprintf(stderr, "PR_Connect failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
total = 0;
|
||||
while (total < sizeof(buf)) {
|
||||
len = PR_Recv(socket, buf + total, sizeof(buf) - total, 0,
|
||||
PR_INTERVAL_NO_TIMEOUT);
|
||||
if (len < 1) {
|
||||
fprintf(stderr, "PR_Recv failed\n");
|
||||
exit(1);
|
||||
}
|
||||
total += len;
|
||||
}
|
||||
|
||||
total = 0;
|
||||
while (total < sizeof(buf)) {
|
||||
len = PR_Send(socket, buf + total, sizeof(buf) - total, 0,
|
||||
PR_INTERVAL_NO_TIMEOUT);
|
||||
if (len < 1) {
|
||||
fprintf(stderr, "PR_Send failed\n");
|
||||
exit(1);
|
||||
}
|
||||
total += len;
|
||||
}
|
||||
|
||||
if (PR_Close(socket) == PR_FAILURE) {
|
||||
fprintf(stderr, "PR_Close failed\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
PRFileDesc* socket;
|
||||
PRFileDesc* acceptSocket;
|
||||
PRThread* thread;
|
||||
PRNetAddr addr;
|
||||
PRUint8 buf[1024];
|
||||
PRInt32 len;
|
||||
PRInt32 total;
|
||||
|
||||
addr.local.family = PR_AF_LOCAL;
|
||||
memcpy(addr.local.path, abstractSocketName, sizeof(abstractSocketName));
|
||||
|
||||
socket = PR_OpenTCPSocket(addr.raw.family);
|
||||
if (!socket) {
|
||||
fprintf(stderr, "PR_OpenTCPSocket failed\n");
|
||||
exit(1);
|
||||
}
|
||||
if (PR_Bind(socket, &addr) == PR_FAILURE) {
|
||||
fprintf(stderr, "PR_Bind failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (PR_Listen(socket, 5) == PR_FAILURE) {
|
||||
fprintf(stderr, "PR_Listen failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
thread = PR_CreateThread(PR_USER_THREAD, ClientThread, 0, PR_PRIORITY_NORMAL,
|
||||
PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0);
|
||||
if (!thread) {
|
||||
fprintf(stderr, "PR_CreateThread failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
acceptSocket = PR_Accept(socket, NULL, PR_INTERVAL_NO_TIMEOUT);
|
||||
if (!acceptSocket) {
|
||||
fprintf(stderr, "PR_Accept failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(buf, 'A', sizeof(buf));
|
||||
|
||||
total = 0;
|
||||
while (total < sizeof(buf)) {
|
||||
len = PR_Send(acceptSocket, buf + total, sizeof(buf) - total, 0,
|
||||
PR_INTERVAL_NO_TIMEOUT);
|
||||
if (len < 1) {
|
||||
fprintf(stderr, "PR_Send failed\n");
|
||||
exit(1);
|
||||
}
|
||||
total += len;
|
||||
}
|
||||
|
||||
total = 0;
|
||||
while (total < sizeof(buf)) {
|
||||
len = PR_Recv(acceptSocket, buf + total, sizeof(buf) - total, 0,
|
||||
PR_INTERVAL_NO_TIMEOUT);
|
||||
if (len < 1) {
|
||||
fprintf(stderr, "PR_Recv failed\n");
|
||||
exit(1);
|
||||
}
|
||||
total += len;
|
||||
}
|
||||
|
||||
if (PR_Close(acceptSocket) == PR_FAILURE) {
|
||||
fprintf(stderr, "PR_Close failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (PR_JoinThread(thread) == PR_FAILURE) {
|
||||
fprintf(stderr, "PR_JoinThread failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (PR_Close(socket) == PR_FAILURE) {
|
||||
fprintf(stderr, "PR_Close failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("PASS\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
int
|
||||
main()
|
||||
{
|
||||
prinf("PASS\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -241,6 +241,7 @@ $prog = shift; # Program to test
|
|||
|
||||
# MAIN ---------------
|
||||
@progs = (
|
||||
"abstract",
|
||||
"accept",
|
||||
"acceptread",
|
||||
"acceptreademu",
|
||||
|
|
|
@ -71,6 +71,7 @@ LOGFILE=${NSPR_TEST_LOGFILE:-$NULL_DEVICE}
|
|||
#
|
||||
|
||||
TESTS="
|
||||
abstract
|
||||
accept
|
||||
acceptread
|
||||
acceptreademu
|
||||
|
|
|
@ -40,7 +40,7 @@ static char *compatible_version[] = {
|
|||
"4.10", "4.10.1", "4.10.2", "4.10.3", "4.10.4",
|
||||
"4.10.5", "4.10.6", "4.10.7", "4.10.8", "4.10.9",
|
||||
"4.10.10", "4.11", "4.12", "4.13", "4.14", "4.15",
|
||||
"4.16", "4.17", "4.18",
|
||||
"4.16", "4.17", "4.18", "4.19",
|
||||
PR_VERSION
|
||||
};
|
||||
|
||||
|
@ -56,8 +56,8 @@ static char *incompatible_version[] = {
|
|||
"3.0", "3.0.1",
|
||||
"3.1", "3.1.1", "3.1.2", "3.1.3",
|
||||
"3.5", "3.5.1",
|
||||
"4.19.1",
|
||||
"4.20", "4.20.1",
|
||||
"4.20.1",
|
||||
"4.21", "4.21.1",
|
||||
"10.0", "11.1", "12.14.20"
|
||||
};
|
||||
|
||||
|
|
|
@ -30,6 +30,17 @@ fn moz_display_values_enabled(context: &ParserContext) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
fn moz_box_display_values_enabled(context: &ParserContext) -> bool {
|
||||
use gecko_bindings::structs;
|
||||
use stylesheets::Origin;
|
||||
context.stylesheet_origin == Origin::UserAgent ||
|
||||
context.chrome_rules_enabled() ||
|
||||
unsafe {
|
||||
structs::StaticPrefs_sVarCache_layout_css_xul_box_display_values_content_enabled
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, MallocSizeOf, Parse, PartialEq,
|
||||
SpecifiedValueInfo, ToComputedValue, ToCss)]
|
||||
|
@ -80,8 +91,10 @@ pub enum Display {
|
|||
#[cfg(feature = "gecko")]
|
||||
WebkitInlineBox,
|
||||
#[cfg(feature = "gecko")]
|
||||
#[parse(condition = "moz_box_display_values_enabled")]
|
||||
MozBox,
|
||||
#[cfg(feature = "gecko")]
|
||||
#[parse(condition = "moz_box_display_values_enabled")]
|
||||
MozInlineBox,
|
||||
#[cfg(feature = "gecko")]
|
||||
#[parse(condition = "moz_display_values_enabled")]
|
||||
|
|
|
@ -46,5 +46,7 @@ marionette.jar:
|
|||
content/test_dialog.xul (chrome/test_dialog.xul)
|
||||
content/test_nested_iframe.xul (chrome/test_nested_iframe.xul)
|
||||
content/test.xul (chrome/test.xul)
|
||||
#ifdef MOZ_CODE_COVERAGE
|
||||
content/PerTestCoverageUtils.jsm (../../tools/code-coverage/PerTestCoverageUtils.jsm)
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -47,6 +47,13 @@ class GeckoMigration(MercurialScript, BalrogMixin, VirtualenvMixin,
|
|||
"default": "ffxbld <release@mozilla.com>",
|
||||
"help": "Specify what user to use to commit to hg.",
|
||||
}],
|
||||
[['--ssh-user', ], {
|
||||
"action": "store",
|
||||
"dest": "ssh_user",
|
||||
"type": "string",
|
||||
"default": None,
|
||||
"help": "The user to push to hg.mozilla.org as.",
|
||||
}],
|
||||
[['--balrog-api-root', ], {
|
||||
"action": "store",
|
||||
"dest": "balrog_api_root",
|
||||
|
@ -191,7 +198,12 @@ class GeckoMigration(MercurialScript, BalrogMixin, VirtualenvMixin,
|
|||
def set_push_to_ssh(self):
|
||||
for cwd in self.query_push_dirs():
|
||||
repo_url = self.read_repo_hg_rc(cwd).get('paths', 'default')
|
||||
push_dest = repo_url.replace('https://', 'ssh://')
|
||||
username = self.config.get('ssh_user', '')
|
||||
# Add a trailing @ to the username if it exists, otherwise it gets
|
||||
# mushed up with the hostname.
|
||||
if username:
|
||||
username += '@'
|
||||
push_dest = repo_url.replace('https://', 'ssh://' + username)
|
||||
|
||||
if not push_dest.startswith('ssh://'):
|
||||
raise Exception('Warning: path "{}" is not supported. Protocol must be ssh')
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<vbox style="width: 24em;margin: 5px;">
|
||||
<label id="info.txt"/>
|
||||
<vbox>
|
||||
<richlistbox id="list" class="theme-listbox" height="80"/>
|
||||
<richlistbox id="list" class="theme-listbox" style="height: 8em;"/>
|
||||
</vbox>
|
||||
</vbox>
|
||||
</dialog>
|
||||
|
|
|
@ -10,12 +10,14 @@
|
|||
@import url("chrome://global/skin/autocomplete.css");
|
||||
@import url("chrome://formautofill-shared/skin/autocomplete-item.css");
|
||||
@import url("chrome://formautofill/skin/autocomplete-item.css");
|
||||
@import url("chrome://global/skin/dialog.css");
|
||||
@import url("chrome://global/skin/dropmarker.css");
|
||||
@import url("chrome://global/skin/groupbox.css");
|
||||
@import url("chrome://global/skin/menu.css");
|
||||
@import url("chrome://global/skin/menulist.css");
|
||||
@import url("chrome://global/skin/notification.css");
|
||||
@import url("chrome://global/skin/popup.css");
|
||||
@import url("chrome://global/skin/progressmeter.css");
|
||||
@import url("chrome://global/skin/richlistbox.css");
|
||||
@import url("chrome://global/skin/splitter.css");
|
||||
@import url("chrome://global/skin/toolbar.css");
|
||||
|
|
|
@ -14,9 +14,6 @@
|
|||
xmlns:xbl="http://www.mozilla.org/xbl">
|
||||
|
||||
<binding id="dialog">
|
||||
<resources>
|
||||
<stylesheet src="chrome://global/skin/dialog.css"/>
|
||||
</resources>
|
||||
<content>
|
||||
<xul:vbox class="box-inherit dialog-content-box" flex="1">
|
||||
<children/>
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
xmlns:xbl="http://www.mozilla.org/xbl">
|
||||
|
||||
<binding id="progressmeter">
|
||||
<resources>
|
||||
<stylesheet src="chrome://global/skin/progressmeter.css"/>
|
||||
</resources>
|
||||
|
||||
<content>
|
||||
<xul:spacer class="progress-bar" xbl:inherits="mode"/>
|
||||
<xul:spacer class="progress-remainder" xbl:inherits="mode"/>
|
||||
|
|
|
@ -319,4 +319,11 @@ this.AppConstants = Object.freeze({
|
|||
#else
|
||||
false,
|
||||
#endif
|
||||
|
||||
MOZ_CODE_COVERAGE:
|
||||
#ifdef MOZ_CODE_COVERAGE
|
||||
true,
|
||||
#else
|
||||
false,
|
||||
#endif
|
||||
});
|
||||
|
|
|
@ -137,7 +137,7 @@ function onProfilesKey(aEvent) {
|
|||
}
|
||||
|
||||
function onProfilesDblClick(aEvent) {
|
||||
if (aEvent.target.localName == "listitem")
|
||||
if (aEvent.target.closest("richlistitem"))
|
||||
document.documentElement.acceptDialog();
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
<separator flex="1"/>
|
||||
|
||||
<vbox flex="1">
|
||||
<richlistbox id="profiles" class="theme-listbox" height="100" seltype="single"
|
||||
<richlistbox id="profiles" class="theme-listbox" seltype="single"
|
||||
ondblclick="onProfilesDblClick(event)"
|
||||
onkeypress="onProfilesKey(event);">
|
||||
</richlistbox>
|
||||
|
|
|
@ -14,3 +14,7 @@ box#managebuttons > button {
|
|||
#managebuttons {
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
#profiles {
|
||||
height: 12em;
|
||||
}
|
||||
|
|
|
@ -14,3 +14,7 @@ box#managebuttons > button {
|
|||
#managebuttons {
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
#profiles {
|
||||
height: 12em;
|
||||
}
|
||||
|
|
|
@ -23,8 +23,10 @@
|
|||
#include "mozilla/Vector.h"
|
||||
|
||||
#include <wchar.h>
|
||||
#include <windows.h>
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
#include "mozilla/MemoryChecking.h"
|
||||
#include "mozilla/TypedEnumBits.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
@ -347,6 +349,48 @@ MakeCommandLine(int argc, wchar_t **argv)
|
|||
return std::move(s);
|
||||
}
|
||||
|
||||
inline bool
|
||||
SetArgv0ToFullBinaryPath(wchar_t* aArgv[])
|
||||
{
|
||||
if (!aArgv) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD bufLen = MAX_PATH;
|
||||
mozilla::UniquePtr<wchar_t[]> buf;
|
||||
DWORD retLen;
|
||||
|
||||
while (true) {
|
||||
buf = mozilla::MakeUnique<wchar_t[]>(bufLen);
|
||||
retLen = ::GetModuleFileNameW(nullptr, buf.get(), bufLen);
|
||||
if (!retLen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (retLen == bufLen && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||||
bufLen *= 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Upon success, retLen *excludes* the null character
|
||||
++retLen;
|
||||
|
||||
// Since we're likely to have a bunch of unused space in buf, let's reallocate
|
||||
// a string to the actual size of the file name.
|
||||
auto newArgv_0 = mozilla::MakeUnique<wchar_t[]>(retLen);
|
||||
if (wcscpy_s(newArgv_0.get(), retLen, buf.get())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We intentionally leak newArgv_0 into argv[0]
|
||||
aArgv[0] = newArgv_0.release();
|
||||
MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(aArgv[0]);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
// Save literal putenv string to environment variable.
|
||||
|
|
|
@ -501,11 +501,11 @@ PLDHashTable::ChangeTable(int32_t aDeltaLog2)
|
|||
for (uint32_t i = 0; i < oldCapacity; ++i) {
|
||||
PLDHashEntryHdr* oldEntry = (PLDHashEntryHdr*)oldEntryAddr;
|
||||
if (EntryIsLive(oldEntry)) {
|
||||
oldEntry->mKeyHash &= ~kCollisionFlag;
|
||||
PLDHashEntryHdr* newEntry = FindFreeEntry(oldEntry->mKeyHash);
|
||||
const PLDHashNumber key = oldEntry->mKeyHash & ~kCollisionFlag;
|
||||
PLDHashEntryHdr* newEntry = FindFreeEntry(key);
|
||||
NS_ASSERTION(EntryIsFree(newEntry), "EntryIsFree(newEntry)");
|
||||
moveEntry(this, oldEntry, newEntry);
|
||||
newEntry->mKeyHash = oldEntry->mKeyHash;
|
||||
newEntry->mKeyHash = key;
|
||||
}
|
||||
oldEntryAddr += mEntrySize;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче