mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 10:44:56 +00:00
Merge m-c to b2ginbound a=merge
This commit is contained in:
commit
12cb0ea254
@ -221,7 +221,7 @@ gint
|
||||
getStartIndexCB(AtkHyperlink *aLink)
|
||||
{
|
||||
MaiHyperlink* maiLink = GetMaiHyperlink(aLink);
|
||||
if (maiLink)
|
||||
if (!maiLink)
|
||||
return -1;
|
||||
|
||||
if (Accessible* hyperlink = maiLink->GetAccHyperlink())
|
||||
|
@ -30,19 +30,14 @@ html xul|scrollbar {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Scrollbar code will reset the margin to the correct side depending on
|
||||
where layout actually puts the scrollbar */
|
||||
xul|scrollbar[orient="vertical"] {
|
||||
-moz-margin-start: -8px;
|
||||
margin-left: -8px;
|
||||
min-width: 8px;
|
||||
max-width: 8px;
|
||||
}
|
||||
|
||||
/* workaround for bug 1119057: as -moz-margin-start may not work as expected,
|
||||
* force a right margin value in RTL mode. */
|
||||
[dir="rtl"] xul|scrollbar[root="true"][orient="vertical"] {
|
||||
-moz-margin-start: unset;
|
||||
margin-right: -8px;
|
||||
}
|
||||
|
||||
xul|scrollbar[orient="vertical"] xul|thumb {
|
||||
max-width: 6px !important;
|
||||
min-width: 6px !important;
|
||||
|
@ -555,8 +555,7 @@
|
||||
<parameter name="aCallback"/>
|
||||
<body><![CDATA[
|
||||
let cb = this.chatboxForURL.get(aURL);
|
||||
if (cb) {
|
||||
cb = cb.get();
|
||||
if (cb && (cb = cb.get())) {
|
||||
// A chatbox is still alive to us when it's parented and still has
|
||||
// content.
|
||||
if (cb.parentNode && cb.contentWindow) {
|
||||
|
@ -340,7 +340,6 @@ skip-if = asan # Disabled because it takes a long time (see test for more inform
|
||||
|
||||
[browser_pinnedTabs.js]
|
||||
[browser_plainTextLinks.js]
|
||||
skip-if = e10s # Bug 1093155 - tries to use context menu from browser-chrome and gets in a mess when in e10s mode
|
||||
[browser_popupUI.js]
|
||||
skip-if = buildapp == 'mulet'
|
||||
[browser_popup_blocker.js]
|
||||
|
@ -1,115 +1,146 @@
|
||||
let doc, range, selection;
|
||||
function setSelection(el1, el2, index1, index2) {
|
||||
while (el1.nodeType != Node.TEXT_NODE)
|
||||
el1 = el1.firstChild;
|
||||
while (el2.nodeType != Node.TEXT_NODE)
|
||||
el2 = el2.firstChild;
|
||||
|
||||
selection.removeAllRanges();
|
||||
range.setStart(el1, index1);
|
||||
range.setEnd(el2, index2);
|
||||
selection.addRange(range);
|
||||
function testExpected(expected, msg) {
|
||||
is(document.getElementById("context-openlinkincurrent").hidden, expected, msg);
|
||||
}
|
||||
|
||||
function initContextMenu(aNode) {
|
||||
document.popupNode = aNode;
|
||||
function testLinkExpected(expected, msg) {
|
||||
is(gContextMenu.linkURL, expected, msg);
|
||||
}
|
||||
|
||||
add_task(function *() {
|
||||
const url = "data:text/html;charset=UTF-8,Test For Non-Hyperlinked url selection";
|
||||
yield BrowserTestUtils.openNewForegroundTab(gBrowser, url);
|
||||
|
||||
yield SimpleTest.promiseFocus(gBrowser.selectedBrowser.contentWindowAsCPOW);
|
||||
|
||||
// Initial setup of the content area.
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, { }, function* (arg) {
|
||||
let doc = content.document;
|
||||
let range = doc.createRange();
|
||||
let selection = content.getSelection();
|
||||
|
||||
let mainDiv = doc.createElement("div");
|
||||
let div = doc.createElement("div");
|
||||
let div2 = doc.createElement("div");
|
||||
let span1 = doc.createElement("span");
|
||||
let span2 = doc.createElement("span");
|
||||
let span3 = doc.createElement("span");
|
||||
let span4 = doc.createElement("span");
|
||||
let p1 = doc.createElement("p");
|
||||
let p2 = doc.createElement("p");
|
||||
span1.textContent = "http://index.";
|
||||
span2.textContent = "example.com example.com";
|
||||
span3.textContent = " - Test";
|
||||
span4.innerHTML = "<a href='http://www.example.com'>http://www.example.com/example</a>";
|
||||
p1.textContent = "mailto:test.com ftp.example.com";
|
||||
p2.textContent = "example.com -";
|
||||
div.appendChild(span1);
|
||||
div.appendChild(span2);
|
||||
div.appendChild(span3);
|
||||
div.appendChild(span4);
|
||||
div.appendChild(p1);
|
||||
div.appendChild(p2);
|
||||
let p3 = doc.createElement("p");
|
||||
p3.textContent = "main.example.com";
|
||||
div2.appendChild(p3);
|
||||
mainDiv.appendChild(div);
|
||||
mainDiv.appendChild(div2);
|
||||
doc.body.appendChild(mainDiv);
|
||||
|
||||
function setSelection(el1, el2, index1, index2) {
|
||||
while (el1.nodeType != el1.TEXT_NODE)
|
||||
el1 = el1.firstChild;
|
||||
while (el2.nodeType != el1.TEXT_NODE)
|
||||
el2 = el2.firstChild;
|
||||
|
||||
selection.removeAllRanges();
|
||||
range.setStart(el1, index1);
|
||||
range.setEnd(el2, index2);
|
||||
selection.addRange(range);
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
// Each of these tests creates a selection and returns a range within it.
|
||||
content.tests = [
|
||||
() => setSelection(span1.firstChild, span2.firstChild, 0, 11),
|
||||
() => setSelection(span1.firstChild, span2.firstChild, 7, 11),
|
||||
() => setSelection(span1.firstChild, span2.firstChild, 8, 11),
|
||||
() => setSelection(span2.firstChild, span2.firstChild, 0, 11),
|
||||
() => setSelection(span2.firstChild, span2.firstChild, 11, 23),
|
||||
() => setSelection(span2.firstChild, span2.firstChild, 0, 10),
|
||||
() => setSelection(span2.firstChild, span3.firstChild, 12, 7),
|
||||
() => setSelection(span2.firstChild, span2.firstChild, 12, 19),
|
||||
() => setSelection(p1.firstChild, p1.firstChild, 0, 15),
|
||||
() => setSelection(p1.firstChild, p1.firstChild, 16, 31),
|
||||
() => setSelection(p2.firstChild, p2.firstChild, 0, 14),
|
||||
() => {
|
||||
selection.selectAllChildren(div2);
|
||||
return selection.getRangeAt(0);
|
||||
},
|
||||
() => {
|
||||
selection.selectAllChildren(span4);
|
||||
return selection.getRangeAt(0);
|
||||
},
|
||||
() => {
|
||||
mainDiv.innerHTML = "(open-suse.ru)";
|
||||
return setSelection(mainDiv, mainDiv, 1, 13);
|
||||
},
|
||||
() => setSelection(mainDiv, mainDiv, 1, 14)
|
||||
];
|
||||
});
|
||||
|
||||
let checks = [
|
||||
() => testExpected(false, "The link context menu should show for http://www.example.com"),
|
||||
() => testExpected(false, "The link context menu should show for www.example.com"),
|
||||
() => testExpected(true, "The link context menu should not show for ww.example.com"),
|
||||
() => {
|
||||
testExpected(false, "The link context menu should show for example.com");
|
||||
testLinkExpected("http://example.com/", "url for example.com selection should not prepend www");
|
||||
},
|
||||
() => testExpected(false, "The link context menu should show for example.com"),
|
||||
() => testExpected(true, "Link options should not show for selection that's not at a word boundary"),
|
||||
() => testExpected(true, "Link options should not show for selection that has whitespace"),
|
||||
() => testExpected(true, "Link options should not show unless a url is selected"),
|
||||
() => testExpected(true, "Link options should not show for mailto: links"),
|
||||
() => {
|
||||
testExpected(false, "Link options should show for ftp.example.com");
|
||||
testLinkExpected("ftp://ftp.example.com/", "ftp.example.com should be preceeded with ftp://");
|
||||
},
|
||||
() => testExpected(false, "Link options should show for www.example.com "),
|
||||
() => testExpected(false, "Link options should show for triple-click selections"),
|
||||
() => testLinkExpected("http://www.example.com/", "Linkified text should open the correct link"),
|
||||
() => {
|
||||
testExpected(false, "Link options should show for open-suse.ru");
|
||||
testLinkExpected("http://open-suse.ru/", "Linkified text should open the correct link");
|
||||
},
|
||||
() => testExpected(true, "Link options should not show for 'open-suse.ru)'")
|
||||
];
|
||||
|
||||
let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
|
||||
let contextMenu = new nsContextMenu(contentAreaContextMenu);
|
||||
return contextMenu;
|
||||
}
|
||||
|
||||
function testExpected(expected, msg, aNode) {
|
||||
let popupNode = aNode || doc.getElementsByTagName("DIV")[0];
|
||||
initContextMenu(popupNode);
|
||||
let linkMenuItem = document.getElementById("context-openlinkincurrent");
|
||||
is(linkMenuItem.hidden, expected, msg);
|
||||
}
|
||||
for (let testid = 0; testid < checks.length; testid++) {
|
||||
let menuPosition = yield ContentTask.spawn(gBrowser.selectedBrowser, { testid: testid }, function* (arg) {
|
||||
let range = content.tests[arg.testid]();
|
||||
|
||||
function testLinkExpected(expected, msg, aNode) {
|
||||
let popupNode = aNode || doc.getElementsByTagName("DIV")[0];
|
||||
let contextMenu = initContextMenu(popupNode);
|
||||
is(contextMenu.linkURL, expected, msg);
|
||||
}
|
||||
// Get the range of the selection and determine its coordinates. These
|
||||
// coordinates will be returned to the parent process and the context menu
|
||||
// will be opened at that location.
|
||||
let rangeRect = range.getBoundingClientRect();
|
||||
return [rangeRect.x + 3, rangeRect.y + 3];
|
||||
});
|
||||
|
||||
function runSelectionTests() {
|
||||
let mainDiv = doc.createElement("div");
|
||||
let div = doc.createElement("div");
|
||||
let div2 = doc.createElement("div");
|
||||
let span1 = doc.createElement("span");
|
||||
let span2 = doc.createElement("span");
|
||||
let span3 = doc.createElement("span");
|
||||
let span4 = doc.createElement("span");
|
||||
let p1 = doc.createElement("p");
|
||||
let p2 = doc.createElement("p");
|
||||
span1.textContent = "http://index.";
|
||||
span2.textContent = "example.com example.com";
|
||||
span3.textContent = " - Test";
|
||||
span4.innerHTML = "<a href='http://www.example.com'>http://www.example.com/example</a>";
|
||||
p1.textContent = "mailto:test.com ftp.example.com";
|
||||
p2.textContent = "example.com -";
|
||||
div.appendChild(span1);
|
||||
div.appendChild(span2);
|
||||
div.appendChild(span3);
|
||||
div.appendChild(span4);
|
||||
div.appendChild(p1);
|
||||
div.appendChild(p2);
|
||||
let p3 = doc.createElement("p");
|
||||
p3.textContent = "main.example.com";
|
||||
div2.appendChild(p3);
|
||||
mainDiv.appendChild(div);
|
||||
mainDiv.appendChild(div2);
|
||||
doc.body.appendChild(mainDiv);
|
||||
setSelection(span1.firstChild, span2.firstChild, 0, 11);
|
||||
testExpected(false, "The link context menu should show for http://www.example.com");
|
||||
setSelection(span1.firstChild, span2.firstChild, 7, 11);
|
||||
testExpected(false, "The link context menu should show for www.example.com");
|
||||
setSelection(span1.firstChild, span2.firstChild, 8, 11);
|
||||
testExpected(true, "The link context menu should not show for ww.example.com");
|
||||
setSelection(span2.firstChild, span2.firstChild, 0, 11);
|
||||
testExpected(false, "The link context menu should show for example.com");
|
||||
testLinkExpected("http://example.com/", "url for example.com selection should not prepend www");
|
||||
setSelection(span2.firstChild, span2.firstChild, 11, 23);
|
||||
testExpected(false, "The link context menu should show for example.com");
|
||||
setSelection(span2.firstChild, span2.firstChild, 0, 10);
|
||||
testExpected(true, "Link options should not show for selection that's not at a word boundary");
|
||||
setSelection(span2.firstChild, span3.firstChild, 12, 7);
|
||||
testExpected(true, "Link options should not show for selection that has whitespace");
|
||||
setSelection(span2.firstChild, span2.firstChild, 12, 19);
|
||||
testExpected(true, "Link options should not show unless a url is selected");
|
||||
setSelection(p1.firstChild, p1.firstChild, 0, 15);
|
||||
testExpected(true, "Link options should not show for mailto: links");
|
||||
setSelection(p1.firstChild, p1.firstChild, 16, 31);
|
||||
testExpected(false, "Link options should show for ftp.example.com");
|
||||
testLinkExpected("ftp://ftp.example.com/", "ftp.example.com should be preceeded with ftp://");
|
||||
setSelection(p2.firstChild, p2.firstChild, 0, 14);
|
||||
testExpected(false, "Link options should show for www.example.com ");
|
||||
selection.selectAllChildren(div2);
|
||||
testExpected(false, "Link options should show for triple-click selections");
|
||||
selection.selectAllChildren(span4);
|
||||
testLinkExpected("http://www.example.com/", "Linkified text should open the correct link", span4.firstChild);
|
||||
let popupShownPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popupshown");
|
||||
yield BrowserTestUtils.synthesizeMouseAtPoint(menuPosition[0], menuPosition[1],
|
||||
{ type: "contextmenu", button: 2 }, gBrowser.selectedBrowser);
|
||||
yield popupShownPromise;
|
||||
|
||||
mainDiv.innerHTML = "(open-suse.ru)";
|
||||
setSelection(mainDiv, mainDiv, 1, 13);
|
||||
testExpected(false, "Link options should show for open-suse.ru");
|
||||
testLinkExpected("http://open-suse.ru/", "Linkified text should open the correct link");
|
||||
setSelection(mainDiv, mainDiv, 1, 14);
|
||||
testExpected(true, "Link options should not show for 'open-suse.ru)'");
|
||||
checks[testid]();
|
||||
|
||||
let popupHiddenPromise = BrowserTestUtils.waitForEvent(contentAreaContextMenu, "popuphidden");
|
||||
contentAreaContextMenu.hidePopup();
|
||||
yield popupHiddenPromise;
|
||||
}
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
range = doc.createRange();
|
||||
selection = content.getSelection();
|
||||
waitForFocus(runSelectionTests, content);
|
||||
}, true);
|
||||
|
||||
content.location =
|
||||
"data:text/html;charset=UTF-8,Test For Non-Hyperlinked url selection";
|
||||
}
|
||||
|
@ -123,10 +123,10 @@ browser.jar:
|
||||
* content/browser/sync/aboutSyncTabs.js (content/sync/aboutSyncTabs.js)
|
||||
content/browser/sync/aboutSyncTabs.css (content/sync/aboutSyncTabs.css)
|
||||
content/browser/sync/aboutSyncTabs-bindings.xml (content/sync/aboutSyncTabs-bindings.xml)
|
||||
* content/browser/sync/setup.xul (content/sync/setup.xul)
|
||||
content/browser/sync/setup.xul (content/sync/setup.xul)
|
||||
content/browser/sync/addDevice.js (content/sync/addDevice.js)
|
||||
content/browser/sync/addDevice.xul (content/sync/addDevice.xul)
|
||||
* content/browser/sync/setup.js (content/sync/setup.js)
|
||||
content/browser/sync/setup.js (content/sync/setup.js)
|
||||
content/browser/sync/genericChange.xul (content/sync/genericChange.xul)
|
||||
content/browser/sync/genericChange.js (content/sync/genericChange.js)
|
||||
content/browser/sync/key.xhtml (content/sync/key.xhtml)
|
||||
|
@ -35,9 +35,6 @@
|
||||
// Eslint built-in rules are documented at <http://eslint.org/docs/rules/>
|
||||
"camelcase": 0, // TODO: Remove (use default)
|
||||
"consistent-return": 0, // TODO: Remove (use default)
|
||||
"curly": 0, // TODO: Remove (use default)
|
||||
"dot-notation": 0, // TODO: Remove (use default)
|
||||
"eol-last": 0, // TODO: Remove (use default)
|
||||
"eqeqeq": 0, // TBD. Might need to be separate for content & chrome
|
||||
"global-strict": 0, // Leave as zero (this will be unsupported in eslint 1.0.0)
|
||||
"key-spacing": 0, // TODO: Remove (use default)
|
||||
@ -60,10 +57,7 @@
|
||||
"no-use-before-define": 0, // TODO: Remove (use default)
|
||||
"no-wrap-func": 0, // TODO: Remove (use default)
|
||||
"quotes": 0, // [2, "double", "avoid-escape"],
|
||||
"space-infix-ops": 0, // TODO: Remove (use default)
|
||||
"space-return-throw-case": 0, // TODO: Remove (use default)
|
||||
"strict": 0, // [2, "function"],
|
||||
"yoda": 0, // [2, "never"],
|
||||
// eslint-plugin-react rules. These are documented at
|
||||
// <https://github.com/yannickcr/eslint-plugin-react#list-of-supported-rules>
|
||||
"react/jsx-quotes": [2, "double", "avoid-escape"],
|
||||
|
@ -693,7 +693,7 @@ loop.contacts = (function(_, mozL10n) {
|
||||
};
|
||||
var tel = this.state.tel.trim();
|
||||
if (!!tel) {
|
||||
contact["tel"] = [{
|
||||
contact.tel = [{
|
||||
pref: true,
|
||||
type: ["fxos"],
|
||||
value: tel
|
||||
|
@ -693,7 +693,7 @@ loop.contacts = (function(_, mozL10n) {
|
||||
};
|
||||
var tel = this.state.tel.trim();
|
||||
if (!!tel) {
|
||||
contact["tel"] = [{
|
||||
contact.tel = [{
|
||||
pref: true,
|
||||
type: ["fxos"],
|
||||
value: tel
|
||||
|
@ -334,7 +334,8 @@ loop.store = loop.store || {};
|
||||
* @param {sharedActions.EmailRoomUrl} actionData The action data.
|
||||
*/
|
||||
emailRoomUrl: function(actionData) {
|
||||
loop.shared.utils.composeCallUrlEmail(actionData.roomUrl);
|
||||
loop.shared.utils.composeCallUrlEmail(actionData.roomUrl, null,
|
||||
actionData.roomDescription);
|
||||
this._mozLoop.notifyUITour("Loop:RoomURLEmailed");
|
||||
},
|
||||
|
||||
|
@ -194,8 +194,13 @@ loop.roomViews = (function(mozL10n) {
|
||||
handleEmailButtonClick: function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
var roomData = this.props.roomData;
|
||||
var contextURL = roomData.roomContextUrls && roomData.roomContextUrls[0];
|
||||
this.props.dispatcher.dispatch(
|
||||
new sharedActions.EmailRoomUrl({roomUrl: this.props.roomData.roomUrl}));
|
||||
new sharedActions.EmailRoomUrl({
|
||||
roomUrl: roomData.roomUrl,
|
||||
roomDescription: contextURL && contextURL.description
|
||||
}));
|
||||
},
|
||||
|
||||
handleCopyButtonClick: function(event) {
|
||||
@ -461,8 +466,9 @@ loop.roomViews = (function(mozL10n) {
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (!this.state.show && !this.state.editMode)
|
||||
if (!this.state.show && !this.state.editMode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var url = this._getURL();
|
||||
var thumbnail = url && url.thumbnail || "";
|
||||
|
@ -194,8 +194,13 @@ loop.roomViews = (function(mozL10n) {
|
||||
handleEmailButtonClick: function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
var roomData = this.props.roomData;
|
||||
var contextURL = roomData.roomContextUrls && roomData.roomContextUrls[0];
|
||||
this.props.dispatcher.dispatch(
|
||||
new sharedActions.EmailRoomUrl({roomUrl: this.props.roomData.roomUrl}));
|
||||
new sharedActions.EmailRoomUrl({
|
||||
roomUrl: roomData.roomUrl,
|
||||
roomDescription: contextURL && contextURL.description
|
||||
}));
|
||||
},
|
||||
|
||||
handleCopyButtonClick: function(event) {
|
||||
@ -461,8 +466,9 @@ loop.roomViews = (function(mozL10n) {
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (!this.state.show && !this.state.editMode)
|
||||
if (!this.state.show && !this.state.editMode) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var url = this._getURL();
|
||||
var thumbnail = url && url.thumbnail || "";
|
||||
|
@ -362,6 +362,7 @@ loop.shared.actions = (function() {
|
||||
*/
|
||||
EmailRoomUrl: Action.define("emailRoomUrl", {
|
||||
roomUrl: String
|
||||
// roomDescription: String, Optional.
|
||||
}),
|
||||
|
||||
/**
|
||||
|
@ -464,7 +464,7 @@ loop.store.ActiveRoomStore = (function() {
|
||||
this._setRefreshTimeout(actionData.expires);
|
||||
|
||||
// Only send media telemetry on one side of the call: the desktop side.
|
||||
actionData["sendTwoWayMediaTelemetry"] = this._isDesktop;
|
||||
actionData.sendTwoWayMediaTelemetry = this._isDesktop;
|
||||
|
||||
this._sdkDriver.connectSession(actionData);
|
||||
|
||||
|
@ -120,10 +120,12 @@ loop.shared.mixins = (function() {
|
||||
if (!menu) {
|
||||
return;
|
||||
}
|
||||
if (menu.style.maxWidth)
|
||||
if (menu.style.maxWidth) {
|
||||
menu.style.maxWidth = "none";
|
||||
if (menu.style.maxHeight)
|
||||
}
|
||||
if (menu.style.maxHeight) {
|
||||
menu.style.maxHeight = "none";
|
||||
}
|
||||
|
||||
// Correct the position of the menu only if necessary.
|
||||
var x, y, boundingBox, boundingRect;
|
||||
@ -453,7 +455,7 @@ loop.shared.mixins = (function() {
|
||||
remoteVideoDimensions.streamWidth = leadingAxis === "width" ?
|
||||
remoteVideoDimensions.width : slaveAxisSize;
|
||||
remoteVideoDimensions.streamHeight = leadingAxis === "height" ?
|
||||
remoteVideoDimensions.height: slaveAxisSize;
|
||||
remoteVideoDimensions.height : slaveAxisSize;
|
||||
} else {
|
||||
// If the leading axis is not "full" then we need to adjust it, based
|
||||
// on the length of the leading axis.
|
||||
@ -462,7 +464,7 @@ loop.shared.mixins = (function() {
|
||||
remoteVideoDimensions.streamWidth = leadingAxis === "height" ?
|
||||
remoteVideoDimensions.width : leadingAxisSize;
|
||||
remoteVideoDimensions.streamHeight = leadingAxis === "width" ?
|
||||
remoteVideoDimensions.height: leadingAxisSize;
|
||||
remoteVideoDimensions.height : leadingAxisSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -321,25 +321,51 @@ var inChrome = typeof Components != "undefined" && "utils" in Components;
|
||||
* Generates and opens a mailto: url with call URL information prefilled.
|
||||
* Note: This only works for Desktop.
|
||||
*
|
||||
* @param {String} callUrl The call URL.
|
||||
* @param {String} recipient The recipient email address (optional).
|
||||
* @param {String} callUrl The call URL.
|
||||
* @param {String} [recipient] The recipient email address (optional).
|
||||
* @param {String} [contextDescription] The context description (optional).
|
||||
*/
|
||||
function composeCallUrlEmail(callUrl, recipient) {
|
||||
function composeCallUrlEmail(callUrl, recipient, contextDescription) {
|
||||
if (typeof navigator.mozLoop === "undefined") {
|
||||
console.warn("composeCallUrlEmail isn't available for Loop standalone.");
|
||||
return;
|
||||
}
|
||||
navigator.mozLoop.composeEmail(
|
||||
mozL10n.get("share_email_subject5", {
|
||||
clientShortname2: mozL10n.get("clientShortname2")
|
||||
}),
|
||||
mozL10n.get("share_email_body5", {
|
||||
|
||||
var subject, body;
|
||||
var brandShortname = mozL10n.get("brandShortname");
|
||||
var clientShortname2 = mozL10n.get("clientShortname2");
|
||||
var clientSuperShortname = mozL10n.get("clientSuperShortname");
|
||||
var learnMoreUrl = navigator.mozLoop.getLoopPref("learnMoreUrl");
|
||||
|
||||
if (contextDescription) {
|
||||
subject = mozL10n.get("share_email_subject_context", {
|
||||
clientShortname2: clientShortname2,
|
||||
title: contextDescription
|
||||
});
|
||||
body = mozL10n.get("share_email_body_context", {
|
||||
callUrl: callUrl,
|
||||
brandShortname: mozL10n.get("brandShortname"),
|
||||
clientShortname2: mozL10n.get("clientShortname2"),
|
||||
clientSuperShortname: mozL10n.get("clientSuperShortname"),
|
||||
learnMoreUrl: navigator.mozLoop.getLoopPref("learnMoreUrl")
|
||||
}).replace(/\r\n/g, "\n").replace(/\n/g, "\r\n"),
|
||||
brandShortname: brandShortname,
|
||||
clientShortname2: clientShortname2,
|
||||
clientSuperShortname: clientSuperShortname,
|
||||
learnMoreUrl: learnMoreUrl,
|
||||
title: contextDescription
|
||||
});
|
||||
} else {
|
||||
subject = mozL10n.get("share_email_subject5", {
|
||||
clientShortname2: clientShortname2
|
||||
});
|
||||
body = mozL10n.get("share_email_body5", {
|
||||
callUrl: callUrl,
|
||||
brandShortname: brandShortname,
|
||||
clientShortname2: clientShortname2,
|
||||
clientSuperShortname: clientSuperShortname,
|
||||
learnMoreUrl: learnMoreUrl
|
||||
});
|
||||
}
|
||||
|
||||
navigator.mozLoop.composeEmail(
|
||||
subject,
|
||||
body.replace(/\r\n/g, "\n").replace(/\n/g, "\r\n"),
|
||||
recipient
|
||||
);
|
||||
}
|
||||
|
@ -29,12 +29,18 @@ loop.validate = (function() {
|
||||
* @return {String}
|
||||
*/
|
||||
function typeName(obj) {
|
||||
if (obj === null)
|
||||
if (obj === null) {
|
||||
return "null";
|
||||
if (typeof obj === "function")
|
||||
}
|
||||
|
||||
if (typeof obj === "function") {
|
||||
return obj.name || obj.toString().match(/^function\s?([^\s(]*)/)[1];
|
||||
if (typeof obj.constructor === "function")
|
||||
}
|
||||
|
||||
if (typeof obj.constructor === "function") {
|
||||
return typeName(obj.constructor);
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
@ -93,8 +99,9 @@ loop.validate = (function() {
|
||||
return typeof values[name] !== "undefined";
|
||||
});
|
||||
var diff = difference(Object.keys(this.schema), definedProperties);
|
||||
if (diff.length > 0)
|
||||
if (diff.length > 0) {
|
||||
throw new TypeError("missing required " + diff.join(", "));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -106,8 +106,9 @@ const getPreferred = function(contact, which = "email") {
|
||||
* @param {Boolean} encode Whether to URLEncode the param string
|
||||
*/
|
||||
const getUrlParam = function(paramValue, prefName, encode = true) {
|
||||
if (Services.prefs.getPrefType(prefName))
|
||||
if (Services.prefs.getPrefType(prefName)) {
|
||||
paramValue = Services.prefs.getCharPref(prefName);
|
||||
}
|
||||
paramValue = Services.urlFormatter.formatURL(paramValue);
|
||||
|
||||
return encode ? encodeURIComponent(paramValue) : paramValue;
|
||||
|
@ -324,8 +324,9 @@ let LoopCallsInternal = {
|
||||
* @return true if the call is opened, false if it is not opened (i.e. busy)
|
||||
*/
|
||||
startDirectCall: function(contact, callType) {
|
||||
if ("id" in this.conversationInProgress)
|
||||
if ("id" in this.conversationInProgress) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var callData = {
|
||||
contact: contact,
|
||||
|
@ -724,8 +724,9 @@ let MozLoopServiceInternal = {
|
||||
* @returns {Map} a map of element ids with localized string values
|
||||
*/
|
||||
get localizedStrings() {
|
||||
if (gLocalizedStrings.size)
|
||||
if (gLocalizedStrings.size) {
|
||||
return gLocalizedStrings;
|
||||
}
|
||||
|
||||
let stringBundle =
|
||||
Services.strings.createBundle("chrome://browser/locale/loop/loop.properties");
|
||||
@ -765,7 +766,7 @@ let MozLoopServiceInternal = {
|
||||
|
||||
let ai = Services.appinfo;
|
||||
let uuid = uuidgen.generateUUID().toString();
|
||||
uuid = uuid.substr(1, uuid.length-2); // remove uuid curly braces
|
||||
uuid = uuid.substr(1, uuid.length - 2); // remove uuid curly braces
|
||||
|
||||
let directory = OS.Path.join(OS.Constants.Path.profileDir,
|
||||
"saved-telemetry-pings");
|
||||
@ -895,7 +896,7 @@ let MozLoopServiceInternal = {
|
||||
var pair = pc.id.split("("); //)
|
||||
if (pair.length == 2) {
|
||||
pc.id = pair[0] + "(session=" + context.sessionId +
|
||||
(context.callId? " call=" + context.callId : "") + " " + pair[1]; //)
|
||||
(context.callId ? " call=" + context.callId : "") + " " + pair[1]; //)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -126,7 +126,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
);
|
||||
}
|
||||
case ROOM_STATES.ENDED: {
|
||||
if (this.props.roomUsed)
|
||||
if (this.props.roomUsed) {
|
||||
return (
|
||||
React.createElement("div", {className: "ended-conversation"},
|
||||
React.createElement(sharedViews.FeedbackView, {
|
||||
@ -134,6 +134,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// In case the room was not used (no one was here), we
|
||||
// bypass the feedback form.
|
||||
|
@ -126,7 +126,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
);
|
||||
}
|
||||
case ROOM_STATES.ENDED: {
|
||||
if (this.props.roomUsed)
|
||||
if (this.props.roomUsed) {
|
||||
return (
|
||||
<div className="ended-conversation">
|
||||
<sharedViews.FeedbackView
|
||||
@ -134,6 +134,7 @@ loop.standaloneRoomViews = (function(mozL10n) {
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// In case the room was not used (no one was here), we
|
||||
// bypass the feedback form.
|
||||
|
@ -115,7 +115,7 @@ describe("loop.Client", function() {
|
||||
|
||||
sinon.assert.calledOnce(callback);
|
||||
sinon.assert.calledWithExactly(callback, sinon.match(function(err) {
|
||||
return err.code == 400 && "invalid token" == err.message;
|
||||
return err.code == 400 && err.message == "invalid token";
|
||||
}));
|
||||
});
|
||||
|
||||
|
@ -476,7 +476,7 @@ describe("loop.contacts", function() {
|
||||
var contact = {fakeField: [{value: "foobar"}]};
|
||||
loop.contacts._setPreferred(contact, "fakeField", "");
|
||||
|
||||
expect(contact["fakeField"][0].value).to.eql("");
|
||||
expect(contact.fakeField[0].value).to.eql("");
|
||||
});
|
||||
|
||||
it("should set the value on the object if the new value is empty," +
|
||||
@ -484,7 +484,7 @@ describe("loop.contacts", function() {
|
||||
var contact = {fakeField: [{value: "foobar"}]};
|
||||
loop.contacts._setPreferred(contact, "fakeField", "barbaz");
|
||||
|
||||
expect(contact["fakeField"][0].value).to.eql("barbaz");
|
||||
expect(contact.fakeField[0].value).to.eql("barbaz");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -54,8 +54,9 @@ describe("loop.conversationViews", function () {
|
||||
send: function() {},
|
||||
abort: function() {},
|
||||
getResponseHeader: function(header) {
|
||||
if (header === "Content-Type")
|
||||
if (header === "Content-Type") {
|
||||
return "audio/ogg";
|
||||
}
|
||||
},
|
||||
responseType: null,
|
||||
response: new ArrayBuffer(10),
|
||||
@ -87,7 +88,7 @@ describe("loop.conversationViews", function () {
|
||||
};
|
||||
sinon.stub(fakeMozLoop, "getLoopPref", function(pref) {
|
||||
if (pref === "fake") {
|
||||
return"http://fakeurl";
|
||||
return "http://fakeurl";
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -390,8 +390,10 @@ describe("loop.panel", function() {
|
||||
beforeEach(function() {
|
||||
supportUrl = "https://example.com";
|
||||
navigator.mozLoop.getLoopPref = function(pref) {
|
||||
if (pref === "support_url")
|
||||
if (pref === "support_url") {
|
||||
return supportUrl;
|
||||
}
|
||||
|
||||
return "unseen";
|
||||
};
|
||||
});
|
||||
|
@ -391,9 +391,24 @@ describe("loop.store.RoomStore", function () {
|
||||
}));
|
||||
|
||||
sinon.assert.calledOnce(sharedUtils.composeCallUrlEmail);
|
||||
sinon.assert.calledWithExactly(sharedUtils.composeCallUrlEmail,
|
||||
sinon.assert.calledWith(sharedUtils.composeCallUrlEmail,
|
||||
"http://invalid");
|
||||
});
|
||||
|
||||
it("should call composeUrlEmail differently with context", function() {
|
||||
sandbox.stub(sharedUtils, "composeCallUrlEmail");
|
||||
|
||||
var url = "http://invalid";
|
||||
var description = "Hello, is it me you're looking for?";
|
||||
store.emailRoomUrl(new sharedActions.EmailRoomUrl({
|
||||
roomUrl: url,
|
||||
roomDescription: description
|
||||
}));
|
||||
|
||||
sinon.assert.calledOnce(sharedUtils.composeCallUrlEmail);
|
||||
sinon.assert.calledWithExactly(sharedUtils.composeCallUrlEmail,
|
||||
url, null, description);
|
||||
});
|
||||
});
|
||||
|
||||
describe("#shareRoomUrl", function() {
|
||||
|
@ -137,7 +137,33 @@ describe("loop.roomViews", function () {
|
||||
|
||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||
sinon.assert.calledWith(dispatcher.dispatch,
|
||||
new sharedActions.EmailRoomUrl({roomUrl: "http://invalid"}));
|
||||
new sharedActions.EmailRoomUrl({
|
||||
roomUrl: "http://invalid",
|
||||
roomDescription: undefined
|
||||
}));
|
||||
});
|
||||
|
||||
it("should dispatch a different EmailRoomUrl action for rooms with context",
|
||||
function() {
|
||||
var url = "http://invalid";
|
||||
var description = "Hello, is it me you're looking for?";
|
||||
view = mountTestComponent({
|
||||
roomData: {
|
||||
roomUrl: url,
|
||||
roomContextUrls: [{ description: description }]
|
||||
}
|
||||
});
|
||||
|
||||
var emailBtn = view.getDOMNode().querySelector(".btn-email");
|
||||
|
||||
React.addons.TestUtils.Simulate.click(emailBtn);
|
||||
|
||||
sinon.assert.calledOnce(dispatcher.dispatch);
|
||||
sinon.assert.calledWith(dispatcher.dispatch,
|
||||
new sharedActions.EmailRoomUrl({
|
||||
roomUrl: url,
|
||||
roomDescription: description
|
||||
}));
|
||||
});
|
||||
|
||||
describe("Copy Button", function() {
|
||||
|
@ -240,14 +240,16 @@ function promiseTabLoadEvent(tab, url, eventType="load") {
|
||||
}
|
||||
|
||||
let timeout = setTimeout(() => {
|
||||
if (tab.linkedBrowser)
|
||||
if (tab.linkedBrowser) {
|
||||
tab.linkedBrowser.removeEventListener(eventType, handle, true);
|
||||
}
|
||||
reject(new Error("Timed out while waiting for a '" + eventType + "'' event"));
|
||||
}, 30000);
|
||||
|
||||
tab.linkedBrowser.addEventListener(eventType, handle, true, true);
|
||||
if (url)
|
||||
if (url) {
|
||||
tab.linkedBrowser.loadURI(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ describe("loop.Dispatcher", function () {
|
||||
|
||||
dispatcher.register(object, ["getWindowData"]);
|
||||
|
||||
expect(dispatcher._eventData["getWindowData"][0]).eql(object);
|
||||
expect(dispatcher._eventData.getWindowData[0]).eql(object);
|
||||
});
|
||||
|
||||
it("should register multiple store against an action name", function() {
|
||||
@ -34,8 +34,8 @@ describe("loop.Dispatcher", function () {
|
||||
dispatcher.register(object1, ["getWindowData"]);
|
||||
dispatcher.register(object2, ["getWindowData"]);
|
||||
|
||||
expect(dispatcher._eventData["getWindowData"][0]).eql(object1);
|
||||
expect(dispatcher._eventData["getWindowData"][1]).eql(object2);
|
||||
expect(dispatcher._eventData.getWindowData[0]).eql(object1);
|
||||
expect(dispatcher._eventData.getWindowData[1]).eql(object2);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -177,8 +177,14 @@ describe("loop.shared.utils", function() {
|
||||
// fake mozL10n
|
||||
sandbox.stub(navigator.mozL10n, "get", function(id) {
|
||||
switch(id) {
|
||||
case "share_email_subject5": return "subject";
|
||||
case "share_email_body5": return "body";
|
||||
case "share_email_subject5":
|
||||
return "subject";
|
||||
case "share_email_body5":
|
||||
return "body";
|
||||
case "share_email_subject_context":
|
||||
return "subject_context";
|
||||
case "share_email_body_context":
|
||||
return "body_context";
|
||||
}
|
||||
});
|
||||
composeEmail = sandbox.spy();
|
||||
@ -195,6 +201,13 @@ describe("loop.shared.utils", function() {
|
||||
sinon.assert.calledWith(composeEmail,
|
||||
"subject", "body", "fake@invalid.tld");
|
||||
});
|
||||
|
||||
it("should compose a different email when context info is provided", function() {
|
||||
sharedUtils.composeCallUrlEmail("http://invalid", null, "Hello, is me you're looking for?");
|
||||
|
||||
sinon.assert.calledOnce(composeEmail);
|
||||
sinon.assert.calledWith(composeEmail, "subject_context", "body_context");
|
||||
});
|
||||
});
|
||||
|
||||
describe("#btoa", function() {
|
||||
|
@ -33,8 +33,9 @@ describe("loop.shared.views", function() {
|
||||
send: function() {},
|
||||
abort: function() {},
|
||||
getResponseHeader: function(header) {
|
||||
if (header === "Content-Type")
|
||||
if (header === "Content-Type") {
|
||||
return "audio/ogg";
|
||||
}
|
||||
},
|
||||
responseType: null,
|
||||
response: new ArrayBuffer(10),
|
||||
@ -552,8 +553,9 @@ describe("loop.shared.views", function() {
|
||||
|
||||
beforeEach(function() {
|
||||
// In standalone, navigator.mozLoop does not exists
|
||||
if (navigator.hasOwnProperty("mozLoop"))
|
||||
if (navigator.hasOwnProperty("mozLoop")) {
|
||||
sandbox.stub(navigator, "mozLoop", undefined);
|
||||
}
|
||||
});
|
||||
|
||||
it("should play a connected sound, once, on session:connected",
|
||||
|
@ -13,7 +13,7 @@ describe("loop.standaloneMedia._MultiplexGum", function() {
|
||||
navigator.getUserMedia ||
|
||||
navigator.mozGetUserMedia ||
|
||||
navigator.webkitGetUserMedia ||
|
||||
(window["TBPlugin"] && TBPlugin.getUserMedia);
|
||||
(window.TBPlugin && TBPlugin.getUserMedia);
|
||||
|
||||
var sandbox;
|
||||
var multiplexGum;
|
||||
|
@ -40,8 +40,9 @@ describe("loop.webapp", function() {
|
||||
send: function() {},
|
||||
abort: function() {},
|
||||
getResponseHeader: function(header) {
|
||||
if (header === "Content-Type")
|
||||
if (header === "Content-Type") {
|
||||
return "audio/ogg";
|
||||
}
|
||||
},
|
||||
responseType: null,
|
||||
response: new ArrayBuffer(10),
|
||||
@ -1013,8 +1014,9 @@ describe("loop.webapp", function() {
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
if (oldLocalStorageValue !== null)
|
||||
if (oldLocalStorageValue !== null) {
|
||||
localStorage.setItem("has-seen-tos", oldLocalStorageValue);
|
||||
}
|
||||
});
|
||||
|
||||
it("should show the TOS", function() {
|
||||
|
@ -462,7 +462,7 @@ add_task(function* test_refresh() {
|
||||
// Test if push updates function as expected.
|
||||
add_task(function* test_roomUpdates() {
|
||||
gExpectedUpdates.push("_nxD4V4FflQ");
|
||||
gExpectedLeaves["_nxD4V4FflQ"] = [
|
||||
gExpectedLeaves._nxD4V4FflQ = [
|
||||
"2a1787a6-4a73-43b5-ae3e-906ec1e763cb",
|
||||
"781f012b-f1ea-4ce1-9105-7cfc36fb4ec7"
|
||||
];
|
||||
@ -471,21 +471,21 @@ add_task(function* test_roomUpdates() {
|
||||
gExpectedUpdates.length === 0);
|
||||
|
||||
gExpectedUpdates.push("_nxD4V4FflQ");
|
||||
gExpectedJoins["_nxD4V4FflQ"] = ["2a1787a6-4a73-43b5-ae3e-906ec1e763cb"];
|
||||
gExpectedJoins._nxD4V4FflQ = ["2a1787a6-4a73-43b5-ae3e-906ec1e763cb"];
|
||||
roomsPushNotification("2", kChannelGuest);
|
||||
yield waitForCondition(() => Object.getOwnPropertyNames(gExpectedJoins).length === 0 &&
|
||||
gExpectedUpdates.length === 0);
|
||||
|
||||
gExpectedUpdates.push("_nxD4V4FflQ");
|
||||
gExpectedJoins["_nxD4V4FflQ"] = ["781f012b-f1ea-4ce1-9105-7cfc36fb4ec7"];
|
||||
gExpectedLeaves["_nxD4V4FflQ"] = ["2a1787a6-4a73-43b5-ae3e-906ec1e763cb"];
|
||||
gExpectedJoins._nxD4V4FflQ = ["781f012b-f1ea-4ce1-9105-7cfc36fb4ec7"];
|
||||
gExpectedLeaves._nxD4V4FflQ = ["2a1787a6-4a73-43b5-ae3e-906ec1e763cb"];
|
||||
roomsPushNotification("3", kChannelGuest);
|
||||
yield waitForCondition(() => Object.getOwnPropertyNames(gExpectedLeaves).length === 0 &&
|
||||
Object.getOwnPropertyNames(gExpectedJoins).length === 0 &&
|
||||
gExpectedUpdates.length === 0);
|
||||
|
||||
gExpectedUpdates.push("_nxD4V4FflQ");
|
||||
gExpectedJoins["_nxD4V4FflQ"] = [
|
||||
gExpectedJoins._nxD4V4FflQ = [
|
||||
"2a1787a6-4a73-43b5-ae3e-906ec1e763cb",
|
||||
"5de6281c-6568-455f-af08-c0b0a973100e"];
|
||||
roomsPushNotification("4", kChannelGuest);
|
||||
@ -507,7 +507,7 @@ add_task(function* test_channelIdsRespected() {
|
||||
MozLoopServiceInternal.fxAOAuthProfile = { email: "fake@invalid.com" };
|
||||
|
||||
gExpectedUpdates.push("_nxD4V4FflQ");
|
||||
gExpectedLeaves["_nxD4V4FflQ"] = [
|
||||
gExpectedLeaves._nxD4V4FflQ = [
|
||||
"2a1787a6-4a73-43b5-ae3e-906ec1e763cb",
|
||||
"5de6281c-6568-455f-af08-c0b0a973100e"
|
||||
];
|
||||
|
@ -22,6 +22,8 @@ support-files =
|
||||
code_function-search-02.js
|
||||
code_function-search-03.js
|
||||
code_location-changes.js
|
||||
code_listworkers-worker1.js
|
||||
code_listworkers-worker2.js
|
||||
code_math.js
|
||||
code_math.map
|
||||
code_math.min.js
|
||||
@ -72,6 +74,7 @@ support-files =
|
||||
doc_inline-debugger-statement.html
|
||||
doc_inline-script.html
|
||||
doc_large-array-buffer.html
|
||||
doc_listworkers-tab.html
|
||||
doc_minified.html
|
||||
doc_minified_bogus_map.html
|
||||
doc_native-event-handler.html
|
||||
@ -250,6 +253,7 @@ skip-if = e10s # TODO
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_listtabs-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_listworkers.js]
|
||||
[browser_dbg_location-changes-01-simple.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_location-changes-02-blank.js]
|
||||
|
59
browser/devtools/debugger/test/browser_dbg_listworkers.js
Normal file
59
browser/devtools/debugger/test/browser_dbg_listworkers.js
Normal file
@ -0,0 +1,59 @@
|
||||
let TAB_URL = EXAMPLE_URL + "doc_listworkers-tab.html";
|
||||
let WORKER1_URL = "code_listworkers-worker1.js";
|
||||
let WORKER2_URL = "code_listworkers-worker2.js";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.addBrowserActors();
|
||||
|
||||
let client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
yield connect(client);
|
||||
|
||||
let tab = yield addTab(TAB_URL);
|
||||
let { tabs } = yield listTabs(client);
|
||||
let [, tabClient] = yield attachTab(client, findTab(tabs, TAB_URL));
|
||||
|
||||
let { workers } = yield listWorkers(tabClient);
|
||||
is(workers.length, 0);
|
||||
|
||||
executeSoon(() => {
|
||||
evalInTab(tab, "let worker1 = new Worker('" + WORKER1_URL + "');");
|
||||
});
|
||||
yield waitForWorkerListChanged(tabClient);
|
||||
|
||||
({ workers } = yield listWorkers(tabClient));
|
||||
is(workers.length, 1);
|
||||
is(workers[0].url, WORKER1_URL);
|
||||
|
||||
executeSoon(() => {
|
||||
evalInTab(tab, "let worker2 = new Worker('" + WORKER2_URL + "');");
|
||||
});
|
||||
yield waitForWorkerListChanged(tabClient);
|
||||
|
||||
({ workers } = yield listWorkers(tabClient));
|
||||
is(workers.length, 2);
|
||||
is(workers[0].url, WORKER1_URL);
|
||||
is(workers[1].url, WORKER2_URL);
|
||||
|
||||
executeSoon(() => {
|
||||
evalInTab(tab, "worker1.terminate()");
|
||||
});
|
||||
yield waitForWorkerListChanged(tabClient);
|
||||
|
||||
({ workers } = yield listWorkers(tabClient));
|
||||
is(workers.length, 1);
|
||||
is(workers[0].url, WORKER2_URL);
|
||||
|
||||
executeSoon(() => {
|
||||
evalInTab(tab, "worker2.terminate()");
|
||||
});
|
||||
yield waitForWorkerListChanged(tabClient);
|
||||
|
||||
({ workers } = yield listWorkers(tabClient));
|
||||
is(workers.length, 0);
|
||||
|
||||
yield close(client);
|
||||
finish();
|
||||
});
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
self.onmessage = function () {};
|
@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
|
||||
self.onmessage = function () {};
|
8
browser/devtools/debugger/test/doc_listworkers-tab.html
Normal file
8
browser/devtools/debugger/test/doc_listworkers-tab.html
Normal file
@ -0,0 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -1025,3 +1025,68 @@ function getSourceForm(aSources, aURL) {
|
||||
let item = aSources.getItemByValue(getSourceActor(gSources, aURL));
|
||||
return item.attachment.source;
|
||||
}
|
||||
|
||||
function connect(client) {
|
||||
info("Connecting client.");
|
||||
return new Promise(function (resolve) {
|
||||
client.connect(function () {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function close(client) {
|
||||
info("Closing client.\n");
|
||||
return new Promise(function (resolve) {
|
||||
client.close(() => {
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function listTabs(client) {
|
||||
info("Listing tabs.");
|
||||
return new Promise(function (resolve) {
|
||||
client.listTabs(function (response) {
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function findTab(tabs, url) {
|
||||
info("Finding tab with url '" + url + "'.");
|
||||
for (let tab of tabs) {
|
||||
if (tab.url === url) {
|
||||
return tab;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function attachTab(client, tab) {
|
||||
info("Attaching to tab with url '" + tab.url + "'.");
|
||||
return new Promise(function (resolve) {
|
||||
client.attachTab(tab.actor, function (response, tabClient) {
|
||||
resolve([response, tabClient]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function listWorkers(tabClient) {
|
||||
info("Listing workers.");
|
||||
return new Promise(function (resolve) {
|
||||
tabClient.listWorkers(function (response) {
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function waitForWorkerListChanged(tabClient) {
|
||||
info("Waiting for worker list to change.");
|
||||
return new Promise(function (resolve) {
|
||||
tabClient.addListener("workerListChanged", function listener() {
|
||||
tabClient.removeListener("workerListChanged", listener);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -64,6 +64,7 @@ skip-if = os == "mac" && os_version == "10.8" || os == "win" && os_version == "5
|
||||
[browser_toolbox_theme_registration.js]
|
||||
[browser_toolbox_options_enable_serviceworkers_testing.js]
|
||||
skip-if = true # Bug 1153407 - this test breaks subsequent tests and is not e10s compatible
|
||||
[browser_toolbox_selected_tool_unavailable.js]
|
||||
|
||||
# We want this test to run for mochitest-dt as well, so we include it here:
|
||||
[../../../base/content/test/general/browser_parsable_css.js]
|
||||
|
@ -0,0 +1,45 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
"use strict";
|
||||
|
||||
// Test that opening the toolbox doesn't throw when the previously selected
|
||||
// tool is not supported.
|
||||
|
||||
const testToolDefinition = {
|
||||
id: "test-tool",
|
||||
isTargetSupported: () => true,
|
||||
visibilityswitch: "devtools.test-tool.enabled",
|
||||
url: "about:blank",
|
||||
label: "someLabel",
|
||||
build: (iframeWindow, toolbox) => {
|
||||
return {
|
||||
target: toolbox.target,
|
||||
toolbox: toolbox,
|
||||
isReady: true,
|
||||
destroy: () => {},
|
||||
panelDoc: iframeWindow.document
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
add_task(function*() {
|
||||
gDevTools.registerTool(testToolDefinition);
|
||||
let tab = yield addTab("about:blank");
|
||||
let target = TargetFactory.forTab(tab);
|
||||
|
||||
let toolbox = yield gDevTools.showToolbox(target, testToolDefinition.id);
|
||||
is(toolbox.currentToolId, "test-tool", "test-tool was selected");
|
||||
yield gDevTools.closeToolbox(target);
|
||||
|
||||
// Make the previously selected tool unavailable.
|
||||
testToolDefinition.isTargetSupported = () => false;
|
||||
|
||||
target = TargetFactory.forTab(tab);
|
||||
toolbox = yield gDevTools.showToolbox(target);
|
||||
is(toolbox.currentToolId, "webconsole", "web console was selected");
|
||||
|
||||
yield gDevTools.closeToolbox(target);
|
||||
gDevTools.unregisterTool(testToolDefinition.id);
|
||||
tab = toolbox = target = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
@ -137,9 +137,6 @@ function Toolbox(target, selectedTool, hostType, hostOptions) {
|
||||
if (!selectedTool) {
|
||||
selectedTool = Services.prefs.getCharPref(this._prefs.LAST_TOOL);
|
||||
}
|
||||
if (!gDevTools.getToolDefinition(selectedTool)) {
|
||||
selectedTool = "webconsole";
|
||||
}
|
||||
this._defaultToolId = selectedTool;
|
||||
|
||||
this._hostOptions = hostOptions;
|
||||
@ -370,6 +367,14 @@ Toolbox.prototype = {
|
||||
|
||||
this._pingTelemetry();
|
||||
|
||||
// The isTargetSupported check needs to happen after the target is
|
||||
// remoted, otherwise we could have done it in the toolbox constructor
|
||||
// (bug 1072764).
|
||||
let toolDef = gDevTools.getToolDefinition(this._defaultToolId);
|
||||
if (!toolDef || !toolDef.isTargetSupported(this._target)) {
|
||||
this._defaultToolId = "webconsole";
|
||||
}
|
||||
|
||||
yield this.selectTool(this._defaultToolId);
|
||||
|
||||
// Wait until the original tool is selected so that the split
|
||||
|
@ -9,8 +9,10 @@ scrollbar {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
/* Scrollbar code will reset the margin to the correct side depending on
|
||||
where layout actually puts the scrollbar */
|
||||
scrollbar[orient="vertical"] {
|
||||
-moz-margin-start: -10px;
|
||||
margin-left: -10px;
|
||||
min-width: 10px;
|
||||
max-width: 10px;
|
||||
}
|
||||
|
@ -10,8 +10,10 @@ scrollbar {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
/* Scrollbar code will reset the margin to the correct side depending on
|
||||
where layout actually puts the scrollbar */
|
||||
scrollbar[orient="vertical"] {
|
||||
-moz-margin-start: -8px;
|
||||
margin-left: -8px;
|
||||
min-width: 8px;
|
||||
max-width: 8px;
|
||||
}
|
||||
|
@ -9,8 +9,10 @@ scrollbar {
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
/* Scrollbar code will reset the margin to the correct side depending on
|
||||
where layout actually puts the scrollbar */
|
||||
scrollbar[orient="vertical"] {
|
||||
-moz-margin-start: -10px;
|
||||
margin-left: -10px;
|
||||
min-width: 10px;
|
||||
max-width: 10px;
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ ArchiveReaderEvent::RunShare(nsresult aStatus)
|
||||
void
|
||||
ArchiveReaderEvent::ShareMainThread()
|
||||
{
|
||||
nsTArray<nsCOMPtr<nsIDOMFile> > fileList;
|
||||
nsTArray<nsRefPtr<File>> fileList;
|
||||
|
||||
if (!NS_FAILED(mStatus)) {
|
||||
// This extra step must run in the main thread:
|
||||
@ -131,7 +131,7 @@ ArchiveReaderEvent::ShareMainThread()
|
||||
}
|
||||
|
||||
// This is a File:
|
||||
nsRefPtr<nsIDOMFile> file = item->File(mArchiveReader);
|
||||
nsRefPtr<File> file = item->GetFile(mArchiveReader);
|
||||
if (file) {
|
||||
fileList.AppendElement(file);
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
virtual nsresult GetFilename(nsString& aFilename) = 0;
|
||||
|
||||
// Generate a File
|
||||
virtual nsIDOMFile* File(ArchiveReader* aArchiveReader) = 0;
|
||||
virtual already_AddRefed<File> GetFile(ArchiveReader* aArchiveReader) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~ArchiveItem();
|
||||
|
@ -24,7 +24,7 @@ USING_ARCHIVEREADER_NAMESPACE
|
||||
|
||||
/* static */ already_AddRefed<ArchiveReader>
|
||||
ArchiveReader::Constructor(const GlobalObject& aGlobal,
|
||||
File& aBlob,
|
||||
Blob& aBlob,
|
||||
const ArchiveReaderOptions& aOptions,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
@ -46,9 +46,9 @@ ArchiveReader::Constructor(const GlobalObject& aGlobal,
|
||||
return reader.forget();
|
||||
}
|
||||
|
||||
ArchiveReader::ArchiveReader(File& aBlob, nsPIDOMWindow* aWindow,
|
||||
ArchiveReader::ArchiveReader(Blob& aBlob, nsPIDOMWindow* aWindow,
|
||||
const nsACString& aEncoding)
|
||||
: mFileImpl(aBlob.Impl())
|
||||
: mBlobImpl(aBlob.Impl())
|
||||
, mWindow(aWindow)
|
||||
, mStatus(NOT_STARTED)
|
||||
, mEncoding(aEncoding)
|
||||
@ -95,7 +95,7 @@ nsresult
|
||||
ArchiveReader::GetInputStream(nsIInputStream** aInputStream)
|
||||
{
|
||||
// Getting the input stream
|
||||
mFileImpl->GetInternalStream(aInputStream);
|
||||
mBlobImpl->GetInternalStream(aInputStream);
|
||||
NS_ENSURE_TRUE(*aInputStream, NS_ERROR_UNEXPECTED);
|
||||
return NS_OK;
|
||||
}
|
||||
@ -104,7 +104,7 @@ nsresult
|
||||
ArchiveReader::GetSize(uint64_t* aSize)
|
||||
{
|
||||
ErrorResult rv;
|
||||
*aSize = mFileImpl->GetSize(rv);
|
||||
*aSize = mBlobImpl->GetSize(rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
@ -136,7 +136,7 @@ ArchiveReader::OpenArchive()
|
||||
|
||||
// Data received from the dispatched event:
|
||||
void
|
||||
ArchiveReader::Ready(nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList,
|
||||
ArchiveReader::Ready(nsTArray<nsRefPtr<File>>& aFileList,
|
||||
nsresult aStatus)
|
||||
{
|
||||
mStatus = READY;
|
||||
@ -199,7 +199,7 @@ ArchiveReader::GenerateArchiveRequest()
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(ArchiveReader,
|
||||
mFileImpl,
|
||||
mBlobImpl,
|
||||
mWindow,
|
||||
mData.fileList,
|
||||
mRequests)
|
||||
|
@ -13,14 +13,14 @@
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIDOMFile.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
struct ArchiveReaderOptions;
|
||||
class Blob;
|
||||
class BlobImpl;
|
||||
class File;
|
||||
class FileImpl;
|
||||
class GlobalObject;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
@ -40,10 +40,10 @@ public:
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ArchiveReader)
|
||||
|
||||
static already_AddRefed<ArchiveReader>
|
||||
Constructor(const GlobalObject& aGlobal, File& aBlob,
|
||||
Constructor(const GlobalObject& aGlobal, Blob& aBlob,
|
||||
const ArchiveReaderOptions& aOptions, ErrorResult& aError);
|
||||
|
||||
ArchiveReader(File& aBlob, nsPIDOMWindow* aWindow,
|
||||
ArchiveReader(Blob& aBlob, nsPIDOMWindow* aWindow,
|
||||
const nsACString& aEncoding);
|
||||
|
||||
nsIDOMWindow* GetParentObject() const
|
||||
@ -64,13 +64,12 @@ public: // for the ArchiveRequest:
|
||||
nsresult RegisterRequest(ArchiveRequest* aRequest);
|
||||
|
||||
public: // For events:
|
||||
FileImpl* GetFileImpl() const
|
||||
BlobImpl* GetBlobImpl() const
|
||||
{
|
||||
return mFileImpl;
|
||||
return mBlobImpl;
|
||||
}
|
||||
|
||||
void Ready(nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList,
|
||||
nsresult aStatus);
|
||||
void Ready(nsTArray<nsRefPtr<File>>& aFileList, nsresult aStatus);
|
||||
|
||||
private:
|
||||
~ArchiveReader();
|
||||
@ -83,7 +82,7 @@ private:
|
||||
|
||||
protected:
|
||||
// The archive blob/file
|
||||
nsRefPtr<FileImpl> mFileImpl;
|
||||
nsRefPtr<BlobImpl> mBlobImpl;
|
||||
|
||||
// The window is needed by the requests
|
||||
nsCOMPtr<nsPIDOMWindow> mWindow;
|
||||
@ -108,7 +107,7 @@ protected:
|
||||
|
||||
// Everything related to the blobs and the status:
|
||||
struct {
|
||||
nsTArray<nsCOMPtr<nsIDOMFile> > fileList;
|
||||
nsTArray<nsRefPtr<File>> fileList;
|
||||
nsresult status;
|
||||
} mData;
|
||||
|
||||
|
@ -122,7 +122,7 @@ ArchiveRequest::OpGetFiles()
|
||||
}
|
||||
|
||||
nsresult
|
||||
ArchiveRequest::ReaderReady(nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList,
|
||||
ArchiveRequest::ReaderReady(nsTArray<nsRefPtr<File>>& aFileList,
|
||||
nsresult aStatus)
|
||||
{
|
||||
if (NS_FAILED(aStatus)) {
|
||||
@ -174,7 +174,7 @@ ArchiveRequest::ReaderReady(nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList,
|
||||
nsresult
|
||||
ArchiveRequest::GetFilenamesResult(JSContext* aCx,
|
||||
JS::Value* aValue,
|
||||
nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList)
|
||||
nsTArray<nsRefPtr<File>>& aFileList)
|
||||
{
|
||||
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aFileList.Length()));
|
||||
nsresult rv;
|
||||
@ -185,7 +185,7 @@ ArchiveRequest::GetFilenamesResult(JSContext* aCx,
|
||||
|
||||
JS::Rooted<JSString*> str(aCx);
|
||||
for (uint32_t i = 0; i < aFileList.Length(); ++i) {
|
||||
nsCOMPtr<nsIDOMFile> file = aFileList[i];
|
||||
nsRefPtr<File> file = aFileList[i];
|
||||
|
||||
nsString filename;
|
||||
rv = file->GetName(filename);
|
||||
@ -211,18 +211,21 @@ ArchiveRequest::GetFilenamesResult(JSContext* aCx,
|
||||
nsresult
|
||||
ArchiveRequest::GetFileResult(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList)
|
||||
nsTArray<nsRefPtr<File>>& aFileList)
|
||||
{
|
||||
for (uint32_t i = 0; i < aFileList.Length(); ++i) {
|
||||
nsCOMPtr<nsIDOMFile> file = aFileList[i];
|
||||
nsRefPtr<File> file = aFileList[i];
|
||||
|
||||
nsString filename;
|
||||
nsresult rv = file->GetName(filename);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (filename == mFilename) {
|
||||
return nsContentUtils::WrapNative(aCx, file, &NS_GET_IID(nsIDOMFile),
|
||||
aValue);
|
||||
if (!ToJSValue(aCx, file, aValue)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
@ -232,7 +235,7 @@ ArchiveRequest::GetFileResult(JSContext* aCx,
|
||||
nsresult
|
||||
ArchiveRequest::GetFilesResult(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList)
|
||||
nsTArray<nsRefPtr<File>>& aFileList)
|
||||
{
|
||||
JS::Rooted<JSObject*> array(aCx, JS_NewArrayObject(aCx, aFileList.Length()));
|
||||
if (!array) {
|
||||
@ -240,13 +243,14 @@ ArchiveRequest::GetFilesResult(JSContext* aCx,
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < aFileList.Length(); ++i) {
|
||||
nsCOMPtr<nsIDOMFile> file = aFileList[i];
|
||||
nsRefPtr<File> file = aFileList[i];
|
||||
|
||||
JS::Rooted<JS::Value> value(aCx);
|
||||
nsresult rv = nsContentUtils::WrapNative(aCx, file, &NS_GET_IID(nsIDOMFile),
|
||||
&value);
|
||||
if (NS_FAILED(rv) ||
|
||||
!JS_DefineElement(aCx, array, i, value, JSPROP_ENUMERATE)) {
|
||||
if (!ToJSValue(aCx, file, &value)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!JS_DefineElement(aCx, array, i, value, JSPROP_ENUMERATE)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
@ -49,8 +49,7 @@ public:
|
||||
void OpGetFile(const nsAString& aFilename);
|
||||
void OpGetFiles();
|
||||
|
||||
nsresult ReaderReady(nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList,
|
||||
nsresult aStatus);
|
||||
nsresult ReaderReady(nsTArray<nsRefPtr<File>>& aFileList, nsresult aStatus);
|
||||
|
||||
public: // static
|
||||
static already_AddRefed<ArchiveRequest> Create(nsPIDOMWindow* aOwner,
|
||||
@ -61,13 +60,13 @@ private:
|
||||
|
||||
nsresult GetFilenamesResult(JSContext* aCx,
|
||||
JS::Value* aValue,
|
||||
nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList);
|
||||
nsTArray<nsRefPtr<File>>& aFileList);
|
||||
nsresult GetFileResult(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList);
|
||||
nsTArray<nsRefPtr<File>>& aFileList);
|
||||
nsresult GetFilesResult(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aValue,
|
||||
nsTArray<nsCOMPtr<nsIDOMFile> >& aFileList);
|
||||
nsTArray<nsRefPtr<File>>& aFileList);
|
||||
|
||||
protected:
|
||||
// The reader:
|
||||
|
@ -75,8 +75,8 @@ ArchiveZipItem::GetFilename(nsString& aFilename)
|
||||
}
|
||||
|
||||
// From zipItem to File:
|
||||
nsIDOMFile*
|
||||
ArchiveZipItem::File(ArchiveReader* aArchiveReader)
|
||||
already_AddRefed<File>
|
||||
ArchiveZipItem::GetFile(ArchiveReader* aArchiveReader)
|
||||
{
|
||||
nsString filename;
|
||||
|
||||
@ -84,11 +84,13 @@ ArchiveZipItem::File(ArchiveReader* aArchiveReader)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return new dom::File(aArchiveReader,
|
||||
new ArchiveZipFileImpl(filename,
|
||||
nsRefPtr<dom::File> file = dom::File::Create(aArchiveReader,
|
||||
new ArchiveZipBlobImpl(filename,
|
||||
NS_ConvertUTF8toUTF16(GetType()),
|
||||
StrToInt32(mCentralStruct.orglen),
|
||||
mCentralStruct, aArchiveReader->GetFileImpl()));
|
||||
mCentralStruct, aArchiveReader->GetBlobImpl()));
|
||||
MOZ_ASSERT(file);
|
||||
return file.forget();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
|
@ -31,7 +31,8 @@ public:
|
||||
nsresult GetFilename(nsString& aFilename) override;
|
||||
|
||||
// From zipItem to File:
|
||||
virtual nsIDOMFile* File(ArchiveReader* aArchiveReader) override;
|
||||
virtual already_AddRefed<File>
|
||||
GetFile(ArchiveReader* aArchiveReader) override;
|
||||
|
||||
public: // for the event
|
||||
static uint32_t StrToInt32(const uint8_t* aStr);
|
||||
|
@ -353,23 +353,23 @@ ArchiveInputStream::SetEOF()
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// ArchiveZipFileImpl
|
||||
// ArchiveZipBlobImpl
|
||||
|
||||
nsresult
|
||||
ArchiveZipFileImpl::GetInternalStream(nsIInputStream** aStream)
|
||||
ArchiveZipBlobImpl::GetInternalStream(nsIInputStream** aStream)
|
||||
{
|
||||
if (mLength > INT32_MAX) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
uint64_t size = mFileImpl->GetSize(rv);
|
||||
uint64_t size = mBlobImpl->GetSize(rv);
|
||||
if (NS_WARN_IF(rv.Failed())) {
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> inputStream;
|
||||
rv = mFileImpl->GetInternalStream(getter_AddRefs(inputStream));
|
||||
rv = mBlobImpl->GetInternalStream(getter_AddRefs(inputStream));
|
||||
if (NS_WARN_IF(rv.Failed()) || !inputStream) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
@ -385,16 +385,16 @@ ArchiveZipFileImpl::GetInternalStream(nsIInputStream** aStream)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<mozilla::dom::FileImpl>
|
||||
ArchiveZipFileImpl::CreateSlice(uint64_t aStart,
|
||||
already_AddRefed<mozilla::dom::BlobImpl>
|
||||
ArchiveZipBlobImpl::CreateSlice(uint64_t aStart,
|
||||
uint64_t aLength,
|
||||
const nsAString& aContentType,
|
||||
mozilla::ErrorResult& aRv)
|
||||
{
|
||||
nsRefPtr<FileImpl> impl =
|
||||
new ArchiveZipFileImpl(mFilename, mContentType, aStart, mLength, mCentral,
|
||||
mFileImpl);
|
||||
nsRefPtr<BlobImpl> impl =
|
||||
new ArchiveZipBlobImpl(mFilename, mContentType, aStart, mLength, mCentral,
|
||||
mBlobImpl);
|
||||
return impl.forget();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(ArchiveZipFileImpl, FileImpl)
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(ArchiveZipBlobImpl, BlobImpl)
|
||||
|
@ -19,57 +19,57 @@
|
||||
BEGIN_ARCHIVEREADER_NAMESPACE
|
||||
|
||||
/**
|
||||
* ArchiveZipFileImpl to FileImpl
|
||||
* ArchiveZipBlobImpl to BlobImpl
|
||||
*/
|
||||
class ArchiveZipFileImpl : public FileImplBase
|
||||
class ArchiveZipBlobImpl : public BlobImplBase
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
ArchiveZipFileImpl(const nsAString& aName,
|
||||
ArchiveZipBlobImpl(const nsAString& aName,
|
||||
const nsAString& aContentType,
|
||||
uint64_t aLength,
|
||||
ZipCentral& aCentral,
|
||||
FileImpl* aFileImpl)
|
||||
: FileImplBase(aName, aContentType, aLength),
|
||||
BlobImpl* aBlobImpl)
|
||||
: BlobImplBase(aName, aContentType, aLength),
|
||||
mCentral(aCentral),
|
||||
mFileImpl(aFileImpl),
|
||||
mBlobImpl(aBlobImpl),
|
||||
mFilename(aName)
|
||||
{
|
||||
MOZ_ASSERT(mFileImpl);
|
||||
MOZ_COUNT_CTOR(ArchiveZipFileImpl);
|
||||
MOZ_ASSERT(mBlobImpl);
|
||||
MOZ_COUNT_CTOR(ArchiveZipBlobImpl);
|
||||
}
|
||||
|
||||
ArchiveZipFileImpl(const nsAString& aName,
|
||||
ArchiveZipBlobImpl(const nsAString& aName,
|
||||
const nsAString& aContentType,
|
||||
uint64_t aStart,
|
||||
uint64_t aLength,
|
||||
ZipCentral& aCentral,
|
||||
FileImpl* aFileImpl)
|
||||
: FileImplBase(aContentType, aStart, aLength),
|
||||
BlobImpl* aBlobImpl)
|
||||
: BlobImplBase(aContentType, aStart, aLength),
|
||||
mCentral(aCentral),
|
||||
mFileImpl(aFileImpl),
|
||||
mBlobImpl(aBlobImpl),
|
||||
mFilename(aName)
|
||||
{
|
||||
MOZ_ASSERT(mFileImpl);
|
||||
MOZ_COUNT_CTOR(ArchiveZipFileImpl);
|
||||
MOZ_ASSERT(mBlobImpl);
|
||||
MOZ_COUNT_CTOR(ArchiveZipBlobImpl);
|
||||
}
|
||||
|
||||
// Overrides:
|
||||
virtual nsresult GetInternalStream(nsIInputStream**) override;
|
||||
protected:
|
||||
virtual ~ArchiveZipFileImpl()
|
||||
virtual ~ArchiveZipBlobImpl()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ArchiveZipFileImpl);
|
||||
MOZ_COUNT_DTOR(ArchiveZipBlobImpl);
|
||||
}
|
||||
|
||||
virtual already_AddRefed<FileImpl>
|
||||
virtual already_AddRefed<BlobImpl>
|
||||
CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType,
|
||||
mozilla::ErrorResult& aRv) override;
|
||||
|
||||
private: // Data
|
||||
ZipCentral mCentral;
|
||||
nsRefPtr<FileImpl> mFileImpl;
|
||||
nsRefPtr<BlobImpl> mBlobImpl;
|
||||
|
||||
nsString mFilename;
|
||||
};
|
||||
|
@ -26,12 +26,12 @@ public:
|
||||
|
||||
nsresult AppendVoidPtr(const void* aData, uint32_t aLength);
|
||||
nsresult AppendString(const nsAString& aString, bool nativeEOL, JSContext* aCx);
|
||||
nsresult AppendBlobImpl(FileImpl* aBlobImpl);
|
||||
nsresult AppendBlobImpls(const nsTArray<nsRefPtr<FileImpl>>& aBlobImpls);
|
||||
nsresult AppendBlobImpl(BlobImpl* aBlobImpl);
|
||||
nsresult AppendBlobImpls(const nsTArray<nsRefPtr<BlobImpl>>& aBlobImpls);
|
||||
|
||||
nsTArray<nsRefPtr<FileImpl>>& GetBlobImpls() { Flush(); return mBlobImpls; }
|
||||
nsTArray<nsRefPtr<BlobImpl>>& GetBlobImpls() { Flush(); return mBlobImpls; }
|
||||
|
||||
already_AddRefed<File> GetBlobInternal(nsISupports* aParent,
|
||||
already_AddRefed<Blob> GetBlobInternal(nsISupports* aParent,
|
||||
const nsACString& aContentType);
|
||||
|
||||
protected:
|
||||
@ -68,8 +68,8 @@ protected:
|
||||
// If we have some data, create a blob for it
|
||||
// and put it on the stack
|
||||
|
||||
nsRefPtr<FileImpl> blobImpl =
|
||||
new FileImplMemory(mData, mDataLen, EmptyString());
|
||||
nsRefPtr<BlobImpl> blobImpl =
|
||||
new BlobImplMemory(mData, mDataLen, EmptyString());
|
||||
mBlobImpls.AppendElement(blobImpl);
|
||||
mData = nullptr; // The nsDOMMemoryFile takes ownership of the buffer
|
||||
mDataLen = 0;
|
||||
@ -77,7 +77,7 @@ protected:
|
||||
}
|
||||
}
|
||||
|
||||
nsTArray<nsRefPtr<FileImpl>> mBlobImpls;
|
||||
nsTArray<nsRefPtr<BlobImpl>> mBlobImpls;
|
||||
void* mData;
|
||||
uint64_t mDataLen;
|
||||
uint64_t mDataBufferLen;
|
||||
|
@ -60,7 +60,7 @@ struct
|
||||
ConsoleStructuredCloneData
|
||||
{
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
nsTArray<nsRefPtr<FileImpl>> mFiles;
|
||||
nsTArray<nsRefPtr<BlobImpl>> mBlobs;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -84,13 +84,13 @@ ConsoleStructuredCloneCallbacksRead(JSContext* aCx,
|
||||
MOZ_ASSERT(data);
|
||||
|
||||
if (aTag == CONSOLE_TAG_BLOB) {
|
||||
MOZ_ASSERT(data->mFiles.Length() > aIndex);
|
||||
MOZ_ASSERT(data->mBlobs.Length() > aIndex);
|
||||
|
||||
JS::Rooted<JS::Value> val(aCx);
|
||||
{
|
||||
nsRefPtr<File> file =
|
||||
new File(data->mParent, data->mFiles.ElementAt(aIndex));
|
||||
if (!GetOrCreateDOMReflector(aCx, file, &val)) {
|
||||
nsRefPtr<Blob> blob =
|
||||
Blob::Create(data->mParent, data->mBlobs.ElementAt(aIndex));
|
||||
if (!ToJSValue(aCx, blob, &val)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@ -114,14 +114,14 @@ ConsoleStructuredCloneCallbacksWrite(JSContext* aCx,
|
||||
static_cast<ConsoleStructuredCloneData*>(aClosure);
|
||||
MOZ_ASSERT(data);
|
||||
|
||||
nsRefPtr<File> file;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, file)) &&
|
||||
file->Impl()->MayBeClonedToOtherThreads()) {
|
||||
if (!JS_WriteUint32Pair(aWriter, CONSOLE_TAG_BLOB, data->mFiles.Length())) {
|
||||
nsRefPtr<Blob> blob;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, aObj, blob)) &&
|
||||
blob->Impl()->MayBeClonedToOtherThreads()) {
|
||||
if (!JS_WriteUint32Pair(aWriter, CONSOLE_TAG_BLOB, data->mBlobs.Length())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
data->mFiles.AppendElement(file->Impl());
|
||||
data->mBlobs.AppendElement(blob->Impl());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
320
dom/base/File.h
320
dom/base/File.h
@ -47,23 +47,131 @@ class FileInfo;
|
||||
struct BlobPropertyBag;
|
||||
struct ChromeFilePropertyBag;
|
||||
struct FilePropertyBag;
|
||||
class FileImpl;
|
||||
class BlobImpl;
|
||||
class File;
|
||||
class OwningArrayBufferOrArrayBufferViewOrBlobOrString;
|
||||
|
||||
class File final : public nsIDOMFile
|
||||
, public nsIXHRSendable
|
||||
, public nsIMutable
|
||||
, public nsSupportsWeakReference
|
||||
, public nsWrapperCache
|
||||
class Blob : public nsIDOMBlob
|
||||
, public nsIXHRSendable
|
||||
, public nsIMutable
|
||||
, public nsSupportsWeakReference
|
||||
, public nsWrapperCache
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIDOMBLOB
|
||||
NS_DECL_NSIDOMFILE
|
||||
NS_DECL_NSIXHRSENDABLE
|
||||
NS_DECL_NSIMUTABLE
|
||||
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(File, nsIDOMFile)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(Blob, nsIDOMBlob)
|
||||
|
||||
static Blob*
|
||||
Create(nsISupports* aParent, BlobImpl* aImpl);
|
||||
|
||||
static already_AddRefed<Blob>
|
||||
Create(nsISupports* aParent, const nsAString& aContentType,
|
||||
uint64_t aLength);
|
||||
|
||||
static already_AddRefed<Blob>
|
||||
Create(nsISupports* aParent, const nsAString& aContentType, uint64_t aStart,
|
||||
uint64_t aLength);
|
||||
|
||||
// The returned Blob takes ownership of aMemoryBuffer. aMemoryBuffer will be
|
||||
// freed by free so it must be allocated by malloc or something
|
||||
// compatible with it.
|
||||
static already_AddRefed<Blob>
|
||||
CreateMemoryBlob(nsISupports* aParent, void* aMemoryBuffer, uint64_t aLength,
|
||||
const nsAString& aContentType);
|
||||
|
||||
static already_AddRefed<Blob>
|
||||
CreateTemporaryBlob(nsISupports* aParent, PRFileDesc* aFD,
|
||||
uint64_t aStartPos, uint64_t aLength,
|
||||
const nsAString& aContentType);
|
||||
|
||||
BlobImpl* Impl() const
|
||||
{
|
||||
return mImpl;
|
||||
}
|
||||
|
||||
bool IsFile() const;
|
||||
|
||||
const nsTArray<nsRefPtr<BlobImpl>>* GetSubBlobImpls() const;
|
||||
|
||||
// This method returns null if this Blob is not a File; it returns
|
||||
// the same object in case this Blob already implements the File interface;
|
||||
// otherwise it returns a new File object with the same BlobImpl.
|
||||
already_AddRefed<File> ToFile();
|
||||
|
||||
// This method creates a new File object with the given name and the same
|
||||
// BlobImpl.
|
||||
already_AddRefed<File> ToFile(const nsAString& aName) const;
|
||||
|
||||
already_AddRefed<Blob>
|
||||
CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// WebIDL methods
|
||||
nsISupports* GetParentObject() const
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
// Blob constructor
|
||||
static already_AddRefed<Blob>
|
||||
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
|
||||
|
||||
// Blob constructor
|
||||
static already_AddRefed<Blob>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
const Sequence<OwningArrayBufferOrArrayBufferViewOrBlobOrString>& aData,
|
||||
const BlobPropertyBag& aBag,
|
||||
ErrorResult& aRv);
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
uint64_t GetSize(ErrorResult& aRv);
|
||||
|
||||
// XPCOM GetType is OK
|
||||
|
||||
already_AddRefed<Blob> Slice(const Optional<int64_t>& aStart,
|
||||
const Optional<int64_t>& aEnd,
|
||||
const nsAString& aContentType,
|
||||
ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
// File constructor should never be used directly. Use Blob::Create instead.
|
||||
Blob(nsISupports* aParent, BlobImpl* aImpl);
|
||||
virtual ~Blob() {};
|
||||
|
||||
virtual bool HasFileInterface() const { return false; }
|
||||
|
||||
// The member is the real backend implementation of this File/Blob.
|
||||
// It's thread-safe and not CC-able and it's the only element that is moved
|
||||
// between threads.
|
||||
// Note: we should not store any other state in this class!
|
||||
nsRefPtr<BlobImpl> mImpl;
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
};
|
||||
|
||||
class File final : public Blob
|
||||
, public nsIDOMFile
|
||||
{
|
||||
friend class Blob;
|
||||
|
||||
public:
|
||||
NS_DECL_NSIDOMFILE
|
||||
NS_FORWARD_NSIDOMBLOB(Blob::)
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(File, Blob);
|
||||
|
||||
// Note: BlobImpl must be a File in order to use this method.
|
||||
// Check impl->IsFile().
|
||||
static File*
|
||||
Create(nsISupports* aParent, BlobImpl* aImpl);
|
||||
|
||||
static already_AddRefed<File>
|
||||
Create(nsISupports* aParent, const nsAString& aName,
|
||||
@ -74,14 +182,6 @@ public:
|
||||
Create(nsISupports* aParent, const nsAString& aName,
|
||||
const nsAString& aContentType, uint64_t aLength);
|
||||
|
||||
static already_AddRefed<File>
|
||||
Create(nsISupports* aParent, const nsAString& aContentType,
|
||||
uint64_t aLength);
|
||||
|
||||
static already_AddRefed<File>
|
||||
Create(nsISupports* aParent, const nsAString& aContentType, uint64_t aStart,
|
||||
uint64_t aLength);
|
||||
|
||||
// The returned File takes ownership of aMemoryBuffer. aMemoryBuffer will be
|
||||
// freed by free so it must be allocated by malloc or something
|
||||
// compatible with it.
|
||||
@ -90,18 +190,6 @@ public:
|
||||
const nsAString& aName, const nsAString& aContentType,
|
||||
int64_t aLastModifiedDate);
|
||||
|
||||
// The returned File takes ownership of aMemoryBuffer. aMemoryBuffer will be
|
||||
// freed by free so it must be allocated by malloc or something
|
||||
// compatible with it.
|
||||
static already_AddRefed<File>
|
||||
CreateMemoryFile(nsISupports* aParent, void* aMemoryBuffer, uint64_t aLength,
|
||||
const nsAString& aContentType);
|
||||
|
||||
static already_AddRefed<File>
|
||||
CreateTemporaryFileBlob(nsISupports* aParent, PRFileDesc* aFD,
|
||||
uint64_t aStartPos, uint64_t aLength,
|
||||
const nsAString& aContentType);
|
||||
|
||||
static already_AddRefed<File>
|
||||
CreateFromFile(nsISupports* aParent, nsIFile* aFile, bool aTemporary = false);
|
||||
|
||||
@ -123,41 +211,10 @@ public:
|
||||
CreateFromFile(nsISupports* aParent, nsIFile* aFile, const nsAString& aName,
|
||||
const nsAString& aContentType);
|
||||
|
||||
File(nsISupports* aParent, FileImpl* aImpl);
|
||||
|
||||
FileImpl* Impl() const
|
||||
{
|
||||
return mImpl;
|
||||
}
|
||||
|
||||
const nsTArray<nsRefPtr<FileImpl>>* GetSubBlobImpls() const;
|
||||
|
||||
bool IsSizeUnknown() const;
|
||||
|
||||
bool IsDateUnknown() const;
|
||||
|
||||
bool IsFile() const;
|
||||
|
||||
already_AddRefed<File>
|
||||
CreateSlice(uint64_t aStart, uint64_t aLength, const nsAString& aContentType,
|
||||
ErrorResult& aRv);
|
||||
|
||||
// WebIDL methods
|
||||
nsISupports* GetParentObject() const
|
||||
{
|
||||
return mParent;
|
||||
}
|
||||
|
||||
// Blob constructor
|
||||
static already_AddRefed<File>
|
||||
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
|
||||
|
||||
// Blob constructor
|
||||
static already_AddRefed<File>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
const Sequence<OwningArrayBufferOrArrayBufferViewOrBlobOrString>& aData,
|
||||
const BlobPropertyBag& aBag,
|
||||
ErrorResult& aRv);
|
||||
virtual JSObject* WrapObject(JSContext *cx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
// File constructor
|
||||
static already_AddRefed<File>
|
||||
@ -170,7 +227,7 @@ public:
|
||||
// File constructor - ChromeOnly
|
||||
static already_AddRefed<File>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
File& aData,
|
||||
Blob& aData,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
ErrorResult& aRv);
|
||||
|
||||
@ -188,46 +245,34 @@ public:
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
ErrorResult& aRv);
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
uint64_t GetSize(ErrorResult& aRv);
|
||||
|
||||
// XPCOM GetType is OK
|
||||
|
||||
// XPCOM GetName is OK
|
||||
|
||||
int64_t GetLastModified(ErrorResult& aRv);
|
||||
|
||||
Date GetLastModifiedDate(ErrorResult& aRv);
|
||||
|
||||
|
||||
void GetMozFullPath(nsAString& aFilename, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<File> Slice(const Optional<int64_t>& aStart,
|
||||
const Optional<int64_t>& aEnd,
|
||||
const nsAString& aContentType,
|
||||
ErrorResult& aRv);
|
||||
protected:
|
||||
virtual bool HasFileInterface() const override { return true; }
|
||||
|
||||
private:
|
||||
// File constructor should never be used directly. Use Blob::Create or
|
||||
// File::Create.
|
||||
File(nsISupports* aParent, BlobImpl* aImpl);
|
||||
~File() {};
|
||||
|
||||
// The member is the real backend implementation of this File/Blob.
|
||||
// It's thread-safe and not CC-able and it's the only element that is moved
|
||||
// between threads.
|
||||
// Note: we should not store any other state in this class!
|
||||
nsRefPtr<FileImpl> mImpl;
|
||||
|
||||
nsCOMPtr<nsISupports> mParent;
|
||||
};
|
||||
|
||||
// This is the abstract class for any File backend. It must be nsISupports
|
||||
// because this class must be ref-counted and it has to work with IPC.
|
||||
class FileImpl : public nsISupports
|
||||
class BlobImpl : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(FILEIMPL_IID)
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
|
||||
FileImpl() {}
|
||||
BlobImpl() {}
|
||||
|
||||
virtual void GetName(nsAString& aName) = 0;
|
||||
|
||||
@ -245,15 +290,15 @@ public:
|
||||
|
||||
virtual void GetType(nsAString& aType) = 0;
|
||||
|
||||
already_AddRefed<FileImpl>
|
||||
already_AddRefed<BlobImpl>
|
||||
Slice(const Optional<int64_t>& aStart, const Optional<int64_t>& aEnd,
|
||||
const nsAString& aContentType, ErrorResult& aRv);
|
||||
|
||||
virtual already_AddRefed<FileImpl>
|
||||
virtual already_AddRefed<BlobImpl>
|
||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
const nsAString& aContentType, ErrorResult& aRv) = 0;
|
||||
|
||||
virtual const nsTArray<nsRefPtr<FileImpl>>*
|
||||
virtual const nsTArray<nsRefPtr<BlobImpl>>*
|
||||
GetSubBlobImpls() const = 0;
|
||||
|
||||
virtual nsresult GetInternalStream(nsIInputStream** aStream) = 0;
|
||||
@ -294,15 +339,15 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~FileImpl() {}
|
||||
virtual ~BlobImpl() {}
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(FileImpl, FILEIMPL_IID)
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(BlobImpl, FILEIMPL_IID)
|
||||
|
||||
class FileImplBase : public FileImpl
|
||||
class BlobImplBase : public BlobImpl
|
||||
{
|
||||
public:
|
||||
FileImplBase(const nsAString& aName, const nsAString& aContentType,
|
||||
BlobImplBase(const nsAString& aName, const nsAString& aContentType,
|
||||
uint64_t aLength, int64_t aLastModifiedDate)
|
||||
: mIsFile(true)
|
||||
, mImmutable(false)
|
||||
@ -316,7 +361,7 @@ public:
|
||||
mContentType.SetIsVoid(false);
|
||||
}
|
||||
|
||||
FileImplBase(const nsAString& aName, const nsAString& aContentType,
|
||||
BlobImplBase(const nsAString& aName, const nsAString& aContentType,
|
||||
uint64_t aLength)
|
||||
: mIsFile(true)
|
||||
, mImmutable(false)
|
||||
@ -330,7 +375,7 @@ public:
|
||||
mContentType.SetIsVoid(false);
|
||||
}
|
||||
|
||||
FileImplBase(const nsAString& aContentType, uint64_t aLength)
|
||||
BlobImplBase(const nsAString& aContentType, uint64_t aLength)
|
||||
: mIsFile(false)
|
||||
, mImmutable(false)
|
||||
, mContentType(aContentType)
|
||||
@ -342,7 +387,7 @@ public:
|
||||
mContentType.SetIsVoid(false);
|
||||
}
|
||||
|
||||
FileImplBase(const nsAString& aContentType, uint64_t aStart,
|
||||
BlobImplBase(const nsAString& aContentType, uint64_t aStart,
|
||||
uint64_t aLength)
|
||||
: mIsFile(false)
|
||||
, mImmutable(false)
|
||||
@ -377,14 +422,14 @@ public:
|
||||
|
||||
virtual void GetType(nsAString& aType) override;
|
||||
|
||||
virtual already_AddRefed<FileImpl>
|
||||
virtual already_AddRefed<BlobImpl>
|
||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
const nsAString& aContentType, ErrorResult& aRv) override
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
virtual const nsTArray<nsRefPtr<FileImpl>>*
|
||||
virtual const nsTArray<nsRefPtr<BlobImpl>>*
|
||||
GetSubBlobImpls() const override
|
||||
{
|
||||
return nullptr;
|
||||
@ -461,7 +506,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ~FileImplBase() {}
|
||||
virtual ~BlobImplBase() {}
|
||||
|
||||
indexedDB::FileInfo* GetFileInfo() const
|
||||
{
|
||||
@ -491,22 +536,22 @@ protected:
|
||||
* This class may be used off the main thread, and in particular, its
|
||||
* constructor and destructor may not run on the same thread. Be careful!
|
||||
*/
|
||||
class FileImplMemory final : public FileImplBase
|
||||
class BlobImplMemory final : public BlobImplBase
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
FileImplMemory(void* aMemoryBuffer, uint64_t aLength, const nsAString& aName,
|
||||
BlobImplMemory(void* aMemoryBuffer, uint64_t aLength, const nsAString& aName,
|
||||
const nsAString& aContentType, int64_t aLastModifiedDate)
|
||||
: FileImplBase(aName, aContentType, aLength, aLastModifiedDate)
|
||||
: BlobImplBase(aName, aContentType, aLength, aLastModifiedDate)
|
||||
, mDataOwner(new DataOwner(aMemoryBuffer, aLength))
|
||||
{
|
||||
NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
|
||||
}
|
||||
|
||||
FileImplMemory(void* aMemoryBuffer, uint64_t aLength,
|
||||
BlobImplMemory(void* aMemoryBuffer, uint64_t aLength,
|
||||
const nsAString& aContentType)
|
||||
: FileImplBase(aContentType, aLength)
|
||||
: BlobImplBase(aContentType, aLength)
|
||||
, mDataOwner(new DataOwner(aMemoryBuffer, aLength))
|
||||
{
|
||||
NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
|
||||
@ -514,7 +559,7 @@ public:
|
||||
|
||||
virtual nsresult GetInternalStream(nsIInputStream** aStream) override;
|
||||
|
||||
virtual already_AddRefed<FileImpl>
|
||||
virtual already_AddRefed<BlobImpl>
|
||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
const nsAString& aContentType, ErrorResult& aRv) override;
|
||||
|
||||
@ -570,29 +615,29 @@ public:
|
||||
|
||||
private:
|
||||
// Create slice
|
||||
FileImplMemory(const FileImplMemory* aOther, uint64_t aStart,
|
||||
BlobImplMemory(const BlobImplMemory* aOther, uint64_t aStart,
|
||||
uint64_t aLength, const nsAString& aContentType)
|
||||
: FileImplBase(aContentType, aOther->mStart + aStart, aLength)
|
||||
: BlobImplBase(aContentType, aOther->mStart + aStart, aLength)
|
||||
, mDataOwner(aOther->mDataOwner)
|
||||
{
|
||||
NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");
|
||||
mImmutable = aOther->mImmutable;
|
||||
}
|
||||
|
||||
~FileImplMemory() {}
|
||||
~BlobImplMemory() {}
|
||||
|
||||
// Used when backed by a memory store
|
||||
nsRefPtr<DataOwner> mDataOwner;
|
||||
};
|
||||
|
||||
class FileImplTemporaryFileBlob final : public FileImplBase
|
||||
class BlobImplTemporaryBlob final : public BlobImplBase
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
FileImplTemporaryFileBlob(PRFileDesc* aFD, uint64_t aStartPos,
|
||||
uint64_t aLength, const nsAString& aContentType)
|
||||
: FileImplBase(aContentType, aLength)
|
||||
BlobImplTemporaryBlob(PRFileDesc* aFD, uint64_t aStartPos,
|
||||
uint64_t aLength, const nsAString& aContentType)
|
||||
: BlobImplBase(aContentType, aLength)
|
||||
, mStartPos(aStartPos)
|
||||
{
|
||||
mFileDescOwner = new nsTemporaryFileInputStream::FileDescOwner(aFD);
|
||||
@ -600,33 +645,33 @@ public:
|
||||
|
||||
virtual nsresult GetInternalStream(nsIInputStream** aStream) override;
|
||||
|
||||
virtual already_AddRefed<FileImpl>
|
||||
virtual already_AddRefed<BlobImpl>
|
||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
const nsAString& aContentType, ErrorResult& aRv) override;
|
||||
|
||||
private:
|
||||
FileImplTemporaryFileBlob(const FileImplTemporaryFileBlob* aOther,
|
||||
uint64_t aStart, uint64_t aLength,
|
||||
const nsAString& aContentType)
|
||||
: FileImplBase(aContentType, aLength)
|
||||
BlobImplTemporaryBlob(const BlobImplTemporaryBlob* aOther,
|
||||
uint64_t aStart, uint64_t aLength,
|
||||
const nsAString& aContentType)
|
||||
: BlobImplBase(aContentType, aLength)
|
||||
, mStartPos(aStart)
|
||||
, mFileDescOwner(aOther->mFileDescOwner)
|
||||
{}
|
||||
|
||||
~FileImplTemporaryFileBlob() {}
|
||||
~BlobImplTemporaryBlob() {}
|
||||
|
||||
uint64_t mStartPos;
|
||||
nsRefPtr<nsTemporaryFileInputStream::FileDescOwner> mFileDescOwner;
|
||||
};
|
||||
|
||||
class FileImplFile : public FileImplBase
|
||||
class BlobImplFile : public BlobImplBase
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// Create as a file
|
||||
explicit FileImplFile(nsIFile* aFile, bool aTemporary = false)
|
||||
: FileImplBase(EmptyString(), EmptyString(), UINT64_MAX, INT64_MAX)
|
||||
explicit BlobImplFile(nsIFile* aFile, bool aTemporary = false)
|
||||
: BlobImplBase(EmptyString(), EmptyString(), UINT64_MAX, INT64_MAX)
|
||||
, mFile(aFile)
|
||||
, mWholeFile(true)
|
||||
, mStoredFile(false)
|
||||
@ -638,8 +683,8 @@ public:
|
||||
mFile->GetLeafName(mName);
|
||||
}
|
||||
|
||||
FileImplFile(nsIFile* aFile, indexedDB::FileInfo* aFileInfo)
|
||||
: FileImplBase(EmptyString(), EmptyString(), UINT64_MAX, INT64_MAX)
|
||||
BlobImplFile(nsIFile* aFile, indexedDB::FileInfo* aFileInfo)
|
||||
: BlobImplBase(EmptyString(), EmptyString(), UINT64_MAX, INT64_MAX)
|
||||
, mFile(aFile)
|
||||
, mWholeFile(true)
|
||||
, mStoredFile(true)
|
||||
@ -655,9 +700,9 @@ public:
|
||||
}
|
||||
|
||||
// Create as a file
|
||||
FileImplFile(const nsAString& aName, const nsAString& aContentType,
|
||||
BlobImplFile(const nsAString& aName, const nsAString& aContentType,
|
||||
uint64_t aLength, nsIFile* aFile)
|
||||
: FileImplBase(aName, aContentType, aLength, UINT64_MAX)
|
||||
: BlobImplBase(aName, aContentType, aLength, UINT64_MAX)
|
||||
, mFile(aFile)
|
||||
, mWholeFile(true)
|
||||
, mStoredFile(false)
|
||||
@ -666,10 +711,10 @@ public:
|
||||
NS_ASSERTION(mFile, "must have file");
|
||||
}
|
||||
|
||||
FileImplFile(const nsAString& aName, const nsAString& aContentType,
|
||||
BlobImplFile(const nsAString& aName, const nsAString& aContentType,
|
||||
uint64_t aLength, nsIFile* aFile,
|
||||
int64_t aLastModificationDate)
|
||||
: FileImplBase(aName, aContentType, aLength, aLastModificationDate)
|
||||
: BlobImplBase(aName, aContentType, aLength, aLastModificationDate)
|
||||
, mFile(aFile)
|
||||
, mWholeFile(true)
|
||||
, mStoredFile(false)
|
||||
@ -679,9 +724,9 @@ public:
|
||||
}
|
||||
|
||||
// Create as a file with custom name
|
||||
FileImplFile(nsIFile* aFile, const nsAString& aName,
|
||||
BlobImplFile(nsIFile* aFile, const nsAString& aName,
|
||||
const nsAString& aContentType)
|
||||
: FileImplBase(aName, aContentType, UINT64_MAX, INT64_MAX)
|
||||
: BlobImplBase(aName, aContentType, UINT64_MAX, INT64_MAX)
|
||||
, mFile(aFile)
|
||||
, mWholeFile(true)
|
||||
, mStoredFile(false)
|
||||
@ -695,10 +740,10 @@ public:
|
||||
}
|
||||
|
||||
// Create as a stored file
|
||||
FileImplFile(const nsAString& aName, const nsAString& aContentType,
|
||||
BlobImplFile(const nsAString& aName, const nsAString& aContentType,
|
||||
uint64_t aLength, nsIFile* aFile,
|
||||
indexedDB::FileInfo* aFileInfo)
|
||||
: FileImplBase(aName, aContentType, aLength, UINT64_MAX)
|
||||
: BlobImplBase(aName, aContentType, aLength, UINT64_MAX)
|
||||
, mFile(aFile)
|
||||
, mWholeFile(true)
|
||||
, mStoredFile(true)
|
||||
@ -709,9 +754,9 @@ public:
|
||||
}
|
||||
|
||||
// Create as a stored blob
|
||||
FileImplFile(const nsAString& aContentType, uint64_t aLength,
|
||||
BlobImplFile(const nsAString& aContentType, uint64_t aLength,
|
||||
nsIFile* aFile, indexedDB::FileInfo* aFileInfo)
|
||||
: FileImplBase(aContentType, aLength)
|
||||
: BlobImplBase(aContentType, aLength)
|
||||
, mFile(aFile)
|
||||
, mWholeFile(true)
|
||||
, mStoredFile(true)
|
||||
@ -722,8 +767,8 @@ public:
|
||||
}
|
||||
|
||||
// Create as a file to be later initialized
|
||||
FileImplFile()
|
||||
: FileImplBase(EmptyString(), EmptyString(), UINT64_MAX, INT64_MAX)
|
||||
BlobImplFile()
|
||||
: BlobImplBase(EmptyString(), EmptyString(), UINT64_MAX, INT64_MAX)
|
||||
, mWholeFile(true)
|
||||
, mStoredFile(false)
|
||||
, mIsTemporary(false)
|
||||
@ -745,9 +790,9 @@ public:
|
||||
void SetPath(const nsAString& aFullPath);
|
||||
|
||||
protected:
|
||||
virtual ~FileImplFile() {
|
||||
virtual ~BlobImplFile() {
|
||||
if (mFile && mIsTemporary) {
|
||||
NS_WARNING("In temporary ~FileImplFile");
|
||||
NS_WARNING("In temporary ~BlobImplFile");
|
||||
// Ignore errors if any, not much we can do. Clean-up will be done by
|
||||
// https://mxr.mozilla.org/mozilla-central/source/xpcom/io/nsAnonymousTemporaryFile.cpp?rev=6c1c7e45c902#127
|
||||
#ifdef DEBUG
|
||||
@ -760,9 +805,9 @@ protected:
|
||||
|
||||
private:
|
||||
// Create slice
|
||||
FileImplFile(const FileImplFile* aOther, uint64_t aStart,
|
||||
BlobImplFile(const BlobImplFile* aOther, uint64_t aStart,
|
||||
uint64_t aLength, const nsAString& aContentType)
|
||||
: FileImplBase(aContentType, aOther->mStart + aStart, aLength)
|
||||
: BlobImplBase(aContentType, aOther->mStart + aStart, aLength)
|
||||
, mFile(aOther->mFile)
|
||||
, mWholeFile(false)
|
||||
, mStoredFile(aOther->mStoredFile)
|
||||
@ -788,7 +833,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
virtual already_AddRefed<FileImpl>
|
||||
virtual already_AddRefed<BlobImpl>
|
||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
const nsAString& aContentType, ErrorResult& aRv) override;
|
||||
|
||||
@ -823,7 +868,8 @@ public:
|
||||
|
||||
NS_DECL_NSIDOMFILELIST
|
||||
|
||||
virtual JSObject* WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto) override;
|
||||
virtual JSObject* WrapObject(JSContext *cx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
nsISupports* GetParentObject()
|
||||
{
|
||||
|
@ -90,8 +90,8 @@ public:
|
||||
|
||||
if (!mFailed) {
|
||||
// The correct parentObject has to be set by the mEncodeCompleteCallback.
|
||||
nsRefPtr<File> blob =
|
||||
File::CreateMemoryFile(nullptr, mImgData, mImgSize, mType);
|
||||
nsRefPtr<Blob> blob =
|
||||
Blob::CreateMemoryBlob(nullptr, mImgData, mImgSize, mType);
|
||||
MOZ_ASSERT(blob);
|
||||
|
||||
rv = mEncodeCompleteCallback->ReceiveBlob(blob.forget());
|
||||
|
@ -116,7 +116,7 @@ class EncodeCompleteCallback
|
||||
public:
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(EncodeCompleteCallback)
|
||||
|
||||
virtual nsresult ReceiveBlob(already_AddRefed<File> aBlob) = 0;
|
||||
virtual nsresult ReceiveBlob(already_AddRefed<Blob> aBlob) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~EncodeCompleteCallback() {}
|
||||
|
@ -111,9 +111,9 @@ PostMessageReadStructuredClone(JSContext* cx,
|
||||
if (tag == SCTAG_DOM_BLOB) {
|
||||
NS_ASSERTION(!data, "Data should be empty");
|
||||
|
||||
// What we get back from the reader is a FileImpl.
|
||||
// What we get back from the reader is a BlobImpl.
|
||||
// From that we create a new File.
|
||||
FileImpl* blobImpl;
|
||||
BlobImpl* blobImpl;
|
||||
if (JS_ReadBytes(reader, &blobImpl, sizeof(blobImpl))) {
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
@ -124,9 +124,9 @@ PostMessageReadStructuredClone(JSContext* cx,
|
||||
// while destructors are running.
|
||||
JS::Rooted<JS::Value> val(cx);
|
||||
{
|
||||
nsRefPtr<File> blob = new File(scInfo->mPort->GetParentObject(),
|
||||
blobImpl);
|
||||
if (!GetOrCreateDOMReflector(cx, blob, &val)) {
|
||||
nsRefPtr<Blob> blob = Blob::Create(scInfo->mPort->GetParentObject(),
|
||||
blobImpl);
|
||||
if (!ToJSValue(cx, blob, &val)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@ -168,9 +168,9 @@ PostMessageWriteStructuredClone(JSContext* cx,
|
||||
|
||||
// See if this is a File/Blob object.
|
||||
{
|
||||
File* blob = nullptr;
|
||||
Blob* blob = nullptr;
|
||||
if (NS_SUCCEEDED(UNWRAP_OBJECT(Blob, obj, blob))) {
|
||||
FileImpl* blobImpl = blob->Impl();
|
||||
BlobImpl* blobImpl = blob->Impl();
|
||||
if (JS_WriteUint32Pair(writer, SCTAG_DOM_BLOB, 0) &&
|
||||
JS_WriteBytes(writer, &blobImpl, sizeof(blobImpl))) {
|
||||
scInfo->mEvent->StoreISupports(blobImpl);
|
||||
|
@ -4,7 +4,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 "MultipartFileImpl.h"
|
||||
#include "MultipartBlobImpl.h"
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/dom/BlobSet.h"
|
||||
#include "mozilla/dom/FileBinding.h"
|
||||
@ -23,10 +23,10 @@
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(MultipartFileImpl, FileImpl)
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(MultipartBlobImpl, BlobImpl)
|
||||
|
||||
nsresult
|
||||
MultipartFileImpl::GetInternalStream(nsIInputStream** aStream)
|
||||
MultipartBlobImpl::GetInternalStream(nsIInputStream** aStream)
|
||||
{
|
||||
nsresult rv;
|
||||
*aStream = nullptr;
|
||||
@ -38,7 +38,7 @@ MultipartFileImpl::GetInternalStream(nsIInputStream** aStream)
|
||||
uint32_t i;
|
||||
for (i = 0; i < mBlobImpls.Length(); i++) {
|
||||
nsCOMPtr<nsIInputStream> scratchStream;
|
||||
FileImpl* blobImpl = mBlobImpls.ElementAt(i).get();
|
||||
BlobImpl* blobImpl = mBlobImpls.ElementAt(i).get();
|
||||
|
||||
rv = blobImpl->GetInternalStream(getter_AddRefs(scratchStream));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@ -51,13 +51,13 @@ MultipartFileImpl::GetInternalStream(nsIInputStream** aStream)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<FileImpl>
|
||||
MultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
already_AddRefed<BlobImpl>
|
||||
MultipartBlobImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
const nsAString& aContentType,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
// If we clamped to nothing we create an empty blob
|
||||
nsTArray<nsRefPtr<FileImpl>> blobImpls;
|
||||
nsTArray<nsRefPtr<BlobImpl>> blobImpls;
|
||||
|
||||
uint64_t length = aLength;
|
||||
uint64_t skipStart = aStart;
|
||||
@ -65,7 +65,7 @@ MultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
// Prune the list of blobs if we can
|
||||
uint32_t i;
|
||||
for (i = 0; length && skipStart && i < mBlobImpls.Length(); i++) {
|
||||
FileImpl* blobImpl = mBlobImpls[i].get();
|
||||
BlobImpl* blobImpl = mBlobImpls[i].get();
|
||||
|
||||
uint64_t l = blobImpl->GetSize(aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
@ -75,14 +75,14 @@ MultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
if (skipStart < l) {
|
||||
uint64_t upperBound = std::min<uint64_t>(l - skipStart, length);
|
||||
|
||||
nsRefPtr<FileImpl> firstBlobImpl =
|
||||
nsRefPtr<BlobImpl> firstBlobImpl =
|
||||
blobImpl->CreateSlice(skipStart, upperBound,
|
||||
aContentType, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Avoid wrapping a single blob inside an MultipartFileImpl
|
||||
// Avoid wrapping a single blob inside an MultipartBlobImpl
|
||||
if (length == upperBound) {
|
||||
return firstBlobImpl.forget();
|
||||
}
|
||||
@ -97,7 +97,7 @@ MultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
|
||||
// Now append enough blobs until we're done
|
||||
for (; length && i < mBlobImpls.Length(); i++) {
|
||||
FileImpl* blobImpl = mBlobImpls[i].get();
|
||||
BlobImpl* blobImpl = mBlobImpls[i].get();
|
||||
|
||||
uint64_t l = blobImpl->GetSize(aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
@ -105,7 +105,7 @@ MultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
}
|
||||
|
||||
if (length < l) {
|
||||
nsRefPtr<FileImpl> lastBlobImpl =
|
||||
nsRefPtr<BlobImpl> lastBlobImpl =
|
||||
blobImpl->CreateSlice(0, length, aContentType, aRv);
|
||||
if (NS_WARN_IF(aRv.Failed())) {
|
||||
return nullptr;
|
||||
@ -119,19 +119,19 @@ MultipartFileImpl::CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
}
|
||||
|
||||
// we can create our blob now
|
||||
nsRefPtr<FileImpl> impl =
|
||||
new MultipartFileImpl(blobImpls, aContentType);
|
||||
nsRefPtr<BlobImpl> impl =
|
||||
new MultipartBlobImpl(blobImpls, aContentType);
|
||||
return impl.forget();
|
||||
}
|
||||
|
||||
void
|
||||
MultipartFileImpl::InitializeBlob()
|
||||
MultipartBlobImpl::InitializeBlob()
|
||||
{
|
||||
SetLengthAndModifiedDate();
|
||||
}
|
||||
|
||||
void
|
||||
MultipartFileImpl::InitializeBlob(
|
||||
MultipartBlobImpl::InitializeBlob(
|
||||
JSContext* aCx,
|
||||
const Sequence<OwningArrayBufferOrArrayBufferViewOrBlobOrString>& aData,
|
||||
const nsAString& aContentType,
|
||||
@ -145,8 +145,8 @@ MultipartFileImpl::InitializeBlob(
|
||||
const OwningArrayBufferOrArrayBufferViewOrBlobOrString& data = aData[i];
|
||||
|
||||
if (data.IsBlob()) {
|
||||
nsRefPtr<File> file = data.GetAsBlob().get();
|
||||
blobSet.AppendBlobImpl(file->Impl());
|
||||
nsRefPtr<Blob> blob = data.GetAsBlob().get();
|
||||
blobSet.AppendBlobImpl(blob->Impl());
|
||||
}
|
||||
|
||||
else if (data.IsString()) {
|
||||
@ -185,7 +185,7 @@ MultipartFileImpl::InitializeBlob(
|
||||
}
|
||||
|
||||
void
|
||||
MultipartFileImpl::SetLengthAndModifiedDate()
|
||||
MultipartBlobImpl::SetLengthAndModifiedDate()
|
||||
{
|
||||
MOZ_ASSERT(mLength == UINT64_MAX);
|
||||
MOZ_ASSERT(mLastModificationDate == INT64_MAX);
|
||||
@ -195,7 +195,7 @@ MultipartFileImpl::SetLengthAndModifiedDate()
|
||||
bool lastModifiedSet = false;
|
||||
|
||||
for (uint32_t index = 0, count = mBlobImpls.Length(); index < count; index++) {
|
||||
nsRefPtr<FileImpl>& blob = mBlobImpls[index];
|
||||
nsRefPtr<BlobImpl>& blob = mBlobImpls[index];
|
||||
|
||||
#ifdef DEBUG
|
||||
MOZ_ASSERT(!blob->IsSizeUnknown());
|
||||
@ -233,17 +233,17 @@ MultipartFileImpl::SetLengthAndModifiedDate()
|
||||
}
|
||||
|
||||
void
|
||||
MultipartFileImpl::GetMozFullPathInternal(nsAString& aFilename,
|
||||
MultipartBlobImpl::GetMozFullPathInternal(nsAString& aFilename,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
if (!mIsFromNsIFile || mBlobImpls.Length() == 0) {
|
||||
FileImplBase::GetMozFullPathInternal(aFilename, aRv);
|
||||
BlobImplBase::GetMozFullPathInternal(aFilename, aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
FileImpl* blobImpl = mBlobImpls.ElementAt(0).get();
|
||||
BlobImpl* blobImpl = mBlobImpls.ElementAt(0).get();
|
||||
if (!blobImpl) {
|
||||
FileImplBase::GetMozFullPathInternal(aFilename, aRv);
|
||||
BlobImplBase::GetMozFullPathInternal(aFilename, aRv);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -251,12 +251,12 @@ MultipartFileImpl::GetMozFullPathInternal(nsAString& aFilename,
|
||||
}
|
||||
|
||||
nsresult
|
||||
MultipartFileImpl::SetMutable(bool aMutable)
|
||||
MultipartBlobImpl::SetMutable(bool aMutable)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// This looks a little sketchy since FileImpl objects are supposed to be
|
||||
// threadsafe. However, we try to enforce that all FileImpl objects must be
|
||||
// This looks a little sketchy since BlobImpl objects are supposed to be
|
||||
// threadsafe. However, we try to enforce that all BlobImpl objects must be
|
||||
// set to immutable *before* being passed to another thread, so this should
|
||||
// be safe.
|
||||
if (!aMutable && !mImmutable && !mBlobImpls.IsEmpty()) {
|
||||
@ -270,7 +270,7 @@ MultipartFileImpl::SetMutable(bool aMutable)
|
||||
}
|
||||
}
|
||||
|
||||
rv = FileImplBase::SetMutable(aMutable);
|
||||
rv = BlobImplBase::SetMutable(aMutable);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
@ -281,7 +281,7 @@ MultipartFileImpl::SetMutable(bool aMutable)
|
||||
}
|
||||
|
||||
void
|
||||
MultipartFileImpl::InitializeChromeFile(File& aBlob,
|
||||
MultipartBlobImpl::InitializeChromeFile(Blob& aBlob,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
@ -312,7 +312,7 @@ MultipartFileImpl::InitializeChromeFile(File& aBlob,
|
||||
}
|
||||
|
||||
void
|
||||
MultipartFileImpl::InitializeChromeFile(nsPIDOMWindow* aWindow,
|
||||
MultipartBlobImpl::InitializeChromeFile(nsPIDOMWindow* aWindow,
|
||||
nsIFile* aFile,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
bool aIsFromNsIFile,
|
||||
@ -385,7 +385,7 @@ MultipartFileImpl::InitializeChromeFile(nsPIDOMWindow* aWindow,
|
||||
}
|
||||
|
||||
void
|
||||
MultipartFileImpl::InitializeChromeFile(nsPIDOMWindow* aWindow,
|
||||
MultipartBlobImpl::InitializeChromeFile(nsPIDOMWindow* aWindow,
|
||||
const nsAString& aData,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
ErrorResult& aRv)
|
||||
@ -400,7 +400,7 @@ MultipartFileImpl::InitializeChromeFile(nsPIDOMWindow* aWindow,
|
||||
}
|
||||
|
||||
bool
|
||||
MultipartFileImpl::MayBeClonedToOtherThreads() const
|
||||
MultipartBlobImpl::MayBeClonedToOtherThreads() const
|
||||
{
|
||||
for (uint32_t i = 0; i < mBlobImpls.Length(); ++i) {
|
||||
if (!mBlobImpls[i]->MayBeClonedToOtherThreads()) {
|
@ -4,8 +4,8 @@
|
||||
* 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_dom_MultipartFileImpl_h
|
||||
#define mozilla_dom_MultipartFileImpl_h
|
||||
#ifndef mozilla_dom_MultipartBlobImpl_h
|
||||
#define mozilla_dom_MultipartBlobImpl_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/CheckedInt.h"
|
||||
@ -18,16 +18,16 @@
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
class MultipartFileImpl final : public FileImplBase
|
||||
class MultipartBlobImpl final : public BlobImplBase
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
// Create as a file
|
||||
MultipartFileImpl(const nsTArray<nsRefPtr<FileImpl>>& aBlobImpls,
|
||||
MultipartBlobImpl(const nsTArray<nsRefPtr<BlobImpl>>& aBlobImpls,
|
||||
const nsAString& aName,
|
||||
const nsAString& aContentType)
|
||||
: FileImplBase(aName, aContentType, UINT64_MAX),
|
||||
: BlobImplBase(aName, aContentType, UINT64_MAX),
|
||||
mBlobImpls(aBlobImpls),
|
||||
mIsFromNsIFile(false)
|
||||
{
|
||||
@ -35,9 +35,9 @@ public:
|
||||
}
|
||||
|
||||
// Create as a blob
|
||||
MultipartFileImpl(const nsTArray<nsRefPtr<FileImpl>>& aBlobImpls,
|
||||
MultipartBlobImpl(const nsTArray<nsRefPtr<BlobImpl>>& aBlobImpls,
|
||||
const nsAString& aContentType)
|
||||
: FileImplBase(aContentType, UINT64_MAX),
|
||||
: BlobImplBase(aContentType, UINT64_MAX),
|
||||
mBlobImpls(aBlobImpls),
|
||||
mIsFromNsIFile(false)
|
||||
{
|
||||
@ -45,15 +45,15 @@ public:
|
||||
}
|
||||
|
||||
// Create as a file to be later initialized
|
||||
explicit MultipartFileImpl(const nsAString& aName)
|
||||
: FileImplBase(aName, EmptyString(), UINT64_MAX),
|
||||
explicit MultipartBlobImpl(const nsAString& aName)
|
||||
: BlobImplBase(aName, EmptyString(), UINT64_MAX),
|
||||
mIsFromNsIFile(false)
|
||||
{
|
||||
}
|
||||
|
||||
// Create as a blob to be later initialized
|
||||
MultipartFileImpl()
|
||||
: FileImplBase(EmptyString(), UINT64_MAX),
|
||||
MultipartBlobImpl()
|
||||
: BlobImplBase(EmptyString(), UINT64_MAX),
|
||||
mIsFromNsIFile(false)
|
||||
{
|
||||
}
|
||||
@ -67,7 +67,7 @@ public:
|
||||
bool aNativeEOL,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void InitializeChromeFile(File& aData,
|
||||
void InitializeChromeFile(Blob& aData,
|
||||
const ChromeFilePropertyBag& aBag,
|
||||
ErrorResult& aRv);
|
||||
|
||||
@ -82,7 +82,7 @@ public:
|
||||
bool aIsFromNsIFile,
|
||||
ErrorResult& aRv);
|
||||
|
||||
virtual already_AddRefed<FileImpl>
|
||||
virtual already_AddRefed<BlobImpl>
|
||||
CreateSlice(uint64_t aStart, uint64_t aLength,
|
||||
const nsAString& aContentType,
|
||||
ErrorResult& aRv) override;
|
||||
@ -94,7 +94,7 @@ public:
|
||||
|
||||
virtual nsresult GetInternalStream(nsIInputStream** aInputStream) override;
|
||||
|
||||
virtual const nsTArray<nsRefPtr<FileImpl>>* GetSubBlobImpls() const override
|
||||
virtual const nsTArray<nsRefPtr<BlobImpl>>* GetSubBlobImpls() const override
|
||||
{
|
||||
return &mBlobImpls;
|
||||
}
|
||||
@ -118,12 +118,12 @@ public:
|
||||
virtual bool MayBeClonedToOtherThreads() const override;
|
||||
|
||||
protected:
|
||||
virtual ~MultipartFileImpl() {}
|
||||
virtual ~MultipartBlobImpl() {}
|
||||
|
||||
void SetLengthAndModifiedDate();
|
||||
|
||||
nsTArray<nsRefPtr<FileImpl>> mBlobImpls;
|
||||
nsTArray<nsRefPtr<BlobImpl>> mBlobImpls;
|
||||
bool mIsFromNsIFile;
|
||||
};
|
||||
|
||||
#endif // mozilla_dom_MultipartFileImpl_h
|
||||
#endif // mozilla_dom_MultipartBlobImpl_h
|
@ -1213,7 +1213,7 @@ Navigator::SendBeacon(const nsAString& aUrl,
|
||||
in = strStream;
|
||||
|
||||
} else if (aData.Value().IsBlob()) {
|
||||
File& blob = aData.Value().GetAsBlob();
|
||||
Blob& blob = aData.Value().GetAsBlob();
|
||||
rv = blob.GetInternalStream(getter_AddRefs(in));
|
||||
if (NS_FAILED(rv)) {
|
||||
aRv.Throw(NS_ERROR_FAILURE);
|
||||
|
@ -112,7 +112,7 @@ URL::Constructor(const nsAString& aUrl, nsIURI* aBase, ErrorResult& aRv)
|
||||
|
||||
void
|
||||
URL::CreateObjectURL(const GlobalObject& aGlobal,
|
||||
File& aBlob,
|
||||
Blob& aBlob,
|
||||
const objectURLOptions& aOptions,
|
||||
nsAString& aResult,
|
||||
ErrorResult& aError)
|
||||
|
@ -22,7 +22,7 @@ class DOMMediaStream;
|
||||
|
||||
namespace dom {
|
||||
|
||||
class File;
|
||||
class Blob;
|
||||
class MediaSource;
|
||||
class GlobalObject;
|
||||
struct objectURLOptions;
|
||||
@ -61,7 +61,7 @@ public:
|
||||
Constructor(const nsAString& aUrl, nsIURI* aBase, ErrorResult& aRv);
|
||||
|
||||
static void CreateObjectURL(const GlobalObject& aGlobal,
|
||||
File& aBlob,
|
||||
Blob& aBlob,
|
||||
const objectURLOptions& aOptions,
|
||||
nsAString& aResult,
|
||||
ErrorResult& aError);
|
||||
|
@ -2210,7 +2210,7 @@ WebSocket::Send(const nsAString& aData,
|
||||
}
|
||||
|
||||
void
|
||||
WebSocket::Send(File& aData, ErrorResult& aRv)
|
||||
WebSocket::Send(Blob& aData, ErrorResult& aRv)
|
||||
{
|
||||
AssertIsOnTargetThread();
|
||||
|
||||
|
@ -28,7 +28,7 @@ class nsIInputStream;
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
class File;
|
||||
class Blob;
|
||||
|
||||
class WebSocketImpl;
|
||||
|
||||
@ -121,7 +121,7 @@ public: // WebIDL interface:
|
||||
// webIDL: void send(DOMString|Blob|ArrayBufferView data);
|
||||
void Send(const nsAString& aData,
|
||||
ErrorResult& aRv);
|
||||
void Send(File& aData,
|
||||
void Send(Blob& aData,
|
||||
ErrorResult& aRv);
|
||||
void Send(const ArrayBuffer& aData,
|
||||
ErrorResult& aRv);
|
||||
|
@ -237,7 +237,7 @@ UNIFIED_SOURCES += [
|
||||
'Link.cpp',
|
||||
'MessageChannel.cpp',
|
||||
'MessagePortList.cpp',
|
||||
'MultipartFileImpl.cpp',
|
||||
'MultipartBlobImpl.cpp',
|
||||
'Navigator.cpp',
|
||||
'NodeInfo.cpp',
|
||||
'NodeIterator.cpp',
|
||||
|
@ -6090,16 +6090,16 @@ nsContentUtils::CreateBlobBuffer(JSContext* aCx,
|
||||
{
|
||||
uint32_t blobLen = aData.Length();
|
||||
void* blobData = malloc(blobLen);
|
||||
nsRefPtr<File> blob;
|
||||
nsRefPtr<Blob> blob;
|
||||
if (blobData) {
|
||||
memcpy(blobData, aData.BeginReading(), blobLen);
|
||||
blob = mozilla::dom::File::CreateMemoryFile(aParent, blobData, blobLen,
|
||||
blob = mozilla::dom::Blob::CreateMemoryBlob(aParent, blobData, blobLen,
|
||||
EmptyString());
|
||||
} else {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (!GetOrCreateDOMReflector(aCx, blob, aBlob)) {
|
||||
if (!ToJSValue(aCx, blob, aBlob)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -7347,27 +7347,27 @@ nsContentUtils::TransferableToIPCTransferable(nsITransferable* aTransferable,
|
||||
}
|
||||
|
||||
// Otherwise, handle this as a file.
|
||||
nsCOMPtr<FileImpl> fileImpl;
|
||||
nsCOMPtr<BlobImpl> blobImpl;
|
||||
nsCOMPtr<nsIFile> file = do_QueryInterface(data);
|
||||
if (file) {
|
||||
fileImpl = new FileImplFile(file, false);
|
||||
blobImpl = new BlobImplFile(file, false);
|
||||
ErrorResult rv;
|
||||
fileImpl->GetSize(rv);
|
||||
fileImpl->GetLastModified(rv);
|
||||
blobImpl->GetSize(rv);
|
||||
blobImpl->GetLastModified(rv);
|
||||
} else {
|
||||
fileImpl = do_QueryInterface(data);
|
||||
blobImpl = do_QueryInterface(data);
|
||||
}
|
||||
if (fileImpl) {
|
||||
if (blobImpl) {
|
||||
IPCDataTransferItem* item = aIPCDataTransfer->items().AppendElement();
|
||||
item->flavor() = nsCString(flavorStr);
|
||||
if (aChild) {
|
||||
item->data() =
|
||||
mozilla::dom::BlobChild::GetOrCreate(aChild,
|
||||
static_cast<FileImpl*>(fileImpl.get()));
|
||||
static_cast<BlobImpl*>(blobImpl.get()));
|
||||
} else if (aParent) {
|
||||
item->data() =
|
||||
mozilla::dom::BlobParent::GetOrCreate(aParent,
|
||||
static_cast<FileImpl*>(fileImpl.get()));
|
||||
static_cast<BlobImpl*>(blobImpl.get()));
|
||||
}
|
||||
} else {
|
||||
// This is a hack to support kFilePromiseMime.
|
||||
|
@ -267,7 +267,7 @@ nsDOMDataChannel::Send(const nsAString& aData, ErrorResult& aRv)
|
||||
}
|
||||
|
||||
void
|
||||
nsDOMDataChannel::Send(File& aData, ErrorResult& aRv)
|
||||
nsDOMDataChannel::Send(Blob& aData, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class File;
|
||||
class Blob;
|
||||
}
|
||||
|
||||
class DataChannel;
|
||||
@ -70,7 +70,7 @@ public:
|
||||
static_cast<int>(aType));
|
||||
}
|
||||
void Send(const nsAString& aData, mozilla::ErrorResult& aRv);
|
||||
void Send(mozilla::dom::File& aData, mozilla::ErrorResult& aRv);
|
||||
void Send(mozilla::dom::Blob& aData, mozilla::ErrorResult& aRv);
|
||||
void Send(const mozilla::dom::ArrayBuffer& aData, mozilla::ErrorResult& aRv);
|
||||
void Send(const mozilla::dom::ArrayBufferView& aData,
|
||||
mozilla::ErrorResult& aRv);
|
||||
|
@ -43,13 +43,13 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileReader)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMFileReader,
|
||||
FileIOObject)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFile)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBlob)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMFileReader,
|
||||
FileIOObject)
|
||||
tmp->mResultArrayBuffer = nullptr;
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFile)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBlob)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
|
||||
@ -183,43 +183,43 @@ nsDOMFileReader::GetError(nsISupports** aError)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileReader::ReadAsArrayBuffer(nsIDOMBlob* aFile, JSContext* aCx)
|
||||
nsDOMFileReader::ReadAsArrayBuffer(nsIDOMBlob* aBlob, JSContext* aCx)
|
||||
{
|
||||
NS_ENSURE_TRUE(aFile, NS_ERROR_NULL_POINTER);
|
||||
NS_ENSURE_TRUE(aBlob, NS_ERROR_NULL_POINTER);
|
||||
ErrorResult rv;
|
||||
nsRefPtr<File> file = static_cast<File*>(aFile);
|
||||
ReadAsArrayBuffer(aCx, *file, rv);
|
||||
nsRefPtr<Blob> blob = static_cast<Blob*>(aBlob);
|
||||
ReadAsArrayBuffer(aCx, *blob, rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileReader::ReadAsBinaryString(nsIDOMBlob* aFile)
|
||||
nsDOMFileReader::ReadAsBinaryString(nsIDOMBlob* aBlob)
|
||||
{
|
||||
NS_ENSURE_TRUE(aFile, NS_ERROR_NULL_POINTER);
|
||||
NS_ENSURE_TRUE(aBlob, NS_ERROR_NULL_POINTER);
|
||||
ErrorResult rv;
|
||||
nsRefPtr<File> file = static_cast<File*>(aFile);
|
||||
ReadAsBinaryString(*file, rv);
|
||||
nsRefPtr<Blob> blob = static_cast<Blob*>(aBlob);
|
||||
ReadAsBinaryString(*blob, rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileReader::ReadAsText(nsIDOMBlob* aFile,
|
||||
nsDOMFileReader::ReadAsText(nsIDOMBlob* aBlob,
|
||||
const nsAString &aCharset)
|
||||
{
|
||||
NS_ENSURE_TRUE(aFile, NS_ERROR_NULL_POINTER);
|
||||
NS_ENSURE_TRUE(aBlob, NS_ERROR_NULL_POINTER);
|
||||
ErrorResult rv;
|
||||
nsRefPtr<File> file = static_cast<File*>(aFile);
|
||||
ReadAsText(*file, aCharset, rv);
|
||||
nsRefPtr<Blob> blob = static_cast<Blob*>(aBlob);
|
||||
ReadAsText(*blob, aCharset, rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMFileReader::ReadAsDataURL(nsIDOMBlob* aFile)
|
||||
nsDOMFileReader::ReadAsDataURL(nsIDOMBlob* aBlob)
|
||||
{
|
||||
NS_ENSURE_TRUE(aFile, NS_ERROR_NULL_POINTER);
|
||||
NS_ENSURE_TRUE(aBlob, NS_ERROR_NULL_POINTER);
|
||||
ErrorResult rv;
|
||||
nsRefPtr<File> file = static_cast<File*>(aFile);
|
||||
ReadAsDataURL(*file, rv);
|
||||
nsRefPtr<Blob> blob = static_cast<Blob*>(aBlob);
|
||||
ReadAsDataURL(*blob, rv);
|
||||
return rv.StealNSResult();
|
||||
}
|
||||
|
||||
@ -241,7 +241,7 @@ nsDOMFileReader::DoAbort(nsAString& aEvent)
|
||||
if (mAsyncStream) {
|
||||
mAsyncStream = nullptr;
|
||||
}
|
||||
mFile = nullptr;
|
||||
mBlob = nullptr;
|
||||
|
||||
//Clean up memory buffer
|
||||
FreeFileData();
|
||||
@ -281,8 +281,8 @@ nsDOMFileReader::DoOnLoadEnd(nsresult aStatus,
|
||||
// Make sure we drop all the objects that could hold files open now.
|
||||
nsCOMPtr<nsIAsyncInputStream> stream;
|
||||
mAsyncStream.swap(stream);
|
||||
nsCOMPtr<nsIDOMBlob> file;
|
||||
mFile.swap(file);
|
||||
nsCOMPtr<nsIDOMBlob> blob;
|
||||
mBlob.swap(blob);
|
||||
|
||||
aSuccessEvent = NS_LITERAL_STRING(LOAD_STR);
|
||||
aTerminationEvent = NS_LITERAL_STRING(LOADEND_STR);
|
||||
@ -319,13 +319,13 @@ nsDOMFileReader::DoOnLoadEnd(nsresult aStatus,
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
break;
|
||||
}
|
||||
rv = GetAsText(file, mCharset, "", mDataLen, mResult);
|
||||
rv = GetAsText(blob, mCharset, "", mDataLen, mResult);
|
||||
break;
|
||||
}
|
||||
rv = GetAsText(file, mCharset, mFileData, mDataLen, mResult);
|
||||
rv = GetAsText(blob, mCharset, mFileData, mDataLen, mResult);
|
||||
break;
|
||||
case FILE_AS_DATAURL:
|
||||
rv = GetAsDataURL(file, mFileData, mDataLen, mResult);
|
||||
rv = GetAsDataURL(blob, mFileData, mDataLen, mResult);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -380,7 +380,7 @@ nsDOMFileReader::DoReadData(nsIAsyncInputStream* aStream, uint64_t aCount)
|
||||
// Helper methods
|
||||
|
||||
void
|
||||
nsDOMFileReader::ReadFileContent(File& aFile,
|
||||
nsDOMFileReader::ReadFileContent(Blob& aBlob,
|
||||
const nsAString &aCharset,
|
||||
eDataFormat aDataFormat,
|
||||
ErrorResult& aRv)
|
||||
@ -394,7 +394,7 @@ nsDOMFileReader::ReadFileContent(File& aFile,
|
||||
mReadyState = nsIDOMFileReader::EMPTY;
|
||||
FreeFileData();
|
||||
|
||||
mFile = &aFile;
|
||||
mBlob = &aBlob;
|
||||
mDataFormat = aDataFormat;
|
||||
CopyUTF16toUTF8(aCharset, mCharset);
|
||||
|
||||
@ -408,7 +408,7 @@ nsDOMFileReader::ReadFileContent(File& aFile,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
rv = mFile->GetInternalStream(getter_AddRefs(stream));
|
||||
rv = mBlob->GetInternalStream(getter_AddRefs(stream));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(rv);
|
||||
return;
|
||||
@ -440,7 +440,7 @@ nsDOMFileReader::ReadFileContent(File& aFile,
|
||||
MOZ_ASSERT(mAsyncStream);
|
||||
|
||||
mTotal = mozilla::dom::kUnknownSize;
|
||||
mFile->GetSize(&mTotal);
|
||||
mBlob->GetSize(&mTotal);
|
||||
|
||||
rv = DoAsyncWait(mAsyncStream);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
@ -462,7 +462,7 @@ nsDOMFileReader::ReadFileContent(File& aFile,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMFileReader::GetAsText(nsIDOMBlob *aFile,
|
||||
nsDOMFileReader::GetAsText(nsIDOMBlob *aBlob,
|
||||
const nsACString &aCharset,
|
||||
const char *aFileData,
|
||||
uint32_t aDataLen,
|
||||
@ -480,7 +480,7 @@ nsDOMFileReader::GetAsText(nsIDOMBlob *aFile,
|
||||
encoding)) {
|
||||
// API argument failed. Try the type property of the blob.
|
||||
nsAutoString type16;
|
||||
aFile->GetType(type16);
|
||||
aBlob->GetType(type16);
|
||||
NS_ConvertUTF16toUTF8 type(type16);
|
||||
nsAutoCString specifiedCharset;
|
||||
bool haveCharset;
|
||||
@ -502,7 +502,7 @@ nsDOMFileReader::GetAsText(nsIDOMBlob *aFile,
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMFileReader::GetAsDataURL(nsIDOMBlob *aFile,
|
||||
nsDOMFileReader::GetAsDataURL(nsIDOMBlob *aBlob,
|
||||
const char *aFileData,
|
||||
uint32_t aDataLen,
|
||||
nsAString& aResult)
|
||||
@ -511,7 +511,7 @@ nsDOMFileReader::GetAsDataURL(nsIDOMBlob *aFile,
|
||||
|
||||
nsresult rv;
|
||||
nsString contentType;
|
||||
rv = aFile->GetType(contentType);
|
||||
rv = aBlob->GetType(contentType);
|
||||
if (NS_SUCCEEDED(rv) && !contentType.IsEmpty()) {
|
||||
aResult.Append(contentType);
|
||||
} else {
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class File;
|
||||
class Blob;
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,7 +38,8 @@ class nsDOMFileReader final : public mozilla::dom::FileIOObject,
|
||||
{
|
||||
typedef mozilla::ErrorResult ErrorResult;
|
||||
typedef mozilla::dom::GlobalObject GlobalObject;
|
||||
typedef mozilla::dom::File File;
|
||||
typedef mozilla::dom::Blob Blob;
|
||||
|
||||
public:
|
||||
nsDOMFileReader();
|
||||
|
||||
@ -68,17 +69,17 @@ public:
|
||||
// WebIDL
|
||||
static already_AddRefed<nsDOMFileReader>
|
||||
Constructor(const GlobalObject& aGlobal, ErrorResult& aRv);
|
||||
void ReadAsArrayBuffer(JSContext* aCx, File& aBlob, ErrorResult& aRv)
|
||||
void ReadAsArrayBuffer(JSContext* aCx, Blob& aBlob, ErrorResult& aRv)
|
||||
{
|
||||
ReadFileContent(aBlob, EmptyString(), FILE_AS_ARRAYBUFFER, aRv);
|
||||
}
|
||||
|
||||
void ReadAsText(File& aBlob, const nsAString& aLabel, ErrorResult& aRv)
|
||||
void ReadAsText(Blob& aBlob, const nsAString& aLabel, ErrorResult& aRv)
|
||||
{
|
||||
ReadFileContent(aBlob, aLabel, FILE_AS_TEXT, aRv);
|
||||
}
|
||||
|
||||
void ReadAsDataURL(File& aBlob, ErrorResult& aRv)
|
||||
void ReadAsDataURL(Blob& aBlob, ErrorResult& aRv)
|
||||
{
|
||||
ReadFileContent(aBlob, EmptyString(), FILE_AS_DATAURL, aRv);
|
||||
}
|
||||
@ -102,7 +103,7 @@ public:
|
||||
using FileIOObject::SetOnerror;
|
||||
IMPL_EVENT_HANDLER(loadend)
|
||||
|
||||
void ReadAsBinaryString(File& aBlob, ErrorResult& aRv)
|
||||
void ReadAsBinaryString(Blob& aBlob, ErrorResult& aRv)
|
||||
{
|
||||
ReadFileContent(aBlob, EmptyString(), FILE_AS_BINARY, aRv);
|
||||
}
|
||||
@ -124,12 +125,14 @@ protected:
|
||||
FILE_AS_DATAURL
|
||||
};
|
||||
|
||||
void ReadFileContent(File& aBlob,
|
||||
void ReadFileContent(Blob& aBlob,
|
||||
const nsAString &aCharset, eDataFormat aDataFormat,
|
||||
ErrorResult& aRv);
|
||||
nsresult GetAsText(nsIDOMBlob *aFile, const nsACString &aCharset,
|
||||
const char *aFileData, uint32_t aDataLen, nsAString &aResult);
|
||||
nsresult GetAsDataURL(nsIDOMBlob *aFile, const char *aFileData, uint32_t aDataLen, nsAString &aResult);
|
||||
nsresult GetAsText(nsIDOMBlob *aBlob, const nsACString &aCharset,
|
||||
const char *aFileData, uint32_t aDataLen,
|
||||
nsAString &aResult);
|
||||
nsresult GetAsDataURL(nsIDOMBlob *aBlob, const char *aFileData,
|
||||
uint32_t aDataLen, nsAString &aResult);
|
||||
|
||||
void FreeFileData() {
|
||||
free(mFileData);
|
||||
@ -138,7 +141,7 @@ protected:
|
||||
}
|
||||
|
||||
char *mFileData;
|
||||
nsCOMPtr<nsIDOMBlob> mFile;
|
||||
nsCOMPtr<nsIDOMBlob> mBlob;
|
||||
nsCString mCharset;
|
||||
uint32_t mDataLen;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "mozilla/dom/File.h"
|
||||
#include "mozilla/dom/HTMLFormElement.h"
|
||||
|
||||
#include "MultipartFileImpl.h"
|
||||
#include "MultipartBlobImpl.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -22,9 +22,10 @@ nsFormData::nsFormData(nsISupports* aOwner)
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Implements steps 3 and 4 of the "create an entry" algorithm of FormData.
|
||||
File*
|
||||
CreateNewFileInstance(File& aBlob, const Optional<nsAString>& aFilename)
|
||||
already_AddRefed<File>
|
||||
CreateNewFileInstance(Blob& aBlob, const Optional<nsAString>& aFilename)
|
||||
{
|
||||
// Step 3 "If value is a Blob object and not a File object, set value to
|
||||
// a new File object, representing the same bytes, whose name attribute value
|
||||
@ -35,25 +36,20 @@ CreateNewFileInstance(File& aBlob, const Optional<nsAString>& aFilename)
|
||||
nsAutoString filename;
|
||||
if (aFilename.WasPassed()) {
|
||||
filename = aFilename.Value();
|
||||
} else if (aBlob.IsFile()) {
|
||||
} else {
|
||||
// If value is already a File and filename is not passed, the spec says not
|
||||
// to create a new instance.
|
||||
return &aBlob;
|
||||
} else {
|
||||
nsRefPtr<File> file = aBlob.ToFile();
|
||||
if (file) {
|
||||
return file.forget();
|
||||
}
|
||||
|
||||
filename = NS_LITERAL_STRING("blob");
|
||||
}
|
||||
|
||||
nsAutoTArray<nsRefPtr<FileImpl>, 1> blobImpls;
|
||||
blobImpls.AppendElement(aBlob.Impl());
|
||||
|
||||
nsAutoString contentType;
|
||||
aBlob.GetType(contentType);
|
||||
|
||||
nsRefPtr<MultipartFileImpl> impl =
|
||||
new MultipartFileImpl(blobImpls, filename, contentType);
|
||||
|
||||
return new File(aBlob.GetParentObject(), impl);
|
||||
return aBlob.ToFile(filename);
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
@ -111,7 +107,7 @@ nsFormData::Append(const nsAString& aName, const nsAString& aValue)
|
||||
}
|
||||
|
||||
void
|
||||
nsFormData::Append(const nsAString& aName, File& aBlob,
|
||||
nsFormData::Append(const nsAString& aName, Blob& aBlob,
|
||||
const Optional<nsAString>& aFilename)
|
||||
{
|
||||
nsRefPtr<File> file = CreateNewFileInstance(aBlob, aFilename);
|
||||
@ -179,6 +175,14 @@ nsFormData::Has(const nsAString& aName)
|
||||
return false;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFormData::AddNameFilePair(const nsAString& aName, File* aFile)
|
||||
{
|
||||
FormDataTuple* data = mFormData.AppendElement();
|
||||
SetNameFilePair(data, aName, aFile);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsFormData::FormDataTuple*
|
||||
nsFormData::RemoveAllOthersAndGetFirstFormDataTuple(const nsAString& aName)
|
||||
{
|
||||
@ -202,7 +206,7 @@ nsFormData::RemoveAllOthersAndGetFirstFormDataTuple(const nsAString& aName)
|
||||
}
|
||||
|
||||
void
|
||||
nsFormData::Set(const nsAString& aName, File& aBlob,
|
||||
nsFormData::Set(const nsAString& aName, Blob& aBlob,
|
||||
const Optional<nsAString>& aFilename)
|
||||
{
|
||||
FormDataTuple* tuple = RemoveAllOthersAndGetFirstFormDataTuple(aName);
|
||||
@ -245,7 +249,7 @@ nsFormData::Append(const nsAString& aName, nsIVariant* aValue)
|
||||
free(iid);
|
||||
|
||||
nsCOMPtr<nsIDOMBlob> domBlob = do_QueryInterface(supports);
|
||||
nsRefPtr<File> blob = static_cast<File*>(domBlob.get());
|
||||
nsRefPtr<Blob> blob = static_cast<Blob*>(domBlob.get());
|
||||
if (domBlob) {
|
||||
Optional<nsAString> temp;
|
||||
Append(aName, *blob, temp);
|
||||
|
@ -35,7 +35,9 @@ class nsFormData final : public nsIDOMFormData,
|
||||
private:
|
||||
~nsFormData() {}
|
||||
|
||||
typedef mozilla::dom::Blob Blob;
|
||||
typedef mozilla::dom::File File;
|
||||
|
||||
struct FormDataTuple
|
||||
{
|
||||
nsString name;
|
||||
@ -61,11 +63,11 @@ private:
|
||||
|
||||
void SetNameFilePair(FormDataTuple* aData,
|
||||
const nsAString& aName,
|
||||
File* aBlob)
|
||||
File* aFile)
|
||||
{
|
||||
MOZ_ASSERT(aData);
|
||||
aData->name = aName;
|
||||
aData->fileValue = aBlob;
|
||||
aData->fileValue = aFile;
|
||||
aData->valueIsFile = true;
|
||||
}
|
||||
|
||||
@ -95,13 +97,13 @@ public:
|
||||
const mozilla::dom::Optional<mozilla::dom::NonNull<mozilla::dom::HTMLFormElement> >& aFormElement,
|
||||
mozilla::ErrorResult& aRv);
|
||||
void Append(const nsAString& aName, const nsAString& aValue);
|
||||
void Append(const nsAString& aName, File& aBlob,
|
||||
void Append(const nsAString& aName, Blob& aBlob,
|
||||
const mozilla::dom::Optional<nsAString>& aFilename);
|
||||
void Delete(const nsAString& aName);
|
||||
void Get(const nsAString& aName, mozilla::dom::Nullable<mozilla::dom::OwningFileOrUSVString>& aOutValue);
|
||||
void GetAll(const nsAString& aName, nsTArray<mozilla::dom::OwningFileOrUSVString>& aValues);
|
||||
bool Has(const nsAString& aName);
|
||||
void Set(const nsAString& aName, File& aBlob,
|
||||
void Set(const nsAString& aName, Blob& aBlob,
|
||||
const mozilla::dom::Optional<nsAString>& aFilename);
|
||||
void Set(const nsAString& aName, const nsAString& aValue);
|
||||
|
||||
@ -116,12 +118,7 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
virtual nsresult AddNameFilePair(const nsAString& aName,
|
||||
File* aBlob) override
|
||||
{
|
||||
FormDataTuple* data = mFormData.AppendElement();
|
||||
SetNameFilePair(data, aName, aBlob);
|
||||
return NS_OK;
|
||||
}
|
||||
File* aFile) override;
|
||||
|
||||
typedef bool (*FormDataEntryCallback)(const nsString& aName, bool aIsFile,
|
||||
const nsString& aValue,
|
||||
|
@ -277,7 +277,7 @@ BuildClonedMessageData(typename BlobTraits<Flavor>::ConcreteContentManagerType*
|
||||
SerializedStructuredCloneBuffer& buffer = aClonedData.data();
|
||||
buffer.data = aData.mData;
|
||||
buffer.dataLength = aData.mDataLength;
|
||||
const nsTArray<nsRefPtr<File>>& blobs = aData.mClosure.mBlobs;
|
||||
const nsTArray<nsRefPtr<Blob>>& blobs = aData.mClosure.mBlobs;
|
||||
if (!blobs.IsEmpty()) {
|
||||
typedef typename BlobTraits<Flavor>::ProtocolType ProtocolType;
|
||||
InfallibleTArray<ProtocolType*>& blobList = DataBlobs<Flavor>::Blobs(aClonedData);
|
||||
@ -329,12 +329,12 @@ UnpackClonedMessageData(const ClonedMessageData& aData)
|
||||
static_cast<typename BlobTraits<Flavor>::BlobType*>(blobs[i]);
|
||||
MOZ_ASSERT(blob);
|
||||
|
||||
nsRefPtr<FileImpl> blobImpl = blob->GetBlobImpl();
|
||||
nsRefPtr<BlobImpl> blobImpl = blob->GetBlobImpl();
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
// This object will be duplicated with a correct parent before being
|
||||
// exposed to JS.
|
||||
nsRefPtr<File> domBlob = new File(nullptr, blobImpl);
|
||||
nsRefPtr<Blob> domBlob = Blob::Create(nullptr, blobImpl);
|
||||
cloneData.mClosure.mBlobs.AppendElement(domBlob);
|
||||
}
|
||||
}
|
||||
|
@ -8050,9 +8050,9 @@ PostMessageReadStructuredClone(JSContext* cx,
|
||||
if (tag == SCTAG_DOM_BLOB) {
|
||||
NS_ASSERTION(!data, "Data should be empty");
|
||||
|
||||
// What we get back from the reader is a FileImpl.
|
||||
// What we get back from the reader is a BlobImpl.
|
||||
// From that we create a new File.
|
||||
FileImpl* blobImpl;
|
||||
BlobImpl* blobImpl;
|
||||
if (JS_ReadBytes(reader, &blobImpl, sizeof(blobImpl))) {
|
||||
MOZ_ASSERT(blobImpl);
|
||||
|
||||
@ -8063,8 +8063,8 @@ PostMessageReadStructuredClone(JSContext* cx,
|
||||
// while destructors are running.
|
||||
JS::Rooted<JS::Value> val(cx);
|
||||
{
|
||||
nsRefPtr<File> blob = new File(scInfo->window, blobImpl);
|
||||
if (!GetOrCreateDOMReflector(cx, blob, &val)) {
|
||||
nsRefPtr<Blob> blob = Blob::Create(scInfo->window, blobImpl);
|
||||
if (!ToJSValue(cx, blob, &val)) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
@ -8106,9 +8106,9 @@ PostMessageWriteStructuredClone(JSContext* cx,
|
||||
|
||||
// See if this is a File/Blob object.
|
||||
{
|
||||
File* blob = nullptr;
|
||||
Blob* blob = nullptr;
|
||||
if (scInfo->subsumes && NS_SUCCEEDED(UNWRAP_OBJECT(Blob, obj, blob))) {
|
||||
FileImpl* blobImpl = blob->Impl();
|
||||
BlobImpl* blobImpl = blob->Impl();
|
||||
if (JS_WriteUint32Pair(writer, SCTAG_DOM_BLOB, 0) &&
|
||||
JS_WriteBytes(writer, &blobImpl, sizeof(blobImpl))) {
|
||||
scInfo->event->StoreISupports(blobImpl);
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/LoadInfo.h"
|
||||
|
||||
using mozilla::dom::FileImpl;
|
||||
using mozilla::dom::BlobImpl;
|
||||
using mozilla::ErrorResult;
|
||||
using mozilla::LoadInfo;
|
||||
|
||||
@ -530,7 +530,7 @@ nsHostObjectProtocolHandler::NewChannel2(nsIURI* uri,
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
|
||||
nsCOMPtr<FileImpl> blob = do_QueryInterface(info->mObject);
|
||||
nsCOMPtr<BlobImpl> blob = do_QueryInterface(info->mObject);
|
||||
if (!blob) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
@ -625,13 +625,13 @@ nsFontTableProtocolHandler::GetScheme(nsACString &result)
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_GetBlobForBlobURI(nsIURI* aURI, FileImpl** aBlob)
|
||||
NS_GetBlobForBlobURI(nsIURI* aURI, BlobImpl** aBlob)
|
||||
{
|
||||
NS_ASSERTION(IsBlobURI(aURI), "Only call this with blob URIs");
|
||||
|
||||
*aBlob = nullptr;
|
||||
|
||||
nsCOMPtr<FileImpl> blob = do_QueryInterface(GetDataObject(aURI));
|
||||
nsCOMPtr<BlobImpl> blob = do_QueryInterface(GetDataObject(aURI));
|
||||
if (!blob) {
|
||||
return NS_ERROR_DOM_BAD_URI;
|
||||
}
|
||||
@ -643,7 +643,7 @@ NS_GetBlobForBlobURI(nsIURI* aURI, FileImpl** aBlob)
|
||||
nsresult
|
||||
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream)
|
||||
{
|
||||
nsRefPtr<FileImpl> blobImpl;
|
||||
nsRefPtr<BlobImpl> blobImpl;
|
||||
nsresult rv = NS_GetBlobForBlobURI(aURI, getter_AddRefs(blobImpl));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
|
@ -24,7 +24,7 @@ class nsIPrincipal;
|
||||
namespace mozilla {
|
||||
class DOMMediaStream;
|
||||
namespace dom {
|
||||
class FileImpl;
|
||||
class BlobImpl;
|
||||
class MediaSource;
|
||||
}
|
||||
}
|
||||
@ -122,7 +122,7 @@ inline bool IsFontTableURI(nsIURI* aUri)
|
||||
}
|
||||
|
||||
extern nsresult
|
||||
NS_GetBlobForBlobURI(nsIURI* aURI, mozilla::dom::FileImpl** aBlob);
|
||||
NS_GetBlobForBlobURI(nsIURI* aURI, mozilla::dom::BlobImpl** aBlob);
|
||||
|
||||
extern nsresult
|
||||
NS_GetStreamForBlobURI(nsIURI* aURI, nsIInputStream** aStream);
|
||||
|
@ -54,8 +54,12 @@ interface nsIDOMBlob : nsISupports
|
||||
[notxpcom] bool isMemoryFile();
|
||||
};
|
||||
|
||||
[scriptable, builtinclass, uuid(74657f92-aa61-492b-8649-fd1cca62e255)]
|
||||
interface nsIDOMFile : nsIDOMBlob
|
||||
// We want to avoid multiple inheritance of nsIDOMBlob so we can downcast from
|
||||
// nsIDOMBlob to Blob safely. Our chain is:
|
||||
// - Blob -> nsIDOMBlob
|
||||
// - File -> nsIDOMFile and Blob
|
||||
[scriptable, builtinclass, uuid(cc28cf12-f1d4-44ff-843f-9289aa14613b)]
|
||||
interface nsIDOMFile : nsISupports
|
||||
{
|
||||
readonly attribute DOMString name;
|
||||
|
||||
|
@ -99,7 +99,7 @@ nsIGlobalObject::TraverseHostObjectURIs(nsCycleCollectionTraversalCallback &aCb)
|
||||
return;
|
||||
}
|
||||
|
||||
// Currently we only store FileImpl objects off the the main-thread and they
|
||||
// Currently we only store BlobImpl objects off the the main-thread and they
|
||||
// are not CCed.
|
||||
if (!NS_IsMainThread()) {
|
||||
return;
|
||||
|
@ -428,7 +428,7 @@ nsXMLHttpRequest::ResetResponse()
|
||||
mResponseBody.Truncate();
|
||||
mResponseText.Truncate();
|
||||
mResponseBlob = nullptr;
|
||||
mDOMFile = nullptr;
|
||||
mDOMBlob = nullptr;
|
||||
mBlobSet = nullptr;
|
||||
mResultArrayBuffer = nullptr;
|
||||
mArrayBufferBuilder.reset();
|
||||
@ -479,7 +479,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLHttpRequest,
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mXMLParserStreamListener)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mResponseBlob)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMFile)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMBlob)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNotificationCallbacks)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChannelEventSink)
|
||||
@ -501,7 +501,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXMLHttpRequest,
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mXMLParserStreamListener)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mResponseBlob)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMFile)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDOMBlob)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mNotificationCallbacks)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mChannelEventSink)
|
||||
@ -789,15 +789,15 @@ nsXMLHttpRequest::CreateResponseParsedJSON(JSContext* aCx)
|
||||
void
|
||||
nsXMLHttpRequest::CreatePartialBlob()
|
||||
{
|
||||
if (mDOMFile) {
|
||||
if (mDOMBlob) {
|
||||
// Use progress info to determine whether load is complete, but use
|
||||
// mDataAvailable to ensure a slice is created based on the uncompressed
|
||||
// data count.
|
||||
if (mLoadTotal == mLoadTransferred) {
|
||||
mResponseBlob = mDOMFile;
|
||||
mResponseBlob = mDOMBlob;
|
||||
} else {
|
||||
ErrorResult rv;
|
||||
mResponseBlob = mDOMFile->CreateSlice(0, mDataAvailable,
|
||||
mResponseBlob = mDOMBlob->CreateSlice(0, mDataAvailable,
|
||||
EmptyString(), rv);
|
||||
}
|
||||
return;
|
||||
@ -1829,7 +1829,7 @@ nsXMLHttpRequest::StreamReaderFunc(nsIInputStream* in,
|
||||
|
||||
if (xmlHttpRequest->mResponseType == XML_HTTP_RESPONSE_TYPE_BLOB ||
|
||||
xmlHttpRequest->mResponseType == XML_HTTP_RESPONSE_TYPE_MOZ_BLOB) {
|
||||
if (!xmlHttpRequest->mDOMFile) {
|
||||
if (!xmlHttpRequest->mDOMBlob) {
|
||||
if (!xmlHttpRequest->mBlobSet) {
|
||||
xmlHttpRequest->mBlobSet = new BlobSet();
|
||||
}
|
||||
@ -1899,7 +1899,7 @@ nsXMLHttpRequest::StreamReaderFunc(nsIInputStream* in,
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool nsXMLHttpRequest::CreateDOMFile(nsIRequest *request)
|
||||
bool nsXMLHttpRequest::CreateDOMBlob(nsIRequest *request)
|
||||
{
|
||||
nsCOMPtr<nsIFile> file;
|
||||
nsCOMPtr<nsIFileChannel> fc = do_QueryInterface(request);
|
||||
@ -1913,7 +1913,7 @@ bool nsXMLHttpRequest::CreateDOMFile(nsIRequest *request)
|
||||
nsAutoCString contentType;
|
||||
mChannel->GetContentType(contentType);
|
||||
|
||||
mDOMFile = File::CreateFromFile(GetOwner(), file, EmptyString(),
|
||||
mDOMBlob = File::CreateFromFile(GetOwner(), file, EmptyString(),
|
||||
NS_ConvertASCIItoUTF16(contentType));
|
||||
|
||||
mBlobSet = nullptr;
|
||||
@ -1936,8 +1936,8 @@ nsXMLHttpRequest::OnDataAvailable(nsIRequest *request,
|
||||
|
||||
bool cancelable = false;
|
||||
if ((mResponseType == XML_HTTP_RESPONSE_TYPE_BLOB ||
|
||||
mResponseType == XML_HTTP_RESPONSE_TYPE_MOZ_BLOB) && !mDOMFile) {
|
||||
cancelable = CreateDOMFile(request);
|
||||
mResponseType == XML_HTTP_RESPONSE_TYPE_MOZ_BLOB) && !mDOMBlob) {
|
||||
cancelable = CreateDOMBlob(request);
|
||||
// The nsIStreamListener contract mandates us
|
||||
// to read from the stream before returning.
|
||||
}
|
||||
@ -1949,7 +1949,7 @@ nsXMLHttpRequest::OnDataAvailable(nsIRequest *request,
|
||||
|
||||
if (cancelable) {
|
||||
// We don't have to read from the local file for the blob response
|
||||
mDOMFile->GetSize(&mDataAvailable);
|
||||
mDOMBlob->GetSize(&mDataAvailable);
|
||||
ChangeState(XML_HTTP_REQUEST_LOADING);
|
||||
return request->Cancel(NS_OK);
|
||||
}
|
||||
@ -2246,12 +2246,12 @@ nsXMLHttpRequest::OnStopRequest(nsIRequest *request, nsISupports *ctxt, nsresult
|
||||
if (NS_SUCCEEDED(status) &&
|
||||
(mResponseType == XML_HTTP_RESPONSE_TYPE_BLOB ||
|
||||
mResponseType == XML_HTTP_RESPONSE_TYPE_MOZ_BLOB)) {
|
||||
if (!mDOMFile) {
|
||||
CreateDOMFile(request);
|
||||
if (!mDOMBlob) {
|
||||
CreateDOMBlob(request);
|
||||
}
|
||||
if (mDOMFile) {
|
||||
mResponseBlob = mDOMFile;
|
||||
mDOMFile = nullptr;
|
||||
if (mDOMBlob) {
|
||||
mResponseBlob = mDOMBlob;
|
||||
mDOMBlob = nullptr;
|
||||
} else {
|
||||
// mBlobSet can be null if the channel is non-file non-cacheable
|
||||
// and if the response length is zero.
|
||||
|
@ -51,8 +51,8 @@ class nsIJSID;
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
class Blob;
|
||||
class BlobSet;
|
||||
class File;
|
||||
}
|
||||
|
||||
// A helper for building up an ArrayBuffer object's data
|
||||
@ -352,7 +352,7 @@ private:
|
||||
{
|
||||
mValue.mArrayBufferView = aArrayBufferView;
|
||||
}
|
||||
explicit RequestBody(mozilla::dom::File& aBlob) : mType(Blob)
|
||||
explicit RequestBody(mozilla::dom::Blob& aBlob) : mType(Blob)
|
||||
{
|
||||
mValue.mBlob = &aBlob;
|
||||
}
|
||||
@ -386,7 +386,7 @@ private:
|
||||
union Value {
|
||||
const mozilla::dom::ArrayBuffer* mArrayBuffer;
|
||||
const mozilla::dom::ArrayBufferView* mArrayBufferView;
|
||||
mozilla::dom::File* mBlob;
|
||||
mozilla::dom::Blob* mBlob;
|
||||
nsIDocument* mDocument;
|
||||
const nsAString* mString;
|
||||
nsFormData* mFormData;
|
||||
@ -450,7 +450,7 @@ public:
|
||||
{
|
||||
aRv = Send(RequestBody(&aArrayBufferView));
|
||||
}
|
||||
void Send(JSContext* /*aCx*/, mozilla::dom::File& aBlob, ErrorResult& aRv)
|
||||
void Send(JSContext* /*aCx*/, mozilla::dom::Blob& aBlob, ErrorResult& aRv)
|
||||
{
|
||||
aRv = Send(RequestBody(aBlob));
|
||||
}
|
||||
@ -606,7 +606,7 @@ protected:
|
||||
uint32_t *writeCount);
|
||||
nsresult CreateResponseParsedJSON(JSContext* aCx);
|
||||
void CreatePartialBlob();
|
||||
bool CreateDOMFile(nsIRequest *request);
|
||||
bool CreateDOMBlob(nsIRequest *request);
|
||||
// Change the state of the object with this. The broadcast argument
|
||||
// determines if the onreadystatechange listener should be called.
|
||||
nsresult ChangeState(uint32_t aState, bool aBroadcast = true);
|
||||
@ -708,12 +708,12 @@ protected:
|
||||
|
||||
// It is either a cached blob-response from the last call to GetResponse,
|
||||
// but is also explicitly set in OnStopRequest.
|
||||
nsRefPtr<mozilla::dom::File> mResponseBlob;
|
||||
nsRefPtr<mozilla::dom::Blob> mResponseBlob;
|
||||
// Non-null only when we are able to get a os-file representation of the
|
||||
// response, i.e. when loading from a file.
|
||||
nsRefPtr<mozilla::dom::File> mDOMFile;
|
||||
nsRefPtr<mozilla::dom::Blob> mDOMBlob;
|
||||
// We stream data to mBlobSet when response type is "blob" or "moz-blob"
|
||||
// and mDOMFile is null.
|
||||
// and mDOMBlob is null.
|
||||
nsAutoPtr<mozilla::dom::BlobSet> mBlobSet;
|
||||
|
||||
nsString mOverrideMimeType;
|
||||
|
@ -138,7 +138,6 @@ DOMInterfaces = {
|
||||
},
|
||||
|
||||
'Blob': {
|
||||
'nativeType': 'mozilla::dom::File',
|
||||
'headerFile': 'mozilla/dom/File.h',
|
||||
},
|
||||
|
||||
|
@ -412,8 +412,8 @@ BluetoothOppManager::SendFile(const nsAString& aDeviceAddress,
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsRefPtr<FileImpl> impl = aActor->GetBlobImpl();
|
||||
nsCOMPtr<nsIDOMBlob> blob = new File(nullptr, impl);
|
||||
nsRefPtr<BlobImpl> impl = aActor->GetBlobImpl();
|
||||
nsRefPtr<Blob> blob = Blob::Create(nullptr, impl);
|
||||
|
||||
return SendFile(aDeviceAddress, blob.get());
|
||||
}
|
||||
|
@ -766,7 +766,7 @@ BluetoothAdapter::IsConnected(const uint16_t aServiceUuid, ErrorResult& aRv)
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
BluetoothAdapter::SendFile(const nsAString& aDeviceAddress,
|
||||
File& aBlob, ErrorResult& aRv)
|
||||
Blob& aBlob, ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
||||
if (!win) {
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class File;
|
||||
class Blob;
|
||||
class DOMRequest;
|
||||
struct MediaMetaData;
|
||||
struct MediaPlayStatus;
|
||||
@ -134,7 +134,7 @@ public:
|
||||
GetConnectedDevices(uint16_t aServiceUuid, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
SendFile(const nsAString& aDeviceAddress, File& aBlob,
|
||||
SendFile(const nsAString& aDeviceAddress, Blob& aBlob,
|
||||
ErrorResult& aRv);
|
||||
already_AddRefed<DOMRequest>
|
||||
StopSendingFile(const nsAString& aDeviceAddress, ErrorResult& aRv);
|
||||
|
@ -1261,7 +1261,7 @@ BluetoothAdapter::Disconnect(BluetoothDevice& aDevice,
|
||||
|
||||
already_AddRefed<DOMRequest>
|
||||
BluetoothAdapter::SendFile(const nsAString& aDeviceAddress,
|
||||
File& aBlob, ErrorResult& aRv)
|
||||
Blob& aBlob, ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindow> win = GetOwner();
|
||||
if (!win) {
|
||||
|
@ -17,8 +17,8 @@
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
class Blob;
|
||||
class DOMRequest;
|
||||
class File;
|
||||
struct MediaMetaData;
|
||||
struct MediaPlayStatus;
|
||||
}
|
||||
@ -132,7 +132,7 @@ public:
|
||||
|
||||
// OPP file transfer related methods
|
||||
already_AddRefed<DOMRequest> SendFile(const nsAString& aDeviceAddress,
|
||||
File& aBlob,
|
||||
Blob& aBlob,
|
||||
ErrorResult& aRv);
|
||||
already_AddRefed<DOMRequest> StopSendingFile(const nsAString& aDeviceAddress,
|
||||
ErrorResult& aRv);
|
||||
|
@ -384,8 +384,8 @@ BluetoothOppManager::SendFile(const nsAString& aDeviceAddress,
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsRefPtr<FileImpl> impl = aActor->GetBlobImpl();
|
||||
nsCOMPtr<nsIDOMBlob> blob = new File(nullptr, impl);
|
||||
nsRefPtr<BlobImpl> impl = aActor->GetBlobImpl();
|
||||
nsCOMPtr<nsIDOMBlob> blob = Blob::Create(nullptr, impl);
|
||||
|
||||
return SendFile(aDeviceAddress, blob.get());
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ public:
|
||||
PBackgroundChild* backgroundManager = mActor->Manager();
|
||||
MOZ_ASSERT(backgroundManager);
|
||||
|
||||
const nsTArray<nsRefPtr<File>>& blobs = mData->mClosure.mBlobs;
|
||||
const nsTArray<nsRefPtr<Blob>>& blobs = mData->mClosure.mBlobs;
|
||||
|
||||
if (!blobs.IsEmpty()) {
|
||||
message.blobsChild().SetCapacity(blobs.Length());
|
||||
@ -541,7 +541,7 @@ BroadcastChannel::PostMessageInternal(JSContext* aCx,
|
||||
return;
|
||||
}
|
||||
|
||||
const nsTArray<nsRefPtr<File>>& blobs = data->mClosure.mBlobs;
|
||||
const nsTArray<nsRefPtr<Blob>>& blobs = data->mClosure.mBlobs;
|
||||
for (uint32_t i = 0, len = blobs.Length(); i < len; ++i) {
|
||||
if (!blobs[i]->Impl()->MayBeClonedToOtherThreads()) {
|
||||
aRv.Throw(NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
|
@ -42,16 +42,16 @@ BroadcastChannelChild::RecvNotify(const ClonedMessageData& aData)
|
||||
{
|
||||
// Make sure to retrieve all blobs from the message before returning to avoid
|
||||
// leaking their actors.
|
||||
nsTArray<nsRefPtr<File>> files;
|
||||
nsTArray<nsRefPtr<Blob>> blobs;
|
||||
if (!aData.blobsChild().IsEmpty()) {
|
||||
files.SetCapacity(aData.blobsChild().Length());
|
||||
blobs.SetCapacity(aData.blobsChild().Length());
|
||||
|
||||
for (uint32_t i = 0, len = aData.blobsChild().Length(); i < len; ++i) {
|
||||
nsRefPtr<FileImpl> impl =
|
||||
nsRefPtr<BlobImpl> impl =
|
||||
static_cast<BlobChild*>(aData.blobsChild()[i])->GetBlobImpl();
|
||||
|
||||
nsRefPtr<File> file = new File(mBC ? mBC->GetOwner() : nullptr, impl);
|
||||
files.AppendElement(file);
|
||||
nsRefPtr<Blob> blob = Blob::Create(mBC ? mBC->GetOwner() : nullptr, impl);
|
||||
blobs.AppendElement(blob);
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,7 +92,7 @@ BroadcastChannelChild::RecvNotify(const ClonedMessageData& aData)
|
||||
StructuredCloneData cloneData;
|
||||
cloneData.mData = buffer.data;
|
||||
cloneData.mDataLength = buffer.dataLength;
|
||||
cloneData.mClosure.mBlobs.SwapElements(files);
|
||||
cloneData.mClosure.mBlobs.SwapElements(blobs);
|
||||
|
||||
JS::Rooted<JS::Value> value(cx, JS::NullValue());
|
||||
if (cloneData.mDataLength && !ReadStructuredClone(cx, cloneData, &value)) {
|
||||
|
@ -117,7 +117,7 @@ BroadcastChannelParent::CheckAndDeliver(const ClonedMessageData& aData,
|
||||
|
||||
// Ricreate the BlobParent for this new message.
|
||||
for (uint32_t i = 0, len = newData.blobsParent().Length(); i < len; ++i) {
|
||||
nsRefPtr<FileImpl> impl =
|
||||
nsRefPtr<BlobImpl> impl =
|
||||
static_cast<BlobParent*>(newData.blobsParent()[i])->GetBlobImpl();
|
||||
|
||||
PBlobParent* blobParent =
|
||||
|
@ -102,13 +102,13 @@ struct MOZ_STACK_CLASS PostMessageData final
|
||||
// We need to keep the array alive for the life-time of this
|
||||
// PostMessageData.
|
||||
if (!aData.blobsParent().IsEmpty()) {
|
||||
mFiles.SetCapacity(aData.blobsParent().Length());
|
||||
mBlobs.SetCapacity(aData.blobsParent().Length());
|
||||
|
||||
for (uint32_t i = 0, len = aData.blobsParent().Length(); i < len; ++i) {
|
||||
nsRefPtr<FileImpl> impl =
|
||||
nsRefPtr<BlobImpl> impl =
|
||||
static_cast<BlobParent*>(aData.blobsParent()[i])->GetBlobImpl();
|
||||
MOZ_ASSERT(impl);
|
||||
mFiles.AppendElement(impl);
|
||||
mBlobs.AppendElement(impl);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -120,7 +120,7 @@ struct MOZ_STACK_CLASS PostMessageData final
|
||||
|
||||
BroadcastChannelParent* mParent;
|
||||
const ClonedMessageData& mData;
|
||||
nsTArray<nsRefPtr<FileImpl>> mFiles;
|
||||
nsTArray<nsRefPtr<BlobImpl>> mBlobs;
|
||||
const nsString mOrigin;
|
||||
const nsString mChannel;
|
||||
uint64_t mAppId;
|
||||
|
@ -1405,7 +1405,7 @@ nsDOMCameraControl::OnTakePictureComplete(nsIDOMBlob* aPicture)
|
||||
promise->MaybeResolve(picture);
|
||||
}
|
||||
|
||||
nsRefPtr<File> blob = static_cast<File*>(aPicture);
|
||||
nsRefPtr<Blob> blob = static_cast<Blob*>(aPicture);
|
||||
BlobEventInit eventInit;
|
||||
eventInit.mData = blob;
|
||||
|
||||
|
@ -360,7 +360,7 @@ DOMCameraControlListener::OnTakePictureComplete(const uint8_t* aData, uint32_t a
|
||||
RunCallback(nsDOMCameraControl* aDOMCameraControl) override
|
||||
{
|
||||
nsCOMPtr<nsIDOMBlob> picture =
|
||||
File::CreateMemoryFile(mDOMCameraControl.get(),
|
||||
Blob::CreateMemoryBlob(mDOMCameraControl.get(),
|
||||
static_cast<void*>(mData),
|
||||
static_cast<uint64_t>(mLength),
|
||||
mMimeType);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user