Merge last green changeset from mozilla-inbound to mozilla-central

This commit is contained in:
Marco Bonardo 2011-07-04 12:46:07 +02:00
Родитель 9fdec57a7b 126e263390
Коммит 82f7b47d00
72 изменённых файлов: 1832 добавлений и 338 удалений

Просмотреть файл

@ -355,8 +355,10 @@ let TabView = {
if (!tabItem)
return;
// Switch to the new tab
// Switch to the new tab, and close the old group if it's now empty.
let oldGroupItem = groupItems.getActiveGroupItem();
window.gBrowser.selectedTab = tabItem.tab;
oldGroupItem.closeIfEmpty();
});
}
}, true);

Просмотреть файл

@ -282,6 +282,11 @@ Drag.prototype = {
Trenches.hideGuides();
this.item.isDragging = false;
if (this.parent && this.parent != this.item.parent &&
this.parent.isEmpty()) {
this.parent.close();
}
if (this.parent && this.parent.expanded)
this.parent.arrange();

Просмотреть файл

@ -649,7 +649,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// Options:
// immediately - (bool) if true, no animation will be used
close: function GroupItem_close(options) {
this.removeAll();
this.removeAll({dontClose: true});
GroupItems.unregister(this);
// remove unfreeze event handlers, if item size is frozen
@ -723,6 +723,21 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
UI.setActive(closestTabItem);
},
// ----------
// Function: closeIfEmpty
// Closes the group if it's empty, has no title, is closable, and
// autoclose is enabled (see pauseAutoclose()). Returns true if the close
// occurred and false otherwise.
closeIfEmpty: function() {
if (!this._children.length && !this.getTitle() &&
!GroupItems.getUnclosableGroupItemId() &&
!GroupItems._autoclosePaused) {
this.close();
return true;
}
return false;
},
// ----------
// Function: _unhide
// Shows the hidden group.
@ -996,7 +1011,8 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
item.addSubscriber(this, "close", function() {
let count = self._children.length;
let dontArrange = self.expanded || !self.shouldStack(count);
self.remove(item, {dontArrange: dontArrange});
let dontClose = !item.closedManually && gBrowser._numPinnedTabs > 0;
self.remove(item, {dontArrange: dontArrange, dontClose: dontClose});
if (dontArrange)
self._freezeItemSize(count);
@ -1043,6 +1059,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
//
// Possible options:
// dontArrange - don't rearrange the remaining items
// dontClose - don't close the group even if it normally would
// immediately - don't animate
remove: function GroupItem_remove(a, options) {
try {
@ -1091,7 +1108,15 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
if (typeof item.setResizable == 'function')
item.setResizable(true, options.immediately);
if (!options.dontArrange) {
// if a blank tab is selected while restoring a tab the blank tab gets
// removed. we need to keep the group alive for the restored tab.
if (item.tab._tabViewTabIsRemovedAfterRestore)
options.dontClose = true;
let closed = options.dontClose ? false : this.closeIfEmpty();
if (closed)
this._makeClosestTabActive();
else if (!options.dontArrange) {
this.arrange({animate: !options.immediately});
this._unfreezeItemSize({dontArrange: true});
}
@ -1706,7 +1731,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
self.arrange();
var groupItem = drag.info.item.parent;
if (groupItem)
groupItem.remove(drag.info.$el);
groupItem.remove(drag.info.$el, {dontClose: true});
iQ(this.container).removeClass("acceptsDrop");
}
@ -1840,6 +1865,7 @@ let GroupItems = {
_arrangesPending: [],
_removingHiddenGroups: false,
_delayedModUpdates: [],
_autoclosePaused: false,
minGroupHeight: 110,
minGroupWidth: 125,
@ -2611,5 +2637,21 @@ let GroupItems = {
return new Point(
Math.max(size.x, GroupItems.minGroupWidth),
Math.max(size.y, GroupItems.minGroupHeight));
},
// ----------
// Function: pauseAutoclose()
// Temporarily disable the behavior that closes groups when they become
// empty. This is used when entering private browsing, to avoid trashing the
// user's groups while private browsing is shuffling things around.
pauseAutoclose: function GroupItems_pauseAutoclose() {
this._autoclosePaused = true;
},
// ----------
// Function: unpauseAutoclose()
// Re-enables the auto-close behavior.
resumeAutoclose: function GroupItems_resumeAutoclose() {
this._autoclosePaused = false;
}
};

Просмотреть файл

@ -179,7 +179,7 @@ Item.prototype = {
out: function() {
let groupItem = drag.info.item.parent;
if (groupItem)
groupItem.remove(drag.info.$el);
groupItem.remove(drag.info.$el, {dontClose: true});
iQ(this.container).removeClass("acceptsDrop");
},
drop: function(event) {

Просмотреть файл

@ -523,9 +523,16 @@ let UI = {
Storage.saveVisibilityData(gWindow, "true");
// Close the active group if it was empty. This will happen when the
// user returns to Panorama after looking at an app tab, having
// closed all other tabs. (If the user is looking at an orphan tab, then
// there is no active group for the purposes of this check.)
let activeGroupItem = null;
if (!UI.getActiveOrphanTab())
if (!UI.getActiveOrphanTab()) {
activeGroupItem = GroupItems.getActiveGroupItem();
if (activeGroupItem && activeGroupItem.closeIfEmpty())
activeGroupItem = null;
}
if (zoomOut && currentTab && currentTab._tabViewTabItem) {
item = currentTab._tabViewTabItem;
@ -631,8 +638,10 @@ let UI = {
// Pauses the storage activity that conflicts with sessionstore updates and
// private browsing mode switches. Calls can be nested.
storageBusy: function UI_storageBusy() {
if (!this._storageBusyCount)
if (!this._storageBusyCount) {
TabItems.pauseReconnecting();
GroupItems.pauseAutoclose();
}
this._storageBusyCount++;
},
@ -650,6 +659,7 @@ let UI = {
TabItems.resumeReconnecting();
GroupItems._updateTabBar();
GroupItems.resumeAutoclose();
}
},

Просмотреть файл

@ -130,7 +130,4 @@ function test() {
is(gBrowser.tabs.length, 1, "sanity check that it matches");
is(gBrowser.selectedTab, origTab, "got the orig tab");
is(origTab.hidden, false, "and it's not hidden -- visible!");
if (tabViewWindow)
tabViewWindow.GroupItems.groupItems[0].close();
}

Просмотреть файл

@ -72,6 +72,8 @@ function testGroupSwitch(contentWindow, groupItemOne, groupItemTwo) {
"The currently selected tab should be the second tab in the groupItemOne");
// cleanup.
gBrowser.removeTab(groupItemTwo.getChild(0).tab);
gBrowser.removeTab(newTabOne);
closeGroupItem(groupItemTwo, finish);
finish();
}

Просмотреть файл

@ -58,17 +58,15 @@ function onTabViewWindowLoaded() {
gBrowser.unpinTab(appXulTab);
gBrowser.removeTab(appXulTab);
ok(!groupItem.getChildren().length, "the second group is empty");
ok(groupItem.closeIfEmpty(), "the second group was empty");
closeGroupItem(groupItem, function () {
// Verify ending state
is(gBrowser.tabs.length, 1, "we finish with one tab");
is(contentWindow.GroupItems.groupItems.length, 1,
"we finish with one group");
ok(!TabView.isVisible(), "we finish with Tab View hidden");
finish();
});
// Verify ending state
is(gBrowser.tabs.length, 1, "we finish with one tab");
is(contentWindow.GroupItems.groupItems.length, 1,
"we finish with one group");
ok(!TabView.isVisible(), "we finish with Tab View hidden");
finish();
}
window.addEventListener("tabviewhidden", onTabViewHidden, false);

Просмотреть файл

@ -28,15 +28,12 @@ function test() {
EventUtils.synthesizeMouseAtCenter(targetTab, {type: 'mousemove'}, cw);
EventUtils.synthesizeMouseAtCenter(targetTab, {type: 'mouseup'}, cw);
is(cw.GroupItems.groupItems.length, 2, 'there are two groupItems');
is(sourceGroup.getChildren().length, 0, 'source group has no tabs');
is(targetGroup.getChildren().length, 2, 'target group has two tabs');
is(cw.GroupItems.groupItems.length, 1, 'sourceGroup was closed');
isnot(cw.GroupItems.groupItems[0], sourceGroup, 'sourceGroup was closed');
targetGroup.getChild(0).close();
closeGroupItem(sourceGroup, function () {
hideTabView(finish);
});
hideTabView(finish);
}
waitForExplicitFinish();

Просмотреть файл

@ -22,13 +22,11 @@ function test() {
"Tab width is bigger than tab clip width");
is(gBrowser.tabContainer.getAttribute("closebuttons"), "alltabs", "Show button on all tabs.")
let cw = TabView.getContentWindow();
let groupItems = cw.GroupItems.groupItems;
is(groupItems.length, 2, "there are two groupItems");
// clean up and finish
newTabs.forEach(function (tab) gBrowser.removeTab(tab));
closeGroupItem(groupItems[1], finish);
newTabs.forEach(function(tab) {
gBrowser.removeTab(tab);
});
finish();
});
});
}

Просмотреть файл

@ -14,11 +14,11 @@ function test() {
// make sure the tab one is selected because undoCloseTab() would remove
// the selected tab if it's a blank tab.
gBrowser.selectedTab = tabOne;
showTabView(onTabViewShown);
showTabView(onTabViewWindowLoaded);
});
}
function onTabViewShown() {
function onTabViewWindowLoaded() {
let contentWindow = TabView.getContentWindow();
let groupItems = contentWindow.GroupItems.groupItems;
is(groupItems.length, 1, "There is only one group");
@ -28,7 +28,8 @@ function onTabViewShown() {
ok(TabView.isVisible(), "Tab View is still visible after removing a tab");
is(groupItems[0].getChildren().length, 2, "The group has two tab items");
restoreTab(function (tabTwo) {
tabTwo = undoCloseTab(0);
whenTabIsReconnected(tabTwo, function() {
ok(TabView.isVisible(), "Tab View is still visible after restoring a tab");
is(groupItems[0].getChildren().length, 3, "The group still has three tab items");
@ -40,3 +41,18 @@ function onTabViewShown() {
});
});
}
// ----------
function whenTabIsReconnected(tab, callback) {
let tabItem = tab._tabViewTabItem;
if (tabItem._reconnected) {
callback();
return;
}
tabItem.addSubscriber(tabItem, "reconnected", function () {
tabItem.removeSubscriber(tabItem, "reconnected");
callback();
});
}

Просмотреть файл

@ -25,11 +25,12 @@ function test() {
is(gBrowser.visibleTabs.length, 1, "The number of visible tabs is 1");
is(gBrowser.visibleTabs[0], origTab,
"The original tab is the only visible tab");
let groupItem = newTab._tabViewTabItem.parent;
isnot(groupItem.id, newTabGroupItemId,
isnot(newTab._tabViewTabItem.parent.id, newTabGroupItemId,
"The moved tab item has a new group id");
closeGroupItem(groupItem, finish);
// clean up
gBrowser.removeTab(newTab);
finish();
});
}

Просмотреть файл

@ -36,14 +36,12 @@ function test() {
// check state after adding tabItem to targetGroup
is(tabItem.parent, targetGroup, 'tabItem changed groups');
is(sourceGroup.getChildren().length, 0, 'source group has no children');
is(cw.GroupItems.groupItems.length, 1, 'source group was closed automatically');
is(targetGroup.getChildren().length, 2, 'target group has now two children');
// cleanup and finish
closeGroupItem(sourceGroup, function () {
tabItem.close();
hideTabView(finishTest);
});
tabItem.close();
hideTabView(finishTest);
});
}

Просмотреть файл

@ -35,7 +35,10 @@ function test() {
is(win.gBrowser.visibleTabs.length, 1, "There is one tab displayed");
is(cw.GroupItems.groupItems.length, 2, "There are two groups still");
waitForFocus(finish);
showTabView(function () {
is(cw.GroupItems.groupItems.length, 1, "There is now only one group");
waitForFocus(finish);
}, win);
});
};

