mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 03:15:11 +00:00
Merge mozilla-central to autoland. a=merge CLOSED TREE
This commit is contained in:
commit
9de29c1f5a
7
.flake8
7
.flake8
@ -7,6 +7,13 @@ exclude =
|
|||||||
browser/moz.configure,
|
browser/moz.configure,
|
||||||
build/moz.configure/*.configure,
|
build/moz.configure/*.configure,
|
||||||
build/pymake/,
|
build/pymake/,
|
||||||
|
dom/canvas/test/webgl-conf/checkout/closure-library/,
|
||||||
|
editor/libeditor/tests/browserscope/,
|
||||||
|
intl/icu/,
|
||||||
|
ipc/chromium/,
|
||||||
|
gfx/angle/,
|
||||||
|
gfx/harfbuzz,
|
||||||
|
glx/skia/,
|
||||||
js/*.configure,
|
js/*.configure,
|
||||||
memory/moz.configure,
|
memory/moz.configure,
|
||||||
mobile/android/*.configure,
|
mobile/android/*.configure,
|
||||||
|
@ -209,7 +209,8 @@ SelectionManager::ProcessSelectionChanged(SelData* aSelData)
|
|||||||
|
|
||||||
HyperTextAccessible* text = nsAccUtils::GetTextContainer(cntrNode);
|
HyperTextAccessible* text = nsAccUtils::GetTextContainer(cntrNode);
|
||||||
if (!text) {
|
if (!text) {
|
||||||
NS_NOTREACHED("We must reach document accessible implementing text interface!");
|
// FIXME bug 1126649
|
||||||
|
NS_ERROR("We must reach document accessible implementing text interface!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -146,12 +146,12 @@
|
|||||||
|
|
||||||
<vbox flex="1">
|
<vbox flex="1">
|
||||||
|
|
||||||
<listbox>
|
<richlistbox>
|
||||||
<listitem label="listitem1" id="listitem1"/>
|
<richlistitem id="listitem1"/>
|
||||||
<listitem label="listitem2" id="listitem2" type="checkbox"/>
|
<richlistitem id="listitem2"><label value="listitem2"/></richlistitem>
|
||||||
<listitem label="listitem3" id="listitem3" type="checkbox"/>
|
<richlistitem id="listitem3"/>
|
||||||
<listitem label="listitem4" id="listitem4"/>
|
<richlistitem id="listitem4"><label value="listitem4"/></richlistitem>
|
||||||
</listbox>
|
</richlistbox>
|
||||||
|
|
||||||
<menubar>
|
<menubar>
|
||||||
<menu label="item1" id="menu_item1">
|
<menu label="item1" id="menu_item1">
|
||||||
|
@ -63,10 +63,10 @@
|
|||||||
|
|
||||||
<vbox flex="1">
|
<vbox flex="1">
|
||||||
<label control="listbox1" value="listbox: "/>
|
<label control="listbox1" value="listbox: "/>
|
||||||
<listbox id="listbox1">
|
<richlistbox id="listbox1">
|
||||||
<listitem label="item1" id="item1"/>
|
<richlistitem id="item1"><label value="item1"/></richlistitem>
|
||||||
<listitem label="item2" id="item2"/>
|
<richlistitem id="item1"><label value="item2"/></richlistitem>
|
||||||
</listbox>
|
</richlistbox>
|
||||||
</vbox>
|
</vbox>
|
||||||
</hbox>
|
</hbox>
|
||||||
|
|
||||||
|
@ -30,16 +30,6 @@
|
|||||||
// Test focus events.
|
// Test focus events.
|
||||||
gQueue = new eventQueue();
|
gQueue = new eventQueue();
|
||||||
|
|
||||||
gQueue.push(new synthFocus("listbox", new focusChecker("lb_item1")));
|
|
||||||
gQueue.push(new synthDownKey("lb_item1", new focusChecker("lb_item2")));
|
|
||||||
gQueue.push(new synthTab("lb_item2", new focusChecker("mslb_item1")));
|
|
||||||
gQueue.push(new synthDownKey("mslb_item1", new focusChecker("mslb_item2"), { shiftKey: true }));
|
|
||||||
gQueue.push(new synthTab("mslb_item2", new focusChecker("emptylistbox")));
|
|
||||||
gQueue.push(new synthFocus("mcolumnlistbox", new focusChecker("mclb_item1")));
|
|
||||||
gQueue.push(new synthDownKey("mclb_item1", new focusChecker("mclb_item2")));
|
|
||||||
gQueue.push(new synthFocus("headerlistbox", new focusChecker("hlb_item1")));
|
|
||||||
gQueue.push(new synthDownKey("hlb_item1", new focusChecker("hlb_item2")));
|
|
||||||
|
|
||||||
gQueue.push(new synthFocus("richlistbox", new focusChecker("rlb_item1")));
|
gQueue.push(new synthFocus("richlistbox", new focusChecker("rlb_item1")));
|
||||||
gQueue.push(new synthDownKey("rlb_item1", new focusChecker("rlb_item2")));
|
gQueue.push(new synthDownKey("rlb_item1", new focusChecker("rlb_item2")));
|
||||||
gQueue.push(new synthFocus("multiselrichlistbox", new focusChecker("msrlb_item1")));
|
gQueue.push(new synthFocus("multiselrichlistbox", new focusChecker("msrlb_item1")));
|
||||||
@ -70,9 +60,8 @@ if (!MAC) {
|
|||||||
|
|
||||||
// no focus events for unfocused list controls when current item is
|
// no focus events for unfocused list controls when current item is
|
||||||
// changed.
|
// changed.
|
||||||
gQueue.push(new synthFocus("emptylistbox"));
|
gQueue.push(new synthFocus("emptyrichlistbox"));
|
||||||
|
|
||||||
gQueue.push(new changeCurrentItem("listbox", "lb_item1"));
|
|
||||||
gQueue.push(new changeCurrentItem("richlistbox", "rlb_item1"));
|
gQueue.push(new changeCurrentItem("richlistbox", "rlb_item1"));
|
||||||
if (!MAC) {
|
if (!MAC) {
|
||||||
gQueue.push(new changeCurrentItem("menulist", WIN ? "ml_marmalade" : "ml_tangerine"));
|
gQueue.push(new changeCurrentItem("menulist", WIN ? "ml_marmalade" : "ml_tangerine"));
|
||||||
@ -110,48 +99,6 @@ if (!MAC) {
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
<vbox flex="1">
|
<vbox flex="1">
|
||||||
<listbox id="listbox" rows="3">
|
|
||||||
<listitem id="lb_item1" label="item1"/>
|
|
||||||
<listitem id="lb_item2" label="item1"/>
|
|
||||||
</listbox>
|
|
||||||
<listbox id="multisellistbox" rows="3" seltype="multiple">
|
|
||||||
<listitem id="mslb_item1" label="item1"/>
|
|
||||||
<listitem id="mslb_item2" label="item1"/>
|
|
||||||
</listbox>
|
|
||||||
<listbox id="emptylistbox" rows="3"/>
|
|
||||||
<listbox id="mcolumnlistbox" rows="3">
|
|
||||||
<listcols>
|
|
||||||
<listcol/>
|
|
||||||
<listcol/>
|
|
||||||
</listcols>
|
|
||||||
<listitem id="mclb_item1">
|
|
||||||
<listcell label="George"/>
|
|
||||||
<listcell label="House Painter"/>
|
|
||||||
</listitem>
|
|
||||||
<listitem id="mclb_item2">
|
|
||||||
<listcell label="Mary Ellen"/>
|
|
||||||
<listcell label="Candle Maker"/>
|
|
||||||
</listitem>
|
|
||||||
</listbox>
|
|
||||||
<listbox id="headerlistbox" rows="3">
|
|
||||||
<listhead>
|
|
||||||
<listheader label="Name"/>
|
|
||||||
<listheader label="Occupation"/>
|
|
||||||
</listhead>
|
|
||||||
<listcols>
|
|
||||||
<listcol/>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
</listcols>
|
|
||||||
<listitem id="hlb_item1">
|
|
||||||
<listcell label="George"/>
|
|
||||||
<listcell label="House Painter"/>
|
|
||||||
</listitem>
|
|
||||||
<listitem id="hlb_item2">
|
|
||||||
<listcell label="Mary Ellen"/>
|
|
||||||
<listcell label="Candle Maker"/>
|
|
||||||
</listitem>
|
|
||||||
</listbox>
|
|
||||||
|
|
||||||
<richlistbox id="richlistbox">
|
<richlistbox id="richlistbox">
|
||||||
<richlistitem id="rlb_item1">
|
<richlistitem id="rlb_item1">
|
||||||
<description>A XUL Description!</description>
|
<description>A XUL Description!</description>
|
||||||
|
@ -166,9 +166,12 @@
|
|||||||
gQueue.push(new advanceTab("tabs", 1, "tab3"));
|
gQueue.push(new advanceTab("tabs", 1, "tab3"));
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// listbox
|
// single selection listbox, the first item is selected by default
|
||||||
gQueue.push(new synthClick("lb1_item1",
|
|
||||||
new invokerChecker(EVENT_SELECTION, "lb1_item1")));
|
gQueue.push(new synthClick("lb1_item2",
|
||||||
|
new invokerChecker(EVENT_SELECTION, "lb1_item2")));
|
||||||
|
gQueue.push(new synthUpKey("lb1_item2",
|
||||||
|
new invokerChecker(EVENT_SELECTION, "lb1_item1")));
|
||||||
gQueue.push(new synthDownKey("lb1_item1",
|
gQueue.push(new synthDownKey("lb1_item1",
|
||||||
new invokerChecker(EVENT_SELECTION, "lb1_item2")));
|
new invokerChecker(EVENT_SELECTION, "lb1_item2")));
|
||||||
|
|
||||||
@ -234,20 +237,20 @@
|
|||||||
</tabpanels>
|
</tabpanels>
|
||||||
</tabbox>
|
</tabbox>
|
||||||
|
|
||||||
<listbox id="listbox">
|
<richlistbox id="listbox">
|
||||||
<listitem id="lb1_item1" label="item1"/>
|
<richlistitem id="lb1_item1"><label value="item1"/></richlistitem>
|
||||||
<listitem id="lb1_item2" label="item2"/>
|
<richlistitem id="lb1_item2"><label value="item2"/></richlistitem>
|
||||||
</listbox>
|
</richlistbox>
|
||||||
|
|
||||||
<listbox id="listbox2" seltype="multiple">
|
<richlistbox id="listbox2" seltype="multiple">
|
||||||
<listitem id="lb2_item1" label="item1"/>
|
<richlistitem id="lb2_item1"><label value="item1"/></richlistitem>
|
||||||
<listitem id="lb2_item2" label="item2"/>
|
<richlistitem id="lb2_item2"><label value="item2"/></richlistitem>
|
||||||
<listitem id="lb2_item3" label="item3"/>
|
<richlistitem id="lb2_item3"><label value="item3"/></richlistitem>
|
||||||
<listitem id="lb2_item4" label="item4"/>
|
<richlistitem id="lb2_item4"><label value="item4"/></richlistitem>
|
||||||
<listitem id="lb2_item5" label="item5"/>
|
<richlistitem id="lb2_item5"><label value="item5"/></richlistitem>
|
||||||
<listitem id="lb2_item6" label="item6"/>
|
<richlistitem id="lb2_item6"><label value="item6"/></richlistitem>
|
||||||
<listitem id="lb2_item7" label="item7"/>
|
<richlistitem id="lb2_item7"><label value="item7"/></richlistitem>
|
||||||
</listbox>
|
</richlistbox>
|
||||||
|
|
||||||
</hbox>
|
</hbox>
|
||||||
</window>
|
</window>
|
||||||
|
@ -95,10 +95,10 @@
|
|||||||
<treechildren id="treechildren"/>
|
<treechildren id="treechildren"/>
|
||||||
</tree>
|
</tree>
|
||||||
|
|
||||||
<listbox id="listbox">
|
<richlistbox id="listbox">
|
||||||
<listitem id="listitem1">item1</listitem>
|
<richlistitem id="listitem1"><label value="item1"/></richlistitem>
|
||||||
<listitem id="listitem2">item2</listitem>
|
<richlistitem id="listitem2"><label value="item2"/></richlistitem>
|
||||||
</listbox>
|
</richlistbox>
|
||||||
|
|
||||||
<vbox id="eventdump"/>
|
<vbox id="eventdump"/>
|
||||||
</vbox>
|
</vbox>
|
||||||
|
@ -276,10 +276,11 @@
|
|||||||
label="labeled element"/>
|
label="labeled element"/>
|
||||||
|
|
||||||
<!-- nsIDOMXULSelectControlItemElement -->
|
<!-- nsIDOMXULSelectControlItemElement -->
|
||||||
<listbox>
|
<richlistbox>
|
||||||
<listitem id="li_nsIDOMXULSelectControlItemElement"
|
<richlistitem id="li_nsIDOMXULSelectControlItemElement">
|
||||||
label="select control item"/>
|
<label value="select control item"/>
|
||||||
</listbox>
|
</richlistitem>
|
||||||
|
</richlistbox>
|
||||||
|
|
||||||
<!-- not nsIDOMXULSelectControlElement -->
|
<!-- not nsIDOMXULSelectControlElement -->
|
||||||
<box id="box_not_nsIDOMXULSelectControlElement" role="group" label="box"/>
|
<box id="box_not_nsIDOMXULSelectControlElement" role="group" label="box"/>
|
||||||
@ -359,11 +360,12 @@
|
|||||||
|
|
||||||
<!-- bug 441991; create name from other menuitem label listitem's own label -->
|
<!-- bug 441991; create name from other menuitem label listitem's own label -->
|
||||||
<hbox>
|
<hbox>
|
||||||
<listbox>
|
<richlistbox>
|
||||||
<listitem id="li_labelledby"
|
<richlistitem id="li_labelledby"
|
||||||
label="The moment the event starts"
|
aria-labelledby="menuitem-DISPLAY li_labelledby">
|
||||||
aria-labelledby="menuitem-DISPLAY li_labelledby"/>
|
<label value="The moment the event starts"/>
|
||||||
</listbox>
|
</richlistitem>
|
||||||
|
</richlistbox>
|
||||||
<menulist>
|
<menulist>
|
||||||
<menupopup>
|
<menupopup>
|
||||||
<menuitem id="menuitem-DISPLAY"
|
<menuitem id="menuitem-DISPLAY"
|
||||||
|
@ -32,13 +32,14 @@
|
|||||||
function doTest()
|
function doTest()
|
||||||
{
|
{
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// single selectable listbox
|
// single selectable listbox, the first item is selected by default
|
||||||
|
|
||||||
var id = "listbox";
|
var id = "listbox";
|
||||||
ok(isAccessible(id, [nsIAccessibleSelectable]),
|
ok(isAccessible(id, [nsIAccessibleSelectable]),
|
||||||
"No selectable accessible for list of " + id);
|
"No selectable accessible for list of " + id);
|
||||||
|
|
||||||
var select = getAccessible(id, [nsIAccessibleSelectable]);
|
var select = getAccessible(id, [nsIAccessibleSelectable]);
|
||||||
|
select.removeItemFromSelection(0);
|
||||||
testSelectableSelection(select, [ ]);
|
testSelectableSelection(select, [ ]);
|
||||||
|
|
||||||
select.addItemToSelection(1);
|
select.addItemToSelection(1);
|
||||||
@ -114,35 +115,27 @@
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
<vbox flex="1">
|
<vbox flex="1">
|
||||||
<listbox id="listbox">
|
<richlistbox id="listbox">
|
||||||
<listcols>
|
<richlistitem id="lb1_item1">
|
||||||
<listcol flex="1"/>
|
<label value="cell0"/>
|
||||||
<listcol flex="1"/>
|
<label value="cell1"/>
|
||||||
</listcols>
|
</richlistitem>
|
||||||
<listitem id="lb1_item1">
|
<richlistitem id="lb1_item2">
|
||||||
<listcell label="cell0"/>
|
<label value="cell3"/>
|
||||||
<listcell label="cell1"/>
|
<label value="cell4"/>
|
||||||
</listitem>
|
</richlistitem>
|
||||||
<listitem id="lb1_item2">
|
</richlistbox>
|
||||||
<listcell label="cell3"/>
|
|
||||||
<listcell label="cell4"/>
|
|
||||||
</listitem>
|
|
||||||
</listbox>
|
|
||||||
|
|
||||||
<listbox id="listbox2" seltype="multiple">
|
<richlistbox id="listbox2" seltype="multiple">
|
||||||
<listcols>
|
<richlistitem id="lb2_item1">
|
||||||
<listcol flex="1"/>
|
<label value="cell0"/>
|
||||||
<listcol flex="1"/>
|
<label value="cell1"/>
|
||||||
</listcols>
|
</richlistitem>
|
||||||
<listitem id="lb2_item1">
|
<richlistitem id="lb2_item2">
|
||||||
<listcell label="cell0"/>
|
<label value="cell3"/>
|
||||||
<listcell label="cell1"/>
|
<label value="cell4"/>
|
||||||
</listitem>
|
</richlistitem>
|
||||||
<listitem id="lb2_item2">
|
</richlistbox>
|
||||||
<listcell label="cell3"/>
|
|
||||||
<listcell label="cell4"/>
|
|
||||||
</listitem>
|
|
||||||
</listbox>
|
|
||||||
|
|
||||||
<vbox id="debug"/>
|
<vbox id="debug"/>
|
||||||
</vbox>
|
</vbox>
|
||||||
|
@ -155,7 +155,7 @@ function testStates(aAccOrElmOrID, aState, aExtraState, aAbsentState,
|
|||||||
"Mixed element cannot be state checked!");
|
"Mixed element cannot be state checked!");
|
||||||
|
|
||||||
// selected/selectable
|
// selected/selectable
|
||||||
if (state & STATE_SELECTED) {
|
if ((state & STATE_SELECTED) && !(aAbsentState & STATE_SELECTABLE)) {
|
||||||
isState(state & STATE_SELECTABLE, STATE_SELECTABLE, false,
|
isState(state & STATE_SELECTABLE, STATE_SELECTABLE, false,
|
||||||
"Selected element must be selectable!");
|
"Selected element must be selectable!");
|
||||||
}
|
}
|
||||||
|
@ -64,9 +64,9 @@
|
|||||||
testStates("combobox", STATE_FOCUSABLE | STATE_HASPOPUP, 0, STATE_UNAVAILABLE);
|
testStates("combobox", STATE_FOCUSABLE | STATE_HASPOPUP, 0, STATE_UNAVAILABLE);
|
||||||
testStates("combobox-disabled", STATE_UNAVAILABLE | STATE_HASPOPUP, 0, STATE_FOCUSABLE);
|
testStates("combobox-disabled", STATE_UNAVAILABLE | STATE_HASPOPUP, 0, STATE_FOCUSABLE);
|
||||||
testStates("listbox", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE);
|
testStates("listbox", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE);
|
||||||
testStates("listitem", STATE_FOCUSABLE | STATE_SELECTABLE, 0, STATE_UNAVAILABLE);
|
testStates("listitem", STATE_FOCUSABLE | STATE_SELECTABLE | STATE_SELECTED, 0, STATE_UNAVAILABLE);
|
||||||
testStates("listbox-disabled", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE | STATE_SELECTABLE);
|
testStates("listbox-disabled", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE | STATE_SELECTABLE);
|
||||||
testStates("listitem-disabledlistbox", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE | STATE_SELECTABLE);
|
testStates("listitem-disabledlistbox", STATE_UNAVAILABLE | STATE_SELECTED, 0, STATE_FOCUSABLE | STATE_SELECTABLE);
|
||||||
testStates("menubar", 0, 0, STATE_FOCUSABLE);
|
testStates("menubar", 0, 0, STATE_FOCUSABLE);
|
||||||
testStates("menu", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE);
|
testStates("menu", STATE_FOCUSABLE, 0, STATE_UNAVAILABLE);
|
||||||
testStates("menu-disabled", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE | STATE_SELECTABLE);
|
testStates("menu-disabled", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE | STATE_SELECTABLE);
|
||||||
@ -135,13 +135,17 @@
|
|||||||
</menupopup>
|
</menupopup>
|
||||||
</menulist>
|
</menulist>
|
||||||
|
|
||||||
<listbox id="listbox">
|
<richlistbox id="listbox">
|
||||||
<listitem id="listitem" label="list item"/>
|
<richlistitem id="listitem">
|
||||||
</listbox>
|
<label value="list item"/>
|
||||||
|
</richlistitem>
|
||||||
|
</richlistbox>
|
||||||
|
|
||||||
<listbox id="listbox-disabled" disabled="true">
|
<richlistbox id="listbox-disabled" disabled="true">
|
||||||
<listitem id="listitem-disabledlistbox" label="list item"/>
|
<richlistitem id="listitem-disabledlistbox">
|
||||||
</listbox>
|
<label value="list item"/>
|
||||||
|
</richlistitem>
|
||||||
|
</richlistbox>
|
||||||
|
|
||||||
<toolbox>
|
<toolbox>
|
||||||
<menubar id="menubar">
|
<menubar id="menubar">
|
||||||
|
@ -5,22 +5,18 @@ support-files =
|
|||||||
[test_css_tables.html]
|
[test_css_tables.html]
|
||||||
[test_headers_ariagrid.html]
|
[test_headers_ariagrid.html]
|
||||||
[test_headers_ariatable.html]
|
[test_headers_ariatable.html]
|
||||||
[test_headers_listbox.xul]
|
|
||||||
[test_headers_table.html]
|
[test_headers_table.html]
|
||||||
[test_headers_tree.xul]
|
[test_headers_tree.xul]
|
||||||
[test_indexes_ariagrid.html]
|
[test_indexes_ariagrid.html]
|
||||||
[test_indexes_listbox.xul]
|
|
||||||
[test_indexes_table.html]
|
[test_indexes_table.html]
|
||||||
[test_indexes_tree.xul]
|
[test_indexes_tree.xul]
|
||||||
[test_layoutguess.html]
|
[test_layoutguess.html]
|
||||||
[test_mtable.html]
|
[test_mtable.html]
|
||||||
[test_sels_ariagrid.html]
|
[test_sels_ariagrid.html]
|
||||||
[test_sels_listbox.xul]
|
|
||||||
[test_sels_table.html]
|
[test_sels_table.html]
|
||||||
[test_sels_tree.xul]
|
[test_sels_tree.xul]
|
||||||
[test_struct_ariagrid.html]
|
[test_struct_ariagrid.html]
|
||||||
[test_struct_ariatreegrid.html]
|
[test_struct_ariatreegrid.html]
|
||||||
[test_struct_listbox.xul]
|
|
||||||
[test_struct_table.html]
|
[test_struct_table.html]
|
||||||
[test_struct_tree.xul]
|
[test_struct_tree.xul]
|
||||||
[test_table_1.html]
|
[test_table_1.html]
|
||||||
|
@ -1,194 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
|
||||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
|
||||||
type="text/css"?>
|
|
||||||
|
|
||||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
||||||
title="Table header information cells for XUL listbox">
|
|
||||||
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
|
||||||
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="../common.js"></script>
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="../table.js"></script>
|
|
||||||
|
|
||||||
<script type="application/javascript">
|
|
||||||
<![CDATA[
|
|
||||||
function doTest()
|
|
||||||
{
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// XUL listbox
|
|
||||||
|
|
||||||
var headerInfoMap = [
|
|
||||||
{
|
|
||||||
cell: "lb1_cell0",
|
|
||||||
rowHeaderCells: [],
|
|
||||||
columnHeaderCells: [ "lb1_header1" ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cell: "lb1_cell1",
|
|
||||||
rowHeaderCells: [],
|
|
||||||
columnHeaderCells: [ "lb1_header2" ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cell: "lb1_cell2",
|
|
||||||
rowHeaderCells: [],
|
|
||||||
columnHeaderCells: [ "lb1_header3" ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cell: "lb1_cell3",
|
|
||||||
rowHeaderCells: [],
|
|
||||||
columnHeaderCells: [ "lb1_header1" ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cell: "lb1_cell4",
|
|
||||||
rowHeaderCells: [],
|
|
||||||
columnHeaderCells: [ "lb1_header2" ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cell: "lb1_cell5",
|
|
||||||
rowHeaderCells: [],
|
|
||||||
columnHeaderCells: [ "lb1_header3" ]
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
testHeaderCells(headerInfoMap);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// XUL listbox with ARIA
|
|
||||||
|
|
||||||
headerInfoMap = [
|
|
||||||
{
|
|
||||||
cell: "lb2_cell0",
|
|
||||||
rowHeaderCells: [],
|
|
||||||
columnHeaderCells: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cell: "lb2_cell1",
|
|
||||||
rowHeaderCells: [],
|
|
||||||
columnHeaderCells: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cell: "lb2_cell2",
|
|
||||||
rowHeaderCells: [],
|
|
||||||
columnHeaderCells: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cell: "lb2_cell3",
|
|
||||||
rowHeaderCells: [],
|
|
||||||
columnHeaderCells: [ "lb2_cell0" ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cell: "lb2_cell4",
|
|
||||||
rowHeaderCells: [ "lb2_cell3" ],
|
|
||||||
columnHeaderCells: [ "lb2_cell1" ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cell: "lb2_cell5",
|
|
||||||
rowHeaderCells: [ "lb2_cell3" ],
|
|
||||||
columnHeaderCells: [ "lb2_cell2" ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cell: "lb2_cell6",
|
|
||||||
rowHeaderCells: [],
|
|
||||||
columnHeaderCells: [ "lb2_cell0" ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cell: "lb2_cell7",
|
|
||||||
rowHeaderCells: [ "lb2_cell6" ],
|
|
||||||
columnHeaderCells: [ "lb2_cell1" ]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
cell: "lb2_cell8",
|
|
||||||
rowHeaderCells: [ "lb2_cell6" ],
|
|
||||||
columnHeaderCells: [ "lb2_cell2" ]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
testHeaderCells(headerInfoMap);
|
|
||||||
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
addA11yLoadEvent(doTest);
|
|
||||||
]]>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<hbox style="overflow: auto;">
|
|
||||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<a target="_blank"
|
|
||||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=512424"
|
|
||||||
title="implement IAccessibleTable2">
|
|
||||||
Mozilla Bug 512424
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<p id="display"></p>
|
|
||||||
<div id="content" style="display: none">
|
|
||||||
</div>
|
|
||||||
<pre id="test">
|
|
||||||
</pre>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<vbox flex="1">
|
|
||||||
|
|
||||||
<label control="listbox" value="multicolumn listbox with header"/>
|
|
||||||
<listbox id="listbox">
|
|
||||||
<listhead>
|
|
||||||
<listheader id="lb1_header1" label="header1"/>
|
|
||||||
<listheader id="lb1_header2" label="header2"/>
|
|
||||||
<listheader id="lb1_header3" label="header3"/>
|
|
||||||
</listhead>
|
|
||||||
<listcols>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
</listcols>
|
|
||||||
<listitem>
|
|
||||||
<listcell id="lb1_cell0" label="cell0"/>
|
|
||||||
<listcell id="lb1_cell1" label="cell1"/>
|
|
||||||
<listcell id="lb1_cell2" label="cell2"/>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<listcell id="lb1_cell3" label="cell3"/>
|
|
||||||
<listcell id="lb1_cell4" label="cell4"/>
|
|
||||||
<listcell id="lb1_cell5" label="cell5"/>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<listcell id="lb1_cell6" label="cell6"/>
|
|
||||||
<listcell id="lb1_cell7" label="cell7"/>
|
|
||||||
<listcell id="lb1_cell8" label="cell8"/>
|
|
||||||
</listitem>
|
|
||||||
</listbox>
|
|
||||||
|
|
||||||
<label control="listbox2" value="multicolumn listbox with ARIA headers"/>
|
|
||||||
<listbox id="listbox2">
|
|
||||||
<listcols>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
</listcols>
|
|
||||||
<listitem>
|
|
||||||
<listcell role="columnheader" id="lb2_cell0" label="cell0"/>
|
|
||||||
<listcell role="columnheader" id="lb2_cell1" label="cell1"/>
|
|
||||||
<listcell role="columnheader" id="lb2_cell2" label="cell2"/>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<listcell role="rowheader" id="lb2_cell3" label="cell3"/>
|
|
||||||
<listcell id="lb2_cell4" label="cell4"/>
|
|
||||||
<listcell id="lb2_cell5" label="cell5"/>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<listcell role="rowheader" id="lb2_cell6" label="cell6"/>
|
|
||||||
<listcell id="lb2_cell7" label="cell7"/>
|
|
||||||
<listcell id="lb2_cell8" label="cell8"/>
|
|
||||||
</listitem>
|
|
||||||
</listbox>
|
|
||||||
|
|
||||||
</vbox>
|
|
||||||
</hbox>
|
|
||||||
|
|
||||||
</window>
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
|
||||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
|
||||||
type="text/css"?>
|
|
||||||
|
|
||||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
||||||
title="Table indices of accessible table for XUL listbox">
|
|
||||||
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
|
||||||
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="../common.js"></script>
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="../table.js"></script>
|
|
||||||
|
|
||||||
<script type="application/javascript">
|
|
||||||
<![CDATA[
|
|
||||||
function doTest()
|
|
||||||
{
|
|
||||||
var idxes = [
|
|
||||||
[0, 1, 2],
|
|
||||||
[3, 4, 5],
|
|
||||||
[6, 7, 8]
|
|
||||||
];
|
|
||||||
testTableIndexes("listbox", idxes);
|
|
||||||
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
addA11yLoadEvent(doTest);
|
|
||||||
]]>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<hbox style="overflow: auto;">
|
|
||||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<a target="_blank"
|
|
||||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=512424"
|
|
||||||
title="implement IAccessibleTable2">
|
|
||||||
Mozilla Bug 512424
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<p id="display"></p>
|
|
||||||
<div id="content" style="display: none">
|
|
||||||
</div>
|
|
||||||
<pre id="test">
|
|
||||||
</pre>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<vbox flex="1">
|
|
||||||
|
|
||||||
<label control="listbox" value="multicolumn listbox with header"/>
|
|
||||||
<listbox id="listbox">
|
|
||||||
<listhead>
|
|
||||||
<listheader label="header1"/>
|
|
||||||
<listheader label="header2"/>
|
|
||||||
<listheader label="header3"/>
|
|
||||||
</listhead>
|
|
||||||
<listcols>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
</listcols>
|
|
||||||
<listitem>
|
|
||||||
<listcell label="cell0"/>
|
|
||||||
<listcell label="cell1"/>
|
|
||||||
<listcell label="cell2"/>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<listcell label="cell3"/>
|
|
||||||
<listcell label="cell4"/>
|
|
||||||
<listcell label="cell5"/>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<listcell label="cell6"/>
|
|
||||||
<listcell label="cell7"/>
|
|
||||||
<listcell label="cell8"/>
|
|
||||||
</listitem>
|
|
||||||
</listbox>
|
|
||||||
</vbox>
|
|
||||||
</hbox>
|
|
||||||
|
|
||||||
</window>
|
|
||||||
|
|
@ -1,247 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
|
||||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
|
||||||
type="text/css"?>
|
|
||||||
|
|
||||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
||||||
title="nsIAccessibleTable selection methods on xul:listbox test.">
|
|
||||||
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
|
||||||
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="../common.js"></script>
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="../table.js"></script>
|
|
||||||
|
|
||||||
<script type="application/javascript">
|
|
||||||
<![CDATA[
|
|
||||||
function doTest()
|
|
||||||
{
|
|
||||||
var id = "listbox3";
|
|
||||||
var acc = getAccessible(id, [nsIAccessibleTable]);
|
|
||||||
|
|
||||||
var rowCount = acc.rows;
|
|
||||||
var colsCount = acc.columns;
|
|
||||||
|
|
||||||
// columns selection
|
|
||||||
testColumnSelection(id, acc, colsCount, 0, null);
|
|
||||||
acc.selectColumn(0);
|
|
||||||
testColumnSelection(id, acc, colsCount, 0, null);
|
|
||||||
|
|
||||||
// rows selection
|
|
||||||
testRowSelection(id, acc, rowCount, 0, null);
|
|
||||||
acc.selectRow(0);
|
|
||||||
testRowSelection(id, acc, rowCount, 1, [0]);
|
|
||||||
acc.selectRow(1);
|
|
||||||
testRowSelection(id, acc, rowCount, 1, [1]);
|
|
||||||
acc.unselectRow(1);
|
|
||||||
testRowSelection(id, acc, rowCount, 0, null);
|
|
||||||
|
|
||||||
// cells selection
|
|
||||||
testCellSelection(id, acc, rowCount, colsCount, 0, null);
|
|
||||||
acc.selectRow(2);
|
|
||||||
testCellSelection(id, acc, rowCount, colsCount, 3, [6, 7, 8]);
|
|
||||||
acc.unselectRow(2);
|
|
||||||
testCellSelection(id, acc, rowCount, colsCount, 0, null);
|
|
||||||
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to test isColumnSelected(), selectedColumnCount and
|
|
||||||
* getSelectedColumn() methods.
|
|
||||||
*/
|
|
||||||
function testColumnSelection(aId, aAcc, aCount, aSelCount, aSelIndexesArray)
|
|
||||||
{
|
|
||||||
// isColumnSelected
|
|
||||||
for (var col = 0; col < aCount; col++) {
|
|
||||||
if (aSelIndexesArray && aSelIndexesArray.includes(col)) {
|
|
||||||
is(aAcc.isColumnSelected(col), true,
|
|
||||||
aId + ": column " + col + " should be selected");
|
|
||||||
} else {
|
|
||||||
is(aAcc.isColumnSelected(col), false,
|
|
||||||
aId + ": column " + col + " shouldn't be selected");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// selectedColumnCount
|
|
||||||
is(aAcc.selectedColumnCount, aSelCount,
|
|
||||||
aId + ": wrong number of selected columns");
|
|
||||||
|
|
||||||
// getSelectedColumns
|
|
||||||
var selColsCount = {}, selCols = {};
|
|
||||||
aAcc.getSelectedColumnIndices(selColsCount, selCols);
|
|
||||||
|
|
||||||
is(selColsCount.value, aSelCount,
|
|
||||||
aId + ": wrong number of selected columns");
|
|
||||||
|
|
||||||
if (!aSelIndexesArray) {
|
|
||||||
is(selCols.value, undefined,
|
|
||||||
aId + ": no columns should be selected");
|
|
||||||
} else {
|
|
||||||
for (var i = 0; i < selCols.length; i++) {
|
|
||||||
is(selCols[i], aSelIndexesArray[i],
|
|
||||||
aId + ": wrong selected column index " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to test isRowSelected(), selectedRowCount() and
|
|
||||||
* getSelectedRow() methods.
|
|
||||||
*/
|
|
||||||
function testRowSelection(aId, aAcc, aCount, aSelCount, aSelIndexesArray)
|
|
||||||
{
|
|
||||||
// isRowSelected
|
|
||||||
for (var row = 0; row < aCount; row++) {
|
|
||||||
if (aSelIndexesArray && aSelIndexesArray.includes(row)) {
|
|
||||||
is(aAcc.isRowSelected(row), true,
|
|
||||||
aId + ": row " + row + " should be selected");
|
|
||||||
} else {
|
|
||||||
is(aAcc.isRowSelected(row), false,
|
|
||||||
aId + ": row " + row + " shouldn't be selected");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// selectedRowCount
|
|
||||||
is(aAcc.selectedRowCount, aSelCount,
|
|
||||||
aId + ": wrong number of selected rows");
|
|
||||||
|
|
||||||
// getSelectedRows
|
|
||||||
var selColsCount = {}, selCols = {};
|
|
||||||
aAcc.getSelectedRowIndices(selColsCount, selCols);
|
|
||||||
|
|
||||||
is(selColsCount.value, aSelCount,
|
|
||||||
aId + ": wrong number of selected rows");
|
|
||||||
|
|
||||||
if (!aSelIndexesArray) {
|
|
||||||
is(selCols.value, undefined,
|
|
||||||
aId + ": no row should be selected");
|
|
||||||
} else {
|
|
||||||
for (var i = 0; i < selCols.length; i++) {
|
|
||||||
is(selCols[i], aSelIndexesArray[i],
|
|
||||||
aId + ": wrong selected row index " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper function to test isCellSelected(), selectedCellCount() and
|
|
||||||
* getSelectedCells() methods.
|
|
||||||
*/
|
|
||||||
function testCellSelection(aId, aAcc, aRowCount, aColCount,
|
|
||||||
aSelCount, aSelIndexesArray)
|
|
||||||
{
|
|
||||||
// isCellSelected
|
|
||||||
for (var row = 0; row < aRowCount; row++) {
|
|
||||||
for (var col = 0; col < aColCount; col++) {
|
|
||||||
var index = aAcc.getIndexAt(row, col);
|
|
||||||
if (aSelIndexesArray && aSelIndexesArray.includes(index)) {
|
|
||||||
is(aAcc.isCellSelected(row, col), true,
|
|
||||||
aId + ": cell (" + row + ", " + col + ") should be selected");
|
|
||||||
} else {
|
|
||||||
is(aAcc.isCellSelected(row, col), false,
|
|
||||||
aId + ": cell (" + row + ", " + col + ") shouldn't be selected");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// selectedCellCount
|
|
||||||
is(aAcc.selectedCellCount, aSelCount,
|
|
||||||
aId + ": wrong number of selected cells");
|
|
||||||
|
|
||||||
// getSelectedCells
|
|
||||||
var selColsCount = {}, selCols = {};
|
|
||||||
aAcc.getSelectedCellIndices(selColsCount, selCols);
|
|
||||||
|
|
||||||
is(selColsCount.value, aSelCount,
|
|
||||||
aId + ": wrong number of selected cells");
|
|
||||||
|
|
||||||
if (!aSelIndexesArray) {
|
|
||||||
is(selCols.value, undefined,
|
|
||||||
aId + ": no cells should be selected");
|
|
||||||
} else {
|
|
||||||
for (var i = 0; i < selCols.length; i++) {
|
|
||||||
is(selCols[i], aSelIndexesArray[i],
|
|
||||||
aId + ": wrong selected cell index " + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
addA11yLoadEvent(doTest);
|
|
||||||
]]>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<hbox style="overflow: auto;">
|
|
||||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<a target="_blank"
|
|
||||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=418371"
|
|
||||||
title="implement the rest of methods of nsIAccessibleTable on xul:listbox">
|
|
||||||
Mozilla Bug 418371
|
|
||||||
</a>
|
|
||||||
<a target="_blank"
|
|
||||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=512424"
|
|
||||||
title="implement IAccessibleTable2">
|
|
||||||
Mozilla Bug 512424
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<p id="display"></p>
|
|
||||||
<div id="content" style="display: none">
|
|
||||||
</div>
|
|
||||||
<pre id="test">
|
|
||||||
</pre>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<vbox flex="1">
|
|
||||||
|
|
||||||
<label control="listbox2" value="multicolumn listbox: "/>
|
|
||||||
<listbox id="listbox2">
|
|
||||||
<listcols>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
</listcols>
|
|
||||||
<listitem>
|
|
||||||
<listcell label="cell1"/>
|
|
||||||
<listcell label="cell2"/>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<listcell label="cell1"/>
|
|
||||||
<listcell label="cell2"/>
|
|
||||||
</listitem>
|
|
||||||
</listbox>
|
|
||||||
|
|
||||||
<label control="listbox3" value="multicolumn listbox with header"/>
|
|
||||||
<listbox id="listbox3">
|
|
||||||
<listhead>
|
|
||||||
<listheader label="header1"/>
|
|
||||||
<listheader label="header2"/>
|
|
||||||
<listheader label="header3"/>
|
|
||||||
</listhead>
|
|
||||||
<listcols>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
</listcols>
|
|
||||||
<listitem>
|
|
||||||
<listcell label="cell0"/>
|
|
||||||
<listcell label="cell1"/>
|
|
||||||
<listcell label="cell2"/>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<listcell label="cell3"/>
|
|
||||||
<listcell label="cell4"/>
|
|
||||||
<listcell label="cell5"/>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<listcell label="cell6"/>
|
|
||||||
<listcell label="cell7"/>
|
|
||||||
<listcell label="cell8"/>
|
|
||||||
</listitem>
|
|
||||||
</listbox>
|
|
||||||
</vbox>
|
|
||||||
</hbox>
|
|
||||||
|
|
||||||
</window>
|
|
||||||
|
|
@ -1,117 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
|
||||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
|
||||||
type="text/css"?>
|
|
||||||
|
|
||||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
|
||||||
title="Table accessible tree and table interface tests for XUL listboxes">
|
|
||||||
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
|
||||||
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="../common.js"></script>
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="../role.js"></script>
|
|
||||||
<script type="application/javascript"
|
|
||||||
src="../table.js"></script>
|
|
||||||
|
|
||||||
<script type="application/javascript">
|
|
||||||
<![CDATA[
|
|
||||||
function doTest()
|
|
||||||
{
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Multicolumn listbox.
|
|
||||||
|
|
||||||
var cellsArray = [
|
|
||||||
[kDataCell, kDataCell],
|
|
||||||
[kDataCell, kDataCell]
|
|
||||||
];
|
|
||||||
|
|
||||||
testTableStruct("listbox1", cellsArray);
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
|
||||||
// Multicolumn listbox with header.
|
|
||||||
|
|
||||||
var cellsArray = [
|
|
||||||
[kDataCell, kDataCell, kDataCell],
|
|
||||||
[kDataCell, kDataCell, kDataCell],
|
|
||||||
[kDataCell, kDataCell, kDataCell]
|
|
||||||
];
|
|
||||||
|
|
||||||
testTableStruct("listbox2", cellsArray, kListboxColumnHeader);
|
|
||||||
|
|
||||||
SimpleTest.finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleTest.waitForExplicitFinish();
|
|
||||||
addA11yLoadEvent(doTest);
|
|
||||||
]]>
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<hbox style="overflow: auto;">
|
|
||||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
|
||||||
<a target="_blank"
|
|
||||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=512424"
|
|
||||||
title="implement IAccessibleTable2">
|
|
||||||
Mozilla Bug 512424
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<p id="display"></p>
|
|
||||||
<div id="content" style="display: none">
|
|
||||||
</div>
|
|
||||||
<pre id="test">
|
|
||||||
</pre>
|
|
||||||
</body>
|
|
||||||
|
|
||||||
<vbox flex="1">
|
|
||||||
|
|
||||||
<label control="listbox1" value="multicolumn listbox: "/>
|
|
||||||
<listbox id="listbox1">
|
|
||||||
<listcols>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
</listcols>
|
|
||||||
<listitem>
|
|
||||||
<listcell label="cell1"/>
|
|
||||||
<listcell label="cell2"/>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<listcell label="cell1"/>
|
|
||||||
<listcell label="cell2"/>
|
|
||||||
</listitem>
|
|
||||||
</listbox>
|
|
||||||
|
|
||||||
<label control="listbox2" value="multicolumn listbox with header"/>
|
|
||||||
<listbox id="listbox2">
|
|
||||||
<listhead>
|
|
||||||
<listheader label="header1"/>
|
|
||||||
<listheader label="header2"/>
|
|
||||||
<listheader label="header3"/>
|
|
||||||
</listhead>
|
|
||||||
<listcols>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
<listcol flex="1"/>
|
|
||||||
</listcols>
|
|
||||||
<listitem>
|
|
||||||
<listcell label="cell0"/>
|
|
||||||
<listcell label="cell1"/>
|
|
||||||
<listcell label="cell2"/>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<listcell label="cell3"/>
|
|
||||||
<listcell label="cell4"/>
|
|
||||||
<listcell label="cell5"/>
|
|
||||||
</listitem>
|
|
||||||
<listitem>
|
|
||||||
<listcell label="cell6"/>
|
|
||||||
<listcell label="cell7"/>
|
|
||||||
<listcell label="cell8"/>
|
|
||||||
</listitem>
|
|
||||||
</listbox>
|
|
||||||
</vbox>
|
|
||||||
</hbox>
|
|
||||||
|
|
||||||
</window>
|
|
||||||
|
|
@ -25,8 +25,10 @@
|
|||||||
{
|
{
|
||||||
this.listboxNode = getNode(aListboxID);
|
this.listboxNode = getNode(aListboxID);
|
||||||
|
|
||||||
this.listitemNode = document.createElement("listitem");
|
this.listitemNode = document.createElement("richlistitem");
|
||||||
this.listitemNode.setAttribute("label", "item1");
|
var label = document.createElement("label");
|
||||||
|
label.setAttribute("value", "item1");
|
||||||
|
this.listitemNode.appendChild(label);
|
||||||
|
|
||||||
this.eventSeq = [
|
this.eventSeq = [
|
||||||
new invokerChecker(EVENT_SHOW, this.listitemNode),
|
new invokerChecker(EVENT_SHOW, this.listitemNode),
|
||||||
@ -168,11 +170,11 @@
|
|||||||
</body>
|
</body>
|
||||||
|
|
||||||
<vbox flex="1">
|
<vbox flex="1">
|
||||||
<listbox id="listbox" rows="2">
|
<richlistbox id="listbox">
|
||||||
<listitem label="item2"/>
|
<richlistitem><label value="item2"/></richlistitem>
|
||||||
<listitem label="item3"/>
|
<richlistitem><label value="item3"/></richlistitem>
|
||||||
<listitem label="item4"/>
|
<richlistitem><label value="item4"/></richlistitem>
|
||||||
</listbox>
|
</richlistbox>
|
||||||
</vbox>
|
</vbox>
|
||||||
</hbox>
|
</hbox>
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ const whitelist = {
|
|||||||
"resource://gre/modules/Log.jsm",
|
"resource://gre/modules/Log.jsm",
|
||||||
|
|
||||||
// Session store
|
// Session store
|
||||||
|
"resource:///modules/sessionstore/ContentSessionStore.jsm",
|
||||||
"resource://gre/modules/sessionstore/SessionHistory.jsm",
|
"resource://gre/modules/sessionstore/SessionHistory.jsm",
|
||||||
|
|
||||||
// Forms and passwords
|
// Forms and passwords
|
||||||
|
1043
browser/components/sessionstore/ContentSessionStore.jsm
Normal file
1043
browser/components/sessionstore/ContentSessionStore.jsm
Normal file
File diff suppressed because it is too large
Load Diff
@ -6,976 +6,6 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm", this);
|
ChromeUtils.import("resource:///modules/sessionstore/ContentSessionStore.jsm");
|
||||||
ChromeUtils.import("resource://gre/modules/Timer.jsm", this);
|
|
||||||
ChromeUtils.import("resource://gre/modules/Services.jsm", this);
|
|
||||||
|
|
||||||
ChromeUtils.defineModuleGetter(this, "TelemetryStopwatch",
|
void new ContentSessionStore(this);
|
||||||
"resource://gre/modules/TelemetryStopwatch.jsm");
|
|
||||||
|
|
||||||
function debug(msg) {
|
|
||||||
Services.console.logStringMessage("SessionStoreContent: " + msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
ChromeUtils.defineModuleGetter(this, "FormData",
|
|
||||||
"resource://gre/modules/FormData.jsm");
|
|
||||||
|
|
||||||
ChromeUtils.defineModuleGetter(this, "ContentRestore",
|
|
||||||
"resource:///modules/sessionstore/ContentRestore.jsm");
|
|
||||||
ChromeUtils.defineModuleGetter(this, "DocShellCapabilities",
|
|
||||||
"resource:///modules/sessionstore/DocShellCapabilities.jsm");
|
|
||||||
ChromeUtils.defineModuleGetter(this, "ScrollPosition",
|
|
||||||
"resource://gre/modules/ScrollPosition.jsm");
|
|
||||||
ChromeUtils.defineModuleGetter(this, "SessionHistory",
|
|
||||||
"resource://gre/modules/sessionstore/SessionHistory.jsm");
|
|
||||||
ChromeUtils.defineModuleGetter(this, "SessionStorage",
|
|
||||||
"resource:///modules/sessionstore/SessionStorage.jsm");
|
|
||||||
|
|
||||||
var contentRestoreInitialized = false;
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(this, "gContentRestore",
|
|
||||||
() => {
|
|
||||||
contentRestoreInitialized = true;
|
|
||||||
return new ContentRestore(this);
|
|
||||||
});
|
|
||||||
|
|
||||||
ChromeUtils.defineModuleGetter(this, "Utils",
|
|
||||||
"resource://gre/modules/sessionstore/Utils.jsm");
|
|
||||||
const ssu = Cc["@mozilla.org/browser/sessionstore/utils;1"]
|
|
||||||
.getService(Ci.nsISessionStoreUtils);
|
|
||||||
|
|
||||||
// The current epoch.
|
|
||||||
var gCurrentEpoch = 0;
|
|
||||||
|
|
||||||
// A bound to the size of data to store for DOM Storage.
|
|
||||||
const DOM_STORAGE_LIMIT_PREF = "browser.sessionstore.dom_storage_limit";
|
|
||||||
|
|
||||||
// This pref controls whether or not we send updates to the parent on a timeout
|
|
||||||
// or not, and should only be used for tests or debugging.
|
|
||||||
const TIMEOUT_DISABLED_PREF = "browser.sessionstore.debug.no_auto_updates";
|
|
||||||
|
|
||||||
const PREF_INTERVAL = "browser.sessionstore.interval";
|
|
||||||
|
|
||||||
const kNoIndex = Number.MAX_SAFE_INTEGER;
|
|
||||||
const kLastIndex = Number.MAX_SAFE_INTEGER - 1;
|
|
||||||
|
|
||||||
// Grab our global so we can access it in functions below.
|
|
||||||
const global = this;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A function that will recursively call |cb| to collect data for all
|
|
||||||
* non-dynamic frames in the current frame/docShell tree.
|
|
||||||
*/
|
|
||||||
function mapFrameTree(callback) {
|
|
||||||
let [data] = Utils.mapFrameTree(content, callback);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listens for state change notifcations from webProgress and notifies each
|
|
||||||
* registered observer for either the start of a page load, or its completion.
|
|
||||||
*/
|
|
||||||
var StateChangeNotifier = {
|
|
||||||
|
|
||||||
init() {
|
|
||||||
this._observers = new Set();
|
|
||||||
let ifreq = docShell.QueryInterface(Ci.nsIInterfaceRequestor);
|
|
||||||
let webProgress = ifreq.getInterface(Ci.nsIWebProgress);
|
|
||||||
webProgress.addProgressListener(this, Ci.nsIWebProgress.NOTIFY_STATE_DOCUMENT);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a given observer |obs| to the set of observers that will be notified
|
|
||||||
* when when a new document starts or finishes loading.
|
|
||||||
*
|
|
||||||
* @param obs (object)
|
|
||||||
*/
|
|
||||||
addObserver(obs) {
|
|
||||||
this._observers.add(obs);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notifies all observers that implement the given |method|.
|
|
||||||
*
|
|
||||||
* @param method (string)
|
|
||||||
*/
|
|
||||||
notifyObservers(method) {
|
|
||||||
for (let obs of this._observers) {
|
|
||||||
if (obs.hasOwnProperty(method)) {
|
|
||||||
obs[method]();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see nsIWebProgressListener.onStateChange
|
|
||||||
*/
|
|
||||||
onStateChange(webProgress, request, stateFlags, status) {
|
|
||||||
// Ignore state changes for subframes because we're only interested in the
|
|
||||||
// top-document starting or stopping its load.
|
|
||||||
if (!webProgress.isTopLevel || webProgress.DOMWindow != content) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// onStateChange will be fired when loading the initial about:blank URI for
|
|
||||||
// a browser, which we don't actually care about. This is particularly for
|
|
||||||
// the case of unrestored background tabs, where the content has not yet
|
|
||||||
// been restored: we don't want to accidentally send any updates to the
|
|
||||||
// parent when the about:blank placeholder page has loaded.
|
|
||||||
if (!docShell.hasLoadedNonBlankURI) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stateFlags & Ci.nsIWebProgressListener.STATE_START) {
|
|
||||||
this.notifyObservers("onPageLoadStarted");
|
|
||||||
} else if (stateFlags & Ci.nsIWebProgressListener.STATE_STOP) {
|
|
||||||
this.notifyObservers("onPageLoadCompleted");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIWebProgressListener,
|
|
||||||
Ci.nsISupportsWeakReference])
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listens for and handles content events that we need for the
|
|
||||||
* session store service to be notified of state changes in content.
|
|
||||||
*/
|
|
||||||
var EventListener = {
|
|
||||||
|
|
||||||
init() {
|
|
||||||
ssu.addDynamicFrameFilteredListener(global, "load", this, true);
|
|
||||||
},
|
|
||||||
|
|
||||||
handleEvent(event) {
|
|
||||||
// Ignore load events from subframes.
|
|
||||||
if (event.target != content.document) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (content.document.documentURI.startsWith("about:reader")) {
|
|
||||||
if (event.type == "load" &&
|
|
||||||
!content.document.body.classList.contains("loaded")) {
|
|
||||||
// Don't restore the scroll position of an about:reader page at this
|
|
||||||
// point; listen for the custom event dispatched from AboutReader.jsm.
|
|
||||||
content.addEventListener("AboutReaderContentReady", this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
content.removeEventListener("AboutReaderContentReady", this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (contentRestoreInitialized) {
|
|
||||||
// Restore the form data and scroll position. If we're not currently
|
|
||||||
// restoring a tab state then this call will simply be a noop.
|
|
||||||
gContentRestore.restoreDocument();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listens for and handles messages sent by the session store service.
|
|
||||||
*/
|
|
||||||
var MessageListener = {
|
|
||||||
|
|
||||||
MESSAGES: [
|
|
||||||
"SessionStore:restoreHistory",
|
|
||||||
"SessionStore:restoreTabContent",
|
|
||||||
"SessionStore:resetRestore",
|
|
||||||
"SessionStore:flush",
|
|
||||||
"SessionStore:becomeActiveProcess",
|
|
||||||
],
|
|
||||||
|
|
||||||
init() {
|
|
||||||
this.MESSAGES.forEach(m => addMessageListener(m, this));
|
|
||||||
},
|
|
||||||
|
|
||||||
receiveMessage({name, data}) {
|
|
||||||
// The docShell might be gone. Don't process messages,
|
|
||||||
// that will just lead to errors anyway.
|
|
||||||
if (!docShell) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A fresh tab always starts with epoch=0. The parent has the ability to
|
|
||||||
// override that to signal a new era in this tab's life. This enables it
|
|
||||||
// to ignore async messages that were already sent but not yet received
|
|
||||||
// and would otherwise confuse the internal tab state.
|
|
||||||
if (data.epoch && data.epoch != gCurrentEpoch) {
|
|
||||||
gCurrentEpoch = data.epoch;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (name) {
|
|
||||||
case "SessionStore:restoreHistory":
|
|
||||||
this.restoreHistory(data);
|
|
||||||
break;
|
|
||||||
case "SessionStore:restoreTabContent":
|
|
||||||
if (data.isRemotenessUpdate) {
|
|
||||||
let histogram = Services.telemetry.getKeyedHistogramById("FX_TAB_REMOTE_NAVIGATION_DELAY_MS");
|
|
||||||
histogram.add("SessionStore:restoreTabContent",
|
|
||||||
Services.telemetry.msSystemNow() - data.requestTime);
|
|
||||||
}
|
|
||||||
this.restoreTabContent(data);
|
|
||||||
break;
|
|
||||||
case "SessionStore:resetRestore":
|
|
||||||
gContentRestore.resetRestore();
|
|
||||||
break;
|
|
||||||
case "SessionStore:flush":
|
|
||||||
this.flush(data);
|
|
||||||
break;
|
|
||||||
case "SessionStore:becomeActiveProcess":
|
|
||||||
SessionHistoryListener.collect();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
debug("received unknown message '" + name + "'");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
restoreHistory({epoch, tabData, loadArguments, isRemotenessUpdate}) {
|
|
||||||
gContentRestore.restoreHistory(tabData, loadArguments, {
|
|
||||||
// Note: The callbacks passed here will only be used when a load starts
|
|
||||||
// that was not initiated by sessionstore itself. This can happen when
|
|
||||||
// some code calls browser.loadURI() or browser.reload() on a pending
|
|
||||||
// browser/tab.
|
|
||||||
|
|
||||||
onLoadStarted() {
|
|
||||||
// Notify the parent that the tab is no longer pending.
|
|
||||||
sendAsyncMessage("SessionStore:restoreTabContentStarted", {epoch});
|
|
||||||
},
|
|
||||||
|
|
||||||
onLoadFinished() {
|
|
||||||
// Tell SessionStore.jsm that it may want to restore some more tabs,
|
|
||||||
// since it restores a max of MAX_CONCURRENT_TAB_RESTORES at a time.
|
|
||||||
sendAsyncMessage("SessionStore:restoreTabContentComplete", {epoch});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_DEFAULT) {
|
|
||||||
// For non-remote tabs, when restoreHistory finishes, we send a synchronous
|
|
||||||
// message to SessionStore.jsm so that it can run SSTabRestoring. Users of
|
|
||||||
// SSTabRestoring seem to get confused if chrome and content are out of
|
|
||||||
// sync about the state of the restore (particularly regarding
|
|
||||||
// docShell.currentURI). Using a synchronous message is the easiest way
|
|
||||||
// to temporarily synchronize them.
|
|
||||||
//
|
|
||||||
// For remote tabs, because all nsIWebProgress notifications are sent
|
|
||||||
// asynchronously using messages, we get the same-order guarantees of the
|
|
||||||
// message manager, and can use an async message.
|
|
||||||
sendSyncMessage("SessionStore:restoreHistoryComplete", {epoch, isRemotenessUpdate});
|
|
||||||
} else {
|
|
||||||
sendAsyncMessage("SessionStore:restoreHistoryComplete", {epoch, isRemotenessUpdate});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
restoreTabContent({loadArguments, isRemotenessUpdate, reason}) {
|
|
||||||
let epoch = gCurrentEpoch;
|
|
||||||
|
|
||||||
// We need to pass the value of didStartLoad back to SessionStore.jsm.
|
|
||||||
let didStartLoad = gContentRestore.restoreTabContent(loadArguments, isRemotenessUpdate, () => {
|
|
||||||
// Tell SessionStore.jsm that it may want to restore some more tabs,
|
|
||||||
// since it restores a max of MAX_CONCURRENT_TAB_RESTORES at a time.
|
|
||||||
sendAsyncMessage("SessionStore:restoreTabContentComplete", {epoch, isRemotenessUpdate});
|
|
||||||
});
|
|
||||||
|
|
||||||
sendAsyncMessage("SessionStore:restoreTabContentStarted", {
|
|
||||||
epoch, isRemotenessUpdate, reason,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!didStartLoad) {
|
|
||||||
// Pretend that the load succeeded so that event handlers fire correctly.
|
|
||||||
sendAsyncMessage("SessionStore:restoreTabContentComplete", {epoch, isRemotenessUpdate});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
flush({id}) {
|
|
||||||
// Flush the message queue, send the latest updates.
|
|
||||||
MessageQueue.send({flushID: id});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listens for changes to the session history. Whenever the user navigates
|
|
||||||
* we will collect URLs and everything belonging to session history.
|
|
||||||
*
|
|
||||||
* Causes a SessionStore:update message to be sent that contains the current
|
|
||||||
* session history.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
* {entries: [{url: "about:mozilla", ...}, ...], index: 1}
|
|
||||||
*/
|
|
||||||
var SessionHistoryListener = {
|
|
||||||
init() {
|
|
||||||
// The state change observer is needed to handle initial subframe loads.
|
|
||||||
// It will redundantly invalidate with the SHistoryListener in some cases
|
|
||||||
// but these invalidations are very cheap.
|
|
||||||
StateChangeNotifier.addObserver(this);
|
|
||||||
|
|
||||||
// By adding the SHistoryListener immediately, we will unfortunately be
|
|
||||||
// notified of every history entry as the tab is restored. We don't bother
|
|
||||||
// waiting to add the listener later because these notifications are cheap.
|
|
||||||
// We will likely only collect once since we are batching collection on
|
|
||||||
// a delay.
|
|
||||||
docShell.QueryInterface(Ci.nsIWebNavigation).
|
|
||||||
sessionHistory.legacySHistory.addSHistoryListener(this);
|
|
||||||
|
|
||||||
// Collect data if we start with a non-empty shistory.
|
|
||||||
if (!SessionHistory.isEmpty(docShell)) {
|
|
||||||
this.collect();
|
|
||||||
// When a tab is detached from the window, for the new window there is a
|
|
||||||
// new SessionHistoryListener created. Normally it is empty at this point
|
|
||||||
// but in a test env. the initial about:blank might have a children in which
|
|
||||||
// case we fire off a history message here with about:blank in it. If we
|
|
||||||
// don't do it ASAP then there is going to be a browser swap and the parent
|
|
||||||
// will be all confused by that message.
|
|
||||||
MessageQueue.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for page title changes.
|
|
||||||
addEventListener("DOMTitleChanged", this);
|
|
||||||
},
|
|
||||||
|
|
||||||
uninit() {
|
|
||||||
let sessionHistory = docShell.QueryInterface(Ci.nsIWebNavigation).sessionHistory;
|
|
||||||
if (sessionHistory) {
|
|
||||||
sessionHistory.legacySHistory.removeSHistoryListener(this);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
collect() {
|
|
||||||
// We want to send down a historychange even for full collects in case our
|
|
||||||
// session history is a partial session history, in which case we don't have
|
|
||||||
// enough information for a full update. collectFrom(-1) tells the collect
|
|
||||||
// function to collect all data avaliable in this process.
|
|
||||||
if (docShell) {
|
|
||||||
this.collectFrom(-1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
_fromIdx: kNoIndex,
|
|
||||||
|
|
||||||
// History can grow relatively big with the nested elements, so if we don't have to, we
|
|
||||||
// don't want to send the entire history all the time. For a simple optimization
|
|
||||||
// we keep track of the smallest index from after any change has occured and we just send
|
|
||||||
// the elements from that index. If something more complicated happens we just clear it
|
|
||||||
// and send the entire history. We always send the additional info like the current selected
|
|
||||||
// index (so for going back and forth between history entries we set the index to kLastIndex
|
|
||||||
// if nothing else changed send an empty array and the additonal info like the selected index)
|
|
||||||
collectFrom(idx) {
|
|
||||||
if (this._fromIdx <= idx) {
|
|
||||||
// If we already know that we need to update history fromn index N we can ignore any changes
|
|
||||||
// tha happened with an element with index larger than N.
|
|
||||||
// Note: initially we use kNoIndex which is MAX_SAFE_INTEGER which means we don't ignore anything
|
|
||||||
// here, and in case of navigation in the history back and forth we use kLastIndex which ignores
|
|
||||||
// only the subsequent navigations, but not any new elements added.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._fromIdx = idx;
|
|
||||||
MessageQueue.push("historychange", () => {
|
|
||||||
if (this._fromIdx === kNoIndex) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let history = SessionHistory.collect(docShell, this._fromIdx);
|
|
||||||
this._fromIdx = kNoIndex;
|
|
||||||
return history;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
handleEvent(event) {
|
|
||||||
this.collect();
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageLoadCompleted() {
|
|
||||||
this.collect();
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageLoadStarted() {
|
|
||||||
this.collect();
|
|
||||||
},
|
|
||||||
|
|
||||||
OnHistoryNewEntry(newURI, oldIndex) {
|
|
||||||
// We ought to collect the previously current entry as well, see bug 1350567.
|
|
||||||
this.collectFrom(oldIndex);
|
|
||||||
},
|
|
||||||
|
|
||||||
OnHistoryGoBack(backURI) {
|
|
||||||
// We ought to collect the previously current entry as well, see bug 1350567.
|
|
||||||
this.collectFrom(kLastIndex);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
OnHistoryGoForward(forwardURI) {
|
|
||||||
// We ought to collect the previously current entry as well, see bug 1350567.
|
|
||||||
this.collectFrom(kLastIndex);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
OnHistoryGotoIndex(index, gotoURI) {
|
|
||||||
// We ought to collect the previously current entry as well, see bug 1350567.
|
|
||||||
this.collectFrom(kLastIndex);
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
OnHistoryPurge(numEntries) {
|
|
||||||
this.collect();
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
OnHistoryReload(reloadURI, reloadFlags) {
|
|
||||||
this.collect();
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
OnHistoryReplaceEntry(index) {
|
|
||||||
this.collect();
|
|
||||||
},
|
|
||||||
|
|
||||||
OnLengthChanged(aCount) {
|
|
||||||
// Ignore, the method is implemented so that XPConnect doesn't throw!
|
|
||||||
},
|
|
||||||
|
|
||||||
OnIndexChanged(aIndex) {
|
|
||||||
// Ignore, the method is implemented so that XPConnect doesn't throw!
|
|
||||||
},
|
|
||||||
|
|
||||||
QueryInterface: ChromeUtils.generateQI([
|
|
||||||
Ci.nsISHistoryListener,
|
|
||||||
Ci.nsISupportsWeakReference
|
|
||||||
])
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listens for scroll position changes. Whenever the user scrolls the top-most
|
|
||||||
* frame we update the scroll position and will restore it when requested.
|
|
||||||
*
|
|
||||||
* Causes a SessionStore:update message to be sent that contains the current
|
|
||||||
* scroll positions as a tree of strings. If no frame of the whole frame tree
|
|
||||||
* is scrolled this will return null so that we don't tack a property onto
|
|
||||||
* the tabData object in the parent process.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
* {scroll: "100,100", children: [null, null, {scroll: "200,200"}]}
|
|
||||||
*/
|
|
||||||
var ScrollPositionListener = {
|
|
||||||
init() {
|
|
||||||
ssu.addDynamicFrameFilteredListener(global, "scroll", this, false);
|
|
||||||
StateChangeNotifier.addObserver(this);
|
|
||||||
},
|
|
||||||
|
|
||||||
handleEvent() {
|
|
||||||
MessageQueue.push("scroll", () => this.collect());
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageLoadCompleted() {
|
|
||||||
MessageQueue.push("scroll", () => this.collect());
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageLoadStarted() {
|
|
||||||
MessageQueue.push("scroll", () => null);
|
|
||||||
},
|
|
||||||
|
|
||||||
collect() {
|
|
||||||
return mapFrameTree(ScrollPosition.collect);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listens for changes to input elements. Whenever the value of an input
|
|
||||||
* element changes we will re-collect data for the current frame tree and send
|
|
||||||
* a message to the parent process.
|
|
||||||
*
|
|
||||||
* Causes a SessionStore:update message to be sent that contains the form data
|
|
||||||
* for all reachable frames.
|
|
||||||
*
|
|
||||||
* Example:
|
|
||||||
* {
|
|
||||||
* formdata: {url: "http://mozilla.org/", id: {input_id: "input value"}},
|
|
||||||
* children: [
|
|
||||||
* null,
|
|
||||||
* {url: "http://sub.mozilla.org/", id: {input_id: "input value 2"}}
|
|
||||||
* ]
|
|
||||||
* }
|
|
||||||
*/
|
|
||||||
var FormDataListener = {
|
|
||||||
init() {
|
|
||||||
ssu.addDynamicFrameFilteredListener(global, "input", this, true);
|
|
||||||
StateChangeNotifier.addObserver(this);
|
|
||||||
},
|
|
||||||
|
|
||||||
handleEvent() {
|
|
||||||
MessageQueue.push("formdata", () => this.collect());
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageLoadStarted() {
|
|
||||||
MessageQueue.push("formdata", () => null);
|
|
||||||
},
|
|
||||||
|
|
||||||
collect() {
|
|
||||||
return mapFrameTree(FormData.collect);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listens for changes to docShell capabilities. Whenever a new load is started
|
|
||||||
* we need to re-check the list of capabilities and send message when it has
|
|
||||||
* changed.
|
|
||||||
*
|
|
||||||
* Causes a SessionStore:update message to be sent that contains the currently
|
|
||||||
* disabled docShell capabilities (all nsIDocShell.allow* properties set to
|
|
||||||
* false) as a string - i.e. capability names separate by commas.
|
|
||||||
*/
|
|
||||||
var DocShellCapabilitiesListener = {
|
|
||||||
/**
|
|
||||||
* This field is used to compare the last docShell capabilities to the ones
|
|
||||||
* that have just been collected. If nothing changed we won't send a message.
|
|
||||||
*/
|
|
||||||
_latestCapabilities: "",
|
|
||||||
|
|
||||||
init() {
|
|
||||||
StateChangeNotifier.addObserver(this);
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageLoadStarted() {
|
|
||||||
// The order of docShell capabilities cannot change while we're running
|
|
||||||
// so calling join() without sorting before is totally sufficient.
|
|
||||||
let caps = DocShellCapabilities.collect(docShell).join(",");
|
|
||||||
|
|
||||||
// Send new data only when the capability list changes.
|
|
||||||
if (caps != this._latestCapabilities) {
|
|
||||||
this._latestCapabilities = caps;
|
|
||||||
MessageQueue.push("disallow", () => caps || null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listens for changes to the DOMSessionStorage. Whenever new keys are added,
|
|
||||||
* existing ones removed or changed, or the storage is cleared we will send a
|
|
||||||
* message to the parent process containing up-to-date sessionStorage data.
|
|
||||||
*
|
|
||||||
* Causes a SessionStore:update message to be sent that contains the current
|
|
||||||
* DOMSessionStorage contents. The data is a nested object using host names
|
|
||||||
* as keys and per-host DOMSessionStorage data as values.
|
|
||||||
*/
|
|
||||||
var SessionStorageListener = {
|
|
||||||
init() {
|
|
||||||
Services.obs.addObserver(this, "browser:purge-domain-data");
|
|
||||||
StateChangeNotifier.addObserver(this);
|
|
||||||
this.resetEventListener();
|
|
||||||
},
|
|
||||||
|
|
||||||
uninit() {
|
|
||||||
Services.obs.removeObserver(this, "browser:purge-domain-data");
|
|
||||||
},
|
|
||||||
|
|
||||||
observe() {
|
|
||||||
// Collect data on the next tick so that any other observer
|
|
||||||
// that needs to purge data can do its work first.
|
|
||||||
setTimeoutWithTarget(() => this.collect(), 0, tabEventTarget);
|
|
||||||
},
|
|
||||||
|
|
||||||
// We don't want to send all the session storage data for all the frames
|
|
||||||
// for every change. So if only a few value changed we send them over as
|
|
||||||
// a "storagechange" event. If however for some reason before we send these
|
|
||||||
// changes we have to send over the entire sessions storage data, we just
|
|
||||||
// reset these changes.
|
|
||||||
_changes: undefined,
|
|
||||||
|
|
||||||
resetChanges() {
|
|
||||||
this._changes = undefined;
|
|
||||||
},
|
|
||||||
|
|
||||||
// The event listener waiting for MozSessionStorageChanged events.
|
|
||||||
_listener: null,
|
|
||||||
|
|
||||||
resetEventListener() {
|
|
||||||
if (!this._listener) {
|
|
||||||
this._listener =
|
|
||||||
ssu.addDynamicFrameFilteredListener(global, "MozSessionStorageChanged",
|
|
||||||
this, true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
removeEventListener() {
|
|
||||||
ssu.removeDynamicFrameFilteredListener(global, "MozSessionStorageChanged",
|
|
||||||
this._listener, true);
|
|
||||||
this._listener = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
handleEvent(event) {
|
|
||||||
if (!docShell) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// How much data does DOMSessionStorage contain?
|
|
||||||
let usage = content.QueryInterface(Ci.nsIInterfaceRequestor)
|
|
||||||
.getInterface(Ci.nsIDOMWindowUtils)
|
|
||||||
.getStorageUsage(event.storageArea);
|
|
||||||
|
|
||||||
// Don't store any data if we exceed the limit. Wipe any data we previously
|
|
||||||
// collected so that we don't confuse websites with partial state.
|
|
||||||
if (usage > Services.prefs.getIntPref(DOM_STORAGE_LIMIT_PREF)) {
|
|
||||||
MessageQueue.push("storage", () => null);
|
|
||||||
this.removeEventListener();
|
|
||||||
this.resetChanges();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let {url, key, newValue} = event;
|
|
||||||
let uri = Services.io.newURI(url);
|
|
||||||
let domain = uri.prePath;
|
|
||||||
if (!this._changes) {
|
|
||||||
this._changes = {};
|
|
||||||
}
|
|
||||||
if (!this._changes[domain]) {
|
|
||||||
this._changes[domain] = {};
|
|
||||||
}
|
|
||||||
this._changes[domain][key] = newValue;
|
|
||||||
|
|
||||||
MessageQueue.push("storagechange", () => {
|
|
||||||
let tmp = this._changes;
|
|
||||||
// If there were multiple changes we send them merged.
|
|
||||||
// First one will collect all the changes the rest of
|
|
||||||
// these messages will be ignored.
|
|
||||||
this.resetChanges();
|
|
||||||
return tmp;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
collect() {
|
|
||||||
if (!docShell) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need the entire session storage, let's reset the pending individual change
|
|
||||||
// messages.
|
|
||||||
this.resetChanges();
|
|
||||||
|
|
||||||
MessageQueue.push("storage", () => SessionStorage.collect(content));
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageLoadCompleted() {
|
|
||||||
this.collect();
|
|
||||||
},
|
|
||||||
|
|
||||||
onPageLoadStarted() {
|
|
||||||
this.resetEventListener();
|
|
||||||
this.collect();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Listen for changes to the privacy status of the tab.
|
|
||||||
* By definition, tabs start in non-private mode.
|
|
||||||
*
|
|
||||||
* Causes a SessionStore:update message to be sent for
|
|
||||||
* field "isPrivate". This message contains
|
|
||||||
* |true| if the tab is now private
|
|
||||||
* |null| if the tab is now public - the field is therefore
|
|
||||||
* not saved.
|
|
||||||
*/
|
|
||||||
var PrivacyListener = {
|
|
||||||
init() {
|
|
||||||
docShell.addWeakPrivacyTransitionObserver(this);
|
|
||||||
|
|
||||||
// Check that value at startup as it might have
|
|
||||||
// been set before the frame script was loaded.
|
|
||||||
if (docShell.QueryInterface(Ci.nsILoadContext).usePrivateBrowsing) {
|
|
||||||
MessageQueue.push("isPrivate", () => true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Ci.nsIPrivacyTransitionObserver
|
|
||||||
privateModeChanged(enabled) {
|
|
||||||
MessageQueue.push("isPrivate", () => enabled || null);
|
|
||||||
},
|
|
||||||
|
|
||||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIPrivacyTransitionObserver,
|
|
||||||
Ci.nsISupportsWeakReference])
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A message queue that takes collected data and will take care of sending it
|
|
||||||
* to the chrome process. It allows flushing using synchronous messages and
|
|
||||||
* takes care of any race conditions that might occur because of that. Changes
|
|
||||||
* will be batched if they're pushed in quick succession to avoid a message
|
|
||||||
* flood.
|
|
||||||
*/
|
|
||||||
var MessageQueue = {
|
|
||||||
/**
|
|
||||||
* A map (string -> lazy fn) holding lazy closures of all queued data
|
|
||||||
* collection routines. These functions will return data collected from the
|
|
||||||
* docShell.
|
|
||||||
*/
|
|
||||||
_data: new Map(),
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The delay (in ms) used to delay sending changes after data has been
|
|
||||||
* invalidated.
|
|
||||||
*/
|
|
||||||
BATCH_DELAY_MS: 1000,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The minimum idle period (in ms) we need for sending data to chrome process.
|
|
||||||
*/
|
|
||||||
NEEDED_IDLE_PERIOD_MS: 5,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Timeout for waiting an idle period to send data. We will set this from
|
|
||||||
* the pref "browser.sessionstore.interval".
|
|
||||||
*/
|
|
||||||
_timeoutWaitIdlePeriodMs: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current timeout ID, null if there is no queue data. We use timeouts
|
|
||||||
* to damp a flood of data changes and send lots of changes as one batch.
|
|
||||||
*/
|
|
||||||
_timeout: null,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not sending batched messages on a timer is disabled. This should
|
|
||||||
* only be used for debugging or testing. If you need to access this value,
|
|
||||||
* you should probably use the timeoutDisabled getter.
|
|
||||||
*/
|
|
||||||
_timeoutDisabled: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if there is already a send pending idle dispatch, set to prevent
|
|
||||||
* scheduling more than one. If false there may or may not be one scheduled.
|
|
||||||
*/
|
|
||||||
_idleScheduled: false,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* True if batched messages are not being fired on a timer. This should only
|
|
||||||
* ever be true when debugging or during tests.
|
|
||||||
*/
|
|
||||||
get timeoutDisabled() {
|
|
||||||
return this._timeoutDisabled;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disables sending batched messages on a timer. Also cancels any pending
|
|
||||||
* timers.
|
|
||||||
*/
|
|
||||||
set timeoutDisabled(val) {
|
|
||||||
this._timeoutDisabled = val;
|
|
||||||
|
|
||||||
if (val && this._timeout) {
|
|
||||||
clearTimeout(this._timeout);
|
|
||||||
this._timeout = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return val;
|
|
||||||
},
|
|
||||||
|
|
||||||
init() {
|
|
||||||
this.timeoutDisabled =
|
|
||||||
Services.prefs.getBoolPref(TIMEOUT_DISABLED_PREF);
|
|
||||||
this._timeoutWaitIdlePeriodMs =
|
|
||||||
Services.prefs.getIntPref(PREF_INTERVAL);
|
|
||||||
|
|
||||||
Services.prefs.addObserver(TIMEOUT_DISABLED_PREF, this);
|
|
||||||
Services.prefs.addObserver(PREF_INTERVAL, this);
|
|
||||||
},
|
|
||||||
|
|
||||||
uninit() {
|
|
||||||
Services.prefs.removeObserver(TIMEOUT_DISABLED_PREF, this);
|
|
||||||
Services.prefs.removeObserver(PREF_INTERVAL, this);
|
|
||||||
this.cleanupTimers();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cleanup pending idle callback and timer.
|
|
||||||
*/
|
|
||||||
cleanupTimers() {
|
|
||||||
this._idleScheduled = false;
|
|
||||||
if (this._timeout) {
|
|
||||||
clearTimeout(this._timeout);
|
|
||||||
this._timeout = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
observe(subject, topic, data) {
|
|
||||||
if (topic == "nsPref:changed") {
|
|
||||||
switch (data) {
|
|
||||||
case TIMEOUT_DISABLED_PREF:
|
|
||||||
this.timeoutDisabled =
|
|
||||||
Services.prefs.getBoolPref(TIMEOUT_DISABLED_PREF);
|
|
||||||
break;
|
|
||||||
case PREF_INTERVAL:
|
|
||||||
this._timeoutWaitIdlePeriodMs =
|
|
||||||
Services.prefs.getIntPref(PREF_INTERVAL);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
debug("received unknown message '" + data + "'");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pushes a given |value| onto the queue. The given |key| represents the type
|
|
||||||
* of data that is stored and can override data that has been queued before
|
|
||||||
* but has not been sent to the parent process, yet.
|
|
||||||
*
|
|
||||||
* @param key (string)
|
|
||||||
* A unique identifier specific to the type of data this is passed.
|
|
||||||
* @param fn (function)
|
|
||||||
* A function that returns the value that will be sent to the parent
|
|
||||||
* process.
|
|
||||||
*/
|
|
||||||
push(key, fn) {
|
|
||||||
this._data.set(key, fn);
|
|
||||||
|
|
||||||
if (!this._timeout && !this._timeoutDisabled) {
|
|
||||||
// Wait a little before sending the message to batch multiple changes.
|
|
||||||
this._timeout = setTimeoutWithTarget(
|
|
||||||
() => this.sendWhenIdle(), this.BATCH_DELAY_MS, tabEventTarget);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends queued data when the remaining idle time is enough or waiting too
|
|
||||||
* long; otherwise, request an idle time again. If the |deadline| is not
|
|
||||||
* given, this function is going to schedule the first request.
|
|
||||||
*
|
|
||||||
* @param deadline (object)
|
|
||||||
* An IdleDeadline object passed by idleDispatch().
|
|
||||||
*/
|
|
||||||
sendWhenIdle(deadline) {
|
|
||||||
if (!content) {
|
|
||||||
// The frameloader is being torn down. Nothing more to do.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deadline) {
|
|
||||||
if (deadline.didTimeout || deadline.timeRemaining() > MessageQueue.NEEDED_IDLE_PERIOD_MS) {
|
|
||||||
MessageQueue.send();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (MessageQueue._idleScheduled) {
|
|
||||||
// Bail out if there's a pending run.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ChromeUtils.idleDispatch(MessageQueue.sendWhenIdle, {timeout: MessageQueue._timeoutWaitIdlePeriodMs});
|
|
||||||
MessageQueue._idleScheduled = true;
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sends queued data to the chrome process.
|
|
||||||
*
|
|
||||||
* @param options (object)
|
|
||||||
* {flushID: 123} to specify that this is a flush
|
|
||||||
* {isFinal: true} to signal this is the final message sent on unload
|
|
||||||
*/
|
|
||||||
send(options = {}) {
|
|
||||||
// Looks like we have been called off a timeout after the tab has been
|
|
||||||
// closed. The docShell is gone now and we can just return here as there
|
|
||||||
// is nothing to do.
|
|
||||||
if (!docShell) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.cleanupTimers();
|
|
||||||
|
|
||||||
let flushID = (options && options.flushID) || 0;
|
|
||||||
let histID = "FX_SESSION_RESTORE_CONTENT_COLLECT_DATA_MS";
|
|
||||||
|
|
||||||
let data = {};
|
|
||||||
for (let [key, func] of this._data) {
|
|
||||||
if (key != "isPrivate") {
|
|
||||||
TelemetryStopwatch.startKeyed(histID, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
let value = func();
|
|
||||||
|
|
||||||
if (key != "isPrivate") {
|
|
||||||
TelemetryStopwatch.finishKeyed(histID, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value || (key != "storagechange" && key != "historychange")) {
|
|
||||||
data[key] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this._data.clear();
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Send all data to the parent process.
|
|
||||||
sendAsyncMessage("SessionStore:update", {
|
|
||||||
data, flushID,
|
|
||||||
isFinal: options.isFinal || false,
|
|
||||||
epoch: gCurrentEpoch
|
|
||||||
});
|
|
||||||
} catch (ex) {
|
|
||||||
if (ex && ex.result == Cr.NS_ERROR_OUT_OF_MEMORY) {
|
|
||||||
Services.telemetry.getHistogramById("FX_SESSION_RESTORE_SEND_UPDATE_CAUSED_OOM").add(1);
|
|
||||||
sendAsyncMessage("SessionStore:error");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
StateChangeNotifier.init();
|
|
||||||
EventListener.init();
|
|
||||||
MessageListener.init();
|
|
||||||
FormDataListener.init();
|
|
||||||
SessionHistoryListener.init();
|
|
||||||
SessionStorageListener.init();
|
|
||||||
ScrollPositionListener.init();
|
|
||||||
DocShellCapabilitiesListener.init();
|
|
||||||
PrivacyListener.init();
|
|
||||||
MessageQueue.init();
|
|
||||||
|
|
||||||
function handleRevivedTab() {
|
|
||||||
if (!content) {
|
|
||||||
removeEventListener("pagehide", handleRevivedTab);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (content.document.documentURI.startsWith("about:tabcrashed")) {
|
|
||||||
if (Services.appinfo.processType != Services.appinfo.PROCESS_TYPE_DEFAULT) {
|
|
||||||
// Sanity check - we'd better be loading this in a non-remote browser.
|
|
||||||
throw new Error("We seem to be navigating away from about:tabcrashed in " +
|
|
||||||
"a non-remote browser. This should really never happen.");
|
|
||||||
}
|
|
||||||
|
|
||||||
removeEventListener("pagehide", handleRevivedTab);
|
|
||||||
|
|
||||||
// Notify the parent.
|
|
||||||
sendAsyncMessage("SessionStore:crashedTabRevived");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we're browsing from the tab crashed UI to a blacklisted URI that keeps
|
|
||||||
// this browser non-remote, we'll handle that in a pagehide event.
|
|
||||||
addEventListener("pagehide", handleRevivedTab);
|
|
||||||
|
|
||||||
addEventListener("unload", () => {
|
|
||||||
// Upon frameLoader destruction, send a final update message to
|
|
||||||
// the parent and flush all data currently held in the child.
|
|
||||||
MessageQueue.send({isFinal: true});
|
|
||||||
|
|
||||||
// If we're browsing from the tab crashed UI to a URI that causes the tab
|
|
||||||
// to go remote again, we catch this in the unload event handler, because
|
|
||||||
// swapping out the non-remote browser for a remote one in
|
|
||||||
// tabbrowser.xml's updateBrowserRemoteness doesn't cause the pagehide
|
|
||||||
// event to be fired.
|
|
||||||
handleRevivedTab();
|
|
||||||
|
|
||||||
// Remove all registered nsIObservers.
|
|
||||||
SessionStorageListener.uninit();
|
|
||||||
SessionHistoryListener.uninit();
|
|
||||||
MessageQueue.uninit();
|
|
||||||
|
|
||||||
if (contentRestoreInitialized) {
|
|
||||||
// Remove progress listeners.
|
|
||||||
gContentRestore.resetRestore();
|
|
||||||
}
|
|
||||||
|
|
||||||
// We don't need to take care of any StateChangeNotifier observers as they
|
|
||||||
// will die with the content script. The same goes for the privacy transition
|
|
||||||
// observer that will die with the docShell when the tab is closed.
|
|
||||||
});
|
|
||||||
|
@ -22,6 +22,7 @@ EXTRA_COMPONENTS += [
|
|||||||
|
|
||||||
EXTRA_JS_MODULES.sessionstore = [
|
EXTRA_JS_MODULES.sessionstore = [
|
||||||
'ContentRestore.jsm',
|
'ContentRestore.jsm',
|
||||||
|
'ContentSessionStore.jsm',
|
||||||
'DocShellCapabilities.jsm',
|
'DocShellCapabilities.jsm',
|
||||||
'GlobalState.jsm',
|
'GlobalState.jsm',
|
||||||
'RecentlyClosedTabsAndWindowsMenuUtils.jsm',
|
'RecentlyClosedTabsAndWindowsMenuUtils.jsm',
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
ChromeUtils.import("resource://formautofill/FormAutofillContent.jsm");
|
ChromeUtils.import("resource://formautofill/FormAutofillContent.jsm");
|
||||||
|
ChromeUtils.defineModuleGetter(this, "setTimeout",
|
||||||
|
"resource://gre/modules/Timer.jsm");
|
||||||
ChromeUtils.defineModuleGetter(this, "FormAutofill",
|
ChromeUtils.defineModuleGetter(this, "FormAutofill",
|
||||||
"resource://formautofill/FormAutofill.jsm");
|
"resource://formautofill/FormAutofill.jsm");
|
||||||
ChromeUtils.defineModuleGetter(this, "FormAutofillUtils",
|
ChromeUtils.defineModuleGetter(this, "FormAutofillUtils",
|
||||||
|
@ -12,14 +12,14 @@
|
|||||||
#include "nsIObjectOutputStream.h"
|
#include "nsIObjectOutputStream.h"
|
||||||
#include "nsIStandardURL.h"
|
#include "nsIStandardURL.h"
|
||||||
|
|
||||||
#include "ContentPrincipal.h"
|
|
||||||
#include "ExpandedPrincipal.h"
|
#include "ExpandedPrincipal.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsIURIWithPrincipal.h"
|
#include "nsIURIWithPrincipal.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
#include "nsScriptSecurityManager.h"
|
#include "nsScriptSecurityManager.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
|
|
||||||
|
#include "mozilla/ContentPrincipal.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "mozilla/dom/ChromeUtils.h"
|
#include "mozilla/dom/ChromeUtils.h"
|
||||||
#include "mozilla/dom/CSPDictionariesBinding.h"
|
#include "mozilla/dom/CSPDictionariesBinding.h"
|
||||||
#include "mozilla/dom/ToJSValue.h"
|
#include "mozilla/dom/ToJSValue.h"
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#ifndef ContentPrincipal_h
|
#ifndef mozilla_ContentPrincipal_h
|
||||||
#define ContentPrincipal_h
|
#define mozilla_ContentPrincipal_h
|
||||||
|
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsJSPrincipals.h"
|
#include "nsJSPrincipals.h"
|
||||||
@ -16,7 +16,9 @@
|
|||||||
#include "mozilla/BasePrincipal.h"
|
#include "mozilla/BasePrincipal.h"
|
||||||
#include "mozilla/extensions/WebExtensionPolicy.h"
|
#include "mozilla/extensions/WebExtensionPolicy.h"
|
||||||
|
|
||||||
class ContentPrincipal final : public mozilla::BasePrincipal
|
namespace mozilla {
|
||||||
|
|
||||||
|
class ContentPrincipal final : public BasePrincipal
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NS_DECL_NSISERIALIZABLE
|
NS_DECL_NSISERIALIZABLE
|
||||||
@ -35,7 +37,7 @@ public:
|
|||||||
|
|
||||||
// Init() must be called before the principal is in a usable state.
|
// Init() must be called before the principal is in a usable state.
|
||||||
nsresult Init(nsIURI* aCodebase,
|
nsresult Init(nsIURI* aCodebase,
|
||||||
const mozilla::OriginAttributes& aOriginAttributes,
|
const OriginAttributes& aOriginAttributes,
|
||||||
const nsACString& aOriginNoSuffix);
|
const nsACString& aOriginNoSuffix);
|
||||||
|
|
||||||
virtual nsresult GetScriptLocation(nsACString& aStr) override;
|
virtual nsresult GetScriptLocation(nsACString& aStr) override;
|
||||||
@ -43,7 +45,7 @@ public:
|
|||||||
static nsresult
|
static nsresult
|
||||||
GenerateOriginNoSuffixFromURI(nsIURI* aURI, nsACString& aOrigin);
|
GenerateOriginNoSuffixFromURI(nsIURI* aURI, nsACString& aOrigin);
|
||||||
|
|
||||||
mozilla::extensions::WebExtensionPolicy* AddonPolicy();
|
extensions::WebExtensionPolicy* AddonPolicy();
|
||||||
|
|
||||||
nsCOMPtr<nsIURI> mDomain;
|
nsCOMPtr<nsIURI> mDomain;
|
||||||
nsCOMPtr<nsIURI> mCodebase;
|
nsCOMPtr<nsIURI> mCodebase;
|
||||||
@ -56,12 +58,14 @@ protected:
|
|||||||
bool MayLoadInternal(nsIURI* aURI) override;
|
bool MayLoadInternal(nsIURI* aURI) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mozilla::Maybe<mozilla::WeakPtr<mozilla::extensions::WebExtensionPolicy>> mAddon;
|
Maybe<WeakPtr<extensions::WebExtensionPolicy>> mAddon;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // mozilla namespace
|
||||||
|
|
||||||
#define NS_PRINCIPAL_CONTRACTID "@mozilla.org/principal;1"
|
#define NS_PRINCIPAL_CONTRACTID "@mozilla.org/principal;1"
|
||||||
#define NS_PRINCIPAL_CID \
|
#define NS_PRINCIPAL_CID \
|
||||||
{ 0x653e0e4d, 0x3ee4, 0x45fa, \
|
{ 0x653e0e4d, 0x3ee4, 0x45fa, \
|
||||||
{ 0xb2, 0x72, 0x97, 0xc2, 0x0b, 0xc0, 0x1e, 0xb8 } }
|
{ 0xb2, 0x72, 0x97, 0xc2, 0x0b, 0xc0, 0x1e, 0xb8 } }
|
||||||
|
|
||||||
#endif // ContentPrincipal_h
|
#endif // mozilla_ContentPrincipal_h
|
||||||
|
@ -69,7 +69,7 @@ NullPrincipal::Create(const OriginAttributes& aOriginAttributes, nsIURI* aURI)
|
|||||||
/* static */ already_AddRefed<NullPrincipal>
|
/* static */ already_AddRefed<NullPrincipal>
|
||||||
NullPrincipal::CreateWithoutOriginAttributes()
|
NullPrincipal::CreateWithoutOriginAttributes()
|
||||||
{
|
{
|
||||||
return NullPrincipal::Create(mozilla::OriginAttributes(), nullptr);
|
return NullPrincipal::Create(OriginAttributes(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -9,8 +9,8 @@
|
|||||||
* same-origin with anything but themselves.
|
* same-origin with anything but themselves.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef NullPrincipal_h
|
#ifndef mozilla_NullPrincipal_h
|
||||||
#define NullPrincipal_h
|
#define mozilla_NullPrincipal_h
|
||||||
|
|
||||||
#include "nsIPrincipal.h"
|
#include "nsIPrincipal.h"
|
||||||
#include "nsJSPrincipals.h"
|
#include "nsJSPrincipals.h"
|
||||||
@ -30,7 +30,9 @@ class nsIURI;
|
|||||||
|
|
||||||
#define NS_NULLPRINCIPAL_SCHEME "moz-nullprincipal"
|
#define NS_NULLPRINCIPAL_SCHEME "moz-nullprincipal"
|
||||||
|
|
||||||
class NullPrincipal final : public mozilla::BasePrincipal
|
namespace mozilla {
|
||||||
|
|
||||||
|
class NullPrincipal final : public BasePrincipal
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// This should only be used by deserialization, and the factory constructor.
|
// This should only be used by deserialization, and the factory constructor.
|
||||||
@ -64,13 +66,13 @@ public:
|
|||||||
CreateWithInheritedAttributes(nsIDocShell* aDocShell, bool aIsFirstParty = false);
|
CreateWithInheritedAttributes(nsIDocShell* aDocShell, bool aIsFirstParty = false);
|
||||||
|
|
||||||
static already_AddRefed<NullPrincipal>
|
static already_AddRefed<NullPrincipal>
|
||||||
Create(const mozilla::OriginAttributes& aOriginAttributes,
|
Create(const OriginAttributes& aOriginAttributes,
|
||||||
nsIURI* aURI = nullptr);
|
nsIURI* aURI = nullptr);
|
||||||
|
|
||||||
static already_AddRefed<NullPrincipal>
|
static already_AddRefed<NullPrincipal>
|
||||||
CreateWithoutOriginAttributes();
|
CreateWithoutOriginAttributes();
|
||||||
|
|
||||||
nsresult Init(const mozilla::OriginAttributes& aOriginAttributes = mozilla::OriginAttributes(),
|
nsresult Init(const OriginAttributes& aOriginAttributes = OriginAttributes(),
|
||||||
nsIURI* aURI = nullptr);
|
nsIURI* aURI = nullptr);
|
||||||
|
|
||||||
virtual nsresult GetScriptLocation(nsACString &aStr) override;
|
virtual nsresult GetScriptLocation(nsACString &aStr) override;
|
||||||
@ -91,7 +93,9 @@ private:
|
|||||||
// If aIsFirstParty is true, this NullPrincipal will be initialized base on
|
// If aIsFirstParty is true, this NullPrincipal will be initialized base on
|
||||||
// the aOriginAttributes with FirstPartyDomain set to an unique value, and this
|
// the aOriginAttributes with FirstPartyDomain set to an unique value, and this
|
||||||
// value is generated from mURI.path, with ".mozilla" appending at the end.
|
// value is generated from mURI.path, with ".mozilla" appending at the end.
|
||||||
nsresult Init(const mozilla::OriginAttributes& aOriginAttributes, bool aIsFirstParty);
|
nsresult Init(const OriginAttributes& aOriginAttributes, bool aIsFirstParty);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NullPrincipal_h__
|
} // mozilla namespace
|
||||||
|
|
||||||
|
#endif // mozilla_NullPrincipal_h
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
#include "nsIUUIDGenerator.h"
|
#include "nsIUUIDGenerator.h"
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
//// NullPrincipalURI
|
//// NullPrincipalURI
|
||||||
|
|
||||||
@ -406,13 +408,13 @@ NullPrincipalURI::Deserialize(const mozilla::ipc::URIParams& aParams)
|
|||||||
//// nsISizeOf
|
//// nsISizeOf
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
NullPrincipalURI::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
NullPrincipalURI::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
|
||||||
{
|
{
|
||||||
return mPath.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
return mPath.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
NullPrincipalURI::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
NullPrincipalURI::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
|
||||||
{
|
{
|
||||||
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
* This wraps nsSimpleURI so that all calls to it are done on the main thread.
|
* This wraps nsSimpleURI so that all calls to it are done on the main thread.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __NullPrincipalURI_h__
|
#ifndef mozilla_NullPrincipalURI_h
|
||||||
#define __NullPrincipalURI_h__
|
#define mozilla_NullPrincipalURI_h
|
||||||
|
|
||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsISizeOf.h"
|
#include "nsISizeOf.h"
|
||||||
@ -27,8 +27,8 @@
|
|||||||
{0xb9, 0x1b, 0x6b, 0x54, 0x10, 0x22, 0x36, 0xe6} }
|
{0xb9, 0x1b, 0x6b, 0x54, 0x10, 0x22, 0x36, 0xe6} }
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
class Encoding;
|
class Encoding;
|
||||||
}
|
|
||||||
|
|
||||||
class NullPrincipalURI final : public nsIURI
|
class NullPrincipalURI final : public nsIURI
|
||||||
, public nsISizeOf
|
, public nsISizeOf
|
||||||
@ -40,8 +40,8 @@ public:
|
|||||||
NS_DECL_NSIIPCSERIALIZABLEURI
|
NS_DECL_NSIIPCSERIALIZABLEURI
|
||||||
|
|
||||||
// nsISizeOf
|
// nsISizeOf
|
||||||
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
|
virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||||
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
|
virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
|
||||||
|
|
||||||
// Returns null on failure.
|
// Returns null on failure.
|
||||||
static already_AddRefed<NullPrincipalURI> Create();
|
static already_AddRefed<NullPrincipalURI> Create();
|
||||||
@ -69,7 +69,7 @@ private:
|
|||||||
nsresult SetRef(const nsACString &input);
|
nsresult SetRef(const nsACString &input);
|
||||||
nsresult SetFilePath(const nsACString &input);
|
nsresult SetFilePath(const nsACString &input);
|
||||||
nsresult SetQuery(const nsACString &input);
|
nsresult SetQuery(const nsACString &input);
|
||||||
nsresult SetQueryWithEncoding(const nsACString &input, const mozilla::Encoding* encoding);
|
nsresult SetQueryWithEncoding(const nsACString &input, const Encoding* encoding);
|
||||||
bool Deserialize(const mozilla::ipc::URIParams&);
|
bool Deserialize(const mozilla::ipc::URIParams&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -110,4 +110,6 @@ public:
|
|||||||
friend class BaseURIMutator<NullPrincipalURI>;
|
friend class BaseURIMutator<NullPrincipalURI>;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __NullPrincipalURI_h__
|
} // mozilla namespace
|
||||||
|
|
||||||
|
#endif // mozilla_NullPrincipalURI_h
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
#include "pratom.h"
|
#include "pratom.h"
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
NS_IMPL_CLASSINFO(SystemPrincipal, nullptr,
|
NS_IMPL_CLASSINFO(SystemPrincipal, nullptr,
|
||||||
nsIClassInfo::SINGLETON | nsIClassInfo::MAIN_THREAD_ONLY,
|
nsIClassInfo::SINGLETON | nsIClassInfo::MAIN_THREAD_ONLY,
|
||||||
NS_SYSTEMPRINCIPAL_CID)
|
NS_SYSTEMPRINCIPAL_CID)
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
|
|
||||||
/* The privileged system principal. */
|
/* The privileged system principal. */
|
||||||
|
|
||||||
#ifndef SystemPrincipal_h
|
#ifndef mozilla_SystemPrincipal_h
|
||||||
#define SystemPrincipal_h
|
#define mozilla_SystemPrincipal_h
|
||||||
|
|
||||||
#include "nsIPrincipal.h"
|
#include "nsIPrincipal.h"
|
||||||
#include "nsJSPrincipals.h"
|
#include "nsJSPrincipals.h"
|
||||||
@ -19,8 +19,9 @@
|
|||||||
{ 0xb7, 0x65, 0x0, 0x60, 0xb0, 0xb6, 0xce, 0xcb }}
|
{ 0xb7, 0x65, 0x0, 0x60, 0xb0, 0xb6, 0xce, 0xcb }}
|
||||||
#define NS_SYSTEMPRINCIPAL_CONTRACTID "@mozilla.org/systemprincipal;1"
|
#define NS_SYSTEMPRINCIPAL_CONTRACTID "@mozilla.org/systemprincipal;1"
|
||||||
|
|
||||||
|
namespace mozilla {
|
||||||
|
|
||||||
class SystemPrincipal final : public mozilla::BasePrincipal
|
class SystemPrincipal final : public BasePrincipal
|
||||||
{
|
{
|
||||||
SystemPrincipal()
|
SystemPrincipal()
|
||||||
: BasePrincipal(eSystemPrincipal)
|
: BasePrincipal(eSystemPrincipal)
|
||||||
@ -63,4 +64,6 @@ protected:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SystemPrincipal_h
|
} // mozilla namespace
|
||||||
|
|
||||||
|
#endif // mozilla_SystemPrincipal_h
|
||||||
|
@ -24,17 +24,17 @@ XPIDL_SOURCES += [
|
|||||||
XPIDL_MODULE = 'caps'
|
XPIDL_MODULE = 'caps'
|
||||||
|
|
||||||
EXPORTS += [
|
EXPORTS += [
|
||||||
'ContentPrincipal.h',
|
|
||||||
'nsJSPrincipals.h',
|
'nsJSPrincipals.h',
|
||||||
'nsScriptSecurityManager.h',
|
'nsScriptSecurityManager.h',
|
||||||
'NullPrincipal.h',
|
|
||||||
'NullPrincipalURI.h',
|
|
||||||
'SystemPrincipal.h',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
EXPORTS.mozilla = [
|
EXPORTS.mozilla = [
|
||||||
'BasePrincipal.h',
|
'BasePrincipal.h',
|
||||||
|
'ContentPrincipal.h',
|
||||||
|
'NullPrincipal.h',
|
||||||
|
'NullPrincipalURI.h',
|
||||||
'OriginAttributes.h',
|
'OriginAttributes.h',
|
||||||
|
'SystemPrincipal.h',
|
||||||
]
|
]
|
||||||
|
|
||||||
SOURCES += [
|
SOURCES += [
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include "mozilla/BasePrincipal.h"
|
#include "mozilla/BasePrincipal.h"
|
||||||
#include "ExpandedPrincipal.h"
|
#include "ExpandedPrincipal.h"
|
||||||
#include "SystemPrincipal.h"
|
#include "SystemPrincipal.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
#include "DomainPolicy.h"
|
#include "DomainPolicy.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsCRT.h"
|
#include "nsCRT.h"
|
||||||
@ -59,6 +58,7 @@
|
|||||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/dom/BindingUtils.h"
|
#include "mozilla/dom/BindingUtils.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
#include "mozilla/ClearOnShutdown.h"
|
#include "mozilla/ClearOnShutdown.h"
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
|
|
||||||
class nsIIOService;
|
class nsIIOService;
|
||||||
class nsIStringBundle;
|
class nsIStringBundle;
|
||||||
class SystemPrincipal;
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class OriginAttributes;
|
class OriginAttributes;
|
||||||
|
class SystemPrincipal;
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
/////////////////////////////
|
/////////////////////////////
|
||||||
@ -50,7 +50,7 @@ public:
|
|||||||
// Invoked exactly once, by XPConnect.
|
// Invoked exactly once, by XPConnect.
|
||||||
static void InitStatics();
|
static void InitStatics();
|
||||||
|
|
||||||
static already_AddRefed<SystemPrincipal>
|
static already_AddRefed<mozilla::SystemPrincipal>
|
||||||
SystemPrincipalSingletonConstructor();
|
SystemPrincipalSingletonConstructor();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
const {
|
const {
|
||||||
CLEAR_FLEXBOX,
|
CLEAR_FLEXBOX,
|
||||||
UPDATE_FLEXBOX,
|
UPDATE_FLEXBOX,
|
||||||
|
UPDATE_FLEXBOX_COLOR,
|
||||||
UPDATE_FLEXBOX_HIGHLIGHTED,
|
UPDATE_FLEXBOX_HIGHLIGHTED,
|
||||||
} = require("./index");
|
} = require("./index");
|
||||||
|
|
||||||
@ -31,6 +32,19 @@ module.exports = {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the color used for the flexbox's highlighter.
|
||||||
|
*
|
||||||
|
* @param {String} color
|
||||||
|
* The color to use for this nodeFront's flexbox highlighter.
|
||||||
|
*/
|
||||||
|
updateFlexboxColor(color) {
|
||||||
|
return {
|
||||||
|
type: UPDATE_FLEXBOX_COLOR,
|
||||||
|
color,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the flexbox highlighted state.
|
* Updates the flexbox highlighted state.
|
||||||
*
|
*
|
||||||
|
@ -14,6 +14,9 @@ createEnum([
|
|||||||
// Updates the flexbox state with the newly selected flexbox.
|
// Updates the flexbox state with the newly selected flexbox.
|
||||||
"UPDATE_FLEXBOX",
|
"UPDATE_FLEXBOX",
|
||||||
|
|
||||||
|
// Update the color used for the overlay of a flexbox.
|
||||||
|
"UPDATE_FLEXBOX_COLOR",
|
||||||
|
|
||||||
// Updates the flexbox highlighted state.
|
// Updates the flexbox highlighted state.
|
||||||
"UPDATE_FLEXBOX_HIGHLIGHTED",
|
"UPDATE_FLEXBOX_HIGHLIGHTED",
|
||||||
|
|
||||||
|
@ -17,8 +17,10 @@ class Flexbox extends PureComponent {
|
|||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
flexbox: PropTypes.shape(Types.flexbox).isRequired,
|
flexbox: PropTypes.shape(Types.flexbox).isRequired,
|
||||||
|
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
|
||||||
setSelectedNode: PropTypes.func.isRequired,
|
setSelectedNode: PropTypes.func.isRequired,
|
||||||
onHideBoxModelHighlighter: PropTypes.func.isRequired,
|
onHideBoxModelHighlighter: PropTypes.func.isRequired,
|
||||||
|
onSetFlexboxOverlayColor: PropTypes.func.isRequired,
|
||||||
onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
|
onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
|
||||||
onToggleFlexboxHighlighter: PropTypes.func.isRequired,
|
onToggleFlexboxHighlighter: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
@ -27,8 +29,10 @@ class Flexbox extends PureComponent {
|
|||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
flexbox,
|
flexbox,
|
||||||
|
getSwatchColorPickerTooltip,
|
||||||
setSelectedNode,
|
setSelectedNode,
|
||||||
onHideBoxModelHighlighter,
|
onHideBoxModelHighlighter,
|
||||||
|
onSetFlexboxOverlayColor,
|
||||||
onShowBoxModelHighlighterForNode,
|
onShowBoxModelHighlighterForNode,
|
||||||
onToggleFlexboxHighlighter,
|
onToggleFlexboxHighlighter,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
@ -46,8 +50,10 @@ class Flexbox extends PureComponent {
|
|||||||
FlexboxItem({
|
FlexboxItem({
|
||||||
key: flexbox.id,
|
key: flexbox.id,
|
||||||
flexbox,
|
flexbox,
|
||||||
|
getSwatchColorPickerTooltip,
|
||||||
setSelectedNode,
|
setSelectedNode,
|
||||||
onHideBoxModelHighlighter,
|
onHideBoxModelHighlighter,
|
||||||
|
onSetFlexboxOverlayColor,
|
||||||
onShowBoxModelHighlighterForNode,
|
onShowBoxModelHighlighterForNode,
|
||||||
onToggleFlexboxHighlighter,
|
onToggleFlexboxHighlighter,
|
||||||
})
|
})
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
const { PureComponent } = require("devtools/client/shared/vendor/react");
|
const { PureComponent } = require("devtools/client/shared/vendor/react");
|
||||||
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
const dom = require("devtools/client/shared/vendor/react-dom-factories");
|
||||||
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
||||||
|
const { findDOMNode } = require("devtools/client/shared/vendor/react-dom");
|
||||||
const { translateNodeFrontToGrip } = require("devtools/client/inspector/shared/utils");
|
const { translateNodeFrontToGrip } = require("devtools/client/inspector/shared/utils");
|
||||||
|
|
||||||
// Reps
|
// Reps
|
||||||
@ -20,8 +21,10 @@ class FlexboxItem extends PureComponent {
|
|||||||
static get propTypes() {
|
static get propTypes() {
|
||||||
return {
|
return {
|
||||||
flexbox: PropTypes.shape(Types.flexbox).isRequired,
|
flexbox: PropTypes.shape(Types.flexbox).isRequired,
|
||||||
|
getSwatchColorPickerTooltip: PropTypes.func.isRequired,
|
||||||
setSelectedNode: PropTypes.func.isRequired,
|
setSelectedNode: PropTypes.func.isRequired,
|
||||||
onHideBoxModelHighlighter: PropTypes.func.isRequired,
|
onHideBoxModelHighlighter: PropTypes.func.isRequired,
|
||||||
|
onSetFlexboxOverlayColor: PropTypes.func.isRequired,
|
||||||
onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
|
onShowBoxModelHighlighterForNode: PropTypes.func.isRequired,
|
||||||
onToggleFlexboxHighlighter: PropTypes.func.isRequired,
|
onToggleFlexboxHighlighter: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
@ -29,10 +32,46 @@ class FlexboxItem extends PureComponent {
|
|||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
this.setFlexboxColor = this.setFlexboxColor.bind(this);
|
||||||
this.onFlexboxCheckboxClick = this.onFlexboxCheckboxClick.bind(this);
|
this.onFlexboxCheckboxClick = this.onFlexboxCheckboxClick.bind(this);
|
||||||
this.onFlexboxInspectIconClick = this.onFlexboxInspectIconClick.bind(this);
|
this.onFlexboxInspectIconClick = this.onFlexboxInspectIconClick.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const {
|
||||||
|
flexbox,
|
||||||
|
getSwatchColorPickerTooltip,
|
||||||
|
onSetFlexboxOverlayColor,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const swatchEl = findDOMNode(this).querySelector(".flexbox-color-swatch");
|
||||||
|
const tooltip = getSwatchColorPickerTooltip();
|
||||||
|
|
||||||
|
let previousColor;
|
||||||
|
tooltip.addSwatch(swatchEl, {
|
||||||
|
onCommit: this.setFlexboxColor,
|
||||||
|
onPreview: this.setFlexboxColor,
|
||||||
|
onRevert: () => {
|
||||||
|
onSetFlexboxOverlayColor(previousColor);
|
||||||
|
},
|
||||||
|
onShow: () => {
|
||||||
|
previousColor = flexbox.color;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnMount() {
|
||||||
|
const swatchEl = findDOMNode(this).querySelector(".flexbox-color-swatch");
|
||||||
|
const tooltip = this.props.getSwatchColorPickerTooltip();
|
||||||
|
tooltip.removeSwatch(swatchEl);
|
||||||
|
}
|
||||||
|
|
||||||
|
setFlexboxColor() {
|
||||||
|
const color = findDOMNode(this).querySelector(".flexbox-color-value").textContent;
|
||||||
|
this.props.onSetFlexboxOverlayColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
onFlexboxCheckboxClick(e) {
|
onFlexboxCheckboxClick(e) {
|
||||||
// If the click was on the svg icon to select the node in the inspector, bail out.
|
// If the click was on the svg icon to select the node in the inspector, bail out.
|
||||||
const originalTarget = e.nativeEvent && e.nativeEvent.explicitOriginalTarget;
|
const originalTarget = e.nativeEvent && e.nativeEvent.explicitOriginalTarget;
|
||||||
@ -65,6 +104,7 @@ class FlexboxItem extends PureComponent {
|
|||||||
} = this.props;
|
} = this.props;
|
||||||
const {
|
const {
|
||||||
actorID,
|
actorID,
|
||||||
|
color,
|
||||||
highlighted,
|
highlighted,
|
||||||
nodeFront,
|
nodeFront,
|
||||||
} = flexbox;
|
} = flexbox;
|
||||||
@ -91,7 +131,21 @@ class FlexboxItem extends PureComponent {
|
|||||||
onInspectIconClick: () => this.onFlexboxInspectIconClick(nodeFront),
|
onInspectIconClick: () => this.onFlexboxInspectIconClick(nodeFront),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
),
|
||||||
|
dom.div(
|
||||||
|
{
|
||||||
|
className: "flexbox-color-swatch",
|
||||||
|
style: {
|
||||||
|
backgroundColor: color,
|
||||||
|
},
|
||||||
|
title: color,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
// The SwatchColorPicker relies on the nextSibling of the swatch element to apply
|
||||||
|
// the selected color. This is why we use a span in display: none for now.
|
||||||
|
// Ideally we should modify the SwatchColorPickerTooltip to bypass this requirement.
|
||||||
|
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1341578
|
||||||
|
dom.span({ className: "flexbox-color-value" }, color)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,15 @@ const { throttle } = require("devtools/client/inspector/shared/utils");
|
|||||||
const {
|
const {
|
||||||
clearFlexbox,
|
clearFlexbox,
|
||||||
updateFlexbox,
|
updateFlexbox,
|
||||||
|
updateFlexboxColor,
|
||||||
updateFlexboxHighlighted,
|
updateFlexboxHighlighted,
|
||||||
} = require("./actions/flexbox");
|
} = require("./actions/flexbox");
|
||||||
|
|
||||||
|
loader.lazyRequireGetter(this, "parseURL", "devtools/client/shared/source-utils", true);
|
||||||
|
loader.lazyRequireGetter(this, "asyncStorage", "devtools/shared/async-storage");
|
||||||
|
|
||||||
|
const FLEXBOX_COLOR = "#9400FF";
|
||||||
|
|
||||||
class FlexboxInspector {
|
class FlexboxInspector {
|
||||||
constructor(inspector, window) {
|
constructor(inspector, window) {
|
||||||
this.document = window.document;
|
this.document = window.document;
|
||||||
@ -22,6 +28,7 @@ class FlexboxInspector {
|
|||||||
this.onHighlighterShown = this.onHighlighterShown.bind(this);
|
this.onHighlighterShown = this.onHighlighterShown.bind(this);
|
||||||
this.onHighlighterHidden = this.onHighlighterHidden.bind(this);
|
this.onHighlighterHidden = this.onHighlighterHidden.bind(this);
|
||||||
this.onReflow = throttle(this.onReflow, 500, this);
|
this.onReflow = throttle(this.onReflow, 500, this);
|
||||||
|
this.onSetFlexboxOverlayColor = this.onSetFlexboxOverlayColor.bind(this);
|
||||||
this.onSidebarSelect = this.onSidebarSelect.bind(this);
|
this.onSidebarSelect = this.onSidebarSelect.bind(this);
|
||||||
this.onToggleFlexboxHighlighter = this.onToggleFlexboxHighlighter.bind(this);
|
this.onToggleFlexboxHighlighter = this.onToggleFlexboxHighlighter.bind(this);
|
||||||
this.onUpdatePanel = this.onUpdatePanel.bind(this);
|
this.onUpdatePanel = this.onUpdatePanel.bind(this);
|
||||||
@ -86,10 +93,21 @@ class FlexboxInspector {
|
|||||||
|
|
||||||
getComponentProps() {
|
getComponentProps() {
|
||||||
return {
|
return {
|
||||||
|
getSwatchColorPickerTooltip: this.getSwatchColorPickerTooltip,
|
||||||
|
onSetFlexboxOverlayColor: this.onSetFlexboxOverlayColor,
|
||||||
onToggleFlexboxHighlighter: this.onToggleFlexboxHighlighter,
|
onToggleFlexboxHighlighter: this.onToggleFlexboxHighlighter,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an object containing the custom flexbox colors for different hosts.
|
||||||
|
*
|
||||||
|
* @return {Object} that maps a host name to a custom flexbox color for a given host.
|
||||||
|
*/
|
||||||
|
async getCustomFlexboxColors() {
|
||||||
|
return await asyncStorage.getItem("flexboxInspectorHostColors") || {};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the layout panel is visible, and false otherwise.
|
* Returns true if the layout panel is visible, and false otherwise.
|
||||||
*/
|
*/
|
||||||
@ -190,6 +208,31 @@ class FlexboxInspector {
|
|||||||
this.update(flexboxFront);
|
this.update(flexboxFront);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for a change in the flexbox overlay color picker for a flex container.
|
||||||
|
*
|
||||||
|
* @param {String} color
|
||||||
|
* A hex string representing the color to use.
|
||||||
|
*/
|
||||||
|
async onSetFlexboxOverlayColor(color) {
|
||||||
|
this.store.dispatch(updateFlexboxColor(color));
|
||||||
|
|
||||||
|
const { flexbox } = this.store.getState();
|
||||||
|
|
||||||
|
if (flexbox.highlighted) {
|
||||||
|
this.highlighters.showFlexboxHighlighter(flexbox.nodeFront);
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentUrl = this.inspector.target.url;
|
||||||
|
// Get the hostname, if there is no hostname, fall back on protocol
|
||||||
|
// ex: `data:` uri, and `about:` pages
|
||||||
|
const hostname = parseURL(currentUrl).hostname || parseURL(currentUrl).protocol;
|
||||||
|
const customFlexboxColors = await this.getCustomFlexboxColors();
|
||||||
|
|
||||||
|
customFlexboxColors[hostname] = color;
|
||||||
|
await asyncStorage.setItem("flexboxInspectorHostColors", customFlexboxColors);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handler for the inspector sidebar "select" event. Updates the flexbox panel if it
|
* Handler for the inspector sidebar "select" event. Updates the flexbox panel if it
|
||||||
* is visible.
|
* is visible.
|
||||||
@ -241,7 +284,7 @@ class FlexboxInspector {
|
|||||||
* with new flexbox data.
|
* with new flexbox data.
|
||||||
*
|
*
|
||||||
* @param {FlexboxFront|Null} flexboxFront
|
* @param {FlexboxFront|Null} flexboxFront
|
||||||
* THe FlexboxFront of the flex container for the current node selection.
|
* The FlexboxFront of the flex container for the current node selection.
|
||||||
*/
|
*/
|
||||||
async update(flexboxFront) {
|
async update(flexboxFront) {
|
||||||
// Stop refreshing if the inspector or store is already destroyed or no node is
|
// Stop refreshing if the inspector or store is already destroyed or no node is
|
||||||
@ -292,8 +335,16 @@ class FlexboxInspector {
|
|||||||
const highlighted = this._highlighters &&
|
const highlighted = this._highlighters &&
|
||||||
nodeFront == this.highlighters.flexboxHighlighterShown;
|
nodeFront == this.highlighters.flexboxHighlighterShown;
|
||||||
|
|
||||||
|
const currentUrl = this.inspector.target.url;
|
||||||
|
// Get the hostname, if there is no hostname, fall back on protocol
|
||||||
|
// ex: `data:` uri, and `about:` pages
|
||||||
|
const hostname = parseURL(currentUrl).hostname || parseURL(currentUrl).protocol;
|
||||||
|
const customColors = await this.getCustomFlexboxColors();
|
||||||
|
const color = customColors[hostname] ? customColors[hostname] : FLEXBOX_COLOR;
|
||||||
|
|
||||||
this.store.dispatch(updateFlexbox({
|
this.store.dispatch(updateFlexbox({
|
||||||
actorID: flexboxFront.actorID,
|
actorID: flexboxFront.actorID,
|
||||||
|
color,
|
||||||
highlighted,
|
highlighted,
|
||||||
nodeFront,
|
nodeFront,
|
||||||
}));
|
}));
|
||||||
|
@ -7,12 +7,15 @@
|
|||||||
const {
|
const {
|
||||||
CLEAR_FLEXBOX,
|
CLEAR_FLEXBOX,
|
||||||
UPDATE_FLEXBOX,
|
UPDATE_FLEXBOX,
|
||||||
|
UPDATE_FLEXBOX_COLOR,
|
||||||
UPDATE_FLEXBOX_HIGHLIGHTED,
|
UPDATE_FLEXBOX_HIGHLIGHTED,
|
||||||
} = require("../actions/index");
|
} = require("../actions/index");
|
||||||
|
|
||||||
const INITIAL_FLEXBOX = {
|
const INITIAL_FLEXBOX = {
|
||||||
// The actor ID of the flex container.
|
// The actor ID of the flex container.
|
||||||
actorID: null,
|
actorID: null,
|
||||||
|
// The color of the flexbox highlighter overlay.
|
||||||
|
color: "",
|
||||||
// Whether or not the flexbox highlighter is highlighting the flex container.
|
// Whether or not the flexbox highlighter is highlighting the flex container.
|
||||||
highlighted: false,
|
highlighted: false,
|
||||||
// The NodeFront of the flex container.
|
// The NodeFront of the flex container.
|
||||||
@ -29,6 +32,12 @@ const reducers = {
|
|||||||
return flexbox;
|
return flexbox;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[UPDATE_FLEXBOX_COLOR](flexbox, { color }) {
|
||||||
|
return Object.assign({}, flexbox, {
|
||||||
|
color,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
[UPDATE_FLEXBOX_HIGHLIGHTED](flexbox, { highlighted }) {
|
[UPDATE_FLEXBOX_HIGHLIGHTED](flexbox, { highlighted }) {
|
||||||
return Object.assign({}, flexbox, {
|
return Object.assign({}, flexbox, {
|
||||||
highlighted,
|
highlighted,
|
||||||
|
@ -9,7 +9,10 @@ const PropTypes = require("devtools/client/shared/vendor/react-prop-types");
|
|||||||
exports.flexbox = {
|
exports.flexbox = {
|
||||||
|
|
||||||
// The actor ID of the flex container.
|
// The actor ID of the flex container.
|
||||||
actorID: PropTypes.number,
|
actorID: PropTypes.string,
|
||||||
|
|
||||||
|
// The color of the flexbox highlighter overlay.
|
||||||
|
color: PropTypes.string,
|
||||||
|
|
||||||
// Whether or not the flexbox highlighter is highlighting the flex container.
|
// Whether or not the flexbox highlighter is highlighting the flex container.
|
||||||
highlighted: PropTypes.bool,
|
highlighted: PropTypes.bool,
|
||||||
|
@ -19,7 +19,6 @@ const {
|
|||||||
} = require("./actions/highlighter-settings");
|
} = require("./actions/highlighter-settings");
|
||||||
|
|
||||||
loader.lazyRequireGetter(this, "compareFragmentsGeometry", "devtools/client/inspector/grids/utils/utils", true);
|
loader.lazyRequireGetter(this, "compareFragmentsGeometry", "devtools/client/inspector/grids/utils/utils", true);
|
||||||
loader.lazyRequireGetter(this, "SwatchColorPickerTooltip", "devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip");
|
|
||||||
loader.lazyRequireGetter(this, "parseURL", "devtools/client/shared/source-utils", true);
|
loader.lazyRequireGetter(this, "parseURL", "devtools/client/shared/source-utils", true);
|
||||||
loader.lazyRequireGetter(this, "asyncStorage", "devtools/shared/async-storage");
|
loader.lazyRequireGetter(this, "asyncStorage", "devtools/shared/async-storage");
|
||||||
|
|
||||||
@ -57,7 +56,6 @@ class GridInspector {
|
|||||||
this.telemetry = inspector.telemetry;
|
this.telemetry = inspector.telemetry;
|
||||||
this.walker = this.inspector.walker;
|
this.walker = this.inspector.walker;
|
||||||
|
|
||||||
this.getSwatchColorPickerTooltip = this.getSwatchColorPickerTooltip.bind(this);
|
|
||||||
this.updateGridPanel = this.updateGridPanel.bind(this);
|
this.updateGridPanel = this.updateGridPanel.bind(this);
|
||||||
|
|
||||||
this.onHighlighterShown = this.onHighlighterShown.bind(this);
|
this.onHighlighterShown = this.onHighlighterShown.bind(this);
|
||||||
@ -83,21 +81,9 @@ class GridInspector {
|
|||||||
return this._highlighters;
|
return this._highlighters;
|
||||||
}
|
}
|
||||||
|
|
||||||
get swatchColorPickerTooltip() {
|
|
||||||
if (!this._swatchColorPickerTooltip) {
|
|
||||||
this._swatchColorPickerTooltip = new SwatchColorPickerTooltip(
|
|
||||||
this.inspector.toolbox.doc,
|
|
||||||
this.inspector,
|
|
||||||
{ supportsCssColor4ColorFunction: () => false }
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this._swatchColorPickerTooltip;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the grid inspector by fetching the LayoutFront from the walker, loading
|
* Initializes the grid inspector by fetching the LayoutFront from the walker and
|
||||||
* the highlighter settings and initalizing the SwatchColorPicker instance.
|
* loading the highlighter settings.
|
||||||
*/
|
*/
|
||||||
async init() {
|
async init() {
|
||||||
if (!this.inspector) {
|
if (!this.inspector) {
|
||||||
@ -138,13 +124,6 @@ class GridInspector {
|
|||||||
|
|
||||||
this.inspector.reflowTracker.untrackReflows(this, this.onReflow);
|
this.inspector.reflowTracker.untrackReflows(this, this.onReflow);
|
||||||
|
|
||||||
// The color picker may not be ready as `init` function is async,
|
|
||||||
// and we do not wait for its completion before calling destroy in tests
|
|
||||||
if (this._swatchColorPickerTooltip) {
|
|
||||||
this._swatchColorPickerTooltip.destroy();
|
|
||||||
this._swatchColorPickerTooltip = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._highlighters = null;
|
this._highlighters = null;
|
||||||
this.document = null;
|
this.document = null;
|
||||||
this.inspector = null;
|
this.inspector = null;
|
||||||
@ -155,7 +134,6 @@ class GridInspector {
|
|||||||
|
|
||||||
getComponentProps() {
|
getComponentProps() {
|
||||||
return {
|
return {
|
||||||
getSwatchColorPickerTooltip: this.getSwatchColorPickerTooltip,
|
|
||||||
onSetGridOverlayColor: this.onSetGridOverlayColor,
|
onSetGridOverlayColor: this.onSetGridOverlayColor,
|
||||||
onShowGridOutlineHighlight: this.onShowGridOutlineHighlight,
|
onShowGridOutlineHighlight: this.onShowGridOutlineHighlight,
|
||||||
onToggleGridHighlighter: this.onToggleGridHighlighter,
|
onToggleGridHighlighter: this.onToggleGridHighlighter,
|
||||||
@ -215,13 +193,6 @@ class GridInspector {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve the shared SwatchColorPicker instance.
|
|
||||||
*/
|
|
||||||
getSwatchColorPickerTooltip() {
|
|
||||||
return this.swatchColorPickerTooltip;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a list of new grid fronts, and if we have a currently highlighted grid, check
|
* Given a list of new grid fronts, and if we have a currently highlighted grid, check
|
||||||
* if its fragments have changed.
|
* if its fragments have changed.
|
||||||
|
@ -20,10 +20,10 @@ const TEST_URI = `
|
|||||||
|
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||||
const { inspector, gridInspector } = await openLayoutView();
|
const { inspector, gridInspector, layoutView } = await openLayoutView();
|
||||||
const { document: doc } = gridInspector;
|
const { document: doc } = gridInspector;
|
||||||
const { store } = inspector;
|
const { store } = inspector;
|
||||||
const cPicker = gridInspector.getSwatchColorPickerTooltip();
|
const cPicker = layoutView.getSwatchColorPickerTooltip();
|
||||||
const spectrum = cPicker.spectrum;
|
const spectrum = cPicker.spectrum;
|
||||||
const swatch = doc.querySelector(".grid-color-swatch");
|
const swatch = doc.querySelector(".grid-color-swatch");
|
||||||
|
|
||||||
|
@ -20,10 +20,10 @@ const TEST_URI = `
|
|||||||
|
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||||
const { inspector, gridInspector } = await openLayoutView();
|
const { inspector, gridInspector, layoutView } = await openLayoutView();
|
||||||
const { document: doc } = gridInspector;
|
const { document: doc } = gridInspector;
|
||||||
const { store } = inspector;
|
const { store } = inspector;
|
||||||
const cPicker = gridInspector.getSwatchColorPickerTooltip();
|
const cPicker = layoutView.getSwatchColorPickerTooltip();
|
||||||
const spectrum = cPicker.spectrum;
|
const spectrum = cPicker.spectrum;
|
||||||
const swatch = doc.querySelector(".grid-color-swatch");
|
const swatch = doc.querySelector(".grid-color-swatch");
|
||||||
|
|
||||||
|
@ -20,10 +20,10 @@ const TEST_URI = `
|
|||||||
|
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||||
const { inspector, gridInspector } = await openLayoutView();
|
const { inspector, gridInspector, layoutView } = await openLayoutView();
|
||||||
const { document: doc } = gridInspector;
|
const { document: doc } = gridInspector;
|
||||||
const { store } = inspector;
|
const { store } = inspector;
|
||||||
const cPicker = gridInspector.getSwatchColorPickerTooltip();
|
const cPicker = layoutView.getSwatchColorPickerTooltip();
|
||||||
const spectrum = cPicker.spectrum;
|
const spectrum = cPicker.spectrum;
|
||||||
const swatch = doc.querySelector(".grid-color-swatch");
|
const swatch = doc.querySelector(".grid-color-swatch");
|
||||||
|
|
||||||
|
@ -20,10 +20,10 @@ const TEST_URI = `
|
|||||||
|
|
||||||
add_task(async function() {
|
add_task(async function() {
|
||||||
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
await addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||||
const { inspector, gridInspector, toolbox } = await openLayoutView();
|
const { inspector, gridInspector, layoutView, toolbox } = await openLayoutView();
|
||||||
const { document: doc } = gridInspector;
|
const { document: doc } = gridInspector;
|
||||||
const { store } = inspector;
|
const { store } = inspector;
|
||||||
const cPicker = gridInspector.getSwatchColorPickerTooltip();
|
const cPicker = layoutView.getSwatchColorPickerTooltip();
|
||||||
const swatch = doc.querySelector(".grid-color-swatch");
|
const swatch = doc.querySelector(".grid-color-swatch");
|
||||||
|
|
||||||
info("Scrolling into view of the #grid color swatch.");
|
info("Scrolling into view of the #grid color swatch.");
|
||||||
|
@ -42,6 +42,7 @@ class LayoutApp extends PureComponent {
|
|||||||
setSelectedNode: PropTypes.func.isRequired,
|
setSelectedNode: PropTypes.func.isRequired,
|
||||||
showBoxModelProperties: PropTypes.bool.isRequired,
|
showBoxModelProperties: PropTypes.bool.isRequired,
|
||||||
onHideBoxModelHighlighter: PropTypes.func.isRequired,
|
onHideBoxModelHighlighter: PropTypes.func.isRequired,
|
||||||
|
onSetFlexboxOverlayColor: PropTypes.func.isRequired,
|
||||||
onSetGridOverlayColor: PropTypes.func.isRequired,
|
onSetGridOverlayColor: PropTypes.func.isRequired,
|
||||||
onShowBoxModelEditor: PropTypes.func.isRequired,
|
onShowBoxModelEditor: PropTypes.func.isRequired,
|
||||||
onShowBoxModelHighlighter: PropTypes.func.isRequired,
|
onShowBoxModelHighlighter: PropTypes.func.isRequired,
|
||||||
|
@ -15,6 +15,7 @@ const INSPECTOR_L10N =
|
|||||||
|
|
||||||
loader.lazyRequireGetter(this, "FlexboxInspector", "devtools/client/inspector/flexbox/flexbox");
|
loader.lazyRequireGetter(this, "FlexboxInspector", "devtools/client/inspector/flexbox/flexbox");
|
||||||
loader.lazyRequireGetter(this, "GridInspector", "devtools/client/inspector/grids/grid-inspector");
|
loader.lazyRequireGetter(this, "GridInspector", "devtools/client/inspector/grids/grid-inspector");
|
||||||
|
loader.lazyRequireGetter(this, "SwatchColorPickerTooltip", "devtools/client/shared/widgets/tooltip/SwatchColorPickerTooltip");
|
||||||
|
|
||||||
class LayoutView {
|
class LayoutView {
|
||||||
constructor(inspector, window) {
|
constructor(inspector, window) {
|
||||||
@ -22,6 +23,8 @@ class LayoutView {
|
|||||||
this.inspector = inspector;
|
this.inspector = inspector;
|
||||||
this.store = inspector.store;
|
this.store = inspector.store;
|
||||||
|
|
||||||
|
this.getSwatchColorPickerTooltip = this.getSwatchColorPickerTooltip.bind(this);
|
||||||
|
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,15 +45,14 @@ class LayoutView {
|
|||||||
onToggleGeometryEditor,
|
onToggleGeometryEditor,
|
||||||
} = this.inspector.getPanel("boxmodel").getComponentProps();
|
} = this.inspector.getPanel("boxmodel").getComponentProps();
|
||||||
|
|
||||||
this.flexboxInspector = new FlexboxInspector(this.inspector,
|
this.flexboxInspector = new FlexboxInspector(this.inspector, this.inspector.panelWin);
|
||||||
this.inspector.panelWin);
|
|
||||||
const {
|
const {
|
||||||
|
onSetFlexboxOverlayColor,
|
||||||
onToggleFlexboxHighlighter,
|
onToggleFlexboxHighlighter,
|
||||||
} = this.flexboxInspector.getComponentProps();
|
} = this.flexboxInspector.getComponentProps();
|
||||||
|
|
||||||
this.gridInspector = new GridInspector(this.inspector, this.inspector.panelWin);
|
this.gridInspector = new GridInspector(this.inspector, this.inspector.panelWin);
|
||||||
const {
|
const {
|
||||||
getSwatchColorPickerTooltip,
|
|
||||||
onSetGridOverlayColor,
|
onSetGridOverlayColor,
|
||||||
onShowGridOutlineHighlight,
|
onShowGridOutlineHighlight,
|
||||||
onToggleGridHighlighter,
|
onToggleGridHighlighter,
|
||||||
@ -60,7 +62,7 @@ class LayoutView {
|
|||||||
} = this.gridInspector.getComponentProps();
|
} = this.gridInspector.getComponentProps();
|
||||||
|
|
||||||
const layoutApp = LayoutApp({
|
const layoutApp = LayoutApp({
|
||||||
getSwatchColorPickerTooltip,
|
getSwatchColorPickerTooltip: this.getSwatchColorPickerTooltip,
|
||||||
setSelectedNode,
|
setSelectedNode,
|
||||||
/**
|
/**
|
||||||
* Shows the box model properties under the box model if true, otherwise, hidden by
|
* Shows the box model properties under the box model if true, otherwise, hidden by
|
||||||
@ -68,6 +70,7 @@ class LayoutView {
|
|||||||
*/
|
*/
|
||||||
showBoxModelProperties: true,
|
showBoxModelProperties: true,
|
||||||
onHideBoxModelHighlighter,
|
onHideBoxModelHighlighter,
|
||||||
|
onSetFlexboxOverlayColor,
|
||||||
onSetGridOverlayColor,
|
onSetGridOverlayColor,
|
||||||
onShowBoxModelEditor,
|
onShowBoxModelEditor,
|
||||||
onShowBoxModelHighlighter,
|
onShowBoxModelHighlighter,
|
||||||
@ -96,6 +99,11 @@ class LayoutView {
|
|||||||
* Destruction function called when the inspector is destroyed. Cleans up references.
|
* Destruction function called when the inspector is destroyed. Cleans up references.
|
||||||
*/
|
*/
|
||||||
destroy() {
|
destroy() {
|
||||||
|
if (this._swatchColorPickerTooltip) {
|
||||||
|
this._swatchColorPickerTooltip.destroy();
|
||||||
|
this._swatchColorPickerTooltip = null;
|
||||||
|
}
|
||||||
|
|
||||||
this.flexboxInspector.destroy();
|
this.flexboxInspector.destroy();
|
||||||
this.gridInspector.destroy();
|
this.gridInspector.destroy();
|
||||||
|
|
||||||
@ -103,6 +111,25 @@ class LayoutView {
|
|||||||
this.inspector = null;
|
this.inspector = null;
|
||||||
this.store = null;
|
this.store = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the shared SwatchColorPicker instance.
|
||||||
|
*/
|
||||||
|
getSwatchColorPickerTooltip() {
|
||||||
|
return this.swatchColorPickerTooltip;
|
||||||
|
}
|
||||||
|
|
||||||
|
get swatchColorPickerTooltip() {
|
||||||
|
if (!this._swatchColorPickerTooltip) {
|
||||||
|
this._swatchColorPickerTooltip = new SwatchColorPickerTooltip(
|
||||||
|
this.inspector.toolbox.doc,
|
||||||
|
this.inspector,
|
||||||
|
{ supportsCssColor4ColorFunction: () => false }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._swatchColorPickerTooltip;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = LayoutView;
|
module.exports = LayoutView;
|
||||||
|
@ -215,6 +215,18 @@ class HighlightersOverlay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a flexbox highlighter settings object for the provided nodeFront.
|
||||||
|
*
|
||||||
|
* @param {NodeFront} nodeFront
|
||||||
|
* The NodeFront for which we need highlighter settings.
|
||||||
|
*/
|
||||||
|
getFlexboxHighlighterSettings(nodeFront) {
|
||||||
|
const { flexbox } = this.store.getState();
|
||||||
|
const color = flexbox.color;
|
||||||
|
return { color };
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle the flexbox highlighter for the given flexbox container element.
|
* Toggle the flexbox highlighter for the given flexbox container element.
|
||||||
*
|
*
|
||||||
@ -246,6 +258,8 @@ class HighlightersOverlay {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
options = Object.assign({}, options, this.getFlexboxHighlighterSettings(node));
|
||||||
|
|
||||||
const isShown = await highlighter.show(node, options);
|
const isShown = await highlighter.show(node, options);
|
||||||
if (!isShown) {
|
if (!isShown) {
|
||||||
return;
|
return;
|
||||||
|
@ -151,6 +151,7 @@ function openLayoutView() {
|
|||||||
inspector: data.inspector,
|
inspector: data.inspector,
|
||||||
boxmodel: data.inspector.getPanel("boxmodel"),
|
boxmodel: data.inspector.getPanel("boxmodel"),
|
||||||
gridInspector: data.inspector.layoutview.gridInspector,
|
gridInspector: data.inspector.layoutview.gridInspector,
|
||||||
|
layoutView: data.inspector.layoutview,
|
||||||
testActor: data.testActor
|
testActor: data.testActor
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -28,6 +28,7 @@ function runCodeMirrorTest(browser) {
|
|||||||
// setting a timeout to check again if not.
|
// setting a timeout to check again if not.
|
||||||
/* eslint-disable max-len */
|
/* eslint-disable max-len */
|
||||||
mm.loadFrameScript("data:," +
|
mm.loadFrameScript("data:," +
|
||||||
|
"ChromeUtils.import('resource://gre/modules/Timer.jsm');" +
|
||||||
"content.wrappedJSObject.mozilla_setStatus = function(statusMsg, type, customMsg) {" +
|
"content.wrappedJSObject.mozilla_setStatus = function(statusMsg, type, customMsg) {" +
|
||||||
" sendSyncMessage('setStatus', {statusMsg: statusMsg, type: type, customMsg: customMsg});" +
|
" sendSyncMessage('setStatus', {statusMsg: statusMsg, type: type, customMsg: customMsg});" +
|
||||||
"};" +
|
"};" +
|
||||||
|
@ -130,9 +130,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Grid Item
|
* Flexbox and Grid Item
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
.flexbox-color-swatch,
|
||||||
.grid-color-swatch {
|
.grid-color-swatch {
|
||||||
width: 12px;
|
width: 12px;
|
||||||
height: 12px;
|
height: 12px;
|
||||||
@ -144,6 +145,7 @@
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flexbox-color-value,
|
||||||
.grid-color-value {
|
.grid-color-value {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
@ -60,12 +60,15 @@ const JUSTIFY_CONTENT = "justify-content";
|
|||||||
* display: [inline-]flex elements.
|
* display: [inline-]flex elements.
|
||||||
*
|
*
|
||||||
* Available Options:
|
* Available Options:
|
||||||
|
* - color(colorValue)
|
||||||
|
* @param {String} colorValue
|
||||||
|
* The color that should be used to draw the highlighter for this flexbox.
|
||||||
* - showAlignment(isShown)
|
* - showAlignment(isShown)
|
||||||
* @param {Boolean} isShown
|
* @param {Boolean} isShown
|
||||||
* Shows the alignment in the flexbox highlighter.
|
* Shows the alignment in the flexbox highlighter.
|
||||||
* - showFlexBasis(isShown)
|
* - showFlexBasis(isShown)
|
||||||
* @param {Boolean} isShown
|
* @param {Boolean} isShown
|
||||||
* Shows the flex basis in the flexbox highlighter.
|
* Shows the flex basis in the flexbox highlighter.
|
||||||
*/
|
*/
|
||||||
class FlexboxHighlighter extends AutoRefreshHighlighter {
|
class FlexboxHighlighter extends AutoRefreshHighlighter {
|
||||||
constructor(highlighterEnv) {
|
constructor(highlighterEnv) {
|
||||||
@ -169,6 +172,10 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
|
|||||||
return this.getElement("canvas");
|
return this.getElement("canvas");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get color() {
|
||||||
|
return this.options.color || DEFAULT_COLOR;
|
||||||
|
}
|
||||||
|
|
||||||
get ctx() {
|
get ctx() {
|
||||||
return this.canvas.getCanvasContext("2d");
|
return this.canvas.getCanvasContext("2d");
|
||||||
}
|
}
|
||||||
@ -211,7 +218,7 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
|
|||||||
ctx.moveTo(0, 0);
|
ctx.moveTo(0, 0);
|
||||||
ctx.lineTo(width, height);
|
ctx.lineTo(width, height);
|
||||||
|
|
||||||
ctx.strokeStyle = DEFAULT_COLOR;
|
ctx.strokeStyle = this.color;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
|
|
||||||
@ -258,7 +265,7 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
|
|||||||
ctx.moveTo(0, height);
|
ctx.moveTo(0, height);
|
||||||
ctx.lineTo(width, 0);
|
ctx.lineTo(width, 0);
|
||||||
|
|
||||||
ctx.strokeStyle = DEFAULT_COLOR;
|
ctx.strokeStyle = this.color;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.restore();
|
ctx.restore();
|
||||||
|
|
||||||
@ -393,7 +400,7 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
|
|||||||
this.ctx.translate(offset - canvasX, offset - canvasY);
|
this.ctx.translate(offset - canvasX, offset - canvasY);
|
||||||
this.ctx.setLineDash(FLEXBOX_LINES_PROPERTIES.alignItems.lineDash);
|
this.ctx.setLineDash(FLEXBOX_LINES_PROPERTIES.alignItems.lineDash);
|
||||||
this.ctx.lineWidth = lineWidth * 3;
|
this.ctx.lineWidth = lineWidth * 3;
|
||||||
this.ctx.strokeStyle = DEFAULT_COLOR;
|
this.ctx.strokeStyle = this.color;
|
||||||
|
|
||||||
const { bounds } = this.currentQuads.content[0];
|
const { bounds } = this.currentQuads.content[0];
|
||||||
const isColumn = this.flexDirection.startsWith("column");
|
const isColumn = this.flexDirection.startsWith("column");
|
||||||
@ -493,7 +500,7 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
|
|||||||
this.ctx.translate(offset - canvasX, offset - canvasY);
|
this.ctx.translate(offset - canvasX, offset - canvasY);
|
||||||
this.ctx.setLineDash(FLEXBOX_LINES_PROPERTIES.edge.lineDash);
|
this.ctx.setLineDash(FLEXBOX_LINES_PROPERTIES.edge.lineDash);
|
||||||
this.ctx.lineWidth = lineWidth;
|
this.ctx.lineWidth = lineWidth;
|
||||||
this.ctx.strokeStyle = DEFAULT_COLOR;
|
this.ctx.strokeStyle = this.color;
|
||||||
|
|
||||||
const { bounds } = this.currentQuads.content[0];
|
const { bounds } = this.currentQuads.content[0];
|
||||||
drawRect(this.ctx, 0, 0, bounds.width, bounds.height, this.currentMatrix);
|
drawRect(this.ctx, 0, 0, bounds.width, bounds.height, this.currentMatrix);
|
||||||
@ -517,7 +524,7 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
|
|||||||
this.ctx.translate(offset - canvasX, offset - canvasY);
|
this.ctx.translate(offset - canvasX, offset - canvasY);
|
||||||
this.ctx.setLineDash(FLEXBOX_LINES_PROPERTIES.edge.lineDash);
|
this.ctx.setLineDash(FLEXBOX_LINES_PROPERTIES.edge.lineDash);
|
||||||
this.ctx.lineWidth = 0;
|
this.ctx.lineWidth = 0;
|
||||||
this.ctx.strokeStyle = DEFAULT_COLOR;
|
this.ctx.strokeStyle = this.color;
|
||||||
this.ctx.fillStyle = this.getFlexContainerPattern(devicePixelRatio);
|
this.ctx.fillStyle = this.getFlexContainerPattern(devicePixelRatio);
|
||||||
|
|
||||||
const { bounds } = this.currentQuads.content[0];
|
const { bounds } = this.currentQuads.content[0];
|
||||||
@ -572,7 +579,7 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
|
|||||||
this.ctx.translate(offset - canvasX, offset - canvasY);
|
this.ctx.translate(offset - canvasX, offset - canvasY);
|
||||||
this.ctx.setLineDash(FLEXBOX_LINES_PROPERTIES.item.lineDash);
|
this.ctx.setLineDash(FLEXBOX_LINES_PROPERTIES.item.lineDash);
|
||||||
this.ctx.lineWidth = lineWidth;
|
this.ctx.lineWidth = lineWidth;
|
||||||
this.ctx.strokeStyle = DEFAULT_COLOR;
|
this.ctx.strokeStyle = this.color;
|
||||||
|
|
||||||
const { bounds } = this.currentQuads.content[0];
|
const { bounds } = this.currentQuads.content[0];
|
||||||
|
|
||||||
@ -615,7 +622,7 @@ class FlexboxHighlighter extends AutoRefreshHighlighter {
|
|||||||
this.ctx.save();
|
this.ctx.save();
|
||||||
this.ctx.translate(offset - canvasX, offset - canvasY);
|
this.ctx.translate(offset - canvasX, offset - canvasY);
|
||||||
this.ctx.lineWidth = lineWidth;
|
this.ctx.lineWidth = lineWidth;
|
||||||
this.ctx.strokeStyle = DEFAULT_COLOR;
|
this.ctx.strokeStyle = this.color;
|
||||||
|
|
||||||
const { bounds } = this.currentQuads.content[0];
|
const { bounds } = this.currentQuads.content[0];
|
||||||
const isColumn = this.flexDirection.startsWith("column");
|
const isColumn = this.flexDirection.startsWith("column");
|
||||||
|
@ -199,8 +199,8 @@
|
|||||||
#include "nsXULAppAPI.h"
|
#include "nsXULAppAPI.h"
|
||||||
|
|
||||||
#include "GeckoProfiler.h"
|
#include "GeckoProfiler.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "Navigator.h"
|
#include "Navigator.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
#include "prenv.h"
|
#include "prenv.h"
|
||||||
#include "URIUtils.h"
|
#include "URIUtils.h"
|
||||||
|
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
#include "nsDOMJSUtils.h"
|
#include "nsDOMJSUtils.h"
|
||||||
#include "nsError.h"
|
#include "nsError.h"
|
||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
#include "mozilla/LoadInfo.h"
|
#include "mozilla/LoadInfo.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "mozilla/dom/BindingUtils.h"
|
#include "mozilla/dom/BindingUtils.h"
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
#include "mozilla/Likely.h"
|
#include "mozilla/Likely.h"
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
#include "NullPrincipal.h"
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
#include "mozilla/dom/LocationBinding.h"
|
#include "mozilla/dom/LocationBinding.h"
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
|
@ -158,6 +158,7 @@
|
|||||||
#include "nsIMIMEService.h"
|
#include "nsIMIMEService.h"
|
||||||
#include "nsINode.h"
|
#include "nsINode.h"
|
||||||
#include "mozilla/dom/NodeInfo.h"
|
#include "mozilla/dom/NodeInfo.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "nsIObjectLoadingContent.h"
|
#include "nsIObjectLoadingContent.h"
|
||||||
#include "nsIObserver.h"
|
#include "nsIObserver.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
@ -187,7 +188,6 @@
|
|||||||
#include "nsNetCID.h"
|
#include "nsNetCID.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsNodeInfoManager.h"
|
#include "nsNodeInfoManager.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
#include "nsParserCIID.h"
|
#include "nsParserCIID.h"
|
||||||
#include "nsParserConstants.h"
|
#include "nsParserConstants.h"
|
||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
|
@ -110,7 +110,7 @@
|
|||||||
#include "nsIPermissionManager.h"
|
#include "nsIPermissionManager.h"
|
||||||
#include "nsIPrincipal.h"
|
#include "nsIPrincipal.h"
|
||||||
#include "ExpandedPrincipal.h"
|
#include "ExpandedPrincipal.h"
|
||||||
#include "NullPrincipal.h"
|
#include "mozilla/NullPrincipal.h"
|
||||||
|
|
||||||
#include "nsIDOMWindow.h"
|
#include "nsIDOMWindow.h"
|
||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
|
@ -44,7 +44,6 @@
|
|||||||
#include "nsIXULWindow.h"
|
#include "nsIXULWindow.h"
|
||||||
#include "nsIMozBrowserFrame.h"
|
#include "nsIMozBrowserFrame.h"
|
||||||
#include "nsISHistory.h"
|
#include "nsISHistory.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
#include "nsGlobalWindow.h"
|
#include "nsGlobalWindow.h"
|
||||||
#include "nsHTMLDocument.h"
|
#include "nsHTMLDocument.h"
|
||||||
@ -76,6 +75,7 @@
|
|||||||
#include "mozilla/BasePrincipal.h"
|
#include "mozilla/BasePrincipal.h"
|
||||||
#include "mozilla/GuardObjects.h"
|
#include "mozilla/GuardObjects.h"
|
||||||
#include "mozilla/HTMLEditor.h"
|
#include "mozilla/HTMLEditor.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
#include "mozilla/dom/ChromeMessageSender.h"
|
#include "mozilla/dom/ChromeMessageSender.h"
|
||||||
@ -102,7 +102,7 @@
|
|||||||
|
|
||||||
#include "mozilla/dom/HTMLBodyElement.h"
|
#include "mozilla/dom/HTMLBodyElement.h"
|
||||||
|
|
||||||
#include "ContentPrincipal.h"
|
#include "mozilla/ContentPrincipal.h"
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
#include "mozilla/plugins/PPluginWidgetParent.h"
|
#include "mozilla/plugins/PPluginWidgetParent.h"
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "mozilla/DebugOnly.h"
|
#include "mozilla/DebugOnly.h"
|
||||||
#include "mozilla/dom/NodeInfo.h"
|
#include "mozilla/dom/NodeInfo.h"
|
||||||
#include "mozilla/dom/NodeInfoInlines.h"
|
#include "mozilla/dom/NodeInfoInlines.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsAtom.h"
|
#include "nsAtom.h"
|
||||||
@ -30,7 +31,6 @@
|
|||||||
#include "nsNameSpaceManager.h"
|
#include "nsNameSpaceManager.h"
|
||||||
#include "nsDocument.h"
|
#include "nsDocument.h"
|
||||||
#include "nsWindowSizes.h"
|
#include "nsWindowSizes.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
|
|
||||||
using namespace mozilla;
|
using namespace mozilla;
|
||||||
using mozilla::dom::NodeInfo;
|
using mozilla::dom::NodeInfo;
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "mozilla/dom/CSSRuleList.h"
|
#include "mozilla/dom/CSSRuleList.h"
|
||||||
#include "mozilla/dom/DocumentFragment.h"
|
#include "mozilla/dom/DocumentFragment.h"
|
||||||
#include "mozilla/dom/SRIMetadata.h"
|
#include "mozilla/dom/SRIMetadata.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "nsCSSPropertyID.h"
|
#include "nsCSSPropertyID.h"
|
||||||
#include "nsUnicharInputStream.h"
|
#include "nsUnicharInputStream.h"
|
||||||
#include "nsAttrName.h"
|
#include "nsAttrName.h"
|
||||||
@ -21,7 +22,6 @@
|
|||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsIParserUtils.h"
|
#include "nsIParserUtils.h"
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
|
@ -10,13 +10,13 @@
|
|||||||
#include "js/Class.h"
|
#include "js/Class.h"
|
||||||
|
|
||||||
#include "nsJSPrincipals.h"
|
#include "nsJSPrincipals.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
|
|
||||||
#include "xpcprivate.h"
|
#include "xpcprivate.h"
|
||||||
|
|
||||||
#include "mozilla/dom/ScriptSettings.h"
|
#include "mozilla/dom/ScriptSettings.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include "ConsoleCommon.h"
|
#include "ConsoleCommon.h"
|
||||||
|
|
||||||
#include "mozilla/ClearOnShutdown.h"
|
#include "mozilla/ClearOnShutdown.h"
|
||||||
#include "NullPrincipal.h"
|
#include "mozilla/NullPrincipal.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
@ -23,12 +23,12 @@
|
|||||||
#include "js/Date.h"
|
#include "js/Date.h"
|
||||||
#include "js/StructuredClone.h"
|
#include "js/StructuredClone.h"
|
||||||
#include "KeyPath.h"
|
#include "KeyPath.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
#include "mozilla/ClearOnShutdown.h"
|
#include "mozilla/ClearOnShutdown.h"
|
||||||
#include "mozilla/EndianUtils.h"
|
#include "mozilla/EndianUtils.h"
|
||||||
#include "mozilla/ErrorResult.h"
|
#include "mozilla/ErrorResult.h"
|
||||||
#include "mozilla/JSObjectHolder.h"
|
#include "mozilla/JSObjectHolder.h"
|
||||||
#include "mozilla/Move.h"
|
#include "mozilla/Move.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "mozilla/dom/BindingUtils.h"
|
#include "mozilla/dom/BindingUtils.h"
|
||||||
#include "mozilla/dom/ContentChild.h"
|
#include "mozilla/dom/ContentChild.h"
|
||||||
#include "mozilla/dom/ContentParent.h"
|
#include "mozilla/dom/ContentParent.h"
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/BackgroundHangMonitor.h"
|
#include "mozilla/BackgroundHangMonitor.h"
|
||||||
#include "mozilla/LookAndFeel.h"
|
#include "mozilla/LookAndFeel.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/ProcessHangMonitorIPC.h"
|
#include "mozilla/ProcessHangMonitorIPC.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
@ -85,7 +86,6 @@
|
|||||||
#include "mozilla/HangDetails.h"
|
#include "mozilla/HangDetails.h"
|
||||||
#include "imgLoader.h"
|
#include "imgLoader.h"
|
||||||
#include "GMPServiceChild.h"
|
#include "GMPServiceChild.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
#include "nsISimpleEnumerator.h"
|
#include "nsISimpleEnumerator.h"
|
||||||
#include "nsIStringBundle.h"
|
#include "nsIStringBundle.h"
|
||||||
#include "nsIWorkerDebuggerManager.h"
|
#include "nsIWorkerDebuggerManager.h"
|
||||||
|
@ -95,10 +95,10 @@
|
|||||||
#include "ImageOps.h"
|
#include "ImageOps.h"
|
||||||
#include "UnitTransforms.h"
|
#include "UnitTransforms.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "mozilla/WebBrowserPersistDocumentParent.h"
|
#include "mozilla/WebBrowserPersistDocumentParent.h"
|
||||||
#include "ProcessPriorityManager.h"
|
#include "ProcessPriorityManager.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
|
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
#include "mozilla/plugins/PluginWidgetParent.h"
|
#include "mozilla/plugins/PluginWidgetParent.h"
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "nsPIDOMWindow.h"
|
#include "nsPIDOMWindow.h"
|
||||||
#include "mozilla/EventStateManager.h"
|
#include "mozilla/EventStateManager.h"
|
||||||
#include "mozilla/MozPromise.h"
|
#include "mozilla/MozPromise.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "mozilla/Telemetry.h"
|
#include "mozilla/Telemetry.h"
|
||||||
#include "mozilla/Types.h"
|
#include "mozilla/Types.h"
|
||||||
#include "mozilla/PeerIdentity.h"
|
#include "mozilla/PeerIdentity.h"
|
||||||
@ -57,7 +58,6 @@
|
|||||||
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
|
||||||
#include "Latency.h"
|
#include "Latency.h"
|
||||||
#include "nsProxyRelease.h"
|
#include "nsProxyRelease.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
#include "nsVariant.h"
|
#include "nsVariant.h"
|
||||||
|
|
||||||
// For snprintf
|
// For snprintf
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include "nsIWritablePropertyBag2.h"
|
#include "nsIWritablePropertyBag2.h"
|
||||||
#include "nsICategoryManager.h"
|
#include "nsICategoryManager.h"
|
||||||
#include "nsPluginStreamListenerPeer.h"
|
#include "nsPluginStreamListenerPeer.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "mozilla/dom/ContentChild.h"
|
#include "mozilla/dom/ContentChild.h"
|
||||||
#include "mozilla/dom/ContentParent.h"
|
#include "mozilla/dom/ContentParent.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
@ -96,7 +97,6 @@
|
|||||||
#include "nsIImageLoadingContent.h"
|
#include "nsIImageLoadingContent.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "nsVersionComparator.h"
|
#include "nsVersionComparator.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
|
|
||||||
#include "mozilla/dom/Promise.h"
|
#include "mozilla/dom/Promise.h"
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
#include "GeckoProfiler.h"
|
#include "GeckoProfiler.h"
|
||||||
#include "nsPluginInstanceOwner.h"
|
#include "nsPluginInstanceOwner.h"
|
||||||
#include "nsDataHashtable.h"
|
#include "nsDataHashtable.h"
|
||||||
#include "NullPrincipal.h"
|
#include "mozilla/NullPrincipal.h"
|
||||||
|
|
||||||
// nsPluginStreamListenerPeer
|
// nsPluginStreamListenerPeer
|
||||||
|
|
||||||
|
@ -13,7 +13,9 @@
|
|||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsIPrincipal.h"
|
#include "nsIPrincipal.h"
|
||||||
#include "nsScriptSecurityManager.h"
|
#include "nsScriptSecurityManager.h"
|
||||||
#include "NullPrincipal.h"
|
#include "mozilla/NullPrincipal.h"
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
static const uint32_t kURIMaxLength = 64;
|
static const uint32_t kURIMaxLength = 64;
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "mozilla/dom/ContentParent.h"
|
#include "mozilla/dom/ContentParent.h"
|
||||||
#include "mozilla/dom/ContentChild.h"
|
#include "mozilla/dom/ContentChild.h"
|
||||||
#include "mozilla/BasePrincipal.h"
|
#include "mozilla/BasePrincipal.h"
|
||||||
|
#include "mozilla/ContentPrincipal.h"
|
||||||
#include "mozilla/Services.h"
|
#include "mozilla/Services.h"
|
||||||
#include "mozilla/SystemGroup.h"
|
#include "mozilla/SystemGroup.h"
|
||||||
#include "mozilla/Unused.h"
|
#include "mozilla/Unused.h"
|
||||||
@ -44,7 +45,6 @@
|
|||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include "mozilla/AbstractThread.h"
|
#include "mozilla/AbstractThread.h"
|
||||||
#include "ContentPrincipal.h"
|
|
||||||
#include "ExpandedPrincipal.h"
|
#include "ExpandedPrincipal.h"
|
||||||
|
|
||||||
static nsPermissionManager *gPermissionManager = nullptr;
|
static nsPermissionManager *gPermissionManager = nullptr;
|
||||||
|
@ -16,15 +16,16 @@
|
|||||||
#include "nspr.h"
|
#include "nspr.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/Maybe.h"
|
#include "mozilla/Maybe.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
#include "nsJSPrincipals.h"
|
#include "nsJSPrincipals.h"
|
||||||
#include "nsIScriptError.h"
|
#include "nsIScriptError.h"
|
||||||
#include "js/Wrapper.h"
|
#include "js/Wrapper.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
|
|
||||||
extern mozilla::LazyLogModule MCD;
|
extern mozilla::LazyLogModule MCD;
|
||||||
using mozilla::AutoSafeJSContext;
|
using mozilla::AutoSafeJSContext;
|
||||||
|
using mozilla::NullPrincipal;
|
||||||
using mozilla::dom::AutoJSAPI;
|
using mozilla::dom::AutoJSAPI;
|
||||||
|
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
|
@ -472,6 +472,7 @@ GetD2D1PropsForIntSize(FilterType aType, uint32_t aIndex, UINT32 *aPropWidth, UI
|
|||||||
static inline REFCLSID GetCLDIDForFilterType(FilterType aType)
|
static inline REFCLSID GetCLDIDForFilterType(FilterType aType)
|
||||||
{
|
{
|
||||||
switch (aType) {
|
switch (aType) {
|
||||||
|
case FilterType::OPACITY:
|
||||||
case FilterType::COLOR_MATRIX:
|
case FilterType::COLOR_MATRIX:
|
||||||
return CLSID_D2D1ColorMatrix;
|
return CLSID_D2D1ColorMatrix;
|
||||||
case FilterType::TRANSFORM:
|
case FilterType::TRANSFORM:
|
||||||
@ -585,6 +586,10 @@ FilterNodeD2D1::Create(ID2D1DeviceContext *aDC, FilterType aType)
|
|||||||
effect->SetValue(D2D1_ARITHMETICCOMPOSITE_PROP_CLAMP_OUTPUT, TRUE);
|
effect->SetValue(D2D1_ARITHMETICCOMPOSITE_PROP_CLAMP_OUTPUT, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aType == FilterType::OPACITY) {
|
||||||
|
return MakeAndAddRef<FilterNodeOpacityD2D1>(effect, aType);
|
||||||
|
}
|
||||||
|
|
||||||
RefPtr<FilterNodeD2D1> filter = new FilterNodeD2D1(effect, aType);
|
RefPtr<FilterNodeD2D1> filter = new FilterNodeD2D1(effect, aType);
|
||||||
|
|
||||||
if (HasUnboundedOutputRegion(aType)) {
|
if (HasUnboundedOutputRegion(aType)) {
|
||||||
@ -870,6 +875,20 @@ FilterNodeD2D1::SetAttribute(uint32_t aIndex, const Matrix &aMatrix)
|
|||||||
mEffect->SetValue(input, D2DMatrix(aMatrix));
|
mEffect->SetValue(input, D2DMatrix(aMatrix));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilterNodeOpacityD2D1::SetAttribute(uint32_t aIndex, Float aValue)
|
||||||
|
{
|
||||||
|
D2D1_MATRIX_5X4_F matrix = D2D1::Matrix5x4F(aValue, 0, 0, 0,
|
||||||
|
0, aValue, 0, 0,
|
||||||
|
0, 0, aValue, 0,
|
||||||
|
0, 0, 0, aValue,
|
||||||
|
0, 0, 0, 0);
|
||||||
|
|
||||||
|
mEffect->SetValue(D2D1_COLORMATRIX_PROP_COLOR_MATRIX, matrix);
|
||||||
|
mEffect->SetValue(D2D1_COLORMATRIX_PROP_ALPHA_MODE, D2D1_COLORMATRIX_ALPHA_MODE_STRAIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
FilterNodeConvolveD2D1::FilterNodeConvolveD2D1(ID2D1DeviceContext *aDC)
|
FilterNodeConvolveD2D1::FilterNodeConvolveD2D1(ID2D1DeviceContext *aDC)
|
||||||
: FilterNodeD2D1(nullptr, FilterType::CONVOLVE_MATRIX)
|
: FilterNodeD2D1(nullptr, FilterType::CONVOLVE_MATRIX)
|
||||||
, mEdgeMode(EDGE_MODE_DUPLICATE)
|
, mEdgeMode(EDGE_MODE_DUPLICATE)
|
||||||
|
@ -108,6 +108,17 @@ private:
|
|||||||
IntRect mSourceRect;
|
IntRect mSourceRect;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FilterNodeOpacityD2D1 : public FilterNodeD2D1
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeOpacityD2D1, override)
|
||||||
|
explicit FilterNodeOpacityD2D1(ID2D1Effect *aEffect, FilterType aType)
|
||||||
|
: FilterNodeD2D1(aEffect, aType)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual void SetAttribute(uint32_t aIndex, Float aValue) override;
|
||||||
|
};
|
||||||
|
|
||||||
class FilterNodeExtendInputAdapterD2D1 : public FilterNodeD2D1
|
class FilterNodeExtendInputAdapterD2D1 : public FilterNodeD2D1
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -514,6 +514,9 @@ FilterNodeSoftware::Create(FilterType aType)
|
|||||||
case FilterType::UNPREMULTIPLY:
|
case FilterType::UNPREMULTIPLY:
|
||||||
filter = new FilterNodeUnpremultiplySoftware();
|
filter = new FilterNodeUnpremultiplySoftware();
|
||||||
break;
|
break;
|
||||||
|
case FilterType::OPACITY:
|
||||||
|
filter = new FilterNodeOpacitySoftware();
|
||||||
|
break;
|
||||||
case FilterType::POINT_DIFFUSE:
|
case FilterType::POINT_DIFFUSE:
|
||||||
filter = new FilterNodeLightingSoftware<PointLightSoftware, DiffuseLightingSoftware>("FilterNodeLightingSoftware<PointLight, DiffuseLighting>");
|
filter = new FilterNodeLightingSoftware<PointLightSoftware, DiffuseLightingSoftware>("FilterNodeLightingSoftware<PointLight, DiffuseLighting>");
|
||||||
break;
|
break;
|
||||||
@ -1432,6 +1435,44 @@ Unpremultiply(DataSourceSurface* aSurface)
|
|||||||
return target.forget();
|
return target.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static already_AddRefed<DataSourceSurface>
|
||||||
|
Opacity(DataSourceSurface* aSurface, Float aValue)
|
||||||
|
{
|
||||||
|
if (aValue == 1.0f) {
|
||||||
|
RefPtr<DataSourceSurface> surface(aSurface);
|
||||||
|
return surface.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
IntSize size = aSurface->GetSize();
|
||||||
|
RefPtr<DataSourceSurface> target =
|
||||||
|
Factory::CreateDataSourceSurface(size, aSurface->GetFormat());
|
||||||
|
if (MOZ2D_WARN_IF(!target)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataSourceSurface::ScopedMap inputMap(aSurface, DataSourceSurface::READ);
|
||||||
|
DataSourceSurface::ScopedMap targetMap(target, DataSourceSurface::WRITE);
|
||||||
|
if (MOZ2D_WARN_IF(!inputMap.IsMapped() || !targetMap.IsMapped())) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* inputData = inputMap.GetData();
|
||||||
|
int32_t inputStride = inputMap.GetStride();
|
||||||
|
uint8_t* targetData = targetMap.GetData();
|
||||||
|
int32_t targetStride = targetMap.GetStride();
|
||||||
|
|
||||||
|
if (aSurface->GetFormat() == SurfaceFormat::A8) {
|
||||||
|
FilterProcessing::DoOpacityCalculationA8(
|
||||||
|
size, targetData, targetStride, inputData, inputStride, aValue);
|
||||||
|
} else {
|
||||||
|
MOZ_ASSERT(aSurface->GetFormat() == SurfaceFormat::B8G8R8A8);
|
||||||
|
FilterProcessing::DoOpacityCalculation(
|
||||||
|
size, targetData, targetStride, inputData, inputStride, aValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return target.forget();
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<DataSourceSurface>
|
already_AddRefed<DataSourceSurface>
|
||||||
FilterNodeColorMatrixSoftware::Render(const IntRect& aRect)
|
FilterNodeColorMatrixSoftware::Render(const IntRect& aRect)
|
||||||
{
|
{
|
||||||
@ -3212,6 +3253,44 @@ FilterNodeUnpremultiplySoftware::GetOutputRectInRect(const IntRect& aRect)
|
|||||||
return GetInputRectInRect(IN_UNPREMULTIPLY_IN, aRect);
|
return GetInputRectInRect(IN_UNPREMULTIPLY_IN, aRect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilterNodeOpacitySoftware::SetAttribute(uint32_t aIndex,
|
||||||
|
Float aValue)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aIndex == ATT_OPACITY_VALUE);
|
||||||
|
mValue = aValue;
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t
|
||||||
|
FilterNodeOpacitySoftware::InputIndex(uint32_t aInputEnumIndex)
|
||||||
|
{
|
||||||
|
switch (aInputEnumIndex) {
|
||||||
|
case IN_OPACITY_IN: return 0;
|
||||||
|
default: return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
already_AddRefed<DataSourceSurface>
|
||||||
|
FilterNodeOpacitySoftware::Render(const IntRect& aRect)
|
||||||
|
{
|
||||||
|
RefPtr<DataSourceSurface> input =
|
||||||
|
GetInputDataSourceSurface(IN_OPACITY_IN, aRect);
|
||||||
|
return input ? Opacity(input, mValue) : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilterNodeOpacitySoftware::RequestFromInputsForRect(const IntRect &aRect)
|
||||||
|
{
|
||||||
|
RequestInputRect(IN_OPACITY_IN, aRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
IntRect
|
||||||
|
FilterNodeOpacitySoftware::GetOutputRectInRect(const IntRect& aRect)
|
||||||
|
{
|
||||||
|
return GetInputRectInRect(IN_OPACITY_IN, aRect);
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
PointLightSoftware::SetAttribute(uint32_t aIndex, const Point3D &aPoint)
|
PointLightSoftware::SetAttribute(uint32_t aIndex, const Point3D &aPoint)
|
||||||
{
|
{
|
||||||
|
@ -688,6 +688,22 @@ protected:
|
|||||||
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
|
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FilterNodeOpacitySoftware : public FilterNodeSoftware
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(FilterNodeOpacitySoftware, override)
|
||||||
|
virtual const char* GetName() override { return "Opacity"; }
|
||||||
|
using FilterNodeSoftware::SetAttribute;
|
||||||
|
virtual void SetAttribute(uint32_t aIndex, Float aValue) override;
|
||||||
|
protected:
|
||||||
|
virtual already_AddRefed<DataSourceSurface> Render(const IntRect& aRect) override;
|
||||||
|
virtual IntRect GetOutputRectInRect(const IntRect& aRect) override;
|
||||||
|
virtual int32_t InputIndex(uint32_t aInputEnumIndex) override;
|
||||||
|
virtual void RequestFromInputsForRect(const IntRect &aRect) override;
|
||||||
|
|
||||||
|
Float mValue = 1.0f;
|
||||||
|
};
|
||||||
|
|
||||||
template<typename LightType, typename LightingType>
|
template<typename LightType, typename LightingType>
|
||||||
class FilterNodeLightingSoftware : public FilterNodeSoftware
|
class FilterNodeLightingSoftware : public FilterNodeSoftware
|
||||||
{
|
{
|
||||||
|
@ -236,6 +236,34 @@ FilterProcessing::DoUnpremultiplicationCalculation(const IntSize& aSize,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilterProcessing::DoOpacityCalculation(const IntSize& aSize,
|
||||||
|
uint8_t* aTargetData, int32_t aTargetStride,
|
||||||
|
uint8_t* aSourceData, int32_t aSourceStride,
|
||||||
|
Float aValue)
|
||||||
|
{
|
||||||
|
if (Factory::HasSSE2()) {
|
||||||
|
#ifdef USE_SSE2
|
||||||
|
DoOpacityCalculation_SSE2(
|
||||||
|
aSize, aTargetData, aTargetStride, aSourceData, aSourceStride, aValue);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
DoOpacityCalculation_Scalar(
|
||||||
|
aSize, aTargetData, aTargetStride, aSourceData, aSourceStride, aValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilterProcessing::DoOpacityCalculationA8(const IntSize& aSize,
|
||||||
|
uint8_t* aTargetData, int32_t aTargetStride,
|
||||||
|
uint8_t* aSourceData, int32_t aSourceStride,
|
||||||
|
Float aValue)
|
||||||
|
{
|
||||||
|
DoOpacityCalculationA8_Scalar(
|
||||||
|
aSize, aTargetData, aTargetStride, aSourceData, aSourceStride, aValue);
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<DataSourceSurface>
|
already_AddRefed<DataSourceSurface>
|
||||||
FilterProcessing::RenderTurbulence(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
|
FilterProcessing::RenderTurbulence(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
|
||||||
int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect)
|
int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect)
|
||||||
|
@ -59,6 +59,14 @@ public:
|
|||||||
static void DoUnpremultiplicationCalculation(const IntSize& aSize,
|
static void DoUnpremultiplicationCalculation(const IntSize& aSize,
|
||||||
uint8_t* aTargetData, int32_t aTargetStride,
|
uint8_t* aTargetData, int32_t aTargetStride,
|
||||||
uint8_t* aSourceData, int32_t aSourceStride);
|
uint8_t* aSourceData, int32_t aSourceStride);
|
||||||
|
static void DoOpacityCalculation(const IntSize& aSize,
|
||||||
|
uint8_t* aTargetData, int32_t aTargetStride,
|
||||||
|
uint8_t* aSourceData, int32_t aSourceStride,
|
||||||
|
Float aValue);
|
||||||
|
static void DoOpacityCalculationA8(const IntSize& aSize,
|
||||||
|
uint8_t* aTargetData, int32_t aTargetStride,
|
||||||
|
uint8_t* aSourceData, int32_t aSourceStride,
|
||||||
|
Float aValue);
|
||||||
static already_AddRefed<DataSourceSurface>
|
static already_AddRefed<DataSourceSurface>
|
||||||
RenderTurbulence(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
|
RenderTurbulence(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
|
||||||
int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect);
|
int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect);
|
||||||
@ -87,6 +95,14 @@ protected:
|
|||||||
static void DoUnpremultiplicationCalculation_Scalar(const IntSize& aSize,
|
static void DoUnpremultiplicationCalculation_Scalar(const IntSize& aSize,
|
||||||
uint8_t* aTargetData, int32_t aTargetStride,
|
uint8_t* aTargetData, int32_t aTargetStride,
|
||||||
uint8_t* aSourceData, int32_t aSourceStride);
|
uint8_t* aSourceData, int32_t aSourceStride);
|
||||||
|
static void DoOpacityCalculation_Scalar(const IntSize& aSize,
|
||||||
|
uint8_t* aTargetData, int32_t aTargetStride,
|
||||||
|
uint8_t* aSourceData, int32_t aSourceStride,
|
||||||
|
Float aValue);
|
||||||
|
static void DoOpacityCalculationA8_Scalar(const IntSize& aSize,
|
||||||
|
uint8_t* aTargetData, int32_t aTargetStride,
|
||||||
|
uint8_t* aSourceData, int32_t aSourceStride,
|
||||||
|
Float aValue);
|
||||||
static already_AddRefed<DataSourceSurface>
|
static already_AddRefed<DataSourceSurface>
|
||||||
RenderTurbulence_Scalar(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
|
RenderTurbulence_Scalar(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
|
||||||
int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect);
|
int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect);
|
||||||
@ -115,6 +131,10 @@ protected:
|
|||||||
static void DoUnpremultiplicationCalculation_SSE2(const IntSize& aSize,
|
static void DoUnpremultiplicationCalculation_SSE2(const IntSize& aSize,
|
||||||
uint8_t* aTargetData, int32_t aTargetStride,
|
uint8_t* aTargetData, int32_t aTargetStride,
|
||||||
uint8_t* aSourceData, int32_t aSourceStride);
|
uint8_t* aSourceData, int32_t aSourceStride);
|
||||||
|
static void DoOpacityCalculation_SSE2(const IntSize& aSize,
|
||||||
|
uint8_t* aTargetData, int32_t aTargetStride,
|
||||||
|
uint8_t* aSourceData, int32_t aSourceStride,
|
||||||
|
Float aValue);
|
||||||
static already_AddRefed<DataSourceSurface>
|
static already_AddRefed<DataSourceSurface>
|
||||||
RenderTurbulence_SSE2(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
|
RenderTurbulence_SSE2(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
|
||||||
int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect);
|
int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect);
|
||||||
|
@ -982,6 +982,38 @@ DoUnpremultiplicationCalculation_SIMD(const IntSize& aSize,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename u16x8_t, typename u8x16_t>
|
||||||
|
static void
|
||||||
|
DoOpacityCalculation_SIMD(const IntSize& aSize,
|
||||||
|
uint8_t* aTargetData, int32_t aTargetStride,
|
||||||
|
uint8_t* aSourceData, int32_t aSourceStride,
|
||||||
|
Float aOpacity)
|
||||||
|
{
|
||||||
|
uint8_t alphaValue = uint8_t(roundf(255.f * aOpacity));
|
||||||
|
u16x8_t alphaValues = simd::FromU16<u16x8_t>(alphaValue, alphaValue, alphaValue, alphaValue,
|
||||||
|
alphaValue, alphaValue, alphaValue, alphaValue);
|
||||||
|
for (int32_t y = 0; y < aSize.height; y++) {
|
||||||
|
for (int32_t x = 0; x < aSize.width; x += 4) {
|
||||||
|
int32_t inputIndex = y * aSourceStride + 4 * x;
|
||||||
|
int32_t targetIndex = y * aTargetStride + 4 * x;
|
||||||
|
|
||||||
|
u8x16_t p1234 = simd::Load8<u8x16_t>(&aSourceData[inputIndex]);
|
||||||
|
u16x8_t p12 = simd::UnpackLo8x8ToU16x8(p1234);
|
||||||
|
u16x8_t p34 = simd::UnpackHi8x8ToU16x8(p1234);
|
||||||
|
|
||||||
|
// Multiply all components with alpha.
|
||||||
|
p12 = simd::Mul16(p12, alphaValues);
|
||||||
|
p34 = simd::Mul16(p34, alphaValues);
|
||||||
|
|
||||||
|
// Divide by 255 and pack.
|
||||||
|
u8x16_t result = simd::PackAndSaturate16To8(simd::ShiftRight16<8>(p12),
|
||||||
|
simd::ShiftRight16<8>(p34));
|
||||||
|
|
||||||
|
simd::Store8(&aTargetData[targetIndex], result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename f32x4_t, typename i32x4_t, typename u8x16_t>
|
template<typename f32x4_t, typename i32x4_t, typename u8x16_t>
|
||||||
static already_AddRefed<DataSourceSurface>
|
static already_AddRefed<DataSourceSurface>
|
||||||
RenderTurbulence_SIMD(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
|
RenderTurbulence_SIMD(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
|
||||||
|
@ -96,6 +96,15 @@ FilterProcessing::DoUnpremultiplicationCalculation_SSE2(
|
|||||||
DoUnpremultiplicationCalculation_SIMD<__m128i,__m128i>(aSize, aTargetData, aTargetStride, aSourceData, aSourceStride);
|
DoUnpremultiplicationCalculation_SIMD<__m128i,__m128i>(aSize, aTargetData, aTargetStride, aSourceData, aSourceStride);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilterProcessing::DoOpacityCalculation_SSE2(const IntSize& aSize,
|
||||||
|
uint8_t* aTargetData, int32_t aTargetStride,
|
||||||
|
uint8_t* aSourceData, int32_t aSourceStride,
|
||||||
|
Float aValue)
|
||||||
|
{
|
||||||
|
DoOpacityCalculation_SIMD<__m128i, __m128i>(aSize, aTargetData, aTargetStride, aSourceData, aSourceStride, aValue);
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<DataSourceSurface>
|
already_AddRefed<DataSourceSurface>
|
||||||
FilterProcessing::RenderTurbulence_SSE2(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
|
FilterProcessing::RenderTurbulence_SSE2(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
|
||||||
int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect)
|
int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect)
|
||||||
|
@ -227,6 +227,46 @@ FilterProcessing::DoUnpremultiplicationCalculation_Scalar(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilterProcessing::DoOpacityCalculation_Scalar(const IntSize& aSize,
|
||||||
|
uint8_t* aTargetData, int32_t aTargetStride,
|
||||||
|
uint8_t* aSourceData, int32_t aSourceStride,
|
||||||
|
Float aValue)
|
||||||
|
{
|
||||||
|
uint8_t alpha = uint8_t(roundf(255.f * aValue));
|
||||||
|
for (int32_t y = 0; y < aSize.height; y++) {
|
||||||
|
for (int32_t x = 0; x < aSize.width; x++) {
|
||||||
|
int32_t inputIndex = y * aSourceStride + 4 * x;
|
||||||
|
int32_t targetIndex = y * aTargetStride + 4 * x;
|
||||||
|
aTargetData[targetIndex + B8G8R8A8_COMPONENT_BYTEOFFSET_R] =
|
||||||
|
(aSourceData[inputIndex + B8G8R8A8_COMPONENT_BYTEOFFSET_R] * alpha) >> 8;
|
||||||
|
aTargetData[targetIndex + B8G8R8A8_COMPONENT_BYTEOFFSET_G] =
|
||||||
|
(aSourceData[inputIndex + B8G8R8A8_COMPONENT_BYTEOFFSET_G] * alpha) >> 8;
|
||||||
|
aTargetData[targetIndex + B8G8R8A8_COMPONENT_BYTEOFFSET_B] =
|
||||||
|
(aSourceData[inputIndex + B8G8R8A8_COMPONENT_BYTEOFFSET_B] * alpha) >> 8;
|
||||||
|
aTargetData[targetIndex + B8G8R8A8_COMPONENT_BYTEOFFSET_A] =
|
||||||
|
(aSourceData[inputIndex + B8G8R8A8_COMPONENT_BYTEOFFSET_A] * alpha) >> 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
FilterProcessing::DoOpacityCalculationA8_Scalar(const IntSize& aSize,
|
||||||
|
uint8_t* aTargetData, int32_t aTargetStride,
|
||||||
|
uint8_t* aSourceData, int32_t aSourceStride,
|
||||||
|
Float aValue)
|
||||||
|
{
|
||||||
|
uint8_t alpha = uint8_t(255.f * aValue);
|
||||||
|
for (int32_t y = 0; y < aSize.height; y++) {
|
||||||
|
for (int32_t x = 0; x < aSize.width; x++) {
|
||||||
|
int32_t inputIndex = y * aSourceStride;
|
||||||
|
int32_t targetIndex = y * aTargetStride;
|
||||||
|
aTargetData[targetIndex] =
|
||||||
|
FastDivideBy255<uint8_t>(aSourceData[inputIndex] * alpha);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
already_AddRefed<DataSourceSurface>
|
already_AddRefed<DataSourceSurface>
|
||||||
FilterProcessing::RenderTurbulence_Scalar(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
|
FilterProcessing::RenderTurbulence_Scalar(const IntSize &aSize, const Point &aOffset, const Size &aBaseFrequency,
|
||||||
int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect)
|
int32_t aSeed, int aNumOctaves, TurbulenceType aType, bool aStitch, const Rect &aTileRect)
|
||||||
|
@ -476,6 +476,16 @@ enum UnpremultiplyInputs
|
|||||||
IN_UNPREMULTIPLY_IN = 0
|
IN_UNPREMULTIPLY_IN = 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum OpacityAtts
|
||||||
|
{
|
||||||
|
ATT_OPACITY_VALUE = 0
|
||||||
|
};
|
||||||
|
|
||||||
|
enum OpacityInputs
|
||||||
|
{
|
||||||
|
IN_OPACITY_IN = 0
|
||||||
|
};
|
||||||
|
|
||||||
class FilterNode : public external::AtomicRefCounted<FilterNode>
|
class FilterNode : public external::AtomicRefCounted<FilterNode>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -128,7 +128,8 @@ enum class FilterType : int8_t {
|
|||||||
DISTANT_SPECULAR,
|
DISTANT_SPECULAR,
|
||||||
CROP,
|
CROP,
|
||||||
PREMULTIPLY,
|
PREMULTIPLY,
|
||||||
UNPREMULTIPLY
|
UNPREMULTIPLY,
|
||||||
|
OPACITY
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class DrawTargetType : int8_t {
|
enum class DrawTargetType : int8_t {
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
# includes
|
# includes
|
||||||
|
from __future__ import print_function
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import xml.etree.ElementTree
|
import xml.etree.ElementTree
|
||||||
@ -34,7 +35,6 @@ class GLConstHeader:
|
|||||||
def __init__(self, f):
|
def __init__(self, f):
|
||||||
self.f = f
|
self.f = f
|
||||||
|
|
||||||
|
|
||||||
def write(self, arg):
|
def write(self, arg):
|
||||||
if isinstance(arg, list):
|
if isinstance(arg, list):
|
||||||
self.f.write('\n'.join(arg) + '\n')
|
self.f.write('\n'.join(arg) + '\n')
|
||||||
@ -43,7 +43,6 @@ class GLConstHeader:
|
|||||||
else:
|
else:
|
||||||
self.f.write(str(arg) + '\n')
|
self.f.write(str(arg) + '\n')
|
||||||
|
|
||||||
|
|
||||||
def formatFileBegin(self):
|
def formatFileBegin(self):
|
||||||
self.write([
|
self.write([
|
||||||
'/* This Source Code Form is subject to the terms of the Mozilla Public',
|
'/* This Source Code Form is subject to the terms of the Mozilla Public',
|
||||||
@ -63,12 +62,10 @@ class GLConstHeader:
|
|||||||
''
|
''
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
def formatLibBegin(self, lib):
|
def formatLibBegin(self, lib):
|
||||||
# lib would be 'GL', 'EGL', 'GLX' or 'WGL'
|
# lib would be 'GL', 'EGL', 'GLX' or 'WGL'
|
||||||
self.write('// ' + lib)
|
self.write('// ' + lib)
|
||||||
|
|
||||||
|
|
||||||
def formatLibConstant(self, lib, name, value):
|
def formatLibConstant(self, lib, name, value):
|
||||||
# lib would be 'GL', 'EGL', 'GLX' or 'WGL'
|
# lib would be 'GL', 'EGL', 'GLX' or 'WGL'
|
||||||
# name is the name of the const (example: MAX_TEXTURE_SIZE)
|
# name is the name of the const (example: MAX_TEXTURE_SIZE)
|
||||||
@ -76,23 +73,21 @@ class GLConstHeader:
|
|||||||
|
|
||||||
define = '#define LOCAL_' + lib + '_' + name
|
define = '#define LOCAL_' + lib + '_' + name
|
||||||
whitespace = 60 - len(define)
|
whitespace = 60 - len(define)
|
||||||
|
|
||||||
if whitespace < 0:
|
if whitespace < 0:
|
||||||
whitespace = whitespace % 8
|
whitespace = whitespace % 8
|
||||||
|
|
||||||
self.write(define + ' ' * whitespace + ' ' + value)
|
|
||||||
|
|
||||||
|
self.write(define + ' ' * whitespace + ' ' + value)
|
||||||
|
|
||||||
def formatLibEnd(self, lib):
|
def formatLibEnd(self, lib):
|
||||||
# lib would be 'GL', 'EGL', 'GLX' or 'WGL'
|
# lib would be 'GL', 'EGL', 'GLX' or 'WGL'
|
||||||
self.write(2)
|
self.write(2)
|
||||||
|
|
||||||
|
|
||||||
def formatFileEnd(self):
|
def formatFileEnd(self):
|
||||||
self.write([
|
self.write([
|
||||||
'',
|
'',
|
||||||
'#endif // GLCONSTS_H_'
|
'#endif // GLCONSTS_H_'
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -132,12 +127,11 @@ class GLDatabase:
|
|||||||
# there is no vendor="EXT" and vendor="ATI" in gl.xml,
|
# there is no vendor="EXT" and vendor="ATI" in gl.xml,
|
||||||
# so we manualy declare them
|
# so we manualy declare them
|
||||||
|
|
||||||
|
|
||||||
def loadXML(self, path):
|
def loadXML(self, path):
|
||||||
xmlPath = getXMLDir() + path
|
xmlPath = getXMLDir() + path
|
||||||
|
|
||||||
if not os.path.isfile(xmlPath):
|
if not os.path.isfile(xmlPath):
|
||||||
print 'missing file "' + xmlPath + '"'
|
print('missing file "' + xmlPath + '"')
|
||||||
return False
|
return False
|
||||||
|
|
||||||
tree = xml.etree.ElementTree.parse(xmlPath)
|
tree = xml.etree.ElementTree.parse(xmlPath)
|
||||||
@ -179,9 +173,8 @@ class GLDatabase:
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def exportConsts(self, path):
|
def exportConsts(self, path):
|
||||||
with open(getScriptDir() + path,'w') as f:
|
with open(getScriptDir() + path, 'w') as f:
|
||||||
|
|
||||||
headerFile = GLConstHeader(f)
|
headerFile = GLConstHeader(f)
|
||||||
headerFile.formatFileBegin()
|
headerFile.formatFileBegin()
|
||||||
|
@ -12,19 +12,22 @@ import tempfile
|
|||||||
import yaml
|
import yaml
|
||||||
import buildconfig
|
import buildconfig
|
||||||
|
|
||||||
def shell_main():
|
|
||||||
parser = argparse.ArgumentParser()
|
|
||||||
parser.add_argument('-o', '--output', type=str, required=True,
|
|
||||||
help='Output file')
|
|
||||||
parser.add_argument('manifest', type=str,
|
|
||||||
help='Manifest source file')
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
with open(args.output, 'w') as out_file:
|
def shell_main():
|
||||||
process_manifest(out_file, args.manifest)
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('-o', '--output', type=str, required=True,
|
||||||
|
help='Output file')
|
||||||
|
parser.add_argument('manifest', type=str,
|
||||||
|
help='Manifest source file')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
with open(args.output, 'w') as out_file:
|
||||||
|
process_manifest(out_file, args.manifest)
|
||||||
|
|
||||||
|
|
||||||
def main(output_fp, input_filename):
|
def main(output_fp, input_filename):
|
||||||
return process_manifest(output_fp, input_filename)
|
return process_manifest(output_fp, input_filename)
|
||||||
|
|
||||||
|
|
||||||
HEADER = """// AUTOGENERATED - DO NOT EDIT
|
HEADER = """// AUTOGENERATED - DO NOT EDIT
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@ -36,123 +39,133 @@ FOOTER = """
|
|||||||
} // namespace layers
|
} // namespace layers
|
||||||
} // namespace mozilla"""
|
} // namespace mozilla"""
|
||||||
|
|
||||||
|
|
||||||
def process_manifest(output_fp, manifest_filename):
|
def process_manifest(output_fp, manifest_filename):
|
||||||
with codecs.open(manifest_filename, 'r', 'UTF-8') as in_fp:
|
with codecs.open(manifest_filename, 'r', 'UTF-8') as in_fp:
|
||||||
manifest = yaml.safe_load(in_fp)
|
manifest = yaml.safe_load(in_fp)
|
||||||
shader_folder, _ = os.path.split(manifest_filename)
|
shader_folder, _ = os.path.split(manifest_filename)
|
||||||
|
|
||||||
output_fp.write(HEADER)
|
output_fp.write(HEADER)
|
||||||
|
|
||||||
deps = set()
|
deps = set()
|
||||||
for block in manifest:
|
for block in manifest:
|
||||||
if 'type' not in block:
|
if 'type' not in block:
|
||||||
raise Exception("Expected 'type' key with shader mode")
|
raise Exception("Expected 'type' key with shader mode")
|
||||||
if 'file' not in block:
|
if 'file' not in block:
|
||||||
raise Exception("Expected 'file' key with shader file")
|
raise Exception("Expected 'file' key with shader file")
|
||||||
if 'shaders' not in block:
|
if 'shaders' not in block:
|
||||||
raise Exception("Expected 'shaders' key with shader name list")
|
raise Exception("Expected 'shaders' key with shader name list")
|
||||||
|
|
||||||
shader_file = os.path.join(shader_folder, block['file'])
|
shader_file = os.path.join(shader_folder, block['file'])
|
||||||
deps.add(shader_file)
|
deps.add(shader_file)
|
||||||
|
|
||||||
shader_model = block['type']
|
shader_model = block['type']
|
||||||
for shader_name in block['shaders']:
|
for shader_name in block['shaders']:
|
||||||
new_deps = run_fxc(
|
new_deps = run_fxc(
|
||||||
shader_model = shader_model,
|
shader_model=shader_model,
|
||||||
shader_file = shader_file,
|
shader_file=shader_file,
|
||||||
shader_name = shader_name,
|
shader_name=shader_name,
|
||||||
output_fp = output_fp)
|
output_fp=output_fp)
|
||||||
deps |= new_deps
|
deps |= new_deps
|
||||||
|
|
||||||
|
output_fp.write(FOOTER)
|
||||||
|
return deps
|
||||||
|
|
||||||
output_fp.write(FOOTER)
|
|
||||||
return deps
|
|
||||||
|
|
||||||
def run_fxc(shader_model,
|
def run_fxc(shader_model,
|
||||||
shader_file,
|
shader_file,
|
||||||
shader_name,
|
shader_name,
|
||||||
output_fp):
|
output_fp):
|
||||||
fxc_location = buildconfig.substs['FXC']
|
fxc_location = buildconfig.substs['FXC']
|
||||||
|
|
||||||
argv = [
|
argv = [
|
||||||
fxc_location,
|
fxc_location,
|
||||||
'-nologo',
|
'-nologo',
|
||||||
'-T{0}'.format(shader_model),
|
'-T{0}'.format(shader_model),
|
||||||
shader_file,
|
shader_file,
|
||||||
'-E{0}'.format(shader_name),
|
'-E{0}'.format(shader_name),
|
||||||
'-Vn{0}'.format(shader_name),
|
'-Vn{0}'.format(shader_name),
|
||||||
'-Vi',
|
'-Vi',
|
||||||
]
|
]
|
||||||
if 'Linux' in buildconfig.substs['HOST_OS_ARCH']:
|
if 'Linux' in buildconfig.substs['HOST_OS_ARCH']:
|
||||||
argv.insert(0, buildconfig.substs['WINE'])
|
argv.insert(0, buildconfig.substs['WINE'])
|
||||||
if shader_model.startswith('vs_'):
|
if shader_model.startswith('vs_'):
|
||||||
argv += ['-DVERTEX_SHADER']
|
argv += ['-DVERTEX_SHADER']
|
||||||
elif shader_model.startswith('ps_'):
|
elif shader_model.startswith('ps_'):
|
||||||
argv += ['-DPIXEL_SHADER']
|
argv += ['-DPIXEL_SHADER']
|
||||||
|
|
||||||
deps = None
|
deps = None
|
||||||
with ScopedTempFilename() as temp_filename:
|
with ScopedTempFilename() as temp_filename:
|
||||||
argv += ['-Fh{0}'.format(temp_filename)]
|
argv += ['-Fh{0}'.format(temp_filename)]
|
||||||
|
|
||||||
sys.stdout.write('{0}\n'.format(' '.join(argv)))
|
sys.stdout.write('{0}\n'.format(' '.join(argv)))
|
||||||
proc_stdout = subprocess.check_output(argv)
|
proc_stdout = subprocess.check_output(argv)
|
||||||
proc_stdout = decode_console_text(sys.stdout, proc_stdout)
|
proc_stdout = decode_console_text(sys.stdout, proc_stdout)
|
||||||
deps = find_dependencies(proc_stdout)
|
deps = find_dependencies(proc_stdout)
|
||||||
assert 'fxc2' in fxc_location or len(deps) > 0
|
assert 'fxc2' in fxc_location or len(deps) > 0
|
||||||
|
|
||||||
with open(temp_filename, 'r') as temp_fp:
|
with open(temp_filename, 'r') as temp_fp:
|
||||||
output_fp.write(temp_fp.read())
|
output_fp.write(temp_fp.read())
|
||||||
|
|
||||||
|
output_fp.write("ShaderBytes s{0} = {{ {0}, sizeof({0}) }};\n".format(
|
||||||
|
shader_name))
|
||||||
|
return deps
|
||||||
|
|
||||||
output_fp.write("ShaderBytes s{0} = {{ {0}, sizeof({0}) }};\n".format(
|
|
||||||
shader_name))
|
|
||||||
return deps
|
|
||||||
|
|
||||||
def find_dependencies(fxc_output):
|
def find_dependencies(fxc_output):
|
||||||
# Dependencies look like this:
|
# Dependencies look like this:
|
||||||
# Resolved to [<path>]
|
# Resolved to [<path>]
|
||||||
#
|
#
|
||||||
# Microsoft likes to change output strings based on the user's language, so
|
# Microsoft likes to change output strings based on the user's language, so
|
||||||
# instead of pattern matching on that string, we take everything in between
|
# instead of pattern matching on that string, we take everything in between
|
||||||
# brackets. We filter out potentially bogus strings later.
|
# brackets. We filter out potentially bogus strings later.
|
||||||
deps = set()
|
deps = set()
|
||||||
for line in fxc_output.split('\n'):
|
for line in fxc_output.split('\n'):
|
||||||
m = re.search(r"\[([^\]]+)\]", line)
|
m = re.search(r"\[([^\]]+)\]", line)
|
||||||
if m is None:
|
if m is None:
|
||||||
continue
|
continue
|
||||||
dep_path = m.group(1)
|
dep_path = m.group(1)
|
||||||
dep_path = os.path.normpath(dep_path)
|
dep_path = os.path.normpath(dep_path)
|
||||||
if os.path.isfile(dep_path):
|
if os.path.isfile(dep_path):
|
||||||
deps.add(dep_path)
|
deps.add(dep_path)
|
||||||
return deps
|
return deps
|
||||||
|
|
||||||
# Python reads the raw bytes from stdout, so we need to try our best to
|
# Python reads the raw bytes from stdout, so we need to try our best to
|
||||||
# capture that as a valid Python string.
|
# capture that as a valid Python string.
|
||||||
|
|
||||||
|
|
||||||
def decode_console_text(pipe, text):
|
def decode_console_text(pipe, text):
|
||||||
try:
|
try:
|
||||||
if pipe.encoding:
|
if pipe.encoding:
|
||||||
return text.decode(pipe.encoding, 'replace')
|
return text.decode(pipe.encoding, 'replace')
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
try:
|
try:
|
||||||
return text.decode(locale.getpreferredencoding(), 'replace')
|
return text.decode(locale.getpreferredencoding(), 'replace')
|
||||||
except:
|
except Exception:
|
||||||
return text.decode('utf8', 'replace')
|
return text.decode('utf8', 'replace')
|
||||||
|
|
||||||
# Allocate a temporary file name and delete it when done. We need an extra
|
# Allocate a temporary file name and delete it when done. We need an extra
|
||||||
# wrapper for this since TemporaryNamedFile holds the file open.
|
# wrapper for this since TemporaryNamedFile holds the file open.
|
||||||
|
|
||||||
|
|
||||||
class ScopedTempFilename(object):
|
class ScopedTempFilename(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.name = None
|
self.name = None
|
||||||
def __enter__(self):
|
|
||||||
with tempfile.NamedTemporaryFile(delete = False) as tmp:
|
def __enter__(self):
|
||||||
self.name = tmp.name
|
with tempfile.NamedTemporaryFile(delete=False) as tmp:
|
||||||
return self.name
|
self.name = tmp.name
|
||||||
def __exit__(self, type, value, traceback):
|
return self.name
|
||||||
if not self.name:
|
|
||||||
return
|
def __exit__(self, type, value, traceback):
|
||||||
try:
|
if not self.name:
|
||||||
os.unlink(self.name)
|
return
|
||||||
except:
|
try:
|
||||||
pass
|
os.unlink(self.name)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
shell_main()
|
shell_main()
|
||||||
|
@ -862,6 +862,17 @@ FilterNodeFromPrimitiveDescription(const FilterPrimitiveDescription& aDescriptio
|
|||||||
return lastFilter.forget();
|
return lastFilter.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case PrimitiveType::Opacity:
|
||||||
|
{
|
||||||
|
RefPtr<FilterNode> filter = aDT->CreateFilter(FilterType::OPACITY);
|
||||||
|
if (!filter) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
filter->SetAttribute(ATT_OPACITY_VALUE, atts.GetFloat(eOpacityOpacity));
|
||||||
|
filter->SetInput(IN_OPACITY_IN, aSources[0]);
|
||||||
|
return filter.forget();
|
||||||
|
}
|
||||||
|
|
||||||
case PrimitiveType::ConvolveMatrix:
|
case PrimitiveType::ConvolveMatrix:
|
||||||
{
|
{
|
||||||
RefPtr<FilterNode> filter = aDT->CreateFilter(FilterType::CONVOLVE_MATRIX);
|
RefPtr<FilterNode> filter = aDT->CreateFilter(FilterType::CONVOLVE_MATRIX);
|
||||||
@ -1394,6 +1405,7 @@ ResultChangeRegionForPrimitive(const FilterPrimitiveDescription& aDescription,
|
|||||||
case PrimitiveType::Blend:
|
case PrimitiveType::Blend:
|
||||||
case PrimitiveType::Composite:
|
case PrimitiveType::Composite:
|
||||||
case PrimitiveType::Merge:
|
case PrimitiveType::Merge:
|
||||||
|
case PrimitiveType::Opacity:
|
||||||
return UnionOfRegions(aInputChangeRegions);
|
return UnionOfRegions(aInputChangeRegions);
|
||||||
|
|
||||||
case PrimitiveType::ColorMatrix:
|
case PrimitiveType::ColorMatrix:
|
||||||
@ -1614,6 +1626,14 @@ FilterSupport::PostFilterExtentsForPrimitive(const FilterPrimitiveDescription& a
|
|||||||
return aInputExtents[0];
|
return aInputExtents[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case PrimitiveType::Opacity:
|
||||||
|
{
|
||||||
|
if (atts.GetFloat(eOpacityOpacity) == 0.0f) {
|
||||||
|
return IntRect();
|
||||||
|
}
|
||||||
|
return ResultChangeRegionForPrimitive(aDescription, aInputExtents);
|
||||||
|
}
|
||||||
|
|
||||||
case PrimitiveType::Turbulence:
|
case PrimitiveType::Turbulence:
|
||||||
case PrimitiveType::Image:
|
case PrimitiveType::Image:
|
||||||
case PrimitiveType::DiffuseLighting:
|
case PrimitiveType::DiffuseLighting:
|
||||||
@ -1692,6 +1712,7 @@ SourceNeededRegionForPrimitive(const FilterPrimitiveDescription& aDescription,
|
|||||||
case PrimitiveType::ColorMatrix:
|
case PrimitiveType::ColorMatrix:
|
||||||
case PrimitiveType::ComponentTransfer:
|
case PrimitiveType::ComponentTransfer:
|
||||||
case PrimitiveType::ToAlpha:
|
case PrimitiveType::ToAlpha:
|
||||||
|
case PrimitiveType::Opacity:
|
||||||
return aResultNeededRegion;
|
return aResultNeededRegion;
|
||||||
|
|
||||||
case PrimitiveType::Morphology:
|
case PrimitiveType::Morphology:
|
||||||
|
@ -95,6 +95,7 @@ enum AttributeName {
|
|||||||
eColorMatrixValues,
|
eColorMatrixValues,
|
||||||
eFloodColor,
|
eFloodColor,
|
||||||
eTileSourceRect,
|
eTileSourceRect,
|
||||||
|
eOpacityOpacity,
|
||||||
eComponentTransferFunctionR,
|
eComponentTransferFunctionR,
|
||||||
eComponentTransferFunctionG,
|
eComponentTransferFunctionG,
|
||||||
eComponentTransferFunctionB,
|
eComponentTransferFunctionB,
|
||||||
@ -277,6 +278,7 @@ enum class PrimitiveType {
|
|||||||
Flood,
|
Flood,
|
||||||
Tile,
|
Tile,
|
||||||
ComponentTransfer,
|
ComponentTransfer,
|
||||||
|
Opacity,
|
||||||
ConvolveMatrix,
|
ConvolveMatrix,
|
||||||
Offset,
|
Offset,
|
||||||
DisplacementMap,
|
DisplacementMap,
|
||||||
|
@ -17,7 +17,7 @@ while True:
|
|||||||
line = f.readline()
|
line = f.readline()
|
||||||
if not line:
|
if not line:
|
||||||
break
|
break
|
||||||
if not 'CJK COMPATIBILITY IDEOGRAPH-' in line:
|
if 'CJK COMPATIBILITY IDEOGRAPH-' not in line:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
m = r.search(line)
|
m = r.search(line)
|
||||||
@ -25,7 +25,7 @@ while True:
|
|||||||
vs = int(m.group(2), 16)
|
vs = int(m.group(2), 16)
|
||||||
compat = int(m.group(3), 16)
|
compat = int(m.group(3), 16)
|
||||||
|
|
||||||
if not vs in vsdict:
|
if vs not in vsdict:
|
||||||
vsdict[vs] = {}
|
vsdict[vs] = {}
|
||||||
vsdict[vs][unified] = compat
|
vsdict[vs][unified] = compat
|
||||||
|
|
||||||
|
@ -15,7 +15,6 @@
|
|||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
#include "nsIInputStream.h"
|
#include "nsIInputStream.h"
|
||||||
#include "nsStringStream.h"
|
#include "nsStringStream.h"
|
||||||
#include "nsStreamUtils.h"
|
#include "nsStreamUtils.h"
|
||||||
@ -25,6 +24,7 @@
|
|||||||
#include "mozilla/dom/FontTableURIProtocolHandler.h"
|
#include "mozilla/dom/FontTableURIProtocolHandler.h"
|
||||||
#include "mozilla/dom/SVGDocument.h"
|
#include "mozilla/dom/SVGDocument.h"
|
||||||
#include "mozilla/LoadInfo.h"
|
#include "mozilla/LoadInfo.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "nsSVGUtils.h"
|
#include "nsSVGUtils.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "gfxFont.h"
|
#include "gfxFont.h"
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "mozilla/dom/ContentChild.h"
|
#include "mozilla/dom/ContentChild.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "nsMimeTypes.h"
|
#include "nsMimeTypes.h"
|
||||||
#include "nsIURL.h"
|
#include "nsIURL.h"
|
||||||
#include "nsXULAppAPI.h"
|
#include "nsXULAppAPI.h"
|
||||||
@ -13,7 +14,6 @@
|
|||||||
#include "nsIStringStream.h"
|
#include "nsIStringStream.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS(nsIconChannel,
|
NS_IMPL_ISUPPORTS(nsIconChannel,
|
||||||
nsIRequest,
|
nsIRequest,
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "mozilla/DebugOnly.h"
|
#include "mozilla/DebugOnly.h"
|
||||||
#include "mozilla/EndianUtils.h"
|
#include "mozilla/EndianUtils.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
@ -25,7 +26,6 @@
|
|||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
#include "nsIStringStream.h"
|
#include "nsIStringStream.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
#include "nsIURL.h"
|
#include "nsIURL.h"
|
||||||
#include "prlink.h"
|
#include "prlink.h"
|
||||||
#include "gfxPlatform.h"
|
#include "gfxPlatform.h"
|
||||||
@ -106,7 +106,8 @@ moz_gdk_pixbuf_to_channel(GdkPixbuf* aPixbuf, nsIURI* aURI,
|
|||||||
// nsIconProtocolHandler::NewChannel2 will provide the correct loadInfo for
|
// nsIconProtocolHandler::NewChannel2 will provide the correct loadInfo for
|
||||||
// this iconChannel. Use the most restrictive security settings for the
|
// this iconChannel. Use the most restrictive security settings for the
|
||||||
// temporary loadInfo to make sure the channel can not be openend.
|
// temporary loadInfo to make sure the channel can not be openend.
|
||||||
nsCOMPtr<nsIPrincipal> nullPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
|
nsCOMPtr<nsIPrincipal> nullPrincipal =
|
||||||
|
mozilla::NullPrincipal::CreateWithoutOriginAttributes();
|
||||||
return NS_NewInputStreamChannel(aChannel,
|
return NS_NewInputStreamChannel(aChannel,
|
||||||
aURI,
|
aURI,
|
||||||
stream.forget(),
|
stream.forget(),
|
||||||
|
@ -9,11 +9,11 @@
|
|||||||
|
|
||||||
#include "ImageLogging.h"
|
#include "ImageLogging.h"
|
||||||
#include "imgLoader.h"
|
#include "imgLoader.h"
|
||||||
#include "NullPrincipal.h"
|
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/ClearOnShutdown.h"
|
#include "mozilla/ClearOnShutdown.h"
|
||||||
#include "mozilla/Move.h"
|
#include "mozilla/Move.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/ChaosMode.h"
|
#include "mozilla/ChaosMode.h"
|
||||||
#include "mozilla/LoadInfo.h"
|
#include "mozilla/LoadInfo.h"
|
||||||
|
@ -84,11 +84,11 @@ def try_run(name, command, cwd=None, **kwargs):
|
|||||||
try:
|
try:
|
||||||
with tempfile.NamedTemporaryFile(prefix=name, delete=False) as f:
|
with tempfile.NamedTemporaryFile(prefix=name, delete=False) as f:
|
||||||
subprocess.check_call(command, cwd=cwd, stdout=f,
|
subprocess.check_call(command, cwd=cwd, stdout=f,
|
||||||
stderr=subprocess.STDOUT, **kwargs)
|
stderr=subprocess.STDOUT, **kwargs)
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
print('''Error running "{}" in directory {}
|
print('''Error running "{}" in directory {}
|
||||||
See output in {}'''.format(' '.join(command), cwd, f.name),
|
See output in {}'''.format(' '.join(command), cwd, f.name),
|
||||||
file=sys.stderr)
|
file=sys.stderr)
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
os.unlink(f.name)
|
os.unlink(f.name)
|
||||||
@ -151,7 +151,7 @@ def update_data_file(topsrcdir):
|
|||||||
shutil.copy(new_data_file, tree_data_path)
|
shutil.copy(new_data_file, tree_data_path)
|
||||||
try:
|
try:
|
||||||
shutil.rmtree(objdir)
|
shutil.rmtree(objdir)
|
||||||
except:
|
except Exception:
|
||||||
print('Warning: failed to remove %s' % objdir, file=sys.stderr)
|
print('Warning: failed to remove %s' % objdir, file=sys.stderr)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -2,26 +2,24 @@
|
|||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
def main(header, propFile):
|
def main(header, propFile):
|
||||||
mappings = {}
|
mappings = {}
|
||||||
|
|
||||||
with open(propFile, 'r') as f:
|
with open(propFile, 'r') as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if not line.startswith('#'):
|
if not line.startswith('#'):
|
||||||
parts = line.split("=", 1)
|
parts = line.split("=", 1)
|
||||||
if len(parts) == 2 and len(parts[0]) > 0:
|
if len(parts) == 2 and len(parts[0]) > 0:
|
||||||
mappings[parts[0].strip()] = parts[1].strip()
|
mappings[parts[0].strip()] = parts[1].strip()
|
||||||
|
|
||||||
keys = mappings.keys()
|
|
||||||
keys.sort()
|
|
||||||
|
|
||||||
header.write("// This is a generated file. Please do not edit.\n")
|
keys = mappings.keys()
|
||||||
header.write("// Please edit the corresponding .properties file instead.\n")
|
keys.sort()
|
||||||
|
|
||||||
entries = ['{ "%s", "%s", %d }'
|
header.write("// This is a generated file. Please do not edit.\n")
|
||||||
% (key, mappings[key], len(mappings[key])) for key in keys]
|
header.write("// Please edit the corresponding .properties file instead.\n")
|
||||||
header.write(',\n'.join(entries) + '\n')
|
|
||||||
|
|
||||||
|
entries = ['{ "%s", "%s", %d }'
|
||||||
|
% (key, mappings[key], len(mappings[key])) for key in keys]
|
||||||
|
header.write(',\n'.join(entries) + '\n')
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#include "MainThreadUtils.h"
|
#include "MainThreadUtils.h"
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/BasePrincipal.h"
|
#include "mozilla/BasePrincipal.h"
|
||||||
|
#include "mozilla/ContentPrincipal.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||||
#include "mozilla/ipc/URIUtils.h"
|
#include "mozilla/ipc/URIUtils.h"
|
||||||
#include "mozilla/net/NeckoChannelParams.h"
|
#include "mozilla/net/NeckoChannelParams.h"
|
||||||
@ -17,8 +19,6 @@
|
|||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "mozilla/LoadInfo.h"
|
#include "mozilla/LoadInfo.h"
|
||||||
#include "ContentPrincipal.h"
|
|
||||||
#include "NullPrincipal.h"
|
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
|
@ -11,12 +11,12 @@
|
|||||||
#include "mozilla/ArrayUtils.h"
|
#include "mozilla/ArrayUtils.h"
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
#include "mozilla/dom/BlobURL.h"
|
#include "mozilla/dom/BlobURL.h"
|
||||||
|
#include "mozilla/NullPrincipalURI.h"
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
#include "nsDebug.h"
|
#include "nsDebug.h"
|
||||||
#include "nsID.h"
|
#include "nsID.h"
|
||||||
#include "nsJARURI.h"
|
#include "nsJARURI.h"
|
||||||
#include "nsIIconURI.h"
|
#include "nsIIconURI.h"
|
||||||
#include "NullPrincipalURI.h"
|
|
||||||
#include "nsJSProtocolHandler.h"
|
#include "nsJSProtocolHandler.h"
|
||||||
#include "nsNetCID.h"
|
#include "nsNetCID.h"
|
||||||
#include "nsSimpleNestedURI.h"
|
#include "nsSimpleNestedURI.h"
|
||||||
|
5
ipc/ipdl/.flake8
Normal file
5
ipc/ipdl/.flake8
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
[flake8]
|
||||||
|
# See http://pep8.readthedocs.io/en/latest/intro.html#configuration
|
||||||
|
ignore = E121, E123, E126, E129, E133, E226, E241, E242, E704, W503, E402, E741, F405, F403
|
||||||
|
max-line-length = 99
|
||||||
|
|
@ -1,22 +1,24 @@
|
|||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
# 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
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
import optparse
|
||||||
import optparse, os, re, sys
|
import os
|
||||||
|
import sys
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
import mozpack.path as mozpath
|
|
||||||
from ConfigParser import RawConfigParser
|
from ConfigParser import RawConfigParser
|
||||||
|
|
||||||
import ipdl
|
import ipdl
|
||||||
|
|
||||||
|
|
||||||
def log(minv, fmt, *args):
|
def log(minv, fmt, *args):
|
||||||
if _verbosity >= minv:
|
if _verbosity >= minv:
|
||||||
print fmt % args
|
print(fmt % args)
|
||||||
|
|
||||||
# process command line
|
# process command line
|
||||||
|
|
||||||
|
|
||||||
op = optparse.OptionParser(usage='ipdl.py [options] IPDLfiles...')
|
op = optparse.OptionParser(usage='ipdl.py [options] IPDLfiles...')
|
||||||
op.add_option('-I', '--include', dest='includedirs', default=[ ],
|
op.add_option('-I', '--include', dest='includedirs', default=[],
|
||||||
action='append',
|
action='append',
|
||||||
help='Additional directory to search for included protocol specifications')
|
help='Additional directory to search for included protocol specifications')
|
||||||
op.add_option('-s', '--sync-msg-list', dest='syncMsgList', default='sync-messages.ini',
|
op.add_option('-s', '--sync-msg-list', dest='syncMsgList', default='sync-messages.ini',
|
||||||
@ -44,7 +46,7 @@ syncMsgList = options.syncMsgList
|
|||||||
msgMetadata = options.msgMetadata
|
msgMetadata = options.msgMetadata
|
||||||
headersdir = options.headersdir
|
headersdir = options.headersdir
|
||||||
cppdir = options.cppdir
|
cppdir = options.cppdir
|
||||||
includedirs = [ os.path.abspath(incdir) for incdir in options.includedirs ]
|
includedirs = [os.path.abspath(incdir) for incdir in options.includedirs]
|
||||||
|
|
||||||
if not len(files):
|
if not len(files):
|
||||||
op.error("No IPDL files specified")
|
op.error("No IPDL files specified")
|
||||||
@ -59,11 +61,13 @@ allmessages = {}
|
|||||||
allmessageprognames = []
|
allmessageprognames = []
|
||||||
allprotocols = []
|
allprotocols = []
|
||||||
|
|
||||||
|
|
||||||
def normalizedFilename(f):
|
def normalizedFilename(f):
|
||||||
if f == '-':
|
if f == '-':
|
||||||
return '<stdin>'
|
return '<stdin>'
|
||||||
return f
|
return f
|
||||||
|
|
||||||
|
|
||||||
log(2, 'Reading sync message list')
|
log(2, 'Reading sync message list')
|
||||||
parser = RawConfigParser()
|
parser = RawConfigParser()
|
||||||
parser.readfp(open(options.syncMsgList))
|
parser.readfp(open(options.syncMsgList))
|
||||||
@ -104,7 +108,7 @@ for f in files:
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if not ipdl.checkSyncMessage(ast, syncMsgList):
|
if not ipdl.checkSyncMessage(ast, syncMsgList):
|
||||||
print >>sys.stderr, 'Error: New sync IPC messages must be reviewed by an IPC peer and recorded in %s' % options.syncMsgList
|
print >>sys.stderr, 'Error: New sync IPC messages must be reviewed by an IPC peer and recorded in %s' % options.syncMsgList # NOQA: E501
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if not ipdl.checkFixedSyncMessages(parser):
|
if not ipdl.checkFixedSyncMessages(parser):
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
__all__ = [ 'gencxx', 'genipdl', 'parse', 'typecheck', 'writeifmodified',
|
__all__ = ['gencxx', 'genipdl', 'parse', 'typecheck', 'writeifmodified',
|
||||||
'checkSyncMessage', 'checkFixedSyncMessages' ]
|
'checkSyncMessage', 'checkFixedSyncMessages']
|
||||||
|
|
||||||
import os, sys
|
import os
|
||||||
|
import sys
|
||||||
from cStringIO import StringIO
|
from cStringIO import StringIO
|
||||||
|
|
||||||
from ipdl.cgen import IPDLCodeGen
|
from ipdl.cgen import IPDLCodeGen
|
||||||
@ -17,7 +18,7 @@ from ipdl.checker import checkSyncMessage, checkFixedSyncMessages
|
|||||||
from ipdl.cxx.cgen import CxxCodeGen
|
from ipdl.cxx.cgen import CxxCodeGen
|
||||||
|
|
||||||
|
|
||||||
def parse(specstring, filename='/stdin', includedirs=[ ], errout=sys.stderr):
|
def parse(specstring, filename='/stdin', includedirs=[], errout=sys.stderr):
|
||||||
'''Return an IPDL AST if parsing was successful. Print errors to |errout|
|
'''Return an IPDL AST if parsing was successful. Print errors to |errout|
|
||||||
if it is not.'''
|
if it is not.'''
|
||||||
# The file type and name are later enforced by the type checker.
|
# The file type and name are later enforced by the type checker.
|
||||||
@ -35,6 +36,7 @@ def parse(specstring, filename='/stdin', includedirs=[ ], errout=sys.stderr):
|
|||||||
print >>errout, p
|
print >>errout, p
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def typecheck(ast, errout=sys.stderr):
|
def typecheck(ast, errout=sys.stderr):
|
||||||
'''Return True iff |ast| is well typed. Print errors to |errout| if
|
'''Return True iff |ast| is well typed. Print errors to |errout| if
|
||||||
it is not.'''
|
it is not.'''
|
||||||
@ -51,11 +53,12 @@ def gencxx(ipdlfilename, ast, outheadersdir, outcppdir, segmentcapacitydict):
|
|||||||
outheadersdir,
|
outheadersdir,
|
||||||
*([ns.name for ns in ast.namespaces] + [hdr.name]))
|
*([ns.name for ns in ast.namespaces] + [hdr.name]))
|
||||||
]
|
]
|
||||||
def resolveCpp(cpp):
|
|
||||||
return [ cpp, os.path.join(outcppdir, cpp.name) ]
|
|
||||||
|
|
||||||
for ast, filename in ([ resolveHeader(hdr) for hdr in headers ]
|
def resolveCpp(cpp):
|
||||||
+ [ resolveCpp(cpp) for cpp in cpps ]):
|
return [cpp, os.path.join(outcppdir, cpp.name)]
|
||||||
|
|
||||||
|
for ast, filename in ([resolveHeader(hdr) for hdr in headers]
|
||||||
|
+ [resolveCpp(cpp) for cpp in cpps]):
|
||||||
tempfile = StringIO()
|
tempfile = StringIO()
|
||||||
CxxCodeGen(tempfile).cgen(ast)
|
CxxCodeGen(tempfile).cgen(ast)
|
||||||
writeifmodified(tempfile.getvalue(), filename)
|
writeifmodified(tempfile.getvalue(), filename)
|
||||||
@ -68,6 +71,7 @@ def genipdl(ast, outdir):
|
|||||||
def genmsgenum(ast):
|
def genmsgenum(ast):
|
||||||
return msgenums(ast.protocol, pretty=True)
|
return msgenums(ast.protocol, pretty=True)
|
||||||
|
|
||||||
|
|
||||||
def writeifmodified(contents, file):
|
def writeifmodified(contents, file):
|
||||||
dir = os.path.dirname(file)
|
dir = os.path.dirname(file)
|
||||||
os.path.exists(dir) or os.makedirs(dir)
|
os.path.exists(dir) or os.makedirs(dir)
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
NOT_NESTED = 1
|
NOT_NESTED = 1
|
||||||
INSIDE_SYNC_NESTED = 2
|
INSIDE_SYNC_NESTED = 2
|
||||||
INSIDE_CPOW_NESTED = 3
|
INSIDE_CPOW_NESTED = 3
|
||||||
@ -12,10 +10,11 @@ NORMAL_PRIORITY = 1
|
|||||||
INPUT_PRIORITY = 2
|
INPUT_PRIORITY = 2
|
||||||
HIGH_PRIORITY = 3
|
HIGH_PRIORITY = 3
|
||||||
|
|
||||||
|
|
||||||
class Visitor:
|
class Visitor:
|
||||||
def defaultVisit(self, node):
|
def defaultVisit(self, node):
|
||||||
raise Exception, "INTERNAL ERROR: no visitor for node type `%s'"% (
|
raise Exception("INTERNAL ERROR: no visitor for node type `%s'" %
|
||||||
node.__class__.__name__)
|
(node.__class__.__name__))
|
||||||
|
|
||||||
def visitTranslationUnit(self, tu):
|
def visitTranslationUnit(self, tu):
|
||||||
for cxxInc in tu.cxxIncludes:
|
for cxxInc in tu.cxxIncludes:
|
||||||
@ -31,7 +30,6 @@ class Visitor:
|
|||||||
if tu.protocol:
|
if tu.protocol:
|
||||||
tu.protocol.accept(self)
|
tu.protocol.accept(self)
|
||||||
|
|
||||||
|
|
||||||
def visitCxxInclude(self, inc):
|
def visitCxxInclude(self, inc):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -88,27 +86,33 @@ class Visitor:
|
|||||||
def visitDecl(self, d):
|
def visitDecl(self, d):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Loc:
|
class Loc:
|
||||||
def __init__(self, filename='<??>', lineno=0):
|
def __init__(self, filename='<??>', lineno=0):
|
||||||
assert filename
|
assert filename
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.lineno = lineno
|
self.lineno = lineno
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '%r:%r'% (self.filename, self.lineno)
|
return '%r:%r' % (self.filename, self.lineno)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '%s:%s'% (self.filename, self.lineno)
|
return '%s:%s' % (self.filename, self.lineno)
|
||||||
|
|
||||||
|
|
||||||
Loc.NONE = Loc(filename='<??>', lineno=0)
|
Loc.NONE = Loc(filename='<??>', lineno=0)
|
||||||
|
|
||||||
|
|
||||||
class _struct:
|
class _struct:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Node:
|
class Node:
|
||||||
def __init__(self, loc=Loc.NONE):
|
def __init__(self, loc=Loc.NONE):
|
||||||
self.loc = loc
|
self.loc = loc
|
||||||
|
|
||||||
def accept(self, visitor):
|
def accept(self, visitor):
|
||||||
visit = getattr(visitor, 'visit'+ self.__class__.__name__, None)
|
visit = getattr(visitor, 'visit' + self.__class__.__name__, None)
|
||||||
if visit is None:
|
if visit is None:
|
||||||
return getattr(visitor, 'defaultVisit')(self)
|
return getattr(visitor, 'defaultVisit')(self)
|
||||||
return visit(self)
|
return visit(self)
|
||||||
@ -122,40 +126,47 @@ class NamespacedNode(Node):
|
|||||||
def __init__(self, loc=Loc.NONE, name=None):
|
def __init__(self, loc=Loc.NONE, name=None):
|
||||||
Node.__init__(self, loc)
|
Node.__init__(self, loc)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.namespaces = [ ]
|
self.namespaces = []
|
||||||
|
|
||||||
def addOuterNamespace(self, namespace):
|
def addOuterNamespace(self, namespace):
|
||||||
self.namespaces.insert(0, namespace)
|
self.namespaces.insert(0, namespace)
|
||||||
|
|
||||||
def qname(self):
|
def qname(self):
|
||||||
return QualifiedId(self.loc, self.name,
|
return QualifiedId(self.loc, self.name,
|
||||||
[ ns.name for ns in self.namespaces ])
|
[ns.name for ns in self.namespaces])
|
||||||
|
|
||||||
|
|
||||||
class TranslationUnit(NamespacedNode):
|
class TranslationUnit(NamespacedNode):
|
||||||
def __init__(self, type, name):
|
def __init__(self, type, name):
|
||||||
NamespacedNode.__init__(self, name=name)
|
NamespacedNode.__init__(self, name=name)
|
||||||
self.filetype = type
|
self.filetype = type
|
||||||
self.filename = None
|
self.filename = None
|
||||||
self.cxxIncludes = [ ]
|
self.cxxIncludes = []
|
||||||
self.includes = [ ]
|
self.includes = []
|
||||||
self.builtinUsing = [ ]
|
self.builtinUsing = []
|
||||||
self.using = [ ]
|
self.using = []
|
||||||
self.structsAndUnions = [ ]
|
self.structsAndUnions = []
|
||||||
self.protocol = None
|
self.protocol = None
|
||||||
|
|
||||||
def addCxxInclude(self, cxxInclude): self.cxxIncludes.append(cxxInclude)
|
def addCxxInclude(self, cxxInclude): self.cxxIncludes.append(cxxInclude)
|
||||||
|
|
||||||
def addInclude(self, inc): self.includes.append(inc)
|
def addInclude(self, inc): self.includes.append(inc)
|
||||||
|
|
||||||
def addStructDecl(self, struct): self.structsAndUnions.append(struct)
|
def addStructDecl(self, struct): self.structsAndUnions.append(struct)
|
||||||
|
|
||||||
def addUnionDecl(self, union): self.structsAndUnions.append(union)
|
def addUnionDecl(self, union): self.structsAndUnions.append(union)
|
||||||
|
|
||||||
def addUsingStmt(self, using): self.using.append(using)
|
def addUsingStmt(self, using): self.using.append(using)
|
||||||
|
|
||||||
def setProtocol(self, protocol): self.protocol = protocol
|
def setProtocol(self, protocol): self.protocol = protocol
|
||||||
|
|
||||||
|
|
||||||
class CxxInclude(Node):
|
class CxxInclude(Node):
|
||||||
def __init__(self, loc, cxxFile):
|
def __init__(self, loc, cxxFile):
|
||||||
Node.__init__(self, loc)
|
Node.__init__(self, loc)
|
||||||
self.file = cxxFile
|
self.file = cxxFile
|
||||||
|
|
||||||
|
|
||||||
class Include(Node):
|
class Include(Node):
|
||||||
def __init__(self, loc, type, name):
|
def __init__(self, loc, type, name):
|
||||||
Node.__init__(self, loc)
|
Node.__init__(self, loc)
|
||||||
@ -164,43 +175,61 @@ class Include(Node):
|
|||||||
suffix += 'h'
|
suffix += 'h'
|
||||||
self.file = "%s.%s" % (name, suffix)
|
self.file = "%s.%s" % (name, suffix)
|
||||||
|
|
||||||
|
|
||||||
class UsingStmt(Node):
|
class UsingStmt(Node):
|
||||||
def __init__(self, loc, cxxTypeSpec, cxxHeader=None, kind=None, refcounted=False):
|
def __init__(self, loc, cxxTypeSpec, cxxHeader=None, kind=None, refcounted=False):
|
||||||
Node.__init__(self, loc)
|
Node.__init__(self, loc)
|
||||||
assert not isinstance(cxxTypeSpec, str)
|
assert not isinstance(cxxTypeSpec, str)
|
||||||
assert cxxHeader is None or isinstance(cxxHeader, str);
|
assert cxxHeader is None or isinstance(cxxHeader, str)
|
||||||
assert kind is None or kind == 'class' or kind == 'struct'
|
assert kind is None or kind == 'class' or kind == 'struct'
|
||||||
self.type = cxxTypeSpec
|
self.type = cxxTypeSpec
|
||||||
self.header = cxxHeader
|
self.header = cxxHeader
|
||||||
self.kind = kind
|
self.kind = kind
|
||||||
self.refcounted = refcounted
|
self.refcounted = refcounted
|
||||||
|
|
||||||
def canBeForwardDeclared(self):
|
def canBeForwardDeclared(self):
|
||||||
return self.isClass() or self.isStruct()
|
return self.isClass() or self.isStruct()
|
||||||
|
|
||||||
def isClass(self):
|
def isClass(self):
|
||||||
return self.kind == 'class'
|
return self.kind == 'class'
|
||||||
|
|
||||||
def isStruct(self):
|
def isStruct(self):
|
||||||
return self.kind == 'struct'
|
return self.kind == 'struct'
|
||||||
|
|
||||||
def isRefcounted(self):
|
def isRefcounted(self):
|
||||||
return self.refcounted
|
return self.refcounted
|
||||||
|
|
||||||
# "singletons"
|
# "singletons"
|
||||||
|
|
||||||
|
|
||||||
class PrettyPrinted:
|
class PrettyPrinted:
|
||||||
@classmethod
|
@classmethod
|
||||||
def __hash__(cls): return hash(cls.pretty)
|
def __hash__(cls): return hash(cls.pretty)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __str__(cls): return cls.pretty
|
def __str__(cls): return cls.pretty
|
||||||
|
|
||||||
|
|
||||||
class ASYNC(PrettyPrinted):
|
class ASYNC(PrettyPrinted):
|
||||||
pretty = 'async'
|
pretty = 'async'
|
||||||
|
|
||||||
|
|
||||||
class INTR(PrettyPrinted):
|
class INTR(PrettyPrinted):
|
||||||
pretty = 'intr'
|
pretty = 'intr'
|
||||||
|
|
||||||
|
|
||||||
class SYNC(PrettyPrinted):
|
class SYNC(PrettyPrinted):
|
||||||
pretty = 'sync'
|
pretty = 'sync'
|
||||||
|
|
||||||
|
|
||||||
class INOUT(PrettyPrinted):
|
class INOUT(PrettyPrinted):
|
||||||
pretty = 'inout'
|
pretty = 'inout'
|
||||||
|
|
||||||
|
|
||||||
class IN(PrettyPrinted):
|
class IN(PrettyPrinted):
|
||||||
pretty = 'in'
|
pretty = 'in'
|
||||||
|
|
||||||
|
|
||||||
class OUT(PrettyPrinted):
|
class OUT(PrettyPrinted):
|
||||||
pretty = 'out'
|
pretty = 'out'
|
||||||
|
|
||||||
@ -210,14 +239,16 @@ class Namespace(Node):
|
|||||||
Node.__init__(self, loc)
|
Node.__init__(self, loc)
|
||||||
self.name = namespace
|
self.name = namespace
|
||||||
|
|
||||||
|
|
||||||
class Protocol(NamespacedNode):
|
class Protocol(NamespacedNode):
|
||||||
def __init__(self, loc):
|
def __init__(self, loc):
|
||||||
NamespacedNode.__init__(self, loc)
|
NamespacedNode.__init__(self, loc)
|
||||||
self.sendSemantics = ASYNC
|
self.sendSemantics = ASYNC
|
||||||
self.nested = NOT_NESTED
|
self.nested = NOT_NESTED
|
||||||
self.managers = [ ]
|
self.managers = []
|
||||||
self.managesStmts = [ ]
|
self.managesStmts = []
|
||||||
self.messageDecls = [ ]
|
self.messageDecls = []
|
||||||
|
|
||||||
|
|
||||||
class StructField(Node):
|
class StructField(Node):
|
||||||
def __init__(self, loc, type, name):
|
def __init__(self, loc, type, name):
|
||||||
@ -225,26 +256,31 @@ class StructField(Node):
|
|||||||
self.typespec = type
|
self.typespec = type
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
|
|
||||||
class StructDecl(NamespacedNode):
|
class StructDecl(NamespacedNode):
|
||||||
def __init__(self, loc, name, fields):
|
def __init__(self, loc, name, fields):
|
||||||
NamespacedNode.__init__(self, loc, name)
|
NamespacedNode.__init__(self, loc, name)
|
||||||
self.fields = fields
|
self.fields = fields
|
||||||
|
|
||||||
|
|
||||||
class UnionDecl(NamespacedNode):
|
class UnionDecl(NamespacedNode):
|
||||||
def __init__(self, loc, name, components):
|
def __init__(self, loc, name, components):
|
||||||
NamespacedNode.__init__(self, loc, name)
|
NamespacedNode.__init__(self, loc, name)
|
||||||
self.components = components
|
self.components = components
|
||||||
|
|
||||||
|
|
||||||
class Manager(Node):
|
class Manager(Node):
|
||||||
def __init__(self, loc, managerName):
|
def __init__(self, loc, managerName):
|
||||||
Node.__init__(self, loc)
|
Node.__init__(self, loc)
|
||||||
self.name = managerName
|
self.name = managerName
|
||||||
|
|
||||||
|
|
||||||
class ManagesStmt(Node):
|
class ManagesStmt(Node):
|
||||||
def __init__(self, loc, managedName):
|
def __init__(self, loc, managedName):
|
||||||
Node.__init__(self, loc)
|
Node.__init__(self, loc)
|
||||||
self.name = managedName
|
self.name = managedName
|
||||||
|
|
||||||
|
|
||||||
class MessageDecl(Node):
|
class MessageDecl(Node):
|
||||||
def __init__(self, loc):
|
def __init__(self, loc):
|
||||||
Node.__init__(self, loc)
|
Node.__init__(self, loc)
|
||||||
@ -253,8 +289,8 @@ class MessageDecl(Node):
|
|||||||
self.nested = NOT_NESTED
|
self.nested = NOT_NESTED
|
||||||
self.prio = NORMAL_PRIORITY
|
self.prio = NORMAL_PRIORITY
|
||||||
self.direction = None
|
self.direction = None
|
||||||
self.inParams = [ ]
|
self.inParams = []
|
||||||
self.outParams = [ ]
|
self.outParams = []
|
||||||
self.compress = ''
|
self.compress = ''
|
||||||
self.verify = ''
|
self.verify = ''
|
||||||
|
|
||||||
@ -271,7 +307,8 @@ class MessageDecl(Node):
|
|||||||
elif modifier == 'verify':
|
elif modifier == 'verify':
|
||||||
self.verify = modifier
|
self.verify = modifier
|
||||||
elif modifier != '':
|
elif modifier != '':
|
||||||
raise Exception, "Unexpected message modifier `%s'"% modifier
|
raise Exception("Unexpected message modifier `%s'" % modifier)
|
||||||
|
|
||||||
|
|
||||||
class Param(Node):
|
class Param(Node):
|
||||||
def __init__(self, loc, typespec, name):
|
def __init__(self, loc, typespec, name):
|
||||||
@ -279,21 +316,25 @@ class Param(Node):
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.typespec = typespec
|
self.typespec = typespec
|
||||||
|
|
||||||
|
|
||||||
class TypeSpec(Node):
|
class TypeSpec(Node):
|
||||||
def __init__(self, loc, spec):
|
def __init__(self, loc, spec):
|
||||||
Node.__init__(self, loc)
|
Node.__init__(self, loc)
|
||||||
self.spec = spec # QualifiedId
|
self.spec = spec # QualifiedId
|
||||||
self.array = 0 # bool
|
self.array = 0 # bool
|
||||||
self.nullable = 0 # bool
|
self.nullable = 0 # bool
|
||||||
|
|
||||||
def basename(self):
|
def basename(self):
|
||||||
return self.spec.baseid
|
return self.spec.baseid
|
||||||
|
|
||||||
def __str__(self): return str(self.spec)
|
def __str__(self): return str(self.spec)
|
||||||
|
|
||||||
|
|
||||||
class QualifiedId: # FIXME inherit from node?
|
class QualifiedId: # FIXME inherit from node?
|
||||||
def __init__(self, loc, baseid, quals=[ ]):
|
def __init__(self, loc, baseid, quals=[]):
|
||||||
assert isinstance(baseid, str)
|
assert isinstance(baseid, str)
|
||||||
for qual in quals: assert isinstance(qual, str)
|
for qual in quals:
|
||||||
|
assert isinstance(qual, str)
|
||||||
|
|
||||||
self.loc = loc
|
self.loc = loc
|
||||||
self.baseid = baseid
|
self.baseid = baseid
|
||||||
@ -306,9 +347,11 @@ class QualifiedId: # FIXME inherit from node?
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
if 0 == len(self.quals):
|
if 0 == len(self.quals):
|
||||||
return self.baseid
|
return self.baseid
|
||||||
return '::'.join(self.quals) +'::'+ self.baseid
|
return '::'.join(self.quals) + '::' + self.baseid
|
||||||
|
|
||||||
# added by type checking passes
|
# added by type checking passes
|
||||||
|
|
||||||
|
|
||||||
class Decl(Node):
|
class Decl(Node):
|
||||||
def __init__(self, loc):
|
def __init__(self, loc):
|
||||||
Node.__init__(self, loc)
|
Node.__init__(self, loc)
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
import os, sys
|
import sys
|
||||||
|
|
||||||
from ipdl.ast import Visitor
|
from ipdl.ast import Visitor
|
||||||
|
|
||||||
|
|
||||||
class CodePrinter:
|
class CodePrinter:
|
||||||
def __init__(self, outf=sys.stdout, indentCols=4):
|
def __init__(self, outf=sys.stdout, indentCols=4):
|
||||||
self.outf = outf
|
self.outf = outf
|
||||||
@ -16,19 +17,20 @@ class CodePrinter:
|
|||||||
self.outf.write(str)
|
self.outf.write(str)
|
||||||
|
|
||||||
def printdent(self, str=''):
|
def printdent(self, str=''):
|
||||||
self.write((' '* self.col) + str)
|
self.write((' ' * self.col) + str)
|
||||||
|
|
||||||
def println(self, str=''):
|
def println(self, str=''):
|
||||||
self.write(str +'\n')
|
self.write(str + '\n')
|
||||||
|
|
||||||
def printdentln(self, str):
|
def printdentln(self, str):
|
||||||
self.write((' '* self.col) + str +'\n')
|
self.write((' ' * self.col) + str + '\n')
|
||||||
|
|
||||||
def indent(self): self.col += self.indentCols
|
def indent(self): self.col += self.indentCols
|
||||||
|
|
||||||
def dedent(self): self.col -= self.indentCols
|
def dedent(self): self.col -= self.indentCols
|
||||||
|
|
||||||
|
|
||||||
##-----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
class IPDLCodeGen(CodePrinter, Visitor):
|
class IPDLCodeGen(CodePrinter, Visitor):
|
||||||
'''Spits back out equivalent IPDL to the code that generated this.
|
'''Spits back out equivalent IPDL to the code that generated this.
|
||||||
Also known as pretty-printing.'''
|
Also known as pretty-printing.'''
|
||||||
@ -40,13 +42,13 @@ Also known as pretty-printing.'''
|
|||||||
def visitTranslationUnit(self, tu):
|
def visitTranslationUnit(self, tu):
|
||||||
self.printed.add(tu.filename)
|
self.printed.add(tu.filename)
|
||||||
self.println('//\n// Automatically generated by ipdlc\n//')
|
self.println('//\n// Automatically generated by ipdlc\n//')
|
||||||
CodeGen.visitTranslationUnit(self, tu)
|
CodeGen.visitTranslationUnit(self, tu) # NOQA: F821
|
||||||
|
|
||||||
def visitCxxInclude(self, inc):
|
def visitCxxInclude(self, inc):
|
||||||
self.println('include "'+ inc.file +'";')
|
self.println('include "' + inc.file + '";')
|
||||||
|
|
||||||
def visitProtocolInclude(self, inc):
|
def visitProtocolInclude(self, inc):
|
||||||
self.println('include protocol "'+ inc.file +'";')
|
self.println('include protocol "' + inc.file + '";')
|
||||||
if inc.tu.filename not in self.printed:
|
if inc.tu.filename not in self.printed:
|
||||||
self.println('/* Included file:')
|
self.println('/* Included file:')
|
||||||
IPDLCodeGen(outf=self.outf, indentCols=self.indentCols,
|
IPDLCodeGen(outf=self.outf, indentCols=self.indentCols,
|
||||||
@ -56,33 +58,37 @@ Also known as pretty-printing.'''
|
|||||||
|
|
||||||
def visitProtocol(self, p):
|
def visitProtocol(self, p):
|
||||||
self.println()
|
self.println()
|
||||||
for namespace in p.namespaces: namespace.accept(self)
|
for namespace in p.namespaces:
|
||||||
|
namespace.accept(self)
|
||||||
|
|
||||||
self.println('%s protocol %s\n{'% (p.sendSemantics[0], p.name))
|
self.println('%s protocol %s\n{' % (p.sendSemantics[0], p.name))
|
||||||
self.indent()
|
self.indent()
|
||||||
|
|
||||||
for mgs in p.managesStmts:
|
for mgs in p.managesStmts:
|
||||||
mgs.accept(self)
|
mgs.accept(self)
|
||||||
if len(p.managesStmts): self.println()
|
if len(p.managesStmts):
|
||||||
|
self.println()
|
||||||
|
|
||||||
for msgDecl in p.messageDecls: msgDecl.accept(self)
|
for msgDecl in p.messageDecls:
|
||||||
|
msgDecl.accept(self)
|
||||||
self.println()
|
self.println()
|
||||||
|
|
||||||
self.dedent()
|
self.dedent()
|
||||||
self.println('}')
|
self.println('}')
|
||||||
self.write('}\n'* len(p.namespaces))
|
self.write('}\n' * len(p.namespaces))
|
||||||
|
|
||||||
def visitManagerStmt(self, mgr):
|
def visitManagerStmt(self, mgr):
|
||||||
self.printdentln('manager '+ mgr.name +';')
|
self.printdentln('manager ' + mgr.name + ';')
|
||||||
|
|
||||||
def visitManagesStmt(self, mgs):
|
def visitManagesStmt(self, mgs):
|
||||||
self.printdentln('manages '+ mgs.name +';')
|
self.printdentln('manages ' + mgs.name + ';')
|
||||||
|
|
||||||
def visitMessageDecl(self, msg):
|
def visitMessageDecl(self, msg):
|
||||||
self.printdent('%s %s %s('% (msg.sendSemantics[0], msg.direction[0], msg.name))
|
self.printdent('%s %s %s(' % (msg.sendSemantics[0], msg.direction[0], msg.name))
|
||||||
for i, inp in enumerate(msg.inParams):
|
for i, inp in enumerate(msg.inParams):
|
||||||
inp.accept(self)
|
inp.accept(self)
|
||||||
if i != (len(msg.inParams) - 1): self.write(', ')
|
if i != (len(msg.inParams) - 1):
|
||||||
|
self.write(', ')
|
||||||
self.write(')')
|
self.write(')')
|
||||||
if 0 == len(msg.outParams):
|
if 0 == len(msg.outParams):
|
||||||
self.println(';')
|
self.println(';')
|
||||||
@ -93,6 +99,7 @@ Also known as pretty-printing.'''
|
|||||||
self.printdent('returns (')
|
self.printdent('returns (')
|
||||||
for i, outp in enumerate(msg.outParams):
|
for i, outp in enumerate(msg.outParams):
|
||||||
outp.accept(self)
|
outp.accept(self)
|
||||||
if i != (len(msg.outParams) - 1): self.write(', ')
|
if i != (len(msg.outParams) - 1):
|
||||||
|
self.write(', ')
|
||||||
self.println(');')
|
self.println(');')
|
||||||
self.dedent()
|
self.dedent()
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user