mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge inbound to m-c.
This commit is contained in:
commit
ad273b968e
3
CLOBBER
3
CLOBBER
@ -22,5 +22,4 @@
|
||||
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
|
||||
# don't change CLOBBER for WebIDL changes any more.
|
||||
|
||||
CLOBBER due to recent changes to JS build files that were causing
|
||||
"STOP! configure has changed and needs to be run in this build directory." bustage
|
||||
JS build system changes are apparently requiring clobbers.
|
||||
|
@ -678,6 +678,32 @@ this.BrailleGenerator = {
|
||||
let output = OutputGenerator.genForContext.apply(this, arguments);
|
||||
|
||||
let acc = aContext.accessible;
|
||||
|
||||
// add the static text indicating a list item; do this for both listitems or
|
||||
// direct first children of listitems, because these are both common browsing
|
||||
// scenarios
|
||||
let addListitemIndicator = function addListitemIndicator(indicator = '*') {
|
||||
output.output.unshift(indicator);
|
||||
};
|
||||
|
||||
if (acc.indexInParent === 1 &&
|
||||
acc.parent.role == Roles.LISTITEM &&
|
||||
acc.previousSibling.role == Roles.STATICTEXT) {
|
||||
if (acc.parent.parent && acc.parent.parent.DOMNode &&
|
||||
acc.parent.parent.DOMNode.nodeName == 'UL') {
|
||||
addListitemIndicator();
|
||||
} else {
|
||||
addListitemIndicator(acc.previousSibling.name.trim());
|
||||
}
|
||||
} else if (acc.role == Roles.LISTITEM && acc.firstChild &&
|
||||
acc.firstChild.role == Roles.STATICTEXT) {
|
||||
if (acc.parent.DOMNode.nodeName == 'UL') {
|
||||
addListitemIndicator();
|
||||
} else {
|
||||
addListitemIndicator(acc.firstChild.name.trim());
|
||||
}
|
||||
}
|
||||
|
||||
if (acc instanceof Ci.nsIAccessibleText) {
|
||||
output.endOffset = this.outputOrder === OUTPUT_DESC_FIRST ?
|
||||
output.output.join(' ').length : acc.characterCount;
|
||||
@ -692,20 +718,7 @@ this.BrailleGenerator = {
|
||||
__proto__: OutputGenerator.objectOutputFunctions,
|
||||
|
||||
defaultFunc: function defaultFunc(aAccessible, aRoleStr, aStates, aFlags) {
|
||||
let braille = this.objectOutputFunctions._generateBaseOutput.apply(this, arguments);
|
||||
|
||||
if (aAccessible.indexInParent === 1 &&
|
||||
aAccessible.parent.role == Roles.LISTITEM &&
|
||||
aAccessible.previousSibling.role == Roles.STATICTEXT) {
|
||||
if (aAccessible.parent.parent && aAccessible.parent.parent.DOMNode &&
|
||||
aAccessible.parent.parent.DOMNode.nodeName == 'UL') {
|
||||
braille.unshift('*');
|
||||
} else {
|
||||
braille.unshift(aAccessible.previousSibling.name);
|
||||
}
|
||||
}
|
||||
|
||||
return braille;
|
||||
return this.objectOutputFunctions._generateBaseOutput.apply(this, arguments);
|
||||
},
|
||||
|
||||
listitem: function listitem(aAccessible, aRoleStr, aStates, aFlags) {
|
||||
|
@ -5,10 +5,9 @@ support-files =
|
||||
doc_traversal.html
|
||||
|
||||
[test_alive.html]
|
||||
[test_braille.html]
|
||||
[test_explicit_names.html]
|
||||
[test_landmarks.html]
|
||||
[test_live_regions.html]
|
||||
[test_output.html]
|
||||
[test_tables.html]
|
||||
[test_traversal.html]
|
||||
[test_utterance_order.html]
|
||||
|
@ -1,122 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=876475
|
||||
-->
|
||||
<head>
|
||||
<title>[AccessFu] braille generation test</title>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="./output.js"></script>
|
||||
<script type="application/javascript">
|
||||
|
||||
function doTest() {
|
||||
// Test the following accOrElmOrID (with optional old accOrElmOrID).
|
||||
// Note: each accOrElmOrID entry maps to a unique object braille
|
||||
// generator function within the BrailleGenerator.
|
||||
var tests = [{
|
||||
accOrElmOrID: "link",
|
||||
expected: [["lnk", "Link"], ["Link", "lnk"]]
|
||||
},{
|
||||
accOrElmOrID: "button",
|
||||
expected: [["btn", "I am a button"], ["I am a button", "btn"]]
|
||||
},{
|
||||
accOrElmOrID: "password_input",
|
||||
expected: [["passwdtxt", "Secret Password"], ["Secret Password", "passwdtxt"]]
|
||||
},{
|
||||
accOrElmOrID: "checkbox_unchecked",
|
||||
expected: [["( )", "checkboxtext"], ["checkboxtext", "( )"]]
|
||||
},{
|
||||
accOrElmOrID: "checkbox_checked",
|
||||
expected: [["(x)", "some more checkbox text"], ["some more checkbox text", "(x)"]]
|
||||
},{
|
||||
accOrElmOrID: "radio_unselected",
|
||||
expected: [["( )", "any old radio button"], ["any old radio button", "( )"]]
|
||||
},{
|
||||
accOrElmOrID: "radio_selected",
|
||||
expected: [["(x)", "a unique radio button"], ["a unique radio button", "(x)"]]
|
||||
},{
|
||||
accOrElmOrID: "togglebutton_notpressed",
|
||||
expected: [["( )", "I ain't pressed"], ["I ain't pressed", "( )"]]
|
||||
},{
|
||||
accOrElmOrID: "togglebutton_pressed",
|
||||
expected: [["(x)", "I am pressed!"], ["I am pressed!", "(x)"]]
|
||||
},{
|
||||
accOrElmOrID: "ul_li_one",
|
||||
expected: [["*", "ul item 1"], ["*", "ul item 1"]]
|
||||
},{
|
||||
accOrElmOrID: "ol_li_one",
|
||||
expected: [["1.", "ol item 1"], ["1.", "ol item 1"]]
|
||||
},{
|
||||
accOrElmOrID: "textarea",
|
||||
expected: [["txtarea", "Here lies treasure."], ["Here lies treasure.", "txtarea"]]
|
||||
},{
|
||||
accOrElmOrID: "textentry",
|
||||
expected: [["entry", "Mario", "First name:"], ["First name:", "Mario", "entry"]]
|
||||
},{
|
||||
accOrElmOrID: "range",
|
||||
expected: [["slider", "3", "Points:"], ["Points:", "3", "slider"]]
|
||||
}];
|
||||
|
||||
// Test all possible braille order preference values.
|
||||
tests.forEach(function run(test) {
|
||||
var brailleOrderValues = [0, 1];
|
||||
brailleOrderValues.forEach(
|
||||
function testBrailleOrder(brailleOrder) {
|
||||
SpecialPowers.setIntPref(PREF_UTTERANCE_ORDER, brailleOrder);
|
||||
var expected = test.expected[brailleOrder];
|
||||
testOutput(expected, test.accOrElmOrID, test.oldAccOrElmOrID, 2);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// If there was an original utterance order preference, revert to it.
|
||||
SpecialPowers.clearUserPref(PREF_UTTERANCE_ORDER);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<a href="example.com" id="link">Link</a>
|
||||
<button id="button">I am a button</button>
|
||||
<label for="password_input">Secret Password</label><input id="password_input" type="password"></input>
|
||||
<label for="checkbox_unchecked">checkboxtext</label><input id="checkbox_unchecked" type="checkbox"></input>
|
||||
<label for="checkbox_checked">some more checkbox text</label><input id="checkbox_checked" type="checkbox" checked></input>
|
||||
<label for="radio_unselected">any old radio button</label><input id="radio_unselected" type="radio"></input>
|
||||
<label for="radio_selected">a unique radio button</label><input id="radio_selected" type="radio" checked></input>
|
||||
<div id="togglebutton_notpressed" aria-pressed="false" role="button" tabindex="-1">I ain't pressed</div>
|
||||
<div id="togglebutton_pressed" aria-pressed="true" role="button" tabindex="-1">I am pressed!</div>
|
||||
<ol id="ordered_list">
|
||||
<li id="ol_li_one">ol item 1</li>
|
||||
<li id="ol_li_two">ol item 2</li>
|
||||
<li id="ol_li_three">ol item 3</li>
|
||||
<li id="ol_li_three">ol item 4</li>
|
||||
</ol>
|
||||
<ul id="unordered_list">
|
||||
<li id="ul_li_one">ul item 1</li>
|
||||
<li id="ul_li_two">ul item 2</li>
|
||||
<li id="ul_li_three">ul item 3</li>
|
||||
<li id="ul_li_three">ul item 4</li>
|
||||
</ul>
|
||||
<textarea id="textarea" cols="80" rows="5">
|
||||
Here lies treasure.
|
||||
</textarea>
|
||||
<label>First name: <input id="textentry" value="Mario"></label>
|
||||
<label>Points: <input id="range" type="range" name="points" min="1" max="10" value="3"></label>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -75,9 +75,7 @@
|
||||
expectedUtterance: [["list 1 item", "complementary", "First item",
|
||||
"A complementary"], ["A complementary", "First item",
|
||||
"complementary", "list 1 item"]],
|
||||
// XXX: The '*' should probably come before all of the context
|
||||
// utterance.
|
||||
expectedBraille: [["complementary", "*", "A complementary"], ["*",
|
||||
expectedBraille: [["*", "complementary", "A complementary"], ["*",
|
||||
"A complementary", "complementary"]]
|
||||
}, {
|
||||
accOrElmOrID: "parent_main",
|
||||
@ -151,4 +149,4 @@
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
459
accessible/tests/mochitest/jsat/test_output.html
Normal file
459
accessible/tests/mochitest/jsat/test_output.html
Normal file
@ -0,0 +1,459 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=753984
|
||||
-->
|
||||
<head>
|
||||
<title>[AccessFu] utterance order test</title>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="./output.js"></script>
|
||||
<script type="application/javascript">
|
||||
|
||||
function doTest() {
|
||||
// Test the following accOrElmOrID (with optional old accOrElmOrID).
|
||||
// Note: each accOrElmOrID entry maps to a unique object utterance
|
||||
// generator function within the UtteranceGenerator.
|
||||
var tests = [{
|
||||
accOrElmOrID: "anchor",
|
||||
expectedUtterance: [["link", "title"], ["title", "link"]],
|
||||
expectedBraille: [["lnk", "title"], ["title", "lnk"]]
|
||||
}, {
|
||||
accOrElmOrID: "anchor_titleandtext",
|
||||
expectedUtterance: [["link", "goes to the tests -", "Tests"],
|
||||
["Tests", "- goes to the tests", "link"]],
|
||||
expectedBraille: [["lnk", "goes to the tests -", "Tests"],
|
||||
["Tests", "- goes to the tests", "lnk"]],
|
||||
}, {
|
||||
accOrElmOrID: "anchor_duplicatedtitleandtext",
|
||||
expectedUtterance: [["link", "Tests"], ["Tests", "link"]],
|
||||
expectedBraille: [["lnk", "Tests"], ["Tests", "lnk"]]
|
||||
}, {
|
||||
accOrElmOrID: "anchor_arialabelandtext",
|
||||
expectedUtterance: [["link", "goes to the tests - Tests"],
|
||||
["Tests - goes to the tests", "link"]],
|
||||
expectedBraille: [["lnk", "goes to the tests - Tests"],
|
||||
["Tests - goes to the tests", "lnk"]],
|
||||
}, {
|
||||
accOrElmOrID: "textarea",
|
||||
expectedUtterance: [[
|
||||
"text area", "This is the text area text."
|
||||
], [
|
||||
"This is the text area text.", "text area"
|
||||
],],
|
||||
expectedBraille: [[
|
||||
"txtarea", "This is the text area text."
|
||||
], [
|
||||
"This is the text area text.", "txtarea"
|
||||
],],
|
||||
}, {
|
||||
accOrElmOrID: "heading",
|
||||
expectedUtterance: [
|
||||
["heading level 1", "Test heading"],
|
||||
["Test heading", "heading level 1"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["heading", "Test heading"],
|
||||
["Test heading", "heading"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "list",
|
||||
expectedUtterance: [
|
||||
["list 1 item", "First item", "1.", "list one"],
|
||||
["1.", "list one", "First item", "list 1 item"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["list", "list one"],
|
||||
["list one", "list"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "dlist",
|
||||
expectedUtterance: [
|
||||
["definition list 0.5 items", "dd one"],
|
||||
["dd one", "definition list 0.5 items"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["definition list", "dd one"],
|
||||
["dd one", "definition list"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "li_one",
|
||||
expectedUtterance: [
|
||||
["list 1 item", "First item", "1.", "list one"],
|
||||
["1.", "list one", "First item", "list 1 item"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["1.", "list one"],
|
||||
["1.", "list one"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "cell",
|
||||
expectedUtterance: [[
|
||||
"table with 1 column and 1 row", "Fruits and vegetables",
|
||||
"Column 1 Row 1", "list 4 items", "First item", "link", "Apples",
|
||||
"link", "Bananas", "link", "Peaches", "Last item", "link", "Plums"
|
||||
], [
|
||||
"Apples", "link", "First item", "Bananas", "link", "Peaches",
|
||||
"link", "Plums", "link", "Last item", "list 4 items",
|
||||
"Column 1 Row 1", "Fruits and vegetables",
|
||||
"table with 1 column and 1 row"
|
||||
]],
|
||||
expectedBraille: [[
|
||||
"c1r1", "list", "lnk", "Apples", "lnk", "Bananas", "lnk",
|
||||
"Peaches", "lnk", "Plums"
|
||||
], [
|
||||
"Apples", "lnk", "Bananas", "lnk", "Peaches", "lnk", "Plums",
|
||||
"lnk", "list", "c1r1"
|
||||
]]
|
||||
}, {
|
||||
accOrElmOrID: "date",
|
||||
expectedUtterance: [["date entry", "2011-09-29"], ["2011-09-29", "date entry"]],
|
||||
expectedBraille: [["date entry", "2011-09-29"], ["2011-09-29", "date entry"]]
|
||||
}, {
|
||||
accOrElmOrID: "email",
|
||||
expectedUtterance: [
|
||||
["e-mail entry", "test@example.com"],
|
||||
["test@example.com", "e-mail entry"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["e-mail entry", "test@example.com"],
|
||||
["test@example.com", "e-mail entry"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "search",
|
||||
expectedUtterance: [
|
||||
["search entry", "This is a search"],
|
||||
["This is a search", "search entry"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["search entry", "This is a search"],
|
||||
["This is a search", "search entry"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "tel",
|
||||
expectedUtterance: [
|
||||
["telephone entry", "555-5555"], ["555-5555", "telephone entry"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["telephone entry", "555-5555"], ["555-5555", "telephone entry"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "url",
|
||||
expectedUtterance: [
|
||||
["URL entry", "http://example.com"],
|
||||
["http://example.com", "URL entry"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["URL entry", "http://example.com"],
|
||||
["http://example.com", "URL entry"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "textInput",
|
||||
expectedUtterance: [["entry", "This is text."], ["This is text.", "entry"]],
|
||||
expectedBraille: [["entry", "This is text."], ["This is text.", "entry"]]
|
||||
}, {
|
||||
// Test pivot to list from li_one.
|
||||
accOrElmOrID: "list",
|
||||
oldAccOrElmOrID: "li_one",
|
||||
expectedUtterance: [
|
||||
["list 1 item", "First item", "1.", "list one"],
|
||||
["1.", "list one", "First item", "list 1 item"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["list", "list one"],
|
||||
["list one", "list"]
|
||||
]
|
||||
}, {
|
||||
// Test pivot to "apples" link from the table cell.
|
||||
accOrElmOrID: "apples",
|
||||
oldAccOrElmOrID: "cell",
|
||||
expectedUtterance: [
|
||||
["list 4 items", "First item", "link", "Apples"],
|
||||
["Apples", "link", "First item", "list 4 items"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["*", "lnk", "Apples"],
|
||||
["*", "Apples", "lnk"]
|
||||
]
|
||||
}, {
|
||||
// Test pivot to 'bananas' link from 'apples' link.
|
||||
accOrElmOrID: "bananas",
|
||||
oldAccOrElmOrID: "apples",
|
||||
expectedUtterance: [["link", "Bananas"], ["Bananas", "link"]],
|
||||
expectedBraille: [["*", "lnk", "Bananas"], ["*", "Bananas", "lnk"]]
|
||||
}, {
|
||||
// test unavailable state utterance
|
||||
accOrElmOrID: 'unavailableButton',
|
||||
expectedUtterance: [["unavailable button", "I am unavailable"],
|
||||
["I am unavailable", "unavailable button"]],
|
||||
expectedBraille: [["btn", "I am unavailable"],
|
||||
["I am unavailable", "btn"]]
|
||||
}, {
|
||||
// test expanded state utterance
|
||||
accOrElmOrID: 'expandedButton',
|
||||
expectedUtterance: [["expanded button", "I am expanded"],
|
||||
["I am expanded", "expanded button"]],
|
||||
expectedBraille: [["btn", "I am expanded"],
|
||||
["I am expanded", "btn"]]
|
||||
}, {
|
||||
// test collapsed state utterance
|
||||
accOrElmOrID: 'collapsedButton',
|
||||
expectedUtterance: [["collapsed button", "I am collapsed"],
|
||||
["I am collapsed", "collapsed button"]],
|
||||
expectedBraille: [["btn", "I am collapsed"],
|
||||
["I am collapsed", "btn"]]
|
||||
}, {
|
||||
// test required state utterance
|
||||
accOrElmOrID: 'requiredInput',
|
||||
expectedUtterance: [["required entry", "I am required"],
|
||||
["I am required", "required entry"]],
|
||||
expectedBraille: [["entry", "I am required"],
|
||||
["I am required", "entry"]]
|
||||
}, {
|
||||
// test has popup state utterance
|
||||
accOrElmOrID: 'hasPopupButton',
|
||||
expectedUtterance: [["has pop up button menu", "I have a popup"],
|
||||
["I have a popup", "has pop up button menu"]],
|
||||
expectedBraille: [["button menu", "I have a popup"],
|
||||
["I have a popup", "button menu"]]
|
||||
}, {
|
||||
// Test selected tab
|
||||
accOrElmOrID: 'tab1',
|
||||
expectedUtterance: [['tab list', 'selected tab 1 of 2', 'Account'],
|
||||
['Account', 'selected tab 1 of 2', 'tab list']],
|
||||
expectedBraille: [['tab 1 of 2', 'Account'],
|
||||
['Account', 'tab 1 of 2']]
|
||||
}, {
|
||||
// Test unselected tab
|
||||
accOrElmOrID: 'tab2',
|
||||
expectedUtterance: [['tab list', 'tab 2 of 2', 'Advanced'],
|
||||
['Advanced', 'tab 2 of 2', 'tab list']],
|
||||
expectedBraille: [['tab 2 of 2', 'Advanced'],
|
||||
['Advanced', 'tab 2 of 2']]
|
||||
},
|
||||
|
||||
{
|
||||
// Landing on this label should mimic landing on the checkbox.
|
||||
accOrElmOrID: "label1",
|
||||
expectedUtterance: [['not checked check button', 'Orange'],
|
||||
['Orange', 'not checked check button']],
|
||||
expectedBraille: [['( )', 'Orange'],
|
||||
['Orange', '( )']]
|
||||
},
|
||||
{
|
||||
// Here we get a top-level view of the form.
|
||||
accOrElmOrID: "form1",
|
||||
expectedUtterance: [['label', 'not checked check button', 'Orange', 'Orange',
|
||||
'not checked check button', 'Blue', 'label', 'Blue'],
|
||||
['Orange', 'not checked check button', 'Orange', 'label',
|
||||
'Blue', 'not checked check button', 'Blue', 'label']],
|
||||
expectedBraille: [['label', '( )', 'Orange', 'Orange',
|
||||
'( )', 'Blue', 'label', 'Blue'],
|
||||
['Orange', '( )', 'Orange', 'label',
|
||||
'Blue', '( )', 'Blue', 'label']]
|
||||
},
|
||||
{
|
||||
// This is a non-nesting label.
|
||||
accOrElmOrID: "label2",
|
||||
expectedUtterance: [['label', 'Blue'], ['Blue', 'label']],
|
||||
expectedBraille: [['label', 'Blue'], ['Blue', 'label']]
|
||||
},
|
||||
{
|
||||
// This is a distinct control.
|
||||
accOrElmOrID: "input2",
|
||||
expectedUtterance: [['not checked check button', 'Blue'],
|
||||
['Blue', 'not checked check button']],
|
||||
expectedBraille: [['( )', 'Blue'],
|
||||
['Blue', '( )']]
|
||||
},
|
||||
{
|
||||
// This is a nested control.
|
||||
accOrElmOrID: "input1",
|
||||
expectedUtterance: [['not checked check button', 'Orange'],
|
||||
['Orange', 'not checked check button']],
|
||||
expectedBraille: [['( )', 'Orange'],
|
||||
['Orange', '( )']]
|
||||
},
|
||||
{
|
||||
// Landing on this label should mimic landing on the entry.
|
||||
accOrElmOrID: "label3",
|
||||
expectedUtterance: [['entry', 'Joe', 'First name:'],
|
||||
['First name:', 'Joe', 'entry']],
|
||||
expectedBraille: [['entry', 'Joe', 'First name:'],
|
||||
['First name:', 'Joe', 'entry']]
|
||||
},
|
||||
{
|
||||
// This is a nested control with a value.
|
||||
accOrElmOrID: "input3",
|
||||
expectedUtterance: [['entry', 'Joe', 'First name:'],
|
||||
['First name:', 'Joe', 'entry']],
|
||||
expectedBraille: [['entry', 'Joe', 'First name:'],
|
||||
['First name:', 'Joe', 'entry']]
|
||||
},
|
||||
{
|
||||
// This is a nested control with a value.
|
||||
accOrElmOrID: "input4",
|
||||
expectedUtterance: [['slider', '3', 'Points:'],
|
||||
['Points:', '3', 'slider']],
|
||||
expectedBraille: [['slider', '3', 'Points:'],
|
||||
['Points:', '3', 'slider']]
|
||||
},{
|
||||
accOrElmOrID: "password",
|
||||
expectedUtterance: [["password text", "Secret Password"],
|
||||
["Secret Password", "password text"]],
|
||||
expectedBraille: [["passwdtxt", "Secret Password"],
|
||||
["Secret Password", "passwdtxt"]]
|
||||
},{
|
||||
accOrElmOrID: "input5",
|
||||
expectedUtterance: [["checked check button", "Boring label"],
|
||||
["Boring label", "checked check button"]],
|
||||
expectedBraille: [["(x)", "Boring label"],
|
||||
["Boring label", "(x)"]]
|
||||
},{
|
||||
accOrElmOrID: "radio_unselected",
|
||||
expectedUtterance: [["not checked radio button", "any old radio button"],
|
||||
["any old radio button", "not checked radio button"]],
|
||||
expectedBraille: [["( )", "any old radio button"],
|
||||
["any old radio button", "( )"]]
|
||||
},{
|
||||
accOrElmOrID: "radio_selected",
|
||||
expectedUtterance: [["checked radio button", "a unique radio button"],
|
||||
["a unique radio button", "checked radio button"]],
|
||||
expectedBraille: [["(x)", "a unique radio button"],
|
||||
["a unique radio button", "(x)"]]
|
||||
},{
|
||||
accOrElmOrID: "togglebutton_notpressed",
|
||||
expectedUtterance: [["not checked toggle button", "I ain't pressed"],
|
||||
["I ain't pressed", "not checked toggle button"]],
|
||||
expectedBraille: [["( )", "I ain't pressed"],
|
||||
["I ain't pressed", "( )"]]
|
||||
},{
|
||||
accOrElmOrID: "togglebutton_pressed",
|
||||
expectedUtterance: [["not checked toggle button", "I am pressed!"],
|
||||
["I am pressed!", "not checked toggle button"]],
|
||||
expectedBraille: [["(x)", "I am pressed!"],
|
||||
["I am pressed!", "(x)"]]
|
||||
}
|
||||
];
|
||||
|
||||
// Test all possible utterance order preference values.
|
||||
tests.forEach(function run(test) {
|
||||
var utteranceOrderValues = [0, 1];
|
||||
utteranceOrderValues.forEach(
|
||||
function testUtteranceOrder(utteranceOrder) {
|
||||
SpecialPowers.setIntPref(PREF_UTTERANCE_ORDER, utteranceOrder);
|
||||
testOutput(test.expectedUtterance[utteranceOrder],
|
||||
test.accOrElmOrID, test.oldAccOrElmOrID, 1);
|
||||
testOutput(test.expectedBraille[utteranceOrder],
|
||||
test.accOrElmOrID, test.oldAccOrElmOrID, 0);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// If there was an original utterance order preference, revert to it.
|
||||
SpecialPowers.clearUserPref(PREF_UTTERANCE_ORDER);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=753984"
|
||||
title="[AccessFu] utterance order test">
|
||||
Mozilla Bug 753984</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=758675"
|
||||
title="[AccessFu] Add support for accDescription">
|
||||
Mozilla Bug 758675</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=876475"
|
||||
title="[AccessFu] Make braille output less verbose">
|
||||
Mozilla Bug 876475</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=924284"
|
||||
title="[AccessFu] Output accessible values">
|
||||
Mozilla Bug 924284</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=925845"
|
||||
title="[AccessFu] Unify output tests">
|
||||
Mozilla Bug 925845</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<a id="anchor" href="#test" title="title"></a>
|
||||
<a id="anchor_titleandtext" href="#test" title="goes to the tests">Tests</a>
|
||||
<a id="anchor_duplicatedtitleandtext" href="#test" title="Tests">Tests</a>
|
||||
<a id="anchor_arialabelandtext" href="#test" aria-label="Tests" title="goes to the tests">Tests</a>
|
||||
<textarea id="textarea" cols="80" rows="5">
|
||||
This is the text area text.
|
||||
</textarea>
|
||||
<h1 id="heading" title="Test heading"></h1>
|
||||
<ol id="list">
|
||||
<li id="li_one">list one</li>
|
||||
</ol>
|
||||
<dl id="dlist">
|
||||
<dd id="dd_one">
|
||||
dd one
|
||||
</dd>
|
||||
</dl>
|
||||
<table>
|
||||
<caption>Fruits and vegetables</caption>
|
||||
<tr>
|
||||
<td id="cell">
|
||||
<ul style="list-style-type: none;">
|
||||
<li><a id="apples" href="#">Apples</a></li>
|
||||
<li><a id="bananas" href="#">Bananas</a></li>
|
||||
<li><a href="#">Peaches</a></li>
|
||||
<li>
|
||||
<a href="#">
|
||||
Plums
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button id="unavailableButton" disabled>I am unavailable</button>
|
||||
<button id="expandedButton" aria-expanded="true">I am expanded</button>
|
||||
<button id="collapsedButton" aria-expanded="false">I am collapsed</button>
|
||||
<input id="requiredInput" required placeholder="I am required" />
|
||||
<button id="hasPopupButton" aria-haspopup="true">I have a popup</button>
|
||||
<div role="tablist">
|
||||
<a id="tab1" href="#" role="tab" aria-selected="true">Account</a>
|
||||
<a id="tab2" href="#" role="tab" aria-selected="false">Advanced</a>
|
||||
</div>
|
||||
<form id="form1">
|
||||
<label id="label1"><input id="input1" type="checkbox">Orange</label>
|
||||
<input id="input2" type="checkbox"><label id="label2" for="input2">Blue</label>
|
||||
</form>
|
||||
<label id="label3">First name: <input id="input3" value="Joe"></label>
|
||||
<label id="label4">Points:
|
||||
<input id="input4" type="range" name="points" min="1" max="10" value="3">
|
||||
</label>
|
||||
<label for="input5">Boring label</label><input id="input5" type="checkbox" checked></input>
|
||||
<label for="password">Secret Password</label><input id="password" type="password"></input>
|
||||
<label for="radio_unselected">any old radio button</label><input id="radio_unselected" type="radio"></input>
|
||||
<label for="radio_selected">a unique radio button</label><input id="radio_selected" type="radio" checked></input>
|
||||
<input id="date" type="date" value="2011-09-29" />
|
||||
<input id="email" type="email" value="test@example.com" />
|
||||
<input id="search" type="search" value="This is a search" />
|
||||
<input id="tel" type="tel" value="555-5555" />
|
||||
<input id="url" type="url" value="http://example.com" />
|
||||
<input id="textInput" type="text" value="This is text." />
|
||||
<label>Points: <input id="range" type="range" name="points" min="1" max="10" value="3"></label>
|
||||
<div id="togglebutton_notpressed" aria-pressed="false" role="button" tabindex="-1">I ain't pressed</div>
|
||||
<div id="togglebutton_pressed" aria-pressed="true" role="button" tabindex="-1">I am pressed!</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,316 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=753984
|
||||
-->
|
||||
<head>
|
||||
<title>[AccessFu] utterance order test</title>
|
||||
<meta charset="utf-8">
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="./output.js"></script>
|
||||
<script type="application/javascript">
|
||||
|
||||
function doTest() {
|
||||
// Test the following accOrElmOrID (with optional old accOrElmOrID).
|
||||
// Note: each accOrElmOrID entry maps to a unique object utterance
|
||||
// generator function within the UtteranceGenerator.
|
||||
var tests = [{
|
||||
accOrElmOrID: "anchor",
|
||||
expected: [["link", "title"], ["title", "link"]]
|
||||
}, {
|
||||
accOrElmOrID: "anchor_titleandtext",
|
||||
expected: [[
|
||||
"link", "goes to the tests -", "Tests"
|
||||
], [
|
||||
"Tests", "- goes to the tests", "link"
|
||||
]]
|
||||
}, {
|
||||
accOrElmOrID: "anchor_duplicatedtitleandtext",
|
||||
expected: [["link", "Tests"], ["Tests", "link"]]
|
||||
}, {
|
||||
accOrElmOrID: "anchor_arialabelandtext",
|
||||
expected: [[
|
||||
"link", "goes to the tests - Tests"
|
||||
], [
|
||||
"Tests - goes to the tests", "link"
|
||||
]]
|
||||
}, {
|
||||
accOrElmOrID: "textarea",
|
||||
expected: [[
|
||||
"text area", "This is the text area text."
|
||||
], [
|
||||
"This is the text area text.", "text area"
|
||||
]]
|
||||
}, {
|
||||
accOrElmOrID: "heading",
|
||||
expected: [
|
||||
["heading level 1", "Test heading"],
|
||||
["Test heading", "heading level 1"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "list",
|
||||
expected: [
|
||||
["list 1 item", "First item", "1.", "list one"],
|
||||
["1.", "list one", "First item", "list 1 item"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "dlist",
|
||||
expected: [
|
||||
["definition list 0.5 items", "dd one"],
|
||||
["dd one", "definition list 0.5 items"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "li_one",
|
||||
expected: [
|
||||
["list 1 item", "First item", "1.", "list one"],
|
||||
["1.", "list one", "First item", "list 1 item"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "cell",
|
||||
expected: [[
|
||||
"table with 1 column and 1 row", "Fruits and vegetables",
|
||||
"Column 1 Row 1", "list 4 items", "First item", "link", "Apples",
|
||||
"link", "Bananas", "link", "Peaches", "Last item", "link", "Plums"
|
||||
], [
|
||||
"Apples", "link", "First item", "Bananas", "link", "Peaches",
|
||||
"link", "Plums", "link", "Last item", "list 4 items",
|
||||
"Column 1 Row 1", "Fruits and vegetables",
|
||||
"table with 1 column and 1 row"
|
||||
]]
|
||||
}, {
|
||||
accOrElmOrID: "date",
|
||||
expected: [["date entry", "2011-09-29"], ["2011-09-29", "date entry"]]
|
||||
}, {
|
||||
accOrElmOrID: "email",
|
||||
expected: [
|
||||
["e-mail entry", "test@example.com"],
|
||||
["test@example.com", "e-mail entry"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "search",
|
||||
expected: [
|
||||
["search entry", "This is a search"],
|
||||
["This is a search", "search entry"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "tel",
|
||||
expected: [
|
||||
["telephone entry", "555-5555"], ["555-5555", "telephone entry"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "url",
|
||||
expected: [
|
||||
["URL entry", "http://example.com"],
|
||||
["http://example.com", "URL entry"]
|
||||
]
|
||||
}, {
|
||||
accOrElmOrID: "textInput",
|
||||
expected: [["entry", "This is text."], ["This is text.", "entry"]]
|
||||
}, {
|
||||
// Test pivot to list from li_one.
|
||||
accOrElmOrID: "list",
|
||||
oldAccOrElmOrID: "li_one",
|
||||
expected: [
|
||||
["list 1 item", "First item", "1.", "list one"],
|
||||
["1.", "list one", "First item", "list 1 item"]
|
||||
]
|
||||
}, {
|
||||
// Test pivot to "apples" link from the table cell.
|
||||
accOrElmOrID: "apples",
|
||||
oldAccOrElmOrID: "cell",
|
||||
expected: [
|
||||
["list 4 items", "First item", "link", "Apples"],
|
||||
["Apples", "link", "First item", "list 4 items"]
|
||||
]
|
||||
}, {
|
||||
// Test pivot to 'bananas' link from 'apples' link.
|
||||
accOrElmOrID: "bananas",
|
||||
oldAccOrElmOrID: "apples",
|
||||
expected: [["link", "Bananas"], ["Bananas", "link"]]
|
||||
}, {
|
||||
// test unavailable state utterance
|
||||
accOrElmOrID: 'unavailableButton',
|
||||
expected: [["unavailable button", "I am unavailable"],
|
||||
["I am unavailable", "unavailable button"]]
|
||||
}, {
|
||||
// test expanded state utterance
|
||||
accOrElmOrID: 'expandedButton',
|
||||
expected: [["expanded button", "I am expanded"],
|
||||
["I am expanded", "expanded button"]]
|
||||
}, {
|
||||
// test collapsed state utterance
|
||||
accOrElmOrID: 'collapsedButton',
|
||||
expected: [["collapsed button", "I am collapsed"],
|
||||
["I am collapsed", "collapsed button"]]
|
||||
}, {
|
||||
// test required state utterance
|
||||
accOrElmOrID: 'requiredInput',
|
||||
expected: [["required entry", "I am required"],
|
||||
["I am required", "required entry"]]
|
||||
}, {
|
||||
// test has popup state utterance
|
||||
accOrElmOrID: 'hasPopupButton',
|
||||
expected: [["has pop up button menu", "I have a popup"],
|
||||
["I have a popup", "has pop up button menu"]]
|
||||
}, {
|
||||
// Test selected tab
|
||||
accOrElmOrID: 'tab1',
|
||||
expected: [['tab list', 'selected tab 1 of 2', 'Account'],
|
||||
['Account', 'selected tab 1 of 2', 'tab list']]
|
||||
}, {
|
||||
// Test unselected tab
|
||||
accOrElmOrID: 'tab2',
|
||||
expected: [['tab list', 'tab 2 of 2', 'Advanced'],
|
||||
['Advanced', 'tab 2 of 2', 'tab list']]
|
||||
},
|
||||
|
||||
{
|
||||
// Landing on this label should mimic landing on the checkbox.
|
||||
accOrElmOrID: "label1",
|
||||
expected: [['not checked check button', 'Orange'],
|
||||
['Orange', 'not checked check button']]
|
||||
},
|
||||
{
|
||||
// Here we get a top-level view of the form.
|
||||
accOrElmOrID: "form1",
|
||||
expected: [['label', 'not checked check button', 'Orange', 'Orange',
|
||||
'not checked check button', 'Blue', 'label', 'Blue'],
|
||||
['Orange', 'not checked check button', 'Orange', 'label',
|
||||
'Blue', 'not checked check button', 'Blue', 'label']]
|
||||
},
|
||||
{
|
||||
// This is a non-nesting label.
|
||||
accOrElmOrID: "label2",
|
||||
expected: [['label', 'Blue'], ['Blue', 'label']]
|
||||
},
|
||||
{
|
||||
// This is a distinct control.
|
||||
accOrElmOrID: "input2",
|
||||
expected: [['not checked check button', 'Blue'],
|
||||
['Blue', 'not checked check button']]
|
||||
},
|
||||
{
|
||||
// This is a nested control.
|
||||
accOrElmOrID: "input1",
|
||||
expected: [['not checked check button', 'Orange'],
|
||||
['Orange', 'not checked check button']]
|
||||
},
|
||||
{
|
||||
// Landing on this label should mimic landing on the entry.
|
||||
accOrElmOrID: "label3",
|
||||
expected: [['entry', 'Joe', 'First name:'],
|
||||
['First name:', 'Joe', 'entry']]
|
||||
},
|
||||
{
|
||||
// This is a nested control with a value.
|
||||
accOrElmOrID: "input3",
|
||||
expected: [['entry', 'Joe', 'First name:'],
|
||||
['First name:', 'Joe', 'entry']]
|
||||
},
|
||||
{
|
||||
// This is a nested control with a value.
|
||||
accOrElmOrID: "input4",
|
||||
expected: [['slider', '3', 'Points:'],
|
||||
['Points:', '3', 'slider']]
|
||||
}];
|
||||
|
||||
// Test all possible utterance order preference values.
|
||||
tests.forEach(function run(test) {
|
||||
var utteranceOrderValues = [0, 1];
|
||||
utteranceOrderValues.forEach(
|
||||
function testUtteranceOrder(utteranceOrder) {
|
||||
SpecialPowers.setIntPref(PREF_UTTERANCE_ORDER, utteranceOrder);
|
||||
var expected = test.expected[utteranceOrder];
|
||||
testOutput(expected, test.accOrElmOrID, test.oldAccOrElmOrID, 1);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
// If there was an original utterance order preference, revert to it.
|
||||
SpecialPowers.clearUserPref(PREF_UTTERANCE_ORDER);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=753984"
|
||||
title="[AccessFu] utterance order test">
|
||||
Mozilla Bug 753984</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=758675"
|
||||
title="[AccessFu] Add support for accDescription">
|
||||
Mozilla Bug 758675</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
<a id="anchor" href="#test" title="title"></a>
|
||||
<a id="anchor_titleandtext" href="#test" title="goes to the tests">Tests</a>
|
||||
<a id="anchor_duplicatedtitleandtext" href="#test" title="Tests">Tests</a>
|
||||
<a id="anchor_arialabelandtext" href="#test" aria-label="Tests" title="goes to the tests">Tests</a>
|
||||
<textarea id="textarea" cols="80" rows="5">
|
||||
This is the text area text.
|
||||
</textarea>
|
||||
<h1 id="heading" title="Test heading"></h1>
|
||||
<ol id="list">
|
||||
<li id="li_one">list one</li>
|
||||
</ol>
|
||||
<dl id="dlist">
|
||||
<dd id="dd_one">
|
||||
dd one
|
||||
</dd>
|
||||
</dl>
|
||||
<table>
|
||||
<caption>Fruits and vegetables</caption>
|
||||
<tr>
|
||||
<td id="cell">
|
||||
<ul style="list-style-type: none;">
|
||||
<li><a id="apples" href="#">Apples</a></li>
|
||||
<li><a id="bananas" href="#">Bananas</a></li>
|
||||
<li><a href="#">Peaches</a></li>
|
||||
<li>
|
||||
<a href="#">
|
||||
Plums
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<button id="unavailableButton" disabled>I am unavailable</button>
|
||||
<button id="expandedButton" aria-expanded="true">I am expanded</button>
|
||||
<button id="collapsedButton" aria-expanded="false">I am collapsed</button>
|
||||
<input id="requiredInput" required placeholder="I am required" />
|
||||
<button id="hasPopupButton" aria-haspopup="true">I have a popup</button>
|
||||
<div role="tablist">
|
||||
<a id="tab1" href="#" role="tab" aria-selected="true">Account</a>
|
||||
<a id="tab2" href="#" role="tab" aria-selected="false">Advanced</a>
|
||||
</div>
|
||||
<form id="form1">
|
||||
<label id="label1"><input id="input1" type="checkbox">Orange</label>
|
||||
<input id="input2" type="checkbox"><label id="label2" for="input2">Blue</label>
|
||||
</form>
|
||||
<label id="label3">First name: <input id="input3" value="Joe"></label>
|
||||
<label id="label4">Points:
|
||||
<input id="input4" type="range" name="points" min="1" max="10" value="3">
|
||||
</label>
|
||||
<input id="date" type="date" value="2011-09-29" />
|
||||
<input id="email" type="email" value="test@example.com" />
|
||||
<input id="search" type="search" value="This is a search" />
|
||||
<input id="tel" type="tel" value="555-5555" />
|
||||
<input id="url" type="url" value="http://example.com" />
|
||||
<input id="textInput" type="text" value="This is text." />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
12
configure.in
12
configure.in
@ -1351,12 +1351,14 @@ if test "$GNU_CC"; then
|
||||
# -Wpointer-arith - good to have
|
||||
# -Wdeclaration-after-statement - MSVC doesn't like these
|
||||
# -Werror=return-type - catches missing returns, zero false positives
|
||||
# -Werror=int-to-pointer-cast - catches cast to pointer from integer of different size
|
||||
# -Wtype-limits - catches overflow bugs, few false positives
|
||||
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
|
||||
# -Wsign-compare - catches comparison of signed and unsigned types
|
||||
#
|
||||
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -Wpointer-arith -Wdeclaration-after-statement"
|
||||
MOZ_C_SUPPORTS_WARNING(-W, error=return-type, ac_c_has_werror_return_type)
|
||||
MOZ_C_SUPPORTS_WARNING(-W, error=int-to-pointer-cast, ac_c_has_werror_int_to_pointer_cast)
|
||||
MOZ_C_SUPPORTS_WARNING(-W, type-limits, ac_c_has_wtype_limits)
|
||||
MOZ_C_SUPPORTS_WARNING(-W, empty-body, ac_c_has_wempty_body)
|
||||
MOZ_C_SUPPORTS_WARNING(-W, sign-compare, ac_c_has_sign_compare)
|
||||
@ -1415,12 +1417,14 @@ if test "$GNU_CXX"; then
|
||||
# -Wpointer-arith - good to have
|
||||
# -Woverloaded-virtual - ???
|
||||
# -Werror=return-type - catches missing returns, zero false positives
|
||||
# -Werror=int-to-pointer-cast - catches cast to pointer from integer of different size
|
||||
# -Wtype-limits - catches overflow bugs, few false positives
|
||||
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
|
||||
# -Wsign-compare - catches comparison of signed and unsigned types
|
||||
#
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall -Wpointer-arith -Woverloaded-virtual"
|
||||
MOZ_CXX_SUPPORTS_WARNING(-W, error=return-type, ac_cxx_has_werror_return_type)
|
||||
MOZ_CXX_SUPPORTS_WARNING(-W, error=int-to-pointer-cast, ac_cxx_has_werror_int_to_pointer_cast)
|
||||
MOZ_CXX_SUPPORTS_WARNING(-W, type-limits, ac_cxx_has_wtype_limits)
|
||||
MOZ_CXX_SUPPORTS_WARNING(-W, empty-body, ac_cxx_has_wempty_body)
|
||||
MOZ_CXX_SUPPORTS_WARNING(-W, sign-compare, ac_cxx_has_sign_compare)
|
||||
@ -7742,8 +7746,14 @@ else
|
||||
else
|
||||
echo '#include <stdio.h>' > dummy-hello.c
|
||||
changequote(,)
|
||||
CL_INCLUDES_PREFIX=`${CC} -showIncludes -c -Fonul dummy-hello.c 2>&1 | sed -ne 's/^\([^:]*:[^:]*:\).*stdio.h$/\1/p'`
|
||||
dnl This output is localized, split at the first double space or colon and space.
|
||||
_CL_PREFIX_REGEX="^\([^:]*:.*[ :] \)\(.*stdio.h\)$"
|
||||
CL_INCLUDES_PREFIX=`${CC} -showIncludes -c -Fonul dummy-hello.c 2>&1 | sed -ne 's/'"$_CL_PREFIX_REGEX"'/\1/p'`
|
||||
_CL_STDIO_PATH=`${CC} -showIncludes -c -Fonul dummy-hello.c 2>&1 | sed -ne 's/'"$_CL_PREFIX_REGEX"'/\2/p'`
|
||||
changequote([,])
|
||||
if ! test -e "$_CL_STDIO_PATH"; then
|
||||
AC_MSG_ERROR([Unable to parse cl -showIncludes prefix. This compiler's locale has an unsupported formatting.])
|
||||
fi
|
||||
if test -z "$CL_INCLUDES_PREFIX"; then
|
||||
AC_MSG_ERROR([Cannot find cl -showIncludes prefix.])
|
||||
fi
|
||||
|
@ -40,7 +40,7 @@ bool WebGLQuery::IsActive() const
|
||||
|
||||
MOZ_ASSERT(targetSlot, "unknown query object's type");
|
||||
|
||||
return *targetSlot == this;
|
||||
return targetSlot && *targetSlot == this;
|
||||
}
|
||||
|
||||
|
||||
|
@ -629,6 +629,25 @@ ManifestHelper.prototype = {
|
||||
return {};
|
||||
},
|
||||
|
||||
get biggestIconURL() {
|
||||
let icons = this._localeProp("icons");
|
||||
if (!icons) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let iconSizes = Object.keys(icons);
|
||||
if (iconSizes.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
iconSizes.sort((a, b) => a - b);
|
||||
let biggestIconSize = iconSizes.pop();
|
||||
let biggestIcon = icons[biggestIconSize];
|
||||
let biggestIconURL = this._origin.resolve(biggestIcon);
|
||||
|
||||
return biggestIconURL;
|
||||
},
|
||||
|
||||
iconURLForSize: function(aSize) {
|
||||
let icons = this._localeProp("icons");
|
||||
if (!icons)
|
||||
|
@ -2546,7 +2546,8 @@ nsGlobalWindow::SetNewDocument(nsIDocument* aDocument,
|
||||
// make sure the cached document property gets updated.
|
||||
|
||||
// XXXmarkh - tell other languages about this?
|
||||
::JS_DeleteProperty(cx, currentInner->mJSObject, "document");
|
||||
JS::Rooted<JSObject*> obj(cx, currentInner->mJSObject);
|
||||
::JS_DeleteProperty(cx, obj, "document");
|
||||
}
|
||||
} else {
|
||||
newInnerWindow->InnerSetNewDocument(aDocument);
|
||||
@ -10865,7 +10866,9 @@ nsGlobalWindow::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
nsCOMPtr<nsIDOMStorageManager> storageManager = do_QueryInterface(GetDocShell());
|
||||
if (storageManager) {
|
||||
rv = storageManager->CheckStorage(principal, changingStorage, &check);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
if (!check) {
|
||||
|
@ -2350,6 +2350,36 @@ CreateGlobal(JSContext* aCx, T* aObject, nsWrapperCache* aCache,
|
||||
return global;
|
||||
}
|
||||
|
||||
/*
|
||||
* Holds a jsid that is initialized to an interned string, with conversion to
|
||||
* Handle<jsid>.
|
||||
*/
|
||||
class InternedStringId
|
||||
{
|
||||
jsid id;
|
||||
|
||||
public:
|
||||
InternedStringId() : id(JSID_VOID) {}
|
||||
|
||||
bool init(JSContext *cx, const char *string) {
|
||||
MOZ_ASSERT(id == JSID_VOID);
|
||||
JSString* str = JS_InternString(cx, string);
|
||||
if (!str)
|
||||
return false;
|
||||
id = INTERNED_STRING_TO_JSID(cx, str);
|
||||
return true;
|
||||
}
|
||||
|
||||
operator const jsid& () {
|
||||
return id;
|
||||
}
|
||||
|
||||
operator JS::Handle<jsid> () {
|
||||
/* This is safe because we have interned the string. */
|
||||
return JS::Handle<jsid>::fromMarkedLocation(&id);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -38,7 +38,8 @@ DOMProxyShadows(JSContext* cx, JS::Handle<JSObject*> proxy, JS::Handle<jsid> id)
|
||||
JS::Value v = js::GetProxyExtra(proxy, JSPROXYSLOT_EXPANDO);
|
||||
if (v.isObject()) {
|
||||
bool hasOwn;
|
||||
if (!JS_AlreadyHasOwnPropertyById(cx, &v.toObject(), id, &hasOwn))
|
||||
Rooted<JSObject*> object(cx, &v.toObject());
|
||||
if (!JS_AlreadyHasOwnPropertyById(cx, object, id, &hasOwn))
|
||||
return js::ShadowCheckFailed;
|
||||
|
||||
return hasOwn ? js::Shadows : js::DoesntShadow;
|
||||
|
@ -68,8 +68,12 @@ this.DataStoreChangeNotifier = {
|
||||
receiveMessage: function(aMessage) {
|
||||
debug("receiveMessage");
|
||||
|
||||
// No check has to be done when the message is 'child-process-shutdown'
|
||||
// because at this point the target is already disconnected from
|
||||
// nsFrameMessageManager, so that assertAppHasStatus will always fail.
|
||||
let prefName = 'dom.testing.datastore_enabled_for_hosted_apps';
|
||||
if ((Services.prefs.getPrefType(prefName) == Services.prefs.PREF_INVALID ||
|
||||
if (aMessage.name != 'child-process-shutdown' &&
|
||||
(Services.prefs.getPrefType(prefName) == Services.prefs.PREF_INVALID ||
|
||||
!Services.prefs.getBoolPref(prefName)) &&
|
||||
!aMessage.target.assertAppHasStatus(Ci.nsIPrincipal.APP_STATUS_CERTIFIED)) {
|
||||
return;
|
||||
|
@ -711,7 +711,7 @@ nsJSObjWrapper::NP_InvokeDefault(NPObject *npobj, const NPVariant *args,
|
||||
|
||||
// static
|
||||
bool
|
||||
nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier id)
|
||||
nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier npid)
|
||||
{
|
||||
NPP npp = NPPStack::Peek();
|
||||
JSContext *cx = GetJSContext(npp);
|
||||
@ -733,11 +733,13 @@ nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier id)
|
||||
nsCxPusher pusher;
|
||||
pusher.Push(cx);
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
JSAutoCompartment ac(cx, npjsobj->mJSObj);
|
||||
JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
|
||||
JSAutoCompartment ac(cx, jsobj);
|
||||
|
||||
NS_ASSERTION(NPIdentifierIsInt(id) || NPIdentifierIsString(id),
|
||||
NS_ASSERTION(NPIdentifierIsInt(npid) || NPIdentifierIsString(npid),
|
||||
"id must be either string or int!\n");
|
||||
ok = ::JS_HasPropertyById(cx, npjsobj->mJSObj, NPIdentifierToJSId(id), &found);
|
||||
JS::Rooted<jsid> id(cx, NPIdentifierToJSId(npid));
|
||||
ok = ::JS_HasPropertyById(cx, jsobj, id, &found);
|
||||
return ok && found;
|
||||
}
|
||||
|
||||
@ -810,7 +812,7 @@ nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier id,
|
||||
|
||||
// static
|
||||
bool
|
||||
nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier id)
|
||||
nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier npid)
|
||||
{
|
||||
NPP npp = NPPStack::Peek();
|
||||
JSContext *cx = GetJSContext(npp);
|
||||
@ -833,17 +835,19 @@ nsJSObjWrapper::NP_RemoveProperty(NPObject *npobj, NPIdentifier id)
|
||||
pusher.Push(cx);
|
||||
AutoJSExceptionReporter reporter(cx);
|
||||
bool deleted = false;
|
||||
JSAutoCompartment ac(cx, npjsobj->mJSObj);
|
||||
JS::Rooted<JSObject*> obj(cx, npjsobj->mJSObj);
|
||||
JSAutoCompartment ac(cx, obj);
|
||||
|
||||
NS_ASSERTION(NPIdentifierIsInt(id) || NPIdentifierIsString(id),
|
||||
NS_ASSERTION(NPIdentifierIsInt(npid) || NPIdentifierIsString(npid),
|
||||
"id must be either string or int!\n");
|
||||
ok = ::JS_DeletePropertyById2(cx, npjsobj->mJSObj, NPIdentifierToJSId(id), &deleted);
|
||||
JS::Rooted<jsid> id(cx, NPIdentifierToJSId(npid));
|
||||
ok = ::JS_DeletePropertyById2(cx, obj, id, &deleted);
|
||||
if (ok && deleted) {
|
||||
// FIXME: See bug 425823, we shouldn't need to do this, and once
|
||||
// that bug is fixed we can remove this code.
|
||||
|
||||
bool hasProp;
|
||||
ok = ::JS_HasPropertyById(cx, npjsobj->mJSObj, NPIdentifierToJSId(id), &hasProp);
|
||||
ok = ::JS_HasPropertyById(cx, obj, id, &hasProp);
|
||||
|
||||
if (ok && hasProp) {
|
||||
// The property might have been deleted, but it got
|
||||
|
@ -457,7 +457,9 @@ DOMStorageManager::CheckStorage(nsIPrincipal* aPrincipal,
|
||||
|
||||
nsAutoCString scope;
|
||||
nsresult rv = CreateScopeKey(aPrincipal, scope);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
DOMStorageCache* cache = GetCache(scope);
|
||||
if (cache != pstorage->GetCache()) {
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#if defined(XP_WIN)
|
||||
#include <windows.h>
|
||||
#include <accctrl.h>
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
#include "jsapi.h"
|
||||
@ -680,6 +681,11 @@ static const dom::ConstantSpec gWinProperties[] =
|
||||
// GetFileAttributes error constant
|
||||
INT_CONSTANT(INVALID_FILE_ATTRIBUTES),
|
||||
|
||||
// GetNamedSecurityInfo and SetNamedSecurityInfo constants
|
||||
INT_CONSTANT(UNPROTECTED_DACL_SECURITY_INFORMATION),
|
||||
INT_CONSTANT(SE_FILE_OBJECT),
|
||||
INT_CONSTANT(DACL_SECURITY_INFORMATION),
|
||||
|
||||
// Errors
|
||||
INT_CONSTANT(ERROR_ACCESS_DENIED),
|
||||
INT_CONSTANT(ERROR_DIR_NOT_EMPTY),
|
||||
|
@ -320,7 +320,9 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent,
|
||||
case MULTITOUCH_INPUT: {
|
||||
const MultiTouchInput& multiTouchInput = aEvent.AsMultiTouchInput();
|
||||
if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_START) {
|
||||
mTouchCount++;
|
||||
// MULTITOUCH_START input contains all active touches of the current
|
||||
// session thus resetting mTouchCount.
|
||||
mTouchCount = multiTouchInput.mTouches.Length();
|
||||
mApzcForInputBlock = GetTargetAPZC(ScreenPoint(multiTouchInput.mTouches[0].mScreenPoint));
|
||||
if (multiTouchInput.mTouches.Length() == 1) {
|
||||
// If we have one touch point, this might be the start of a pan.
|
||||
@ -363,6 +365,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent,
|
||||
if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_CANCEL ||
|
||||
multiTouchInput.mType == MultiTouchInput::MULTITOUCH_END) {
|
||||
if (mTouchCount >= multiTouchInput.mTouches.Length()) {
|
||||
// MULTITOUCH_END input contains only released touches thus decrementing.
|
||||
mTouchCount -= multiTouchInput.mTouches.Length();
|
||||
} else {
|
||||
NS_WARNING("Got an unexpected touchend/touchcancel");
|
||||
@ -438,7 +441,9 @@ APZCTreeManager::ProcessTouchEvent(const WidgetTouchEvent& aEvent,
|
||||
return ret;
|
||||
}
|
||||
if (aEvent.message == NS_TOUCH_START) {
|
||||
mTouchCount++;
|
||||
// NS_TOUCH_START event contains all active touches of the current
|
||||
// session thus resetting mTouchCount.
|
||||
mTouchCount = aEvent.touches.Length();
|
||||
mApzcForInputBlock = GetTouchInputBlockAPZC(aEvent);
|
||||
if (mApzcForInputBlock) {
|
||||
// Cache apz transform so it can be used for future events in this block.
|
||||
@ -477,6 +482,7 @@ APZCTreeManager::ProcessTouchEvent(const WidgetTouchEvent& aEvent,
|
||||
if (aEvent.message == NS_TOUCH_CANCEL ||
|
||||
aEvent.message == NS_TOUCH_END) {
|
||||
if (mTouchCount >= aEvent.touches.Length()) {
|
||||
// NS_TOUCH_END event contains only released touches thus decrementing.
|
||||
mTouchCount -= aEvent.touches.Length();
|
||||
} else {
|
||||
NS_WARNING("Got an unexpected touchend/touchcancel");
|
||||
|
@ -541,6 +541,20 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFram
|
||||
return appliedTransform;
|
||||
}
|
||||
|
||||
static bool
|
||||
LayerHasNonContainerDescendants(ContainerLayer* aContainer)
|
||||
{
|
||||
for (Layer* child = aContainer->GetFirstChild();
|
||||
child; child = child->GetNextSibling()) {
|
||||
ContainerLayer* container = child->AsContainerLayer();
|
||||
if (!container || LayerHasNonContainerDescendants(container)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
AsyncCompositionManager::ApplyAsyncTransformToScrollbar(ContainerLayer* aLayer)
|
||||
{
|
||||
@ -551,6 +565,11 @@ AsyncCompositionManager::ApplyAsyncTransformToScrollbar(ContainerLayer* aLayer)
|
||||
// Note that it is possible that the content layer is no longer there; in
|
||||
// this case we don't need to do anything because there can't be an async
|
||||
// transform on the content.
|
||||
// We only apply the transform if the scroll-target layer has non-container
|
||||
// children (i.e. when it has some possibly-visible content). This is to
|
||||
// avoid moving scroll-bars in the situation that only a scroll information
|
||||
// layer has been built for a scroll frame, as this would result in a
|
||||
// disparity between scrollbars and visible content.
|
||||
for (Layer* scrollTarget = aLayer->GetPrevSibling();
|
||||
scrollTarget;
|
||||
scrollTarget = scrollTarget->GetPrevSibling()) {
|
||||
@ -565,6 +584,9 @@ AsyncCompositionManager::ApplyAsyncTransformToScrollbar(ContainerLayer* aLayer)
|
||||
if (metrics.mScrollId != aLayer->GetScrollbarTargetContainerId()) {
|
||||
continue;
|
||||
}
|
||||
if (!LayerHasNonContainerDescendants(scrollTarget->AsContainerLayer())) {
|
||||
return;
|
||||
}
|
||||
|
||||
gfx3DMatrix asyncTransform = gfx3DMatrix(apzc->GetCurrentAsyncTransform());
|
||||
gfx3DMatrix nontransientTransform = apzc->GetNontransientAsyncTransform();
|
||||
|
@ -1552,6 +1552,10 @@ void
|
||||
CompositorOGL::Pause()
|
||||
{
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (!gl() || gl()->IsDestroyed())
|
||||
return;
|
||||
|
||||
// ReleaseSurface internally calls MakeCurrent.
|
||||
gl()->ReleaseSurface();
|
||||
#endif
|
||||
}
|
||||
@ -1560,6 +1564,10 @@ bool
|
||||
CompositorOGL::Resume()
|
||||
{
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
if (!gl() || gl()->IsDestroyed())
|
||||
return false;
|
||||
|
||||
// RenewSurface internally calls MakeCurrent.
|
||||
return gl()->RenewSurface();
|
||||
#endif
|
||||
return true;
|
||||
|
@ -18,8 +18,6 @@
|
||||
#define SS2 0x4e
|
||||
#define SS3 0x4f
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
class nsISO2022CNToUnicode : public nsBasicDecoderSupport
|
||||
{
|
||||
public:
|
||||
@ -28,7 +26,8 @@ public:
|
||||
mPlaneID(0),
|
||||
mRunLength(0)
|
||||
{
|
||||
Telemetry::Accumulate(Telemetry::DECODER_INSTANTIATED_ISO2022CN, true);
|
||||
mozilla::Telemetry::Accumulate(
|
||||
mozilla::Telemetry::DECODER_INSTANTIATED_ISO2022CN, true);
|
||||
}
|
||||
|
||||
virtual ~nsISO2022CNToUnicode() {}
|
||||
|
@ -7,8 +7,6 @@
|
||||
#include "nsUCSupport.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
class nsShiftJISToUnicode : public nsBasicDecoderSupport
|
||||
{
|
||||
public:
|
||||
@ -85,7 +83,8 @@ public:
|
||||
mGB2312Decoder = nullptr;
|
||||
mEUCKRDecoder = nullptr;
|
||||
mISO88597Decoder = nullptr;
|
||||
Telemetry::Accumulate(Telemetry::DECODER_INSTANTIATED_ISO2022JP, true);
|
||||
mozilla::Telemetry::Accumulate(
|
||||
mozilla::Telemetry::DECODER_INSTANTIATED_ISO2022JP, true);
|
||||
}
|
||||
virtual ~nsISO2022JPToUnicodeV2()
|
||||
{
|
||||
|
@ -7,8 +7,6 @@
|
||||
#include "nsUCSupport.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
class nsISO2022KRToUnicode : public nsBasicDecoderSupport
|
||||
{
|
||||
public:
|
||||
@ -19,7 +17,8 @@ public:
|
||||
mData = 0;
|
||||
mEUCKRDecoder = nullptr;
|
||||
mRunLength = 0;
|
||||
Telemetry::Accumulate(Telemetry::DECODER_INSTANTIATED_ISO2022KR, true);
|
||||
mozilla::Telemetry::Accumulate(
|
||||
mozilla::Telemetry::DECODER_INSTANTIATED_ISO2022KR, true);
|
||||
}
|
||||
|
||||
virtual ~nsISO2022KRToUnicode()
|
||||
|
@ -138,6 +138,7 @@ struct NullPtr
|
||||
|
||||
namespace gc {
|
||||
struct Cell;
|
||||
struct PersistentRootedMarker;
|
||||
} /* namespace gc */
|
||||
|
||||
} /* namespace js */
|
||||
@ -1098,7 +1099,6 @@ MutableHandle<T>::MutableHandle(PersistentRooted<T> *root)
|
||||
ptr = root->address();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* A copyable, assignable global GC root type with arbitrary lifetime, an
|
||||
* infallible constructor, and automatic unrooting on destruction.
|
||||
@ -1132,9 +1132,10 @@ MutableHandle<T>::MutableHandle(PersistentRooted<T> *root)
|
||||
* marked when the object itself is marked.
|
||||
*/
|
||||
template<typename T>
|
||||
class PersistentRooted : public mozilla::LinkedListElement<PersistentRooted<T> > {
|
||||
typedef mozilla::LinkedList<PersistentRooted> List;
|
||||
typedef mozilla::LinkedListElement<PersistentRooted> Element;
|
||||
class PersistentRooted : private mozilla::LinkedListElement<PersistentRooted<T> > {
|
||||
friend class mozilla::LinkedList<PersistentRooted>;
|
||||
friend class mozilla::LinkedListElement<PersistentRooted>;
|
||||
friend class js::gc::PersistentRootedMarker;
|
||||
|
||||
void registerWithRuntime(JSRuntime *rt) {
|
||||
JS::shadow::Runtime *srt = JS::shadow::Runtime::asShadowRuntime(rt);
|
||||
|
@ -1137,12 +1137,14 @@ if test "$GNU_CC"; then
|
||||
# -Wpointer-arith - good to have
|
||||
# -Wdeclaration-after-statement - MSVC doesn't like these
|
||||
# -Werror=return-type - catches missing returns, zero false positives
|
||||
# -Werror=int-to-pointer-cast - catches cast to pointer from integer of different size
|
||||
# -Wtype-limits - catches overflow bugs, few false positives
|
||||
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
|
||||
# -Wsign-compare - catches comparison of signed and unsigned types
|
||||
#
|
||||
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wall -Wpointer-arith -Wdeclaration-after-statement"
|
||||
MOZ_C_SUPPORTS_WARNING(-W, error=return-type, ac_c_has_werror_return_type)
|
||||
MOZ_C_SUPPORTS_WARNING(-W, error=int-to-pointer-cast, ac_c_has_werror_int_to_pointer_cast)
|
||||
MOZ_C_SUPPORTS_WARNING(-W, empty-body, ac_c_has_wempty_body)
|
||||
MOZ_C_SUPPORTS_WARNING(-W, sign-compare, ac_c_has_sign_compare)
|
||||
|
||||
@ -1196,6 +1198,7 @@ if test "$GNU_CXX"; then
|
||||
# -Wpointer-arith - good to have
|
||||
# -Woverloaded-virtual - ???
|
||||
# -Werror=return-type - catches missing returns, zero false positives
|
||||
# -Werror=int-to-pointer-cast - catches cast to pointer from integer of different size
|
||||
# -Wtype-limits - catches overflow bugs, few false positives
|
||||
# -Wempty-body - catches bugs, e.g. "if (c); foo();", few false positives
|
||||
# -Werror=conversion-null - catches conversions between NULL and non-pointer types
|
||||
@ -1203,6 +1206,7 @@ if test "$GNU_CXX"; then
|
||||
#
|
||||
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wall -Wpointer-arith -Woverloaded-virtual"
|
||||
MOZ_CXX_SUPPORTS_WARNING(-W, error=return-type, ac_cxx_has_werror_return_type)
|
||||
MOZ_CXX_SUPPORTS_WARNING(-W, error=int-to-pointer-cast, ac_cxx_has_werror_int_to_pointer_cast)
|
||||
MOZ_CXX_SUPPORTS_WARNING(-W, type-limits, ac_cxx_has_wtype_limits)
|
||||
MOZ_CXX_SUPPORTS_WARNING(-W, empty-body, ac_cxx_has_wempty_body)
|
||||
MOZ_CXX_SUPPORTS_WARNING(-W, error=conversion-null, ac_cxx_has_werror_conversion_null)
|
||||
@ -3820,8 +3824,14 @@ else
|
||||
else
|
||||
echo '#include <stdio.h>' > dummy-hello.c
|
||||
changequote(,)
|
||||
CL_INCLUDES_PREFIX=`${CC} -showIncludes -c -Fonul dummy-hello.c 2>&1 | sed -ne 's/^\([^:]*:[^:]*:\).*stdio.h$/\1/p'`
|
||||
dnl This output is localized, split at the first double space or colon and space.
|
||||
_CL_PREFIX_REGEX="^\([^:]*:.*[ :] \)\(.*stdio.h\)$"
|
||||
CL_INCLUDES_PREFIX=`${CC} -showIncludes -c -Fonul dummy-hello.c 2>&1 | sed -ne 's/'"$_CL_PREFIX_REGEX"'/\1/p'`
|
||||
_CL_STDIO_PATH=`${CC} -showIncludes -c -Fonul dummy-hello.c 2>&1 | sed -ne 's/'"$_CL_PREFIX_REGEX"'/\2/p'`
|
||||
changequote([,])
|
||||
if ! test -e "$_CL_STDIO_PATH"; then
|
||||
AC_MSG_ERROR([Unable to parse cl -showIncludes prefix. This compiler's locale has an unsupported formatting.])
|
||||
fi
|
||||
if test -z "$CL_INCLUDES_PREFIX"; then
|
||||
AC_MSG_ERROR([Cannot find cl -showIncludes prefix.])
|
||||
fi
|
||||
|
@ -618,21 +618,35 @@ JSPropertyDescriptor::trace(JSTracer *trc)
|
||||
}
|
||||
}
|
||||
|
||||
// Mark a chain of PersistentRooted pointers that might be null.
|
||||
template<typename Referent>
|
||||
static void
|
||||
MarkPersistentRootedChain(JSTracer *trc,
|
||||
mozilla::LinkedList<PersistentRooted<Referent *> > &list,
|
||||
void (*marker)(JSTracer *trc, Referent **ref, const char *name),
|
||||
const char *name)
|
||||
namespace js {
|
||||
namespace gc {
|
||||
struct PersistentRootedMarker
|
||||
{
|
||||
for (PersistentRooted<Referent *> *r = list.getFirst();
|
||||
r != nullptr;
|
||||
r = r->getNext())
|
||||
template<typename Referent>
|
||||
static void
|
||||
markChainIfNotNull(JSTracer *trc,
|
||||
mozilla::LinkedList<PersistentRooted<Referent *> > &list,
|
||||
void (*marker)(JSTracer *trc, Referent **ref, const char *name),
|
||||
const char *name)
|
||||
{
|
||||
if (r->get())
|
||||
for (PersistentRooted<Referent *> *r = list.getFirst(); r; r = r->getNext()) {
|
||||
if (r->get())
|
||||
marker(trc, r->address(), name);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Referent>
|
||||
static void
|
||||
markChain(JSTracer *trc,
|
||||
mozilla::LinkedList<PersistentRooted<Referent> > &list,
|
||||
void (*marker)(JSTracer *trc, Referent *ref, const char *name),
|
||||
const char *name)
|
||||
{
|
||||
for (PersistentRooted<Referent> *r = list.getFirst(); r; r = r->getNext())
|
||||
marker(trc, r->address(), name);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -640,20 +654,21 @@ js::gc::MarkPersistentRootedChains(JSTracer *trc)
|
||||
{
|
||||
JSRuntime *rt = trc->runtime;
|
||||
|
||||
MarkPersistentRootedChain(trc, rt->functionPersistentRooteds, &MarkObjectRoot,
|
||||
"PersistentRooted<JSFunction *>");
|
||||
MarkPersistentRootedChain(trc, rt->objectPersistentRooteds, &MarkObjectRoot,
|
||||
"PersistentRooted<JSObject *>");
|
||||
MarkPersistentRootedChain(trc, rt->scriptPersistentRooteds, &MarkScriptRoot,
|
||||
"PersistentRooted<JSScript *>");
|
||||
MarkPersistentRootedChain(trc, rt->stringPersistentRooteds, &MarkStringRoot,
|
||||
"PersistentRooted<JSString *>");
|
||||
// Mark the PersistentRooted chains of types that may be null.
|
||||
PersistentRootedMarker::markChainIfNotNull(trc, rt->functionPersistentRooteds, &MarkObjectRoot,
|
||||
"PersistentRooted<JSFunction *>");
|
||||
PersistentRootedMarker::markChainIfNotNull(trc, rt->objectPersistentRooteds, &MarkObjectRoot,
|
||||
"PersistentRooted<JSObject *>");
|
||||
PersistentRootedMarker::markChainIfNotNull(trc, rt->scriptPersistentRooteds, &MarkScriptRoot,
|
||||
"PersistentRooted<JSScript *>");
|
||||
PersistentRootedMarker::markChainIfNotNull(trc, rt->stringPersistentRooteds, &MarkStringRoot,
|
||||
"PersistentRooted<JSString *>");
|
||||
|
||||
// Mark the PersistentRooted chains of types that are never null.
|
||||
for (JS::PersistentRootedId *r = rt->idPersistentRooteds.getFirst(); r != nullptr; r = r->getNext())
|
||||
MarkIdRoot(trc, r->address(), "PersistentRooted<jsid>");
|
||||
for (JS::PersistentRootedValue *r = rt->valuePersistentRooteds.getFirst(); r != nullptr; r = r->getNext())
|
||||
MarkValueRoot(trc, r->address(), "PersistentRooted<Value>");
|
||||
PersistentRootedMarker::markChain(trc, rt->idPersistentRooteds, &MarkIdRoot,
|
||||
"PersistentRooted<jsid>");
|
||||
PersistentRootedMarker::markChain(trc, rt->valuePersistentRooteds, &MarkValueRoot,
|
||||
"PersistentRooted<Value>");
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -87,17 +87,13 @@ class StoreBuffer
|
||||
* type of edge: e.g. Value or Cell*.
|
||||
*/
|
||||
template<typename T>
|
||||
class MonoTypeBuffer
|
||||
struct MonoTypeBuffer
|
||||
{
|
||||
friend class StoreBuffer;
|
||||
|
||||
LifoAlloc *storage_;
|
||||
|
||||
explicit MonoTypeBuffer() : storage_(nullptr) {}
|
||||
~MonoTypeBuffer() { js_delete(storage_); }
|
||||
|
||||
MonoTypeBuffer &operator=(const MonoTypeBuffer& other) MOZ_DELETE;
|
||||
|
||||
bool init() {
|
||||
if (!storage_)
|
||||
storage_ = js_new<LifoAlloc>(LifoAllocBlockSize);
|
||||
@ -142,6 +138,9 @@ class StoreBuffer
|
||||
|
||||
/* Mark the source of all edges in the store buffer. */
|
||||
void mark(StoreBuffer *owner, JSTracer *trc);
|
||||
|
||||
private:
|
||||
MonoTypeBuffer &operator=(const MonoTypeBuffer& other) MOZ_DELETE;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -149,10 +148,8 @@ class StoreBuffer
|
||||
* memory outside of the GC's control.
|
||||
*/
|
||||
template <typename T>
|
||||
class RelocatableMonoTypeBuffer : public MonoTypeBuffer<T>
|
||||
struct RelocatableMonoTypeBuffer : public MonoTypeBuffer<T>
|
||||
{
|
||||
friend class StoreBuffer;
|
||||
|
||||
/* Override compaction to filter out removed items. */
|
||||
void compactMoved(StoreBuffer *owner);
|
||||
virtual void compact(StoreBuffer *owner) MOZ_OVERRIDE;
|
||||
@ -163,17 +160,13 @@ class StoreBuffer
|
||||
}
|
||||
};
|
||||
|
||||
class GenericBuffer
|
||||
struct GenericBuffer
|
||||
{
|
||||
friend class StoreBuffer;
|
||||
|
||||
LifoAlloc *storage_;
|
||||
|
||||
explicit GenericBuffer() : storage_(nullptr) {}
|
||||
~GenericBuffer() { js_delete(storage_); }
|
||||
|
||||
GenericBuffer &operator=(const GenericBuffer& other) MOZ_DELETE;
|
||||
|
||||
bool init() {
|
||||
if (!storage_)
|
||||
storage_ = js_new<LifoAlloc>(LifoAllocBlockSize);
|
||||
@ -215,14 +208,13 @@ class StoreBuffer
|
||||
if (isAboutToOverflow())
|
||||
owner->setAboutToOverflow();
|
||||
}
|
||||
|
||||
private:
|
||||
GenericBuffer &operator=(const GenericBuffer& other) MOZ_DELETE;
|
||||
};
|
||||
|
||||
class CellPtrEdge
|
||||
struct CellPtrEdge
|
||||
{
|
||||
friend class StoreBuffer;
|
||||
friend class StoreBuffer::MonoTypeBuffer<CellPtrEdge>;
|
||||
friend class StoreBuffer::RelocatableMonoTypeBuffer<CellPtrEdge>;
|
||||
|
||||
Cell **edge;
|
||||
|
||||
explicit CellPtrEdge(Cell **v) : edge(v) {}
|
||||
@ -246,12 +238,8 @@ class StoreBuffer
|
||||
bool isTagged() const { return bool(uintptr_t(edge) & 1); }
|
||||
};
|
||||
|
||||
class ValueEdge
|
||||
struct ValueEdge
|
||||
{
|
||||
friend class StoreBuffer;
|
||||
friend class StoreBuffer::MonoTypeBuffer<ValueEdge>;
|
||||
friend class StoreBuffer::RelocatableMonoTypeBuffer<ValueEdge>;
|
||||
|
||||
JS::Value *edge;
|
||||
|
||||
explicit ValueEdge(JS::Value *v) : edge(v) {}
|
||||
@ -278,9 +266,6 @@ class StoreBuffer
|
||||
|
||||
struct SlotEdge
|
||||
{
|
||||
friend class StoreBuffer;
|
||||
friend class StoreBuffer::MonoTypeBuffer<SlotEdge>;
|
||||
|
||||
JSObject *object;
|
||||
uint32_t offset;
|
||||
int kind; // this is really just HeapSlot::Kind, but we can't see that type easily here
|
||||
@ -307,11 +292,8 @@ class StoreBuffer
|
||||
void mark(JSTracer *trc);
|
||||
};
|
||||
|
||||
class WholeCellEdges
|
||||
struct WholeCellEdges
|
||||
{
|
||||
friend class StoreBuffer;
|
||||
friend class StoreBuffer::MonoTypeBuffer<WholeCellEdges>;
|
||||
|
||||
Cell *tenured;
|
||||
|
||||
WholeCellEdges(Cell *cell) : tenured(cell) {
|
||||
@ -332,9 +314,8 @@ class StoreBuffer
|
||||
};
|
||||
|
||||
template <typename Key>
|
||||
class CallbackRef : public BufferableRef
|
||||
struct CallbackRef : public BufferableRef
|
||||
{
|
||||
public:
|
||||
typedef void (*MarkCallback)(JSTracer *trc, Key *key, void *data);
|
||||
|
||||
CallbackRef(MarkCallback cb, Key *k, void *d) : callback(cb), key(k), data(d) {}
|
||||
|
@ -789,7 +789,7 @@ CodeGenerator::visitRegExpTest(LRegExpTest *lir)
|
||||
}
|
||||
|
||||
typedef JSString *(*RegExpReplaceFn)(JSContext *, HandleString, HandleObject, HandleString);
|
||||
static const VMFunction RegExpReplaceInfo = FunctionInfo<RegExpReplaceFn>(regexp_replace);
|
||||
static const VMFunction RegExpReplaceInfo = FunctionInfo<RegExpReplaceFn>(RegExpReplace);
|
||||
|
||||
bool
|
||||
CodeGenerator::visitRegExpReplace(LRegExpReplace *lir)
|
||||
@ -799,7 +799,7 @@ CodeGenerator::visitRegExpReplace(LRegExpReplace *lir)
|
||||
else
|
||||
pushArg(ToRegister(lir->replacement()));
|
||||
|
||||
pushArg(ToRegister(lir->regexp()));
|
||||
pushArg(ToRegister(lir->pattern()));
|
||||
|
||||
if (lir->string()->isConstant())
|
||||
pushArg(ImmGCPtr(lir->string()->toConstant()->toString()));
|
||||
@ -809,6 +809,31 @@ CodeGenerator::visitRegExpReplace(LRegExpReplace *lir)
|
||||
return callVM(RegExpReplaceInfo, lir);
|
||||
}
|
||||
|
||||
typedef JSString *(*StringReplaceFn)(JSContext *, HandleString, HandleString, HandleString);
|
||||
static const VMFunction StringReplaceInfo = FunctionInfo<StringReplaceFn>(StringReplace);
|
||||
|
||||
bool
|
||||
CodeGenerator::visitStringReplace(LStringReplace *lir)
|
||||
{
|
||||
if (lir->replacement()->isConstant())
|
||||
pushArg(ImmGCPtr(lir->replacement()->toConstant()->toString()));
|
||||
else
|
||||
pushArg(ToRegister(lir->replacement()));
|
||||
|
||||
if (lir->pattern()->isConstant())
|
||||
pushArg(ImmGCPtr(lir->pattern()->toConstant()->toString()));
|
||||
else
|
||||
pushArg(ToRegister(lir->pattern()));
|
||||
|
||||
if (lir->string()->isConstant())
|
||||
pushArg(ImmGCPtr(lir->string()->toConstant()->toString()));
|
||||
else
|
||||
pushArg(ToRegister(lir->string()));
|
||||
|
||||
return callVM(StringReplaceInfo, lir);
|
||||
}
|
||||
|
||||
|
||||
typedef JSObject *(*LambdaFn)(JSContext *, HandleFunction, HandleObject);
|
||||
static const VMFunction LambdaInfo =
|
||||
FunctionInfo<LambdaFn>(js::Lambda);
|
||||
|
@ -93,6 +93,7 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
bool visitRegExpExec(LRegExpExec *lir);
|
||||
bool visitRegExpTest(LRegExpTest *lir);
|
||||
bool visitRegExpReplace(LRegExpReplace *lir);
|
||||
bool visitStringReplace(LStringReplace *lir);
|
||||
bool visitLambda(LLambda *lir);
|
||||
bool visitLambdaForSingleton(LLambdaForSingleton *lir);
|
||||
bool visitLambdaPar(LLambdaPar *lir);
|
||||
|
@ -11,8 +11,8 @@
|
||||
|
||||
#include "jsscriptinlines.h"
|
||||
|
||||
using namespace js;
|
||||
using namespace jit;
|
||||
namespace js {
|
||||
namespace jit {
|
||||
|
||||
inline RegExpObject *
|
||||
CompileInfo::getRegExp(jsbytecode *pc) const
|
||||
@ -26,4 +26,7 @@ CompileInfo::getFunction(jsbytecode *pc) const
|
||||
return script_->getFunction(GET_UINT32_INDEX(pc));
|
||||
}
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
#endif /* jit_CompileInfo_inl_h */
|
||||
|
@ -629,7 +629,7 @@ class IonBuilder : public MIRGenerator
|
||||
InliningStatus inlineStrCharCodeAt(CallInfo &callInfo);
|
||||
InliningStatus inlineStrFromCharCode(CallInfo &callInfo);
|
||||
InliningStatus inlineStrCharAt(CallInfo &callInfo);
|
||||
InliningStatus inlineStrReplaceRegExp(CallInfo &callInfo);
|
||||
InliningStatus inlineStrReplace(CallInfo &callInfo);
|
||||
|
||||
// RegExp natives.
|
||||
InliningStatus inlineRegExpExec(CallInfo &callInfo);
|
||||
|
@ -3246,34 +3246,61 @@ class LRegExpTest : public LCallInstructionHelper<1, 2, 0>
|
||||
}
|
||||
};
|
||||
|
||||
class LRegExpReplace : public LCallInstructionHelper<1, 3, 0>
|
||||
|
||||
class LStrReplace : public LCallInstructionHelper<1, 3, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(RegExpReplace)
|
||||
|
||||
LRegExpReplace(const LAllocation &string, const LAllocation ®exp,
|
||||
LStrReplace(const LAllocation &string, const LAllocation &pattern,
|
||||
const LAllocation &replacement)
|
||||
{
|
||||
setOperand(0, string);
|
||||
setOperand(1, regexp);
|
||||
setOperand(1, pattern);
|
||||
setOperand(2, replacement);
|
||||
}
|
||||
|
||||
const LAllocation *string() {
|
||||
return getOperand(0);
|
||||
}
|
||||
const LAllocation *regexp() {
|
||||
const LAllocation *pattern() {
|
||||
return getOperand(1);
|
||||
}
|
||||
const LAllocation *replacement() {
|
||||
return getOperand(2);
|
||||
}
|
||||
};
|
||||
|
||||
class LRegExpReplace: public LStrReplace
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(RegExpReplace);
|
||||
|
||||
LRegExpReplace(const LAllocation &string, const LAllocation &pattern,
|
||||
const LAllocation &replacement)
|
||||
: LStrReplace(string, pattern, replacement)
|
||||
{
|
||||
}
|
||||
|
||||
const MRegExpReplace *mir() const {
|
||||
return mir_->toRegExpReplace();
|
||||
}
|
||||
};
|
||||
|
||||
class LStringReplace: public LStrReplace
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(StringReplace);
|
||||
|
||||
LStringReplace(const LAllocation &string, const LAllocation &pattern,
|
||||
const LAllocation &replacement)
|
||||
: LStrReplace(string, pattern, replacement)
|
||||
{
|
||||
}
|
||||
|
||||
const MStringReplace *mir() const {
|
||||
return mir_->toStringReplace();
|
||||
}
|
||||
};
|
||||
|
||||
class LLambdaForSingleton : public LCallInstructionHelper<1, 1, 0>
|
||||
{
|
||||
public:
|
||||
|
@ -152,6 +152,7 @@
|
||||
_(RegExpExec) \
|
||||
_(RegExpTest) \
|
||||
_(RegExpReplace) \
|
||||
_(StringReplace) \
|
||||
_(Lambda) \
|
||||
_(LambdaForSingleton) \
|
||||
_(LambdaPar) \
|
||||
|
@ -1939,12 +1939,25 @@ LIRGenerator::visitRegExpTest(MRegExpTest *ins)
|
||||
bool
|
||||
LIRGenerator::visitRegExpReplace(MRegExpReplace *ins)
|
||||
{
|
||||
JS_ASSERT(ins->regexp()->type() == MIRType_Object);
|
||||
JS_ASSERT(ins->pattern()->type() == MIRType_Object);
|
||||
JS_ASSERT(ins->string()->type() == MIRType_String);
|
||||
JS_ASSERT(ins->replacement()->type() == MIRType_String);
|
||||
|
||||
LRegExpReplace *lir = new(alloc()) LRegExpReplace(useRegisterOrConstantAtStart(ins->string()),
|
||||
useRegisterAtStart(ins->regexp()),
|
||||
useRegisterAtStart(ins->pattern()),
|
||||
useRegisterOrConstantAtStart(ins->replacement()));
|
||||
return defineReturn(lir, ins) && assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitStringReplace(MStringReplace *ins)
|
||||
{
|
||||
JS_ASSERT(ins->pattern()->type() == MIRType_String);
|
||||
JS_ASSERT(ins->string()->type() == MIRType_String);
|
||||
JS_ASSERT(ins->replacement()->type() == MIRType_String);
|
||||
|
||||
LStringReplace *lir = new(alloc()) LStringReplace(useRegisterOrConstantAtStart(ins->string()),
|
||||
useRegisterAtStart(ins->pattern()),
|
||||
useRegisterOrConstantAtStart(ins->replacement()));
|
||||
return defineReturn(lir, ins) && assignSafepoint(lir, ins);
|
||||
}
|
||||
|
@ -148,6 +148,7 @@ class LIRGenerator : public LIRGeneratorSpecific
|
||||
bool visitRegExpExec(MRegExpExec *ins);
|
||||
bool visitRegExpTest(MRegExpTest *ins);
|
||||
bool visitRegExpReplace(MRegExpReplace *ins);
|
||||
bool visitStringReplace(MStringReplace *ins);
|
||||
bool visitLambda(MLambda *ins);
|
||||
bool visitLambdaPar(MLambdaPar *ins);
|
||||
bool visitImplicitThis(MImplicitThis *ins);
|
||||
|
@ -120,7 +120,7 @@ IonBuilder::inlineNativeCall(CallInfo &callInfo, JSNative native)
|
||||
if (native == js_str_charAt)
|
||||
return inlineStrCharAt(callInfo);
|
||||
if (native == str_replace)
|
||||
return inlineStrReplaceRegExp(callInfo);
|
||||
return inlineStrReplace(callInfo);
|
||||
|
||||
// RegExp natives.
|
||||
if (native == regexp_exec && CallResultEscapes(pc))
|
||||
@ -1178,7 +1178,7 @@ IonBuilder::inlineRegExpTest(CallInfo &callInfo)
|
||||
}
|
||||
|
||||
IonBuilder::InliningStatus
|
||||
IonBuilder::inlineStrReplaceRegExp(CallInfo &callInfo)
|
||||
IonBuilder::inlineStrReplace(CallInfo &callInfo)
|
||||
{
|
||||
if (callInfo.argc() != 2 || callInfo.constructing())
|
||||
return InliningStatus_NotInlined;
|
||||
@ -1194,7 +1194,7 @@ IonBuilder::inlineStrReplaceRegExp(CallInfo &callInfo)
|
||||
// Arg 0: RegExp.
|
||||
types::TemporaryTypeSet *arg0Type = callInfo.getArg(0)->resultTypeSet();
|
||||
const Class *clasp = arg0Type ? arg0Type->getKnownClass() : nullptr;
|
||||
if (clasp != &RegExpObject::class_)
|
||||
if (clasp != &RegExpObject::class_ && callInfo.getArg(0)->type() != MIRType_String)
|
||||
return InliningStatus_NotInlined;
|
||||
|
||||
// Arg 1: String.
|
||||
@ -1203,13 +1203,18 @@ IonBuilder::inlineStrReplaceRegExp(CallInfo &callInfo)
|
||||
|
||||
callInfo.setImplicitlyUsedUnchecked();
|
||||
|
||||
MInstruction *cte = MRegExpReplace::New(alloc(), callInfo.thisArg(), callInfo.getArg(0),
|
||||
callInfo.getArg(1));
|
||||
MInstruction *cte;
|
||||
if (callInfo.getArg(0)->type() == MIRType_String) {
|
||||
cte = MStringReplace::New(alloc(), callInfo.thisArg(), callInfo.getArg(0),
|
||||
callInfo.getArg(1));
|
||||
} else {
|
||||
cte = MRegExpReplace::New(alloc(), callInfo.thisArg(), callInfo.getArg(0),
|
||||
callInfo.getArg(1));
|
||||
}
|
||||
current->add(cte);
|
||||
current->push(cte);
|
||||
if (!resumeAfter(cte))
|
||||
if (cte->isEffectful() && !resumeAfter(cte))
|
||||
return InliningStatus_Error;
|
||||
|
||||
return InliningStatus_Inlined;
|
||||
}
|
||||
|
||||
|
@ -4885,29 +4885,26 @@ class MRegExpTest
|
||||
}
|
||||
};
|
||||
|
||||
class MRegExpReplace
|
||||
template <class Policy1>
|
||||
class MStrReplace
|
||||
: public MTernaryInstruction,
|
||||
public Mix3Policy<StringPolicy<0>, ObjectPolicy<1>, StringPolicy<2> >
|
||||
public Mix3Policy<StringPolicy<0>, Policy1, StringPolicy<2> >
|
||||
{
|
||||
private:
|
||||
protected:
|
||||
|
||||
MRegExpReplace(MDefinition *string, MDefinition *regexp, MDefinition *replacement)
|
||||
: MTernaryInstruction(string, regexp, replacement)
|
||||
MStrReplace(MDefinition *string, MDefinition *pattern, MDefinition *replacement)
|
||||
: MTernaryInstruction(string, pattern, replacement)
|
||||
{
|
||||
setMovable();
|
||||
setResultType(MIRType_String);
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(RegExpReplace)
|
||||
|
||||
static MRegExpReplace *New(TempAllocator &alloc, MDefinition *string, MDefinition *regexp, MDefinition *replacement) {
|
||||
return new(alloc) MRegExpReplace(string, regexp, replacement);
|
||||
}
|
||||
|
||||
MDefinition *string() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
MDefinition *regexp() const {
|
||||
MDefinition *pattern() const {
|
||||
return getOperand(1);
|
||||
}
|
||||
MDefinition *replacement() const {
|
||||
@ -4923,6 +4920,46 @@ class MRegExpReplace
|
||||
}
|
||||
};
|
||||
|
||||
class MRegExpReplace
|
||||
: public MStrReplace< ObjectPolicy<1> >
|
||||
{
|
||||
private:
|
||||
|
||||
MRegExpReplace(MDefinition *string, MDefinition *pattern, MDefinition *replacement)
|
||||
: MStrReplace< ObjectPolicy<1> >(string, pattern, replacement)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(RegExpReplace);
|
||||
|
||||
static MRegExpReplace *New(TempAllocator &alloc, MDefinition *string, MDefinition *pattern, MDefinition *replacement) {
|
||||
return new(alloc) MRegExpReplace(string, pattern, replacement);
|
||||
}
|
||||
};
|
||||
|
||||
class MStringReplace
|
||||
: public MStrReplace< StringPolicy<1> >
|
||||
{
|
||||
private:
|
||||
|
||||
MStringReplace(MDefinition *string, MDefinition *pattern, MDefinition *replacement)
|
||||
: MStrReplace< StringPolicy<1> >(string, pattern, replacement)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(StringReplace);
|
||||
|
||||
static MStringReplace *New(TempAllocator &alloc, MDefinition *string, MDefinition *pattern, MDefinition *replacement) {
|
||||
return new(alloc) MStringReplace(string, pattern, replacement);
|
||||
}
|
||||
|
||||
AliasSet getAliasSet() const {
|
||||
return AliasSet::None();
|
||||
}
|
||||
};
|
||||
|
||||
struct LambdaFunctionInfo
|
||||
{
|
||||
// The functions used in lambdas are the canonical original function in
|
||||
|
@ -101,6 +101,7 @@ namespace jit {
|
||||
_(RegExpExec) \
|
||||
_(RegExpTest) \
|
||||
_(RegExpReplace) \
|
||||
_(StringReplace) \
|
||||
_(Lambda) \
|
||||
_(ImplicitThis) \
|
||||
_(Slots) \
|
||||
|
@ -281,6 +281,7 @@ class ParallelSafetyVisitor : public MInstructionVisitor
|
||||
UNSAFE_OP(RegExpTest)
|
||||
UNSAFE_OP(RegExpExec)
|
||||
UNSAFE_OP(RegExpReplace)
|
||||
UNSAFE_OP(StringReplace)
|
||||
UNSAFE_OP(CallInstanceOf)
|
||||
UNSAFE_OP(FunctionBoundary)
|
||||
UNSAFE_OP(GuardString)
|
||||
|
@ -914,10 +914,10 @@ JSObject *CreateDerivedTypedObj(JSContext *cx, HandleObject type,
|
||||
}
|
||||
|
||||
JSString *
|
||||
regexp_replace(JSContext *cx, HandleString string, HandleObject regexp, HandleString repl)
|
||||
RegExpReplace(JSContext *cx, HandleString string, HandleObject regexp, HandleString repl)
|
||||
{
|
||||
JS_ASSERT(!!string);
|
||||
JS_ASSERT(!!repl);
|
||||
JS_ASSERT(string);
|
||||
JS_ASSERT(repl);
|
||||
|
||||
RootedValue rval(cx);
|
||||
if (!str_replace_regexp_raw(cx, string, regexp, repl, &rval))
|
||||
@ -926,6 +926,20 @@ regexp_replace(JSContext *cx, HandleString string, HandleObject regexp, HandleSt
|
||||
return rval.toString();
|
||||
}
|
||||
|
||||
JSString *
|
||||
StringReplace(JSContext *cx, HandleString string, HandleString pattern, HandleString repl)
|
||||
{
|
||||
JS_ASSERT(string);
|
||||
JS_ASSERT(pattern);
|
||||
JS_ASSERT(repl);
|
||||
|
||||
RootedValue rval(cx);
|
||||
if (!str_replace_string_raw(cx, string, pattern, repl, &rval))
|
||||
return nullptr;
|
||||
|
||||
return rval.toString();
|
||||
}
|
||||
|
||||
bool
|
||||
Recompile(JSContext *cx)
|
||||
{
|
||||
|
@ -663,8 +663,10 @@ JSObject *CreateDerivedTypedObj(JSContext *cx, HandleObject type,
|
||||
HandleObject owner, int32_t offset);
|
||||
|
||||
bool Recompile(JSContext *cx);
|
||||
JSString *regexp_replace(JSContext *cx, HandleString string, HandleObject regexp,
|
||||
HandleString repl);
|
||||
JSString *RegExpReplace(JSContext *cx, HandleString string, HandleObject regexp,
|
||||
HandleString repl);
|
||||
JSString *StringReplace(JSContext *cx, HandleString string, HandleString pattern,
|
||||
HandleString repl);
|
||||
|
||||
#ifdef DEBUG
|
||||
void AssertValidObjectPtr(JSContext *cx, JSObject *obj);
|
||||
|
@ -76,11 +76,12 @@ class BailoutStack
|
||||
uintptr_t tableOffset_;
|
||||
};
|
||||
|
||||
private:
|
||||
protected: // Silence Clang warning about unused private fields.
|
||||
mozilla::Array<double, FloatRegisters::Total> fpregs_;
|
||||
mozilla::Array<uintptr_t, Registers::Total> regs_;
|
||||
|
||||
uintptr_t snapshotOffset_;
|
||||
uintptr_t padding_;
|
||||
|
||||
public:
|
||||
FrameSizeClass frameClass() const {
|
||||
@ -109,6 +110,9 @@ class BailoutStack
|
||||
}
|
||||
};
|
||||
|
||||
// Make sure the compiler doesn't add extra padding.
|
||||
static_assert((sizeof(BailoutStack) % 8) == 0, "BailoutStack should be 8-byte aligned.");
|
||||
|
||||
} // namespace jit
|
||||
} // namespace js
|
||||
|
||||
|
@ -281,8 +281,8 @@ bool
|
||||
CodeGeneratorARM::visitOutOfLineBailout(OutOfLineBailout *ool)
|
||||
{
|
||||
masm.ma_mov(Imm32(ool->snapshot()->snapshotOffset()), ScratchRegister);
|
||||
masm.ma_push(ScratchRegister);
|
||||
masm.ma_push(ScratchRegister);
|
||||
masm.ma_push(ScratchRegister); // BailoutStack::padding_
|
||||
masm.ma_push(ScratchRegister); // BailoutStack::snapshotOffset_
|
||||
masm.ma_b(&deoptLabel_);
|
||||
return true;
|
||||
}
|
||||
|
@ -765,9 +765,10 @@ JitRuntime::generateVMWrapper(JSContext *cx, const VMFunction &f)
|
||||
// Test for failure.
|
||||
switch (f.failType()) {
|
||||
case Type_Object:
|
||||
masm.branchTestPtr(Assembler::Zero, r0, r0, masm.failureLabel(f.executionMode));
|
||||
break;
|
||||
case Type_Bool:
|
||||
// Called functions return bools, which are 0/false and non-zero/true
|
||||
masm.branch32(Assembler::Equal, r0, Imm32(0), masm.failureLabel(f.executionMode));
|
||||
masm.branchIfFalseBool(r0, masm.failureLabel(f.executionMode));
|
||||
break;
|
||||
default:
|
||||
MOZ_ASSUME_UNREACHABLE("unknown failure kind");
|
||||
|
@ -2814,10 +2814,8 @@ JS_LookupPropertyWithFlags(JSContext *cx, HandleObject obj, const char *name, un
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_HasPropertyById(JSContext *cx, JSObject *objArg, jsid idArg, bool *foundp)
|
||||
JS_HasPropertyById(JSContext *cx, HandleObject obj, HandleId id, bool *foundp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
RootedId id(cx, idArg);
|
||||
RootedObject obj2(cx);
|
||||
RootedShape prop(cx);
|
||||
bool ok = LookupPropertyById(cx, obj, id, 0, &obj2, &prop);
|
||||
@ -2826,9 +2824,8 @@ JS_HasPropertyById(JSContext *cx, JSObject *objArg, jsid idArg, bool *foundp)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_HasElement(JSContext *cx, JSObject *objArg, uint32_t index, bool *foundp)
|
||||
JS_HasElement(JSContext *cx, HandleObject obj, uint32_t index, bool *foundp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
RootedId id(cx);
|
||||
@ -2838,26 +2835,28 @@ JS_HasElement(JSContext *cx, JSObject *objArg, uint32_t index, bool *foundp)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_HasProperty(JSContext *cx, JSObject *objArg, const char *name, bool *foundp)
|
||||
JS_HasProperty(JSContext *cx, HandleObject obj, const char *name, bool *foundp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
JSAtom *atom = Atomize(cx, name, strlen(name));
|
||||
return atom && JS_HasPropertyById(cx, obj, AtomToId(atom), foundp);
|
||||
if (!atom)
|
||||
return false;
|
||||
RootedId id(cx, AtomToId(atom));
|
||||
return JS_HasPropertyById(cx, obj, id, foundp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_HasUCProperty(JSContext *cx, JSObject *objArg, const jschar *name, size_t namelen, bool *foundp)
|
||||
JS_HasUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen, bool *foundp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && JS_HasPropertyById(cx, obj, AtomToId(atom), foundp);
|
||||
if (!atom)
|
||||
return false;
|
||||
RootedId id(cx, AtomToId(atom));
|
||||
return JS_HasPropertyById(cx, obj, id, foundp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_AlreadyHasOwnPropertyById(JSContext *cx, JSObject *objArg, jsid id_, bool *foundp)
|
||||
JS_AlreadyHasOwnPropertyById(JSContext *cx, HandleObject obj, HandleId id, bool *foundp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
RootedId id(cx, id_);
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, id);
|
||||
@ -2882,9 +2881,8 @@ JS_AlreadyHasOwnPropertyById(JSContext *cx, JSObject *objArg, jsid id_, bool *fo
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_AlreadyHasOwnElement(JSContext *cx, JSObject *objArg, uint32_t index, bool *foundp)
|
||||
JS_AlreadyHasOwnElement(JSContext *cx, HandleObject obj, uint32_t index, bool *foundp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
RootedId id(cx);
|
||||
@ -2894,20 +2892,24 @@ JS_AlreadyHasOwnElement(JSContext *cx, JSObject *objArg, uint32_t index, bool *f
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_AlreadyHasOwnProperty(JSContext *cx, JSObject *objArg, const char *name, bool *foundp)
|
||||
JS_AlreadyHasOwnProperty(JSContext *cx, HandleObject obj, const char *name, bool *foundp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
JSAtom *atom = Atomize(cx, name, strlen(name));
|
||||
return atom && JS_AlreadyHasOwnPropertyById(cx, obj, AtomToId(atom), foundp);
|
||||
if (!atom)
|
||||
return false;
|
||||
RootedId id(cx, AtomToId(atom));
|
||||
return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_AlreadyHasOwnUCProperty(JSContext *cx, JSObject *objArg, const jschar *name, size_t namelen,
|
||||
JS_AlreadyHasOwnUCProperty(JSContext *cx, HandleObject obj, const jschar *name, size_t namelen,
|
||||
bool *foundp)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
JSAtom *atom = AtomizeChars(cx, name, AUTO_NAMELEN(name, namelen));
|
||||
return atom && JS_AlreadyHasOwnPropertyById(cx, obj, AtomToId(atom), foundp);
|
||||
if (!atom)
|
||||
return false;
|
||||
RootedId id(cx, AtomToId(atom));
|
||||
return JS_AlreadyHasOwnPropertyById(cx, obj, id, foundp);
|
||||
}
|
||||
|
||||
/* Wrapper functions to create wrappers with no corresponding JSJitInfo from API
|
||||
@ -3457,9 +3459,8 @@ JS_SetUCProperty(JSContext *cx, JSObject *objArg, const jschar *name, size_t nam
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_DeletePropertyById2(JSContext *cx, JSObject *objArg, jsid id, bool *result)
|
||||
JS_DeletePropertyById2(JSContext *cx, HandleObject obj, HandleId id, bool *result)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, id);
|
||||
@ -3473,9 +3474,8 @@ JS_DeletePropertyById2(JSContext *cx, JSObject *objArg, jsid id, bool *result)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_DeleteElement2(JSContext *cx, JSObject *objArg, uint32_t index, bool *result)
|
||||
JS_DeleteElement2(JSContext *cx, HandleObject obj, uint32_t index, bool *result)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
@ -3485,9 +3485,8 @@ JS_DeleteElement2(JSContext *cx, JSObject *objArg, uint32_t index, bool *result)
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_DeleteProperty2(JSContext *cx, JSObject *objArg, const char *name, bool *result)
|
||||
JS_DeleteProperty2(JSContext *cx, HandleObject obj, const char *name, bool *result)
|
||||
{
|
||||
RootedObject obj(cx, objArg);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj);
|
||||
JSAutoResolveFlags rf(cx, 0);
|
||||
@ -3514,24 +3513,24 @@ JS_DeleteUCProperty2(JSContext *cx, JSObject *objArg, const jschar *name, size_t
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_DeletePropertyById(JSContext *cx, JSObject *objArg, jsid idArg)
|
||||
JS_DeletePropertyById(JSContext *cx, HandleObject obj, HandleId id)
|
||||
{
|
||||
bool junk;
|
||||
return JS_DeletePropertyById2(cx, objArg, idArg, &junk);
|
||||
return JS_DeletePropertyById2(cx, obj, id, &junk);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_DeleteElement(JSContext *cx, JSObject *objArg, uint32_t index)
|
||||
JS_DeleteElement(JSContext *cx, HandleObject obj, uint32_t index)
|
||||
{
|
||||
bool junk;
|
||||
return JS_DeleteElement2(cx, objArg, index, &junk);
|
||||
return JS_DeleteElement2(cx, obj, index, &junk);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_DeleteProperty(JSContext *cx, JSObject *objArg, const char *name)
|
||||
JS_DeleteProperty(JSContext *cx, HandleObject obj, const char *name)
|
||||
{
|
||||
bool junk;
|
||||
return JS_DeleteProperty2(cx, objArg, name, &junk);
|
||||
return JS_DeleteProperty2(cx, obj, name, &junk);
|
||||
}
|
||||
|
||||
static Shape *
|
||||
|
@ -2787,18 +2787,18 @@ JS_DefinePropertyWithTinyId(JSContext *cx, JSObject *obj, const char *name,
|
||||
unsigned attrs);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_AlreadyHasOwnProperty(JSContext *cx, JSObject *obj, const char *name,
|
||||
JS_AlreadyHasOwnProperty(JSContext *cx, JS::HandleObject obj, const char *name,
|
||||
bool *foundp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_AlreadyHasOwnPropertyById(JSContext *cx, JSObject *obj, jsid id,
|
||||
JS_AlreadyHasOwnPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id,
|
||||
bool *foundp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_HasProperty(JSContext *cx, JSObject *obj, const char *name, bool *foundp);
|
||||
JS_HasProperty(JSContext *cx, JS::HandleObject obj, const char *name, bool *foundp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_HasPropertyById(JSContext *cx, JSObject *obj, jsid id, bool *foundp);
|
||||
JS_HasPropertyById(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *foundp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_LookupProperty(JSContext *cx, JSObject *obj, const char *name, JS::MutableHandleValue vp);
|
||||
@ -3001,16 +3001,16 @@ extern JS_PUBLIC_API(bool)
|
||||
JS_SetPropertyById(JSContext *cx, JSObject *obj, jsid id, JS::HandleValue v);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DeleteProperty(JSContext *cx, JSObject *obj, const char *name);
|
||||
JS_DeleteProperty(JSContext *cx, JS::HandleObject obj, const char *name);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DeleteProperty2(JSContext *cx, JSObject *obj, const char *name, bool *succeeded);
|
||||
JS_DeleteProperty2(JSContext *cx, JS::HandleObject obj, const char *name, bool *succeeded);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DeletePropertyById(JSContext *cx, JSObject *obj, jsid id);
|
||||
JS_DeletePropertyById(JSContext *cx, JS::HandleObject obj, jsid id);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DeletePropertyById2(JSContext *cx, JSObject *obj, jsid id, bool *succeeded);
|
||||
JS_DeletePropertyById2(JSContext *cx, JS::HandleObject obj, JS::HandleId id, bool *succeeded);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DefineUCProperty(JSContext *cx, JSObject *obj,
|
||||
@ -3026,11 +3026,11 @@ JS_DefineUCPropertyWithTinyId(JSContext *cx, JSObject *obj,
|
||||
unsigned attrs);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_AlreadyHasOwnUCProperty(JSContext *cx, JSObject *obj, const jschar *name,
|
||||
JS_AlreadyHasOwnUCProperty(JSContext *cx, JS::HandleObject obj, const jschar *name,
|
||||
size_t namelen, bool *foundp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_HasUCProperty(JSContext *cx, JSObject *obj,
|
||||
JS_HasUCProperty(JSContext *cx, JS::HandleObject obj,
|
||||
const jschar *name, size_t namelen,
|
||||
bool *vp);
|
||||
|
||||
@ -3070,10 +3070,10 @@ JS_DefineElement(JSContext *cx, JSObject *obj, uint32_t index, jsval value,
|
||||
JSPropertyOp getter, JSStrictPropertyOp setter, unsigned attrs);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_AlreadyHasOwnElement(JSContext *cx, JSObject *obj, uint32_t index, bool *foundp);
|
||||
JS_AlreadyHasOwnElement(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *foundp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_HasElement(JSContext *cx, JSObject *obj, uint32_t index, bool *foundp);
|
||||
JS_HasElement(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *foundp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_LookupElement(JSContext *cx, JSObject *obj, uint32_t index, JS::MutableHandleValue vp);
|
||||
@ -3089,10 +3089,10 @@ extern JS_PUBLIC_API(bool)
|
||||
JS_SetElement(JSContext *cx, JSObject *obj, uint32_t index, JS::MutableHandleValue vp);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DeleteElement(JSContext *cx, JSObject *obj, uint32_t index);
|
||||
JS_DeleteElement(JSContext *cx, JS::HandleObject obj, uint32_t index);
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_DeleteElement2(JSContext *cx, JSObject *obj, uint32_t index, bool *succeeded);
|
||||
JS_DeleteElement2(JSContext *cx, JS::HandleObject obj, uint32_t index, bool *succeeded);
|
||||
|
||||
/*
|
||||
* Remove all configurable properties from the given (non-global) object and
|
||||
|
@ -387,8 +387,10 @@ EnsureTrackPropertyTypes(JSContext *cx, JSObject *obj, jsid id)
|
||||
cx->clearPendingException();
|
||||
return;
|
||||
}
|
||||
if (!obj->type()->unknownProperties())
|
||||
obj->type()->getProperty(cx, id);
|
||||
if (!obj->type()->unknownProperties() && !obj->type()->getProperty(cx, id)) {
|
||||
cx->compartment()->types.setPendingNukeTypes(cx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JS_ASSERT(obj->type()->unknownProperties() || TrackPropertyTypes(cx, obj, id));
|
||||
|
@ -447,22 +447,19 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
|
||||
nconsts = nobjects = nregexps = ntrynotes = nblockscopes = 0;
|
||||
|
||||
/* XDR arguments and vars. */
|
||||
uint16_t nargs = 0, nvars = 0;
|
||||
uint32_t argsVars = 0;
|
||||
uint16_t nargs = 0;
|
||||
uint32_t nvars = 0;
|
||||
if (mode == XDR_ENCODE) {
|
||||
script = scriptp.get();
|
||||
JS_ASSERT_IF(enclosingScript, enclosingScript->compartment() == script->compartment());
|
||||
|
||||
nargs = script->bindings.numArgs();
|
||||
nvars = script->bindings.numVars();
|
||||
argsVars = (nargs << 16) | nvars;
|
||||
}
|
||||
if (!xdr->codeUint32(&argsVars))
|
||||
if (!xdr->codeUint16(&nargs))
|
||||
return false;
|
||||
if (!xdr->codeUint32(&nvars))
|
||||
return false;
|
||||
if (mode == XDR_DECODE) {
|
||||
nargs = argsVars >> 16;
|
||||
nvars = argsVars & 0xFFFF;
|
||||
}
|
||||
|
||||
if (mode == XDR_ENCODE)
|
||||
length = script->length();
|
||||
|
@ -1731,6 +1731,13 @@ class MOZ_STACK_CLASS StringRegExpGuard
|
||||
return true;
|
||||
}
|
||||
|
||||
bool init(JSContext *cx, HandleString pattern) {
|
||||
fm.patstr = AtomizeString(cx, pattern);
|
||||
if (!fm.patstr)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to match |patstr| to |textstr|. A flags argument, metachars in
|
||||
* the pattern string, or a lengthy pattern string can thwart this process.
|
||||
@ -2449,7 +2456,7 @@ ReplaceRegExp(JSContext *cx, RegExpStatics *res, ReplaceData &rdata)
|
||||
|
||||
static bool
|
||||
BuildFlatReplacement(JSContext *cx, HandleString textstr, HandleString repstr,
|
||||
const FlatMatch &fm, CallArgs *args)
|
||||
const FlatMatch &fm, MutableHandleValue rval)
|
||||
{
|
||||
RopeBuilder builder(cx);
|
||||
size_t match = fm.match();
|
||||
@ -2521,7 +2528,7 @@ BuildFlatReplacement(JSContext *cx, HandleString textstr, HandleString repstr,
|
||||
}
|
||||
}
|
||||
|
||||
args->rval().setString(builder.result());
|
||||
rval.setString(builder.result());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2533,7 +2540,7 @@ BuildFlatReplacement(JSContext *cx, HandleString textstr, HandleString repstr,
|
||||
*/
|
||||
static inline bool
|
||||
BuildDollarReplacement(JSContext *cx, JSString *textstrArg, JSLinearString *repstr,
|
||||
const jschar *firstDollar, const FlatMatch &fm, CallArgs *args)
|
||||
const jschar *firstDollar, const FlatMatch &fm, MutableHandleValue rval)
|
||||
{
|
||||
Rooted<JSLinearString*> textstr(cx, textstrArg->ensureLinear(cx));
|
||||
if (!textstr)
|
||||
@ -2605,7 +2612,7 @@ BuildDollarReplacement(JSContext *cx, JSString *textstrArg, JSLinearString *reps
|
||||
builder.append(rightSide));
|
||||
#undef ENSURE
|
||||
|
||||
args->rval().setString(builder.result());
|
||||
rval.setString(builder.result());
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2860,11 +2867,47 @@ js::str_replace_regexp_raw(JSContext *cx, HandleString string, HandleObject rege
|
||||
return StrReplaceRegExp(cx, rdata, rval);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
StrReplaceString(JSContext *cx, ReplaceData &rdata, const FlatMatch &fm, MutableHandleValue rval)
|
||||
{
|
||||
/*
|
||||
* Note: we could optimize the text.length == pattern.length case if we wanted,
|
||||
* even in the presence of dollar metachars.
|
||||
*/
|
||||
if (rdata.dollar)
|
||||
return BuildDollarReplacement(cx, rdata.str, rdata.repstr, rdata.dollar, fm, rval);
|
||||
return BuildFlatReplacement(cx, rdata.str, rdata.repstr, fm, rval);
|
||||
}
|
||||
|
||||
static const uint32_t ReplaceOptArg = 2;
|
||||
|
||||
bool
|
||||
js::str_replace_string_raw(JSContext *cx, HandleString string, HandleString pattern,
|
||||
HandleString replacement, MutableHandleValue rval)
|
||||
{
|
||||
ReplaceData rdata(cx);
|
||||
|
||||
rdata.str = string;
|
||||
JSLinearString *repl = replacement->ensureLinear(cx);
|
||||
if (!repl)
|
||||
return false;
|
||||
rdata.setReplacementString(repl);
|
||||
|
||||
if (!rdata.g.init(cx, pattern))
|
||||
return false;
|
||||
const FlatMatch *fm = rdata.g.tryFlatMatch(cx, rdata.str, ReplaceOptArg, ReplaceOptArg, false);
|
||||
|
||||
if (fm->match() < 0) {
|
||||
rval.setString(string);
|
||||
return true;
|
||||
}
|
||||
|
||||
return StrReplaceString(cx, rdata, *fm, rval);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
str_replace_flat_lambda(JSContext *cx, CallArgs outerArgs, ReplaceData &rdata, const FlatMatch &fm)
|
||||
{
|
||||
JS_ASSERT(fm.match() >= 0);
|
||||
|
||||
RootedString matchStr(cx, js_NewDependentString(cx, rdata.str, fm.match(), fm.patternLength()));
|
||||
if (!matchStr)
|
||||
return false;
|
||||
@ -2911,8 +2954,6 @@ str_replace_flat_lambda(JSContext *cx, CallArgs outerArgs, ReplaceData &rdata, c
|
||||
return true;
|
||||
}
|
||||
|
||||
static const uint32_t ReplaceOptArg = 2;
|
||||
|
||||
/*
|
||||
* Pattern match the script to check if it is is indexing into a particular
|
||||
* object, e.g. 'function(a) { return b[a]; }'. Avoid calling the script in
|
||||
@ -3017,6 +3058,7 @@ js::str_replace(JSContext *cx, unsigned argc, Value *vp)
|
||||
*/
|
||||
|
||||
const FlatMatch *fm = rdata.g.tryFlatMatch(cx, rdata.str, ReplaceOptArg, args.length(), false);
|
||||
|
||||
if (!fm) {
|
||||
if (cx->isExceptionPending()) /* oom in RopeMatch in tryFlatMatch */
|
||||
return false;
|
||||
@ -3030,15 +3072,7 @@ js::str_replace(JSContext *cx, unsigned argc, Value *vp)
|
||||
|
||||
if (rdata.lambda)
|
||||
return str_replace_flat_lambda(cx, args, rdata, *fm);
|
||||
|
||||
/*
|
||||
* Note: we could optimize the text.length == pattern.length case if we wanted,
|
||||
* even in the presence of dollar metachars.
|
||||
*/
|
||||
if (rdata.dollar)
|
||||
return BuildDollarReplacement(cx, rdata.str, rdata.repstr, rdata.dollar, *fm, &args);
|
||||
|
||||
return BuildFlatReplacement(cx, rdata.str, rdata.repstr, *fm, &args);
|
||||
return StrReplaceString(cx, rdata, *fm, args.rval());
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -370,6 +370,10 @@ bool
|
||||
str_replace_regexp_raw(JSContext *cx, HandleString string, HandleObject regexp,
|
||||
HandleString replacement, MutableHandleValue rval);
|
||||
|
||||
bool
|
||||
str_replace_string_raw(JSContext *cx, HandleString string, HandleString pattern,
|
||||
HandleString replacement, MutableHandleValue rval);
|
||||
|
||||
} /* namespace js */
|
||||
|
||||
extern bool
|
||||
|
@ -22,7 +22,7 @@ namespace js {
|
||||
* and saved versions. If deserialization fails, the data should be
|
||||
* invalidated if possible.
|
||||
*/
|
||||
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 163);
|
||||
static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 164);
|
||||
|
||||
class XDRBuffer {
|
||||
public:
|
||||
|
@ -625,7 +625,8 @@ nsJSCID::NewID(const char* str)
|
||||
NS_ENSURE_TRUE(registrar, nullptr);
|
||||
|
||||
nsCID *cid;
|
||||
NS_ENSURE_SUCCESS(registrar->ContractIDToCID(str, &cid), nullptr);
|
||||
if (NS_FAILED(registrar->ContractIDToCID(str, &cid)))
|
||||
return nullptr;
|
||||
bool success = idObj->mDetails.InitWithName(*cid, str);
|
||||
nsMemory::Free(cid);
|
||||
if (!success)
|
||||
|
@ -193,27 +193,20 @@ def print_cpp_file(fd, conf):
|
||||
if not c in conf.exclude_automatic_type_include:
|
||||
fd.write("#include \"%s.h\"\n" % c)
|
||||
|
||||
fd.write("\nusing namespace mozilla::idl;\n\n")
|
||||
fd.write("\n"
|
||||
"using namespace mozilla::idl;\n"
|
||||
"using namespace mozilla::dom;\n\n")
|
||||
|
||||
for a in attrnames:
|
||||
fd.write("static jsid %s = JSID_VOID;\n"% get_jsid(a))
|
||||
fd.write("static InternedStringId %s;\n" % get_jsid(a))
|
||||
|
||||
fd.write("\n"
|
||||
"static bool\n"
|
||||
"InternStaticJSVal(JSContext* aCx, jsid &id, const char* aString)\n"
|
||||
"{\n"
|
||||
" if (JSString* str = JS_InternString(aCx, aString)) {\n"
|
||||
" id = INTERNED_STRING_TO_JSID(aCx, str);\n"
|
||||
" return true;\n"
|
||||
" }\n"
|
||||
" return false;\n"
|
||||
"}\n\n"
|
||||
"bool\n"
|
||||
"InternStaticDictionaryJSVals(JSContext* aCx)\n"
|
||||
"{\n"
|
||||
" return\n")
|
||||
for a in attrnames:
|
||||
fd.write(" InternStaticJSVal(aCx, %s, \"%s\") &&\n"
|
||||
fd.write(" %s.init(aCx, \"%s\") &&\n"
|
||||
% (get_jsid(a), a))
|
||||
|
||||
fd.write(" true;\n")
|
||||
|
@ -155,16 +155,23 @@
|
||||
|
||||
/*
|
||||
* MOZ_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time
|
||||
* instrumentation shipped with Clang) to not instrument the annotated function.
|
||||
* Furthermore, it will prevent the compiler from inlining the function because
|
||||
* inlining currently breaks the blacklisting mechanism of AddressSanitizer.
|
||||
* instrumentation shipped with Clang and GCC) to not instrument the annotated
|
||||
* function. Furthermore, it will prevent the compiler from inlining the
|
||||
* function because inlining currently breaks the blacklisting mechanism of
|
||||
* AddressSanitizer.
|
||||
*/
|
||||
#if defined(__has_feature)
|
||||
# if __has_feature(address_sanitizer)
|
||||
# define MOZ_ASAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_address))
|
||||
# else
|
||||
# define MOZ_ASAN_BLACKLIST /* nothing */
|
||||
# define MOZ_HAVE_ASAN_BLACKLIST
|
||||
# endif
|
||||
#elif defined(__GNUC__)
|
||||
# if defined(__SANITIZE_ADDRESS__)
|
||||
# define MOZ_HAVE_ASAN_BLACKLIST
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_HAVE_ASAN_BLACKLIST)
|
||||
# define MOZ_ASAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_address))
|
||||
#else
|
||||
# define MOZ_ASAN_BLACKLIST /* nothing */
|
||||
#endif
|
||||
|
@ -12,6 +12,8 @@ Cu.import("resource://gre/modules/Services.jsm")
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/AppsUtils.jsm");
|
||||
|
||||
const DEFAULT_ICON = "chrome://browser/skin/images/default-app-icon.png";
|
||||
|
||||
let gStrings = Services.strings.createBundle("chrome://browser/locale/aboutApps.properties");
|
||||
|
||||
XPCOMUtils.defineLazyGetter(window, "gChromeWin", function()
|
||||
@ -39,6 +41,7 @@ function openLink(aEvent) {
|
||||
} catch (ex) {}
|
||||
}
|
||||
|
||||
#ifndef MOZ_ANDROID_SYNTHAPKS
|
||||
var ContextMenus = {
|
||||
target: null,
|
||||
|
||||
@ -58,8 +61,7 @@ var ContextMenus = {
|
||||
|
||||
addToHomescreen: function() {
|
||||
let manifest = this.target.manifest;
|
||||
let origin = Services.io.newURI(this.target.app.origin, null, null);
|
||||
gChromeWin.WebappsUI.createShortcut(manifest.name, manifest.fullLaunchPath(), gChromeWin.WebappsUI.getBiggestIcon(manifest.icons, origin), "webapp");
|
||||
gChromeWin.WebappsUI.createShortcut(manifest.name, manifest.fullLaunchPath(), manifest.biggestIconURL || DEFAULT_ICON, "webapp");
|
||||
this.target = null;
|
||||
},
|
||||
|
||||
@ -77,15 +79,9 @@ var ContextMenus = {
|
||||
this.target = null;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
function onLoad(aEvent) {
|
||||
try {
|
||||
let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
|
||||
let link = document.getElementById("marketplaceURL");
|
||||
let url = formatter.formatURLPref(link.getAttribute("pref"));
|
||||
link.setAttribute("href", url);
|
||||
} catch (e) {}
|
||||
|
||||
let elmts = document.querySelectorAll("[pref]");
|
||||
for (let i = 0; i < elmts.length; i++) {
|
||||
elmts[i].addEventListener("click", openLink, false);
|
||||
@ -95,7 +91,9 @@ function onLoad(aEvent) {
|
||||
navigator.mozApps.mgmt.onuninstall = onUninstall;
|
||||
updateList();
|
||||
|
||||
#ifndef MOZ_ANDROID_SYNTHAPKS
|
||||
ContextMenus.init();
|
||||
#endif
|
||||
}
|
||||
|
||||
function updateList() {
|
||||
@ -119,16 +117,21 @@ function addApplication(aApp) {
|
||||
|
||||
let container = document.createElement("div");
|
||||
container.className = "app list-item";
|
||||
#ifndef MOZ_ANDROID_SYNTHAPKS
|
||||
container.setAttribute("contextmenu", "appmenu");
|
||||
#endif
|
||||
container.setAttribute("id", "app-" + aApp.origin);
|
||||
container.setAttribute("mozApp", aApp.origin);
|
||||
container.setAttribute("title", manifest.name);
|
||||
|
||||
let img = document.createElement("img");
|
||||
let origin = Services.io.newURI(aApp.origin, null, null);
|
||||
img.src = gChromeWin.WebappsUI.getBiggestIcon(manifest.icons, origin);
|
||||
img.src = manifest.biggestIconURL || DEFAULT_ICON;
|
||||
img.onerror = function() {
|
||||
img.src = "chrome://browser/skin/images/default-app-icon.png";
|
||||
// If the image failed to load, and it was not our default icon, attempt to
|
||||
// use our default as a fallback.
|
||||
if (img.src != DEFAULT_ICON) {
|
||||
img.src = DEFAULT_ICON;
|
||||
}
|
||||
}
|
||||
img.setAttribute("title", manifest.name);
|
||||
|
||||
|
@ -29,11 +29,13 @@
|
||||
|
||||
<body dir="&locale.dir;">
|
||||
|
||||
#ifndef MOZ_ANDROID_SYNTHAPKS
|
||||
<menu type="context" id="appmenu">
|
||||
<menuitem id="addToHomescreenLabel" label="&aboutApps.addToHomescreen;"></menuitem>
|
||||
<menuitem id="uninstallLabel" label="&aboutApps.uninstall;"></menuitem>
|
||||
</menu>
|
||||
|
||||
#endif
|
||||
|
||||
<div class="header">
|
||||
<div>&aboutApps.header;</div>
|
||||
<div id="header-button" role="button" aria-label="&aboutApps.browseMarketplace;" pref="app.marketplaceURL"/>
|
||||
|
@ -418,9 +418,8 @@ var BrowserApp = {
|
||||
this.isGuest = window.arguments[4];
|
||||
}
|
||||
|
||||
let status = this.startupStatus();
|
||||
if (pinned) {
|
||||
this._initRuntime(status, url, aUrl => this.addTab(aUrl));
|
||||
this._initRuntime(this._startupStatus, url, aUrl => this.addTab(aUrl));
|
||||
} else {
|
||||
SearchEngines.init();
|
||||
this.initContextMenu();
|
||||
@ -437,7 +436,7 @@ var BrowserApp = {
|
||||
event.initEvent("UIReady", true, false);
|
||||
window.dispatchEvent(event);
|
||||
|
||||
if (status)
|
||||
if (this._startupStatus)
|
||||
this.onAppUpdated();
|
||||
|
||||
// Store the low-precision buffer pref
|
||||
@ -452,18 +451,22 @@ var BrowserApp = {
|
||||
#endif
|
||||
},
|
||||
|
||||
startupStatus: function() {
|
||||
let savedmstone = null;
|
||||
get _startupStatus() {
|
||||
delete this._startupStatus;
|
||||
|
||||
let savedMilestone = null;
|
||||
try {
|
||||
savedmstone = Services.prefs.getCharPref("browser.startup.homepage_override.mstone");
|
||||
savedMilestone = Services.prefs.getCharPref("browser.startup.homepage_override.mstone");
|
||||
} catch (e) {
|
||||
}
|
||||
#expand let ourmstone = "__MOZ_APP_VERSION__";
|
||||
if (ourmstone != savedmstone) {
|
||||
Services.prefs.setCharPref("browser.startup.homepage_override.mstone", ourmstone);
|
||||
return savedmstone ? "upgrade" : "new";
|
||||
#expand let ourMilestone = "__MOZ_APP_VERSION__";
|
||||
this._startupStatus = "";
|
||||
if (ourMilestone != savedMilestone) {
|
||||
Services.prefs.setCharPref("browser.startup.homepage_override.mstone", ourMilestone);
|
||||
this._startupStatus = savedMilestone ? "upgrade" : "new";
|
||||
}
|
||||
return "";
|
||||
|
||||
return this._startupStatus;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -916,8 +919,8 @@ var BrowserApp = {
|
||||
|
||||
#ifdef MOZ_ANDROID_SYNTHAPKS
|
||||
_loadWebapp: function(aMessage) {
|
||||
// TODO: figure out when (if ever) to pass "new" to the status parameter.
|
||||
this._initRuntime("", aMessage.url, aUrl => {
|
||||
|
||||
this._initRuntime(this._startupStatus, aMessage.url, aUrl => {
|
||||
this.manifestUrl = aMessage.url;
|
||||
this.addTab(aUrl, { title: aMessage.name });
|
||||
});
|
||||
@ -7093,6 +7096,7 @@ var WebappsUI = {
|
||||
Services.obs.removeObserver(this, "webapps-install-error");
|
||||
},
|
||||
|
||||
DEFAULT_ICON: "chrome://browser/skin/images/default-app-icon.png",
|
||||
DEFAULT_PREFS_FILENAME: "default-prefs.js",
|
||||
|
||||
observe: function observe(aSubject, aTopic, aData) {
|
||||
@ -7134,39 +7138,6 @@ var WebappsUI = {
|
||||
}
|
||||
},
|
||||
|
||||
getBiggestIcon: function getBiggestIcon(aIcons, aOrigin) {
|
||||
const DEFAULT_ICON = "chrome://browser/skin/images/default-app-icon.png";
|
||||
if (!aIcons)
|
||||
return DEFAULT_ICON;
|
||||
|
||||
let iconSizes = Object.keys(aIcons);
|
||||
if (iconSizes.length == 0)
|
||||
return DEFAULT_ICON;
|
||||
iconSizes.sort(function(a, b) a - b);
|
||||
|
||||
let biggestIcon = aIcons[iconSizes.pop()];
|
||||
let iconURI = null;
|
||||
try {
|
||||
iconURI = Services.io.newURI(biggestIcon, null, null);
|
||||
if (iconURI.scheme == "data") {
|
||||
return iconURI.spec;
|
||||
}
|
||||
} catch (ex) {
|
||||
// we don't have a biggestIcon or its not a valid url
|
||||
}
|
||||
|
||||
// if we have an origin, try to resolve biggestIcon as a relative url
|
||||
if (!iconURI && aOrigin) {
|
||||
try {
|
||||
iconURI = Services.io.newURI(aOrigin.resolve(biggestIcon), null, null);
|
||||
} catch (ex) {
|
||||
console.log("Could not resolve url: " + aOrigin.spec + " " + biggestIcon + " - " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
return iconURI ? iconURI.spec : DEFAULT_ICON;
|
||||
},
|
||||
|
||||
doInstall: function doInstall(aData) {
|
||||
let jsonManifest = aData.isPackage ? aData.app.updateManifest : aData.app.manifest;
|
||||
let manifest = new ManifestHelper(jsonManifest, aData.app.origin);
|
||||
@ -7192,7 +7163,7 @@ var WebappsUI = {
|
||||
|
||||
// the manifest argument is the manifest from within the zip file,
|
||||
// TODO so now would be a good time to ask about permissions.
|
||||
self.makeBase64Icon(self.getBiggestIcon(manifest.icons, Services.io.newURI(aData.app.origin, null, null)),
|
||||
self.makeBase64Icon(localeManifest.biggestIconURL || this.DEFAULT_ICON,
|
||||
function(scaledIcon, fullsizeIcon) {
|
||||
// if java returned a profile path to us, try to use it to pre-populate the app cache
|
||||
// also save the icon so that it can be used in the splash screen
|
||||
@ -7322,9 +7293,8 @@ var WebappsUI = {
|
||||
|
||||
// if the image failed to load, and it was not our default icon, attempt to
|
||||
// use our default as a fallback
|
||||
let uri = Services.io.newURI(favicon.src, null, null);
|
||||
if (!/^chrome$/.test(uri.scheme)) {
|
||||
favicon.src = WebappsUI.getBiggestIcon(null);
|
||||
if (favicon.src != WebappsUI.DEFAULT_ICON) {
|
||||
favicon.src = WebappsUI.DEFAULT_ICON;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -26,8 +26,8 @@ chrome.jar:
|
||||
content/readerWorker.js (content/readerWorker.js)
|
||||
content/aboutHome.xhtml (content/aboutHome.xhtml)
|
||||
content/aboutRights.xhtml (content/aboutRights.xhtml)
|
||||
content/aboutApps.xhtml (content/aboutApps.xhtml)
|
||||
content/aboutApps.js (content/aboutApps.js)
|
||||
* content/aboutApps.xhtml (content/aboutApps.xhtml)
|
||||
* content/aboutApps.js (content/aboutApps.js)
|
||||
content/blockedSite.xhtml (content/blockedSite.xhtml)
|
||||
content/languages.properties (content/languages.properties)
|
||||
content/browser.xul (content/browser.xul)
|
||||
|
37
security/manager/ssl/tests/compiled/TestCertDB.cpp
Normal file
37
security/manager/ssl/tests/compiled/TestCertDB.cpp
Normal file
@ -0,0 +1,37 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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 "nsCOMPtr.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIX509CertDB.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
{
|
||||
NS_InitXPCOM2(nullptr, nullptr, nullptr);
|
||||
nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
if (!prefs) {
|
||||
return -1;
|
||||
}
|
||||
// When NSS initializes, it attempts to get some localized strings.
|
||||
// As a result, OS X and Windows flip out if this isn't set.
|
||||
// (This isn't done automatically since this test doesn't have a
|
||||
// lot of the other boilerplate components that would otherwise
|
||||
// keep the certificate db alive longer than we want it to.)
|
||||
nsresult rv = prefs->SetBoolPref("intl.locale.matchOS", true);
|
||||
if (NS_FAILED(rv)) {
|
||||
return -1;
|
||||
}
|
||||
nsCOMPtr<nsIX509CertDB> certdb(do_GetService(NS_X509CERTDB_CONTRACTID));
|
||||
if (!certdb) {
|
||||
return -1;
|
||||
}
|
||||
} // this scopes the nsCOMPtrs
|
||||
// no nsCOMPtrs are allowed to be alive when you call NS_ShutdownXPCOM
|
||||
NS_ShutdownXPCOM(nullptr);
|
||||
return 0;
|
||||
}
|
9
security/manager/ssl/tests/compiled/moz.build
Normal file
9
security/manager/ssl/tests/compiled/moz.build
Normal file
@ -0,0 +1,9 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
CPP_UNIT_TESTS += [
|
||||
'TestCertDB.cpp',
|
||||
]
|
@ -11,4 +11,8 @@ TEST_DIRS += [
|
||||
'mochitest',
|
||||
]
|
||||
|
||||
TEST_TOOL_DIRS += [
|
||||
'compiled',
|
||||
]
|
||||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['unit/xpcshell.ini']
|
||||
|
@ -2,8 +2,9 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import traceback
|
||||
|
||||
class ErrorCodes(object):
|
||||
|
||||
SUCCESS = 0
|
||||
NO_SUCH_ELEMENT = 7
|
||||
NO_SUCH_FRAME = 8
|
||||
@ -33,18 +34,26 @@ class ErrorCodes(object):
|
||||
MARIONETTE_ERROR = 500
|
||||
|
||||
class MarionetteException(Exception):
|
||||
|
||||
def __init__(self, message=None, status=ErrorCodes.MARIONETTE_ERROR, stacktrace=None):
|
||||
def __init__(self, message=None,
|
||||
status=ErrorCodes.MARIONETTE_ERROR, cause=None,
|
||||
stacktrace=None):
|
||||
self.msg = message
|
||||
self.status = status
|
||||
self.cause = cause
|
||||
self.stacktrace = stacktrace
|
||||
|
||||
def __str__(self):
|
||||
msg = str(self.msg)
|
||||
tb = None
|
||||
|
||||
if self.cause:
|
||||
msg += ", caused by %r" % self.cause[0]
|
||||
tb = self.cause[2]
|
||||
if self.stacktrace:
|
||||
return '%s\n\tstacktrace:\n%s' % (str(self.msg),
|
||||
''.join(['\t%s\n' % x for x in self.stacktrace.split('\n')]))
|
||||
else:
|
||||
return str(self.msg)
|
||||
stack = "".join(["\t%s\n" % x for x in self.stacktrace.splitlines()])
|
||||
msg += "\nstacktrace:\n%s" % stack
|
||||
|
||||
return "".join(traceback.format_exception(self.__class__, msg, tb))
|
||||
|
||||
class InstallGeckoError(MarionetteException):
|
||||
pass
|
||||
|
@ -509,6 +509,8 @@ class Marionette(object):
|
||||
busybox=busybox)
|
||||
|
||||
def cleanup(self):
|
||||
if self.session:
|
||||
self.delete_session()
|
||||
if self.emulator:
|
||||
self.emulator.close()
|
||||
if self.instance:
|
||||
|
@ -0,0 +1,46 @@
|
||||
# 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/.
|
||||
|
||||
import sys
|
||||
|
||||
import errors
|
||||
import marionette_test
|
||||
|
||||
from errors import ErrorCodes
|
||||
|
||||
def fake_cause():
|
||||
try:
|
||||
raise ValueError("bar")
|
||||
except ValueError as e:
|
||||
return sys.exc_info()
|
||||
|
||||
message = "foo"
|
||||
status = ErrorCodes.TIMEOUT
|
||||
cause = fake_cause()
|
||||
stacktrace = "first\nsecond"
|
||||
|
||||
class TestMarionetteException(marionette_test.MarionetteTestCase):
|
||||
def test_defaults(self):
|
||||
exc = errors.MarionetteException()
|
||||
self.assertIsNone(exc.msg)
|
||||
self.assertEquals(exc.status, ErrorCodes.MARIONETTE_ERROR)
|
||||
self.assertIsNone(exc.cause)
|
||||
self.assertIsNone(exc.stacktrace)
|
||||
|
||||
def test_construction(self):
|
||||
exc = errors.MarionetteException(
|
||||
message=message, status=status, cause=cause, stacktrace=stacktrace)
|
||||
self.assertEquals(exc.msg, message)
|
||||
self.assertEquals(exc.status, status)
|
||||
self.assertEquals(exc.cause, cause)
|
||||
self.assertEquals(exc.stacktrace, stacktrace)
|
||||
|
||||
def test_str(self):
|
||||
exc = errors.MarionetteException(
|
||||
message=message, status=status, cause=cause, stacktrace=stacktrace)
|
||||
s = str(exc)
|
||||
self.assertIn(message, s)
|
||||
self.assertIn(", caused by %r" % cause[0], s)
|
||||
self.assertIn("\nstacktrace:\n\tfirst\n\tsecond\n", s)
|
||||
self.assertIn("MarionetteException:", s)
|
@ -73,10 +73,10 @@ class TestNavigate(MarionetteTestCase):
|
||||
try:
|
||||
self.marionette.navigate("thisprotocoldoesnotexist://")
|
||||
self.fail("Should have thrown a MarionetteException")
|
||||
except TimeoutException:
|
||||
except TimeoutException:
|
||||
self.fail("The socket shouldn't have timed out when navigating to a non-existent URL")
|
||||
except MarionetteException as e:
|
||||
self.assertEqual(str(e), 'Error loading page')
|
||||
self.assertIn("Error loading page", str(e))
|
||||
except Exception as inst:
|
||||
import traceback
|
||||
print traceback.format_exc()
|
||||
@ -108,4 +108,3 @@ class TestNavigate(MarionetteTestCase):
|
||||
self.marionette.navigate(test_iframe)
|
||||
self.assertTrue('test_iframe.html' in self.marionette.get_url())
|
||||
self.assertTrue(self.marionette.find_element("id", "test_iframe"))
|
||||
|
||||
|
@ -2,7 +2,6 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import unittest
|
||||
import time
|
||||
import sys
|
||||
|
||||
@ -167,14 +166,29 @@ class WaitUntilTest(MarionetteTestCase):
|
||||
self.assertEqual(self.clock.ticks, 10)
|
||||
|
||||
def test_exception_raises_immediately(self):
|
||||
with self.assertRaises(Exception):
|
||||
self.w.until(lambda x: x.exception())
|
||||
with self.assertRaises(TypeError):
|
||||
self.w.until(lambda x: x.exception(e=TypeError))
|
||||
self.assertEqual(self.clock.ticks, 0)
|
||||
|
||||
def test_custom_ignored_exception(self):
|
||||
self.w.exceptions = self.w.exceptions + (Exception,)
|
||||
with self.assertRaises(Exception):
|
||||
self.w.until(lambda x: x.exception(e=Exception))
|
||||
def test_ignored_exception(self):
|
||||
self.w.exceptions = (TypeError,)
|
||||
with self.assertRaises(errors.TimeoutException):
|
||||
self.w.until(lambda x: x.exception(e=TypeError))
|
||||
|
||||
def test_ignored_exception_wrapped_in_timeoutexception(self):
|
||||
self.w.exceptions = (TypeError,)
|
||||
|
||||
exc = None
|
||||
try:
|
||||
self.w.until(lambda x: x.exception(e=TypeError))
|
||||
except Exception as e:
|
||||
exc = e
|
||||
|
||||
s = str(exc)
|
||||
self.assertIsNotNone(exc)
|
||||
self.assertIsInstance(exc, errors.TimeoutException)
|
||||
self.assertIn(", caused by %r" % TypeError, s)
|
||||
self.assertIn("self.w.until(lambda x: x.exception(e=TypeError))", s)
|
||||
|
||||
def test_ignored_exception_after_timeout_is_not_raised(self):
|
||||
with self.assertRaises(errors.TimeoutException):
|
||||
|
@ -93,7 +93,6 @@ b2g = false
|
||||
b2g = false
|
||||
[test_implicit_waits.py]
|
||||
[test_wait.py]
|
||||
qemu = false
|
||||
[test_date_time_value.py]
|
||||
[test_getactiveframe_oop.py]
|
||||
disabled = "Bug 925688"
|
||||
@ -101,3 +100,4 @@ disabled = "Bug 925688"
|
||||
[test_chrome_async_finish.js]
|
||||
[test_screen_orientation.py]
|
||||
browser = false
|
||||
[test_errors.py]
|
@ -4,6 +4,7 @@
|
||||
|
||||
import collections
|
||||
import errors
|
||||
import sys
|
||||
import time
|
||||
|
||||
DEFAULT_TIMEOUT = 5
|
||||
@ -108,7 +109,7 @@ class Wait(object):
|
||||
except (KeyboardInterrupt, SystemExit) as e:
|
||||
raise e
|
||||
except self.exceptions as e:
|
||||
last_exc = e
|
||||
last_exc = sys.exc_info()
|
||||
|
||||
if isinstance(rv, bool) and not rv:
|
||||
self.clock.sleep(self.interval)
|
||||
@ -119,11 +120,9 @@ class Wait(object):
|
||||
|
||||
self.clock.sleep(self.interval)
|
||||
|
||||
if last_exc is not None:
|
||||
raise last_exc
|
||||
|
||||
raise errors.TimeoutException(
|
||||
"Timed out after %s seconds" % (self.clock.now - start))
|
||||
"Timed out after %s seconds" % (self.clock.now - start),
|
||||
cause=last_exc)
|
||||
|
||||
def until_pred(clock, end):
|
||||
return clock.now >= end
|
||||
|
@ -39,6 +39,7 @@
|
||||
let SysAll = require("resource://gre/modules/osfile/osfile_win_allthreads.jsm");
|
||||
let LOG = SharedAll.LOG.bind(SharedAll, "Unix", "back");
|
||||
let libc = SysAll.libc;
|
||||
let advapi32 = new SharedAll.Library("advapi32", "advapi32.dll");
|
||||
let Const = SharedAll.Constants.Win;
|
||||
|
||||
/**
|
||||
@ -121,9 +122,30 @@
|
||||
Type.zero_or_nothing =
|
||||
Type.int.withName("zero_or_nothing");
|
||||
|
||||
/**
|
||||
* A C integer holding flags related to NTFS security.
|
||||
*/
|
||||
Type.SECURITY_ATTRIBUTES =
|
||||
Type.void_t.withName("SECURITY_ATTRIBUTES");
|
||||
|
||||
/**
|
||||
* A C integer holding pointers related to NTFS security.
|
||||
*/
|
||||
Type.PSID =
|
||||
Type.voidptr_t.withName("PSID");
|
||||
|
||||
Type.PACL =
|
||||
Type.voidptr_t.withName("PACL");
|
||||
|
||||
Type.PSECURITY_DESCRIPTOR =
|
||||
Type.voidptr_t.withName("PSECURITY_DESCRIPTOR");
|
||||
|
||||
/**
|
||||
* A C integer holding Win32 local memory handle.
|
||||
*/
|
||||
Type.HLOCAL =
|
||||
Type.voidptr_t.withName("HLOCAL");
|
||||
|
||||
Type.FILETIME =
|
||||
new SharedAll.Type("FILETIME",
|
||||
ctypes.StructType("FILETIME", [
|
||||
@ -356,6 +378,34 @@
|
||||
/*return*/ Type.zero_or_nothing,
|
||||
/*fileName*/ Type.path,
|
||||
/*fileAttributes*/ Type.DWORD);
|
||||
|
||||
advapi32.declareLazyFFI(SysFile, "GetNamedSecurityInfo",
|
||||
"GetNamedSecurityInfoW", ctypes.winapi_abi,
|
||||
/*return*/ Type.DWORD,
|
||||
/*objectName*/ Type.path,
|
||||
/*objectType*/ Type.DWORD,
|
||||
/*securityInfo*/ Type.DWORD,
|
||||
/*sidOwner*/ Type.PSID.out_ptr,
|
||||
/*sidGroup*/ Type.PSID.out_ptr,
|
||||
/*dacl*/ Type.PACL.out_ptr,
|
||||
/*sacl*/ Type.PACL.out_ptr,
|
||||
/*securityDesc*/ Type.PSECURITY_DESCRIPTOR.out_ptr);
|
||||
|
||||
advapi32.declareLazyFFI(SysFile, "SetNamedSecurityInfo",
|
||||
"SetNamedSecurityInfoW", ctypes.winapi_abi,
|
||||
/*return*/ Type.DWORD,
|
||||
/*objectName*/ Type.path,
|
||||
/*objectType*/ Type.DWORD,
|
||||
/*securityInfo*/ Type.DWORD,
|
||||
/*sidOwner*/ Type.PSID,
|
||||
/*sidGroup*/ Type.PSID,
|
||||
/*dacl*/ Type.PACL,
|
||||
/*sacl*/ Type.PACL);
|
||||
|
||||
declareLazyFFI(SysFile, "LocalFree", libc,
|
||||
"LocalFree", ctypes.winapi_abi,
|
||||
/*return*/ Type.HLOCAL,
|
||||
/*mem*/ Type.HLOCAL);
|
||||
};
|
||||
|
||||
exports.OS.Win = {
|
||||
|
@ -516,6 +516,37 @@
|
||||
throw_on_zero("move",
|
||||
WinFile.MoveFileEx(sourcePath, destPath, flags)
|
||||
);
|
||||
|
||||
// Inherit NTFS permissions from the destination directory
|
||||
// if possible.
|
||||
if (Path.dirname(sourcePath) === Path.dirname(destPath)) {
|
||||
// Skip if the move operation was the simple rename,
|
||||
return;
|
||||
}
|
||||
// The function may fail for various reasons (e.g. not all
|
||||
// filesystems support NTFS permissions or the user may not
|
||||
// have the enough rights to read/write permissions).
|
||||
// However we can safely ignore errors. The file was already
|
||||
// moved. Setting permissions is not mandatory.
|
||||
let dacl = new ctypes.voidptr_t();
|
||||
let sd = new ctypes.voidptr_t();
|
||||
WinFile.GetNamedSecurityInfo(destPath, Const.SE_FILE_OBJECT,
|
||||
Const.DACL_SECURITY_INFORMATION,
|
||||
null /*sidOwner*/, null /*sidGroup*/,
|
||||
dacl.address(), null /*sacl*/,
|
||||
sd.address());
|
||||
// dacl will be set only if the function succeeds.
|
||||
if (!dacl.isNull()) {
|
||||
WinFile.SetNamedSecurityInfo(destPath, Const.SE_FILE_OBJECT,
|
||||
Const.DACL_SECURITY_INFORMATION |
|
||||
Const.UNPROTECTED_DACL_SECURITY_INFORMATION,
|
||||
null /*sidOwner*/, null /*sidGroup*/,
|
||||
dacl, null /*sacl*/);
|
||||
}
|
||||
// sd will be set only if the function succeeds.
|
||||
if (!sd.isNull()) {
|
||||
WinFile.LocalFree(Type.HLOCAL.cast(sd));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user