Просмотреть файл

@ -20,6 +20,23 @@ function test() {
return groupItem;
}
let hideGroupItem = function (groupItem, callback) {
groupItem.addSubscriber(groupItem, 'groupHidden', function () {
groupItem.removeSubscriber(groupItem, 'groupHidden');
callback();
});
groupItem.closeAll();
}
let closeGroupItem = function (groupItem, callback) {
afterAllTabsLoaded(function () {
hideGroupItem(groupItem, function () {
groupItem.closeHidden();
callback();
});
});
}
let tests = [];
let next = function () {
@ -197,13 +214,10 @@ function test() {
let tabItem = groupItem.getChild(0);
groupItem.remove(tabItem);
closeGroupItem(groupItem, function () {
hideTabView(function () {
assertNumberOfGroupItems(0);
hideTabView(function () {
createGroupItem().add(tabItem);
next();
});
createGroupItem().add(tabItem);
next();
});
}
@ -215,17 +229,14 @@ function test() {
let tabItem = groupItem.getChild(0);
groupItem.remove(tabItem);
closeGroupItem(groupItem, function () {
assertNumberOfGroupItems(0);
let newGroupItem = createGroupItem(1);
assertNumberOfGroupItems(1);
closeGroupItem(newGroupItem, function () {
assertNumberOfGroupItems(0);
let newGroupItem = createGroupItem(1);
assertNumberOfGroupItems(1);
closeGroupItem(newGroupItem, function () {
assertNumberOfGroupItems(0);
createGroupItem().add(tabItem);
hideTabView(next);
});
createGroupItem().add(tabItem);
hideTabView(next);
});
}
@ -237,18 +248,15 @@ function test() {
let tabItem = groupItem.getChild(0);
groupItem.remove(tabItem);
closeGroupItem(groupItem, function () {
assertNumberOfGroupItems(0);
assertNumberOfGroupItems(0);
let newGroupItem = createGroupItem(1);
assertNumberOfGroupItems(1);
let newGroupItem = createGroupItem(1);
assertNumberOfGroupItems(1);
hideGroupItem(newGroupItem, function () {
hideTabView(function () {
assertNumberOfGroupItems(0);
createGroupItem().add(tabItem);
next();
});
hideGroupItem(newGroupItem, function () {
hideTabView(function () {
assertNumberOfGroupItems(0);
createGroupItem().add(tabItem);
next();
});
});
}

Просмотреть файл

@ -39,6 +39,10 @@ function test() {
tests.push([tab2, tab1]);
tests.push([tab1]);
// test reordering of empty groups - removes the last tab and causes
// the groupItem to close
tests.push([]);
while (tests.length) {
let test = tests.shift();
@ -59,7 +63,7 @@ function test() {
groupItem.reorderTabsBasedOnTabItemOrder();
}
closeGroupItem(groupItem, testMoveBetweenGroups);
testMoveBetweenGroups();
}
let testMoveBetweenGroups = function () {

Просмотреть файл

@ -119,8 +119,7 @@ function test() {
enterAndLeavePrivateBrowsing(function () {
assertNumberOfVisibleTabs(2);
gBrowser.selectedTab = gBrowser.tabs[0];
closeGroupItem(cw.GroupItems.groupItems[1], next);
next();
});
});
}

Просмотреть файл

@ -41,6 +41,20 @@ function test() {
return createTab('about:blank');
}
let restoreTab = function (callback) {
let tab = undoCloseTab(0);
if (tab._tabViewTabItem._reconnected) {
afterAllTabsLoaded(callback);
return;
}
tab._tabViewTabItem.addSubscriber(tab, 'reconnected', function () {
tab._tabViewTabItem.removeSubscriber(tab, 'reconnected');
afterAllTabsLoaded(callback);
});
}
let finishTest = function () {
prefix = 'finish';
assertValidPrerequisites();

Просмотреть файл

@ -33,10 +33,13 @@ function test() {
ok(!document.getElementById("context_closeTab").disabled, "The 'Close tab' menu item is enabled");
ok(!document.getElementById("context_openTabInWindow").disabled, "The 'Move to New Window' menu item is enabled");
let newTabTwo = gBrowser.selectedTab;
gBrowser.selected = originalTab;
gBrowser.removeTab(newTabOne);
closeGroupItem(newGroup, finish);
gBrowser.removeTab(newTabOne);
gBrowser.removeTab(newTabTwo);
finish();
});
let newGroup = contentWindow.GroupItems.newGroup();
newGroup.newTab();

Просмотреть файл

@ -39,9 +39,7 @@ function test() {
synthesizeMiddleMouseDrag(tabContainer, 10);
ok(!groupItem.getChild(0), 'tabItem was closed');
closeGroupItem(groupItem, function () {
hideTabView(finish);
});
hideTabView(finish);
}
waitForExplicitFinish();

Просмотреть файл

@ -25,25 +25,20 @@ function onTabViewWindowLoaded(win) {
is(group.getChildren().length, 1, "The group has one child now.");
let tab = group.getChild(0);
function finalize() {
is(contentWindow.GroupItems.getActiveGroupItem(), originalGroup,
"The original group is active.");
is(contentWindow.UI.getActiveTab(), originalTab._tabViewTabItem,
"The original tab is active");
callback();
}
function check() {
if (groupOrTab == 'group') {
group.removeSubscriber(group, "groupHidden", check);
group.closeHidden();
finalize();
} else {
} else
tab.removeSubscriber(tab, "tabRemoved", check);
closeGroupItem(group, finalize);
}
is(contentWindow.GroupItems.getActiveGroupItem(), originalGroup,
"The original group is active.");
is(contentWindow.UI.getActiveTab(), originalTab._tabViewTabItem,
"The original tab is active");
callback();
}
if (groupOrTab == 'group') {
@ -63,4 +58,4 @@ function onTabViewWindowLoaded(win) {
finish();
});
});
}
}

Просмотреть файл

@ -25,6 +25,20 @@ function test() {
return cw.GroupItems.groupItems[index];
}
let restoreTab = function (callback) {
let tab = undoCloseTab(0);
if (tab._tabViewTabItem._reconnected) {
callback();
return;
}
tab._tabViewTabItem.addSubscriber(tab, 'reconnected', function () {
tab._tabViewTabItem.removeSubscriber(tab, 'reconnected');
afterAllTabsLoaded(callback);
});
}
let activateFirstGroupItem = function () {
let activeTabItem = getGroupItem(0).getChild(0);
cw.GroupItems.updateActiveGroupItemAndTabBar(activeTabItem);
@ -77,7 +91,9 @@ function test() {
assertNumberOfTabsInGroup(groupItem, 2);
activateFirstGroupItem();
closeGroupItem(groupItem, finishTest);
gBrowser.removeTab(gBrowser.tabs[1]);
gBrowser.removeTab(gBrowser.tabs[1]);
finishTest();
});
}

Просмотреть файл

@ -85,7 +85,7 @@ function addTest(contentWindow, groupOneId, groupTwoId, originalTab) {
};
groupTwo.addSubscriber(groupTwo, "close", function() {
groupTwo.removeSubscriber(groupTwo, "close");
closeGroupItem(groupOne, finish);
finish();
});
window.addEventListener("tabviewhidden", onTabViewHidden, false);
gBrowser.selectedTab = originalTab;

Просмотреть файл

@ -95,7 +95,7 @@ function testGroupItemWithTabItem(contentWindow) {
let endGame = function() {
window.removeEventListener("tabviewhidden", endGame, false);
ok(!TabView.isVisible(), "Tab View is hidden");
closeGroupItem(groupItem, finish);
finish();
};
window.addEventListener("tabviewhidden", endGame, false);

Просмотреть файл

@ -1244,7 +1244,7 @@ nsWebSocket::Send(const nsAString& aData, PRBool *aRet)
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
// We need to check if there isn't unpaired surrogates.
// Check for unpaired surrogates.
PRUint32 i, length = aData.Length();
for (i = 0; i < length; ++i) {
if (NS_IS_LOW_SURROGATE(aData[i])) {

Просмотреть файл

@ -129,15 +129,11 @@ function CreateTestWS(ws_location, ws_protocol)
function forcegc()
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
Components.utils.forceGC();
var wu = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
wu.garbageCollect();
SpecialPowers.forceGC();
SpecialPowers.gc();
setTimeout(function()
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
wu.garbageCollect();
SpecialPowers.gc();
}, 1);
}

Просмотреть файл

@ -22,11 +22,8 @@ var params = ["protocol", "resource", "origin", "end"];
var results = ["test", "/tests/content/base/test/file_ws_basic_tests", "http://mochi.test:8888", "end"];
function forcegc(){
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
Components.utils.forceGC();
var wu = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
wu.garbageCollect();
SpecialPowers.forceGC();
SpecialPowers.gc();
}
function finishWSTest() {

Просмотреть файл

@ -0,0 +1,25 @@
<!DOCTYPE HTML>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Testcase for bug </title>
<style>
#ie {
border: 5px solid red;
}
#ie {
display: block;
}
#moz {
color: blue;
/* display: none; */
}
</style>
</head>
<body>
<p id="foo">foo</p>
<p id="ie">ie</p>
<p id="moz">moz</p>
</body>
</html>

Просмотреть файл

@ -22,7 +22,7 @@ include autofocus/reftest.list
== 596455-2b.html 596455-ref-2.html
== 610935.html 610935-ref.html
== 649134-1.html 649134-ref.html
== 649134-2.html 649134-ref.html
skip-if(Android) == 649134-2.html 649134-2-ref.html
== hidden-1a.html hidden-1-ref.html
== hidden-1b.html hidden-1-ref.html

Просмотреть файл

@ -397,7 +397,6 @@ nsHTMLLinkElement::GetStyleSheetURL(PRBool* aIsInline)
*aIsInline = PR_FALSE;
nsAutoString href;
GetAttr(kNameSpaceID_None, nsGkAtoms::href, href);
href.Trim(" \t\n\r\f"); // trim HTML5 whitespace
if (href.IsEmpty()) {
return nsnull;
}

Просмотреть файл

@ -55,7 +55,7 @@ DOMCI_DATA(SVGAnimatedIntegerPair, nsSVGIntegerPair::DOMAnimatedIntegerPair)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGIntegerPair::DOMAnimatedIntegerPair)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedInteger)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimatedIntegerPair)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimatedInteger)
NS_INTERFACE_MAP_END
/* Implementation */

