mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to b2g-inbound.
This commit is contained in:
commit
3930dce798
@ -391,9 +391,6 @@ pref("content.ime.strict_policy", true);
|
||||
// $ adb shell start
|
||||
pref("browser.dom.window.dump.enabled", false);
|
||||
|
||||
// Turn on the CSP 1.0 parser for Content Security Policy headers
|
||||
pref("security.csp.speccompliant", true);
|
||||
|
||||
// Default Content Security Policy to apply to privileged and certified apps
|
||||
pref("security.apps.privileged.CSP.default", "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'");
|
||||
// If you change this CSP, make sure to update the fast path in nsCSPService.cpp
|
||||
|
@ -600,38 +600,6 @@ SettingsListener.observe("accessibility.screenreader", false, function(value) {
|
||||
});
|
||||
})();
|
||||
|
||||
// =================== AsyncPanZoom ======================
|
||||
SettingsListener.observe('apz.displayport.heuristics', 'default', function(value) {
|
||||
// first reset everything to default
|
||||
Services.prefs.clearUserPref('apz.velocity_bias');
|
||||
Services.prefs.clearUserPref('apz.use_paint_duration');
|
||||
Services.prefs.clearUserPref('apz.x_skate_size_multiplier');
|
||||
Services.prefs.clearUserPref('apz.y_skate_size_multiplier');
|
||||
Services.prefs.clearUserPref('apz.allow-checkerboarding');
|
||||
// and then set the things that we want to change
|
||||
switch (value) {
|
||||
case 'default':
|
||||
break;
|
||||
case 'center-displayport':
|
||||
Services.prefs.setCharPref('apz.velocity_bias', '0.0');
|
||||
break;
|
||||
case 'perfect-paint-times':
|
||||
Services.prefs.setBoolPref('apz.use_paint_duration', false);
|
||||
Services.prefs.setCharPref('apz.velocity_bias', '0.32'); // 16/50 (assumes 16ms paint times instead of 50ms)
|
||||
break;
|
||||
case 'taller-displayport':
|
||||
Services.prefs.setCharPref('apz.y_skate_size_multiplier', '3.5');
|
||||
break;
|
||||
case 'faster-paint':
|
||||
Services.prefs.setCharPref('apz.x_skate_size_multiplier', '1.0');
|
||||
Services.prefs.setCharPref('apz.y_skate_size_multiplier', '1.5');
|
||||
break;
|
||||
case 'no-checkerboard':
|
||||
Services.prefs.setBoolPref('apz.allow-checkerboarding', false);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// =================== Various simple mapping ======================
|
||||
let settingsToObserve = {
|
||||
'ril.mms.retrieval_mode': {
|
||||
@ -666,7 +634,6 @@ let settingsToObserve = {
|
||||
},
|
||||
'layers.enable-tiles': true,
|
||||
'layers.simple-tiles': false,
|
||||
'layers.progressive-paint': false,
|
||||
'layers.draw-tile-borders': false,
|
||||
'layers.dump': false,
|
||||
'debug.fps.enabled': {
|
||||
|
@ -935,13 +935,18 @@ chatbox:-moz-full-screen-ancestor > .chat-titlebar {
|
||||
-moz-binding: url("chrome://browser/content/places/menu.xml#places-popup-arrow");
|
||||
background: transparent;
|
||||
border: none;
|
||||
/* The popup inherits -moz-image-region from the button, must reset it */
|
||||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
%ifndef MOZ_WIDGET_GTK
|
||||
|
||||
#BMB_bookmarksPopup {
|
||||
transform: scale(.7);
|
||||
opacity: 0;
|
||||
transition-property: transform, opacity;
|
||||
transition-duration: 0.15s;
|
||||
transition-timing-function: ease;
|
||||
/* The popup inherits -moz-image-region from the button, must reset it */
|
||||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
#BMB_bookmarksPopup[animate="open"] {
|
||||
@ -975,6 +980,7 @@ chatbox:-moz-full-screen-ancestor > .chat-titlebar {
|
||||
transform: scale(.7) skew(-30deg, -20deg);
|
||||
}
|
||||
|
||||
%endif
|
||||
|
||||
/* Customize mode */
|
||||
#navigator-toolbox,
|
||||
|
@ -259,9 +259,7 @@ let gSyncPane = {
|
||||
gSyncUtils._openLink(url);
|
||||
return;
|
||||
}
|
||||
win.switchToTabHavingURI(url, true);
|
||||
// seeing as we are doing this in a tab we close the prefs dialog.
|
||||
window.close();
|
||||
win.openUILinkIn(url, "tab");
|
||||
},
|
||||
|
||||
signUp: function() {
|
||||
|
@ -404,7 +404,7 @@ CodeMirror.defineMode("css", function(config, parserConfig) {
|
||||
"font-variant-alternates", "font-variant-caps", "font-variant-east-asian",
|
||||
"font-variant-ligatures", "font-variant-numeric", "font-variant-position",
|
||||
"font-weight", "grid", "grid-area", "grid-auto-columns", "grid-auto-flow",
|
||||
"grid-auto-position", "grid-auto-rows", "grid-column", "grid-column-end",
|
||||
"grid-auto-rows", "grid-column", "grid-column-end",
|
||||
"grid-column-start", "grid-row", "grid-row-end", "grid-row-start",
|
||||
"grid-template", "grid-template-areas", "grid-template-columns",
|
||||
"grid-template-rows", "hanging-punctuation", "height", "hyphens",
|
||||
|
@ -49,7 +49,7 @@ XPCOMUtils.defineLazyServiceGetter(this, "gCrashReporter",
|
||||
"nsICrashReporter");
|
||||
|
||||
const FILE_CACHE = "experiments.json";
|
||||
const OBSERVER_TOPIC = "experiments-changed";
|
||||
const EXPERIMENTS_CHANGED_TOPIC = "experiments-changed";
|
||||
const MANIFEST_VERSION = 1;
|
||||
const CACHE_VERSION = 1;
|
||||
|
||||
@ -114,6 +114,7 @@ let gLogAppenderDump = null;
|
||||
let gPolicyCounter = 0;
|
||||
let gExperimentsCounter = 0;
|
||||
let gExperimentEntryCounter = 0;
|
||||
let gPreviousProviderCounter = 0;
|
||||
|
||||
// Tracks active AddonInstall we know about so we can deny external
|
||||
// installs.
|
||||
@ -464,7 +465,7 @@ Experiments.Experiments.prototype = {
|
||||
this._log.info("Completed uninitialization.");
|
||||
}),
|
||||
|
||||
_registerWithAddonManager: function () {
|
||||
_registerWithAddonManager: function (previousExperimentsProvider) {
|
||||
this._log.trace("Registering instance with Addon Manager.");
|
||||
|
||||
AddonManager.addAddonListener(this);
|
||||
@ -474,15 +475,15 @@ Experiments.Experiments.prototype = {
|
||||
// The properties of this AddonType should be kept in sync with the
|
||||
// experiment AddonType registered in XPIProvider.
|
||||
this._log.trace("Registering previous experiment add-on provider.");
|
||||
gAddonProvider = new Experiments.PreviousExperimentProvider(this, [
|
||||
gAddonProvider = previousExperimentsProvider || new Experiments.PreviousExperimentProvider(this);
|
||||
AddonManagerPrivate.registerProvider(gAddonProvider, [
|
||||
new AddonManagerPrivate.AddonType("experiment",
|
||||
URI_EXTENSION_STRINGS,
|
||||
STRING_TYPE_NAME,
|
||||
AddonManager.VIEW_TYPE_LIST,
|
||||
11000,
|
||||
AddonManager.TYPE_UI_HIDE_EMPTY),
|
||||
]);
|
||||
AddonManagerPrivate.registerProvider(gAddonProvider);
|
||||
]);
|
||||
}
|
||||
|
||||
},
|
||||
@ -500,6 +501,15 @@ Experiments.Experiments.prototype = {
|
||||
AddonManager.removeAddonListener(this);
|
||||
},
|
||||
|
||||
/*
|
||||
* Change the PreviousExperimentsProvider that this instance uses.
|
||||
* For testing only.
|
||||
*/
|
||||
_setPreviousExperimentsProvider: function (provider) {
|
||||
this._unregisterWithAddonManager();
|
||||
this._registerWithAddonManager(provider);
|
||||
},
|
||||
|
||||
/**
|
||||
* Throws an exception if we've already shut down.
|
||||
*/
|
||||
@ -1151,7 +1161,7 @@ Experiments.Experiments.prototype = {
|
||||
gPrefs.set(PREF_ACTIVE_EXPERIMENT, activeExperiment != null);
|
||||
|
||||
if (activeChanged) {
|
||||
Services.obs.notifyObservers(null, OBSERVER_TOPIC, null);
|
||||
Services.obs.notifyObservers(null, EXPERIMENTS_CHANGED_TOPIC, null);
|
||||
}
|
||||
|
||||
if ("@mozilla.org/toolkit/crash-reporter;1" in Cc && activeExperiment) {
|
||||
@ -1970,7 +1980,7 @@ ExperimentsProvider.prototype = Object.freeze({
|
||||
],
|
||||
|
||||
_OBSERVERS: [
|
||||
OBSERVER_TOPIC,
|
||||
EXPERIMENTS_CHANGED_TOPIC,
|
||||
],
|
||||
|
||||
postInit: function () {
|
||||
@ -1991,7 +2001,7 @@ ExperimentsProvider.prototype = Object.freeze({
|
||||
|
||||
observe: function (subject, topic, data) {
|
||||
switch (topic) {
|
||||
case OBSERVER_TOPIC:
|
||||
case EXPERIMENTS_CHANGED_TOPIC:
|
||||
this.recordLastActiveExperiment();
|
||||
break;
|
||||
}
|
||||
@ -2040,26 +2050,40 @@ ExperimentsProvider.prototype = Object.freeze({
|
||||
*/
|
||||
this.Experiments.PreviousExperimentProvider = function (experiments) {
|
||||
this._experiments = experiments;
|
||||
this._experimentList = [];
|
||||
this._log = Log.repository.getLoggerWithMessagePrefix(
|
||||
"Browser.Experiments.Experiments",
|
||||
"PreviousExperimentProvider #" + gPreviousProviderCounter++ + "::");
|
||||
}
|
||||
|
||||
this.Experiments.PreviousExperimentProvider.prototype = Object.freeze({
|
||||
startup: function () {},
|
||||
shutdown: function () {},
|
||||
startup: function () {
|
||||
this._log.trace("startup()");
|
||||
Services.obs.addObserver(this, EXPERIMENTS_CHANGED_TOPIC, false);
|
||||
},
|
||||
|
||||
shutdown: function () {
|
||||
this._log.trace("shutdown()");
|
||||
Services.obs.removeObserver(this, EXPERIMENTS_CHANGED_TOPIC);
|
||||
},
|
||||
|
||||
observe: function (subject, topic, data) {
|
||||
switch (topic) {
|
||||
case EXPERIMENTS_CHANGED_TOPIC:
|
||||
this._updateExperimentList();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
getAddonByID: function (id, cb) {
|
||||
this._getPreviousExperiments().then((experiments) => {
|
||||
for (let experiment of experiments) {
|
||||
if (experiment.id == id) {
|
||||
cb(new PreviousExperimentAddon(experiment));
|
||||
return;
|
||||
}
|
||||
for (let experiment of this._experimentList) {
|
||||
if (experiment.id == id) {
|
||||
cb(new PreviousExperimentAddon(experiment));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cb(null);
|
||||
},
|
||||
(error) => {
|
||||
cb(null);
|
||||
});
|
||||
cb(null);
|
||||
},
|
||||
|
||||
getAddonsByTypes: function (types, cb) {
|
||||
@ -2068,17 +2092,45 @@ this.Experiments.PreviousExperimentProvider.prototype = Object.freeze({
|
||||
return;
|
||||
}
|
||||
|
||||
this._getPreviousExperiments().then((experiments) => {
|
||||
cb([new PreviousExperimentAddon(e) for (e of experiments)]);
|
||||
},
|
||||
(error) => {
|
||||
cb([]);
|
||||
});
|
||||
cb([new PreviousExperimentAddon(e) for (e of this._experimentList)]);
|
||||
},
|
||||
|
||||
_getPreviousExperiments: function () {
|
||||
_updateExperimentList: function () {
|
||||
return this._experiments.getExperiments().then((experiments) => {
|
||||
return Promise.resolve([e for (e of experiments) if (!e.active)]);
|
||||
let list = [e for (e of experiments) if (!e.active)];
|
||||
|
||||
let newMap = new Map([[e.id, e] for (e of list)]);
|
||||
let oldMap = new Map([[e.id, e] for (e of this._experimentList)]);
|
||||
|
||||
let added = [e.id for (e of list) if (!oldMap.has(e.id))];
|
||||
let removed = [e.id for (e of this._experimentList) if (!newMap.has(e.id))];
|
||||
|
||||
for (let id of added) {
|
||||
this._log.trace("updateExperimentList() - adding " + id);
|
||||
let wrapper = new PreviousExperimentAddon(newMap.get(id));
|
||||
AddonManagerPrivate.callInstallListeners("onExternalInstall", null, wrapper, null, false);
|
||||
AddonManagerPrivate.callAddonListeners("onInstalling", wrapper, false);
|
||||
}
|
||||
|
||||
for (let id of removed) {
|
||||
this._log.trace("updateExperimentList() - removing " + id);
|
||||
let wrapper = new PreviousExperimentAddon(oldMap.get(id));
|
||||
AddonManagerPrivate.callAddonListeners("onUninstalling", plugin, false);
|
||||
}
|
||||
|
||||
this._experimentList = list;
|
||||
|
||||
for (let id of added) {
|
||||
let wrapper = new PreviousExperimentAddon(newMap.get(id));
|
||||
AddonManagerPrivate.callAddonListeners("onInstalled", wrapper);
|
||||
}
|
||||
|
||||
for (let id of removed) {
|
||||
let wrapper = new PreviousExperimentAddon(oldMap.get(id));
|
||||
AddonManagerPrivate.callAddonListeners("onUninstalled", wrapper);
|
||||
}
|
||||
|
||||
return this._experimentList;
|
||||
});
|
||||
},
|
||||
});
|
||||
|
@ -44,6 +44,8 @@ add_task(function* test_provider_basic() {
|
||||
let e = Experiments.instance();
|
||||
|
||||
let provider = new Experiments.PreviousExperimentProvider(e);
|
||||
e._setPreviousExperimentsProvider(provider);
|
||||
|
||||
let deferred = Promise.defer();
|
||||
provider.getAddonsByTypes(["experiment"], (addons) => {
|
||||
deferred.resolve(addons);
|
||||
@ -124,6 +126,7 @@ add_task(function* test_active_and_previous() {
|
||||
// Building on the previous test, activate experiment 2.
|
||||
let e = Experiments.instance();
|
||||
let provider = new Experiments.PreviousExperimentProvider(e);
|
||||
e._setPreviousExperimentsProvider(provider);
|
||||
|
||||
gManifestObject = {
|
||||
version: 1,
|
||||
|
@ -53,9 +53,13 @@ DEFINES += -DJAREXT=
|
||||
|
||||
ifdef MOZ_ANGLE_RENDERER
|
||||
DEFINES += -DMOZ_ANGLE_RENDERER=$(MOZ_ANGLE_RENDERER)
|
||||
ifdef MOZ_D3DCOMPILER_VISTA_DLL
|
||||
DEFINES += -DMOZ_D3DCOMPILER_VISTA_DLL=$(MOZ_D3DCOMPILER_VISTA_DLL)
|
||||
endif
|
||||
ifdef MOZ_D3DCOMPILER_XP_DLL
|
||||
DEFINES += -DMOZ_D3DCOMPILER_XP_DLL=$(MOZ_D3DCOMPILER_XP_DLL)
|
||||
endif
|
||||
endif
|
||||
|
||||
DEFINES += -DMOZ_CHILD_PROCESS_NAME=$(MOZ_CHILD_PROCESS_NAME)
|
||||
|
||||
|
@ -614,7 +614,7 @@ nsChromeRegistryChrome::kTableOps = {
|
||||
nsChromeRegistryChrome::ProviderEntry*
|
||||
nsChromeRegistryChrome::nsProviderArray::GetProvider(const nsACString& aPreferred, MatchType aType)
|
||||
{
|
||||
int32_t i = mArray.Count();
|
||||
int32_t i = mArray.Length();
|
||||
if (!i)
|
||||
return nullptr;
|
||||
|
||||
@ -622,7 +622,7 @@ nsChromeRegistryChrome::nsProviderArray::GetProvider(const nsACString& aPreferre
|
||||
ProviderEntry* entry;
|
||||
|
||||
while (i--) {
|
||||
entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
|
||||
entry = &mArray[i];
|
||||
if (aPreferred.Equals(entry->provider))
|
||||
return entry;
|
||||
|
||||
@ -677,35 +677,18 @@ nsChromeRegistryChrome::nsProviderArray::SetBase(const nsACString& aProvider, ns
|
||||
}
|
||||
|
||||
// no existing entries, add a new one
|
||||
provider = new ProviderEntry(aProvider, aBaseURL);
|
||||
if (!provider)
|
||||
return; // It's safe to silently fail on OOM
|
||||
|
||||
mArray.AppendElement(provider);
|
||||
mArray.AppendElement(ProviderEntry(aProvider, aBaseURL));
|
||||
}
|
||||
|
||||
void
|
||||
nsChromeRegistryChrome::nsProviderArray::EnumerateToArray(nsTArray<nsCString> *a)
|
||||
{
|
||||
int32_t i = mArray.Count();
|
||||
int32_t i = mArray.Length();
|
||||
while (i--) {
|
||||
ProviderEntry *entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
|
||||
a->AppendElement(entry->provider);
|
||||
a->AppendElement(mArray[i].provider);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsChromeRegistryChrome::nsProviderArray::Clear()
|
||||
{
|
||||
int32_t i = mArray.Count();
|
||||
while (i--) {
|
||||
ProviderEntry* entry = reinterpret_cast<ProviderEntry*>(mArray[i]);
|
||||
delete entry;
|
||||
}
|
||||
|
||||
mArray.Clear();
|
||||
}
|
||||
|
||||
void
|
||||
nsChromeRegistryChrome::OverlayListEntry::AddURI(nsIURI* aURI)
|
||||
{
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsChromeRegistry.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/Move.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -85,8 +85,7 @@ class nsChromeRegistryChrome : public nsChromeRegistry
|
||||
public:
|
||||
nsProviderArray() :
|
||||
mArray(1) { }
|
||||
~nsProviderArray()
|
||||
{ Clear(); }
|
||||
~nsProviderArray() { }
|
||||
|
||||
// When looking up locales and skins, the "selected" locale is not always
|
||||
// available. This enum identifies what kind of match is desired/found.
|
||||
@ -100,12 +99,11 @@ class nsChromeRegistryChrome : public nsChromeRegistry
|
||||
const nsACString& GetSelected(const nsACString& aPreferred, MatchType aType);
|
||||
void SetBase(const nsACString& aProvider, nsIURI* base);
|
||||
void EnumerateToArray(nsTArray<nsCString> *a);
|
||||
void Clear();
|
||||
|
||||
private:
|
||||
ProviderEntry* GetProvider(const nsACString& aPreferred, MatchType aType);
|
||||
|
||||
nsVoidArray mArray;
|
||||
nsTArray<ProviderEntry> mArray;
|
||||
};
|
||||
|
||||
struct PackageEntry : public PLDHashEntryHdr
|
||||
|
@ -1826,6 +1826,11 @@ protected:
|
||||
nsSlots* mSlots;
|
||||
};
|
||||
|
||||
inline nsIDOMNode* GetAsDOMNode(nsINode* aNode)
|
||||
{
|
||||
return aNode ? aNode->AsDOMNode() : nullptr;
|
||||
}
|
||||
|
||||
// Useful inline function for getting a node given an nsIContent and an
|
||||
// nsIDocument. Returns the first argument cast to nsINode if it is non-null,
|
||||
// otherwise returns the second (which may be null). We use type variables
|
||||
|
@ -1321,7 +1321,7 @@ private:
|
||||
bool SupportsSetRangeText() const {
|
||||
return mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_SEARCH ||
|
||||
mType == NS_FORM_INPUT_URL || mType == NS_FORM_INPUT_TEL ||
|
||||
mType == NS_FORM_INPUT_PASSWORD;
|
||||
mType == NS_FORM_INPUT_PASSWORD || mType == NS_FORM_INPUT_NUMBER;
|
||||
}
|
||||
|
||||
static bool MayFireChangeOnBlur(uint8_t aType) {
|
||||
|
@ -20,6 +20,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=850364
|
||||
<input type="url" id="input_url"></input>
|
||||
<input type="tel" id="input_tel"></input>
|
||||
<input type="password" id="input_password"></input>
|
||||
<input type="number" id="input_number"></input>
|
||||
<textarea id="input_textarea"></textarea>
|
||||
|
||||
<!-- "SetRangeText() non-supported types" -->
|
||||
@ -39,7 +40,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=850364
|
||||
|
||||
/** Tests for Bug 850364 && Bug 918940**/
|
||||
|
||||
var SupportedTypes = ["text", "search", "url", "tel", "password", "textarea"];
|
||||
var SupportedTypes = ["text", "search", "url", "tel", "password", "textarea", "number"];
|
||||
var NonSupportedTypes = ["button", "submit", "image", "reset", "radio",
|
||||
"checkbox", "range", "file", "email"];
|
||||
|
||||
@ -92,58 +93,58 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=850364
|
||||
}, false);
|
||||
|
||||
var test = " setRange(replacement), shrink";
|
||||
elem.value = "0123456789ABCDEF";
|
||||
elem.value = "0123456789123456";
|
||||
elem.setSelectionRange(1, 6);
|
||||
elem.setRangeText("xyz");
|
||||
is(elem.value, "0xyz6789ABCDEF", msg + test);
|
||||
elem.setRangeText("999");
|
||||
is(elem.value, "09996789123456", msg + test);
|
||||
is(elem.selectionStart, 1, msg + test);
|
||||
is(elem.selectionEnd, 4, msg + test);
|
||||
elem.setRangeText("mnk");
|
||||
is(elem.value, "0mnk6789ABCDEF", msg + test);
|
||||
elem.setRangeText("222");
|
||||
is(elem.value, "02226789123456", msg + test);
|
||||
expectedNumOfSelectCalls += 3;
|
||||
|
||||
test = " setRange(replacement), expand";
|
||||
elem.value = "0123456789ABCDEF";
|
||||
elem.value = "0123456789123456";
|
||||
elem.setSelectionRange(1, 2);
|
||||
elem.setRangeText("xyz");
|
||||
is(elem.value, "0xyz23456789ABCDEF", msg + test);
|
||||
elem.setRangeText("999");
|
||||
is(elem.value, "099923456789123456", msg + test);
|
||||
is(elem.selectionStart, 1, msg + test);
|
||||
is(elem.selectionEnd, 4, msg + test);
|
||||
elem.setRangeText("mnk");
|
||||
is(elem.value, "0mnk23456789ABCDEF", msg + test);
|
||||
elem.setRangeText("222");
|
||||
is(elem.value, "022223456789123456", msg + test);
|
||||
expectedNumOfSelectCalls += 3;
|
||||
|
||||
test = " setRange(replacement) pure insertion at start";
|
||||
elem.value = "0123456789ABCDEF";
|
||||
elem.value = "0123456789123456";
|
||||
elem.setSelectionRange(0, 0);
|
||||
elem.setRangeText("xyz");
|
||||
is(elem.value, "xyz0123456789ABCDEF", msg + test);
|
||||
elem.setRangeText("999");
|
||||
is(elem.value, "9990123456789123456", msg + test);
|
||||
is(elem.selectionStart, 0, msg + test);
|
||||
is(elem.selectionEnd, 0, msg + test);
|
||||
elem.setRangeText("mnk");
|
||||
is(elem.value, "mnkxyz0123456789ABCDEF", msg + test);
|
||||
elem.setRangeText("222");
|
||||
is(elem.value, "2229990123456789123456", msg + test);
|
||||
expectedNumOfSelectCalls += 3;
|
||||
|
||||
test = " setRange(replacement) pure insertion in the middle";
|
||||
elem.value = "0123456789ABCDEF";
|
||||
elem.value = "0123456789123456";
|
||||
elem.setSelectionRange(4, 4);
|
||||
elem.setRangeText("xyz");
|
||||
is(elem.value, "0123xyz456789ABCDEF", msg + test);
|
||||
elem.setRangeText("999");
|
||||
is(elem.value, "0123999456789123456", msg + test);
|
||||
is(elem.selectionStart, 4, msg + test);
|
||||
is(elem.selectionEnd, 4, msg + test);
|
||||
elem.setRangeText("mnk");
|
||||
is(elem.value, "0123mnkxyz456789ABCDEF", msg + test);
|
||||
elem.setRangeText("222");
|
||||
is(elem.value, "0123222999456789123456", msg + test);
|
||||
expectedNumOfSelectCalls += 3;
|
||||
|
||||
test = " setRange(replacement) pure insertion at the end";
|
||||
elem.value = "0123456789ABCDEF";
|
||||
elem.value = "1123456789123456";
|
||||
elem.setSelectionRange(16, 16);
|
||||
elem.setRangeText("xyz");
|
||||
is(elem.value, "0123456789ABCDEFxyz", msg + test);
|
||||
elem.setRangeText("999");
|
||||
is(elem.value, "1123456789123456999", msg + test);
|
||||
is(elem.selectionStart, 16, msg + test);
|
||||
is(elem.selectionEnd, 16, msg + test);
|
||||
elem.setRangeText("mnk");
|
||||
is(elem.value, "0123456789ABCDEFmnkxyz", msg + test);
|
||||
elem.setRangeText("222");
|
||||
is(elem.value, "1123456789123456222999", msg + test);
|
||||
expectedNumOfSelectCalls += 3;
|
||||
|
||||
//test SetRange(replacement, start, end, mode) with start > end
|
||||
@ -155,43 +156,43 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=850364
|
||||
is(opThrows, true, msg + " should throw IndexSizeError");
|
||||
|
||||
//test SelectionMode 'select'
|
||||
elem.value = "0123456789ABCDEF";
|
||||
elem.setRangeText("xyz", 4, 9, "select");
|
||||
is(elem.value, "0123xyz9ABCDEF", msg + ".value == \"0123xyz9ABCDEF\"");
|
||||
elem.value = "1023456789123456";
|
||||
elem.setRangeText("999", 4, 9, "select");
|
||||
is(elem.value, "10239999123456", msg + ".value == \"10239999123456\"");
|
||||
is(elem.selectionStart, 4, msg + ".selectionStart == 4, with \"select\"");
|
||||
is(elem.selectionEnd, 7, msg + ".selectionEnd == 7, with \"select\"");
|
||||
expectedNumOfSelectCalls += 1;
|
||||
|
||||
elem.setRangeText("pqm", 6, 25, "select");
|
||||
is(elem.value, "0123xypqm", msg + ".value == \"0123xypqm\"");
|
||||
elem.setRangeText("888", 6, 25, "select");
|
||||
is(elem.value, "102399888", msg + ".value == \"102399888\"");
|
||||
is(elem.selectionStart, 6, msg + ".selectionStart == 6, with \"select\"");
|
||||
is(elem.selectionEnd, 9, msg + ".selectionEnd == 9, with \"select\"");
|
||||
expectedNumOfSelectCalls += 1;
|
||||
|
||||
//test SelectionMode 'start'
|
||||
elem.value = "0123456789ABCDEF";
|
||||
elem.setRangeText("xyz", 4, 9, "start");
|
||||
is(elem.value, "0123xyz9ABCDEF", msg + ".value == \"0123xyz9ABCDEF\"");
|
||||
elem.value = "0123456789123456";
|
||||
elem.setRangeText("999", 4, 9, "start");
|
||||
is(elem.value, "01239999123456", msg + ".value == \"01239999123456\"");
|
||||
is(elem.selectionStart, 4, msg + ".selectionStart == 4, with \"start\"");
|
||||
is(elem.selectionEnd, 4, msg + ".selectionEnd == 4, with \"start\"");
|
||||
expectedNumOfSelectCalls += 1;
|
||||
|
||||
elem.setRangeText("pqm", 6, 25, "start");
|
||||
is(elem.value, "0123xypqm", msg + ".value == \"0123xypqm\"");
|
||||
elem.setRangeText("888", 6, 25, "start");
|
||||
is(elem.value, "012399888", msg + ".value == \"012399888\"");
|
||||
is(elem.selectionStart, 6, msg + ".selectionStart == 6, with \"start\"");
|
||||
is(elem.selectionEnd, 6, msg + ".selectionEnd == 6, with \"start\"");
|
||||
expectedNumOfSelectCalls += 1;
|
||||
|
||||
//test SelectionMode 'end'
|
||||
elem.value = "0123456789ABCDEF";
|
||||
elem.setRangeText("xyz", 4, 9, "end");
|
||||
is(elem.value, "0123xyz9ABCDEF", msg + ".value == \"0123xyz9ABCDEF\"");
|
||||
elem.value = "1023456789123456";
|
||||
elem.setRangeText("999", 4, 9, "end");
|
||||
is(elem.value, "10239999123456", msg + ".value == \"10239999123456\"");
|
||||
is(elem.selectionStart, 7, msg + ".selectionStart == 7, with \"end\"");
|
||||
is(elem.selectionEnd, 7, msg + ".selectionEnd == 7, with \"end\"");
|
||||
expectedNumOfSelectCalls += 1;
|
||||
|
||||
elem.setRangeText("pqm", 6, 25, "end");
|
||||
is(elem.value, "0123xypqm", msg + ".value == \"0123xypqm\"");
|
||||
elem.setRangeText("888", 6, 25, "end");
|
||||
is(elem.value, "102399888", msg + ".value == \"102399888\"");
|
||||
is(elem.selectionStart, 9, msg + ".selectionStart == 9, with \"end\"");
|
||||
is(elem.selectionEnd, 9, msg + ".selectionEnd == 9, with \"end\"");
|
||||
expectedNumOfSelectCalls += 1;
|
||||
@ -201,8 +202,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=850364
|
||||
//subcase: selection{Start|End} > end
|
||||
elem.value = "0123456789";
|
||||
elem.setSelectionRange(6, 9);
|
||||
elem.setRangeText("Z", 1, 2, "preserve");
|
||||
is(elem.value, "0Z23456789", msg + ".value == \"0Z23456789\"");
|
||||
elem.setRangeText("7", 1, 2, "preserve");
|
||||
is(elem.value, "0723456789", msg + ".value == \"0723456789\"");
|
||||
is(elem.selectionStart, 6, msg + ".selectionStart == 6, with \"preserve\"");
|
||||
is(elem.selectionEnd, 9, msg + ".selectionEnd == 9, with \"preserve\"");
|
||||
expectedNumOfSelectCalls += 2;
|
||||
@ -210,8 +211,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=850364
|
||||
//subcase: selection{Start|End} < end
|
||||
elem.value = "0123456789";
|
||||
elem.setSelectionRange(4, 5);
|
||||
elem.setRangeText("QRST", 2, 9, "preserve");
|
||||
is(elem.value, "01QRST9", msg + ".value == \"01QRST9\"");
|
||||
elem.setRangeText("3456", 2, 9, "preserve");
|
||||
is(elem.value, "0134569", msg + ".value == \"0134569\"");
|
||||
is(elem.selectionStart, 2, msg + ".selectionStart == 2, with \"preserve\"");
|
||||
is(elem.selectionEnd, 6, msg + ".selectionEnd == 6, with \"preserve\"");
|
||||
expectedNumOfSelectCalls += 2;
|
||||
@ -219,8 +220,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=850364
|
||||
//subcase: selectionStart > end, selectionEnd < end
|
||||
elem.value = "0123456789";
|
||||
elem.setSelectionRange(8, 4);
|
||||
elem.setRangeText("QRST", 1, 5);
|
||||
is(elem.value, "0QRST56789", msg + ".value == \"0QRST56789\"");
|
||||
elem.setRangeText("3456", 1, 5);
|
||||
is(elem.value, "0345656789", msg + ".value == \"0345656789\"");
|
||||
is(elem.selectionStart, 1, msg + ".selectionStart == 1, with \"default\"");
|
||||
is(elem.selectionEnd, 5, msg + ".selectionEnd == 5, with \"default\"");
|
||||
expectedNumOfSelectCalls += 2;
|
||||
@ -228,8 +229,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=850364
|
||||
//subcase: selectionStart < end, selectionEnd > end
|
||||
elem.value = "0123456789";
|
||||
elem.setSelectionRange(4, 9);
|
||||
elem.setRangeText("QRST", 2, 6);
|
||||
is(elem.value, "01QRST6789", msg + ".value == \"01QRST6789\"");
|
||||
elem.setRangeText("3456", 2, 6);
|
||||
is(elem.value, "0134566789", msg + ".value == \"0134566789\"");
|
||||
is(elem.selectionStart, 2, msg + ".selectionStart == 2, with \"default\"");
|
||||
is(elem.selectionEnd, 9, msg + ".selectionEnd == 9, with \"default\"");
|
||||
expectedNumOfSelectCalls += 2;
|
||||
|
@ -900,17 +900,27 @@ Console::Method(JSContext* aCx, MethodName aMethodName,
|
||||
}
|
||||
|
||||
// Monotonic timer for 'time' and 'timeEnd'
|
||||
if ((aMethodName == MethodTime || aMethodName == MethodTimeEnd) && mWindow) {
|
||||
nsGlobalWindow *win = static_cast<nsGlobalWindow*>(mWindow.get());
|
||||
MOZ_ASSERT(win);
|
||||
if ((aMethodName == MethodTime || aMethodName == MethodTimeEnd)) {
|
||||
if (mWindow) {
|
||||
nsGlobalWindow *win = static_cast<nsGlobalWindow*>(mWindow.get());
|
||||
MOZ_ASSERT(win);
|
||||
|
||||
ErrorResult rv;
|
||||
nsRefPtr<nsPerformance> performance = win->GetPerformance(rv);
|
||||
if (rv.Failed()) {
|
||||
return;
|
||||
ErrorResult rv;
|
||||
nsRefPtr<nsPerformance> performance = win->GetPerformance(rv);
|
||||
if (rv.Failed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
callData->mMonotonicTimer = performance->Now();
|
||||
} else {
|
||||
WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
|
||||
MOZ_ASSERT(workerPrivate);
|
||||
|
||||
TimeDuration duration =
|
||||
mozilla::TimeStamp::Now() - workerPrivate->CreationTimeStamp();
|
||||
|
||||
callData->mMonotonicTimer = duration.ToMilliseconds();
|
||||
}
|
||||
|
||||
callData->mMonotonicTimer = performance->Now();
|
||||
}
|
||||
|
||||
// The operation is completed. RAII class has to be disabled.
|
||||
|
@ -576,6 +576,23 @@ nsDOMWindowUtils::GetResolution(float* aXResolution, float* aYResolution)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::GetIsHistoryRestored(bool* aIsHistoryRestored) {
|
||||
if (!nsContentUtils::IsCallerChrome()) {
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
nsIPresShell* presShell = GetPresShell();
|
||||
if (!presShell) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
const nsIScrollableFrame* sf = presShell->GetRootScrollFrameAsScrollable();
|
||||
*aIsHistoryRestored = sf && sf->DidHistoryRestore();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMWindowUtils::SetIsFirstPaint(bool aIsFirstPaint)
|
||||
{
|
||||
|
@ -48,7 +48,7 @@ interface nsIRunnable;
|
||||
interface nsICompositionStringSynthesizer;
|
||||
interface nsITranslationNodeList;
|
||||
|
||||
[scriptable, uuid(d68ea9fa-b1ea-4744-a78e-bb0e6ef95f55)]
|
||||
[scriptable, uuid(8489681a-7407-457e-b889-53d1ae999b30)]
|
||||
interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
/**
|
||||
@ -230,6 +230,15 @@ interface nsIDOMWindowUtils : nsISupports {
|
||||
|
||||
void getResolution(out float aXResolution, out float aYResolution);
|
||||
|
||||
/**
|
||||
* Whether the current window has been restored from session history.
|
||||
* This gives a way to check whether the provided resolution and scroll
|
||||
* position are default values or restored from a previous session.
|
||||
*
|
||||
* Can only be accessed with chrome privileges.
|
||||
*/
|
||||
readonly attribute boolean isHistoryRestored;
|
||||
|
||||
/**
|
||||
* Whether the next paint should be flagged as the first paint for a document.
|
||||
* This gives a way to track the next paint that occurs after the flag is
|
||||
|
@ -196,7 +196,7 @@ TabChildBase::HandlePossibleViewportChange()
|
||||
nsViewportInfo viewportInfo = nsContentUtils::GetViewportInfo(document, mInnerSize);
|
||||
uint32_t presShellId;
|
||||
mozilla::layers::FrameMetrics::ViewID viewId;
|
||||
bool scrollIdentifiersValid = APZCCallbackHelper::GetScrollIdentifiers(
|
||||
bool scrollIdentifiersValid = APZCCallbackHelper::GetOrCreateScrollIdentifiers(
|
||||
document->GetDocumentElement(), &presShellId, &viewId);
|
||||
if (scrollIdentifiersValid) {
|
||||
ZoomConstraints constraints(
|
||||
@ -726,8 +726,8 @@ TabChild::Observe(nsISupports *aSubject,
|
||||
nsCOMPtr<nsIDocument> doc(GetDocument());
|
||||
uint32_t presShellId;
|
||||
ViewID viewId;
|
||||
if (APZCCallbackHelper::GetScrollIdentifiers(doc->GetDocumentElement(),
|
||||
&presShellId, &viewId)) {
|
||||
if (APZCCallbackHelper::GetOrCreateScrollIdentifiers(doc->GetDocumentElement(),
|
||||
&presShellId, &viewId)) {
|
||||
CSSRect rect;
|
||||
sscanf(NS_ConvertUTF16toUTF8(aData).get(),
|
||||
"{\"x\":%f,\"y\":%f,\"w\":%f,\"h\":%f}",
|
||||
|
@ -25,6 +25,10 @@ XPCOMUtils.defineLazyServiceGetter(this, "powerManagerService",
|
||||
"@mozilla.org/power/powermanagerservice;1",
|
||||
"nsIPowerManagerService");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "appsService",
|
||||
"@mozilla.org/AppsService;1",
|
||||
"nsIAppsService");
|
||||
|
||||
// Limit the number of pending messages for a given page.
|
||||
let kMaxPendingMessages;
|
||||
try {
|
||||
@ -83,6 +87,7 @@ function SystemMessageInternal() {
|
||||
Services.obs.addObserver(this, "xpcom-shutdown", false);
|
||||
Services.obs.addObserver(this, "webapps-registry-start", false);
|
||||
Services.obs.addObserver(this, "webapps-registry-ready", false);
|
||||
Services.obs.addObserver(this, "webapps-clear-data", false);
|
||||
kMessages.forEach(function(aMsg) {
|
||||
ppmm.addMessageListener(aMsg, this);
|
||||
}, this);
|
||||
@ -499,6 +504,7 @@ SystemMessageInternal.prototype = {
|
||||
Services.obs.removeObserver(this, "xpcom-shutdown");
|
||||
Services.obs.removeObserver(this, "webapps-registry-start");
|
||||
Services.obs.removeObserver(this, "webapps-registry-ready");
|
||||
Services.obs.removeObserver(this, "webapps-clear-data");
|
||||
ppmm = null;
|
||||
this._pages = null;
|
||||
this._bufferedSysMsgs = null;
|
||||
@ -524,6 +530,35 @@ SystemMessageInternal.prototype = {
|
||||
}, this);
|
||||
this._bufferedSysMsgs.length = 0;
|
||||
break;
|
||||
case "webapps-clear-data":
|
||||
let params =
|
||||
aSubject.QueryInterface(Ci.mozIApplicationClearPrivateDataParams);
|
||||
if (!params) {
|
||||
debug("Error updating registered pages for an uninstalled app.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Only update registered pages for apps.
|
||||
if (params.browserOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
let manifestURL = appsService.getManifestURLByLocalId(params.appId);
|
||||
if (!manifestURL) {
|
||||
debug("Error updating registered pages for an uninstalled app.");
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = this._pages.length - 1; i >= 0; i--) {
|
||||
let page = this._pages[i];
|
||||
if (page.manifestURL === manifestURL) {
|
||||
this._pages.splice(i, 1);
|
||||
debug("Remove " + page.pageURL + " @ " + page.manifestURL +
|
||||
" from registered pages due to app uninstallation.");
|
||||
}
|
||||
}
|
||||
debug("Finish updating registered pages for an uninstalled app.");
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -839,7 +839,7 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char*
|
||||
TestNPObject* scriptableObject = (TestNPObject*)NPN_CreateObject(instance, &sNPClass);
|
||||
if (!scriptableObject) {
|
||||
printf("NPN_CreateObject failed to create an object, can't create a plugin instance\n");
|
||||
free(instanceData);
|
||||
delete instanceData;
|
||||
return NPERR_GENERIC_ERROR;
|
||||
}
|
||||
scriptableObject->npp = instance;
|
||||
|
@ -6,6 +6,8 @@ support-files =
|
||||
network_geolocation.sjs
|
||||
page_privatestorageevent.html
|
||||
test-console-api.html
|
||||
test_bug1004814.html
|
||||
worker_bug1004814.js
|
||||
|
||||
[browser_test__content.js]
|
||||
[browser_ConsoleAPITests.js]
|
||||
@ -30,3 +32,4 @@ support-files =
|
||||
[browser_webapps_perms_reinstall.js]
|
||||
disabled = re-enable when bug 794920 is fixed
|
||||
[browser_xhr_sandbox.js]
|
||||
[browser_bug1004814.js]
|
||||
|
46
dom/tests/browser/browser_bug1004814.js
Normal file
46
dom/tests/browser/browser_bug1004814.js
Normal file
@ -0,0 +1,46 @@
|
||||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* 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/. */
|
||||
|
||||
const TEST_URI = "http://example.com/browser/dom/tests/browser/test_bug1004814.html";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
ConsoleObserver.init();
|
||||
|
||||
var tab = gBrowser.addTab(TEST_URI);
|
||||
gBrowser.selectedTab = tab;
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
}
|
||||
|
||||
var ConsoleObserver = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
|
||||
|
||||
init: function() {
|
||||
Services.obs.addObserver(this, "console-api-log-event", false);
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
Services.obs.removeObserver(this, "console-api-log-event");
|
||||
},
|
||||
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
var obj = aSubject.wrappedJSObject;
|
||||
if (obj.arguments.length != 1 || obj.arguments[0] != 'bug1004814' ||
|
||||
obj.level != 'timeEnd') {
|
||||
return;
|
||||
}
|
||||
|
||||
ok("timer" in obj, "ConsoleEvent contains 'timer' property");
|
||||
ok("duration" in obj.timer, "ConsoleEvent.timer contains 'duration' property");
|
||||
ok(obj.timer.duration > 0, "ConsoleEvent.timer.duration > 0: " + obj.timer.duration + " ~ 200ms");
|
||||
|
||||
this.destroy();
|
||||
finish();
|
||||
}
|
||||
};
|
14
dom/tests/browser/test_bug1004814.html
Normal file
14
dom/tests/browser/test_bug1004814.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Console API test bug 1004814</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
var w = new Worker('worker_bug1004814.js');
|
||||
w.postMessage(true);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
6
dom/tests/browser/worker_bug1004814.js
Normal file
6
dom/tests/browser/worker_bug1004814.js
Normal file
@ -0,0 +1,6 @@
|
||||
onmessage = function(evt) {
|
||||
console.time('bug1004814');
|
||||
setTimeout(function() {
|
||||
console.timeEnd('bug1004814');
|
||||
}, 200);
|
||||
}
|
@ -2111,7 +2111,8 @@ WorkerPrivateParent<Derived>::WorkerPrivateParent(
|
||||
mSharedWorkerName(aSharedWorkerName), mBusyCount(0), mMessagePortSerial(0),
|
||||
mParentStatus(Pending), mParentSuspended(false),
|
||||
mIsChromeWorker(aIsChromeWorker), mMainThreadObjectsForgotten(false),
|
||||
mWorkerType(aWorkerType)
|
||||
mWorkerType(aWorkerType),
|
||||
mCreationTimeStamp(TimeStamp::Now())
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
|
||||
|
@ -241,6 +241,7 @@ private:
|
||||
bool mIsChromeWorker;
|
||||
bool mMainThreadObjectsForgotten;
|
||||
WorkerType mWorkerType;
|
||||
TimeStamp mCreationTimeStamp;
|
||||
|
||||
protected:
|
||||
// The worker is owned by its thread, which is represented here. This is set
|
||||
@ -508,6 +509,11 @@ public:
|
||||
return mLoadInfo.mResolvedScriptURI;
|
||||
}
|
||||
|
||||
TimeStamp CreationTimeStamp() const
|
||||
{
|
||||
return mCreationTimeStamp;
|
||||
}
|
||||
|
||||
nsIPrincipal*
|
||||
GetPrincipal() const
|
||||
{
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
CreateElementTxn::CreateElementTxn()
|
||||
: EditTxn()
|
||||
@ -60,11 +61,9 @@ NS_IMETHODIMP CreateElementTxn::DoTransaction(void)
|
||||
NS_ASSERTION(mEditor && mParent, "bad state");
|
||||
NS_ENSURE_TRUE(mEditor && mParent, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsCOMPtr<dom::Element> newContent;
|
||||
|
||||
//new call to use instead to get proper HTML element, bug# 39919
|
||||
nsresult result = mEditor->CreateHTMLContent(mTag, getter_AddRefs(newContent));
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
ErrorResult rv;
|
||||
nsCOMPtr<Element> newContent = mEditor->CreateHTMLContent(mTag, rv);
|
||||
NS_ENSURE_SUCCESS(rv.ErrorCode(), rv.ErrorCode());
|
||||
NS_ENSURE_STATE(newContent);
|
||||
|
||||
mNewNode = newContent;
|
||||
@ -73,7 +72,6 @@ NS_IMETHODIMP CreateElementTxn::DoTransaction(void)
|
||||
|
||||
// insert the new node
|
||||
if (CreateElementTxn::eAppend == int32_t(mOffsetInParent)) {
|
||||
ErrorResult rv;
|
||||
mParent->AppendChild(*mNewNode, rv);
|
||||
return rv.ErrorCode();
|
||||
}
|
||||
@ -84,7 +82,6 @@ NS_IMETHODIMP CreateElementTxn::DoTransaction(void)
|
||||
// note, it's ok for mRefNode to be null. that means append
|
||||
mRefNode = mParent->GetChildAt(mOffsetInParent);
|
||||
|
||||
ErrorResult rv;
|
||||
mParent->InsertBefore(*mNewNode, mRefNode, rv);
|
||||
NS_ENSURE_SUCCESS(rv.ErrorCode(), rv.ErrorCode());
|
||||
|
||||
@ -97,7 +94,7 @@ NS_IMETHODIMP CreateElementTxn::DoTransaction(void)
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
result = mEditor->GetSelection(getter_AddRefs(selection));
|
||||
nsresult result = mEditor->GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "mozilla/TextComposition.h" // for TextComposition
|
||||
#include "mozilla/TextEvents.h"
|
||||
#include "mozilla/dom/Element.h" // for Element, nsINode::AsElement
|
||||
#include "mozilla/dom/Text.h"
|
||||
#include "mozilla/mozalloc.h" // for operator new, etc
|
||||
#include "nsAString.h" // for nsAString_internal::Length, etc
|
||||
#include "nsCCUncollectableMarker.h" // for nsCCUncollectableMarker
|
||||
@ -1379,6 +1380,13 @@ NS_IMETHODIMP nsEditor::CreateNode(const nsAString& aTag,
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsEditor::InsertNode(nsIContent* aContent, nsINode* aParent, int32_t aPosition)
|
||||
{
|
||||
MOZ_ASSERT(aContent && aParent);
|
||||
return InsertNode(GetAsDOMNode(aContent), GetAsDOMNode(aParent), aPosition);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsEditor::InsertNode(nsIDOMNode * aNode,
|
||||
nsIDOMNode * aParent,
|
||||
int32_t aPosition)
|
||||
@ -1571,15 +1579,16 @@ nsEditor::ReplaceContainer(nsINode* aNode,
|
||||
int32_t offset = parent->IndexOf(aNode);
|
||||
|
||||
// create new container
|
||||
//new call to use instead to get proper HTML element, bug# 39919
|
||||
nsresult res = CreateHTMLContent(aNodeType, outNode);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
ErrorResult rv;
|
||||
*outNode = CreateHTMLContent(aNodeType, rv).take();
|
||||
NS_ENSURE_SUCCESS(rv.ErrorCode(), rv.ErrorCode());
|
||||
|
||||
nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(*outNode);
|
||||
|
||||
nsIDOMNode* inNode = aNode->AsDOMNode();
|
||||
|
||||
// set attribute if needed
|
||||
nsresult res;
|
||||
if (aAttribute && aValue && !aAttribute->IsEmpty()) {
|
||||
res = elem->SetAttribute(*aAttribute, *aValue);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
@ -1694,13 +1703,12 @@ nsEditor::InsertContainerAbove(nsIContent* aNode,
|
||||
int32_t offset = parent->IndexOf(aNode);
|
||||
|
||||
// create new container
|
||||
nsCOMPtr<dom::Element> newContent;
|
||||
|
||||
//new call to use instead to get proper HTML element, bug# 39919
|
||||
nsresult res = CreateHTMLContent(aNodeType, getter_AddRefs(newContent));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
ErrorResult rv;
|
||||
nsCOMPtr<Element> newContent = CreateHTMLContent(aNodeType, rv);
|
||||
NS_ENSURE_SUCCESS(rv.ErrorCode(), rv.ErrorCode());
|
||||
|
||||
// set attribute if needed
|
||||
nsresult res;
|
||||
if (aAttribute && aValue && !aAttribute->IsEmpty()) {
|
||||
nsIDOMNode* elem = newContent->AsDOMNode();
|
||||
res = static_cast<nsIDOMElement*>(elem)->SetAttribute(*aAttribute, *aValue);
|
||||
@ -2435,6 +2443,16 @@ nsEditor::InsertTextImpl(const nsAString& aStringToInsert,
|
||||
}
|
||||
|
||||
|
||||
nsresult nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
|
||||
Text* aTextNode,
|
||||
int32_t aOffset,
|
||||
bool aSuppressIME)
|
||||
{
|
||||
return InsertTextIntoTextNodeImpl(aStringToInsert,
|
||||
static_cast<nsIDOMCharacterData*>(GetAsDOMNode(aTextNode)),
|
||||
aOffset, aSuppressIME);
|
||||
}
|
||||
|
||||
nsresult nsEditor::InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
|
||||
nsIDOMCharacterData *aTextNode,
|
||||
int32_t aOffset,
|
||||
@ -3481,8 +3499,14 @@ nsEditor::IsDescendantOfEditorRoot(nsINode* aNode)
|
||||
return nsContentUtils::ContentIsDescendantOf(aNode, root);
|
||||
}
|
||||
|
||||
bool
|
||||
nsEditor::IsContainer(nsIDOMNode *aNode)
|
||||
bool
|
||||
nsEditor::IsContainer(nsINode* aNode)
|
||||
{
|
||||
return aNode ? true : false;
|
||||
}
|
||||
|
||||
bool
|
||||
nsEditor::IsContainer(nsIDOMNode* aNode)
|
||||
{
|
||||
return aNode ? true : false;
|
||||
}
|
||||
@ -3553,11 +3577,14 @@ nsEditor::IsEditable(nsIDOMNode *aNode)
|
||||
}
|
||||
|
||||
bool
|
||||
nsEditor::IsEditable(nsIContent *aNode)
|
||||
nsEditor::IsEditable(nsINode* aNode)
|
||||
{
|
||||
NS_ENSURE_TRUE(aNode, false);
|
||||
|
||||
if (IsMozEditorBogusNode(aNode) || !IsModifiableNode(aNode)) return false;
|
||||
if (!aNode->IsNodeOfType(nsINode::eCONTENT) || IsMozEditorBogusNode(aNode) ||
|
||||
!IsModifiableNode(aNode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// see if it has a frame. If so, we'll edit it.
|
||||
// special case for textnodes: frame must have width.
|
||||
@ -3577,11 +3604,12 @@ nsEditor::IsEditable(nsIContent *aNode)
|
||||
}
|
||||
|
||||
bool
|
||||
nsEditor::IsMozEditorBogusNode(nsIContent *element)
|
||||
nsEditor::IsMozEditorBogusNode(nsINode* element)
|
||||
{
|
||||
return element &&
|
||||
element->AttrValueIs(kNameSpaceID_None, kMOZEditorBogusNodeAttrAtom,
|
||||
kMOZEditorBogusNodeValue, eCaseMatters);
|
||||
return element && element->IsElement() &&
|
||||
element->AsElement()->AttrValueIs(kNameSpaceID_None,
|
||||
kMOZEditorBogusNodeAttrAtom, kMOZEditorBogusNodeValue,
|
||||
eCaseMatters);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@ -4736,22 +4764,31 @@ nsresult nsEditor::ClearSelection()
|
||||
return selection->RemoveAllRanges();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEditor::CreateHTMLContent(const nsAString& aTag, dom::Element** aContent)
|
||||
already_AddRefed<Element>
|
||||
nsEditor::CreateHTMLContent(const nsAString& aTag, ErrorResult& rv)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc = GetDocument();
|
||||
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
|
||||
if (!doc) {
|
||||
rv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// XXX Wallpaper over editor bug (editor tries to create elements with an
|
||||
// empty nodename).
|
||||
if (aTag.IsEmpty()) {
|
||||
NS_ERROR("Don't pass an empty tag to nsEditor::CreateHTMLContent, "
|
||||
"check caller.");
|
||||
return NS_ERROR_FAILURE;
|
||||
rv.Throw(NS_ERROR_FAILURE);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return doc->CreateElem(aTag, nullptr, kNameSpaceID_XHTML,
|
||||
reinterpret_cast<nsIContent**>(aContent));
|
||||
nsCOMPtr<nsIContent> ret;
|
||||
nsresult res = doc->CreateElem(aTag, nullptr, kNameSpaceID_XHTML,
|
||||
getter_AddRefs(ret));
|
||||
if (NS_FAILED(res)) {
|
||||
rv.Throw(res);
|
||||
}
|
||||
return dont_AddRef(ret.forget().take()->AsElement());
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -67,6 +67,7 @@ class nsString;
|
||||
class nsTransactionManager;
|
||||
|
||||
namespace mozilla {
|
||||
class ErrorResult;
|
||||
class TextComposition;
|
||||
|
||||
namespace dom {
|
||||
@ -74,6 +75,7 @@ class DataTransfer;
|
||||
class Element;
|
||||
class EventTarget;
|
||||
class Selection;
|
||||
class Text;
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
@ -195,6 +197,10 @@ public:
|
||||
nsCOMPtr<nsIDOMNode> *aInOutNode,
|
||||
int32_t *aInOutOffset,
|
||||
nsIDOMDocument *aDoc);
|
||||
nsresult InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
|
||||
mozilla::dom::Text* aTextNode,
|
||||
int32_t aOffset,
|
||||
bool aSuppressIME = false);
|
||||
nsresult InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
|
||||
nsIDOMCharacterData *aTextNode,
|
||||
int32_t aOffset,
|
||||
@ -206,6 +212,8 @@ public:
|
||||
|
||||
/* helper routines for node/parent manipulations */
|
||||
nsresult DeleteNode(nsINode* aNode);
|
||||
nsresult InsertNode(nsIContent* aContent, nsINode* aParent,
|
||||
int32_t aPosition);
|
||||
nsresult ReplaceContainer(nsINode* inNode,
|
||||
mozilla::dom::Element** outNode,
|
||||
const nsAString& aNodeType,
|
||||
@ -238,10 +246,9 @@ public:
|
||||
/* Method to replace certain CreateElementNS() calls.
|
||||
Arguments:
|
||||
nsString& aTag - tag you want
|
||||
nsIContent** aContent - returned Content that was created with above namespace.
|
||||
*/
|
||||
nsresult CreateHTMLContent(const nsAString& aTag,
|
||||
mozilla::dom::Element** aContent);
|
||||
already_AddRefed<mozilla::dom::Element>
|
||||
CreateHTMLContent(const nsAString& aTag, mozilla::ErrorResult& rv);
|
||||
|
||||
// IME event handlers
|
||||
virtual nsresult BeginIMEComposition(mozilla::WidgetCompositionEvent* aEvent);
|
||||
@ -585,14 +592,15 @@ public:
|
||||
bool IsDescendantOfEditorRoot(nsINode* aNode);
|
||||
|
||||
/** returns true if aNode is a container */
|
||||
virtual bool IsContainer(nsIDOMNode *aNode);
|
||||
virtual bool IsContainer(nsINode* aNode);
|
||||
virtual bool IsContainer(nsIDOMNode* aNode);
|
||||
|
||||
/** returns true if aNode is an editable node */
|
||||
bool IsEditable(nsIDOMNode *aNode);
|
||||
virtual bool IsEditable(nsIContent *aNode);
|
||||
virtual bool IsEditable(nsINode* aNode);
|
||||
|
||||
/** returns true if aNode is a MozEditorBogus node */
|
||||
bool IsMozEditorBogusNode(nsIContent *aNode);
|
||||
bool IsMozEditorBogusNode(nsINode* aNode);
|
||||
|
||||
/** counts number of editable child nodes */
|
||||
uint32_t CountEditableChildren(nsINode* aNode);
|
||||
|
@ -138,38 +138,35 @@ nsDOMSubtreeIterator::Init(nsIDOMRange* aRange)
|
||||
* some general purpose editor utils
|
||||
*****************************************************************************/
|
||||
|
||||
bool
|
||||
nsEditorUtils::IsDescendantOf(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t *aOffset)
|
||||
bool
|
||||
nsEditorUtils::IsDescendantOf(nsINode* aNode, nsINode* aParent, int32_t* aOffset)
|
||||
{
|
||||
NS_ENSURE_TRUE(aNode || aParent, false);
|
||||
if (aNode == aParent) return false;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> parent, node = do_QueryInterface(aNode);
|
||||
nsresult res;
|
||||
|
||||
do
|
||||
{
|
||||
res = node->GetParentNode(getter_AddRefs(parent));
|
||||
NS_ENSURE_SUCCESS(res, false);
|
||||
if (parent == aParent)
|
||||
{
|
||||
if (aOffset)
|
||||
{
|
||||
nsCOMPtr<nsIContent> pCon(do_QueryInterface(parent));
|
||||
nsCOMPtr<nsIContent> cCon(do_QueryInterface(node));
|
||||
if (pCon)
|
||||
{
|
||||
*aOffset = pCon->IndexOf(cCon);
|
||||
}
|
||||
MOZ_ASSERT(aNode && aParent);
|
||||
if (aNode == aParent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (nsCOMPtr<nsINode> node = aNode; node; node = node->GetParentNode()) {
|
||||
if (node->GetParentNode() == aParent) {
|
||||
if (aOffset) {
|
||||
*aOffset = aParent->IndexOf(node);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
node = parent;
|
||||
} while (parent);
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
nsEditorUtils::IsDescendantOf(nsIDOMNode* aNode, nsIDOMNode* aParent, int32_t* aOffset)
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
|
||||
nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
|
||||
NS_ENSURE_TRUE(node && parent, false);
|
||||
return IsDescendantOf(node, parent, aOffset);
|
||||
}
|
||||
|
||||
bool
|
||||
nsEditorUtils::IsLeafNode(nsIDOMNode *aNode)
|
||||
{
|
||||
|
@ -204,19 +204,27 @@ class nsTrivialFunctor : public nsBoolDomIterFunctor
|
||||
*****************************************************************************/
|
||||
struct MOZ_STACK_CLASS DOMPoint
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
nsCOMPtr<nsINode> node;
|
||||
int32_t offset;
|
||||
|
||||
DOMPoint() : node(0),offset(0) {}
|
||||
DOMPoint(nsIDOMNode *aNode, int32_t aOffset) :
|
||||
node(aNode),offset(aOffset) {}
|
||||
void SetPoint(nsIDOMNode *aNode, int32_t aOffset)
|
||||
DOMPoint(nsINode* aNode, int32_t aOffset)
|
||||
: node(aNode)
|
||||
, offset(aOffset)
|
||||
{}
|
||||
DOMPoint(nsIDOMNode* aNode, int32_t aOffset)
|
||||
: node(do_QueryInterface(aNode))
|
||||
, offset(aOffset)
|
||||
{}
|
||||
|
||||
void SetPoint(nsINode* aNode, int32_t aOffset)
|
||||
{
|
||||
node = aNode; offset = aOffset;
|
||||
node = aNode;
|
||||
offset = aOffset;
|
||||
}
|
||||
void GetPoint(nsCOMPtr<nsIDOMNode> &aNode, int32_t &aOffset)
|
||||
void SetPoint(nsIDOMNode* aNode, int32_t aOffset)
|
||||
{
|
||||
aNode = node; aOffset = offset;
|
||||
node = do_QueryInterface(aNode);
|
||||
offset = aOffset;
|
||||
}
|
||||
};
|
||||
|
||||
@ -224,6 +232,7 @@ struct MOZ_STACK_CLASS DOMPoint
|
||||
class nsEditorUtils
|
||||
{
|
||||
public:
|
||||
static bool IsDescendantOf(nsINode* aNode, nsINode* aParent, int32_t* aOffset = 0);
|
||||
static bool IsDescendantOf(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t *aOffset = 0);
|
||||
static bool IsLeafNode(nsIDOMNode *aNode);
|
||||
};
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "nsEditor.h" // for nsEditor
|
||||
#include "nsEditorUtils.h" // for nsEditorUtils
|
||||
#include "nsError.h" // for NS_OK, etc
|
||||
#include "nsIContent.h" // for nsIContent
|
||||
#include "nsIDOMCharacterData.h" // for nsIDOMCharacterData
|
||||
#include "nsIDOMNode.h" // for nsIDOMNode
|
||||
#include "nsIDOMRange.h" // for nsIDOMRange, etc
|
||||
@ -89,8 +90,7 @@ nsSelectionState::RestoreSelection(nsISelection *aSel)
|
||||
// set the selection ranges anew
|
||||
for (i=0; i<arrayCount; i++)
|
||||
{
|
||||
nsRefPtr<nsRange> range;
|
||||
mArray[i]->GetRange(getter_AddRefs(range));
|
||||
nsRefPtr<nsRange> range = mArray[i]->GetRange();
|
||||
NS_ENSURE_TRUE(range, NS_ERROR_UNEXPECTED);
|
||||
|
||||
res = aSel->AddRange(range);
|
||||
@ -104,8 +104,7 @@ bool
|
||||
nsSelectionState::IsCollapsed()
|
||||
{
|
||||
if (1 != mArray.Length()) return false;
|
||||
nsRefPtr<nsRange> range;
|
||||
mArray[0]->GetRange(getter_AddRefs(range));
|
||||
nsRefPtr<nsRange> range = mArray[0]->GetRange();
|
||||
NS_ENSURE_TRUE(range, false);
|
||||
bool bIsCollapsed = false;
|
||||
range->GetCollapsed(&bIsCollapsed);
|
||||
@ -122,9 +121,8 @@ nsSelectionState::IsEqual(nsSelectionState *aSelState)
|
||||
|
||||
for (i=0; i<myCount; i++)
|
||||
{
|
||||
nsRefPtr<nsRange> myRange, itsRange;
|
||||
mArray[i]->GetRange(getter_AddRefs(myRange));
|
||||
aSelState->mArray[i]->GetRange(getter_AddRefs(itsRange));
|
||||
nsRefPtr<nsRange> myRange = mArray[i]->GetRange();
|
||||
nsRefPtr<nsRange> itsRange = aSelState->mArray[i]->GetRange();
|
||||
NS_ENSURE_TRUE(myRange && itsRange, false);
|
||||
|
||||
int16_t compResult;
|
||||
@ -212,30 +210,45 @@ nsRangeUpdater::DropSelectionState(nsSelectionState &aSelState)
|
||||
// gravity methods:
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::SelAdjCreateNode(nsIDOMNode *aParent, int32_t aPosition)
|
||||
nsRangeUpdater::SelAdjCreateNode(nsINode* aParent, int32_t aPosition)
|
||||
{
|
||||
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
|
||||
if (mLock) {
|
||||
// lock set by Will/DidReplaceParent, etc...
|
||||
return NS_OK;
|
||||
}
|
||||
NS_ENSURE_TRUE(aParent, NS_ERROR_NULL_POINTER);
|
||||
uint32_t i, count = mArray.Length();
|
||||
uint32_t count = mArray.Length();
|
||||
if (!count) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRangeStore *item;
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
item = mArray[i];
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
nsRangeStore* item = mArray[i];
|
||||
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if ((item->startNode.get() == aParent) && (item->startOffset > aPosition))
|
||||
|
||||
if (item->startNode == aParent && item->startOffset > aPosition) {
|
||||
item->startOffset++;
|
||||
if ((item->endNode.get() == aParent) && (item->endOffset > aPosition))
|
||||
}
|
||||
if (item->endNode == aParent && item->endOffset > aPosition) {
|
||||
item->endOffset++;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::SelAdjCreateNode(nsIDOMNode* aParent, int32_t aPosition)
|
||||
{
|
||||
nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
|
||||
return SelAdjCreateNode(parent, aPosition);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::SelAdjInsertNode(nsINode* aParent, int32_t aPosition)
|
||||
{
|
||||
return SelAdjCreateNode(aParent, aPosition);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::SelAdjInsertNode(nsIDOMNode *aParent, int32_t aPosition)
|
||||
{
|
||||
@ -243,49 +256,46 @@ nsRangeUpdater::SelAdjInsertNode(nsIDOMNode *aParent, int32_t aPosition)
|
||||
}
|
||||
|
||||
void
|
||||
nsRangeUpdater::SelAdjDeleteNode(nsIDOMNode *aNode)
|
||||
nsRangeUpdater::SelAdjDeleteNode(nsINode* aNode)
|
||||
{
|
||||
if (mLock) {
|
||||
// lock set by Will/DidReplaceParent, etc...
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(aNode);
|
||||
uint32_t i, count = mArray.Length();
|
||||
uint32_t count = mArray.Length();
|
||||
if (!count) {
|
||||
return;
|
||||
}
|
||||
|
||||
int32_t offset = 0;
|
||||
nsCOMPtr<nsIDOMNode> parent = nsEditor::GetNodeLocation(aNode, &offset);
|
||||
|
||||
nsCOMPtr<nsINode> parent = aNode->GetParentNode();
|
||||
int32_t offset = parent ? parent->IndexOf(aNode) : -1;
|
||||
|
||||
// check for range endpoints that are after aNode and in the same parent
|
||||
nsRangeStore *item;
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
item = mArray[i];
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
nsRangeStore* item = mArray[i];
|
||||
MOZ_ASSERT(item);
|
||||
|
||||
if ((item->startNode.get() == parent) && (item->startOffset > offset))
|
||||
|
||||
if (item->startNode == parent && item->startOffset > offset) {
|
||||
item->startOffset--;
|
||||
if ((item->endNode.get() == parent) && (item->endOffset > offset))
|
||||
}
|
||||
if (item->endNode == parent && item->endOffset > offset) {
|
||||
item->endOffset--;
|
||||
|
||||
}
|
||||
|
||||
// check for range endpoints that are in aNode
|
||||
if (item->startNode == aNode)
|
||||
{
|
||||
if (item->startNode == aNode) {
|
||||
item->startNode = parent;
|
||||
item->startOffset = offset;
|
||||
}
|
||||
if (item->endNode == aNode)
|
||||
{
|
||||
if (item->endNode == aNode) {
|
||||
item->endNode = parent;
|
||||
item->endOffset = offset;
|
||||
}
|
||||
|
||||
// check for range endpoints that are in descendants of aNode
|
||||
nsCOMPtr<nsIDOMNode> oldStart;
|
||||
if (nsEditorUtils::IsDescendantOf(item->startNode, aNode))
|
||||
{
|
||||
nsCOMPtr<nsINode> oldStart;
|
||||
if (nsEditorUtils::IsDescendantOf(item->startNode, aNode)) {
|
||||
oldStart = item->startNode; // save for efficiency hack below.
|
||||
item->startNode = parent;
|
||||
item->startOffset = offset;
|
||||
@ -300,51 +310,52 @@ nsRangeUpdater::SelAdjDeleteNode(nsIDOMNode *aNode)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsRangeUpdater::SelAdjDeleteNode(nsIDOMNode *aNode)
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
|
||||
NS_ENSURE_TRUE(node, );
|
||||
return SelAdjDeleteNode(node);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::SelAdjSplitNode(nsIDOMNode *aOldRightNode, int32_t aOffset, nsIDOMNode *aNewLeftNode)
|
||||
nsRangeUpdater::SelAdjSplitNode(nsINode* aOldRightNode, int32_t aOffset,
|
||||
nsINode* aNewLeftNode)
|
||||
{
|
||||
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
|
||||
if (mLock) {
|
||||
// lock set by Will/DidReplaceParent, etc...
|
||||
return NS_OK;
|
||||
}
|
||||
NS_ENSURE_TRUE(aOldRightNode && aNewLeftNode, NS_ERROR_NULL_POINTER);
|
||||
uint32_t i, count = mArray.Length();
|
||||
uint32_t count = mArray.Length();
|
||||
if (!count) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
int32_t offset;
|
||||
nsCOMPtr<nsIDOMNode> parent = nsEditor::GetNodeLocation(aOldRightNode, &offset);
|
||||
|
||||
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);
|
||||
nsresult result = SelAdjInsertNode(parent, offset - 1);
|
||||
NS_ENSURE_SUCCESS(result, result);
|
||||
|
||||
// next step is to check for range enpoints inside aOldRightNode
|
||||
nsRangeStore *item;
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
item = mArray[i];
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
nsRangeStore* item = mArray[i];
|
||||
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (item->startNode.get() == aOldRightNode)
|
||||
{
|
||||
if (item->startOffset > aOffset)
|
||||
{
|
||||
|
||||
if (item->startNode == aOldRightNode) {
|
||||
if (item->startOffset > aOffset) {
|
||||
item->startOffset -= aOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
item->startNode = aNewLeftNode;
|
||||
}
|
||||
}
|
||||
if (item->endNode.get() == aOldRightNode)
|
||||
{
|
||||
if (item->endOffset > aOffset)
|
||||
{
|
||||
if (item->endNode == aOldRightNode) {
|
||||
if (item->endOffset > aOffset) {
|
||||
item->endOffset -= aOffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
item->endNode = aNewLeftNode;
|
||||
}
|
||||
}
|
||||
@ -352,143 +363,171 @@ nsRangeUpdater::SelAdjSplitNode(nsIDOMNode *aOldRightNode, int32_t aOffset, nsID
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::SelAdjJoinNodes(nsIDOMNode *aLeftNode,
|
||||
nsIDOMNode *aRightNode,
|
||||
nsIDOMNode *aParent,
|
||||
int32_t aOffset,
|
||||
int32_t aOldLeftNodeLength)
|
||||
nsRangeUpdater::SelAdjSplitNode(nsIDOMNode* aOldRightNode, int32_t aOffset,
|
||||
nsIDOMNode* aNewLeftNode)
|
||||
{
|
||||
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
|
||||
NS_ENSURE_TRUE(aLeftNode && aRightNode && aParent, NS_ERROR_NULL_POINTER);
|
||||
uint32_t i, count = mArray.Length();
|
||||
if (!count) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRangeStore *item;
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
item = mArray[i];
|
||||
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (item->startNode.get() == 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->startOffset = aOldLeftNodeLength;
|
||||
}
|
||||
}
|
||||
else if (item->startNode.get() == aRightNode)
|
||||
{
|
||||
// adjust start point in aRightNode
|
||||
item->startOffset += aOldLeftNodeLength;
|
||||
}
|
||||
else if (item->startNode.get() == aLeftNode)
|
||||
{
|
||||
// adjust start point in aLeftNode
|
||||
item->startNode = aRightNode;
|
||||
}
|
||||
|
||||
if (item->endNode.get() == 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->endOffset = aOldLeftNodeLength;
|
||||
}
|
||||
}
|
||||
else if (item->endNode.get() == aRightNode)
|
||||
{
|
||||
// adjust end point in aRightNode
|
||||
item->endOffset += aOldLeftNodeLength;
|
||||
}
|
||||
else if (item->endNode.get() == aLeftNode)
|
||||
{
|
||||
// adjust end point in aLeftNode
|
||||
item->endNode = aRightNode;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
nsCOMPtr<nsINode> oldRightNode = do_QueryInterface(aOldRightNode);
|
||||
nsCOMPtr<nsINode> newLeftNode = do_QueryInterface(aNewLeftNode);
|
||||
return SelAdjSplitNode(oldRightNode, aOffset, newLeftNode);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::SelAdjInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString)
|
||||
nsRangeUpdater::SelAdjJoinNodes(nsINode* aLeftNode,
|
||||
nsINode* aRightNode,
|
||||
nsINode* aParent,
|
||||
int32_t aOffset,
|
||||
int32_t aOldLeftNodeLength)
|
||||
{
|
||||
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
|
||||
if (mLock) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
nsRangeStore* item = mArray[i];
|
||||
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
|
||||
|
||||
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->startOffset = aOldLeftNodeLength;
|
||||
}
|
||||
} else if (item->startNode == aRightNode) {
|
||||
// adjust start point in aRightNode
|
||||
item->startOffset += aOldLeftNodeLength;
|
||||
} else if (item->startNode == aLeftNode) {
|
||||
// adjust start point in aLeftNode
|
||||
item->startNode = aRightNode;
|
||||
}
|
||||
|
||||
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->endOffset = aOldLeftNodeLength;
|
||||
}
|
||||
} else if (item->endNode == aRightNode) {
|
||||
// adjust end point in aRightNode
|
||||
item->endOffset += aOldLeftNodeLength;
|
||||
} else if (item->endNode == aLeftNode) {
|
||||
// adjust end point in aLeftNode
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::SelAdjInsertText(nsIContent* aTextNode, int32_t aOffset,
|
||||
const nsAString &aString)
|
||||
{
|
||||
if (mLock) {
|
||||
// lock set by Will/DidReplaceParent, etc...
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t count = mArray.Length();
|
||||
if (!count) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aTextNode));
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
|
||||
|
||||
uint32_t len=aString.Length(), i;
|
||||
nsRangeStore *item;
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
item = mArray[i];
|
||||
NS_ENSURE_TRUE(aTextNode, NS_ERROR_NULL_POINTER);
|
||||
|
||||
uint32_t len = aString.Length();
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
nsRangeStore* item = mArray[i];
|
||||
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if ((item->startNode.get() == node) && (item->startOffset > aOffset))
|
||||
|
||||
if (item->startNode == aTextNode && item->startOffset > aOffset) {
|
||||
item->startOffset += len;
|
||||
if ((item->endNode.get() == node) && (item->endOffset > aOffset))
|
||||
}
|
||||
if (item->endNode == aTextNode && item->endOffset > aOffset) {
|
||||
item->endOffset += len;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::SelAdjInsertText(nsIDOMCharacterData* aTextNode,
|
||||
int32_t aOffset, const nsAString &aString)
|
||||
{
|
||||
nsCOMPtr<nsIContent> textNode = do_QueryInterface(aTextNode);
|
||||
return SelAdjInsertText(textNode, aOffset, aString);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::SelAdjDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength)
|
||||
nsRangeUpdater::SelAdjDeleteText(nsIContent* aTextNode, int32_t aOffset,
|
||||
int32_t aLength)
|
||||
{
|
||||
if (mLock) return NS_OK; // lock set by Will/DidReplaceParent, etc...
|
||||
if (mLock) {
|
||||
// lock set by Will/DidReplaceParent, etc...
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
uint32_t i, count = mArray.Length();
|
||||
uint32_t count = mArray.Length();
|
||||
if (!count) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsRangeStore *item;
|
||||
nsCOMPtr<nsIDOMNode> node(do_QueryInterface(aTextNode));
|
||||
NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
item = mArray[i];
|
||||
NS_ENSURE_TRUE(aTextNode, NS_ERROR_NULL_POINTER);
|
||||
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
nsRangeStore* item = mArray[i];
|
||||
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if ((item->startNode.get() == node) && (item->startOffset > aOffset))
|
||||
{
|
||||
|
||||
if (item->startNode == aTextNode && item->startOffset > aOffset) {
|
||||
item->startOffset -= aLength;
|
||||
if (item->startOffset < 0) item->startOffset = 0;
|
||||
if (item->startOffset < 0) {
|
||||
item->startOffset = 0;
|
||||
}
|
||||
}
|
||||
if ((item->endNode.get() == node) && (item->endOffset > aOffset))
|
||||
{
|
||||
if (item->endNode == aTextNode && item->endOffset > aOffset) {
|
||||
item->endOffset -= aLength;
|
||||
if (item->endOffset < 0) item->endOffset = 0;
|
||||
if (item->endOffset < 0) {
|
||||
item->endOffset = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::SelAdjDeleteText(nsIDOMCharacterData* aTextNode,
|
||||
int32_t aOffset, int32_t aLength)
|
||||
{
|
||||
nsCOMPtr<nsIContent> textNode = do_QueryInterface(aTextNode);
|
||||
return SelAdjDeleteText(textNode, aOffset, aLength);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::WillReplaceContainer()
|
||||
@ -500,32 +539,40 @@ nsRangeUpdater::WillReplaceContainer()
|
||||
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::DidReplaceContainer(nsIDOMNode *aOriginalNode, nsIDOMNode *aNewNode)
|
||||
nsRangeUpdater::DidReplaceContainer(nsINode* aOriginalNode, nsINode* aNewNode)
|
||||
{
|
||||
NS_ENSURE_TRUE(mLock, NS_ERROR_UNEXPECTED);
|
||||
NS_ENSURE_TRUE(mLock, NS_ERROR_UNEXPECTED);
|
||||
mLock = false;
|
||||
|
||||
NS_ENSURE_TRUE(aOriginalNode && aNewNode, NS_ERROR_NULL_POINTER);
|
||||
uint32_t i, count = mArray.Length();
|
||||
uint32_t count = mArray.Length();
|
||||
if (!count) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRangeStore *item;
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
item = mArray[i];
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
nsRangeStore* item = mArray[i];
|
||||
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (item->startNode.get() == aOriginalNode)
|
||||
if (item->startNode == aOriginalNode) {
|
||||
item->startNode = aNewNode;
|
||||
if (item->endNode.get() == aOriginalNode)
|
||||
}
|
||||
if (item->endNode == aOriginalNode) {
|
||||
item->endNode = aNewNode;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::DidReplaceContainer(nsIDOMNode* aOriginalNode,
|
||||
nsIDOMNode* aNewNode)
|
||||
{
|
||||
nsCOMPtr<nsINode> originalNode = do_QueryInterface(aOriginalNode);
|
||||
nsCOMPtr<nsINode> newNode = do_QueryInterface(aNewNode);
|
||||
return DidReplaceContainer(originalNode, newNode);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::WillRemoveContainer()
|
||||
@ -537,43 +584,48 @@ nsRangeUpdater::WillRemoveContainer()
|
||||
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::DidRemoveContainer(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aOffset, uint32_t aNodeOrigLen)
|
||||
nsRangeUpdater::DidRemoveContainer(nsINode* aNode, nsINode* aParent,
|
||||
int32_t aOffset, uint32_t aNodeOrigLen)
|
||||
{
|
||||
NS_ENSURE_TRUE(mLock, NS_ERROR_UNEXPECTED);
|
||||
NS_ENSURE_TRUE(mLock, NS_ERROR_UNEXPECTED);
|
||||
mLock = false;
|
||||
|
||||
NS_ENSURE_TRUE(aNode && aParent, NS_ERROR_NULL_POINTER);
|
||||
uint32_t i, count = mArray.Length();
|
||||
uint32_t count = mArray.Length();
|
||||
if (!count) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsRangeStore *item;
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
item = mArray[i];
|
||||
for (uint32_t i = 0; i < count; i++) {
|
||||
nsRangeStore* item = mArray[i];
|
||||
NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER);
|
||||
|
||||
if (item->startNode.get() == aNode)
|
||||
{
|
||||
if (item->startNode == aNode) {
|
||||
item->startNode = aParent;
|
||||
item->startOffset += aOffset;
|
||||
} else if (item->startNode == aParent && item->startOffset > aOffset) {
|
||||
item->startOffset += (int32_t)aNodeOrigLen - 1;
|
||||
}
|
||||
else if ((item->startNode.get() == aParent) && (item->startOffset > aOffset))
|
||||
item->startOffset += (int32_t)aNodeOrigLen-1;
|
||||
|
||||
if (item->endNode.get() == aNode)
|
||||
{
|
||||
if (item->endNode == aNode) {
|
||||
item->endNode = aParent;
|
||||
item->endOffset += aOffset;
|
||||
} else if (item->endNode == aParent && item->endOffset > aOffset) {
|
||||
item->endOffset += (int32_t)aNodeOrigLen - 1;
|
||||
}
|
||||
else if ((item->endNode.get() == aParent) && (item->endOffset > aOffset))
|
||||
item->endOffset += (int32_t)aNodeOrigLen-1;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::DidRemoveContainer(nsIDOMNode* aNode, nsIDOMNode* aParent,
|
||||
int32_t aOffset, uint32_t aNodeOrigLen)
|
||||
{
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
|
||||
nsCOMPtr<nsINode> parent = do_QueryInterface(aParent);
|
||||
return DidRemoveContainer(node, parent, aOffset, aNodeOrigLen);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsRangeUpdater::WillInsertContainer()
|
||||
@ -609,26 +661,23 @@ nsRangeUpdater::DidMoveNode(nsINode* aOldParent, int32_t aOldOffset,
|
||||
NS_ENSURE_TRUE_VOID(mLock);
|
||||
mLock = false;
|
||||
|
||||
nsIDOMNode* oldParent = aOldParent->AsDOMNode();
|
||||
nsIDOMNode* newParent = aNewParent->AsDOMNode();
|
||||
|
||||
for (uint32_t i = 0, count = mArray.Length(); i < count; ++i) {
|
||||
nsRangeStore* item = mArray[i];
|
||||
NS_ENSURE_TRUE_VOID(item);
|
||||
|
||||
// like a delete in aOldParent
|
||||
if (item->startNode == oldParent && item->startOffset > aOldOffset) {
|
||||
if (item->startNode == aOldParent && item->startOffset > aOldOffset) {
|
||||
item->startOffset--;
|
||||
}
|
||||
if (item->endNode == oldParent && item->endOffset > aOldOffset) {
|
||||
if (item->endNode == aOldParent && item->endOffset > aOldOffset) {
|
||||
item->endOffset--;
|
||||
}
|
||||
|
||||
// and like an insert in aNewParent
|
||||
if (item->startNode == newParent && item->startOffset > aNewOffset) {
|
||||
if (item->startNode == aNewParent && item->startOffset > aNewOffset) {
|
||||
item->startOffset++;
|
||||
}
|
||||
if (item->endNode == newParent && item->endOffset > aNewOffset) {
|
||||
if (item->endNode == aNewParent && item->endOffset > aNewOffset) {
|
||||
item->endOffset++;
|
||||
}
|
||||
}
|
||||
@ -640,29 +689,28 @@ nsRangeUpdater::DidMoveNode(nsINode* aOldParent, int32_t aOldOffset,
|
||||
* helper class for nsSelectionState. nsRangeStore stores range endpoints.
|
||||
*/
|
||||
|
||||
// DEBUG: int32_t nsRangeStore::n = 0;
|
||||
|
||||
nsRangeStore::nsRangeStore()
|
||||
{
|
||||
// DEBUG: n++; printf("range store alloc count=%d\n", n);
|
||||
}
|
||||
nsRangeStore::~nsRangeStore()
|
||||
{
|
||||
// DEBUG: n--; printf("range store alloc count=%d\n", n);
|
||||
}
|
||||
|
||||
nsresult nsRangeStore::StoreRange(nsIDOMRange *aRange)
|
||||
void
|
||||
nsRangeStore::StoreRange(nsRange* aRange)
|
||||
{
|
||||
NS_ENSURE_TRUE(aRange, NS_ERROR_NULL_POINTER);
|
||||
aRange->GetStartContainer(getter_AddRefs(startNode));
|
||||
aRange->GetEndContainer(getter_AddRefs(endNode));
|
||||
aRange->GetStartOffset(&startOffset);
|
||||
aRange->GetEndOffset(&endOffset);
|
||||
return NS_OK;
|
||||
MOZ_ASSERT(aRange);
|
||||
startNode = aRange->GetStartParent();
|
||||
startOffset = aRange->StartOffset();
|
||||
endNode = aRange->GetEndParent();
|
||||
endOffset = aRange->EndOffset();
|
||||
}
|
||||
|
||||
nsresult nsRangeStore::GetRange(nsRange** outRange)
|
||||
already_AddRefed<nsRange>
|
||||
nsRangeStore::GetRange()
|
||||
{
|
||||
return nsRange::CreateRange(startNode, startOffset, endNode, endOffset,
|
||||
outRange);
|
||||
nsRefPtr<nsRange> range = new nsRange(startNode);
|
||||
nsresult res = range->Set(startNode, startOffset, endNode, endOffset);
|
||||
NS_ENSURE_SUCCESS(res, nullptr);
|
||||
return range.forget();
|
||||
}
|
||||
|
@ -39,16 +39,15 @@ private:
|
||||
~nsRangeStore();
|
||||
|
||||
public:
|
||||
nsresult StoreRange(nsIDOMRange *aRange);
|
||||
nsresult GetRange(nsRange** outRange);
|
||||
void StoreRange(nsRange* aRange);
|
||||
already_AddRefed<nsRange> GetRange();
|
||||
|
||||
NS_INLINE_DECL_REFCOUNTING(nsRangeStore)
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startNode;
|
||||
int32_t startOffset;
|
||||
nsCOMPtr<nsIDOMNode> endNode;
|
||||
int32_t endOffset;
|
||||
// DEBUG: static int32_t n;
|
||||
nsCOMPtr<nsINode> startNode;
|
||||
int32_t startOffset;
|
||||
nsCOMPtr<nsINode> endNode;
|
||||
int32_t endOffset;
|
||||
};
|
||||
|
||||
class nsSelectionState
|
||||
@ -90,22 +89,39 @@ class nsRangeUpdater
|
||||
// if you move a node, that corresponds to deleting it and reinserting it.
|
||||
// DOM Range gravity will promote the selection out of the node on deletion,
|
||||
// which is not what you want if you know you are reinserting it.
|
||||
nsresult SelAdjCreateNode(nsINode* aParent, int32_t aPosition);
|
||||
nsresult SelAdjCreateNode(nsIDOMNode *aParent, int32_t aPosition);
|
||||
nsresult SelAdjInsertNode(nsINode* aParent, int32_t aPosition);
|
||||
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,
|
||||
int32_t aOffset,
|
||||
int32_t aOldLeftNodeLength);
|
||||
nsresult SelAdjInsertText(nsIContent* aTextNode, int32_t aOffset,
|
||||
const nsAString &aString);
|
||||
nsresult SelAdjInsertText(nsIDOMCharacterData *aTextNode, int32_t aOffset, const nsAString &aString);
|
||||
nsresult SelAdjDeleteText(nsIContent* aTextNode, int32_t aOffset,
|
||||
int32_t aLength);
|
||||
nsresult SelAdjDeleteText(nsIDOMCharacterData *aTextNode, int32_t aOffset, int32_t aLength);
|
||||
// the following gravity routines need will/did sandwiches, because the other gravity
|
||||
// routines will be called inside of these sandwiches, but should be ignored.
|
||||
nsresult WillReplaceContainer();
|
||||
nsresult DidReplaceContainer(nsINode* aOriginalNode, nsINode* aNewNode);
|
||||
nsresult DidReplaceContainer(nsIDOMNode *aOriginalNode, nsIDOMNode *aNewNode);
|
||||
nsresult WillRemoveContainer();
|
||||
nsresult DidRemoveContainer(nsINode* aNode, nsINode* aParent,
|
||||
int32_t aOffset, uint32_t aNodeOrigLen);
|
||||
nsresult DidRemoveContainer(nsIDOMNode *aNode, nsIDOMNode *aParent, int32_t aOffset, uint32_t aNodeOrigLen);
|
||||
nsresult WillInsertContainer();
|
||||
nsresult DidInsertContainer();
|
||||
@ -127,14 +143,18 @@ class MOZ_STACK_CLASS nsAutoTrackDOMPoint
|
||||
{
|
||||
private:
|
||||
nsRangeUpdater &mRU;
|
||||
nsCOMPtr<nsIDOMNode> *mNode;
|
||||
int32_t *mOffset;
|
||||
// Allow tracking either nsIDOMNode or nsINode until nsIDOMNode is gone
|
||||
nsCOMPtr<nsINode>* mNode;
|
||||
nsCOMPtr<nsIDOMNode>* mDOMNode;
|
||||
int32_t* mOffset;
|
||||
nsRefPtr<nsRangeStore> mRangeItem;
|
||||
public:
|
||||
nsAutoTrackDOMPoint(nsRangeUpdater &aRangeUpdater, nsCOMPtr<nsIDOMNode> *aNode, int32_t *aOffset) :
|
||||
mRU(aRangeUpdater)
|
||||
,mNode(aNode)
|
||||
,mOffset(aOffset)
|
||||
nsAutoTrackDOMPoint(nsRangeUpdater &aRangeUpdater,
|
||||
nsCOMPtr<nsINode>* aNode, int32_t* aOffset)
|
||||
: mRU(aRangeUpdater)
|
||||
, mNode(aNode)
|
||||
, mDOMNode(nullptr)
|
||||
, mOffset(aOffset)
|
||||
{
|
||||
mRangeItem = new nsRangeStore();
|
||||
mRangeItem->startNode = *mNode;
|
||||
@ -143,11 +163,30 @@ class MOZ_STACK_CLASS nsAutoTrackDOMPoint
|
||||
mRangeItem->endOffset = *mOffset;
|
||||
mRU.RegisterRangeItem(mRangeItem);
|
||||
}
|
||||
|
||||
|
||||
nsAutoTrackDOMPoint(nsRangeUpdater &aRangeUpdater,
|
||||
nsCOMPtr<nsIDOMNode>* aNode, int32_t* aOffset)
|
||||
: mRU(aRangeUpdater)
|
||||
, mNode(nullptr)
|
||||
, mDOMNode(aNode)
|
||||
, mOffset(aOffset)
|
||||
{
|
||||
mRangeItem = new nsRangeStore();
|
||||
mRangeItem->startNode = do_QueryInterface(*mDOMNode);
|
||||
mRangeItem->endNode = do_QueryInterface(*mDOMNode);
|
||||
mRangeItem->startOffset = *mOffset;
|
||||
mRangeItem->endOffset = *mOffset;
|
||||
mRU.RegisterRangeItem(mRangeItem);
|
||||
}
|
||||
|
||||
~nsAutoTrackDOMPoint()
|
||||
{
|
||||
mRU.DropRangeItem(mRangeItem);
|
||||
*mNode = mRangeItem->startNode;
|
||||
if (mNode) {
|
||||
*mNode = mRangeItem->startNode;
|
||||
} else {
|
||||
*mDOMNode = GetAsDOMNode(mRangeItem->startNode);
|
||||
}
|
||||
*mOffset = mRangeItem->startOffset;
|
||||
}
|
||||
};
|
||||
|
@ -49,6 +49,7 @@ class nsIDOMEventListener;
|
||||
class nsISelection;
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
|
||||
// retrieve an integer stored into a CSS computed float value
|
||||
static int32_t GetCSSFloatValue(nsIDOMCSSStyleDeclaration * aDecl,
|
||||
@ -146,14 +147,15 @@ nsHTMLEditor::CreateAnonymousElement(const nsAString & aTag, nsIDOMNode * aPare
|
||||
NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// Create a new node through the element factory
|
||||
nsCOMPtr<dom::Element> newContent;
|
||||
nsresult res = CreateHTMLContent(aTag, getter_AddRefs(newContent));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
ErrorResult rv;
|
||||
nsCOMPtr<Element> newContent = CreateHTMLContent(aTag, rv);
|
||||
NS_ENSURE_SUCCESS(rv.ErrorCode(), rv.ErrorCode());
|
||||
|
||||
nsCOMPtr<nsIDOMElement> newElement = do_QueryInterface(newContent);
|
||||
NS_ENSURE_TRUE(newElement, NS_ERROR_FAILURE);
|
||||
|
||||
// add the "hidden" class if needed
|
||||
nsresult res;
|
||||
if (aIsCreatedHidden) {
|
||||
res = newElement->SetAttribute(NS_LITERAL_STRING("class"),
|
||||
NS_LITERAL_STRING("hidden"));
|
||||
|
@ -568,10 +568,9 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
|
||||
curNode->GetFirstChild(getter_AddRefs(child));
|
||||
}
|
||||
|
||||
}
|
||||
// Check for pre's going into pre's.
|
||||
else if (nsHTMLEditUtils::IsPre(parentBlock) && nsHTMLEditUtils::IsPre(curNode))
|
||||
{
|
||||
} else if (parentBlock && nsHTMLEditUtils::IsPre(parentBlock) &&
|
||||
nsHTMLEditUtils::IsPre(curNode)) {
|
||||
// Check for pre's going into pre's.
|
||||
nsCOMPtr<nsIDOMNode> child, tmp;
|
||||
curNode->GetFirstChild(getter_AddRefs(child));
|
||||
while (child)
|
||||
@ -677,7 +676,7 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
|
||||
{
|
||||
// don't leave selection past an invisible break;
|
||||
// reset {selNode,selOffset} to point before break
|
||||
selNode = GetNodeLocation(wsRunObj.mStartReasonNode, &selOffset);
|
||||
selNode = GetNodeLocation(GetAsDOMNode(wsRunObj.mStartReasonNode), &selOffset);
|
||||
// we want to be inside any inline style prior to break
|
||||
nsWSRunObject wsRunObj(this, selNode, selOffset);
|
||||
wsRunObj.PriorVisibleNode(selNode, selOffset, address_of(visNode),
|
||||
@ -688,7 +687,7 @@ nsHTMLEditor::DoInsertHTMLWithContext(const nsAString & aInputString,
|
||||
} else if (visType == WSType::special) {
|
||||
// prior visible thing is an image or some other non-text thingy.
|
||||
// We want to be right after it.
|
||||
selNode = GetNodeLocation(wsRunObj.mStartReasonNode, &selOffset);
|
||||
selNode = GetNodeLocation(GetAsDOMNode(wsRunObj.mStartReasonNode), &selOffset);
|
||||
++selOffset;
|
||||
}
|
||||
}
|
||||
|
@ -304,26 +304,17 @@ nsHTMLEditRules::BeforeEdit(EditAction action,
|
||||
// remember where our selection was before edit action took place:
|
||||
|
||||
// get selection
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
nsresult res = mHTMLEditor->GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
// get the selection start location
|
||||
nsCOMPtr<nsIDOMNode> selStartNode, selEndNode;
|
||||
int32_t selOffset;
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
res = mHTMLEditor->GetStartNodeAndOffset(selection, getter_AddRefs(selStartNode), &selOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
mRangeItem->startNode = selStartNode;
|
||||
mRangeItem->startOffset = selOffset;
|
||||
nsRefPtr<Selection> selection = mHTMLEditor->GetSelection();
|
||||
|
||||
// get the selection end location
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
res = mHTMLEditor->GetEndNodeAndOffset(selection, getter_AddRefs(selEndNode), &selOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
mRangeItem->endNode = selEndNode;
|
||||
mRangeItem->endOffset = selOffset;
|
||||
// get the selection location
|
||||
NS_ENSURE_STATE(selection->GetRangeCount());
|
||||
mRangeItem->startNode = selection->GetRangeAt(0)->GetStartParent();
|
||||
mRangeItem->startOffset = selection->GetRangeAt(0)->StartOffset();
|
||||
mRangeItem->endNode = selection->GetRangeAt(0)->GetEndParent();
|
||||
mRangeItem->endOffset = selection->GetRangeAt(0)->EndOffset();
|
||||
nsCOMPtr<nsIDOMNode> selStartNode = GetAsDOMNode(mRangeItem->startNode);
|
||||
nsCOMPtr<nsIDOMNode> selEndNode = GetAsDOMNode(mRangeItem->endNode);
|
||||
|
||||
// register this range with range updater to track this as we perturb the doc
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
@ -352,7 +343,7 @@ nsHTMLEditRules::BeforeEdit(EditAction action,
|
||||
nsCOMPtr<nsIDOMNode> selNode = selStartNode;
|
||||
if (aDirection == nsIEditor::eNext)
|
||||
selNode = selEndNode;
|
||||
res = CacheInlineStyles(selNode);
|
||||
nsresult res = CacheInlineStyles(selNode);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
|
||||
@ -490,13 +481,13 @@ nsHTMLEditRules::AfterEditInner(EditAction action,
|
||||
|
||||
// also do this for original selection endpoints.
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
nsWSRunObject(mHTMLEditor, mRangeItem->startNode,
|
||||
nsWSRunObject(mHTMLEditor, GetAsDOMNode(mRangeItem->startNode),
|
||||
mRangeItem->startOffset).AdjustWhitespace();
|
||||
// we only need to handle old selection endpoint if it was different from start
|
||||
if (mRangeItem->startNode != mRangeItem->endNode ||
|
||||
mRangeItem->startOffset != mRangeItem->endOffset) {
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
nsWSRunObject(mHTMLEditor, mRangeItem->endNode,
|
||||
nsWSRunObject(mHTMLEditor, GetAsDOMNode(mRangeItem->endNode),
|
||||
mRangeItem->endOffset).AdjustWhitespace();
|
||||
}
|
||||
}
|
||||
@ -536,7 +527,7 @@ nsHTMLEditRules::AfterEditInner(EditAction action,
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
|
||||
res = mHTMLEditor->HandleInlineSpellCheck(action, selection,
|
||||
mRangeItem->startNode,
|
||||
GetAsDOMNode(mRangeItem->startNode),
|
||||
mRangeItem->startOffset,
|
||||
rangeStartParent, rangeStartOffset,
|
||||
rangeEndParent, rangeEndOffset);
|
||||
@ -1275,8 +1266,7 @@ nsHTMLEditRules::WillInsert(nsISelection *aSelection, bool *aCancel)
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
block2 = mHTMLEditor->GetBlockNodeParent(priorNode);
|
||||
|
||||
if (block1 == block2)
|
||||
{
|
||||
if (block1 && block1 == block2) {
|
||||
// if we are here then the selection is right after a mozBR
|
||||
// that is in the same block as the selection. We need to move
|
||||
// the selection start to be before the mozBR.
|
||||
@ -1490,8 +1480,11 @@ nsHTMLEditRules::WillInsertText(EditAction aAction,
|
||||
// is it a return?
|
||||
else if (subStr.Equals(newlineStr))
|
||||
{
|
||||
res = wsObj.InsertBreak(address_of(curNode), &curOffset, address_of(unused), nsIEditor::eNone);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
nsCOMPtr<nsINode> node(do_QueryInterface(curNode));
|
||||
nsCOMPtr<Element> br =
|
||||
wsObj.InsertBreak(address_of(node), &curOffset, nsIEditor::eNone);
|
||||
NS_ENSURE_TRUE(br, NS_ERROR_FAILURE);
|
||||
curNode = GetAsDOMNode(node);
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
@ -1706,8 +1699,12 @@ nsHTMLEditRules::StandardBreakImpl(nsIDOMNode* aNode, int32_t aOffset,
|
||||
node = linkParent;
|
||||
aOffset = newOffset;
|
||||
}
|
||||
res = wsObj.InsertBreak(address_of(node), &aOffset,
|
||||
address_of(brNode), nsIEditor::eNone);
|
||||
nsCOMPtr<nsINode> node_ = do_QueryInterface(node);
|
||||
nsCOMPtr<Element> br =
|
||||
wsObj.InsertBreak(address_of(node_), &aOffset, nsIEditor::eNone);
|
||||
node = GetAsDOMNode(node_);
|
||||
brNode = GetAsDOMNode(br);
|
||||
NS_ENSURE_TRUE(brNode, NS_ERROR_FAILURE);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
node = nsEditor::GetNodeLocation(brNode, &aOffset);
|
||||
@ -2392,8 +2389,7 @@ nsHTMLEditRules::WillDeleteSelection(Selection* aSelection,
|
||||
}
|
||||
|
||||
// are endpoint block parents the same? use default deletion
|
||||
if (leftParent == rightParent)
|
||||
{
|
||||
if (leftParent && leftParent == rightParent) {
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
res = mHTMLEditor->DeleteSelectionImpl(aAction, aStripWrappers);
|
||||
}
|
||||
@ -2692,6 +2688,7 @@ nsHTMLEditRules::JoinBlocks(nsIDOMNode *aLeftNode,
|
||||
nsCOMPtr<nsIDOMNode> realRight = mHTMLEditor->GetBlockNodeParent(aRightBlock);
|
||||
aRightBlock = realRight;
|
||||
}
|
||||
NS_ENSURE_STATE(aLeftBlock && aRightBlock);
|
||||
|
||||
// bail if both blocks the same
|
||||
if (aLeftBlock == aRightBlock) {
|
||||
@ -2751,16 +2748,21 @@ nsHTMLEditRules::JoinBlocks(nsIDOMNode *aLeftNode,
|
||||
// Do ws adjustment. This just destroys non-visible ws at boundaries we will be joining.
|
||||
rightOffset++;
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
nsCOMPtr<nsINode> leftBlock(do_QueryInterface(aLeftBlock));
|
||||
res = nsWSRunObject::ScrubBlockBoundary(mHTMLEditor,
|
||||
address_of(aLeftBlock),
|
||||
nsWSRunObject::kBlockEnd);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
res = nsWSRunObject::ScrubBlockBoundary(mHTMLEditor,
|
||||
address_of(aRightBlock),
|
||||
nsWSRunObject::kAfterBlock,
|
||||
&rightOffset);
|
||||
nsWSRunObject::kBlockEnd,
|
||||
leftBlock);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
|
||||
{
|
||||
nsAutoTrackDOMPoint tracker(mHTMLEditor->mRangeUpdater,
|
||||
address_of(aRightBlock), &rightOffset);
|
||||
nsCOMPtr<nsINode> rightBlock(do_QueryInterface(aRightBlock));
|
||||
res = nsWSRunObject::ScrubBlockBoundary(mHTMLEditor,
|
||||
nsWSRunObject::kAfterBlock,
|
||||
rightBlock, rightOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
// Do br adjustment.
|
||||
nsCOMPtr<nsIDOMNode> brNode;
|
||||
res = CheckForInvisibleBR(aLeftBlock, kBlockEnd, address_of(brNode));
|
||||
@ -2796,16 +2798,21 @@ nsHTMLEditRules::JoinBlocks(nsIDOMNode *aLeftNode,
|
||||
// tricky case. right block is inside left block.
|
||||
// Do ws adjustment. This just destroys non-visible ws at boundaries we will be joining.
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
nsCOMPtr<nsINode> rightBlock(do_QueryInterface(aRightBlock));
|
||||
res = nsWSRunObject::ScrubBlockBoundary(mHTMLEditor,
|
||||
address_of(aRightBlock),
|
||||
nsWSRunObject::kBlockStart);
|
||||
nsWSRunObject::kBlockStart,
|
||||
rightBlock);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
res = nsWSRunObject::ScrubBlockBoundary(mHTMLEditor,
|
||||
address_of(aLeftBlock),
|
||||
nsWSRunObject::kBeforeBlock,
|
||||
&leftOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
{
|
||||
nsAutoTrackDOMPoint tracker(mHTMLEditor->mRangeUpdater,
|
||||
address_of(aLeftBlock), &leftOffset);
|
||||
nsCOMPtr<nsINode> leftBlock(do_QueryInterface(aLeftBlock));
|
||||
res = nsWSRunObject::ScrubBlockBoundary(mHTMLEditor,
|
||||
nsWSRunObject::kBeforeBlock,
|
||||
leftBlock, leftOffset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
// Do br adjustment.
|
||||
nsCOMPtr<nsIDOMNode> brNode;
|
||||
res = CheckForInvisibleBR(aLeftBlock, kBeforeBlock, address_of(brNode),
|
||||
@ -5089,18 +5096,20 @@ nsHTMLEditRules::CheckForEmptyBlock(nsIDOMNode *aStartNode,
|
||||
else
|
||||
block = mHTMLEditor->GetBlockNodeParent(aStartNode);
|
||||
bool bIsEmptyNode;
|
||||
if (block != aBodyNode) // efficiency hack. avoiding IsEmptyNode() call when in body
|
||||
{
|
||||
if (block && block != aBodyNode) {
|
||||
// efficiency hack. avoiding IsEmptyNode() call when in body
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
res = mHTMLEditor->IsEmptyNode(block, &bIsEmptyNode, true, false);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
while (bIsEmptyNode && !nsHTMLEditUtils::IsTableElement(block) && (block != aBodyNode))
|
||||
{
|
||||
while (block && bIsEmptyNode && !nsHTMLEditUtils::IsTableElement(block) &&
|
||||
block != aBodyNode) {
|
||||
emptyBlock = block;
|
||||
block = mHTMLEditor->GetBlockNodeParent(emptyBlock);
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
res = mHTMLEditor->IsEmptyNode(block, &bIsEmptyNode, true, false);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
if (block) {
|
||||
res = mHTMLEditor->IsEmptyNode(block, &bIsEmptyNode, true, false);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -5194,7 +5203,7 @@ nsHTMLEditRules::CheckForInvisibleBR(nsIDOMNode *aBlock,
|
||||
{
|
||||
nsWSRunObject wsTester(mHTMLEditor, testNode, testOffset);
|
||||
if (WSType::br == wsTester.mStartReason) {
|
||||
*outBRNode = wsTester.mStartReasonNode;
|
||||
*outBRNode = GetAsDOMNode(wsTester.mStartReasonNode);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5284,6 +5293,7 @@ nsHTMLEditRules::ExpandSelectionForDeletion(nsISelection *aSelection)
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
if (!IsBlockNode(selCommon))
|
||||
selCommon = nsHTMLEditor::GetBlockNodeParent(selCommon);
|
||||
NS_ENSURE_STATE(selCommon);
|
||||
|
||||
// set up for loops and cache our root element
|
||||
bool stillLooking = true;
|
||||
@ -5305,15 +5315,14 @@ nsHTMLEditRules::ExpandSelectionForDeletion(nsISelection *aSelection)
|
||||
if (wsType == WSType::thisBlock) {
|
||||
// we want to keep looking up. But stop if we are crossing table element
|
||||
// boundaries, or if we hit the root.
|
||||
if ( nsHTMLEditUtils::IsTableElement(wsObj.mStartReasonNode) ||
|
||||
(selCommon == wsObj.mStartReasonNode) ||
|
||||
(rootElement == wsObj.mStartReasonNode) )
|
||||
{
|
||||
if (nsHTMLEditUtils::IsTableElement(wsObj.mStartReasonNode) ||
|
||||
selCommon == GetAsDOMNode(wsObj.mStartReasonNode) ||
|
||||
rootElement == GetAsDOMNode(wsObj.mStartReasonNode)) {
|
||||
stillLooking = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
selStartNode = nsEditor::GetNodeLocation(wsObj.mStartReasonNode,
|
||||
selStartNode = nsEditor::GetNodeLocation(GetAsDOMNode(wsObj.mStartReasonNode),
|
||||
&selStartOffset);
|
||||
}
|
||||
}
|
||||
@ -5345,21 +5354,20 @@ nsHTMLEditRules::ExpandSelectionForDeletion(nsISelection *aSelection)
|
||||
firstBRParent = selEndNode;
|
||||
firstBROffset = selEndOffset;
|
||||
}
|
||||
selEndNode = nsEditor::GetNodeLocation(wsObj.mEndReasonNode, &selEndOffset);
|
||||
selEndNode = nsEditor::GetNodeLocation(GetAsDOMNode(wsObj.mEndReasonNode), &selEndOffset);
|
||||
++selEndOffset;
|
||||
}
|
||||
} else if (wsType == WSType::thisBlock) {
|
||||
// we want to keep looking up. But stop if we are crossing table element
|
||||
// boundaries, or if we hit the root.
|
||||
if ( nsHTMLEditUtils::IsTableElement(wsObj.mEndReasonNode) ||
|
||||
(selCommon == wsObj.mEndReasonNode) ||
|
||||
(rootElement == wsObj.mEndReasonNode) )
|
||||
{
|
||||
if (nsHTMLEditUtils::IsTableElement(wsObj.mEndReasonNode) ||
|
||||
selCommon == GetAsDOMNode(wsObj.mEndReasonNode) ||
|
||||
rootElement == GetAsDOMNode(wsObj.mEndReasonNode)) {
|
||||
stillLooking = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
selEndNode = nsEditor::GetNodeLocation(wsObj.mEndReasonNode, &selEndOffset);
|
||||
selEndNode = nsEditor::GetNodeLocation(GetAsDOMNode(wsObj.mEndReasonNode), &selEndOffset);
|
||||
++selEndOffset;
|
||||
}
|
||||
}
|
||||
@ -5395,7 +5403,10 @@ nsHTMLEditRules::ExpandSelectionForDeletion(nsISelection *aSelection)
|
||||
|
||||
// check if block is entirely inside range
|
||||
nsCOMPtr<nsIContent> brContentBlock = do_QueryInterface(brBlock);
|
||||
res = nsRange::CompareNodeToRange(brContentBlock, range, &nodeBefore, &nodeAfter);
|
||||
if (brContentBlock) {
|
||||
res = nsRange::CompareNodeToRange(brContentBlock, range, &nodeBefore,
|
||||
&nodeAfter);
|
||||
}
|
||||
|
||||
// if block isn't contained, forgo grabbing the br in the expanded selection
|
||||
if (nodeBefore || nodeAfter)
|
||||
@ -5479,7 +5490,7 @@ nsHTMLEditRules::NormalizeSelection(nsISelection *inSelection)
|
||||
// of going "down" into a block and "up" out of a block.
|
||||
if (wsEndObj.mStartReason == WSType::otherBlock) {
|
||||
// endpoint is just after the close of a block.
|
||||
nsCOMPtr<nsIDOMNode> child = mHTMLEditor->GetRightmostChild(wsEndObj.mStartReasonNode, true);
|
||||
nsCOMPtr<nsIDOMNode> child = mHTMLEditor->GetRightmostChild(GetAsDOMNode(wsEndObj.mStartReasonNode), true);
|
||||
if (child)
|
||||
{
|
||||
newEndNode = nsEditor::GetNodeLocation(child, &newEndOffset);
|
||||
@ -5499,7 +5510,7 @@ nsHTMLEditRules::NormalizeSelection(nsISelection *inSelection)
|
||||
// else block is empty - we can leave selection alone here, i think.
|
||||
} else if (wsEndObj.mStartReason == WSType::br) {
|
||||
// endpoint is just after break. lets adjust it to before it.
|
||||
newEndNode = nsEditor::GetNodeLocation(wsEndObj.mStartReasonNode,
|
||||
newEndNode = nsEditor::GetNodeLocation(GetAsDOMNode(wsEndObj.mStartReasonNode),
|
||||
&newEndOffset);
|
||||
}
|
||||
}
|
||||
@ -5516,7 +5527,7 @@ nsHTMLEditRules::NormalizeSelection(nsISelection *inSelection)
|
||||
// of going "down" into a block and "up" out of a block.
|
||||
if (wsStartObj.mEndReason == WSType::otherBlock) {
|
||||
// startpoint is just before the start of a block.
|
||||
nsCOMPtr<nsIDOMNode> child = mHTMLEditor->GetLeftmostChild(wsStartObj.mEndReasonNode, true);
|
||||
nsCOMPtr<nsIDOMNode> child = mHTMLEditor->GetLeftmostChild(GetAsDOMNode(wsStartObj.mEndReasonNode), true);
|
||||
if (child)
|
||||
{
|
||||
newStartNode = nsEditor::GetNodeLocation(child, &newStartOffset);
|
||||
@ -5534,7 +5545,7 @@ nsHTMLEditRules::NormalizeSelection(nsISelection *inSelection)
|
||||
// else block is empty - we can leave selection alone here, i think.
|
||||
} else if (wsStartObj.mEndReason == WSType::br) {
|
||||
// startpoint is just before a break. lets adjust it to after it.
|
||||
newStartNode = nsEditor::GetNodeLocation(wsStartObj.mEndReasonNode,
|
||||
newStartNode = nsEditor::GetNodeLocation(GetAsDOMNode(wsStartObj.mEndReasonNode),
|
||||
&newStartOffset);
|
||||
++newStartOffset; // offset *after* break
|
||||
}
|
||||
@ -5937,7 +5948,7 @@ nsHTMLEditRules::GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges,
|
||||
{
|
||||
opRange = inArrayOfRanges[0];
|
||||
rangeItemArray[i] = new nsRangeStore();
|
||||
rangeItemArray[i]->StoreRange(opRange);
|
||||
rangeItemArray[i]->StoreRange(static_cast<nsRange*>(opRange.get()));
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
mHTMLEditor->mRangeUpdater.RegisterRangeItem(rangeItemArray[i]);
|
||||
inArrayOfRanges.RemoveObjectAt(0);
|
||||
@ -5954,14 +5965,7 @@ nsHTMLEditRules::GetNodesForOperation(nsCOMArray<nsIDOMRange>& inArrayOfRanges,
|
||||
nsRangeStore* item = rangeItemArray[i];
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
mHTMLEditor->mRangeUpdater.DropRangeItem(item);
|
||||
nsRefPtr<nsRange> range;
|
||||
nsresult res2 = item->GetRange(getter_AddRefs(range));
|
||||
opRange = range;
|
||||
if (NS_FAILED(res2) && NS_SUCCEEDED(res)) {
|
||||
// Remember the failure, but keep going so we make sure to unregister
|
||||
// all our range items.
|
||||
res = res2;
|
||||
}
|
||||
opRange = item->GetRange();
|
||||
inArrayOfRanges.AppendObject(opRange);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
@ -6326,7 +6330,8 @@ nsHTMLEditRules::BustUpInlinesAtRangeEndpoints(nsRangeStore &item)
|
||||
nsresult res = NS_OK;
|
||||
bool isCollapsed = ((item.startNode == item.endNode) && (item.startOffset == item.endOffset));
|
||||
|
||||
nsCOMPtr<nsIDOMNode> endInline = GetHighestInlineParent(item.endNode);
|
||||
nsCOMPtr<nsIDOMNode> endInline =
|
||||
GetHighestInlineParent(GetAsDOMNode(item.endNode));
|
||||
|
||||
// if we have inline parents above range endpoints, split them
|
||||
if (endInline && !isCollapsed)
|
||||
@ -6335,14 +6340,16 @@ nsHTMLEditRules::BustUpInlinesAtRangeEndpoints(nsRangeStore &item)
|
||||
int32_t resultEndOffset;
|
||||
endInline->GetParentNode(getter_AddRefs(resultEndNode));
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
res = mHTMLEditor->SplitNodeDeep(endInline, item.endNode, item.endOffset,
|
||||
&resultEndOffset, true);
|
||||
res = mHTMLEditor->SplitNodeDeep(endInline, GetAsDOMNode(item.endNode),
|
||||
item.endOffset, &resultEndOffset, true);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
// reset range
|
||||
item.endNode = resultEndNode; item.endOffset = resultEndOffset;
|
||||
item.endNode = do_QueryInterface(resultEndNode);
|
||||
item.endOffset = resultEndOffset;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> startInline = GetHighestInlineParent(item.startNode);
|
||||
nsCOMPtr<nsIDOMNode> startInline =
|
||||
GetHighestInlineParent(GetAsDOMNode(item.startNode));
|
||||
|
||||
if (startInline)
|
||||
{
|
||||
@ -6350,11 +6357,13 @@ nsHTMLEditRules::BustUpInlinesAtRangeEndpoints(nsRangeStore &item)
|
||||
int32_t resultStartOffset;
|
||||
startInline->GetParentNode(getter_AddRefs(resultStartNode));
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
res = mHTMLEditor->SplitNodeDeep(startInline, item.startNode, item.startOffset,
|
||||
&resultStartOffset, true);
|
||||
res = mHTMLEditor->SplitNodeDeep(startInline, GetAsDOMNode(item.startNode),
|
||||
item.startOffset, &resultStartOffset,
|
||||
true);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
// reset range
|
||||
item.startNode = resultStartNode; item.startOffset = resultStartOffset;
|
||||
item.startNode = do_QueryInterface(resultStartNode);
|
||||
item.startOffset = resultStartOffset;
|
||||
}
|
||||
|
||||
return res;
|
||||
@ -6465,22 +6474,10 @@ nsHTMLEditRules::GetNodesFromPoint(::DOMPoint point,
|
||||
nsCOMArray<nsIDOMNode> &arrayOfNodes,
|
||||
bool dontTouchContent)
|
||||
{
|
||||
nsresult res;
|
||||
|
||||
// get our point
|
||||
nsCOMPtr<nsIDOMNode> node;
|
||||
int32_t offset;
|
||||
point.GetPoint(node, offset);
|
||||
|
||||
// use it to make a range
|
||||
nsCOMPtr<nsINode> nativeNode = do_QueryInterface(node);
|
||||
NS_ENSURE_STATE(nativeNode);
|
||||
nsRefPtr<nsRange> range = new nsRange(nativeNode);
|
||||
res = range->SetStart(node, offset);
|
||||
NS_ENSURE_STATE(point.node);
|
||||
nsRefPtr<nsRange> range = new nsRange(point.node);
|
||||
nsresult res = range->SetStart(point.node, point.offset);
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
/* SetStart() will also set the end for this new range
|
||||
res = range->SetEnd(node, offset);
|
||||
NS_ENSURE_SUCCESS(res, res); */
|
||||
|
||||
// expand the range to include adjacent inlines
|
||||
res = PromoteRange(range, operation);
|
||||
@ -7200,8 +7197,7 @@ nsHTMLEditRules::RemoveBlockStyle(nsCOMArray<nsIDOMNode>& arrayOfNodes)
|
||||
}
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
curBlock = mHTMLEditor->GetBlockNodeParent(curNode);
|
||||
if (nsHTMLEditUtils::IsFormatNode(curBlock))
|
||||
{
|
||||
if (curBlock && nsHTMLEditUtils::IsFormatNode(curBlock)) {
|
||||
firstNode = curNode;
|
||||
lastNode = curNode;
|
||||
}
|
||||
@ -7932,8 +7928,7 @@ nsHTMLEditRules::AdjustSelection(nsISelection *aSelection, nsIEditor::EDirection
|
||||
}
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
nearBlock = mHTMLEditor->GetBlockNodeParent(nearNode);
|
||||
if (block == nearBlock)
|
||||
{
|
||||
if (block && block == nearBlock) {
|
||||
if (nearNode && nsTextEditUtils::IsBreak(nearNode) )
|
||||
{
|
||||
NS_ENSURE_STATE(mHTMLEditor);
|
||||
|
@ -234,12 +234,18 @@ nsHTMLEditUtils::IsTableElementButNotTable(nsINode* aNode)
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// IsTable: true if node an html table
|
||||
//
|
||||
bool
|
||||
bool
|
||||
nsHTMLEditUtils::IsTable(nsIDOMNode* aNode)
|
||||
{
|
||||
return nsEditor::NodeIsType(aNode, nsEditProperty::table);
|
||||
}
|
||||
|
||||
bool
|
||||
nsHTMLEditUtils::IsTable(nsINode* aNode)
|
||||
{
|
||||
return aNode && aNode->IsElement() && aNode->Tag() == nsGkAtoms::table;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// IsTableRow: true if node an html tr
|
||||
//
|
||||
@ -359,13 +365,22 @@ nsHTMLEditUtils::IsImage(nsIDOMNode* aNode)
|
||||
bool
|
||||
nsHTMLEditUtils::IsLink(nsIDOMNode *aNode)
|
||||
{
|
||||
NS_ENSURE_TRUE(aNode, false);
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
|
||||
return node && IsLink(node);
|
||||
}
|
||||
|
||||
bool
|
||||
nsHTMLEditUtils::IsLink(nsINode* aNode)
|
||||
{
|
||||
MOZ_ASSERT(aNode);
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLAnchorElement> anchor = do_QueryInterface(aNode);
|
||||
if (anchor)
|
||||
{
|
||||
nsAutoString tmpText;
|
||||
if (NS_SUCCEEDED(anchor->GetHref(tmpText)) && !tmpText.IsEmpty())
|
||||
if (NS_SUCCEEDED(anchor->GetHref(tmpText)) && !tmpText.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ public:
|
||||
static bool IsListItem(nsINode* aNode);
|
||||
static bool IsListItem(nsIDOMNode *aNode);
|
||||
static bool IsTable(nsIDOMNode *aNode);
|
||||
static bool IsTable(nsINode* aNode);
|
||||
static bool IsTableRow(nsIDOMNode *aNode);
|
||||
static bool IsTableElement(nsINode* aNode);
|
||||
static bool IsTableElement(nsIDOMNode *aNode);
|
||||
@ -46,6 +47,7 @@ public:
|
||||
static bool IsAnchor(nsIDOMNode *aNode);
|
||||
static bool IsImage(nsIDOMNode *aNode);
|
||||
static bool IsLink(nsIDOMNode *aNode);
|
||||
static bool IsLink(nsINode* aNode);
|
||||
static bool IsNamedAnchor(nsINode* aNode);
|
||||
static bool IsNamedAnchor(nsIDOMNode *aNode);
|
||||
static bool IsDiv(nsIDOMNode *aNode);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -111,7 +111,7 @@ public:
|
||||
virtual already_AddRefed<nsIContent> FindSelectionRoot(nsINode *aNode);
|
||||
virtual bool IsAcceptableInputEvent(nsIDOMEvent* aEvent);
|
||||
virtual already_AddRefed<nsIContent> GetInputEventTargetContent();
|
||||
virtual bool IsEditable(nsIContent *aNode);
|
||||
virtual bool IsEditable(nsINode* aNode) MOZ_OVERRIDE;
|
||||
using nsEditor::IsEditable;
|
||||
|
||||
/* ------------ nsStubMutationObserver overrides --------- */
|
||||
@ -229,6 +229,7 @@ public:
|
||||
NS_IMETHOD SetHTMLBackgroundColor(const nsAString& aColor);
|
||||
|
||||
/* ------------ Block methods moved from nsEditor -------------- */
|
||||
static already_AddRefed<mozilla::dom::Element> GetBlockNodeParent(nsINode* aNode);
|
||||
static already_AddRefed<nsIDOMNode> GetBlockNodeParent(nsIDOMNode *aNode);
|
||||
|
||||
void IsNextCharInNodeWhitespace(nsIContent* aContent,
|
||||
@ -286,7 +287,8 @@ public:
|
||||
virtual bool TagCanContainTag(nsIAtom* aParentTag, nsIAtom* aChildTag);
|
||||
|
||||
/** returns true if aNode is a container */
|
||||
virtual bool IsContainer(nsIDOMNode *aNode);
|
||||
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);
|
||||
@ -342,7 +344,8 @@ public:
|
||||
// This will stop at a table, however, since we don't want to
|
||||
// "drill down" into nested tables.
|
||||
// aSelection is optional -- if null, we get current seletion
|
||||
nsresult CollapseSelectionToDeepestNonTableFirstChild(nsISelection *aSelection, nsIDOMNode *aNode);
|
||||
void CollapseSelectionToDeepestNonTableFirstChild(
|
||||
mozilla::dom::Selection* aSelection, nsINode* aNode);
|
||||
|
||||
/**
|
||||
* aNode must be a non-null text node.
|
||||
@ -417,6 +420,8 @@ protected:
|
||||
|
||||
// key event helpers
|
||||
NS_IMETHOD TabInTable(bool inIsShift, bool *outHandled);
|
||||
already_AddRefed<mozilla::dom::Element> CreateBR(nsINode* aNode,
|
||||
int32_t aOffset, EDirection aSelect = eNone);
|
||||
NS_IMETHOD CreateBR(nsIDOMNode *aNode, int32_t aOffset,
|
||||
nsCOMPtr<nsIDOMNode> *outBRNode, nsIEditor::EDirection aSelect = nsIEditor::eNone);
|
||||
|
||||
@ -485,6 +490,8 @@ protected:
|
||||
|
||||
// End of Table Editing utilities
|
||||
|
||||
static already_AddRefed<mozilla::dom::Element>
|
||||
GetEnclosingTable(nsINode* aNode);
|
||||
static nsCOMPtr<nsIDOMNode> GetEnclosingTable(nsIDOMNode *aNode);
|
||||
|
||||
/** content-based query returns true if <aProperty aAttribute=aValue> effects aNode
|
||||
@ -608,6 +615,7 @@ protected:
|
||||
nsIDOMNode* GetArrayEndpoint(bool aEnd, nsCOMArray<nsIDOMNode>& aNodeArray);
|
||||
|
||||
/* small utility routine to test if a break node is visible to user */
|
||||
bool IsVisBreak(nsINode* aNode);
|
||||
bool IsVisBreak(nsIDOMNode *aNode);
|
||||
|
||||
/* utility routine to possibly adjust the insertion position when
|
||||
@ -956,6 +964,10 @@ private:
|
||||
void DoContentInserted(nsIDocument* aDocument, nsIContent* aContainer,
|
||||
nsIContent* aChild, int32_t aIndexInContainer,
|
||||
InsertedOrAppended aInsertedOrAppended);
|
||||
already_AddRefed<mozilla::dom::Element> GetElementOrParentByTagName(
|
||||
const nsAString& aTagName, nsINode* aNode);
|
||||
already_AddRefed<mozilla::dom::Element> CreateElementWithDefaults(
|
||||
const nsAString& aTagName);
|
||||
};
|
||||
#endif //nsHTMLEditor_h__
|
||||
|
||||
|
@ -312,11 +312,10 @@ nsHTMLEditor::IsSimpleModifiableNode(nsIContent* aContent,
|
||||
// "text-decoration: underline", which decomposes into four different text-*
|
||||
// properties. So for now, we just create a span, add the desired style, and
|
||||
// see if it matches.
|
||||
nsCOMPtr<dom::Element> newSpan;
|
||||
nsresult res = CreateHTMLContent(NS_LITERAL_STRING("span"),
|
||||
getter_AddRefs(newSpan));
|
||||
NS_ASSERTION(NS_SUCCEEDED(res), "CreateHTMLContent failed");
|
||||
NS_ENSURE_SUCCESS(res, false);
|
||||
ErrorResult rv;
|
||||
nsCOMPtr<Element> newSpan = CreateHTMLContent(NS_LITERAL_STRING("span"), rv);
|
||||
NS_ASSERTION(!rv.Failed(), "CreateHTMLContent failed");
|
||||
NS_ENSURE_SUCCESS(rv.ErrorCode(), false);
|
||||
mHTMLCSSUtils->SetCSSEquivalentToHTMLStyle(newSpan, aProperty,
|
||||
aAttribute, aValue,
|
||||
/*suppress transaction*/ true);
|
||||
|
@ -3086,9 +3086,8 @@ nsHTMLEditor::SetSelectionAfterTableEdit(nsIDOMElement* aTable, int32_t aRow, in
|
||||
{
|
||||
NS_ENSURE_TRUE(aTable, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
nsCOMPtr<nsISelection>selection;
|
||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
||||
NS_ENSURE_SUCCESS(res, res);
|
||||
nsRefPtr<Selection> selection = GetSelection();
|
||||
nsresult res;
|
||||
|
||||
if (!selection)
|
||||
{
|
||||
@ -3117,7 +3116,11 @@ nsHTMLEditor::SetSelectionAfterTableEdit(nsIDOMElement* aTable, int32_t aRow, in
|
||||
// but don't go into nested tables
|
||||
// TODO: Should we really be placing the caret at the END
|
||||
// of the cell content?
|
||||
return CollapseSelectionToDeepestNonTableFirstChild(selection, cell);
|
||||
nsCOMPtr<nsINode> cellNode = do_QueryInterface(cell);
|
||||
if (cellNode) {
|
||||
CollapseSelectionToDeepestNonTableFirstChild(selection, cellNode);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
// Setup index to find another cell in the
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -8,11 +8,11 @@
|
||||
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsINode.h"
|
||||
#include "nscore.h"
|
||||
#include "mozilla/dom/Text.h"
|
||||
|
||||
class nsHTMLEditor;
|
||||
class nsIDOMDocument;
|
||||
@ -153,6 +153,7 @@ class MOZ_STACK_CLASS nsWSRunObject
|
||||
enum {eBoth = eBefore | eAfter};
|
||||
|
||||
// constructor / destructor -----------------------------------------------
|
||||
nsWSRunObject(nsHTMLEditor* aEd, nsINode* aNode, int32_t aOffset);
|
||||
nsWSRunObject(nsHTMLEditor *aEd, nsIDOMNode *aNode, int32_t aOffset);
|
||||
~nsWSRunObject();
|
||||
|
||||
@ -160,10 +161,10 @@ class MOZ_STACK_CLASS nsWSRunObject
|
||||
|
||||
// ScrubBlockBoundary removes any non-visible whitespace at the specified
|
||||
// location relative to a block node.
|
||||
static nsresult ScrubBlockBoundary(nsHTMLEditor *aHTMLEd,
|
||||
nsCOMPtr<nsIDOMNode> *aBlock,
|
||||
static nsresult ScrubBlockBoundary(nsHTMLEditor* aHTMLEd,
|
||||
BlockBoundary aBoundary,
|
||||
int32_t *aOffset = 0);
|
||||
nsINode* aBlock,
|
||||
int32_t aOffset = -1);
|
||||
|
||||
// PrepareToJoinBlocks fixes up ws at the end of aLeftParent and the
|
||||
// beginning of aRightParent in preperation for them to be joined.
|
||||
@ -179,6 +180,11 @@ class MOZ_STACK_CLASS nsWSRunObject
|
||||
// adjusting ws.
|
||||
// example of fixup: trailingws before {aStartNode,aStartOffset}
|
||||
// needs to be removed.
|
||||
static nsresult PrepareToDeleteRange(nsHTMLEditor* aHTMLEd,
|
||||
nsCOMPtr<nsINode>* aStartNode,
|
||||
int32_t* aStartOffset,
|
||||
nsCOMPtr<nsINode>* aEndNode,
|
||||
int32_t* aEndOffset);
|
||||
static nsresult PrepareToDeleteRange(nsHTMLEditor *aHTMLEd,
|
||||
nsCOMPtr<nsIDOMNode> *aStartNode,
|
||||
int32_t *aStartOffset,
|
||||
@ -206,10 +212,9 @@ class MOZ_STACK_CLASS nsWSRunObject
|
||||
// and makes any needed adjustments to ws around that point.
|
||||
// example of fixup: normalws after {aInOutParent,aInOutOffset}
|
||||
// needs to begin with nbsp.
|
||||
nsresult InsertBreak(nsCOMPtr<nsIDOMNode> *aInOutParent,
|
||||
int32_t *aInOutOffset,
|
||||
nsCOMPtr<nsIDOMNode> *outBRNode,
|
||||
nsIEditor::EDirection aSelect);
|
||||
already_AddRefed<mozilla::dom::Element>
|
||||
InsertBreak(nsCOMPtr<nsINode>* aInOutParent, int32_t* aInOutOffset,
|
||||
nsIEditor::EDirection aSelect);
|
||||
|
||||
// InsertText inserts a string at {aInOutParent,aInOutOffset}
|
||||
// and makes any needed adjustments to ws around that point.
|
||||
@ -266,10 +271,10 @@ class MOZ_STACK_CLASS nsWSRunObject
|
||||
// still span multiple nodes.
|
||||
struct WSFragment
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> mStartNode; // node where ws run starts
|
||||
nsCOMPtr<nsIDOMNode> mEndNode; // node where ws run ends
|
||||
int32_t mStartOffset; // offset where ws run starts
|
||||
int32_t mEndOffset; // offset where ws run ends
|
||||
nsCOMPtr<nsINode> mStartNode; // node where ws run starts
|
||||
nsCOMPtr<nsINode> mEndNode; // node where ws run ends
|
||||
int32_t mStartOffset; // offset where ws run starts
|
||||
int32_t mEndOffset; // offset where ws run ends
|
||||
// type of ws, and what is to left and right of it
|
||||
WSType mType, mLeftType, mRightType;
|
||||
// other ws runs to left or right. may be null.
|
||||
@ -290,21 +295,17 @@ class MOZ_STACK_CLASS nsWSRunObject
|
||||
// stored in the struct.
|
||||
struct MOZ_STACK_CLASS WSPoint
|
||||
{
|
||||
nsCOMPtr<nsIContent> mTextNode;
|
||||
nsCOMPtr<mozilla::dom::Text> mTextNode;
|
||||
uint32_t mOffset;
|
||||
char16_t mChar;
|
||||
|
||||
WSPoint() : mTextNode(0),mOffset(0),mChar(0) {}
|
||||
WSPoint(nsIDOMNode *aNode, int32_t aOffset, char16_t aChar) :
|
||||
WSPoint(nsINode* aNode, int32_t aOffset, char16_t aChar) :
|
||||
mTextNode(do_QueryInterface(aNode)),mOffset(aOffset),mChar(aChar)
|
||||
{
|
||||
if (!mTextNode->IsNodeOfType(nsINode::eDATA_NODE)) {
|
||||
// Not sure if this is needed, but it'll maintain the same
|
||||
// functionality
|
||||
mTextNode = nullptr;
|
||||
}
|
||||
MOZ_ASSERT(mTextNode->IsNodeOfType(nsINode::eTEXT));
|
||||
}
|
||||
WSPoint(nsIContent *aTextNode, int32_t aOffset, char16_t aChar) :
|
||||
WSPoint(mozilla::dom::Text* aTextNode, int32_t aOffset, char16_t aChar) :
|
||||
mTextNode(aTextNode),mOffset(aOffset),mChar(aChar) {}
|
||||
};
|
||||
|
||||
@ -321,34 +322,20 @@ class MOZ_STACK_CLASS nsWSRunObject
|
||||
* closest block within the DOM subtree we're editing, or if none is
|
||||
* found, the (inline) root of the editable subtree.
|
||||
*/
|
||||
already_AddRefed<nsIDOMNode> GetWSBoundingParent();
|
||||
already_AddRefed<nsINode> GetWSBoundingParent();
|
||||
|
||||
nsresult GetWSNodes();
|
||||
void GetRuns();
|
||||
void ClearRuns();
|
||||
void MakeSingleWSRun(WSType aType);
|
||||
nsresult PrependNodeToList(nsIDOMNode *aNode);
|
||||
nsresult AppendNodeToList(nsIDOMNode *aNode);
|
||||
nsresult GetPreviousWSNode(nsIDOMNode *aStartNode,
|
||||
nsIDOMNode *aBlockParent,
|
||||
nsCOMPtr<nsIDOMNode> *aPriorNode);
|
||||
nsresult GetPreviousWSNode(nsIDOMNode *aStartNode,
|
||||
int32_t aOffset,
|
||||
nsIDOMNode *aBlockParent,
|
||||
nsCOMPtr<nsIDOMNode> *aPriorNode);
|
||||
nsresult PrependNodeToList(nsINode* aNode);
|
||||
nsresult AppendNodeToList(nsINode* aNode);
|
||||
nsresult GetPreviousWSNode(::DOMPoint aPoint,
|
||||
nsIDOMNode *aBlockParent,
|
||||
nsCOMPtr<nsIDOMNode> *aPriorNode);
|
||||
nsresult GetNextWSNode(nsIDOMNode *aStartNode,
|
||||
nsIDOMNode *aBlockParent,
|
||||
nsCOMPtr<nsIDOMNode> *aNextNode);
|
||||
nsresult GetNextWSNode(nsIDOMNode *aStartNode,
|
||||
int32_t aOffset,
|
||||
nsIDOMNode *aBlockParent,
|
||||
nsCOMPtr<nsIDOMNode> *aNextNode);
|
||||
nsINode* aBlockParent,
|
||||
nsCOMPtr<nsINode>* aPriorNode);
|
||||
nsresult GetNextWSNode(::DOMPoint aPoint,
|
||||
nsIDOMNode *aBlockParent,
|
||||
nsCOMPtr<nsIDOMNode> *aNextNode);
|
||||
nsINode* aBlockParent,
|
||||
nsCOMPtr<nsINode>* aNextNode);
|
||||
nsresult PrepareToDeleteRangePriv(nsWSRunObject* aEndObject);
|
||||
nsresult PrepareToSplitAcrossBlocksPriv();
|
||||
nsresult DeleteChars(nsIDOMNode *aStartNode, int32_t aStartOffset,
|
||||
@ -360,6 +347,11 @@ class MOZ_STACK_CLASS nsWSRunObject
|
||||
WSPoint GetCharBefore(const WSPoint &aPoint);
|
||||
nsresult ConvertToNBSP(WSPoint aPoint,
|
||||
AreaRestriction aAR = eAnywhere);
|
||||
void GetAsciiWSBounds(int16_t aDir, nsINode* aNode, int32_t aOffset,
|
||||
mozilla::dom::Text** outStartNode,
|
||||
int32_t* outStartOffset,
|
||||
mozilla::dom::Text** outEndNode,
|
||||
int32_t* outEndOffset);
|
||||
void GetAsciiWSBounds(int16_t aDir, nsIDOMNode *aNode, int32_t aOffset,
|
||||
nsCOMPtr<nsIDOMNode> *outStartNode, int32_t *outStartOffset,
|
||||
nsCOMPtr<nsIDOMNode> *outEndNode, int32_t *outEndOffset);
|
||||
@ -371,40 +363,41 @@ class MOZ_STACK_CLASS nsWSRunObject
|
||||
nsresult CheckTrailingNBSP(WSFragment *aRun, nsIDOMNode *aNode, int32_t aOffset);
|
||||
nsresult CheckLeadingNBSP(WSFragment *aRun, nsIDOMNode *aNode, int32_t aOffset);
|
||||
|
||||
static nsresult ScrubBlockBoundaryInner(nsHTMLEditor *aHTMLEd,
|
||||
nsCOMPtr<nsIDOMNode> *aBlock,
|
||||
BlockBoundary aBoundary);
|
||||
nsresult Scrub();
|
||||
nsresult GetPreviousWSNodeInner(nsINode* aStartNode, nsINode* aBlockParent,
|
||||
nsCOMPtr<nsINode>* aPriorNode);
|
||||
nsresult GetNextWSNodeInner(nsINode* aStartNode, nsINode* aBlockParent,
|
||||
nsCOMPtr<nsINode>* aNextNode);
|
||||
|
||||
// member variables ---------------------------------------------------------
|
||||
|
||||
nsCOMPtr<nsIDOMNode> mNode; // the node passed to our constructor
|
||||
int32_t mOffset; // the offset passed to our contructor
|
||||
nsCOMPtr<nsINode> mNode; // the node passed to our constructor
|
||||
int32_t mOffset; // the offset passed to our contructor
|
||||
// together, the above represent the point at which we are building up ws info.
|
||||
|
||||
bool mPRE; // true if we are in preformatted whitespace context
|
||||
nsCOMPtr<nsIDOMNode> mStartNode; // node/offset where ws starts
|
||||
int32_t mStartOffset; // ...
|
||||
WSType mStartReason; // reason why ws starts (eText, eOtherBlock, etc)
|
||||
nsCOMPtr<nsIDOMNode> mStartReasonNode;// the node that implicated by start reason
|
||||
bool mPRE; // true if we are in preformatted whitespace context
|
||||
nsCOMPtr<nsINode> mStartNode; // node/offset where ws starts
|
||||
int32_t mStartOffset; // ...
|
||||
WSType mStartReason; // reason why ws starts (eText, eOtherBlock, etc)
|
||||
nsCOMPtr<nsINode> mStartReasonNode;// the node that implicated by start reason
|
||||
|
||||
nsCOMPtr<nsIDOMNode> mEndNode; // node/offset where ws ends
|
||||
int32_t mEndOffset; // ...
|
||||
WSType mEndReason; // reason why ws ends (eText, eOtherBlock, etc)
|
||||
nsCOMPtr<nsIDOMNode> mEndReasonNode; // the node that implicated by end reason
|
||||
nsCOMPtr<nsINode> mEndNode; // node/offset where ws ends
|
||||
int32_t mEndOffset; // ...
|
||||
WSType mEndReason; // reason why ws ends (eText, eOtherBlock, etc)
|
||||
nsCOMPtr<nsINode> mEndReasonNode; // the node that implicated by end reason
|
||||
|
||||
nsCOMPtr<nsIDOMNode> mFirstNBSPNode; // location of first nbsp in ws run, if any
|
||||
int32_t mFirstNBSPOffset; // ...
|
||||
nsCOMPtr<nsINode> mFirstNBSPNode; // location of first nbsp in ws run, if any
|
||||
int32_t mFirstNBSPOffset; // ...
|
||||
|
||||
nsCOMPtr<nsIDOMNode> mLastNBSPNode; // location of last nbsp in ws run, if any
|
||||
int32_t mLastNBSPOffset; // ...
|
||||
nsCOMPtr<nsINode> mLastNBSPNode; // location of last nbsp in ws run, if any
|
||||
int32_t mLastNBSPOffset; // ...
|
||||
|
||||
nsCOMArray<nsIDOMNode> mNodeArray;//the list of nodes containing ws in this run
|
||||
nsCOMArray<nsINode> mNodeArray; //the list of nodes containing ws in this run
|
||||
|
||||
WSFragment *mStartRun; // the first WSFragment in the run
|
||||
WSFragment *mEndRun; // the last WSFragment in the run, may be same as first
|
||||
WSFragment *mStartRun; // the first WSFragment in the run
|
||||
WSFragment *mEndRun; // the last WSFragment in the run, may be same as first
|
||||
|
||||
nsHTMLEditor *mHTMLEditor; // non-owning.
|
||||
nsHTMLEditor *mHTMLEditor; // non-owning.
|
||||
|
||||
friend class nsHTMLEditRules; // opening this class up for pillaging
|
||||
friend class nsHTMLEditor; // opening this class up for more pillaging
|
||||
|
@ -438,6 +438,20 @@ nsPlaintextEditor::TypedText(const nsAString& aString, ETypingAction aAction)
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<Element>
|
||||
nsPlaintextEditor::CreateBRImpl(nsCOMPtr<nsINode>* aInOutParent,
|
||||
int32_t* aInOutOffset,
|
||||
EDirection aSelect)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> parent(GetAsDOMNode(*aInOutParent));
|
||||
nsCOMPtr<nsIDOMNode> br;
|
||||
// We ignore the retval, and assume it's fine if the br is non-null
|
||||
CreateBRImpl(address_of(parent), aInOutOffset, address_of(br), aSelect);
|
||||
*aInOutParent = do_QueryInterface(parent);
|
||||
nsCOMPtr<Element> ret(do_QueryInterface(br));
|
||||
return ret.forget();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPlaintextEditor::CreateBRImpl(nsCOMPtr<nsIDOMNode>* aInOutParent,
|
||||
int32_t* aInOutOffset,
|
||||
|
@ -176,6 +176,9 @@ protected:
|
||||
// key event helpers
|
||||
NS_IMETHOD CreateBR(nsIDOMNode *aNode, int32_t aOffset,
|
||||
nsCOMPtr<nsIDOMNode> *outBRNode, EDirection aSelect = eNone);
|
||||
already_AddRefed<mozilla::dom::Element>
|
||||
CreateBRImpl(nsCOMPtr<nsINode>* aInOutParent, int32_t* aInOutOffset,
|
||||
EDirection aSelect);
|
||||
nsresult CreateBRImpl(nsCOMPtr<nsIDOMNode>* aInOutParent,
|
||||
int32_t* aInOutOffset,
|
||||
nsCOMPtr<nsIDOMNode>* outBRNode,
|
||||
|
@ -1158,9 +1158,10 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsISelection *aSelection)
|
||||
}
|
||||
|
||||
// Create a br.
|
||||
nsCOMPtr<dom::Element> newContent;
|
||||
nsresult rv = mEditor->CreateHTMLContent(NS_LITERAL_STRING("br"), getter_AddRefs(newContent));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
ErrorResult res;
|
||||
nsCOMPtr<Element> newContent =
|
||||
mEditor->CreateHTMLContent(NS_LITERAL_STRING("br"), res);
|
||||
NS_ENSURE_SUCCESS(res.ErrorCode(), res.ErrorCode());
|
||||
|
||||
// set mBogusNode to be the newly created <br>
|
||||
mBogusNode = do_QueryInterface(newContent);
|
||||
@ -1172,7 +1173,7 @@ nsTextEditRules::CreateBogusNodeIfNeeded(nsISelection *aSelection)
|
||||
|
||||
// Put the node in the document.
|
||||
nsCOMPtr<nsIDOMNode> bodyNode = do_QueryInterface(body);
|
||||
rv = mEditor->InsertNode(mBogusNode, bodyNode, 0);
|
||||
nsresult rv = mEditor->InsertNode(mBogusNode, bodyNode, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Set selection.
|
||||
|
@ -38,6 +38,13 @@ nsTextEditUtils::IsBreak(nsIDOMNode *node)
|
||||
{
|
||||
return nsEditor::NodeIsType(node, nsGkAtoms::br);
|
||||
}
|
||||
|
||||
bool
|
||||
nsTextEditUtils::IsBreak(nsINode* aNode)
|
||||
{
|
||||
MOZ_ASSERT(aNode);
|
||||
return aNode->IsElement() && aNode->AsElement()->IsHTML(nsGkAtoms::br);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -23,6 +23,7 @@ public:
|
||||
// from nsTextEditRules:
|
||||
static bool IsBody(nsIDOMNode* aNode);
|
||||
static bool IsBreak(nsIDOMNode* aNode);
|
||||
static bool IsBreak(nsINode* aNode);
|
||||
static bool IsMozBR(nsIDOMNode* aNode);
|
||||
static bool IsMozBR(nsINode* aNode);
|
||||
static bool HasMozAttr(nsIDOMNode* aNode);
|
||||
|
@ -613,6 +613,10 @@ CairoImage::~CairoImage()
|
||||
TextureClient*
|
||||
CairoImage::GetTextureClient(CompositableClient *aClient)
|
||||
{
|
||||
if (!aClient) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CompositableForwarder* forwarder = aClient->GetForwarder();
|
||||
RefPtr<TextureClient> textureClient = mTextureClients.Get(forwarder->GetSerial());
|
||||
if (textureClient) {
|
||||
@ -621,12 +625,18 @@ CairoImage::GetTextureClient(CompositableClient *aClient)
|
||||
|
||||
RefPtr<SourceSurface> surface = GetAsSourceSurface();
|
||||
MOZ_ASSERT(surface);
|
||||
if (!surface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// gfx::BackendType::NONE means default to content backend
|
||||
textureClient = aClient->CreateTextureClientForDrawing(surface->GetFormat(),
|
||||
TextureFlags::DEFAULT,
|
||||
gfx::BackendType::NONE,
|
||||
surface->GetSize());
|
||||
if (!textureClient) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(textureClient->CanExposeDrawTarget());
|
||||
if (!textureClient->AllocateForSurface(surface->GetSize()) ||
|
||||
!textureClient->Lock(OpenMode::OPEN_WRITE_ONLY)) {
|
||||
|
@ -329,13 +329,14 @@ APZCCallbackHelper::GetDOMWindowUtils(const nsIContent* aContent)
|
||||
}
|
||||
|
||||
bool
|
||||
APZCCallbackHelper::GetScrollIdentifiers(const nsIContent* aContent,
|
||||
uint32_t* aPresShellIdOut,
|
||||
FrameMetrics::ViewID* aViewIdOut)
|
||||
APZCCallbackHelper::GetOrCreateScrollIdentifiers(nsIContent* aContent,
|
||||
uint32_t* aPresShellIdOut,
|
||||
FrameMetrics::ViewID* aViewIdOut)
|
||||
{
|
||||
if (!aContent || !nsLayoutUtils::FindIDFor(aContent, aViewIdOut)) {
|
||||
if (!aContent) {
|
||||
return false;
|
||||
}
|
||||
*aViewIdOut = nsLayoutUtils::FindOrCreateIDFor(aContent);
|
||||
nsCOMPtr<nsIDOMWindowUtils> utils = GetDOMWindowUtils(aContent);
|
||||
return utils && (utils->GetPresShellId(aPresShellIdOut) == NS_OK);
|
||||
}
|
||||
|
@ -58,11 +58,13 @@ public:
|
||||
element. This might be an iframe inside the tab, for instance. */
|
||||
static already_AddRefed<nsIDOMWindowUtils> GetDOMWindowUtils(const nsIContent* aContent);
|
||||
|
||||
/* Get the presShellId and view ID for the given content element, if they can be
|
||||
found. Returns false if the values could not be found, true if they could. */
|
||||
static bool GetScrollIdentifiers(const nsIContent* aContent,
|
||||
uint32_t* aPresShellIdOut,
|
||||
FrameMetrics::ViewID* aViewIdOut);
|
||||
/* Get the presShellId and view ID for the given content element.
|
||||
* If the view ID does not exist, one is created.
|
||||
* The pres shell ID should generally already exist; if it doesn't for some
|
||||
* reason, false is returned. */
|
||||
static bool GetOrCreateScrollIdentifiers(nsIContent* aContent,
|
||||
uint32_t* aPresShellIdOut,
|
||||
FrameMetrics::ViewID* aViewIdOut);
|
||||
|
||||
/* Tell layout that we received the scroll offset update for the given view ID, so
|
||||
that it accepts future scroll offset updates from APZ. */
|
||||
|
@ -399,6 +399,16 @@ class StoreBuffer
|
||||
buffer.unput(this, edge);
|
||||
}
|
||||
|
||||
template <typename Buffer, typename Edge>
|
||||
void putFromMainThread(Buffer &buffer, const Edge &edge) {
|
||||
if (!isEnabled())
|
||||
return;
|
||||
JS_ASSERT(CurrentThreadCanAccessRuntime(runtime_));
|
||||
mozilla::ReentrancyGuard g(*this);
|
||||
if (edge.maybeInRememberedSet(nursery_))
|
||||
buffer.put(this, edge);
|
||||
}
|
||||
|
||||
MonoTypeBuffer<ValueEdge> bufferVal;
|
||||
MonoTypeBuffer<CellPtrEdge> bufferCell;
|
||||
MonoTypeBuffer<SlotsEdge> bufferSlot;
|
||||
@ -438,9 +448,9 @@ class StoreBuffer
|
||||
void putSlotFromAnyThread(JSObject *obj, int kind, int32_t start, int32_t count) {
|
||||
putFromAnyThread(bufferSlot, SlotsEdge(obj, kind, start, count));
|
||||
}
|
||||
void putWholeCell(Cell *cell) {
|
||||
void putWholeCellFromMainThread(Cell *cell) {
|
||||
JS_ASSERT(cell->isTenured());
|
||||
putFromAnyThread(bufferWholeCell, WholeCellEdges(cell));
|
||||
putFromMainThread(bufferWholeCell, WholeCellEdges(cell));
|
||||
}
|
||||
|
||||
/* Insert or update a single edge in the Relocatable buffer. */
|
||||
|
@ -67,7 +67,7 @@ class Linker
|
||||
masm.link(code);
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (masm.embedsNurseryPointers())
|
||||
cx->runtime()->gc.storeBuffer.putWholeCell(code);
|
||||
cx->runtime()->gc.storeBuffer.putWholeCellFromMainThread(code);
|
||||
#endif
|
||||
return code;
|
||||
}
|
||||
|
@ -553,8 +553,8 @@ NewCallObject(JSContext *cx, HandleShape shape, HandleTypeObject type, HeapSlot
|
||||
// The JIT creates call objects in the nursery, so elides barriers for
|
||||
// the initializing writes. The interpreter, however, may have allocated
|
||||
// the call object tenured, so barrier as needed before re-entering.
|
||||
if (!IsInsideNursery(cx->runtime(), obj))
|
||||
cx->runtime()->gc.storeBuffer.putWholeCell(obj);
|
||||
if (!IsInsideNursery(obj))
|
||||
cx->runtime()->gc.storeBuffer.putWholeCellFromMainThread(obj);
|
||||
#endif
|
||||
|
||||
return obj;
|
||||
@ -571,9 +571,9 @@ NewSingletonCallObject(JSContext *cx, HandleShape shape, HeapSlot *slots)
|
||||
// The JIT creates call objects in the nursery, so elides barriers for
|
||||
// the initializing writes. The interpreter, however, may have allocated
|
||||
// the call object tenured, so barrier as needed before re-entering.
|
||||
MOZ_ASSERT(!IsInsideNursery(cx->runtime(), obj),
|
||||
MOZ_ASSERT(!IsInsideNursery(obj),
|
||||
"singletons are created in the tenured heap");
|
||||
cx->runtime()->gc.storeBuffer.putWholeCell(obj);
|
||||
cx->runtime()->gc.storeBuffer.putWholeCellFromMainThread(obj);
|
||||
#endif
|
||||
|
||||
return obj;
|
||||
@ -714,7 +714,7 @@ void
|
||||
PostWriteBarrier(JSRuntime *rt, JSObject *obj)
|
||||
{
|
||||
JS_ASSERT(!IsInsideNursery(rt, obj));
|
||||
rt->gc.storeBuffer.putWholeCell(obj);
|
||||
rt->gc.storeBuffer.putWholeCellFromMainThread(obj);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -1503,7 +1503,7 @@ static void
|
||||
GeneratorWriteBarrierPost(JSContext *cx, JSGenerator *gen)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
cx->runtime()->gc.storeBuffer.putWholeCell(gen->obj);
|
||||
cx->runtime()->gc.storeBuffer.putWholeCellFromMainThread(gen->obj);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -276,7 +276,7 @@ PostBarrierTypedArrayObject(JSObject *obj)
|
||||
JS_ASSERT(obj);
|
||||
JSRuntime *rt = obj->runtimeFromMainThread();
|
||||
if (!rt->isHeapBusy() && !IsInsideNursery(rt, obj))
|
||||
rt->gc.storeBuffer.putWholeCell(obj);
|
||||
rt->gc.storeBuffer.putWholeCellFromMainThread(obj);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -42,6 +42,8 @@ NS_IMPL_FRAMEARENA_HELPERS(nsNumberControlFrame)
|
||||
NS_QUERYFRAME_HEAD(nsNumberControlFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsNumberControlFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIAnonymousContentCreator)
|
||||
NS_QUERYFRAME_ENTRY(nsITextControlFrame)
|
||||
NS_QUERYFRAME_ENTRY(nsIFormControlFrame)
|
||||
NS_QUERYFRAME_TAIL_INHERITING(nsContainerFrame)
|
||||
|
||||
nsNumberControlFrame::nsNumberControlFrame(nsStyleContext* aContext)
|
||||
@ -254,6 +256,12 @@ nsNumberControlFrame::ContentStatesChanged(EventStates aStates)
|
||||
}
|
||||
}
|
||||
|
||||
nsITextControlFrame*
|
||||
nsNumberControlFrame::GetTextFieldFrame()
|
||||
{
|
||||
return do_QueryFrame(GetAnonTextControl()->GetPrimaryFrame());
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNumberControlFrame::MakeAnonymousElement(Element** aResult,
|
||||
nsTArray<ContentInfo>& aElements,
|
||||
@ -407,6 +415,84 @@ nsNumberControlFrame::GetType() const
|
||||
return nsGkAtoms::numberControlFrame;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNumberControlFrame::GetEditor(nsIEditor **aEditor)
|
||||
{
|
||||
return GetTextFieldFrame()->GetEditor(aEditor);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNumberControlFrame::SetSelectionStart(int32_t aSelectionStart)
|
||||
{
|
||||
return GetTextFieldFrame()->SetSelectionStart(aSelectionStart);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNumberControlFrame::SetSelectionEnd(int32_t aSelectionEnd)
|
||||
{
|
||||
return GetTextFieldFrame()->SetSelectionEnd(aSelectionEnd);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNumberControlFrame::SetSelectionRange(int32_t aSelectionStart,
|
||||
int32_t aSelectionEnd,
|
||||
SelectionDirection aDirection)
|
||||
{
|
||||
return GetTextFieldFrame()->SetSelectionRange(aSelectionStart, aSelectionEnd,
|
||||
aDirection);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNumberControlFrame::GetSelectionRange(int32_t* aSelectionStart,
|
||||
int32_t* aSelectionEnd,
|
||||
SelectionDirection* aDirection)
|
||||
{
|
||||
return GetTextFieldFrame()->GetSelectionRange(aSelectionStart, aSelectionEnd,
|
||||
aDirection);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNumberControlFrame::GetOwnedSelectionController(nsISelectionController** aSelCon)
|
||||
{
|
||||
return GetTextFieldFrame()->GetOwnedSelectionController(aSelCon);
|
||||
}
|
||||
|
||||
nsFrameSelection*
|
||||
nsNumberControlFrame::GetOwnedFrameSelection()
|
||||
{
|
||||
return GetTextFieldFrame()->GetOwnedFrameSelection();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNumberControlFrame::GetPhonetic(nsAString& aPhonetic)
|
||||
{
|
||||
return GetTextFieldFrame()->GetPhonetic(aPhonetic);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNumberControlFrame::EnsureEditorInitialized()
|
||||
{
|
||||
return GetTextFieldFrame()->EnsureEditorInitialized();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNumberControlFrame::ScrollSelectionIntoView()
|
||||
{
|
||||
return GetTextFieldFrame()->ScrollSelectionIntoView();
|
||||
}
|
||||
|
||||
void
|
||||
nsNumberControlFrame::SetFocus(bool aOn, bool aRepaint)
|
||||
{
|
||||
GetTextFieldFrame()->SetFocus(aOn, aRepaint);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNumberControlFrame::SetFormProperty(nsIAtom* aName, const nsAString& aValue)
|
||||
{
|
||||
return GetTextFieldFrame()->SetFormProperty(aName, aValue);
|
||||
}
|
||||
|
||||
HTMLInputElement*
|
||||
nsNumberControlFrame::GetAnonTextControl()
|
||||
{
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsContainerFrame.h"
|
||||
#include "nsIFormControlFrame.h"
|
||||
#include "nsITextControlFrame.h"
|
||||
#include "nsIAnonymousContentCreator.h"
|
||||
#include "nsCOMPtr.h"
|
||||
|
||||
@ -27,6 +28,7 @@ class HTMLInputElement;
|
||||
*/
|
||||
class nsNumberControlFrame MOZ_FINAL : public nsContainerFrame
|
||||
, public nsIAnonymousContentCreator
|
||||
, public nsITextControlFrame
|
||||
{
|
||||
friend nsIFrame*
|
||||
NS_NewNumberControlFrame(nsIPresShell* aPresShell, nsStyleContext* aContext);
|
||||
@ -83,6 +85,38 @@ public:
|
||||
~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock));
|
||||
}
|
||||
|
||||
// nsITextControlFrame
|
||||
NS_IMETHOD GetEditor(nsIEditor **aEditor) MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD SetSelectionStart(int32_t aSelectionStart) MOZ_OVERRIDE;
|
||||
NS_IMETHOD SetSelectionEnd(int32_t aSelectionEnd) MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD SetSelectionRange(int32_t aSelectionStart,
|
||||
int32_t aSelectionEnd,
|
||||
SelectionDirection aDirection = eNone) MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD GetSelectionRange(int32_t* aSelectionStart,
|
||||
int32_t* aSelectionEnd,
|
||||
SelectionDirection* aDirection = nullptr) MOZ_OVERRIDE;
|
||||
|
||||
NS_IMETHOD GetOwnedSelectionController(nsISelectionController** aSelCon) MOZ_OVERRIDE;
|
||||
virtual nsFrameSelection* GetOwnedFrameSelection() MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult GetPhonetic(nsAString& aPhonetic) MOZ_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Ensure mEditor is initialized with the proper flags and the default value.
|
||||
* @throws NS_ERROR_NOT_INITIALIZED if mEditor has not been created
|
||||
* @throws various and sundry other things
|
||||
*/
|
||||
virtual nsresult EnsureEditorInitialized() MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult ScrollSelectionIntoView() MOZ_OVERRIDE;
|
||||
|
||||
// nsIFormControlFrame
|
||||
virtual void SetFocus(bool aOn, bool aRepaint) MOZ_OVERRIDE;
|
||||
virtual nsresult SetFormProperty(nsIAtom* aName, const nsAString& aValue) MOZ_OVERRIDE;
|
||||
|
||||
/**
|
||||
* This method attempts to localizes aValue and then sets the result as the
|
||||
* value of our anonymous text control. It's called when our
|
||||
@ -158,6 +192,7 @@ public:
|
||||
|
||||
private:
|
||||
|
||||
nsITextControlFrame* GetTextFieldFrame();
|
||||
nsresult MakeAnonymousElement(Element** aResult,
|
||||
nsTArray<ContentInfo>& aElements,
|
||||
nsIAtom* aTagName,
|
||||
|
@ -658,7 +658,7 @@ public:
|
||||
virtual void ResetScrollPositionForLayerPixelAlignment() MOZ_OVERRIDE {
|
||||
mHelper.ResetScrollPositionForLayerPixelAlignment();
|
||||
}
|
||||
virtual bool DidHistoryRestore() MOZ_OVERRIDE {
|
||||
virtual bool DidHistoryRestore() const MOZ_OVERRIDE {
|
||||
return mHelper.mDidHistoryRestore;
|
||||
}
|
||||
virtual void ClearDidHistoryRestore() MOZ_OVERRIDE {
|
||||
@ -972,7 +972,7 @@ public:
|
||||
virtual void ResetScrollPositionForLayerPixelAlignment() MOZ_OVERRIDE {
|
||||
mHelper.ResetScrollPositionForLayerPixelAlignment();
|
||||
}
|
||||
virtual bool DidHistoryRestore() MOZ_OVERRIDE {
|
||||
virtual bool DidHistoryRestore() const MOZ_OVERRIDE {
|
||||
return mHelper.mDidHistoryRestore;
|
||||
}
|
||||
virtual void ClearDidHistoryRestore() MOZ_OVERRIDE {
|
||||
|
@ -270,7 +270,7 @@ public:
|
||||
/**
|
||||
* Was the current presentation state for this frame restored from history?
|
||||
*/
|
||||
virtual bool DidHistoryRestore() = 0;
|
||||
virtual bool DidHistoryRestore() const = 0;
|
||||
/**
|
||||
* Clear the flag so that DidHistoryRestore() returns false until the next
|
||||
* RestoreState call.
|
||||
|
@ -994,7 +994,7 @@ Declaration::GetValue(nsCSSProperty aProperty, nsAString& aValue,
|
||||
aValue, aSerialization);
|
||||
break;
|
||||
} else if (!(autoFlowValue.GetUnit() == eCSSUnit_Enumerated &&
|
||||
autoFlowValue.GetIntValue() == NS_STYLE_GRID_AUTO_FLOW_NONE &&
|
||||
autoFlowValue.GetIntValue() == NS_STYLE_GRID_AUTO_FLOW_ROW &&
|
||||
autoColumnsValue.GetUnit() == eCSSUnit_Auto &&
|
||||
autoRowsValue.GetUnit() == eCSSUnit_Auto)) {
|
||||
// Not serializable, bail.
|
||||
|
@ -508,6 +508,7 @@ CSS_KEY(space-around, space_around)
|
||||
CSS_KEY(space-between, space_between)
|
||||
CSS_KEY(span, span)
|
||||
CSS_KEY(square, square)
|
||||
CSS_KEY(stack, stack)
|
||||
CSS_KEY(stacked-fractions, stacked_fractions)
|
||||
CSS_KEY(start, start)
|
||||
CSS_KEY(static, static)
|
||||
|
@ -694,7 +694,6 @@ protected:
|
||||
bool ParseGrid();
|
||||
bool ParseGridShorthandAutoProps();
|
||||
bool ParseGridLine(nsCSSValue& aValue);
|
||||
bool ParseGridAutoPosition();
|
||||
bool ParseGridColumnRowStartEnd(nsCSSProperty aPropID);
|
||||
bool ParseGridColumnRow(nsCSSProperty aStartPropID,
|
||||
nsCSSProperty aEndPropID);
|
||||
@ -6952,7 +6951,8 @@ CSSParserImpl::ParseGridAutoFlow()
|
||||
}
|
||||
|
||||
static const int32_t mask[] = {
|
||||
NS_STYLE_GRID_AUTO_FLOW_COLUMN | NS_STYLE_GRID_AUTO_FLOW_ROW,
|
||||
NS_STYLE_GRID_AUTO_FLOW_ROW | NS_STYLE_GRID_AUTO_FLOW_COLUMN,
|
||||
NS_STYLE_GRID_AUTO_FLOW_DENSE | NS_STYLE_GRID_AUTO_FLOW_STACK,
|
||||
MASK_END_VALUE
|
||||
};
|
||||
if (!ParseBitmaskValues(value, nsCSSProps::kGridAutoFlowKTable, mask)) {
|
||||
@ -6961,16 +6961,16 @@ CSSParserImpl::ParseGridAutoFlow()
|
||||
int32_t bitField = value.GetIntValue();
|
||||
|
||||
// Requires one of these
|
||||
if (!(bitField & NS_STYLE_GRID_AUTO_FLOW_NONE ||
|
||||
if (!(bitField & NS_STYLE_GRID_AUTO_FLOW_ROW ||
|
||||
bitField & NS_STYLE_GRID_AUTO_FLOW_COLUMN ||
|
||||
bitField & NS_STYLE_GRID_AUTO_FLOW_ROW)) {
|
||||
bitField & NS_STYLE_GRID_AUTO_FLOW_STACK)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 'none' is only valid if it occurs alone:
|
||||
if (bitField & NS_STYLE_GRID_AUTO_FLOW_NONE &&
|
||||
bitField != NS_STYLE_GRID_AUTO_FLOW_NONE) {
|
||||
return false;
|
||||
// 'stack' without 'row' or 'column' defaults to 'stack row'
|
||||
if (bitField == NS_STYLE_GRID_AUTO_FLOW_STACK) {
|
||||
value.SetIntValue(bitField | NS_STYLE_GRID_AUTO_FLOW_ROW,
|
||||
eCSSUnit_Enumerated);
|
||||
}
|
||||
|
||||
AppendValue(eCSSProperty_grid_auto_flow, value);
|
||||
@ -7825,37 +7825,17 @@ CSSParserImpl::ParseGrid()
|
||||
return true;
|
||||
}
|
||||
|
||||
// 'none' at the beginning could be a <'grid-auto-flow'>
|
||||
// (which also covers 'none' by itself)
|
||||
// or a <'grid-template-columns'> (as part of <'grid-template'>)
|
||||
if (ParseVariant(value, VARIANT_NONE, nullptr)) {
|
||||
if (ExpectSymbol('/', true)) {
|
||||
AppendValue(eCSSProperty_grid_template_columns, value);
|
||||
|
||||
// Set grid-auto-* subproperties to their initial values.
|
||||
value.SetIntValue(NS_STYLE_GRID_AUTO_FLOW_NONE, eCSSUnit_Enumerated);
|
||||
AppendValue(eCSSProperty_grid_auto_flow, value);
|
||||
value.SetAutoValue();
|
||||
AppendValue(eCSSProperty_grid_auto_columns, value);
|
||||
AppendValue(eCSSProperty_grid_auto_rows, value);
|
||||
|
||||
return ParseGridTemplateAfterSlash(/* aColumnsIsTrackList = */ false);
|
||||
}
|
||||
value.SetIntValue(NS_STYLE_GRID_AUTO_FLOW_NONE, eCSSUnit_Enumerated);
|
||||
AppendValue(eCSSProperty_grid_auto_flow, value);
|
||||
return ParseGridShorthandAutoProps();
|
||||
}
|
||||
|
||||
// An empty value is always invalid.
|
||||
if (!GetToken(true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If the value starts with a 'dense', 'column' or 'row' keyword,
|
||||
// it can only start with a <'grid-auto-flow'>
|
||||
// The values starts with a <'grid-auto-flow'> if and only if
|
||||
// it starts with a 'stack', 'dense', 'column' or 'row' keyword.
|
||||
if (mToken.mType == eCSSToken_Ident) {
|
||||
nsCSSKeyword keyword = nsCSSKeywords::LookupKeyword(mToken.mIdent);
|
||||
if (keyword == eCSSKeyword_dense ||
|
||||
if (keyword == eCSSKeyword_stack ||
|
||||
keyword == eCSSKeyword_dense ||
|
||||
keyword == eCSSKeyword_column ||
|
||||
keyword == eCSSKeyword_row) {
|
||||
UngetToken();
|
||||
@ -7866,7 +7846,7 @@ CSSParserImpl::ParseGrid()
|
||||
|
||||
// Set other subproperties to their initial values
|
||||
// and parse <'grid-template'>.
|
||||
value.SetIntValue(NS_STYLE_GRID_AUTO_FLOW_NONE, eCSSUnit_Enumerated);
|
||||
value.SetIntValue(NS_STYLE_GRID_AUTO_FLOW_ROW, eCSSUnit_Enumerated);
|
||||
AppendValue(eCSSProperty_grid_auto_flow, value);
|
||||
value.SetAutoValue();
|
||||
AppendValue(eCSSProperty_grid_auto_columns, value);
|
||||
@ -8010,26 +7990,6 @@ CSSParserImpl::ParseGridLine(nsCSSValue& aValue)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseGridAutoPosition()
|
||||
{
|
||||
nsCSSValue value;
|
||||
if (ParseVariant(value, VARIANT_INHERIT, nullptr)) {
|
||||
AppendValue(eCSSProperty_grid_auto_position, value);
|
||||
return true;
|
||||
}
|
||||
nsCSSValue columnStartValue;
|
||||
nsCSSValue rowStartValue;
|
||||
if (ParseGridLine(columnStartValue) &&
|
||||
ExpectSymbol('/', true) &&
|
||||
ParseGridLine(rowStartValue)) {
|
||||
value.SetPairValue(columnStartValue, rowStartValue);
|
||||
AppendValue(eCSSProperty_grid_auto_position, value);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
CSSParserImpl::ParseGridColumnRowStartEnd(nsCSSProperty aPropID)
|
||||
{
|
||||
@ -9179,8 +9139,6 @@ CSSParserImpl::ParsePropertyByFunction(nsCSSProperty aPropID)
|
||||
return ParseGridTemplate();
|
||||
case eCSSProperty_grid:
|
||||
return ParseGrid();
|
||||
case eCSSProperty_grid_auto_position:
|
||||
return ParseGridAutoPosition();
|
||||
case eCSSProperty_grid_column_start:
|
||||
case eCSSProperty_grid_column_end:
|
||||
case eCSSProperty_grid_row_start:
|
||||
|
@ -2034,16 +2034,6 @@ CSS_PROP_POSITION(
|
||||
kGridTrackBreadthKTable,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_POSITION(
|
||||
grid-auto-position,
|
||||
grid_auto_position,
|
||||
GridAutoPosition,
|
||||
CSS_PROPERTY_PARSE_FUNCTION,
|
||||
"layout.css.grid.enabled",
|
||||
0,
|
||||
nullptr,
|
||||
CSS_PROP_NO_OFFSET,
|
||||
eStyleAnimType_None)
|
||||
CSS_PROP_POSITION(
|
||||
grid-template-areas,
|
||||
grid_template_areas,
|
||||
|
@ -1238,9 +1238,9 @@ const KTableValue nsCSSProps::kFontWeightKTable[] = {
|
||||
};
|
||||
|
||||
const KTableValue nsCSSProps::kGridAutoFlowKTable[] = {
|
||||
eCSSKeyword_none, NS_STYLE_GRID_AUTO_FLOW_NONE,
|
||||
eCSSKeyword_column, NS_STYLE_GRID_AUTO_FLOW_COLUMN,
|
||||
eCSSKeyword_stack, NS_STYLE_GRID_AUTO_FLOW_STACK,
|
||||
eCSSKeyword_row, NS_STYLE_GRID_AUTO_FLOW_ROW,
|
||||
eCSSKeyword_column, NS_STYLE_GRID_AUTO_FLOW_COLUMN,
|
||||
eCSSKeyword_dense, NS_STYLE_GRID_AUTO_FLOW_DENSE,
|
||||
eCSSKeyword_UNKNOWN,-1
|
||||
};
|
||||
|
@ -1032,12 +1032,11 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
|
||||
|
||||
case eCSSProperty_grid_auto_flow:
|
||||
nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
|
||||
NS_STYLE_GRID_AUTO_FLOW_NONE,
|
||||
NS_STYLE_GRID_AUTO_FLOW_STACK,
|
||||
NS_STYLE_GRID_AUTO_FLOW_DENSE,
|
||||
aResult);
|
||||
break;
|
||||
|
||||
case eCSSProperty_grid_auto_position:
|
||||
case eCSSProperty_grid_column_start:
|
||||
case eCSSProperty_grid_column_end:
|
||||
case eCSSProperty_grid_row_start:
|
||||
@ -1326,10 +1325,6 @@ nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult,
|
||||
nsStyleUtil::ComputeFunctionalAlternates(list, altValues);
|
||||
nsStyleUtil::SerializeFunctionalAlternates(altValues, out);
|
||||
aResult.Append(out);
|
||||
} else if (eCSSProperty_grid_auto_position == aProperty) {
|
||||
GetPairValue().mXValue.AppendToString(aProperty, aResult, aSerialization);
|
||||
aResult.AppendLiteral(" / ");
|
||||
GetPairValue().mYValue.AppendToString(aProperty, aResult, aSerialization);
|
||||
} else {
|
||||
GetPairValue().AppendToString(aProperty, aResult, aSerialization);
|
||||
}
|
||||
|
@ -2398,7 +2398,7 @@ nsComputedDOMStyle::DoGetGridAutoFlow()
|
||||
nsAutoString str;
|
||||
nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_grid_auto_flow,
|
||||
StylePosition()->mGridAutoFlow,
|
||||
NS_STYLE_GRID_AUTO_FLOW_NONE,
|
||||
NS_STYLE_GRID_AUTO_FLOW_STACK,
|
||||
NS_STYLE_GRID_AUTO_FLOW_DENSE,
|
||||
str);
|
||||
nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue;
|
||||
@ -2468,24 +2468,6 @@ nsComputedDOMStyle::GetGridLine(const nsStyleGridLine& aGridLine)
|
||||
return valueList;
|
||||
}
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::DoGetGridAutoPosition()
|
||||
{
|
||||
nsDOMCSSValueList* valueList = GetROCSSValueList(false);
|
||||
|
||||
valueList->AppendCSSValue(
|
||||
GetGridLine(StylePosition()->mGridAutoPositionColumn));
|
||||
|
||||
nsROCSSPrimitiveValue* slash = new nsROCSSPrimitiveValue;
|
||||
slash->SetString(NS_LITERAL_STRING("/"));
|
||||
valueList->AppendCSSValue(slash);
|
||||
|
||||
valueList->AppendCSSValue(
|
||||
GetGridLine(StylePosition()->mGridAutoPositionRow));
|
||||
|
||||
return valueList;
|
||||
}
|
||||
|
||||
CSSValue*
|
||||
nsComputedDOMStyle::DoGetGridColumnStart()
|
||||
{
|
||||
|
@ -268,7 +268,6 @@ private:
|
||||
mozilla::dom::CSSValue* DoGetGridAutoFlow();
|
||||
mozilla::dom::CSSValue* DoGetGridAutoColumns();
|
||||
mozilla::dom::CSSValue* DoGetGridAutoRows();
|
||||
mozilla::dom::CSSValue* DoGetGridAutoPosition();
|
||||
mozilla::dom::CSSValue* DoGetGridTemplateAreas();
|
||||
mozilla::dom::CSSValue* DoGetGridTemplateColumns();
|
||||
mozilla::dom::CSSValue* DoGetGridTemplateRows();
|
||||
|
@ -132,7 +132,6 @@ COMPUTED_STYLE_PROP(font_variant_position, FontVariantPosition)
|
||||
COMPUTED_STYLE_PROP(font_weight, FontWeight)
|
||||
COMPUTED_STYLE_PROP(grid_auto_columns, GridAutoColumns)
|
||||
COMPUTED_STYLE_PROP(grid_auto_flow, GridAutoFlow)
|
||||
COMPUTED_STYLE_PROP(grid_auto_position, GridAutoPosition)
|
||||
COMPUTED_STYLE_PROP(grid_auto_rows, GridAutoRows)
|
||||
COMPUTED_STYLE_PROP(grid_column_end, GridColumnEnd)
|
||||
COMPUTED_STYLE_PROP(grid_column_start, GridColumnStart)
|
||||
|
@ -7505,7 +7505,7 @@ nsRuleNode::ComputePositionData(void* aStartStruct,
|
||||
break;
|
||||
case eCSSUnit_Initial:
|
||||
case eCSSUnit_Unset:
|
||||
pos->mGridAutoFlow = NS_STYLE_GRID_AUTO_FLOW_NONE;
|
||||
pos->mGridAutoFlow = NS_STYLE_GRID_AUTO_FLOW_ROW;
|
||||
break;
|
||||
default:
|
||||
NS_ASSERTION(gridAutoFlow.GetUnit() == eCSSUnit_Enumerated,
|
||||
@ -7545,33 +7545,6 @@ nsRuleNode::ComputePositionData(void* aStartStruct,
|
||||
parentPos->mGridTemplateAreas,
|
||||
canStoreInRuleTree);
|
||||
|
||||
// grid-auto-position
|
||||
const nsCSSValue& gridAutoPosition = *aRuleData->ValueForGridAutoPosition();
|
||||
switch (gridAutoPosition.GetUnit()) {
|
||||
case eCSSUnit_Null:
|
||||
break;
|
||||
case eCSSUnit_Inherit:
|
||||
canStoreInRuleTree = false;
|
||||
pos->mGridAutoPositionColumn = parentPos->mGridAutoPositionColumn;
|
||||
pos->mGridAutoPositionRow = parentPos->mGridAutoPositionRow;
|
||||
break;
|
||||
case eCSSUnit_Initial:
|
||||
case eCSSUnit_Unset:
|
||||
// '1 / 1'
|
||||
pos->mGridAutoPositionColumn.SetToInteger(1);
|
||||
pos->mGridAutoPositionRow.SetToInteger(1);
|
||||
break;
|
||||
default:
|
||||
SetGridLine(gridAutoPosition.GetPairValue().mXValue,
|
||||
pos->mGridAutoPositionColumn,
|
||||
parentPos->mGridAutoPositionColumn,
|
||||
canStoreInRuleTree);
|
||||
SetGridLine(gridAutoPosition.GetPairValue().mYValue,
|
||||
pos->mGridAutoPositionRow,
|
||||
parentPos->mGridAutoPositionRow,
|
||||
canStoreInRuleTree);
|
||||
}
|
||||
|
||||
// grid-column-start
|
||||
SetGridLine(*aRuleData->ValueForGridColumnStart(),
|
||||
pos->mGridColumnStart,
|
||||
|
@ -544,9 +544,9 @@ static inline mozilla::css::Side operator++(mozilla::css::Side& side, int) {
|
||||
#define NS_STYLE_FONT_FIELD 16
|
||||
|
||||
// grid-auto-flow keywords
|
||||
#define NS_STYLE_GRID_AUTO_FLOW_NONE (1 << 0)
|
||||
#define NS_STYLE_GRID_AUTO_FLOW_COLUMN (1 << 1)
|
||||
#define NS_STYLE_GRID_AUTO_FLOW_ROW (1 << 2)
|
||||
#define NS_STYLE_GRID_AUTO_FLOW_STACK (1 << 0)
|
||||
#define NS_STYLE_GRID_AUTO_FLOW_ROW (1 << 1)
|
||||
#define NS_STYLE_GRID_AUTO_FLOW_COLUMN (1 << 2)
|
||||
#define NS_STYLE_GRID_AUTO_FLOW_DENSE (1 << 3)
|
||||
|
||||
// 'subgrid' keyword in grid-template-{columns,rows}
|
||||
|
@ -1243,7 +1243,7 @@ nsStylePosition::nsStylePosition(void)
|
||||
mGridAutoRowsMax.SetIntValue(NS_STYLE_GRID_TRACK_BREADTH_MAX_CONTENT,
|
||||
eStyleUnit_Enumerated);
|
||||
|
||||
mGridAutoFlow = NS_STYLE_GRID_AUTO_FLOW_NONE;
|
||||
mGridAutoFlow = NS_STYLE_GRID_AUTO_FLOW_ROW;
|
||||
mBoxSizing = NS_STYLE_BOX_SIZING_CONTENT;
|
||||
mAlignContent = NS_STYLE_ALIGN_CONTENT_STRETCH;
|
||||
mAlignItems = NS_STYLE_ALIGN_ITEMS_INITIAL_VALUE;
|
||||
@ -1255,8 +1255,6 @@ nsStylePosition::nsStylePosition(void)
|
||||
mFlexGrow = 0.0f;
|
||||
mFlexShrink = 1.0f;
|
||||
mZIndex.SetAutoValue();
|
||||
mGridAutoPositionColumn.SetToInteger(1);
|
||||
mGridAutoPositionRow.SetToInteger(1);
|
||||
// Other members get their default constructors
|
||||
// which initialize them to representations of their respective initial value.
|
||||
// mGridTemplateAreas: nullptr for 'none'
|
||||
@ -1273,8 +1271,6 @@ nsStylePosition::nsStylePosition(const nsStylePosition& aSource)
|
||||
: mGridTemplateColumns(aSource.mGridTemplateColumns)
|
||||
, mGridTemplateRows(aSource.mGridTemplateRows)
|
||||
, mGridTemplateAreas(aSource.mGridTemplateAreas)
|
||||
, mGridAutoPositionColumn(aSource.mGridAutoPositionColumn)
|
||||
, mGridAutoPositionRow(aSource.mGridAutoPositionRow)
|
||||
, mGridColumnStart(aSource.mGridColumnStart)
|
||||
, mGridColumnEnd(aSource.mGridColumnEnd)
|
||||
, mGridRowStart(aSource.mGridRowStart)
|
||||
@ -1292,8 +1288,6 @@ nsStylePosition::nsStylePosition(const nsStylePosition& aSource)
|
||||
sizeof(mGridTemplateColumns) +
|
||||
sizeof(mGridTemplateRows) +
|
||||
sizeof(mGridTemplateAreas) +
|
||||
sizeof(mGridAutoPositionColumn) +
|
||||
sizeof(mGridAutoPositionRow) +
|
||||
sizeof(mGridColumnStart) +
|
||||
sizeof(mGridColumnEnd) +
|
||||
sizeof(mGridRowStart) +
|
||||
|
@ -1316,10 +1316,6 @@ struct nsStylePosition {
|
||||
// nullptr for 'none'
|
||||
nsRefPtr<mozilla::css::GridTemplateAreasValue> mGridTemplateAreas;
|
||||
|
||||
// We represent the "grid-auto-position" property in two parts:
|
||||
nsStyleGridLine mGridAutoPositionColumn;
|
||||
nsStyleGridLine mGridAutoPositionRow;
|
||||
|
||||
nsStyleGridLine mGridColumnStart;
|
||||
nsStyleGridLine mGridColumnEnd;
|
||||
nsStyleGridLine mGridRowStart;
|
||||
|
@ -4802,22 +4802,26 @@ if (SpecialPowers.getBoolPref("layout.css.grid.enabled")) {
|
||||
domProp: "gridAutoFlow",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "none" ],
|
||||
initial_values: [ "row" ],
|
||||
other_values: [
|
||||
"column",
|
||||
"row",
|
||||
"column dense",
|
||||
"row dense",
|
||||
"dense column",
|
||||
"dense row",
|
||||
"stack column",
|
||||
"stack row",
|
||||
"stack",
|
||||
],
|
||||
invalid_values: [
|
||||
"",
|
||||
"auto",
|
||||
"none",
|
||||
"10px",
|
||||
"dense",
|
||||
"none row",
|
||||
"none dense",
|
||||
"stack dense",
|
||||
"stack stack",
|
||||
"stack row stack",
|
||||
"column row",
|
||||
"dense row dense",
|
||||
]
|
||||
@ -5046,12 +5050,9 @@ if (SpecialPowers.getBoolPref("layout.css.grid.enabled")) {
|
||||
initial_values: [
|
||||
"none",
|
||||
"none / none",
|
||||
"none auto",
|
||||
"none auto / auto",
|
||||
],
|
||||
other_values: [
|
||||
"row",
|
||||
"none 40px",
|
||||
"stack 40px",
|
||||
"column dense auto",
|
||||
"dense row minmax(min-content, 2fr)",
|
||||
"row 40px / 100px",
|
||||
@ -5067,6 +5068,7 @@ if (SpecialPowers.getBoolPref("layout.css.grid.enabled")) {
|
||||
].concat(
|
||||
gCSSProperties["grid-template"].invalid_values,
|
||||
gCSSProperties["grid-auto-flow"].invalid_values
|
||||
.filter((v) => v != 'none')
|
||||
)
|
||||
};
|
||||
|
||||
@ -5144,46 +5146,21 @@ if (SpecialPowers.getBoolPref("layout.css.grid.enabled")) {
|
||||
invalid_values: gridLineInvalidValues
|
||||
};
|
||||
|
||||
var gridAutoPositionOtherValues = [];
|
||||
gridLineOtherValues.concat([ "auto" ]).forEach(function(val) {
|
||||
gridAutoPositionOtherValues.push(" foo / " + val);
|
||||
gridAutoPositionOtherValues.push(val + "/2");
|
||||
});
|
||||
var gridAutoPositionInvalidValues = [
|
||||
"foo",
|
||||
"foo, bar",
|
||||
"foo / bar / baz",
|
||||
];
|
||||
gridLineInvalidValues.forEach(function(val) {
|
||||
gridAutoPositionInvalidValues.push("span 3 / " + val);
|
||||
gridAutoPositionInvalidValues.push(val + " / foo");
|
||||
});
|
||||
gCSSProperties["grid-auto-position"] = {
|
||||
domProp: "gridAutoPosition",
|
||||
inherited: false,
|
||||
type: CSS_TYPE_LONGHAND,
|
||||
initial_values: [ "1 / 1" ],
|
||||
other_values: gridAutoPositionOtherValues,
|
||||
invalid_values: gridAutoPositionInvalidValues
|
||||
};
|
||||
|
||||
// The grid-column and grid-row shorthands take values of the form
|
||||
// <grid-line> [ / <grid-line> ]?
|
||||
// which is equivalent to:
|
||||
// <grid-line> | [ <grid-line> / <grid-line> ]
|
||||
// which is equivalent to:
|
||||
// <grid-line> | <'grid-auto-position'>
|
||||
var gridColumnRowOtherValues = [].concat(
|
||||
gridLineOtherValues,
|
||||
gridAutoPositionOtherValues);
|
||||
var gridColumnRowInvalidValues = [].concat(
|
||||
gridLineInvalidValues,
|
||||
gridAutoPositionInvalidValues);
|
||||
// A single <grid-line> is invalid for grid-auto-position,
|
||||
// but not for grid-column or grid-row:
|
||||
gridColumnRowInvalidValues.splice(
|
||||
gridColumnRowInvalidValues.indexOf("foo"),
|
||||
1);
|
||||
var gridColumnRowOtherValues = [].concat(gridLineOtherValues);
|
||||
gridLineOtherValues.concat([ "auto" ]).forEach(function(val) {
|
||||
gridColumnRowOtherValues.push(" foo / " + val);
|
||||
gridColumnRowOtherValues.push(val + "/2");
|
||||
});
|
||||
var gridColumnRowInvalidValues = [
|
||||
"foo, bar",
|
||||
"foo / bar / baz",
|
||||
].concat(gridLineInvalidValues);
|
||||
gridLineInvalidValues.forEach(function(val) {
|
||||
gridColumnRowInvalidValues.push("span 3 / " + val);
|
||||
gridColumnRowInvalidValues.push(val + " / foo");
|
||||
});
|
||||
gCSSProperties["grid-column"] = {
|
||||
domProp: "gridColumn",
|
||||
inherited: false,
|
||||
|
@ -16,7 +16,7 @@ var initial_values = {
|
||||
gridTemplateAreas: "none",
|
||||
gridTemplateColumns: "none",
|
||||
gridTemplateRows: "none",
|
||||
gridAutoFlow: "none",
|
||||
gridAutoFlow: "row",
|
||||
// Computed value for 'auto'
|
||||
gridAutoColumns: "minmax(min-content, max-content)",
|
||||
gridAutoRows: "minmax(min-content, max-content)",
|
||||
@ -179,8 +179,13 @@ grid_test_cases = grid_template_test_cases.concat([
|
||||
gridAutoFlow: "row",
|
||||
},
|
||||
{
|
||||
specified: "none 40px",
|
||||
gridAutoFlow: "none",
|
||||
specified: "stack 40px",
|
||||
gridAutoFlow: "stack row",
|
||||
gridAutoColumns: "40px",
|
||||
},
|
||||
{
|
||||
specified: "stack column 40px",
|
||||
gridAutoFlow: "stack column",
|
||||
gridAutoColumns: "40px",
|
||||
},
|
||||
{
|
||||
|
@ -16,7 +16,7 @@ var initial_values = {
|
||||
gridTemplateAreas: "none",
|
||||
gridTemplateColumns: "none",
|
||||
gridTemplateRows: "none",
|
||||
gridAutoFlow: "none",
|
||||
gridAutoFlow: "row",
|
||||
gridAutoColumns: "auto",
|
||||
gridAutoRows: "auto",
|
||||
};
|
||||
@ -88,7 +88,7 @@ grid_test_cases = grid_template_test_cases.concat([
|
||||
},
|
||||
{
|
||||
gridAutoColumns: "40px",
|
||||
shorthand: "none 40px / auto",
|
||||
shorthand: "row 40px / auto",
|
||||
},
|
||||
{
|
||||
gridAutoFlow: "column dense",
|
||||
|
@ -1380,7 +1380,10 @@ nsXULPopupManager::FirePopupHidingEvent(nsIContent* aPopup,
|
||||
// able to see it. If there is a next popup, indicating that mutliple popups
|
||||
// are rolling up, don't wait and hide the popup right away since the effect
|
||||
// would likely be undesirable. This also does a quick check to see if the
|
||||
// popup has a transition defined, and skips the wait if not.
|
||||
// popup has a transition defined, and skips the wait if not. Transitions
|
||||
// are currently disabled on Linux due to rendering issues on certain
|
||||
// configurations.
|
||||
#ifndef MOZ_WIDGET_GTK
|
||||
if (!aNextPopup && aPopup->HasAttr(kNameSpaceID_None, nsGkAtoms::animate) &&
|
||||
popupFrame->StyleDisplay()->mTransitionPropertyCount > 0) {
|
||||
nsAutoString animate;
|
||||
@ -1397,6 +1400,7 @@ nsXULPopupManager::FirePopupHidingEvent(nsIContent* aPopup,
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
HidePopupCallback(aPopup, popupFrame, aNextPopup, aLastPopup,
|
||||
aPopupType, aDeselectMenu);
|
||||
|
@ -132,7 +132,7 @@ extern "C" {
|
||||
* for use in implementing release-build assertions.
|
||||
*/
|
||||
static MOZ_ALWAYS_INLINE void
|
||||
MOZ_ReportAssertionFailure(const char* s, const char* file, int ln)
|
||||
MOZ_ReportAssertionFailure(const char* s, const char* file, int ln) MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
|
||||
{
|
||||
#ifdef ANDROID
|
||||
__android_log_print(ANDROID_LOG_FATAL, "MOZ_Assert",
|
||||
@ -147,7 +147,7 @@ MOZ_ReportAssertionFailure(const char* s, const char* file, int ln)
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE void
|
||||
MOZ_ReportCrash(const char* s, const char* file, int ln)
|
||||
MOZ_ReportCrash(const char* s, const char* file, int ln) MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
|
||||
{
|
||||
#ifdef ANDROID
|
||||
__android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH",
|
||||
|
@ -111,6 +111,16 @@
|
||||
// http://stackoverflow.com/questions/20498142/visual-studio-2013-explicit-keyword-bug
|
||||
#endif
|
||||
|
||||
/*
|
||||
* When built with clang analyzer (a.k.a scan-build), define MOZ_HAVE_NORETURN
|
||||
* to mark some false positives
|
||||
*/
|
||||
#ifdef __clang_analyzer__
|
||||
# if __has_extension(attribute_analyzer_noreturn)
|
||||
# define MOZ_HAVE_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The MOZ_CONSTEXPR specifier declares that a C++11 compiler can evaluate a
|
||||
* function at compile time. A constexpr function cannot examine any values
|
||||
@ -185,6 +195,27 @@
|
||||
# define MOZ_NORETURN /* no support */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS, specified at the end of a function
|
||||
* declaration, indicates that for the purposes of static analysis, this
|
||||
* function does not return. (The function definition does not need to be
|
||||
* annotated.)
|
||||
*
|
||||
* MOZ_ReportCrash(const char* s, const char* file, int ln) MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
|
||||
*
|
||||
* Some static analyzers, like scan-build from clang, can use this information
|
||||
* to eliminate false positives. From the upstream documentation of scan-build:
|
||||
* "This attribute is useful for annotating assertion handlers that actually
|
||||
* can return, but for the purpose of using the analyzer we want to pretend
|
||||
* that such functions do not return."
|
||||
*
|
||||
*/
|
||||
#if defined(MOZ_HAVE_ANALYZER_NORETURN)
|
||||
# define MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS MOZ_HAVE_ANALYZER_NORETURN
|
||||
#else
|
||||
# define MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS /* no support */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MOZ_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time
|
||||
* instrumentation shipped with Clang and GCC) to not instrument the annotated
|
||||
|
@ -4204,20 +4204,26 @@ Tab.prototype = {
|
||||
sendMessageToJava(message);
|
||||
},
|
||||
|
||||
_getGeckoZoom: function() {
|
||||
let res = {x: {}, y: {}};
|
||||
let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
cwu.getResolution(res.x, res.y);
|
||||
let zoom = res.x.value * window.devicePixelRatio;
|
||||
return zoom;
|
||||
},
|
||||
|
||||
saveSessionZoom: function(aZoom) {
|
||||
let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
cwu.setResolution(aZoom / window.devicePixelRatio, aZoom / window.devicePixelRatio);
|
||||
},
|
||||
|
||||
restoredSessionZoom: function() {
|
||||
if (!this._restoreZoom) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let cwu = this.browser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||
let res = {x: {}, y: {}};
|
||||
cwu.getResolution(res.x, res.y);
|
||||
return res.x.value * window.devicePixelRatio;
|
||||
|
||||
if (this._restoreZoom && cwu.isHistoryRestored) {
|
||||
return this._getGeckoZoom();
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
OnHistoryNewEntry: function(aUri) {
|
||||
|
@ -523,7 +523,11 @@ pref("accessibility.typeaheadfind.timeout", 4000);
|
||||
pref("accessibility.typeaheadfind.enabletimeout", true);
|
||||
pref("accessibility.typeaheadfind.soundURL", "beep");
|
||||
pref("accessibility.typeaheadfind.enablesound", true);
|
||||
#ifdef XP_MACOSX
|
||||
pref("accessibility.typeaheadfind.prefillwithselection", false);
|
||||
#else
|
||||
pref("accessibility.typeaheadfind.prefillwithselection", true);
|
||||
#endif
|
||||
pref("accessibility.typeaheadfind.matchesCountTimeout", 250);
|
||||
pref("accessibility.typeaheadfind.matchesCountLimit", 100);
|
||||
|
||||
|
@ -359,12 +359,10 @@
|
||||
highlightButton.click();
|
||||
ok(highlightButton.checked, "testFindWithHighlight 3: Highlight All should be checked.");
|
||||
|
||||
if (!gHasFindClipboard) {
|
||||
a = gFindBar._findField.value;
|
||||
b = gFindBar._browser.finder._fastFind.searchString;
|
||||
c = gFindBar._browser.finder.searchString;
|
||||
ok(a == searchStr && b == c, "testFindWithHighlight 4: " + a + ", " + b + ", " + c + ".");
|
||||
}
|
||||
a = gFindBar._findField.value;
|
||||
b = gFindBar._browser.finder._fastFind.searchString;
|
||||
c = gFindBar._browser.finder.searchString;
|
||||
ok(a == searchStr && b == c, "testFindWithHighlight 4: " + a + ", " + b + ", " + c + ".");
|
||||
|
||||
gFindBar.onFindAgainCommand();
|
||||
a = gFindBar._findField.value;
|
||||
|
@ -176,23 +176,27 @@ function nextTest()
|
||||
$("bottomright").removeAttribute("right");
|
||||
}
|
||||
|
||||
var transitions = 0;
|
||||
function transitionEnded(event) {
|
||||
transitions++;
|
||||
// Two properties transition so continue on the second one finishing.
|
||||
if (!(transitions % 2)) {
|
||||
SimpleTest.executeSoon(() => runNextTest.next());
|
||||
// Test that a transition occurs when opening or closing the popup. The transition is
|
||||
// disabled on Linux.
|
||||
if (navigator.platform.indexOf("Linux") == -1) {
|
||||
var transitions = 0;
|
||||
function transitionEnded(event) {
|
||||
transitions++;
|
||||
// Two properties transition so continue on the second one finishing.
|
||||
if (!(transitions % 2)) {
|
||||
SimpleTest.executeSoon(() => runNextTest.next());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the transition occurs for an arrow panel with animate="true"
|
||||
window.addEventListener("transitionend", transitionEnded, false);
|
||||
$("animatepanel").openPopup($("topleft"), "after_start", 0, 0, false, false, null, "start");
|
||||
yield;
|
||||
window.removeEventListener("transitionend", transitionEnded, false);
|
||||
synthesizeKey("VK_ESCAPE", { });
|
||||
ok(!animatedPopupHidden, "animated popup not hidden yet");
|
||||
yield;
|
||||
// Check that the transition occurs for an arrow panel with animate="true"
|
||||
window.addEventListener("transitionend", transitionEnded, false);
|
||||
$("animatepanel").openPopup($("topleft"), "after_start", 0, 0, false, false, null, "start");
|
||||
yield;
|
||||
window.removeEventListener("transitionend", transitionEnded, false);
|
||||
synthesizeKey("VK_ESCAPE", { });
|
||||
ok(!animatedPopupHidden, "animated popup not hidden yet");
|
||||
yield;
|
||||
}
|
||||
|
||||
SimpleTest.finish()
|
||||
yield;
|
||||
|
@ -31,8 +31,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=288254
|
||||
|
||||
/** Test for Bug 257061 and Bug 288254 **/
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
window.open("findbar_window.xul", "findbartest",
|
||||
"chrome,width=600,height=600");
|
||||
|
||||
// Since bug 978861, this pref is set to `false` on OSX. For this test, we'll
|
||||
// set it `true` to disable the find clipboard on OSX, which interferes with
|
||||
// our tests.
|
||||
SpecialPowers.pushPrefEnv({
|
||||
set: [["accessibility.typeaheadfind.prefillwithselection", true]]
|
||||
}, () => {
|
||||
window.open("findbar_window.xul", "findbartest", "chrome,width=600,height=600");
|
||||
});
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
@ -1198,6 +1198,13 @@
|
||||
|
||||
<method name="_onFindFieldFocus">
|
||||
<body><![CDATA[
|
||||
let prefsvc =
|
||||
Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefBranch);
|
||||
const kPref = "accessibility.typeaheadfind.prefillwithselection";
|
||||
if (this.prefillWithSelection && prefsvc.getBoolPref(kPref))
|
||||
return;
|
||||
|
||||
let clipboardSearchString = this._browser.finder.clipboardSearchString;
|
||||
if (clipboardSearchString && this._findField.value != clipboardSearchString) {
|
||||
this._findField.value = clipboardSearchString;
|
||||
|
@ -426,6 +426,8 @@ panel[type="arrow"] {
|
||||
-moz-binding: url("chrome://global/content/bindings/popup.xml#arrowpanel");
|
||||
}
|
||||
|
||||
%ifndef MOZ_WIDGET_GTK
|
||||
|
||||
panel[type="arrow"]:not([animate="false"]) {
|
||||
transform: scale(.7);
|
||||
opacity: 0;
|
||||
@ -485,6 +487,8 @@ panel[arrowposition="end_after"][animate="cancel"] {
|
||||
transform: scale(.7) skew(-10deg, -10deg);
|
||||
}
|
||||
|
||||
%endif
|
||||
|
||||
%ifdef XP_MACOSX
|
||||
.statusbar-resizerpanel {
|
||||
display: none;
|
||||
|
@ -284,12 +284,8 @@ add_task(function testDeactivateExperiment() {
|
||||
Assert.equal(addons[0].id, "experiment-1", "Add-on ID matches expected.");
|
||||
|
||||
// Verify the UI looks sane.
|
||||
// TODO remove the pane cycle once the UI refreshes automatically.
|
||||
yield gCategoryUtilities.openType("extension");
|
||||
|
||||
Assert.ok(gCategoryUtilities.isTypeVisible("experiment"), "Experiment tab visible.");
|
||||
yield gCategoryUtilities.openType("experiment");
|
||||
|
||||
let item = get_addon_element(gManagerWindow, "experiment-1");
|
||||
Assert.ok(item, "Got add-on element.");
|
||||
Assert.ok(!item.active, "Element should not be active.");
|
||||
|
Loading…
Reference in New Issue
Block a user