mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 06:43:32 +00:00
Merge fx-team to m-c a=merge
This commit is contained in:
commit
895e881439
@ -1766,3 +1766,10 @@ pref("browser.apps.URL", "https://marketplace.firefox.com/discovery/");
|
||||
|
||||
pref("browser.polaris.enabled", false);
|
||||
pref("privacy.trackingprotection.ui.enabled", false);
|
||||
|
||||
// Temporary pref to allow printing in e10s windows on some platforms.
|
||||
#ifdef UNIX_BUT_NOT_MAC
|
||||
pref("print.enable_e10s_testing", false);
|
||||
#else
|
||||
pref("print.enable_e10s_testing", true);
|
||||
#endif
|
||||
|
@ -28,7 +28,7 @@
|
||||
oncommand="MailIntegration.sendLinkForWindow(window.content);"/>
|
||||
|
||||
<command id="cmd_pageSetup" oncommand="PrintUtils.showPageSetup();"/>
|
||||
<command id="cmd_print" oncommand="PrintUtils.print();"/>
|
||||
<command id="cmd_print" oncommand="PrintUtils.print(window.gBrowser.selectedBrowser.contentWindowAsCPOW, window.gBrowser.selectedBrowser);"/>
|
||||
<command id="cmd_printPreview" oncommand="PrintUtils.printPreview(PrintPreviewListener);"/>
|
||||
<command id="cmd_close" oncommand="BrowserCloseTabOrWindow()"/>
|
||||
<command id="cmd_closeWindow" oncommand="BrowserTryToCloseWindow()"/>
|
||||
|
@ -1663,7 +1663,8 @@ function HandleAppCommandEvent(evt) {
|
||||
BrowserOpenFileWindow();
|
||||
break;
|
||||
case "Print":
|
||||
PrintUtils.print();
|
||||
PrintUtils.print(gBrowser.selectedBrowser.contentWindowAsCPOW,
|
||||
gBrowser.selectedBrowser);
|
||||
break;
|
||||
case "Save":
|
||||
saveDocument(window.content.document);
|
||||
|
@ -294,7 +294,8 @@ let LoopCallsInternal = {
|
||||
var callData = {
|
||||
contact: contact,
|
||||
callType: callType,
|
||||
callId: Math.floor((Math.random() * 10))
|
||||
// XXX Really we shouldn't be using random numbers, bug 1090209 will fix this.
|
||||
callId: Math.floor((Math.random() * 100000000))
|
||||
};
|
||||
|
||||
this._startCall(callData, "outgoing");
|
||||
|
@ -571,18 +571,17 @@
|
||||
background-color: rgba(0,0,0,.2)
|
||||
}
|
||||
|
||||
/* Force full height on all parents up to the video elements
|
||||
* this way we can ensure the aspect ratio and use height 100%
|
||||
* on the video element
|
||||
* */
|
||||
html, .fx-embedded, #main,
|
||||
.video-layout-wrapper,
|
||||
.conversation {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@media screen and (min-width:640px) {
|
||||
|
||||
/* Force full height on all parents up to the video elements
|
||||
* this way we can ensure the aspect ratio and use height 100%
|
||||
* on the video element
|
||||
* */
|
||||
html, body, #main,
|
||||
.video-layout-wrapper,
|
||||
.conversation {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.standalone .conversation-toolbar {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
|
@ -117,7 +117,7 @@ Tools.inspector = {
|
||||
},
|
||||
|
||||
isTargetSupported: function(target) {
|
||||
return !target.isAddon;
|
||||
return !target.isAddon && target.hasActor("inspector");
|
||||
},
|
||||
|
||||
build: function(iframeWindow, toolbox) {
|
||||
@ -199,7 +199,8 @@ Tools.styleEditor = {
|
||||
commands: "devtools/styleeditor/styleeditor-commands",
|
||||
|
||||
isTargetSupported: function(target) {
|
||||
return !target.isAddon;
|
||||
return !target.isAddon &&
|
||||
(target.hasActor("styleEditor") || target.hasActor("styleSheets"));
|
||||
},
|
||||
|
||||
build: function(iframeWindow, toolbox) {
|
||||
@ -267,7 +268,7 @@ Tools.jsprofiler = {
|
||||
isTargetSupported: function (target) {
|
||||
// Hide the profiler when debugging devices pre bug 1046394,
|
||||
// that don't expose profiler actor in content processes.
|
||||
return !target.isAddon && (!target.isApp || target.form.profilerActor);
|
||||
return !target.isAddon && target.hasActor("profiler");
|
||||
},
|
||||
|
||||
build: function (frame, target) {
|
||||
@ -291,9 +292,7 @@ Tools.performance = {
|
||||
inMenu: true,
|
||||
|
||||
isTargetSupported: function (target) {
|
||||
// Hide the profiler when debugging devices pre bug 1046394,
|
||||
// that don't expose profiler actor in content processes.
|
||||
return !target.isAddon && (!target.isApp || target.form.profilerActor);
|
||||
return !target.isAddon && target.hasActor("profiler");
|
||||
},
|
||||
|
||||
build: function (frame, target) {
|
||||
@ -338,8 +337,7 @@ Tools.netMonitor = {
|
||||
inMenu: true,
|
||||
|
||||
isTargetSupported: function(target) {
|
||||
let root = target.client.mainRoot;
|
||||
return !target.isAddon && (root.traits.networkMonitor || !target.isApp);
|
||||
return !target.isAddon && target.getTrait("networkMonitor");
|
||||
},
|
||||
|
||||
build: function(iframeWindow, toolbox) {
|
||||
|
@ -29,7 +29,7 @@ function test() {
|
||||
|
||||
is(container.childNodes[0].childNodes[0].getAttribute("type"), "duration",
|
||||
"The root node in the tree has a duration cell.");
|
||||
is(container.childNodes[0].childNodes[0].getAttribute("value"), "18",
|
||||
is(container.childNodes[0].childNodes[0].getAttribute("value"), "15",
|
||||
"The root node in the tree has the correct duration cell value.");
|
||||
|
||||
is(container.childNodes[0].childNodes[1].getAttribute("type"), "percentage",
|
||||
@ -49,7 +49,7 @@ function test() {
|
||||
|
||||
is(container.childNodes[0].childNodes[4].getAttribute("type"), "samples",
|
||||
"The root node in the tree has an samples cell.");
|
||||
is(container.childNodes[0].childNodes[4].getAttribute("value"), "3",
|
||||
is(container.childNodes[0].childNodes[4].getAttribute("value"), "4",
|
||||
"The root node in the tree has the correct samples cell value.");
|
||||
|
||||
is(container.childNodes[0].childNodes[5].getAttribute("type"), "function",
|
||||
@ -69,7 +69,7 @@ let gSamples = [{
|
||||
{ category: 32, location: "C (http://foo/bar/baz:56)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6,
|
||||
time: 5 + 1,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
@ -77,7 +77,15 @@ let gSamples = [{
|
||||
{ category: 64, location: "D (http://foo/bar/baz:78)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6 + 7,
|
||||
time: 5 + 1 + 2,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
{ category: 16, location: "B (http://foo/bar/baz:34)" },
|
||||
{ category: 64, location: "D (http://foo/bar/baz:78)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 1 + 2 + 7,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
|
@ -27,11 +27,11 @@ function test() {
|
||||
is(container.childNodes[0].className, "call-tree-item",
|
||||
"The root node in the tree has the correct class name.");
|
||||
|
||||
is($$dur(0).getAttribute("value"), "18",
|
||||
is($$dur(0).getAttribute("value"), "15",
|
||||
"The root's duration cell displays the correct value.");
|
||||
is($$perc(0).getAttribute("value"), "100%",
|
||||
"The root's percentage cell displays the correct value.");
|
||||
is($$sampl(0).getAttribute("value"), "3",
|
||||
is($$sampl(0).getAttribute("value"), "4",
|
||||
"The root's samples cell displays the correct value.");
|
||||
is($$fun(".call-tree-name")[0].getAttribute("value"), "(root)",
|
||||
"The root's function cell displays the correct name.");
|
||||
@ -53,11 +53,11 @@ function test() {
|
||||
is(container.childNodes[1].className, "call-tree-item",
|
||||
"The .A node in the tree has the correct class name.");
|
||||
|
||||
is($$dur(1).getAttribute("value"), "18",
|
||||
is($$dur(1).getAttribute("value"), "15",
|
||||
"The .A node's duration cell displays the correct value.");
|
||||
is($$perc(1).getAttribute("value"), "100%",
|
||||
"The .A node's percentage cell displays the correct value.");
|
||||
is($$sampl(1).getAttribute("value"), "3",
|
||||
is($$sampl(1).getAttribute("value"), "4",
|
||||
"The .A node's samples cell displays the correct value.");
|
||||
is($$fun(".call-tree-name")[1].getAttribute("value"), "A",
|
||||
"The .A node's function cell displays the correct name.");
|
||||
@ -82,11 +82,11 @@ function test() {
|
||||
is(container.childNodes[3].className, "call-tree-item",
|
||||
"The .E node in the tree has the correct class name.");
|
||||
|
||||
is($$dur(2).getAttribute("value"), "11",
|
||||
is($$dur(2).getAttribute("value"), "8",
|
||||
"The .A.B node's duration cell displays the correct value.");
|
||||
is($$perc(2).getAttribute("value"), "66.66%",
|
||||
is($$perc(2).getAttribute("value"), "75%",
|
||||
"The .A.B node's percentage cell displays the correct value.");
|
||||
is($$sampl(2).getAttribute("value"), "2",
|
||||
is($$sampl(2).getAttribute("value"), "3",
|
||||
"The .A.B node's samples cell displays the correct value.");
|
||||
is($$fun(".call-tree-name")[2].getAttribute("value"), "B",
|
||||
"The .A.B node's function cell displays the correct name.");
|
||||
@ -103,7 +103,7 @@ function test() {
|
||||
|
||||
is($$dur(3).getAttribute("value"), "7",
|
||||
"The .A.E node's duration cell displays the correct value.");
|
||||
is($$perc(3).getAttribute("value"), "33.33%",
|
||||
is($$perc(3).getAttribute("value"), "25%",
|
||||
"The .A.E node's percentage cell displays the correct value.");
|
||||
is($$sampl(3).getAttribute("value"), "1",
|
||||
"The .A.E node's samples cell displays the correct value.");
|
||||
@ -132,7 +132,7 @@ let gSamples = [{
|
||||
{ category: 32, location: "C (http://foo/bar/baz:56)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6,
|
||||
time: 5 + 1,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
@ -140,7 +140,15 @@ let gSamples = [{
|
||||
{ category: 64, location: "D (http://foo/bar/baz:78)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6 + 7,
|
||||
time: 5 + 1 + 2,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
{ category: 16, location: "B (http://foo/bar/baz:34)" },
|
||||
{ category: 64, location: "D (http://foo/bar/baz:78)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 1 + 2 + 7,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
|
@ -55,13 +55,13 @@ function test() {
|
||||
is($$name(6).getAttribute("value"), "F",
|
||||
"The .A.E.F node's function cell displays the correct name.");
|
||||
|
||||
is($$duration(0).getAttribute("value"), "18",
|
||||
is($$duration(0).getAttribute("value"), "15",
|
||||
"The root node's function cell displays the correct duration.");
|
||||
is($$duration(1).getAttribute("value"), "18",
|
||||
is($$duration(1).getAttribute("value"), "15",
|
||||
"The .A node's function cell displays the correct duration.");
|
||||
is($$duration(2).getAttribute("value"), "11",
|
||||
is($$duration(2).getAttribute("value"), "8",
|
||||
"The .A.B node's function cell displays the correct duration.");
|
||||
is($$duration(3).getAttribute("value"), "6",
|
||||
is($$duration(3).getAttribute("value"), "3",
|
||||
"The .A.B.D node's function cell displays the correct duration.");
|
||||
is($$duration(4).getAttribute("value"), "5",
|
||||
"The .A.B.C node's function cell displays the correct duration.");
|
||||
@ -82,7 +82,7 @@ let gSamples = [{
|
||||
{ category: 32, location: "C (http://foo/bar/baz:56)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6,
|
||||
time: 5 + 1,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
@ -90,7 +90,15 @@ let gSamples = [{
|
||||
{ category: 64, location: "D (http://foo/bar/baz:78)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6 + 7,
|
||||
time: 5 + 1 + 2,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
{ category: 16, location: "B (http://foo/bar/baz:34)" },
|
||||
{ category: 64, location: "D (http://foo/bar/baz:78)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 1 + 2 + 7,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
|
@ -29,35 +29,35 @@ function test() {
|
||||
|
||||
let A = treeRoot.getChild();
|
||||
let B = A.getChild();
|
||||
let C = B.getChild();
|
||||
let D = B.getChild();
|
||||
|
||||
is(C.target.getAttribute("origin"), "chrome",
|
||||
"The .A.B.C node's 'origin' attribute is correct.");
|
||||
is(C.target.getAttribute("category"), "gc",
|
||||
"The .A.B.C node's 'category' attribute is correct.");
|
||||
is(C.target.getAttribute("tooltiptext"), "D (http://foo/bar/baz:78)",
|
||||
"The .A.B.C node's 'tooltiptext' attribute is correct.");
|
||||
is(D.target.getAttribute("origin"), "chrome",
|
||||
"The .A.B.D node's 'origin' attribute is correct.");
|
||||
is(D.target.getAttribute("category"), "gc",
|
||||
"The .A.B.D node's 'category' attribute is correct.");
|
||||
is(D.target.getAttribute("tooltiptext"), "D (http://foo/bar/baz:78)",
|
||||
"The .A.B.D node's 'tooltiptext' attribute is correct.");
|
||||
ok(!A.target.querySelector(".call-tree-zoom").hidden,
|
||||
"The .A.B.C node's zoom button cell should not be hidden.");
|
||||
"The .A.B.D node's zoom button cell should not be hidden.");
|
||||
ok(!A.target.querySelector(".call-tree-category").hidden,
|
||||
"The .A.B.C node's category label cell should not be hidden.");
|
||||
"The .A.B.D node's category label cell should not be hidden.");
|
||||
|
||||
is(C.target.childNodes.length, 6,
|
||||
is(D.target.childNodes.length, 6,
|
||||
"The number of columns displayed for tree items is correct.");
|
||||
is(C.target.childNodes[0].getAttribute("type"), "duration",
|
||||
is(D.target.childNodes[0].getAttribute("type"), "duration",
|
||||
"The first column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[1].getAttribute("type"), "percentage",
|
||||
is(D.target.childNodes[1].getAttribute("type"), "percentage",
|
||||
"The third column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[2].getAttribute("type"), "self-duration",
|
||||
is(D.target.childNodes[2].getAttribute("type"), "self-duration",
|
||||
"The second column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[3].getAttribute("type"), "self-percentage",
|
||||
is(D.target.childNodes[3].getAttribute("type"), "self-percentage",
|
||||
"The fourth column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[4].getAttribute("type"), "samples",
|
||||
is(D.target.childNodes[4].getAttribute("type"), "samples",
|
||||
"The fifth column displayed for tree items is correct.");
|
||||
is(C.target.childNodes[5].getAttribute("type"), "function",
|
||||
is(D.target.childNodes[5].getAttribute("type"), "function",
|
||||
"The sixth column displayed for tree items is correct.");
|
||||
|
||||
let functionCell = C.target.childNodes[5];
|
||||
let functionCell = D.target.childNodes[5];
|
||||
|
||||
is(functionCell.childNodes.length, 8,
|
||||
"The number of columns displayed for function cells is correct.");
|
||||
@ -90,7 +90,7 @@ let gSamples = [{
|
||||
{ category: 32, location: "C (http://foo/bar/baz:56)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6,
|
||||
time: 5 + 1,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
@ -98,7 +98,15 @@ let gSamples = [{
|
||||
{ category: 64, location: "D (http://foo/bar/baz:78)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6 + 7,
|
||||
time: 5 + 1 + 2,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
{ category: 16, location: "B (http://foo/bar/baz:34)" },
|
||||
{ category: 64, location: "D (http://foo/bar/baz:78)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 1 + 2 + 7,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
|
@ -40,7 +40,7 @@ let gSamples = [{
|
||||
{ category: 32, location: "C (http://foo/bar/baz:56)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6,
|
||||
time: 5 + 1,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
@ -48,7 +48,15 @@ let gSamples = [{
|
||||
{ category: 64, location: "D (http://foo/bar/baz:78)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6 + 7,
|
||||
time: 5 + 1 + 2,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
{ category: 16, location: "B (http://foo/bar/baz:34)" },
|
||||
{ category: 64, location: "D (http://foo/bar/baz:78)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 1 + 2 + 7,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
|
@ -18,19 +18,19 @@ let test = Task.async(function*() {
|
||||
|
||||
let A = treeRoot.getChild();
|
||||
let B = A.getChild();
|
||||
let C = B.getChild();
|
||||
let D = B.getChild();
|
||||
|
||||
let receivedLinkEvent = treeRoot.once("link");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, C.target.querySelector(".call-tree-url"));
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, D.target.querySelector(".call-tree-url"));
|
||||
|
||||
let eventItem = yield receivedLinkEvent;
|
||||
is(eventItem, C, "The 'link' event target is correct.");
|
||||
is(eventItem, D, "The 'link' event target is correct.");
|
||||
|
||||
let receivedZoomEvent = treeRoot.once("zoom");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, C.target.querySelector(".call-tree-zoom"));
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, D.target.querySelector(".call-tree-zoom"));
|
||||
|
||||
eventItem = yield receivedZoomEvent;
|
||||
is(eventItem, C, "The 'zoom' event target is correct.");
|
||||
is(eventItem, D, "The 'zoom' event target is correct.");
|
||||
|
||||
finish();
|
||||
});
|
||||
@ -44,7 +44,7 @@ let gSamples = [{
|
||||
{ category: 32, location: "C (http://foo/bar/baz:56)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6,
|
||||
time: 5 + 1,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
@ -52,7 +52,15 @@ let gSamples = [{
|
||||
{ category: 64, location: "D (http://foo/bar/baz:78)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6 + 7,
|
||||
time: 5 + 1 + 2,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
{ category: 16, location: "B (http://foo/bar/baz:34)" },
|
||||
{ category: 64, location: "D (http://foo/bar/baz:78)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 1 + 2 + 7,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
|
@ -19,18 +19,18 @@ function test() {
|
||||
|
||||
let A = treeRoot.getChild();
|
||||
let B = A.getChild();
|
||||
let C = B.getChild();
|
||||
let D = B.getChild();
|
||||
|
||||
is(C.root, treeRoot,
|
||||
"The .A.B.C node has the correct root.");
|
||||
is(C.parent, B,
|
||||
"The .A.B.C node has the correct parent.");
|
||||
is(C.level, 3,
|
||||
"The .A.B.C node has the correct level.");
|
||||
is(C.target.className, "call-tree-item",
|
||||
"The .A.B.C node has the correct target node.");
|
||||
is(C.container.id, "call-tree-container",
|
||||
"The .A.B.C node has the correct container node.");
|
||||
is(D.root, treeRoot,
|
||||
"The .A.B.D node has the correct root.");
|
||||
is(D.parent, B,
|
||||
"The .A.B.D node has the correct parent.");
|
||||
is(D.level, 3,
|
||||
"The .A.B.D node has the correct level.");
|
||||
is(D.target.className, "call-tree-item",
|
||||
"The .A.B.D node has the correct target node.");
|
||||
is(D.container.id, "call-tree-container",
|
||||
"The .A.B.D node has the correct container node.");
|
||||
|
||||
finish();
|
||||
}
|
||||
@ -44,7 +44,7 @@ let gSamples = [{
|
||||
{ category: 32, location: "C (http://foo/bar/baz:56)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6,
|
||||
time: 5 + 1,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
@ -52,7 +52,15 @@ let gSamples = [{
|
||||
{ category: 64, location: "D (http://foo/bar/baz:78)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 6 + 7,
|
||||
time: 5 + 1 + 2,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
{ category: 16, location: "B (http://foo/bar/baz:34)" },
|
||||
{ category: 64, location: "D (http://foo/bar/baz:78)" }
|
||||
]
|
||||
}, {
|
||||
time: 5 + 1 + 2 + 7,
|
||||
frames: [
|
||||
{ category: 8, location: "(root)" },
|
||||
{ category: 8, location: "A (http://foo/bar/baz:12)" },
|
||||
|
@ -174,8 +174,8 @@ CallView.prototype = Heritage.extend(AbstractTreeItem.prototype, {
|
||||
}));
|
||||
}
|
||||
|
||||
// Sort the "callees" asc. by duration, before inserting them in the tree.
|
||||
children.sort((a, b) => a.frame.duration < b.frame.duration ? 1 : -1);
|
||||
// Sort the "callees" asc. by samples, before inserting them in the tree.
|
||||
children.sort((a, b) => a.frame.samples < b.frame.samples ? 1 : -1);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -273,12 +273,14 @@ this.ContentSearch = {
|
||||
}),
|
||||
|
||||
_onMessageAddFormHistoryEntry: function (msg, entry) {
|
||||
// There are some tests that use about:home and newtab that trigger a search
|
||||
// and then immediately close the tab. In those cases, the browser may have
|
||||
// been destroyed by the time we receive this message, and as a result
|
||||
// contentWindow is undefined.
|
||||
if (!msg.target.contentWindow ||
|
||||
PrivateBrowsingUtils.isBrowserPrivate(msg.target)) {
|
||||
let isPrivate = true;
|
||||
try {
|
||||
// isBrowserPrivate assumes that the passed-in browser has all the normal
|
||||
// properties, which won't be true if the browser has been destroyed.
|
||||
// That may be the case here due to the asynchronous nature of messaging.
|
||||
isPrivate = PrivateBrowsingUtils.isBrowserPrivate(msg.target);
|
||||
} catch (err) {}
|
||||
if (isPrivate || entry === "") {
|
||||
return Promise.resolve();
|
||||
}
|
||||
let browserData = this._suggestionDataForBrowser(msg.target, true);
|
||||
|
@ -175,6 +175,7 @@ using namespace mozilla::dom::mobileconnection;
|
||||
using namespace mozilla::dom::mobilemessage;
|
||||
using namespace mozilla::dom::telephony;
|
||||
using namespace mozilla::dom::voicemail;
|
||||
using namespace mozilla::embedding;
|
||||
using namespace mozilla::hal_sandbox;
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::layers;
|
||||
@ -1391,6 +1392,24 @@ ContentChild::DeallocPNeckoChild(PNeckoChild* necko)
|
||||
return true;
|
||||
}
|
||||
|
||||
PPrintingChild*
|
||||
ContentChild::AllocPPrintingChild()
|
||||
{
|
||||
// The ContentParent should never attempt to allocate the
|
||||
// nsPrintingPromptServiceProxy, which implements PPrintingChild. Instead,
|
||||
// the nsPrintingPromptServiceProxy service is requested and instantiated
|
||||
// via XPCOM, and the constructor of nsPrintingPromptServiceProxy sets up
|
||||
// the IPC connection.
|
||||
NS_NOTREACHED("Should never get here!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::DeallocPPrintingChild(PPrintingChild* printing)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
PScreenManagerChild*
|
||||
ContentChild::AllocPScreenManagerChild(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
|
@ -207,6 +207,9 @@ public:
|
||||
virtual PNeckoChild* AllocPNeckoChild() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPNeckoChild(PNeckoChild*) MOZ_OVERRIDE;
|
||||
|
||||
virtual PPrintingChild* AllocPPrintingChild() MOZ_OVERRIDE;
|
||||
virtual bool DeallocPPrintingChild(PPrintingChild*) MOZ_OVERRIDE;
|
||||
|
||||
virtual PScreenManagerChild*
|
||||
AllocPScreenManagerChild(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
|
@ -57,6 +57,7 @@
|
||||
#include "mozilla/dom/telephony/TelephonyParent.h"
|
||||
#include "mozilla/dom/time/DateCacheCleaner.h"
|
||||
#include "mozilla/dom/voicemail/VoicemailParent.h"
|
||||
#include "mozilla/embedding/printingui/PrintingParent.h"
|
||||
#include "mozilla/hal_sandbox/PHalParent.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/BackgroundParent.h"
|
||||
@ -208,6 +209,7 @@ using namespace mozilla::dom::mobileconnection;
|
||||
using namespace mozilla::dom::mobilemessage;
|
||||
using namespace mozilla::dom::telephony;
|
||||
using namespace mozilla::dom::voicemail;
|
||||
using namespace mozilla::embedding;
|
||||
using namespace mozilla::hal;
|
||||
using namespace mozilla::ipc;
|
||||
using namespace mozilla::layers;
|
||||
@ -3116,6 +3118,25 @@ ContentParent::DeallocPNeckoParent(PNeckoParent* necko)
|
||||
return true;
|
||||
}
|
||||
|
||||
PPrintingParent*
|
||||
ContentParent::AllocPPrintingParent()
|
||||
{
|
||||
return new PrintingParent();
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvPPrintingConstructor(PPrintingParent* aActor)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::DeallocPPrintingParent(PPrintingParent* printing)
|
||||
{
|
||||
delete printing;
|
||||
return true;
|
||||
}
|
||||
|
||||
PScreenManagerParent*
|
||||
ContentParent::AllocPScreenManagerParent(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
|
@ -245,6 +245,10 @@ public:
|
||||
return PContentParent::RecvPNeckoConstructor(aActor);
|
||||
}
|
||||
|
||||
virtual PPrintingParent* AllocPPrintingParent() MOZ_OVERRIDE;
|
||||
virtual bool RecvPPrintingConstructor(PPrintingParent* aActor) MOZ_OVERRIDE;
|
||||
virtual bool DeallocPPrintingParent(PPrintingParent* aActor) MOZ_OVERRIDE;
|
||||
|
||||
virtual PScreenManagerParent*
|
||||
AllocPScreenManagerParent(uint32_t* aNumberOfScreens,
|
||||
float* aSystemDefaultScale,
|
||||
|
@ -25,6 +25,7 @@ include protocol PImageBridge;
|
||||
include protocol PMemoryReportRequest;
|
||||
include protocol PMobileConnection;
|
||||
include protocol PNecko;
|
||||
include protocol PPrinting;
|
||||
include protocol PScreenManager;
|
||||
include protocol PSharedBufferManager;
|
||||
include protocol PSms;
|
||||
@ -349,6 +350,7 @@ prio(normal upto high) intr protocol PContent
|
||||
manages PMemoryReportRequest;
|
||||
manages PMobileConnection;
|
||||
manages PNecko;
|
||||
manages PPrinting;
|
||||
manages PScreenManager;
|
||||
manages PSms;
|
||||
manages PSpeechSynthesis;
|
||||
@ -553,6 +555,8 @@ parent:
|
||||
|
||||
PNecko();
|
||||
|
||||
PPrinting();
|
||||
|
||||
prio(high) sync PScreenManager()
|
||||
returns (uint32_t numberOfScreens,
|
||||
float systemDefaultScale,
|
||||
|
@ -110,6 +110,7 @@ LOCAL_INCLUDES += [
|
||||
'/dom/mobilemessage/ipc',
|
||||
'/dom/storage',
|
||||
'/editor/libeditor',
|
||||
'/embedding/components/printingui/ipc',
|
||||
'/extensions/cookie',
|
||||
'/extensions/spellcheck/src',
|
||||
'/hal/sandbox',
|
||||
|
@ -15,11 +15,13 @@ LOCAL_INCLUDES += [
|
||||
'../appstartup',
|
||||
'../commandhandler',
|
||||
'../find',
|
||||
'../printingui/ipc',
|
||||
'../webbrowserpersist',
|
||||
'../windowwatcher',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
|
||||
DEFINES['PROXY_PRINTING'] = 1
|
||||
LOCAL_INCLUDES += [
|
||||
'../printingui/win',
|
||||
]
|
||||
@ -29,7 +31,10 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_PDF_PRINTING']:
|
||||
DEFINES['PROXY_PRINTING'] = 1
|
||||
LOCAL_INCLUDES += [
|
||||
'../printingui/unixshared',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
#include "nsPrintingPromptService.h"
|
||||
#include "nsPrintingPromptServiceProxy.h"
|
||||
#endif
|
||||
|
||||
|
||||
@ -38,6 +39,9 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsBaseCommandController)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDialogParamBlock)
|
||||
#ifdef NS_PRINTING
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintingPromptService, Init)
|
||||
#ifdef PROXY_PRINTING
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintingPromptServiceProxy, Init)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -62,8 +66,16 @@ static const mozilla::Module::CIDEntry kEmbeddingCIDs[] = {
|
||||
#ifdef MOZ_XUL
|
||||
{ &kNS_DIALOGPARAMBLOCK_CID, false, nullptr, nsDialogParamBlockConstructor },
|
||||
#ifdef NS_PRINTING
|
||||
|
||||
#ifdef PROXY_PRINTING
|
||||
{ &kNS_PRINTINGPROMPTSERVICE_CID, false, nullptr, nsPrintingPromptServiceConstructor,
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_PRINTINGPROMPTSERVICE_CID, false, nullptr, nsPrintingPromptServiceProxyConstructor,
|
||||
mozilla::Module::CONTENT_PROCESS_ONLY },
|
||||
#else
|
||||
{ &kNS_PRINTINGPROMPTSERVICE_CID, false, nullptr, nsPrintingPromptServiceConstructor },
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
{ &kNS_WINDOWWATCHER_CID, false, nullptr, nsWindowWatcherConstructor },
|
||||
{ &kNS_FIND_CID, false, nullptr, nsFindConstructor },
|
||||
|
101
embedding/components/printingui/ipc/PPrinting.ipdl
Normal file
101
embedding/components/printingui/ipc/PPrinting.ipdl
Normal file
@ -0,0 +1,101 @@
|
||||
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PContent;
|
||||
include protocol PBrowser;
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
struct PrintData {
|
||||
int32_t startPageRange;
|
||||
int32_t endPageRange;
|
||||
double edgeTop;
|
||||
double edgeLeft;
|
||||
double edgeBottom;
|
||||
double edgeRight;
|
||||
double marginTop;
|
||||
double marginLeft;
|
||||
double marginBottom;
|
||||
double marginRight;
|
||||
double unwriteableMarginTop;
|
||||
double unwriteableMarginLeft;
|
||||
double unwriteableMarginBottom;
|
||||
double unwriteableMarginRight;
|
||||
double scaling;
|
||||
bool printBGColors;
|
||||
bool printBGImages;
|
||||
short printRange;
|
||||
nsString title;
|
||||
nsString docURL;
|
||||
nsString headerStrLeft;
|
||||
nsString headerStrCenter;
|
||||
nsString headerStrRight;
|
||||
nsString footerStrLeft;
|
||||
nsString footerStrCenter;
|
||||
nsString footerStrRight;
|
||||
|
||||
short howToEnableFrameUI;
|
||||
bool isCancelled;
|
||||
short printFrameTypeUsage;
|
||||
short printFrameType;
|
||||
bool printSilent;
|
||||
bool shrinkToFit;
|
||||
bool showPrintProgress;
|
||||
|
||||
nsString paperName;
|
||||
short paperSizeType;
|
||||
short paperData;
|
||||
double paperWidth;
|
||||
double paperHeight;
|
||||
short paperSizeUnit;
|
||||
nsString plexName;
|
||||
nsString colorspace;
|
||||
nsString resolutionName;
|
||||
bool downloadFonts;
|
||||
bool printReversed;
|
||||
bool printInColor;
|
||||
int32_t orientation;
|
||||
nsString printCommand;
|
||||
int32_t numCopies;
|
||||
nsString printerName;
|
||||
bool printToFile;
|
||||
nsString toFileName;
|
||||
short outputFormat;
|
||||
int32_t printPageDelay;
|
||||
int32_t resolution;
|
||||
int32_t duplex;
|
||||
bool isInitializedFromPrinter;
|
||||
bool isInitializedFromPrefs;
|
||||
bool persistMarginBoxSettings;
|
||||
|
||||
/* Windows-specific things */
|
||||
nsString driverName;
|
||||
nsString deviceName;
|
||||
bool isFramesetDocument;
|
||||
bool isFramesetFrameSelected;
|
||||
bool isIFrameSelected;
|
||||
bool isRangeSelection;
|
||||
|
||||
/* TODO: OS X specific things - specifically, an array of names for the
|
||||
* document to be supplied by nsIWebBrowserPrint::enumerateDocumentNames
|
||||
*/
|
||||
};
|
||||
|
||||
sync protocol PPrinting
|
||||
{
|
||||
manager PContent;
|
||||
|
||||
parent:
|
||||
sync ShowProgress(PBrowser browser, bool isForPrinting);
|
||||
sync ShowPrintDialog(PBrowser browser, PrintData settings)
|
||||
returns(PrintData modifiedSettings, bool success);
|
||||
|
||||
child:
|
||||
__delete__();
|
||||
};
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
143
embedding/components/printingui/ipc/PrintDataUtils.cpp
Normal file
143
embedding/components/printingui/ipc/PrintDataUtils.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "PrintDataUtils.h"
|
||||
#include "nsIPrintOptions.h"
|
||||
#include "nsIPrintSettings.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIWebBrowserPrint.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
/**
|
||||
* MockWebBrowserPrint is a mostly useless implementation of nsIWebBrowserPrint,
|
||||
* but wraps a PrintData so that it's able to return information to print
|
||||
* settings dialogs that need an nsIWebBrowserPrint to interrogate.
|
||||
*/
|
||||
|
||||
NS_IMPL_ISUPPORTS(MockWebBrowserPrint, nsIWebBrowserPrint);
|
||||
|
||||
MockWebBrowserPrint::MockWebBrowserPrint(PrintData aData)
|
||||
: mData(aData)
|
||||
{
|
||||
MOZ_COUNT_CTOR(MockWebBrowserPrint);
|
||||
}
|
||||
|
||||
MockWebBrowserPrint::~MockWebBrowserPrint()
|
||||
{
|
||||
MOZ_COUNT_DTOR(MockWebBrowserPrint);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetGlobalPrintSettings(nsIPrintSettings **aGlobalPrintSettings)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetCurrentPrintSettings(nsIPrintSettings **aCurrentPrintSettings)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetCurrentChildDOMWindow(nsIDOMWindow **aCurrentPrintSettings)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetDoingPrint(bool *aDoingPrint)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetDoingPrintPreview(bool *aDoingPrintPreview)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetIsFramesetDocument(bool *aIsFramesetDocument)
|
||||
{
|
||||
*aIsFramesetDocument = mData.isFramesetDocument();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetIsFramesetFrameSelected(bool *aIsFramesetFrameSelected)
|
||||
{
|
||||
*aIsFramesetFrameSelected = mData.isFramesetFrameSelected();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetIsIFrameSelected(bool *aIsIFrameSelected)
|
||||
{
|
||||
*aIsIFrameSelected = mData.isIFrameSelected();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetIsRangeSelection(bool *aIsRangeSelection)
|
||||
{
|
||||
*aIsRangeSelection = mData.isRangeSelection();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::GetPrintPreviewNumPages(int32_t *aPrintPreviewNumPages)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::Print(nsIPrintSettings* aThePrintSettings,
|
||||
nsIWebProgressListener* aWPListener)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::PrintPreview(nsIPrintSettings* aThePrintSettings,
|
||||
nsIDOMWindow* aChildDOMWin,
|
||||
nsIWebProgressListener* aWPListener)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::PrintPreviewNavigate(int16_t aNavType,
|
||||
int32_t aPageNum)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::Cancel()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::EnumerateDocumentNames(uint32_t* aCount,
|
||||
char16_t*** aResult)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MockWebBrowserPrint::ExitPrintPreview()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
39
embedding/components/printingui/ipc/PrintDataUtils.h
Normal file
39
embedding/components/printingui/ipc/PrintDataUtils.h
Normal file
@ -0,0 +1,39 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_embedding_PrintDataUtils_h
|
||||
#define mozilla_embedding_PrintDataUtils_h
|
||||
|
||||
#include "mozilla/embedding/PPrinting.h"
|
||||
#include "nsIWebBrowserPrint.h"
|
||||
|
||||
/**
|
||||
* nsIPrintSettings and nsIWebBrowserPrint information is sent back and forth
|
||||
* across PPrinting via the PrintData struct. These are utilities for
|
||||
* manipulating PrintData that can be used on either side of the communications
|
||||
* channel.
|
||||
*/
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
|
||||
class MockWebBrowserPrint MOZ_FINAL : public nsIWebBrowserPrint
|
||||
{
|
||||
public:
|
||||
MockWebBrowserPrint(PrintData aData);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIWEBBROWSERPRINT
|
||||
|
||||
private:
|
||||
~MockWebBrowserPrint();
|
||||
PrintData mData;
|
||||
};
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
150
embedding/components/printingui/ipc/PrintingParent.cpp
Normal file
150
embedding/components/printingui/ipc/PrintingParent.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "mozilla/dom/TabParent.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "nsIPrintProgressParams.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "PrintingParent.h"
|
||||
#include "nsIPrintOptions.h"
|
||||
#include "PrintDataUtils.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
bool
|
||||
PrintingParent::RecvShowProgress(PBrowserParent* parent,
|
||||
const bool& isForPrinting)
|
||||
{
|
||||
TabParent* tabParent = static_cast<TabParent*>(parent);
|
||||
if (!tabParent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<Element> frameElement = tabParent->GetOwnerElement();
|
||||
if (!frameElement) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> frame(do_QueryInterface(frameElement));
|
||||
if (!frame) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> parentWin = do_QueryInterface(frame->OwnerDoc()->GetWindow());
|
||||
if (!parentWin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrintingPromptService> pps(do_GetService("@mozilla.org/embedcomp/printingprompt-service;1"));
|
||||
|
||||
if (!pps) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWebProgressListener> printProgressListener;
|
||||
nsCOMPtr<nsIPrintProgressParams> printProgressParams;
|
||||
|
||||
// TODO: What do I do with this thing?
|
||||
bool doNotify = false;
|
||||
|
||||
pps->ShowProgress(parentWin, nullptr, nullptr, nullptr,
|
||||
isForPrinting,
|
||||
getter_AddRefs(printProgressListener),
|
||||
getter_AddRefs(printProgressParams),
|
||||
&doNotify);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PrintingParent::RecvShowPrintDialog(PBrowserParent* parent,
|
||||
const PrintData& data,
|
||||
PrintData* retVal,
|
||||
bool* success)
|
||||
{
|
||||
*success = false;
|
||||
|
||||
TabParent* tabParent = static_cast<TabParent*>(parent);
|
||||
if (!tabParent) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<Element> frameElement = tabParent->GetOwnerElement();
|
||||
if (!frameElement) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> frame(do_QueryInterface(frameElement));
|
||||
if (!frame) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMWindow> parentWin = do_QueryInterface(frame->OwnerDoc()->GetWindow());
|
||||
if (!parentWin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrintingPromptService> pps(do_GetService("@mozilla.org/embedcomp/printingprompt-service;1"));
|
||||
|
||||
if (!pps) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The initSettings we got can be wrapped using
|
||||
// PrintDataUtils' MockWebBrowserPrint, which implements enough of
|
||||
// nsIWebBrowserPrint to keep the dialogs happy.
|
||||
nsCOMPtr<nsIWebBrowserPrint> wbp = new MockWebBrowserPrint(data);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrintOptions> po = do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
|
||||
nsCOMPtr<nsIPrintSettings> settings;
|
||||
rv = po->CreatePrintSettings(getter_AddRefs(settings));
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
|
||||
rv = po->DeserializeToPrintSettings(data, settings);
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
|
||||
rv = pps->ShowPrintDialog(parentWin, wbp, settings);
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
|
||||
// And send it back.
|
||||
PrintData result;
|
||||
rv = po->SerializeToPrintData(settings, nullptr, &result);
|
||||
NS_ENSURE_SUCCESS(rv, true);
|
||||
|
||||
*retVal = result;
|
||||
*success = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PrintingParent::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
}
|
||||
|
||||
MOZ_IMPLICIT PrintingParent::PrintingParent()
|
||||
{
|
||||
MOZ_COUNT_CTOR(PrintingParent);
|
||||
}
|
||||
|
||||
MOZ_IMPLICIT PrintingParent::~PrintingParent()
|
||||
{
|
||||
MOZ_COUNT_DTOR(PrintingParent);
|
||||
}
|
||||
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
37
embedding/components/printingui/ipc/PrintingParent.h
Normal file
37
embedding/components/printingui/ipc/PrintingParent.h
Normal file
@ -0,0 +1,37 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set sw=4 ts=8 et tw=80 : */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_embedding_PrintingParent_h
|
||||
#define mozilla_embedding_PrintingParent_h
|
||||
|
||||
#include "mozilla/embedding/PPrintingParent.h"
|
||||
#include "mozilla/dom/PBrowserParent.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
class PrintingParent : public PPrintingParent
|
||||
{
|
||||
public:
|
||||
virtual bool
|
||||
RecvShowProgress(PBrowserParent* parent,
|
||||
const bool& isForPrinting);
|
||||
virtual bool
|
||||
RecvShowPrintDialog(PBrowserParent* parent,
|
||||
const PrintData& initSettings,
|
||||
PrintData* retVal,
|
||||
bool* success);
|
||||
|
||||
virtual void
|
||||
ActorDestroy(ActorDestroyReason aWhy);
|
||||
|
||||
MOZ_IMPLICIT PrintingParent();
|
||||
virtual ~PrintingParent();
|
||||
};
|
||||
} // namespace embedding
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
25
embedding/components/printingui/ipc/moz.build
Normal file
25
embedding/components/printingui/ipc/moz.build
Normal file
@ -0,0 +1,25 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXPORTS.mozilla.embedding.printingui += [
|
||||
'PrintingParent.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'nsPrintingPromptServiceProxy.cpp',
|
||||
'PrintDataUtils.cpp',
|
||||
'PrintingParent.cpp',
|
||||
]
|
||||
|
||||
IPDL_SOURCES += [
|
||||
'PPrinting.ipdl',
|
||||
]
|
||||
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
@ -0,0 +1,135 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/TabChild.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPrintingPromptServiceProxy.h"
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "PrintDataUtils.h"
|
||||
#include "nsPrintOptionsImpl.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::embedding;
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPrintingPromptServiceProxy, nsIPrintingPromptService)
|
||||
|
||||
nsPrintingPromptServiceProxy::nsPrintingPromptServiceProxy()
|
||||
{
|
||||
}
|
||||
|
||||
nsPrintingPromptServiceProxy::~nsPrintingPromptServiceProxy()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPrintingPromptServiceProxy::Init()
|
||||
{
|
||||
mozilla::unused << ContentChild::GetSingleton()->SendPPrintingConstructor(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptServiceProxy::ShowPrintDialog(nsIDOMWindow *parent,
|
||||
nsIWebBrowserPrint *webBrowserPrint,
|
||||
nsIPrintSettings *printSettings)
|
||||
{
|
||||
NS_ENSURE_ARG(parent);
|
||||
NS_ENSURE_ARG(webBrowserPrint);
|
||||
NS_ENSURE_ARG(printSettings);
|
||||
|
||||
// Get the root docshell owner of this nsIDOMWindow, which
|
||||
// should map to a TabChild, which we can then pass up to
|
||||
// the parent.
|
||||
nsCOMPtr<nsPIDOMWindow> pwin = do_QueryInterface(parent);
|
||||
NS_ENSURE_STATE(pwin);
|
||||
nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
|
||||
NS_ENSURE_STATE(docShell);
|
||||
nsCOMPtr<nsIDocShellTreeOwner> owner;
|
||||
nsresult rv = docShell->GetTreeOwner(getter_AddRefs(owner));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsITabChild> tabchild = do_GetInterface(owner);
|
||||
NS_ENSURE_STATE(tabchild);
|
||||
|
||||
TabChild* pBrowser = static_cast<TabChild*>(tabchild.get());
|
||||
|
||||
// Next, serialize the nsIWebBrowserPrint and nsIPrintSettings we were given.
|
||||
nsCOMPtr<nsIPrintOptions> po =
|
||||
do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PrintData inSettings;
|
||||
rv = po->SerializeToPrintData(printSettings, webBrowserPrint, &inSettings);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PrintData modifiedSettings;
|
||||
bool success;
|
||||
|
||||
mozilla::unused << SendShowPrintDialog(pBrowser, inSettings, &modifiedSettings, &success);
|
||||
|
||||
if (!success) {
|
||||
// Something failed in the parent.
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
rv = po->DeserializeToPrintSettings(modifiedSettings, printSettings);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptServiceProxy::ShowProgress(nsIDOMWindow* parent,
|
||||
nsIWebBrowserPrint* webBrowserPrint, // ok to be null
|
||||
nsIPrintSettings* printSettings, // ok to be null
|
||||
nsIObserver* openDialogObserver, // ok to be null
|
||||
bool isForPrinting,
|
||||
nsIWebProgressListener** webProgressListener,
|
||||
nsIPrintProgressParams** printProgressParams,
|
||||
bool* notifyOnOpen)
|
||||
{
|
||||
NS_ENSURE_ARG(parent);
|
||||
NS_ENSURE_ARG(webProgressListener);
|
||||
NS_ENSURE_ARG(printProgressParams);
|
||||
NS_ENSURE_ARG(notifyOnOpen);
|
||||
|
||||
// Get the root docshell owner of this nsIDOMWindow, which
|
||||
// should map to a TabChild, which we can then pass up to
|
||||
// the parent.
|
||||
nsCOMPtr<nsPIDOMWindow> pwin = do_QueryInterface(parent);
|
||||
NS_ENSURE_STATE(pwin);
|
||||
nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
|
||||
NS_ENSURE_STATE(docShell);
|
||||
nsCOMPtr<nsIDocShellTreeOwner> owner;
|
||||
nsresult rv = docShell->GetTreeOwner(getter_AddRefs(owner));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsITabChild> tabchild = do_GetInterface(owner);
|
||||
TabChild* pBrowser = static_cast<TabChild*>(tabchild.get());
|
||||
|
||||
mozilla::unused << SendShowProgress(pBrowser, isForPrinting);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptServiceProxy::ShowPageSetup(nsIDOMWindow *parent,
|
||||
nsIPrintSettings *printSettings,
|
||||
nsIObserver *aObs)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintingPromptServiceProxy::ShowPrinterProperties(nsIDOMWindow *parent,
|
||||
const char16_t *printerName,
|
||||
nsIPrintSettings *printSettings)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef __nsPrintingPromptServiceProxy_h
|
||||
#define __nsPrintingPromptServiceProxy_h
|
||||
|
||||
#include "nsIPrintingPromptService.h"
|
||||
#include "mozilla/embedding/PPrintingChild.h"
|
||||
|
||||
class nsPrintingPromptServiceProxy: public nsIPrintingPromptService,
|
||||
public mozilla::embedding::PPrintingChild
|
||||
{
|
||||
virtual ~nsPrintingPromptServiceProxy();
|
||||
|
||||
public:
|
||||
nsPrintingPromptServiceProxy();
|
||||
|
||||
nsresult Init();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPRINTINGPROMPTSERVICE
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -6,6 +6,8 @@
|
||||
|
||||
toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
|
||||
|
||||
DIRS += ['ipc']
|
||||
|
||||
if toolkit == 'windows':
|
||||
DIRS += ['win']
|
||||
elif toolkit == 'cocoa':
|
||||
|
@ -11,6 +11,10 @@ UNIFIED_SOURCES += [
|
||||
'nsPrintProgressParams.cpp',
|
||||
]
|
||||
|
||||
EXPORTS += [
|
||||
'nsPrintDialogUtil.h',
|
||||
]
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
@ -682,7 +682,7 @@ static UINT CALLBACK PrintHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM
|
||||
// This function assumes that aPrintName has already been converted from
|
||||
// unicode
|
||||
//
|
||||
static HGLOBAL CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, nsIPrintSettings* aPS)
|
||||
HGLOBAL CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, nsIPrintSettings* aPS)
|
||||
{
|
||||
HGLOBAL hGlobalDevMode = nullptr;
|
||||
|
||||
|
@ -9,4 +9,6 @@ nsresult NativeShowPrintDialog(HWND aHWnd,
|
||||
nsIWebBrowserPrint* aWebBrowserPrint,
|
||||
nsIPrintSettings* aPrintSettings);
|
||||
|
||||
HGLOBAL CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, nsIPrintSettings* aPS);
|
||||
|
||||
#endif /* nsFlyOwnDialog_h___ */
|
||||
|
@ -21,7 +21,6 @@ import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.DynamicToolbar.PinReason;
|
||||
import org.mozilla.gecko.DynamicToolbar.VisibilityTransition;
|
||||
import org.mozilla.gecko.GeckoProfileDirectories.NoMozillaDirectoryException;
|
||||
import org.mozilla.gecko.ReadingListHelper;
|
||||
import org.mozilla.gecko.animation.PropertyAnimator;
|
||||
import org.mozilla.gecko.animation.ViewHelper;
|
||||
import org.mozilla.gecko.db.BrowserContract.Combined;
|
||||
@ -52,6 +51,7 @@ import org.mozilla.gecko.home.HomePanelsManager;
|
||||
import org.mozilla.gecko.home.SearchEngine;
|
||||
import org.mozilla.gecko.menu.GeckoMenu;
|
||||
import org.mozilla.gecko.menu.GeckoMenuItem;
|
||||
import org.mozilla.gecko.mozglue.ContextUtils;
|
||||
import org.mozilla.gecko.preferences.ClearOnShutdownPref;
|
||||
import org.mozilla.gecko.preferences.GeckoPreferences;
|
||||
import org.mozilla.gecko.prompts.Prompt;
|
||||
@ -684,7 +684,7 @@ public class BrowserApp extends GeckoApp
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
final String args = StringUtils.getStringExtra(getIntent(), "args");
|
||||
final String args = ContextUtils.getStringExtra(getIntent(), "args");
|
||||
// If an external intent tries to start Fennec in guest mode, and it's not already
|
||||
// in guest mode, this will change modes before opening the url.
|
||||
// NOTE: OnResume is called twice sometimes when showing on the lock screen.
|
||||
@ -2666,12 +2666,12 @@ public class BrowserApp extends GeckoApp
|
||||
}
|
||||
|
||||
// Disable share menuitem for about:, chrome:, file:, and resource: URIs
|
||||
final boolean shareEnabled = RestrictedProfiles.isAllowed(RestrictedProfiles.Restriction.DISALLOW_SHARE);
|
||||
final boolean shareEnabled = RestrictedProfiles.isAllowed(this, RestrictedProfiles.Restriction.DISALLOW_SHARE);
|
||||
share.setVisible(shareEnabled);
|
||||
share.setEnabled(StringUtils.isShareableUrl(url) && shareEnabled);
|
||||
MenuUtils.safeSetEnabled(aMenu, R.id.apps, RestrictedProfiles.isAllowed(RestrictedProfiles.Restriction.DISALLOW_INSTALL_APPS));
|
||||
MenuUtils.safeSetEnabled(aMenu, R.id.addons, RestrictedProfiles.isAllowed(RestrictedProfiles.Restriction.DISALLOW_INSTALL_EXTENSION));
|
||||
MenuUtils.safeSetEnabled(aMenu, R.id.downloads, RestrictedProfiles.isAllowed(RestrictedProfiles.Restriction.DISALLOW_DOWNLOADS));
|
||||
MenuUtils.safeSetEnabled(aMenu, R.id.apps, RestrictedProfiles.isAllowed(this, RestrictedProfiles.Restriction.DISALLOW_INSTALL_APPS));
|
||||
MenuUtils.safeSetEnabled(aMenu, R.id.addons, RestrictedProfiles.isAllowed(this, RestrictedProfiles.Restriction.DISALLOW_INSTALL_EXTENSION));
|
||||
MenuUtils.safeSetEnabled(aMenu, R.id.downloads, RestrictedProfiles.isAllowed(this, RestrictedProfiles.Restriction.DISALLOW_DOWNLOADS));
|
||||
|
||||
// NOTE: Use MenuUtils.safeSetEnabled because some actions might
|
||||
// be on the BrowserToolbar context menu.
|
||||
|
@ -40,6 +40,8 @@ import org.mozilla.gecko.health.StubbedHealthRecorder;
|
||||
import org.mozilla.gecko.menu.GeckoMenu;
|
||||
import org.mozilla.gecko.menu.GeckoMenuInflater;
|
||||
import org.mozilla.gecko.menu.MenuPanel;
|
||||
import org.mozilla.gecko.mozglue.ContextUtils;
|
||||
import org.mozilla.gecko.mozglue.ContextUtils.SafeIntent;
|
||||
import org.mozilla.gecko.mozglue.GeckoLoader;
|
||||
import org.mozilla.gecko.preferences.ClearOnShutdownPref;
|
||||
import org.mozilla.gecko.preferences.GeckoPreferences;
|
||||
@ -55,7 +57,6 @@ import org.mozilla.gecko.util.HardwareUtils;
|
||||
import org.mozilla.gecko.util.NativeEventListener;
|
||||
import org.mozilla.gecko.util.NativeJSObject;
|
||||
import org.mozilla.gecko.util.PrefUtils;
|
||||
import org.mozilla.gecko.util.StringUtils;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.webapp.EventListener;
|
||||
import org.mozilla.gecko.webapp.UninstallListener;
|
||||
@ -1102,8 +1103,8 @@ public abstract class GeckoApp
|
||||
/**
|
||||
* Check and start the Java profiler if MOZ_PROFILER_STARTUP env var is specified.
|
||||
**/
|
||||
protected static void earlyStartJavaSampler(Intent intent) {
|
||||
String env = StringUtils.getStringExtra(intent, "env0");
|
||||
protected static void earlyStartJavaSampler(SafeIntent intent) {
|
||||
String env = intent.getStringExtra("env0");
|
||||
for (int i = 1; env != null; i++) {
|
||||
if (env.startsWith("MOZ_PROFILER_STARTUP=")) {
|
||||
if (!env.endsWith("=")) {
|
||||
@ -1123,8 +1124,7 @@ public abstract class GeckoApp
|
||||
* and other one-shot constructions.
|
||||
**/
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
GeckoAppShell.ensureCrashHandling();
|
||||
|
||||
// Enable Android Strict Mode for developers' local builds (the "default" channel).
|
||||
@ -1136,9 +1136,9 @@ public abstract class GeckoApp
|
||||
mJavaUiStartupTimer = new Telemetry.UptimeTimer("FENNEC_STARTUP_TIME_JAVAUI");
|
||||
mGeckoReadyStartupTimer = new Telemetry.UptimeTimer("FENNEC_STARTUP_TIME_GECKOREADY");
|
||||
|
||||
final Intent intent = getIntent();
|
||||
final SafeIntent intent = new SafeIntent(getIntent());
|
||||
final String action = intent.getAction();
|
||||
final String args = StringUtils.getStringExtra(intent, "args");
|
||||
final String args = intent.getStringExtra("args");
|
||||
|
||||
earlyStartJavaSampler(intent);
|
||||
|
||||
@ -1254,7 +1254,7 @@ public abstract class GeckoApp
|
||||
}, 1000 * 5 /* 5 seconds */);
|
||||
}
|
||||
|
||||
Bundle stateBundle = getIntent().getBundleExtra(EXTRA_STATE_BUNDLE);
|
||||
Bundle stateBundle = ContextUtils.getBundleExtra(getIntent(), EXTRA_STATE_BUNDLE);
|
||||
if (stateBundle != null) {
|
||||
// Use the state bundle if it was given as an intent extra. This is
|
||||
// only intended to be used internally via Robocop, so a boolean
|
||||
@ -1458,18 +1458,21 @@ public abstract class GeckoApp
|
||||
private void initialize() {
|
||||
mInitialized = true;
|
||||
|
||||
Intent intent = getIntent();
|
||||
String action = intent.getAction();
|
||||
final SafeIntent intent = new SafeIntent(getIntent());
|
||||
final String action = intent.getAction();
|
||||
|
||||
String passedUri = null;
|
||||
final String uri = getURIFromIntent(intent);
|
||||
|
||||
final String passedUri;
|
||||
if (!TextUtils.isEmpty(uri)) {
|
||||
passedUri = uri;
|
||||
} else {
|
||||
passedUri = null;
|
||||
}
|
||||
|
||||
final boolean isExternalURL = passedUri != null &&
|
||||
!AboutPages.isAboutHome(passedUri);
|
||||
StartupAction startupAction;
|
||||
final StartupAction startupAction;
|
||||
if (isExternalURL) {
|
||||
startupAction = StartupAction.URL;
|
||||
} else {
|
||||
@ -1532,7 +1535,7 @@ public abstract class GeckoApp
|
||||
if (ACTION_LAUNCH_SETTINGS.equals(action)) {
|
||||
Intent settingsIntent = new Intent(GeckoApp.this, GeckoPreferences.class);
|
||||
// Copy extras.
|
||||
settingsIntent.putExtras(intent);
|
||||
settingsIntent.putExtras(intent.getUnsafe());
|
||||
startActivity(settingsIntent);
|
||||
}
|
||||
|
||||
@ -1732,7 +1735,7 @@ public abstract class GeckoApp
|
||||
}
|
||||
|
||||
private boolean getRestartFromIntent() {
|
||||
return getIntent().getBooleanExtra("didRestart", false);
|
||||
return ContextUtils.getBooleanExtra(getIntent(), "didRestart", false);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1798,7 +1801,7 @@ public abstract class GeckoApp
|
||||
AppConstants.USER_AGENT_FENNEC_MOBILE;
|
||||
}
|
||||
|
||||
private void processAlertCallback(Intent intent) {
|
||||
private void processAlertCallback(SafeIntent intent) {
|
||||
String alertName = "";
|
||||
String alertCookie = "";
|
||||
Uri data = intent.getData();
|
||||
@ -1814,7 +1817,9 @@ public abstract class GeckoApp
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent) {
|
||||
protected void onNewIntent(Intent externalIntent) {
|
||||
final SafeIntent intent = new SafeIntent(externalIntent);
|
||||
|
||||
if (GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoExiting)) {
|
||||
// We're exiting and shouldn't try to do anything else. In the case
|
||||
// where we are hung while exiting, we should force the process to exit.
|
||||
@ -1825,7 +1830,7 @@ public abstract class GeckoApp
|
||||
// if we were previously OOM killed, we can end up here when launching
|
||||
// from external shortcuts, so set this as the intent for initialization
|
||||
if (!mInitialized) {
|
||||
setIntent(intent);
|
||||
setIntent(externalIntent);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1859,7 +1864,7 @@ public abstract class GeckoApp
|
||||
// Check if launched from data reporting notification.
|
||||
Intent settingsIntent = new Intent(GeckoApp.this, GeckoPreferences.class);
|
||||
// Copy extras.
|
||||
settingsIntent.putExtras(intent);
|
||||
settingsIntent.putExtras(intent.getUnsafe());
|
||||
startActivity(settingsIntent);
|
||||
}
|
||||
}
|
||||
@ -1868,7 +1873,7 @@ public abstract class GeckoApp
|
||||
* Handles getting a URI from an intent in a way that is backwards-
|
||||
* compatible with our previous implementations.
|
||||
*/
|
||||
protected String getURIFromIntent(Intent intent) {
|
||||
protected String getURIFromIntent(SafeIntent intent) {
|
||||
final String action = intent.getAction();
|
||||
if (ACTION_ALERT_CALLBACK.equals(action) || NotificationHelper.HELPER_BROADCAST_ACTION.equals(action)) {
|
||||
return null;
|
||||
|
@ -25,27 +25,24 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.TreeMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.AppConstants.Versions;
|
||||
import org.mozilla.gecko.favicons.OnFaviconLoadedListener;
|
||||
import org.mozilla.gecko.favicons.decoders.FaviconDecoder;
|
||||
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||
import org.mozilla.gecko.gfx.LayerView;
|
||||
import org.mozilla.gecko.gfx.PanZoomController;
|
||||
import org.mozilla.gecko.mozglue.ContextUtils;
|
||||
import org.mozilla.gecko.mozglue.GeckoLoader;
|
||||
import org.mozilla.gecko.mozglue.JNITarget;
|
||||
import org.mozilla.gecko.mozglue.RobocopTarget;
|
||||
import org.mozilla.gecko.mozglue.generatorannotations.OptionalGeneratedParameter;
|
||||
import org.mozilla.gecko.mozglue.generatorannotations.WrapElementForJNI;
|
||||
import org.mozilla.gecko.prompts.PromptService;
|
||||
import org.mozilla.gecko.SmsManager;
|
||||
import org.mozilla.gecko.util.EventCallback;
|
||||
import org.mozilla.gecko.util.GeckoRequest;
|
||||
import org.mozilla.gecko.util.HardwareUtils;
|
||||
@ -53,7 +50,6 @@ import org.mozilla.gecko.util.NativeEventListener;
|
||||
import org.mozilla.gecko.util.NativeJSContainer;
|
||||
import org.mozilla.gecko.util.NativeJSObject;
|
||||
import org.mozilla.gecko.util.ProxySelector;
|
||||
import org.mozilla.gecko.util.StringUtils;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
|
||||
import android.app.Activity;
|
||||
@ -2519,7 +2515,7 @@ public class GeckoAppShell
|
||||
/* Downloads the URI pointed to by a share intent, and alters the intent to point to the locally stored file.
|
||||
*/
|
||||
public static void downloadImageForIntent(final Intent intent) {
|
||||
final String src = StringUtils.getStringExtra(intent, Intent.EXTRA_TEXT);
|
||||
final String src = ContextUtils.getStringExtra(intent, Intent.EXTRA_TEXT);
|
||||
if (src == null) {
|
||||
showImageShareFailureToast();
|
||||
return;
|
||||
|
@ -5,17 +5,17 @@
|
||||
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
import org.mozilla.gecko.util.StringUtils;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.mozilla.gecko.gfx.BitmapUtils;
|
||||
import org.mozilla.gecko.mozglue.ContextUtils.SafeIntent;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
@ -23,9 +23,6 @@ import android.net.Uri;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.HashMap;
|
||||
|
||||
public final class NotificationHelper implements GeckoEventListener {
|
||||
public static final String HELPER_BROADCAST_ACTION = AppConstants.ANDROID_PACKAGE_NAME + ".helperBroadcastAction";
|
||||
|
||||
@ -110,7 +107,7 @@ public final class NotificationHelper implements GeckoEventListener {
|
||||
return i.getBooleanExtra(HELPER_NOTIFICATION, false);
|
||||
}
|
||||
|
||||
public void handleNotificationIntent(Intent i) {
|
||||
public void handleNotificationIntent(SafeIntent i) {
|
||||
final Uri data = i.getData();
|
||||
if (data == null) {
|
||||
Log.e(LOGTAG, "handleNotificationEvent: empty data");
|
||||
@ -137,7 +134,7 @@ public final class NotificationHelper implements GeckoEventListener {
|
||||
|
||||
// The handler and cookie parameters are optional.
|
||||
final String handler = data.getQueryParameter(HANDLER_ATTR);
|
||||
final String cookie = StringUtils.getStringExtra(i, COOKIE_ATTR);
|
||||
final String cookie = i.getStringExtra(COOKIE_ATTR);
|
||||
|
||||
try {
|
||||
args.put(ID_ATTR, id);
|
||||
|
@ -25,7 +25,7 @@ import android.util.Log;
|
||||
public class RestrictedProfiles {
|
||||
private static final String LOGTAG = "GeckoRestrictedProfiles";
|
||||
|
||||
private static Boolean inGuest = null;
|
||||
private static volatile Boolean inGuest = null;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static final List<String> BANNED_SCHEMES = new ArrayList<String>() {{
|
||||
@ -36,6 +36,16 @@ public class RestrictedProfiles {
|
||||
add("wyciwyg");
|
||||
}};
|
||||
|
||||
/**
|
||||
* This is a hack to allow non-GeckoApp activities to safely call into
|
||||
* RestrictedProfiles without reworking this class or GeckoProfile.
|
||||
*
|
||||
* It can be removed after Bug 1077590 lands.
|
||||
*/
|
||||
public static void initWithProfile(GeckoProfile profile) {
|
||||
inGuest = profile.inGuestMode();
|
||||
}
|
||||
|
||||
private static boolean getInGuest() {
|
||||
if (inGuest == null) {
|
||||
inGuest = GeckoAppShell.getGeckoInterface().getProfile().inGuestMode();
|
||||
@ -86,9 +96,8 @@ public class RestrictedProfiles {
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
|
||||
@RobocopTarget
|
||||
private static Bundle getRestrictions() {
|
||||
final UserManager mgr = (UserManager) GeckoAppShell.getContext().getSystemService(Context.USER_SERVICE);
|
||||
private static Bundle getRestrictions(final Context context) {
|
||||
final UserManager mgr = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||
return mgr.getUserRestrictions();
|
||||
}
|
||||
|
||||
@ -101,17 +110,17 @@ public class RestrictedProfiles {
|
||||
*
|
||||
* Returns true otherwise.
|
||||
*/
|
||||
private static boolean getRestriction(final String name) {
|
||||
private static boolean getRestriction(final Context context, final String name) {
|
||||
// Early versions don't support restrictions at all,
|
||||
// so no action can be restricted.
|
||||
if (Versions.preJBMR2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return getRestrictions().getBoolean(name, false);
|
||||
return getRestrictions(context).getBoolean(name, false);
|
||||
}
|
||||
|
||||
private static boolean canLoadUrl(final String url) {
|
||||
private static boolean canLoadUrl(final Context context, final String url) {
|
||||
// Null URLs are always permitted.
|
||||
if (url == null) {
|
||||
return true;
|
||||
@ -120,7 +129,7 @@ public class RestrictedProfiles {
|
||||
try {
|
||||
// If we're not in guest mode, and the system restriction isn't in place, everything is allowed.
|
||||
if (!getInGuest() &&
|
||||
!getRestriction(Restriction.DISALLOW_BROWSE_FILES.name)) {
|
||||
!getRestriction(context, Restriction.DISALLOW_BROWSE_FILES.name)) {
|
||||
return true;
|
||||
}
|
||||
} catch (IllegalArgumentException ex) {
|
||||
@ -145,6 +154,10 @@ public class RestrictedProfiles {
|
||||
|
||||
@WrapElementForJNI
|
||||
public static boolean isUserRestricted() {
|
||||
return isUserRestricted(GeckoAppShell.getContext());
|
||||
}
|
||||
|
||||
private static boolean isUserRestricted(final Context context) {
|
||||
// Guest mode is supported in all Android versions.
|
||||
if (getInGuest()) {
|
||||
return true;
|
||||
@ -154,15 +167,19 @@ public class RestrictedProfiles {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !getRestrictions().isEmpty();
|
||||
return !getRestrictions(context).isEmpty();
|
||||
}
|
||||
|
||||
public static boolean isAllowed(Restriction action) {
|
||||
return isAllowed(action.id, null);
|
||||
public static boolean isAllowed(final Context context, final Restriction action) {
|
||||
return isAllowed(context, action.id, null);
|
||||
}
|
||||
|
||||
@WrapElementForJNI
|
||||
public static boolean isAllowed(int action, String url) {
|
||||
return isAllowed(GeckoAppShell.getContext(), action, url);
|
||||
}
|
||||
|
||||
private static boolean isAllowed(final Context context, int action, String url) {
|
||||
final Restriction restriction;
|
||||
try {
|
||||
restriction = geckoActionToRestriction(action);
|
||||
@ -175,7 +192,7 @@ public class RestrictedProfiles {
|
||||
|
||||
if (getInGuest()) {
|
||||
if (Restriction.DISALLOW_BROWSE_FILES == restriction) {
|
||||
return canLoadUrl(url);
|
||||
return canLoadUrl(context, url);
|
||||
}
|
||||
|
||||
// Guest users can't do anything.
|
||||
@ -183,11 +200,15 @@ public class RestrictedProfiles {
|
||||
}
|
||||
|
||||
// NOTE: Restrictions hold the opposite intention, so we need to flip it.
|
||||
return !getRestriction(restriction.name);
|
||||
return !getRestriction(context, restriction.name);
|
||||
}
|
||||
|
||||
@WrapElementForJNI
|
||||
public static String getUserRestrictions() {
|
||||
return getUserRestrictions(GeckoAppShell.getContext());
|
||||
}
|
||||
|
||||
private static String getUserRestrictions(final Context context) {
|
||||
// Guest mode is supported in all Android versions
|
||||
if (getInGuest()) {
|
||||
StringBuilder builder = new StringBuilder("{ ");
|
||||
@ -205,7 +226,7 @@ public class RestrictedProfiles {
|
||||
}
|
||||
|
||||
final JSONObject json = new JSONObject();
|
||||
final Bundle restrictions = getRestrictions();
|
||||
final Bundle restrictions = getRestrictions(context);
|
||||
final Set<String> keys = restrictions.keySet();
|
||||
|
||||
for (String key : keys) {
|
||||
|
@ -338,9 +338,12 @@ public class LoadFaviconTask {
|
||||
// Attempt to decode the favicon URL as a data URL. We don't bother storing such URIs in
|
||||
// the database: the cost of decoding them here probably doesn't exceed the cost of mucking
|
||||
// about with the DB.
|
||||
LoadFaviconResult uriBitmaps = FaviconDecoder.decodeDataURI(faviconURL);
|
||||
if (uriBitmaps != null) {
|
||||
return pushToCacheAndGetResult(uriBitmaps);
|
||||
final boolean isEmpty = TextUtils.isEmpty(faviconURL);
|
||||
if (!isEmpty) {
|
||||
LoadFaviconResult uriBitmaps = FaviconDecoder.decodeDataURI(faviconURL);
|
||||
if (uriBitmaps != null) {
|
||||
return pushToCacheAndGetResult(uriBitmaps);
|
||||
}
|
||||
}
|
||||
|
||||
String storedFaviconUrl;
|
||||
@ -348,7 +351,7 @@ public class LoadFaviconTask {
|
||||
|
||||
// Handle the case of malformed favicon URL.
|
||||
// If favicon is empty, fall back to the stored one.
|
||||
if (TextUtils.isEmpty(faviconURL)) {
|
||||
if (isEmpty) {
|
||||
// Try to get the favicon URL from the memory cache.
|
||||
storedFaviconUrl = Favicons.getFaviconURLForPageURLFromCache(pageUrl);
|
||||
|
||||
|
@ -85,7 +85,7 @@ class HomeConfigPrefsBackend implements HomeConfigBackend {
|
||||
|
||||
// We disable Synced Tabs for guest mode profiles.
|
||||
final PanelConfig remoteTabsEntry;
|
||||
if (RestrictedProfiles.isAllowed(RestrictedProfiles.Restriction.DISALLOW_MODIFY_ACCOUNTS)) {
|
||||
if (RestrictedProfiles.isAllowed(mContext, RestrictedProfiles.Restriction.DISALLOW_MODIFY_ACCOUNTS)) {
|
||||
remoteTabsEntry = createBuiltinPanelConfig(mContext, PanelType.REMOTE_TABS);
|
||||
} else {
|
||||
remoteTabsEntry = null;
|
||||
|
@ -27,6 +27,7 @@ resjar.javac_flags += ['-Xlint:all']
|
||||
mgjar = add_java_jar('gecko-mozglue')
|
||||
mgjar.sources += [
|
||||
'mozglue/ByteBufferInputStream.java',
|
||||
'mozglue/ContextUtils.java',
|
||||
'mozglue/DirectBufferAllocator.java',
|
||||
'mozglue/generatorannotations/OptionalGeneratedParameter.java',
|
||||
'mozglue/generatorannotations/WrapElementForJNI.java',
|
||||
|
102
mobile/android/base/mozglue/ContextUtils.java
Normal file
102
mobile/android/base/mozglue/ContextUtils.java
Normal file
@ -0,0 +1,102 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.mozglue;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
public class ContextUtils {
|
||||
private static final String LOGTAG = "GeckoContextUtils";
|
||||
|
||||
public static Bundle getBundleExtra(final Intent intent, final String name) {
|
||||
return new SafeIntent(intent).getBundleExtra(name);
|
||||
}
|
||||
|
||||
public static String getStringExtra(final Intent intent, final String name) {
|
||||
return new SafeIntent(intent).getStringExtra(name);
|
||||
}
|
||||
|
||||
public static boolean getBooleanExtra(Intent intent, String name, boolean defaultValue) {
|
||||
return new SafeIntent(intent).getBooleanExtra(name, defaultValue);
|
||||
}
|
||||
|
||||
public static class SafeIntent {
|
||||
private final Intent intent;
|
||||
|
||||
public SafeIntent(final Intent intent) {
|
||||
this.intent = intent;
|
||||
}
|
||||
|
||||
public boolean getBooleanExtra(final String name, final boolean defaultValue) {
|
||||
try {
|
||||
return intent.getBooleanExtra(name, defaultValue);
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.w(LOGTAG, "Couldn't get intent extras: OOM. Malformed?");
|
||||
return defaultValue;
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(LOGTAG, "Couldn't get intent extras.", e);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public String getStringExtra(final String name) {
|
||||
try {
|
||||
return intent.getStringExtra(name);
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.w(LOGTAG, "Couldn't get intent extras: OOM. Malformed?");
|
||||
return null;
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(LOGTAG, "Couldn't get intent extras.", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Bundle getBundleExtra(final String name) {
|
||||
try {
|
||||
return intent.getBundleExtra(name);
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.w(LOGTAG, "Couldn't get intent extras: OOM. Malformed?");
|
||||
return null;
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(LOGTAG, "Couldn't get intent extras.", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getAction() {
|
||||
return intent.getAction();
|
||||
}
|
||||
|
||||
public String getDataString() {
|
||||
try {
|
||||
return intent.getDataString();
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.w(LOGTAG, "Couldn't get intent data string: OOM. Malformed?");
|
||||
return null;
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(LOGTAG, "Couldn't get intent data string.", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Uri getData() {
|
||||
try {
|
||||
return intent.getData();
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.w(LOGTAG, "Couldn't get intent data: OOM. Malformed?");
|
||||
return null;
|
||||
} catch (RuntimeException e) {
|
||||
Log.w(LOGTAG, "Couldn't get intent data.", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Intent getUnsafe() {
|
||||
return intent;
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,8 @@ import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
|
||||
import org.mozilla.gecko.mozglue.ContextUtils.SafeIntent;
|
||||
|
||||
public final class GeckoLoader {
|
||||
private static final String LOGTAG = "GeckoLoader";
|
||||
|
||||
@ -29,7 +31,7 @@ public final class GeckoLoader {
|
||||
private static final String ANDROID_PACKAGE_NAME = "@ANDROID_PACKAGE_NAME@";
|
||||
private static final String MOZ_APP_ABI = "@MOZ_APP_ABI@";
|
||||
|
||||
private static volatile Intent sIntent;
|
||||
private static volatile SafeIntent sIntent;
|
||||
private static File sCacheFile;
|
||||
private static File sGREDir;
|
||||
|
||||
@ -123,14 +125,14 @@ public final class GeckoLoader {
|
||||
return tmpDir;
|
||||
}
|
||||
|
||||
public static void setLastIntent(Intent intent) {
|
||||
public static void setLastIntent(SafeIntent intent) {
|
||||
sIntent = intent;
|
||||
}
|
||||
|
||||
public static void setupGeckoEnvironment(Context context, String[] pluginDirs, String profilePath) {
|
||||
// if we have an intent (we're being launched by an activity)
|
||||
// read in any environmental variables from it here
|
||||
final Intent intent = sIntent;
|
||||
final SafeIntent intent = sIntent;
|
||||
if (intent != null) {
|
||||
String env = intent.getStringExtra("env0");
|
||||
Log.d(LOGTAG, "Gecko environment env0: " + env);
|
||||
|
@ -19,8 +19,8 @@ import org.mozilla.gecko.overlays.service.sharemethods.ParcelableClientRecord;
|
||||
import org.mozilla.gecko.overlays.service.sharemethods.SendTab;
|
||||
import org.mozilla.gecko.overlays.service.sharemethods.ShareMethod;
|
||||
import org.mozilla.gecko.sync.setup.activities.WebURLFinder;
|
||||
import org.mozilla.gecko.mozglue.ContextUtils;
|
||||
import org.mozilla.gecko.util.HardwareUtils;
|
||||
import org.mozilla.gecko.util.StringUtils;
|
||||
import org.mozilla.gecko.util.ThreadUtils;
|
||||
import org.mozilla.gecko.util.UIAsyncTask;
|
||||
|
||||
@ -121,7 +121,7 @@ public class ShareDialog extends LocaleAware.LocaleAwareActivity implements Send
|
||||
final Resources resources = getResources();
|
||||
|
||||
// The URL is usually hiding somewhere in the extra text. Extract it.
|
||||
final String extraText = StringUtils.getStringExtra(intent, Intent.EXTRA_TEXT);
|
||||
final String extraText = ContextUtils.getStringExtra(intent, Intent.EXTRA_TEXT);
|
||||
if (TextUtils.isEmpty(extraText)) {
|
||||
abortDueToNoURL();
|
||||
return;
|
||||
|
@ -26,7 +26,7 @@ class AndroidImportPreference extends MultiPrefMultiChoicePreference {
|
||||
|
||||
public static class Handler implements GeckoPreferences.PrefHandler {
|
||||
public boolean setupPref(Context context, Preference pref) {
|
||||
return RestrictedProfiles.isAllowed(Restriction.DISALLOW_IMPORT_SETTINGS);
|
||||
return RestrictedProfiles.isAllowed(context, Restriction.DISALLOW_IMPORT_SETTINGS);
|
||||
}
|
||||
|
||||
public void onChange(Context context, Preference pref, Object newValue) { }
|
||||
|
@ -296,6 +296,9 @@ OnSharedPreferenceChangeListener
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
// Make sure RestrictedProfiles is ready.
|
||||
RestrictedProfiles.initWithProfile(GeckoProfile.get(this));
|
||||
|
||||
if (GeckoProfile.get(this).inGuestMode()) {
|
||||
GuestSession.configureWindow(getWindow());
|
||||
}
|
||||
@ -700,7 +703,7 @@ OnSharedPreferenceChangeListener
|
||||
i--;
|
||||
continue;
|
||||
} else if (PREFS_DEVTOOLS_REMOTE_ENABLED.equals(key)) {
|
||||
if (!RestrictedProfiles.isAllowed(RestrictedProfiles.Restriction.DISALLOW_REMOTE_DEBUGGING)) {
|
||||
if (!RestrictedProfiles.isAllowed(this, RestrictedProfiles.Restriction.DISALLOW_REMOTE_DEBUGGING)) {
|
||||
preferences.removePreference(pref);
|
||||
i--;
|
||||
continue;
|
||||
@ -728,7 +731,7 @@ OnSharedPreferenceChangeListener
|
||||
listPref.setSummary(selectedEntry);
|
||||
continue;
|
||||
} else if (PREFS_SYNC.equals(key) &&
|
||||
!RestrictedProfiles.isAllowed(RestrictedProfiles.Restriction.DISALLOW_MODIFY_ACCOUNTS)) {
|
||||
!RestrictedProfiles.isAllowed(this, RestrictedProfiles.Restriction.DISALLOW_MODIFY_ACCOUNTS)) {
|
||||
// Don't show sync prefs while in guest mode.
|
||||
preferences.removePreference(pref);
|
||||
i--;
|
||||
|
@ -183,7 +183,7 @@ public class TabsPanel extends LinearLayout
|
||||
mTabWidget.addTab(R.drawable.tabs_normal, R.string.tabs_normal);
|
||||
mTabWidget.addTab(R.drawable.tabs_private, R.string.tabs_private);
|
||||
|
||||
if (RestrictedProfiles.isAllowed(RestrictedProfiles.Restriction.DISALLOW_MODIFY_ACCOUNTS)) {
|
||||
if (RestrictedProfiles.isAllowed(mContext, RestrictedProfiles.Restriction.DISALLOW_MODIFY_ACCOUNTS)) {
|
||||
// The initial icon is not the animated icon, because on Android
|
||||
// 4.4.2, the animation starts immediately (and can start at other
|
||||
// unpredictable times). See Bug 1015974.
|
||||
|
@ -104,6 +104,7 @@ skip-if = android_version == "10"
|
||||
[testBrowserDiscovery]
|
||||
[testDebuggerServer]
|
||||
[testDeviceSearchEngine]
|
||||
[testFilePicker]
|
||||
[testJNI]
|
||||
# [testMozPay] # see bug 945675
|
||||
[testNetworkManager]
|
||||
|
52
mobile/android/base/tests/testFilePicker.java
Normal file
52
mobile/android/base/tests/testFilePicker.java
Normal file
@ -0,0 +1,52 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.gecko.tests;
|
||||
|
||||
import static org.mozilla.gecko.tests.helpers.AssertionHelper.fFail;
|
||||
|
||||
import org.mozilla.gecko.EventDispatcher;
|
||||
import org.mozilla.gecko.GeckoAppShell;
|
||||
import org.mozilla.gecko.GeckoEvent;
|
||||
import org.mozilla.gecko.util.GeckoEventListener;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class testFilePicker extends JavascriptTest implements GeckoEventListener {
|
||||
private static final String TEST_FILENAME = "/mnt/sdcard/my-favorite-martian.png";
|
||||
|
||||
public testFilePicker() {
|
||||
super("testFilePicker.js");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(String event, final JSONObject message) {
|
||||
// We handle the FilePicker message here so we can send back hard coded file information. We
|
||||
// don't want to try to emulate "picking" a file using the Android intent chooser.
|
||||
if (event.equals("FilePicker:Show")) {
|
||||
try {
|
||||
message.put("file", TEST_FILENAME);
|
||||
} catch (JSONException ex) {
|
||||
fFail("Can't add filename to message " + TEST_FILENAME);
|
||||
}
|
||||
|
||||
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("FilePicker:Result", message.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
|
||||
EventDispatcher.getInstance().registerGeckoThreadListener(this, "FilePicker:Show");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
|
||||
EventDispatcher.getInstance().unregisterGeckoThreadListener(this, "FilePicker:Show");
|
||||
}
|
||||
}
|
80
mobile/android/base/tests/testFilePicker.js
Normal file
80
mobile/android/base/tests/testFilePicker.js
Normal file
@ -0,0 +1,80 @@
|
||||
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
function ok(passed, text) {
|
||||
do_report_result(passed, text, Components.stack.caller, false);
|
||||
}
|
||||
|
||||
function is(lhs, rhs, text) {
|
||||
do_report_result(lhs === rhs, text, Components.stack.caller, false);
|
||||
}
|
||||
|
||||
add_test(function filepicker_open() {
|
||||
let chromeWin = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
|
||||
do_test_pending();
|
||||
|
||||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||
fp.appendFilter("Martian files", "*.martian");
|
||||
fp.appendFilters(Ci.nsIFilePicker.filterAll);
|
||||
fp.filterIndex = 0;
|
||||
|
||||
let fpCallback = function(result) {
|
||||
if (result == Ci.nsIFilePicker.returnOK || result == Ci.nsIFilePicker.returnReplace) {
|
||||
do_print("File: " + fp.file.path);
|
||||
is(fp.file.path, "/mnt/sdcard/my-favorite-martian.png", "Retrieve the right martian file!");
|
||||
|
||||
let files = fp.files;
|
||||
while (files.hasMoreElements()) {
|
||||
let file = files.getNext().QueryInterface(Ci.nsIFile);
|
||||
do_print("File: " + file.path);
|
||||
is(file.path, "/mnt/sdcard/my-favorite-martian.png", "Retrieve the right martian file from array!");
|
||||
}
|
||||
|
||||
do_print("DOMFile: " + fp.domfile.mozFullPath);
|
||||
is(fp.domfile.mozFullPath, "/mnt/sdcard/my-favorite-martian.png", "Retrieve the right martian domfile!");
|
||||
|
||||
let domfiles = fp.domfiles;
|
||||
while (domfiles.hasMoreElements()) {
|
||||
let domfile = domfiles.getNext();
|
||||
do_print("DOMFile: " + domfile.mozFullPath);
|
||||
is(domfile.mozFullPath, "/mnt/sdcard/my-favorite-martian.png", "Retrieve the right martian file from domfile array!");
|
||||
}
|
||||
|
||||
do_test_finished();
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
fp.init(chromeWin, "Open", Ci.nsIFilePicker.modeOpen);
|
||||
} catch(ex) {
|
||||
ok(false, "Android should support FilePicker.modeOpen: " + ex);
|
||||
}
|
||||
fp.open(fpCallback);
|
||||
});
|
||||
|
||||
add_test(function filepicker_save() {
|
||||
let failed = false;
|
||||
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||
try {
|
||||
fp.init(null, "Save", Ci.nsIFilePicker.modeSave);
|
||||
} catch(ex) {
|
||||
failed = true;
|
||||
}
|
||||
ok(failed, "Android does not support FilePicker.modeSave");
|
||||
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
run_next_test();
|
||||
|
@ -5,10 +5,8 @@
|
||||
|
||||
package org.mozilla.gecko.util;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
public class StringUtils {
|
||||
private static final String LOGTAG = "GeckoStringUtils";
|
||||
@ -189,16 +187,4 @@ public class StringUtils {
|
||||
public static String encodeUserEnteredUrl(String url) {
|
||||
return Uri.fromParts("user-entered", url, null).toString();
|
||||
}
|
||||
|
||||
public static String getStringExtra(Intent intent, String name) {
|
||||
try {
|
||||
return intent.getStringExtra(name);
|
||||
} catch (android.os.BadParcelableException ex) {
|
||||
Log.w(LOGTAG, "Couldn't get string extra: malformed intent.");
|
||||
return null;
|
||||
} catch (RuntimeException re) {
|
||||
Log.w(LOGTAG, "Couldn't get string extra.", re);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import org.mozilla.gecko.GeckoThread;
|
||||
import org.mozilla.gecko.R;
|
||||
import org.mozilla.gecko.Tab;
|
||||
import org.mozilla.gecko.Tabs;
|
||||
import org.mozilla.gecko.mozglue.ContextUtils.SafeIntent;
|
||||
import org.mozilla.gecko.util.NativeJSObject;
|
||||
import org.mozilla.gecko.webapp.InstallHelper.InstallCallback;
|
||||
|
||||
@ -157,7 +158,7 @@ public class WebappImpl extends GeckoApp implements InstallCallback {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getURIFromIntent(Intent intent) {
|
||||
protected String getURIFromIntent(SafeIntent intent) {
|
||||
String uri = super.getURIFromIntent(intent);
|
||||
if (uri != null) {
|
||||
return uri;
|
||||
|
@ -76,7 +76,7 @@ var WebcompatReporter = {
|
||||
},
|
||||
|
||||
reportIssue: function(url) {
|
||||
let webcompatURL = new URL("http://webcompat.com/");
|
||||
let webcompatURL = new URL("https://webcompat.com/");
|
||||
webcompatURL.searchParams.append("open", "1");
|
||||
webcompatURL.searchParams.append("url", url);
|
||||
if (PrivateBrowsingUtils.isBrowserPrivate(BrowserApp.selectedTab.browser)) {
|
||||
|
@ -146,8 +146,10 @@ FilePicker.prototype = {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this._domWin) {
|
||||
return new this._domWin.File(f);
|
||||
let win = this._domWin;
|
||||
if (win) {
|
||||
let utils = win.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
return utils.wrapDOMFile(f);
|
||||
}
|
||||
|
||||
return new File(f);
|
||||
@ -213,7 +215,6 @@ FilePicker.prototype = {
|
||||
let msg = {
|
||||
type: "FilePicker:Show",
|
||||
guid: this.guid,
|
||||
guid: this.guid,
|
||||
title: this._title,
|
||||
};
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
<content>
|
||||
<xul:button label="&print.label;" accesskey="&print.accesskey;"
|
||||
oncommand="PrintUtils.print();" icon="print"/>
|
||||
oncommand="this.parentNode.print();" icon="print"/>
|
||||
|
||||
<xul:button label="&pageSetup.label;" accesskey="&pageSetup.accesskey;"
|
||||
oncommand="this.parentNode.doPageSetup();"/>
|
||||
@ -93,7 +93,7 @@
|
||||
<xul:data value="&customPrompt.title;"/>
|
||||
</content>
|
||||
|
||||
<implementation>
|
||||
<implementation implements="nsIMessageListener">
|
||||
<field name="mPrintButton">
|
||||
document.getAnonymousNodes(this)[0]
|
||||
</field>
|
||||
@ -125,16 +125,24 @@
|
||||
</field>
|
||||
<field name="mWebProgress">
|
||||
</field>
|
||||
|
||||
<constructor>
|
||||
<![CDATA[
|
||||
var print = PrintUtils.getPrintPreview();
|
||||
this.mTotalPages.value = print.printPreviewNumPages;
|
||||
this.mPageTextBox.max = print.printPreviewNumPages;
|
||||
<field name="mPPBrowser">
|
||||
null
|
||||
</field>
|
||||
<field name="mMessageManager">
|
||||
null
|
||||
</field>
|
||||
|
||||
this.updateToolbar();
|
||||
]]>
|
||||
</constructor>
|
||||
<method name="initialize">
|
||||
<parameter name="aPPBrowser"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
this.mPPBrowser = aPPBrowser;
|
||||
this.mMessageManager = aPPBrowser.messageManager;
|
||||
this.mMessageManager.addMessageListener("Printing:Preview:UpdatePageCount", this);
|
||||
this.updateToolbar();
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="doPageSetup">
|
||||
<body>
|
||||
@ -156,38 +164,47 @@
|
||||
<parameter name="aPageNum"/>
|
||||
<parameter name="aHomeOrEnd"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var print = PrintUtils.getPrintPreview();
|
||||
<![CDATA[
|
||||
const nsIWebBrowserPrint = Components.interfaces.nsIWebBrowserPrint;
|
||||
let navType, pageNum;
|
||||
|
||||
// we use only one of aHomeOrEnd, aDirection, or aPageNum
|
||||
if (aHomeOrEnd)
|
||||
{
|
||||
var homeOrEnd;
|
||||
if (aHomeOrEnd == "home")
|
||||
{
|
||||
homeOrEnd = print.PRINTPREVIEW_HOME;
|
||||
this.mPageTextBox.value = 1;
|
||||
if (aHomeOrEnd) {
|
||||
// We're going to either the very first page ("home"), or the
|
||||
// very last page ("end").
|
||||
if (aHomeOrEnd == "home") {
|
||||
navType = nsIWebBrowserPrint.PRINTPREVIEW_HOME;
|
||||
this.mPageTextBox.value = 1;
|
||||
} else {
|
||||
navType = nsIWebBrowserPrint.PRINTPREVIEW_END;
|
||||
this.mPageTextBox.value = this.mPageTextBox.max;
|
||||
}
|
||||
else
|
||||
{
|
||||
homeOrEnd = print.PRINTPREVIEW_END;
|
||||
this.mPageTextBox.value = print.printPreviewNumPages;
|
||||
}
|
||||
|
||||
print.printPreviewNavigate(homeOrEnd, 0);
|
||||
}
|
||||
else if (aDirection)
|
||||
{
|
||||
pageNum = 0;
|
||||
} else if (aDirection) {
|
||||
// aDirection is either +1 or -1, and allows us to increment
|
||||
// or decrement our currently viewed page.
|
||||
this.mPageTextBox.valueNumber += aDirection;
|
||||
print.printPreviewNavigate(
|
||||
print.PRINTPREVIEW_GOTO_PAGENUM,
|
||||
this.mPageTextBox.valueNumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
print.printPreviewNavigate(
|
||||
print.PRINTPREVIEW_GOTO_PAGENUM, aPageNum);
|
||||
navType = nsIWebBrowserPrint.PRINTPREVIEW_GOTO_PAGENUM;
|
||||
pageNum = this.mPageTextBox.value; // TODO: back to valueNumber?
|
||||
} else {
|
||||
// We're going to a specific page (aPageNum)
|
||||
navType = nsIWebBrowserPrint.PRINTPREVIEW_GOTO_PAGENUM;
|
||||
pageNum = aPageNum;
|
||||
}
|
||||
|
||||
this.mMessageManager.sendAsyncMessage("Printing:Preview:Navigate", {
|
||||
navType: navType,
|
||||
pageNum: pageNum,
|
||||
});
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="print">
|
||||
<body>
|
||||
<![CDATA[
|
||||
let contentWindow = this.mPPBrowser.contentWindowAsCPOW;
|
||||
PrintUtils.print(contentWindow, this.mPPBrowser);
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
@ -290,7 +307,6 @@
|
||||
<method name="updateToolbar">
|
||||
<body>
|
||||
<![CDATA[
|
||||
var print = PrintUtils.getPrintPreview();
|
||||
var settings = PrintUtils.getPrintSettings();
|
||||
|
||||
var isPortrait = settings.orientation == Components.interfaces.nsIPrintSettings.kPortraitOrientation;
|
||||
@ -304,9 +320,9 @@
|
||||
this.setScaleCombobox(settings.scaling);
|
||||
}
|
||||
|
||||
this.mTotalPages.value = print.printPreviewNumPages;
|
||||
this.mPageTextBox.max = print.printPreviewNumPages;
|
||||
this.mPageTextBox.value = 1;
|
||||
|
||||
this.mMessageManager.sendAsyncMessage("Printing:Preview:UpdatePageCount");
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
@ -320,6 +336,20 @@
|
||||
PSSVC.savePrintSettingsToPrefs(settings, true, flags);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<!-- nsIMessageListener -->
|
||||
<method name="receiveMessage">
|
||||
<parameter name="message"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (message.name == "Printing:Preview:UpdatePageCount") {
|
||||
let numPages = message.data.numPages;
|
||||
this.mTotalPages.value = numPages;
|
||||
this.mPageTextBox.max = numPages;
|
||||
}
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
</implementation>
|
||||
</binding>
|
||||
|
||||
|
@ -1,29 +1,93 @@
|
||||
|
||||
// -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/**
|
||||
* PrintUtils is a utility for front-end code to trigger common print
|
||||
* operations (printing, show print preview, show page settings).
|
||||
*
|
||||
* Unfortunately, likely due to inconsistencies in how different operating
|
||||
* systems do printing natively, our XPCOM-level printing interfaces
|
||||
* are a bit confusing and the method by which we do something basic
|
||||
* like printing a page is quite circuitous.
|
||||
*
|
||||
* To compound that, we need to support remote browsers, and that means
|
||||
* kicking off the print jobs in the content process. This means we send
|
||||
* messages back and forth to that process. browser-content.js contains
|
||||
* the object that listens and responds to the messages that PrintUtils
|
||||
* sends.
|
||||
*
|
||||
* PrintUtils sends messages at different points in its implementation, but
|
||||
* their documentation is consolidated here for ease-of-access.
|
||||
*
|
||||
*
|
||||
* Messages sent:
|
||||
*
|
||||
* Printing:Print
|
||||
* This message is sent to kick off a print job for a particular content
|
||||
* window (which is passed along with the message). We also pass print
|
||||
* settings with this message - though bug 1088070 will have us gather
|
||||
* those settings from the content process instead.
|
||||
*
|
||||
* Printing:Preview:Enter
|
||||
* This message is sent to put content into print preview mode. We pass
|
||||
* the content window of the browser we're showing the preview of, and
|
||||
* the target of the message is the browser that we'll be showing the
|
||||
* preview in. We also pass print settings in this message, but
|
||||
* bug 1088070 will have us gather those settings from the content process
|
||||
* instead.
|
||||
*
|
||||
* Printing:Preview:Exit
|
||||
* This message is sent to take content out of print preview mode.
|
||||
*
|
||||
*
|
||||
* Messages Received
|
||||
*
|
||||
* Printing:Preview:Entered
|
||||
* This message is sent by the content process once it has completed
|
||||
* putting the content into print preview mode. We must wait for that to
|
||||
* to complete before switching the chrome UI to print preview mode,
|
||||
* otherwise we have layout issues.
|
||||
*
|
||||
* Printing:Preview:StateChange, Printing:Preview:ProgressChange
|
||||
* Due to a timing issue resulting in a main-process crash, we have to
|
||||
* manually open the progress dialog for print preview. The progress
|
||||
* dialog is opened here in PrintUtils, and then we listen for update
|
||||
* messages from the child. Bug 1088061 has been filed to investigate
|
||||
* other solutions.
|
||||
*
|
||||
*/
|
||||
|
||||
var gPrintSettingsAreGlobal = false;
|
||||
var gSavePrintSettings = false;
|
||||
var gFocusedElement = null;
|
||||
|
||||
var PrintUtils = {
|
||||
bailOut: function () {
|
||||
let remote = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsILoadContext)
|
||||
.useRemoteTabs;
|
||||
if (remote) {
|
||||
let pref = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
let allow_for_testing = false;
|
||||
try {
|
||||
allow_for_testing = pref.getBoolPref("print.enable_e10s_testing");
|
||||
} catch(e) {
|
||||
// The pref wasn't set, so I guess we're not overriding.
|
||||
}
|
||||
if (this.usingRemoteTabs && !allow_for_testing) {
|
||||
alert("e10s printing is not implemented yet. Bug 927188.");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
showPageSetup: function ()
|
||||
{
|
||||
/**
|
||||
* Shows the page setup dialog, and saves any settings changed in
|
||||
* that dialog if print.save_print_settings is set to true.
|
||||
*
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
showPageSetup: function () {
|
||||
if (this.bailOut()) {
|
||||
return;
|
||||
}
|
||||
@ -45,102 +109,261 @@ var PrintUtils = {
|
||||
return true;
|
||||
},
|
||||
|
||||
print: function (aWindow)
|
||||
/**
|
||||
* Starts printing the contents of aWindow.
|
||||
*
|
||||
* @param aWindow
|
||||
* An nsIDOMWindow to initiate the printing of. If the chrome window
|
||||
* is not running with remote tabs, this defaults to window.content if
|
||||
* omitted. If running with remote tabs, the caller must pass in the
|
||||
* content window to be printed. This function throws if that invariant
|
||||
* is violated.
|
||||
* @param aBrowser (optional for non-remote browsers)
|
||||
* The remote <xul:browser> that contains aWindow. This argument is
|
||||
* not necessary if aWindow came from a non-remote browser, but is
|
||||
* strictly required otherwise. This function will throw if aWindow
|
||||
* comes from a remote browser and aBrowser is not provided.
|
||||
*/
|
||||
print: function (aWindow, aBrowser)
|
||||
{
|
||||
if (this.bailOut()) {
|
||||
return;
|
||||
}
|
||||
var webBrowserPrint = this.getWebBrowserPrint(aWindow);
|
||||
var printSettings = this.getPrintSettings();
|
||||
try {
|
||||
webBrowserPrint.print(printSettings, null);
|
||||
if (gPrintSettingsAreGlobal && gSavePrintSettings) {
|
||||
var PSSVC = Components.classes["@mozilla.org/gfx/printsettings-service;1"]
|
||||
.getService(Components.interfaces.nsIPrintSettingsService);
|
||||
PSSVC.savePrintSettingsToPrefs(printSettings, true,
|
||||
printSettings.kInitSaveAll);
|
||||
PSSVC.savePrintSettingsToPrefs(printSettings, false,
|
||||
printSettings.kInitSavePrinterName);
|
||||
|
||||
if (!aWindow) {
|
||||
// If we're using remote browsers, chances are that window.content will
|
||||
// not be defined.
|
||||
if (this.usingRemoteTabs) {
|
||||
throw new Error("Windows running with remote tabs must explicitly pass " +
|
||||
"a content window to PrintUtils.print.");
|
||||
}
|
||||
} catch (e) {
|
||||
// Pressing cancel is expressed as an NS_ERROR_ABORT return value,
|
||||
// causing an exception to be thrown which we catch here.
|
||||
// Unfortunately this will also consume helpful failures, so add a
|
||||
// dump("print: "+e+"\n"); // if you need to debug
|
||||
// Otherwise, we should have access to window.content.
|
||||
aWindow = window.content;
|
||||
}
|
||||
|
||||
if (Cu.isCrossProcessWrapper(aWindow)) {
|
||||
if (!aBrowser) {
|
||||
throw new Error("PrintUtils.print expects a remote browser passed as " +
|
||||
"an argument if the content window is a CPOW.");
|
||||
}
|
||||
} else {
|
||||
// For content windows coming from non-remote browsers, the browser can
|
||||
// be resolved as the chromeEventHandler.
|
||||
aBrowser = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler;
|
||||
}
|
||||
|
||||
if (!aBrowser) {
|
||||
throw new Error("PrintUtils.print could not resolve content window " +
|
||||
"to a browser.");
|
||||
}
|
||||
|
||||
let printSettings = this.getPrintSettings();
|
||||
|
||||
let mm = aBrowser.messageManager;
|
||||
mm.sendAsyncMessage("Printing:Print", null, {
|
||||
printSettings: printSettings,
|
||||
contentWindow: aWindow,
|
||||
});
|
||||
},
|
||||
|
||||
// If aCallback is not null, it must be an object which has the following methods:
|
||||
// getPrintPreviewBrowser(), getSourceBrowser(),
|
||||
// getNavToolbox(), onEnter() and onExit().
|
||||
// If aCallback is null, then printPreview must previously have been called with
|
||||
// non-null aCallback and that object will be reused.
|
||||
printPreview: function (aCallback)
|
||||
/**
|
||||
* Initializes print preview.
|
||||
*
|
||||
* @param aListenerObj
|
||||
* An object that defines the following functions:
|
||||
*
|
||||
* getPrintPreviewBrowser:
|
||||
* Returns the <xul:browser> to display the print preview in.
|
||||
*
|
||||
* getSourceBrowser:
|
||||
* Returns the <xul:browser> that contains the document being
|
||||
* printed.
|
||||
*
|
||||
* getNavToolbox:
|
||||
* Returns the primary toolbox for this window.
|
||||
*
|
||||
* onEnter:
|
||||
* Called upon entering print preview.
|
||||
*
|
||||
* onExit:
|
||||
* Called upon exiting print preview.
|
||||
*
|
||||
* These methods must be defined. printPreview can be called
|
||||
* with aListenerObj as null iff this window is already displaying
|
||||
* print preview (in which case, the previous aListenerObj passed
|
||||
* to it will be used).
|
||||
*/
|
||||
printPreview: function (aListenerObj)
|
||||
{
|
||||
if (this.bailOut()) {
|
||||
return;
|
||||
}
|
||||
// if we're already in PP mode, don't set the callback; chances
|
||||
// if we're already in PP mode, don't set the listener; chances
|
||||
// are it is null because someone is calling printPreview() to
|
||||
// get us to refresh the display.
|
||||
if (!document.getElementById("print-preview-toolbar")) {
|
||||
this._callback = aCallback;
|
||||
this._sourceBrowser = aCallback.getSourceBrowser();
|
||||
this._originalTitle = this._sourceBrowser.contentDocument.title;
|
||||
if (!this.inPrintPreview) {
|
||||
this._listener = aListenerObj;
|
||||
this._sourceBrowser = aListenerObj.getSourceBrowser();
|
||||
this._originalTitle = this._sourceBrowser.contentTitle;
|
||||
this._originalURL = this._sourceBrowser.currentURI.spec;
|
||||
} else {
|
||||
// collapse the browser here -- it will be shown in
|
||||
// enterPrintPreview; this forces a reflow which fixes display
|
||||
// issues in bug 267422.
|
||||
this._sourceBrowser = this._callback.getPrintPreviewBrowser();
|
||||
this._sourceBrowser = this._listener.getPrintPreviewBrowser();
|
||||
this._sourceBrowser.collapsed = true;
|
||||
}
|
||||
|
||||
this._webProgressPP = {};
|
||||
var ppParams = {};
|
||||
var notifyOnOpen = {};
|
||||
var webBrowserPrint = this.getWebBrowserPrint();
|
||||
var printSettings = this.getPrintSettings();
|
||||
let ppParams = {};
|
||||
let notifyOnOpen = {};
|
||||
let printSettings = this.getPrintSettings();
|
||||
// Here we get the PrintingPromptService so we can display the PP Progress from script
|
||||
// For the browser implemented via XUL with the PP toolbar we cannot let it be
|
||||
// automatically opened from the print engine because the XUL scrollbars in the PP window
|
||||
// will layout before the content window and a crash will occur.
|
||||
// Doing it all from script, means it lays out before hand and we can let printing do its own thing
|
||||
var PPROMPTSVC = Components.classes["@mozilla.org/embedcomp/printingprompt-service;1"]
|
||||
let PPROMPTSVC = Components.classes["@mozilla.org/embedcomp/printingprompt-service;1"]
|
||||
.getService(Components.interfaces.nsIPrintingPromptService);
|
||||
// just in case we are already printing,
|
||||
// an error code could be returned if the Prgress Dialog is already displayed
|
||||
// just in case we are already printing,
|
||||
// an error code could be returned if the Progress Dialog is already displayed
|
||||
try {
|
||||
PPROMPTSVC.showProgress(window, webBrowserPrint, printSettings, this._obsPP, false,
|
||||
PPROMPTSVC.showProgress(window, null, printSettings, this._obsPP, false,
|
||||
this._webProgressPP, ppParams, notifyOnOpen);
|
||||
if (ppParams.value) {
|
||||
ppParams.value.docTitle = this._originalTitle;
|
||||
ppParams.value.docURL = this._originalURL;
|
||||
}
|
||||
|
||||
// this tells us whether we should continue on with PP or
|
||||
// this tells us whether we should continue on with PP or
|
||||
// wait for the callback via the observer
|
||||
if (!notifyOnOpen.value.valueOf() || this._webProgressPP.value == null)
|
||||
if (!notifyOnOpen.value.valueOf() || this._webProgressPP.value == null) {
|
||||
this.enterPrintPreview();
|
||||
}
|
||||
} catch (e) {
|
||||
this.enterPrintPreview();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the nsIWebBrowserPrint associated with some content window.
|
||||
* This method is being kept here for compatibility reasons, but should not
|
||||
* be called by code hoping to support e10s / remote browsers.
|
||||
*
|
||||
* @param aWindow
|
||||
* The window from which to get the nsIWebBrowserPrint from.
|
||||
* @return nsIWebBrowserPrint
|
||||
*/
|
||||
getWebBrowserPrint: function (aWindow)
|
||||
{
|
||||
let Deprecated = Components.utils.import("resource://gre/modules/Deprecated.jsm", {}).Deprecated;
|
||||
let text = "getWebBrowserPrint is now deprecated, and fully unsupported for " +
|
||||
"multi-process browsers. Please use a frame script to get " +
|
||||
"access to nsIWebBrowserPrint from content.";
|
||||
let url = "https://developer.mozilla.org/en-US/docs/Printing_from_a_XUL_App";
|
||||
Deprecated.warning(text, url);
|
||||
|
||||
if (this.usingRemoteTabs) {
|
||||
return {};
|
||||
}
|
||||
|
||||
var contentWindow = aWindow || window.content;
|
||||
return contentWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebBrowserPrint);
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns the nsIWebBrowserPrint from the print preview browser's docShell.
|
||||
* This method is being kept here for compatibility reasons, but should not
|
||||
* be called by code hoping to support e10s / remote browsers.
|
||||
*
|
||||
* @return nsIWebBrowserPrint
|
||||
*/
|
||||
getPrintPreview: function() {
|
||||
return this._callback.getPrintPreviewBrowser().docShell.printPreview;
|
||||
let Deprecated = Components.utils.import("resource://gre/modules/Deprecated.jsm", {}).Deprecated;
|
||||
let text = "getPrintPreview is now deprecated, and fully unsupported for " +
|
||||
"multi-process browsers. Please use a frame script to get " +
|
||||
"access to nsIWebBrowserPrint from content.";
|
||||
let url = "https://developer.mozilla.org/en-US/docs/Printing_from_a_XUL_App";
|
||||
Deprecated.warning(text, url);
|
||||
|
||||
if (this.usingRemoteTabs) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return this._listener.getPrintPreviewBrowser().docShell.printPreview;
|
||||
},
|
||||
|
||||
////////////////////////////////////////
|
||||
// "private" methods. Don't use them. //
|
||||
////////////////////////////////////////
|
||||
get inPrintPreview() {
|
||||
return document.getElementById("print-preview-toolbar") != null;
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// "private" methods and members. Don't use them. //
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
_listener: null,
|
||||
_closeHandlerPP: null,
|
||||
_webProgressPP: null,
|
||||
_sourceBrowser: null,
|
||||
_originalTitle: "",
|
||||
_originalURL: "",
|
||||
|
||||
get usingRemoteTabs() {
|
||||
// We memoize this, since it's highly unlikely to change over the lifetime
|
||||
// of the window.
|
||||
let usingRemoteTabs =
|
||||
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsILoadContext)
|
||||
.useRemoteTabs;
|
||||
delete this.usingRemoteTabs;
|
||||
return this.usingRemoteTabs = usingRemoteTabs;
|
||||
},
|
||||
|
||||
receiveMessage(aMessage) {
|
||||
if (!this._webProgressPP.value) {
|
||||
// We somehow didn't get a nsIWebProgressListener to be updated...
|
||||
// I guess there's nothing to do.
|
||||
return;
|
||||
}
|
||||
|
||||
let listener = this._webProgressPP.value;
|
||||
let mm = aMessage.target.messageManager;
|
||||
let data = aMessage.data;
|
||||
|
||||
switch (aMessage.name) {
|
||||
case "Printing:Preview:ProgressChange": {
|
||||
return listener.onProgressChange(null, null,
|
||||
data.curSelfProgress,
|
||||
data.maxSelfProgress,
|
||||
data.curTotalProgress,
|
||||
data.maxTotalProgress);
|
||||
break;
|
||||
}
|
||||
|
||||
case "Printing:Preview:StateChange": {
|
||||
if (data.stateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP) {
|
||||
// Strangely, the printing engine sends 2 STATE_STOP messages when
|
||||
// print preview is finishing. One has the STATE_IS_DOCUMENT flag,
|
||||
// the other has the STATE_IS_NETWORK flag. However, the webProgressPP
|
||||
// listener stops listening once the first STATE_STOP is sent.
|
||||
// Any subsequent messages result in NS_ERROR_FAILURE errors getting
|
||||
// thrown. This should all get torn out once bug 1088061 is fixed.
|
||||
mm.removeMessageListener("Printing:Preview:StateChange", this);
|
||||
mm.removeMessageListener("Printing:Preview:ProgressChange", this);
|
||||
}
|
||||
|
||||
return listener.onStateChange(null, null,
|
||||
data.stateFlags,
|
||||
data.status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
setPrinterDefaultsForSelectedPrinter: function (aPSSVC, aPrintSettings)
|
||||
{
|
||||
@ -178,15 +401,8 @@ var PrintUtils = {
|
||||
return printSettings;
|
||||
},
|
||||
|
||||
_closeHandlerPP: null,
|
||||
_webProgressPP: null,
|
||||
_callback: null,
|
||||
_sourceBrowser: null,
|
||||
_originalTitle: "",
|
||||
_originalURL: "",
|
||||
|
||||
// This observer is called once the progress dialog has been "opened"
|
||||
_obsPP:
|
||||
_obsPP:
|
||||
{
|
||||
observe: function(aSubject, aTopic, aData)
|
||||
{
|
||||
@ -199,84 +415,87 @@ var PrintUtils = {
|
||||
if (iid.equals(Components.interfaces.nsIObserver) ||
|
||||
iid.equals(Components.interfaces.nsISupportsWeakReference) ||
|
||||
iid.equals(Components.interfaces.nsISupports))
|
||||
return this;
|
||||
return this;
|
||||
throw Components.results.NS_NOINTERFACE;
|
||||
}
|
||||
},
|
||||
|
||||
enterPrintPreview: function ()
|
||||
{
|
||||
gFocusedElement = document.commandDispatcher.focusedElement;
|
||||
// Send a message to the print preview browser to initialize
|
||||
// print preview. If we happen to have gotten a print preview
|
||||
// progress listener from nsIPrintingPromptService.showProgress
|
||||
// in printPreview, we add listeners to feed that progress
|
||||
// listener.
|
||||
let ppBrowser = this._listener.getPrintPreviewBrowser();
|
||||
let mm = ppBrowser.messageManager;
|
||||
let printSettings = this.getPrintSettings();
|
||||
mm.sendAsyncMessage("Printing:Preview:Enter", null, {
|
||||
printSettings: printSettings,
|
||||
contentWindow: this._sourceBrowser.contentWindowAsCPOW,
|
||||
});
|
||||
|
||||
var webBrowserPrint;
|
||||
var printSettings = this.getPrintSettings();
|
||||
var originalWindow = this._sourceBrowser.contentWindow;
|
||||
|
||||
try {
|
||||
webBrowserPrint = this.getPrintPreview();
|
||||
webBrowserPrint.printPreview(printSettings, originalWindow,
|
||||
this._webProgressPP.value);
|
||||
} catch (e) {
|
||||
// Pressing cancel is expressed as an NS_ERROR_ABORT return value,
|
||||
// causing an exception to be thrown which we catch here.
|
||||
// Unfortunately this will also consume helpful failures, so add a
|
||||
// dump(e); // if you need to debug
|
||||
|
||||
// Need to call enter and exit so that UI gets back to normal.
|
||||
this._callback.onEnter();
|
||||
this._callback.onExit();
|
||||
return;
|
||||
if (this._webProgressPP.value) {
|
||||
mm.addMessageListener("Printing:Preview:StateChange", this);
|
||||
mm.addMessageListener("Printing:Preview:ProgressChange", this);
|
||||
}
|
||||
|
||||
var printPreviewTB = document.getElementById("print-preview-toolbar");
|
||||
if (printPreviewTB) {
|
||||
printPreviewTB.updateToolbar();
|
||||
var browser = this._callback.getPrintPreviewBrowser();
|
||||
browser.collapsed = false;
|
||||
browser.contentWindow.focus();
|
||||
return;
|
||||
}
|
||||
let onEntered = (message) => {
|
||||
mm.removeMessageListener("Printing:PrintPreview:Entered", onEntered);
|
||||
// Stash the focused element so that we can return to it after exiting
|
||||
// print preview.
|
||||
gFocusedElement = document.commandDispatcher.focusedElement;
|
||||
|
||||
// Set the original window as an active window so any mozPrintCallbacks can
|
||||
// run without delayed setTimeouts.
|
||||
var docShell = originalWindow.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShell);
|
||||
docShell.isActive = true;
|
||||
let printPreviewTB = document.getElementById("print-preview-toolbar");
|
||||
if (printPreviewTB) {
|
||||
printPreviewTB.updateToolbar();
|
||||
ppBrowser.collapsed = false;
|
||||
ppBrowser.focus();
|
||||
return;
|
||||
}
|
||||
|
||||
// show the toolbar after we go into print preview mode so
|
||||
// that we can initialize the toolbar with total num pages
|
||||
var XUL_NS =
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
printPreviewTB = document.createElementNS(XUL_NS, "toolbar");
|
||||
printPreviewTB.setAttribute("printpreview", true);
|
||||
printPreviewTB.id = "print-preview-toolbar";
|
||||
printPreviewTB.className = "toolbar-primary";
|
||||
// Set the original window as an active window so any mozPrintCallbacks can
|
||||
// run without delayed setTimeouts.
|
||||
this._sourceBrowser.docShellIsActive = true;
|
||||
|
||||
var navToolbox = this._callback.getNavToolbox();
|
||||
navToolbox.parentNode.insertBefore(printPreviewTB, navToolbox);
|
||||
// show the toolbar after we go into print preview mode so
|
||||
// that we can initialize the toolbar with total num pages
|
||||
const XUL_NS =
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
printPreviewTB = document.createElementNS(XUL_NS, "toolbar");
|
||||
printPreviewTB.setAttribute("printpreview", true);
|
||||
printPreviewTB.id = "print-preview-toolbar";
|
||||
printPreviewTB.className = "toolbar-primary";
|
||||
|
||||
// copy the window close handler
|
||||
if (document.documentElement.hasAttribute("onclose"))
|
||||
this._closeHandlerPP = document.documentElement.getAttribute("onclose");
|
||||
else
|
||||
this._closeHandlerPP = null;
|
||||
document.documentElement.setAttribute("onclose", "PrintUtils.exitPrintPreview(); return false;");
|
||||
let navToolbox = this._listener.getNavToolbox();
|
||||
navToolbox.parentNode.insertBefore(printPreviewTB, navToolbox);
|
||||
printPreviewTB.initialize(ppBrowser);
|
||||
|
||||
// disable chrome shortcuts...
|
||||
window.addEventListener("keydown", this.onKeyDownPP, true);
|
||||
window.addEventListener("keypress", this.onKeyPressPP, true);
|
||||
// copy the window close handler
|
||||
if (document.documentElement.hasAttribute("onclose"))
|
||||
this._closeHandlerPP = document.documentElement.getAttribute("onclose");
|
||||
else
|
||||
this._closeHandlerPP = null;
|
||||
document.documentElement.setAttribute("onclose", "PrintUtils.exitPrintPreview(); return false;");
|
||||
|
||||
var browser = this._callback.getPrintPreviewBrowser();
|
||||
browser.collapsed = false;
|
||||
browser.contentWindow.focus();
|
||||
// disable chrome shortcuts...
|
||||
window.addEventListener("keydown", this.onKeyDownPP, true);
|
||||
window.addEventListener("keypress", this.onKeyPressPP, true);
|
||||
|
||||
// on Enter PP Call back
|
||||
this._callback.onEnter();
|
||||
ppBrowser.collapsed = false;
|
||||
ppBrowser.focus();
|
||||
// on Enter PP Call back
|
||||
this._listener.onEnter();
|
||||
};
|
||||
|
||||
mm.addMessageListener("Printing:Preview:Entered", onEntered);
|
||||
},
|
||||
|
||||
exitPrintPreview: function ()
|
||||
{
|
||||
let ppBrowser = this._listener.getPrintPreviewBrowser();
|
||||
let browserMM = ppBrowser.messageManager;
|
||||
browserMM.sendAsyncMessage("Printing:Preview:Exit");
|
||||
window.removeEventListener("keydown", this.onKeyDownPP, true);
|
||||
window.removeEventListener("keypress", this.onKeyPressPP, true);
|
||||
|
||||
@ -284,14 +503,11 @@ var PrintUtils = {
|
||||
document.documentElement.setAttribute("onclose", this._closeHandlerPP);
|
||||
this._closeHandlerPP = null;
|
||||
|
||||
var webBrowserPrint = this.getPrintPreview();
|
||||
webBrowserPrint.exitPrintPreview();
|
||||
|
||||
// remove the print preview toolbar
|
||||
var printPreviewTB = document.getElementById("print-preview-toolbar");
|
||||
this._callback.getNavToolbox().parentNode.removeChild(printPreviewTB);
|
||||
let printPreviewTB = document.getElementById("print-preview-toolbar");
|
||||
this._listener.getNavToolbox().parentNode.removeChild(printPreviewTB);
|
||||
|
||||
var fm = Components.classes["@mozilla.org/focus-manager;1"]
|
||||
let fm = Components.classes["@mozilla.org/focus-manager;1"]
|
||||
.getService(Components.interfaces.nsIFocusManager);
|
||||
if (gFocusedElement)
|
||||
fm.setFocus(gFocusedElement, fm.FLAG_NOSCROLL);
|
||||
@ -299,7 +515,7 @@ var PrintUtils = {
|
||||
window.content.focus();
|
||||
gFocusedElement = null;
|
||||
|
||||
this._callback.onExit();
|
||||
this._listener.onExit();
|
||||
},
|
||||
|
||||
onKeyDownPP: function (aEvent)
|
||||
@ -329,7 +545,7 @@ var PrintUtils = {
|
||||
var printKey = document.getElementById("printKb").getAttribute("key").toUpperCase();
|
||||
var pressedKey = String.fromCharCode(aEvent.charCode).toUpperCase();
|
||||
if (printKey == pressedKey) {
|
||||
PrintUtils.print();
|
||||
printPreviewTB.print();
|
||||
}
|
||||
}
|
||||
// cancel shortkeys
|
||||
|
@ -6,8 +6,10 @@
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
let Cu = Components.utils;
|
||||
let Cr = Components.results;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
var global = this;
|
||||
|
||||
@ -353,3 +355,130 @@ PopupBlocking.init();
|
||||
// Set up console.* for frame scripts.
|
||||
let Console = Components.utils.import("resource://gre/modules/devtools/Console.jsm", {});
|
||||
this.console = new Console.ConsoleAPI();
|
||||
|
||||
let Printing = {
|
||||
// Bug 1088061: nsPrintEngine's DoCommonPrint currently expects the
|
||||
// progress listener passed to it to QI to an nsIPrintingPromptService
|
||||
// in order to know that a printing progress dialog has been shown. That's
|
||||
// really all the interface is used for, hence the fact that I don't actually
|
||||
// implement the interface here. Bug 1088061 has been filed to remove
|
||||
// this hackery.
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
|
||||
Ci.nsIPrintingPromptService]),
|
||||
|
||||
MESSAGES: [
|
||||
"Printing:Preview:Enter",
|
||||
"Printing:Preview:Exit",
|
||||
"Printing:Preview:Navigate",
|
||||
"Printing:Preview:UpdatePageCount",
|
||||
"Printing:Print",
|
||||
],
|
||||
|
||||
init() {
|
||||
this.MESSAGES.forEach(msgName => addMessageListener(msgName, this));
|
||||
},
|
||||
|
||||
receiveMessage(message) {
|
||||
let objects = message.objects;
|
||||
let data = message.data;
|
||||
switch(message.name) {
|
||||
case "Printing:Preview:Enter": {
|
||||
this.enterPrintPreview(objects.printSettings, objects.contentWindow);
|
||||
break;
|
||||
}
|
||||
|
||||
case "Printing:Preview:Exit": {
|
||||
this.exitPrintPreview();
|
||||
break;
|
||||
}
|
||||
|
||||
case "Printing:Preview:Navigate": {
|
||||
this.navigate(data.navType, data.pageNum);
|
||||
break;
|
||||
}
|
||||
|
||||
case "Printing:Preview:UpdatePageCount": {
|
||||
this.updatePageCount();
|
||||
break;
|
||||
}
|
||||
|
||||
case "Printing:Print": {
|
||||
this.print(objects.printSettings, objects.contentWindow);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
enterPrintPreview(printSettings, contentWindow) {
|
||||
// Bug 1088070 - we should instantiate nsIPrintSettings here in the
|
||||
// content script instead of passing it down as a CPOW.
|
||||
if (Cu.isCrossProcessWrapper(printSettings)) {
|
||||
printSettings = null;
|
||||
}
|
||||
|
||||
// We have to wait for the print engine to finish reflowing all of the
|
||||
// documents and subdocuments before we can tell the parent to flip to
|
||||
// the print preview UI - otherwise, the print preview UI might ask for
|
||||
// information (like the number of pages in the document) before we have
|
||||
// our PresShells set up.
|
||||
addEventListener("printPreviewUpdate", function onPrintPreviewReady() {
|
||||
removeEventListener("printPreviewUpdate", onPrintPreviewReady);
|
||||
sendAsyncMessage("Printing:Preview:Entered");
|
||||
});
|
||||
|
||||
docShell.printPreview.printPreview(printSettings, contentWindow, this);
|
||||
},
|
||||
|
||||
exitPrintPreview() {
|
||||
docShell.printPreview.exitPrintPreview();
|
||||
},
|
||||
|
||||
print(printSettings, contentWindow) {
|
||||
// Bug 1088070 - we should instantiate nsIPrintSettings here in the
|
||||
// content script instead of passing it down as a CPOW.
|
||||
if (Cu.isCrossProcessWrapper(printSettings)) {
|
||||
printSettings = null;
|
||||
}
|
||||
|
||||
let print = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebBrowserPrint);
|
||||
print.print(printSettings, null);
|
||||
},
|
||||
|
||||
updatePageCount() {
|
||||
let numPages = docShell.printPreview.printPreviewNumPages;
|
||||
sendAsyncMessage("Printing:Preview:UpdatePageCount", {
|
||||
numPages: numPages,
|
||||
});
|
||||
},
|
||||
|
||||
navigate(navType, pageNum) {
|
||||
docShell.printPreview.printPreviewNavigate(navType, pageNum);
|
||||
},
|
||||
|
||||
/* nsIWebProgressListener for print preview */
|
||||
|
||||
onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
sendAsyncMessage("Printing:Preview:StateChange", {
|
||||
stateFlags: aStateFlags,
|
||||
status: aStatus,
|
||||
});
|
||||
},
|
||||
|
||||
onProgressChange(aWebProgress, aRequest, aCurSelfProgress,
|
||||
aMaxSelfProgress, aCurTotalProgress,
|
||||
aMaxTotalProgress) {
|
||||
sendAsyncMessage("Printing:Preview:ProgressChange", {
|
||||
curSelfProgress: aCurSelfProgress,
|
||||
maxSelfProgress: aMaxSelfProgress,
|
||||
curTotalProgress: aCurTotalProgress,
|
||||
maxTotalProgress: aMaxTotalProgress,
|
||||
});
|
||||
},
|
||||
|
||||
onLocationChange(aWebProgress, aRequest, aLocation, aFlags) {},
|
||||
onStatusChange(aWebProgress, aRequest, aStatus, aMessage) {},
|
||||
onSecurityChange(aWebProgress, aRequest, aState) {},
|
||||
}
|
||||
Printing.init();
|
||||
|
||||
|
@ -37,7 +37,7 @@ function TouchEventHandler (window) {
|
||||
|
||||
let TouchEventHandler = {
|
||||
enabled: false,
|
||||
events: ['mousedown', 'mousemove', 'mouseup'],
|
||||
events: ['mousedown', 'mousemove', 'mouseup', 'touchstart', 'touchend'],
|
||||
start: function teh_start() {
|
||||
if (this.enabled)
|
||||
return false;
|
||||
@ -61,18 +61,43 @@ function TouchEventHandler (window) {
|
||||
}).bind(this));
|
||||
},
|
||||
handleEvent: function teh_handleEvent(evt) {
|
||||
// Ignore all but real mouse event coming from physical mouse
|
||||
// (especially ignore mouse event being dispatched from a touch event)
|
||||
if (evt.button || evt.mozInputSource != Ci.nsIDOMMouseEvent.MOZ_SOURCE_MOUSE || evt.isSynthesized) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The gaia system window use an hybrid system even on the device which is
|
||||
// a mix of mouse/touch events. So let's not cancel *all* mouse events
|
||||
// if it is the current target.
|
||||
let content = this.getContent(evt.target);
|
||||
let isSystemWindow = content.location.toString().indexOf("system.gaiamobile.org") != -1;
|
||||
|
||||
// App touchstart & touchend should also be dispatched on the system app
|
||||
// to match on-device behavior.
|
||||
if (evt.type.startsWith('touch') && !isSystemWindow) {
|
||||
let sysFrame = content.realFrameElement;
|
||||
let sysDocument = sysFrame.ownerDocument;
|
||||
let sysWindow = sysDocument.defaultView;
|
||||
|
||||
let touchEvent = sysDocument.createEvent('touchevent');
|
||||
let touch = evt.touches[0] || evt.changedTouches[0];
|
||||
let point = sysDocument.createTouch(sysWindow, sysFrame, 0,
|
||||
touch.pageX, touch.pageY,
|
||||
touch.screenX, touch.screenY,
|
||||
touch.clientX, touch.clientY,
|
||||
1, 1, 0, 0);
|
||||
|
||||
let touches = sysDocument.createTouchList(point);
|
||||
let targetTouches = touches;
|
||||
let changedTouches = touches;
|
||||
touchEvent.initTouchEvent(evt.type, true, true, sysWindow, 0,
|
||||
false, false, false, false,
|
||||
touches, targetTouches, changedTouches);
|
||||
sysFrame.dispatchEvent(touchEvent);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore all but real mouse event coming from physical mouse
|
||||
// (especially ignore mouse event being dispatched from a touch event)
|
||||
if (evt.button || evt.mozInputSource != Ci.nsIDOMMouseEvent.MOZ_SOURCE_MOUSE || evt.isSynthesized) {
|
||||
return;
|
||||
}
|
||||
|
||||
let eventTarget = this.target;
|
||||
let type = '';
|
||||
switch (evt.type) {
|
||||
|
@ -1066,13 +1066,14 @@ nsViewManager::ProcessPendingUpdates()
|
||||
return;
|
||||
}
|
||||
|
||||
mPresShell->GetPresContext()->RefreshDriver()->RevokeViewManagerFlush();
|
||||
|
||||
// Flush things like reflows by calling WillPaint on observer presShells.
|
||||
if (mPresShell) {
|
||||
mPresShell->GetPresContext()->RefreshDriver()->RevokeViewManagerFlush();
|
||||
|
||||
CallWillPaintOnObservers();
|
||||
|
||||
ProcessPendingUpdatesForView(mRootView, true);
|
||||
}
|
||||
ProcessPendingUpdatesForView(mRootView, true);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -29,7 +29,7 @@ nsPrintOptionsX::ReadPrefs(nsIPrintSettings* aPS, const nsAString& aPrinterName,
|
||||
return NS_ERROR_NO_INTERFACE;
|
||||
rv = printSettingsX->ReadPageFormatFromPrefs();
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPrintOptionsX::_CreatePrintSettings(nsIPrintSettings **_retval)
|
||||
|
@ -140,13 +140,10 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
{ &kNS_THEMERENDERER_CID, false, NULL, nsNativeThemeCocoaConstructor },
|
||||
{ &kNS_SCREENMANAGER_CID, false, NULL, nsScreenManagerCocoaConstructor,
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_DEVICE_CONTEXT_SPEC_CID, false, NULL, nsDeviceContextSpecXConstructor,
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_PRINTSESSION_CID, false, NULL, nsPrintSessionConstructor,
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_DEVICE_CONTEXT_SPEC_CID, false, NULL, nsDeviceContextSpecXConstructor },
|
||||
{ &kNS_PRINTSESSION_CID, false, NULL, nsPrintSessionConstructor },
|
||||
{ &kNS_PRINTSETTINGSSERVICE_CID, false, NULL, nsPrintOptionsXConstructor },
|
||||
{ &kNS_PRINTDIALOGSERVICE_CID, false, NULL, nsPrintDialogServiceXConstructor,
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_PRINTDIALOGSERVICE_CID, false, NULL, nsPrintDialogServiceXConstructor },
|
||||
{ &kNS_IDLE_SERVICE_CID, false, NULL, nsIdleServiceXConstructor },
|
||||
{ &kNS_SYSTEMALERTSSERVICE_CID, false, NULL, OSXNotificationCenterConstructor },
|
||||
{ &kNS_NATIVEMENUSERVICE_CID, false, NULL, nsNativeMenuServiceXConstructor },
|
||||
@ -180,13 +177,10 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
|
||||
{ "@mozilla.org/chrome/chrome-native-theme;1", &kNS_THEMERENDERER_CID },
|
||||
{ "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID,
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID,
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID,
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID },
|
||||
{ "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID },
|
||||
{ "@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID },
|
||||
{ NS_PRINTDIALOGSERVICE_CONTRACTID, &kNS_PRINTDIALOGSERVICE_CID,
|
||||
mozilla::Module::MAIN_PROCESS_ONLY },
|
||||
{ NS_PRINTDIALOGSERVICE_CONTRACTID, &kNS_PRINTDIALOGSERVICE_CID },
|
||||
{ "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID },
|
||||
{ "@mozilla.org/system-alerts-service;1", &kNS_SYSTEMALERTSSERVICE_CID },
|
||||
{ "@mozilla.org/widget/nativemenuservice;1", &kNS_NATIVEMENUSERVICE_CID },
|
||||
|
@ -219,14 +219,10 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
{ &kNS_THEMERENDERER_CID, false, nullptr, nsNativeThemeGTKConstructor },
|
||||
#ifdef NS_PRINTING
|
||||
{ &kNS_PRINTSETTINGSSERVICE_CID, false, nullptr, nsPrintOptionsGTKConstructor },
|
||||
{ &kNS_PRINTER_ENUMERATOR_CID, false, nullptr, nsPrinterEnumeratorGTKConstructor,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_PRINTSESSION_CID, false, nullptr, nsPrintSessionConstructor,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_DEVICE_CONTEXT_SPEC_CID, false, nullptr, nsDeviceContextSpecGTKConstructor,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_PRINTDIALOGSERVICE_CID, false, nullptr, nsPrintDialogServiceGTKConstructor,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_PRINTER_ENUMERATOR_CID, false, nullptr, nsPrinterEnumeratorGTKConstructor },
|
||||
{ &kNS_PRINTSESSION_CID, false, nullptr, nsPrintSessionConstructor },
|
||||
{ &kNS_DEVICE_CONTEXT_SPEC_CID, false, nullptr, nsDeviceContextSpecGTKConstructor },
|
||||
{ &kNS_PRINTDIALOGSERVICE_CID, false, nullptr, nsPrintDialogServiceGTKConstructor },
|
||||
#endif
|
||||
{ &kNS_IMAGE_TO_PIXBUF_CID, false, nullptr, nsImageToPixbufConstructor },
|
||||
#if defined(MOZ_X11)
|
||||
@ -256,14 +252,10 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
|
||||
{ "@mozilla.org/chrome/chrome-native-theme;1", &kNS_THEMERENDERER_CID },
|
||||
#ifdef NS_PRINTING
|
||||
{ "@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID },
|
||||
{ "@mozilla.org/gfx/printerenumerator;1", &kNS_PRINTER_ENUMERATOR_CID,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ NS_PRINTDIALOGSERVICE_CONTRACTID, &kNS_PRINTDIALOGSERVICE_CID,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/gfx/printerenumerator;1", &kNS_PRINTER_ENUMERATOR_CID },
|
||||
{ "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID },
|
||||
{ "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID },
|
||||
{ NS_PRINTDIALOGSERVICE_CONTRACTID, &kNS_PRINTDIALOGSERVICE_CID },
|
||||
#endif
|
||||
{ "@mozilla.org/widget/image-to-gdk-pixbuf;1", &kNS_IMAGE_TO_PIXBUF_CID },
|
||||
#if defined(MOZ_X11)
|
||||
|
@ -102,6 +102,7 @@ EXPORTS += [
|
||||
'nsIRollupListener.h',
|
||||
'nsIWidget.h',
|
||||
'nsIWidgetListener.h',
|
||||
'nsPrintOptionsImpl.h',
|
||||
'nsWidgetInitData.h',
|
||||
'nsWidgetsCID.h',
|
||||
]
|
||||
|
@ -8,14 +8,23 @@
|
||||
|
||||
%{ C++
|
||||
struct nsFont;
|
||||
|
||||
namespace mozilla {
|
||||
namespace embedding {
|
||||
class PrintData;
|
||||
}
|
||||
}
|
||||
%}
|
||||
|
||||
interface nsIStringEnumerator;
|
||||
interface nsIWebBrowserPrint;
|
||||
|
||||
/**
|
||||
* Native types
|
||||
*/
|
||||
[ref] native nsNativeFontRef(nsFont);
|
||||
[ref] native PrintDataRef(const mozilla::embedding::PrintData);
|
||||
[ptr] native PrintDataPtr(mozilla::embedding::PrintData);
|
||||
|
||||
/**
|
||||
* Print options interface
|
||||
@ -24,7 +33,7 @@ interface nsIStringEnumerator;
|
||||
* John Keiser <jkeiser@netscape.com> and Roland Mainz
|
||||
* <roland.mainz@informatik.med.uni-giessen.de> for futher details.
|
||||
*/
|
||||
[scriptable, uuid(92597c2b-109b-40bb-8f93-9b9acfa31de8)]
|
||||
[scriptable, uuid(2ac74034-700e-40fd-8059-81d33223af58)]
|
||||
|
||||
interface nsIPrintOptions : nsISupports
|
||||
{
|
||||
@ -57,6 +66,39 @@ interface nsIPrintOptions : nsISupports
|
||||
const short kNativeDataPrintRecord = 0;
|
||||
|
||||
[noscript] voidPtr GetNativeData(in short aDataType);
|
||||
|
||||
/**
|
||||
* Given some nsIPrintSettings and (optionally) an nsIWebBrowserPrint, populates
|
||||
* a PrintData representing them which can be sent over IPC. Values are only
|
||||
* ever read from aSettings and aWBP.
|
||||
*
|
||||
* @param aSettings
|
||||
* An nsIPrintSettings for a print job.
|
||||
* @param aWBP (optional)
|
||||
* The nsIWebBrowserPrint for the print job.
|
||||
* @param data
|
||||
* Pointer to a pre-existing PrintData to populate.
|
||||
*
|
||||
* @return nsresult
|
||||
*/
|
||||
[noscript] void SerializeToPrintData(in nsIPrintSettings aPrintSettings,
|
||||
in nsIWebBrowserPrint aWebBrowserPrint,
|
||||
in PrintDataPtr data);
|
||||
|
||||
/**
|
||||
* This function is the opposite of SerializeToPrintData, in that it takes
|
||||
* a PrintData, and populates a pre-existing nsIPrintSettings with the data
|
||||
* from PrintData.
|
||||
*
|
||||
* @param PrintData
|
||||
* Printing information sent through IPC.
|
||||
* @param settings
|
||||
* A pre-existing nsIPrintSettings to populate with the PrintData.
|
||||
*
|
||||
* @return nsresult
|
||||
*/
|
||||
[noscript] void DeserializeToPrintSettings(in PrintDataRef data,
|
||||
in nsIPrintSettings aPrintSettings);
|
||||
};
|
||||
|
||||
[scriptable, uuid(5e738fff-404c-4c94-9189-e8f2cce93e94)]
|
||||
|
@ -3,6 +3,7 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/embedding/PPrinting.h"
|
||||
#include "nsPrintOptionsImpl.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsPrintSettingsImpl.h"
|
||||
@ -22,8 +23,10 @@
|
||||
#include "nsAutoPtr.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsPrintfCString.h"
|
||||
#include "nsIWebBrowserPrint.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::embedding;
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsPrintOptions, nsIPrintOptions, nsIPrintSettingsService)
|
||||
|
||||
@ -97,6 +100,221 @@ nsPrintOptions::Init()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintOptions::SerializeToPrintData(nsIPrintSettings* aSettings,
|
||||
nsIWebBrowserPrint* aWBP,
|
||||
PrintData* data)
|
||||
{
|
||||
aSettings->GetStartPageRange(&data->startPageRange());
|
||||
aSettings->GetEndPageRange(&data->endPageRange());
|
||||
|
||||
aSettings->GetEdgeTop(&data->edgeTop());
|
||||
aSettings->GetEdgeLeft(&data->edgeLeft());
|
||||
aSettings->GetEdgeBottom(&data->edgeBottom());
|
||||
aSettings->GetEdgeRight(&data->edgeRight());
|
||||
|
||||
aSettings->GetMarginTop(&data->marginTop());
|
||||
aSettings->GetMarginLeft(&data->marginLeft());
|
||||
aSettings->GetMarginBottom(&data->marginBottom());
|
||||
aSettings->GetMarginRight(&data->marginRight());
|
||||
aSettings->GetUnwriteableMarginTop(&data->unwriteableMarginTop());
|
||||
aSettings->GetUnwriteableMarginLeft(&data->unwriteableMarginLeft());
|
||||
aSettings->GetUnwriteableMarginBottom(&data->unwriteableMarginBottom());
|
||||
aSettings->GetUnwriteableMarginRight(&data->unwriteableMarginRight());
|
||||
|
||||
aSettings->GetScaling(&data->scaling());
|
||||
|
||||
aSettings->GetPrintBGColors(&data->printBGColors());
|
||||
aSettings->GetPrintBGImages(&data->printBGImages());
|
||||
aSettings->GetPrintRange(&data->printRange());
|
||||
|
||||
// I have no idea if I'm doing this string copying correctly...
|
||||
nsXPIDLString title;
|
||||
aSettings->GetTitle(getter_Copies(title));
|
||||
data->title() = title;
|
||||
|
||||
nsXPIDLString docURL;
|
||||
aSettings->GetDocURL(getter_Copies(docURL));
|
||||
data->docURL() = docURL;
|
||||
|
||||
// Header strings...
|
||||
nsXPIDLString headerStrLeft;
|
||||
aSettings->GetHeaderStrLeft(getter_Copies(headerStrLeft));
|
||||
data->headerStrLeft() = headerStrLeft;
|
||||
|
||||
nsXPIDLString headerStrCenter;
|
||||
aSettings->GetHeaderStrCenter(getter_Copies(headerStrCenter));
|
||||
data->headerStrCenter() = headerStrCenter;
|
||||
|
||||
nsXPIDLString headerStrRight;
|
||||
aSettings->GetHeaderStrRight(getter_Copies(headerStrRight));
|
||||
data->headerStrRight() = headerStrRight;
|
||||
|
||||
// Footer strings...
|
||||
nsXPIDLString footerStrLeft;
|
||||
aSettings->GetFooterStrLeft(getter_Copies(footerStrLeft));
|
||||
data->footerStrLeft() = footerStrLeft;
|
||||
|
||||
nsXPIDLString footerStrCenter;
|
||||
aSettings->GetFooterStrCenter(getter_Copies(footerStrCenter));
|
||||
data->footerStrCenter() = footerStrCenter;
|
||||
|
||||
nsXPIDLString footerStrRight;
|
||||
aSettings->GetFooterStrRight(getter_Copies(footerStrRight));
|
||||
data->footerStrRight() = footerStrRight;
|
||||
|
||||
aSettings->GetHowToEnableFrameUI(&data->howToEnableFrameUI());
|
||||
aSettings->GetIsCancelled(&data->isCancelled());
|
||||
aSettings->GetPrintFrameTypeUsage(&data->printFrameTypeUsage());
|
||||
aSettings->GetPrintFrameType(&data->printFrameType());
|
||||
aSettings->GetPrintSilent(&data->printSilent());
|
||||
aSettings->GetShrinkToFit(&data->shrinkToFit());
|
||||
aSettings->GetShowPrintProgress(&data->showPrintProgress());
|
||||
|
||||
nsXPIDLString paperName;
|
||||
aSettings->GetPaperName(getter_Copies(paperName));
|
||||
data->paperName() = paperName;
|
||||
|
||||
aSettings->GetPaperSizeType(&data->paperSizeType());
|
||||
aSettings->GetPaperData(&data->paperData());
|
||||
aSettings->GetPaperWidth(&data->paperWidth());
|
||||
aSettings->GetPaperHeight(&data->paperHeight());
|
||||
aSettings->GetPaperSizeUnit(&data->paperSizeUnit());
|
||||
|
||||
nsXPIDLString plexName;
|
||||
aSettings->GetPlexName(getter_Copies(plexName));
|
||||
data->plexName() = plexName;
|
||||
|
||||
nsXPIDLString colorspace;
|
||||
aSettings->GetColorspace(getter_Copies(colorspace));
|
||||
data->colorspace() = colorspace;
|
||||
|
||||
nsXPIDLString resolutionName;
|
||||
aSettings->GetResolutionName(getter_Copies(resolutionName));
|
||||
data->resolutionName() = resolutionName;
|
||||
|
||||
aSettings->GetDownloadFonts(&data->downloadFonts());
|
||||
aSettings->GetPrintReversed(&data->printReversed());
|
||||
aSettings->GetPrintInColor(&data->printInColor());
|
||||
aSettings->GetOrientation(&data->orientation());
|
||||
|
||||
nsXPIDLString printCommand;
|
||||
aSettings->GetPrintCommand(getter_Copies(printCommand));
|
||||
data->printCommand() = printCommand;
|
||||
|
||||
aSettings->GetNumCopies(&data->numCopies());
|
||||
|
||||
nsXPIDLString printerName;
|
||||
aSettings->GetPrinterName(getter_Copies(printerName));
|
||||
data->printerName() = printerName;
|
||||
|
||||
aSettings->GetPrintToFile(&data->printToFile());
|
||||
|
||||
nsXPIDLString toFileName;
|
||||
aSettings->GetToFileName(getter_Copies(toFileName));
|
||||
data->toFileName() = toFileName;
|
||||
|
||||
aSettings->GetOutputFormat(&data->outputFormat());
|
||||
aSettings->GetPrintPageDelay(&data->printPageDelay());
|
||||
aSettings->GetResolution(&data->resolution());
|
||||
aSettings->GetDuplex(&data->duplex());
|
||||
aSettings->GetIsInitializedFromPrinter(&data->isInitializedFromPrinter());
|
||||
aSettings->GetIsInitializedFromPrefs(&data->isInitializedFromPrefs());
|
||||
aSettings->GetPersistMarginBoxSettings(&data->persistMarginBoxSettings());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintOptions::DeserializeToPrintSettings(const PrintData& data,
|
||||
nsIPrintSettings* settings)
|
||||
{
|
||||
settings->SetStartPageRange(data.startPageRange());
|
||||
settings->SetEndPageRange(data.endPageRange());
|
||||
|
||||
settings->SetEdgeTop(data.edgeTop());
|
||||
settings->SetEdgeLeft(data.edgeLeft());
|
||||
settings->SetEdgeBottom(data.edgeBottom());
|
||||
settings->SetEdgeRight(data.edgeRight());
|
||||
|
||||
settings->SetMarginTop(data.marginTop());
|
||||
settings->SetMarginLeft(data.marginLeft());
|
||||
settings->SetMarginBottom(data.marginBottom());
|
||||
settings->SetMarginRight(data.marginRight());
|
||||
settings->SetUnwriteableMarginTop(data.unwriteableMarginTop());
|
||||
settings->SetUnwriteableMarginLeft(data.unwriteableMarginLeft());
|
||||
settings->SetUnwriteableMarginBottom(data.unwriteableMarginBottom());
|
||||
settings->SetUnwriteableMarginRight(data.unwriteableMarginRight());
|
||||
|
||||
settings->SetScaling(data.scaling());
|
||||
|
||||
settings->SetPrintBGColors(data.printBGColors());
|
||||
settings->SetPrintBGImages(data.printBGImages());
|
||||
settings->SetPrintRange(data.printRange());
|
||||
|
||||
// I have no idea if I'm doing this string copying correctly...
|
||||
settings->SetTitle(data.title().get());
|
||||
settings->SetDocURL(data.docURL().get());
|
||||
|
||||
// Header strings...
|
||||
settings->SetHeaderStrLeft(data.headerStrLeft().get());
|
||||
settings->SetHeaderStrCenter(data.headerStrCenter().get());
|
||||
settings->SetHeaderStrRight(data.headerStrRight().get());
|
||||
|
||||
// Footer strings...
|
||||
settings->SetFooterStrLeft(data.footerStrLeft().get());
|
||||
settings->SetFooterStrCenter(data.footerStrCenter().get());
|
||||
settings->SetFooterStrRight(data.footerStrRight().get());
|
||||
|
||||
settings->SetHowToEnableFrameUI(data.howToEnableFrameUI());
|
||||
settings->SetIsCancelled(data.isCancelled());
|
||||
settings->SetPrintFrameTypeUsage(data.printFrameTypeUsage());
|
||||
settings->SetPrintFrameType(data.printFrameType());
|
||||
settings->SetPrintSilent(data.printSilent());
|
||||
settings->SetShrinkToFit(data.shrinkToFit());
|
||||
settings->SetShowPrintProgress(data.showPrintProgress());
|
||||
|
||||
settings->SetPaperName(data.paperName().get());
|
||||
|
||||
settings->SetPaperSizeType(data.paperSizeType());
|
||||
settings->SetPaperData(data.paperData());
|
||||
settings->SetPaperWidth(data.paperWidth());
|
||||
settings->SetPaperHeight(data.paperHeight());
|
||||
settings->SetPaperSizeUnit(data.paperSizeUnit());
|
||||
|
||||
settings->SetPlexName(data.plexName().get());
|
||||
|
||||
settings->SetColorspace(data.colorspace().get());
|
||||
|
||||
settings->SetResolutionName(data.resolutionName().get());
|
||||
|
||||
settings->SetDownloadFonts(data.downloadFonts());
|
||||
settings->SetPrintReversed(data.printReversed());
|
||||
settings->SetPrintInColor(data.printInColor());
|
||||
settings->SetOrientation(data.orientation());
|
||||
|
||||
settings->SetPrintCommand(data.printCommand().get());
|
||||
|
||||
settings->SetNumCopies(data.numCopies());
|
||||
|
||||
settings->SetPrinterName(data.printerName().get());
|
||||
|
||||
settings->SetPrintToFile(data.printToFile());
|
||||
|
||||
settings->SetToFileName(data.toFileName().get());
|
||||
|
||||
settings->SetOutputFormat(data.outputFormat());
|
||||
settings->SetPrintPageDelay(data.printPageDelay());
|
||||
settings->SetResolution(data.resolution());
|
||||
settings->SetDuplex(data.duplex());
|
||||
settings->SetIsInitializedFromPrinter(data.isInitializedFromPrinter());
|
||||
settings->SetIsInitializedFromPrefs(data.isInitializedFromPrefs());
|
||||
settings->SetPersistMarginBoxSettings(data.persistMarginBoxSettings());
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintOptions::ShowPrintSetupDialog(nsIPrintSettings *aPS)
|
||||
{
|
||||
|
@ -7,12 +7,16 @@
|
||||
#ifndef nsPrintOptionsImpl_h__
|
||||
#define nsPrintOptionsImpl_h__
|
||||
|
||||
#include "mozilla/embedding/PPrinting.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPrintOptions.h"
|
||||
#include "nsIPrintSettingsService.h"
|
||||
#include "nsString.h"
|
||||
#include "nsFont.h"
|
||||
|
||||
class nsIPrintSettings;
|
||||
class nsIWebBrowserPrint;
|
||||
|
||||
/**
|
||||
* Class nsPrintOptions
|
||||
*/
|
||||
|
@ -5,11 +5,16 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsPrintOptionsWin.h"
|
||||
#include "nsPrintSettingsWin.h"
|
||||
#include "nsPrintDialogUtil.h"
|
||||
|
||||
#include "nsGfxCIID.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIWebBrowserPrint.h"
|
||||
|
||||
const char kPrinterEnumeratorContractID[] = "@mozilla.org/gfx/printerenumerator;1";
|
||||
|
||||
using namespace mozilla::embedding;
|
||||
|
||||
/** ---------------------------------------------------
|
||||
* See documentation in nsPrintOptionsWin.h
|
||||
* @update 6/21/00 dwc
|
||||
@ -27,6 +32,71 @@ nsPrintOptionsWin::~nsPrintOptionsWin()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintOptionsWin::SerializeToPrintData(nsIPrintSettings* aSettings,
|
||||
nsIWebBrowserPrint* aWBP,
|
||||
PrintData* data)
|
||||
{
|
||||
nsresult rv = nsPrintOptions::SerializeToPrintData(aSettings, aWBP, data);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Windows wants this information for its print dialogs
|
||||
if (aWBP) {
|
||||
aWBP->GetIsFramesetDocument(&data->isFramesetDocument());
|
||||
aWBP->GetIsFramesetFrameSelected(&data->isFramesetFrameSelected());
|
||||
aWBP->GetIsIFrameSelected(&data->isIFrameSelected());
|
||||
aWBP->GetIsRangeSelection(&data->isRangeSelection());
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aSettings);
|
||||
if (!psWin) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
char16_t* deviceName;
|
||||
char16_t* driverName;
|
||||
|
||||
psWin->GetDeviceName(&deviceName);
|
||||
psWin->GetDriverName(&driverName);
|
||||
|
||||
data->deviceName().Assign(deviceName);
|
||||
data->driverName().Assign(driverName);
|
||||
|
||||
free(deviceName);
|
||||
free(driverName);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPrintOptionsWin::DeserializeToPrintSettings(const PrintData& data,
|
||||
nsIPrintSettings* settings)
|
||||
{
|
||||
nsresult rv = nsPrintOptions::DeserializeToPrintSettings(data, settings);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(settings);
|
||||
if (!settings) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
psWin->SetDeviceName(data.deviceName().get());
|
||||
psWin->SetDriverName(data.driverName().get());
|
||||
|
||||
// We also need to prepare a DevMode and stuff it into our newly
|
||||
// created nsIPrintSettings...
|
||||
nsXPIDLString printerName;
|
||||
settings->GetPrinterName(getter_Copies(printerName));
|
||||
HGLOBAL gDevMode = CreateGlobalDevModeAndInit(printerName, settings);
|
||||
LPDEVMODEW devMode = (LPDEVMODEW)::GlobalLock(gDevMode);
|
||||
psWin->SetDevMode(devMode);
|
||||
|
||||
::GlobalUnlock(gDevMode);
|
||||
::GlobalFree(gDevMode);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIPrintSettings CreatePrintSettings (); */
|
||||
nsresult nsPrintOptionsWin::_CreatePrintSettings(nsIPrintSettings **_retval)
|
||||
{
|
||||
|
@ -7,8 +7,11 @@
|
||||
#ifndef nsPrintOptionsWin_h__
|
||||
#define nsPrintOptionsWin_h__
|
||||
|
||||
#include "mozilla/embedding/PPrinting.h"
|
||||
#include "nsPrintOptionsImpl.h"
|
||||
|
||||
class nsIPrintSettings;
|
||||
class nsIWebBrowserPrint;
|
||||
|
||||
//*****************************************************************************
|
||||
//*** nsPrintOptions
|
||||
@ -19,6 +22,12 @@ public:
|
||||
nsPrintOptionsWin();
|
||||
virtual ~nsPrintOptionsWin();
|
||||
|
||||
NS_IMETHODIMP SerializeToPrintData(nsIPrintSettings* aSettings,
|
||||
nsIWebBrowserPrint* aWBP,
|
||||
mozilla::embedding::PrintData* data);
|
||||
NS_IMETHODIMP DeserializeToPrintSettings(const mozilla::embedding::PrintData& data,
|
||||
nsIPrintSettings* settings);
|
||||
|
||||
virtual nsresult _CreatePrintSettings(nsIPrintSettings **_retval);
|
||||
};
|
||||
|
||||
|
@ -244,12 +244,9 @@ static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
|
||||
#endif
|
||||
#ifdef NS_PRINTING
|
||||
{ &kNS_PRINTSETTINGSSERVICE_CID, false, nullptr, nsPrintOptionsWinConstructor },
|
||||
{ &kNS_PRINTER_ENUMERATOR_CID, false, nullptr, nsPrinterEnumeratorWinConstructor,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_PRINTSESSION_CID, false, nullptr, nsPrintSessionConstructor,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_DEVICE_CONTEXT_SPEC_CID, false, nullptr, nsDeviceContextSpecWinConstructor,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ &kNS_PRINTER_ENUMERATOR_CID, false, nullptr, nsPrinterEnumeratorWinConstructor },
|
||||
{ &kNS_PRINTSESSION_CID, false, nullptr, nsPrintSessionConstructor },
|
||||
{ &kNS_DEVICE_CONTEXT_SPEC_CID, false, nullptr, nsDeviceContextSpecWinConstructor },
|
||||
#endif
|
||||
{ nullptr }
|
||||
};
|
||||
@ -282,12 +279,9 @@ static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
|
||||
#endif
|
||||
#ifdef NS_PRINTING
|
||||
{ "@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID },
|
||||
{ "@mozilla.org/gfx/printerenumerator;1", &kNS_PRINTER_ENUMERATOR_CID,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID,
|
||||
Module::MAIN_PROCESS_ONLY },
|
||||
{ "@mozilla.org/gfx/printerenumerator;1", &kNS_PRINTER_ENUMERATOR_CID },
|
||||
{ "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID },
|
||||
{ "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID },
|
||||
#endif
|
||||
{ nullptr }
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user