Просмотреть файл

@ -55,7 +55,7 @@ DOMCI_DATA(SVGAnimatedNumberPair, nsSVGNumberPair::DOMAnimatedNumberPair)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGNumberPair::DOMAnimatedNumberPair)
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGAnimatedNumber)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimatedNumberPair)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAnimatedNumber)
NS_INTERFACE_MAP_END
/* Implementation */

Просмотреть файл

@ -67,6 +67,7 @@ IPDLDIRS = \
netwerk/protocol/ftp \
netwerk/protocol/http \
netwerk/protocol/wyciwyg \
netwerk/protocol/websocket \
netwerk/cookie \
uriloader/prefetch \
$(NULL)

Просмотреть файл

@ -0,0 +1,3 @@
<box xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<label style="margin: 0px 300px;" value="Shadow"/>
</box>

Просмотреть файл

@ -0,0 +1,3 @@
<box xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<label style="margin: 0px 300px; text-shadow: blue 4px 10px 2px" value="Shadow"/>
</box>

Просмотреть файл

@ -1649,4 +1649,5 @@ fails-if(layersGPUAccelerated&&cocoaWidget) == 654950-1.html 654950-1-ref.html #
== 658952.html 658952-ref.html
== 664127-1.xul 664127-1-ref.xul
== 660682-1.html 660682-1-ref.html
!= 669015-1.xul 669015-1-notref.xul
== 668319-1.xul about:blank

Просмотреть файл

@ -14,17 +14,20 @@
div {
font-family: DejaVuSansMono;
width: 60px;
overflow: hidden;
white-space: nowrap;
font-size: 14px;
text-overflow: "...";
padding-left: 1em;
}
/* We put the text and marker into separate spans, because
overflow markers (and their shadows) are drawn separately
from the text frame. */
span {
text-shadow: -0.5em 3px 2px red;
}
</style>
</head>
<body>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;a</div>
<div><span>Hello</span><span>...</span></div>
</body>
</html>

Просмотреть файл

@ -14,20 +14,24 @@
src: url(../fonts/DejaVuSansMono.woff);
}
/* overflow:hidden will clip off some of our text-shadow too.
Give us some padding, so we can put the shadow to the left and bottom
and beat the overflow clipping. */
div {
font-family: DejaVuSansMono;
width: 60px;
width: 5em;
padding-left: 1em;
padding-bottom: 1em;
overflow: hidden;
white-space: nowrap;
font-size: 14px;
text-overflow: "...";
text-shadow: 0px 2px 2px red;
text-shadow: -0.5em 3px 2px red;
}
</style>
</head>
<body>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;a</div>
<div>HelloKitty</div>
</body>
</html>

Просмотреть файл

@ -13,4 +13,4 @@ HTTP(..) == quirks-line-height.html quirks-line-height-ref.html
HTTP(..) == standards-decorations.html standards-decorations-ref.html
HTTP(..) == standards-line-height.html standards-line-height-ref.html
HTTP(..) == selection.html selection-ref.html
HTTP(..) != marker-shadow.html marker-shadow-notref.html
HTTP(..) == marker-shadow.html marker-shadow-ref.html

Просмотреть файл

@ -88,7 +88,8 @@ function selectText() {
addRange(t1.firstChild);
var t2 = document.getElementById('t2');
addRange(t2.firstChild);
document.documentElement.removeAttribute('class');
document.body.offsetHeight;
setTimeout(function(){document.documentElement.removeAttribute('class')},1000);
}
</script>
</head><body onload="selectText();">

Просмотреть файл

@ -86,7 +86,8 @@ function selectText() {
for (i = 0; i < divs.length; ++i) {
addRange(divs[i]);
}
document.documentElement.removeAttribute('class');
document.body.offsetHeight;
setTimeout(function(){document.documentElement.removeAttribute('class')},1000);
}
</script>
</head><body onload="selectText();">

Просмотреть файл

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">
document.createElementNS("http://www.w3.org/2000/svg", "filter").filterResX;
</script>
</svg>

После

Ширина:  |  Высота:  |  Размер: 199 B

Просмотреть файл

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg">
<script type="text/javascript">
document.createElementNS("http://www.w3.org/2000/svg", "feGaussianBlur").stdDeviationX;
</script>
</svg>

После

Ширина:  |  Высота:  |  Размер: 210 B

Просмотреть файл

@ -113,3 +113,5 @@ load 655025-1.svg
load 655025-2.svg
load 655025-3.svg
load 657077-1.svg
load 669025-1.svg
load 669025-2.svg

Просмотреть файл

@ -347,9 +347,9 @@ public:
virtual void DisableComponentAlpha() { mDisableSubpixelAA = PR_TRUE; }
void PaintTextWithOffset(nsRenderingContext* aCtx,
nsPoint aOffset,
const nscolor* aColor);
void PaintTextToContext(nsRenderingContext* aCtx,
nsPoint aOffset,
const nscolor* aColor);
PRPackedBool mDisableSubpixelAA;
};
@ -361,7 +361,7 @@ PaintTextShadowCallback(nsRenderingContext* aCtx,
void* aData)
{
reinterpret_cast<nsDisplayXULTextBox*>(aData)->
PaintTextWithOffset(aCtx, aShadowOffset, &aShadowColor);
PaintTextToContext(aCtx, aShadowOffset, &aShadowColor);
}
void
@ -372,20 +372,21 @@ nsDisplayXULTextBox::Paint(nsDisplayListBuilder* aBuilder,
mDisableSubpixelAA);
// Paint the text shadow before doing any foreground stuff
nsRect drawRect = static_cast<nsTextBoxFrame*>(mFrame)->mTextDrawRect;
nsRect drawRect = static_cast<nsTextBoxFrame*>(mFrame)->mTextDrawRect +
ToReferenceFrame();
nsLayoutUtils::PaintTextShadow(mFrame, aCtx,
drawRect, mVisibleRect,
mFrame->GetStyleColor()->mColor,
PaintTextShadowCallback,
(void*)this);
PaintTextWithOffset(aCtx, nsPoint(0, 0), nsnull);
PaintTextToContext(aCtx, nsPoint(0, 0), nsnull);
}
void
nsDisplayXULTextBox::PaintTextWithOffset(nsRenderingContext* aCtx,
nsPoint aOffset,
const nscolor* aColor)
nsDisplayXULTextBox::PaintTextToContext(nsRenderingContext* aCtx,
nsPoint aOffset,
const nscolor* aColor)
{
static_cast<nsTextBoxFrame*>(mFrame)->
PaintTitle(*aCtx, mVisibleRect, ToReferenceFrame() + aOffset, aColor);

Просмотреть файл

@ -0,0 +1,25 @@
diff --git a/media/libvpx/build/make/ads2gas.pl b/media/libvpx/build/make/ads2gas.pl
--- a/media/libvpx/build/make/ads2gas.pl
+++ b/media/libvpx/build/make/ads2gas.pl
@@ -74,17 +74,20 @@ while (<STDIN>)
# Convert INCLUDE to .INCLUDE "file"
s/INCLUDE(\s*)(.*)$/.include $1\"$2\"/;
# Code directive (ARM vs Thumb)
s/CODE([0-9][0-9])/.code $1/;
# No AREA required
- s/^\s*AREA.*$/.text/;
+ # But ALIGNs in AREA must be obeyed
+ s/^\s*AREA.*ALIGN=([0-9])$/.text\n.p2align $1/;
+ # If no ALIGN, strip the AREA and align to 4 bytes
+ s/^\s*AREA.*$/.text\n.p2align 2/;
# DCD to .word
# This one is for incoming symbols
s/DCD\s+\|(\w*)\|/.long $1/;
# DCW to .short
s/DCW\s+\|(\w*)\|/.short $1/;
s/DCW(.*)/.short $1/;

Просмотреть файл

@ -79,7 +79,10 @@ while (<STDIN>)
s/CODE([0-9][0-9])/.code $1/;
# No AREA required
s/^\s*AREA.*$/.text/;
# But ALIGNs in AREA must be obeyed
s/^\s*AREA.*ALIGN=([0-9])$/.text\n.p2align $1/;
# If no ALIGN, strip the AREA and align to 4 bytes
s/^\s*AREA.*$/.text\n.p2align 2/;
# DCD to .word
# This one is for incoming symbols

Просмотреть файл

@ -326,3 +326,6 @@ patch -p3 < bug640935.patch
# Patch to avoid text relocations on ARM
patch -p3 < bug646815.patch
# Patch to fix alignment problems with using ARM asm in Thumb mode.
patch -p3 < bug666931.patch

Просмотреть файл

@ -64,6 +64,7 @@
#include "nsNetStrings.h"
#include "nsDNSPrefetch.h"
#include "nsAboutProtocolHandler.h"
#include "nsXULAppAPI.h"
#include "nsNetCID.h"
@ -283,10 +284,47 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsWyciwygProtocolHandler)
#ifdef NECKO_PROTOCOL_websocket
#include "nsWebSocketHandler.h"
#include "WebSocketChannelChild.h"
namespace mozilla {
namespace net {
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWebSocketHandler)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsWebSocketSSLHandler)
static BaseWebSocketChannel*
WebSocketHandlerConstructor(bool aSecure)
{
if (IsNeckoChild()) {
return new WebSocketChannelChild(aSecure);
}
if (aSecure) {
return new nsWebSocketSSLHandler;
} else {
return new nsWebSocketHandler;
}
}
#define WEB_SOCKET_HANDLER_CONSTRUCTOR(type, secure) \
static nsresult \
type##Constructor(nsISupports *aOuter, REFNSIID aIID, \
void **aResult) \
{ \
nsresult rv; \
\
BaseWebSocketChannel * inst; \
\
*aResult = NULL; \
if (NULL != aOuter) { \
rv = NS_ERROR_NO_AGGREGATION; \
return rv; \
} \
inst = WebSocketHandlerConstructor(secure); \
NS_ADDREF(inst); \
rv = inst->QueryInterface(aIID, aResult); \
NS_RELEASE(inst); \
return rv; \
}
WEB_SOCKET_HANDLER_CONSTRUCTOR(nsWebSocketHandler, false)
WEB_SOCKET_HANDLER_CONSTRUCTOR(nsWebSocketSSLHandler, true)
#undef WEB_SOCKET_HANDLER_CONSTRUCTOR
} // namespace mozilla::net
} // namespace mozilla
#endif

