Merge m-i to m-c, a=merge

This commit is contained in:
Phil Ringnalda 2014-11-02 08:27:08 -08:00
commit 3bb307d604
244 changed files with 5842 additions and 5060 deletions

View File

@ -67,10 +67,6 @@ var FullScreen = {
this.showXULChrome("toolbar", !enterFS);
if (enterFS) {
if (gPrefService.getBoolPref("browser.fullscreen.autohide"))
gBrowser.mPanelContainer.addEventListener("mousemove",
this._collapseCallback, false);
document.addEventListener("keypress", this._keyToggleCallback, false);
document.addEventListener("popupshown", this._setPopupOpen, false);
document.addEventListener("popuphidden", this._setPopupOpen, false);
@ -79,9 +75,6 @@ var FullScreen = {
// mozfullscreenchange event fired, which could confuse content script.
this._shouldAnimate = !document.mozFullScreen;
this.mouseoverToggle(false);
// Autohide prefs
gPrefService.addObserver("browser.fullscreen", this, false);
}
else {
// The user may quit fullscreen during an animation
@ -185,12 +178,10 @@ var FullScreen = {
cleanup: function () {
if (window.fullScreen) {
gBrowser.mPanelContainer.removeEventListener("mousemove",
this._collapseCallback, false);
MousePosTracker.removeListener(this);
document.removeEventListener("keypress", this._keyToggleCallback, false);
document.removeEventListener("popupshown", this._setPopupOpen, false);
document.removeEventListener("popuphidden", this._setPopupOpen, false);
gPrefService.removeObserver("browser.fullscreen", this);
this.cancelWarning();
gBrowser.tabContainer.removeEventListener("TabOpen", this.exitDomFullScreen);
@ -204,18 +195,9 @@ var FullScreen = {
}
},
observe: function(aSubject, aTopic, aData)
getMouseTargetRect: function()
{
if (aData == "browser.fullscreen.autohide") {
if (gPrefService.getBoolPref("browser.fullscreen.autohide")) {
gBrowser.mPanelContainer.addEventListener("mousemove",
this._collapseCallback, false);
}
else {
gBrowser.mPanelContainer.removeEventListener("mousemove",
this._collapseCallback, false);
}
}
return this._mouseTargetRect;
},
// Event callbacks
@ -223,7 +205,7 @@ var FullScreen = {
{
FullScreen.mouseoverToggle(true);
},
_collapseCallback: function()
onMouseEnter: function()
{
FullScreen.mouseoverToggle(false);
},
@ -512,22 +494,26 @@ var FullScreen = {
return;
}
// The chrome is collapsed so don't spam needless mousemove events
if (aShow) {
gBrowser.mPanelContainer.addEventListener("mousemove",
this._collapseCallback, false);
}
else {
gBrowser.mPanelContainer.removeEventListener("mousemove",
this._collapseCallback, false);
}
// Hiding/collapsing the toolbox interferes with the tab bar's scrollbox,
// so we just move it off-screen instead. See bug 430687.
gNavToolbox.style.marginTop =
aShow ? "" : -gNavToolbox.getBoundingClientRect().height + "px";
this._fullScrToggler.hidden = aShow || document.mozFullScreen;
if (aShow) {
let rect = gBrowser.mPanelContainer.getBoundingClientRect();
this._mouseTargetRect = {
top: rect.top + 50,
bottom: rect.bottom,
left: rect.left,
right: rect.right
};
MousePosTracker.addListener(this);
} else {
MousePosTracker.removeListener(this);
}
this._isChromeCollapsed = !aShow;
if (gPrefService.getIntPref("browser.fullscreen.animateUp") == 2)
this._shouldAnimate = true;

View File

@ -406,6 +406,33 @@ const gSessionHistoryObserver = {
}
};
const gGatherTelemetryObserver = {
observe: function(subject, topic, data) {
if (topic != "gather-telemetry") {
return;
}
let engine;
try {
engine = Services.search.defaultEngine;
} catch (e) {}
let name;
if (!engine) {
name = "NONE";
} else if (engine.identifier) {
name = engine.identifier;
} else if (engine.name) {
name = "other-" + engine.name;
} else {
name = "UNDEFINED";
}
let engines = Services.telemetry.getKeyedHistogramById("SEARCH_DEFAULT_ENGINE");
engines.add(name, true)
},
};
/**
* Given a starting docshell and a URI to look up, find the docshell the URI
* is loaded in.
@ -1160,6 +1187,7 @@ var gBrowserInit = {
Services.obs.addObserver(gXPInstallObserver, "addon-install-blocked", false);
Services.obs.addObserver(gXPInstallObserver, "addon-install-failed", false);
Services.obs.addObserver(gXPInstallObserver, "addon-install-complete", false);
Services.obs.addObserver(gGatherTelemetryObserver, "gather-telemetry", false);
window.messageManager.addMessageListener("Browser:URIFixup", gKeywordURIFixup);
window.messageManager.addMessageListener("Browser:LoadURI", RedirectLoad);
@ -1473,6 +1501,7 @@ var gBrowserInit = {
Services.obs.removeObserver(gXPInstallObserver, "addon-install-blocked");
Services.obs.removeObserver(gXPInstallObserver, "addon-install-failed");
Services.obs.removeObserver(gXPInstallObserver, "addon-install-complete");
Services.obs.removeObserver(gGatherTelemetryObserver, "gather-telemetry");
window.messageManager.removeMessageListener("Browser:URIFixup", gKeywordURIFixup);
window.messageManager.removeMessageListener("Browser:LoadURI", RedirectLoad);
@ -3356,6 +3385,7 @@ const BrowserSearch = {
*/
recordSearchInHealthReport: function (engine, source, selection) {
BrowserUITelemetry.countSearchEvent(source, null, selection);
this.recordSearchInTelemetry(engine, source);
#ifdef MOZ_SERVICES_HEALTHREPORT
let reporter = Cc["@mozilla.org/datareporting/service;1"]
.getService()
@ -3377,6 +3407,38 @@ const BrowserSearch = {
});
#endif
},
_getSearchEngineId: function (engine) {
if (!engine) {
return "other";
}
if (engine.identifier) {
return engine.identifier;
}
return "other-" + engine.name;
},
recordSearchInTelemetry: function (engine, source) {
const SOURCES = [
"abouthome",
"contextmenu",
"newtab",
"searchbar",
"urlbar",
];
if (SOURCES.indexOf(source) == -1) {
Cu.reportError("Unknown source for search: " + source);
return;
}
let countId = this._getSearchEngineId(engine) + "." + source;
let count = Services.telemetry.getKeyedHistogramById("SEARCH_COUNTS");
count.add(countId);
},
};
function FillHistoryMenu(aParent) {

View File

@ -356,6 +356,15 @@ BrowserGlue.prototype = {
// nsBrowserGlue to prevent double counting.
let win = this.getMostRecentBrowserWindow();
BrowserUITelemetry.countSearchEvent("urlbar", win.gURLBar.value);
let engine = null;
try {
engine = subject.QueryInterface(Ci.nsISearchEngine);
} catch (ex) {
Cu.reportError(ex);
}
win.BrowserSearch.recordSearchInTelemetry(engine, "urlbar");
#ifdef MOZ_SERVICES_HEALTHREPORT
let reporter = Cc["@mozilla.org/datareporting/service;1"]
.getService()
@ -368,7 +377,6 @@ BrowserGlue.prototype = {
reporter.onInit().then(function record() {
try {
let engine = subject.QueryInterface(Ci.nsISearchEngine);
reporter.getProvider("org.mozilla.searches").recordSearch(engine, "urlbar");
} catch (ex) {
Cu.reportError(ex);

View File

@ -240,15 +240,9 @@ browser.jar:
skin/classic/browser/places/unstarred48.png (places/unstarred48.png)
skin/classic/browser/places/unfiledBookmarks.png (places/unfiledBookmarks.png)
skin/classic/browser/places/unfiledBookmarks@2x.png (places/unfiledBookmarks@2x.png)
skin/classic/browser/places/twisty-open.gif (places/twisty-open.gif)
skin/classic/browser/places/twisty-closed.gif (places/twisty-closed.gif)
skin/classic/browser/places/tag.png (places/tag.png)
skin/classic/browser/places/tag@2x.png (places/tag@2x.png)
skin/classic/browser/places/downloads.png (places/downloads.png)
skin/classic/browser/places/expander-closed-active.png (places/expander-closed-active.png)
skin/classic/browser/places/expander-closed.png (places/expander-closed.png)
skin/classic/browser/places/expander-open-active.png (places/expander-open-active.png)
skin/classic/browser/places/expander-open.png (places/expander-open.png)
skin/classic/browser/places/livemark-item.png (places/livemark-item.png)
skin/classic/browser/preferences/alwaysAsk.png (preferences/alwaysAsk.png)
skin/classic/browser/preferences/application.png (preferences/application.png)

View File

@ -34,27 +34,16 @@
.expander-up,
.expander-down {
-moz-appearance: none;
margin: 0;
margin-left: 8px;
margin: 0 4px 1px 8px;
padding: 0;
min-width: 0;
}
.expander-up {
list-style-image: url("chrome://browser/skin/places/expander-open.png");
-moz-appearance: -moz-mac-disclosure-button-open;
}
.expander-down {
list-style-image: url("chrome://browser/skin/places/expander-closed.png");
}
.expander-down:hover:active {
list-style-image: url("chrome://browser/skin/places/expander-closed-active.png");
}
.expander-up:hover:active {
list-style-image: url("chrome://browser/skin/places/expander-open-active.png");
-moz-appearance: -moz-mac-disclosure-button-closed;
}
#editBookmarkPanelContent {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 837 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 818 B

View File

@ -228,50 +228,30 @@
.expander-up,
.expander-down {
-moz-appearance: none;
margin-left: 8px;
margin: 0 4px 1px 8px;
padding: 0;
min-width: 0;
}
.expander-up {
list-style-image: url("chrome://browser/skin/places/expander-open.png") !important;
-moz-appearance: -moz-mac-disclosure-button-open;
}
.expander-down {
list-style-image: url("chrome://browser/skin/places/expander-closed.png") !important;
}
.expander-down:hover:active {
list-style-image: url("chrome://browser/skin/places/expander-closed-active.png") !important;
}
.expander-up:hover:active {
list-style-image: url("chrome://browser/skin/places/expander-open-active.png") !important;
-moz-appearance: -moz-mac-disclosure-button-closed;
}
/**
* info pane
*/
/* More/Less button */
#infoBoxExpander {
list-style-image: url("chrome://browser/skin/places/twisty-open.gif");
-moz-appearance: none;
margin: 0;
padding: 0;
max-width: 0;
margin: 2px;
}
#infoBoxExpanderLabel {
display: none;
}
#infoBox[minimal="true"] #infoBoxExpander {
list-style-image: url("chrome://browser/skin/places/twisty-closed.gif");
}
#itemsCountText,
#selectItemDescription {
color: GrayText;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 B

View File

@ -52,35 +52,22 @@
padding: 0;
margin-top: 6px;
margin-bottom: 6px;
-moz-margin-start: -2px;
-moz-margin-end: 0;
}
.expander-up,
.expander-down {
-moz-appearance: none;
min-width: 0;
padding: 0;
margin: 0;
}
.expander-up {
list-style-image: url("chrome://browser/skin/places/expander-open.png");
}
.expander-up:hover:active {
list-style-image: url("chrome://browser/skin/places/expander-open-active.png");
-moz-appearance: -moz-mac-disclosure-button-open;
}
.expander-down {
list-style-image: url("chrome://browser/skin/places/expander-closed.png");
-moz-appearance: -moz-mac-disclosure-button-closed;
}
.expander-down:hover:active {
list-style-image: url("chrome://browser/skin/places/expander-closed-active.png");
}
/* Make the item list the same width as the warning box */
#itemList {
-moz-margin-start: 0;

View File

@ -23,7 +23,6 @@ __all__ = [
"dumpLeakLog",
"isURL",
"processLeakLog",
"replaceBackSlashes",
'KeyValueParseError',
'parseKeyValue',
'systemMemory',
@ -379,9 +378,6 @@ def processLeakLog(leakLogFile, options):
processSingleLeakFile(thisFile, processType, leakThreshold,
processType in ignoreMissingLeaks)
def replaceBackSlashes(input):
return input.replace('\\', '/')
class KeyValueParseError(Exception):
"""error when parsing strings of serialized key-values"""
def __init__(self, msg, errors=()):

View File

@ -244,7 +244,8 @@ DEFAULT_GMAKE_FLAGS += XCFLAGS='$(CFLAGS)'
DEFAULT_GMAKE_FLAGS += DARWIN_DYLIB_VERSIONS='-compatibility_version 1 -current_version 1 $(LDFLAGS)'
endif
ifeq (1_1,$(CLANG_CL)_$(MOZ_ASAN))
DEFAULT_GMAKE_FLAGS += XLDFLAGS='$(OS_LDFLAGS)'
XLDFLAGS := $(OS_LDFLAGS)
DEFAULT_GMAKE_FLAGS += XLDFLAGS='$(XLDFLAGS)'
endif
DEFAULT_GMAKE_FLAGS += NSS_NO_PKCS11_BYPASS=1

View File

@ -1,4 +1,3 @@
dnl -*- Mode: Autoconf; tab-width: 4; indent-tabs-mode: nil; -*-
dnl vi: set tabstop=4 shiftwidth=4 expandtab syntax=m4:
dnl This Source Code Form is subject to the terms of the Mozilla Public
@ -1316,6 +1315,15 @@ fi
AC_SUBST(MOZ_NO_WLZDEFS)
AC_SUBST(MOZ_CFLAGS_NSS)
dnl ========================================================
dnl = Enable treating compiler warnings as errors
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(warnings-as-errors,
[ --enable-warnings-as-errors
Enable treating warnings as errors],
MOZ_ENABLE_WARNINGS_AS_ERRORS=1,
MOZ_ENABLE_WARNINGS_AS_ERRORS=)
dnl ========================================================
dnl GNU specific defaults
dnl ========================================================
@ -1463,21 +1471,23 @@ if test "$GNU_CC"; then
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wsign-compare"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Wtype-limits"
# Treat some warnings as errors:
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=char-subscripts"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=comment"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=endif-labels"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=enum-compare"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=ignored-qualifiers"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=int-to-pointer-cast"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=multichar"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=nonnull"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=pointer-arith"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=pointer-sign"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=return-type"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=sequence-point"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=trigraphs"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=unknown-pragmas"
# Treat some warnings as errors if --enable-warnings-as-errors:
if test "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=char-subscripts"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=comment"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=endif-labels"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=enum-compare"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=ignored-qualifiers"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=int-to-pointer-cast"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=multichar"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=nonnull"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=pointer-arith"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=pointer-sign"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=return-type"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=sequence-point"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=trigraphs"
_WARNINGS_CFLAGS="${_WARNINGS_CFLAGS} -Werror=unknown-pragmas"
fi
# Turn off the following warnings that -Wall turns on:
# -Wno-unused - lots of violations in third-party code
@ -1537,10 +1547,12 @@ if test "$GNU_CXX"; then
# -Wint-to-pointer-cast - catches cast to pointer from integer of different size
# -Wmissing-braces - catches aggregate initializers missing nested braces
# -Woverloaded-virtual - function declaration hides virtual function from base class
# -Wparentheses - catches `if (a=b)` and operator precedence bugs
# -Wpointer-arith - catches pointer arithmetic using NULL or sizeof(void)
# -Wreturn-type - catches missing returns, zero false positives
# -Wsequence-point - catches undefined order behavior like `a = a++`
# -Wsign-compare - catches comparison of signed and unsigned types
# -Wswitch - catches switches without all enum cases or default case
# -Wtrigraphs - catches unlikely use of trigraphs
# -Wtype-limits - catches overflow bugs, few false positives
# -Wunused-label - catches unused goto labels
@ -1552,16 +1564,20 @@ if test "$GNU_CXX"; then
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wsign-compare"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wwrite-strings"
# Treat some warnings as errors:
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=endif-labels"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=int-to-pointer-cast"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=missing-braces"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=pointer-arith"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=return-type"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=sequence-point"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-label"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=trigraphs"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=type-limits"
# Treat some warnings as errors if --enable-warnings-as-errors:
if test "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=endif-labels"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=int-to-pointer-cast"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=missing-braces"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=parentheses"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=pointer-arith"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=return-type"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=sequence-point"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=switch"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=trigraphs"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=type-limits"
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Werror=unused-label"
fi
# Turn off the following warnings that -Wall turns on:
# -Wno-invalid-offsetof - we use offsetof on non-POD types frequently
@ -6950,13 +6966,8 @@ fi
AC_SUBST(MOZ_STACKWALKING)
dnl ========================================================
dnl = Enable any treating of compile warnings as errors
dnl = Disable treating compiler warnings as errors
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(warnings-as-errors,
[ --enable-warnings-as-errors
Enable treating of warnings as errors],
MOZ_ENABLE_WARNINGS_AS_ERRORS=1,
MOZ_ENABLE_WARNINGS_AS_ERRORS=)
if test -z "$MOZ_ENABLE_WARNINGS_AS_ERRORS"; then
WARNINGS_AS_ERRORS=''
elif test "$GNU_CC"; then

View File

@ -492,7 +492,10 @@ public:
mWriteParams(aWriteParams),
mNeedAllowNextSynchronizedOp(false),
mPersistence(quota::PERSISTENCE_TYPE_INVALID),
mState(eInitial)
mState(eInitial),
mIsApp(false),
mHasUnlimStoragePerm(false),
mEnforcingQuota(true)
{
MOZ_ASSERT(IsMainProcess());
}
@ -593,6 +596,9 @@ protected:
}
private:
void
InitPersistenceType();
nsresult
InitOnMainThread();
@ -659,8 +665,58 @@ private:
eFinished, // Terminal state
};
State mState;
bool mIsApp;
bool mHasUnlimStoragePerm;
bool mEnforcingQuota;
};
void
MainProcessRunnable::InitPersistenceType()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mState == eInitial);
if (mOpenMode == eOpenForWrite) {
MOZ_ASSERT(mPersistence == quota::PERSISTENCE_TYPE_INVALID);
// If we are performing install-time caching of an app, we'd like to store
// the cache entry in persistent storage so the entry is never evicted,
// but we need to check that quota is not enforced for the app.
// That justifies us in skipping all quota checks when storing the cache
// entry and avoids all the issues around the persistent quota prompt.
// If quota is enforced for the app, then we can still cache in temporary
// for a likely good first-run experience.
MOZ_ASSERT_IF(mWriteParams.mInstalled, mIsApp);
if (mWriteParams.mInstalled &&
!QuotaManager::IsQuotaEnforced(quota::PERSISTENCE_TYPE_PERSISTENT,
mOrigin, mHasUnlimStoragePerm)) {
mPersistence = quota::PERSISTENCE_TYPE_PERSISTENT;
} else {
mPersistence = quota::PERSISTENCE_TYPE_TEMPORARY;
}
return;
}
// For the reasons described above, apps may have cache entries in both
// persistent and temporary storage. At lookup time we don't know how and
// where the given script was cached, so start the search in persistent
// storage and, if that fails, search in temporary storage. (Non-apps can
// only be stored in temporary storage.)
MOZ_ASSERT_IF(mPersistence != quota::PERSISTENCE_TYPE_INVALID,
mIsApp && mPersistence == quota::PERSISTENCE_TYPE_PERSISTENT);
if (mPersistence == quota::PERSISTENCE_TYPE_INVALID && mIsApp) {
mPersistence = quota::PERSISTENCE_TYPE_PERSISTENT;
} else {
mPersistence = quota::PERSISTENCE_TYPE_TEMPORARY;
}
}
nsresult
MainProcessRunnable::InitOnMainThread()
{
@ -670,58 +726,29 @@ MainProcessRunnable::InitOnMainThread()
QuotaManager* qm = QuotaManager::GetOrCreate();
NS_ENSURE_STATE(qm);
nsresult rv = QuotaManager::GetInfoFromPrincipal(mPrincipal, &mGroup,
&mOrigin, nullptr, nullptr);
nsresult rv =
QuotaManager::GetInfoFromPrincipal(mPrincipal,
quota::PERSISTENCE_TYPE_INVALID,
&mGroup, &mOrigin, &mIsApp,
&mHasUnlimStoragePerm);
NS_ENSURE_SUCCESS(rv, rv);
bool isApp = mPrincipal->GetAppStatus() !=
nsIPrincipal::APP_STATUS_NOT_INSTALLED;
// XXX Don't use mGroup yet! We might need to update it right after we
// initialize persistence type.
if (mOpenMode == eOpenForWrite) {
MOZ_ASSERT(mPersistence == quota::PERSISTENCE_TYPE_INVALID);
if (mWriteParams.mInstalled) {
// If we are performing install-time caching of an app, we'd like to store
// the cache entry in persistent storage so the entry is never evicted,
// but we need to verify that the app has unlimited storage permissions
// first. Unlimited storage permissions justify us in skipping all quota
// checks when storing the cache entry and avoids all the issues around
// the persistent quota prompt.
MOZ_ASSERT(isApp);
InitPersistenceType();
nsCOMPtr<nsIPermissionManager> pm =
services::GetPermissionManager();
NS_ENSURE_TRUE(pm, NS_ERROR_UNEXPECTED);
uint32_t permission;
rv = pm->TestPermissionFromPrincipal(mPrincipal,
PERMISSION_STORAGE_UNLIMITED,
&permission);
NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED);
// If app doens't have the unlimited storage permission, we can still
// cache in temporary for a likely good first-run experience.
mPersistence = permission == nsIPermissionManager::ALLOW_ACTION
? quota::PERSISTENCE_TYPE_PERSISTENT
: quota::PERSISTENCE_TYPE_TEMPORARY;
} else {
mPersistence = quota::PERSISTENCE_TYPE_TEMPORARY;
}
} else {
// For the reasons described above, apps may have cache entries in both
// persistent and temporary storage. At lookup time we don't know how and
// where the given script was cached, so start the search in persistent
// storage and, if that fails, search in temporary storage. (Non-apps can
// only be stored in temporary storage.)
if (mPersistence == quota::PERSISTENCE_TYPE_INVALID) {
mPersistence = isApp ? quota::PERSISTENCE_TYPE_PERSISTENT
: quota::PERSISTENCE_TYPE_TEMPORARY;
} else {
MOZ_ASSERT(isApp);
MOZ_ASSERT(mPersistence == quota::PERSISTENCE_TYPE_PERSISTENT);
mPersistence = quota::PERSISTENCE_TYPE_TEMPORARY;
}
// XXX Since we couldn't pass persistence type to GetInfoFromPrincipal(),
// we need to do this manually.
// This hack is only temporary, it will go away once we have regular
// metadata files for persistent storge.
if (mPersistence == quota::PERSISTENCE_TYPE_PERSISTENT) {
mGroup = mOrigin;
}
mEnforcingQuota =
QuotaManager::IsQuotaEnforced(mPersistence, mOrigin, mHasUnlimStoragePerm);
QuotaManager::GetStorageId(mPersistence, mOrigin, quota::Client::ASMJS,
NS_LITERAL_STRING("asmjs"), mStorageId);
@ -737,13 +764,10 @@ MainProcessRunnable::ReadMetadata()
QuotaManager* qm = QuotaManager::Get();
MOZ_ASSERT(qm, "We are on the QuotaManager's IO thread");
// Only track quota for temporary storage. For persistent storage, we've
// already checked that we have unlimited-storage permissions.
bool trackQuota = mPersistence == quota::PERSISTENCE_TYPE_TEMPORARY;
nsresult rv = qm->EnsureOriginIsInitialized(mPersistence, mGroup, mOrigin,
trackQuota,
getter_AddRefs(mDirectory));
nsresult rv =
qm->EnsureOriginIsInitialized(mPersistence, mGroup, mOrigin,
mHasUnlimStoragePerm,
getter_AddRefs(mDirectory));
NS_ENSURE_SUCCESS(rv, rv);
rv = mDirectory->Append(NS_LITERAL_STRING(ASMJSCACHE_DIRECTORY_NAME));
@ -811,11 +835,7 @@ MainProcessRunnable::OpenCacheFileForWrite()
QuotaManager* qm = QuotaManager::Get();
MOZ_ASSERT(qm, "We are on the QuotaManager's IO thread");
// If we are allocating in temporary storage, ask the QuotaManager if we're
// within the quota. If we are allocating in persistent storage, we've already
// checked that we have the unlimited-storage permission, so there is nothing
// to check.
if (mPersistence == quota::PERSISTENCE_TYPE_TEMPORARY) {
if (mEnforcingQuota) {
// Create the QuotaObject before all file IO and keep it alive until caching
// completes to get maximum assertion coverage in QuotaManager against
// concurrent removal, etc.
@ -866,7 +886,7 @@ MainProcessRunnable::OpenCacheFileForRead()
QuotaManager* qm = QuotaManager::Get();
MOZ_ASSERT(qm, "We are on the QuotaManager's IO thread");
if (mPersistence == quota::PERSISTENCE_TYPE_TEMPORARY) {
if (mEnforcingQuota) {
// Even though it's not strictly necessary, create the QuotaObject before
// all file IO and keep it alive until caching completes to get maximum
// assertion coverage in QuotaManager against concurrent removal, etc.

View File

@ -3093,13 +3093,6 @@ nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId,
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
nsCString origin;
quota::PersistenceType defaultPersistenceType;
nsresult rv =
quota::QuotaManager::GetInfoFromWindow(window, nullptr, &origin, nullptr,
&defaultPersistenceType);
NS_ENSURE_SUCCESS(rv, rv);
IDBOpenDBOptions options;
JS::Rooted<JS::Value> optionsVal(aCx, aOptions);
if (!options.Init(aCx, optionsVal)) {
@ -3107,7 +3100,13 @@ nsDOMWindowUtils::GetFileReferences(const nsAString& aDatabaseName, int64_t aId,
}
quota::PersistenceType persistenceType =
quota::PersistenceTypeFromStorage(options.mStorage, defaultPersistenceType);
quota::PersistenceTypeFromStorage(options.mStorage);
nsCString origin;
nsresult rv =
quota::QuotaManager::GetInfoFromWindow(window, persistenceType, nullptr,
&origin, nullptr, nullptr);
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<indexedDB::IndexedDatabaseManager> mgr =
indexedDB::IndexedDatabaseManager::Get();

View File

@ -5,7 +5,6 @@
#include "ActorsParent.h"
#include <algorithm>
#include "CheckQuotaHelper.h"
#include "FileInfo.h"
#include "FileManager.h"
#include "IDBObjectStore.h"
@ -3892,6 +3891,7 @@ protected:
nsCString mOrigin;
nsCString mDatabaseId;
State mState;
bool mHasUnlimStoragePerm;
bool mEnforcingQuota;
const bool mDeleting;
bool mBlockedQuotaManager;
@ -5938,6 +5938,12 @@ Factory::AllocPBackgroundIDBFactoryRequestParent(
return nullptr;
}
if (NS_WARN_IF(principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo &&
metadata.persistenceType() != PERSISTENCE_TYPE_PERSISTENT)) {
ASSERT_UNLESS_FUZZING();
return nullptr;
}
nsRefPtr<ContentParent> contentParent =
BackgroundParent::GetContentParent(Manager());
@ -10442,6 +10448,7 @@ FactoryOp::FactoryOp(Factory* aFactory,
, mContentParent(Move(aContentParent))
, mCommonParams(aCommonParams)
, mState(State_Initial)
, mHasUnlimStoragePerm(false)
, mEnforcingQuota(true)
, mDeleting(aDeleting)
, mBlockedQuotaManager(false)
@ -10687,11 +10694,14 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
}
PersistenceType persistenceType = mCommonParams.metadata().persistenceType();
const PrincipalInfo& principalInfo = mCommonParams.principalInfo();
MOZ_ASSERT(principalInfo.type() != PrincipalInfo::TNullPrincipalInfo);
if (principalInfo.type() == PrincipalInfo::TSystemPrincipalInfo) {
MOZ_ASSERT(mState == State_Initial);
MOZ_ASSERT(persistenceType == PERSISTENCE_TYPE_PERSISTENT);
if (aContentParent) {
// Check to make sure that the child process has access to the database it
@ -10740,8 +10750,12 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
}
if (State_Initial == mState) {
QuotaManager::GetInfoForChrome(&mGroup, &mOrigin, nullptr, nullptr);
mEnforcingQuota = false;
QuotaManager::GetInfoForChrome(&mGroup, &mOrigin, nullptr,
&mHasUnlimStoragePerm);
mEnforcingQuota =
QuotaManager::IsQuotaEnforced(persistenceType, mOrigin,
mHasUnlimStoragePerm);
}
*aPermission = PermissionRequestBase::kPermissionAllowed;
@ -10759,13 +10773,11 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
PermissionRequestBase::PermissionValue permission;
if (mCommonParams.metadata().persistenceType() ==
PERSISTENCE_TYPE_TEMPORARY) {
if (persistenceType == PERSISTENCE_TYPE_TEMPORARY) {
// Temporary storage doesn't need to check the permission.
permission = PermissionRequestBase::kPermissionAllowed;
} else {
MOZ_ASSERT(mCommonParams.metadata().persistenceType() ==
PERSISTENCE_TYPE_PERSISTENT);
MOZ_ASSERT(persistenceType == PERSISTENCE_TYPE_PERSISTENT);
#ifdef MOZ_CHILD_PERMISSIONS
if (aContentParent) {
@ -10791,22 +10803,15 @@ FactoryOp::CheckPermission(ContentParent* aContentParent,
if (permission != PermissionRequestBase::kPermissionDenied &&
State_Initial == mState) {
rv = QuotaManager::GetInfoFromPrincipal(principal, &mGroup, &mOrigin,
nullptr, nullptr);
rv = QuotaManager::GetInfoFromPrincipal(principal, persistenceType, &mGroup,
&mOrigin, nullptr,
&mHasUnlimStoragePerm);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
}
if (permission == PermissionRequestBase::kPermissionAllowed &&
mEnforcingQuota)
{
// If we're running from a window then we should check the quota permission
// as well.
uint32_t quotaPermission = CheckQuotaHelper::GetQuotaPermission(principal);
if (quotaPermission == nsIPermissionManager::ALLOW_ACTION) {
mEnforcingQuota = false;
}
mEnforcingQuota = QuotaManager::IsQuotaEnforced(persistenceType, mOrigin,
mHasUnlimStoragePerm);
}
*aPermission = permission;
@ -11211,7 +11216,7 @@ OpenDatabaseOp::DoDatabaseWork()
quotaManager->EnsureOriginIsInitialized(persistenceType,
mGroup,
mOrigin,
mEnforcingQuota,
mHasUnlimStoragePerm,
getter_AddRefs(dbDirectory));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;

View File

@ -973,8 +973,10 @@ IDBDatabase::GetQuotaInfo(nsACString& aOrigin,
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
MOZ_ASSERT(NS_IsMainThread());
PersistenceType persistenceType = mSpec->metadata().persistenceType();
if (aPersistenceType) {
*aPersistenceType = mSpec->metadata().persistenceType();
*aPersistenceType = persistenceType;
MOZ_ASSERT(*aPersistenceType != PERSISTENCE_TYPE_INVALID);
}
@ -998,6 +1000,7 @@ IDBDatabase::GetQuotaInfo(nsACString& aOrigin,
}
rv = QuotaManager::GetInfoFromPrincipal(principal,
persistenceType,
nullptr,
&aOrigin,
nullptr,

View File

@ -483,8 +483,7 @@ IDBFactory::OpenInternal(nsIPrincipal* aPrincipal,
persistenceType = PERSISTENCE_TYPE_PERSISTENT;
persistenceTypeIsExplicit = false;
} else {
persistenceType =
PersistenceTypeFromStorage(aStorageType, PERSISTENCE_TYPE_PERSISTENT);
persistenceType = PersistenceTypeFromStorage(aStorageType);
persistenceTypeIsExplicit = aStorageType.WasPassed();
}

View File

@ -157,9 +157,15 @@ IDBMutableFile::Create(IDBDatabase* aDatabase,
return nullptr;
}
const DatabaseSpec* spec = aDatabase->Spec();
MOZ_ASSERT(spec);
PersistenceType persistenceType = spec->metadata().persistenceType();
nsCString group;
nsCString origin;
if (NS_WARN_IF(NS_FAILED(QuotaManager::GetInfoFromPrincipal(principal,
persistenceType,
&group,
&origin,
nullptr,
@ -167,11 +173,6 @@ IDBMutableFile::Create(IDBDatabase* aDatabase,
return nullptr;
}
const DatabaseSpec* spec = aDatabase->Spec();
MOZ_ASSERT(spec);
PersistenceType persistenceType = spec->metadata().persistenceType();
nsCString storageId;
QuotaManager::GetStorageId(persistenceType,
origin,

View File

@ -93,7 +93,6 @@ FAIL_ON_WARNINGS = True
LOCAL_INCLUDES += [
'/db/sqlite3/src',
'/dom/base',
'/dom/quota',
'/dom/storage',
'/ipc/glue',
'/xpcom/build',

View File

@ -148,7 +148,9 @@ skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_deleteDatabase_interactions.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_disabled_quota_prompt.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
# Test temporarily disabled.
skip-if = true
# skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_error_events_abort_transactions.html]
skip-if = (buildapp == 'b2g' && toolkit != 'gonk') # Bug 931116
[test_event_propagation.html]

View File

@ -3,8 +3,6 @@
* http://creativecommons.org/publicdomain/zero/1.0/
*/
Components.utils.importGlobalProperties(['Blob']);
var testGenerator = testSteps();
function testSteps()
@ -37,6 +35,11 @@ function testSteps()
const lastIndex = urls.length - 1;
const lastUrl = urls[lastIndex].url;
const openDBOptions = [
{ version: 1, storage: "temporary" },
{ version: 1 }
];
let quotaManager =
Components.classes["@mozilla.org/dom/quota/manager;1"]
.getService(Components.interfaces.nsIQuotaManager);
@ -46,8 +49,6 @@ function testSteps()
let dbSize = 0;
let databases = [];
function setLimit(limit) {
if (limit) {
SpecialPowers.setIntPref("dom.quotaManager.temporaryStorage.fixedLimit",
@ -112,18 +113,66 @@ function testSteps()
getUsageForUrl(lastUrl, grabUsageAndContinueHandler);
dbSize = yield undefined;
setLimit(lastIndex * dbSize / 1024);
quotaManager.clear();
for (let options of openDBOptions) {
setLimit(lastIndex * dbSize / 1024);
quotaManager.clear();
info("Stage 1");
info("Stage 1");
for (let i = 0; i < lastIndex; i++) {
let data = urls[i];
let databases = [];
for (let i = 0; i < lastIndex; i++) {
let data = urls[i];
info("Opening database for " + data.url);
info("Opening database for " + data.url);
request = indexedDB.openForPrincipal(getPrincipal(data.url), name,
{ storage: "temporary" });
request = indexedDB.openForPrincipal(getPrincipal(data.url), name,
options);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "upgradeneeded", "Got correct event type");
let db = event.target.result;
db.createObjectStore("foo", { });
event = yield undefined;
is(event.type, "success", "Got correct event type");
databases.push(event.target.result);
}
request = indexedDB.openForPrincipal(getPrincipal(lastUrl), name, options);
request.addEventListener("error", new ExpectError("QuotaExceededError"));
request.onsuccess = unexpectedSuccessHandler;
event = yield undefined;
checkUsage(1);
yield undefined;
info("Stage 2");
for (let i = 1; i < urls.length; i++) {
databases[i] = null;
scheduleGC();
yield undefined;
// The origin access time is set to the current system time when the first
// database for an origin is registered or the last one is unregistered.
// The registration happens when the database object is being created and
// the unregistration when it is unlinked/garbage collected.
// Some older windows systems have the system time limited to a maximum
// resolution of 10 or 15 milliseconds, so without a pause here we would
// end up with origins with the same access time which would cause random
// failures.
setTimeout(function() { testGenerator.next(); }, 20);
yield undefined;
}
request = indexedDB.openForPrincipal(getPrincipal(lastUrl), name, options);
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
@ -138,91 +187,43 @@ function testSteps()
is(event.type, "success", "Got correct event type");
databases.push(event.target.result);
}
request = indexedDB.openForPrincipal(getPrincipal(lastUrl), name,
{ storage: "temporary" });
request.addEventListener("error", new ExpectError("QuotaExceededError"));
request.onsuccess = unexpectedSuccessHandler;
event = yield undefined;
checkUsage(1);
yield undefined;
info("Stage 2");
for (let i = 1; i < urls.length; i++) {
databases[i] = null;
scheduleGC();
checkUsage(2);
yield undefined;
// The origin access time is set to the current system time when the first
// database for an origin is registered or the last one is unregistered.
// The registration happens when the database object is being created and
// the unregistration when it is unlinked/garbage collected.
// Some older windows systems have the system time limited to a maximum
// resolution of 10 or 15 milliseconds, so without a pause here we would
// end up with origins with the same access time which would cause random
// failures.
setTimeout(function() { testGenerator.next(); }, 20);
info("Stage 3");
setLimit(14 * dbSize / 1024);
quotaManager.reset();
request = indexedDB.openForPrincipal(getPrincipal(lastUrl), name, options);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "success", "Got correct event type");
db = event.target.result;
checkUsage(3);
yield undefined;
info("Stage 4");
let trans = db.transaction(["foo"], "readwrite");
let blob = new Blob(["bar"]);
request = trans.objectStore("foo").add(blob, 42);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
trans.oncomplete = grabEventAndContinueHandler;
event = yield undefined;
checkUsage(4);
yield undefined;
}
request = indexedDB.openForPrincipal(getPrincipal(lastUrl), name,
{ storage: "temporary" });
request.onerror = errorHandler;
request.onupgradeneeded = grabEventAndContinueHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "upgradeneeded", "Got correct event type");
let db = event.target.result;
db.createObjectStore("foo", { });
event = yield undefined;
is(event.type, "success", "Got correct event type");
checkUsage(2);
yield undefined;
info("Stage 3");
setLimit(14 * dbSize / 1024);
quotaManager.reset();
request = indexedDB.openForPrincipal(getPrincipal(lastUrl), name,
{ storage: "temporary" });
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
is(event.type, "success", "Got correct event type");
db = event.target.result;
checkUsage(3);
yield undefined;
info("Stage 4");
let trans = db.transaction(["foo"], "readwrite");
let blob = new Blob(["bar"]);
request = trans.objectStore("foo").add(blob, 42);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield undefined;
trans.oncomplete = grabEventAndContinueHandler;
event = yield undefined;
checkUsage(4);
yield undefined;
info("Cleanup");
setLimit();

View File

@ -0,0 +1,323 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* ManifestProcessor
* Implementation of processing algorithms from:
* http://www.w3.org/2008/webapps/manifest/
*
* Creates manifest processor that lets you process a JSON file
* or individual parts of a manifest object. A manifest is just a
* standard JS object that has been cleaned up.
*
* .process(jsonText, manifestURL, docURL);
*
* TODO: The constructor should accept the UA's supported orientations.
* TODO: The constructor should accept the UA's supported display modes.
* TODO: hook up developer tools to issueDeveloperWarning (1086997).
*/
/*globals Components*/
/*exported EXPORTED_SYMBOLS */
'use strict';
this.EXPORTED_SYMBOLS = ['ManifestProcessor'];
const {
utils: Cu,
classes: Cc,
interfaces: Ci
} = Components;
const imports = {};
Cu.import('resource://gre/modules/Services.jsm', imports);
Cu.importGlobalProperties(['URL']);
const securityManager = imports.Services.scriptSecurityManager;
const netutil = Cc['@mozilla.org/network/util;1'].getService(Ci.nsINetUtil);
const defaultDisplayMode = 'browser';
const displayModes = new Set([
'fullscreen',
'standalone',
'minimal-ui',
'browser'
]);
const orientationTypes = new Set([
'any',
'natural',
'landscape',
'portrait',
'portrait-primary',
'portrait-secondary',
'landscape-primary',
'landscape-secondary'
]);
this.ManifestProcessor = function ManifestProcessor() {};
/**
* process method: processes json text into a clean manifest
* that conforms with the W3C specification.
* @param jsonText - the JSON string to be processd.
* @param manifestURL - the URL of the manifest, to resolve URLs.
* @param docURL - the URL of the owner doc, for security checks
*/
this.ManifestProcessor.prototype.process = function({
jsonText: jsonText,
manifestURL: manifestURL,
docLocation: docURL
}) {
/*
* This helper function is used to extract values from manifest members.
* It also reports conformance violations.
*/
function extractValue(obj) {
let value = obj.object[obj.property];
//we need to special-case "array", as it's not a JS primitive
const type = (Array.isArray(value)) ? 'array' : typeof value;
if (type !== obj.expectedType) {
if (type !== 'undefined') {
let msg = `Expected the ${obj.objectName}'s ${obj.property}`;
msg += `member to a be a ${obj.expectedType}.`;
issueDeveloperWarning(msg);
}
value = undefined;
}
return value;
}
function issueDeveloperWarning(msg) {
//https://bugzilla.mozilla.org/show_bug.cgi?id=1086997
}
function processNameMember(manifest) {
const obj = {
objectName: 'manifest',
object: manifest,
property: 'name',
expectedType: 'string'
};
let value = extractValue(obj);
return (value) ? value.trim() : value;
}
function processShortNameMember(manifest) {
const obj = {
objectName: 'manifest',
object: manifest,
property: 'short_name',
expectedType: 'string'
};
let value = extractValue(obj);
return (value) ? value.trim() : value;
}
function processOrientationMember(manifest) {
const obj = {
objectName: 'manifest',
object: manifest,
property: 'orientation',
expectedType: 'string'
};
let value = extractValue(obj);
value = (value) ? value.trim() : undefined;
//The spec special-cases orientation to return the empty string
return (orientationTypes.has(value)) ? value : '';
}
function processDisplayMember(manifest) {
const obj = {
objectName: 'manifest',
object: manifest,
property: 'display',
expectedType: 'string'
};
let value = extractValue(obj);
value = (value) ? value.trim() : value;
return (displayModes.has(value)) ? value : defaultDisplayMode;
}
function processStartURLMember(manifest, manifestURL, docURL) {
const obj = {
objectName: 'manifest',
object: manifest,
property: 'start_url',
expectedType: 'string'
};
let value = extractValue(obj),
result = new URL(docURL),
targetURI = makeURI(result),
sameOrigin = false,
potentialResult,
referrerURI;
if (value === undefined || value === '') {
return result;
}
try {
potentialResult = new URL(value, manifestURL);
} catch (e) {
issueDeveloperWarning('Invalid URL.');
return result;
}
referrerURI = makeURI(potentialResult);
try {
securityManager.checkSameOriginURI(referrerURI, targetURI, false);
sameOrigin = true;
} catch (e) {}
if (!sameOrigin) {
let msg = 'start_url must be same origin as document.';
issueDeveloperWarning(msg);
} else {
result = potentialResult;
}
return result;
//Converts a URL to a Gecko URI
function makeURI(webURL) {
return imports.Services.io.newURI(webURL.toString(), null, null);
}
}
//Constants used by IconsProcessor
const onlyDecimals = /^\d+$/,
anyRegEx = new RegExp('any', 'i');
function IconsProcessor() {}
IconsProcessor.prototype.processIcons = function(manifest, baseURL) {
const obj = {
objectName: 'manifest',
object: manifest,
property: 'icons',
expectedType: 'array'
},
icons = [];
let value = extractValue(obj);
if (Array.isArray(value)) {
//filter out icons with no "src" or src is empty string
let processableIcons = value.filter(
icon => icon && Object.prototype.hasOwnProperty.call(icon, 'src') && icon.src !== ''
);
for (let potentialIcon of processableIcons) {
let src = processSrcMember(potentialIcon, baseURL)
if(src !== undefined){
let icon = {
src: src,
type: processTypeMember(potentialIcon),
sizes: processSizesMember(potentialIcon),
density: processDensityMember(potentialIcon)
};
icons.push(icon);
}
}
}
return icons;
function processTypeMember(icon) {
const charset = {},
hadCharset = {},
obj = {
objectName: 'icon',
object: icon,
property: 'type',
expectedType: 'string'
};
let value = extractValue(obj),
isParsable = (typeof value === 'string' && value.length > 0);
value = (isParsable) ? netutil.parseContentType(value.trim(), charset, hadCharset) : undefined;
return (value === '') ? undefined : value;
}
function processDensityMember(icon) {
const hasDensity = Object.prototype.hasOwnProperty.call(icon, 'density'),
rawValue = (hasDensity) ? icon.density : undefined,
value = parseFloat(rawValue),
result = (Number.isNaN(value) || value === +Infinity || value <= 0) ? 1.0 : value;
return result;
}
function processSrcMember(icon, baseURL) {
const obj = {
objectName: 'icon',
object: icon,
property: 'src',
expectedType: 'string'
},
value = extractValue(obj);
let url;
if (typeof value === 'string' && value.trim() !== '') {
try {
url = new URL(value, baseURL);
} catch (e) {}
}
return url;
}
function processSizesMember(icon) {
const sizes = new Set(),
obj = {
objectName: 'icon',
object: icon,
property: 'sizes',
expectedType: 'string'
};
let value = extractValue(obj);
value = (value) ? value.trim() : value;
if (value) {
//split on whitespace and filter out invalid values
let validSizes = value.split(/\s+/).filter(isValidSizeValue);
validSizes.forEach((size) => sizes.add(size));
}
return sizes;
/*
* Implementation of HTML's link@size attribute checker
*/
function isValidSizeValue(size) {
if (anyRegEx.test(size)) {
return true;
}
size = size.toLowerCase();
if (!size.contains('x') || size.indexOf('x') !== size.lastIndexOf('x')) {
return false;
}
//split left of x for width, after x for height
const width = size.substring(0, size.indexOf('x'));
const height = size.substring(size.indexOf('x') + 1, size.length);
const isValid = !(height.startsWith('0') || width.startsWith('0') || !onlyDecimals.test(width + height));
return isValid;
}
}
};
function processIconsMember(manifest, manifestURL) {
const iconsProcessor = new IconsProcessor();
return iconsProcessor.processIcons(manifest, manifestURL);
}
//Processing starts here!
let manifest = {};
try {
manifest = JSON.parse(jsonText);
if (typeof manifest !== 'object' || manifest === null) {
let msg = 'Manifest needs to be an object.';
issueDeveloperWarning(msg);
manifest = {};
}
} catch (e) {
issueDeveloperWarning(e);
}
const processedManifest = {
start_url: processStartURLMember(manifest, manifestURL, docURL),
display: processDisplayMember(manifest),
orientation: processOrientationMember(manifest),
name: processNameMember(manifest),
icons: processIconsMember(manifest, manifestURL),
short_name: processShortNameMember(manifest)
};
return processedManifest;
};

12
dom/manifest/moz.build Normal file
View File

@ -0,0 +1,12 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXTRA_JS_MODULES += [
'ManifestProcessor.jsm',
]
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
# BROWSER_CHROME_MANIFESTS += ['test/browser.ini']

View File

@ -0,0 +1,20 @@
/**
* Common infrastructure for manifest tests.
**/
'use strict';
const bsp = SpecialPowers.Cu.import('resource://gre/modules/ManifestProcessor.jsm'),
processor = new bsp.ManifestProcessor(),
manifestURL = new URL(document.location.origin + '/manifest.json'),
docLocation = new URL('', document.location.origin),
seperators = '\u2028\u2029\u0020\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000',
lineTerminators = '\u000D\u000A\u2028\u2029',
whiteSpace = `${seperators}${lineTerminators}`,
typeTests = [1, null, {},
[], false
],
data = {
jsonText: '{}',
manifestURL: manifestURL,
docLocation: docLocation
};

View File

@ -0,0 +1,16 @@
[DEFAULT]
skip-if = e10s
support-files =
common.js
[test_IconsProcessor_density.html]
[test_IconsProcessor_sizes.html]
[test_IconsProcessor_src.html]
[test_IconsProcessor_type.html]
[test_ManifestProcessor_display.html]
[test_ManifestProcessor_icons.html]
[test_ManifestProcessor_JSON.html]
[test_ManifestProcessor_name_and_short_name.html]
[test_ManifestProcessor_orientation.html]
[test_ManifestProcessor_start_url.html]

View File

@ -0,0 +1,57 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1079453</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
/**
* icon member's density member
* https://w3c.github.io/manifest/#density-member
**/
'use strict';
var testIcon = {
icons: [{
src: 'test',
density: undefined
}]
};
var iconDensityValueTests = [null, {},
[], false, '', -0, '-0', -1.0000, -123131132, -1.2e+200,
'Infinity', '-Infinity',
'-1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000',
'1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
];
iconDensityValueTests.forEach((density) => {
var expected = `Expect density to default to 1.0.`;
testIcon.icons[0].density = density;
data.jsonText = JSON.stringify(testIcon);
var result = processor.process(data);
ise(result.icons[0].density, 1.0, expected);
});
testIcon = {
icons: [{
src: 'test',
density: undefined
}]
};
var parseFloatTests = [3.14, '3.14', `${whiteSpace}3.14${whiteSpace}`, 12e300];
parseFloatTests.forEach((testNumber) => {
var expected = `Expect density to be ${parseFloat(testNumber)}.`;
testIcon.icons[0].density = testNumber;
data.jsonText = JSON.stringify(testIcon);
var result = processor.process(data);
ise(result.icons[0].density, parseFloat(testNumber), expected);
});
</script>
</head>

View File

@ -0,0 +1,101 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1079453</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
/**
* icon member's sizes property
* https://w3c.github.io/manifest/#sizes-member
**/
'use strict';
var validSizes = [{
test: '16x16',
expect: ['16x16']
}, {
test: 'hello 16x16 16x16',
expect: ['16x16']
}, {
test: '32x32 16 48x48 12',
expect: ['32x32', '48x48']
}, {
test: `${whiteSpace}128x128${whiteSpace}512x512 8192x8192 32768x32768${whiteSpace}`,
expect: ['128x128', '512x512', '8192x8192', '32768x32768']
}, {
test: 'any',
expect: ['any']
}, {
test: 'Any',
expect: ['Any']
}, {
test: '16x32',
expect: ['16x32']
}, {
test: '17x33',
expect: ['17x33']
}, {
test: '32x32 32x32',
expect: ['32x32']
}, {
test: '32X32',
expect: ['32X32']
}, {
test: 'any 32x32',
expect: ['any', '32x32']
}];
var testIcon = {
icons: [{
src: 'test',
sizes: undefined
}]
};
validSizes.forEach(({
test, expect
}) => {
testIcon.icons[0].sizes = test;
data.jsonText = JSON.stringify(testIcon);
var result = processor.process(data);
var sizes = result.icons[0].sizes;
for (var expectedSize of expect) {
var expected = `Expect sizes to contain ${expectedSize}`;
ise(sizes.has(expectedSize), true, expected);
}
expected = `Expect the size of the set to be ${expect.length}.`;
ise(sizes.size, expect.length, expected);
});
var testIcon = {
icons: [{
src: 'test',
sizes: undefined
}]
};
var invalidSizes = ['invalid', '', ' ', '16 x 16', '32', '21', '16xx16', '16 x x 6'];
invalidSizes.forEach((invalidSize) => {
var expected = 'Expect invalid sizes to return an empty set.';
testIcon.icons[0].sizes = invalidSize;
data.jsonText = JSON.stringify(testIcon);
var result = processor.process(data);
var sizes = result.icons[0].sizes;
ise(sizes.size, 0, expected);
});
typeTests.forEach((type) => {
var expected = `Expect non-string sizes to be empty set: ${typeof type}.`;
testIcon.icons[0].sizes = type;
data.jsonText = JSON.stringify(testIcon);
var result = processor.process(data);
var sizes = result.icons[0].sizes;
ise(sizes.size, 0, expected);
});
</script>
</head>

View File

@ -0,0 +1,110 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1079453</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
/**
* icon member's src member
* https://w3c.github.io/manifest/#src-member
**/
'use strict';
var noSrc = {
icons: [{}, {
src: []
}, {
src: {}
}, {
src: null
}, {
density: '1'
}, {
type: 'image/jpg'
}, {
sizes: '1x1,2x2'
}, {
density: '1',
sizes: 'any',
type: 'image/jpg'
}]
};
var expected = `Expect icons without a src prop to be filtered out.`;
data.jsonText = JSON.stringify(noSrc);
var result = processor.process(data);
ise(result.icons.length, 0, expected);
var invalidSrc = {
icons: [{
src: null
}, {
src: 1
}, {
src: []
}, {
src: {}
}, {
src: true
}, {
src: ''
}]
};
var expected = `Expect icons with invalid src prop to be filtered out.`;
data.jsonText = JSON.stringify(noSrc);
var result = processor.process(data);
ise(result.icons.length, 0, expected);
var expected = `Expect icon's src to be an instance of URL.`;
var withSrc = {
icons: [{
src: 'pass'
}]
};
data.jsonText = JSON.stringify(withSrc);
var result = processor.process(data);
ise(SpecialPowers.unwrap(result.icons[0].src) instanceof URL, true, expected);
var expected = `Expect only icons with a src prop to be kept.`;
var withSrc = {
icons: [{
src: 'pass'
}, {
src: 'pass',
density: 1
}, {}, {
foo: 'foo'
}]
};
data.jsonText = JSON.stringify(withSrc);
var result = processor.process(data);
ise(result.icons.length, 2, expected);
var expectedURL = new URL('pass', manifestURL);
for (var icon of result.icons) {
var expected = `Expect src prop to be ${expectedURL.toString()}`;
ise(icon.src.toString(), expectedURL.toString(), expected);
}
//Resolve URLs relative to manfiest
var URLs = ['path', '/path', '../../path'];
URLs.forEach((url) => {
var expected = `Resolve icon src URLs relative to manifest.`;
data.jsonText = JSON.stringify({
icons: [{
src: url
}]
});
var absURL = new URL(url, manifestURL).toString();
var result = processor.process(data);
ise(result.icons[0].src.toString(), absURL, expected);
});
</script>
</head>

View File

@ -0,0 +1,51 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1079453</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
/**
* icon member's type property
* https://w3c.github.io/manifest/#type-member
**/
'use strict';
var testIcon = {
icons: [{
src: 'test',
type: undefined
}]
};
var invalidMimeTypes = ['application / text', 'test;test', ';test?test', 'application\\text'];
invalidMimeTypes.forEach((invalidMime) => {
var expected = `Expect invalid mime to be treated like undefined.`;
testIcon.icons[0].type = invalidMime;
data.jsonText = JSON.stringify(testIcon);
var result = processor.process(data);
ise(result.icons[0].type, undefined, expected);
});
var validTypes = [
'image/jpeg',
'IMAGE/jPeG',
`${whiteSpace}image/jpeg${whiteSpace}`,
'image/JPEG; whatever=something',
'image/JPEG;whatever'
];
validTypes.forEach((validMime) => {
var expected = `Expect valid mime to be parsed to : image/jpeg.`;
testIcon.icons[0].type = validMime;
data.jsonText = JSON.stringify(testIcon);
var result = processor.process(data);
ise(result.icons[0].type, 'image/jpeg', expected);
});
</script>
</head>

View File

@ -0,0 +1,34 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1079453</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
/**
* JSON parsing/processing tests
* https://w3c.github.io/manifest/#processing
**/
'use strict';
var invalidJson = ['', ` \t \n ${whiteSpace} `, '{', '{[[}'];
invalidJson.forEach((testString) => {
var expected = `Expect to recover from invalid JSON: ${testString}`;
data.jsonText = testString;
var result = processor.process(data);
SimpleTest.ok(result.start_url.href === docLocation.href, true, expected);
});
var validButUnhelpful = ["1", 1, "", "[{}]", "null"];
validButUnhelpful.forEach((testString) => {
var expected = `Expect to recover from invalid JSON: ${testString}`;
data.jsonText = testString;
var result = processor.process(data);
SimpleTest.ok(result.start_url.href === docLocation.href, true, expected);
});
</script>
</head>

View File

@ -0,0 +1,61 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1079453</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
/**
* display member
* https://w3c.github.io/manifest/#display-member
**/
'use strict';
//Type checks
typeTests.forEach((type) => {
var expected = `Expect non - string display to default to "browser".`;
data.jsonText = JSON.stringify({
display: type
});
var result = processor.process(data);
ise(result.display, 'browser', expected);
});
/*Test valid modes*/
var validModes = ['fullscreen', 'standalone', 'minimal-ui', 'browser']
validModes.forEach((mode) => {
var expected = `Expect display mode to be ${mode}.`;
data.jsonText = JSON.stringify({
display: mode
});
var result = processor.process(data);
ise(result.display, mode, expected);
});
//trim tests
validModes.forEach((display) => {
var expected = `Expect trimmed display mode to be returned.`;
var expandedDisplay = seperators + lineTerminators + display + lineTerminators + seperators;
data.jsonText = JSON.stringify({
display: expandedDisplay
});
var result = processor.process(data);
ise(result.display, display, expected);
});
//Unknown modes
var invalidModes = ['foo', `fooo${whiteSpace}`, '', 'fullscreen,standalone', 'standalone fullscreen', 'FULLSCreEN'];
invalidModes.forEach((invalidMode) => {
var expected = `Expect default display mode "browser" to be returned: '${invalidMode}'`;
data.jsonText = JSON.stringify({
display: invalidMode
});
var result = processor.process(data);
ise(result.display, 'browser', expected);
});
</script>
</head>

View File

@ -0,0 +1,30 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1079453</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
/**
* Manifest icons member
* https://w3c.github.io/manifest/#icons-member
**/
'use strict';
typeTests.forEach((type) => {
var expected = `Expect non-array icons to be empty array: ${typeof type}.`;
data.jsonText = JSON.stringify({
icons: type
});
var result = processor.process(data);
var y = SpecialPowers.unwrap(result.icons);
ise(result.icons.length, 0, expected);
});
</script>
</head>

View File

@ -0,0 +1,79 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1079453</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
/**
* name and short_name members
* https://w3c.github.io/manifest/#name-member
* https://w3c.github.io/manifest/#short_name-member
**/
'use strict';
var trimNamesTests = [
`${seperators}pass${seperators}`,
`${lineTerminators}pass${lineTerminators}`,
`${whiteSpace}pass${whiteSpace}`,
//BOM
`\uFEFFpass\uFEFF`
];
var props = ['name', 'short_name'];
props.forEach((prop) => {
trimNamesTests.forEach((trimmableString) => {
var assetion = `Expecting ${prop} to be trimmed.`;
var obj = {};
obj[prop] = trimmableString;
data.jsonText = JSON.stringify(obj);
var result = processor.process(data);
ise(result[prop], 'pass', assetion);
});
});
/*
* If the object is not a string, it becomes undefined
*/
props.forEach((prop) => {
typeTests.forEach((type) => {
var expected = `Expect non - string ${prop} to be undefined: ${typeof type}`;
var obj = {};
obj[prop] = type;
data.jsonText = JSON.stringify(obj);
var result = processor.process(data);
SimpleTest.ok(result[prop] === undefined, true, expected);
});
});
/**
* acceptable names - including long names
*/
var acceptableNames = [
'pass',
`pass pass pass pass pass pass pass pass pass pass pass pass pass pass
pass pass pass pass pass pass pass pass pass pass pass pass pass pass
pass pass pass pass pass pass pass pass pass pass pass pass pass pass
pass pass pass pass pass pass pass pass pass pass pass pass`,
'これは許容できる名前です',
'ນີ້ແມ່ນຊື່ທີ່ຍອມຮັບໄດ້'
];
props.forEach((prop) => {
acceptableNames.forEach((name) => {
var expected = `Expecting name to be acceptable : ${name}`;
var obj = {};
obj[prop] = name;
data.jsonText = JSON.stringify(obj);
var result = processor.process(data);
ise(result[prop], name, expected);
});
});
</script>
</head>

View File

@ -0,0 +1,83 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1079453</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
/**
* orientation member
* https://w3c.github.io/manifest/#orientation-member
**/
'use strict';
typeTests.forEach((type) => {
var expected = `Expect non-string orientation to be empty string : ${typeof type}.`;
data.jsonText = JSON.stringify({
orientation: type
});
var result = processor.process(data);
ise(result.orientation, '', expected);
});
var validOrientations = [
'any',
'natural',
'landscape',
'portrait',
'portrait-primary',
'portrait-secondary',
'landscape-primary',
'landscape-secondary'
];
validOrientations.forEach((orientation) => {
var expected = `Expect orientation to be returned: ${orientation}.`;
data.jsonText = JSON.stringify({
orientation: orientation
});
var result = processor.process(data);
ise(result.orientation, orientation, expected);
});
var invalidOrientations = [
'all',
'ANY',
'NaTuRal',
'portrait-primary portrait-secondary',
'portrait-primary,portrait-secondary',
'any-natural',
'portrait-landscape',
'primary-portrait',
'secondary-portrait',
'landscape-landscape',
'secondary-primary'
]
invalidOrientations.forEach((orientation) => {
var expected = `Expect orientation to be empty string: ${orientation}.`;
data.jsonText = JSON.stringify({
orientation: orientation
});
var result = processor.process(data);
ise(result.orientation, "", expected);
});
//Trim tests
validOrientations.forEach((orientation) => {
var expected = `Expect trimmed orientation to be returned.`;
var expandedOrientation = `${seperators}${lineTerminators}${orientation}${lineTerminators}${seperators}`;
data.jsonText = JSON.stringify({
orientation: expandedOrientation
});
var result = processor.process(data);
ise(result.orientation, orientation, expected);
});
</script>
</head>

View File

@ -0,0 +1,59 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1079453
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1079453</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script src="common.js"></script>
<script>
/**
* Manifest start_url
* https://w3c.github.io/manifest/#start_url-member
**/
'use strict';
typeTests.forEach((type) => {
var expected = `Expect non - string start_url to be doc's url: ${typeof type}.`;
data.jsonText = JSON.stringify({
start_url: type
});
var result = processor.process(data);
ise(result.start_url.toString(), docLocation.toString(), expected);
});
//Not same origin
var expected = `Expect different origin URLs to become document's URL.`;
data.jsonText = JSON.stringify({
start_url: 'http://not-same-origin'
});
var result = processor.process(data);
ise(result.start_url.toString(), docLocation.toString(), expected);
//Empty string test
var expected = `Expect empty string for start_url to become document's URL.`;
data.jsonText = JSON.stringify({
start_url: ''
});
var result = processor.process(data);
ise(result.start_url.toString(), docLocation.toString(), expected);
//Resolve URLs relative to manfiest
var URLs = ['path', '/path', '../../path',
`${whiteSpace}path${whiteSpace}`,
`${whiteSpace}/path`,
`${whiteSpace}../../path`
];
URLs.forEach((url) => {
var expected = `Resolve URLs relative to manifest.`;
data.jsonText = JSON.stringify({
start_url: url
});
var absURL = new URL(url, manifestURL).toString();
var result = processor.process(data);
ise(result.start_url.toString(), absURL, expected);
});
</script>
</head>

View File

@ -102,6 +102,7 @@ DIRS += [
'xslt',
'xul',
'resourcestats',
'manifest',
]
if CONFIG['OS_ARCH'] == 'WINNT':

View File

@ -29,8 +29,9 @@ public:
AddPattern(const nsACString& aPattern)
{
MOZ_ASSERT(!mOrigins.Count());
MOZ_ASSERT(!ContainsPattern(aPattern));
mPatterns.AppendElement(aPattern);
if (!ContainsPattern(aPattern)) {
mPatterns.AppendElement(aPattern);
}
}
bool
@ -48,8 +49,9 @@ public:
void
AddOrigin(const nsACString& aOrigin)
{
MOZ_ASSERT(!ContainsOrigin(aOrigin));
mOrigins.PutEntry(aOrigin);
if (!ContainsOrigin(aOrigin)) {
mOrigins.PutEntry(aOrigin);
}
}
private:

View File

@ -82,14 +82,24 @@ PersistenceTypeToStorage(PersistenceType aPersistenceType)
}
inline PersistenceType
PersistenceTypeFromStorage(const Optional<mozilla::dom::StorageType>& aStorage,
PersistenceType aDefaultPersistenceType)
PersistenceTypeFromStorage(const Optional<mozilla::dom::StorageType>& aStorage)
{
if (aStorage.WasPassed()) {
return PersistenceType(static_cast<int>(aStorage.Value()));
}
return aDefaultPersistenceType;
return PERSISTENCE_TYPE_PERSISTENT;
}
inline PersistenceType
ComplementaryPersistenceType(PersistenceType aPersistenceType)
{
if (aPersistenceType == PERSISTENCE_TYPE_PERSISTENT) {
return PERSISTENCE_TYPE_TEMPORARY;
}
MOZ_ASSERT(aPersistenceType == PERSISTENCE_TYPE_TEMPORARY);
return PERSISTENCE_TYPE_PERSISTENT;
}
END_QUOTA_NAMESPACE

File diff suppressed because it is too large Load Diff

View File

@ -21,7 +21,6 @@
#include "ArrayCluster.h"
#include "Client.h"
#include "PersistenceType.h"
#include "StoragePrivilege.h"
#define QUOTA_MANAGER_CONTRACTID "@mozilla.org/dom/quota/manager;1"
@ -55,6 +54,18 @@ class QuotaObject;
class ResetOrClearRunnable;
struct SynchronizedOp;
struct OriginParams
{
OriginParams(PersistenceType aPersistenceType,
const nsACString& aOrigin)
: mOrigin(aOrigin)
, mPersistenceType(aPersistenceType)
{ }
nsCString mOrigin;
PersistenceType mPersistenceType;
};
class QuotaManager MOZ_FINAL : public nsIQuotaManager,
public nsIObserver
{
@ -79,6 +90,9 @@ class QuotaManager MOZ_FINAL : public nsIQuotaManager,
typedef void
(*WaitingOnStoragesCallback)(nsTArray<nsCOMPtr<nsIOfflineStorage> >&, void*);
typedef nsClassHashtable<nsCStringHashKey,
nsTArray<nsIOfflineStorage*>> LiveStorageTable;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIQUOTAMANAGER
@ -122,7 +136,7 @@ public:
RemoveQuota();
void
RemoveQuotaForPersistenceType(PersistenceType);
RemoveQuotaForTemporaryStorage();
void
RemoveQuotaForOrigin(PersistenceType aPersistenceType,
@ -253,7 +267,7 @@ public:
EnsureOriginIsInitialized(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
bool aTrackQuota,
bool aHasUnlimStoragePerm,
nsIFile** aDirectory);
void
@ -314,30 +328,49 @@ public:
GetInfoFromURI(nsIURI* aURI,
uint32_t aAppId,
bool aInMozBrowser,
PersistenceType aPersistenceType,
nsACString* aGroup,
nsACString* aOrigin,
StoragePrivilege* aPrivilege,
PersistenceType* aDefaultPersistenceType);
bool* aIsApp,
bool* aHasUnlimStoragePerm);
static nsresult
GetInfoFromPrincipal(nsIPrincipal* aPrincipal,
PersistenceType aPersistenceType,
nsACString* aGroup,
nsACString* aOrigin,
StoragePrivilege* aPrivilege,
PersistenceType* aDefaultPersistenceType);
bool* aIsApp,
bool* aHasUnlimStoragePerm);
static nsresult
GetInfoFromWindow(nsPIDOMWindow* aWindow,
PersistenceType aPersistenceType,
nsACString* aGroup,
nsACString* aOrigin,
StoragePrivilege* aPrivilege,
PersistenceType* aDefaultPersistenceType);
bool* aIsApp,
bool* aHasUnlimStoragePerm);
static void
GetInfoForChrome(nsACString* aGroup,
nsACString* aOrigin,
StoragePrivilege* aPrivilege,
PersistenceType* aDefaultPersistenceType);
bool* aIsApp,
bool* aHasUnlimStoragePerm);
static bool
IsTreatedAsPersistent(PersistenceType aPersistenceType,
const nsACString& aOrigin);
static bool
IsTreatedAsTemporary(PersistenceType aPersistenceType,
const nsACString& aOrigin)
{
return !IsTreatedAsPersistent(aPersistenceType, aOrigin);
}
static bool
IsQuotaEnforced(PersistenceType aPersistenceType,
const nsACString& aOrigin,
bool aHasUnlimStoragePerm);
static void
ChromeOrigin(nsACString& aOrigin);
@ -412,11 +445,14 @@ private:
nsresult
MaybeUpgradeIndexedDBDirectory();
nsresult
InitializeRepository(PersistenceType aPersistenceType);
nsresult
InitializeOrigin(PersistenceType aPersistenceType,
const nsACString& aGroup,
const nsACString& aOrigin,
bool aTrackQuota,
bool aHasUnlimStoragePerm,
int64_t aAccessTime,
nsIFile* aDirectory);
@ -432,13 +468,16 @@ private:
nsTArray<OriginInfo*>& aOriginInfos);
void
DeleteTemporaryFilesForOrigin(const nsACString& aOrigin);
DeleteFilesForOrigin(PersistenceType aPersistenceType,
const nsACString& aOrigin);
void
FinalizeOriginEviction(nsTArray<nsCString>& aOrigins);
FinalizeOriginEviction(nsTArray<OriginParams>& aOrigins);
void
SaveOriginAccessTime(const nsACString& aOrigin, int64_t aTimestamp);
SaveOriginAccessTime(PersistenceType aPersistenceType,
const nsACString& aOrigin,
int64_t aTimestamp);
void
ReleaseIOThreadObjects()
@ -454,6 +493,9 @@ private:
void
AbortCloseStoragesFor(OwnerClass* aOwnerClass);
LiveStorageTable&
GetLiveStorageTable(PersistenceType aPersistenceType);
static void
GetOriginPatternString(uint32_t aAppId,
MozBrowserPatternFlag aBrowserFlag,
@ -461,9 +503,9 @@ private:
nsAutoCString& _retval);
static PLDHashOperator
RemoveQuotaForPersistenceTypeCallback(const nsACString& aKey,
nsAutoPtr<GroupInfoPair>& aValue,
void* aUserArg);
RemoveQuotaForTemporaryStorageCallback(const nsACString& aKey,
nsAutoPtr<GroupInfoPair>& aValue,
void* aUserArg);
static PLDHashOperator
RemoveQuotaCallback(const nsACString& aKey,
@ -486,9 +528,9 @@ private:
void* aUserArg);
static PLDHashOperator
AddTemporaryStorageOrigins(const nsACString& aKey,
ArrayCluster<nsIOfflineStorage*>* aValue,
void* aUserArg);
AddLiveStorageOrigins(const nsACString& aKey,
nsTArray<nsIOfflineStorage*>* aValue,
void* aUserArg);
static PLDHashOperator
GetInactiveTemporaryStorageOrigins(const nsACString& aKey,
@ -510,6 +552,9 @@ private:
nsClassHashtable<nsCStringHashKey,
ArrayCluster<nsIOfflineStorage*> > mLiveStorages;
LiveStorageTable mPersistentLiveStorageTable;
LiveStorageTable mTemporaryLiveStorageTable;
// Maintains a list of synchronized operatons that are in progress or queued.
nsAutoTArray<nsAutoPtr<SynchronizedOp>, 5> mSynchronizedOps;

View File

@ -75,7 +75,7 @@ QuotaObject::UpdateSize(int64_t aSize)
GroupInfo* groupInfo = mOriginInfo->mGroupInfo;
if (groupInfo->IsForTemporaryStorage()) {
if (mOriginInfo->IsTreatedAsTemporary()) {
quotaManager->mTemporaryStorageUsage -= mSize;
}
groupInfo->mUsage -= mSize;
@ -85,7 +85,7 @@ QuotaObject::UpdateSize(int64_t aSize)
mOriginInfo->mUsage += mSize;
groupInfo->mUsage += mSize;
if (groupInfo->IsForTemporaryStorage()) {
if (mOriginInfo->IsTreatedAsTemporary()) {
quotaManager->mTemporaryStorageUsage += mSize;
}
}
@ -106,7 +106,7 @@ QuotaObject::MaybeAllocateMoreSpace(int64_t aOffset, int32_t aCount)
GroupInfo* groupInfo = mOriginInfo->mGroupInfo;
if (groupInfo->IsForPersistentStorage()) {
if (mOriginInfo->IsTreatedAsPersistent()) {
uint64_t newUsage = mOriginInfo->mUsage - mSize + end;
if (newUsage > mOriginInfo->mLimit) {
@ -135,7 +135,7 @@ QuotaObject::MaybeAllocateMoreSpace(int64_t aOffset, int32_t aCount)
NS_ASSERTION(!mOriginInfo,
"Should have cleared in LockedClearOriginInfos!");
quotaManager->LockedRemoveQuotaForOrigin(PERSISTENCE_TYPE_PERSISTENT,
quotaManager->LockedRemoveQuotaForOrigin(groupInfo->mPersistenceType,
group, origin);
// Some other thread could increase the size without blocking (increasing
@ -156,8 +156,9 @@ QuotaObject::MaybeAllocateMoreSpace(int64_t aOffset, int32_t aCount)
return true;
}
NS_ASSERTION(groupInfo->mPersistenceType == PERSISTENCE_TYPE_TEMPORARY,
"Huh?");
nsRefPtr<GroupInfo> complementaryGroupInfo =
groupInfo->mGroupInfoPair->LockedGetGroupInfo(
ComplementaryPersistenceType(groupInfo->mPersistenceType));
uint64_t delta = end - mSize;
@ -168,9 +169,14 @@ QuotaObject::MaybeAllocateMoreSpace(int64_t aOffset, int32_t aCount)
uint64_t newGroupUsage = groupInfo->mUsage + delta;
uint64_t groupUsage = groupInfo->LockedGetTemporaryUsage();
if (complementaryGroupInfo) {
groupUsage += complementaryGroupInfo->LockedGetTemporaryUsage();
}
// Temporary storage has a hard limit for group usage (20 % of the global
// limit).
if (newGroupUsage > quotaManager->GetGroupLimit()) {
if (groupUsage + delta > quotaManager->GetGroupLimit()) {
return false;
}
@ -194,7 +200,11 @@ QuotaObject::MaybeAllocateMoreSpace(int64_t aOffset, int32_t aCount)
MutexAutoUnlock autoUnlock(quotaManager->mQuotaMutex);
for (uint32_t i = 0; i < originInfos.Length(); i++) {
quotaManager->DeleteTemporaryFilesForOrigin(originInfos[i]->mOrigin);
OriginInfo* originInfo = originInfos[i];
quotaManager->DeleteFilesForOrigin(
originInfo->mGroupInfo->mPersistenceType,
originInfo->mOrigin);
}
}
@ -202,22 +212,23 @@ QuotaObject::MaybeAllocateMoreSpace(int64_t aOffset, int32_t aCount)
NS_ASSERTION(mOriginInfo, "How come?!");
nsTArray<nsCString> origins;
nsTArray<OriginParams> origins;
for (uint32_t i = 0; i < originInfos.Length(); i++) {
OriginInfo* originInfo = originInfos[i];
NS_ASSERTION(originInfo != mOriginInfo, "Deleted itself!");
PersistenceType persistenceType =
originInfo->mGroupInfo->mPersistenceType;
nsCString group = originInfo->mGroupInfo->mGroup;
nsCString origin = originInfo->mOrigin;
quotaManager->LockedRemoveQuotaForOrigin(PERSISTENCE_TYPE_TEMPORARY,
group, origin);
quotaManager->LockedRemoveQuotaForOrigin(persistenceType, group, origin);
#ifdef DEBUG
originInfos[i] = nullptr;
#endif
origins.AppendElement(origin);
origins.AppendElement(OriginParams(persistenceType, origin));
}
// We unlocked and relocked several times so we need to recompute all the
@ -229,7 +240,12 @@ QuotaObject::MaybeAllocateMoreSpace(int64_t aOffset, int32_t aCount)
newGroupUsage = groupInfo->mUsage + delta;
if (newGroupUsage > quotaManager->GetGroupLimit()) {
groupUsage = groupInfo->LockedGetTemporaryUsage();
if (complementaryGroupInfo) {
groupUsage += complementaryGroupInfo->LockedGetTemporaryUsage();
}
if (groupUsage + delta > quotaManager->GetGroupLimit()) {
// Unfortunately some other thread increased the group usage in the
// meantime and we are not below the group limit anymore.
@ -276,6 +292,20 @@ QuotaObject::MaybeAllocateMoreSpace(int64_t aOffset, int32_t aCount)
return true;
}
bool
OriginInfo::IsTreatedAsPersistent() const
{
return QuotaManager::IsTreatedAsPersistent(mGroupInfo->mPersistenceType,
mOrigin);
}
bool
OriginInfo::IsTreatedAsTemporary() const
{
return QuotaManager::IsTreatedAsTemporary(mGroupInfo->mPersistenceType,
mOrigin);
}
void
OriginInfo::LockedDecreaseUsage(int64_t aSize)
{
@ -285,7 +315,7 @@ OriginInfo::LockedDecreaseUsage(int64_t aSize)
mGroupInfo->mUsage -= aSize;
if (mGroupInfo->IsForTemporaryStorage()) {
if (IsTreatedAsTemporary()) {
QuotaManager* quotaManager = QuotaManager::Get();
NS_ASSERTION(quotaManager, "Shouldn't be null!");
@ -335,7 +365,7 @@ GroupInfo::LockedAddOriginInfo(OriginInfo* aOriginInfo)
mUsage += aOriginInfo->mUsage;
if (IsForTemporaryStorage()) {
if (aOriginInfo->IsTreatedAsTemporary()) {
QuotaManager* quotaManager = QuotaManager::Get();
NS_ASSERTION(quotaManager, "Shouldn't be null!");
@ -352,7 +382,7 @@ GroupInfo::LockedRemoveOriginInfo(const nsACString& aOrigin)
if (mOriginInfos[index]->mOrigin == aOrigin) {
mUsage -= mOriginInfos[index]->mUsage;
if (IsForTemporaryStorage()) {
if (mOriginInfos[index]->IsTreatedAsTemporary()) {
QuotaManager* quotaManager = QuotaManager::Get();
NS_ASSERTION(quotaManager, "Shouldn't be null!");
@ -372,13 +402,15 @@ GroupInfo::LockedRemoveOriginInfos()
AssertCurrentThreadOwnsQuotaMutex();
for (uint32_t index = mOriginInfos.Length(); index > 0; index--) {
mUsage -= mOriginInfos[index - 1]->mUsage;
OriginInfo* originInfo = mOriginInfos[index - 1];
if (IsForTemporaryStorage()) {
mUsage -= originInfo->mUsage;
if (originInfo->IsTreatedAsTemporary()) {
QuotaManager* quotaManager = QuotaManager::Get();
NS_ASSERTION(quotaManager, "Shouldn't be null!");
quotaManager->mTemporaryStorageUsage -= mOriginInfos[index - 1]->mUsage;
quotaManager->mTemporaryStorageUsage -= originInfo->mUsage;
}
mOriginInfos.RemoveElementAt(index - 1);
@ -394,7 +426,7 @@ GroupInfo::LockedRemoveOriginInfosForPattern(const nsACString& aPattern)
if (PatternMatchesOrigin(aPattern, mOriginInfos[index - 1]->mOrigin)) {
mUsage -= mOriginInfos[index - 1]->mUsage;
if (IsForTemporaryStorage()) {
if (mOriginInfos[index - 1]->IsTreatedAsTemporary()) {
QuotaManager* quotaManager = QuotaManager::Get();
NS_ASSERTION(quotaManager, "Shouldn't be null!");
@ -406,6 +438,62 @@ GroupInfo::LockedRemoveOriginInfosForPattern(const nsACString& aPattern)
}
}
uint64_t
GroupInfo::LockedGetTemporaryUsage()
{
uint64_t usage = 0;
for (uint32_t count = mOriginInfos.Length(), index = 0;
index < count;
index++) {
nsRefPtr<OriginInfo>& originInfo = mOriginInfos[index];
if (originInfo->IsTreatedAsTemporary()) {
usage += originInfo->mUsage;
}
}
return usage;
}
void
GroupInfo::LockedGetTemporaryOriginInfos(nsTArray<OriginInfo*>* aOriginInfos)
{
AssertCurrentThreadOwnsQuotaMutex();
for (uint32_t count = mOriginInfos.Length(), index = 0;
index < count;
index++) {
nsRefPtr<OriginInfo>& originInfo = mOriginInfos[index];
if (originInfo->IsTreatedAsTemporary()) {
aOriginInfos->AppendElement(originInfo);
}
}
}
void
GroupInfo::LockedRemoveTemporaryOriginInfos()
{
AssertCurrentThreadOwnsQuotaMutex();
QuotaManager* quotaManager = QuotaManager::Get();
MOZ_ASSERT(quotaManager);
for (uint32_t index = mOriginInfos.Length(); index > 0; index--) {
OriginInfo* originInfo = mOriginInfos[index - 1];
if (originInfo->IsTreatedAsTemporary()) {
MOZ_ASSERT(mUsage >= originInfo->mUsage);
mUsage -= originInfo->mUsage;
MOZ_ASSERT(quotaManager->mTemporaryStorageUsage >= originInfo->mUsage);
quotaManager->mTemporaryStorageUsage -= originInfo->mUsage;
mOriginInfos.RemoveElementAt(index - 1);
}
}
}
nsRefPtr<GroupInfo>&
GroupInfoPair::GetGroupInfoForPersistenceType(PersistenceType aPersistenceType)
{

View File

@ -91,6 +91,12 @@ public:
return mAccessTime;
}
bool
IsTreatedAsPersistent() const;
bool
IsTreatedAsTemporary() const;
private:
// Private destructor, to discourage deletion outside of Release():
~OriginInfo()
@ -124,8 +130,8 @@ private:
nsDataHashtable<nsStringHashKey, QuotaObject*> mQuotaObjects;
GroupInfo* mGroupInfo;
nsCString mOrigin;
uint64_t mLimit;
const nsCString mOrigin;
const uint64_t mLimit;
uint64_t mUsage;
int64_t mAccessTime;
};
@ -155,26 +161,16 @@ class GroupInfo MOZ_FINAL
friend class QuotaObject;
public:
GroupInfo(PersistenceType aPersistenceType, const nsACString& aGroup)
: mPersistenceType(aPersistenceType), mGroup(aGroup), mUsage(0)
GroupInfo(GroupInfoPair* aGroupInfoPair, PersistenceType aPersistenceType,
const nsACString& aGroup)
: mGroupInfoPair(aGroupInfoPair), mPersistenceType(aPersistenceType),
mGroup(aGroup), mUsage(0)
{
MOZ_COUNT_CTOR(GroupInfo);
}
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GroupInfo)
bool
IsForPersistentStorage() const
{
return mPersistenceType == PERSISTENCE_TYPE_PERSISTENT;
}
bool
IsForTemporaryStorage() const
{
return mPersistenceType == PERSISTENCE_TYPE_TEMPORARY;
}
private:
// Private destructor, to discourage deletion outside of Release():
~GroupInfo()
@ -205,8 +201,18 @@ private:
return !mOriginInfos.IsEmpty();
}
uint64_t
LockedGetTemporaryUsage();
void
LockedGetTemporaryOriginInfos(nsTArray<OriginInfo*>* aOriginInfos);
void
LockedRemoveTemporaryOriginInfos();
nsTArray<nsRefPtr<OriginInfo> > mOriginInfos;
GroupInfoPair* mGroupInfoPair;
PersistenceType mPersistenceType;
nsCString mGroup;
uint64_t mUsage;
@ -215,6 +221,7 @@ private:
class GroupInfoPair
{
friend class QuotaManager;
friend class QuotaObject;
public:
GroupInfoPair()

View File

@ -1,29 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_dom_quota_storageprivilege_h__
#define mozilla_dom_quota_storageprivilege_h__
#include "mozilla/dom/quota/QuotaCommon.h"
BEGIN_QUOTA_NAMESPACE
enum StoragePrivilege {
// Quota not tracked, persistence type is always "persistent".
Chrome,
// Quota tracked, persistence type can be either "persistent" or "temporary".
// The permission "defaul-persistent-storage" is used to determine the
// default persistence type.
Content,
// Only needed for IPC serialization helper, should never be used in code.
Invalid
};
END_QUOTA_NAMESPACE
#endif // mozilla_dom_quota_storageprivilege_h__

View File

@ -26,7 +26,6 @@ EXPORTS.mozilla.dom.quota += [
'QuotaCommon.h',
'QuotaManager.h',
'QuotaObject.h',
'StoragePrivilege.h',
'UsageInfo.h',
'Utilities.h',
]

View File

@ -159,10 +159,13 @@ function runTest()
is(rect3aBounds.width, 108, "rect3a.getBoundingClientRect().width");
is(rect3aBounds.height, 108, "rect3a.getBoundingClientRect().height");
is(rect3bBounds.left, 198, "rect3b.getBoundingClientRect().left");
is(rect3bBounds.top, 198, "rect3b.getBoundingClientRect().top");
is(rect3bBounds.width, 54, "rect3b.getBoundingClientRect().width");
is(rect3bBounds.height, 54, "rect3b.getBoundingClientRect().height");
// Our PathExtentsToMaxStrokeExtents implementation considers the stroke
// width to be sqrt(2)*stroke-width in case the rect is rotated 45 degrees,
// so unfortunately we get slightly large results currently. Bug 1092125.
isWithAbsTolerance(rect3bBounds.left, 198, 1, "rect3b.getBoundingClientRect().left");
isWithAbsTolerance(rect3bBounds.top, 198, 1, "rect3b.getBoundingClientRect().top");
isWithAbsTolerance(rect3bBounds.width, 54, 2, "rect3b.getBoundingClientRect().width");
isWithAbsTolerance(rect3bBounds.height, 54, 2, "rect3b.getBoundingClientRect().height");
rect = new Rect(350 - 108 * sin45, 150 - 108 * sin45, 108 * sin45 * 2, 108 * sin45 * 2);
isWithAbsTolerance(rect4aBounds.left, rect.left, 0.1, "rect4a.getBoundingClientRect().left");

View File

@ -162,10 +162,11 @@ TelephonyIPCService::EnumerateCalls(nsITelephonyListener *aListener)
NS_IMETHODIMP
TelephonyIPCService::Dial(uint32_t aClientId, const nsAString& aNumber,
bool aIsEmergency,
nsITelephonyDialCallback *aCallback)
bool aIsEmergency,
nsITelephonyDialCallback *aCallback)
{
return SendRequest(nullptr, aCallback,
nsCOMPtr<nsITelephonyCallback> callback = do_QueryInterface(aCallback);
return SendRequest(nullptr, callback,
DialRequest(aClientId, nsString(aNumber), aIsEmergency));
}

View File

@ -180,7 +180,7 @@ FakeTVService::SetSource(const nsAString& aTunerId,
return NS_DispatchToCurrentThread(runnable);
}
class EITBroadcastedCallback : public nsITimerCallback
class EITBroadcastedCallback MOZ_FINAL : public nsITimerCallback
{
public:
NS_DECL_ISUPPORTS
@ -228,7 +228,7 @@ private:
NS_IMPL_ISUPPORTS(EITBroadcastedCallback, nsITimerCallback)
class ScanCompleteCallback : public nsITimerCallback
class ScanCompleteCallback MOZ_FINAL : public nsITimerCallback
{
public:
NS_DECL_ISUPPORTS

View File

@ -45,3 +45,5 @@ XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini']
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
FAIL_ON_WARNINGS = True

View File

@ -10,6 +10,7 @@
#include "mozilla/Preferences.h" // for Preferences
#include "mozilla/Services.h" // for GetXULChromeRegistryService
#include "mozilla/dom/Element.h" // for Element
#include "mozilla/dom/Selection.h"
#include "mozilla/mozalloc.h" // for operator delete, etc
#include "nsAString.h" // for nsAString_internal::IsEmpty, etc
#include "nsComponentManagerUtils.h" // for do_CreateInstance
@ -23,7 +24,6 @@
#include "nsIContentPrefService2.h" // for nsIContentPrefService2, etc
#include "nsIDOMDocument.h" // for nsIDOMDocument
#include "nsIDOMElement.h" // for nsIDOMElement
#include "nsIDOMRange.h" // for nsIDOMRange
#include "nsIDocument.h" // for nsIDocument
#include "nsIEditor.h" // for nsIEditor
#include "nsIHTMLEditor.h" // for nsIHTMLEditor
@ -38,6 +38,7 @@
#include "nsIVariant.h" // for nsIWritableVariant, etc
#include "nsLiteralString.h" // for NS_LITERAL_STRING, etc
#include "nsMemory.h" // for nsMemory
#include "nsRange.h"
#include "nsReadableUtils.h" // for ToNewUnicode, EmptyString, etc
#include "nsServiceManagerUtils.h" // for do_GetService
#include "nsString.h" // for nsAutoString, nsString, etc
@ -46,6 +47,7 @@
#include "nsXULAppAPI.h" // for XRE_GetProcessType
using namespace mozilla;
using namespace mozilla::dom;
class UpdateDictionaryHolder {
private:
@ -343,10 +345,9 @@ nsEditorSpellCheck::InitSpellChecker(nsIEditor* aEditor, bool aEnableSelectionCh
// Find out if the section is collapsed or not.
// If it isn't, we want to spellcheck just the selection.
nsCOMPtr<nsISelection> selection;
rv = aEditor->GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISelection> domSelection;
aEditor->GetSelection(getter_AddRefs(domSelection));
nsRefPtr<Selection> selection = static_cast<Selection*>(domSelection.get());
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
int32_t count = 0;
@ -355,10 +356,8 @@ nsEditorSpellCheck::InitSpellChecker(nsIEditor* aEditor, bool aEnableSelectionCh
NS_ENSURE_SUCCESS(rv, rv);
if (count > 0) {
nsCOMPtr<nsIDOMRange> range;
rv = selection->GetRangeAt(0, getter_AddRefs(range));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<nsRange> range = selection->GetRangeAt(0);
NS_ENSURE_STATE(range);
bool collapsed = false;
rv = range->GetCollapsed(&collapsed);
@ -368,10 +367,7 @@ nsEditorSpellCheck::InitSpellChecker(nsIEditor* aEditor, bool aEnableSelectionCh
// We don't want to touch the range in the selection,
// so create a new copy of it.
nsCOMPtr<nsIDOMRange> rangeBounds;
rv = range->CloneRange(getter_AddRefs(rangeBounds));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(rangeBounds, NS_ERROR_FAILURE);
nsRefPtr<nsRange> rangeBounds = range->CloneRange();
// Make sure the new range spans complete words.

View File

@ -21,7 +21,6 @@
#include "nsIDOMCharacterData.h"
#include "nsIEditor.h"
#include "nsINode.h"
#include "nsISelection.h"
#include "nsISupportsUtils.h"
#include "nsMemory.h"
#include "nsReadableUtils.h"

View File

@ -19,8 +19,6 @@
#include "nsINode.h"
#include "nsAString.h"
class nsIDOMRange;
using namespace mozilla;
using namespace mozilla::dom;

View File

@ -11,7 +11,6 @@
#include "nsEditor.h"
#include "nsError.h"
#include "nsIEditor.h"
#include "nsISelection.h"
#include "nsISupportsImpl.h"
#include "nsSelectionState.h"
#include "nsAString.h"

View File

@ -1,120 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdio.h> // for printf
#include "JoinElementTxn.h"
#include "nsAString.h"
#include "nsDebug.h" // for NS_ASSERTION, etc
#include "nsEditor.h" // for nsEditor
#include "nsError.h" // for NS_ERROR_NULL_POINTER, etc
#include "nsIContent.h" // for nsIContent
#include "nsIDOMCharacterData.h" // for nsIDOMCharacterData
#include "nsIEditor.h" // for nsEditor::IsModifiableNode
#include "nsISupportsImpl.h" // for EditTxn::QueryInterface, etc
using namespace mozilla;
JoinElementTxn::JoinElementTxn()
: EditTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(JoinElementTxn, EditTxn,
mLeftNode,
mRightNode,
mParent)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(JoinElementTxn)
NS_INTERFACE_MAP_END_INHERITING(EditTxn)
NS_IMETHODIMP JoinElementTxn::Init(nsEditor *aEditor,
nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode)
{
NS_PRECONDITION((aEditor && aLeftNode && aRightNode), "null arg");
if (!aEditor || !aLeftNode || !aRightNode) { return NS_ERROR_NULL_POINTER; }
mEditor = aEditor;
mLeftNode = do_QueryInterface(aLeftNode);
nsCOMPtr<nsIDOMNode>leftParent;
nsresult result = mLeftNode->GetParentNode(getter_AddRefs(leftParent));
NS_ENSURE_SUCCESS(result, result);
if (!mEditor->IsModifiableNode(leftParent)) {
return NS_ERROR_FAILURE;
}
mRightNode = do_QueryInterface(aRightNode);
mOffset = 0;
return NS_OK;
}
// After DoTransaction() and RedoTransaction(), the left node is removed from the content tree and right node remains.
NS_IMETHODIMP JoinElementTxn::DoTransaction(void)
{
NS_PRECONDITION((mEditor && mLeftNode && mRightNode), "null arg");
if (!mEditor || !mLeftNode || !mRightNode) { return NS_ERROR_NOT_INITIALIZED; }
// get the parent node
nsCOMPtr<nsINode> leftNode = do_QueryInterface(mLeftNode);
nsCOMPtr<nsINode> leftParent = leftNode->GetParentNode();
NS_ENSURE_TRUE(leftParent, NS_ERROR_NULL_POINTER);
// verify that mLeftNode and mRightNode have the same parent
nsCOMPtr<nsINode> rightNode = do_QueryInterface(mRightNode);
nsCOMPtr<nsINode> rightParent = rightNode->GetParentNode();
NS_ENSURE_TRUE(rightParent, NS_ERROR_NULL_POINTER);
if (leftParent != rightParent) {
NS_ASSERTION(false, "2 nodes do not have same parent");
return NS_ERROR_INVALID_ARG;
}
// set this instance mParent.
// Other methods will see a non-null mParent and know all is well
mParent = leftParent->AsDOMNode();
mOffset = leftNode->Length();
nsCOMPtr<nsINode> parent = do_QueryInterface(mParent);
return mEditor->JoinNodesImpl(rightNode, leftNode, parent);
}
//XXX: what if instead of split, we just deleted the unneeded children of mRight
// and re-inserted mLeft?
NS_IMETHODIMP JoinElementTxn::UndoTransaction(void)
{
NS_ASSERTION(mRightNode && mLeftNode && mParent, "bad state");
if (!mRightNode || !mLeftNode || !mParent) { return NS_ERROR_NOT_INITIALIZED; }
// first, massage the existing node so it is in its post-split state
nsresult result;
nsCOMPtr<nsIDOMNode>resultNode;
nsCOMPtr<nsIDOMCharacterData>rightNodeAsText = do_QueryInterface(mRightNode);
if (rightNodeAsText)
{
result = rightNodeAsText->DeleteData(0, mOffset);
}
else
{
nsCOMPtr<nsIDOMNode>child;
result = mRightNode->GetFirstChild(getter_AddRefs(child));
nsCOMPtr<nsIDOMNode>nextSibling;
uint32_t i;
for (i=0; i<mOffset; i++)
{
if (NS_FAILED(result)) {return result;}
if (!child) {return NS_ERROR_NULL_POINTER;}
child->GetNextSibling(getter_AddRefs(nextSibling));
result = mLeftNode->AppendChild(child, getter_AddRefs(resultNode));
child = do_QueryInterface(nextSibling);
}
}
// second, re-insert the left node into the tree
result = mParent->InsertBefore(mLeftNode, mRightNode, getter_AddRefs(resultNode));
return result;
}
NS_IMETHODIMP JoinElementTxn::GetTxnDescription(nsAString& aString)
{
aString.AssignLiteral("JoinElementTxn");
return NS_OK;
}

View File

@ -1,63 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef JoinElementTxn_h__
#define JoinElementTxn_h__
#include "EditTxn.h" // for EditTxn, NS_DECL_EDITTXN
#include "nsCOMPtr.h" // for nsCOMPtr
#include "nsCycleCollectionParticipant.h"
#include "nsID.h" // for REFNSIID
#include "nsIDOMNode.h" // for nsIDOMNode
#include "nscore.h" // for NS_IMETHOD
class nsEditor;
/**
* A transaction that joins two elements E1 (left node) and E2 (right node)
* into a single node E.
* The children of E are the children of E1 followed by the children of E2.
* After DoTransaction() and RedoTransaction(), E1 is removed from the content
* tree and E2 remains.
*/
class JoinElementTxn : public EditTxn
{
public:
/** initialize the transaction
* @param aEditor the provider of core editing operations
* @param aLeftNode the first of two nodes to join
* @param aRightNode the second of two nodes to join
*/
NS_IMETHOD Init(nsEditor *aEditor,
nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode);
JoinElementTxn();
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(JoinElementTxn, EditTxn)
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_DECL_EDITTXN
protected:
/** the elements to operate upon.
* After the merge, mRightNode remains and mLeftNode is removed from the content tree.
*/
nsCOMPtr<nsIDOMNode> mLeftNode;
nsCOMPtr<nsIDOMNode> mRightNode;
/** the offset into mNode where the children of mElement are split (for undo).<BR>
* mOffset is the index of the first child in the right node.
* -1 means the left node had no children.
*/
uint32_t mOffset;
/** the parent node containing mLeftNode and mRightNode */
nsCOMPtr<nsIDOMNode> mParent;
nsEditor* mEditor;
};
#endif

View File

@ -0,0 +1,107 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdio.h> // for printf
#include "JoinNodeTxn.h"
#include "nsAString.h"
#include "nsDebug.h" // for NS_ASSERTION, etc
#include "nsEditor.h" // for nsEditor
#include "nsError.h" // for NS_ERROR_NULL_POINTER, etc
#include "nsIContent.h" // for nsIContent
#include "nsIDOMCharacterData.h" // for nsIDOMCharacterData
#include "nsIEditor.h" // for nsEditor::IsModifiableNode
#include "nsISupportsImpl.h" // for EditTxn::QueryInterface, etc
using namespace mozilla;
using namespace mozilla::dom;
JoinNodeTxn::JoinNodeTxn(nsEditor& aEditor, nsINode& aLeftNode,
nsINode& aRightNode)
: EditTxn()
, mEditor(aEditor)
, mLeftNode(&aLeftNode)
, mRightNode(&aRightNode)
, mOffset(0)
, mParent(nullptr)
{
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(JoinNodeTxn, EditTxn,
mLeftNode,
mRightNode,
mParent)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(JoinNodeTxn)
NS_INTERFACE_MAP_END_INHERITING(EditTxn)
nsresult
JoinNodeTxn::CheckValidity()
{
if (!mEditor.IsModifiableNode(mLeftNode->GetParentNode())) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
// After DoTransaction() and RedoTransaction(), the left node is removed from
// the content tree and right node remains.
NS_IMETHODIMP
JoinNodeTxn::DoTransaction()
{
// Get the parent node
nsCOMPtr<nsINode> leftParent = mLeftNode->GetParentNode();
NS_ENSURE_TRUE(leftParent, NS_ERROR_NULL_POINTER);
// Verify that mLeftNode and mRightNode have the same parent
if (leftParent != mRightNode->GetParentNode()) {
NS_ASSERTION(false, "Nodes do not have same parent");
return NS_ERROR_INVALID_ARG;
}
// Set this instance's mParent. Other methods will see a non-null mParent
// and know all is well
mParent = leftParent;
mOffset = mLeftNode->Length();
return mEditor.JoinNodesImpl(mRightNode, mLeftNode, mParent);
}
//XXX: What if instead of split, we just deleted the unneeded children of
// mRight and re-inserted mLeft?
NS_IMETHODIMP
JoinNodeTxn::UndoTransaction()
{
MOZ_ASSERT(mParent);
// First, massage the existing node so it is in its post-split state
ErrorResult rv;
if (mRightNode->GetAsText()) {
rv = mRightNode->GetAsText()->DeleteData(0, mOffset);
} else {
nsCOMPtr<nsIContent> child = mRightNode->GetFirstChild();
for (uint32_t i = 0; i < mOffset; i++) {
if (rv.Failed()) {
return rv.ErrorCode();
}
if (!child) {
return NS_ERROR_NULL_POINTER;
}
nsCOMPtr<nsIContent> nextSibling = child->GetNextSibling();
mLeftNode->AppendChild(*child, rv);
child = nextSibling;
}
}
// Second, re-insert the left node into the tree
mParent->InsertBefore(*mLeftNode, mRightNode, rv);
return rv.ErrorCode();
}
NS_IMETHODIMP
JoinNodeTxn::GetTxnDescription(nsAString& aString)
{
aString.AssignLiteral("JoinNodeTxn");
return NS_OK;
}

View File

@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef JoinNodeTxn_h__
#define JoinNodeTxn_h__
#include "EditTxn.h" // for EditTxn, NS_DECL_EDITTXN
#include "nsCOMPtr.h" // for nsCOMPtr
#include "nsCycleCollectionParticipant.h"
#include "nsID.h" // for REFNSIID
#include "nscore.h" // for NS_IMETHOD
class nsEditor;
class nsINode;
namespace mozilla {
namespace dom {
/**
* A transaction that joins two nodes E1 (left node) and E2 (right node) into a
* single node E. The children of E are the children of E1 followed by the
* children of E2. After DoTransaction() and RedoTransaction(), E1 is removed
* from the content tree and E2 remains.
*/
class JoinNodeTxn : public EditTxn
{
public:
/** @param aEditor the provider of core editing operations
* @param aLeftNode the first of two nodes to join
* @param aRightNode the second of two nodes to join
*/
JoinNodeTxn(nsEditor& aEditor, nsINode& aLeftNode, nsINode& aRightNode);
/* Call this after constructing to ensure the inputs are correct */
nsresult CheckValidity();
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(JoinNodeTxn, EditTxn)
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr);
NS_DECL_EDITTXN
protected:
nsEditor& mEditor;
/** The nodes to operate upon. After the merge, mRightNode remains and
* mLeftNode is removed from the content tree.
*/
nsCOMPtr<nsINode> mLeftNode;
nsCOMPtr<nsINode> mRightNode;
/** The offset into mNode where the children of mElement are split (for
* undo). mOffset is the index of the first child in the right node. -1
* means the left node had no children.
*/
uint32_t mOffset;
/** The parent node containing mLeftNode and mRightNode */
nsCOMPtr<nsINode> mParent;
};
}
}
#endif

View File

@ -75,9 +75,7 @@ NS_IMETHODIMP PlaceholderTxn::UndoTransaction(void)
NS_ENSURE_TRUE(mStartSel, NS_ERROR_NULL_POINTER);
// now restore selection
nsCOMPtr<nsISelection> selection;
res = mEditor->GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = mEditor->GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
return mStartSel->RestoreSelection(selection);
}
@ -90,9 +88,7 @@ NS_IMETHODIMP PlaceholderTxn::RedoTransaction(void)
NS_ENSURE_SUCCESS(res, res);
// now restore selection
nsCOMPtr<nsISelection> selection;
res = mEditor->GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = mEditor->GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
return mEndSel.RestoreSelection(selection);
}

View File

@ -1,161 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdio.h> // for printf
#include "SplitElementTxn.h"
#include "nsAString.h"
#include "nsDebug.h" // for NS_ASSERTION, etc
#include "nsEditor.h" // for nsEditor
#include "nsError.h" // for NS_ERROR_NOT_INITIALIZED, etc
#include "nsIContent.h" // for nsIContent
#include "nsIDOMCharacterData.h" // for nsIDOMCharacterData
#include "nsIEditor.h" // for nsEditor::DebugDumpContent, etc
#include "nsISelection.h" // for nsISelection
#include "nsISupportsUtils.h" // for NS_ADDREF
using namespace mozilla;
// note that aEditor is not refcounted
SplitElementTxn::SplitElementTxn()
: EditTxn()
{
}
SplitElementTxn::~SplitElementTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(SplitElementTxn, EditTxn,
mParent,
mNewLeftNode)
NS_IMPL_ADDREF_INHERITED(SplitElementTxn, EditTxn)
NS_IMPL_RELEASE_INHERITED(SplitElementTxn, EditTxn)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SplitElementTxn)
NS_INTERFACE_MAP_END_INHERITING(EditTxn)
NS_IMETHODIMP SplitElementTxn::Init(nsEditor *aEditor,
nsIDOMNode *aNode,
int32_t aOffset)
{
NS_ASSERTION(aEditor && aNode, "bad args");
if (!aEditor || !aNode) { return NS_ERROR_NOT_INITIALIZED; }
mEditor = aEditor;
mExistingRightNode = do_QueryInterface(aNode);
mOffset = aOffset;
return NS_OK;
}
NS_IMETHODIMP SplitElementTxn::DoTransaction(void)
{
NS_ASSERTION(mExistingRightNode && mEditor, "bad state");
if (!mExistingRightNode || !mEditor) { return NS_ERROR_NOT_INITIALIZED; }
// create a new node
nsresult result = mExistingRightNode->CloneNode(false, 1, getter_AddRefs(mNewLeftNode));
NS_ASSERTION(((NS_SUCCEEDED(result)) && (mNewLeftNode)), "could not create element.");
NS_ENSURE_SUCCESS(result, result);
mEditor->MarkNodeDirty(mExistingRightNode);
// get the parent node
result = mExistingRightNode->GetParentNode(getter_AddRefs(mParent));
NS_ENSURE_SUCCESS(result, result);
NS_ENSURE_TRUE(mParent, NS_ERROR_NULL_POINTER);
// insert the new node
result = mEditor->SplitNodeImpl(mExistingRightNode, mOffset, mNewLeftNode, mParent);
if (mNewLeftNode) {
bool bAdjustSelection;
mEditor->ShouldTxnSetSelection(&bAdjustSelection);
if (bAdjustSelection)
{
nsCOMPtr<nsISelection> selection;
result = mEditor->GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(result, result);
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
result = selection->Collapse(mNewLeftNode, mOffset);
}
else
{
// do nothing - dom range gravity will adjust selection
}
}
return result;
}
NS_IMETHODIMP SplitElementTxn::UndoTransaction(void)
{
NS_ASSERTION(mEditor && mExistingRightNode && mNewLeftNode && mParent, "bad state");
if (!mEditor || !mExistingRightNode || !mNewLeftNode || !mParent) {
return NS_ERROR_NOT_INITIALIZED;
}
// this assumes Do inserted the new node in front of the prior existing node
nsCOMPtr<nsINode> right = do_QueryInterface(mExistingRightNode);
nsCOMPtr<nsINode> left = do_QueryInterface(mNewLeftNode);
nsCOMPtr<nsINode> parent = do_QueryInterface(mParent);
return mEditor->JoinNodesImpl(right, left, parent);
}
/* redo cannot simply resplit the right node, because subsequent transactions
* on the redo stack may depend on the left node existing in its previous state.
*/
NS_IMETHODIMP SplitElementTxn::RedoTransaction(void)
{
NS_ASSERTION(mEditor && mExistingRightNode && mNewLeftNode && mParent, "bad state");
if (!mEditor || !mExistingRightNode || !mNewLeftNode || !mParent) {
return NS_ERROR_NOT_INITIALIZED;
}
nsresult result;
nsCOMPtr<nsIDOMNode>resultNode;
// first, massage the existing node so it is in its post-split state
nsCOMPtr<nsIDOMCharacterData>rightNodeAsText = do_QueryInterface(mExistingRightNode);
if (rightNodeAsText)
{
nsresult result = rightNodeAsText->DeleteData(0, mOffset);
NS_ENSURE_SUCCESS(result, result);
}
else
{
nsCOMPtr<nsIDOMNode>child;
nsCOMPtr<nsIDOMNode>nextSibling;
result = mExistingRightNode->GetFirstChild(getter_AddRefs(child));
int32_t i;
for (i=0; i<mOffset; i++)
{
if (NS_FAILED(result)) {return result;}
if (!child) {return NS_ERROR_NULL_POINTER;}
child->GetNextSibling(getter_AddRefs(nextSibling));
result = mExistingRightNode->RemoveChild(child, getter_AddRefs(resultNode));
if (NS_SUCCEEDED(result))
{
result = mNewLeftNode->AppendChild(child, getter_AddRefs(resultNode));
}
child = do_QueryInterface(nextSibling);
}
}
// second, re-insert the left node into the tree
result = mParent->InsertBefore(mNewLeftNode, mExistingRightNode, getter_AddRefs(resultNode));
return result;
}
NS_IMETHODIMP SplitElementTxn::GetTxnDescription(nsAString& aString)
{
aString.AssignLiteral("SplitElementTxn");
return NS_OK;
}
NS_IMETHODIMP SplitElementTxn::GetNewNode(nsIDOMNode **aNewNode)
{
NS_ENSURE_TRUE(aNewNode, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(mNewLeftNode, NS_ERROR_NOT_INITIALIZED);
*aNewNode = mNewLeftNode;
NS_ADDREF(*aNewNode);
return NS_OK;
}

View File

@ -1,67 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef SplitElementTxn_h__
#define SplitElementTxn_h__
#include "EditTxn.h" // for EditTxn, NS_DECL_EDITTXN
#include "nsCOMPtr.h" // for nsCOMPtr
#include "nsCycleCollectionParticipant.h"
#include "nsIDOMNode.h" // for nsIDOMNode
#include "nsISupportsImpl.h" // for NS_DECL_ISUPPORTS_INHERITED
#include "nscore.h" // for NS_IMETHOD
class nsEditor;
/**
* A transaction that splits an element E into two identical nodes, E1 and E2
* with the children of E divided between E1 and E2.
*/
class SplitElementTxn : public EditTxn
{
public:
/** initialize the transaction.
* @param aEditor the provider of core editing operations
* @param aNode the node to split
* @param aOffset the location within aNode to do the split.
* aOffset may refer to children of aNode, or content of aNode.
* The left node will have child|content 0..aOffset-1.
*/
NS_IMETHOD Init (nsEditor *aEditor,
nsIDOMNode *aNode,
int32_t aOffset);
SplitElementTxn();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SplitElementTxn, EditTxn)
NS_DECL_EDITTXN
NS_IMETHOD RedoTransaction(void);
NS_IMETHOD GetNewNode(nsIDOMNode **aNewNode);
protected:
virtual ~SplitElementTxn();
/** the element to operate upon */
nsCOMPtr<nsIDOMNode> mExistingRightNode;
/** the offset into mElement where the children of mElement are split.<BR>
* mOffset is the index of the first child in the right node.
* -1 means the new node gets no children.
*/
int32_t mOffset;
/** the element we create when splitting mElement */
nsCOMPtr<nsIDOMNode> mNewLeftNode;
/** the parent shared by mExistingRightNode and mNewLeftNode */
nsCOMPtr<nsIDOMNode> mParent;
nsEditor* mEditor;
};
#endif

View File

@ -0,0 +1,128 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdio.h> // for printf
#include "mozilla/dom/Selection.h"
#include "SplitNodeTxn.h"
#include "nsAString.h"
#include "nsDebug.h" // for NS_ASSERTION, etc
#include "nsEditor.h" // for nsEditor
#include "nsError.h" // for NS_ERROR_NOT_INITIALIZED, etc
#include "nsIContent.h" // for nsIContent
using namespace mozilla;
using namespace mozilla::dom;
// note that aEditor is not refcounted
SplitNodeTxn::SplitNodeTxn(nsEditor& aEditor, nsIContent& aNode,
int32_t aOffset)
: EditTxn()
, mEditor(aEditor)
, mExistingRightNode(&aNode)
, mOffset(aOffset)
, mNewLeftNode(nullptr)
, mParent(nullptr)
{
}
SplitNodeTxn::~SplitNodeTxn()
{
}
NS_IMPL_CYCLE_COLLECTION_INHERITED(SplitNodeTxn, EditTxn,
mParent,
mNewLeftNode)
NS_IMPL_ADDREF_INHERITED(SplitNodeTxn, EditTxn)
NS_IMPL_RELEASE_INHERITED(SplitNodeTxn, EditTxn)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SplitNodeTxn)
NS_INTERFACE_MAP_END_INHERITING(EditTxn)
NS_IMETHODIMP
SplitNodeTxn::DoTransaction()
{
// Create a new node
ErrorResult rv;
// Don't use .downcast directly because AsContent has an assertion we want
nsCOMPtr<nsINode> clone = mExistingRightNode->CloneNode(false, rv);
NS_ASSERTION(!rv.Failed() && clone, "Could not create clone");
NS_ENSURE_TRUE(!rv.Failed() && clone, rv.ErrorCode());
mNewLeftNode = dont_AddRef(clone.forget().take()->AsContent());
mEditor.MarkNodeDirty(mExistingRightNode->AsDOMNode());
// Get the parent node
mParent = mExistingRightNode->GetParentNode();
NS_ENSURE_TRUE(mParent, NS_ERROR_NULL_POINTER);
// Insert the new node
rv = mEditor.SplitNodeImpl(*mExistingRightNode, mOffset, *mNewLeftNode);
if (mEditor.GetShouldTxnSetSelection()) {
nsRefPtr<Selection> selection = mEditor.GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
rv = selection->Collapse(mNewLeftNode, mOffset);
}
return rv.ErrorCode();
}
NS_IMETHODIMP
SplitNodeTxn::UndoTransaction()
{
MOZ_ASSERT(mNewLeftNode && mParent);
// This assumes Do inserted the new node in front of the prior existing node
return mEditor.JoinNodesImpl(mExistingRightNode, mNewLeftNode, mParent);
}
/* Redo cannot simply resplit the right node, because subsequent transactions
* on the redo stack may depend on the left node existing in its previous
* state.
*/
NS_IMETHODIMP
SplitNodeTxn::RedoTransaction()
{
MOZ_ASSERT(mNewLeftNode && mParent);
ErrorResult rv;
// First, massage the existing node so it is in its post-split state
if (mExistingRightNode->GetAsText()) {
rv = mExistingRightNode->GetAsText()->DeleteData(0, mOffset);
NS_ENSURE_SUCCESS(rv.ErrorCode(), rv.ErrorCode());
} else {
nsCOMPtr<nsIContent> child = mExistingRightNode->GetFirstChild();
nsCOMPtr<nsIContent> nextSibling;
for (int32_t i=0; i < mOffset; i++) {
if (rv.Failed()) {
return rv.ErrorCode();
}
if (!child) {
return NS_ERROR_NULL_POINTER;
}
nextSibling = child->GetNextSibling();
mExistingRightNode->RemoveChild(*child, rv);
if (!rv.Failed()) {
mNewLeftNode->AppendChild(*child, rv);
}
child = nextSibling;
}
}
// Second, re-insert the left node into the tree
mParent->InsertBefore(*mNewLeftNode, mExistingRightNode, rv);
return rv.ErrorCode();
}
NS_IMETHODIMP
SplitNodeTxn::GetTxnDescription(nsAString& aString)
{
aString.AssignLiteral("SplitNodeTxn");
return NS_OK;
}
nsIContent*
SplitNodeTxn::GetNewNode()
{
return mNewLeftNode;
}

View File

@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef SplitNodeTxn_h__
#define SplitNodeTxn_h__
#include "EditTxn.h" // for EditTxn, NS_DECL_EDITTXN
#include "nsCOMPtr.h" // for nsCOMPtr
#include "nsCycleCollectionParticipant.h"
#include "nsISupportsImpl.h" // for NS_DECL_ISUPPORTS_INHERITED
#include "nscore.h" // for NS_IMETHOD
class nsEditor;
class nsIContent;
namespace mozilla {
namespace dom {
/**
* A transaction that splits a node into two identical nodes, with the children
* divided between the new nodes.
*/
class SplitNodeTxn : public EditTxn
{
public:
/** @param aEditor The provider of core editing operations
* @param aNode The node to split
* @param aOffset The location within aNode to do the split.
* aOffset may refer to children of aNode, or content of aNode.
* The left node will have child|content 0..aOffset-1.
*/
SplitNodeTxn(nsEditor& aEditor, nsIContent& aNode, int32_t aOffset);
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SplitNodeTxn, EditTxn)
NS_DECL_EDITTXN
NS_IMETHOD RedoTransaction();
nsIContent* GetNewNode();
protected:
virtual ~SplitNodeTxn();
nsEditor& mEditor;
/** The node to operate upon */
nsCOMPtr<nsIContent> mExistingRightNode;
/** The offset into mExistingRightNode where its children are split. mOffset
* is the index of the first child in the right node. -1 means the new node
* gets no children.
*/
int32_t mOffset;
/** The node we create when splitting mExistingRightNode */
nsCOMPtr<nsIContent> mNewLeftNode;
/** The parent shared by mExistingRightNode and mNewLeftNode */
nsCOMPtr<nsINode> mParent;
};
}
}
#endif

View File

@ -7,6 +7,7 @@
#include <stddef.h>
#include "TypeInState.h"
#include "mozilla/dom/Selection.h"
#include "mozilla/mozalloc.h"
#include "nsAString.h"
#include "nsDebug.h"
@ -14,7 +15,6 @@
#include "nsError.h"
#include "nsGkAtoms.h"
#include "nsIDOMNode.h"
#include "nsISelection.h"
#include "nsISupportsBase.h"
#include "nsISupportsImpl.h"
#include "nsReadableUtils.h"
@ -23,6 +23,9 @@
class nsIAtom;
class nsIDOMDocument;
using namespace mozilla;
using namespace mozilla::dom;
/********************************************************************
* XPCOM cruft
*******************************************************************/
@ -56,7 +59,8 @@ TypeInState::~TypeInState()
Reset();
}
nsresult TypeInState::UpdateSelState(nsISelection *aSelection)
nsresult
TypeInState::UpdateSelState(Selection* aSelection)
{
NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
@ -79,17 +83,18 @@ NS_IMETHODIMP TypeInState::NotifySelectionChanged(nsIDOMDocument *, nsISelection
// XXX:
// XXX: This code temporarily fixes the problem where clicking the mouse in
// XXX: the same location clears the type-in-state.
nsRefPtr<Selection> selection = static_cast<Selection*>(aSelection);
if (aSelection) {
int32_t rangeCount = 0;
nsresult result = aSelection->GetRangeCount(&rangeCount);
NS_ENSURE_SUCCESS(result, result);
int32_t rangeCount = selection->GetRangeCount();
if (aSelection->Collapsed() && rangeCount) {
if (selection->Collapsed() && rangeCount) {
nsCOMPtr<nsIDOMNode> selNode;
int32_t selOffset = 0;
result = nsEditor::GetStartNodeAndOffset(aSelection, getter_AddRefs(selNode), &selOffset);
nsresult result =
nsEditor::GetStartNodeAndOffset(selection, getter_AddRefs(selNode),
&selOffset);
NS_ENSURE_SUCCESS(result, result);

View File

@ -16,7 +16,11 @@
class nsIAtom;
class nsIDOMNode;
class nsISelection;
namespace mozilla {
namespace dom {
class Selection;
}
}
struct PropItem
{
@ -39,7 +43,7 @@ public:
TypeInState();
void Reset();
nsresult UpdateSelState(nsISelection *aSelection);
nsresult UpdateSelState(mozilla::dom::Selection* aSelection);
// nsISelectionListener
NS_DECL_NSISELECTIONLISTENER

View File

@ -23,7 +23,7 @@ UNIFIED_SOURCES += [
'IMETextTxn.cpp',
'InsertNodeTxn.cpp',
'InsertTextTxn.cpp',
'JoinElementTxn.cpp',
'JoinNodeTxn.cpp',
'nsEditor.cpp',
'nsEditorCommands.cpp',
'nsEditorController.cpp',
@ -53,7 +53,7 @@ UNIFIED_SOURCES += [
'nsWSRunObject.cpp',
'PlaceholderTxn.cpp',
'SetDocTitleTxn.cpp',
'SplitElementTxn.cpp',
'SplitNodeTxn.cpp',
'TextEditorTest.cpp',
'TypeInState.cpp',
]

View File

@ -10,10 +10,14 @@
{ 0x3836386d, 0x806a, 0x488d, \
{ 0x8b, 0xab, 0xaf, 0x42, 0xbb, 0x4c, 0x90, 0x66 } }
#include "nsEditor.h"
#include "nsEditor.h" // for EditAction enum
class nsPlaintextEditor;
class nsISelection;
namespace mozilla {
namespace dom {
class Selection;
}
}
/***************************************************************************
* base for an object to encapsulate any additional info needed to be passed
@ -50,7 +54,8 @@ public:
nsIEditor::EDirection aDirection) = 0;
NS_IMETHOD WillDoAction(mozilla::dom::Selection* aSelection, nsRulesInfo* aInfo,
bool* aCancel, bool* aHandled) = 0;
NS_IMETHOD DidDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult)=0;
NS_IMETHOD DidDoAction(mozilla::dom::Selection* aSelection,
nsRulesInfo* aInfo, nsresult aResult) = 0;
NS_IMETHOD DocumentIsEmpty(bool *aDocumentIsEmpty)=0;
NS_IMETHOD DocumentModified()=0;
};

File diff suppressed because it is too large Load Diff

View File

@ -30,9 +30,7 @@
class AddStyleSheetTxn;
class DeleteNodeTxn;
class EditAggregateTxn;
class JoinElementTxn;
class RemoveStyleSheetTxn;
class SplitElementTxn;
class nsIAtom;
class nsIContent;
class nsIDOMCharacterData;
@ -44,7 +42,6 @@ class nsIDOMEventListener;
class nsIDOMEventTarget;
class nsIDOMKeyEvent;
class nsIDOMNode;
class nsIDOMRange;
class nsIDocument;
class nsIDocumentStateListener;
class nsIEditActionListener;
@ -52,13 +49,13 @@ class nsIEditorObserver;
class nsIInlineSpellChecker;
class nsINode;
class nsIPresShell;
class nsISelection;
class nsISupports;
class nsITransaction;
class nsIWidget;
class nsRange;
class nsString;
class nsTransactionManager;
struct DOMPoint;
namespace mozilla {
class CSSStyleSheet;
@ -75,7 +72,9 @@ class EventTarget;
class IMETextTxn;
class InsertTextTxn;
class InsertNodeTxn;
class JoinNodeTxn;
class Selection;
class SplitNodeTxn;
class Text;
} // namespace dom
} // namespace mozilla
@ -202,18 +201,19 @@ public:
virtual bool IsModifiableNode(nsINode *aNode);
NS_IMETHOD InsertTextImpl(const nsAString& aStringToInsert,
nsCOMPtr<nsIDOMNode> *aInOutNode,
int32_t *aInOutOffset,
nsIDOMDocument *aDoc);
virtual nsresult InsertTextImpl(const nsAString& aStringToInsert,
nsCOMPtr<nsINode>* aInOutNode,
int32_t* aInOutOffset,
nsIDocument* aDoc);
nsresult InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
mozilla::dom::Text& aTextNode,
int32_t aOffset,
bool aSuppressIME = false);
NS_IMETHOD DeleteSelectionImpl(EDirection aAction,
EStripWrappers aStripWrappers);
NS_IMETHOD DeleteSelectionAndCreateNode(const nsAString& aTag,
nsIDOMNode ** aNewNode);
already_AddRefed<mozilla::dom::Element>
DeleteSelectionAndCreateElement(nsIAtom& aTag);
/* helper routines for node/parent manipulations */
nsresult DeleteNode(nsINode* aNode);
@ -234,7 +234,9 @@ public:
nsIAtom* aNodeType,
nsIAtom* aAttribute = nullptr,
const nsAString* aValue = nullptr);
nsresult JoinNodes(nsINode* aNodeToKeep, nsIContent* aNodeToMove);
nsIContent* SplitNode(nsIContent& aNode, int32_t aOffset,
mozilla::ErrorResult& aResult);
nsresult JoinNodes(nsINode& aLeftNode, nsINode& aRightNode);
nsresult MoveNode(nsIContent* aNode, nsINode* aParent, int32_t aOffset);
/* Method to replace certain CreateElementNS() calls.
@ -337,13 +339,11 @@ protected:
CreateTxnForDeleteCharacter(nsGenericDOMDataNode& aData, uint32_t aOffset,
EDirection aDirection);
NS_IMETHOD CreateTxnForSplitNode(nsIDOMNode *aNode,
uint32_t aOffset,
SplitElementTxn **aTxn);
already_AddRefed<mozilla::dom::SplitNodeTxn>
CreateTxnForSplitNode(nsIContent& aNode, uint32_t aOffset);
NS_IMETHOD CreateTxnForJoinNode(nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode,
JoinElementTxn **aTxn);
already_AddRefed<mozilla::dom::JoinNodeTxn>
CreateTxnForJoinNode(nsINode& aLeftNode, nsINode& aRightNode);
/**
* This method first deletes the selection, if it's not collapsed. Then if
@ -372,7 +372,7 @@ protected:
NS_IMETHOD NotifyDocumentListeners(TDocumentListenerNotification aNotificationType);
/** make the given selection span the entire document */
NS_IMETHOD SelectEntireDocument(nsISelection *aSelection);
virtual nsresult SelectEntireDocument(mozilla::dom::Selection* aSelection);
/** helper method for scrolling the selection into view after
* an edit operation. aScrollToAnchor should be true if you
@ -437,20 +437,22 @@ public:
* various editor actions */
bool ArePreservingSelection();
void PreserveSelectionAcrossActions(mozilla::dom::Selection* aSel);
nsresult RestorePreservedSelection(nsISelection *aSel);
nsresult RestorePreservedSelection(mozilla::dom::Selection* aSel);
void StopPreservingSelection();
/**
* SplitNode() creates a new node identical to an existing node, and split the contents between the two nodes
* @param aExistingRightNode the node to split. It will become the new node's next sibling.
* @param aOffset the offset of aExistingRightNode's content|children to do the split at
* @param aNewLeftNode [OUT] the new node resulting from the split, becomes aExistingRightNode's previous sibling.
* @param aParent the parent of aExistingRightNode
* SplitNode() creates a new node identical to an existing node, and split
* the contents between the two nodes
* @param aExistingRightNode The node to split. It will become the new
* node's next sibling.
* @param aOffset The offset of aExistingRightNode's
* content|children to do the split at
* @param aNewLeftNode The new node resulting from the split, becomes
* aExistingRightNode's previous sibling.
*/
nsresult SplitNodeImpl(nsIDOMNode *aExistingRightNode,
int32_t aOffset,
nsIDOMNode *aNewLeftNode,
nsIDOMNode *aParent);
nsresult SplitNodeImpl(nsIContent& aExistingRightNode,
int32_t aOffset,
nsIContent& aNewLeftNode);
/**
* JoinNodes() takes 2 nodes and merge their content|children.
@ -494,19 +496,10 @@ public:
* If there is no prior node, aResultNode will be nullptr.
* @param bNoBlockCrossing If true, don't move across "block" nodes, whatever that means.
*/
nsresult GetPriorNode(nsIDOMNode *aCurrentNode,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
bool bNoBlockCrossing = false);
nsIContent* GetPriorNode(nsINode* aCurrentNode, bool aEditableNode,
bool aNoBlockCrossing = false);
// and another version that takes a {parent,offset} pair rather than a node
nsresult GetPriorNode(nsIDOMNode *aParentNode,
int32_t aOffset,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
bool bNoBlockCrossing = false);
nsIContent* GetPriorNode(nsINode* aParentNode,
int32_t aOffset,
bool aEditableNode,
@ -520,20 +513,11 @@ public:
* skipping non-editable nodes if aEditableNode is true.
* If there is no prior node, aResultNode will be nullptr.
*/
nsresult GetNextNode(nsIDOMNode *aCurrentNode,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
bool bNoBlockCrossing = false);
nsIContent* GetNextNode(nsINode* aCurrentNode,
bool aEditableNode,
bool bNoBlockCrossing = false);
// and another version that takes a {parent,offset} pair rather than a node
nsresult GetNextNode(nsIDOMNode *aParentNode,
int32_t aOffset,
bool aEditableNode,
nsCOMPtr<nsIDOMNode> *aResultNode,
bool bNoBlockCrossing = false);
nsIContent* GetNextNode(nsINode* aParentNode,
int32_t aOffset,
bool aEditableNode,
@ -548,8 +532,6 @@ public:
* Get the rightmost child of aCurrentNode;
* return nullptr if aCurrentNode has no children.
*/
nsIDOMNode* GetRightmostChild(nsIDOMNode* aCurrentNode,
bool bNoBlockCrossing = false);
nsIContent* GetRightmostChild(nsINode *aCurrentNode,
bool bNoBlockCrossing = false);
@ -557,8 +539,6 @@ public:
* Get the leftmost child of aCurrentNode;
* return nullptr if aCurrentNode has no children.
*/
nsIDOMNode* GetLeftmostChild(nsIDOMNode* aCurrentNode,
bool bNoBlockCrossing = false);
nsIContent* GetLeftmostChild(nsINode *aCurrentNode,
bool bNoBlockCrossing = false);
@ -569,10 +549,10 @@ public:
}
/** returns true if aParent can contain a child of type aTag */
bool CanContain(nsIDOMNode* aParent, nsIDOMNode* aChild);
bool CanContainTag(nsIDOMNode* aParent, nsIAtom* aTag);
bool TagCanContain(nsIAtom* aParentTag, nsIDOMNode* aChild);
virtual bool TagCanContainTag(nsIAtom* aParentTag, nsIAtom* aChildTag);
bool CanContain(nsINode& aParent, nsIContent& aChild);
bool CanContainTag(nsINode& aParent, nsIAtom& aTag);
bool TagCanContain(nsIAtom& aParentTag, nsIContent& aChild);
virtual bool TagCanContainTag(nsIAtom& aParentTag, nsIAtom& aChildTag);
/** returns true if aNode is our root node */
bool IsRoot(nsIDOMNode* inNode);
@ -624,11 +604,15 @@ public:
static nsCOMPtr<nsIDOMNode> GetChildAt(nsIDOMNode *aParent, int32_t aOffset);
static nsCOMPtr<nsIDOMNode> GetNodeAtRangeOffsetPoint(nsIDOMNode* aParentOrNode, int32_t aOffset);
static nsresult GetStartNodeAndOffset(nsISelection *aSelection, nsIDOMNode **outStartNode, int32_t *outStartOffset);
static nsresult GetStartNodeAndOffset(mozilla::dom::Selection* aSelection,
nsIDOMNode** outStartNode,
int32_t* outStartOffset);
static nsresult GetStartNodeAndOffset(mozilla::dom::Selection* aSelection,
nsINode** aStartNode,
int32_t* aStartOffset);
static nsresult GetEndNodeAndOffset(nsISelection *aSelection, nsIDOMNode **outEndNode, int32_t *outEndOffset);
static nsresult GetEndNodeAndOffset(mozilla::dom::Selection* aSelection,
nsIDOMNode** outEndNode,
int32_t* outEndOffset);
static nsresult GetEndNodeAndOffset(mozilla::dom::Selection* aSelection,
nsINode** aEndNode,
int32_t* aEndOffset);
@ -641,7 +625,7 @@ public:
// Used by table cell selection methods
nsresult CreateRange(nsIDOMNode *aStartParent, int32_t aStartOffset,
nsIDOMNode *aEndParent, int32_t aEndOffset,
nsIDOMRange **aRange);
nsRange** aRange);
// Creates a range with just the supplied node and appends that to the selection
nsresult AppendNodeToSelectionAsRange(nsIDOMNode *aNode);
@ -657,7 +641,7 @@ public:
bool aNoEmptyContainers = false,
nsCOMPtr<nsIDOMNode> *outLeftNode = 0,
nsCOMPtr<nsIDOMNode> *outRightNode = 0);
nsresult JoinNodeDeep(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, nsCOMPtr<nsIDOMNode> *aOutJoinNode, int32_t *outOffset);
::DOMPoint JoinNodeDeep(nsIContent& aLeftNode, nsIContent& aRightNode);
nsresult GetString(const nsAString& name, nsAString& value);
@ -669,7 +653,7 @@ public:
virtual nsresult HandleKeyPressEvent(nsIDOMKeyEvent* aKeyEvent);
nsresult HandleInlineSpellCheck(EditAction action,
nsISelection *aSelection,
mozilla::dom::Selection* aSelection,
nsIDOMNode *previousSelectedNode,
int32_t previousSelectedOffset,
nsIDOMNode *aStartNode,

View File

@ -10,6 +10,7 @@
#include "mozilla/TextEvents.h" // for WidgetCompositionEvent
#include "mozilla/dom/Element.h" // for Element
#include "mozilla/dom/EventTarget.h" // for EventTarget
#include "mozilla/dom/Selection.h"
#include "nsAString.h"
#include "nsCaret.h" // for nsCaret
#include "nsDebug.h" // for NS_ENSURE_TRUE, etc
@ -31,7 +32,6 @@
#include "nsIDOMKeyEvent.h" // for nsIDOMKeyEvent
#include "nsIDOMMouseEvent.h" // for nsIDOMMouseEvent
#include "nsIDOMNode.h" // for nsIDOMNode
#include "nsIDOMRange.h" // for nsIDOMRange
#include "nsIDocument.h" // for nsIDocument
#include "nsIEditor.h" // for nsEditor::GetSelection, etc
#include "nsIEditorIMESupport.h"
@ -42,14 +42,13 @@
#include "nsINode.h" // for nsINode, ::NODE_IS_EDITABLE, etc
#include "nsIPlaintextEditor.h" // for nsIPlaintextEditor, etc
#include "nsIPresShell.h" // for nsIPresShell
#include "nsISelection.h" // for nsISelection
#include "nsISelectionController.h" // for nsISelectionController, etc
#include "nsISelectionPrivate.h" // for nsISelectionPrivate
#include "nsITransferable.h" // for kFileMime, kHTMLMime, etc
#include "nsIWidget.h" // for nsIWidget
#include "nsLiteralString.h" // for NS_LITERAL_STRING
#include "nsPIWindowRoot.h" // for nsPIWindowRoot
#include "nsPrintfCString.h" // for nsPrintfCString
#include "nsRange.h"
#include "nsServiceManagerUtils.h" // for do_GetService
#include "nsString.h" // for nsAutoString
#ifdef HANDLE_NATIVE_TEXT_DIRECTION_SWITCH
@ -713,8 +712,8 @@ nsEditorEventListener::HandleMiddleClickPaste(nsIDOMMouseEvent* aMouseEvent)
return NS_ERROR_NULL_POINTER;
}
nsCOMPtr<nsISelection> selection;
if (NS_SUCCEEDED(mEditor->GetSelection(getter_AddRefs(selection)))) {
nsRefPtr<Selection> selection = mEditor->GetSelection();
if (selection) {
selection->Collapse(parent, offset);
}
@ -983,9 +982,8 @@ nsEditorEventListener::CanDrop(nsIDOMDragEvent* aEvent)
return true;
}
nsCOMPtr<nsISelection> selection;
rv = mEditor->GetSelection(getter_AddRefs(selection));
if (NS_FAILED(rv) || !selection) {
nsRefPtr<Selection> selection = mEditor->GetSelection();
if (!selection) {
return false;
}
@ -1009,9 +1007,8 @@ nsEditorEventListener::CanDrop(nsIDOMDragEvent* aEvent)
NS_ENSURE_SUCCESS(rv, false);
for (int32_t i = 0; i < rangeCount; i++) {
nsCOMPtr<nsIDOMRange> range;
rv = selection->GetRangeAt(i, getter_AddRefs(range));
if (NS_FAILED(rv) || !range) {
nsRefPtr<nsRange> range = selection->GetRangeAt(i);
if (!range) {
// Don't bail yet, iterate through them all
continue;
}

View File

@ -20,8 +20,8 @@
#include "nsINode.h"
#include "nsISimpleEnumerator.h"
class nsIDOMRange;
class nsISupports;
class nsRange;
using namespace mozilla;
using namespace mozilla::dom;
@ -75,7 +75,7 @@ nsDOMIterator::~nsDOMIterator()
}
nsresult
nsDOMIterator::Init(nsIDOMRange* aRange)
nsDOMIterator::Init(nsRange* aRange)
{
nsresult res;
mIter = do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res);
@ -95,6 +95,23 @@ nsDOMIterator::Init(nsIDOMNode* aNode)
return mIter->Init(content);
}
nsresult
nsDOMIterator::AppendList(nsBoolDomIterFunctor& functor,
nsTArray<nsCOMPtr<nsINode>>& arrayOfNodes) const
{
// Iterate through dom and build list
while (!mIter->IsDone()) {
nsCOMPtr<nsINode> node = mIter->GetCurrentNode();
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
if (functor(node)) {
arrayOfNodes.AppendElement(node);
}
mIter->Next();
}
return NS_OK;
}
nsresult
nsDOMIterator::AppendList(nsBoolDomIterFunctor& functor,
nsCOMArray<nsIDOMNode>& arrayOfNodes) const
@ -125,7 +142,7 @@ nsDOMSubtreeIterator::~nsDOMSubtreeIterator()
}
nsresult
nsDOMSubtreeIterator::Init(nsIDOMRange* aRange)
nsDOMSubtreeIterator::Init(nsRange* aRange)
{
nsresult res;
mIter = do_CreateInstance("@mozilla.org/content/subtree-content-iterator;1", &res);

View File

@ -18,9 +18,13 @@
class nsIAtom;
class nsIContentIterator;
class nsIDOMDocument;
class nsIDOMRange;
class nsISelection;
class nsRange;
template <class E> class nsCOMArray;
namespace mozilla {
namespace dom {
class Selection;
}
}
/***************************************************************************
* stack based helper class for batching a collection of txns inside a
@ -164,6 +168,10 @@ class nsBoolDomIterFunctor
{
public:
virtual bool operator()(nsIDOMNode* aNode)=0;
bool operator()(nsINode* aNode)
{
return operator()(GetAsDOMNode(aNode));
}
};
class MOZ_STACK_CLASS nsDOMIterator
@ -172,8 +180,10 @@ class MOZ_STACK_CLASS nsDOMIterator
nsDOMIterator();
virtual ~nsDOMIterator();
nsresult Init(nsIDOMRange* aRange);
nsresult Init(nsRange* aRange);
nsresult Init(nsIDOMNode* aNode);
nsresult AppendList(nsBoolDomIterFunctor& functor,
nsTArray<nsCOMPtr<nsINode>>& arrayOfNodes) const;
nsresult AppendList(nsBoolDomIterFunctor& functor,
nsCOMArray<nsIDOMNode>& arrayOfNodes) const;
protected:
@ -186,7 +196,7 @@ class MOZ_STACK_CLASS nsDOMSubtreeIterator : public nsDOMIterator
nsDOMSubtreeIterator();
virtual ~nsDOMSubtreeIterator();
nsresult Init(nsIDOMRange* aRange);
nsresult Init(nsRange* aRange);
};
class nsTrivialFunctor : public nsBoolDomIterFunctor
@ -206,7 +216,8 @@ struct MOZ_STACK_CLASS DOMPoint
{
nsCOMPtr<nsINode> node;
int32_t offset;
DOMPoint() : node(nullptr), offset(-1) {}
DOMPoint(nsINode* aNode, int32_t aOffset)
: node(aNode)
, offset(aOffset)

View File

@ -38,7 +38,6 @@
#include "nsIHTMLObjectResizer.h"
#include "nsINode.h"
#include "nsIPresShell.h"
#include "nsISelection.h"
#include "nsISupportsImpl.h"
#include "nsISupportsUtils.h"
#include "nsLiteralString.h"
@ -438,8 +437,7 @@ nsHTMLEditor::EndMoving()
mGrabberClicked = false;
mIsMoving = false;
nsCOMPtr<nsISelection> selection;
GetSelection(getter_AddRefs(selection));
nsRefPtr<Selection> selection = GetSelection();
if (!selection) {
return NS_ERROR_NOT_INITIALIZED;
}

View File

@ -48,7 +48,6 @@
#include "nsIDOMHTMLObjectElement.h"
#include "nsIDOMHTMLScriptElement.h"
#include "nsIDOMNode.h"
#include "nsIDOMRange.h"
#include "nsIDocument.h"
#include "nsIEditor.h"
#include "nsIEditorIMESupport.h"
@ -60,7 +59,6 @@
#include "nsINode.h"
#include "nsIParserUtils.h"
#include "nsIPlaintextEditor.h"
#include "nsISelection.h"
#include "nsISupportsImpl.h"
#include "nsISupportsPrimitives.h"
#include "nsISupportsUtils.h"
@ -169,9 +167,7 @@ NS_IMETHODIMP nsHTMLEditor::LoadHTML(const nsAString & aInputString)
}
// Get the first range in the selection, for context:
nsCOMPtr<nsIDOMRange> range;
rv = selection->GetRangeAt(0, getter_AddRefs(range));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<nsRange> range = selection->GetRangeAt(0);
NS_ENSURE_TRUE(range, NS_ERROR_NULL_POINTER);
// create fragment for pasted html
@ -633,8 +629,9 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
// but don't cross tables
if (!nsHTMLEditUtils::IsTable(lastInsertNode))
{
rv = GetLastEditableLeaf(lastInsertNode, address_of(selNode));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsINode> lastInsertNode_ = do_QueryInterface(lastInsertNode);
NS_ENSURE_STATE(lastInsertNode_ || !lastInsertNode);
selNode = GetAsDOMNode(GetLastEditableLeaf(*lastInsertNode_));
tmp = selNode;
while (tmp && (tmp != lastInsertNode))
{
@ -1592,16 +1589,13 @@ NS_IMETHODIMP nsHTMLEditor::PasteAsCitedQuotation(const nsAString & aCitation,
return NS_OK; // rules canceled the operation
}
nsCOMPtr<nsIDOMNode> newNode;
rv = DeleteSelectionAndCreateNode(NS_LITERAL_STRING("blockquote"), getter_AddRefs(newNode));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<Element> newNode =
DeleteSelectionAndCreateElement(*nsGkAtoms::blockquote);
NS_ENSURE_TRUE(newNode, NS_ERROR_NULL_POINTER);
// Try to set type=cite. Ignore it if this fails.
nsCOMPtr<nsIDOMElement> newElement = do_QueryInterface(newNode);
if (newElement) {
newElement->SetAttribute(NS_LITERAL_STRING("type"), NS_LITERAL_STRING("cite"));
}
newNode->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
NS_LITERAL_STRING("cite"), true);
// Set the selection to the underneath the node we just inserted:
rv = selection->Collapse(newNode, 0);
@ -1771,7 +1765,6 @@ nsHTMLEditor::InsertAsPlaintextQuotation(const nsAString & aQuotedText,
if (mWrapToWindow)
return nsPlaintextEditor::InsertAsQuotation(aQuotedText, aNodeInserted);
nsCOMPtr<nsIDOMNode> newNode;
// get selection
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
@ -1791,25 +1784,22 @@ nsHTMLEditor::InsertAsPlaintextQuotation(const nsAString & aQuotedText,
}
// Wrap the inserted quote in a <span> so it won't be wrapped:
rv = DeleteSelectionAndCreateNode(NS_LITERAL_STRING("span"), getter_AddRefs(newNode));
nsCOMPtr<Element> newNode =
DeleteSelectionAndCreateElement(*nsGkAtoms::span);
// If this succeeded, then set selection inside the pre
// so the inserted text will end up there.
// If it failed, we don't care what the return value was,
// but we'll fall through and try to insert the text anyway.
if (NS_SUCCEEDED(rv) && newNode)
{
if (newNode) {
// Add an attribute on the pre node so we'll know it's a quotation.
// Do this after the insertion, so that
nsCOMPtr<nsIDOMElement> preElement = do_QueryInterface(newNode);
if (preElement)
{
preElement->SetAttribute(NS_LITERAL_STRING("_moz_quote"),
NS_LITERAL_STRING("true"));
// turn off wrapping on spans
preElement->SetAttribute(NS_LITERAL_STRING("style"),
NS_LITERAL_STRING("white-space: pre;"));
}
newNode->SetAttr(kNameSpaceID_None, nsGkAtoms::mozquote,
NS_LITERAL_STRING("true"), true);
// turn off wrapping on spans
newNode->SetAttr(kNameSpaceID_None, nsGkAtoms::style,
NS_LITERAL_STRING("white-space: pre;"), true);
// and set the selection inside it:
selection->Collapse(newNode, 0);
}
@ -1824,15 +1814,15 @@ nsHTMLEditor::InsertAsPlaintextQuotation(const nsAString & aQuotedText,
if (aNodeInserted && NS_SUCCEEDED(rv))
{
*aNodeInserted = newNode;
*aNodeInserted = GetAsDOMNode(newNode);
NS_IF_ADDREF(*aNodeInserted);
}
// Set the selection to just after the inserted node:
if (NS_SUCCEEDED(rv) && newNode)
{
int32_t offset;
nsCOMPtr<nsIDOMNode> parent = GetNodeLocation(newNode, &offset);
nsCOMPtr<nsINode> parent = newNode->GetParentNode();
int32_t offset = parent ? parent->IndexOf(newNode) : -1;
if (parent) {
selection->Collapse(parent, offset + 1);
}
@ -1865,8 +1855,6 @@ nsHTMLEditor::InsertAsCitedQuotation(const nsAString & aQuotedText,
return InsertAsPlaintextQuotation(aQuotedText, true, aNodeInserted);
}
nsCOMPtr<nsIDOMNode> newNode;
// get selection
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
@ -1885,24 +1873,21 @@ nsHTMLEditor::InsertAsCitedQuotation(const nsAString & aQuotedText,
return NS_OK; // rules canceled the operation
}
rv = DeleteSelectionAndCreateNode(NS_LITERAL_STRING("blockquote"), getter_AddRefs(newNode));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<Element> newNode =
DeleteSelectionAndCreateElement(*nsGkAtoms::blockquote);
NS_ENSURE_TRUE(newNode, NS_ERROR_NULL_POINTER);
// Try to set type=cite. Ignore it if this fails.
nsCOMPtr<nsIDOMElement> newElement = do_QueryInterface(newNode);
if (newElement)
{
NS_NAMED_LITERAL_STRING(citeStr, "cite");
newElement->SetAttribute(NS_LITERAL_STRING("type"), citeStr);
newNode->SetAttr(kNameSpaceID_None, nsGkAtoms::type,
NS_LITERAL_STRING("cite"), true);
if (!aCitation.IsEmpty())
newElement->SetAttribute(citeStr, aCitation);
// Set the selection inside the blockquote so aQuotedText will go there:
selection->Collapse(newNode, 0);
if (!aCitation.IsEmpty()) {
newNode->SetAttr(kNameSpaceID_None, nsGkAtoms::cite, aCitation, true);
}
// Set the selection inside the blockquote so aQuotedText will go there:
selection->Collapse(newNode, 0);
if (aInsertHTML)
rv = LoadHTML(aQuotedText);
else
@ -1910,15 +1895,15 @@ nsHTMLEditor::InsertAsCitedQuotation(const nsAString & aQuotedText,
if (aNodeInserted && NS_SUCCEEDED(rv))
{
*aNodeInserted = newNode;
*aNodeInserted = GetAsDOMNode(newNode);
NS_IF_ADDREF(*aNodeInserted);
}
// Set the selection to just after the inserted node:
if (NS_SUCCEEDED(rv) && newNode)
{
int32_t offset;
nsCOMPtr<nsIDOMNode> parent = GetNodeLocation(newNode, &offset);
nsCOMPtr<nsINode> parent = newNode->GetParentNode();
int32_t offset = parent ? parent->IndexOf(newNode) : -1;
if (parent) {
selection->Collapse(parent, offset + 1);
}

File diff suppressed because it is too large Load Diff

View File

@ -25,10 +25,8 @@ class nsIDOMCharacterData;
class nsIDOMDocument;
class nsIDOMElement;
class nsIDOMNode;
class nsIDOMRange;
class nsIEditor;
class nsINode;
class nsISelection;
class nsPlaintextEditor;
class nsRange;
class nsRulesInfo;
@ -79,7 +77,8 @@ public:
nsIEditor::EDirection aDirection);
NS_IMETHOD WillDoAction(mozilla::dom::Selection* aSelection, nsRulesInfo* aInfo,
bool* aCancel, bool* aHandled);
NS_IMETHOD DidDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
NS_IMETHOD DidDoAction(mozilla::dom::Selection* aSelection,
nsRulesInfo* aInfo, nsresult aResult);
NS_IMETHOD DocumentModified();
nsresult GetListState(bool *aMixed, bool *aOL, bool *aUL, bool *aDL);
@ -126,7 +125,7 @@ protected:
void InitFields();
// nsHTMLEditRules implementation methods
nsresult WillInsert(nsISelection *aSelection, bool *aCancel);
nsresult WillInsert(mozilla::dom::Selection* aSelection, bool* aCancel);
nsresult WillInsertText( EditAction aAction,
mozilla::dom::Selection* aSelection,
bool *aCancel,
@ -134,22 +133,24 @@ protected:
const nsAString *inString,
nsAString *outString,
int32_t aMaxLength);
nsresult WillLoadHTML(nsISelection *aSelection, bool *aCancel);
nsresult WillLoadHTML(mozilla::dom::Selection* aSelection, bool* aCancel);
nsresult WillInsertBreak(mozilla::dom::Selection* aSelection,
bool* aCancel, bool* aHandled);
nsresult StandardBreakImpl(nsIDOMNode *aNode, int32_t aOffset, nsISelection *aSelection);
nsresult DidInsertBreak(nsISelection *aSelection, nsresult aResult);
nsresult SplitMailCites(nsISelection *aSelection, bool aPlaintext, bool *aHandled);
nsresult StandardBreakImpl(nsIDOMNode* aNode, int32_t aOffset,
mozilla::dom::Selection* aSelection);
nsresult DidInsertBreak(mozilla::dom::Selection* aSelection,
nsresult aResult);
nsresult SplitMailCites(mozilla::dom::Selection* aSelection, bool* aHandled);
nsresult WillDeleteSelection(mozilla::dom::Selection* aSelection,
nsIEditor::EDirection aAction,
nsIEditor::EStripWrappers aStripWrappers,
bool* aCancel, bool* aHandled);
nsresult DidDeleteSelection(nsISelection *aSelection,
nsresult DidDeleteSelection(mozilla::dom::Selection* aSelection,
nsIEditor::EDirection aDir,
nsresult aResult);
nsresult InsertBRIfNeeded(nsISelection *aSelection);
nsresult GetGoodSelPointForNode(nsIDOMNode *aNode, nsIEditor::EDirection aAction,
nsCOMPtr<nsIDOMNode> *outSelNode, int32_t *outSelOffset);
nsresult InsertBRIfNeeded(mozilla::dom::Selection* aSelection);
::DOMPoint GetGoodSelPointForNode(nsINode& aNode,
nsIEditor::EDirection aAction);
nsresult JoinBlocks(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, bool *aCanceled);
nsresult MoveBlock(nsIDOMNode *aLeft, nsIDOMNode *aRight, int32_t aLeftOffset, int32_t aRightOffset);
nsresult MoveNodeSmart(nsIDOMNode *aSource, nsIDOMNode *aDest, int32_t *aOffset);
@ -187,7 +188,8 @@ protected:
nsresult WillMakeBasicBlock(mozilla::dom::Selection* aSelection,
const nsAString* aBlockType,
bool* aCancel, bool* aHandled);
nsresult DidMakeBasicBlock(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
nsresult DidMakeBasicBlock(mozilla::dom::Selection* aSelection,
nsRulesInfo* aInfo, nsresult aResult);
nsresult DidAbsolutePosition();
nsresult AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType);
nsresult AlignBlockContents(nsIDOMNode *aNode, const nsAString *alignType);
@ -199,14 +201,20 @@ protected:
nsresult GetInnerContent(nsIDOMNode *aNode, nsCOMArray<nsIDOMNode>& outArrayOfNodes, int32_t *aIndex, bool aList = true, bool aTble = true);
already_AddRefed<nsIDOMNode> IsInListItem(nsIDOMNode* aNode);
mozilla::dom::Element* IsInListItem(nsINode* aNode);
nsresult ReturnInHeader(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, int32_t aOffset);
nsresult ReturnInParagraph(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, int32_t aOffset, bool *aCancel, bool *aHandled);
nsresult ReturnInHeader(mozilla::dom::Selection* aSelection,
nsIDOMNode* aHeader, nsIDOMNode* aTextNode,
int32_t aOffset);
nsresult ReturnInParagraph(mozilla::dom::Selection* aSelection,
nsIDOMNode* aHeader, nsIDOMNode* aTextNode,
int32_t aOffset, bool* aCancel, bool* aHandled);
nsresult SplitParagraph(nsIDOMNode *aPara,
nsIDOMNode *aBRNode,
nsISelection *aSelection,
mozilla::dom::Selection* aSelection,
nsCOMPtr<nsIDOMNode> *aSelNode,
int32_t *aOffset);
nsresult ReturnInListItem(nsISelection *aSelection, nsIDOMNode *aHeader, nsIDOMNode *aTextNode, int32_t aOffset);
nsresult ReturnInListItem(mozilla::dom::Selection* aSelection,
nsIDOMNode* aHeader, nsIDOMNode* aTextNode,
int32_t aOffset);
nsresult AfterEditInner(EditAction action,
nsIEditor::EDirection aDirection);
nsresult RemovePartOfBlock(nsIDOMNode *aBlock,
@ -236,30 +244,30 @@ protected:
nsIAtom* aListType,
nsIAtom* aItemType);
nsresult CreateStyleForInsertText(nsISelection *aSelection, nsIDOMDocument *aDoc);
nsresult CreateStyleForInsertText(mozilla::dom::Selection* aSelection,
nsIDOMDocument* aDoc);
nsresult IsEmptyBlock(nsIDOMNode *aNode,
bool *outIsEmptyBlock,
bool aMozBRDoesntCount = false,
bool aListItemsNotEmpty = false);
nsresult CheckForEmptyBlock(nsIDOMNode *aStartNode,
nsIDOMNode *aBodyNode,
nsISelection *aSelection,
bool *aHandled);
nsresult CheckForEmptyBlock(nsINode* aStartNode,
mozilla::dom::Element* aBodyNode,
mozilla::dom::Selection* aSelection,
bool* aHandled);
nsresult CheckForInvisibleBR(nsIDOMNode *aBlock, nsHTMLEditRules::BRLocation aWhere,
nsCOMPtr<nsIDOMNode> *outBRNode, int32_t aOffset=0);
nsresult ExpandSelectionForDeletion(nsISelection *aSelection);
nsresult ExpandSelectionForDeletion(mozilla::dom::Selection* aSelection);
bool IsFirstNode(nsIDOMNode *aNode);
bool IsLastNode(nsIDOMNode *aNode);
nsresult NormalizeSelection(nsISelection *inSelection);
nsresult NormalizeSelection(mozilla::dom::Selection* aSelection);
void GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode* aNode,
int32_t aOffset, EditAction actionID,
nsCOMPtr<nsIDOMNode>* outNode, int32_t* outOffset);
nsresult GetPromotedRanges(nsISelection *inSelection,
nsCOMArray<nsIDOMRange> &outArrayOfRanges,
nsresult GetPromotedRanges(mozilla::dom::Selection* aSelection,
nsTArray<nsRefPtr<nsRange>>& outArrayOfRanges,
EditAction inOperationType);
nsresult PromoteRange(nsIDOMRange *inRange,
EditAction inOperationType);
nsresult GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges,
nsresult PromoteRange(nsRange* inRange, EditAction inOperationType);
nsresult GetNodesForOperation(nsTArray<nsRefPtr<nsRange>>& inArrayOfRanges,
nsCOMArray<nsIDOMNode>& outArrayOfNodes,
EditAction inOperationType,
bool aDontTouchContent=false);
@ -269,7 +277,7 @@ protected:
EditAction operation,
nsCOMArray<nsIDOMNode>& arrayOfNodes,
bool dontTouchContent);
nsresult GetNodesFromSelection(nsISelection *selection,
nsresult GetNodesFromSelection(mozilla::dom::Selection* selection,
EditAction operation,
nsCOMArray<nsIDOMNode>& arrayOfNodes,
bool aDontTouchContent=false);
@ -289,21 +297,19 @@ protected:
nsresult SplitAsNeeded(nsIAtom& aTag, nsCOMPtr<nsINode>& inOutParent,
int32_t& inOutOffset);
nsresult AddTerminatingBR(nsIDOMNode *aBlock);
nsresult JoinNodesSmart( nsIDOMNode *aNodeLeft,
nsIDOMNode *aNodeRight,
nsCOMPtr<nsIDOMNode> *aOutMergeParent,
int32_t *aOutMergeOffset);
nsresult GetTopEnclosingMailCite(nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutCiteNode, bool aPlaintext);
::DOMPoint JoinNodesSmart(nsIContent& aNodeLeft, nsIContent& aNodeRight);
mozilla::dom::Element* GetTopEnclosingMailCite(nsINode& aNode);
nsresult PopListItem(nsIDOMNode *aListItem, bool *aOutOfList);
nsresult RemoveListStructure(nsIDOMNode *aList);
nsresult CacheInlineStyles(nsIDOMNode *aNode);
nsresult ReapplyCachedStyles();
void ClearCachedStyles();
nsresult AdjustSpecialBreaks(bool aSafeToAskFrames = false);
nsresult AdjustWhitespace(nsISelection *aSelection);
nsresult PinSelectionToNewBlock(nsISelection *aSelection);
nsresult CheckInterlinePosition(nsISelection *aSelection);
nsresult AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection aAction);
nsresult AdjustWhitespace(mozilla::dom::Selection* aSelection);
nsresult PinSelectionToNewBlock(mozilla::dom::Selection* aSelection);
nsresult CheckInterlinePosition(mozilla::dom::Selection* aSelection);
nsresult AdjustSelection(mozilla::dom::Selection* aSelection,
nsIEditor::EDirection aAction);
nsresult FindNearSelectableNode(nsIDOMNode *aSelNode,
int32_t aSelOffset,
nsIEditor::EDirection &aDirection,
@ -319,7 +325,7 @@ protected:
bool InDifferentTableElements(nsINode* aNode1, nsINode* aNode2);
nsresult RemoveEmptyNodes();
nsresult SelectionEndpointInNode(nsINode *aNode, bool *aResult);
nsresult UpdateDocChangeRange(nsIDOMRange *aRange);
nsresult UpdateDocChangeRange(nsRange* aRange);
nsresult ConfirmSelectionInBody();
nsresult InsertMozBRIfNeeded(nsIDOMNode *aNode);
bool IsEmptyInline(nsIDOMNode *aNode);

View File

@ -124,10 +124,9 @@ nsHTMLEditUtils::IsSmall(nsIDOMNode* aNode)
// IsHeader: true if node an html header
//
bool
nsHTMLEditUtils::IsHeader(nsIDOMNode* aNode)
nsHTMLEditUtils::IsHeader(nsINode& aNode)
{
NS_PRECONDITION(aNode, "null parent passed to nsHTMLEditUtils::IsHeader");
nsCOMPtr<nsIAtom> nodeAtom = nsEditor::GetTag(aNode);
nsCOMPtr<nsIAtom> nodeAtom = aNode.Tag();
return (nodeAtom == nsGkAtoms::h1)
|| (nodeAtom == nsGkAtoms::h2)
|| (nodeAtom == nsGkAtoms::h3)
@ -136,6 +135,14 @@ nsHTMLEditUtils::IsHeader(nsIDOMNode* aNode)
|| (nodeAtom == nsGkAtoms::h6);
}
bool
nsHTMLEditUtils::IsHeader(nsIDOMNode* aNode)
{
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
NS_PRECONDITION(node, "null parent passed to nsHTMLEditUtils::IsHeader");
return IsHeader(*node);
}
///////////////////////////////////////////////////////////////////////////
// IsParagraph: true if node an html paragraph
@ -355,6 +362,12 @@ nsHTMLEditUtils::IsPre(nsIDOMNode* aNode)
///////////////////////////////////////////////////////////////////////////
// IsImage: true if node an html image node
//
bool
nsHTMLEditUtils::IsImage(nsINode* aNode)
{
return aNode && aNode->Tag() == nsGkAtoms::img;
}
bool
nsHTMLEditUtils::IsImage(nsIDOMNode* aNode)
{

View File

@ -23,6 +23,7 @@ public:
static bool IsFormatNode(nsINode* aNode);
static bool IsFormatNode(nsIDOMNode *aNode);
static bool IsNodeThatCanOutdent(nsIDOMNode *aNode);
static bool IsHeader(nsINode& aNode);
static bool IsHeader(nsIDOMNode *aNode);
static bool IsParagraph(nsIDOMNode *aNode);
static bool IsHR(nsIDOMNode *aNode);
@ -45,6 +46,7 @@ public:
static bool IsBlockquote(nsIDOMNode *aNode);
static bool IsPre(nsIDOMNode *aNode);
static bool IsAnchor(nsIDOMNode *aNode);
static bool IsImage(nsINode* aNode);
static bool IsImage(nsIDOMNode *aNode);
static bool IsLink(nsIDOMNode *aNode);
static bool IsLink(nsINode* aNode);

View File

@ -42,7 +42,6 @@
#include "nsIContent.h"
#include "nsIContentIterator.h"
#include "nsIDOMRange.h"
#include "nsISupportsArray.h"
#include "nsContentUtils.h"
#include "nsIDocumentEncoder.h"
@ -121,22 +120,19 @@ nsHTMLEditor::~nsHTMLEditor()
//the autopointers will clear themselves up.
//but we need to also remove the listeners or we have a leak
nsCOMPtr<nsISelection>selection;
nsresult result = GetSelection(getter_AddRefs(selection));
nsRefPtr<Selection> selection = GetSelection();
// if we don't get the selection, just skip this
if (NS_SUCCEEDED(result) && selection)
{
nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
if (selection) {
nsCOMPtr<nsISelectionListener>listener;
listener = do_QueryInterface(mTypeInState);
if (listener)
{
selPriv->RemoveSelectionListener(listener);
selection->RemoveSelectionListener(listener);
}
listener = do_QueryInterface(mSelectionListenerP);
if (listener)
{
selPriv->RemoveSelectionListener(listener);
selection->RemoveSelectionListener(listener);
}
}
@ -286,20 +282,17 @@ nsHTMLEditor::Init(nsIDOMDocument *aDoc,
AddOverrideStyleSheet(NS_LITERAL_STRING("resource://gre/res/EditorOverride.css"));
}
nsCOMPtr<nsISelection>selection;
result = GetSelection(getter_AddRefs(selection));
if (NS_FAILED(result)) { return result; }
nsRefPtr<Selection> selection = GetSelection();
if (selection)
{
nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
nsCOMPtr<nsISelectionListener>listener;
listener = do_QueryInterface(mTypeInState);
if (listener) {
selPriv->AddSelectionListener(listener);
selection->AddSelectionListener(listener);
}
listener = do_QueryInterface(mSelectionListenerP);
if (listener) {
selPriv->AddSelectionListener(listener);
selection->AddSelectionListener(listener);
}
}
}
@ -510,79 +503,73 @@ nsHTMLEditor::InitRules()
NS_IMETHODIMP
nsHTMLEditor::BeginningOfDocument()
{
if (!mDocWeak) { return NS_ERROR_NOT_INITIALIZED; }
if (!mDocWeak) {
return NS_ERROR_NOT_INITIALIZED;
}
// get the selection
nsCOMPtr<nsISelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
// Get the selection
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NOT_INITIALIZED);
// Get the root element.
nsCOMPtr<nsIDOMElement> rootElement = do_QueryInterface(GetRoot());
nsCOMPtr<Element> rootElement = GetRoot();
if (!rootElement) {
NS_WARNING("GetRoot() returned a null pointer (mRootElement is null)");
return NS_OK;
}
// find first editable thingy
// Find first editable thingy
bool done = false;
nsCOMPtr<nsIDOMNode> curNode(rootElement), selNode;
nsCOMPtr<nsINode> curNode = rootElement.get(), selNode;
int32_t curOffset = 0, selOffset;
while (!done)
{
while (!done) {
nsWSRunObject wsObj(this, curNode, curOffset);
int32_t visOffset=0;
int32_t visOffset = 0;
WSType visType;
nsCOMPtr<nsINode> visNode, curNode_(do_QueryInterface(curNode));
wsObj.NextVisibleNode(curNode_, curOffset, address_of(visNode), &visOffset, &visType);
nsCOMPtr<nsINode> visNode;
wsObj.NextVisibleNode(curNode, curOffset, address_of(visNode), &visOffset,
&visType);
if (visType == WSType::normalWS || visType == WSType::text) {
selNode = GetAsDOMNode(visNode);
selNode = visNode;
selOffset = visOffset;
done = true;
} else if (visType == WSType::br || visType == WSType::special) {
selNode = GetNodeLocation(GetAsDOMNode(visNode), &selOffset);
selNode = visNode->GetParentNode();
selOffset = selNode ? selNode->IndexOf(visNode) : -1;
done = true;
} else if (visType == WSType::otherBlock) {
// By definition of nsWSRunObject, a block element terminates
// a whitespace run. That is, although we are calling a method
// that is named "NextVisibleNode", the node returned
// might not be visible/editable!
// If the given block does not contain any visible/editable items,
// we want to skip it and continue our search.
// By definition of nsWSRunObject, a block element terminates a
// whitespace run. That is, although we are calling a method that is
// named "NextVisibleNode", the node returned might not be
// visible/editable!
//
// If the given block does not contain any visible/editable items, we
// want to skip it and continue our search.
if (!IsContainer(visNode))
{
// However, we were given a block that is not a container.
// Since the block can not contain anything that's visible,
// such a block only makes sense if it is visible by itself,
// like a <hr>
// We want to place the caret in front of that block.
selNode = GetNodeLocation(GetAsDOMNode(visNode), &selOffset);
if (!IsContainer(visNode)) {
// However, we were given a block that is not a container. Since the
// block can not contain anything that's visible, such a block only
// makes sense if it is visible by itself, like a <hr>. We want to
// place the caret in front of that block.
selNode = visNode->GetParentNode();
selOffset = selNode ? selNode->IndexOf(visNode) : -1;
done = true;
}
else
{
} else {
bool isEmptyBlock;
if (NS_SUCCEEDED(IsEmptyNode(GetAsDOMNode(visNode), &isEmptyBlock)) &&
isEmptyBlock)
{
// skip the empty block
curNode = GetNodeLocation(GetAsDOMNode(visNode), &curOffset);
++curOffset;
}
else
{
curNode = GetAsDOMNode(visNode);
if (NS_SUCCEEDED(IsEmptyNode(visNode, &isEmptyBlock)) &&
isEmptyBlock) {
// Skip the empty block
curNode = visNode->GetParentNode();
curOffset = curNode ? curNode->IndexOf(visNode) : -1;
curOffset++;
} else {
curNode = visNode;
curOffset = 0;
}
// keep looping
// Keep looping
}
}
else
{
// else we found nothing useful
} else {
// Else we found nothing useful
selNode = curNode;
selOffset = curOffset;
done = true;
@ -1106,7 +1093,7 @@ nsHTMLEditor::TabInTable(bool inIsShift, bool* outHandled)
*outHandled = true;
// Put selection in right place. Use table code to get selection and index
// to new row...
nsCOMPtr<nsISelection> selection;
nsRefPtr<Selection> selection;
nsCOMPtr<nsIDOMElement> tblElement, cell;
int32_t row;
res = GetCellContext(getter_AddRefs(selection),
@ -1602,46 +1589,50 @@ nsHTMLEditor::InsertNodeAtPoint(nsIDOMNode *aNode,
int32_t *ioOffset,
bool aNoEmptyNodes)
{
NS_ENSURE_TRUE(aNode, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIContent> node = do_QueryInterface(aNode);
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(ioParent, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(*ioParent, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(ioOffset, NS_ERROR_NULL_POINTER);
nsresult res = NS_OK;
nsCOMPtr<nsIDOMNode> parent = *ioParent;
nsCOMPtr<nsIDOMNode> topChild = *ioParent;
nsCOMPtr<nsIDOMNode> tmp;
nsCOMPtr<nsINode> parent = do_QueryInterface(*ioParent);
NS_ENSURE_TRUE(parent, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsINode> topChild = parent;
int32_t offsetOfInsert = *ioOffset;
// Search up the parent chain to find a suitable container
while (!CanContain(parent, aNode)) {
while (!CanContain(*parent, *node)) {
// If the current parent is a root (body or table element)
// then go no further - we can't insert
if (nsTextEditUtils::IsBody(parent) || nsHTMLEditUtils::IsTableElement(parent))
if (parent->Tag() == nsGkAtoms::body ||
nsHTMLEditUtils::IsTableElement(parent)) {
return NS_ERROR_FAILURE;
}
// Get the next parent
parent->GetParentNode(getter_AddRefs(tmp));
NS_ENSURE_TRUE(tmp, NS_ERROR_FAILURE);
if (!IsEditable(tmp)) {
NS_ENSURE_TRUE(parent->GetParentNode(), NS_ERROR_FAILURE);
if (!IsEditable(parent->GetParentNode())) {
// There's no suitable place to put the node in this editing host. Maybe
// someone is trying to put block content in a span. So just put it
// where we were originally asked.
parent = topChild = *ioParent;
parent = topChild = do_QueryInterface(*ioParent);
NS_ENSURE_STATE(parent);
break;
}
topChild = parent;
parent = tmp;
parent = parent->GetParentNode();
}
if (parent != topChild)
{
// we need to split some levels above the original selection parent
res = SplitNodeDeep(topChild, *ioParent, *ioOffset, &offsetOfInsert, aNoEmptyNodes);
res = SplitNodeDeep(GetAsDOMNode(topChild), *ioParent, *ioOffset,
&offsetOfInsert, aNoEmptyNodes);
NS_ENSURE_SUCCESS(res, res);
*ioParent = parent;
*ioParent = GetAsDOMNode(parent);
*ioOffset = offsetOfInsert;
}
// Now we can insert the new node
res = InsertNode(aNode, parent, offsetOfInsert);
res = InsertNode(*node, *parent, offsetOfInsert);
return res;
}
@ -1652,9 +1643,7 @@ nsHTMLEditor::SelectElement(nsIDOMElement* aElement)
// Must be sure that element is contained in the document body
if (IsDescendantOfEditorRoot(aElement)) {
nsCOMPtr<nsISelection> selection;
res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode>parent;
res = aElement->GetParentNode(getter_AddRefs(parent));
@ -1680,9 +1669,7 @@ nsHTMLEditor::SetCaretAfterElement(nsIDOMElement* aElement)
// Be sure the element is contained in the document body
if (aElement && IsDescendantOfEditorRoot(aElement)) {
nsCOMPtr<nsISelection> selection;
res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode>parent;
res = aElement->GetParentNode(getter_AddRefs(parent));
@ -1756,14 +1743,14 @@ nsHTMLEditor::GetCSSBackgroundColorState(bool *aMixed, nsAString &aOutColor, boo
aOutColor.AssignLiteral("transparent");
// get selection
nsCOMPtr<nsISelection>selection;
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_STATE(selection);
// get selection location
nsCOMPtr<nsIDOMNode> parent;
int32_t offset;
res = GetStartNodeAndOffset(selection, getter_AddRefs(parent), &offset);
nsresult res = GetStartNodeAndOffset(selection, getter_AddRefs(parent),
&offset);
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_TRUE(parent, NS_ERROR_NULL_POINTER);
@ -1970,7 +1957,7 @@ nsHTMLEditor::MakeOrChangeList(const nsAString& aListType, bool entireList, cons
// Find out if the selection is collapsed:
bool isCollapsed = selection->Collapsed();
nsCOMPtr<nsIDOMNode> node;
nsCOMPtr<nsINode> node;
int32_t offset;
res = GetStartNodeAndOffset(selection, getter_AddRefs(node), &offset);
if (!node) res = NS_ERROR_FAILURE;
@ -1979,33 +1966,29 @@ nsHTMLEditor::MakeOrChangeList(const nsAString& aListType, bool entireList, cons
if (isCollapsed)
{
// have to find a place to put the list
nsCOMPtr<nsIDOMNode> parent = node;
nsCOMPtr<nsIDOMNode> topChild = node;
nsCOMPtr<nsIDOMNode> tmp;
nsCOMPtr<nsINode> parent = node;
nsCOMPtr<nsINode> topChild = node;
nsCOMPtr<nsIAtom> listAtom = do_GetAtom(aListType);
while (!CanContainTag(parent, listAtom)) {
parent->GetParentNode(getter_AddRefs(tmp));
NS_ENSURE_TRUE(tmp, NS_ERROR_FAILURE);
while (!CanContainTag(*parent, *listAtom)) {
topChild = parent;
parent = tmp;
parent = parent->GetParentNode();
}
if (parent != node)
{
// we need to split up to the child of parent
res = SplitNodeDeep(topChild, node, offset, &offset);
res = SplitNodeDeep(GetAsDOMNode(topChild), GetAsDOMNode(node), offset,
&offset);
NS_ENSURE_SUCCESS(res, res);
}
// make a list
nsCOMPtr<nsIDOMNode> newList;
res = CreateNode(aListType, parent, offset, getter_AddRefs(newList));
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<Element> newList = CreateNode(listAtom, parent, offset);
NS_ENSURE_STATE(newList);
// make a list item
nsCOMPtr<nsIDOMNode> newItem;
res = CreateNode(NS_LITERAL_STRING("li"), newList, 0, getter_AddRefs(newItem));
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<Element> newItem = CreateNode(nsGkAtoms::li, newList, 0);
NS_ENSURE_STATE(newItem);
res = selection->Collapse(newItem,0);
NS_ENSURE_SUCCESS(res, res);
}
@ -2105,7 +2088,7 @@ nsHTMLEditor::InsertBasicBlock(const nsAString& aBlockType)
// Find out if the selection is collapsed:
bool isCollapsed = selection->Collapsed();
nsCOMPtr<nsIDOMNode> node;
nsCOMPtr<nsINode> node;
int32_t offset;
res = GetStartNodeAndOffset(selection, getter_AddRefs(node), &offset);
if (!node) res = NS_ERROR_FAILURE;
@ -2114,29 +2097,27 @@ nsHTMLEditor::InsertBasicBlock(const nsAString& aBlockType)
if (isCollapsed)
{
// have to find a place to put the block
nsCOMPtr<nsIDOMNode> parent = node;
nsCOMPtr<nsIDOMNode> topChild = node;
nsCOMPtr<nsIDOMNode> tmp;
nsCOMPtr<nsINode> parent = node;
nsCOMPtr<nsINode> topChild = node;
nsCOMPtr<nsIAtom> blockAtom = do_GetAtom(aBlockType);
while (!CanContainTag(parent, blockAtom)) {
parent->GetParentNode(getter_AddRefs(tmp));
NS_ENSURE_TRUE(tmp, NS_ERROR_FAILURE);
while (!CanContainTag(*parent, *blockAtom)) {
NS_ENSURE_TRUE(parent->GetParentNode(), NS_ERROR_FAILURE);
topChild = parent;
parent = tmp;
parent = parent->GetParentNode();
}
if (parent != node)
{
// we need to split up to the child of parent
res = SplitNodeDeep(topChild, node, offset, &offset);
res = SplitNodeDeep(GetAsDOMNode(topChild), GetAsDOMNode(node), offset,
&offset);
NS_ENSURE_SUCCESS(res, res);
}
// make a block
nsCOMPtr<nsIDOMNode> newBlock;
res = CreateNode(aBlockType, parent, offset, getter_AddRefs(newBlock));
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<Element> newBlock = CreateNode(blockAtom, parent, offset);
NS_ENSURE_STATE(newBlock);
// reposition selection to inside the block
res = selection->Collapse(newBlock,0);
@ -2177,7 +2158,7 @@ nsHTMLEditor::Indent(const nsAString& aIndent)
if (!handled)
{
// Do default - insert a blockquote node if selection collapsed
nsCOMPtr<nsIDOMNode> node;
nsCOMPtr<nsINode> node;
int32_t offset;
bool isCollapsed = selection->Collapsed();
@ -2190,28 +2171,25 @@ nsHTMLEditor::Indent(const nsAString& aIndent)
if (isCollapsed)
{
// have to find a place to put the blockquote
nsCOMPtr<nsIDOMNode> parent = node;
nsCOMPtr<nsIDOMNode> topChild = node;
nsCOMPtr<nsIDOMNode> tmp;
while (!CanContainTag(parent, nsGkAtoms::blockquote)) {
parent->GetParentNode(getter_AddRefs(tmp));
NS_ENSURE_TRUE(tmp, NS_ERROR_FAILURE);
nsCOMPtr<nsINode> parent = node;
nsCOMPtr<nsINode> topChild = node;
while (!CanContainTag(*parent, *nsGkAtoms::blockquote)) {
NS_ENSURE_TRUE(parent->GetParentNode(), NS_ERROR_FAILURE);
topChild = parent;
parent = tmp;
parent = parent->GetParentNode();
}
if (parent != node)
{
// we need to split up to the child of parent
res = SplitNodeDeep(topChild, node, offset, &offset);
res = SplitNodeDeep(GetAsDOMNode(topChild), GetAsDOMNode(node),
offset, &offset);
NS_ENSURE_SUCCESS(res, res);
}
// make a blockquote
nsCOMPtr<nsIDOMNode> newBQ;
res = CreateNode(NS_LITERAL_STRING("blockquote"), parent, offset,
getter_AddRefs(newBQ));
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<Element> newBQ = CreateNode(nsGkAtoms::blockquote, parent, offset);
NS_ENSURE_STATE(newBQ);
// put a space in it so layout will draw the list item
res = selection->Collapse(newBQ,0);
NS_ENSURE_SUCCESS(res, res);
@ -2366,11 +2344,8 @@ nsHTMLEditor::GetSelectedElement(const nsAString& aTagName, nsIDOMElement** aRet
*aReturn = nullptr;
// First look for a single element in selection
nsCOMPtr<nsISelection>selection;
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
Selection* sel = static_cast<Selection*>(selection.get());
bool bNodeFound = false;
bool isCollapsed = selection->Collapsed();
@ -2384,13 +2359,12 @@ nsHTMLEditor::GetSelectedElement(const nsAString& aTagName, nsIDOMElement** aRet
bool isNamedAnchorTag = IsNamedAnchorTag(TagName);
nsCOMPtr<nsIDOMElement> selectedElement;
nsCOMPtr<nsIDOMRange> range;
res = selection->GetRangeAt(0, getter_AddRefs(range));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<nsRange> range = selection->GetRangeAt(0);
NS_ENSURE_STATE(range);
nsCOMPtr<nsIDOMNode> startParent;
int32_t startOffset, endOffset;
res = range->GetStartContainer(getter_AddRefs(startParent));
nsresult res = range->GetStartContainer(getter_AddRefs(startParent));
NS_ENSURE_SUCCESS(res, res);
res = range->GetStartOffset(&startOffset);
NS_ENSURE_SUCCESS(res, res);
@ -2487,7 +2461,7 @@ nsHTMLEditor::GetSelectedElement(const nsAString& aTagName, nsIDOMElement** aRet
if (!isCollapsed) // Don't bother to examine selection if it is collapsed
{
nsRefPtr<nsRange> currange = sel->GetRangeAt(0);
nsRefPtr<nsRange> currange = selection->GetRangeAt(0);
if (currange) {
nsCOMPtr<nsIContentIterator> iter =
do_CreateInstance("@mozilla.org/content/post-content-iterator;1", &res);
@ -2632,13 +2606,7 @@ nsHTMLEditor::InsertLinkAroundSelection(nsIDOMElement* aAnchorElement)
NS_ENSURE_TRUE(aAnchorElement, NS_ERROR_NULL_POINTER);
// We must have a real selection
nsCOMPtr<nsISelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
if (!selection)
{
res = NS_ERROR_NULL_POINTER;
}
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
if (selection->Collapsed()) {
@ -2653,7 +2621,7 @@ nsHTMLEditor::InsertLinkAroundSelection(nsIDOMElement* aAnchorElement)
}
nsAutoString href;
res = anchor->GetHref(href);
nsresult res = anchor->GetHref(href);
NS_ENSURE_SUCCESS(res, res);
if (href.IsEmpty()) {
return NS_OK;
@ -3194,17 +3162,18 @@ nsHTMLEditor::DeleteText(nsGenericDOMDataNode& aCharData, uint32_t aOffset,
return nsEditor::DeleteText(aCharData, aOffset, aLength);
}
NS_IMETHODIMP nsHTMLEditor::InsertTextImpl(const nsAString& aStringToInsert,
nsCOMPtr<nsIDOMNode> *aInOutNode,
int32_t *aInOutOffset,
nsIDOMDocument *aDoc)
nsresult
nsHTMLEditor::InsertTextImpl(const nsAString& aStringToInsert,
nsCOMPtr<nsINode>* aInOutNode,
int32_t* aInOutOffset, nsIDocument* aDoc)
{
// do nothing if the node is read-only
// Do nothing if the node is read-only
if (!IsModifiableNode(*aInOutNode)) {
return NS_ERROR_FAILURE;
}
return nsEditor::InsertTextImpl(aStringToInsert, aInOutNode, aInOutOffset, aDoc);
return nsEditor::InsertTextImpl(aStringToInsert, aInOutNode, aInOutOffset,
aDoc);
}
void
@ -3337,7 +3306,7 @@ nsHTMLEditor::GetIsSelectionEditable(bool* aIsSelectionEditable)
}
static nsresult
SetSelectionAroundHeadChildren(nsISelection* aSelection,
SetSelectionAroundHeadChildren(Selection* aSelection,
nsIWeakReference* aDocWeak)
{
// Set selection around <head> node
@ -3488,21 +3457,19 @@ nsHTMLEditor::EndOperation()
}
bool
nsHTMLEditor::TagCanContainTag(nsIAtom* aParentTag, nsIAtom* aChildTag)
nsHTMLEditor::TagCanContainTag(nsIAtom& aParentTag, nsIAtom& aChildTag)
{
MOZ_ASSERT(aParentTag && aChildTag);
nsIParserService* parserService = nsContentUtils::GetParserService();
int32_t childTagEnum;
// XXX Should this handle #cdata-section too?
if (aChildTag == nsGkAtoms::textTagName) {
if (&aChildTag == nsGkAtoms::textTagName) {
childTagEnum = eHTMLTag_text;
} else {
childTagEnum = parserService->HTMLAtomTagToId(aChildTag);
childTagEnum = parserService->HTMLAtomTagToId(&aChildTag);
}
int32_t parentTagEnum = parserService->HTMLAtomTagToId(aParentTag);
int32_t parentTagEnum = parserService->HTMLAtomTagToId(&aParentTag);
return nsHTMLEditUtils::CanContain(parentTagEnum, childTagEnum);
}
@ -3533,8 +3500,8 @@ nsHTMLEditor::IsContainer(nsIDOMNode *aNode)
}
NS_IMETHODIMP
nsHTMLEditor::SelectEntireDocument(nsISelection *aSelection)
nsresult
nsHTMLEditor::SelectEntireDocument(Selection* aSelection)
{
if (!aSelection || !mRules) { return NS_ERROR_NULL_POINTER; }
@ -3563,18 +3530,11 @@ nsHTMLEditor::SelectAll()
{
ForceCompositionEnd();
nsresult rv;
nsCOMPtr<nsISelectionController> selCon;
rv = GetSelectionController(getter_AddRefs(selCon));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISelection> selection;
rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
getter_AddRefs(selection));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_STATE(selection);
nsCOMPtr<nsIDOMNode> anchorNode;
rv = selection->GetAnchorNode(getter_AddRefs(anchorNode));
nsresult rv = selection->GetAnchorNode(getter_AddRefs(anchorNode));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIContent> anchorContent = do_QueryInterface(anchorNode, &rv);
@ -3583,9 +3543,7 @@ nsHTMLEditor::SelectAll()
// If the anchor content has independent selection, we never need to explicitly
// select its children.
if (anchorContent->HasIndependentSelection()) {
nsCOMPtr<nsISelectionPrivate> selPriv = do_QueryInterface(selection);
NS_ENSURE_TRUE(selPriv, NS_ERROR_UNEXPECTED);
rv = selPriv->SetAncestorLimiter(nullptr);
rv = selection->SetAncestorLimiter(nullptr);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> rootElement = do_QueryInterface(mRootElement, &rv);
NS_ENSURE_SUCCESS(rv, rv);
@ -3709,9 +3667,7 @@ nsHTMLEditor::SetCaretInTableCell(nsIDOMElement* aElement)
}
// Set selection at beginning of the found node
nsCOMPtr<nsISelection> selection;
nsresult rv = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(rv, false);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, false);
return NS_SUCCEEDED(selection->CollapseNative(node, 0));
@ -3753,8 +3709,8 @@ nsHTMLEditor::GetEnclosingTable(nsIDOMNode *aNode)
* Uses nsEditor::JoinNodes so action is undoable.
* Should be called within the context of a batch transaction.
*/
NS_IMETHODIMP
nsHTMLEditor::CollapseAdjacentTextNodes(nsIDOMRange *aInRange)
nsresult
nsHTMLEditor::CollapseAdjacentTextNodes(nsRange* aInRange)
{
NS_ENSURE_TRUE(aInRange, NS_ERROR_NULL_POINTER);
nsAutoTxnsConserveSelection dontSpazMySelection(this);
@ -3814,8 +3770,8 @@ nsHTMLEditor::CollapseAdjacentTextNodes(nsIDOMRange *aInRange)
return result;
}
NS_IMETHODIMP
nsHTMLEditor::SetSelectionAtDocumentStart(nsISelection *aSelection)
nsresult
nsHTMLEditor::SetSelectionAtDocumentStart(Selection* aSelection)
{
dom::Element* rootElement = GetRoot();
NS_ENSURE_TRUE(rootElement, NS_ERROR_NULL_POINTER);
@ -3832,7 +3788,8 @@ nsHTMLEditor::SetSelectionAtDocumentStart(nsISelection *aSelection)
nsresult
nsHTMLEditor::RemoveBlockContainer(nsIDOMNode *inNode)
{
NS_ENSURE_TRUE(inNode, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIContent> node = do_QueryInterface(inNode);
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
nsresult res;
nsCOMPtr<nsIDOMNode> sibling, child, unused;
@ -3844,8 +3801,7 @@ nsHTMLEditor::RemoveBlockContainer(nsIDOMNode *inNode)
// and compare following sibling and last child to determine if we need a
// trailing br.
res = GetFirstEditableChild(inNode, address_of(child));
NS_ENSURE_SUCCESS(res, res);
child = GetAsDOMNode(GetFirstEditableChild(*node));
if (child) // the case of inNode not being empty
{
@ -3859,10 +3815,7 @@ nsHTMLEditor::RemoveBlockContainer(nsIDOMNode *inNode)
NS_ENSURE_SUCCESS(res, res);
if (sibling && !IsBlockNode(sibling) && !nsTextEditUtils::IsBreak(sibling))
{
res = GetFirstEditableChild(inNode, address_of(child));
NS_ENSURE_SUCCESS(res, res);
if (child && !IsBlockNode(child))
{
if (!IsBlockNode(child)) {
// insert br node
res = CreateBR(inNode, 0, address_of(unused));
NS_ENSURE_SUCCESS(res, res);
@ -3879,8 +3832,7 @@ nsHTMLEditor::RemoveBlockContainer(nsIDOMNode *inNode)
NS_ENSURE_SUCCESS(res, res);
if (sibling && !IsBlockNode(sibling))
{
res = GetLastEditableChild(inNode, address_of(child));
NS_ENSURE_SUCCESS(res, res);
child = GetAsDOMNode(GetLastEditableChild(*node));
if (child && !IsBlockNode(child) && !nsTextEditUtils::IsBreak(child))
{
// insert br node
@ -3916,8 +3868,6 @@ nsHTMLEditor::RemoveBlockContainer(nsIDOMNode *inNode)
}
// now remove container
nsCOMPtr<nsIContent> node = do_QueryInterface(inNode);
NS_ENSURE_STATE(node);
return RemoveContainer(node);
}
@ -4180,166 +4130,95 @@ nsHTMLEditor::GetNextHTMLNode(nsIDOMNode* aNode, int32_t aOffset,
nsresult
nsHTMLEditor::IsFirstEditableChild( nsIDOMNode *aNode, bool *aOutIsFirst)
{
// check parms
NS_ENSURE_TRUE(aOutIsFirst && aNode, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
NS_ENSURE_TRUE(aOutIsFirst && node, NS_ERROR_NULL_POINTER);
// init out parms
*aOutIsFirst = false;
// find first editable child and compare it to aNode
nsCOMPtr<nsIDOMNode> parent, firstChild;
nsresult res = aNode->GetParentNode(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<nsINode> parent = node->GetParentNode();
NS_ENSURE_TRUE(parent, NS_ERROR_FAILURE);
res = GetFirstEditableChild(parent, address_of(firstChild));
NS_ENSURE_SUCCESS(res, res);
*aOutIsFirst = (firstChild.get() == aNode);
return res;
*aOutIsFirst = (GetFirstEditableChild(*parent) == node);
return NS_OK;
}
nsresult
nsHTMLEditor::IsLastEditableChild( nsIDOMNode *aNode, bool *aOutIsLast)
{
// check parms
NS_ENSURE_TRUE(aOutIsLast && aNode, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
NS_ENSURE_TRUE(aOutIsLast && node, NS_ERROR_NULL_POINTER);
// init out parms
*aOutIsLast = false;
// find last editable child and compare it to aNode
nsCOMPtr<nsIDOMNode> parent, lastChild;
nsresult res = aNode->GetParentNode(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<nsINode> parent = node->GetParentNode();
NS_ENSURE_TRUE(parent, NS_ERROR_FAILURE);
res = GetLastEditableChild(parent, address_of(lastChild));
NS_ENSURE_SUCCESS(res, res);
*aOutIsLast = (lastChild.get() == aNode);
return res;
*aOutIsLast = (GetLastEditableChild(*parent) == node);
return NS_OK;
}
nsresult
nsHTMLEditor::GetFirstEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutFirstChild)
nsIContent*
nsHTMLEditor::GetFirstEditableChild(nsINode& aNode)
{
// check parms
NS_ENSURE_TRUE(aOutFirstChild && aNode, NS_ERROR_NULL_POINTER);
// init out parms
*aOutFirstChild = nullptr;
// find first editable child
nsCOMPtr<nsIDOMNode> child;
nsresult res = aNode->GetFirstChild(getter_AddRefs(child));
NS_ENSURE_SUCCESS(res, res);
while (child && !IsEditable(child))
{
nsCOMPtr<nsIDOMNode> tmp;
res = child->GetNextSibling(getter_AddRefs(tmp));
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_TRUE(tmp, NS_ERROR_FAILURE);
child = tmp;
nsCOMPtr<nsIContent> child = aNode.GetFirstChild();
while (child && !IsEditable(child)) {
child = child->GetNextSibling();
}
*aOutFirstChild = child;
return res;
return child;
}
nsresult
nsHTMLEditor::GetLastEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutLastChild)
nsIContent*
nsHTMLEditor::GetLastEditableChild(nsINode& aNode)
{
// check parms
NS_ENSURE_TRUE(aOutLastChild && aNode, NS_ERROR_NULL_POINTER);
// init out parms
*aOutLastChild = aNode;
// find last editable child
nsCOMPtr<nsIDOMNode> child;
nsresult res = aNode->GetLastChild(getter_AddRefs(child));
NS_ENSURE_SUCCESS(res, res);
while (child && !IsEditable(child))
{
nsCOMPtr<nsIDOMNode> tmp;
res = child->GetPreviousSibling(getter_AddRefs(tmp));
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_TRUE(tmp, NS_ERROR_FAILURE);
child = tmp;
nsCOMPtr<nsIContent> child = aNode.GetLastChild();
while (child && !IsEditable(child)) {
child = child->GetPreviousSibling();
}
*aOutLastChild = child;
return res;
return child;
}
nsresult
nsHTMLEditor::GetFirstEditableLeaf( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutFirstLeaf)
nsIContent*
nsHTMLEditor::GetFirstEditableLeaf(nsINode& aNode)
{
// check parms
NS_ENSURE_TRUE(aOutFirstLeaf && aNode, NS_ERROR_NULL_POINTER);
// init out parms
*aOutFirstLeaf = aNode;
// find leftmost leaf
nsCOMPtr<nsIDOMNode> child;
nsresult res = NS_OK;
child = GetLeftmostChild(aNode);
while (child && (!IsEditable(child) || !nsEditorUtils::IsLeafNode(child)))
{
nsCOMPtr<nsIDOMNode> tmp;
res = GetNextHTMLNode(child, address_of(tmp));
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_TRUE(tmp, NS_ERROR_FAILURE);
// only accept nodes that are descendants of aNode
if (nsEditorUtils::IsDescendantOf(tmp, aNode))
child = tmp;
else
{
child = nullptr; // this will abort the loop
nsCOMPtr<nsIContent> child = GetLeftmostChild(&aNode);
while (child && (!IsEditable(child) || child->HasChildren())) {
child = GetNextHTMLNode(child);
// Only accept nodes that are descendants of aNode
if (!aNode.Contains(child)) {
return nullptr;
}
}
*aOutFirstLeaf = child;
return res;
return child;
}
nsresult
nsHTMLEditor::GetLastEditableLeaf(nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutLastLeaf)
nsIContent*
nsHTMLEditor::GetLastEditableLeaf(nsINode& aNode)
{
// check parms
NS_ENSURE_TRUE(aOutLastLeaf && aNode, NS_ERROR_NULL_POINTER);
// init out parms
*aOutLastLeaf = nullptr;
// find rightmost leaf
nsCOMPtr<nsIDOMNode> child = GetRightmostChild(aNode, false);
nsresult res = NS_OK;
while (child && (!IsEditable(child) || !nsEditorUtils::IsLeafNode(child)))
{
nsCOMPtr<nsIDOMNode> tmp;
res = GetPriorHTMLNode(child, address_of(tmp));
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_TRUE(tmp, NS_ERROR_FAILURE);
// only accept nodes that are descendants of aNode
if (nsEditorUtils::IsDescendantOf(tmp, aNode))
child = tmp;
else
{
child = nullptr;
nsCOMPtr<nsIContent> child = GetRightmostChild(&aNode, false);
while (child && (!IsEditable(child) || child->HasChildren())) {
child = GetPriorHTMLNode(child);
// Only accept nodes that are descendants of aNode
if (!aNode.Contains(child)) {
return nullptr;
}
}
*aOutLastLeaf = child;
return res;
return child;
}
@ -4908,8 +4787,9 @@ nsHTMLEditor::CopyLastEditableChildStyles(nsIDOMNode * aPreviousBlock, nsIDOMNod
tmp = aPreviousBlock;
while (tmp) {
child = tmp;
res = GetLastEditableChild(child, address_of(tmp));
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<nsINode> child_ = do_QueryInterface(child);
NS_ENSURE_STATE(child_ || !child);
tmp = GetAsDOMNode(GetLastEditableChild(*child_));
}
while (child && nsTextEditUtils::IsBreak(child)) {
nsCOMPtr<nsIDOMNode> priorNode;
@ -4982,9 +4862,7 @@ nsHTMLEditor::EndUpdateViewBatch()
// to listen too (in particular when an ancestor of the selection is
// changed but the selection itself is not changed).
if (mUpdateCount == 0) {
nsCOMPtr<nsISelection> selection;
res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NOT_INITIALIZED);
res = CheckSelectionStateForAnonymousButtons(selection);
}
@ -4994,13 +4872,15 @@ nsHTMLEditor::EndUpdateViewBatch()
NS_IMETHODIMP
nsHTMLEditor::GetSelectionContainer(nsIDOMElement ** aReturn)
{
nsCOMPtr<nsISelection>selection;
nsresult res = GetSelection(getter_AddRefs(selection));
nsRefPtr<Selection> selection = GetSelection();
// if we don't get the selection, just skip this
if (NS_FAILED(res) || !selection) return res;
if (!selection) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMNode> focusNode;
nsresult res;
if (selection->Collapsed()) {
res = selection->GetFocusNode(getter_AddRefs(focusNode));
NS_ENSURE_SUCCESS(res, res);
@ -5012,9 +4892,7 @@ nsHTMLEditor::GetSelectionContainer(nsIDOMElement ** aReturn)
if (rangeCount == 1) {
nsCOMPtr<nsIDOMRange> range;
res = selection->GetRangeAt(0, getter_AddRefs(range));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<nsRange> range = selection->GetRangeAt(0);
NS_ENSURE_TRUE(range, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode> startContainer, endContainer;
@ -5042,11 +4920,11 @@ nsHTMLEditor::GetSelectionContainer(nsIDOMElement ** aReturn)
}
else {
int32_t i;
nsCOMPtr<nsIDOMRange> range;
nsRefPtr<nsRange> range;
for (i = 0; i < rangeCount; i++)
{
res = selection->GetRangeAt(i, getter_AddRefs(range));
NS_ENSURE_SUCCESS(res, res);
range = selection->GetRangeAt(i);
NS_ENSURE_STATE(range);
nsCOMPtr<nsIDOMNode> startContainer;
res = range->GetStartContainer(getter_AddRefs(startContainer));
if (NS_FAILED(res)) continue;
@ -5206,11 +5084,10 @@ nsHTMLEditor::GetActiveEditingHost()
}
// We're HTML editor for contenteditable
nsCOMPtr<nsISelection> selection;
nsresult rv = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(rv, nullptr);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, nullptr);
nsCOMPtr<nsIDOMNode> focusNode;
rv = selection->GetFocusNode(getter_AddRefs(focusNode));
nsresult rv = selection->GetFocusNode(getter_AddRefs(focusNode));
NS_ENSURE_SUCCESS(rv, nullptr);
nsCOMPtr<nsIContent> content = do_QueryInterface(focusNode);
if (!content) {

View File

@ -50,6 +50,8 @@ class nsIContentFilter;
class nsIURL;
class nsILinkHandler;
class nsTableOuterFrame;
class nsIDOMRange;
class nsRange;
struct PropItem;
namespace mozilla {
@ -205,7 +207,7 @@ public:
nsIDOMElement** aTableElement);
NS_IMETHOD GetSelectedCellsType(nsIDOMElement *aElement, uint32_t *aSelectionType);
nsresult GetCellFromRange(nsIDOMRange *aRange, nsIDOMElement **aCell);
nsresult GetCellFromRange(nsRange* aRange, nsIDOMElement** aCell);
// Finds the first selected cell in first range of selection
// This is in the *order of selection*, not order in the table
@ -284,14 +286,15 @@ public:
NS_IMETHOD EndOperation();
/** returns true if aParentTag can contain a child of type aChildTag */
virtual bool TagCanContainTag(nsIAtom* aParentTag, nsIAtom* aChildTag);
virtual bool TagCanContainTag(nsIAtom& aParentTag, nsIAtom& aChildTag)
MOZ_OVERRIDE;
/** returns true if aNode is a container */
virtual bool IsContainer(nsINode* aNode) MOZ_OVERRIDE;
virtual bool IsContainer(nsIDOMNode* aNode) MOZ_OVERRIDE;
/** make the given selection span the entire document */
NS_IMETHOD SelectEntireDocument(nsISelection *aSelection);
virtual nsresult SelectEntireDocument(mozilla::dom::Selection* aSelection);
NS_IMETHOD SetAttributeOrEquivalent(nsIDOMElement * aElement,
const nsAString & aAttribute,
@ -302,7 +305,7 @@ public:
bool aSuppressTransaction);
/** join together any adjacent editable text nodes in the range */
NS_IMETHOD CollapseAdjacentTextNodes(nsIDOMRange *aInRange);
nsresult CollapseAdjacentTextNodes(nsRange* aRange);
virtual bool AreNodesSameType(nsIContent* aNode1, nsIContent* aNode2)
MOZ_OVERRIDE;
@ -313,10 +316,10 @@ public:
NS_IMETHODIMP DeleteNode(nsIDOMNode * aNode);
nsresult DeleteText(nsGenericDOMDataNode& aTextNode, uint32_t aOffset,
uint32_t aLength);
NS_IMETHOD InsertTextImpl(const nsAString& aStringToInsert,
nsCOMPtr<nsIDOMNode> *aInOutNode,
int32_t *aInOutOffset,
nsIDOMDocument *aDoc);
virtual nsresult InsertTextImpl(const nsAString& aStringToInsert,
nsCOMPtr<nsINode>* aInOutNode,
int32_t* aInOutOffset,
nsIDocument* aDoc) MOZ_OVERRIDE;
NS_IMETHOD_(bool) IsModifiableNode(nsIDOMNode *aNode);
virtual bool IsModifiableNode(nsINode *aNode);
@ -443,7 +446,8 @@ protected:
// Move all contents from aCellToMerge into aTargetCell (append at end)
NS_IMETHOD MergeCells(nsCOMPtr<nsIDOMElement> aTargetCell, nsCOMPtr<nsIDOMElement> aCellToMerge, bool aDeleteCellToMerge);
NS_IMETHOD DeleteTable2(nsIDOMElement *aTable, nsISelection *aSelection);
nsresult DeleteTable2(nsIDOMElement* aTable,
mozilla::dom::Selection* aSelection);
NS_IMETHOD SetColSpan(nsIDOMElement *aCell, int32_t aColSpan);
NS_IMETHOD SetRowSpan(nsIDOMElement *aCell, int32_t aRowSpan);
@ -463,11 +467,10 @@ protected:
// Input: *aCell is a known cell,
// if null, cell is obtained from the anchor node of the selection
// Returns NS_EDITOR_ELEMENT_NOT_FOUND if cell is not found even if aCell is null
NS_IMETHOD GetCellContext(nsISelection **aSelection,
nsIDOMElement **aTable,
nsIDOMElement **aCell,
nsIDOMNode **aCellParent, int32_t *aCellOffset,
int32_t *aRowIndex, int32_t *aColIndex);
nsresult GetCellContext(mozilla::dom::Selection** aSelection,
nsIDOMElement** aTable, nsIDOMElement** aCell,
nsIDOMNode** aCellParent, int32_t* aCellOffset,
int32_t* aRowIndex, int32_t* aColIndex);
NS_IMETHOD GetCellSpansAt(nsIDOMElement* aTable, int32_t aRowIndex, int32_t aColIndex,
int32_t& aActualRowSpan, int32_t& aActualColSpan);
@ -486,7 +489,7 @@ protected:
// Fallback method: Call this after using ClearSelection() and you
// failed to set selection to some other content in the document
NS_IMETHOD SetSelectionAtDocumentStart(nsISelection *aSelection);
nsresult SetSelectionAtDocumentStart(mozilla::dom::Selection* aSelection);
// End of Table Editing utilities
@ -658,9 +661,9 @@ protected:
const nsAString* aAttribute,
const nsAString* aValue);
nsresult PromoteInlineRange(nsIDOMRange *inRange);
nsresult PromoteRangeIfStartsOrEndsInNamedAnchor(nsIDOMRange *inRange);
nsresult SplitStyleAboveRange(nsIDOMRange *aRange,
nsresult PromoteInlineRange(nsRange* aRange);
nsresult PromoteRangeIfStartsOrEndsInNamedAnchor(nsRange* aRange);
nsresult SplitStyleAboveRange(nsRange* aRange,
nsIAtom *aProperty,
const nsAString *aAttribute);
nsresult SplitStyleAbovePoint(nsCOMPtr<nsIDOMNode> *aNode,
@ -709,11 +712,11 @@ protected:
nsresult IsFirstEditableChild( nsIDOMNode *aNode, bool *aOutIsFirst);
nsresult IsLastEditableChild( nsIDOMNode *aNode, bool *aOutIsLast);
nsresult GetFirstEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutFirstChild);
nsresult GetLastEditableChild( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutLastChild);
nsIContent* GetFirstEditableChild(nsINode& aNode);
nsIContent* GetLastEditableChild(nsINode& aNode);
nsresult GetFirstEditableLeaf( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutFirstLeaf);
nsresult GetLastEditableLeaf( nsIDOMNode *aNode, nsCOMPtr<nsIDOMNode> *aOutLastLeaf);
nsIContent* GetFirstEditableLeaf(nsINode& aNode);
nsIContent* GetLastEditableLeaf(nsINode& aNode);
nsresult GetInlinePropertyBase(nsIAtom *aProperty,
const nsAString *aAttribute,

View File

@ -2,6 +2,7 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/dom/Selection.h"
#include "nsAutoPtr.h"
#include "nsCOMPtr.h"
#include "nsDebug.h"
@ -15,14 +16,16 @@
#include "nsIDOMEventTarget.h"
#include "nsIDOMMouseEvent.h"
#include "nsIDOMNode.h"
#include "nsIDOMRange.h"
#include "nsIEditor.h"
#include "nsIHTMLEditor.h"
#include "nsIHTMLInlineTableEditor.h"
#include "nsIHTMLObjectResizer.h"
#include "nsISelection.h"
#include "nsISupportsImpl.h"
#include "nsLiteralString.h"
#include "nsRange.h"
using namespace mozilla;
using namespace mozilla::dom;
/*
* nsHTMLEditorEventListener implementation
@ -99,8 +102,7 @@ nsHTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent)
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(target);
if (isContextClick || (buttonNumber == 0 && clickCount == 2)) {
nsCOMPtr<nsISelection> selection;
mEditor->GetSelection(getter_AddRefs(selection));
nsRefPtr<Selection> selection = mEditor->GetSelection();
NS_ENSURE_TRUE(selection, NS_OK);
// Get location of mouse within target node
@ -121,10 +123,8 @@ nsHTMLEditorEventListener::MouseDown(nsIDOMMouseEvent* aMouseEvent)
NS_ENSURE_SUCCESS(rv, rv);
for (int32_t i = 0; i < rangeCount; i++) {
nsCOMPtr<nsIDOMRange> range;
rv = selection->GetRangeAt(i, getter_AddRefs(range));
if (NS_FAILED(rv) || !range) {
nsRefPtr<nsRange> range = selection->GetRangeAt(i);
if (!range) {
// Don't bail yet, iterate through them all
continue;
}

View File

@ -29,15 +29,13 @@
#include "nsIDOMCharacterData.h"
#include "nsIDOMElement.h"
#include "nsIDOMNode.h"
#include "nsIDOMRange.h"
#include "nsIEditor.h"
#include "nsIEditorIMESupport.h"
#include "nsNameSpaceManager.h"
#include "nsINode.h"
#include "nsISelection.h"
#include "nsISelectionPrivate.h"
#include "nsISupportsImpl.h"
#include "nsLiteralString.h"
#include "nsRange.h"
#include "nsReadableUtils.h"
#include "nsSelectionState.h"
#include "nsString.h"
@ -331,12 +329,11 @@ nsHTMLEditor::SetInlinePropertyOnTextNode( nsIDOMCharacterData *aTextNode,
const nsAString *aValue)
{
MOZ_ASSERT(aValue);
NS_ENSURE_TRUE(aTextNode, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMNode> parent;
nsresult res = aTextNode->GetParentNode(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<nsIContent> textNode = do_QueryInterface(aTextNode);
NS_ENSURE_TRUE(textNode, NS_ERROR_NULL_POINTER);
if (!CanContainTag(parent, aProperty)) {
if (!textNode->GetParentNode() ||
!CanContainTag(*textNode->GetParentNode(), *aProperty)) {
return NS_OK;
}
@ -364,6 +361,7 @@ nsHTMLEditor::SetInlinePropertyOnTextNode( nsIDOMCharacterData *aTextNode,
uint32_t textLen;
aTextNode->GetLength(&textLen);
nsresult res;
if (uint32_t(aEndOffset) != textLen) {
// we need to split off back of text node
nsCOMPtr<nsIDOMNode> tmp;
@ -414,7 +412,7 @@ nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent* aNode,
// If this is an element that can't be contained in a span, we have to
// recurse to its children.
if (!TagCanContain(nsGkAtoms::span, aNode->AsDOMNode())) {
if (!TagCanContain(*nsGkAtoms::span, *aNode)) {
if (aNode->HasChildren()) {
nsCOMArray<nsIContent> arrayOfNodes;
@ -446,7 +444,7 @@ nsHTMLEditor::SetInlinePropertyOnNodeImpl(nsIContent* aNode,
res = MoveNode(aNode, previousSibling, -1);
NS_ENSURE_SUCCESS(res, res);
if (IsSimpleModifiableNode(nextSibling, aProperty, aAttribute, aValue)) {
res = JoinNodes(previousSibling, nextSibling);
res = JoinNodes(*previousSibling, *nextSibling);
NS_ENSURE_SUCCESS(res, res);
}
return NS_OK;
@ -580,9 +578,9 @@ nsHTMLEditor::SetInlinePropertyOnNode(nsIContent* aNode,
}
nsresult nsHTMLEditor::SplitStyleAboveRange(nsIDOMRange *inRange,
nsIAtom *aProperty,
const nsAString *aAttribute)
nsresult
nsHTMLEditor::SplitStyleAboveRange(nsRange* inRange, nsIAtom* aProperty,
const nsAString* aAttribute)
{
NS_ENSURE_TRUE(inRange, NS_ERROR_NULL_POINTER);
nsresult res;
@ -686,7 +684,10 @@ nsHTMLEditor::ClearStyle(nsCOMPtr<nsIDOMNode>* aNode, int32_t* aOffset,
}
}
if (rightNode) {
nsCOMPtr<nsIDOMNode> secondSplitParent = GetLeftmostChild(rightNode);
nsCOMPtr<nsINode> rightNode_ = do_QueryInterface(rightNode);
NS_ENSURE_STATE(rightNode_);
nsCOMPtr<nsIDOMNode> secondSplitParent =
GetAsDOMNode(GetLeftmostChild(rightNode_));
// don't try to split non-containers (br's, images, hr's, etc)
if (!secondSplitParent) {
secondSplitParent = rightNode;
@ -707,9 +708,9 @@ nsHTMLEditor::ClearStyle(nsCOMPtr<nsIDOMNode>* aNode, int32_t* aOffset,
address_of(leftNode), address_of(rightNode));
NS_ENSURE_SUCCESS(res, res);
// should be impossible to not get a new leftnode here
NS_ENSURE_TRUE(leftNode, NS_ERROR_FAILURE);
nsCOMPtr<nsINode> newSelParent =
do_QueryInterface(GetLeftmostChild(leftNode));
nsCOMPtr<nsINode> leftNode_ = do_QueryInterface(leftNode);
NS_ENSURE_TRUE(leftNode_, NS_ERROR_FAILURE);
nsCOMPtr<nsINode> newSelParent = GetLeftmostChild(leftNode_);
if (!newSelParent) {
newSelParent = do_QueryInterface(leftNode);
NS_ENSURE_STATE(newSelParent);
@ -947,7 +948,8 @@ bool nsHTMLEditor::HasAttr(nsIDOMNode* aNode,
}
nsresult nsHTMLEditor::PromoteRangeIfStartsOrEndsInNamedAnchor(nsIDOMRange *inRange)
nsresult
nsHTMLEditor::PromoteRangeIfStartsOrEndsInNamedAnchor(nsRange* inRange)
{
NS_ENSURE_TRUE(inRange, NS_ERROR_NULL_POINTER);
nsresult res;
@ -1001,7 +1003,8 @@ nsresult nsHTMLEditor::PromoteRangeIfStartsOrEndsInNamedAnchor(nsIDOMRange *inRa
return res;
}
nsresult nsHTMLEditor::PromoteInlineRange(nsIDOMRange *inRange)
nsresult
nsHTMLEditor::PromoteInlineRange(nsRange* inRange)
{
NS_ENSURE_TRUE(inRange, NS_ERROR_NULL_POINTER);
nsresult res;
@ -1046,7 +1049,8 @@ nsresult nsHTMLEditor::PromoteInlineRange(nsIDOMRange *inRange)
bool nsHTMLEditor::IsAtFrontOfNode(nsIDOMNode *aNode, int32_t aOffset)
{
NS_ENSURE_TRUE(aNode, false); // oops
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
NS_ENSURE_TRUE(node, false);
if (!aOffset) {
return true;
}
@ -1057,10 +1061,9 @@ bool nsHTMLEditor::IsAtFrontOfNode(nsIDOMNode *aNode, int32_t aOffset)
}
else
{
nsCOMPtr<nsIDOMNode> firstNode;
GetFirstEditableChild(aNode, address_of(firstNode));
nsCOMPtr<nsIContent> firstNode = GetFirstEditableChild(*node);
NS_ENSURE_TRUE(firstNode, true);
int32_t offset = GetChildOffset(firstNode, aNode);
int32_t offset = node->IndexOf(firstNode);
if (offset < aOffset) return false;
return true;
}
@ -1068,9 +1071,9 @@ bool nsHTMLEditor::IsAtFrontOfNode(nsIDOMNode *aNode, int32_t aOffset)
bool nsHTMLEditor::IsAtEndOfNode(nsIDOMNode *aNode, int32_t aOffset)
{
NS_ENSURE_TRUE(aNode, false); // oops
uint32_t len;
GetLengthOfDOMNode(aNode, len);
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
NS_ENSURE_TRUE(node, false);
uint32_t len = node->Length();
if (aOffset == (int32_t)len) return true;
if (IsTextNode(aNode))
@ -1079,10 +1082,9 @@ bool nsHTMLEditor::IsAtEndOfNode(nsIDOMNode *aNode, int32_t aOffset)
}
else
{
nsCOMPtr<nsIDOMNode> lastNode;
GetLastEditableChild(aNode, address_of(lastNode));
nsCOMPtr<nsIContent> lastNode = GetLastEditableChild(*node);
NS_ENSURE_TRUE(lastNode, true);
int32_t offset = GetChildOffset(lastNode, aNode);
int32_t offset = node->IndexOf(lastNode);
if (offset < aOffset) return true;
return false;
}
@ -1107,15 +1109,12 @@ nsHTMLEditor::GetInlinePropertyBase(nsIAtom *aProperty,
*aFirst = false;
bool first = true;
nsCOMPtr<nsISelection> selection;
result = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(result, result);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
Selection* sel = static_cast<Selection*>(selection.get());
bool isCollapsed = selection->Collapsed();
nsCOMPtr<nsIDOMNode> collapsedNode;
nsRefPtr<nsRange> range = sel->GetRangeAt(0);
nsRefPtr<nsRange> range = selection->GetRangeAt(0);
// XXX: should be a while loop, to get each separate range
// XXX: ERROR_HANDLING can currentItem be null?
if (range) {
@ -1521,16 +1520,13 @@ nsHTMLEditor::RelativeFontChange( int32_t aSizeChange)
// Let's see in what kind of element the selection is
int32_t offset;
nsCOMPtr<nsIDOMNode> selectedNode;
nsCOMPtr<nsINode> selectedNode;
GetStartNodeAndOffset(selection, getter_AddRefs(selectedNode), &offset);
NS_ENSURE_TRUE(selectedNode, NS_OK);
if (IsTextNode(selectedNode)) {
nsCOMPtr<nsIDOMNode> parent;
nsresult res = selectedNode->GetParentNode(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(res, res);
selectedNode = parent;
selectedNode = selectedNode->GetParentNode();
}
if (!CanContainTag(selectedNode, atom)) {
if (!CanContainTag(*selectedNode, *atom)) {
return NS_OK;
}
@ -1647,16 +1643,14 @@ nsHTMLEditor::RelativeFontChangeOnTextNode( int32_t aSizeChange,
// Can only change font size by + or - 1
if ( !( (aSizeChange==1) || (aSizeChange==-1) ) )
return NS_ERROR_ILLEGAL_VALUE;
NS_ENSURE_TRUE(aTextNode, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIContent> textNode = do_QueryInterface(aTextNode);
NS_ENSURE_TRUE(textNode, NS_ERROR_NULL_POINTER);
// don't need to do anything if no characters actually selected
if (aStartOffset == aEndOffset) return NS_OK;
nsresult res = NS_OK;
nsCOMPtr<nsIDOMNode> parent;
res = aTextNode->GetParentNode(getter_AddRefs(parent));
NS_ENSURE_SUCCESS(res, res);
if (!CanContainTag(parent, nsGkAtoms::big)) {
if (!textNode->GetParentNode() ||
!CanContainTag(*textNode->GetParentNode(), *nsGkAtoms::big)) {
return NS_OK;
}
@ -1671,6 +1665,7 @@ nsHTMLEditor::RelativeFontChangeOnTextNode( int32_t aSizeChange,
// -1 is a magic value meaning to the end of node
if (aEndOffset == -1) aEndOffset = textLen;
nsresult res = NS_OK;
if ( (uint32_t)aEndOffset != textLen )
{
// we need to split off back of text node
@ -1777,7 +1772,7 @@ nsHTMLEditor::RelativeFontChangeOnNode(int32_t aSizeChange, nsIContent* aNode)
}
// can it be put inside a "big" or "small"?
if (TagCanContain(atom, aNode->AsDOMNode())) {
if (TagCanContain(*atom, *aNode)) {
// first populate any nested font tags that have the size attr set
nsresult rv = RelativeFontChangeHelper(aSizeChange, aNode);
NS_ENSURE_SUCCESS(rv, rv);

View File

@ -5,6 +5,7 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/dom/Selection.h"
#include "nsAString.h"
#include "nsCOMPtr.h"
#include "nsCRT.h"
@ -21,7 +22,6 @@
#include "nsIDOMDragEvent.h"
#include "nsIDOMEvent.h"
#include "nsIDOMNode.h"
#include "nsIDOMRange.h"
#include "nsIDOMUIEvent.h"
#include "nsIDocument.h"
#include "nsIDragService.h"
@ -33,12 +33,12 @@
#include "nsIPrincipal.h"
#include "nsIFormControl.h"
#include "nsIPlaintextEditor.h"
#include "nsISelection.h"
#include "nsISupportsPrimitives.h"
#include "nsITransferable.h"
#include "nsIVariant.h"
#include "nsLiteralString.h"
#include "nsPlaintextEditor.h"
#include "nsRange.h"
#include "nsSelectionState.h"
#include "nsServiceManagerUtils.h"
#include "nsString.h"
@ -77,9 +77,8 @@ nsresult nsPlaintextEditor::InsertTextAt(const nsAString &aStringToInsert,
if (aDestinationNode)
{
nsresult res;
nsCOMPtr<nsISelection>selection;
res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_STATE(selection);
nsCOMPtr<nsIDOMNode> targetNode = aDestinationNode;
int32_t targetOffset = aDestOffset;
@ -220,9 +219,7 @@ nsresult nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
rv = uiEvent->GetRangeOffset(&newSelectionOffset);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISelection> selection;
rv = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
bool isCollapsed = selection->Collapsed();
@ -259,10 +256,11 @@ nsresult nsPlaintextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
for (int32_t j = 0; j < rangeCount; j++)
{
nsCOMPtr<nsIDOMRange> range;
rv = selection->GetRangeAt(j, getter_AddRefs(range));
if (NS_FAILED(rv) || !range)
continue; // don't bail yet, iterate through them all
nsRefPtr<nsRange> range = selection->GetRangeAt(j);
if (!range) {
// don't bail yet, iterate through them all
continue;
}
rv = range->IsPointInRange(newSelectionParent, newSelectionOffset, &cursorIsInSelection);
if (cursorIsInSelection)

View File

@ -40,9 +40,7 @@
#include "nsNameSpaceManager.h"
#include "nsINode.h"
#include "nsIPresShell.h"
#include "nsISelection.h"
#include "nsISelectionController.h"
#include "nsISelectionPrivate.h"
#include "nsISupportsPrimitives.h"
#include "nsITransferable.h"
#include "nsIWeakReferenceUtils.h"
@ -509,20 +507,18 @@ nsPlaintextEditor::CreateBRImpl(nsCOMPtr<nsIDOMNode>* aInOutParent,
int32_t offset;
nsCOMPtr<nsIDOMNode> parent = GetNodeLocation(*outBRNode, &offset);
nsCOMPtr<nsISelection> selection;
res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_STATE(selection);
if (aSelect == eNext)
{
// position selection after br
selPriv->SetInterlinePosition(true);
selection->SetInterlinePosition(true);
res = selection->Collapse(parent, offset+1);
}
else if (aSelect == ePrevious)
{
// position selection before br
selPriv->SetInterlinePosition(true);
selection->SetInterlinePosition(true);
res = selection->Collapse(parent, offset);
}
}
@ -546,10 +542,10 @@ nsPlaintextEditor::InsertBR(nsCOMPtr<nsIDOMNode>* outBRNode)
// calling it text insertion to trigger moz br treatment by rules
nsAutoRules beginRulesSniffing(this, EditAction::insertText, nsIEditor::eNext);
nsCOMPtr<nsISelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_STATE(selection);
nsresult res;
if (!selection->Collapsed()) {
res = DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
NS_ENSURE_SUCCESS(res, res);
@ -565,13 +561,12 @@ nsPlaintextEditor::InsertBR(nsCOMPtr<nsIDOMNode>* outBRNode)
// position selection after br
selNode = GetNodeLocation(*outBRNode, &selOffset);
nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
selPriv->SetInterlinePosition(true);
selection->SetInterlinePosition(true);
return selection->Collapse(selNode, selOffset+1);
}
nsresult
nsPlaintextEditor::ExtendSelectionForDelete(nsISelection *aSelection,
nsPlaintextEditor::ExtendSelectionForDelete(Selection* aSelection,
nsIEditor::EDirection *aAction)
{
nsresult result = NS_OK;
@ -770,18 +765,19 @@ NS_IMETHODIMP nsPlaintextEditor::InsertLineBreak()
if (!cancel && !handled)
{
// get the (collapsed) selection location
nsCOMPtr<nsIDOMNode> selNode;
int32_t selOffset;
res = GetStartNodeAndOffset(selection, getter_AddRefs(selNode), &selOffset);
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_STATE(selection->GetRangeAt(0));
nsCOMPtr<nsINode> selNode = selection->GetRangeAt(0)->GetStartParent();
int32_t selOffset = selection->GetRangeAt(0)->StartOffset();
NS_ENSURE_STATE(selNode);
// don't put text in places that can't have it
if (!IsTextNode(selNode) && !CanContainTag(selNode, nsGkAtoms::textTagName)) {
if (!IsTextNode(selNode) && !CanContainTag(*selNode,
*nsGkAtoms::textTagName)) {
return NS_ERROR_FAILURE;
}
// we need to get the doc
nsCOMPtr<nsIDOMDocument> doc = GetDOMDocument();
nsCOMPtr<nsIDocument> doc = GetDocument();
NS_ENSURE_TRUE(doc, NS_ERROR_NOT_INITIALIZED);
// don't spaz my selection in subtransactions
@ -803,8 +799,8 @@ NS_IMETHODIMP nsPlaintextEditor::InsertLineBreak()
int32_t endOffset;
res = GetEndNodeAndOffset(selection, getter_AddRefs(endNode), &endOffset);
if (NS_SUCCEEDED(res) && endNode == selNode && endOffset == selOffset)
{
if (NS_SUCCEEDED(res) && endNode == GetAsDOMNode(selNode)
&& endOffset == selOffset) {
// SetInterlinePosition(true) means we want the caret to stick to the content on the "right".
// We want the caret to stick to whatever is past the break. This is
// because the break is on the same line we were on, but the next content
@ -857,9 +853,8 @@ nsPlaintextEditor::UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent)
nsCOMPtr<nsIPresShell> ps = GetPresShell();
NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED);
nsCOMPtr<nsISelection> selection;
nsresult rv = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_STATE(selection);
// NOTE: TextComposition should receive selection change notification before
// CompositionChangeEventHandlingMarker notifies TextComposition of the
@ -878,6 +873,7 @@ nsPlaintextEditor::UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent)
nsRefPtr<nsCaret> caretP = ps->GetCaret();
nsresult rv;
{
nsAutoPlaceHolderBatch batch(this, nsGkAtoms::IMETxnName);
@ -1159,9 +1155,10 @@ nsPlaintextEditor::Redo(uint32_t aCount)
bool
nsPlaintextEditor::CanCutOrCopy()
{
nsCOMPtr<nsISelection> selection;
if (NS_FAILED(GetSelection(getter_AddRefs(selection))))
nsRefPtr<Selection> selection = GetSelection();
if (!selection) {
return false;
}
if (IsPasswordEditor())
return false;
@ -1178,9 +1175,10 @@ nsPlaintextEditor::FireClipboardEvent(int32_t aType, int32_t aSelectionType)
nsCOMPtr<nsIPresShell> presShell = GetPresShell();
NS_ENSURE_TRUE(presShell, false);
nsCOMPtr<nsISelection> selection;
if (NS_FAILED(GetSelection(getter_AddRefs(selection))))
nsRefPtr<Selection> selection = GetSelection();
if (!selection) {
return false;
}
if (!nsCopySupport::FireClipboardEvent(aType, aSelectionType, presShell, selection))
return false;
@ -1251,13 +1249,10 @@ nsPlaintextEditor::GetAndInitDocEncoder(const nsAString& aFormatType,
// in which case we use our existing selection ...
if (aFlags & nsIDocumentEncoder::OutputSelectionOnly)
{
nsCOMPtr<nsISelection> selection;
rv = GetSelection(getter_AddRefs(selection));
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_STATE(selection);
rv = docEncoder->SetSelection(selection);
NS_ENSURE_SUCCESS(rv, rv);
if (selection) {
rv = docEncoder->SetSelection(selection);
NS_ENSURE_SUCCESS(rv, rv);
}
}
// ... or if the root element is not a body,
// in which case we set the selection to encompass the root.
@ -1458,9 +1453,7 @@ nsPlaintextEditor::SharedOutputString(uint32_t aFlags,
bool* aIsCollapsed,
nsAString& aResult)
{
nsCOMPtr<nsISelection> selection;
nsresult rv = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_NOT_INITIALIZED);
*aIsCollapsed = selection->Collapsed();
@ -1563,8 +1556,8 @@ nsPlaintextEditor::EndOperation()
}
NS_IMETHODIMP
nsPlaintextEditor::SelectEntireDocument(nsISelection *aSelection)
nsresult
nsPlaintextEditor::SelectEntireDocument(Selection* aSelection)
{
if (!aSelection || !mRules) { return NS_ERROR_NULL_POINTER; }

View File

@ -26,10 +26,15 @@ class nsIDOMNode;
class nsIDocumentEncoder;
class nsIEditRules;
class nsIOutputStream;
class nsISelection;
class nsISelectionController;
class nsITransferable;
namespace mozilla {
namespace dom {
class Selection;
}
}
/**
* The text editor implementation.
* Use to edit text document represented as a DOM tree.
@ -116,7 +121,7 @@ public:
NS_IMETHOD EndOperation();
/** make the given selection span the entire document */
NS_IMETHOD SelectEntireDocument(nsISelection *aSelection);
virtual nsresult SelectEntireDocument(mozilla::dom::Selection* aSelection);
virtual nsresult HandleKeyPressEvent(nsIDOMKeyEvent* aKeyEvent);
@ -149,7 +154,7 @@ public:
* If done, also update aAction to what's actually left to do after the
* extension.
*/
nsresult ExtendSelectionForDelete(nsISelection* aSelection,
nsresult ExtendSelectionForDelete(mozilla::dom::Selection* aSelection,
nsIEditor::EDirection *aAction);
// Return true if the data is safe to insert as the source and destination

View File

@ -15,8 +15,6 @@
#include "nsIContent.h" // for nsIContent
#include "nsIDOMCharacterData.h" // for nsIDOMCharacterData
#include "nsIDOMNode.h" // for nsIDOMNode
#include "nsIDOMRange.h" // for nsIDOMRange, etc
#include "nsISelection.h" // for nsISelection
#include "nsISupportsImpl.h" // for nsRange::Release
#include "nsRange.h" // for nsRange
#include "nsSelectionState.h"
@ -78,7 +76,7 @@ nsSelectionState::SaveSelection(Selection* aSel)
}
nsresult
nsSelectionState::RestoreSelection(nsISelection *aSel)
nsSelectionState::RestoreSelection(Selection* aSel)
{
NS_ENSURE_TRUE(aSel, NS_ERROR_NULL_POINTER);
nsresult res;
@ -150,7 +148,7 @@ nsSelectionState::IsEmpty()
}
/***************************************************************************
* nsRangeUpdater: class for updating nsIDOMRanges in response to editor actions.
* nsRangeUpdater: class for updating nsRanges in response to editor actions.
*/
nsRangeUpdater::nsRangeUpdater() : mArray(), mLock(false) {}
@ -320,21 +318,21 @@ nsRangeUpdater::SelAdjDeleteNode(nsIDOMNode *aNode)
nsresult
nsRangeUpdater::SelAdjSplitNode(nsINode* aOldRightNode, int32_t aOffset,
nsINode* aNewLeftNode)
nsRangeUpdater::SelAdjSplitNode(nsIContent& aOldRightNode, int32_t aOffset,
nsIContent* aNewLeftNode)
{
if (mLock) {
// lock set by Will/DidReplaceParent, etc...
return NS_OK;
}
NS_ENSURE_TRUE(aOldRightNode && aNewLeftNode, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(aNewLeftNode, NS_ERROR_NULL_POINTER);
uint32_t count = mArray.Length();
if (!count) {
return NS_OK;
}
nsCOMPtr<nsINode> parent = aOldRightNode->GetParentNode();
int32_t offset = parent ? parent->IndexOf(aOldRightNode) : -1;
nsCOMPtr<nsINode> parent = aOldRightNode.GetParentNode();
int32_t offset = parent ? parent->IndexOf(&aOldRightNode) : -1;
// first part is same as inserting aNewLeftnode
nsresult result = SelAdjInsertNode(parent, offset - 1);
@ -345,14 +343,14 @@ nsRangeUpdater::SelAdjSplitNode(nsINode* aOldRightNode, int32_t aOffset,
nsRangeStore* item = mArray[i];
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
if (item->startNode == aOldRightNode) {
if (item->startNode == &aOldRightNode) {
if (item->startOffset > aOffset) {
item->startOffset -= aOffset;
} else {
item->startNode = aNewLeftNode;
}
}
if (item->endNode == aOldRightNode) {
if (item->endNode == &aOldRightNode) {
if (item->endOffset > aOffset) {
item->endOffset -= aOffset;
} else {
@ -364,19 +362,9 @@ nsRangeUpdater::SelAdjSplitNode(nsINode* aOldRightNode, int32_t aOffset,
}
nsresult
nsRangeUpdater::SelAdjSplitNode(nsIDOMNode* aOldRightNode, int32_t aOffset,
nsIDOMNode* aNewLeftNode)
{
nsCOMPtr<nsINode> oldRightNode = do_QueryInterface(aOldRightNode);
nsCOMPtr<nsINode> newLeftNode = do_QueryInterface(aNewLeftNode);
return SelAdjSplitNode(oldRightNode, aOffset, newLeftNode);
}
nsresult
nsRangeUpdater::SelAdjJoinNodes(nsINode* aLeftNode,
nsINode* aRightNode,
nsINode* aParent,
nsRangeUpdater::SelAdjJoinNodes(nsINode& aLeftNode,
nsINode& aRightNode,
nsINode& aParent,
int32_t aOffset,
int32_t aOldLeftNodeLength)
{
@ -384,7 +372,6 @@ nsRangeUpdater::SelAdjJoinNodes(nsINode* aLeftNode,
// lock set by Will/DidReplaceParent, etc...
return NS_OK;
}
NS_ENSURE_TRUE(aLeftNode && aRightNode && aParent, NS_ERROR_NULL_POINTER);
uint32_t count = mArray.Length();
if (!count) {
return NS_OK;
@ -394,57 +381,44 @@ nsRangeUpdater::SelAdjJoinNodes(nsINode* aLeftNode,
nsRangeStore* item = mArray[i];
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
if (item->startNode == aParent) {
if (item->startNode == &aParent) {
// adjust start point in aParent
if (item->startOffset > aOffset) {
item->startOffset--;
} else if (item->startOffset == aOffset) {
// join keeps right hand node
item->startNode = aRightNode;
item->startNode = &aRightNode;
item->startOffset = aOldLeftNodeLength;
}
} else if (item->startNode == aRightNode) {
} else if (item->startNode == &aRightNode) {
// adjust start point in aRightNode
item->startOffset += aOldLeftNodeLength;
} else if (item->startNode == aLeftNode) {
} else if (item->startNode == &aLeftNode) {
// adjust start point in aLeftNode
item->startNode = aRightNode;
item->startNode = &aRightNode;
}
if (item->endNode == aParent) {
if (item->endNode == &aParent) {
// adjust end point in aParent
if (item->endOffset > aOffset) {
item->endOffset--;
} else if (item->endOffset == aOffset) {
// join keeps right hand node
item->endNode = aRightNode;
item->endNode = &aRightNode;
item->endOffset = aOldLeftNodeLength;
}
} else if (item->endNode == aRightNode) {
} else if (item->endNode == &aRightNode) {
// adjust end point in aRightNode
item->endOffset += aOldLeftNodeLength;
} else if (item->endNode == aLeftNode) {
} else if (item->endNode == &aLeftNode) {
// adjust end point in aLeftNode
item->endNode = aRightNode;
item->endNode = &aRightNode;
}
}
return NS_OK;
}
nsresult
nsRangeUpdater::SelAdjJoinNodes(nsIDOMNode* aLeftNode,
nsIDOMNode* aRightNode,
nsIDOMNode* aParent,
int32_t aOffset,
int32_t aOldLeftNodeLength)
{
nsCOMPtr<nsINode> leftNode = do_QueryInterface(aLeftNode);
nsCOMPtr<nsINode> rightNode = do_QueryInterface(aRightNode);
nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
return SelAdjJoinNodes(leftNode, rightNode, parent, aOffset, aOldLeftNodeLength);
}
void
nsRangeUpdater::SelAdjInsertText(Text& aTextNode, int32_t aOffset,

View File

@ -14,8 +14,6 @@
class nsCycleCollectionTraversalCallback;
class nsIDOMCharacterData;
class nsIDOMRange;
class nsISelection;
class nsRange;
namespace mozilla {
namespace dom {
@ -62,7 +60,7 @@ class nsSelectionState
void DoUnlink() { MakeEmpty(); }
void SaveSelection(mozilla::dom::Selection *aSel);
nsresult RestoreSelection(nsISelection *aSel);
nsresult RestoreSelection(mozilla::dom::Selection* aSel);
bool IsCollapsed();
bool IsEqual(nsSelectionState *aSelState);
void MakeEmpty();
@ -96,17 +94,11 @@ class nsRangeUpdater
nsresult SelAdjInsertNode(nsIDOMNode *aParent, int32_t aPosition);
void SelAdjDeleteNode(nsINode* aNode);
void SelAdjDeleteNode(nsIDOMNode *aNode);
nsresult SelAdjSplitNode(nsINode* aOldRightNode, int32_t aOffset,
nsINode* aNewLeftNode);
nsresult SelAdjSplitNode(nsIDOMNode *aOldRightNode, int32_t aOffset, nsIDOMNode *aNewLeftNode);
nsresult SelAdjJoinNodes(nsINode* aLeftNode,
nsINode* aRightNode,
nsINode* aParent,
int32_t aOffset,
int32_t aOldLeftNodeLength);
nsresult SelAdjJoinNodes(nsIDOMNode *aLeftNode,
nsIDOMNode *aRightNode,
nsIDOMNode *aParent,
nsresult SelAdjSplitNode(nsIContent& aOldRightNode, int32_t aOffset,
nsIContent* aNewLeftNode);
nsresult SelAdjJoinNodes(nsINode& aLeftNode,
nsINode& aRightNode,
nsINode& aParent,
int32_t aOffset,
int32_t aOldLeftNodeLength);
void SelAdjInsertText(mozilla::dom::Text& aTextNode, int32_t aOffset,

View File

@ -22,7 +22,6 @@
#include "nsIContent.h"
#include "nsIDOMElement.h"
#include "nsIDOMNode.h"
#include "nsIDOMRange.h"
#include "nsIEditor.h"
#include "nsIFrame.h"
#include "nsIHTMLEditor.h"
@ -33,6 +32,7 @@
#include "nsITableEditor.h"
#include "nsLiteralString.h"
#include "nsQueryFrame.h"
#include "nsRange.h"
#include "nsString.h"
#include "nsTArray.h"
#include "nsTableCellFrame.h"
@ -79,12 +79,11 @@ class MOZ_STACK_CLASS nsSetSelectionAfterTableEdit
class MOZ_STACK_CLASS nsSelectionBatcherForTable
{
private:
nsCOMPtr<nsISelectionPrivate> mSelection;
nsRefPtr<mozilla::dom::Selection> mSelection;
public:
explicit nsSelectionBatcherForTable(nsISelection *aSelection)
explicit nsSelectionBatcherForTable(Selection* aSelection)
{
nsCOMPtr<nsISelection> sel(aSelection);
mSelection = do_QueryInterface(sel);
mSelection = aSelection;
if (mSelection) mSelection->StartBatchChanges();
}
virtual ~nsSelectionBatcherForTable()
@ -394,7 +393,7 @@ nsHTMLEditor::GetLastCellInRow(nsIDOMNode* aRowNode, nsIDOMNode** aCellNode)
NS_IMETHODIMP
nsHTMLEditor::InsertTableColumn(int32_t aNumber, bool aAfter)
{
nsCOMPtr<nsISelection> selection;
nsRefPtr<Selection> selection;
nsCOMPtr<nsIDOMElement> table;
nsCOMPtr<nsIDOMElement> curCell;
int32_t startRowIndex, startColIndex;
@ -521,7 +520,7 @@ nsHTMLEditor::InsertTableColumn(int32_t aNumber, bool aAfter)
NS_IMETHODIMP
nsHTMLEditor::InsertTableRow(int32_t aNumber, bool aAfter)
{
nsCOMPtr<nsISelection> selection;
nsRefPtr<Selection> selection;
nsCOMPtr<nsIDOMElement> table;
nsCOMPtr<nsIDOMElement> curCell;
@ -702,8 +701,8 @@ nsHTMLEditor::InsertTableRow(int32_t aNumber, bool aAfter)
// Editor helper only
// XXX Code changed for bug 217717 and now we don't need aSelection param
// TODO: Remove aSelection param
NS_IMETHODIMP
nsHTMLEditor::DeleteTable2(nsIDOMElement *aTable, nsISelection *aSelection)
nsresult
nsHTMLEditor::DeleteTable2(nsIDOMElement* aTable, Selection* aSelection)
{
NS_ENSURE_TRUE(aTable, NS_ERROR_NULL_POINTER);
@ -719,7 +718,7 @@ nsHTMLEditor::DeleteTable2(nsIDOMElement *aTable, nsISelection *aSelection)
NS_IMETHODIMP
nsHTMLEditor::DeleteTable()
{
nsCOMPtr<nsISelection> selection;
nsRefPtr<Selection> selection;
nsCOMPtr<nsIDOMElement> table;
nsresult res = GetCellContext(getter_AddRefs(selection),
getter_AddRefs(table),
@ -734,7 +733,7 @@ nsHTMLEditor::DeleteTable()
NS_IMETHODIMP
nsHTMLEditor::DeleteTableCell(int32_t aNumber)
{
nsCOMPtr<nsISelection> selection;
nsRefPtr<Selection> selection;
nsCOMPtr<nsIDOMElement> table;
nsCOMPtr<nsIDOMElement> cell;
int32_t startRowIndex, startColIndex;
@ -928,7 +927,7 @@ nsHTMLEditor::DeleteTableCell(int32_t aNumber)
NS_IMETHODIMP
nsHTMLEditor::DeleteTableCellContents()
{
nsCOMPtr<nsISelection> selection;
nsRefPtr<Selection> selection;
nsCOMPtr<nsIDOMElement> table;
nsCOMPtr<nsIDOMElement> cell;
int32_t startRowIndex, startColIndex;
@ -1005,7 +1004,7 @@ nsHTMLEditor::DeleteCellContents(nsIDOMElement *aCell)
NS_IMETHODIMP
nsHTMLEditor::DeleteTableColumn(int32_t aNumber)
{
nsCOMPtr<nsISelection> selection;
nsRefPtr<Selection> selection;
nsCOMPtr<nsIDOMElement> table;
nsCOMPtr<nsIDOMElement> cell;
int32_t startRowIndex, startColIndex, rowCount, colCount;
@ -1148,9 +1147,7 @@ nsHTMLEditor::DeleteColumn(nsIDOMElement *aTable, int32_t aColIndex)
if (rowCount == 1)
{
nsCOMPtr<nsISelection> selection;
res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
return DeleteTable2(aTable, selection);
}
@ -1183,7 +1180,7 @@ nsHTMLEditor::DeleteColumn(nsIDOMElement *aTable, int32_t aColIndex)
NS_IMETHODIMP
nsHTMLEditor::DeleteTableRow(int32_t aNumber)
{
nsCOMPtr<nsISelection> selection;
nsRefPtr<Selection> selection;
nsCOMPtr<nsIDOMElement> table;
nsCOMPtr<nsIDOMElement> cell;
int32_t startRowIndex, startColIndex;
@ -1421,14 +1418,13 @@ nsHTMLEditor::SelectBlockOfCells(nsIDOMElement *aStartCell, nsIDOMElement *aEndC
{
NS_ENSURE_TRUE(aStartCell && aEndCell, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsISelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
NS_NAMED_LITERAL_STRING(tableStr, "table");
nsCOMPtr<nsIDOMElement> table;
res = GetElementOrParentByTagName(tableStr, aStartCell, getter_AddRefs(table));
nsresult res = GetElementOrParentByTagName(tableStr, aStartCell,
getter_AddRefs(table));
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_TRUE(table, NS_ERROR_FAILURE);
@ -1528,9 +1524,7 @@ nsHTMLEditor::SelectAllTableCells()
res = GetTableSize(table, &rowCount, &colCount);
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<nsISelection> selection;
res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
// Suppress nsISelectionListener notification
@ -1583,7 +1577,7 @@ nsHTMLEditor::SelectTableRow()
nsCOMPtr<nsIDOMElement> startCell = cell;
// Get table and location of cell:
nsCOMPtr<nsISelection> selection;
nsRefPtr<Selection> selection;
nsCOMPtr<nsIDOMElement> table;
int32_t startRowIndex, startColIndex;
@ -1650,7 +1644,7 @@ nsHTMLEditor::SelectTableColumn()
nsCOMPtr<nsIDOMElement> startCell = cell;
// Get location of cell:
nsCOMPtr<nsISelection> selection;
nsRefPtr<Selection> selection;
nsCOMPtr<nsIDOMElement> table;
int32_t startRowIndex, startColIndex;
@ -2213,21 +2207,18 @@ nsHTMLEditor::JoinTableCells(bool aMergeNonContiguousContents)
}
}
// Cleanup selection: remove ranges where cells were deleted
nsCOMPtr<nsISelection> selection;
res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
int32_t rangeCount;
res = selection->GetRangeCount(&rangeCount);
NS_ENSURE_SUCCESS(res, res);
nsCOMPtr<nsIDOMRange> range;
nsRefPtr<nsRange> range;
int32_t i;
for (i = 0; i < rangeCount; i++)
{
res = selection->GetRangeAt(i, getter_AddRefs(range));
NS_ENSURE_SUCCESS(res, res);
range = selection->GetRangeAt(i);
NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMElement> deletedCell;
@ -2777,8 +2768,8 @@ nsHTMLEditor::GetCellSpansAt(nsIDOMElement* aTable, int32_t aRowIndex, int32_t a
return NS_OK;
}
NS_IMETHODIMP
nsHTMLEditor::GetCellContext(nsISelection **aSelection,
nsresult
nsHTMLEditor::GetCellContext(Selection** aSelection,
nsIDOMElement **aTable,
nsIDOMElement **aCell,
nsIDOMNode **aCellParent, int32_t *aCellOffset,
@ -2793,9 +2784,7 @@ nsHTMLEditor::GetCellContext(nsISelection **aSelection,
if (aRowIndex) *aRowIndex = 0;
if (aColIndex) *aColIndex = 0;
nsCOMPtr <nsISelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
if (aSelection)
@ -2813,6 +2802,7 @@ nsHTMLEditor::GetCellContext(nsISelection **aSelection,
// ...but if not supplied,
// get cell if it's the child of selection anchor node,
// or get the enclosing by a cell
nsresult res;
if (!cell)
{
// Find a selected or enclosing table element
@ -2886,7 +2876,7 @@ nsHTMLEditor::GetCellContext(nsISelection **aSelection,
}
nsresult
nsHTMLEditor::GetCellFromRange(nsIDOMRange *aRange, nsIDOMElement **aCell)
nsHTMLEditor::GetCellFromRange(nsRange* aRange, nsIDOMElement** aCell)
{
// Note: this might return a node that is outside of the range.
// Use carefully.
@ -2942,19 +2932,15 @@ nsHTMLEditor::GetFirstSelectedCell(nsIDOMRange **aRange, nsIDOMElement **aCell)
*aCell = nullptr;
if (aRange) *aRange = nullptr;
nsCOMPtr<nsISelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
nsCOMPtr<nsIDOMRange> range;
res = selection->GetRangeAt(0, getter_AddRefs(range));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<nsRange> range = selection->GetRangeAt(0);
NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
mSelectedCellIndex = 0;
res = GetCellFromRange(range, aCell);
nsresult res = GetCellFromRange(range, aCell);
// Failure here probably means selection is in a text node,
// so there's no selected cell
if (NS_FAILED(res)) {
@ -2984,25 +2970,21 @@ nsHTMLEditor::GetNextSelectedCell(nsIDOMRange **aRange, nsIDOMElement **aCell)
*aCell = nullptr;
if (aRange) *aRange = nullptr;
nsCOMPtr<nsISelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
int32_t rangeCount;
res = selection->GetRangeCount(&rangeCount);
NS_ENSURE_SUCCESS(res, res);
int32_t rangeCount = selection->GetRangeCount();
// Don't even try if index exceeds range count
if (mSelectedCellIndex >= rangeCount)
return NS_EDITOR_ELEMENT_NOT_FOUND;
// Scan through ranges to find next valid selected cell
nsCOMPtr<nsIDOMRange> range;
nsRefPtr<nsRange> range;
nsresult res;
for (; mSelectedCellIndex < rangeCount; mSelectedCellIndex++)
{
res = selection->GetRangeAt(mSelectedCellIndex, getter_AddRefs(range));
NS_ENSURE_SUCCESS(res, res);
range = selection->GetRangeAt(mSelectedCellIndex);
NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
res = GetCellFromRange(range, aCell);
@ -3165,14 +3147,13 @@ nsHTMLEditor::GetSelectedOrParentTableElement(nsAString& aTagName,
aTagName.Truncate();
*aSelectedCount = 0;
nsCOMPtr<nsISelection> selection;
nsresult res = GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = GetSelection();
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
// Try to get the first selected cell
nsCOMPtr<nsIDOMElement> tableOrCellElement;
res = GetFirstSelectedCell(nullptr, getter_AddRefs(tableOrCellElement));
nsresult res = GetFirstSelectedCell(nullptr,
getter_AddRefs(tableOrCellElement));
NS_ENSURE_SUCCESS(res, res);
NS_NAMED_LITERAL_STRING(tdName, "td");

View File

@ -33,8 +33,6 @@
#include "nsNameSpaceManager.h"
#include "nsINode.h"
#include "nsIPlaintextEditor.h"
#include "nsISelection.h"
#include "nsISelectionPrivate.h"
#include "nsISupportsBase.h"
#include "nsLiteralString.h"
#include "mozilla/dom/NodeIterator.h"
@ -117,8 +115,7 @@ nsTextEditRules::Init(nsPlaintextEditor *aEditor)
InitFields();
mEditor = aEditor; // we hold a non-refcounted reference back to our editor
nsCOMPtr<nsISelection> selection;
mEditor->GetSelection(getter_AddRefs(selection));
nsRefPtr<Selection> selection = mEditor->GetSelection();
NS_WARN_IF_FALSE(selection, "editor cannot get selection");
// Put in a magic br if needed. This method handles null selection,
@ -184,10 +181,9 @@ nsTextEditRules::BeforeEdit(EditAction action,
mActionNesting++;
// get the selection and cache the position before editing
nsCOMPtr<nsISelection> selection;
NS_ENSURE_STATE(mEditor);
nsresult res = mEditor->GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = mEditor->GetSelection();
NS_ENSURE_STATE(selection);
selection->GetAnchorNode(getter_AddRefs(mCachedSelectionNode));
selection->GetAnchorOffset(&mCachedSelectionOffset);
@ -208,10 +204,9 @@ nsTextEditRules::AfterEdit(EditAction action,
nsresult res = NS_OK;
if (!--mActionNesting)
{
nsCOMPtr<nsISelection>selection;
NS_ENSURE_STATE(mEditor);
res = mEditor->GetSelection(getter_AddRefs(selection));
NS_ENSURE_SUCCESS(res, res);
nsRefPtr<Selection> selection = mEditor->GetSelection();
NS_ENSURE_STATE(selection);
NS_ENSURE_STATE(mEditor);
res = mEditor->HandleInlineSpellCheck(action, selection,
@ -285,7 +280,7 @@ nsTextEditRules::WillDoAction(Selection* aSelection,
}
NS_IMETHODIMP
nsTextEditRules::DidDoAction(nsISelection *aSelection,
nsTextEditRules::DidDoAction(Selection* aSelection,
nsRulesInfo *aInfo, nsresult aResult)
{
NS_ENSURE_STATE(mEditor);
@ -339,7 +334,7 @@ nsTextEditRules::DocumentIsEmpty(bool *aDocumentIsEmpty)
nsresult
nsTextEditRules::WillInsert(nsISelection *aSelection, bool *aCancel)
nsTextEditRules::WillInsert(Selection* aSelection, bool* aCancel)
{
NS_ENSURE_TRUE(aSelection && aCancel, NS_ERROR_NULL_POINTER);
@ -360,7 +355,7 @@ nsTextEditRules::WillInsert(nsISelection *aSelection, bool *aCancel)
}
nsresult
nsTextEditRules::DidInsert(nsISelection *aSelection, nsresult aResult)
nsTextEditRules::DidInsert(Selection* aSelection, nsresult aResult)
{
return NS_OK;
}
@ -416,13 +411,13 @@ nsTextEditRules::WillInsertBreak(Selection* aSelection,
}
nsresult
nsTextEditRules::DidInsertBreak(nsISelection *aSelection, nsresult aResult)
nsTextEditRules::DidInsertBreak(Selection* aSelection, nsresult aResult)
{
return NS_OK;
}
nsresult
nsTextEditRules::CollapseSelectionToTrailingBRIfNeeded(nsISelection* aSelection)
nsTextEditRules::CollapseSelectionToTrailingBRIfNeeded(Selection* aSelection)
{
// we only need to execute the stuff below if we are a plaintext editor.
// html editors have a different mechanism for putting in mozBR's
@ -470,7 +465,7 @@ nsTextEditRules::CollapseSelectionToTrailingBRIfNeeded(nsISelection* aSelection)
}
static inline already_AddRefed<nsIDOMNode>
GetTextNode(nsISelection *selection, nsEditor *editor) {
GetTextNode(Selection* selection, nsEditor* editor) {
int32_t selOffset;
nsCOMPtr<nsIDOMNode> selNode;
nsresult res = editor->GetStartNodeAndOffset(selection, getter_AddRefs(selNode), &selOffset);
@ -700,22 +695,21 @@ nsTextEditRules::WillInsertText(EditAction aAction,
}
// get the (collapsed) selection location
nsCOMPtr<nsIDOMNode> selNode;
int32_t selOffset;
NS_ENSURE_STATE(mEditor);
res = mEditor->GetStartNodeAndOffset(aSelection, getter_AddRefs(selNode), &selOffset);
NS_ENSURE_SUCCESS(res, res);
NS_ENSURE_STATE(aSelection->GetRangeAt(0));
nsCOMPtr<nsINode> selNode = aSelection->GetRangeAt(0)->GetStartParent();
int32_t selOffset = aSelection->GetRangeAt(0)->StartOffset();
NS_ENSURE_STATE(selNode);
// don't put text in places that can't have it
NS_ENSURE_STATE(mEditor);
if (!mEditor->IsTextNode(selNode) &&
!mEditor->CanContainTag(selNode, nsGkAtoms::textTagName)) {
!mEditor->CanContainTag(*selNode, *nsGkAtoms::textTagName)) {
return NS_ERROR_FAILURE;
}
// we need to get the doc
NS_ENSURE_STATE(mEditor);
nsCOMPtr<nsIDOMDocument> doc = mEditor->GetDOMDocument();
nsCOMPtr<nsIDocument> doc = mEditor->GetDocument();
NS_ENSURE_TRUE(doc, NS_ERROR_NOT_INITIALIZED);
if (aAction == EditAction::insertIMEText) {
@ -724,7 +718,7 @@ nsTextEditRules::WillInsertText(EditAction aAction,
NS_ENSURE_SUCCESS(res, res);
} else {
// aAction == EditAction::insertText; find where we are
nsCOMPtr<nsIDOMNode> curNode = selNode;
nsCOMPtr<nsINode> curNode = selNode;
int32_t curOffset = selOffset;
// don't spaz my selection in subtransactions
@ -751,8 +745,7 @@ nsTextEditRules::WillInsertText(EditAction aAction,
}
nsresult
nsTextEditRules::DidInsertText(nsISelection *aSelection,
nsresult aResult)
nsTextEditRules::DidInsertText(Selection* aSelection, nsresult aResult)
{
return DidInsert(aSelection, aResult);
}
@ -760,7 +753,8 @@ nsTextEditRules::DidInsertText(nsISelection *aSelection,
nsresult
nsTextEditRules::WillSetTextProperty(nsISelection *aSelection, bool *aCancel, bool *aHandled)
nsTextEditRules::WillSetTextProperty(Selection* aSelection, bool* aCancel,
bool* aHandled)
{
if (!aSelection || !aCancel || !aHandled)
{ return NS_ERROR_NULL_POINTER; }
@ -773,13 +767,14 @@ nsTextEditRules::WillSetTextProperty(nsISelection *aSelection, bool *aCancel, bo
}
nsresult
nsTextEditRules::DidSetTextProperty(nsISelection *aSelection, nsresult aResult)
nsTextEditRules::DidSetTextProperty(Selection* aSelection, nsresult aResult)
{
return NS_OK;
}
nsresult
nsTextEditRules::WillRemoveTextProperty(nsISelection *aSelection, bool *aCancel, bool *aHandled)
nsTextEditRules::WillRemoveTextProperty(Selection* aSelection, bool* aCancel,
bool* aHandled)
{
if (!aSelection || !aCancel || !aHandled)
{ return NS_ERROR_NULL_POINTER; }
@ -792,7 +787,7 @@ nsTextEditRules::WillRemoveTextProperty(nsISelection *aSelection, bool *aCancel,
}
nsresult
nsTextEditRules::DidRemoveTextProperty(nsISelection *aSelection, nsresult aResult)
nsTextEditRules::DidRemoveTextProperty(Selection* aSelection, nsresult aResult)
{
return NS_OK;
}
@ -890,7 +885,7 @@ nsTextEditRules::WillDeleteSelection(Selection* aSelection,
}
nsresult
nsTextEditRules::DidDeleteSelection(nsISelection *aSelection,
nsTextEditRules::DidDeleteSelection(Selection* aSelection,
nsIEditor::EDirection aCollapsedAction,
nsresult aResult)
{
@ -920,14 +915,13 @@ nsTextEditRules::DidDeleteSelection(nsISelection *aSelection,
{
// We prevent the caret from sticking on the left of prior BR
// (i.e. the end of previous line) after this deletion. Bug 92124
nsCOMPtr<nsISelectionPrivate> selPriv = do_QueryInterface(aSelection);
if (selPriv) res = selPriv->SetInterlinePosition(true);
res = aSelection->SetInterlinePosition(true);
}
return res;
}
nsresult
nsTextEditRules::WillUndo(nsISelection *aSelection, bool *aCancel, bool *aHandled)
nsTextEditRules::WillUndo(Selection* aSelection, bool* aCancel, bool* aHandled)
{
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
@ -943,7 +937,7 @@ nsTextEditRules::WillUndo(nsISelection *aSelection, bool *aCancel, bool *aHandle
* Since undo and redo are relatively rare, it makes sense to take the (small) performance hit here.
*/
nsresult
nsTextEditRules::DidUndo(nsISelection *aSelection, nsresult aResult)
nsTextEditRules::DidUndo(Selection* aSelection, nsresult aResult)
{
NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
// If aResult is an error, we return it.
@ -962,7 +956,7 @@ nsTextEditRules::DidUndo(nsISelection *aSelection, nsresult aResult)
}
nsresult
nsTextEditRules::WillRedo(nsISelection *aSelection, bool *aCancel, bool *aHandled)
nsTextEditRules::WillRedo(Selection* aSelection, bool* aCancel, bool* aHandled)
{
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
CANCEL_OPERATION_IF_READONLY_OR_DISABLED
@ -973,7 +967,7 @@ nsTextEditRules::WillRedo(nsISelection *aSelection, bool *aCancel, bool *aHandle
}
nsresult
nsTextEditRules::DidRedo(nsISelection *aSelection, nsresult aResult)
nsTextEditRules::DidRedo(Selection* aSelection, nsresult aResult)
{
nsresult res = aResult; // if aResult is an error, we return it.
if (!aSelection) { return NS_ERROR_NULL_POINTER; }
@ -1013,7 +1007,7 @@ nsTextEditRules::DidRedo(nsISelection *aSelection, nsresult aResult)
}
nsresult
nsTextEditRules::WillOutputText(nsISelection *aSelection,
nsTextEditRules::WillOutputText(Selection* aSelection,
const nsAString *aOutputFormat,
nsAString *aOutString,
bool *aCancel,
@ -1046,7 +1040,7 @@ nsTextEditRules::WillOutputText(nsISelection *aSelection,
}
nsresult
nsTextEditRules::DidOutputText(nsISelection *aSelection, nsresult aResult)
nsTextEditRules::DidOutputText(Selection* aSelection, nsresult aResult)
{
return NS_OK;
}
@ -1132,7 +1126,7 @@ nsTextEditRules::CreateTrailingBRIfNeeded()
}
nsresult
nsTextEditRules::CreateBogusNodeIfNeeded(nsISelection *aSelection)
nsTextEditRules::CreateBogusNodeIfNeeded(Selection* aSelection)
{
NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
NS_ENSURE_TRUE(mEditor, NS_ERROR_NULL_POINTER);

View File

@ -19,7 +19,6 @@
class nsIDOMElement;
class nsIDOMNode;
class nsISelection;
namespace mozilla {
namespace dom {
class Selection;
@ -56,7 +55,8 @@ public:
nsIEditor::EDirection aDirection);
NS_IMETHOD WillDoAction(mozilla::dom::Selection* aSelection,
nsRulesInfo* aInfo, bool* aCancel, bool* aHandled);
NS_IMETHOD DidDoAction(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
NS_IMETHOD DidDoAction(mozilla::dom::Selection* aSelection,
nsRulesInfo* aInfo, nsresult aResult);
NS_IMETHOD DocumentIsEmpty(bool *aDocumentIsEmpty);
NS_IMETHOD DocumentModified();
@ -114,35 +114,43 @@ protected:
const nsAString *inString,
nsAString *outString,
int32_t aMaxLength);
nsresult DidInsertText(nsISelection *aSelection, nsresult aResult);
nsresult DidInsertText(mozilla::dom::Selection* aSelection,
nsresult aResult);
nsresult GetTopEnclosingPre(nsIDOMNode *aNode, nsIDOMNode** aOutPreNode);
nsresult WillInsertBreak(mozilla::dom::Selection* aSelection, bool* aCancel,
bool *aHandled, int32_t aMaxLength);
nsresult DidInsertBreak(nsISelection *aSelection, nsresult aResult);
nsresult DidInsertBreak(mozilla::dom::Selection* aSelection,
nsresult aResult);
nsresult WillInsert(nsISelection *aSelection, bool *aCancel);
nsresult DidInsert(nsISelection *aSelection, nsresult aResult);
nsresult WillInsert(mozilla::dom::Selection* aSelection, bool* aCancel);
nsresult DidInsert(mozilla::dom::Selection* aSelection, nsresult aResult);
nsresult WillDeleteSelection(mozilla::dom::Selection* aSelection,
nsIEditor::EDirection aCollapsedAction,
bool *aCancel,
bool *aHandled);
nsresult DidDeleteSelection(nsISelection *aSelection,
nsresult DidDeleteSelection(mozilla::dom::Selection* aSelection,
nsIEditor::EDirection aCollapsedAction,
nsresult aResult);
nsresult WillSetTextProperty(nsISelection *aSelection, bool *aCancel, bool *aHandled);
nsresult DidSetTextProperty(nsISelection *aSelection, nsresult aResult);
nsresult WillSetTextProperty(mozilla::dom::Selection* aSelection,
bool* aCancel, bool* aHandled);
nsresult DidSetTextProperty(mozilla::dom::Selection* aSelection,
nsresult aResult);
nsresult WillRemoveTextProperty(nsISelection *aSelection, bool *aCancel, bool *aHandled);
nsresult DidRemoveTextProperty(nsISelection *aSelection, nsresult aResult);
nsresult WillRemoveTextProperty(mozilla::dom::Selection* aSelection,
bool* aCancel, bool* aHandled);
nsresult DidRemoveTextProperty(mozilla::dom::Selection* aSelection,
nsresult aResult);
nsresult WillUndo(nsISelection *aSelection, bool *aCancel, bool *aHandled);
nsresult DidUndo(nsISelection *aSelection, nsresult aResult);
nsresult WillUndo(mozilla::dom::Selection* aSelection, bool* aCancel,
bool* aHandled);
nsresult DidUndo(mozilla::dom::Selection* aSelection, nsresult aResult);
nsresult WillRedo(nsISelection *aSelection, bool *aCancel, bool *aHandled);
nsresult DidRedo(nsISelection *aSelection, nsresult aResult);
nsresult WillRedo(mozilla::dom::Selection* aSelection, bool* aCancel,
bool* aHandled);
nsresult DidRedo(mozilla::dom::Selection* aSelection, nsresult aResult);
/** called prior to nsIEditor::OutputToString
* @param aSelection
@ -151,13 +159,13 @@ protected:
* @param aOutCancel if set to true, the caller should cancel the operation
* and use aOutText as the result.
*/
nsresult WillOutputText(nsISelection *aSelection,
nsresult WillOutputText(mozilla::dom::Selection* aSelection,
const nsAString *aInFormat,
nsAString *aOutText,
bool *aOutCancel,
bool *aHandled);
nsresult DidOutputText(nsISelection *aSelection, nsresult aResult);
nsresult DidOutputText(mozilla::dom::Selection* aSelection, nsresult aResult);
// helper functions
@ -169,7 +177,7 @@ protected:
nsresult CreateTrailingBRIfNeeded();
/** creates a bogus text node if the document has no editable content */
nsresult CreateBogusNodeIfNeeded(nsISelection *aSelection);
nsresult CreateBogusNodeIfNeeded(mozilla::dom::Selection* aSelection);
/** returns a truncated insertion string if insertion would place us
over aMaxLength */
@ -185,7 +193,7 @@ protected:
nsresult CreateMozBR(nsIDOMNode* inParent, int32_t inOffset,
nsIDOMNode** outBRNode = nullptr);
nsresult CheckBidiLevelForDeletion(nsISelection *aSelection,
nsresult CheckBidiLevelForDeletion(mozilla::dom::Selection* aSelection,
nsIDOMNode *aSelNode,
int32_t aSelOffset,
nsIEditor::EDirection aAction,
@ -193,7 +201,7 @@ protected:
nsresult HideLastPWInput();
nsresult CollapseSelectionToTrailingBRIfNeeded(nsISelection *aSelection);
nsresult CollapseSelectionToTrailingBRIfNeeded(mozilla::dom::Selection* aSelection);
bool IsPasswordEditor() const
{

View File

@ -13,7 +13,6 @@
#include "nsIEditor.h"
#include "nsIPresShell.h"
#include "mozilla/dom/Selection.h"
#include "nsISelectionPrivate.h"
#include "nsISupportsImpl.h"
#include "nsPlaintextEditor.h"
#include "nsPresContext.h"
@ -25,7 +24,7 @@ using namespace mozilla::dom;
// Test for distance between caret and text that will be deleted
nsresult
nsTextEditRules::CheckBidiLevelForDeletion(nsISelection *aSelection,
nsTextEditRules::CheckBidiLevelForDeletion(Selection* aSelection,
nsIDOMNode *aSelNode,
int32_t aSelOffset,
nsIEditor::EDirection aAction,

View File

@ -382,11 +382,8 @@ nsWSRunObject::InsertText(const nsAString& aStringToInsert,
}
// Ready, aim, fire!
nsCOMPtr<nsIDOMNode> parent(GetAsDOMNode(*aInOutParent));
nsCOMPtr<nsIDOMDocument> doc(do_QueryInterface(aDoc));
res = mHTMLEditor->InsertTextImpl(theString, address_of(parent),
aInOutOffset, doc);
*aInOutParent = do_QueryInterface(parent);
res = mHTMLEditor->InsertTextImpl(theString, aInOutParent, aInOutOffset,
aDoc);
return NS_OK;
}

View File

@ -13,7 +13,6 @@
#include "nsIContent.h"
#include "nsIContentIterator.h"
#include "nsIDOMNode.h"
#include "nsIDOMRange.h"
#include "nsINode.h"
#include "nsISupportsBase.h"
#include "nsISupportsUtils.h"
@ -86,14 +85,11 @@ nsFilteredContentIterator::Init(nsIDOMRange* aRange)
mDirection = eForward;
mCurrentIterator = mPreIterator;
nsCOMPtr<nsIDOMRange> domRange;
nsresult rv = aRange->CloneRange(getter_AddRefs(domRange));
NS_ENSURE_SUCCESS(rv, rv);
mRange = do_QueryInterface(domRange);
mRange = static_cast<nsRange*>(aRange)->CloneRange();
rv = mPreIterator->Init(domRange);
nsresult rv = mPreIterator->Init(mRange);
NS_ENSURE_SUCCESS(rv, rv);
return mIterator->Init(domRange);
return mIterator->Init(mRange);
}
//------------------------------------------------------------
@ -237,7 +233,7 @@ ContentIsInTraversalRange(nsIContent *aContent, bool aIsPreMode,
}
static bool
ContentIsInTraversalRange(nsIDOMRange *aRange, nsIDOMNode* aNextNode, bool aIsPreMode)
ContentIsInTraversalRange(nsRange* aRange, nsIDOMNode* aNextNode, bool aIsPreMode)
{
nsCOMPtr<nsIContent> content(do_QueryInterface(aNextNode));
NS_ENSURE_TRUE(content && aRange, false);

View File

@ -17,6 +17,7 @@ class nsIDOMNode;
class nsIDOMRange;
class nsINode;
class nsITextServicesFilter;
class nsRange;
class nsFilteredContentIterator MOZ_FINAL : public nsIContentIterator
{
@ -65,7 +66,7 @@ protected:
nsCOMPtr<nsIAtom> mMapAtom;
nsCOMPtr<nsITextServicesFilter> mFilter;
nsCOMPtr<nsIDOMRange> mRange;
nsRefPtr<nsRange> mRange;
bool mDidSkip;
bool mIsOutOfRange;
eDirectionType mDirection;

View File

@ -6,6 +6,7 @@
#include <stddef.h> // for nullptr
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
#include "mozilla/dom/Selection.h"
#include "mozilla/mozalloc.h" // for operator new, etc
#include "nsAString.h" // for nsAString_internal::Length, etc
#include "nsAutoPtr.h" // for nsRefPtr
@ -42,6 +43,7 @@
#define UNLOCK_DOC(doc)
using namespace mozilla;
using namespace mozilla::dom;
class OffsetEntry
{
@ -234,17 +236,11 @@ nsTextServicesDocument::SetExtent(nsIDOMRange* aDOMRange)
// We need to store a copy of aDOMRange since we don't
// know where it came from.
nsresult result = aDOMRange->CloneRange(getter_AddRefs(mExtent));
if (NS_FAILED(result))
{
UNLOCK_DOC(this);
return result;
}
mExtent = static_cast<nsRange*>(aDOMRange)->CloneRange();
// Create a new iterator based on our new extent range.
result = CreateContentIterator(mExtent, getter_AddRefs(mIterator));
nsresult result = CreateContentIterator(mExtent, getter_AddRefs(mIterator));
if (NS_FAILED(result))
{
@ -268,14 +264,14 @@ NS_IMETHODIMP
nsTextServicesDocument::ExpandRangeToWordBoundaries(nsIDOMRange *aRange)
{
NS_ENSURE_ARG_POINTER(aRange);
nsRefPtr<nsRange> range = static_cast<nsRange*>(aRange);
// Get the end points of the range.
nsCOMPtr<nsIDOMNode> rngStartNode, rngEndNode;
int32_t rngStartOffset, rngEndOffset;
nsresult result = GetRangeEndPoints(aRange,
getter_AddRefs(rngStartNode),
nsresult result = GetRangeEndPoints(range, getter_AddRefs(rngStartNode),
&rngStartOffset,
getter_AddRefs(rngEndNode),
&rngEndOffset);
@ -285,7 +281,7 @@ nsTextServicesDocument::ExpandRangeToWordBoundaries(nsIDOMRange *aRange)
// Create a content iterator based on the range.
nsCOMPtr<nsIContentIterator> iter;
result = CreateContentIterator(aRange, getter_AddRefs(iter));
result = CreateContentIterator(range, getter_AddRefs(iter));
NS_ENSURE_SUCCESS(result, result);
@ -425,10 +421,10 @@ nsTextServicesDocument::ExpandRangeToWordBoundaries(nsIDOMRange *aRange)
// Now adjust the range so that it uses our new
// end points.
result = aRange->SetEnd(rngEndNode, rngEndOffset);
result = range->SetEnd(rngEndNode, rngEndOffset);
NS_ENSURE_SUCCESS(result, result);
return aRange->SetStart(rngStartNode, rngStartOffset);
return range->SetStart(rngStartNode, rngStartOffset);
}
NS_IMETHODIMP
@ -519,27 +515,21 @@ nsTextServicesDocument::LastSelectedBlock(TSDBlockSelectionStatus *aSelStatus,
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsISelection> selection;
bool isCollapsed = false;
result = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
nsCOMPtr<nsISelection> domSelection;
result = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
getter_AddRefs(domSelection));
if (NS_FAILED(result))
{
UNLOCK_DOC(this);
return result;
}
result = selection->GetIsCollapsed(&isCollapsed);
nsRefPtr<Selection> selection = static_cast<Selection*>(domSelection.get());
if (NS_FAILED(result))
{
UNLOCK_DOC(this);
return result;
}
bool isCollapsed = selection->IsCollapsed();
nsCOMPtr<nsIContentIterator> iter;
nsCOMPtr<nsIDOMRange> range;
nsRefPtr<nsRange> range;
nsCOMPtr<nsIDOMNode> parent;
int32_t i, rangeCount, offset;
@ -550,13 +540,7 @@ nsTextServicesDocument::LastSelectedBlock(TSDBlockSelectionStatus *aSelStatus,
// If the caret isn't in a text node, search forwards in
// the document, till we find a text node.
result = selection->GetRangeAt(0, getter_AddRefs(range));
if (NS_FAILED(result))
{
UNLOCK_DOC(this);
return result;
}
range = selection->GetRangeAt(0);
if (!range)
{
@ -769,10 +753,9 @@ nsTextServicesDocument::LastSelectedBlock(TSDBlockSelectionStatus *aSelStatus,
{
// Get the i'th range from the selection.
result = selection->GetRangeAt(i, getter_AddRefs(range));
range = selection->GetRangeAt(i);
if (NS_FAILED(result))
{
if (!range) {
UNLOCK_DOC(this);
return result;
}
@ -843,13 +826,7 @@ nsTextServicesDocument::LastSelectedBlock(TSDBlockSelectionStatus *aSelStatus,
// to the end of the document, then iterate forwards through
// it till you find a text node!
result = selection->GetRangeAt(rangeCount - 1, getter_AddRefs(range));
if (NS_FAILED(result))
{
UNLOCK_DOC(this);
return result;
}
range = selection->GetRangeAt(rangeCount - 1);
if (!range)
{
@ -1977,7 +1954,8 @@ nsTextServicesDocument::DidJoinNodes(nsIDOMNode *aLeftNode,
}
nsresult
nsTextServicesDocument::CreateContentIterator(nsIDOMRange *aRange, nsIContentIterator **aIterator)
nsTextServicesDocument::CreateContentIterator(nsRange* aRange,
nsIContentIterator** aIterator)
{
NS_ENSURE_TRUE(aRange && aIterator, NS_ERROR_NULL_POINTER);
@ -2043,7 +2021,7 @@ nsTextServicesDocument::GetDocumentContentRootNode(nsIDOMNode **aNode)
}
nsresult
nsTextServicesDocument::CreateDocumentContentRange(nsIDOMRange **aRange)
nsTextServicesDocument::CreateDocumentContentRange(nsRange** aRange)
{
*aRange = nullptr;
@ -2065,7 +2043,8 @@ nsTextServicesDocument::CreateDocumentContentRange(nsIDOMRange **aRange)
}
nsresult
nsTextServicesDocument::CreateDocumentContentRootToNodeOffsetRange(nsIDOMNode *aParent, int32_t aOffset, bool aToStart, nsIDOMRange **aRange)
nsTextServicesDocument::CreateDocumentContentRootToNodeOffsetRange(
nsIDOMNode* aParent, int32_t aOffset, bool aToStart, nsRange** aRange)
{
NS_ENSURE_TRUE(aParent && aRange, NS_ERROR_NULL_POINTER);
@ -2116,7 +2095,7 @@ nsTextServicesDocument::CreateDocumentContentIterator(nsIContentIterator **aIter
NS_ENSURE_TRUE(aIterator, NS_ERROR_NULL_POINTER);
nsCOMPtr<nsIDOMRange> range;
nsRefPtr<nsRange> range;
result = CreateDocumentContentRange(getter_AddRefs(range));
@ -2541,10 +2520,14 @@ nsTextServicesDocument::GetSelection(nsITextServicesDocument::TSDBlockSelectionS
nsresult
nsTextServicesDocument::GetCollapsedSelection(nsITextServicesDocument::TSDBlockSelectionStatus *aSelStatus, int32_t *aSelOffset, int32_t *aSelLength)
{
nsCOMPtr<nsISelection> selection;
nsresult result = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
nsCOMPtr<nsISelection> domSelection;
nsresult result =
mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
getter_AddRefs(domSelection));
NS_ENSURE_SUCCESS(result, result);
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(domSelection, NS_ERROR_FAILURE);
nsRefPtr<Selection> selection = static_cast<Selection*>(domSelection.get());
// The calling function should have done the GetIsCollapsed()
// check already. Just assume it's collapsed!
@ -2569,9 +2552,8 @@ nsTextServicesDocument::GetCollapsedSelection(nsITextServicesDocument::TSDBlockS
int32_t eStartOffset = eStart->mNodeOffset;
int32_t eEndOffset = eEnd->mNodeOffset + eEnd->mLength;
nsCOMPtr<nsIDOMRange> range;
result = selection->GetRangeAt(0, getter_AddRefs(range));
NS_ENSURE_SUCCESS(result, result);
nsRefPtr<nsRange> range = selection->GetRangeAt(0);
NS_ENSURE_STATE(range);
nsCOMPtr<nsIDOMNode> domParent;
result = range->GetStartContainer(getter_AddRefs(domParent));
@ -2754,15 +2736,16 @@ nsTextServicesDocument::GetUncollapsedSelection(nsITextServicesDocument::TSDBloc
{
nsresult result;
nsCOMPtr<nsISelection> selection;
nsCOMPtr<nsIDOMRange> range;
nsRefPtr<nsRange> range;
OffsetEntry *entry;
result = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
nsCOMPtr<nsISelection> domSelection;
result = mSelCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
getter_AddRefs(domSelection));
NS_ENSURE_SUCCESS(result, result);
NS_ENSURE_TRUE(domSelection, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
nsRefPtr<Selection> selection = static_cast<Selection*>(domSelection.get());
// It is assumed that the calling function has made sure that the
// selection is not collapsed, and that the input params to this
@ -2800,9 +2783,8 @@ nsTextServicesDocument::GetUncollapsedSelection(nsITextServicesDocument::TSDBloc
for (i = 0; i < rangeCount; i++)
{
result = selection->GetRangeAt(i, getter_AddRefs(range));
NS_ENSURE_SUCCESS(result, result);
range = selection->GetRangeAt(i);
NS_ENSURE_STATE(range);
result = GetRangeEndPoints(range,
getter_AddRefs(startParent), &startOffset,
@ -3054,7 +3036,7 @@ nsTextServicesDocument::SelectionIsValid()
}
nsresult
nsTextServicesDocument::GetRangeEndPoints(nsIDOMRange *aRange,
nsTextServicesDocument::GetRangeEndPoints(nsRange* aRange,
nsIDOMNode **aStartParent, int32_t *aStartOffset,
nsIDOMNode **aEndParent, int32_t *aEndOffset)
{
@ -3087,7 +3069,7 @@ nsTextServicesDocument::GetRangeEndPoints(nsIDOMRange *aRange,
nsresult
nsTextServicesDocument::CreateRange(nsIDOMNode *aStartParent, int32_t aStartOffset,
nsIDOMNode *aEndParent, int32_t aEndOffset,
nsIDOMRange **aRange)
nsRange** aRange)
{
return nsRange::CreateRange(aStartParent, aStartOffset, aEndParent,
aEndOffset, aRange);
@ -3322,8 +3304,7 @@ nsresult
nsTextServicesDocument::CreateOffsetTable(nsTArray<OffsetEntry*> *aOffsetTable,
nsIContentIterator *aIterator,
TSDIteratorStatus *aIteratorStatus,
nsIDOMRange *aIterRange,
nsString *aStr)
nsRange* aIterRange, nsString* aStr)
{
nsresult result = NS_OK;

View File

@ -83,7 +83,7 @@ private:
int32_t mSelEndIndex;
int32_t mSelEndOffset;
nsCOMPtr<nsIDOMRange> mExtent;
nsRefPtr<nsRange> mExtent;
nsCOMPtr<nsITextServicesFilter> mTxtSvcFilter;
@ -160,17 +160,25 @@ public:
NS_IMETHOD DidDeleteSelection(nsISelection *aSelection);
/* Helper functions */
static nsresult GetRangeEndPoints(nsIDOMRange *aRange, nsIDOMNode **aParent1, int32_t *aOffset1, nsIDOMNode **aParent2, int32_t *aOffset2);
static nsresult CreateRange(nsIDOMNode *aStartParent, int32_t aStartOffset, nsIDOMNode *aEndParent, int32_t aEndOffset, nsIDOMRange **aRange);
static nsresult GetRangeEndPoints(nsRange* aRange, nsIDOMNode** aParent1,
int32_t* aOffset1, nsIDOMNode** aParent2,
int32_t* aOffset2);
static nsresult CreateRange(nsIDOMNode* aStartParent, int32_t aStartOffset,
nsIDOMNode* aEndParent, int32_t aEndOffset,
nsRange** aRange);
private:
/* nsTextServicesDocument private methods. */
nsresult CreateContentIterator(nsIDOMRange *aRange, nsIContentIterator **aIterator);
nsresult CreateContentIterator(nsRange* aRange,
nsIContentIterator** aIterator);
nsresult GetDocumentContentRootNode(nsIDOMNode **aNode);
nsresult CreateDocumentContentRange(nsIDOMRange **aRange);
nsresult CreateDocumentContentRootToNodeOffsetRange(nsIDOMNode *aParent, int32_t aOffset, bool aToStart, nsIDOMRange **aRange);
nsresult CreateDocumentContentRange(nsRange** aRange);
nsresult CreateDocumentContentRootToNodeOffsetRange(nsIDOMNode* aParent,
int32_t aOffset,
bool aToStart,
nsRange** aRange);
nsresult CreateDocumentContentIterator(nsIContentIterator **aIterator);
nsresult AdjustContentIterator();
@ -205,8 +213,7 @@ private:
static nsresult CreateOffsetTable(nsTArray<OffsetEntry*> *aOffsetTable,
nsIContentIterator *aIterator,
TSDIteratorStatus *aIteratorStatus,
nsIDOMRange *aIterRange,
nsString *aStr);
nsRange* aIterRange, nsString* aStr);
static nsresult ClearOffsetTable(nsTArray<OffsetEntry*> *aOffsetTable);
static nsresult NodeHasOffsetEntry(nsTArray<OffsetEntry*> *aOffsetTable,

View File

@ -458,6 +458,11 @@ EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurfacePointerANGLE (EGLDisplay dpy, EGLSu
#define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x3208
#endif /* EGL_ANGLE_platform_angle_opengl */
#ifndef EGL_ANGLE_keyed_mutex
#define EGL_ANGLE_keyed_mutex 1
#define EGL_DXGI_KEYED_MUTEX_ANGLE 0x3209
#endif /* EGL_ANGLE_keyed_mutex */
#ifndef EGL_ARM_pixmap_multisample_discard
#define EGL_ARM_pixmap_multisample_discard 1
#define EGL_DISCARD_SAMPLES_ARM 0x3286

View File

@ -495,6 +495,12 @@ EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surf
*value = (void*) (swapchain ? swapchain->getShareHandle() : NULL);
}
break;
case EGL_DXGI_KEYED_MUTEX_ANGLE:
{
rx::SwapChain *swapchain = eglSurface->getSwapChain();
*value = (void*) (swapchain ? swapchain->getKeyedMutex() : NULL);
}
break;
default:
return egl::error(EGL_BAD_ATTRIBUTE, EGL_FALSE);
}

Some files were not shown because too many files have changed in this diff Show More