mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-21 17:59:34 +00:00
Bug 581732 - Merge mozilla-central to tabcandy-central 2010/07/24 (with conflicts).
This commit is contained in:
commit
e99995210d
@ -1250,7 +1250,8 @@ nsDocAccessible::ContentInserted(nsIDocument *aDocument, nsIContent* aContainer,
|
||||
|
||||
void
|
||||
nsDocAccessible::ContentRemoved(nsIDocument *aDocument, nsIContent* aContainer,
|
||||
nsIContent* aChild, PRInt32 /* unused */)
|
||||
nsIContent* aChild, PRInt32 /* unused */,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
// It's no needed to invalidate the subtree of the removed element,
|
||||
// because we get notifications directly from content (see
|
||||
|
@ -51,7 +51,6 @@ CPPSRCS = \
|
||||
nsAccessibleWrap.cpp \
|
||||
nsTextAccessibleWrap.cpp \
|
||||
nsDocAccessibleWrap.cpp \
|
||||
nsRootAccessibleWrap.cpp \
|
||||
nsHTMLWin32ObjectAccessible.cpp \
|
||||
nsARIAGridAccessibleWrap.cpp \
|
||||
nsXULMenuAccessibleWrap.cpp \
|
||||
|
@ -219,10 +219,16 @@ __try {
|
||||
nsIView *rootView;
|
||||
viewManager->GetRootView(rootView);
|
||||
if (rootView == view) {
|
||||
// If the current object has a widget but was created by an
|
||||
// outer object with its own outer window, then
|
||||
// we want the native accessible for that outer window
|
||||
hwnd = ::GetParent(hwnd);
|
||||
// If the client accessible (OBJID_CLIENT) has a window but its window
|
||||
// was created by an outer window then we want the native accessible
|
||||
// for that outer window. If the accessible was created for outer
|
||||
// window (if the outer window has inner windows then they share the
|
||||
// same client accessible with it) then return native accessible for
|
||||
// the outer window.
|
||||
HWND parenthwnd = ::GetParent(hwnd);
|
||||
if (parenthwnd)
|
||||
hwnd = parenthwnd;
|
||||
|
||||
NS_ASSERTION(hwnd, "No window handle for window");
|
||||
}
|
||||
}
|
||||
|
@ -43,15 +43,8 @@
|
||||
#ifndef _nsRootAccessibleWrap_H_
|
||||
#define _nsRootAccessibleWrap_H_
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsRootAccessible.h"
|
||||
|
||||
class nsRootAccessibleWrap: public nsRootAccessible
|
||||
{
|
||||
public:
|
||||
nsRootAccessibleWrap(nsIDocument *aDocument, nsIContent *aRootContent,
|
||||
nsIWeakReference *aShell);
|
||||
virtual ~nsRootAccessibleWrap();
|
||||
};
|
||||
typedef class nsRootAccessible nsRootAccessibleWrap;
|
||||
|
||||
#endif
|
||||
|
@ -48,14 +48,14 @@
|
||||
label="&openLinkCmdInCurrent.label;"
|
||||
accesskey="&openLinkCmdInCurrent.accesskey;"
|
||||
oncommand="gContextMenu.openLinkInCurrent();"/>
|
||||
<menuitem id="context-openlink"
|
||||
label="&openLinkCmd.label;"
|
||||
accesskey="&openLinkCmd.accesskey;"
|
||||
oncommand="gContextMenu.openLink();"/>
|
||||
<menuitem id="context-openlinkintab"
|
||||
label="&openLinkCmdInTab.label;"
|
||||
accesskey="&openLinkCmdInTab.accesskey;"
|
||||
oncommand="gContextMenu.openLinkInTab();"/>
|
||||
<menuitem id="context-openlink"
|
||||
label="&openLinkCmd.label;"
|
||||
accesskey="&openLinkCmd.accesskey;"
|
||||
oncommand="gContextMenu.openLink();"/>
|
||||
<menuseparator id="context-sep-open"/>
|
||||
<menuitem id="context-bookmarklink"
|
||||
label="&bookmarkThisLinkCmd.label;"
|
||||
@ -250,14 +250,14 @@
|
||||
label="&showOnlyThisFrameCmd.label;"
|
||||
accesskey="&showOnlyThisFrameCmd.accesskey;"
|
||||
oncommand="gContextMenu.showOnlyThisFrame();"/>
|
||||
<menuitem id="context-openframe"
|
||||
label="&openFrameCmd.label;"
|
||||
accesskey="&openFrameCmd.accesskey;"
|
||||
oncommand="gContextMenu.openFrame();"/>
|
||||
<menuitem id="context-openframeintab"
|
||||
label="&openFrameCmdInTab.label;"
|
||||
accesskey="&openFrameCmdInTab.accesskey;"
|
||||
oncommand="gContextMenu.openFrameInTab();"/>
|
||||
<menuitem id="context-openframe"
|
||||
label="&openFrameCmd.label;"
|
||||
accesskey="&openFrameCmd.accesskey;"
|
||||
oncommand="gContextMenu.openFrame();"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="context-reloadframe"
|
||||
label="&reloadFrameCmd.label;"
|
||||
|
@ -48,35 +48,20 @@ const MOUSE_SCROLL_ZOOM = 3;
|
||||
* Controls the "full zoom" setting and its site-specific preferences.
|
||||
*/
|
||||
var FullZoom = {
|
||||
|
||||
//**************************************************************************//
|
||||
// Name & Values
|
||||
|
||||
// The name of the setting. Identifies the setting in the prefs database.
|
||||
// Identifies the setting in the content prefs database.
|
||||
name: "browser.content.full-zoom",
|
||||
|
||||
// The global value (if any) for the setting. Lazily loaded from the service
|
||||
// when first requested, then updated by the pref change listener as it changes.
|
||||
// If there is no global value, then this should be undefined.
|
||||
get globalValue() {
|
||||
var globalValue = this._cps.getPref(null, this.name);
|
||||
var globalValue = Services.contentPrefs.getPref(null, this.name);
|
||||
if (typeof globalValue != "undefined")
|
||||
globalValue = this._ensureValid(globalValue);
|
||||
delete this.globalValue;
|
||||
return this.globalValue = globalValue;
|
||||
},
|
||||
|
||||
|
||||
//**************************************************************************//
|
||||
// Convenience Getters
|
||||
|
||||
// Content Pref Service
|
||||
get _cps() {
|
||||
delete this._cps;
|
||||
return this._cps = Cc["@mozilla.org/content-pref/service;1"].
|
||||
getService(Ci.nsIContentPrefService);
|
||||
},
|
||||
|
||||
// browser.zoom.siteSpecific preference cache
|
||||
_siteSpecificPref: undefined,
|
||||
|
||||
@ -93,19 +78,11 @@ var FullZoom = {
|
||||
//**************************************************************************//
|
||||
// nsISupports
|
||||
|
||||
// We can't use the Ci shortcut here because it isn't defined yet.
|
||||
interfaces: [Components.interfaces.nsIDOMEventListener,
|
||||
Components.interfaces.nsIObserver,
|
||||
Components.interfaces.nsIContentPrefObserver,
|
||||
Components.interfaces.nsISupportsWeakReference,
|
||||
Components.interfaces.nsISupports],
|
||||
|
||||
QueryInterface: function FullZoom_QueryInterface(aIID) {
|
||||
if (!this.interfaces.some(function (v) aIID.equals(v)))
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMEventListener,
|
||||
Ci.nsIObserver,
|
||||
Ci.nsIContentPrefObserver,
|
||||
Ci.nsISupportsWeakReference,
|
||||
Ci.nsISupports]),
|
||||
|
||||
//**************************************************************************//
|
||||
// Initialization & Destruction
|
||||
@ -115,13 +92,11 @@ var FullZoom = {
|
||||
window.addEventListener("DOMMouseScroll", this, false);
|
||||
|
||||
// Register ourselves with the service so we know when our pref changes.
|
||||
this._cps.addObserver(this.name, this);
|
||||
Services.contentPrefs.addObserver(this.name, this);
|
||||
|
||||
// We disable site-specific preferences in Private Browsing mode, because the
|
||||
// content preferences module is disabled
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.addObserver(this, "private-browsing", true);
|
||||
Services.obs.addObserver(this, "private-browsing", true);
|
||||
|
||||
// Retrieve the initial status of the Private Browsing mode.
|
||||
this._inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
|
||||
@ -138,13 +113,10 @@ var FullZoom = {
|
||||
},
|
||||
|
||||
destroy: function FullZoom_destroy() {
|
||||
let os = Cc["@mozilla.org/observer-service;1"].
|
||||
getService(Ci.nsIObserverService);
|
||||
os.removeObserver(this, "private-browsing");
|
||||
Services.obs.removeObserver(this, "private-browsing");
|
||||
gPrefService.removeObserver("browser.zoom.", this);
|
||||
this._cps.removeObserver(this.name, this);
|
||||
Services.contentPrefs.removeObserver(this.name, this);
|
||||
window.removeEventListener("DOMMouseScroll", this, false);
|
||||
delete this._cps;
|
||||
},
|
||||
|
||||
|
||||
@ -231,7 +203,7 @@ var FullZoom = {
|
||||
// nsIContentPrefObserver
|
||||
|
||||
onContentPrefSet: function FullZoom_onContentPrefSet(aGroup, aName, aValue) {
|
||||
if (aGroup == this._cps.grouper.group(gBrowser.currentURI))
|
||||
if (aGroup == Services.contentPrefs.grouper.group(gBrowser.currentURI))
|
||||
this._applyPrefToSetting(aValue);
|
||||
else if (aGroup == null) {
|
||||
this.globalValue = this._ensureValid(aValue);
|
||||
@ -239,13 +211,13 @@ var FullZoom = {
|
||||
// If the current page doesn't have a site-specific preference,
|
||||
// then its zoom should be set to the new global preference now that
|
||||
// the global preference has changed.
|
||||
if (!this._cps.hasPref(gBrowser.currentURI, this.name))
|
||||
if (!Services.contentPrefs.hasPref(gBrowser.currentURI, this.name))
|
||||
this._applyPrefToSetting();
|
||||
}
|
||||
},
|
||||
|
||||
onContentPrefRemoved: function FullZoom_onContentPrefRemoved(aGroup, aName) {
|
||||
if (aGroup == this._cps.grouper.group(gBrowser.currentURI))
|
||||
if (aGroup == Services.contentPrefs.grouper.group(gBrowser.currentURI))
|
||||
this._applyPrefToSetting();
|
||||
else if (aGroup == null) {
|
||||
this.globalValue = undefined;
|
||||
@ -253,7 +225,7 @@ var FullZoom = {
|
||||
// If the current page doesn't have a site-specific preference,
|
||||
// then its zoom should be set to the default preference now that
|
||||
// the global preference has changed.
|
||||
if (!this._cps.hasPref(gBrowser.currentURI, this.name))
|
||||
if (!Services.contentPrefs.hasPref(gBrowser.currentURI, this.name))
|
||||
this._applyPrefToSetting();
|
||||
}
|
||||
},
|
||||
@ -282,7 +254,7 @@ var FullZoom = {
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this._cps.getPref(aURI, this.name, function(aResult) {
|
||||
Services.contentPrefs.getPref(aURI, this.name, function (aResult) {
|
||||
// Check that we're still where we expect to be in case this took a while.
|
||||
let isSaneURI = (aBrowser && aBrowser.currentURI) ?
|
||||
aURI.equals(aBrowser.currentURI) : false;
|
||||
@ -366,12 +338,12 @@ var FullZoom = {
|
||||
return;
|
||||
|
||||
var zoomLevel = ZoomManager.zoom;
|
||||
this._cps.setPref(gBrowser.currentURI, this.name, zoomLevel);
|
||||
Services.contentPrefs.setPref(gBrowser.currentURI, this.name, zoomLevel);
|
||||
},
|
||||
|
||||
_removePref: function FullZoom__removePref() {
|
||||
if (!(content.document instanceof Ci.nsIImageDocument))
|
||||
this._cps.removePref(gBrowser.currentURI, this.name);
|
||||
Services.contentPrefs.removePref(gBrowser.currentURI, this.name);
|
||||
},
|
||||
|
||||
|
||||
|
@ -42,16 +42,16 @@
|
||||
<menu id="file-menu" label="&fileMenu.label;"
|
||||
accesskey="&fileMenu.accesskey;">
|
||||
<menupopup id="menu_FilePopup">
|
||||
<menuitem id="menu_newNavigator"
|
||||
label="&newNavigatorCmd.label;"
|
||||
accesskey="&newNavigatorCmd.accesskey;"
|
||||
key="key_newNavigator"
|
||||
command="cmd_newNavigator"/>
|
||||
<menuitem id="menu_newNavigatorTab"
|
||||
label="&tabCmd.label;"
|
||||
command="cmd_newNavigatorTab"
|
||||
key="key_newNavigatorTab"
|
||||
accesskey="&tabCmd.accesskey;"/>
|
||||
<menuitem id="menu_newNavigator"
|
||||
label="&newNavigatorCmd.label;"
|
||||
accesskey="&newNavigatorCmd.accesskey;"
|
||||
key="key_newNavigator"
|
||||
command="cmd_newNavigator"/>
|
||||
<menuitem id="menu_openLocation"
|
||||
label="&openLocationCmd.label;"
|
||||
command="Browser:OpenLocation"
|
||||
@ -62,17 +62,17 @@
|
||||
command="Browser:OpenFile"
|
||||
key="openFileKb"
|
||||
accesskey="&openFileCmd.accesskey;"/>
|
||||
<menuitem id="menu_close"
|
||||
label="&closeCmd.label;"
|
||||
key="key_close"
|
||||
accesskey="&closeCmd.accesskey;"
|
||||
command="cmd_close"/>
|
||||
<menuitem id="menu_closeWindow"
|
||||
hidden="true"
|
||||
command="cmd_closeWindow"
|
||||
key="key_closeWindow"
|
||||
label="&closeWindow.label;"
|
||||
accesskey="&closeWindow.accesskey;"/>
|
||||
<menuitem id="menu_close"
|
||||
label="&closeCmd.label;"
|
||||
key="key_close"
|
||||
accesskey="&closeCmd.accesskey;"
|
||||
command="cmd_close"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="menu_savePage"
|
||||
label="&savePageCmd.label;"
|
||||
@ -615,10 +615,10 @@
|
||||
accesskey="&errorConsoleCmd.accesskey;"
|
||||
key="key_errorConsole"
|
||||
oncommand="toJavaScriptConsole();"/>
|
||||
<menuitem id="headsUpDisplayConsole"
|
||||
label="&hudConsoleCmd.label;"
|
||||
accesskey="&hudConsoleCmd.accesskey;"
|
||||
key="key_hudConsole"
|
||||
<menuitem id="webConsole"
|
||||
label="&webConsoleCmd.label;"
|
||||
accesskey="&webConsoleCmd.accesskey;"
|
||||
key="key_webConsole"
|
||||
oncommand="HUDConsoleUI.toggleHUD();"/>
|
||||
<menuitem id="menu_pageInfo"
|
||||
accesskey="&pageInfoCmd.accesskey;"
|
||||
|
@ -236,7 +236,7 @@
|
||||
<key id="key_openDownloads" key="&downloads.commandkey;" command="Tools:Downloads" modifiers="accel"/>
|
||||
#endif
|
||||
<key id="key_errorConsole" key="&errorConsoleCmd.commandkey;" oncommand="toJavaScriptConsole();" modifiers="accel,shift"/>
|
||||
<key id="key_hudConsole" key="&hudConsoleCmd.commandkey;" oncommand="HUDConsoleUI.toggleHUD();" modifiers="accel,shift"/>
|
||||
<key id="key_webConsole" key="&webConsoleCmd.commandkey;" oncommand="HUDConsoleUI.toggleHUD();" modifiers="accel,shift"/>
|
||||
<key id="key_inspect" key="&inspectMenu.commandkey;" command="Tools:Inspect" modifiers="accel,shift"/>
|
||||
<key id="openFileKb" key="&openFileCmd.commandkey;" command="Browser:OpenFile" modifiers="accel"/>
|
||||
<key id="key_savePage" key="&savePageCmd.commandkey;" command="Browser:SavePage" modifiers="accel"/>
|
||||
|
@ -80,7 +80,7 @@ toolbar[printpreview="true"] {
|
||||
-moz-box-ordinal-group: 100;
|
||||
}
|
||||
|
||||
#navigator-toolbox[tabsontop="true"] > #TabsToolbar {
|
||||
#TabsToolbar[tabsontop="true"] {
|
||||
-moz-box-ordinal-group: 10;
|
||||
}
|
||||
|
||||
|
@ -7778,6 +7778,12 @@ var TabContextMenu = {
|
||||
// Only one of pin/unpin should be visible
|
||||
document.getElementById("context_pinTab").hidden = this.contextTab.pinned;
|
||||
document.getElementById("context_unpinTab").hidden = !this.contextTab.pinned;
|
||||
|
||||
// Disable "Close other Tabs" if there is only one unpinned tab and
|
||||
// hide it when the user rightclicked on a pinned tab.
|
||||
var unpinnedTabs = gBrowser.tabs.length - gBrowser._numPinnedTabs;
|
||||
document.getElementById("context_closeOtherTabs").disabled = unpinnedTabs <= 1;
|
||||
document.getElementById("context_closeOtherTabs").hidden = this.contextTab.pinned;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -112,17 +112,11 @@
|
||||
<menupopup id="tabContextMenu"
|
||||
onpopupshowing="if (event.target == this) TabContextMenu.updateContextMenu(this);"
|
||||
onpopuphidden="if (event.target == this) TabContextMenu.contextTab = null;">
|
||||
<menuitem id="context_newTab" label="&newTab.label;" accesskey="&newTab.accesskey;"
|
||||
command="cmd_newNavigatorTab"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="context_reloadTab" label="&reloadTab.label;" accesskey="&reloadTab.accesskey;"
|
||||
oncommand="gBrowser.reloadTab(TabContextMenu.contextTab);"/>
|
||||
<menuitem id="context_reloadAllTabs" label="&reloadAllTabs.label;" accesskey="&reloadAllTabs.accesskey;"
|
||||
tbattr="tabbrowser-multiple"
|
||||
oncommand="gBrowser.reloadAllTabs();"/>
|
||||
<menuitem id="context_closeOtherTabs" label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
|
||||
tbattr="tabbrowser-multiple"
|
||||
oncommand="gBrowser.removeAllTabsBut(TabContextMenu.contextTab);"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="context_openTabInWindow" label="&openTabInNewWindow.label;"
|
||||
accesskey="&openTabInNewWindow.accesskey;"
|
||||
@ -143,11 +137,13 @@
|
||||
label="&bookmarkAllTabs.label;"
|
||||
accesskey="&bookmarkAllTabs.accesskey;"
|
||||
command="Browser:BookmarkAllTabs"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="context_closeOtherTabs" label="&closeOtherTabs.label;" accesskey="&closeOtherTabs.accesskey;"
|
||||
oncommand="gBrowser.removeAllTabsBut(TabContextMenu.contextTab);"/>
|
||||
<menuitem id="context_undoCloseTab"
|
||||
label="&undoCloseTab.label;"
|
||||
accesskey="&undoCloseTab.accesskey;"
|
||||
command="History:UndoCloseTab"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="context_closeTab" label="&closeTab.label;" accesskey="&closeTab.accesskey;"
|
||||
oncommand="gBrowser.removeTab(TabContextMenu.contextTab);"/>
|
||||
</menupopup>
|
||||
|
@ -219,6 +219,7 @@
|
||||
<li>Josh Aas</li>
|
||||
<li>Robert Accettura</li>
|
||||
<li>Lucas Adamski</li>
|
||||
<li>Raymond Etornam Agbeame</li>
|
||||
<li>Ehsan Akhgari</li>
|
||||
<li>Sean Alamares</li>
|
||||
<li>Pedro Alves</li>
|
||||
@ -403,6 +404,7 @@
|
||||
<li>Gervase Markham</li>
|
||||
<li>Sean Martell</li>
|
||||
<li>Jim Mathies</li>
|
||||
<li>Blair McBride</li>
|
||||
<li>Erica McClure</li>
|
||||
<li>Graeme McCutcheon</li>
|
||||
<li>Patrick McManus</li>
|
||||
@ -578,6 +580,7 @@
|
||||
<li>Christine Yen</li>
|
||||
<li>Kohei Yoshino</li>
|
||||
<li>Shigeru Yoshitake</li>
|
||||
<li>Tanner M. Young</li>
|
||||
<li>Boris Zbarsky</li>
|
||||
<li>Marco Zehe</li>
|
||||
<li>Matthew Zeier</li>
|
||||
|
@ -80,8 +80,8 @@
|
||||
<menulist id="openWhereList">
|
||||
<menupopup>
|
||||
<menuitem value="0" id="currentWindow" label="&topTab.label;"/>
|
||||
<menuitem value="1" label="&newWindow.label;"/>
|
||||
<menuitem value="3" label="&newTab.label;"/>
|
||||
<menuitem value="1" label="&newWindow.label;"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<spacer flex="1"/>
|
||||
|
@ -54,6 +54,9 @@ var EXPORTED_SYMBOLS = ["style"];
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var style = {
|
||||
|
||||
|
@ -1226,8 +1226,13 @@
|
||||
<body>
|
||||
<![CDATA[
|
||||
var tabsToClose = this.tabs.length;
|
||||
|
||||
if (!aAll)
|
||||
<<<<<<< local
|
||||
tabsToClose = this.visibleTabs.length - 1;
|
||||
=======
|
||||
tabsToClose -= 1 + gBrowser._numPinnedTabs;
|
||||
>>>>>>> other
|
||||
if (tabsToClose <= 1)
|
||||
return true;
|
||||
|
||||
@ -1274,13 +1279,22 @@
|
||||
<parameter name="aTab"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (aTab.pinned)
|
||||
return;
|
||||
|
||||
if (this.warnAboutClosingTabs(false)) {
|
||||
var tabs = this.visibleTabs;
|
||||
this.selectedTab = aTab;
|
||||
|
||||
<<<<<<< local
|
||||
for (let i = tabs.length - 1; i >= 0; --i) {
|
||||
if (tabs[i] != aTab)
|
||||
this.removeTab(tabs[i]);
|
||||
=======
|
||||
for (let i = this.tabs.length - 1; i >= 0; --i) {
|
||||
if (this.tabs[i] != aTab && !this.tabs[i].pinned)
|
||||
this.removeTab(this.tabs[i]);
|
||||
>>>>>>> other
|
||||
}
|
||||
}
|
||||
]]>
|
||||
@ -2326,7 +2340,8 @@
|
||||
inherited from the binding parent -->
|
||||
<method name="_getScrollableElements">
|
||||
<body><![CDATA[
|
||||
return document.getBindingParent(this).childNodes;
|
||||
return Array.filter(document.getBindingParent(this).childNodes,
|
||||
this._canScrollToElement, this);
|
||||
]]></body>
|
||||
</method>
|
||||
<method name="_canScrollToElement">
|
||||
|
@ -136,6 +136,7 @@ _BROWSER_FILES = \
|
||||
browser_bug556061.js \
|
||||
browser_bug562649.js \
|
||||
browser_bug563588.js \
|
||||
browser_bug577121.js \
|
||||
browser_contextSearchTabPosition.js \
|
||||
browser_ctrlTab.js \
|
||||
browser_discovery.js \
|
||||
@ -146,7 +147,6 @@ _BROWSER_FILES = \
|
||||
browser_inspector_treeSelection.js \
|
||||
browser_inspector_highlighter.js \
|
||||
browser_inspector_stylePanel.js \
|
||||
browser_overflowScroll.js \
|
||||
browser_pageInfo.js \
|
||||
browser_page_style_menu.js \
|
||||
browser_pinnedTabs.js \
|
||||
@ -181,9 +181,19 @@ _BROWSER_FILES = \
|
||||
$(NULL)
|
||||
|
||||
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
_BROWSER_FILES += browser_bug462289.js
|
||||
_BROWSER_FILES += \
|
||||
browser_bug462289.js \
|
||||
$(NULL)
|
||||
else
|
||||
_BROWSER_FILES += browser_customize.js
|
||||
_BROWSER_FILES += \
|
||||
browser_customize.js \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifneq (gtk2,$(MOZ_WIDGET_TOOLKIT))
|
||||
_BROWSER_FILES += \
|
||||
browser_overflowScroll.js \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
56
browser/base/content/test/browser_bug577121.js
Normal file
56
browser/base/content/test/browser_bug577121.js
Normal file
@ -0,0 +1,56 @@
|
||||
/* ***** 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 bug 577121 test.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Michael Kohler <michaelkohler@live.com>.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
function test() {
|
||||
// Open 2 other tabs, and pin the second one. Like that, the initial tab
|
||||
// should get closed.
|
||||
let testTab1 = gBrowser.addTab();
|
||||
let testTab2 = gBrowser.addTab();
|
||||
gBrowser.pinTab(testTab2);
|
||||
|
||||
// Now execute "Close other Tabs" on the first manually opened tab (tab1).
|
||||
// -> tab2 ist pinned, tab1 should remain open and the initial tab should
|
||||
// get closed.
|
||||
gBrowser.removeAllTabsBut(testTab1);
|
||||
|
||||
is(gBrowser.tabs.length, 2, "there are two remaining tabs open");
|
||||
is(gBrowser.tabs[0], testTab2, "pinned tab2 stayed open");
|
||||
is(gBrowser.tabs[1], testTab1, "tab1 stayed open");
|
||||
|
||||
// Cleanup. Close only one tab because we need an opened tab at the end of
|
||||
// the test.
|
||||
gBrowser.removeTab(testTab2);
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
var tabContainer = gBrowser.tabContainer;
|
||||
var tabstrip = tabContainer.mTabstrip;
|
||||
var tabstrip = gBrowser.tabContainer.mTabstrip;
|
||||
var scrollbox = tabstrip._scrollbox;
|
||||
var originalSmoothScroll = tabstrip.smoothScroll;
|
||||
var tabs = gBrowser.tabs;
|
||||
|
||||
function rect(ele) ele.getBoundingClientRect();
|
||||
function width(ele) rect(ele).width;
|
||||
@ -12,13 +12,9 @@ function isRight(ele, msg) is(right(ele), right(scrollbox), msg);
|
||||
function elementFromPoint(x) tabstrip._elementFromPoint(x);
|
||||
function nextLeftElement() elementFromPoint(left(scrollbox) - 1);
|
||||
function nextRightElement() elementFromPoint(right(scrollbox) + 1);
|
||||
function firstScrollable() tabs[gBrowser._numPinnedTabs];
|
||||
|
||||
function test() {
|
||||
if (TabsOnTop.enabled) {
|
||||
todo(false, "need to figure out why this doesn't work with tabs on top on OS X and Windows 7 (bug 575748)");
|
||||
return;
|
||||
}
|
||||
|
||||
waitForExplicitFinish();
|
||||
|
||||
// If the previous (or more) test finished with cleaning up the tabs,
|
||||
@ -32,8 +28,9 @@ function doTest() {
|
||||
|
||||
var tabMinWidth = parseInt(getComputedStyle(gBrowser.selectedTab, null).minWidth);
|
||||
var tabCountForOverflow = Math.ceil(width(tabstrip) / tabMinWidth * 3);
|
||||
while (tabContainer.childNodes.length < tabCountForOverflow)
|
||||
while (tabs.length < tabCountForOverflow)
|
||||
gBrowser.addTab("about:blank", {skipAnimation: true});
|
||||
gBrowser.pinTab(tabs[0]);
|
||||
|
||||
tabstrip.addEventListener("overflow", runOverflowTests, false);
|
||||
}
|
||||
@ -48,37 +45,37 @@ function runOverflowTests(aEvent) {
|
||||
var downButton = tabstrip._scrollButtonDown;
|
||||
var element;
|
||||
|
||||
gBrowser.selectedTab = tabContainer.firstChild;
|
||||
isLeft(tabContainer.firstChild, "Selecting the first tab scrolls it into view");
|
||||
gBrowser.selectedTab = firstScrollable();
|
||||
isLeft(firstScrollable(), "Selecting the first tab scrolls it into view");
|
||||
|
||||
element = nextRightElement();
|
||||
EventUtils.synthesizeMouse(downButton, 0, 0, {});
|
||||
EventUtils.synthesizeMouse(downButton, 1, 1, {});
|
||||
isRight(element, "Scrolled one tab to the right with a single click");
|
||||
|
||||
gBrowser.selectedTab = tabContainer.lastChild;
|
||||
isRight(tabContainer.lastChild, "Selecting the last tab scrolls it into view");
|
||||
gBrowser.selectedTab = tabs[tabs.length - 1];
|
||||
isRight(gBrowser.selectedTab, "Selecting the last tab scrolls it into view");
|
||||
|
||||
element = nextLeftElement();
|
||||
EventUtils.synthesizeMouse(upButton, 0, 0, {});
|
||||
EventUtils.synthesizeMouse(upButton, 1, 1, {});
|
||||
isLeft(element, "Scrolled one tab to the left with a single click");
|
||||
|
||||
element = elementFromPoint(left(scrollbox) - width(scrollbox));
|
||||
EventUtils.synthesizeMouse(upButton, 0, 0, {clickCount: 2});
|
||||
EventUtils.synthesizeMouse(upButton, 1, 1, {clickCount: 2});
|
||||
isLeft(element, "Scrolled one page of tabs with a double click");
|
||||
|
||||
EventUtils.synthesizeMouse(upButton, 0, 0, {clickCount: 3});
|
||||
isLeft(tabContainer.firstChild, "Scrolled to the start with a triple click");
|
||||
EventUtils.synthesizeMouse(upButton, 1, 1, {clickCount: 3});
|
||||
isLeft(firstScrollable(), "Scrolled to the start with a triple click");
|
||||
|
||||
for (var i = 2; i; i--)
|
||||
EventUtils.synthesizeMouseScroll(scrollbox, 0, 0, {axis: "horizontal", delta: -1});
|
||||
isLeft(tabContainer.firstChild, "Remained at the start with the mouse wheel");
|
||||
EventUtils.synthesizeMouseScroll(scrollbox, 1, 1, {axis: "horizontal", delta: -1});
|
||||
isLeft(firstScrollable(), "Remained at the start with the mouse wheel");
|
||||
|
||||
element = nextRightElement();
|
||||
EventUtils.synthesizeMouseScroll(scrollbox, 0, 0, {axis: "horizontal", delta: 1});
|
||||
EventUtils.synthesizeMouseScroll(scrollbox, 1, 1, {axis: "horizontal", delta: 1});
|
||||
isRight(element, "Scrolled one tab to the right with the mouse wheel");
|
||||
|
||||
while (tabContainer.childNodes.length > 1)
|
||||
gBrowser.removeTab(tabContainer.lastChild);
|
||||
while (tabs.length > 1)
|
||||
gBrowser.removeTab(tabs[0]);
|
||||
|
||||
tabstrip.smoothScroll = originalSmoothScroll;
|
||||
finish();
|
||||
|
@ -182,8 +182,8 @@ function runTest(testNum) {
|
||||
|
||||
case 3:
|
||||
// Context menu for text link
|
||||
checkContextMenu(["context-openlink", true,
|
||||
"context-openlinkintab", true,
|
||||
checkContextMenu(["context-openlinkintab", true,
|
||||
"context-openlink", true,
|
||||
"---", null,
|
||||
"context-bookmarklink", true,
|
||||
"context-savelink", true,
|
||||
@ -303,8 +303,8 @@ function runTest(testNum) {
|
||||
"context-selectall", true,
|
||||
"frame", null,
|
||||
["context-showonlythisframe", true,
|
||||
"context-openframe", true,
|
||||
"context-openframeintab", true,
|
||||
"context-openframe", true,
|
||||
"---", null,
|
||||
"context-reloadframe", true,
|
||||
"---", null,
|
||||
|
@ -554,9 +554,9 @@ FeedWriter.prototype = {
|
||||
var url = makeURI(aURL);
|
||||
url.QueryInterface(Ci.nsIURL);
|
||||
if (url == null || url.fileName.length == 0)
|
||||
return aURL;
|
||||
return decodeURIComponent(aURL);
|
||||
|
||||
return decodeURI(url.fileName);
|
||||
return decodeURIComponent(url.fileName);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -55,6 +55,8 @@ _TEST_FILES = test_bug408328.html \
|
||||
bug408328-data.xml \
|
||||
test_bug368464.html \
|
||||
bug368464-data.xml \
|
||||
test_bug494328.html \
|
||||
bug494328-data.xml \
|
||||
test_registerHandler.html \
|
||||
$(NULL)
|
||||
|
||||
|
24
browser/components/feeds/test/bug494328-data.xml
Normal file
24
browser/components/feeds/test/bug494328-data.xml
Normal file
@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0">
|
||||
<channel>
|
||||
<title>Channel title</title>
|
||||
<description>Channel description</description>
|
||||
<link>Channel link</link>
|
||||
<item>
|
||||
<title>Episode 1</title>
|
||||
<enclosure url="http://www.example.com/podcasts/Episode%201" length="0" type="audio/x-m4a" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Episode 2</title>
|
||||
<enclosure url="http://www.example.com/podcasts/Episode%20%232" length="0" type="audio/x-m4a" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Episode 3</title>
|
||||
<enclosure url="http://www.example.com/podcasts/Episode%20%233/" length="0" type="audio/x-m4a" />
|
||||
</item>
|
||||
<item>
|
||||
<title>Episode 4</title>
|
||||
<enclosure url="http://www.example.com/podcasts/Is%20This%20Episode%20%234%3F" length="0" type="audio/x-m4a" />
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
38
browser/components/feeds/test/test_bug494328.html
Normal file
38
browser/components/feeds/test/test_bug494328.html
Normal file
@ -0,0 +1,38 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=494328
|
||||
-->
|
||||
<head>
|
||||
<title>Test for bug 494328</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=494328">Mozilla Bug 494328</a>
|
||||
<p id="display"><iframe id="testFrame" src="bug494328-data.xml"></iframe></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 494328 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(function() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
|
||||
var links = $("testFrame").contentDocument.getElementById("feedContent").querySelectorAll("div.enclosure > a");
|
||||
is(links[0].textContent, "Episode 1", "filename decoded incorrectly");
|
||||
is(links[1].textContent, "Episode #2", "filename decoded incorrectly");
|
||||
is(links[2].textContent, "http://www.example.com/podcasts/Episode #3/", "filename decoded incorrectly");
|
||||
is(links[3].textContent, "Is This Episode #4?", "filename decoded incorrectly");
|
||||
});
|
||||
addLoadEvent(SimpleTest.finish);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -134,12 +134,6 @@
|
||||
default="true"
|
||||
selectiontype="single"
|
||||
selection="link"/>
|
||||
<menuitem id="placesContext_open:newwindow"
|
||||
command="placesCmd_open:window"
|
||||
label="&cmd.open_window.label;"
|
||||
accesskey="&cmd.open_window.accesskey;"
|
||||
selectiontype="single"
|
||||
selection="link"/>
|
||||
<menuitem id="placesContext_open:newtab"
|
||||
command="placesCmd_open:tab"
|
||||
label="&cmd.open_tab.label;"
|
||||
@ -162,6 +156,12 @@
|
||||
accesskey="&cmd.open_all_in_tabs.accesskey;"
|
||||
selectiontype="multiple"
|
||||
selection="link"/>
|
||||
<menuitem id="placesContext_open:newwindow"
|
||||
command="placesCmd_open:window"
|
||||
label="&cmd.open_window.label;"
|
||||
accesskey="&cmd.open_window.accesskey;"
|
||||
selectiontype="single"
|
||||
selection="link"/>
|
||||
<menuseparator id="placesContext_openSeparator"/>
|
||||
<menuitem id="placesContext_new:bookmark"
|
||||
command="placesCmd_new:bookmark"
|
||||
|
@ -129,11 +129,17 @@ function check_sidebar_tree_order(aExpectedRows) {
|
||||
var tree = sidebar.contentDocument.getElementById("historyTree");
|
||||
var treeView = tree.view;
|
||||
var rc = treeView.rowCount;
|
||||
is(rc, aExpectedRows, "All expected tree rows are present");
|
||||
var columns = tree.columns;
|
||||
is(columns.count, 1, "There should be only 1 column in the sidebar");
|
||||
var found = 0;
|
||||
for (var r = 0; r < rc; r++) {
|
||||
var node = treeView.nodeForTreeIndex(r);
|
||||
// We could inherit visits from previous tests, skip them since they are
|
||||
// not interesting for us.
|
||||
if (pages.indexOf(node.uri) == -1)
|
||||
continue;
|
||||
is(node.uri, pages[r], "Node is in correct position based on its visit date");
|
||||
found++;
|
||||
}
|
||||
ok(found, aExpectedRows, "Found all expected results");
|
||||
}
|
||||
|
@ -1015,12 +1015,12 @@ SessionStoreService.prototype = {
|
||||
// create a new tab
|
||||
let browser = aWindow.gBrowser;
|
||||
let tab = browser.addTab();
|
||||
|
||||
// restore the tab's position
|
||||
browser.moveTabTo(tab, closedTab.pos);
|
||||
|
||||
// restore tab content
|
||||
this.restoreHistoryPrecursor(aWindow, [tab], [closedTabState], 1, 0, 0);
|
||||
|
||||
// restore the tab's position
|
||||
browser.moveTabTo(tab, closedTab.pos);
|
||||
|
||||
// focus the tab's content area
|
||||
let content = browser.getBrowserForTab(tab).contentWindow;
|
||||
|
@ -114,6 +114,7 @@ _BROWSER_TEST_FILES = \
|
||||
browser_522545.js \
|
||||
browser_524745.js \
|
||||
browser_528776.js \
|
||||
browser_579879.js \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
@ -0,0 +1,21 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
var tab1 = gBrowser.addTab("data:text/plain,foo");
|
||||
gBrowser.pinTab(tab1);
|
||||
|
||||
tab1.linkedBrowser.addEventListener("load", function () {
|
||||
var tab2 = gBrowser.addTab();
|
||||
gBrowser.pinTab(tab2);
|
||||
|
||||
is(Array.indexOf(gBrowser.tabs, tab1), 0, "pinned tab 1 is at the first position");
|
||||
gBrowser.removeTab(tab1);
|
||||
tab1 = undoCloseTab();
|
||||
ok(tab1.pinned, "pinned tab 1 has been restored as a pinned tab");
|
||||
is(Array.indexOf(gBrowser.tabs, tab1), 0, "pinned tab 1 has been restored to the first position");
|
||||
|
||||
gBrowser.removeTab(tab1);
|
||||
gBrowser.removeTab(tab2);
|
||||
finish();
|
||||
}, true);
|
||||
}
|
@ -12,8 +12,6 @@
|
||||
<!ENTITY mainWindow.titlePrivateBrowsingSuffix "(Private Browsing)">
|
||||
|
||||
<!-- Tab context menu -->
|
||||
<!ENTITY newTab.label "New Tab">
|
||||
<!ENTITY newTab.accesskey "N">
|
||||
<!ENTITY reloadTab.label "Reload Tab">
|
||||
<!ENTITY reloadTab.accesskey "R">
|
||||
<!ENTITY reloadAllTabs.label "Reload All Tabs">
|
||||
@ -171,9 +169,9 @@
|
||||
<!ENTITY errorConsoleCmd.accesskey "C">
|
||||
<!ENTITY errorConsoleCmd.commandkey "j">
|
||||
|
||||
<!ENTITY hudConsoleCmd.label "Heads Up Display">
|
||||
<!ENTITY hudConsoleCmd.accesskey "U">
|
||||
<!ENTITY hudConsoleCmd.commandkey "k">
|
||||
<!ENTITY webConsoleCmd.label "Web Console">
|
||||
<!ENTITY webConsoleCmd.accesskey "W">
|
||||
<!ENTITY webConsoleCmd.commandkey "k">
|
||||
|
||||
<!ENTITY inspectMenu.label "Inspect">
|
||||
<!ENTITY inspectMenu.accesskey "T">
|
||||
@ -291,16 +289,16 @@
|
||||
<!ENTITY searchFocus.commandkey2 "e">
|
||||
<!ENTITY searchFocusUnix.commandkey "j">
|
||||
|
||||
<!ENTITY openLinkCmdInTab.label "Open Link in New Tab">
|
||||
<!ENTITY openLinkCmdInTab.accesskey "T">
|
||||
<!ENTITY openLinkCmd.label "Open Link in New Window">
|
||||
<!ENTITY openLinkCmd.accesskey "W">
|
||||
<!ENTITY openLinkCmdInCurrent.label "Open Link">
|
||||
<!ENTITY openLinkCmdInCurrent.accesskey "O">
|
||||
<!ENTITY openLinkCmdInTab.label "Open Link in New Tab">
|
||||
<!ENTITY openLinkCmdInTab.accesskey "T">
|
||||
<!ENTITY openFrameCmd.label "Open Frame in New Window">
|
||||
<!ENTITY openFrameCmd.accesskey "W">
|
||||
<!ENTITY openFrameCmdInTab.label "Open Frame in New Tab">
|
||||
<!ENTITY openFrameCmdInTab.accesskey "T">
|
||||
<!ENTITY openFrameCmd.label "Open Frame in New Window">
|
||||
<!ENTITY openFrameCmd.accesskey "W">
|
||||
<!ENTITY showOnlyThisFrameCmd.label "Show Only This Frame">
|
||||
<!ENTITY showOnlyThisFrameCmd.accesskey "S">
|
||||
<!ENTITY reloadCmd.commandkey "r">
|
||||
|
@ -2,8 +2,8 @@
|
||||
|
||||
<!ENTITY enter.label "Enter the web location (URL), or specify the local file you would like to open:">
|
||||
<!ENTITY chooseFile.label "Choose File…">
|
||||
<!ENTITY newWindow.label "New Window">
|
||||
<!ENTITY newTab.label "New Tab">
|
||||
<!ENTITY newWindow.label "New Window">
|
||||
<!ENTITY topTab.label "Current Tab">
|
||||
<!ENTITY caption.label "Open Web Location">
|
||||
<!ENTITY openWhere.label "Open in:">
|
||||
|
@ -1,7 +1,7 @@
|
||||
searchtip=Search using %S
|
||||
|
||||
cmd_clearHistory=Clear Search History
|
||||
cmd_clearHistory_accesskey=C
|
||||
cmd_clearHistory_accesskey=H
|
||||
|
||||
cmd_showSuggestions=Show Suggestions
|
||||
cmd_showSuggestions_accesskey=S
|
||||
|
@ -1259,15 +1259,6 @@ statusbarpanel#statusbar-display {
|
||||
-moz-image-region: rect(0, 144px, 16px, 128px);
|
||||
}
|
||||
|
||||
#context_newTab {
|
||||
list-style-image: url("chrome://browser/skin/Toolbar-small.png");
|
||||
-moz-image-region: rect(0px 64px 16px 48px);
|
||||
}
|
||||
|
||||
#context_newTab[disabled] {
|
||||
-moz-image-region: rect(16px 64px 32px 48px);
|
||||
}
|
||||
|
||||
#context_reloadTab {
|
||||
list-style-image: url("moz-icon://stock/gtk-refresh?size=menu");
|
||||
}
|
||||
|
@ -174,6 +174,12 @@ groupbox.treebox .groupbox-body {
|
||||
#imagetree {
|
||||
min-height: 10em;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#mediaSplitter {
|
||||
-moz-appearance: none;
|
||||
height: .8em;
|
||||
}
|
||||
|
||||
#mediaGrid {
|
||||
|
@ -122,6 +122,11 @@ groupbox.treebox .groupbox-body {
|
||||
/* Media Tab */
|
||||
#imagetree {
|
||||
min-height: 10em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#mediaSplitter {
|
||||
background: none;
|
||||
}
|
||||
|
||||
#mediaGrid {
|
||||
|
@ -39,9 +39,9 @@
|
||||
}
|
||||
|
||||
#toolbar-menubar:not(:-moz-lwtheme),
|
||||
#navigator-toolbox[tabsontop="true"] > #TabsToolbar:not(:-moz-lwtheme),
|
||||
#navigator-toolbox:not([tabsontop="true"]) > #nav-bar:not(:-moz-lwtheme),
|
||||
#navigator-toolbox:not([tabsontop="true"]) > #nav-bar + #customToolbars + #PersonalToolbar[collapsed="true"] + #TabsToolbar:last-child:not(:-moz-lwtheme) {
|
||||
#TabsToolbar[tabsontop="true"]:not(:-moz-lwtheme),
|
||||
#navigator-toolbox[tabsontop="false"] > #nav-bar:not(:-moz-lwtheme),
|
||||
#nav-bar + #customToolbars + #PersonalToolbar[collapsed="true"] + #TabsToolbar[tabsontop="false"]:last-child:not(:-moz-lwtheme) {
|
||||
background: transparent !important;
|
||||
color: black;
|
||||
text-shadow: 0 0 .7em white, 0 0 .7em white, 0 1px 0 rgba(255,255,255,.4);
|
||||
@ -54,9 +54,9 @@
|
||||
|
||||
/* Make the window draggable by glassed toolbars (bug 555081) */
|
||||
#toolbar-menubar:not([autohide="true"]),
|
||||
#navigator-toolbox[tabsontop="true"] > #TabsToolbar,
|
||||
#navigator-toolbox:not([tabsontop="true"]) > #nav-bar,
|
||||
#navigator-toolbox:not([tabsontop="true"]) > #nav-bar + #customToolbars + #PersonalToolbar[collapsed="true"] + #TabsToolbar:last-child,
|
||||
#TabsToolbar[tabsontop="true"],
|
||||
#navigator-toolbox[tabsontop="false"] > #nav-bar,
|
||||
#nav-bar + #customToolbars + #PersonalToolbar[collapsed="true"] + #TabsToolbar[tabsontop="false"]:last-child,
|
||||
#navigator-toolbox > toolbar:not(#toolbar-menubar):-moz-lwtheme {
|
||||
-moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
|
||||
}
|
||||
|
@ -80,11 +80,12 @@
|
||||
padding-bottom: 1px;
|
||||
}
|
||||
|
||||
#nav-bar:not(:-moz-lwtheme) {
|
||||
#nav-bar:not(:-moz-lwtheme),
|
||||
#navigator-toolbox[tabsontop="true"] > #nav-bar {
|
||||
background-image: -moz-linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
|
||||
}
|
||||
|
||||
#navigator-toolbox:not([tabsontop="true"]) > #toolbar-menubar:not(:-moz-lwtheme) {
|
||||
#navigator-toolbox[tabsontop="false"] > #toolbar-menubar:not(:-moz-lwtheme) {
|
||||
background-image: -moz-linear-gradient(@toolbarHighlight@, @toolbarHighlight@);
|
||||
}
|
||||
|
||||
@ -1092,11 +1093,11 @@ richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-i
|
||||
#TabsToolbar {
|
||||
min-height: 0;
|
||||
padding: 0;
|
||||
-moz-box-shadow: 0 -1px ThreeDShadow inset;
|
||||
}
|
||||
|
||||
#TabsToolbar:not(:-moz-lwtheme),
|
||||
#navigator-toolbox:not([tabsontop="true"]) > #TabsToolbar {
|
||||
#TabsToolbar[tabsontop="false"] {
|
||||
-moz-box-shadow: 0 -1px ThreeDShadow inset;
|
||||
background-image: -moz-linear-gradient(transparent, transparent 10%,
|
||||
rgba(0,0,0,.03) 50%, rgba(0,0,0,.1) 90%, rgba(0,0,0,.2));
|
||||
}
|
||||
@ -1145,21 +1146,26 @@ richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-i
|
||||
.tabbrowser-tab:-moz-lwtheme-darktext,
|
||||
.tabs-newtab-button:-moz-lwtheme-darktext {
|
||||
background-image: -moz-linear-gradient(left, transparent, transparent 1px,
|
||||
rgba(255,255,255,.4) 1px, rgba(255,255,255,.4));
|
||||
rgba(60%,60%,60%,.5) 1px, rgba(60%,60%,60%,.5));
|
||||
}
|
||||
|
||||
.tabbrowser-tab:-moz-lwtheme-darktext:not([selected="true"]):hover,
|
||||
.tabs-newtab-button:-moz-lwtheme-darktext:hover {
|
||||
background-image: -moz-linear-gradient(left, transparent, transparent 1px,
|
||||
rgba(255,255,255,.6) 1px, rgba(255,255,255,.6));
|
||||
rgba(80%,80%,80%,.5) 1px, rgba(80%,80%,80%,.5));
|
||||
}
|
||||
|
||||
.tabbrowser-tab[selected="true"] {
|
||||
.tabbrowser-tab[selected="true"]:-moz-lwtheme {
|
||||
background-image: -moz-linear-gradient(left, transparent, transparent 1px,
|
||||
@toolbarHighlight@ 1px, @toolbarHighlight@);
|
||||
}
|
||||
|
||||
#tabbrowser-tabs[tabsontop="false"] > .tabbrowser-tab[selected="true"]:not(:-moz-lwtheme) {
|
||||
background-image: -moz-linear-gradient(left, transparent, transparent 1px, white 1px, white);
|
||||
color: black;
|
||||
}
|
||||
|
||||
#navigator-toolbox[tabsontop="true"] > #TabsToolbar > #tabbrowser-tabs > .tabbrowser-tab[selected="true"]:not(:-moz-lwtheme) {
|
||||
#tabbrowser-tabs[tabsontop="true"] > .tabbrowser-tab[selected="true"]:not(:-moz-lwtheme) {
|
||||
background-image: -moz-radial-gradient(center top, white, rgba(255,255,255,0) 60%),
|
||||
-moz-linear-gradient(left, transparent, transparent 1px,
|
||||
@toolbarHighlight@ 1px, @toolbarHighlight@),
|
||||
@ -1170,11 +1176,7 @@ richlistitem[type="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-i
|
||||
color: -moz-dialogText;
|
||||
}
|
||||
|
||||
.tabbrowser-tab:-moz-lwtheme[selected="true"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.tabbrowser-tab:-moz-lwtheme:not([selected="true"]) {
|
||||
.tabbrowser-tab:-moz-lwtheme {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
|
@ -188,6 +188,13 @@ groupbox tree {
|
||||
/* Media Tab */
|
||||
#imagetree {
|
||||
min-height: 10em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#mediaSplitter {
|
||||
border-style: none;
|
||||
background: none;
|
||||
height: .8em;
|
||||
}
|
||||
|
||||
#mediaGrid {
|
||||
|
@ -1401,12 +1401,15 @@ host_%.$(OBJ_SUFFIX): %.mm $(GLOBAL_DEPS)
|
||||
@$(MAKE_DEPS_AUTO_CC)
|
||||
$(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(_VPATH_SRCS)
|
||||
|
||||
# DEFINES and ACDEFINES are needed here to enable conditional compilation of Q_OBJECTs:
|
||||
# 'moc' only knows about #defines it gets on the command line (-D...), not in
|
||||
# included headers like mozilla-config.h
|
||||
moc_%.cpp: %.h $(GLOBAL_DEPS)
|
||||
$(MOC) $< $(OUTOPTION)$@
|
||||
$(MOC) $(DEFINES) $(ACDEFINES) $< $(OUTOPTION)$@
|
||||
|
||||
moc_%.cc: %.cc $(GLOBAL_DEPS)
|
||||
$(REPORT_BUILD)
|
||||
$(ELOG) $(MOC) $(_VPATH_SRCS:.cc=.h) $(OUTOPTION)$@
|
||||
$(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $(_VPATH_SRCS:.cc=.h) $(OUTOPTION)$@
|
||||
|
||||
ifdef ASFILES
|
||||
# The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept
|
||||
|
@ -132,7 +132,7 @@ GCONF_VERSION=1.2.1
|
||||
GIO_VERSION=2.0
|
||||
STARTUP_NOTIFICATION_VERSION=0.8
|
||||
DBUS_VERSION=0.60
|
||||
SQLITE_VERSION=3.6.23.1
|
||||
SQLITE_VERSION=3.7.0
|
||||
LIBNOTIFY_VERSION=0.4
|
||||
|
||||
MSMANIFEST_TOOL=
|
||||
@ -905,7 +905,7 @@ EOF
|
||||
AC_MSG_RESULT("yes")
|
||||
else
|
||||
AC_MSG_RESULT("no")
|
||||
AC_MSG_ERROR([You are targeting Windows version 0x$MOZ_WINSDK_TARGETVER, but your SDK only supports up to version $MOZ_WINSDK_MAXVER. Install and use an updated SDK, or target a lower version using --with-windows-version. See https://developer.mozilla.org/En/Windows_SDK_versions for more details on fixing this.])
|
||||
AC_MSG_ERROR([You are targeting Windows version 0x$MOZ_WINSDK_TARGETVER, but your SDK only supports up to version $MOZ_WINSDK_MAXVER. Install and use an updated SDK, or target a lower version using --with-windows-version. Alternatively, try running the Windows SDK Configuration Tool and selecting a newer SDK. See https://developer.mozilla.org/En/Windows_SDK_versions for more details on fixing this.])
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(MOZ_WINSDK_TARGETVER,0x$MOZ_WINSDK_TARGETVER)
|
||||
|
@ -84,7 +84,7 @@ class Element : public nsIContent
|
||||
{
|
||||
public:
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
Element(nsINodeInfo* aNodeInfo) : nsIContent(aNodeInfo) {}
|
||||
Element(already_AddRefed<nsINodeInfo> aNodeInfo) : nsIContent(aNodeInfo) {}
|
||||
#endif // MOZILLA_INTERNAL_API
|
||||
};
|
||||
|
||||
|
@ -108,6 +108,7 @@ XPIDLSRCS = \
|
||||
nsIDOMParser.idl \
|
||||
nsIDOMSerializer.idl \
|
||||
nsISelection2.idl \
|
||||
nsISelection3.idl \
|
||||
nsISelectionController.idl \
|
||||
nsISelectionDisplay.idl \
|
||||
nsISelectionListener.idl \
|
||||
|
@ -66,10 +66,10 @@ class nsGenericHTMLElement;
|
||||
|
||||
nsresult
|
||||
NS_NewElement(nsIContent** aResult, PRInt32 aElementType,
|
||||
nsINodeInfo* aNodeInfo, PRUint32 aFromParser);
|
||||
already_AddRefed<nsINodeInfo> aNodeInfo, PRUint32 aFromParser);
|
||||
|
||||
nsresult
|
||||
NS_NewXMLElement(nsIContent** aResult, nsINodeInfo* aNodeInfo);
|
||||
NS_NewXMLElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
|
||||
/**
|
||||
* aNodeInfoManager must not be null.
|
||||
@ -108,36 +108,39 @@ NS_NewXMLCDATASection(nsIContent** aInstancePtrResult,
|
||||
nsNodeInfoManager *aNodeInfoManager);
|
||||
|
||||
nsresult
|
||||
NS_NewHTMLElement(nsIContent** aResult, nsINodeInfo *aNodeInfo,
|
||||
NS_NewHTMLElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
PRUint32 aFromParser);
|
||||
|
||||
// First argument should be nsHTMLTag, but that adds dependency to parser
|
||||
// for a bunch of files.
|
||||
already_AddRefed<nsGenericHTMLElement>
|
||||
CreateHTMLElement(PRUint32 aNodeType, nsINodeInfo *aNodeInfo,
|
||||
CreateHTMLElement(PRUint32 aNodeType, already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
PRUint32 aFromParser);
|
||||
|
||||
#ifdef MOZ_MATHML
|
||||
nsresult
|
||||
NS_NewMathMLElement(nsIContent** aResult, nsINodeInfo* aNodeInfo);
|
||||
NS_NewMathMLElement(nsIContent** aResult,
|
||||
already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
nsresult
|
||||
NS_NewXULElement(nsIContent** aResult, nsINodeInfo* aNodeInfo);
|
||||
NS_NewXULElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_SVG
|
||||
nsresult
|
||||
NS_NewSVGElement(nsIContent** aResult, nsINodeInfo* aNodeInfo,
|
||||
NS_NewSVGElement(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
PRUint32 aFromParser);
|
||||
#endif
|
||||
|
||||
nsresult
|
||||
NS_NewGenConImageContent(nsIContent** aResult, nsINodeInfo* aNodeInfo,
|
||||
NS_NewGenConImageContent(nsIContent** aResult,
|
||||
already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
imgIRequest* aImageRequest);
|
||||
|
||||
nsresult
|
||||
NS_NewXMLEventsElement(nsIContent** aResult, nsINodeInfo* aNodeInfo);
|
||||
NS_NewXMLEventsElement(nsIContent** aResult,
|
||||
already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
|
||||
#endif // nsContentCreatorFunctions_h__
|
||||
|
@ -1573,17 +1573,33 @@ public:
|
||||
// If non-null aHolder will keep the jsval alive
|
||||
// while there's a ref to it
|
||||
nsIXPConnectJSObjectHolder** aHolder = nsnull,
|
||||
PRBool aAllowWrapping = PR_FALSE);
|
||||
PRBool aAllowWrapping = PR_FALSE)
|
||||
{
|
||||
return WrapNative(cx, scope, native, nsnull, aIID, vp, aHolder,
|
||||
aAllowWrapping);
|
||||
}
|
||||
|
||||
// Same as the WrapNative above, but use this one if aIID is nsISupports' IID.
|
||||
static nsresult WrapNative(JSContext *cx, JSObject *scope,
|
||||
nsISupports *native, jsval *vp,
|
||||
nsISupports *native, jsval *vp,
|
||||
// If non-null aHolder will keep the jsval alive
|
||||
// while there's a ref to it
|
||||
nsIXPConnectJSObjectHolder** aHolder = nsnull,
|
||||
PRBool aAllowWrapping = PR_FALSE)
|
||||
{
|
||||
return WrapNative(cx, scope, native, nsnull, vp, aHolder, aAllowWrapping);
|
||||
return WrapNative(cx, scope, native, nsnull, nsnull, vp, aHolder,
|
||||
aAllowWrapping);
|
||||
}
|
||||
static nsresult WrapNative(JSContext *cx, JSObject *scope,
|
||||
nsISupports *native, nsWrapperCache *cache,
|
||||
jsval *vp,
|
||||
// If non-null aHolder will keep the jsval alive
|
||||
// while there's a ref to it
|
||||
nsIXPConnectJSObjectHolder** aHolder = nsnull,
|
||||
PRBool aAllowWrapping = PR_FALSE)
|
||||
{
|
||||
return WrapNative(cx, scope, native, cache, nsnull, vp, aHolder,
|
||||
aAllowWrapping);
|
||||
}
|
||||
|
||||
static void StripNullChars(const nsAString& aInStr, nsAString& aOutStr);
|
||||
@ -1674,6 +1690,12 @@ private:
|
||||
static PRBool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
|
||||
nsIPrincipal* aPrincipal);
|
||||
|
||||
static nsresult WrapNative(JSContext *cx, JSObject *scope,
|
||||
nsISupports *native, nsWrapperCache *cache,
|
||||
const nsIID* aIID, jsval *vp,
|
||||
nsIXPConnectJSObjectHolder** aHolder,
|
||||
PRBool aAllowWrapping);
|
||||
|
||||
static nsIDOMScriptObjectFactory *sDOMScriptObjectFactory;
|
||||
|
||||
static nsIXPConnect *sXPConnect;
|
||||
|
@ -76,7 +76,7 @@ public:
|
||||
|
||||
protected:
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
nsIAttribute(nsDOMAttributeMap *aAttrMap, nsINodeInfo *aNodeInfo)
|
||||
nsIAttribute(nsDOMAttributeMap *aAttrMap, already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsINode(aNodeInfo), mAttrMap(aAttrMap)
|
||||
{
|
||||
}
|
||||
|
@ -71,8 +71,8 @@ enum nsLinkState {
|
||||
|
||||
// IID for the nsIContent interface
|
||||
#define NS_ICONTENT_IID \
|
||||
{ 0x1450010b, 0xcdca, 0x451c, \
|
||||
{ 0xba, 0xdc, 0x07, 0x90, 0x89, 0x7b, 0xce, 0xb8 } }
|
||||
{ 0xdd254504, 0xe273, 0x4923, \
|
||||
{ 0x9e, 0xc1, 0xd8, 0x42, 0x1a, 0x66, 0x35, 0xf1 } }
|
||||
|
||||
/**
|
||||
* A node of content in a document's content model. This interface
|
||||
@ -84,11 +84,11 @@ public:
|
||||
// If you're using the external API, the only thing you can know about
|
||||
// nsIContent is that it exists with an IID
|
||||
|
||||
nsIContent(nsINodeInfo *aNodeInfo)
|
||||
nsIContent(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsINode(aNodeInfo),
|
||||
mPrimaryFrame(nsnull)
|
||||
{
|
||||
NS_ASSERTION(aNodeInfo,
|
||||
NS_ASSERTION(mNodeInfo,
|
||||
"No nsINodeInfo passed to nsIContent, PREPARE TO CRASH!!!");
|
||||
}
|
||||
#endif // MOZILLA_INTERNAL_API
|
||||
@ -928,6 +928,19 @@ public:
|
||||
|
||||
virtual PRBool IsEqualNode(nsINode* aOther);
|
||||
|
||||
/**
|
||||
* If this content has independent selection, e.g., if this is input field
|
||||
* or textarea, this return TRUE. Otherwise, false.
|
||||
*/
|
||||
PRBool HasIndependentSelection();
|
||||
|
||||
/**
|
||||
* If the content is a part of HTML editor, this returns editing
|
||||
* host content. When the content is in designMode, this returns its body
|
||||
* element. Also, when the content isn't editable, this returns null.
|
||||
*/
|
||||
nsIContent* GetEditingHost();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Hook for implementing GetID. This is guaranteed to only be
|
||||
|
@ -118,8 +118,8 @@ class Element;
|
||||
|
||||
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x19df0b2c, 0xf89a, 0x4c83, \
|
||||
{ 0x82, 0x29, 0x3a, 0xe0, 0xb6, 0x42, 0x71, 0x9c } }
|
||||
{ 0xda512fdc, 0x2d83, 0x44b0, \
|
||||
{ 0xb0, 0x99, 0x00, 0xc6, 0xbb, 0x72, 0x39, 0xed } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
@ -830,7 +830,7 @@ public:
|
||||
* for that document (currently XHTML in HTML documents and XUL in XUL
|
||||
* documents), otherwise we use the type specified by the namespace ID.
|
||||
*/
|
||||
virtual nsresult CreateElem(nsIAtom *aName, nsIAtom *aPrefix,
|
||||
virtual nsresult CreateElem(const nsAString& aName, nsIAtom *aPrefix,
|
||||
PRInt32 aNamespaceID,
|
||||
PRBool aDocumentDefaultType,
|
||||
nsIContent** aResult) = 0;
|
||||
|
@ -45,8 +45,8 @@ class nsIDocument;
|
||||
class nsINode;
|
||||
|
||||
#define NS_IMUTATION_OBSERVER_IID \
|
||||
{0x365d600b, 0x868a, 0x452a, \
|
||||
{0x8d, 0xe8, 0xf4, 0x6f, 0xad, 0x8f, 0xee, 0x53 } }
|
||||
{ 0x85eea794, 0xed8e, 0x4e1b, \
|
||||
{ 0xa1, 0x28, 0xd0, 0x93, 0x00, 0xae, 0x51, 0xaa } }
|
||||
|
||||
/**
|
||||
* Information details about a characterdata change. Basically, we
|
||||
@ -117,6 +117,12 @@ public:
|
||||
* @param aDocument The owner-document of aContent. Can be null.
|
||||
* @param aContent The piece of content that changed. Is never null.
|
||||
* @param aInfo The structure with information details about the change.
|
||||
*
|
||||
* @note Callers of this method might not hold a strong reference to the
|
||||
* observer. The observer is responsible for making sure it stays
|
||||
* alive for the duration of the call as needed. The observer may
|
||||
* assume that this call will happen when there are script blockers on
|
||||
* the stack.
|
||||
*/
|
||||
virtual void CharacterDataWillChange(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
@ -133,6 +139,12 @@ public:
|
||||
* @param aDocument The owner-document of aContent. Can be null.
|
||||
* @param aContent The piece of content that changed. Is never null.
|
||||
* @param aInfo The structure with information details about the change.
|
||||
*
|
||||
* @note Callers of this method might not hold a strong reference to the
|
||||
* observer. The observer is responsible for making sure it stays
|
||||
* alive for the duration of the call as needed. The observer may
|
||||
* assume that this call will happen when there are script blockers on
|
||||
* the stack.
|
||||
*/
|
||||
virtual void CharacterDataChanged(nsIDocument *aDocument,
|
||||
nsIContent* aContent,
|
||||
@ -152,6 +164,12 @@ public:
|
||||
* @param aModType Whether or not the attribute will be added, changed, or
|
||||
* removed. The constants are defined in
|
||||
* nsIDOMMutationEvent.h.
|
||||
*
|
||||
* @note Callers of this method might not hold a strong reference to the
|
||||
* observer. The observer is responsible for making sure it stays
|
||||
* alive for the duration of the call as needed. The observer may
|
||||
* assume that this call will happen when there are script blockers on
|
||||
* the stack.
|
||||
*/
|
||||
virtual void AttributeWillChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
@ -169,6 +187,12 @@ public:
|
||||
* @param aModType Whether or not the attribute was added, changed, or
|
||||
* removed. The constants are defined in
|
||||
* nsIDOMMutationEvent.h.
|
||||
*
|
||||
* @note Callers of this method might not hold a strong reference to the
|
||||
* observer. The observer is responsible for making sure it stays
|
||||
* alive for the duration of the call as needed. The observer may
|
||||
* assume that this call will happen when there are script blockers on
|
||||
* the stack.
|
||||
*/
|
||||
virtual void AttributeChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
@ -186,6 +210,12 @@ public:
|
||||
* @param aFirstNewContent the node at aIndexInContainer in aContainer.
|
||||
* @param aNewIndexInContainer the index in the container of the first
|
||||
* new child
|
||||
*
|
||||
* @note Callers of this method might not hold a strong reference to the
|
||||
* observer. The observer is responsible for making sure it stays
|
||||
* alive for the duration of the call as needed. The observer may
|
||||
* assume that this call will happen when there are script blockers on
|
||||
* the stack.
|
||||
*/
|
||||
virtual void ContentAppended(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
@ -204,6 +234,12 @@ public:
|
||||
* aDocument
|
||||
* @param aChild The newly inserted child.
|
||||
* @param aIndexInContainer The index in the container of the new child.
|
||||
*
|
||||
* @note Callers of this method might not hold a strong reference to the
|
||||
* observer. The observer is responsible for making sure it stays
|
||||
* alive for the duration of the call as needed. The observer may
|
||||
* assume that this call will happen when there are script blockers on
|
||||
* the stack.
|
||||
*/
|
||||
virtual void ContentInserted(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
@ -223,11 +259,20 @@ public:
|
||||
* @param aChild The child that was removed.
|
||||
* @param aIndexInContainer The index in the container which the child used
|
||||
* to have.
|
||||
* @param aPreviousSibling The previous sibling to the child that was removed.
|
||||
* Can be null if there was no previous sibling.
|
||||
*
|
||||
* @note Callers of this method might not hold a strong reference to the
|
||||
* observer. The observer is responsible for making sure it stays
|
||||
* alive for the duration of the call as needed. The observer may
|
||||
* assume that this call will happen when there are script blockers on
|
||||
* the stack.
|
||||
*/
|
||||
virtual void ContentRemoved(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer) = 0;
|
||||
PRInt32 aIndexInContainer,
|
||||
nsIContent* aPreviousSibling) = 0;
|
||||
|
||||
/**
|
||||
* The node is in the process of being destroyed. Calling QI on the node is
|
||||
@ -241,6 +286,10 @@ public:
|
||||
* removed from the observed node, use the ContentRemoved notification.
|
||||
*
|
||||
* @param aNode The node being destroyed.
|
||||
*
|
||||
* @note Callers of this method might not hold a strong reference to
|
||||
* the observer. The observer is responsible for making sure it
|
||||
* stays alive for the duration of the call as needed.
|
||||
*/
|
||||
virtual void NodeWillBeDestroyed(const nsINode *aNode) = 0;
|
||||
|
||||
@ -254,6 +303,10 @@ public:
|
||||
* parent chain changed.
|
||||
*
|
||||
* @param aContent The piece of content that had its parent changed.
|
||||
*
|
||||
* @note Callers of this method might not hold a strong reference to
|
||||
* the observer. The observer is responsible for making sure it
|
||||
* stays alive for the duration of the call as needed.
|
||||
*/
|
||||
|
||||
virtual void ParentChainChanged(nsIContent *aContent) = 0;
|
||||
@ -301,7 +354,8 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIMutationObserver, NS_IMUTATION_OBSERVER_IID)
|
||||
virtual void ContentRemoved(nsIDocument* aDocument, \
|
||||
nsIContent* aContainer, \
|
||||
nsIContent* aChild, \
|
||||
PRInt32 aIndexInContainer);
|
||||
PRInt32 aIndexInContainer, \
|
||||
nsIContent* aPreviousSibling);
|
||||
|
||||
#define NS_DECL_NSIMUTATIONOBSERVER_NODEWILLBEDESTROYED \
|
||||
virtual void NodeWillBeDestroyed(const nsINode* aNode);
|
||||
@ -373,7 +427,8 @@ void \
|
||||
_class::ContentRemoved(nsIDocument* aDocument, \
|
||||
nsIContent* aContainer, \
|
||||
nsIContent* aChild, \
|
||||
PRInt32 aIndexInContainer) \
|
||||
PRInt32 aIndexInContainer, \
|
||||
nsIContent* aPreviousSibling) \
|
||||
{ \
|
||||
} \
|
||||
void \
|
||||
|
@ -69,6 +69,7 @@ class nsIEditor;
|
||||
class nsIVariant;
|
||||
class nsIDOMUserDataHandler;
|
||||
class nsAttrAndChildArray;
|
||||
class nsXPCClassInfo;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -293,8 +294,8 @@ private:
|
||||
|
||||
// IID for the nsINode interface
|
||||
#define NS_INODE_IID \
|
||||
{ 0x58695b2f, 0x39bd, 0x434d, \
|
||||
{ 0xa2, 0x0b, 0xde, 0xd3, 0xa8, 0xa0, 0xb6, 0x95 } }
|
||||
{ 0x2a8dc794, 0x9178, 0x400e, \
|
||||
{ 0x81, 0xff, 0x55, 0x30, 0x30, 0xb6, 0x74, 0x3b } }
|
||||
|
||||
/**
|
||||
* An internal interface that abstracts some DOMNode-related parts that both
|
||||
@ -313,15 +314,16 @@ public:
|
||||
friend class nsAttrAndChildArray;
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
nsINode(nsINodeInfo* aNodeInfo)
|
||||
: mNodeInfo(aNodeInfo),
|
||||
mParentPtrBits(0),
|
||||
mFlagsOrSlots(NODE_DOESNT_HAVE_SLOTS),
|
||||
mNextSibling(nsnull),
|
||||
mPreviousSibling(nsnull),
|
||||
mFirstChild(nsnull)
|
||||
nsINode(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: mNodeInfo(aNodeInfo),
|
||||
mParentPtrBits(0),
|
||||
mFlagsOrSlots(NODE_DOESNT_HAVE_SLOTS),
|
||||
mNextSibling(nsnull),
|
||||
mPreviousSibling(nsnull),
|
||||
mFirstChild(nsnull)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
virtual ~nsINode();
|
||||
@ -1145,6 +1147,8 @@ public:
|
||||
NS_NOTREACHED("How did we get here?");
|
||||
}
|
||||
|
||||
// Optimized way to get classinfo. May return null.
|
||||
virtual nsXPCClassInfo* GetClassInfo() = 0;
|
||||
protected:
|
||||
|
||||
// Override this function to create a custom slots class.
|
||||
|
@ -310,14 +310,26 @@ protected:
|
||||
class nsNodeInfoInner
|
||||
{
|
||||
public:
|
||||
nsNodeInfoInner()
|
||||
: mName(nsnull), mPrefix(nsnull), mNamespaceID(kNameSpaceID_Unknown),
|
||||
mNameString(nsnull)
|
||||
{
|
||||
}
|
||||
nsNodeInfoInner(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID)
|
||||
: mName(aName), mPrefix(aPrefix), mNamespaceID(aNamespaceID)
|
||||
: mName(aName), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
|
||||
mNameString(nsnull)
|
||||
{
|
||||
}
|
||||
nsNodeInfoInner(const nsAString& aTmpName, nsIAtom *aPrefix, PRInt32 aNamespaceID)
|
||||
: mName(nsnull), mPrefix(aPrefix), mNamespaceID(aNamespaceID),
|
||||
mNameString(&aTmpName)
|
||||
{
|
||||
}
|
||||
|
||||
nsIAtom* mName;
|
||||
nsIAtom* mPrefix;
|
||||
PRInt32 mNamespaceID;
|
||||
const nsAString* mNameString;
|
||||
};
|
||||
|
||||
// nsNodeInfoManager needs to pass mInner to the hash table.
|
||||
|
@ -46,10 +46,10 @@ interface nsIDOMRange;
|
||||
* Interface for manipulating and querying the current selected range
|
||||
* of nodes within the document.
|
||||
*
|
||||
* @version 1.1
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
[scriptable, uuid(24bb8c1c-407c-4a97-b652-af767d847716)]
|
||||
[scriptable, uuid(B2C7ED59-8634-4352-9E37-5484C8B6E4E1)]
|
||||
interface nsISelection : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -154,27 +154,6 @@ interface nsISelection : nsISupports
|
||||
*/
|
||||
void deleteFromDocument();
|
||||
|
||||
/**
|
||||
* Modifies the selection. Note that the parameters are case-insensitive.
|
||||
*
|
||||
* @param alter can be one of { "move", "extend" }
|
||||
* - "move" collapses the selection to the end of the selection and
|
||||
* applies the movement direction/granularity to the collapsed
|
||||
* selection.
|
||||
* - "extend" leaves the start of the selection unchanged, and applies
|
||||
* movement direction/granularity to the end of the selection.
|
||||
* @param direction can be one of { "forward", "backward", "left", "right" }
|
||||
* @param granularity can be one of { "character", "word",
|
||||
* "line", "lineboundary" }
|
||||
*
|
||||
* @returns NS_ERROR_NOT_IMPLEMENTED if the granularity is "sentence",
|
||||
* "sentenceboundary", "paragraph", "paragraphboundary", or
|
||||
* "documentboundary". Returns NS_ERROR_INVALID_ARG if alter, direction,
|
||||
* or granularity has an unrecognized value.
|
||||
*/
|
||||
void modify(in DOMString alter, in DOMString direction,
|
||||
in DOMString granularity);
|
||||
|
||||
/**
|
||||
* Modifies the cursor Bidi level after a change in keyboard direction
|
||||
* @param langRTL is PR_TRUE if the new language is right-to-left or
|
||||
|
65
content/base/public/nsISelection3.idl
Normal file
65
content/base/public/nsISelection3.idl
Normal file
@ -0,0 +1,65 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* ***** 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 Selection code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2010
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Justin Lebar <justin.lebar@gmail.com>
|
||||
*
|
||||
* 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 "nsISupports.idl"
|
||||
|
||||
[scriptable, uuid(94ac0cb4-95b4-11df-8e13-0026b9792740)]
|
||||
interface nsISelection3 : nsISupports
|
||||
{
|
||||
/**
|
||||
* Modifies the selection. Note that the parameters are case-insensitive.
|
||||
*
|
||||
* @param alter can be one of { "move", "extend" }
|
||||
* - "move" collapses the selection to the end of the selection and
|
||||
* applies the movement direction/granularity to the collapsed
|
||||
* selection.
|
||||
* - "extend" leaves the start of the selection unchanged, and applies
|
||||
* movement direction/granularity to the end of the selection.
|
||||
* @param direction can be one of { "forward", "backward", "left", "right" }
|
||||
* @param granularity can be one of { "character", "word",
|
||||
* "line", "lineboundary" }
|
||||
*
|
||||
* @returns NS_ERROR_NOT_IMPLEMENTED if the granularity is "sentence",
|
||||
* "sentenceboundary", "paragraph", "paragraphboundary", or
|
||||
* "documentboundary". Returns NS_ERROR_INVALID_ARG if alter, direction,
|
||||
* or granularity has an unrecognized value.
|
||||
*/
|
||||
void modify(in DOMString alter, in DOMString direction,
|
||||
in DOMString granularity);
|
||||
|
||||
};
|
@ -48,7 +48,7 @@ class nsCommentNode : public nsGenericDOMDataNode,
|
||||
public nsIDOMComment
|
||||
{
|
||||
public:
|
||||
nsCommentNode(nsINodeInfo *aNodeInfo);
|
||||
nsCommentNode(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
virtual ~nsCommentNode();
|
||||
|
||||
// nsISupports
|
||||
@ -66,6 +66,7 @@ public:
|
||||
// nsIContent
|
||||
virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
|
||||
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
#ifdef DEBUG
|
||||
virtual void List(FILE* out, PRInt32 aIndent) const;
|
||||
virtual void DumpContent(FILE* out = stdout, PRInt32 aIndent = 0,
|
||||
@ -87,7 +88,7 @@ NS_NewCommentNode(nsIContent** aInstancePtrResult,
|
||||
nsCOMPtr<nsINodeInfo> ni = aNodeInfoManager->GetCommentNodeInfo();
|
||||
NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsCommentNode *instance = new nsCommentNode(ni);
|
||||
nsCommentNode *instance = new nsCommentNode(ni.forget());
|
||||
if (!instance) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -97,7 +98,7 @@ NS_NewCommentNode(nsIContent** aInstancePtrResult,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCommentNode::nsCommentNode(nsINodeInfo *aNodeInfo)
|
||||
nsCommentNode::nsCommentNode(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsGenericDOMDataNode(aNodeInfo)
|
||||
{
|
||||
}
|
||||
@ -106,7 +107,7 @@ nsCommentNode::~nsCommentNode()
|
||||
{
|
||||
}
|
||||
|
||||
DOMCI_DATA(Comment, nsCommentNode)
|
||||
DOMCI_NODE_DATA(Comment, nsCommentNode)
|
||||
|
||||
// QueryInterface implementation for nsCommentNode
|
||||
NS_INTERFACE_TABLE_HEAD(nsCommentNode)
|
||||
@ -155,7 +156,8 @@ nsCommentNode::GetNodeType(PRUint16* aNodeType)
|
||||
nsGenericDOMDataNode*
|
||||
nsCommentNode::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
|
||||
{
|
||||
nsCommentNode *it = new nsCommentNode(aNodeInfo);
|
||||
nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
|
||||
nsCommentNode *it = new nsCommentNode(ni.forget());
|
||||
if (it && aCloneText) {
|
||||
it->mText = mText;
|
||||
}
|
||||
|
@ -586,7 +586,7 @@ nsContentList::GetNodeAt(PRUint32 aIndex)
|
||||
return Item(aIndex, PR_TRUE);
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
nsIContent*
|
||||
nsContentList::GetNodeAt(PRUint32 aIndex, nsresult* aResult)
|
||||
{
|
||||
*aResult = NS_OK;
|
||||
@ -594,10 +594,14 @@ nsContentList::GetNodeAt(PRUint32 aIndex, nsresult* aResult)
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
nsContentList::GetNamedItem(const nsAString& aName, nsresult* aResult)
|
||||
nsContentList::GetNamedItem(const nsAString& aName, nsWrapperCache **aCache,
|
||||
nsresult* aResult)
|
||||
{
|
||||
*aResult = NS_OK;
|
||||
return NamedItem(aName, PR_TRUE);
|
||||
|
||||
nsIContent *item;
|
||||
*aCache = item = NamedItem(aName, PR_TRUE);
|
||||
return item;
|
||||
}
|
||||
|
||||
void
|
||||
@ -750,7 +754,8 @@ void
|
||||
nsContentList::ContentRemoved(nsIDocument *aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
PRInt32 aIndexInContainer,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
// Note that aContainer can be null here if we are removing from
|
||||
// the document itself; any attempted optimizations to this method
|
||||
|
@ -269,8 +269,10 @@ public:
|
||||
virtual PRInt32 IndexOf(nsIContent* aContent);
|
||||
|
||||
// nsIHTMLCollection
|
||||
virtual nsISupports* GetNodeAt(PRUint32 aIndex, nsresult* aResult);
|
||||
virtual nsISupports* GetNamedItem(const nsAString& aName, nsresult* aResult);
|
||||
virtual nsIContent* GetNodeAt(PRUint32 aIndex, nsresult* aResult);
|
||||
virtual nsISupports* GetNamedItem(const nsAString& aName,
|
||||
nsWrapperCache** aCache,
|
||||
nsresult* aResult);
|
||||
|
||||
// nsContentList public methods
|
||||
NS_HIDDEN_(nsINode*) GetParentObject() { return mRootNode; }
|
||||
|
@ -1600,12 +1600,10 @@ nsContentSink::DropParserAndPerfHint(void)
|
||||
// Do this hack to make sure that the parser
|
||||
// doesn't get destroyed, accidently, before
|
||||
// the circularity, between sink & parser, is
|
||||
// actually borken.
|
||||
nsCOMPtr<nsIParser> kungFuDeathGrip(mParser);
|
||||
|
||||
// actually broken.
|
||||
// Drop our reference to the parser to get rid of a circular
|
||||
// reference.
|
||||
mParser = nsnull;
|
||||
nsCOMPtr<nsIParser> kungFuDeathGrip(mParser.forget());
|
||||
|
||||
if (mDynamicLowerValue) {
|
||||
// Reset the performance hint which was set to FALSE
|
||||
|
@ -3793,15 +3793,16 @@ nsContentUtils::CreateContextualFragment(nsINode* aContextNode,
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> fragment = do_QueryInterface(frag);
|
||||
if (contextAsContent) {
|
||||
parser->ParseFragment(aFragment,
|
||||
frag,
|
||||
fragment,
|
||||
contextAsContent->Tag(),
|
||||
contextAsContent->GetNameSpaceID(),
|
||||
(document->GetCompatibilityMode() == eCompatibility_NavQuirks));
|
||||
} else {
|
||||
parser->ParseFragment(aFragment,
|
||||
frag,
|
||||
fragment,
|
||||
nsGkAtoms::body,
|
||||
kNameSpaceID_XHTML,
|
||||
(document->GetCompatibilityMode() == eCompatibility_NavQuirks));
|
||||
@ -5352,7 +5353,7 @@ nsContentUtils::DispatchXULCommand(nsIContent* aTarget,
|
||||
// static
|
||||
nsresult
|
||||
nsContentUtils::WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
|
||||
const nsIID* aIID, jsval *vp,
|
||||
nsWrapperCache *cache, const nsIID* aIID, jsval *vp,
|
||||
nsIXPConnectJSObjectHolder **aHolder,
|
||||
PRBool aAllowWrapping)
|
||||
{
|
||||
@ -5389,7 +5390,7 @@ nsContentUtils::WrapNative(JSContext *cx, JSObject *scope, nsISupports *native,
|
||||
rv = sThreadJSContextStack->Push(cx);
|
||||
}
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = sXPConnect->WrapNativeToJSVal(cx, scope, native, aIID,
|
||||
rv = sXPConnect->WrapNativeToJSVal(cx, scope, native, cache, aIID,
|
||||
aAllowWrapping, vp, aHolder);
|
||||
if (push) {
|
||||
sThreadJSContextStack->Pop(nsnull);
|
||||
@ -5966,6 +5967,7 @@ AllocClassMatchingInfo(nsINode* aRootNode,
|
||||
}
|
||||
|
||||
info->mCaseTreatment =
|
||||
aRootNode->GetOwnerDoc() &&
|
||||
aRootNode->GetOwnerDoc()->GetCompatibilityMode() == eCompatibility_NavQuirks ?
|
||||
eIgnoreCase : eCaseMatters;
|
||||
return info;
|
||||
|
@ -64,7 +64,7 @@
|
||||
PRBool nsDOMAttribute::sInitialized;
|
||||
|
||||
nsDOMAttribute::nsDOMAttribute(nsDOMAttributeMap *aAttrMap,
|
||||
nsINodeInfo *aNodeInfo,
|
||||
already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
const nsAString &aValue)
|
||||
: nsIAttribute(aAttrMap, aNodeInfo), mValue(aValue), mChild(nsnull)
|
||||
{
|
||||
@ -124,7 +124,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMAttribute)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_USERDATA
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
DOMCI_DATA(Attr, nsDOMAttribute)
|
||||
DOMCI_NODE_DATA(Attr, nsDOMAttribute)
|
||||
|
||||
// QueryInterface implementation for nsDOMAttribute
|
||||
NS_INTERFACE_TABLE_HEAD(nsDOMAttribute)
|
||||
@ -415,7 +415,8 @@ nsDOMAttribute::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
|
||||
nsAutoString value;
|
||||
const_cast<nsDOMAttribute*>(this)->GetValue(value);
|
||||
|
||||
*aResult = new nsDOMAttribute(nsnull, aNodeInfo, value);
|
||||
nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
|
||||
*aResult = new nsDOMAttribute(nsnull, ni.forget(), value);
|
||||
if (!*aResult) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -764,6 +765,8 @@ nsDOMAttribute::AttributeChanged(nsIDocument* aDocument,
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
||||
|
||||
// Just blow away our mChild and recreate it if needed
|
||||
if (mChild) {
|
||||
static_cast<nsTextNode*>(mChild)->UnbindFromAttribute();
|
||||
|
@ -63,7 +63,8 @@ class nsDOMAttribute : public nsIAttribute,
|
||||
public nsStubMutationObserver
|
||||
{
|
||||
public:
|
||||
nsDOMAttribute(nsDOMAttributeMap* aAttrMap, nsINodeInfo *aNodeInfo,
|
||||
nsDOMAttribute(nsDOMAttributeMap* aAttrMap,
|
||||
already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
const nsAString& aValue);
|
||||
virtual ~nsDOMAttribute();
|
||||
|
||||
@ -122,6 +123,7 @@ public:
|
||||
|
||||
NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
|
||||
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
protected:
|
||||
virtual mozilla::dom::Element* GetNameSpaceElement()
|
||||
{
|
||||
|
@ -179,7 +179,9 @@ nsDOMAttributeMap::RemoveAttribute(nsINodeInfo* aNodeInfo, nsIDOMNode** aReturn)
|
||||
// As we are removing the attribute we need to set the current value in
|
||||
// the attribute node.
|
||||
mContent->GetAttr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom(), value);
|
||||
nsCOMPtr<nsIDOMNode> newAttr = new nsDOMAttribute(nsnull, aNodeInfo, value);
|
||||
nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
|
||||
nsCOMPtr<nsIDOMNode> newAttr =
|
||||
new nsDOMAttribute(nsnull, ni.forget(), value);
|
||||
if (!newAttr) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -207,8 +209,9 @@ nsDOMAttributeMap::GetAttribute(nsINodeInfo* aNodeInfo)
|
||||
|
||||
nsDOMAttribute* node = mAttributeCache.GetWeak(attr);
|
||||
if (!node) {
|
||||
nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
|
||||
nsRefPtr<nsDOMAttribute> newAttr =
|
||||
new nsDOMAttribute(this, aNodeInfo, EmptyString());
|
||||
new nsDOMAttribute(this, ni.forget(), EmptyString());
|
||||
if (newAttr && mAttributeCache.Put(attr, newAttr)) {
|
||||
node = newAttr;
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType,
|
||||
kNameSpaceID_None);
|
||||
NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
*aDocType = new nsDOMDocumentType(ni, aName, aEntities, aNotations,
|
||||
*aDocType = new nsDOMDocumentType(ni.forget(), aName, aEntities, aNotations,
|
||||
aPublicId, aSystemId, aInternalSubset);
|
||||
if (!*aDocType) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -100,7 +100,7 @@ NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsDOMDocumentType::nsDOMDocumentType(nsINodeInfo *aNodeInfo,
|
||||
nsDOMDocumentType::nsDOMDocumentType(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
nsIAtom *aName,
|
||||
nsIDOMNamedNodeMap *aEntities,
|
||||
nsIDOMNamedNodeMap *aNotations,
|
||||
@ -121,7 +121,7 @@ nsDOMDocumentType::~nsDOMDocumentType()
|
||||
{
|
||||
}
|
||||
|
||||
DOMCI_DATA(DocumentType, nsDOMDocumentType)
|
||||
DOMCI_NODE_DATA(DocumentType, nsDOMDocumentType)
|
||||
|
||||
// QueryInterface implementation for nsDOMDocumentType
|
||||
NS_INTERFACE_TABLE_HEAD(nsDOMDocumentType)
|
||||
@ -236,7 +236,8 @@ nsDOMDocumentType::GetNodeType(PRUint16* aNodeType)
|
||||
nsGenericDOMDataNode*
|
||||
nsDOMDocumentType::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
|
||||
{
|
||||
return new nsDOMDocumentType(aNodeInfo, mName, mEntities, mNotations,
|
||||
nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
|
||||
return new nsDOMDocumentType(ni.forget(), mName, mEntities, mNotations,
|
||||
mPublicId, mSystemId, mInternalSubset);
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ class nsDOMDocumentType : public nsGenericDOMDataNode,
|
||||
public nsIDOMDocumentType
|
||||
{
|
||||
public:
|
||||
nsDOMDocumentType(nsINodeInfo* aNodeInfo,
|
||||
nsDOMDocumentType(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
nsIAtom *aName,
|
||||
nsIDOMNamedNodeMap *aEntities,
|
||||
nsIDOMNamedNodeMap *aNotations,
|
||||
@ -83,7 +83,7 @@ public:
|
||||
nsIContent *aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
|
||||
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
protected:
|
||||
nsCOMPtr<nsIAtom> mName;
|
||||
nsCOMPtr<nsIDOMNamedNodeMap> mEntities;
|
||||
|
@ -1907,11 +1907,13 @@ nsDocument::ResetToURI(nsIURI *aURI, nsILoadGroup *aLoadGroup,
|
||||
for (PRInt32 i = PRInt32(count) - 1; i >= 0; i--) {
|
||||
nsCOMPtr<nsIContent> content = mChildren.ChildAt(i);
|
||||
|
||||
nsIContent* previousSibling = content->GetPreviousSibling();
|
||||
|
||||
if (nsINode::GetFirstChild() == content) {
|
||||
mFirstChild = content->GetNextSibling();
|
||||
}
|
||||
mChildren.RemoveChildAt(i);
|
||||
nsNodeUtils::ContentRemoved(this, content, i);
|
||||
nsNodeUtils::ContentRemoved(this, content, i, previousSibling);
|
||||
content->UnbindFromTree();
|
||||
}
|
||||
}
|
||||
@ -2162,9 +2164,79 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
||||
|
||||
mChannel = aChannel;
|
||||
|
||||
nsresult rv = InitCSP();
|
||||
nsresult rv = CheckFrameOptions();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = InitCSP();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Check if X-Frame-Options permits this document to be loaded as a subdocument.
|
||||
nsresult nsDocument::CheckFrameOptions()
|
||||
{
|
||||
nsAutoString xfoHeaderValue;
|
||||
this->GetHeaderData(nsGkAtoms::headerXFO, xfoHeaderValue);
|
||||
|
||||
// return early if header does not have one of the two values with meaning
|
||||
if (!xfoHeaderValue.LowerCaseEqualsLiteral("deny") &&
|
||||
!xfoHeaderValue.LowerCaseEqualsLiteral("sameorigin"))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
|
||||
|
||||
if (docShell) {
|
||||
PRBool framingAllowed = true;
|
||||
|
||||
// We need to check the location of this window and the location of the top
|
||||
// window, if we're not the top. X-F-O: SAMEORIGIN requires that the
|
||||
// document must be same-origin with top window. X-F-O: DENY requires that
|
||||
// the document must never be framed.
|
||||
nsCOMPtr<nsIDOMWindow> thisWindow = do_GetInterface(docShell);
|
||||
nsCOMPtr<nsIDOMWindow> topWindow;
|
||||
thisWindow->GetTop(getter_AddRefs(topWindow));
|
||||
|
||||
// if the document is in the top window, it's not in a frame.
|
||||
if (thisWindow == topWindow)
|
||||
return NS_OK;
|
||||
|
||||
// If the value of the header is DENY, then the document
|
||||
// should never be permitted to load as a subdocument.
|
||||
if (xfoHeaderValue.LowerCaseEqualsLiteral("deny")) {
|
||||
framingAllowed = false;
|
||||
}
|
||||
|
||||
else if (xfoHeaderValue.LowerCaseEqualsLiteral("sameorigin")) {
|
||||
// If the X-Frame-Options value is SAMEORIGIN, then the top frame in the
|
||||
// parent chain must be from the same origin as this document.
|
||||
nsCOMPtr<nsIURI> uri = static_cast<nsIDocument*>(this)->GetDocumentURI();
|
||||
nsCOMPtr<nsIDOMDocument> topDOMDoc;
|
||||
topWindow->GetDocument(getter_AddRefs(topDOMDoc));
|
||||
nsCOMPtr<nsIDocument> topDoc = do_QueryInterface(topDOMDoc);
|
||||
if (topDoc) {
|
||||
nsCOMPtr<nsIURI> topUri = topDoc->GetDocumentURI();
|
||||
nsresult rv = nsContentUtils::GetSecurityManager()->
|
||||
CheckSameOriginURI(uri, topUri, PR_TRUE);
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
framingAllowed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!framingAllowed) {
|
||||
// cancel the load and display about:blank
|
||||
mChannel->Cancel(NS_BINDING_ABORTED);
|
||||
nsCOMPtr<nsIWebNavigation> webNav(do_QueryInterface(docShell));
|
||||
if (webNav) {
|
||||
webNav->LoadURI(NS_LITERAL_STRING("about:blank").get(),
|
||||
0, nsnull, nsnull, nsnull);
|
||||
}
|
||||
return NS_ERROR_CONTENT_BLOCKED;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -4020,23 +4092,43 @@ nsDocument::CreateElement(const nsAString& aTagName,
|
||||
nsIDOMElement** aReturn)
|
||||
{
|
||||
*aReturn = nsnull;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
nsresult rv = CreateElement(aTagName, getter_AddRefs(content));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return CallQueryInterface(content, aReturn);
|
||||
}
|
||||
|
||||
PRBool IsLowercaseASCII(const nsAString& aValue)
|
||||
{
|
||||
PRInt32 len = aValue.Length();
|
||||
for (PRInt32 i = 0; i < len; ++i) {
|
||||
PRUnichar c = aValue[i];
|
||||
if (!(0x0061 <= (c) && ((c) <= 0x007a))) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::CreateElement(const nsAString& aTagName,
|
||||
nsIContent** aReturn)
|
||||
{
|
||||
*aReturn = nsnull;
|
||||
|
||||
nsresult rv = nsContentUtils::CheckQName(aTagName, PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
NS_ASSERTION(!IsHTML(),
|
||||
"nsDocument::CreateElement() called on document that is not "
|
||||
"case sensitive. Fix caller, or fix "
|
||||
"nsDocument::CreateElement()!");
|
||||
PRBool needsLowercase = IsHTML() && !IsLowercaseASCII(aTagName);
|
||||
nsAutoString lcTagName;
|
||||
if (needsLowercase) {
|
||||
ToLowerCase(aTagName, lcTagName);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> name = do_GetAtom(aTagName);
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
rv = CreateElem(name, nsnull, GetDefaultNamespaceID(), PR_TRUE,
|
||||
getter_AddRefs(content));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(content, aReturn);
|
||||
rv = CreateElem(needsLowercase ? lcTagName : aTagName, nsnull,
|
||||
IsHTML() ? kNameSpaceID_XHTML : GetDefaultNamespaceID(),
|
||||
PR_TRUE, aReturn);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -4054,8 +4146,8 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIContent> content;
|
||||
NS_NewElement(getter_AddRefs(content), nodeInfo->NamespaceID(), nodeInfo,
|
||||
PR_FALSE);
|
||||
PRInt32 ns = nodeInfo->NamespaceID();
|
||||
NS_NewElement(getter_AddRefs(content), ns, nodeInfo.forget(), PR_FALSE);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(content, aReturn);
|
||||
@ -4065,17 +4157,20 @@ NS_IMETHODIMP
|
||||
nsDocument::CreateTextNode(const nsAString& aData, nsIDOMText** aReturn)
|
||||
{
|
||||
*aReturn = nsnull;
|
||||
nsCOMPtr<nsIContent> content;
|
||||
nsresult rv = CreateTextNode(aData, getter_AddRefs(content));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return CallQueryInterface(content, aReturn);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> text;
|
||||
nsresult rv = NS_NewTextNode(getter_AddRefs(text), mNodeInfoManager);
|
||||
|
||||
nsresult
|
||||
nsDocument::CreateTextNode(const nsAString& aData, nsIContent** aReturn)
|
||||
{
|
||||
nsresult rv = NS_NewTextNode(aReturn, mNodeInfoManager);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Don't notify; this node is still being created.
|
||||
text->SetText(aData, PR_FALSE);
|
||||
|
||||
rv = CallQueryInterface(text, aReturn);
|
||||
(*aReturn)->SetText(aData, PR_FALSE);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -4175,7 +4270,7 @@ nsDocument::CreateAttribute(const nsAString& aName,
|
||||
getter_AddRefs(nodeInfo));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
attribute = new nsDOMAttribute(nsnull, nodeInfo, value);
|
||||
attribute = new nsDOMAttribute(nsnull, nodeInfo.forget(), value);
|
||||
NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return CallQueryInterface(attribute, aReturn);
|
||||
@ -4197,7 +4292,8 @@ nsDocument::CreateAttributeNS(const nsAString & aNamespaceURI,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsAutoString value;
|
||||
nsDOMAttribute* attribute = new nsDOMAttribute(nsnull, nodeInfo, value);
|
||||
nsDOMAttribute* attribute =
|
||||
new nsDOMAttribute(nsnull, nodeInfo.forget(), value);
|
||||
NS_ENSURE_TRUE(attribute, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return CallQueryInterface(attribute, aResult);
|
||||
@ -4910,7 +5006,7 @@ nsDocument::SetTitle(const nsAString& aTitle)
|
||||
kNameSpaceID_XHTML);
|
||||
if (!titleInfo)
|
||||
return NS_OK;
|
||||
title = NS_NewHTMLTitleElement(titleInfo);
|
||||
title = NS_NewHTMLTitleElement(titleInfo.forget());
|
||||
if (!title)
|
||||
return NS_OK;
|
||||
}
|
||||
@ -5468,13 +5564,9 @@ nsDocument::CloneNode(PRBool aDeep, nsIDOMNode** aReturn)
|
||||
NS_IMETHODIMP
|
||||
nsDocument::Normalize()
|
||||
{
|
||||
PRInt32 count = mChildren.ChildCount();
|
||||
for (PRInt32 i = 0; i < count; ++i) {
|
||||
for (PRInt32 i = 0; i < mChildren.ChildCount(); ++i) {
|
||||
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(mChildren.ChildAt(i)));
|
||||
|
||||
if (node) {
|
||||
node->Normalize();
|
||||
}
|
||||
node->Normalize();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -6442,6 +6534,7 @@ nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel)
|
||||
"x-dns-prefetch-control",
|
||||
"x-content-security-policy",
|
||||
"x-content-security-policy-report-only",
|
||||
"x-frame-options",
|
||||
// add more http headers if you need
|
||||
// XXXbz don't add content-location support without reading bug
|
||||
// 238654 and its dependencies/dups first.
|
||||
@ -6510,7 +6603,7 @@ nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel)
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::CreateElem(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
|
||||
nsDocument::CreateElem(const nsAString& aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
|
||||
PRBool aDocumentDefaultType, nsIContent **aResult)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
@ -6519,7 +6612,7 @@ nsDocument::CreateElem(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
|
||||
aPrefix->ToString(qName);
|
||||
qName.Append(':');
|
||||
}
|
||||
qName.Append(nsAtomString(aName));
|
||||
qName.Append(aName);
|
||||
|
||||
// Note: "a:b:c" is a valid name in non-namespaces XML, and
|
||||
// nsDocument::CreateElement can call us with such a name and no prefix,
|
||||
@ -6536,10 +6629,11 @@ nsDocument::CreateElem(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
|
||||
aNamespaceID;
|
||||
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
nodeInfo = mNodeInfoManager->GetNodeInfo(aName, aPrefix, aNamespaceID);
|
||||
mNodeInfoManager->GetNodeInfo(aName, aPrefix, aNamespaceID,
|
||||
getter_AddRefs(nodeInfo));
|
||||
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
return NS_NewElement(aResult, elementType, nodeInfo, PR_FALSE);
|
||||
return NS_NewElement(aResult, elementType, nodeInfo.forget(), PR_FALSE);
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -834,11 +834,16 @@ public:
|
||||
|
||||
virtual nsresult AddXMLEventsContent(nsIContent * aXMLEventsElement);
|
||||
|
||||
virtual nsresult CreateElem(nsIAtom *aName, nsIAtom *aPrefix,
|
||||
virtual nsresult CreateElem(const nsAString& aName, nsIAtom *aPrefix,
|
||||
PRInt32 aNamespaceID,
|
||||
PRBool aDocumentDefaultType,
|
||||
nsIContent **aResult);
|
||||
|
||||
nsresult CreateElement(const nsAString& aTagName,
|
||||
nsIContent** aReturn);
|
||||
|
||||
nsresult CreateTextNode(const nsAString& aData, nsIContent** aReturn);
|
||||
|
||||
virtual NS_HIDDEN_(nsresult) Sanitize();
|
||||
|
||||
virtual NS_HIDDEN_(void) EnumerateSubDocuments(nsSubDocEnumFunc aCallback,
|
||||
@ -1019,9 +1024,9 @@ protected:
|
||||
virtual nsPIDOMWindow *GetInnerWindowInternal();
|
||||
virtual nsIScriptGlobalObject* GetScriptHandlingObjectInternal() const;
|
||||
|
||||
#define NS_DOCUMENT_NOTIFY_OBSERVERS(func_, params_) \
|
||||
NS_OBSERVER_ARRAY_NOTIFY_OBSERVERS(mObservers, nsIDocumentObserver, \
|
||||
func_, params_);
|
||||
#define NS_DOCUMENT_NOTIFY_OBSERVERS(func_, params_) \
|
||||
NS_OBSERVER_ARRAY_NOTIFY_XPCOM_OBSERVERS(mObservers, nsIDocumentObserver, \
|
||||
func_, params_);
|
||||
|
||||
#ifdef DEBUG
|
||||
void VerifyRootContentState();
|
||||
@ -1143,6 +1148,7 @@ private:
|
||||
void PostUnblockOnloadEvent();
|
||||
void DoUnblockOnload();
|
||||
|
||||
nsresult CheckFrameOptions();
|
||||
nsresult InitCSP();
|
||||
|
||||
/**
|
||||
|
@ -59,7 +59,7 @@ class nsDocumentFragment : public nsGenericElement,
|
||||
public nsIDOMDocumentFragment
|
||||
{
|
||||
public:
|
||||
nsDocumentFragment(nsINodeInfo *aNodeInfo);
|
||||
nsDocumentFragment(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
virtual ~nsDocumentFragment();
|
||||
|
||||
// nsISupports
|
||||
@ -154,6 +154,8 @@ public:
|
||||
|
||||
virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
|
||||
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
virtual nsIAtom* DoGetID() const;
|
||||
virtual nsIAtom *GetIDAttributeName() const;
|
||||
|
||||
@ -172,7 +174,7 @@ NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
|
||||
nsnull, kNameSpaceID_None);
|
||||
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
nsDocumentFragment *it = new nsDocumentFragment(nodeInfo);
|
||||
nsDocumentFragment *it = new nsDocumentFragment(nodeInfo.forget());
|
||||
if (!it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -182,7 +184,7 @@ NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsDocumentFragment::nsDocumentFragment(nsINodeInfo *aNodeInfo)
|
||||
nsDocumentFragment::nsDocumentFragment(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsGenericElement(aNodeInfo)
|
||||
{
|
||||
UnsetFlags(NODE_IS_ELEMENT);
|
||||
@ -210,7 +212,7 @@ nsDocumentFragment::GetIDAttributeName() const
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
DOMCI_DATA(DocumentFragment, nsDocumentFragment)
|
||||
DOMCI_NODE_DATA(DocumentFragment, nsDocumentFragment)
|
||||
|
||||
// QueryInterface implementation for nsDocumentFragment
|
||||
NS_INTERFACE_TABLE_HEAD(nsDocumentFragment)
|
||||
|
@ -52,7 +52,7 @@ class nsGenConImageContent : public nsXMLElement,
|
||||
public nsImageLoadingContent
|
||||
{
|
||||
public:
|
||||
nsGenConImageContent(nsINodeInfo* aNodeInfo)
|
||||
nsGenConImageContent(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsXMLElement(aNodeInfo)
|
||||
{
|
||||
}
|
||||
@ -77,7 +77,7 @@ NS_IMPL_ISUPPORTS_INHERITED3(nsGenConImageContent, nsXMLElement,
|
||||
nsIImageLoadingContent, imgIContainerObserver, imgIDecoderObserver)
|
||||
|
||||
nsresult
|
||||
NS_NewGenConImageContent(nsIContent** aResult, nsINodeInfo* aNodeInfo,
|
||||
NS_NewGenConImageContent(nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
imgIRequest* aImageRequest)
|
||||
{
|
||||
NS_PRECONDITION(aImageRequest, "Must have request!");
|
||||
|
@ -67,7 +67,7 @@
|
||||
#include "pldhash.h"
|
||||
#include "prprf.h"
|
||||
|
||||
nsGenericDOMDataNode::nsGenericDOMDataNode(nsINodeInfo *aNodeInfo)
|
||||
nsGenericDOMDataNode::nsGenericDOMDataNode(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsIContent(aNodeInfo)
|
||||
{
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ class nsGenericDOMDataNode : public nsIContent
|
||||
public:
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
||||
nsGenericDOMDataNode(nsINodeInfo *aNodeInfo);
|
||||
nsGenericDOMDataNode(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
virtual ~nsGenericDOMDataNode();
|
||||
|
||||
// Implementation for nsIDOMNode
|
||||
@ -366,7 +366,8 @@ private:
|
||||
class nsGenericTextNode : public nsGenericDOMDataNode
|
||||
{
|
||||
public:
|
||||
nsGenericTextNode(nsINodeInfo *aNodeInfo) : nsGenericDOMDataNode(aNodeInfo)
|
||||
nsGenericTextNode(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsGenericDOMDataNode(aNodeInfo)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -366,8 +366,7 @@ nsINode::GetSelectionRootContent(nsIPresShell* aPresShell)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsIFrame* frame = static_cast<nsIContent*>(this)->GetPrimaryFrame();
|
||||
if (frame && frame->GetStateBits() & NS_FRAME_INDEPENDENT_SELECTION) {
|
||||
if (static_cast<nsIContent*>(this)->HasIndependentSelection()) {
|
||||
// This node should be a descendant of input/textarea editor.
|
||||
nsIContent* content = GetTextEditorRootContent();
|
||||
if (content)
|
||||
@ -388,15 +387,9 @@ nsINode::GetSelectionRootContent(nsIPresShell* aPresShell)
|
||||
editorRoot :
|
||||
GetRootForContentSubtree(static_cast<nsIContent*>(this));
|
||||
}
|
||||
// If the current document is not editable, but current content is
|
||||
// editable, we should assume that the child of the nearest non-editable
|
||||
// ancestor is selection root.
|
||||
nsIContent* content = static_cast<nsIContent*>(this);
|
||||
for (nsIContent* parent = GetParent();
|
||||
parent && parent->HasFlag(NODE_IS_EDITABLE);
|
||||
parent = content->GetParent())
|
||||
content = parent;
|
||||
return content;
|
||||
// If the document isn't editable but this is editable, this is in
|
||||
// contenteditable. Use the editing host element for selection root.
|
||||
return static_cast<nsIContent*>(this)->GetEditingHost();
|
||||
}
|
||||
}
|
||||
|
||||
@ -830,14 +823,13 @@ nsIContent::GetDesiredIMEState()
|
||||
if (!IsEditableInternal()) {
|
||||
return IME_STATUS_DISABLE;
|
||||
}
|
||||
nsIContent *editableAncestor = nsnull;
|
||||
for (nsIContent* parent = GetParent();
|
||||
parent && parent->HasFlag(NODE_IS_EDITABLE);
|
||||
parent = parent->GetParent()) {
|
||||
editableAncestor = parent;
|
||||
}
|
||||
// NOTE: The content for independent editors (e.g., input[type=text],
|
||||
// textarea) must override this method, so, we don't need to worry about
|
||||
// that here.
|
||||
nsIContent *editableAncestor = GetEditingHost();
|
||||
|
||||
// This is in another editable content, use the result of it.
|
||||
if (editableAncestor) {
|
||||
if (editableAncestor && editableAncestor != this) {
|
||||
return editableAncestor->GetDesiredIMEState();
|
||||
}
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
@ -865,6 +857,35 @@ nsIContent::GetDesiredIMEState()
|
||||
return state;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsIContent::HasIndependentSelection()
|
||||
{
|
||||
nsIFrame* frame = GetPrimaryFrame();
|
||||
return (frame && frame->GetStateBits() & NS_FRAME_INDEPENDENT_SELECTION);
|
||||
}
|
||||
|
||||
nsIContent*
|
||||
nsIContent::GetEditingHost()
|
||||
{
|
||||
// If this isn't editable, return NULL.
|
||||
NS_ENSURE_TRUE(HasFlag(NODE_IS_EDITABLE), nsnull);
|
||||
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
NS_ENSURE_TRUE(doc, nsnull);
|
||||
// If this is in designMode, we should return <body>
|
||||
if (doc->HasFlag(NODE_IS_EDITABLE)) {
|
||||
return doc->GetBodyElement();
|
||||
}
|
||||
|
||||
nsIContent* content = this;
|
||||
for (nsIContent* parent = GetParent();
|
||||
parent && parent->HasFlag(NODE_IS_EDITABLE);
|
||||
parent = content->GetParent()) {
|
||||
content = parent;
|
||||
}
|
||||
return content;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsIContent::LookupNamespaceURI(const nsAString& aNamespacePrefix,
|
||||
nsAString& aNamespaceURI) const
|
||||
@ -2067,7 +2088,7 @@ nsGenericElement::nsDOMSlots::~nsDOMSlots()
|
||||
}
|
||||
}
|
||||
|
||||
nsGenericElement::nsGenericElement(nsINodeInfo *aNodeInfo)
|
||||
nsGenericElement::nsGenericElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: Element(aNodeInfo)
|
||||
{
|
||||
// Set the default scriptID to JS - but skip SetScriptTypeID as it
|
||||
@ -3676,6 +3697,8 @@ nsINode::doRemoveChildAt(PRUint32 aIndex, PRBool aNotify,
|
||||
}
|
||||
}
|
||||
|
||||
nsIContent* previousSibling = aKid->GetPreviousSibling();
|
||||
|
||||
if (GetFirstChild() == aKid) {
|
||||
mFirstChild = aKid->GetNextSibling();
|
||||
}
|
||||
@ -3683,7 +3706,7 @@ nsINode::doRemoveChildAt(PRUint32 aIndex, PRBool aNotify,
|
||||
aChildArray.RemoveChildAt(aIndex);
|
||||
|
||||
if (aNotify) {
|
||||
nsNodeUtils::ContentRemoved(this, aKid, aIndex);
|
||||
nsNodeUtils::ContentRemoved(this, aKid, aIndex, previousSibling);
|
||||
}
|
||||
|
||||
aKid->UnbindFromTree();
|
||||
|
@ -325,7 +325,7 @@ class nsNSElementTearoff;
|
||||
class nsGenericElement : public mozilla::dom::Element
|
||||
{
|
||||
public:
|
||||
nsGenericElement(nsINodeInfo *aNodeInfo);
|
||||
nsGenericElement(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
virtual ~nsGenericElement();
|
||||
|
||||
friend class nsNSElementTearoff;
|
||||
@ -1084,8 +1084,8 @@ nsresult \
|
||||
_elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const \
|
||||
{ \
|
||||
*aResult = nsnull; \
|
||||
\
|
||||
_elementName *it = new _elementName(aNodeInfo); \
|
||||
nsCOMPtr<nsINodeInfo> ni = aNodeInfo; \
|
||||
_elementName *it = new _elementName(ni.forget()); \
|
||||
if (!it) { \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
@ -1104,8 +1104,8 @@ nsresult \
|
||||
_elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const \
|
||||
{ \
|
||||
*aResult = nsnull; \
|
||||
\
|
||||
_elementName *it = new _elementName(aNodeInfo); \
|
||||
nsCOMPtr<nsINodeInfo> ni = aNodeInfo; \
|
||||
_elementName *it = new _elementName(ni.forget()); \
|
||||
if (!it) { \
|
||||
return NS_ERROR_OUT_OF_MEMORY; \
|
||||
} \
|
||||
@ -1120,6 +1120,14 @@ _elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const \
|
||||
return rv; \
|
||||
}
|
||||
|
||||
#define DOMCI_NODE_DATA(_interface, _class) \
|
||||
DOMCI_DATA(_interface, _class) \
|
||||
nsXPCClassInfo* _class::GetClassInfo() \
|
||||
{ \
|
||||
return static_cast<nsXPCClassInfo*>( \
|
||||
NS_GetDOMClassInfoInstance(eDOMClassInfo_##_interface##_id)); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Yet another tearoff class for nsGenericElement
|
||||
* to implement additional interfaces
|
||||
|
@ -1025,6 +1025,7 @@ GK_ATOM(wrap, "wrap")
|
||||
GK_ATOM(headerDNSPrefetchControl,"x-dns-prefetch-control")
|
||||
GK_ATOM(headerCSP, "x-content-security-policy")
|
||||
GK_ATOM(headerCSPReportOnly, "x-content-security-policy-report-only")
|
||||
GK_ATOM(headerXFO, "x-frame-options")
|
||||
GK_ATOM(xml, "xml")
|
||||
GK_ATOM(xmlns, "xmlns")
|
||||
GK_ATOM(xmp, "xmp")
|
||||
|
@ -60,7 +60,7 @@ class nsMappedAttributeElement : public nsMappedAttributeElementBase
|
||||
|
||||
protected:
|
||||
|
||||
nsMappedAttributeElement(nsINodeInfo *aNodeInfo)
|
||||
nsMappedAttributeElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsMappedAttributeElementBase(aNodeInfo)
|
||||
{}
|
||||
|
||||
|
@ -227,7 +227,7 @@ NameSpaceManagerImpl::GetNameSpaceID(const nsAString& aURI)
|
||||
|
||||
nsresult
|
||||
NS_NewElement(nsIContent** aResult, PRInt32 aElementType,
|
||||
nsINodeInfo* aNodeInfo, PRUint32 aFromParser)
|
||||
already_AddRefed<nsINodeInfo> aNodeInfo, PRUint32 aFromParser)
|
||||
{
|
||||
if (aElementType == kNameSpaceID_XHTML) {
|
||||
return NS_NewHTMLElement(aResult, aNodeInfo, aFromParser);
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsLayoutStatics.h"
|
||||
#include "nsBindingManager.h"
|
||||
#include "nsHashKeys.h"
|
||||
|
||||
#ifdef MOZ_LOGGING
|
||||
// so we can get logging even in release builds
|
||||
@ -72,8 +73,10 @@ nsNodeInfoManager::GetNodeInfoInnerHashValue(const void *key)
|
||||
const nsINodeInfo::nsNodeInfoInner *node =
|
||||
reinterpret_cast<const nsINodeInfo::nsNodeInfoInner *>(key);
|
||||
|
||||
// Is this an acceptable hash value?
|
||||
return (PLHashNumber(NS_PTR_TO_INT32(node->mName)) & 0xffff) >> 8;
|
||||
if (node->mName) {
|
||||
return HashString(nsAtomString(node->mName));
|
||||
}
|
||||
return HashString(*(node->mNameString));
|
||||
}
|
||||
|
||||
|
||||
@ -87,9 +90,21 @@ nsNodeInfoManager::NodeInfoInnerKeyCompare(const void *key1, const void *key2)
|
||||
const nsINodeInfo::nsNodeInfoInner *node2 =
|
||||
reinterpret_cast<const nsINodeInfo::nsNodeInfoInner *>(key2);
|
||||
|
||||
return (node1->mName == node2->mName &&
|
||||
node1->mPrefix == node2->mPrefix &&
|
||||
node1->mNamespaceID == node2->mNamespaceID);
|
||||
if (node1->mPrefix != node2->mPrefix ||
|
||||
node1->mNamespaceID != node2->mNamespaceID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (node1->mName) {
|
||||
if (node2->mName) {
|
||||
return (node1->mName == node2->mName);
|
||||
}
|
||||
return (node1->mName->Equals(*(node2->mNameString)));
|
||||
}
|
||||
if (node2->mName) {
|
||||
return (node2->mName->Equals(*(node1->mNameString)));
|
||||
}
|
||||
return (node1->mNameString->Equals(*(node2->mNameString)));
|
||||
}
|
||||
|
||||
|
||||
@ -229,9 +244,35 @@ nsresult
|
||||
nsNodeInfoManager::GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix,
|
||||
PRInt32 aNamespaceID, nsINodeInfo** aNodeInfo)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> name = do_GetAtom(aName);
|
||||
*aNodeInfo = nsNodeInfoManager::GetNodeInfo(name, aPrefix, aNamespaceID).get();
|
||||
return *aNodeInfo ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ASSERTION(!aName.IsEmpty(),
|
||||
"Don't pass an empty string to GetNodeInfo, fix caller.");
|
||||
|
||||
nsINodeInfo::nsNodeInfoInner tmpKey(aName, aPrefix, aNamespaceID);
|
||||
|
||||
void *node = PL_HashTableLookup(mNodeInfoHash, &tmpKey);
|
||||
|
||||
if (node) {
|
||||
nsINodeInfo* nodeInfo = static_cast<nsINodeInfo *>(node);
|
||||
|
||||
NS_ADDREF(*aNodeInfo = nodeInfo);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRefPtr<nsNodeInfo> newNodeInfo = nsNodeInfo::Create();
|
||||
NS_ENSURE_TRUE(newNodeInfo, nsnull);
|
||||
|
||||
nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aName);
|
||||
nsresult rv = newNodeInfo->Init(nameAtom, aPrefix, aNamespaceID, this);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PLHashEntry *he;
|
||||
he = PL_HashTableAdd(mNodeInfoHash, &newNodeInfo->mInner, newNodeInfo);
|
||||
NS_ENSURE_TRUE(he, NS_ERROR_FAILURE);
|
||||
|
||||
newNodeInfo.forget(aNodeInfo);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -65,19 +65,27 @@ nsNodeIterator::NodePointer::NodePointer(nsINode *aNode,
|
||||
|
||||
PRBool nsNodeIterator::NodePointer::MoveToNext(nsINode *aRoot)
|
||||
{
|
||||
NS_ASSERTION(mNode, "Iterating an uninitialized NodePointer");
|
||||
if (!mNode)
|
||||
return PR_FALSE;
|
||||
|
||||
if (mBeforeNode) {
|
||||
mBeforeNode = PR_FALSE;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return MoveForward(aRoot, mNode, -1);
|
||||
nsINode* child = mNode->GetFirstChild();
|
||||
if (child) {
|
||||
mNode = child;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return MoveForward(aRoot, mNode);
|
||||
}
|
||||
|
||||
PRBool nsNodeIterator::NodePointer::MoveToPrevious(nsINode *aRoot)
|
||||
{
|
||||
NS_ASSERTION(mNode, "Iterating an uninitialized NodePointer");
|
||||
if (!mNode)
|
||||
return PR_FALSE;
|
||||
|
||||
if (!mBeforeNode) {
|
||||
mBeforeNode = PR_TRUE;
|
||||
@ -87,109 +95,72 @@ PRBool nsNodeIterator::NodePointer::MoveToPrevious(nsINode *aRoot)
|
||||
if (mNode == aRoot)
|
||||
return PR_FALSE;
|
||||
|
||||
NS_ASSERTION(mNodeParent == mNode->GetNodeParent(), "Parent node incorrect in MoveToPrevious");
|
||||
NS_ASSERTION(mIndexInParent == mNodeParent->IndexOf(mNode), "Index mismatch in MoveToPrevious");
|
||||
MoveBackward(mNodeParent, mIndexInParent);
|
||||
MoveBackward(mNode->GetNodeParent(), mNode->GetPreviousSibling());
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void nsNodeIterator::NodePointer::AdjustAfterInsertion(nsINode *aRoot,
|
||||
nsINode *aContainer,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
// If mNode is null or the root there is nothing to do. This also prevents
|
||||
// valgrind from complaining about consuming uninitialized memory for
|
||||
// mNodeParent and mIndexInParent
|
||||
if (!mNode || mNode == aRoot)
|
||||
return;
|
||||
|
||||
// check if earlier sibling was added
|
||||
if (aContainer == mNodeParent && aIndexInContainer <= mIndexInParent)
|
||||
mIndexInParent++;
|
||||
}
|
||||
|
||||
void nsNodeIterator::NodePointer::AdjustAfterRemoval(nsINode *aRoot,
|
||||
nsINode *aContainer,
|
||||
nsIContent *aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
nsIContent *aPreviousSibling)
|
||||
{
|
||||
// If mNode is null or the root there is nothing to do. This also prevents
|
||||
// valgrind from complaining about consuming uninitialized memory for
|
||||
// mNodeParent and mIndexInParent
|
||||
// If mNode is null or the root there is nothing to do.
|
||||
if (!mNode || mNode == aRoot)
|
||||
return;
|
||||
|
||||
// Check if earlier sibling was removed.
|
||||
if (aContainer == mNodeParent && aIndexInContainer < mIndexInParent) {
|
||||
--mIndexInParent;
|
||||
return;
|
||||
}
|
||||
|
||||
// check if ancestor was removed
|
||||
if (!nsContentUtils::ContentIsDescendantOf(mNode, aChild))
|
||||
return;
|
||||
|
||||
if (mBeforeNode) {
|
||||
|
||||
if (MoveForward(aRoot, aContainer, aIndexInContainer-1))
|
||||
// Try the next sibling
|
||||
nsINode *nextSibling = aPreviousSibling ? aPreviousSibling->GetNextSibling()
|
||||
: aContainer->GetFirstChild();
|
||||
|
||||
if (nextSibling) {
|
||||
mNode = nextSibling;
|
||||
return;
|
||||
}
|
||||
|
||||
// Next try siblings of ancestors
|
||||
if (MoveForward(aRoot, aContainer))
|
||||
return;
|
||||
|
||||
// No suitable node was found so try going backwards
|
||||
mBeforeNode = PR_FALSE;
|
||||
}
|
||||
|
||||
MoveBackward(aContainer, aIndexInContainer);
|
||||
MoveBackward(aContainer, aPreviousSibling);
|
||||
}
|
||||
|
||||
PRBool nsNodeIterator::NodePointer::MoveForward(nsINode *aRoot, nsINode *aParent, PRInt32 aChildNum)
|
||||
PRBool nsNodeIterator::NodePointer::MoveForward(nsINode *aRoot, nsINode *aNode)
|
||||
{
|
||||
while (1) {
|
||||
nsINode *node = aParent->GetChildAt(aChildNum+1);
|
||||
if (node) {
|
||||
mNode = node;
|
||||
mIndexInParent = aChildNum+1;
|
||||
mNodeParent = aParent;
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (aParent == aRoot)
|
||||
if (aNode == aRoot)
|
||||
break;
|
||||
|
||||
node = aParent;
|
||||
|
||||
if (node == mNode) {
|
||||
NS_ASSERTION(mNodeParent == mNode->GetNodeParent(), "Parent node incorrect in MoveForward");
|
||||
NS_ASSERTION(mIndexInParent == mNodeParent->IndexOf(mNode), "Index mismatch in MoveForward");
|
||||
|
||||
aParent = mNodeParent;
|
||||
aChildNum = mIndexInParent;
|
||||
} else {
|
||||
aParent = node->GetNodeParent();
|
||||
aChildNum = aParent->IndexOf(node);
|
||||
nsINode *sibling = aNode->GetNextSibling();
|
||||
if (sibling) {
|
||||
mNode = sibling;
|
||||
return PR_TRUE;
|
||||
}
|
||||
aNode = aNode->GetNodeParent();
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
void nsNodeIterator::NodePointer::MoveBackward(nsINode *aParent, PRInt32 aChildNum)
|
||||
void nsNodeIterator::NodePointer::MoveBackward(nsINode *aParent, nsINode *aNode)
|
||||
{
|
||||
nsINode *sibling = aParent->GetChildAt(aChildNum-1);
|
||||
mNode = aParent;
|
||||
if (sibling) {
|
||||
if (aNode) {
|
||||
do {
|
||||
mIndexInParent = aChildNum-1;
|
||||
mNodeParent = mNode;
|
||||
mNode = sibling;
|
||||
|
||||
aChildNum = mNode->GetChildCount();
|
||||
sibling = mNode->GetChildAt(aChildNum-1);
|
||||
} while (sibling);
|
||||
mNode = aNode;
|
||||
aNode = aNode->GetLastChild();
|
||||
} while (aNode);
|
||||
} else {
|
||||
mNodeParent = mNode->GetNodeParent();
|
||||
if (mNodeParent)
|
||||
mIndexInParent = mNodeParent->IndexOf(mNode);
|
||||
mNode = aParent;
|
||||
}
|
||||
}
|
||||
|
||||
@ -267,8 +238,7 @@ NS_IMETHODIMP nsNodeIterator::GetFilter(nsIDOMNodeFilter **aFilter)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aFilter);
|
||||
|
||||
nsCOMPtr<nsIDOMNodeFilter> filter = mFilter;
|
||||
filter.swap((*aFilter = nsnull));
|
||||
NS_IF_ADDREF(*aFilter = mFilter);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -364,25 +334,14 @@ NS_IMETHODIMP nsNodeIterator::GetPointerBeforeReferenceNode(PRBool *aBeforeNode)
|
||||
* nsIMutationObserver interface
|
||||
*/
|
||||
|
||||
void nsNodeIterator::ContentInserted(nsIDocument *aDocument,
|
||||
nsIContent *aContainer,
|
||||
nsIContent *aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
{
|
||||
nsINode *container = NODE_FROM(aContainer, aDocument);
|
||||
|
||||
mPointer.AdjustAfterInsertion(mRoot, container, aIndexInContainer);
|
||||
mWorkingPointer.AdjustAfterInsertion(mRoot, container, aIndexInContainer);
|
||||
}
|
||||
|
||||
|
||||
void nsNodeIterator::ContentRemoved(nsIDocument *aDocument,
|
||||
nsIContent *aContainer,
|
||||
nsIContent *aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
PRInt32 aIndexInContainer,
|
||||
nsIContent *aPreviousSibling)
|
||||
{
|
||||
nsINode *container = NODE_FROM(aContainer, aDocument);
|
||||
|
||||
mPointer.AdjustAfterRemoval(mRoot, container, aChild, aIndexInContainer);
|
||||
mWorkingPointer.AdjustAfterRemoval(mRoot, container, aChild, aIndexInContainer);
|
||||
mPointer.AdjustAfterRemoval(mRoot, container, aChild, aPreviousSibling);
|
||||
mWorkingPointer.AdjustAfterRemoval(mRoot, container, aChild, aPreviousSibling);
|
||||
}
|
||||
|
@ -67,7 +67,6 @@ public:
|
||||
PRBool aExpandEntityReferences);
|
||||
virtual ~nsNodeIterator();
|
||||
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsNodeIterator, nsIDOMNodeIterator)
|
||||
@ -81,22 +80,15 @@ private:
|
||||
PRBool MoveToNext(nsINode *aRoot);
|
||||
PRBool MoveToPrevious(nsINode *aRoot);
|
||||
|
||||
PRBool MoveForward(nsINode *aRoot, nsINode *aParent, PRInt32 aChildNum);
|
||||
void MoveBackward(nsINode *aParent, PRInt32 aChildNum);
|
||||
PRBool MoveForward(nsINode *aRoot, nsINode *aNode);
|
||||
void MoveBackward(nsINode *aParent, nsINode *aNode);
|
||||
|
||||
void AdjustAfterInsertion(nsINode *aRoot, nsINode *aContainer, PRInt32 aIndexInContainer);
|
||||
void AdjustAfterRemoval(nsINode *aRoot, nsINode *aContainer, nsIContent *aChild, PRInt32 aIndexInContainer);
|
||||
void AdjustAfterRemoval(nsINode *aRoot, nsINode *aContainer, nsIContent *aChild, nsIContent *aPreviousSibling);
|
||||
|
||||
void Clear() { mNode = nsnull; }
|
||||
|
||||
nsINode *mNode;
|
||||
// pointer to the parent of mNode. Can be dangling if mNode is null or
|
||||
// points to the root
|
||||
nsINode *mNodeParent;
|
||||
PRBool mBeforeNode;
|
||||
// mNode's index in mNodeParent. Uninitialized if mNodeParent is null
|
||||
// or dangling (per above comment).
|
||||
PRInt32 mIndexInParent;
|
||||
};
|
||||
|
||||
inline nsresult
|
||||
|
@ -86,7 +86,6 @@ using namespace mozilla::dom;
|
||||
} while (node); \
|
||||
PR_END_MACRO
|
||||
|
||||
|
||||
void
|
||||
nsNodeUtils::CharacterDataWillChange(nsIContent* aContent,
|
||||
CharacterDataChangeInfo* aInfo)
|
||||
@ -168,7 +167,8 @@ nsNodeUtils::ContentInserted(nsINode* aContainer,
|
||||
void
|
||||
nsNodeUtils::ContentRemoved(nsINode* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
PRInt32 aIndexInContainer,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
NS_PRECONDITION(aContainer->IsNodeOfType(nsINode::eCONTENT) ||
|
||||
aContainer->IsNodeOfType(nsINode::eDOCUMENT),
|
||||
@ -186,7 +186,8 @@ nsNodeUtils::ContentRemoved(nsINode* aContainer,
|
||||
}
|
||||
|
||||
IMPL_MUTATION_NOTIFICATION(ContentRemoved, aContainer,
|
||||
(document, container, aChild, aIndexInContainer));
|
||||
(document, container, aChild, aIndexInContainer,
|
||||
aPreviousSibling));
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -126,7 +126,8 @@ public:
|
||||
*/
|
||||
static void ContentRemoved(nsINode* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer);
|
||||
PRInt32 aIndexInContainer,
|
||||
nsIContent* aPreviousSibling);
|
||||
/**
|
||||
* Send ParentChainChanged notifications to nsIMutationObservers
|
||||
* @param aContent The piece of content that had its parent changed.
|
||||
|
@ -544,7 +544,11 @@ nsObjectLoadingContent::OnStartRequest(nsIRequest *aRequest,
|
||||
// end up trying to dispatch to a nsFrameLoader, which will complain that
|
||||
// it couldn't find a way to handle application/octet-stream
|
||||
|
||||
chan->SetContentType(mContentType);
|
||||
nsCAutoString typeHint, dummy;
|
||||
NS_ParseContentType(mContentType, typeHint, dummy);
|
||||
if (!typeHint.IsEmpty()) {
|
||||
chan->SetContentType(typeHint);
|
||||
}
|
||||
} else {
|
||||
mContentType = channelType;
|
||||
}
|
||||
@ -1437,7 +1441,11 @@ nsObjectLoadingContent::LoadObject(nsIURI* aURI,
|
||||
|
||||
// MIME Type hint
|
||||
if (!aTypeHint.IsEmpty()) {
|
||||
chan->SetContentType(aTypeHint);
|
||||
nsCAutoString typeHint, dummy;
|
||||
NS_ParseContentType(aTypeHint, typeHint, dummy);
|
||||
if (!typeHint.IsEmpty()) {
|
||||
chan->SetContentType(typeHint);
|
||||
}
|
||||
}
|
||||
|
||||
// Set up the channel's principal and such, like nsDocShell::DoURILoad does
|
||||
|
@ -315,7 +315,8 @@ void
|
||||
nsRange::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
PRInt32 aIndexInContainer,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
NS_ASSERTION(mIsPositioned, "shouldn't be notified if not positioned");
|
||||
|
||||
@ -353,6 +354,8 @@ nsRange::ParentChainChanged(nsIContent *aContent)
|
||||
NS_ASSERTION(newRoot, "No valid boundary or root found!");
|
||||
NS_ASSERTION(newRoot == IsValidBoundary(mEndParent),
|
||||
"Start parent and end parent give different root!");
|
||||
// This is safe without holding a strong ref to self as long as the change
|
||||
// of mRoot is the last thing in DoSetRange.
|
||||
DoSetRange(mStartParent, mStartOffset, mEndParent, mEndOffset, newRoot);
|
||||
}
|
||||
|
||||
@ -473,6 +476,8 @@ nsRange::DoSetRange(nsINode* aStartN, PRInt32 aStartOffset,
|
||||
mEndParent = aEndN;
|
||||
mEndOffset = aEndOffset;
|
||||
mIsPositioned = !!mStartParent;
|
||||
// This needs to be the last thing this function does. See comment
|
||||
// in ParentChainChanged.
|
||||
mRoot = aRoot;
|
||||
}
|
||||
|
||||
|
@ -97,20 +97,12 @@ public:
|
||||
virtual nsresult SetStart(nsINode* aParent, PRInt32 aOffset);
|
||||
virtual nsresult SetEnd(nsINode* aParent, PRInt32 aOffset);
|
||||
virtual nsresult CloneRange(nsIRange** aNewRange) const;
|
||||
|
||||
|
||||
// nsIMutationObserver methods
|
||||
virtual void CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
CharacterDataChangeInfo* aChangeInfo);
|
||||
virtual void ContentInserted(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer);
|
||||
virtual void ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer);
|
||||
virtual void ParentChainChanged(nsIContent *aContent);
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
|
||||
NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED
|
||||
|
||||
private:
|
||||
// no copy's or assigns
|
||||
|
@ -58,7 +58,7 @@ class nsStyledElement : public nsStyledElementBase
|
||||
|
||||
protected:
|
||||
|
||||
inline nsStyledElement(nsINodeInfo *aNodeInfo)
|
||||
inline nsStyledElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsStyledElementBase(aNodeInfo)
|
||||
{}
|
||||
|
||||
|
@ -59,7 +59,7 @@ class nsAttributeTextNode : public nsTextNode,
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
nsAttributeTextNode(nsINodeInfo *aNodeInfo,
|
||||
nsAttributeTextNode(already_AddRefed<nsINodeInfo> aNodeInfo,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttrName) :
|
||||
nsTextNode(aNodeInfo),
|
||||
@ -87,7 +87,8 @@ public:
|
||||
virtual nsGenericDOMDataNode *CloneDataNode(nsINodeInfo *aNodeInfo,
|
||||
PRBool aCloneText) const
|
||||
{
|
||||
nsAttributeTextNode *it = new nsAttributeTextNode(aNodeInfo,
|
||||
nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
|
||||
nsAttributeTextNode *it = new nsAttributeTextNode(ni.forget(),
|
||||
mNameSpaceID,
|
||||
mAttrName);
|
||||
if (it && aCloneText) {
|
||||
@ -129,7 +130,7 @@ NS_NewTextNode(nsIContent** aInstancePtrResult,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsIContent *instance = new nsTextNode(ni);
|
||||
nsTextNode *instance = new nsTextNode(ni.forget());
|
||||
if (!instance) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -139,7 +140,7 @@ NS_NewTextNode(nsIContent** aInstancePtrResult,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsTextNode::nsTextNode(nsINodeInfo *aNodeInfo)
|
||||
nsTextNode::nsTextNode(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsGenericTextNode(aNodeInfo)
|
||||
{
|
||||
}
|
||||
@ -151,7 +152,7 @@ nsTextNode::~nsTextNode()
|
||||
NS_IMPL_ADDREF_INHERITED(nsTextNode, nsGenericDOMDataNode)
|
||||
NS_IMPL_RELEASE_INHERITED(nsTextNode, nsGenericDOMDataNode)
|
||||
|
||||
DOMCI_DATA(Text, nsTextNode)
|
||||
DOMCI_NODE_DATA(Text, nsTextNode)
|
||||
|
||||
// QueryInterface implementation for nsTextNode
|
||||
NS_INTERFACE_TABLE_HEAD(nsTextNode)
|
||||
@ -197,7 +198,8 @@ nsTextNode::IsNodeOfType(PRUint32 aFlags) const
|
||||
nsGenericDOMDataNode*
|
||||
nsTextNode::CloneDataNode(nsINodeInfo *aNodeInfo, PRBool aCloneText) const
|
||||
{
|
||||
nsTextNode *it = new nsTextNode(aNodeInfo);
|
||||
nsCOMPtr<nsINodeInfo> ni = aNodeInfo;
|
||||
nsTextNode *it = new nsTextNode(ni.forget());
|
||||
if (it && aCloneText) {
|
||||
it->mText = mText;
|
||||
}
|
||||
@ -281,7 +283,8 @@ NS_NewAttributeContent(nsNodeInfoManager *aNodeInfoManager,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nsAttributeTextNode* textNode = new nsAttributeTextNode(ni, aNameSpaceID,
|
||||
nsAttributeTextNode* textNode = new nsAttributeTextNode(ni.forget(),
|
||||
aNameSpaceID,
|
||||
aAttrName);
|
||||
if (!textNode) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
@ -341,15 +344,12 @@ nsAttributeTextNode::AttributeChanged(nsIDocument* aDocument,
|
||||
{
|
||||
if (aNameSpaceID == mNameSpaceID && aAttribute == mAttrName &&
|
||||
aContent == mGrandparent) {
|
||||
// Since UpdateText notifies, do it asynchronously. Note that if we get
|
||||
// unbound while the event is up that's ok -- we'll just have no
|
||||
// grandparent when it fires, and will do nothing.
|
||||
// XXXbz ideally we'd either process this on layout flushes or do it right
|
||||
// after nsIMutationObserver notifications are over or something, instead
|
||||
// of doing it fully async.
|
||||
// Since UpdateText notifies, do it when it's safe to run script. Note
|
||||
// that if we get unbound while the event is up that's ok -- we'll just
|
||||
// have no grandparent when it fires, and will do nothing.
|
||||
void (nsAttributeTextNode::*update)() = &nsAttributeTextNode::UpdateText;
|
||||
nsCOMPtr<nsIRunnable> ev = NS_NewRunnableMethod(this, update);
|
||||
NS_DispatchToCurrentThread(ev);
|
||||
nsContentUtils::AddScriptRunner(ev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ class nsTextNode : public nsGenericTextNode,
|
||||
public nsIDOMText
|
||||
{
|
||||
public:
|
||||
nsTextNode(nsINodeInfo *aNodeInfo);
|
||||
nsTextNode(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
virtual ~nsTextNode();
|
||||
|
||||
// nsISupports
|
||||
@ -78,6 +78,8 @@ public:
|
||||
nsresult BindToAttribute(nsIAttribute* aAttr);
|
||||
nsresult UnbindFromAttribute();
|
||||
|
||||
virtual nsXPCClassInfo* GetClassInfo();
|
||||
|
||||
#ifdef DEBUG
|
||||
virtual void List(FILE* out, PRInt32 aIndent) const;
|
||||
virtual void DumpContent(FILE* out, PRInt32 aIndent, PRBool aDumpAll) const;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=4 et sw=4 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
|
||||
@ -22,6 +22,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <sicking@bigfoot.com> (Original Author)
|
||||
* Craig Topper <craig.topper@gmail.com>
|
||||
*
|
||||
* 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"),
|
||||
@ -47,9 +48,6 @@
|
||||
#include "nsIDOMNodeFilter.h"
|
||||
#include "nsDOMError.h"
|
||||
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
/*
|
||||
@ -61,8 +59,7 @@ nsTreeWalker::nsTreeWalker(nsINode *aRoot,
|
||||
nsIDOMNodeFilter *aFilter,
|
||||
PRBool aExpandEntityReferences) :
|
||||
nsTraversal(aRoot, aWhatToShow, aFilter, aExpandEntityReferences),
|
||||
mCurrentNode(aRoot),
|
||||
mPossibleIndexesPos(-1)
|
||||
mCurrentNode(aRoot)
|
||||
{
|
||||
}
|
||||
|
||||
@ -119,8 +116,7 @@ NS_IMETHODIMP nsTreeWalker::GetFilter(nsIDOMNodeFilter * *aFilter)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aFilter);
|
||||
|
||||
nsCOMPtr<nsIDOMNodeFilter> filter = mFilter;
|
||||
filter.swap((*aFilter = nsnull));
|
||||
NS_IF_ADDREF(*aFilter = mFilter);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -152,8 +148,6 @@ NS_IMETHODIMP nsTreeWalker::SetCurrentNode(nsIDOMNode * aCurrentNode)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mCurrentNode = do_QueryInterface(aCurrentNode);
|
||||
mPossibleIndexes.Clear();
|
||||
mPossibleIndexesPos = -1;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -166,16 +160,13 @@ NS_IMETHODIMP nsTreeWalker::SetCurrentNode(nsIDOMNode * aCurrentNode)
|
||||
NS_IMETHODIMP nsTreeWalker::ParentNode(nsIDOMNode **_retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
|
||||
|
||||
nsresult rv;
|
||||
|
||||
PRInt32 indexPos = mPossibleIndexesPos;
|
||||
nsCOMPtr<nsINode> node = mCurrentNode;
|
||||
|
||||
|
||||
while (node && node != mRoot) {
|
||||
node = node->GetNodeParent();
|
||||
|
||||
indexPos--;
|
||||
|
||||
if (node) {
|
||||
PRInt16 filtered;
|
||||
@ -183,8 +174,6 @@ NS_IMETHODIMP nsTreeWalker::ParentNode(nsIDOMNode **_retval)
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT) {
|
||||
mCurrentNode = node;
|
||||
mPossibleIndexesPos = indexPos >= 0 ? indexPos : -1;
|
||||
|
||||
return CallQueryInterface(node, _retval);
|
||||
}
|
||||
}
|
||||
@ -196,374 +185,260 @@ NS_IMETHODIMP nsTreeWalker::ParentNode(nsIDOMNode **_retval)
|
||||
/* nsIDOMNode firstChild (); */
|
||||
NS_IMETHODIMP nsTreeWalker::FirstChild(nsIDOMNode **_retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
|
||||
nsCOMPtr<nsINode> result;
|
||||
nsresult rv = FirstChildOf(mCurrentNode,
|
||||
PR_FALSE,
|
||||
mPossibleIndexesPos + 1,
|
||||
getter_AddRefs(result));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return result ? CallQueryInterface(result, _retval) : NS_OK;
|
||||
return FirstChildInternal(PR_FALSE, _retval);
|
||||
}
|
||||
|
||||
/* nsIDOMNode lastChild (); */
|
||||
NS_IMETHODIMP nsTreeWalker::LastChild(nsIDOMNode **_retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
|
||||
nsCOMPtr<nsINode> result;
|
||||
nsresult rv = FirstChildOf(mCurrentNode,
|
||||
PR_TRUE,
|
||||
mPossibleIndexesPos + 1,
|
||||
getter_AddRefs(result));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return result ? CallQueryInterface(result, _retval) : NS_OK;
|
||||
return FirstChildInternal(PR_TRUE, _retval);
|
||||
}
|
||||
|
||||
/* nsIDOMNode previousSibling (); */
|
||||
NS_IMETHODIMP nsTreeWalker::PreviousSibling(nsIDOMNode **_retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
|
||||
nsCOMPtr<nsINode> result;
|
||||
nsresult rv = NextSiblingOf(mCurrentNode,
|
||||
PR_TRUE,
|
||||
mPossibleIndexesPos,
|
||||
getter_AddRefs(result));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return result ? CallQueryInterface(result, _retval) : NS_OK;
|
||||
return NextSiblingInternal(PR_TRUE, _retval);
|
||||
}
|
||||
|
||||
/* nsIDOMNode nextSibling (); */
|
||||
NS_IMETHODIMP nsTreeWalker::NextSibling(nsIDOMNode **_retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
|
||||
nsCOMPtr<nsINode> result;
|
||||
nsresult rv = NextSiblingOf(mCurrentNode,
|
||||
PR_FALSE,
|
||||
mPossibleIndexesPos,
|
||||
getter_AddRefs(result));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return result ? CallQueryInterface(result, _retval) : NS_OK;
|
||||
return NextSiblingInternal(PR_FALSE, _retval);
|
||||
}
|
||||
|
||||
/* nsIDOMNode previousNode (); */
|
||||
NS_IMETHODIMP nsTreeWalker::PreviousNode(nsIDOMNode **_retval)
|
||||
{
|
||||
nsresult rv;
|
||||
PRInt16 filtered;
|
||||
|
||||
*_retval = nsnull;
|
||||
|
||||
nsCOMPtr<nsINode> result;
|
||||
nsresult rv = NextInDocumentOrderOf(mCurrentNode,
|
||||
PR_TRUE,
|
||||
mPossibleIndexesPos,
|
||||
getter_AddRefs(result));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsINode> node = mCurrentNode;
|
||||
|
||||
return result ? CallQueryInterface(result, _retval) : NS_OK;
|
||||
while (node != mRoot) {
|
||||
while (nsINode *previousSibling = node->GetPreviousSibling()) {
|
||||
node = previousSibling;
|
||||
|
||||
rv = TestNode(node, &filtered);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsINode *lastChild;
|
||||
while (filtered != nsIDOMNodeFilter::FILTER_REJECT &&
|
||||
(lastChild = node->GetLastChild())) {
|
||||
node = lastChild;
|
||||
rv = TestNode(node, &filtered);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT) {
|
||||
mCurrentNode = node;
|
||||
return CallQueryInterface(node, _retval);
|
||||
}
|
||||
}
|
||||
|
||||
if (node == mRoot)
|
||||
break;
|
||||
|
||||
node = node->GetNodeParent();
|
||||
if (!node)
|
||||
break;
|
||||
|
||||
rv = TestNode(node, &filtered);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT) {
|
||||
mCurrentNode = node;
|
||||
return CallQueryInterface(node, _retval);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsIDOMNode nextNode (); */
|
||||
NS_IMETHODIMP nsTreeWalker::NextNode(nsIDOMNode **_retval)
|
||||
{
|
||||
nsresult rv;
|
||||
PRInt16 filtered = nsIDOMNodeFilter::FILTER_ACCEPT; // pre-init for inner loop
|
||||
|
||||
*_retval = nsnull;
|
||||
|
||||
nsCOMPtr<nsINode> result;
|
||||
nsresult rv = NextInDocumentOrderOf(mCurrentNode,
|
||||
PR_FALSE,
|
||||
mPossibleIndexesPos,
|
||||
getter_AddRefs(result));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsINode> node = mCurrentNode;
|
||||
|
||||
return result ? CallQueryInterface(result, _retval) : NS_OK;
|
||||
while (1) {
|
||||
|
||||
nsINode *firstChild;
|
||||
while (filtered != nsIDOMNodeFilter::FILTER_REJECT &&
|
||||
(firstChild = node->GetFirstChild())) {
|
||||
node = firstChild;
|
||||
|
||||
rv = TestNode(node, &filtered);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT) {
|
||||
// Node found
|
||||
mCurrentNode = node;
|
||||
return CallQueryInterface(node, _retval);
|
||||
}
|
||||
}
|
||||
|
||||
nsINode *sibling = nsnull;
|
||||
nsINode *temp = node;
|
||||
do {
|
||||
if (temp == mRoot)
|
||||
break;
|
||||
|
||||
sibling = temp->GetNextSibling();
|
||||
if (sibling)
|
||||
break;
|
||||
|
||||
temp = temp->GetNodeParent();
|
||||
} while (temp);
|
||||
|
||||
if (!sibling)
|
||||
break;
|
||||
|
||||
node = sibling;
|
||||
|
||||
// Found a sibling. Either ours or ancestor's
|
||||
rv = TestNode(node, &filtered);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT) {
|
||||
// Node found
|
||||
mCurrentNode = node;
|
||||
return CallQueryInterface(node, _retval);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* nsTreeWalker helper functions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Finds the first child of aNode and returns it. If a child is
|
||||
* found, mCurrentNode is set to that child.
|
||||
* @param aNode Node to search for children.
|
||||
* @param aReversed Reverses search to find the last child instead
|
||||
* of first.
|
||||
* @param aIndexPos Position of aNode in mPossibleIndexes.
|
||||
* Implements FirstChild and LastChild which only vary in which direction
|
||||
* they search.
|
||||
* @param aReversed Controls whether we search forwards or backwards
|
||||
* @param _retval Returned node. Null if no child is found
|
||||
* @returns Errorcode
|
||||
*/
|
||||
nsresult
|
||||
nsTreeWalker::FirstChildOf(nsINode* aNode,
|
||||
PRBool aReversed,
|
||||
PRInt32 aIndexPos,
|
||||
nsINode** _retval)
|
||||
{
|
||||
*_retval = nsnull;
|
||||
PRInt32 start = aReversed ? (PRInt32)aNode->GetChildCount() : -1;
|
||||
|
||||
return ChildOf(aNode, start, aReversed, aIndexPos, _retval);
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds the following sibling of aNode and returns it. If a sibling
|
||||
* is found, mCurrentNode is set to that node.
|
||||
* @param aNode Node to start search at.
|
||||
* @param aReversed Reverses search to find the previous sibling
|
||||
* instead of next.
|
||||
* @param aIndexPos Position of aNode in mPossibleIndexes.
|
||||
* @param _retval Returned node. Null if no sibling is found
|
||||
* @returns Errorcode
|
||||
*/
|
||||
nsresult
|
||||
nsTreeWalker::NextSiblingOf(nsINode* aNode,
|
||||
PRBool aReversed,
|
||||
PRInt32 aIndexPos,
|
||||
nsINode** _retval)
|
||||
nsresult nsTreeWalker::FirstChildInternal(PRBool aReversed, nsIDOMNode **_retval)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsINode> node = aNode;
|
||||
PRInt16 filtered;
|
||||
PRInt32 childNum;
|
||||
|
||||
if (node == mRoot) {
|
||||
*_retval = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
nsCOMPtr<nsINode> parent = node->GetNodeParent();
|
||||
|
||||
if (!parent)
|
||||
break;
|
||||
|
||||
childNum = IndexOf(parent, node, aIndexPos);
|
||||
NS_ENSURE_TRUE(childNum >= 0, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// Search siblings
|
||||
rv = ChildOf(parent, childNum, aReversed, aIndexPos, _retval);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (*_retval)
|
||||
return NS_OK;
|
||||
|
||||
// Is parent the root?
|
||||
if (parent == mRoot)
|
||||
break;
|
||||
|
||||
// Is parent transparent in filtered view?
|
||||
rv = TestNode(parent, &filtered);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT)
|
||||
break;
|
||||
|
||||
node = parent;
|
||||
aIndexPos = aIndexPos < 0 ? -1 : aIndexPos-1;
|
||||
}
|
||||
|
||||
*_retval = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds the next node in document order of aNode and returns it.
|
||||
* If a node is found, mCurrentNode is set to that node.
|
||||
* @param aNode Node to start search at.
|
||||
* @param aReversed Reverses search to find the preceding node
|
||||
* instead of next.
|
||||
* @param aIndexPos Position of aNode in mPossibleIndexes.
|
||||
* @param _retval Returned node. Null if no node is found
|
||||
* @returns Errorcode
|
||||
*/
|
||||
nsresult
|
||||
nsTreeWalker::NextInDocumentOrderOf(nsINode* aNode,
|
||||
PRBool aReversed,
|
||||
PRInt32 aIndexPos,
|
||||
nsINode** _retval)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsINode> node = aReversed ? mCurrentNode->GetLastChild()
|
||||
: mCurrentNode->GetFirstChild();
|
||||
|
||||
if (!aReversed) {
|
||||
rv = FirstChildOf(aNode, aReversed, aIndexPos+1, _retval);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (*_retval)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aNode == mRoot){
|
||||
*_retval = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsINode> node = aNode;
|
||||
nsCOMPtr<nsINode> currentNodeBackup = mCurrentNode;
|
||||
PRInt16 filtered;
|
||||
PRInt32 childNum;
|
||||
|
||||
while (1) {
|
||||
// Get our index in the parent
|
||||
nsCOMPtr<nsINode> parent = node->GetNodeParent();
|
||||
if (!parent)
|
||||
break;
|
||||
|
||||
childNum = IndexOf(parent, node, aIndexPos);
|
||||
NS_ENSURE_TRUE(childNum >= 0, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// Search siblings
|
||||
nsCOMPtr<nsINode> sibling;
|
||||
rv = ChildOf(parent, childNum, aReversed, aIndexPos,
|
||||
getter_AddRefs(sibling));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (sibling) {
|
||||
if (aReversed) {
|
||||
// in reversed walking we first test if there are
|
||||
// any children. I don't like this piece of code :(
|
||||
nsCOMPtr<nsINode> child = sibling;
|
||||
while (child) {
|
||||
sibling = child;
|
||||
rv = FirstChildOf(sibling,
|
||||
PR_TRUE,
|
||||
aIndexPos,
|
||||
getter_AddRefs(child));
|
||||
if (NS_FAILED(rv)) {
|
||||
// ChildOf set mCurrentNode and then something
|
||||
// failed. Restore the old value before returning
|
||||
mCurrentNode = currentNodeBackup;
|
||||
mPossibleIndexesPos = -1;
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
*_retval = sibling;
|
||||
NS_ADDREF(*_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
aIndexPos = aIndexPos < 0 ? -1 : aIndexPos-1;
|
||||
|
||||
if (aReversed) {
|
||||
// Is parent transparent in filtered view?
|
||||
rv = TestNode(parent, &filtered);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT) {
|
||||
mCurrentNode = parent;
|
||||
mPossibleIndexesPos = aIndexPos;
|
||||
*_retval = parent;
|
||||
NS_ADDREF(*_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Is parent the root?
|
||||
if (parent == mRoot)
|
||||
break;
|
||||
|
||||
node = parent;
|
||||
}
|
||||
|
||||
*_retval = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds the first child of aNode after child N and returns it. If a
|
||||
* child is found, mCurrentNode is set to that child
|
||||
* @param aNode Node to search for children
|
||||
* @param childNum Child number to start search from. The child with
|
||||
* this number is not searched
|
||||
* @param aReversed Reverses search to find the last child instead
|
||||
* of first
|
||||
* @param aIndexPos Position of aNode in mPossibleIndexes
|
||||
* @param _retval Returned node. Null if no child is found
|
||||
* @returns Errorcode
|
||||
*/
|
||||
nsresult
|
||||
nsTreeWalker::ChildOf(nsINode* aNode,
|
||||
PRInt32 childNum,
|
||||
PRBool aReversed,
|
||||
PRInt32 aIndexPos,
|
||||
nsINode** _retval)
|
||||
{
|
||||
PRInt16 filtered;
|
||||
nsresult rv;
|
||||
|
||||
PRInt32 dir = aReversed ? -1 : 1;
|
||||
|
||||
// Step through all children
|
||||
PRInt32 i = childNum;
|
||||
while (1) {
|
||||
i += dir;
|
||||
nsCOMPtr<nsINode> child = aNode->GetChildAt(i);
|
||||
if (!child) {
|
||||
break;
|
||||
}
|
||||
|
||||
rv = TestNode(child, &filtered);
|
||||
while (node) {
|
||||
rv = TestNode(node, &filtered);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
switch (filtered) {
|
||||
case nsIDOMNodeFilter::FILTER_ACCEPT:
|
||||
// Child found
|
||||
mCurrentNode = child;
|
||||
mPossibleIndexesPos = aIndexPos;
|
||||
*_retval = child;
|
||||
NS_ADDREF(*_retval);
|
||||
|
||||
SetChildIndex(aIndexPos, i);
|
||||
|
||||
return NS_OK;
|
||||
|
||||
case nsIDOMNodeFilter::FILTER_SKIP:
|
||||
// Search children
|
||||
rv = FirstChildOf(child, aReversed, aIndexPos+1, _retval);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (*_retval) {
|
||||
SetChildIndex(aIndexPos, i);
|
||||
return NS_OK;
|
||||
// Node found
|
||||
mCurrentNode = node;
|
||||
return CallQueryInterface(node, _retval);
|
||||
case nsIDOMNodeFilter::FILTER_SKIP: {
|
||||
nsINode *child = aReversed ? node->GetLastChild()
|
||||
: node->GetFirstChild();
|
||||
if (child) {
|
||||
node = child;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIDOMNodeFilter::FILTER_REJECT:
|
||||
// Keep searching
|
||||
break;
|
||||
|
||||
default:
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
do {
|
||||
nsINode *sibling = aReversed ? node->GetPreviousSibling()
|
||||
: node->GetNextSibling();
|
||||
if (sibling) {
|
||||
node = sibling;
|
||||
break;
|
||||
}
|
||||
nsINode *parent = node->GetNodeParent();
|
||||
|
||||
if (!parent || parent == mRoot || parent == mCurrentNode) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} while (node);
|
||||
}
|
||||
|
||||
*_retval = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gets the child index of a node within its parent. Gets a possible index
|
||||
* from mPossibleIndexes to gain speed. If the value in mPossibleIndexes
|
||||
* isn't correct it'll get the index the usual way
|
||||
* @param aParent in which to get the index
|
||||
* @param aChild node to get the index of
|
||||
* @param aIndexPos position in mPossibleIndexes that contains the possible.
|
||||
* index
|
||||
* @returns resulting index
|
||||
* Implements NextSibling and PreviousSibling which only vary in which
|
||||
* direction they search.
|
||||
* @param aReversed Controls whether we search forwards or backwards
|
||||
* @param _retval Returned node. Null if no child is found
|
||||
* @returns Errorcode
|
||||
*/
|
||||
PRInt32 nsTreeWalker::IndexOf(nsINode* aParent,
|
||||
nsINode* aChild,
|
||||
PRInt32 aIndexPos)
|
||||
nsresult nsTreeWalker::NextSiblingInternal(PRBool aReversed, nsIDOMNode **_retval)
|
||||
|
||||
{
|
||||
if (aIndexPos >= 0 && aIndexPos < PRInt32(mPossibleIndexes.Length())) {
|
||||
PRInt32 possibleIndex = mPossibleIndexes.ElementAt(aIndexPos);
|
||||
if (aChild == aParent->GetChildAt(possibleIndex)) {
|
||||
return possibleIndex;
|
||||
nsresult rv;
|
||||
PRInt16 filtered;
|
||||
|
||||
*_retval = nsnull;
|
||||
|
||||
nsCOMPtr<nsINode> node = mCurrentNode;
|
||||
|
||||
if (node == mRoot)
|
||||
return NS_OK;
|
||||
|
||||
while (1) {
|
||||
nsCOMPtr<nsINode> sibling = aReversed ? node->GetPreviousSibling()
|
||||
: node->GetNextSibling();
|
||||
|
||||
while (sibling) {
|
||||
rv = TestNode(sibling, &filtered);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
switch (filtered) {
|
||||
case nsIDOMNodeFilter::FILTER_ACCEPT:
|
||||
// Node found
|
||||
mCurrentNode = sibling;
|
||||
return CallQueryInterface(sibling, _retval);
|
||||
case nsIDOMNodeFilter::FILTER_SKIP: {
|
||||
nsINode *firstChild = aReversed ? sibling->GetLastChild()
|
||||
: sibling->GetFirstChild();
|
||||
if (firstChild) {
|
||||
sibling = firstChild;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case nsIDOMNodeFilter::FILTER_REJECT:
|
||||
// Keep searching
|
||||
break;
|
||||
}
|
||||
sibling = aReversed ? sibling->GetPreviousSibling()
|
||||
: sibling->GetNextSibling();
|
||||
}
|
||||
|
||||
node = node->GetNodeParent();
|
||||
|
||||
if (!node || node == mRoot)
|
||||
break;
|
||||
|
||||
// Is parent transparent in filtered view?
|
||||
rv = TestNode(node, &filtered);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT)
|
||||
break;
|
||||
}
|
||||
|
||||
return aParent->IndexOf(aChild);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* vim: set ts=4 et sw=4 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
|
||||
@ -22,6 +22,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <sicking@bigfoot.com> (Original Author)
|
||||
* Craig Topper <craig.topper@gmail.com>
|
||||
*
|
||||
* 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"),
|
||||
@ -70,108 +71,24 @@ public:
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsINode> mCurrentNode;
|
||||
|
||||
|
||||
/*
|
||||
* Array with all child indexes up the tree. This should only be
|
||||
* considered a hint and the value could be wrong.
|
||||
*/
|
||||
nsAutoTArray<PRInt32, 8> mPossibleIndexes;
|
||||
|
||||
/*
|
||||
* Position of mCurrentNode in mPossibleIndexes
|
||||
*/
|
||||
PRInt32 mPossibleIndexesPos;
|
||||
|
||||
/*
|
||||
* Finds the first child of aNode and returns it. If a child is
|
||||
* found, mCurrentNode is set to that child.
|
||||
* @param aNode Node to search for children.
|
||||
* @param aReversed Reverses search to find the last child instead
|
||||
* of first.
|
||||
* @param aIndexPos Position of aNode in mPossibleIndexes.
|
||||
* Implements FirstChild and LastChild which only vary in which direction
|
||||
* they search.
|
||||
* @param aReversed Controls whether we search forwards or backwards
|
||||
* @param _retval Returned node. Null if no child is found
|
||||
* @returns Errorcode
|
||||
*/
|
||||
nsresult FirstChildOf(nsINode* aNode,
|
||||
PRBool aReversed,
|
||||
PRInt32 aIndexPos,
|
||||
nsINode** _retval);
|
||||
nsresult FirstChildInternal(PRBool aReversed, nsIDOMNode **_retval);
|
||||
|
||||
/*
|
||||
* Finds the following sibling of aNode and returns it. If a sibling
|
||||
* is found, mCurrentNode is set to that node.
|
||||
* @param aNode Node to start search at.
|
||||
* @param aReversed Reverses search to find the previous sibling
|
||||
* instead of next.
|
||||
* @param aIndexPos Position of aNode in mPossibleIndexes.
|
||||
* @param _retval Returned node. Null if no sibling is found
|
||||
* @returns Errorcode
|
||||
*/
|
||||
nsresult NextSiblingOf(nsINode* aNode,
|
||||
PRBool aReversed,
|
||||
PRInt32 aIndexPos,
|
||||
nsINode** _retval);
|
||||
|
||||
/*
|
||||
* Finds the next node in document order of aNode and returns it.
|
||||
* If a node is found, mCurrentNode is set to that node.
|
||||
* @param aNode Node to start search at.
|
||||
* @param aReversed Reverses search to find the preceding node
|
||||
* instead of next.
|
||||
* @param aIndexPos Position of aNode in mPossibleIndexes.
|
||||
* @param _retval Returned node. Null if no node is found
|
||||
* @returns Errorcode
|
||||
*/
|
||||
nsresult NextInDocumentOrderOf(nsINode* aNode,
|
||||
PRBool aReversed,
|
||||
PRInt32 aIndexPos,
|
||||
nsINode** _retval);
|
||||
|
||||
/*
|
||||
* Finds the first child of aNode after child N and returns it. If a
|
||||
* child is found, mCurrentNode is set to that child
|
||||
* @param aNode Node to search for children
|
||||
* @param childNum Child number to start search from. The child with
|
||||
* this number is not searched
|
||||
* @param aReversed Reverses search to find the last child instead
|
||||
* of first
|
||||
* @param aIndexPos Position of aNode in mPossibleIndexes
|
||||
* Implements NextSibling and PreviousSibling which only vary in which
|
||||
* direction they search.
|
||||
* @param aReversed Controls whether we search forwards or backwards
|
||||
* @param _retval Returned node. Null if no child is found
|
||||
* @returns Errorcode
|
||||
*/
|
||||
nsresult ChildOf(nsINode* aNode,
|
||||
PRInt32 childNum,
|
||||
PRBool aReversed,
|
||||
PRInt32 aIndexPos,
|
||||
nsINode** _retval);
|
||||
|
||||
/*
|
||||
* Gets the child index of a node within its parent. Gets a possible index
|
||||
* from mPossibleIndexes to gain speed. If the value in mPossibleIndexes
|
||||
* isn't correct it'll get the index the usual way.
|
||||
* @param aParent in which to get the index
|
||||
* @param aChild node to get the index of
|
||||
* @param aIndexPos position in mPossibleIndexes that contains the possible.
|
||||
* index
|
||||
* @returns resulting index
|
||||
*/
|
||||
PRInt32 IndexOf(nsINode* aParent,
|
||||
nsINode* aChild,
|
||||
PRInt32 aIndexPos);
|
||||
|
||||
/*
|
||||
* Sets the child index at the specified level. It doesn't matter if this
|
||||
* fails since mPossibleIndexes should only be considered a hint
|
||||
* @param aIndexPos position in mPossibleIndexes to set
|
||||
* @param aChildIndex child index at specified position
|
||||
*/
|
||||
void SetChildIndex(PRInt32 aIndexPos, PRInt32 aChildIndex)
|
||||
{
|
||||
if (aIndexPos >= 0 &&
|
||||
mPossibleIndexes.EnsureLengthAtLeast(aIndexPos+1)) {
|
||||
mPossibleIndexes.ElementAt(aIndexPos) = aChildIndex;
|
||||
}
|
||||
}
|
||||
nsresult NextSiblingInternal(PRBool aReversed, nsIDOMNode **_retval);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -241,12 +241,14 @@ public:
|
||||
nsresult Disconnect();
|
||||
|
||||
// These are called always on the main thread (they dispatch themselves).
|
||||
// ATTENTION, this method when called can release both the WebSocket object
|
||||
// (i.e. mOwner) and its connection (i.e. *this*) if there are no strong event
|
||||
// listeners.
|
||||
// ATTENTION, these method when called can release both the WebSocket object
|
||||
// (i.e. mOwner) and its connection (i.e. *this*).
|
||||
DECL_RUNNABLE_ON_MAIN_THREAD_METHOD(Close)
|
||||
DECL_RUNNABLE_ON_MAIN_THREAD_METHOD(FailConnection)
|
||||
|
||||
PRBool HasOutgoingMessages()
|
||||
{ return mOutgoingMessages.GetSize() != 0; }
|
||||
|
||||
PRBool ClosedCleanly() { return mClosedCleanly; }
|
||||
|
||||
nsresult PostMessage(const nsString& aMessage);
|
||||
@ -311,8 +313,6 @@ private:
|
||||
const PRUnichar *aError,
|
||||
const PRUnichar **aFormatStrings,
|
||||
PRUint32 aFormatStringsLen);
|
||||
PRBool SentAlreadyTheCloseFrame()
|
||||
{ return mPostedCloseFrame && mOutgoingMessages.GetSize() == 0; }
|
||||
|
||||
// auth specific methods
|
||||
DECL_RUNNABLE_ON_MAIN_THREAD_METHOD(ProcessAuthentication)
|
||||
@ -327,6 +327,7 @@ private:
|
||||
DECL_RUNNABLE_ON_MAIN_THREAD_METHOD(DispatchNewMessage)
|
||||
DECL_RUNNABLE_ON_MAIN_THREAD_METHOD(Retry)
|
||||
DECL_RUNNABLE_ON_MAIN_THREAD_METHOD(ResolveNextProxyAndConnect)
|
||||
DECL_RUNNABLE_ON_MAIN_THREAD_METHOD(UpdateMustKeepAlive)
|
||||
|
||||
// called to cause the underlying socket to start speaking SSL
|
||||
nsresult ProxyStartSSL();
|
||||
@ -400,6 +401,7 @@ private:
|
||||
PRPackedBool mAuthenticating;
|
||||
|
||||
PRPackedBool mPostedCloseFrame;
|
||||
PRPackedBool mSentCloseFrame;
|
||||
PRPackedBool mClosedCleanly;
|
||||
|
||||
/**
|
||||
@ -658,6 +660,7 @@ nsWebSocketEstablishedConnection::nsWebSocketEstablishedConnection() :
|
||||
mFailureStatus(NS_OK),
|
||||
mAuthenticating(PR_FALSE),
|
||||
mPostedCloseFrame(PR_FALSE),
|
||||
mSentCloseFrame(PR_FALSE),
|
||||
mClosedCleanly(PR_FALSE),
|
||||
mStatus(CONN_NOT_CONNECTED)
|
||||
{
|
||||
@ -710,6 +713,8 @@ nsWebSocketEstablishedConnection::PostData(nsCString *aBuffer,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
UpdateMustKeepAlive();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1214,7 +1219,7 @@ nsWebSocketEstablishedConnection::HandleNewInputString(PRUint32 aStart)
|
||||
// check if it is the close frame
|
||||
if (mLengthToDiscard == 0 && frameType == START_BYTE_OF_CLOSE_FRAME) {
|
||||
mBytesInBuffer = 0;
|
||||
if (SentAlreadyTheCloseFrame()) {
|
||||
if (mSentCloseFrame) {
|
||||
mClosedCleanly = PR_TRUE;
|
||||
mStatus = CONN_CLOSED;
|
||||
} else {
|
||||
@ -2247,6 +2252,12 @@ IMPL_RUNNABLE_ON_MAIN_THREAD_METHOD_BEGIN(ResolveNextProxyAndConnect)
|
||||
}
|
||||
IMPL_RUNNABLE_ON_MAIN_THREAD_METHOD_END
|
||||
|
||||
IMPL_RUNNABLE_ON_MAIN_THREAD_METHOD_BEGIN(UpdateMustKeepAlive)
|
||||
{
|
||||
mOwner->UpdateMustKeepAlive();
|
||||
}
|
||||
IMPL_RUNNABLE_ON_MAIN_THREAD_METHOD_END
|
||||
|
||||
void
|
||||
nsWebSocketEstablishedConnection::RemoveFromLoadGroup()
|
||||
{
|
||||
@ -2695,7 +2706,6 @@ nsWebSocketEstablishedConnection::OnOutputStreamReady(nsIAsyncOutputStream *aStr
|
||||
strToSend->Length() - mBytesAlreadySentOfFirstOutString;
|
||||
PRBool currentStrHasStartFrameByte =
|
||||
(mBytesAlreadySentOfFirstOutString == 0);
|
||||
PRBool strIsMessage = (frameToSend->mType == eUTF8MessageFrame);
|
||||
|
||||
if (sizeToSend != 0) {
|
||||
PRUint32 written;
|
||||
@ -2730,7 +2740,7 @@ nsWebSocketEstablishedConnection::OnOutputStreamReady(nsIAsyncOutputStream *aStr
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
if (strIsMessage) {
|
||||
if (frameToSend->mType == eUTF8MessageFrame) {
|
||||
PRBool currentStrHasEndFrameByte =
|
||||
(mBytesAlreadySentOfFirstOutString + written ==
|
||||
strToSend->Length());
|
||||
@ -2760,17 +2770,20 @@ nsWebSocketEstablishedConnection::OnOutputStreamReady(nsIAsyncOutputStream *aStr
|
||||
}
|
||||
|
||||
// ok, send the next string
|
||||
if (frameToSend->mType == eCloseFrame) {
|
||||
mSentCloseFrame = PR_TRUE;
|
||||
}
|
||||
mOutgoingMessages.PopFront();
|
||||
delete frameToSend;
|
||||
mBytesAlreadySentOfFirstOutString = 0;
|
||||
UpdateMustKeepAlive();
|
||||
}
|
||||
|
||||
if (mOutgoingMessages.GetSize() != 0) {
|
||||
rv = mSocketOutput->AsyncWait(this, 0, 0, gWebSocketThread);
|
||||
ENSURE_SUCCESS_AND_FAIL_IF_FAILED(rv, rv);
|
||||
} else {
|
||||
if (mStatus == CONN_SENDING_ACK_CLOSE_FRAME &&
|
||||
SentAlreadyTheCloseFrame()) {
|
||||
if (mStatus == CONN_SENDING_ACK_CLOSE_FRAME && mSentCloseFrame) {
|
||||
mClosedCleanly = PR_TRUE;
|
||||
mStatus = CONN_CLOSED;
|
||||
return Close();
|
||||
@ -2833,8 +2846,9 @@ nsWebSocketEstablishedConnection::GetInterface(const nsIID &aIID,
|
||||
// nsWebSocket
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsWebSocket::nsWebSocket() : mHasStrongEventListeners(PR_FALSE),
|
||||
mCheckThereAreStrongEventListeners(PR_TRUE),
|
||||
nsWebSocket::nsWebSocket() : mKeepingAlive(PR_FALSE),
|
||||
mCheckMustKeepAlive(PR_TRUE),
|
||||
mTriggeredCloseEvent(PR_FALSE),
|
||||
mReadyState(nsIWebSocket::CONNECTING),
|
||||
mOutgoingBufferedAmount(0)
|
||||
{
|
||||
@ -3063,6 +3077,8 @@ nsWebSocket::CreateAndDispatchCloseEvent(PRBool aWasClean)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
mTriggeredCloseEvent = PR_TRUE;
|
||||
|
||||
rv = CheckInnerWindowCorrectness();
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_OK;
|
||||
@ -3138,6 +3154,7 @@ nsWebSocket::SetReadyState(PRUint16 aNewReadyState)
|
||||
rv = NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch the close event");
|
||||
mTriggeredCloseEvent = PR_TRUE;
|
||||
UpdateMustKeepAlive();
|
||||
}
|
||||
}
|
||||
@ -3251,45 +3268,71 @@ nsWebSocket::SetProtocol(const nsString& aProtocol)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Methods that keep alive the WebSocket object when there are
|
||||
// onopen/onmessage event listeners.
|
||||
// Methods that keep alive the WebSocket object when:
|
||||
// 1. the object has registered event listeners that can be triggered
|
||||
// ("strong event listeners");
|
||||
// 2. there are outgoing not sent messages.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void
|
||||
nsWebSocket::UpdateMustKeepAlive()
|
||||
{
|
||||
if (!mCheckThereAreStrongEventListeners) {
|
||||
if (!mCheckMustKeepAlive) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mHasStrongEventListeners) {
|
||||
if (!mListenerManager ||
|
||||
((mReadyState != nsIWebSocket::CONNECTING ||
|
||||
!mListenerManager->HasListenersFor(NS_LITERAL_STRING("open"))) &&
|
||||
(mReadyState == nsIWebSocket::CLOSED ||
|
||||
!mListenerManager->HasListenersFor(NS_LITERAL_STRING("message"))))) {
|
||||
mHasStrongEventListeners = PR_FALSE;
|
||||
static_cast<nsPIDOMEventTarget*>(this)->Release();
|
||||
}
|
||||
} else {
|
||||
if ((mReadyState == nsIWebSocket::CONNECTING && mListenerManager &&
|
||||
mListenerManager->HasListenersFor(NS_LITERAL_STRING("open"))) ||
|
||||
(mReadyState != nsIWebSocket::CLOSED && mListenerManager &&
|
||||
mListenerManager->HasListenersFor(NS_LITERAL_STRING("message")))) {
|
||||
mHasStrongEventListeners = PR_TRUE;
|
||||
static_cast<nsPIDOMEventTarget*>(this)->AddRef();
|
||||
PRBool shouldKeepAlive = PR_FALSE;
|
||||
|
||||
if (mListenerManager) {
|
||||
switch (mReadyState)
|
||||
{
|
||||
case nsIWebSocket::CONNECTING:
|
||||
{
|
||||
if (mListenerManager->HasListenersFor(NS_LITERAL_STRING("open")) ||
|
||||
mListenerManager->HasListenersFor(NS_LITERAL_STRING("message")) ||
|
||||
mListenerManager->HasListenersFor(NS_LITERAL_STRING("close"))) {
|
||||
shouldKeepAlive = PR_TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIWebSocket::OPEN:
|
||||
case nsIWebSocket::CLOSING:
|
||||
{
|
||||
if (mListenerManager->HasListenersFor(NS_LITERAL_STRING("message")) ||
|
||||
mListenerManager->HasListenersFor(NS_LITERAL_STRING("close")) ||
|
||||
mConnection->HasOutgoingMessages()) {
|
||||
shouldKeepAlive = PR_TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case nsIWebSocket::CLOSED:
|
||||
{
|
||||
shouldKeepAlive =
|
||||
(!mTriggeredCloseEvent &&
|
||||
mListenerManager->HasListenersFor(NS_LITERAL_STRING("close")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mKeepingAlive && !shouldKeepAlive) {
|
||||
mKeepingAlive = PR_FALSE;
|
||||
static_cast<nsPIDOMEventTarget*>(this)->Release();
|
||||
} else if (!mKeepingAlive && shouldKeepAlive) {
|
||||
mKeepingAlive = PR_TRUE;
|
||||
static_cast<nsPIDOMEventTarget*>(this)->AddRef();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsWebSocket::DontKeepAliveAnyMore()
|
||||
{
|
||||
if (mHasStrongEventListeners) {
|
||||
mCheckThereAreStrongEventListeners = PR_FALSE;
|
||||
mHasStrongEventListeners = PR_FALSE;
|
||||
if (mKeepingAlive) {
|
||||
mKeepingAlive = PR_FALSE;
|
||||
static_cast<nsPIDOMEventTarget*>(this)->Release();
|
||||
}
|
||||
mCheckMustKeepAlive = PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -3431,8 +3474,8 @@ nsWebSocket::Close()
|
||||
}
|
||||
|
||||
if (mReadyState == nsIWebSocket::CONNECTING) {
|
||||
// FailConnection() can release the object if there are no strong event
|
||||
// listeners, so we keep a reference before calling it
|
||||
// FailConnection() can release the object, so we keep a reference
|
||||
// before calling it
|
||||
nsRefPtr<nsWebSocket> kungfuDeathGrip = this;
|
||||
|
||||
mConnection->FailConnection();
|
||||
|
@ -115,12 +115,12 @@ protected:
|
||||
// called from mConnection accordingly to the situation
|
||||
void SetReadyState(PRUint16 aNewReadyState);
|
||||
|
||||
// if there are onopen or onmessage event listeners ("strong event listeners")
|
||||
// then this method keeps the object alive when js doesn't have strong
|
||||
// references to it.
|
||||
// if there are "strong event listeners" (see comment in nsWebSocket.cpp) or
|
||||
// outgoing not sent messages then this method keeps the object alive
|
||||
// when js doesn't have strong references to it.
|
||||
void UpdateMustKeepAlive();
|
||||
// Releases, if necessary, the strong event listeners. ATTENTION, when calling
|
||||
// this method the object can be released (and possibly collected).
|
||||
// ATTENTION, when calling this method the object can be released
|
||||
// (and possibly collected).
|
||||
void DontKeepAliveAnyMore();
|
||||
|
||||
nsRefPtr<nsDOMEventListenerWrapper> mOnOpenListener;
|
||||
@ -133,8 +133,9 @@ protected:
|
||||
PRPackedBool mSecure; // if true it is using SSL and the wss scheme,
|
||||
// otherwise it is using the ws scheme with no SSL
|
||||
|
||||
PRPackedBool mHasStrongEventListeners;
|
||||
PRPackedBool mCheckThereAreStrongEventListeners;
|
||||
PRPackedBool mKeepingAlive;
|
||||
PRPackedBool mCheckMustKeepAlive;
|
||||
PRPackedBool mTriggeredCloseEvent;
|
||||
|
||||
nsCString mAsciiHost; // hostname
|
||||
PRUint32 mPort;
|
||||
|
@ -403,6 +403,9 @@ _TEST_FILES2 = \
|
||||
file_websocket_wsh.py \
|
||||
file_websocket_http_resource.txt \
|
||||
test_bug574596.html \
|
||||
test_x-frame-options.html \
|
||||
file_x-frame-options_main.html \
|
||||
file_x-frame-options_page.sjs \
|
||||
$(NULL)
|
||||
|
||||
# This test fails on the Mac for some reason
|
||||
|
19
content/base/test/file_x-frame-options_main.html
Normal file
19
content/base/test/file_x-frame-options_main.html
Normal file
@ -0,0 +1,19 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>X-Frame-Options tests</title>
|
||||
<script type="text/javascript">
|
||||
// This frame loading means all subframes have either loaded or errored out. We
|
||||
// can now tell the test harness to check each subframe for the expected result.
|
||||
window.addEventListener('load', parent.testFramesLoaded, false);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<iframe id="control1" src="http://mochi.test:8888/tests/content/base/test/file_x-frame-options_page.sjs?testid=control1"></iframe><br>
|
||||
<iframe id="control2" src="http://example.com/tests/content/base/test/file_x-frame-options_page.sjs?testid=control2"></iframe><br>
|
||||
<iframe id="deny" src="http://mochi.test:8888/tests/content/base/test/file_x-frame-options_page.sjs?testid=deny&xfo=deny"></iframe><br>
|
||||
<iframe id="sameorigin1" src="http://mochi.test:8888/tests/content/base/test/file_x-frame-options_page.sjs?testid=sameorigin1&xfo=sameorigin"></iframe><br>
|
||||
<iframe id="sameorigin2" src="http://example.com/tests/content/base/test/file_x-frame-options_page.sjs?testid=sameorigin2&xfo=sameorigin"></iframe><br>
|
||||
|
||||
</body>
|
||||
</html>
|
25
content/base/test/file_x-frame-options_page.sjs
Normal file
25
content/base/test/file_x-frame-options_page.sjs
Normal file
@ -0,0 +1,25 @@
|
||||
// SJS file for X-Frame-Options mochitests
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var query = {};
|
||||
request.queryString.split('&').forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
|
||||
// X-Frame-Options header value
|
||||
if (query['xfo'] == "deny") {
|
||||
for (var i = 0 ; i < 0x7fffff ; i++) { }
|
||||
response.setHeader("X-Frame-Options", "DENY", false);
|
||||
}
|
||||
else if (query['xfo'] == "sameorigin") {
|
||||
response.setHeader("X-Frame-Options", "SAMEORIGIN", false);
|
||||
}
|
||||
|
||||
// from the test harness we'll be checking for the presence of this element
|
||||
// to test if the page loaded
|
||||
response.write("<h1 id=\"test\">" + query["testid"] + "</h1>");
|
||||
}
|
@ -437,7 +437,7 @@ window._test17 = function()
|
||||
{
|
||||
var local_ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test 17");
|
||||
local_ws._testNumber = "local17";
|
||||
current_test++;
|
||||
local_ws._testNumber = current_test++;
|
||||
|
||||
status_test17 = "started";
|
||||
|
||||
@ -510,14 +510,18 @@ window._test20 = function()
|
||||
{
|
||||
var local_ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test 20");
|
||||
local_ws._testNumber = "local20";
|
||||
current_test++;
|
||||
local_ws._testNumber = current_test++;
|
||||
|
||||
local_ws.onerror = function()
|
||||
{
|
||||
ok(false, "onerror called on test " + e.target._testNumber + "!");
|
||||
};
|
||||
|
||||
local_ws.onclose = shouldNotReceiveCloseEvent;
|
||||
local_ws.onclose = function(e)
|
||||
{
|
||||
shouldCloseCleanly(e);
|
||||
doTest(21);
|
||||
};
|
||||
|
||||
local_ws = null;
|
||||
window._test20 = null;
|
||||
@ -527,7 +531,6 @@ window._test20 = function()
|
||||
function test20()
|
||||
{
|
||||
window._test20();
|
||||
doTest(21);
|
||||
}
|
||||
|
||||
var timeoutTest21;
|
||||
@ -535,7 +538,7 @@ var timeoutTest21;
|
||||
window._test21 = function()
|
||||
{
|
||||
var local_ws = new WebSocket("ws://mochi.test:8888/tests/content/base/test/file_websocket", "test 21");
|
||||
current_test++;
|
||||
local_ws._testNumber = current_test++;
|
||||
|
||||
local_ws.onopen = function(e)
|
||||
{
|
||||
@ -563,7 +566,11 @@ window._test21 = function()
|
||||
forcegc();
|
||||
};
|
||||
|
||||
local_ws.onclose = shouldNotReceiveCloseEvent;
|
||||
local_ws.onclose = function(e)
|
||||
{
|
||||
shouldCloseCleanly(e);
|
||||
doTest(22);
|
||||
};
|
||||
|
||||
local_ws = null;
|
||||
window._test21 = null;
|
||||
@ -573,7 +580,6 @@ window._test21 = function()
|
||||
function test21()
|
||||
{
|
||||
window._test21();
|
||||
doTest(22);
|
||||
}
|
||||
|
||||
function test22()
|
||||
|
50
content/base/test/test_x-frame-options.html
Normal file
50
content/base/test/test_x-frame-options.html
Normal file
@ -0,0 +1,50 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for X-Frame-Options response header</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
|
||||
<iframe style="width:100%;height:300px;" id="harness"></iframe>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var path = "/tests/content/base/test/";
|
||||
// contains { test_frame_id : expected_result }
|
||||
var testExpectedResults = { "control1": true,
|
||||
"control2": true,
|
||||
"deny": false,
|
||||
"sameorigin1": true,
|
||||
"sameorigin2": false
|
||||
};
|
||||
|
||||
var testFramesLoaded = function() {
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
var harness = document.getElementById("harness");
|
||||
|
||||
for (var t in testExpectedResults) {
|
||||
var frame = harness.contentDocument.getElementById(t);
|
||||
// test if frame loaded by checking for a contentDocument we can access
|
||||
test = frame.contentDocument.getElementById("test");
|
||||
is(test != null, testExpectedResults[t], "test "+t);
|
||||
}
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// load the test harness
|
||||
document.getElementById("harness").src = "file_x-frame-options_main.html";
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -109,13 +109,25 @@ Canvas2D_GetStyleHelper(JSContext *cx, JSObject *obj, jsval id, jsval *vp,
|
||||
return xpc_qsStringToJsval(cx, resultString, vp);
|
||||
|
||||
case nsIDOMCanvasRenderingContext2D::CMG_STYLE_PATTERN:
|
||||
return xpc_qsXPCOMObjectToJsval(lccx, resultInterface, xpc_qsGetWrapperCache(resultInterface),
|
||||
&NS_GET_IID(nsIDOMCanvasPattern), &interfaces[k_nsIDOMCanvasPattern], vp);
|
||||
|
||||
{
|
||||
nsWrapperCache* cache = xpc_qsGetWrapperCache(resultInterface);
|
||||
qsObjectHelper helper(ToSupports(resultInterface));
|
||||
helper.SetNode(resultInterface);
|
||||
helper.SetCanonical(ToCanonicalSupports(resultInterface));
|
||||
return xpc_qsXPCOMObjectToJsval(lccx, &helper, cache,
|
||||
&NS_GET_IID(nsIDOMCanvasPattern),
|
||||
&interfaces[k_nsIDOMCanvasPattern], vp);
|
||||
}
|
||||
case nsIDOMCanvasRenderingContext2D::CMG_STYLE_GRADIENT:
|
||||
return xpc_qsXPCOMObjectToJsval(lccx, resultInterface, xpc_qsGetWrapperCache(resultInterface),
|
||||
&NS_GET_IID(nsIDOMCanvasGradient), &interfaces[k_nsIDOMCanvasGradient], vp);
|
||||
|
||||
{
|
||||
nsWrapperCache* cache = xpc_qsGetWrapperCache(resultInterface);
|
||||
qsObjectHelper helper(ToSupports(resultInterface));
|
||||
helper.SetNode(resultInterface);
|
||||
helper.SetCanonical(ToCanonicalSupports(resultInterface));
|
||||
return xpc_qsXPCOMObjectToJsval(lccx, &helper, cache,
|
||||
&NS_GET_IID(nsIDOMCanvasGradient),
|
||||
&interfaces[k_nsIDOMCanvasGradient], vp);
|
||||
}
|
||||
default:
|
||||
return xpc_qsThrowGetterSetterFailed(cx, NS_ERROR_FAILURE, JSVAL_TO_OBJECT(*vp), id);
|
||||
}
|
||||
|
@ -320,9 +320,9 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
|
||||
gl->fViewport(0, 0, mWidth, mHeight);
|
||||
gl->fClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
#ifdef USE_GLES2
|
||||
gl->fClearDepthf(0.0f);
|
||||
gl->fClearDepthf(1.0f);
|
||||
#else
|
||||
gl->fClearDepth(0.0f);
|
||||
gl->fClearDepth(1.0f);
|
||||
#endif
|
||||
gl->fClearStencil(0);
|
||||
gl->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT);
|
||||
|
@ -74,6 +74,7 @@
|
||||
|
||||
#include "nsCSSParser.h"
|
||||
#include "nsICSSStyleRule.h"
|
||||
#include "mozilla/css/Declaration.h"
|
||||
#include "nsComputedDOMStyle.h"
|
||||
#include "nsStyleSet.h"
|
||||
|
||||
@ -2243,28 +2244,36 @@ CreateFontStyleRule(const nsAString& aFont,
|
||||
nsCSSParser parser;
|
||||
NS_ENSURE_TRUE(parser, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
// aFont is to be parsed as the value of a CSS 'font' shorthand,
|
||||
// and then any line-height setting in that shorthand is to be
|
||||
// overridden with "normal". Because of the way style rules are
|
||||
// stored, it is more efficient to fabricate a text string that
|
||||
// can be processed in one go with ParseStyleAttribute than to
|
||||
// make two calls to ParseDeclaration.
|
||||
|
||||
nsAutoString styleAttr(NS_LITERAL_STRING("font:"));
|
||||
styleAttr.Append(aFont);
|
||||
styleAttr.AppendLiteral(";line-height:normal");
|
||||
nsCOMPtr<nsICSSStyleRule> rule;
|
||||
PRBool changed;
|
||||
|
||||
nsIPrincipal* principal = aNode->NodePrincipal();
|
||||
nsIDocument* document = aNode->GetOwnerDoc();
|
||||
|
||||
nsIURI* docURL = document->GetDocumentURI();
|
||||
nsIURI* baseURL = document->GetDocBaseURI();
|
||||
|
||||
nsresult rv = parser.ParseStyleAttribute(styleAttr, docURL, baseURL,
|
||||
principal, aResult);
|
||||
nsresult rv = parser.ParseStyleAttribute(EmptyString(), docURL, baseURL,
|
||||
principal, getter_AddRefs(rule));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
(*aResult)->RuleMatched();
|
||||
rv = parser.ParseProperty(eCSSProperty_font, aFont, docURL, baseURL,
|
||||
principal, rule->GetDeclaration(), &changed,
|
||||
PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = parser.ParseProperty(eCSSProperty_line_height,
|
||||
NS_LITERAL_STRING("normal"), docURL, baseURL,
|
||||
principal, rule->GetDeclaration(), &changed,
|
||||
PR_FALSE);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rule->RuleMatched();
|
||||
|
||||
rule.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -2299,6 +2308,23 @@ nsCanvasRenderingContext2D::SetFont(const nsAString& font)
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
css::Declaration *declaration = rule->GetDeclaration();
|
||||
// The easiest way to see whether we got a syntax error or whether
|
||||
// we got 'inherit' or 'initial' is to look at font-size-adjust,
|
||||
// which the shorthand resets to either 'none' or
|
||||
// '-moz-system-font'.
|
||||
// We know the declaration is not !important, so we can use
|
||||
// GetNormalBlock().
|
||||
const nsCSSValue *fsaVal =
|
||||
declaration->GetNormalBlock()->
|
||||
ValueStorageFor(eCSSProperty_font_size_adjust);
|
||||
if (!fsaVal || (fsaVal->GetUnit() != eCSSUnit_None &&
|
||||
fsaVal->GetUnit() != eCSSUnit_System_Font)) {
|
||||
// We got an all-property value or a syntax error. The spec says
|
||||
// this value must be ignored.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
rules.AppendObject(rule);
|
||||
|
||||
nsStyleSet* styleSet = presShell->StyleSet();
|
||||
@ -2367,7 +2393,13 @@ nsCanvasRenderingContext2D::SetFont(const nsAString& font)
|
||||
&style,
|
||||
presShell->GetPresContext()->GetUserFontSet());
|
||||
NS_ASSERTION(CurrentState().fontGroup, "Could not get font group");
|
||||
CurrentState().font = font;
|
||||
|
||||
// The font getter is required to be reserialized based on what we
|
||||
// parsed (including having line-height removed). (Older drafts of
|
||||
// the spec required font sizes be converted to pixels, but that no
|
||||
// longer seems to be required.)
|
||||
declaration->GetValue(eCSSProperty_font, CurrentState().font);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -66,6 +66,7 @@ _TEST_FILES_0 = \
|
||||
image_green-redirect \
|
||||
image_green-redirect^headers^ \
|
||||
test_drawImageIncomplete.html \
|
||||
test_canvas_font_setter.html \
|
||||
$(NULL)
|
||||
|
||||
# xor and lighter aren't well handled by cairo; they mostly work, but we don't want
|
||||
|
69
content/canvas/test/test_canvas_font_setter.html
Normal file
69
content/canvas/test/test_canvas_font_setter.html
Normal file
@ -0,0 +1,69 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug </title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a>
|
||||
<canvas id="display" height="200" width="200"></canvas>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
var canvas = document.getElementById("display");
|
||||
var cx = canvas.getContext("2d");
|
||||
|
||||
is(cx.font, "10px sans-serif", "initial font of canvas context");
|
||||
|
||||
cx.font = "italic 16px sans-serif";
|
||||
is(cx.font, "italic 16px sans-serif", "valid font should round-trip");
|
||||
cx.font = "bold 12px serif; background: green";
|
||||
is(cx.font, "italic 16px sans-serif", "invalid font should be ignored");
|
||||
|
||||
cx.font = "bold 12px/3.0 serif";
|
||||
is(cx.font, "bold 12px serif", "line-height should be dropped");
|
||||
cx.font = "inherit";
|
||||
is(cx.font, "bold 12px serif", "inherit should be ignored");
|
||||
cx.font = "boold 18px sans-serif";
|
||||
is(cx.font, "bold 12px serif", "syntax error should be ignored");
|
||||
cx.font = "menu";
|
||||
todo_is(cx.font, "menu", "system fonts should work");
|
||||
|
||||
function textmeas() {
|
||||
return cx.measureText("hello").width;
|
||||
}
|
||||
|
||||
cx.font = "66px serif";
|
||||
var w_at_66 = textmeas();
|
||||
cx.font = "20px serif";
|
||||
var w_at_20 = textmeas();
|
||||
ok(w_at_66 > w_at_20, "text should be wider at 66px than at 20px");
|
||||
|
||||
canvas.style.fontSize = "33px";
|
||||
cx.font = "2em serif";
|
||||
is(cx.font, "2em serif", "serialization of em");
|
||||
is(textmeas(), w_at_66, "em should be relative to canvas font size");
|
||||
canvas.style.fontSize = "16px";
|
||||
is(cx.font, "2em serif", "serialization of em");
|
||||
is(textmeas(), w_at_66,
|
||||
"em should be relative to canvas font size at time of setting");
|
||||
document.body.removeChild(canvas);
|
||||
is(cx.font, "2em serif", "serialization of em");
|
||||
is(textmeas(), w_at_66,
|
||||
"em should be relative to canvas font size at time of setting");
|
||||
canvas.style.fontSize = "33px";
|
||||
cx.font = "2em serif";
|
||||
is(cx.font, "2em serif", "serialization of em");
|
||||
is(textmeas(), w_at_20,
|
||||
"em should be relative to 10px when canvas not in document");
|
||||
document.body.appendChild(canvas);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -458,9 +458,10 @@ nsTextStateManager::ContentInserted(nsIDocument* aDocument,
|
||||
|
||||
void
|
||||
nsTextStateManager::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
PRUint32 offset = 0, childOffset = 1;
|
||||
if (NS_FAILED(nsContentEventHandler::GetFlatTextOffsetOfRange(
|
||||
|
@ -42,7 +42,7 @@
|
||||
|
||||
class nsXMLEventsElement : public nsXMLElement {
|
||||
public:
|
||||
nsXMLEventsElement(nsINodeInfo *aNodeInfo);
|
||||
nsXMLEventsElement(already_AddRefed<nsINodeInfo> aNodeInfo);
|
||||
virtual ~nsXMLEventsElement();
|
||||
NS_FORWARD_NSIDOMNODE(nsXMLElement::)
|
||||
|
||||
@ -53,7 +53,7 @@ public:
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
};
|
||||
|
||||
nsXMLEventsElement::nsXMLEventsElement(nsINodeInfo *aNodeInfo)
|
||||
nsXMLEventsElement::nsXMLEventsElement(already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
: nsXMLElement(aNodeInfo)
|
||||
{
|
||||
}
|
||||
@ -85,7 +85,8 @@ nsXMLEventsElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, nsIAtom* aPref
|
||||
NS_IMPL_ELEMENT_CLONE(nsXMLEventsElement)
|
||||
|
||||
nsresult
|
||||
NS_NewXMLEventsElement(nsIContent** aInstancePtrResult, nsINodeInfo *aNodeInfo)
|
||||
NS_NewXMLEventsElement(nsIContent** aInstancePtrResult,
|
||||
already_AddRefed<nsINodeInfo> aNodeInfo)
|
||||
{
|
||||
nsXMLEventsElement* it = new nsXMLEventsElement(aNodeInfo);
|
||||
if (!it) {
|
||||
|
@ -306,6 +306,8 @@ PRBool nsXMLEventsManager::RemoveListener(nsIContent * aContent)
|
||||
|
||||
void nsXMLEventsManager::AddListeners(nsIDocument* aDocument)
|
||||
{
|
||||
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
||||
|
||||
nsIContent *cur;
|
||||
for (int i = 0; i < mIncomplete.Count(); ++i) {
|
||||
cur = mIncomplete[i];
|
||||
@ -315,41 +317,21 @@ void nsXMLEventsManager::AddListeners(nsIDocument* aDocument)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLEventsManager::BeginUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType) {}
|
||||
void
|
||||
nsXMLEventsManager::EndUpdate(nsIDocument* aDocument, nsUpdateType aUpdateType) {}
|
||||
void
|
||||
nsXMLEventsManager::NodeWillBeDestroyed(const nsINode* aNode)
|
||||
{
|
||||
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
||||
mIncomplete.Clear();
|
||||
mListeners.Enumerate(EnumAndUnregisterListener, this);
|
||||
mListeners.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLEventsManager::BeginLoad(nsIDocument* aDocument) {}
|
||||
|
||||
void
|
||||
nsXMLEventsManager::EndLoad(nsIDocument* aDocument)
|
||||
{
|
||||
AddListeners(aDocument);
|
||||
}
|
||||
NS_IMPL_NSIDOCUMENTOBSERVER_STATE_STUB(nsXMLEventsManager)
|
||||
void
|
||||
nsXMLEventsManager::CharacterDataWillChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
CharacterDataChangeInfo* aInfo) {}
|
||||
void
|
||||
nsXMLEventsManager::CharacterDataChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
CharacterDataChangeInfo* aInfo) {}
|
||||
void
|
||||
nsXMLEventsManager::AttributeWillChange(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType) {}
|
||||
|
||||
void
|
||||
nsXMLEventsManager::AttributeChanged(nsIDocument* aDocument,
|
||||
nsIContent* aContent,
|
||||
@ -357,6 +339,8 @@ nsXMLEventsManager::AttributeChanged(nsIDocument* aDocument,
|
||||
nsIAtom* aAttribute,
|
||||
PRInt32 aModType)
|
||||
{
|
||||
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
||||
|
||||
if (aNameSpaceID == kNameSpaceID_XMLEvents &&
|
||||
(aAttribute == nsGkAtoms::event ||
|
||||
aAttribute == nsGkAtoms::handler ||
|
||||
@ -412,10 +396,11 @@ nsXMLEventsManager::ContentInserted(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLEventsManager::ContentRemoved(nsIDocument* aDocument,
|
||||
nsXMLEventsManager::ContentRemoved(nsIDocument* aDocument,
|
||||
nsIContent* aContainer,
|
||||
nsIContent* aChild,
|
||||
PRInt32 aIndexInContainer)
|
||||
PRInt32 aIndexInContainer,
|
||||
nsIContent* aPreviousSibling)
|
||||
{
|
||||
if (!aChild || !aChild->IsElement())
|
||||
return;
|
||||
@ -423,6 +408,8 @@ nsXMLEventsManager::ContentRemoved(nsIDocument* aDocument,
|
||||
//And to remember: the same observer can be referenced by many
|
||||
//XMLEventsListeners
|
||||
|
||||
nsCOMPtr<nsIMutationObserver> kungFuDeathGrip(this);
|
||||
|
||||
//If the content was an XML Events observer or handler
|
||||
mListeners.Enumerate(EnumAndSetIncomplete, aChild);
|
||||
|
||||
@ -434,14 +421,6 @@ nsXMLEventsManager::ContentRemoved(nsIDocument* aDocument,
|
||||
|
||||
PRUint32 count = aChild->GetChildCount();
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
ContentRemoved(aDocument, aChild, aChild->GetChildAt(i), i);
|
||||
ContentRemoved(aDocument, aChild, aChild->GetChildAt(i), i, aChild->GetPreviousSibling());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsXMLEventsManager::ParentChainChanged(nsIContent *aContent)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_NSIDOCUMENTOBSERVER_STYLE_STUB(nsXMLEventsManager)
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user