Просмотреть файл

@ -39,7 +39,7 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsIChannel.h"
#include "nsISupports.h"
#include "mozilla/net/ChannelEventQueue.h"
namespace mozilla {
@ -51,7 +51,7 @@ ChannelEventQueue::FlushQueue()
// Events flushed could include destruction of channel (and our own
// destructor) unless we make sure its refcount doesn't drop to 0 while this
// method is running.
nsCOMPtr<nsIChannel> kungFuDeathGrip(mOwner);
nsCOMPtr<nsISupports> kungFuDeathGrip(mOwner);
// Prevent flushed events from flushing the queue recursively
mFlushing = true;

Просмотреть файл

@ -45,7 +45,7 @@
#include <nsTArray.h>
#include <nsAutoPtr.h>
class nsIChannel;
class nsISupports;
namespace mozilla {
namespace net {
@ -70,7 +70,7 @@ class AutoEventEnqueuerBase;
class ChannelEventQueue
{
public:
ChannelEventQueue(nsIChannel *owner)
ChannelEventQueue(nsISupports *owner)
: mForced(false)
, mSuspended(false)
, mFlushing(false)
@ -116,7 +116,7 @@ class ChannelEventQueue
bool mFlushing;
// Keep ptr to avoid refcount cycle: only grab ref during flushing.
nsIChannel *mOwner;
nsISupports *mOwner;
friend class AutoEventEnqueuer;
};

Просмотреть файл

@ -46,6 +46,7 @@
#include "mozilla/net/CookieServiceChild.h"
#include "mozilla/net/WyciwygChannelChild.h"
#include "mozilla/net/FTPChannelChild.h"
#include "mozilla/net/WebSocketChannelChild.h"
namespace mozilla {
namespace net {
@ -167,5 +168,20 @@ NeckoChild::DeallocPWyciwygChannel(PWyciwygChannelChild* channel)
return true;
}
PWebSocketChild*
NeckoChild::AllocPWebSocket(PBrowserChild* browser)
{
NS_NOTREACHED("AllocPWebSocket should not be called");
return nsnull;
}
bool
NeckoChild::DeallocPWebSocket(PWebSocketChild* child)
{
WebSocketChannelChild* p = static_cast<WebSocketChannelChild*>(child);
p->ReleaseIPDLReference();
return true;
}
}} // mozilla::net

Просмотреть файл

@ -67,6 +67,8 @@ protected:
virtual bool DeallocPWyciwygChannel(PWyciwygChannelChild*);
virtual PFTPChannelChild* AllocPFTPChannel();
virtual bool DeallocPFTPChannel(PFTPChannelChild*);
virtual PWebSocketChild* AllocPWebSocket(PBrowserChild*);
virtual bool DeallocPWebSocket(PWebSocketChild*);
};
/**

Просмотреть файл

@ -44,9 +44,13 @@
#include "mozilla/net/CookieServiceParent.h"
#include "mozilla/net/WyciwygChannelParent.h"
#include "mozilla/net/FTPChannelParent.h"
#include "mozilla/net/WebSocketChannelParent.h"
#include "mozilla/dom/TabParent.h"
#include "nsHTMLDNSPrefetch.h"
using mozilla::dom::TabParent;
namespace mozilla {
namespace net {
@ -120,6 +124,23 @@ NeckoParent::DeallocPWyciwygChannel(PWyciwygChannelParent* channel)
return true;
}
PWebSocketParent*
NeckoParent::AllocPWebSocket(PBrowserParent* browser)
{
TabParent* tabParent = static_cast<TabParent*>(browser);
WebSocketChannelParent* p = new WebSocketChannelParent(tabParent);
p->AddRef();
return p;
}
bool
NeckoParent::DeallocPWebSocket(PWebSocketParent* actor)
{
WebSocketChannelParent* p = static_cast<WebSocketChannelParent*>(actor);
p->Release();
return true;
}
bool
NeckoParent::RecvHTMLDNSPrefetch(const nsString& hostname,
const PRUint16& flags)

Просмотреть файл

@ -64,6 +64,8 @@ protected:
virtual bool DeallocPWyciwygChannel(PWyciwygChannelParent*);
virtual PFTPChannelParent* AllocPFTPChannel();
virtual bool DeallocPFTPChannel(PFTPChannelParent*);
virtual PWebSocketParent* AllocPWebSocket(PBrowserParent* browser);
virtual bool DeallocPWebSocket(PWebSocketParent*);
virtual bool RecvHTMLDNSPrefetch(const nsString& hostname,
const PRUint16& flags);
};

Просмотреть файл

@ -44,6 +44,7 @@ include protocol PCookieService;
include protocol PBrowser;
include protocol PWyciwygChannel;
include protocol PFTPChannel;
include protocol PWebSocket;
namespace mozilla {
namespace net {
@ -57,6 +58,7 @@ sync protocol PNecko
manages PCookieService;
manages PWyciwygChannel;
manages PFTPChannel;
manages PWebSocket;
parent:
__delete__();
@ -64,6 +66,7 @@ parent:
PCookieService();
PWyciwygChannel();
PFTPChannel();
PWebSocket(PBrowser browser);
HTMLDNSPrefetch(nsString hostname, PRUint16 flags);

Просмотреть файл

@ -57,7 +57,7 @@ namespace net {
FTPChannelChild::FTPChannelChild(nsIURI* uri)
: mIPCOpen(false)
, mEventQ(this)
, mEventQ(static_cast<nsIFTPChannel*>(this))
, mCanceled(false)
, mSuspendCount(0)
, mIsPending(PR_FALSE)

Просмотреть файл

@ -66,7 +66,7 @@ HttpChannelChild::HttpChannelChild()
, mSendResumeAt(false)
, mIPCOpen(false)
, mKeptAlive(false)
, mEventQ(this)
, mEventQ(static_cast<nsIHttpChannel*>(this))
{
LOG(("Creating HttpChannelChild @%x\n", this));
}

Просмотреть файл

@ -0,0 +1,222 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Josh Matthews <josh@joshmatthews.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "WebSocketLog.h"
#include "BaseWebSocketChannel.h"
#include "nsWebSocketHandler.h"
#include "nsILoadGroup.h"
#include "nsIInterfaceRequestor.h"
#include "nsIURI.h"
#include "nsAutoPtr.h"
#include "nsStandardURL.h"
#if defined(PR_LOGGING)
PRLogModuleInfo *webSocketLog = nsnull;
#endif
namespace mozilla {
namespace net {
BaseWebSocketChannel::BaseWebSocketChannel()
: mEncrypted(false)
{
#if defined(PR_LOGGING)
if (!webSocketLog)
webSocketLog = PR_NewLogModule("nsWebSocket");
#endif
}
//-----------------------------------------------------------------------------
// BaseWebSocketChannel::nsIWebSocketProtocol
//-----------------------------------------------------------------------------
NS_IMETHODIMP
BaseWebSocketChannel::GetOriginalURI(nsIURI **aOriginalURI)
{
LOG(("BaseWebSocketChannel::GetOriginalURI() %p\n", this));
if (!mOriginalURI)
return NS_ERROR_NOT_INITIALIZED;
NS_ADDREF(*aOriginalURI = mOriginalURI);
return NS_OK;
}
NS_IMETHODIMP
BaseWebSocketChannel::GetURI(nsIURI **aURI)
{
LOG(("BaseWebSocketChannel::GetURI() %p\n", this));
if (!mOriginalURI)
return NS_ERROR_NOT_INITIALIZED;
if (mURI)
NS_ADDREF(*aURI = mURI);
else
NS_ADDREF(*aURI = mOriginalURI);
return NS_OK;
}
NS_IMETHODIMP
BaseWebSocketChannel::
GetNotificationCallbacks(nsIInterfaceRequestor **aNotificationCallbacks)
{
LOG(("BaseWebSocketChannel::GetNotificationCallbacks() %p\n", this));
NS_IF_ADDREF(*aNotificationCallbacks = mCallbacks);
return NS_OK;
}
NS_IMETHODIMP
BaseWebSocketChannel::
SetNotificationCallbacks(nsIInterfaceRequestor *aNotificationCallbacks)
{
LOG(("BaseWebSocketChannel::SetNotificationCallbacks() %p\n", this));
mCallbacks = aNotificationCallbacks;
return NS_OK;
}
NS_IMETHODIMP
BaseWebSocketChannel::GetLoadGroup(nsILoadGroup **aLoadGroup)
{
LOG(("BaseWebSocketChannel::GetLoadGroup() %p\n", this));
NS_IF_ADDREF(*aLoadGroup = mLoadGroup);
return NS_OK;
}
NS_IMETHODIMP
BaseWebSocketChannel::SetLoadGroup(nsILoadGroup *aLoadGroup)
{
LOG(("BaseWebSocketChannel::SetLoadGroup() %p\n", this));
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP
BaseWebSocketChannel::GetProtocol(nsACString &aProtocol)
{
LOG(("BaseWebSocketChannel::GetProtocol() %p\n", this));
aProtocol = mProtocol;
return NS_OK;
}
NS_IMETHODIMP
BaseWebSocketChannel::SetProtocol(const nsACString &aProtocol)
{
LOG(("BaseWebSocketChannel::SetProtocol() %p\n", this));
mProtocol = aProtocol; /* the sub protocol */
return NS_OK;
}
//-----------------------------------------------------------------------------
// BaseWebSocketChannel::nsIProtocolHandler
//-----------------------------------------------------------------------------
NS_IMETHODIMP
BaseWebSocketChannel::GetScheme(nsACString &aScheme)
{
LOG(("BaseWebSocketHandler::GetScheme() %p\n", this));
if (mEncrypted)
aScheme.AssignLiteral("wss");
else
aScheme.AssignLiteral("ws");
return NS_OK;
}
NS_IMETHODIMP
BaseWebSocketChannel::GetDefaultPort(PRInt32 *aDefaultPort)
{
LOG(("BaseWebSocketHandler::GetDefaultPort() %p\n", this));
if (mEncrypted)
*aDefaultPort = kDefaultWSSPort;
else
*aDefaultPort = kDefaultWSPort;
return NS_OK;
}
NS_IMETHODIMP
BaseWebSocketChannel::GetProtocolFlags(PRUint32 *aProtocolFlags)
{
LOG(("BaseWebSocketHandler::GetProtocolFlags() %p\n", this));
*aProtocolFlags = URI_NORELATIVE | URI_NON_PERSISTABLE | ALLOWS_PROXY |
ALLOWS_PROXY_HTTP | URI_DOES_NOT_RETURN_DATA | URI_DANGEROUS_TO_LOAD;
return NS_OK;
}
NS_IMETHODIMP
BaseWebSocketChannel::NewURI(const nsACString & aSpec, const char *aOriginCharset,
nsIURI *aBaseURI, nsIURI **_retval NS_OUTPARAM)
{
LOG(("BaseWebSocketHandler::NewURI() %p\n", this));
PRInt32 port;
nsresult rv = GetDefaultPort(&port);
if (NS_FAILED(rv))
return rv;
nsRefPtr<nsStandardURL> url = new nsStandardURL();
rv = url->Init(nsIStandardURL::URLTYPE_AUTHORITY, port, aSpec,
aOriginCharset, aBaseURI);
if (NS_FAILED(rv))
return rv;
NS_ADDREF(*_retval = url);
return NS_OK;
}
NS_IMETHODIMP
BaseWebSocketChannel::NewChannel(nsIURI *aURI, nsIChannel **_retval NS_OUTPARAM)
{
LOG(("BaseWebSocketHandler::NewChannel() %p\n", this));
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
BaseWebSocketChannel::AllowPort(PRInt32 port, const char *scheme,
PRBool *_retval NS_OUTPARAM)
{
LOG(("BaseWebSocketHandler::AllowPort() %p\n", this));
// do not override any blacklisted ports
*_retval = PR_FALSE;
return NS_OK;
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,94 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Josh Matthews <josh@joshmatthews.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozilla_net_BaseWebSocketChannel_h
#define mozilla_net_BaseWebSocketChannel_h
#include "nsIWebSocketProtocol.h"
#include "nsIProtocolHandler.h"
#include "nsCOMPtr.h"
#include "nsString.h"
namespace mozilla {
namespace net {
const static PRInt32 kDefaultWSPort = 80;
const static PRInt32 kDefaultWSSPort = 443;
class BaseWebSocketChannel : public nsIWebSocketProtocol,
public nsIProtocolHandler
{
public:
BaseWebSocketChannel();
NS_DECL_NSIPROTOCOLHANDLER
NS_IMETHOD QueryInterface(const nsIID & uuid, void **result NS_OUTPARAM) = 0;
NS_IMETHOD_(nsrefcnt ) AddRef(void) = 0;
NS_IMETHOD_(nsrefcnt ) Release(void) = 0;
// Partial implementation of nsIWebSocketProtocol
//
NS_IMETHOD GetOriginalURI(nsIURI **aOriginalURI);
NS_IMETHOD GetURI(nsIURI **aURI);
NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor **aNotificationCallbacks);
NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor *aNotificationCallbacks);
NS_IMETHOD GetLoadGroup(nsILoadGroup **aLoadGroup);
NS_IMETHOD SetLoadGroup(nsILoadGroup *aLoadGroup);
NS_IMETHOD GetProtocol(nsACString &aProtocol);
NS_IMETHOD SetProtocol(const nsACString &aProtocol);
protected:
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIWebSocketListener> mListener;
nsCOMPtr<nsISupports> mContext;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsILoadGroup> mLoadGroup;
nsCString mProtocol;
nsCString mOrigin;
PRBool mEncrypted;
};
} // namespace net
} // namespace mozilla
#endif // mozilla_net_BaseWebSocketChannel_h

