mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 11:55:49 +00:00
Merge m-i to m-c, a=merge
This commit is contained in:
commit
3bb307d604
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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 |
@ -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 |
@ -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;
|
||||
|
@ -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=()):
|
||||
|
3
config/external/nss/Makefile.in
vendored
3
config/external/nss/Makefile.in
vendored
@ -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
|
||||
|
75
configure.in
75
configure.in
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -93,7 +93,6 @@ FAIL_ON_WARNINGS = True
|
||||
LOCAL_INCLUDES += [
|
||||
'/db/sqlite3/src',
|
||||
'/dom/base',
|
||||
'/dom/quota',
|
||||
'/dom/storage',
|
||||
'/ipc/glue',
|
||||
'/xpcom/build',
|
||||
|
@ -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]
|
||||
|
@ -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();
|
||||
|
323
dom/manifest/ManifestProcessor.jsm
Normal file
323
dom/manifest/ManifestProcessor.jsm
Normal 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
12
dom/manifest/moz.build
Normal 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']
|
20
dom/manifest/test/common.js
Normal file
20
dom/manifest/test/common.js
Normal 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
|
||||
};
|
16
dom/manifest/test/mochitest.ini
Normal file
16
dom/manifest/test/mochitest.ini
Normal 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]
|
57
dom/manifest/test/test_IconsProcessor_density.html
Normal file
57
dom/manifest/test/test_IconsProcessor_density.html
Normal 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>
|
101
dom/manifest/test/test_IconsProcessor_sizes.html
Normal file
101
dom/manifest/test/test_IconsProcessor_sizes.html
Normal 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>
|
110
dom/manifest/test/test_IconsProcessor_src.html
Normal file
110
dom/manifest/test/test_IconsProcessor_src.html
Normal 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>
|
51
dom/manifest/test/test_IconsProcessor_type.html
Normal file
51
dom/manifest/test/test_IconsProcessor_type.html
Normal 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>
|
34
dom/manifest/test/test_ManifestProcessor_JSON.html
Normal file
34
dom/manifest/test/test_ManifestProcessor_JSON.html
Normal 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>
|
61
dom/manifest/test/test_ManifestProcessor_display.html
Normal file
61
dom/manifest/test/test_ManifestProcessor_display.html
Normal 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>
|
30
dom/manifest/test/test_ManifestProcessor_icons.html
Normal file
30
dom/manifest/test/test_ManifestProcessor_icons.html
Normal 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>
|
@ -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>
|
83
dom/manifest/test/test_ManifestProcessor_orientation.html
Normal file
83
dom/manifest/test/test_ManifestProcessor_orientation.html
Normal 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>
|
59
dom/manifest/test/test_ManifestProcessor_start_url.html
Normal file
59
dom/manifest/test/test_ManifestProcessor_start_url.html
Normal 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>
|
@ -102,6 +102,7 @@ DIRS += [
|
||||
'xslt',
|
||||
'xul',
|
||||
'resourcestats',
|
||||
'manifest',
|
||||
]
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
|
@ -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:
|
||||
|
@ -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
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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()
|
||||
|
@ -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__
|
@ -26,7 +26,6 @@ EXPORTS.mozilla.dom.quota += [
|
||||
'QuotaCommon.h',
|
||||
'QuotaManager.h',
|
||||
'QuotaObject.h',
|
||||
'StoragePrivilege.h',
|
||||
'UsageInfo.h',
|
||||
'Utilities.h',
|
||||
]
|
||||
|
@ -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");
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -45,3 +45,5 @@ XPCSHELL_TESTS_MANIFESTS += ['test/xpcshell/xpcshell.ini']
|
||||
include('/ipc/chromium/chromium-config.mozbuild')
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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"
|
||||
|
@ -19,8 +19,6 @@
|
||||
#include "nsINode.h"
|
||||
#include "nsAString.h"
|
||||
|
||||
class nsIDOMRange;
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
107
editor/libeditor/JoinNodeTxn.cpp
Normal file
107
editor/libeditor/JoinNodeTxn.cpp
Normal 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;
|
||||
}
|
66
editor/libeditor/JoinNodeTxn.h
Normal file
66
editor/libeditor/JoinNodeTxn.h
Normal 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
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
128
editor/libeditor/SplitNodeTxn.cpp
Normal file
128
editor/libeditor/SplitNodeTxn.cpp
Normal 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;
|
||||
}
|
69
editor/libeditor/SplitNodeTxn.h
Normal file
69
editor/libeditor/SplitNodeTxn.h
Normal 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
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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',
|
||||
]
|
||||
|
@ -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
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user