Просмотреть файл

@ -49,16 +49,30 @@ XPIDL_MODULE = necko_websocket
GRE_MODULE = 1
FORCE_STATIC_LIB = 1
EXPORTS_NAMESPACES = mozilla/net
XPIDLSRCS = \
nsIWebSocketProtocol.idl \
$(NULL)
CPPSRCS = \
nsWebSocketHandler.cpp
nsWebSocketHandler.cpp \
WebSocketChannelParent.cpp \
WebSocketChannelChild.cpp \
BaseWebSocketChannel.cpp \
$(NULL)
EXPORTS_mozilla/net = \
nsWebSocketHandler.h \
WebSocketChannelParent.h \
WebSocketChannelChild.h \
BaseWebSocketChannel.h \
$(NULL)
LOCAL_INCLUDES = \
-I$(srcdir)/../../base/src \
-I$(topsrcdir)/content/base/src \
-I$(topsrcdir)/content/events/src \
-I$(topsrcdir)/xpcom/ds \
$(NULL)

Просмотреть файл

@ -0,0 +1,81 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Josh Matthews <josh@joshmatthews.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
include protocol PNecko;
include protocol PBrowser;
include "mozilla/net/NeckoMessageUtils.h";
using IPC::URI;
namespace mozilla {
namespace net {
async protocol PWebSocket
{
manager PNecko;
parent:
// Forwarded methods corresponding to methods on nsIWebSocketProtocolHandler
AsyncOpen(URI aURI, nsCString aOrigin, nsCString aProtocol, bool aSecure);
Close();
SendMsg(nsCString aMsg);
SendBinaryMsg(nsCString aMsg);
DeleteSelf();
child:
// Forwarded notifications corresponding to the nsIWebSocketListener interface
OnStart(nsCString aProtocol);
OnStop(nsresult aStatusCode);
OnMessageAvailable(nsCString aMsg);
OnBinaryMessageAvailable(nsCString aMsg);
OnAcknowledge(PRUint32 aSize);
OnServerClose();
// Only sent in the event that AsyncOpen fails
AsyncOpenFailed();
__delete__();
};
} //namespace net
} //namespace mozilla

Просмотреть файл

@ -0,0 +1,446 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Josh Matthews <josh@joshmatthews.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "WebSocketLog.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/net/NeckoChild.h"
#include "WebSocketChannelChild.h"
#include "nsITabChild.h"
namespace mozilla {
namespace net {
NS_IMPL_ADDREF(WebSocketChannelChild)
NS_IMETHODIMP_(nsrefcnt) WebSocketChannelChild::Release()
{
NS_PRECONDITION(0 != mRefCnt, "dup release");
NS_ASSERT_OWNINGTHREAD(WebSocketChannelChild);
--mRefCnt;
NS_LOG_RELEASE(this, mRefCnt, "WebSocketChannelChild");
if (mRefCnt == 1 && mIPCOpen) {
SendDeleteSelf();
return mRefCnt;
}
if (mRefCnt == 0) {
mRefCnt = 1; /* stabilize */
delete this;
return 0;
}
return mRefCnt;
}
NS_INTERFACE_MAP_BEGIN(WebSocketChannelChild)
NS_INTERFACE_MAP_ENTRY(nsIWebSocketProtocol)
NS_INTERFACE_MAP_ENTRY(nsIProtocolHandler)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIWebSocketProtocol)
NS_INTERFACE_MAP_END
WebSocketChannelChild::WebSocketChannelChild(bool aSecure)
: mEventQ(static_cast<nsIWebSocketProtocol*>(this))
, mIPCOpen(false)
, mCancelled(false)
{
LOG(("WebSocketChannelChild::WebSocketChannelChild() %p\n", this));
BaseWebSocketChannel::mEncrypted = aSecure;
}
WebSocketChannelChild::~WebSocketChannelChild()
{
LOG(("WebSocketChannelChild::~WebSocketChannelChild() %p\n", this));
}
void
WebSocketChannelChild::AddIPDLReference()
{
NS_ABORT_IF_FALSE(!mIPCOpen, "Attempt to retain more than one IPDL reference");
mIPCOpen = true;
AddRef();
}
void
WebSocketChannelChild::ReleaseIPDLReference()
{
NS_ABORT_IF_FALSE(mIPCOpen, "Attempt to release nonexistent IPDL reference");
mIPCOpen = false;
Release();
}
class StartEvent : public ChannelEvent
{
public:
StartEvent(WebSocketChannelChild* aChild,
const nsCString& aProtocol)
: mChild(aChild)
, mProtocol(aProtocol)
{}
void Run()
{
mChild->OnStart(mProtocol);
}
private:
WebSocketChannelChild* mChild;
nsCString mProtocol;
};
bool
WebSocketChannelChild::RecvOnStart(const nsCString& aProtocol)
{
if (mEventQ.ShouldEnqueue()) {
mEventQ.Enqueue(new StartEvent(this, aProtocol));
} else {
OnStart(aProtocol);
}
return true;
}
void
WebSocketChannelChild::OnStart(const nsCString& aProtocol)
{
LOG(("WebSocketChannelChild::RecvOnStart() %p\n", this));
SetProtocol(aProtocol);
if (mListener) {
AutoEventEnqueuer ensureSerialDispatch(mEventQ);;
mListener->OnStart(mContext);
}
}
class StopEvent : public ChannelEvent
{
public:
StopEvent(WebSocketChannelChild* aChild,
const nsresult& aStatusCode)
: mChild(aChild)
, mStatusCode(aStatusCode)
{}
void Run()
{
mChild->OnStop(mStatusCode);
}
private:
WebSocketChannelChild* mChild;
nsresult mStatusCode;
};
bool
WebSocketChannelChild::RecvOnStop(const nsresult& aStatusCode)
{
if (mEventQ.ShouldEnqueue()) {
mEventQ.Enqueue(new StopEvent(this, aStatusCode));
} else {
OnStop(aStatusCode);
}
return true;
}
void
WebSocketChannelChild::OnStop(const nsresult& aStatusCode)
{
LOG(("WebSocketChannelChild::RecvOnStop() %p\n", this));
if (mListener) {
AutoEventEnqueuer ensureSerialDispatch(mEventQ);;
mListener->OnStop(mContext, aStatusCode);
}
}
class MessageEvent : public ChannelEvent
{
public:
MessageEvent(WebSocketChannelChild* aChild,
const nsCString& aMessage,
bool aBinary)
: mChild(aChild)
, mMessage(aMessage)
, mBinary(aBinary)
{}
void Run()
{
if (!mBinary) {
mChild->OnMessageAvailable(mMessage);
} else {
mChild->OnBinaryMessageAvailable(mMessage);
}
}
private:
WebSocketChannelChild* mChild;
nsCString mMessage;
bool mBinary;
};
bool
WebSocketChannelChild::RecvOnMessageAvailable(const nsCString& aMsg)
{
if (mEventQ.ShouldEnqueue()) {
mEventQ.Enqueue(new MessageEvent(this, aMsg, false));
} else {
OnMessageAvailable(aMsg);
}
return true;
}
void
WebSocketChannelChild::OnMessageAvailable(const nsCString& aMsg)
{
LOG(("WebSocketChannelChild::RecvOnMessageAvailable() %p\n", this));
if (mListener) {
AutoEventEnqueuer ensureSerialDispatch(mEventQ);;
mListener->OnMessageAvailable(mContext, aMsg);
}
}
bool
WebSocketChannelChild::RecvOnBinaryMessageAvailable(const nsCString& aMsg)
{
if (mEventQ.ShouldEnqueue()) {
mEventQ.Enqueue(new MessageEvent(this, aMsg, true));
} else {
OnBinaryMessageAvailable(aMsg);
}
return true;
}
void
WebSocketChannelChild::OnBinaryMessageAvailable(const nsCString& aMsg)
{
LOG(("WebSocketChannelChild::RecvOnBinaryMessageAvailable() %p\n", this));
if (mListener) {
AutoEventEnqueuer ensureSerialDispatch(mEventQ);;
mListener->OnBinaryMessageAvailable(mContext, aMsg);
}
}
class AcknowledgeEvent : public ChannelEvent
{
public:
AcknowledgeEvent(WebSocketChannelChild* aChild,
const PRUint32& aSize)
: mChild(aChild)
, mSize(aSize)
{}
void Run()
{
mChild->OnAcknowledge(mSize);
}
private:
WebSocketChannelChild* mChild;
PRUint32 mSize;
};
bool
WebSocketChannelChild::RecvOnAcknowledge(const PRUint32& aSize)
{
if (mEventQ.ShouldEnqueue()) {
mEventQ.Enqueue(new AcknowledgeEvent(this, aSize));
} else {
OnAcknowledge(aSize);
}
return true;
}
void
WebSocketChannelChild::OnAcknowledge(const PRUint32& aSize)
{
LOG(("WebSocketChannelChild::RecvOnAcknowledge() %p\n", this));
if (mListener) {
AutoEventEnqueuer ensureSerialDispatch(mEventQ);;
mListener->OnAcknowledge(mContext, aSize);
}
}
class ServerCloseEvent : public ChannelEvent
{
public:
ServerCloseEvent(WebSocketChannelChild* aChild)
: mChild(aChild)
{}
void Run()
{
mChild->OnServerClose();
}
private:
WebSocketChannelChild* mChild;
};
bool
WebSocketChannelChild::RecvOnServerClose()
{
if (mEventQ.ShouldEnqueue()) {
mEventQ.Enqueue(new ServerCloseEvent(this));
} else {
OnServerClose();
}
return true;
}
void
WebSocketChannelChild::OnServerClose()
{
LOG(("WebSocketChannelChild::RecvOnServerClose() %p\n", this));
if (mListener) {
AutoEventEnqueuer ensureSerialDispatch(mEventQ);;
mListener->OnServerClose(mContext);
}
}
class AsyncOpenFailedEvent : public ChannelEvent
{
public:
AsyncOpenFailedEvent(WebSocketChannelChild* aChild)
: mChild(aChild)
{}
void Run()
{
mChild->AsyncOpenFailed();
}
private:
WebSocketChannelChild* mChild;
};
bool
WebSocketChannelChild::RecvAsyncOpenFailed()
{
if (mEventQ.ShouldEnqueue()) {
mEventQ.Enqueue(new AsyncOpenFailedEvent(this));
} else {
AsyncOpenFailed();
}
return true;
}
void
WebSocketChannelChild::AsyncOpenFailed()
{
LOG(("WebSocketChannelChild::RecvAsyncOpenFailed() %p\n", this));
mCancelled = true;
if (mIPCOpen)
SendDeleteSelf();
}
NS_IMETHODIMP
WebSocketChannelChild::AsyncOpen(nsIURI *aURI,
const nsACString &aOrigin,
nsIWebSocketListener *aListener,
nsISupports *aContext)
{
LOG(("WebSocketChannelChild::AsyncOpen() %p\n", this));
NS_ABORT_IF_FALSE(aURI && aListener && !mListener,
"Invalid state for WebSocketChannelChild::AsyncOpen");
mozilla::dom::TabChild* tabChild = nsnull;
nsCOMPtr<nsITabChild> iTabChild;
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
NS_GET_IID(nsITabChild),
getter_AddRefs(iTabChild));
if (iTabChild) {
tabChild = static_cast<mozilla::dom::TabChild*>(iTabChild.get());
}
// Corresponding release in DeallocPWebSocket
AddIPDLReference();
gNeckoChild->SendPWebSocketConstructor(this, tabChild);
if (!SendAsyncOpen(aURI, nsCString(aOrigin), mProtocol, mEncrypted))
return NS_ERROR_UNEXPECTED;
mOriginalURI = aURI;
mURI = mOriginalURI;
mListener = aListener;
mContext = aContext;
mOrigin = aOrigin;
return NS_OK;
}
NS_IMETHODIMP
WebSocketChannelChild::Close()
{
LOG(("WebSocketChannelChild::Close() %p\n", this));
if (mCancelled)
return NS_ERROR_UNEXPECTED;
if (!mIPCOpen || !SendClose())
return NS_ERROR_UNEXPECTED;
return NS_OK;
}
NS_IMETHODIMP
WebSocketChannelChild::SendMsg(const nsACString &aMsg)
{
LOG(("WebSocketChannelChild::SendMsg() %p\n", this));
if (mCancelled)
return NS_ERROR_UNEXPECTED;
if (!mIPCOpen || !SendSendMsg(nsCString(aMsg)))
return NS_ERROR_UNEXPECTED;
return NS_OK;
}
NS_IMETHODIMP
WebSocketChannelChild::SendBinaryMsg(const nsACString &aMsg)
{
LOG(("WebSocketChannelChild::SendBinaryMsg() %p\n", this));
if (mCancelled)
return NS_ERROR_UNEXPECTED;
if (!mIPCOpen || !SendSendBinaryMsg(nsCString(aMsg)))
return NS_ERROR_UNEXPECTED;
return NS_OK;
}
NS_IMETHODIMP
WebSocketChannelChild::GetSecurityInfo(nsISupports **aSecurityInfo)
{
LOG(("WebSocketChannelChild::GetSecurityInfo() %p\n", this));
return NS_ERROR_NOT_AVAILABLE;
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,107 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Josh Matthews <josh@joshmatthews.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozilla_net_WebSocketChannelChild_h
#define mozilla_net_WebSocketChannelChild_h
#include "mozilla/net/PWebSocketChild.h"
#include "mozilla/net/ChannelEventQueue.h"
#include "mozilla/net/BaseWebSocketChannel.h"
#include "nsCOMPtr.h"
#include "nsString.h"
namespace mozilla {
namespace net {
class WebSocketChannelChild : public BaseWebSocketChannel,
public PWebSocketChild
{
public:
WebSocketChannelChild(bool aSecure);
~WebSocketChannelChild();
NS_DECL_ISUPPORTS
// nsIWebSocketProtocol methods BaseWebSocketChannel didn't implement for us
//
NS_SCRIPTABLE NS_IMETHOD AsyncOpen(nsIURI *aURI,
const nsACString &aOrigin,
nsIWebSocketListener *aListener,
nsISupports *aContext);
NS_SCRIPTABLE NS_IMETHOD Close();
NS_SCRIPTABLE NS_IMETHOD SendMsg(const nsACString &aMsg);
NS_SCRIPTABLE NS_IMETHOD SendBinaryMsg(const nsACString &aMsg);
NS_SCRIPTABLE NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo);
void AddIPDLReference();
void ReleaseIPDLReference();
private:
bool RecvOnStart(const nsCString& aProtocol);
bool RecvOnStop(const nsresult& aStatusCode);
bool RecvOnMessageAvailable(const nsCString& aMsg);
bool RecvOnBinaryMessageAvailable(const nsCString& aMsg);
bool RecvOnAcknowledge(const PRUint32& aSize);
bool RecvOnServerClose();
bool RecvAsyncOpenFailed();
void OnStart(const nsCString& aProtocol);
void OnStop(const nsresult& aStatusCode);
void OnMessageAvailable(const nsCString& aMsg);
void OnBinaryMessageAvailable(const nsCString& aMsg);
void OnAcknowledge(const PRUint32& aSize);
void OnServerClose();
void AsyncOpenFailed();
ChannelEventQueue mEventQ;
bool mIPCOpen;
bool mCancelled;
friend class StartEvent;
friend class StopEvent;
friend class MessageEvent;
friend class AcknowledgeEvent;
friend class ServerCloseEvent;
friend class AsyncOpenFailedEvent;
};
} // namespace net
} // namespace mozilla
#endif // mozilla_net_WebSocketChannelChild_h

Просмотреть файл

@ -0,0 +1,226 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Josh Matthews <josh@joshmatthews.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "WebSocketLog.h"
#include "WebSocketChannelParent.h"
#include "nsIAuthPromptProvider.h"
namespace mozilla {
namespace net {
NS_IMPL_THREADSAFE_ISUPPORTS2(WebSocketChannelParent,
nsIWebSocketListener,
nsIInterfaceRequestor)
WebSocketChannelParent::WebSocketChannelParent(nsIAuthPromptProvider* aAuthProvider)
: mAuthProvider(aAuthProvider)
, mIPCOpen(true)
{
#if defined(PR_LOGGING)
if (!webSocketLog)
webSocketLog = PR_NewLogModule("nsWebSocket");
#endif
}
bool
WebSocketChannelParent::RecvDeleteSelf()
{
LOG(("WebSocketChannelParent::RecvDeleteSelf() %p\n", this));
mChannel = nsnull;
mAuthProvider = nsnull;
return mIPCOpen ? Send__delete__(this) : true;
}
bool
WebSocketChannelParent::RecvAsyncOpen(const IPC::URI& aURI,
const nsCString& aOrigin,
const nsCString& aProtocol,
const bool& aSecure)
{
LOG(("WebSocketChannelParent::RecvAsyncOpen() %p\n", this));
nsresult rv;
if (aSecure) {
mChannel =
do_CreateInstance("@mozilla.org/network/protocol;1?name=wss", &rv);
} else {
mChannel =
do_CreateInstance("@mozilla.org/network/protocol;1?name=ws", &rv);
}
if (NS_FAILED(rv))
return CancelEarly();
rv = mChannel->SetNotificationCallbacks(this);
if (NS_FAILED(rv))
return CancelEarly();
rv = mChannel->SetProtocol(aProtocol);
if (NS_FAILED(rv))
return CancelEarly();
rv = mChannel->AsyncOpen(aURI, aOrigin, this, nsnull);
if (NS_FAILED(rv))
return CancelEarly();
return true;
}
bool
WebSocketChannelParent::RecvClose()
{
LOG(("WebSocketChannelParent::RecvClose() %p\n", this));
if (mChannel) {
nsresult rv = mChannel->Close();
NS_ENSURE_SUCCESS(rv, true);
}
return true;
}
bool
WebSocketChannelParent::RecvSendMsg(const nsCString& aMsg)
{
LOG(("WebSocketChannelParent::RecvSendMsg() %p\n", this));
if (mChannel) {
nsresult rv = mChannel->SendMsg(aMsg);
NS_ENSURE_SUCCESS(rv, true);
}
return true;
}
bool
WebSocketChannelParent::RecvSendBinaryMsg(const nsCString& aMsg)
{
LOG(("WebSocketChannelParent::RecvSendBinaryMsg() %p\n", this));
if (mChannel) {
nsresult rv = mChannel->SendBinaryMsg(aMsg);
NS_ENSURE_SUCCESS(rv, true);
}
return true;
}
bool
WebSocketChannelParent::CancelEarly()
{
LOG(("WebSocketChannelParent::CancelEarly() %p\n", this));
return mIPCOpen ? SendAsyncOpenFailed() : true;
}
NS_IMETHODIMP
WebSocketChannelParent::GetInterface(const nsIID & iid, void **result NS_OUTPARAM)
{
LOG(("WebSocketChannelParent::GetInterface() %p\n", this));
if (mAuthProvider && iid.Equals(NS_GET_IID(nsIAuthPromptProvider)))
return mAuthProvider->GetAuthPrompt(nsIAuthPromptProvider::PROMPT_NORMAL,
iid, result);
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
WebSocketChannelParent::OnStart(nsISupports *aContext)
{
LOG(("WebSocketChannelParent::OnStart() %p\n", this));
nsCAutoString protocol;
if (mChannel) {
mChannel->GetProtocol(protocol);
}
if (!mIPCOpen || !SendOnStart(protocol)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
WebSocketChannelParent::OnStop(nsISupports *aContext, nsresult aStatusCode)
{
LOG(("WebSocketChannelParent::OnStop() %p\n", this));
if (!mIPCOpen || !SendOnStop(aStatusCode)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
WebSocketChannelParent::OnMessageAvailable(nsISupports *aContext, const nsACString& aMsg)
{
LOG(("WebSocketChannelParent::OnMessageAvailable() %p\n", this));
if (!mIPCOpen || !SendOnMessageAvailable(nsCString(aMsg))) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
WebSocketChannelParent::OnBinaryMessageAvailable(nsISupports *aContext, const nsACString& aMsg)
{
LOG(("WebSocketChannelParent::OnBinaryMessageAvailable() %p\n", this));
if (!mIPCOpen || !SendOnBinaryMessageAvailable(nsCString(aMsg))) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
WebSocketChannelParent::OnAcknowledge(nsISupports *aContext, PRUint32 aSize)
{
LOG(("WebSocketChannelParent::OnAcknowledge() %p\n", this));
if (!mIPCOpen || !SendOnAcknowledge(aSize)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
WebSocketChannelParent::OnServerClose(nsISupports *aContext)
{
LOG(("WebSocketChannelParent::OnServerClose() %p\n", this));
if (!mIPCOpen || !SendOnServerClose()) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
void
WebSocketChannelParent::ActorDestroy(ActorDestroyReason why)
{
LOG(("WebSocketChannelParent::ActorDestroy() %p\n", this));
mIPCOpen = false;
}
} // namespace net
} // namespace mozilla

Просмотреть файл

@ -0,0 +1,85 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Josh Matthews <josh@joshmatthews.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozilla_net_WebSocketChannelParent_h
#define mozilla_net_WebSocketChannelParent_h
#include "mozilla/net/PWebSocketParent.h"
#include "mozilla/net/nsWebSocketHandler.h"
#include "nsCOMPtr.h"
#include "nsString.h"
class nsIAuthPromptProvider;
namespace mozilla {
namespace net {
class WebSocketChannelParent : public PWebSocketParent,
public nsIWebSocketListener,
public nsIInterfaceRequestor
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBSOCKETLISTENER
NS_DECL_NSIINTERFACEREQUESTOR
WebSocketChannelParent(nsIAuthPromptProvider* aAuthProvider);
private:
bool RecvAsyncOpen(const IPC::URI& aURI,
const nsCString& aOrigin,
const nsCString& aProtocol,
const bool& aSecure);
bool RecvClose();
bool RecvSendMsg(const nsCString& aMsg);
bool RecvSendBinaryMsg(const nsCString& aMsg);
bool RecvDeleteSelf();
bool CancelEarly();
void ActorDestroy(ActorDestroyReason why);
nsCOMPtr<nsIAuthPromptProvider> mAuthProvider;
nsCOMPtr<nsIWebSocketProtocol> mChannel;
bool mIPCOpen;
};
} // namespace net
} // namespace mozilla
#endif // mozilla_net_WebSocketChannelParent_h

Просмотреть файл

@ -0,0 +1,62 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 : */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Josh Matthews <josh@joshmatthews.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef WebSocketLog_h
#define WebSocketLog_h
#ifdef MOZ_LOGGING
#define FORCE_PR_LOG
#endif
#if defined(PR_LOG)
#error "This file must be #included before any IPDL-generated files or other files that #include prlog.h"
#endif
#include "base/basictypes.h"
#include "prlog.h"
#include "mozilla/net/NeckoChild.h"
#ifdef PR_LOGGING
extern PRLogModuleInfo* webSocketLog;
#endif
#undef LOG
#define LOG(args) PR_LOG(webSocketLog, PR_LOG_DEBUG, args)
#endif

Просмотреть файл

@ -0,0 +1,40 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Mozilla Firefox.
#
# The Initial Developer of the Original Code is
# The Mozilla Foundation <http://www.mozilla.org/>.
# Portions created by the Initial Developer are Copyright (C) 2011
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Josh Matthews <josh@joshmatthews.net>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
IPDLSRCS = \
PWebSocket.ipdl \
$(NULL)

Просмотреть файл

@ -37,6 +37,7 @@
*
* ***** END LICENSE BLOCK ***** */
#include "WebSocketLog.h"
#include "nsWebSocketHandler.h"
#include "nsISocketTransportService.h"
@ -69,7 +70,6 @@
#include "prmem.h"
#include "prnetdb.h"
#include "prbit.h"
#include "prlog.h"
#include "zlib.h"
extern PRThread *gSocketThread;
@ -90,11 +90,6 @@ NS_IMPL_THREADSAFE_ISUPPORTS11(nsWebSocketHandler,
nsIInterfaceRequestor,
nsIChannelEventSink)
#if defined(PR_LOGGING)
static PRLogModuleInfo *webSocketLog = nsnull;
#endif
#define LOG(args) PR_LOG(webSocketLog, PR_LOG_DEBUG, args)
// Use this fake ptr so the Fin message stays in sequence in the
// main transmit queue
#define kFinMessage (reinterpret_cast<nsCString *>(0x01))
@ -490,7 +485,6 @@ static nsWSAdmissionManager *sWebSocketAdmissions = nsnull;
// nsWebSocketHandler
nsWebSocketHandler::nsWebSocketHandler() :
mEncrypted(PR_FALSE),
mCloseTimeout(20000),
mOpenTimeout(20000),
mPingTimeout(0),
@ -522,10 +516,6 @@ nsWebSocketHandler::nsWebSocketHandler() :
mDynamicOutput(nsnull)
{
NS_ABORT_IF_FALSE(NS_IsMainThread(), "not main thread");
#if defined(PR_LOGGING)
if (!webSocketLog)
webSocketLog = PR_NewLogModule("nsWebSocket");
#endif
LOG(("WebSocketHandler::nsWebSocketHandler() %p\n", this));
@ -1894,50 +1884,6 @@ nsWebSocketHandler::Notify(nsITimer *timer)
return NS_OK;
}
// nsIWebSocketProtocol
NS_IMETHODIMP
nsWebSocketHandler::GetOriginalURI(nsIURI **aOriginalURI)
{
LOG(("WebSocketHandler::GetOriginalURI() %p\n", this));
if (!mOriginalURI)
return NS_ERROR_NOT_INITIALIZED;
NS_ADDREF(*aOriginalURI = mOriginalURI);
return NS_OK;
}
NS_IMETHODIMP
nsWebSocketHandler::GetURI(nsIURI **aURI)
{
LOG(("WebSocketHandler::GetURI() %p\n", this));
if (!mOriginalURI)
return NS_ERROR_NOT_INITIALIZED;
if (mURI)
NS_ADDREF(*aURI = mURI);
else
NS_ADDREF(*aURI = mOriginalURI);
return NS_OK;
}
NS_IMETHODIMP
nsWebSocketHandler::
GetNotificationCallbacks(nsIInterfaceRequestor **aNotificationCallbacks)
{
LOG(("WebSocketHandler::GetNotificationCallbacks() %p\n", this));
NS_IF_ADDREF(*aNotificationCallbacks = mCallbacks);
return NS_OK;
}
NS_IMETHODIMP
nsWebSocketHandler::
SetNotificationCallbacks(nsIInterfaceRequestor *aNotificationCallbacks)
{
LOG(("WebSocketHandler::SetNotificationCallbacks() %p\n", this));
mCallbacks = aNotificationCallbacks;
return NS_OK;
}
NS_IMETHODIMP
nsWebSocketHandler::GetSecurityInfo(nsISupports **aSecurityInfo)
@ -1952,37 +1898,6 @@ nsWebSocketHandler::GetSecurityInfo(nsISupports **aSecurityInfo)
return NS_OK;
}
NS_IMETHODIMP
nsWebSocketHandler::GetLoadGroup(nsILoadGroup **aLoadGroup)
{
LOG(("WebSocketHandler::GetLoadGroup() %p\n", this));
NS_IF_ADDREF(*aLoadGroup = mLoadGroup);
return NS_OK;
}
NS_IMETHODIMP
nsWebSocketHandler::SetLoadGroup(nsILoadGroup *aLoadGroup)
{
LOG(("WebSocketHandler::SetLoadGroup() %p\n", this));
mLoadGroup = aLoadGroup;
return NS_OK;
}
NS_IMETHODIMP
nsWebSocketHandler::GetProtocol(nsACString &aProtocol)
{
LOG(("WebSocketHandler::GetProtocol() %p\n", this));
aProtocol = mProtocol;
return NS_OK;
}
NS_IMETHODIMP
nsWebSocketHandler::SetProtocol(const nsACString &aProtocol)
{
LOG(("WebSocketHandler::SetProtocol() %p\n", this));
mProtocol = aProtocol; /* the sub protocol */
return NS_OK;
}
NS_IMETHODIMP
nsWebSocketHandler::AsyncOpen(nsIURI *aURI,
@ -2664,79 +2579,5 @@ nsWebSocketHandler::OnDataAvailable(nsIRequest *aRequest,
return NS_OK;
}
// nsIProtocolHandler
NS_IMETHODIMP
nsWebSocketHandler::GetScheme(nsACString &aScheme)
{
LOG(("WebSocketHandler::GetScheme() %p\n", this));
if (mEncrypted)
aScheme.AssignLiteral("wss");
else
aScheme.AssignLiteral("ws");
return NS_OK;
}
NS_IMETHODIMP
nsWebSocketHandler::GetDefaultPort(PRInt32 *aDefaultPort)
{
LOG(("WebSocketHandler::GetDefaultPort() %p\n", this));
if (mEncrypted)
*aDefaultPort = kDefaultWSSPort;
else
*aDefaultPort = kDefaultWSPort;
return NS_OK;
}
NS_IMETHODIMP
nsWebSocketHandler::GetProtocolFlags(PRUint32 *aProtocolFlags)
{
LOG(("WebSocketHandler::GetProtocolFlags() %p\n", this));
*aProtocolFlags = URI_NORELATIVE | URI_NON_PERSISTABLE | ALLOWS_PROXY |
ALLOWS_PROXY_HTTP | URI_DOES_NOT_RETURN_DATA | URI_DANGEROUS_TO_LOAD;
return NS_OK;
}
NS_IMETHODIMP
nsWebSocketHandler::NewURI(const nsACString & aSpec, const char *aOriginCharset,
nsIURI *aBaseURI, nsIURI **_retval NS_OUTPARAM)
{
LOG(("WebSocketHandler::NewURI() %p\n", this));
PRInt32 port;
nsresult rv = GetDefaultPort(&port);
if (NS_FAILED(rv))
return rv;
nsRefPtr<nsStandardURL> url = new nsStandardURL();
rv = url->Init(nsIStandardURL::URLTYPE_AUTHORITY, port, aSpec,
aOriginCharset, aBaseURI);
if (NS_FAILED(rv))
return rv;
NS_ADDREF(*_retval = url);
return NS_OK;
}
NS_IMETHODIMP
nsWebSocketHandler::NewChannel(nsIURI *aURI, nsIChannel **_retval NS_OUTPARAM)
{
LOG(("WebSocketHandler::NewChannel() %p\n", this));
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsWebSocketHandler::AllowPort(PRInt32 port, const char *scheme,
PRBool *_retval NS_OUTPARAM)
{
LOG(("WebSocketHandler::AllowPort() %p\n", this));
// do not override any blacklisted ports
*_retval = PR_FALSE;
return NS_OK;
}
} // namespace mozilla::net
} // namespace mozilla

Просмотреть файл

@ -37,6 +37,8 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef mozilla_net_nsWebSocketHandler_h
#define mozilla_net_nsWebSocketHandler_h
#include "nsIWebSocketProtocol.h"
#include "nsIURI.h"
@ -57,6 +59,7 @@
#include "nsIStringStream.h"
#include "nsIHttpChannelInternal.h"
#include "nsIRandomGenerator.h"
#include "BaseWebSocketChannel.h"
#include "nsCOMPtr.h"
#include "nsString.h"
@ -68,10 +71,9 @@ class nsPostMessage;
class nsWSAdmissionManager;
class nsWSCompression;
class nsWebSocketHandler : public nsIWebSocketProtocol,
class nsWebSocketHandler : public BaseWebSocketChannel,
public nsIHttpUpgradeListener,
public nsIStreamListener,
public nsIProtocolHandler,
public nsIInputStreamCallback,
public nsIOutputStreamCallback,
public nsITimerCallback,
@ -81,11 +83,9 @@ class nsWebSocketHandler : public nsIWebSocketProtocol,
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBSOCKETPROTOCOL
NS_DECL_NSIHTTPUPGRADELISTENER
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIPROTOCOLHANDLER
NS_DECL_NSIINPUTSTREAMCALLBACK
NS_DECL_NSIOUTPUTSTREAMCALLBACK
NS_DECL_NSITIMERCALLBACK
@ -93,6 +93,17 @@ public:
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSICHANNELEVENTSINK
// nsIWebSocketProtocol methods BaseWebSocketChannel didn't implement for us
//
NS_IMETHOD AsyncOpen(nsIURI *aURI,
const nsACString &aOrigin,
nsIWebSocketListener *aListener,
nsISupports *aContext);
NS_IMETHOD Close();
NS_IMETHOD SendMsg(const nsACString &aMsg);
NS_IMETHOD SendBinaryMsg(const nsACString &aMsg);
NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo);
nsWebSocketHandler();
static void Shutdown();
@ -109,8 +120,6 @@ public:
};
const static PRUint32 kControlFrameMask = 0x8;
const static PRInt32 kDefaultWSPort = 80;
const static PRInt32 kDefaultWSSPort = 443;
const static PRUint8 kMaskBit = 0x80;
const static PRUint8 kFinalFragBit = 0x80;
@ -125,8 +134,7 @@ public:
protected:
virtual ~nsWebSocketHandler();
PRBool mEncrypted;
private:
friend class nsPostMessage;
friend class nsWSAdmissionManager;
@ -196,11 +204,6 @@ private:
PRInt32 mBinaryLen;
};
nsCOMPtr<nsIURI> mOriginalURI;
nsCOMPtr<nsIURI> mURI;
nsCOMPtr<nsIWebSocketListener> mListener;
nsCOMPtr<nsISupports> mContext;
nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
nsCOMPtr<nsIEventTarget> mSocketThread;
nsCOMPtr<nsIHttpChannelInternal> mChannel;
nsCOMPtr<nsIHttpChannel> mHttpChannel;
@ -209,8 +212,6 @@ private:
nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback;
nsCOMPtr<nsIRandomGenerator> mRandomGenerator;
nsCString mProtocol;
nsCString mOrigin;
nsCString mHashedSecret;
nsCString mAddress;
@ -280,9 +281,11 @@ private:
class nsWebSocketSSLHandler : public nsWebSocketHandler
{
public:
nsWebSocketSSLHandler() {nsWebSocketHandler::mEncrypted = PR_TRUE;}
nsWebSocketSSLHandler() { BaseWebSocketChannel::mEncrypted = PR_TRUE; }
protected:
virtual ~nsWebSocketSSLHandler() {}
};
}} // namespace mozilla::net
#endif // mozilla_net_nsWebSocketHandler_h

Просмотреть файл

@ -212,6 +212,10 @@ SpecialPowers.prototype = {
this.DOMWindowUtils.garbageCollect();
},
forceGC: function() {
Components.utils.forceGC();
},
hasContentProcesses: function() {
try {
var rt = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);

Просмотреть файл

@ -208,9 +208,8 @@ TelemetryPing.prototype = {
let memReporters = {};
while (e.hasMoreElements()) {
let mr = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
// memReporters[mr.path] = mr.amount;
let id = MEM_HISTOGRAMS[mr.path];
if (!id) {
if (!id || mr.amount == -1) {
continue;
}
@ -224,15 +223,15 @@ TelemetryPing.prototype = {
// Read mr.amount just once so our arithmetic is consistent.
let curVal = mr.amount;
let prevVal = this._prevValues[mr.path];
if (!prevVal) {
if (!(mr.path in this._prevValues)) {
// If this is the first time we're reading this reporter, store its
// current value but don't report it in the telemetry ping, so we
// ignore the effect startup had on the reporter.
this._prevValues[mr.path] = curVal;
continue;
}
val = curVal - prevVal;
val = curVal - this._prevValues[mr.path];
this._prevValues[mr.path] = curVal;
}
else {
@ -245,9 +244,7 @@ TelemetryPing.prototype = {
h = Telemetry.getHistogramById(id);
this._histograms[mr.path] = h;
}
// hack to deal with some memory reporters returning 0
if (val)
h.add(val);
h.add(val);
}
return memReporters;
},