import changes from `dev' branch of rmottola/Arctic-Fox:

- bug 1215748 - use llvm-dsymutil for mac builds. r=mshal (a217006d89)
- warnings (31ea43d0d8)
- Bug 1175154 - Unit tests for IAC on 3.0. r=ferjm (12c424bab3)
- Bug 1219543 - Part 1: isRunningOnCompositor flag is now a member of AnimationProperty. r=bbirtles (85bc668501)
- Bug 1219543 - Part 2: Avoid the period that mIsRunningOnCompositor is false between restyling and building display list. r=bbirtles (597e46d479)
- Bug 1219543 - Part 3: MutationObserver should disconnect when the test is finished. r=bbirtles (70c26a266e)
- Bug 1214148 - patch 1 - propagation from the nested iframe back to the toplevel iframe, r=alwu (b42002f43a)
- Bug 1214148 - patch 2 - from toplevel iframe to the nested iframe, r=alwu (7b07fe5399)
- Bug 1214148 - patch 3 - correct window for nested iframes, r=alwu (27ee08caf1)
- Bug 1166910 - put referrer attribute behind pref in webidl, r=bz (93e421fa1b)
- Bug 1187357 - rename referrer attribute to referrerpolicy. r=hsivonen (70c67f5def)
- Bug 1187357 - Generated code for renaming referrer to referrerpolicy in html parser. r=hsivonen (738de3f278)
- Bug 1221341. Snap box shadow clip rect to device pixels. r=mstange (b63b783714)
- Bug 1228634 - Implement Element.getAttributeNames, r=peterv (4594d9c14c)
- Bug 1216193. Implement webkitMatchesSelector. r=khuey (39742b7e0b)
- Bug 1134648, handle dynamic changes to rel=dns-prefetch, r=bz (e27638080e)
- Bug 1229962 - use UniquePtr<T[]> instead of nsAutoArrayPtr<T> in parser/html/; r=hsivonen (75de6314f1)
- Bug 1226437 - Speculative CSP should set speculative referrer policy instead of actual referrer policy. r=sicking (f7dfd3fd18)
- Bug 1227554 - Default to NullPrincipal if doc is not available within expatdriver. r=bz (336a562965)
- Bug 1215781 - Use MOZ_UTF16 to generate sTagUnicodeTable. r=mrbkap (eca371a36b)
- Bug 1082598 - Part 5: Fix NPAPI for Skia update. r=jrmuizel (25c4d080ab)
- Bug 1183828 - Remove 'nsWindow::GetNativeData not implemented for this type' warning. r=roc (0a60404b57)
- Bug 1224445 - Add NS_NATIVE_OPENGL_CONTEXT handling to nsWindow::GetNativeData() r=mwu (ee35844be4)
- Bug 1179632 part.1 native IME context should not be stored in InputContext but should be able to retrieve with nsIWidget::GetNativeData() r=smaug (5f1804bb72)
- Bug 1179632 part.2 WidgetCompositionEvent should store NativeIMEContext which caused the event and PuppetWidget should store it for GetNativeIMEContext() r=smaug, sr=smaug (e00ca78e3f)
- Bug 1179632 part.3 TabParent::RecvEndIMEComposition() shouldn't return true with aNoCompositionEvent when there is no widget r=smaug (ee065ed491)
- Bug 1179632 part.4 Clean up the code to request IME to commit composition across process boundary r=smaug (9567c4dc57)
- Bug 1179632 part.5 WidgetCompositionEvent::mNativeIMEContext should be used at looking for a TextComposition instance for a WidgetCompositionEvent r=smaug (f4e27ec28c)
- Bug 1179632 part.6 KeyboardEvent.isComposing shouldn't expose IME state on different document r=smaug (ca8b8a6a02)
- Bug 1227544 - Scaling on 720p devices is broken. r=timdream (cb89af839f)
This commit is contained in:
2023-06-13 15:52:32 +08:00
parent 41532ef15e
commit 2ddfe368e1
107 changed files with 1741 additions and 983 deletions
+2
View File
@@ -17,11 +17,13 @@ if [ -d "$topsrcdir/clang" ]; then
export CC=$topsrcdir/clang/bin/clang
export CXX=$topsrcdir/clang/bin/clang++
export LLVMCONFIG=$topsrcdir/clang/bin/llvm-config
export DSYMUTIL=$topsrcdir/clang/bin/llvm-dsymutil
elif [ -d "$topsrcdir/../clang" ]; then
# comm-central based build
export CC=$topsrcdir/../clang/bin/clang
export CXX=$topsrcdir/../clang/bin/clang++
export LLVMCONFIG=$topsrcdir/../clang/bin/llvm-config
export DSYMUTIL=$topsrcdir/../clang/bin/llvm-dsymutil
fi
# If not set use the system default clang
+1
View File
@@ -70,4 +70,5 @@ if CONFIG['GNU_CXX']:
# installing it in dist/lib.
NO_EXPAND_LIBS = True
# We allow warnings for third-party code that can be updated from upstream.
ALLOW_COMPILER_WARNINGS = True
+1 -1
View File
@@ -13530,7 +13530,7 @@ nsDocShell::OnLinkClickSync(nsIContent* aContent,
// if per element referrer is enabled, the element referrer overrules
// the document wide referrer
if (IsElementAnchor(aContent)) {
net::ReferrerPolicy refPolEnum = aContent->AsElement()->GetReferrerPolicy();
net::ReferrerPolicy refPolEnum = aContent->AsElement()->GetReferrerPolicyAsEnum();
if (refPolEnum != net::RP_Unset) {
refererPolicy = refPolEnum;
}
+10 -32
View File
@@ -96,7 +96,6 @@ KeyframeEffectReadOnly::KeyframeEffectReadOnly(
, mPseudoType(aPseudoType)
{
MOZ_ASSERT(aTarget, "null animation target is not yet supported");
ResetIsRunningOnCompositor();
}
JSObject*
@@ -466,19 +465,6 @@ KeyframeEffectReadOnly::ComposeStyle(RefPtr<AnimValuesStyleRule>& aStyleRule,
}
}
bool
KeyframeEffectReadOnly::IsPropertyRunningOnCompositor(
nsCSSProperty aProperty) const
{
const auto& info = LayerAnimationInfo::sRecords;
for (size_t i = 0; i < ArrayLength(mIsPropertyRunningOnCompositor); i++) {
if (info[i].mProperty == aProperty) {
return mIsPropertyRunningOnCompositor[i];
}
}
return false;
}
bool
KeyframeEffectReadOnly::IsRunningOnCompositor() const
{
@@ -486,8 +472,8 @@ KeyframeEffectReadOnly::IsRunningOnCompositor() const
// one property running on compositor.
// Animation.IsRunningOnCompotitor will return more fine grained
// information in bug 1196114.
for (bool isPropertyRunningOnCompositor : mIsPropertyRunningOnCompositor) {
if (isPropertyRunningOnCompositor) {
for (const AnimationProperty& property : mProperties) {
if (property.mIsRunningOnCompositor) {
return true;
}
}
@@ -498,19 +484,13 @@ void
KeyframeEffectReadOnly::SetIsRunningOnCompositor(nsCSSProperty aProperty,
bool aIsRunning)
{
static_assert(
MOZ_ARRAY_LENGTH(LayerAnimationInfo::sRecords) ==
MOZ_ARRAY_LENGTH(mIsPropertyRunningOnCompositor),
"The length of mIsPropertyRunningOnCompositor should equal to"
"the length of LayserAnimationInfo::sRecords");
MOZ_ASSERT(nsCSSProps::PropHasFlags(aProperty,
CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR),
"Property being animated on compositor is a recognized "
"compositor-animatable property");
const auto& info = LayerAnimationInfo::sRecords;
for (size_t i = 0; i < ArrayLength(mIsPropertyRunningOnCompositor); i++) {
if (info[i].mProperty == aProperty) {
mIsPropertyRunningOnCompositor[i] = aIsRunning;
for (AnimationProperty& property : mProperties) {
if (property.mProperty == aProperty) {
property.mIsRunningOnCompositor = aIsRunning;
return;
}
}
@@ -523,8 +503,8 @@ KeyframeEffectReadOnly::~KeyframeEffectReadOnly()
void
KeyframeEffectReadOnly::ResetIsRunningOnCompositor()
{
for (bool& isPropertyRunningOnCompositor : mIsPropertyRunningOnCompositor) {
isPropertyRunningOnCompositor = false;
for (AnimationProperty& property : mProperties) {
property.mIsRunningOnCompositor = false;
}
}
@@ -556,9 +536,7 @@ KeyframeEffectReadOnly::UpdateTargetRegistration()
// Any effects not in the effect set will not be included in the set of
// candidate effects for running on the compositor and hence they won't
// have their compositor status updated so we should do that now.
for (bool& isRunningOnCompositor : mIsPropertyRunningOnCompositor) {
isRunningOnCompositor = false;
}
ResetIsRunningOnCompositor();
}
}
@@ -1822,7 +1800,7 @@ KeyframeEffectReadOnly::CanThrottle() const
}
// First we need to check layer generation and transform overflow
// prior to the IsPropertyRunningOnCompositor check because we should
// prior to the property.mIsRunningOnCompositor check because we should
// occasionally unthrottle these animations even if the animations are
// already running on compositor.
for (const LayerAnimationInfo::Record& record :
@@ -1854,7 +1832,7 @@ KeyframeEffectReadOnly::CanThrottle() const
}
for (const AnimationProperty& property : mProperties) {
if (!IsPropertyRunningOnCompositor(property.mProperty)) {
if (!property.mIsRunningOnCompositor) {
return false;
}
}
+15 -18
View File
@@ -118,7 +118,7 @@ struct AnimationPropertySegment
struct AnimationProperty
{
nsCSSProperty mProperty;
nsCSSProperty mProperty = eCSSProperty_UNKNOWN;
// Does this property win in the CSS Cascade?
//
@@ -136,16 +136,26 @@ struct AnimationProperty
// For other properties, we make it always be true.
// **NOTE 2**: This member is not included when comparing AnimationProperty
// objects for equality.
bool mWinsInCascade;
bool mWinsInCascade = true;
// If true, the propery is currently being animated on the compositor.
//
// Note that when the owning Animation requests a non-throttled restyle, in
// between calling RequestRestyle on its AnimationCollection and when the
// restyle is performed, this member may temporarily become false even if
// the animation remains on the layer after the restyle.
bool mIsRunningOnCompositor = false;
InfallibleTArray<AnimationPropertySegment> mSegments;
// NOTE: This operator does *not* compare the mWinsInCascade member.
// NOTE: This operator does *not* compare the mWinsInCascade member *or* the
// mIsRunningOnCompositor member.
// This is because AnimationProperty objects are compared when recreating
// CSS animations to determine if mutation observer change records need to
// be created or not. However, at the point when these objects are compared
// the mWinsInCascade will not have been set on the new objects so we ignore
// this member to avoid generating spurious change records.
// neither the mWinsInCascade nor the mIsRunningOnCompositor will have been
// set on the new objects so we ignore these members to avoid generating
// spurious change records.
bool operator==(const AnimationProperty& aOther) const {
return mProperty == aOther.mProperty &&
mSegments == aOther.mSegments;
@@ -279,8 +289,6 @@ public:
// Any updated properties are added to |aSetProperties|.
void ComposeStyle(RefPtr<AnimValuesStyleRule>& aStyleRule,
nsCSSPropertySet& aSetProperties);
// Returns true if |aProperty| is currently being animated on compositor.
bool IsPropertyRunningOnCompositor(nsCSSProperty aProperty) const;
// Returns true if at least one property is being animated on compositor.
bool IsRunningOnCompositor() const;
void SetIsRunningOnCompositor(nsCSSProperty aProperty, bool aIsRunning);
@@ -341,17 +349,6 @@ protected:
InfallibleTArray<AnimationProperty> mProperties;
// Parallel array corresponding to CommonAnimationManager::sLayerAnimationInfo
// such that mIsPropertyRunningOnCompositor[x] is true only if this effect has
// an animation of CommonAnimationManager::sLayerAnimationInfo[x].mProperty
// that is currently running on the compositor.
//
// Note that when the owning Animation requests a non-throttled restyle, in
// between calling RequestRestyle on its AnimationCollection and when the
// restyle is performed, this member may temporarily become false even if
// the animation remains on the layer after the restyle.
bool mIsPropertyRunningOnCompositor[LayerAnimationInfo::kRecords];
private:
nsIFrame* GetAnimationFrame() const;
@@ -207,6 +207,9 @@ promise_test(function(t) {
resolve();
}));
observer.observe(div, { animations: true, subtree: false });
t.add_cleanup(function() {
observer.disconnect();
});
div.style.animationDuration = "200s";
}));
}));
+27 -9
View File
@@ -10,7 +10,6 @@ this.EXPORTED_SYMBOLS = ["InterAppCommService"];
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/AppsUtils.jsm");
const DEBUG = false;
function debug(aMsg) {
@@ -220,6 +219,24 @@ this.InterAppCommService = {
this._messagePortPairs = {};
},
/* These attributes main use is to allow testing this in an isolated way
* that doesn't depend on the app service, or the system messenger working on
* the test environment
*/
get appsService() {
return this._appsService || appsService;
},
set appsService(aService) {
this._appsService = aService;
},
get messenger() {
return this._messenger || messenger;
},
set messenger(aMessenger) {
this._messenger = aMessenger;
},
/**
* Registration of a page that wants to be connected to other apps through
* the Inter-App Communication API.
@@ -389,8 +406,8 @@ this.InterAppCommService = {
_matchRules: function(aPubAppManifestURL, aPubRules,
aSubAppManifestURL, aSubRules,
aPubPageURL, aSubPageURL) {
let pubApp = appsService.getAppByManifestURL(aPubAppManifestURL);
let subApp = appsService.getAppByManifestURL(aSubAppManifestURL);
let pubApp = this.appsService.getAppByManifestURL(aPubAppManifestURL);
let subApp = this.appsService.getAppByManifestURL(aSubAppManifestURL);
let isPubAppCertified =
(pubApp.appStatus == Ci.nsIPrincipal.APP_STATUS_CERTIFIED);
@@ -514,7 +531,7 @@ this.InterAppCommService = {
};
// Fire system message to deliver the message port to the subscriber.
messenger.sendMessage("connection",
this.messenger.sendMessage("connection",
{ keyword: aKeyword,
messagePortID: messagePortID,
pubPageURL: aPubPageURL},
@@ -677,7 +694,7 @@ this.InterAppCommService = {
};
let glue = Cc["@mozilla.org/dom/apps/inter-app-comm-ui-glue;1"]
.createInstance(Ci.nsIInterAppCommUIGlue);
.createInstance(Ci.nsIInterAppCommUIGlue);
if (glue) {
glue.selectApps(callerID, pubAppManifestURL, keyword, appsToSelect).then(
function(aData) {
@@ -699,7 +716,7 @@ this.InterAppCommService = {
);
} else {
if (DEBUG) {
debug("Error! The UI glue component is not implemented.")
debug("Error! The UI glue component is not implemented.");
}
// Resolve the caller as if there were no selected apps.
@@ -951,14 +968,14 @@ this.InterAppCommService = {
if (selectedApps.length == 0) {
// Only do the connections for the existing allowed subscribers because
// no new apps are selected to connect.
if (DEBUG) debug("No new apps are selected to connect.")
if (DEBUG) debug("No new apps are selected to connect.");
allowedSubAppManifestURLs =
this._getAllowedSubAppManifestURLs(keyword, pubAppManifestURL);
} else {
// Do connections for for the existing allowed subscribers and the newly
// selected subscribers.
if (DEBUG) debug("Some new apps are selected to connect.")
if (DEBUG) debug("Some new apps are selected to connect.");
allowedSubAppManifestURLs =
this._addSelectedApps(keyword, pubAppManifestURL, selectedApps);
@@ -1044,7 +1061,8 @@ this.InterAppCommService = {
return;
}
let manifestURL = appsService.getManifestURLByLocalId(params.appId);
let manifestURL =
this.appsService.getManifestURLByLocalId(params.appId);
if (!manifestURL) {
if (DEBUG) {
debug("Error updating registered/allowed connections for an " +
+82 -12
View File
@@ -6,7 +6,11 @@
#include "AudioChannelAgent.h"
#include "AudioChannelService.h"
#include "mozilla/Preferences.h"
#include "nsIAppsService.h"
#include "nsIDocument.h"
#include "nsIDOMWindow.h"
#include "nsIPrincipal.h"
#include "nsPIDOMWindow.h"
#include "nsXULAppAPI.h"
@@ -77,6 +81,81 @@ AudioChannelAgent::InitWithWeakCallback(nsIDOMWindow* aWindow,
/* useWeakRef = */ true);
}
nsresult
AudioChannelAgent::FindCorrectWindow(nsIDOMWindow* aWindow)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryInterface(aWindow);
MOZ_ASSERT(window->IsInnerWindow());
mWindow = window->GetScriptableTop();
if (NS_WARN_IF(!mWindow)) {
return NS_OK;
}
mWindow = mWindow->GetOuterWindow();
if (NS_WARN_IF(!mWindow)) {
return NS_ERROR_FAILURE;
}
// From here we do an hack for nested iframes.
// The system app doesn't have access to the nested iframe objects so it
// cannot control the volume of the agents running in nested apps. What we do
// here is to assign those Agents to the top scriptable window of the parent
// iframe (what is controlled by the system app).
// For doing this we go recursively back into the chain of windows until we
// find apps that are not the system one.
window = mWindow->GetParent();
if (!window || window == mWindow) {
return NS_OK;
}
window = window->GetCurrentInnerWindow();
if (!window) {
return NS_OK;
}
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
if (!doc) {
return NS_OK;
}
nsCOMPtr<nsIPrincipal> principal = doc->NodePrincipal();
uint32_t appId;
nsresult rv = principal->GetAppId(&appId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (appId == nsIScriptSecurityManager::NO_APP_ID ||
appId == nsIScriptSecurityManager::UNKNOWN_APP_ID) {
return NS_OK;
}
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
if (NS_WARN_IF(!appsService)) {
return NS_ERROR_FAILURE;
}
nsAdoptingString systemAppManifest =
mozilla::Preferences::GetString("b2g.system_manifest_url");
if (!systemAppManifest) {
return NS_OK;
}
uint32_t systemAppId;
rv = appsService->GetAppLocalIdByManifestURL(systemAppManifest, &systemAppId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
if (systemAppId == appId) {
return NS_OK;
}
return FindCorrectWindow(window);
}
nsresult
AudioChannelAgent::InitInternal(nsIDOMWindow* aWindow, int32_t aChannelType,
nsIAudioChannelAgentCallback *aCallback,
@@ -108,18 +187,9 @@ AudioChannelAgent::InitInternal(nsIDOMWindow* aWindow, int32_t aChannelType,
MOZ_ASSERT(pInnerWindow->IsInnerWindow());
mInnerWindowID = pInnerWindow->WindowID();
nsCOMPtr<nsPIDOMWindow> topWindow = pInnerWindow->GetScriptableTop();
if (NS_WARN_IF(!topWindow)) {
return NS_OK;
}
mWindow = do_QueryInterface(topWindow);
if (mWindow) {
mWindow = mWindow->GetOuterWindow();
}
if (NS_WARN_IF(!mWindow)) {
return NS_ERROR_FAILURE;
nsresult rv = FindCorrectWindow(aWindow);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
mAudioChannelType = aChannelType;
+2
View File
@@ -56,6 +56,8 @@ private:
void Shutdown();
nsresult FindCorrectWindow(nsIDOMWindow* aWindow);
nsCOMPtr<nsPIDOMWindow> mWindow;
nsCOMPtr<nsIAudioChannelAgentCallback> mCallback;
+45 -2
View File
@@ -14,6 +14,7 @@
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/TabParent.h"
#include "nsContentUtils.h"
#include "nsIScriptSecurityManager.h"
@@ -219,6 +220,7 @@ AudioChannelService::Shutdown()
gAudioChannelService->mWindows.Clear();
gAudioChannelService->mPlayingChildren.Clear();
gAudioChannelService->mTabParents.Clear();
#ifdef MOZ_WIDGET_GONK
gAudioChannelService->mSpeakerManager.Clear();
#endif
@@ -341,6 +343,21 @@ AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent,
MaybeSendStatusUpdate();
}
void
AudioChannelService::RegisterTabParent(TabParent* aTabParent)
{
MOZ_ASSERT(aTabParent);
MOZ_ASSERT(!mTabParents.Contains(aTabParent));
mTabParents.AppendElement(aTabParent);
}
void
AudioChannelService::UnregisterTabParent(TabParent* aTabParent)
{
MOZ_ASSERT(aTabParent);
mTabParents.RemoveElement(aTabParent);
}
void
AudioChannelService::GetState(nsPIDOMWindow* aWindow, uint32_t aAudioChannel,
float* aVolume, bool* aMuted)
@@ -560,6 +577,32 @@ AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic,
return NS_OK;
}
void
AudioChannelService::RefreshAgentsVolumeAndPropagate(AudioChannel aAudioChannel,
nsPIDOMWindow* aWindow)
{
MOZ_ASSERT(aWindow);
MOZ_ASSERT(aWindow->IsOuterWindow());
nsCOMPtr<nsPIDOMWindow> topWindow = aWindow->GetScriptableTop();
if (!topWindow) {
return;
}
AudioChannelWindow* winData = GetWindowData(topWindow->WindowID());
if (!winData) {
return;
}
for (uint32_t i = 0; i < mTabParents.Length(); ++i) {
mTabParents[i]->AudioChannelChangeNotification(aWindow, aAudioChannel,
winData->mChannels[(uint32_t)aAudioChannel].mVolume,
winData->mChannels[(uint32_t)aAudioChannel].mMuted);
}
RefreshAgentsVolume(aWindow);
}
void
AudioChannelService::RefreshAgentsVolume(nsPIDOMWindow* aWindow)
{
@@ -751,7 +794,7 @@ AudioChannelService::SetAudioChannelVolume(nsPIDOMWindow* aWindow,
AudioChannelWindow* winData = GetOrCreateWindowData(aWindow);
winData->mChannels[(uint32_t)aAudioChannel].mVolume = aVolume;
RefreshAgentsVolume(aWindow);
RefreshAgentsVolumeAndPropagate(aAudioChannel, aWindow);
}
NS_IMETHODIMP
@@ -814,7 +857,7 @@ AudioChannelService::SetAudioChannelMuted(nsPIDOMWindow* aWindow,
AudioChannelWindow* winData = GetOrCreateWindowData(aWindow);
winData->mChannels[(uint32_t)aAudioChannel].mMuted = aMuted;
RefreshAgentsVolume(aWindow);
RefreshAgentsVolumeAndPropagate(aAudioChannel, aWindow);
}
NS_IMETHODIMP
+15
View File
@@ -23,10 +23,13 @@ struct PRLogModuleInfo;
namespace mozilla {
namespace dom {
#ifdef MOZ_WIDGET_GONK
class SpeakerManagerService;
#endif
class TabParent;
#define NUMBER_OF_AUDIO_CHANNELS (uint32_t)AudioChannel::EndGuard_
class AudioChannelService final : public nsIAudioChannelService
@@ -63,6 +66,12 @@ public:
void UnregisterAudioChannelAgent(AudioChannelAgent* aAgent,
uint32_t aNotifyPlayback);
/**
* For nested iframes.
*/
void RegisterTabParent(TabParent* aTabParent);
void UnregisterTabParent(TabParent* aTabParent);
/**
* Return the state to indicate this audioChannel for his window should keep
* playing/muted.
@@ -108,6 +117,9 @@ public:
void RefreshAgentsVolume(nsPIDOMWindow* aWindow);
void RefreshAgentsVolumeAndPropagate(AudioChannel aAudioChannel,
nsPIDOMWindow* aWindow);
// This method needs to know the inner window that wants to capture audio. We
// group agents per top outer window, but we can have multiple innerWindow per
// top outerWindow (subiframes, etc.) and we have to identify all the agents
@@ -223,6 +235,9 @@ private:
nsTArray<SpeakerManagerService*> mSpeakerManager;
#endif
// Raw pointers because TabParents must unregister themselves.
nsTArray<TabParent*> mTabParents;
nsCOMPtr<nsIRunnable> mRunnable;
uint64_t mDefChannelChildID;
+12 -2
View File
@@ -552,6 +552,16 @@ Element::GetClassList(nsISupports** aClassList)
NS_ADDREF(*aClassList = ClassList());
}
void
Element::GetAttributeNames(nsTArray<nsString>& aResult)
{
uint32_t count = mAttrsAndChildren.AttrCount();
for (uint32_t i = 0; i < count; ++i) {
const nsAttrName* name = mAttrsAndChildren.AttrNameAt(i);
name->GetQualifiedName(*aResult.AppendElement());
}
}
already_AddRefed<nsIHTMLCollection>
Element::GetElementsByTagName(const nsAString& aLocalName)
{
@@ -3721,11 +3731,11 @@ Element::FontSizeInflation()
}
net::ReferrerPolicy
Element::GetReferrerPolicy()
Element::GetReferrerPolicyAsEnum()
{
if (Preferences::GetBool("network.http.enablePerElementReferrer", false) &&
IsHTMLElement()) {
const nsAttrValue* referrerValue = GetParsedAttr(nsGkAtoms::referrer);
const nsAttrValue* referrerValue = GetParsedAttr(nsGkAtoms::referrerpolicy);
if (referrerValue && referrerValue->Type() == nsAttrValue::eEnum) {
return net::ReferrerPolicy(referrerValue->GetEnumValue());
}
+6 -9
View File
@@ -634,6 +634,9 @@ public:
return slots->mAttributeMap;
}
void GetAttributeNames(nsTArray<nsString>& aResult);
void GetAttribute(const nsAString& aName, nsString& aReturn)
{
DOMString str;
@@ -680,12 +683,6 @@ public:
ErrorResult& aError);
already_AddRefed<nsIHTMLCollection>
GetElementsByClassName(const nsAString& aClassNames);
bool MozMatchesSelector(const nsAString& aSelector,
ErrorResult& aError)
{
return Matches(aSelector, aError);
}
private:
/**
* Implement the algorithm specified at
@@ -1111,7 +1108,7 @@ public:
*/
float FontSizeInflation();
net::ReferrerPolicy GetReferrerPolicy();
net::ReferrerPolicy GetReferrerPolicyAsEnum();
protected:
/*
@@ -1817,8 +1814,8 @@ NS_IMETHOD MozMatchesSelector(const nsAString& selector, \
bool* _retval) final override \
{ \
mozilla::ErrorResult rv; \
*_retval = Element::MozMatchesSelector(selector, rv); \
return rv.StealNSResult(); \
*_retval = Element::Matches(selector, rv); \
return rv.StealNSResult(); \
} \
NS_IMETHOD SetCapture(bool retargetToElement) final override \
{ \
+26
View File
@@ -14,6 +14,7 @@
#include "nsEscape.h"
#include "nsGkAtoms.h"
#include "nsHTMLDNSPrefetch.h"
#include "nsString.h"
#include "mozAutoDocUpdate.h"
@@ -46,6 +47,31 @@ Link::ElementHasHref() const
mElement->HasAttr(kNameSpaceID_XLink, nsGkAtoms::href)));
}
void
Link::TryDNSPrefetch()
{
MOZ_ASSERT(mElement->IsInComposedDoc());
if (ElementHasHref() && nsHTMLDNSPrefetch::IsAllowed(mElement->OwnerDoc())) {
nsHTMLDNSPrefetch::PrefetchLow(this);
}
}
void
Link::CancelDNSPrefetch(nsWrapperCache::FlagsType aDeferredFlag,
nsWrapperCache::FlagsType aRequestedFlag)
{
// If prefetch was deferred, clear flag and move on
if (mElement->HasFlag(aDeferredFlag)) {
mElement->UnsetFlags(aDeferredFlag);
// Else if prefetch was requested, clear flag and send cancellation
} else if (mElement->HasFlag(aRequestedFlag)) {
mElement->UnsetFlags(aRequestedFlag);
// Possible that hostname could have changed since binding, but since this
// covers common cases, most DNS prefetch requests will be canceled
nsHTMLDNSPrefetch::CancelPrefetchLow(this, NS_ERROR_ABORT);
}
}
void
Link::SetLinkState(nsLinkState aState)
{
+5
View File
@@ -111,6 +111,11 @@ public:
bool ElementHasHref() const;
void TryDNSPrefetch();
void CancelDNSPrefetch(nsWrapperCache::FlagsType aDeferredFlag,
nsWrapperCache::FlagsType aRequestedFlag);
protected:
virtual ~Link();
+5 -16
View File
@@ -2682,23 +2682,12 @@ nsDocument::ApplySettingsFromCSP(bool aSpeculative)
}
// 2) apply settings from speculative csp
nsCOMPtr<nsIContentSecurityPolicy> preloadCsp;
rv = NodePrincipal()->GetPreloadCsp(getter_AddRefs(preloadCsp));
if (preloadCsp) {
// Set up any Referrer Policy specified by CSP
bool hasReferrerPolicy = false;
uint32_t referrerPolicy = mozilla::net::RP_Default;
rv = preloadCsp->GetReferrerPolicy(&referrerPolicy, &hasReferrerPolicy);
if (!mUpgradeInsecurePreloads) {
nsCOMPtr<nsIContentSecurityPolicy> preloadCsp;
rv = NodePrincipal()->GetPreloadCsp(getter_AddRefs(preloadCsp));
NS_ENSURE_SUCCESS_VOID(rv);
if (hasReferrerPolicy) {
// please note that referrer policy spec defines that the latest
// policy awlays wins, hence we can safely overwrite the policy here.
mReferrerPolicy = static_cast<ReferrerPolicy>(referrerPolicy);
mReferrerPolicySet = true;
}
if (!mUpgradeInsecurePreloads) {
rv = preloadCsp->GetUpgradeInsecureRequests(&mUpgradeInsecurePreloads);
NS_ENSURE_SUCCESS_VOID(rv);
if (preloadCsp) {
preloadCsp->GetUpgradeInsecureRequests(&mUpgradeInsecurePreloads);
}
}
}
+1 -1
View File
@@ -417,7 +417,7 @@ nsFrameLoader::ReallyStartLoadingInternal()
net::ReferrerPolicy referrerPolicy = mOwnerContent->OwnerDoc()->GetReferrerPolicy();
HTMLIFrameElement* iframe = HTMLIFrameElement::FromContent(mOwnerContent);
if (iframe) {
net::ReferrerPolicy iframeReferrerPolicy = iframe->GetReferrerPolicy();
net::ReferrerPolicy iframeReferrerPolicy = iframe->GetReferrerPolicyAsEnum();
if (iframeReferrerPolicy != net::RP_Unset) {
referrerPolicy = iframeReferrerPolicy;
}
+1
View File
@@ -594,6 +594,7 @@ GK_ATOM(menuseparator, "menuseparator")
GK_ATOM(message, "message")
GK_ATOM(meta, "meta")
GK_ATOM(referrer, "referrer")
GK_ATOM(referrerpolicy, "referrerpolicy")
GK_ATOM(meter, "meter")
GK_ATOM(method, "method")
GK_ATOM(microdataProperties, "microdataProperties")
+8 -1
View File
@@ -5,6 +5,7 @@
#include "nsISupports.idl"
interface mozIApplication;
interface nsFrameLoader;
interface nsIDocShell;
interface nsIURI;
@@ -214,7 +215,7 @@ class nsFrameLoader;
native alreadyAddRefed_nsFrameLoader(already_AddRefed<nsFrameLoader>);
[scriptable, uuid(c4abebcf-55f3-47d4-af15-151311971255)]
[scriptable, uuid(adc1b3ba-8deb-4943-8045-e6de0044f2ce)]
interface nsIFrameLoaderOwner : nsISupports
{
/**
@@ -223,6 +224,12 @@ interface nsIFrameLoaderOwner : nsISupports
readonly attribute nsIFrameLoader frameLoader;
[noscript, notxpcom] alreadyAddRefed_nsFrameLoader GetFrameLoader();
/**
* The principal of parent mozIApplication in case of nested mozbrowser
* iframes.
*/
readonly attribute mozIApplication parentApplication;
/**
* Puts the FrameLoaderOwner in prerendering mode.
*/
+11
View File
@@ -1213,6 +1213,17 @@ nsObjectLoadingContent::GetFrameLoader()
return loader.forget();
}
NS_IMETHODIMP
nsObjectLoadingContent::GetParentApplication(mozIApplication** aApplication)
{
if (!aApplication) {
return NS_ERROR_FAILURE;
}
*aApplication = nullptr;
return NS_OK;
}
NS_IMETHODIMP
nsObjectLoadingContent::SetIsPrerendered()
{
@@ -7,6 +7,8 @@
#include "mozilla/Services.h"
#include "mozilla/dom/BrowserElementAudioChannelBinding.h"
#include "mozilla/dom/DOMRequest.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/PromiseNativeHandler.h"
#include "mozilla/dom/ToJSValue.h"
@@ -23,16 +25,6 @@
#include "nsPIDOMWindow.h"
#include "nsServiceManagerUtils.h"
namespace {
void
AssertIsInMainProcess()
{
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_Default);
}
} // anonymous namespace
namespace mozilla {
namespace dom {
@@ -89,7 +81,6 @@ BrowserElementAudioChannel::BrowserElementAudioChannel(
, mState(eStateUnknown)
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsInMainProcess();
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
@@ -107,7 +98,6 @@ BrowserElementAudioChannel::BrowserElementAudioChannel(
BrowserElementAudioChannel::~BrowserElementAudioChannel()
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsInMainProcess();
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
@@ -173,8 +163,6 @@ AudioChannel
BrowserElementAudioChannel::Name() const
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsInMainProcess();
return mAudioChannel;
}
@@ -361,7 +349,6 @@ already_AddRefed<dom::DOMRequest>
BrowserElementAudioChannel::GetVolume(ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsInMainProcess();
if (!mFrameWindow) {
nsCOMPtr<nsIDOMDOMRequest> request;
@@ -387,7 +374,6 @@ already_AddRefed<dom::DOMRequest>
BrowserElementAudioChannel::SetVolume(float aVolume, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsInMainProcess();
if (!mFrameWindow) {
nsCOMPtr<nsIDOMDOMRequest> request;
@@ -420,7 +406,6 @@ already_AddRefed<dom::DOMRequest>
BrowserElementAudioChannel::GetMuted(ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsInMainProcess();
if (!mFrameWindow) {
nsCOMPtr<nsIDOMDOMRequest> request;
@@ -446,7 +431,6 @@ already_AddRefed<dom::DOMRequest>
BrowserElementAudioChannel::SetMuted(bool aMuted, ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsInMainProcess();
if (!mFrameWindow) {
nsCOMPtr<nsIDOMDOMRequest> request;
@@ -479,7 +463,6 @@ already_AddRefed<dom::DOMRequest>
BrowserElementAudioChannel::IsActive(ErrorResult& aRv)
{
MOZ_ASSERT(NS_IsMainThread());
AssertIsInMainProcess();
if (mState != eStateUnknown) {
RefPtr<DOMRequest> domRequest = new DOMRequest(GetOwner());
@@ -593,8 +576,29 @@ BrowserElementAudioChannel::Observe(nsISupports* aSubject, const char* aTopic,
}
nsCOMPtr<nsISupportsPRUint64> wrapper = do_QueryInterface(aSubject);
if (NS_WARN_IF(!wrapper)) {
return NS_ERROR_FAILURE;
// This can be a nested iframe.
if (!wrapper) {
nsCOMPtr<nsITabParent> iTabParent = do_QueryInterface(aSubject);
if (!iTabParent) {
return NS_ERROR_FAILURE;
}
RefPtr<TabParent> tabParent = TabParent::GetFrom(iTabParent);
if (!tabParent) {
return NS_ERROR_FAILURE;
}
Element* element = tabParent->GetOwnerElement();
if (!element) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsPIDOMWindow> window = element->OwnerDoc()->GetWindow();
if (window == mFrameWindow) {
ProcessStateChanged(aData);
}
return NS_OK;
}
uint64_t windowID;
@@ -144,7 +144,10 @@ function runTests() {
}
addEventListener('load', function() {
SimpleTest.executeSoon(runTests);
addEventListener('testready', function() {
SpecialPowers.pushPrefEnv({'set': [["b2g.system_manifest_url", "http://mochi.test:8888/manifest.webapp"]]},
function() {
SimpleTest.executeSoon(runTests);
});
});
@@ -0,0 +1,79 @@
/* Any copyright is dedicated to the public domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Bug 1113086 - tests for AudioChannel API into BrowserElement
"use strict";
SimpleTest.waitForExplicitFinish();
browserElementTestHelpers.setEnabledPref(true);
browserElementTestHelpers.addPermission();
function runTests() {
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
iframe.setAttribute('mozapp', 'http://example.org/manifest.webapp');
var listener = function(e) {
var message = e.detail.message;
if (/^OK/.exec(message)) {
ok(true, "Message from app: " + message);
} else if (/^KO/.exec(message)) {
ok(false, "Message from app: " + message);
} else if (/DONE/.exec(message)) {
ok(true, "Messaging from app complete");
iframe.removeEventListener('mozbrowsershowmodalprompt', listener);
}
}
function audio_loadend() {
ok("mute" in iframe, "iframe.mute exists");
ok("unmute" in iframe, "iframe.unmute exists");
ok("getMuted" in iframe, "iframe.getMuted exists");
ok("getVolume" in iframe, "iframe.getVolume exists");
ok("setVolume" in iframe, "iframe.setVolume exists");
ok("allowedAudioChannels" in iframe, "allowedAudioChannels exist");
var channels = iframe.allowedAudioChannels;
is(channels.length, 1, "1 audio channel by default");
var ac = channels[0];
ok(ac instanceof BrowserElementAudioChannel, "Correct class");
ok("getVolume" in ac, "ac.getVolume exists");
ok("setVolume" in ac, "ac.setVolume exists");
ok("getMuted" in ac, "ac.getMuted exists");
ok("setMuted" in ac, "ac.setMuted exists");
ok("isActive" in ac, "ac.isActive exists");
info("Setting the volume...");
ac.setVolume(0.5);
ac.onactivestatechanged = function() {
ok(true, "activestatechanged event received.");
ac.onactivestatechanged = null;
SimpleTest.finish();
}
}
iframe.addEventListener('mozbrowserloadend', audio_loadend);
iframe.addEventListener('mozbrowsershowmodalprompt', listener, false);
document.body.appendChild(iframe);
var context = { 'url': 'http://example.org',
'appId': SpecialPowers.Ci.nsIScriptSecurityManager.NO_APP_ID,
'isInBrowserElement': true };
SpecialPowers.pushPermissions([
{'type': 'browser', 'allow': 1, 'context': context},
{'type': 'embed-apps', 'allow': 1, 'context': context}
], function() {
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_browserElement_AudioChannel_nested.html';
});
}
addEventListener('testready', function() {
SpecialPowers.pushPrefEnv({'set': [["b2g.system_manifest_url", "http://mochi.test:8888/manifest.webapp"]]},
function() {
SimpleTest.executeSoon(runTests);
});
});
@@ -0,0 +1,63 @@
<html>
<head>
<script type="text/javascript">
function ok(a, msg) {
alert((!!a ? "OK" : "KO") + " " + msg);
}
function is(a, b, msg) {
ok(a === b, msg);
}
function finish(a, b, msg) {
alert("DONE");
}
addEventListener('load', function(e) {
var iframe = document.createElement('iframe');
iframe.setAttribute('mozbrowser', 'true');
// set 'remote' to true here will make the the iframe remote in _inproc_
// test and in-process in _oop_ test.
iframe.setAttribute('remote', 'true');
iframe.setAttribute('mozapp', 'http://example.org/manifest.webapp');
iframe.addEventListener('mozbrowserloadend', function(e) {
ok("mute" in iframe, "iframe.mute exists");
ok("unmute" in iframe, "iframe.unmute exists");
ok("getMuted" in iframe, "iframe.getMuted exists");
ok("getVolume" in iframe, "iframe.getVolume exists");
ok("setVolume" in iframe, "iframe.setVolume exists");
ok("allowedAudioChannels" in iframe, "allowedAudioChannels exist");
var channels = iframe.allowedAudioChannels;
is(channels.length, 1, "1 audio channel by default");
var ac = channels[0];
ok(ac instanceof BrowserElementAudioChannel, "Correct class");
ok("getVolume" in ac, "ac.getVolume exists");
ok("setVolume" in ac, "ac.setVolume exists");
ok("getMuted" in ac, "ac.getMuted exists");
ok("setMuted" in ac, "ac.setMuted exists");
ok("isActive" in ac, "ac.isActive exists");
ac.onactivestatechanged = function() {
ok("activestatechanged event received.");
ac.getVolume().onsuccess = function(e) {
ok(e.target.result, 1, "Default volume is 1");
};
finish();
}
});
document.body.appendChild(iframe);
iframe.src = 'http://example.org/tests/dom/browser-element/mochitest/file_audio.html';
});
</script>
</head>
<body>
</body>
</html>
@@ -115,6 +115,7 @@ disabled = bug 924771
disabled = bug 924771
[test_browserElement_oop_GetContentDimensions.html]
[test_browserElement_oop_AudioChannel.html]
[test_browserElement_oop_AudioChannel_nested.html]
[test_browserElement_oop_SetNFCFocus.html]
[test_browserElement_oop_getWebManifest.html]
[test_browserElement_oop_OpenWindowEmpty.html]
@@ -82,11 +82,13 @@ support-files =
browserElement_XFrameOptionsSameOrigin.js
browserElement_GetContentDimensions.js
browserElement_AudioChannel.js
browserElement_AudioChannel_nested.js
file_browserElement_AlertInFrame.html
file_browserElement_AlertInFrame_Inner.html
file_browserElement_AllowEmbedAppsInNestedOOIframe.html
file_browserElement_AppFramePermission.html
file_browserElement_AppWindowNamespace.html
file_browserElement_AudioChannel_nested.html
file_browserElement_Viewmode.html
file_browserElement_ThemeColor.html
file_browserElement_BrowserWindowNamespace.html
@@ -246,6 +248,7 @@ skip-if = (toolkit == 'android' && processor == 'x86') #x86 only bug 936226
disabled = bug 774100
[test_browserElement_inproc_GetContentDimensions.html]
[test_browserElement_inproc_AudioChannel.html]
[test_browserElement_inproc_AudioChannel_nested.html]
[test_browserElement_inproc_SetNFCFocus.html]
[test_browserElement_inproc_getStructuredData.html]
[test_browserElement_inproc_OpenWindowEmpty.html]
@@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test of browser element audioChannel in nested mozbrowser iframes.</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7" src="browserElement_AudioChannel_nested.js">
</script>
</body>
</html>
@@ -0,0 +1,13 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test of browser element audioChannel.</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="browserElementTestHelpers.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7" src="browserElement_AudioChannel_nested.js">
</script>
</body>
</html>
+7 -5
View File
@@ -737,15 +737,17 @@ EventStateManager::PreHandleEvent(nsPresContext* aPresContext,
if (content)
mCurrentTargetContent = content;
// NOTE: Don't refer TextComposition::IsComposing() since DOM Level 3
// Events defines that KeyboardEvent.isComposing is true when it's
// NOTE: Don't refer TextComposition::IsComposing() since UI Events
// defines that KeyboardEvent.isComposing is true when it's
// dispatched after compositionstart and compositionend.
// TextComposition::IsComposing() is false even before
// compositionend if there is no composing string.
WidgetKeyboardEvent* keyEvent = aEvent->AsKeyboardEvent();
// And also don't expose other document's composition state.
// A native IME context is typically shared by multiple documents.
// So, don't use GetTextCompositionFor(nsIWidget*) here.
RefPtr<TextComposition> composition =
IMEStateManager::GetTextCompositionFor(keyEvent);
keyEvent->mIsComposing = !!composition;
IMEStateManager::GetTextCompositionFor(aPresContext);
aEvent->AsKeyboardEvent()->mIsComposing = !!composition;
}
break;
case eWheel:
+43 -7
View File
@@ -1137,11 +1137,21 @@ IMEStateManager::DispatchCompositionEvent(
MOZ_LOG(sISMLog, LogLevel::Info,
("ISM: IMEStateManager::DispatchCompositionEvent(aNode=0x%p, "
"aPresContext=0x%p, aCompositionEvent={ message=%s, "
"aPresContext=0x%p, aCompositionEvent={ mMessage=%s, "
"mNativeIMEContext={ mRawNativeIMEContext=0x%X, "
"mOriginProcessID=0x%X }, widget(0x%p)={ "
"GetNativeIMEContext()={ mRawNativeIMEContext=0x%X, "
"mOriginProcessID=0x%X }, Destroyed()=%s }, "
"mFlags={ mIsTrusted=%s, mPropagationStopped=%s } }, "
"aIsSynthesized=%s), tabParent=%p",
aEventTargetNode, aPresContext,
ToChar(aCompositionEvent->mMessage),
aCompositionEvent->mNativeIMEContext.mRawNativeIMEContext,
aCompositionEvent->mNativeIMEContext.mOriginProcessID,
aCompositionEvent->widget.get(),
aCompositionEvent->widget->GetNativeIMEContext().mRawNativeIMEContext,
aCompositionEvent->widget->GetNativeIMEContext().mOriginProcessID,
GetBoolName(aCompositionEvent->widget->Destroyed()),
GetBoolName(aCompositionEvent->mFlags.mIsTrusted),
GetBoolName(aCompositionEvent->mFlags.mPropagationStopped),
GetBoolName(aIsSynthesized), tabParent.get()));
@@ -1157,7 +1167,7 @@ IMEStateManager::DispatchCompositionEvent(
EnsureTextCompositionArray();
RefPtr<TextComposition> composition =
sTextCompositions->GetCompositionFor(aCompositionEvent->widget);
sTextCompositions->GetCompositionFor(aCompositionEvent);
if (!composition) {
// If synthesized event comes after delayed native composition events
// for request of commit or cancel, we should ignore it.
@@ -1271,8 +1281,18 @@ IMEStateManager::OnCompositionEventDiscarded(
MOZ_LOG(sISMLog, LogLevel::Info,
("ISM: IMEStateManager::OnCompositionEventDiscarded(aCompositionEvent={ "
"mMessage=%s, mFlags={ mIsTrusted=%s } })",
"mMessage=%s, mNativeIMEContext={ mRawNativeIMEContext=0x%X, "
"mOriginProcessID=0x%X }, widget(0x%p)={ "
"GetNativeIMEContext()={ mRawNativeIMEContext=0x%X, "
"mOriginProcessID=0x%X }, Destroyed()=%s }, "
"mFlags={ mIsTrusted=%s } })",
ToChar(aCompositionEvent->mMessage),
aCompositionEvent->mNativeIMEContext.mRawNativeIMEContext,
aCompositionEvent->mNativeIMEContext.mOriginProcessID,
aCompositionEvent->widget.get(),
aCompositionEvent->widget->GetNativeIMEContext().mRawNativeIMEContext,
aCompositionEvent->widget->GetNativeIMEContext().mOriginProcessID,
GetBoolName(aCompositionEvent->widget->Destroyed()),
GetBoolName(aCompositionEvent->mFlags.mIsTrusted)));
if (!aCompositionEvent->mFlags.mIsTrusted) {
@@ -1631,11 +1651,27 @@ IMEStateManager::GetTextCompositionFor(nsIWidget* aWidget)
// static
already_AddRefed<TextComposition>
IMEStateManager::GetTextCompositionFor(WidgetGUIEvent* aGUIEvent)
IMEStateManager::GetTextCompositionFor(
const WidgetCompositionEvent* aCompositionEvent)
{
MOZ_ASSERT(aGUIEvent->AsCompositionEvent() || aGUIEvent->AsKeyboardEvent(),
"aGUIEvent has to be WidgetCompositionEvent or WidgetKeyboardEvent");
return GetTextCompositionFor(aGUIEvent->widget);
if (!sTextCompositions) {
return nullptr;
}
RefPtr<TextComposition> textComposition =
sTextCompositions->GetCompositionFor(aCompositionEvent);
return textComposition.forget();
}
// static
already_AddRefed<TextComposition>
IMEStateManager::GetTextCompositionFor(nsPresContext* aPresContext)
{
if (!sTextCompositions) {
return nullptr;
}
RefPtr<TextComposition> textComposition =
sTextCompositions->GetCompositionFor(aPresContext);
return textComposition.forget();
}
} // namespace mozilla
+9 -3
View File
@@ -181,11 +181,17 @@ public:
/**
* Returns TextComposition instance for the event.
*
* @param aGUIEvent Should be a composition event which is being dispatched.
*/
static already_AddRefed<TextComposition>
GetTextCompositionFor(WidgetGUIEvent* aGUIEvent);
GetTextCompositionFor(const WidgetCompositionEvent* aCompositionEvent);
/**
* Returns TextComposition instance for the pres context.
* Be aware, even if another pres context which shares native IME context with
* specified pres context has composition, this returns nullptr.
*/
static already_AddRefed<TextComposition>
GetTextCompositionFor(nsPresContext* aPresContext);
/**
* Send a notification to IME. It depends on the IME or platform spec what
+37 -10
View File
@@ -39,8 +39,7 @@ TextComposition::TextComposition(nsPresContext* aPresContext,
: mPresContext(aPresContext)
, mNode(aNode)
, mTabParent(aTabParent)
, mNativeContext(
aCompositionEvent->widget->GetInputContext().mNativeIMEContext)
, mNativeContext(aCompositionEvent->mNativeIMEContext)
, mCompositionStartOffset(0)
, mCompositionTargetOffset(0)
, mIsSynthesizedForTests(aCompositionEvent->mFlags.mIsSynthesizedForTests)
@@ -54,6 +53,7 @@ TextComposition::TextComposition(nsPresContext* aPresContext,
Preferences::GetBool("dom.compositionevent.allow_control_characters",
false))
{
MOZ_ASSERT(aCompositionEvent->mNativeIMEContext.IsValid());
}
void
@@ -66,12 +66,6 @@ TextComposition::Destroy()
// this being destroyed for cleaning up the stuff.
}
bool
TextComposition::MatchesNativeContext(nsIWidget* aWidget) const
{
return mNativeContext == aWidget->GetInputContext().mNativeIMEContext;
}
bool
TextComposition::IsValidStateForComposition(nsIWidget* aWidget) const
{
@@ -114,6 +108,7 @@ TextComposition::CloneAndDispatchAs(
compositionEvent.time = aCompositionEvent->time;
compositionEvent.timeStamp = aCompositionEvent->timeStamp;
compositionEvent.mData = aCompositionEvent->mData;
compositionEvent.mNativeIMEContext = aCompositionEvent->mNativeIMEContext;
compositionEvent.mOriginalMessage = aCompositionEvent->mMessage;
compositionEvent.mFlags.mIsSynthesizedForTests =
aCompositionEvent->mFlags.mIsSynthesizedForTests;
@@ -613,6 +608,7 @@ TextComposition::CompositionEventDispatcher::Run()
switch (mEventMessage) {
case eCompositionStart: {
WidgetCompositionEvent compStart(true, eCompositionStart, widget);
compStart.mNativeIMEContext = mTextComposition->mNativeContext;
WidgetQueryContentEvent selectedText(true, eQuerySelectedText, widget);
ContentEventHandler handler(presContext);
handler.OnQuerySelectedText(&selectedText);
@@ -629,6 +625,7 @@ TextComposition::CompositionEventDispatcher::Run()
case eCompositionCommitAsIs:
case eCompositionCommit: {
WidgetCompositionEvent compEvent(true, mEventMessage, widget);
compEvent.mNativeIMEContext = mTextComposition->mNativeContext;
if (mEventMessage != eCompositionCommitAsIs) {
compEvent.mData = mData;
}
@@ -650,16 +647,25 @@ TextComposition::CompositionEventDispatcher::Run()
******************************************************************************/
TextCompositionArray::index_type
TextCompositionArray::IndexOf(nsIWidget* aWidget)
TextCompositionArray::IndexOf(const NativeIMEContext& aNativeIMEContext)
{
if (!aNativeIMEContext.IsValid()) {
return NoIndex;
}
for (index_type i = Length(); i > 0; --i) {
if (ElementAt(i - 1)->MatchesNativeContext(aWidget)) {
if (ElementAt(i - 1)->GetNativeIMEContext() == aNativeIMEContext) {
return i - 1;
}
}
return NoIndex;
}
TextCompositionArray::index_type
TextCompositionArray::IndexOf(nsIWidget* aWidget)
{
return IndexOf(aWidget->GetNativeIMEContext());
}
TextCompositionArray::index_type
TextCompositionArray::IndexOf(nsPresContext* aPresContext)
{
@@ -693,6 +699,27 @@ TextCompositionArray::GetCompositionFor(nsIWidget* aWidget)
return ElementAt(i);
}
TextComposition*
TextCompositionArray::GetCompositionFor(
const WidgetCompositionEvent* aCompositionEvent)
{
index_type i = IndexOf(aCompositionEvent->mNativeIMEContext);
if (i == NoIndex) {
return nullptr;
}
return ElementAt(i);
}
TextComposition*
TextCompositionArray::GetCompositionFor(nsPresContext* aPresContext)
{
index_type i = IndexOf(aPresContext);
if (i == NoIndex) {
return nullptr;
}
return ElementAt(i);
}
TextComposition*
TextCompositionArray::GetCompositionFor(nsPresContext* aPresContext,
nsINode* aNode)
+14 -3
View File
@@ -76,7 +76,10 @@ public:
// came from nsDOMWindowUtils.
bool IsSynthesizedForTests() const { return mIsSynthesizedForTests; }
bool MatchesNativeContext(nsIWidget* aWidget) const;
const widget::NativeIMEContext& GetNativeIMEContext() const
{
return mNativeContext;
}
/**
* This is called when IMEStateManager stops managing the instance.
@@ -191,7 +194,7 @@ private:
// mNativeContext stores a opaque pointer. This works as the "ID" for this
// composition. Don't access the instance, it may not be available.
void* mNativeContext;
widget::NativeIMEContext mNativeContext;
// mEditorWeak is a weak reference to the focused editor handling composition.
nsWeakPtr mEditorWeak;
@@ -400,11 +403,19 @@ class TextCompositionArray final :
public nsAutoTArray<RefPtr<TextComposition>, 2>
{
public:
// Looking for per native IME context.
index_type IndexOf(const widget::NativeIMEContext& aNativeIMEContext);
index_type IndexOf(nsIWidget* aWidget);
TextComposition* GetCompositionFor(nsIWidget* aWidget);
TextComposition* GetCompositionFor(
const WidgetCompositionEvent* aCompositionEvent);
// Looking for per nsPresContext
index_type IndexOf(nsPresContext* aPresContext);
index_type IndexOf(nsPresContext* aPresContext, nsINode* aNode);
TextComposition* GetCompositionFor(nsIWidget* aWidget);
TextComposition* GetCompositionFor(nsPresContext* aPresContext);
TextComposition* GetCompositionFor(nsPresContext* aPresContext,
nsINode* aNode);
TextComposition* GetCompositionInContent(nsPresContext* aPresContext,
+19 -15
View File
@@ -158,9 +158,7 @@ HTMLAnchorElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIDocument* doc = GetComposedDoc();
if (doc) {
doc->RegisterPendingLinkUpdate(this);
if (nsHTMLDNSPrefetch::IsAllowed(OwnerDoc())) {
nsHTMLDNSPrefetch::PrefetchLow(this);
}
TryDNSPrefetch();
}
return rv;
@@ -172,18 +170,9 @@ HTMLAnchorElement::UnbindFromTree(bool aDeep, bool aNullParent)
// Cancel any DNS prefetches
// Note: Must come before ResetLinkState. If called after, it will recreate
// mCachedURI based on data that is invalid - due to a call to GetHostname.
CancelDNSPrefetch(HTML_ANCHOR_DNS_PREFETCH_DEFERRED,
HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
// If prefetch was deferred, clear flag and move on
if (HasFlag(HTML_ANCHOR_DNS_PREFETCH_DEFERRED))
UnsetFlags(HTML_ANCHOR_DNS_PREFETCH_DEFERRED);
// Else if prefetch was requested, clear flag and send cancellation
else if (HasFlag(HTML_ANCHOR_DNS_PREFETCH_REQUESTED)) {
UnsetFlags(HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
// Possible that hostname could have changed since binding, but since this
// covers common cases, most DNS prefetch requests will be canceled
nsHTMLDNSPrefetch::CancelPrefetchLow(this, NS_ERROR_ABORT);
}
// If this link is ever reinserted into a document, it might
// be under a different xml:base, so forget the cached state now.
Link::ResetLinkState(false, Link::ElementHasHref());
@@ -406,6 +395,10 @@ HTMLAnchorElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
reset = true;
}
}
if (reset) {
CancelDNSPrefetch(HTML_ANCHOR_DNS_PREFETCH_DEFERRED,
HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
}
}
nsresult rv = nsGenericHTMLElement::SetAttr(aNameSpaceID, aName, aPrefix,
@@ -418,6 +411,9 @@ HTMLAnchorElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
// to get updated information about the visitedness from Link.
if (reset) {
Link::ResetLinkState(!!aNotify, true);
if (IsInComposedDoc()) {
TryDNSPrefetch();
}
}
return rv;
@@ -427,6 +423,14 @@ nsresult
HTMLAnchorElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
bool aNotify)
{
bool href =
(aAttribute == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID);
if (href) {
CancelDNSPrefetch(HTML_ANCHOR_DNS_PREFETCH_DEFERRED,
HTML_ANCHOR_DNS_PREFETCH_REQUESTED);
}
nsresult rv = nsGenericHTMLElement::UnsetAttr(aNameSpaceID, aAttribute,
aNotify);
@@ -435,7 +439,7 @@ HTMLAnchorElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
// we will need the updated attribute value because notifying the document
// that content states have changed will call IntrinsicState, which will try
// to get updated information about the visitedness from Link.
if (aAttribute == nsGkAtoms::href && kNameSpaceID_None == aNameSpaceID) {
if (href) {
Link::ResetLinkState(!!aNotify, false);
}
+4 -4
View File
@@ -121,13 +121,13 @@ public:
{
SetHTMLAttr(nsGkAtoms::rel, aValue, rv);
}
void SetReferrer(const nsAString& aValue, mozilla::ErrorResult& rv)
void SetReferrerPolicy(const nsAString& aValue, mozilla::ErrorResult& rv)
{
SetHTMLAttr(nsGkAtoms::referrer, aValue, rv);
SetHTMLAttr(nsGkAtoms::referrerpolicy, aValue, rv);
}
void GetReferrer(nsAString& aReferrer)
void GetReferrerPolicy(nsAString& aReferrer)
{
GetHTMLAttr(nsGkAtoms::referrer, aReferrer);
GetHTMLAttr(nsGkAtoms::referrerpolicy, aReferrer);
}
nsDOMTokenList* RelList();
void GetHreflang(DOMString& aValue)
+4 -4
View File
@@ -125,13 +125,13 @@ public:
}
nsDOMTokenList* RelList();
void SetReferrer(const nsAString& aValue, mozilla::ErrorResult& rv)
void SetReferrerPolicy(const nsAString& aValue, mozilla::ErrorResult& rv)
{
SetHTMLAttr(nsGkAtoms::referrer, aValue, rv);
SetHTMLAttr(nsGkAtoms::referrerpolicy, aValue, rv);
}
void GetReferrer(nsAString& aReferrer)
void GetReferrerPolicy(nsAString& aReferrer)
{
GetHTMLAttr(nsGkAtoms::referrer, aReferrer);
GetHTMLAttr(nsGkAtoms::referrerpolicy, aReferrer);
}
// The Link::GetOrigin is OK for us
+4 -4
View File
@@ -159,13 +159,13 @@ public:
{
SetHTMLAttr(nsGkAtoms::marginheight, aMarginHeight, aError);
}
void SetReferrer(const nsAString& aReferrer, ErrorResult& aError)
void SetReferrerPolicy(const nsAString& aReferrer, ErrorResult& aError)
{
SetHTMLAttr(nsGkAtoms::referrer, aReferrer, aError);
SetHTMLAttr(nsGkAtoms::referrerpolicy, aReferrer, aError);
}
void GetReferrer(nsAString& aReferrer)
void GetReferrerPolicy(nsAString& aReferrer)
{
GetHTMLAttr(nsGkAtoms::referrer, aReferrer);
GetHTMLAttr(nsGkAtoms::referrerpolicy, aReferrer);
}
nsIDocument* GetSVGDocument()
+5 -5
View File
@@ -189,19 +189,19 @@ public:
{
SetHTMLAttr(nsGkAtoms::border, aBorder, aError);
}
void SetReferrer(const nsAString& aReferrer, ErrorResult& aError)
void SetReferrerPolicy(const nsAString& aReferrer, ErrorResult& aError)
{
SetHTMLAttr(nsGkAtoms::referrer, aReferrer, aError);
SetHTMLAttr(nsGkAtoms::referrerpolicy, aReferrer, aError);
}
void GetReferrer(nsAString& aReferrer)
void GetReferrerPolicy(nsAString& aReferrer)
{
GetHTMLAttr(nsGkAtoms::referrer, aReferrer);
GetHTMLAttr(nsGkAtoms::referrerpolicy, aReferrer);
}
net::ReferrerPolicy
GetImageReferrerPolicy() override
{
return GetReferrerPolicy();
return GetReferrerPolicyAsEnum();
}
int32_t X();
+76
View File
@@ -29,6 +29,22 @@
#include "nsStyleConsts.h"
#include "nsUnicharUtils.h"
#define LINK_ELEMENT_FLAG_BIT(n_) \
NODE_FLAG_BIT(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + (n_))
// Link element specific bits
enum {
// Indicates that a DNS Prefetch has been requested from this Link element.
HTML_LINK_DNS_PREFETCH_REQUESTED = LINK_ELEMENT_FLAG_BIT(0),
// Indicates that a DNS Prefetch was added to the deferral queue
HTML_LINK_DNS_PREFETCH_DEFERRED = LINK_ELEMENT_FLAG_BIT(1)
};
#undef LINK_ELEMENT_FLAG_BIT
ASSERT_NODE_FLAGS_SPACE(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + 2);
NS_IMPL_NS_NEW_HTML_ELEMENT(Link)
namespace mozilla {
@@ -127,6 +143,26 @@ HTMLLinkElement::SetItemValueText(const nsAString& aValue)
SetHref(aValue);
}
void
HTMLLinkElement::OnDNSPrefetchRequested()
{
UnsetFlags(HTML_LINK_DNS_PREFETCH_DEFERRED);
SetFlags(HTML_LINK_DNS_PREFETCH_REQUESTED);
}
void
HTMLLinkElement::OnDNSPrefetchDeferred()
{
UnsetFlags(HTML_LINK_DNS_PREFETCH_REQUESTED);
SetFlags(HTML_LINK_DNS_PREFETCH_DEFERRED);
}
bool
HTMLLinkElement::HasDeferredDNSPrefetchRequest()
{
return HasFlag(HTML_LINK_DNS_PREFETCH_DEFERRED);
}
nsresult
HTMLLinkElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
@@ -146,6 +182,9 @@ HTMLLinkElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
if (IsInComposedDoc()) {
UpdatePreconnect();
if (HasDNSPrefetchRel()) {
TryDNSPrefetch();
}
}
void (HTMLLinkElement::*update)() = &HTMLLinkElement::UpdateStyleSheetInternal;
@@ -174,6 +213,12 @@ HTMLLinkElement::LinkRemoved()
void
HTMLLinkElement::UnbindFromTree(bool aDeep, bool aNullParent)
{
// Cancel any DNS prefetches
// Note: Must come before ResetLinkState. If called after, it will recreate
// mCachedURI based on data that is invalid - due to a call to GetHostname.
CancelDNSPrefetch(HTML_LINK_DNS_PREFETCH_DEFERRED,
HTML_LINK_DNS_PREFETCH_REQUESTED);
// If this link is ever reinserted into a document, it might
// be under a different xml:base, so forget the cached state now.
Link::ResetLinkState(false, Link::ElementHasHref());
@@ -323,6 +368,32 @@ HTMLLinkElement::UpdatePreconnect()
}
}
bool
HTMLLinkElement::HasDNSPrefetchRel()
{
nsAutoString rel;
if (GetAttr(kNameSpaceID_None, nsGkAtoms::rel, rel)) {
return !!(ParseLinkTypes(rel, NodePrincipal()) &
nsStyleLinkElement::eDNS_PREFETCH);
}
return false;
}
nsresult
HTMLLinkElement::BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
nsAttrValueOrString* aValue, bool aNotify)
{
if (aNameSpaceID == kNameSpaceID_None &&
(aName == nsGkAtoms::href || aName == nsGkAtoms::rel)) {
CancelDNSPrefetch(HTML_LINK_DNS_PREFETCH_DEFERRED,
HTML_LINK_DNS_PREFETCH_REQUESTED);
}
return nsGenericHTMLElement::BeforeSetAttr(aNameSpaceID, aName,
aValue, aNotify);
}
nsresult
HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
const nsAttrValue* aValue, bool aNotify)
@@ -369,6 +440,11 @@ HTMLLinkElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
}
}
if ((aName == nsGkAtoms::rel || aName == nsGkAtoms::href) &&
HasDNSPrefetchRel() && IsInComposedDoc()) {
TryDNSPrefetch();
}
UpdateStyleSheetInternal(nullptr, nullptr,
dropSheet ||
(aName == nsGkAtoms::title ||
+10
View File
@@ -61,6 +61,9 @@ public:
bool aCompileEventHandlers) override;
virtual void UnbindFromTree(bool aDeep = true,
bool aNullParent = true) override;
virtual nsresult BeforeSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
nsAttrValueOrString* aValue,
bool aNotify) override;
virtual nsresult AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
const nsAttrValue* aValue,
bool aNotify) override;
@@ -77,6 +80,10 @@ public:
void CreateAndDispatchEvent(nsIDocument* aDoc, const nsAString& aEventName);
virtual void OnDNSPrefetchDeferred() override;
virtual void OnDNSPrefetchRequested() override;
virtual bool HasDeferredDNSPrefetchRequest() override;
// WebIDL
bool Disabled();
void SetDisabled(bool aDisabled);
@@ -166,6 +173,9 @@ protected:
// nsGenericHTMLElement
virtual void GetItemValueText(DOMString& text) override;
virtual void SetItemValueText(const nsAString& text) override;
bool HasDNSPrefetchRel();
RefPtr<nsDOMTokenList > mRelList;
private:
RefPtr<ImportLoader> mImportLoader;
+22 -2
View File
@@ -563,12 +563,18 @@ nsBrowserElement::GetAllowedAudioChannels(
return;
}
nsCOMPtr<mozIApplication> parentApp;
aRv = GetParentApplication(getter_AddRefs(parentApp));
if (NS_WARN_IF(aRv.Failed())) {
return;
}
MOZ_LOG(AudioChannelService::GetAudioChannelLog(), LogLevel::Debug,
("nsBrowserElement, GetAllowedAudioChannels, this = %p\n", this));
GenerateAllowedAudioChannels(window, frameLoader, mBrowserElementAPI,
manifestURL, mBrowserElementAudioChannels,
aRv);
manifestURL, parentApp,
mBrowserElementAudioChannels, aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
@@ -583,6 +589,7 @@ nsBrowserElement::GenerateAllowedAudioChannels(
nsIFrameLoader* aFrameLoader,
nsIBrowserElementAPI* aAPI,
const nsAString& aManifestURL,
mozIApplication* aParentApp,
nsTArray<RefPtr<BrowserElementAudioChannel>>& aAudioChannels,
ErrorResult& aRv)
{
@@ -625,6 +632,19 @@ nsBrowserElement::GenerateAllowedAudioChannels(
permissionName.AssignASCII("audio-channel-");
permissionName.AppendASCII(audioChannelTable[i].tag);
// In case of nested iframes we want to check if the parent has the
// permission to use this AudioChannel.
if (aParentApp) {
aRv = aParentApp->HasPermission(permissionName.get(), &allowed);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
if (!allowed) {
continue;
}
}
aRv = app->HasPermission(permissionName.get(), &allowed);
if (NS_WARN_IF(aRv.Failed())) {
return;
+3
View File
@@ -125,11 +125,14 @@ public:
nsIFrameLoader* aFrameLoader,
nsIBrowserElementAPI* aAPI,
const nsAString& aManifestURL,
mozIApplication* aParentApp,
nsTArray<RefPtr<dom::BrowserElementAudioChannel>>& aAudioChannels,
ErrorResult& aRv);
protected:
NS_IMETHOD_(already_AddRefed<nsFrameLoader>) GetFrameLoader() = 0;
NS_IMETHOD GetParentApplication(mozIApplication** aApplication) = 0;
void InitBrowserElementAPI();
nsCOMPtr<nsIBrowserElementAPI> mBrowserElementAPI;
nsTArray<RefPtr<dom::BrowserElementAudioChannel>> mBrowserElementAudioChannels;
+1 -1
View File
@@ -1003,7 +1003,7 @@ nsGenericHTMLElement::ParseAttribute(int32_t aNamespaceID,
return aResult.ParseIntValue(aValue);
}
if (aAttribute == nsGkAtoms::referrer) {
if (aAttribute == nsGkAtoms::referrerpolicy) {
return ParseReferrerAttribute(aValue, aResult);
}
+29
View File
@@ -188,6 +188,35 @@ nsGenericHTMLFrameElement::GetFrameLoader()
return loader.forget();
}
NS_IMETHODIMP
nsGenericHTMLFrameElement::GetParentApplication(mozIApplication** aApplication)
{
if (!aApplication) {
return NS_ERROR_FAILURE;
}
*aApplication = nullptr;
uint32_t appId;
nsIPrincipal *principal = NodePrincipal();
nsresult rv = principal->GetAppId(&appId);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
if (NS_WARN_IF(!appsService)) {
return NS_ERROR_FAILURE;
}
rv = appsService->GetAppByLocalId(appId, aApplication);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return NS_OK;
}
NS_IMETHODIMP
nsGenericHTMLFrameElement::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner)
{
+1 -1
View File
@@ -5,7 +5,7 @@
#include "domstubs.idl"
[scriptable, uuid(7615408c-1fb3-4128-8dd5-a3e2f3fa8842)]
[builtinclass, scriptable, uuid(8e49f7b0-1f98-4939-bf91-e9c39cd56434)]
interface nsITabParent : nsISupports
{
void injectTouchEvent(in AString aType,
+18 -13
View File
@@ -235,20 +235,19 @@ parent:
IMENotification notification);
/**
* Instructs chrome to end any pending composition
* Requests chrome to commit or cancel composition of IME.
*
* cancel true if composition should be cancelled
* noCompositionEvent true if no composition event is fired by commit or
* cancel
* composition Text to commit before ending the composition
* cancel Set true if composition should be cancelled.
*
* if cancel is true,
* widget should return empty string for composition
* if cancel is false,
* widget should return the current composition text
* isCommitted Returns true if the request causes composition
* being committed synchronously.
* committedString Returns committed string. The may be non-empty
* string even if cancel is true because IME may
* try to restore selected string which was
* replaced with the composition.
*/
prio(urgent) sync EndIMEComposition(bool cancel)
returns (bool noCompositionEvent, nsString composition);
prio(urgent) sync RequestIMEToCommitComposition(bool cancel)
returns (bool isCommitted, nsString committedString);
/**
* OnEventNeedingAckHandled() is called after a child process dispatches a
@@ -296,8 +295,7 @@ parent:
nsCString[] disabledCommands);
prio(urgent) sync GetInputContext() returns (int32_t IMEEnabled,
int32_t IMEOpen,
intptr_t NativeIMEContext);
int32_t IMEOpen);
prio(urgent) async SetInputContext(int32_t IMEEnabled,
int32_t IMEOpen,
@@ -748,6 +746,13 @@ child:
*/
HandleAccessKey(uint32_t[] charCodes, bool isTrusted, int32_t modifierMask);
/**
* Propagate a refresh to the child process
*/
AudioChannelChangeNotification(uint32_t aAudioChannel,
float aVolume,
bool aMuted);
/*
* FIXME: write protocol!
+21
View File
@@ -2212,6 +2212,27 @@ TabChild::RecvHandleAccessKey(nsTArray<uint32_t>&& aCharCodes,
return true;
}
bool
TabChild::RecvAudioChannelChangeNotification(const uint32_t& aAudioChannel,
const float& aVolume,
const bool& aMuted)
{
nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(WebNavigation());
if (window) {
RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
MOZ_ASSERT(service);
service->SetAudioChannelVolume(window,
static_cast<AudioChannel>(aAudioChannel),
aVolume);
service->SetAudioChannelMuted(window,
static_cast<AudioChannel>(aAudioChannel),
aMuted);
}
return true;
}
bool
TabChild::RecvDestroy()
{
+4
View File
@@ -501,6 +501,10 @@ public:
const bool& aIsTrusted,
const int32_t& aModifierMask) override;
virtual bool RecvAudioChannelChangeNotification(const uint32_t& aAudioChannel,
const float& aVolume,
const bool& aMuted) override;
/**
* Native widget remoting protocol for use with windowed plugins with e10s.
*/
+48 -12
View File
@@ -183,7 +183,7 @@ private:
// Our TabParent may have been destroyed already. If so, don't send any
// fds over, just go back to the IO thread and close them.
if (!tabParent->IsDestroyed()) {
mozilla::Unused << tabParent->SendCacheFileDescriptor(mPath, fd);
Unused << tabParent->SendCacheFileDescriptor(mPath, fd);
}
if (!mFD) {
@@ -231,7 +231,7 @@ private:
// Intentionally leak the runnable (but not the fd) rather
// than crash when trying to release a main thread object
// off the main thread.
mozilla::Unused << mTabParent.forget();
Unused << mTabParent.forget();
CloseFile();
}
}
@@ -384,6 +384,11 @@ TabParent::AddWindowListeners()
mPresShellWithRefreshListener = shell;
shell->AddPostRefreshObserver(this);
}
RefPtr<AudioChannelService> acs = AudioChannelService::GetOrCreate();
if (acs) {
acs->RegisterTabParent(this);
}
}
}
@@ -402,6 +407,11 @@ TabParent::RemoveWindowListeners()
mPresShellWithRefreshListener->RemovePostRefreshObserver(this);
mPresShellWithRefreshListener = nullptr;
}
RefPtr<AudioChannelService> acs = AudioChannelService::GetOrCreate();
if (acs) {
acs->UnregisterTabParent(this);
}
}
void
@@ -2319,16 +2329,19 @@ TabParent::GetRenderFrame()
}
bool
TabParent::RecvEndIMEComposition(const bool& aCancel,
bool* aNoCompositionEvent,
nsString* aComposition)
TabParent::RecvRequestIMEToCommitComposition(const bool& aCancel,
bool* aIsCommitted,
nsString* aCommittedString)
{
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
*aIsCommitted = false;
return true;
}
*aNoCompositionEvent =
!mContentCache.RequestToCommitComposition(widget, aCancel, *aComposition);
*aIsCommitted =
mContentCache.RequestIMEToCommitComposition(widget, aCancel,
*aCommittedString);
return true;
}
@@ -2361,21 +2374,18 @@ TabParent::RecvSetPluginFocused(const bool& aFocused)
bool
TabParent::RecvGetInputContext(int32_t* aIMEEnabled,
int32_t* aIMEOpen,
intptr_t* aNativeIMEContext)
int32_t* aIMEOpen)
{
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
*aIMEEnabled = IMEState::DISABLED;
*aIMEOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
*aNativeIMEContext = 0;
return true;
}
InputContext context = widget->GetInputContext();
*aIMEEnabled = static_cast<int32_t>(context.mIMEState.mEnabled);
*aIMEOpen = static_cast<int32_t>(context.mIMEState.mOpen);
*aNativeIMEContext = reinterpret_cast<intptr_t>(context.mNativeIMEContext);
return true;
}
@@ -2634,7 +2644,6 @@ TabParent::RecvAudioChannelActivityNotification(const uint32_t& aAudioChannel,
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (os) {
RefPtr<AudioChannelService> service = AudioChannelService::GetOrCreate();
nsAutoCString topic;
topic.Assign("audiochannel-activity-");
topic.Append(AudioChannelService::GetAudioChannelTable()[aAudioChannel].tag);
@@ -3371,6 +3380,33 @@ TabParent::GetShowInfo()
mDPI, mDefaultScale.scale);
}
void
TabParent::AudioChannelChangeNotification(nsPIDOMWindow* aWindow,
AudioChannel aAudioChannel,
float aVolume,
bool aMuted)
{
if (!mFrameElement || !mFrameElement->OwnerDoc()) {
return;
}
nsCOMPtr<nsPIDOMWindow> window = mFrameElement->OwnerDoc()->GetWindow();
while (window) {
if (window == aWindow) {
Unused << SendAudioChannelChangeNotification(static_cast<uint32_t>(aAudioChannel),
aVolume, aMuted);
break;
}
nsCOMPtr<nsPIDOMWindow> win = window->GetScriptableParent();
if (window == win) {
break;
}
window = win;
}
}
NS_IMETHODIMP
FakeChannel::OnAuthAvailable(nsISupports *aContext, nsIAuthInformation *aAuthInfo)
{
+10 -5
View File
@@ -9,6 +9,7 @@
#include "js/TypeDecls.h"
#include "mozilla/ContentCache.h"
#include "mozilla/dom/AudioChannelBinding.h"
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/dom/PBrowserParent.h"
#include "mozilla/dom/PContent.h"
@@ -185,17 +186,16 @@ public:
virtual bool RecvNotifyIMEPositionChange(const ContentCache& aContentCache,
const widget::IMENotification& aEventMessage) override;
virtual bool RecvOnEventNeedingAckHandled(const EventMessage& aMessage) override;
virtual bool RecvEndIMEComposition(const bool& aCancel,
bool* aNoCompositionEvent,
nsString* aComposition) override;
virtual bool RecvRequestIMEToCommitComposition(const bool& aCancel,
bool* aIsCommitted,
nsString* aCommittedString) override;
virtual bool RecvStartPluginIME(const WidgetKeyboardEvent& aKeyboardEvent,
const int32_t& aPanelX,
const int32_t& aPanelY,
nsString* aCommitted) override;
virtual bool RecvSetPluginFocused(const bool& aFocused) override;
virtual bool RecvGetInputContext(int32_t* aIMEEnabled,
int32_t* aIMEOpen,
intptr_t* aNativeIMEContext) override;
int32_t* aIMEOpen) override;
virtual bool RecvSetInputContext(const int32_t& aIMEEnabled,
const int32_t& aIMEOpen,
const nsString& aType,
@@ -453,6 +453,11 @@ public:
void OnStartSignedPackageRequest(nsIChannel* aChannel,
const nsACString& aPackageId);
void AudioChannelChangeNotification(nsPIDOMWindow* aWindow,
AudioChannel aAudioChannel,
float aVolume,
bool aMuted);
protected:
bool ReceiveMessage(const nsString& aMessage,
bool aSync,
+2 -2
View File
@@ -213,8 +213,8 @@ AudioChannelManager::GetAllowedAudioChannels(
}
nsBrowserElement::GenerateAllowedAudioChannels(window, nullptr, nullptr,
manifestURL, aAudioChannels,
aRv);
manifestURL, nullptr,
aAudioChannels, aRv);
NS_WARN_IF(aRv.Failed());
}
+5 -1
View File
@@ -36,6 +36,8 @@ interface Element : Node {
[SameObject]
readonly attribute NamedNodeMap attributes;
[Pure]
sequence<DOMString> getAttributeNames();
[Pure]
DOMString? getAttribute(DOMString name);
[Pure]
DOMString? getAttributeNS(DOMString? namespace, DOMString localName);
@@ -61,6 +63,8 @@ interface Element : Node {
[Throws, Pure]
boolean matches(DOMString selector);
[Throws, Pure, BinaryName="matches"]
boolean webkitMatchesSelector(DOMString selector);
[Pure]
HTMLCollection getElementsByTagName(DOMString localName);
@@ -100,7 +104,7 @@ interface Element : Node {
*
* See <http://dev.w3.org/2006/webapi/selectors-api2/#matchesselector>
*/
[Throws, Pure]
[Throws, Pure, BinaryName="matches"]
boolean mozMatchesSelector(DOMString selector);
// Pointer events methods.
+1 -1
View File
@@ -22,7 +22,7 @@ interface HTMLAnchorElement : HTMLElement {
[SetterThrows]
attribute DOMString rel;
[SetterThrows, Pref="network.http.enablePerElementReferrer"]
attribute DOMString referrer;
attribute DOMString referrerPolicy;
readonly attribute DOMTokenList relList;
[SetterThrows]
attribute DOMString hreflang;
+1 -1
View File
@@ -29,7 +29,7 @@ interface HTMLAreaElement : HTMLElement {
[SetterThrows]
attribute DOMString rel;
[SetterThrows, Pref="network.http.enablePerElementReferrer"]
attribute DOMString referrer;
attribute DOMString referrerPolicy;
readonly attribute DOMTokenList relList;
};
+1 -1
View File
@@ -27,7 +27,7 @@ interface HTMLIFrameElement : HTMLElement {
[SetterThrows, Pure]
attribute DOMString height;
[SetterThrows, Pure, Pref="network.http.enablePerElementReferrer"]
attribute DOMString referrer;
attribute DOMString referrerPolicy;
readonly attribute Document? contentDocument;
readonly attribute WindowProxy? contentWindow;
};
+2 -2
View File
@@ -29,8 +29,8 @@ interface HTMLImageElement : HTMLElement {
attribute DOMString? crossOrigin;
[SetterThrows]
attribute DOMString useMap;
[SetterThrows]
attribute DOMString referrer;
[SetterThrows, Pref="network.http.enablePerElementReferrer"]
attribute DOMString referrerPolicy;
[SetterThrows]
attribute boolean isMap;
[SetterThrows]
-7
View File
@@ -617,13 +617,6 @@ nsXMLContentSink::CloseElement(nsIContent* aContent)
PrefetchHref(hrefVal, aContent, hasPrefetch);
}
}
if (linkTypes & nsStyleLinkElement::eDNS_PREFETCH) {
nsAutoString hrefVal;
aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
if (!hrefVal.IsEmpty()) {
PrefetchDNS(hrefVal);
}
}
}
}
}
+11
View File
@@ -1612,6 +1612,17 @@ nsXULElement::GetFrameLoader()
return loader.forget();
}
nsresult
nsXULElement::GetParentApplication(mozIApplication** aApplication)
{
if (!aApplication) {
return NS_ERROR_FAILURE;
}
*aApplication = nullptr;
return NS_OK;
}
nsresult
nsXULElement::SetIsPrerendered()
{
+1
View File
@@ -437,6 +437,7 @@ public:
virtual mozilla::EventStates IntrinsicState() const override;
nsresult GetFrameLoader(nsIFrameLoader** aFrameLoader);
nsresult GetParentApplication(mozIApplication** aApplication);
nsresult SetIsPrerendered();
nsresult SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner);
+2 -2
View File
@@ -1993,14 +1993,14 @@ nsEditor::StopPreservingSelection()
}
void
nsEditor::EnsureComposition(mozilla::WidgetGUIEvent* aEvent)
nsEditor::EnsureComposition(mozilla::WidgetCompositionEvent* aCompositionEvent)
{
if (mComposition) {
return;
}
// The compositionstart event must cause creating new TextComposition
// instance at being dispatched by IMEStateManager.
mComposition = IMEStateManager::GetTextCompositionFor(aEvent);
mComposition = IMEStateManager::GetTextCompositionFor(aCompositionEvent);
if (!mComposition) {
MOZ_CRASH("IMEStateManager doesn't return proper composition");
}
+1 -1
View File
@@ -413,7 +413,7 @@ protected:
* EnsureComposition() should be called by composition event handlers. This
* tries to get the composition for the event and set it to mComposition.
*/
void EnsureComposition(mozilla::WidgetGUIEvent* aEvent);
void EnsureComposition(mozilla::WidgetCompositionEvent* aCompositionEvent);
nsresult GetSelection(int16_t aSelectionType, nsISelection** aSelection);
+9 -5
View File
@@ -1286,12 +1286,11 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext,
}
}
Rect frameGfxRect = NSRectToRect(frameRect, twipsPerPixel);
frameGfxRect.Round();
// We don't show anything that intersects with the frame we're blurring on. So tell the
// blurrer not to do unnecessary work there.
gfxRect skipGfxRect = ThebesRect(frameGfxRect);
gfxRect skipGfxRect = ThebesRect(NSRectToRect(frameRect, twipsPerPixel));
skipGfxRect.Round();
bool useSkipGfxRect = true;
if (nativeTheme) {
// Optimize non-leaf native-themed frames by skipping computing pixels
@@ -1394,15 +1393,20 @@ nsCSSRendering::PaintBoxShadowOuter(nsPresContext* aPresContext,
renderContext->Save();
{
Rect innerClipRect = NSRectToRect(frameRect, twipsPerPixel);
if (!MaybeSnapToDevicePixels(innerClipRect, aDrawTarget, true)) {
innerClipRect.Round();
}
// Clip out the interior of the frame's border edge so that the shadow
// is only painted outside that area.
RefPtr<PathBuilder> builder =
aDrawTarget.CreatePathBuilder(FillRule::FILL_EVEN_ODD);
AppendRectToPath(builder, shadowGfxRectPlusBlur);
if (hasBorderRadius) {
AppendRoundedRectToPath(builder, frameGfxRect, borderRadii);
AppendRoundedRectToPath(builder, innerClipRect, borderRadii);
} else {
AppendRectToPath(builder, frameGfxRect);
AppendRectToPath(builder, innerClipRect);
}
RefPtr<Path> path = builder->Finish();
renderContext->Clip(path);
+26 -1
View File
@@ -386,6 +386,26 @@ nsAnimationManager::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
}
void
nsAnimationManager::CopyIsRunningOnCompositor(
KeyframeEffectReadOnly& aSourceEffect,
KeyframeEffectReadOnly& aDestEffect)
{
nsCSSPropertySet sourceProperties;
for (AnimationProperty& property : aSourceEffect.Properties()) {
if (property.mIsRunningOnCompositor) {
sourceProperties.AddProperty(property.mProperty);
}
}
for (AnimationProperty& property : aDestEffect.Properties()) {
if (sourceProperties.HasProperty(property.mProperty)) {
property.mIsRunningOnCompositor = true;
}
}
}
nsIStyleRule*
nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
mozilla::dom::Element* aElement)
@@ -493,6 +513,12 @@ nsAnimationManager::CheckAnimationRule(nsStyleContext* aStyleContext,
oldEffect->Timing() != newEffect->Timing() ||
oldEffect->Properties() != newEffect->Properties();
oldEffect->SetTiming(newEffect->Timing());
// To preserve the mIsRunningOnCompositor value on each property,
// we copy it from the old effect to the new effect since, in the
// following step, we will completely clobber the properties on the
// old effect with the values on the new effect.
CopyIsRunningOnCompositor(*oldEffect, *newEffect);
oldEffect->Properties() = newEffect->Properties();
}
@@ -789,7 +815,6 @@ nsAnimationManager::BuildAnimations(nsStyleContext* aStyleContext,
AnimationProperty &propData = *destEffect->Properties().AppendElement();
propData.mProperty = prop;
propData.mWinsInCascade = true;
KeyframeData *fromKeyframe = nullptr;
RefPtr<nsStyleContext> fromContext;
+4
View File
@@ -22,6 +22,7 @@ namespace css {
class Declaration;
} /* namespace css */
namespace dom {
class KeyframeEffectReadOnly;
class Promise;
} /* namespace dom */
@@ -373,6 +374,9 @@ private:
static void UpdateCascadeResults(nsStyleContext* aStyleContext,
mozilla::AnimationCollection*
aElementAnimations);
static void CopyIsRunningOnCompositor(
mozilla::dom::KeyframeEffectReadOnly& aSourceEffect,
mozilla::dom::KeyframeEffectReadOnly& aDestEffect);
};
#endif /* !defined(nsAnimationManager_h_) */
-1
View File
@@ -679,7 +679,6 @@ nsTransitionManager::ConsiderStartingTransition(
AnimationProperty& prop = *pt->Properties().AppendElement();
prop.mProperty = aProperty;
prop.mWinsInCascade = true;
AnimationPropertySegment& segment = *prop.mSegments.AppendElement();
segment.mFromValue = startValue;
+9 -4
View File
@@ -153,13 +153,18 @@ static void anp_drawBitmapRect(ANPCanvas* canvas, const ANPBitmap* bitmap,
const ANPPaint* paint) {
SkBitmap bm;
SkRect dstR;
SkIRect srcR, *srcPtr = NULL;
SkIRect srcR;
if (src) {
srcPtr = SkANP::SetRect(&srcR, *src);
canvas->skcanvas->drawBitmapRect(*SkANP::SetBitmap(&bm, *bitmap),
*SkANP::SetRect(&srcR, *src),
*SkANP::SetRect(&dstR, *dst),
paint);
} else {
canvas->skcanvas->drawBitmapRect(*SkANP::SetBitmap(&bm, *bitmap),
*SkANP::SetRect(&dstR, *dst),
paint);
}
canvas->skcanvas->drawBitmapRect(*SkANP::SetBitmap(&bm, *bitmap), srcPtr,
*SkANP::SetRect(&dstR, *dst), paint);
}
///////////////////////////////////////////////////////////////////////////////
@@ -27,6 +27,7 @@
#include "SkANP.h"
#include "SkFontHost.h"
#include "SkStream.h"
#include <stdlib.h>
static ANPTypeface* anp_createFromName(const char name[], ANPTypefaceStyle s) {
SkTypeface* tf = SkTypeface::CreateFromName(name,
+5 -5
View File
@@ -545,7 +545,7 @@ public final class AttributeName
// builder.append(" | ");
// }
// builder.append("NCNAME_HTML");
// }
// }
// if ((flags & NCNAME_FOREIGN) != 0) {
// if (builder.length() != 0) {
// builder.append(" | ");
@@ -683,7 +683,7 @@ public final class AttributeName
//
// /**
// * Regenerate self
// *
// *
// * @param args
// */
// public static void main(String[] args) {
@@ -990,7 +990,6 @@ public final class AttributeName
public static final AttributeName READONLY = new AttributeName(ALL_NO_NS, SAME_LOCAL("readonly"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
public static final AttributeName SELECTED = new AttributeName(ALL_NO_NS, SAME_LOCAL("selected"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG | CASE_FOLDED | BOOLEAN);
public static final AttributeName ROWLINES = new AttributeName(ALL_NO_NS, SAME_LOCAL("rowlines"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName REFERRER = new AttributeName(ALL_NO_NS, SAME_LOCAL("referrer"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName SEAMLESS = new AttributeName(ALL_NO_NS, SAME_LOCAL("seamless"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName ROWALIGN = new AttributeName(ALL_NO_NS, SAME_LOCAL("rowalign"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName STRETCHY = new AttributeName(ALL_NO_NS, SAME_LOCAL("stretchy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
@@ -1234,6 +1233,7 @@ public final class AttributeName
public static final AttributeName V_MATHEMATICAL = new AttributeName(ALL_NO_NS, SAME_LOCAL("v-mathematical"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName POINTER_EVENTS = new AttributeName(ALL_NO_NS, SAME_LOCAL("pointer-events"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName PRIMITIVEUNITS = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("primitiveunits", "primitiveUnits"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName REFERRERPOLICY = new AttributeName(ALL_NO_NS, SAME_LOCAL("referrerpolicy"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName SYSTEMLANGUAGE = new AttributeName(ALL_NO_NS, SVG_DIFFERENT("systemlanguage", "systemLanguage"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName STROKE_LINECAP = new AttributeName(ALL_NO_NS, SAME_LOCAL("stroke-linecap"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
public static final AttributeName SUBSCRIPTSHIFT = new AttributeName(ALL_NO_NS, SAME_LOCAL("subscriptshift"), ALL_NO_PREFIX, NCNAME_HTML | NCNAME_FOREIGN | NCNAME_LANG);
@@ -1574,7 +1574,6 @@ public final class AttributeName
READONLY,
SELECTED,
ROWLINES,
REFERRER,
SEAMLESS,
ROWALIGN,
STRETCHY,
@@ -1818,6 +1817,7 @@ public final class AttributeName
V_MATHEMATICAL,
POINTER_EVENTS,
PRIMITIVEUNITS,
REFERRERPOLICY,
SYSTEMLANGUAGE,
STROKE_LINECAP,
SUBSCRIPTSHIFT,
@@ -2159,7 +2159,6 @@ public final class AttributeName
291557706,
291665349,
291804100,
291862420,
292138018,
292166446,
292418738,
@@ -2403,6 +2402,7 @@ public final class AttributeName
490661867,
491574090,
491578272,
492891370,
493041952,
493441205,
493582844,
+1 -1
View File
@@ -349,7 +349,6 @@ HTML5_ATOM(property, "property")
HTML5_ATOM(readonly, "readonly")
HTML5_ATOM(selected, "selected")
HTML5_ATOM(rowlines, "rowlines")
HTML5_ATOM(referrer, "referrer")
HTML5_ATOM(seamless, "seamless")
HTML5_ATOM(rowalign, "rowalign")
HTML5_ATOM(stretchy, "stretchy")
@@ -632,6 +631,7 @@ HTML5_ATOM(v_mathematical, "v-mathematical")
HTML5_ATOM(pointer_events, "pointer-events")
HTML5_ATOM(primitiveunits, "primitiveunits")
HTML5_ATOM(primitiveUnits, "primitiveUnits")
HTML5_ATOM(referrerpolicy, "referrerpolicy")
HTML5_ATOM(systemlanguage, "systemlanguage")
HTML5_ATOM(systemLanguage, "systemLanguage")
HTML5_ATOM(stroke_linecap, "stroke-linecap")
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -365,7 +365,6 @@ class nsHtml5AttributeName
static nsHtml5AttributeName* ATTR_READONLY;
static nsHtml5AttributeName* ATTR_SELECTED;
static nsHtml5AttributeName* ATTR_ROWLINES;
static nsHtml5AttributeName* ATTR_REFERRER;
static nsHtml5AttributeName* ATTR_SEAMLESS;
static nsHtml5AttributeName* ATTR_ROWALIGN;
static nsHtml5AttributeName* ATTR_STRETCHY;
@@ -609,6 +608,7 @@ class nsHtml5AttributeName
static nsHtml5AttributeName* ATTR_V_MATHEMATICAL;
static nsHtml5AttributeName* ATTR_POINTER_EVENTS;
static nsHtml5AttributeName* ATTR_PRIMITIVEUNITS;
static nsHtml5AttributeName* ATTR_REFERRERPOLICY;
static nsHtml5AttributeName* ATTR_SYSTEMLANGUAGE;
static nsHtml5AttributeName* ATTR_STROKE_LINECAP;
static nsHtml5AttributeName* ATTR_SUBSCRIPTSHIFT;
-7
View File
@@ -96,13 +96,6 @@ nsHtml5DocumentBuilder::UpdateStyleSheet(nsIContent* aElement)
PrefetchHref(hrefVal, aElement, hasPrefetch);
}
}
if (linkTypes & nsStyleLinkElement::eDNS_PREFETCH) {
nsAutoString hrefVal;
aElement->GetAttr(kNameSpaceID_None, nsGkAtoms::href, hrefVal);
if (!hrefVal.IsEmpty()) {
PrefetchDNS(hrefVal);
}
}
}
}
+3 -3
View File
@@ -57,7 +57,7 @@ nsHtml5Highlighter::nsHtml5Highlighter(nsAHtml5TreeOpSink* aOpSink)
, mCurrentRun(nullptr)
, mAmpersand(nullptr)
, mSlash(nullptr)
, mHandles(new nsIContent*[NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH])
, mHandles(MakeUnique<nsIContent*[]>(NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH))
, mHandlesUsed(0)
, mSeenBase(false)
{
@@ -641,8 +641,8 @@ nsIContent**
nsHtml5Highlighter::AllocateContentHandle()
{
if (mHandlesUsed == NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH) {
mOldHandles.AppendElement(mHandles.forget());
mHandles = new nsIContent*[NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH];
mOldHandles.AppendElement(Move(mHandles));
mHandles = MakeUnique<nsIContent*[]>(NS_HTML5_HIGHLIGHTER_HANDLE_ARRAY_LENGTH);
mHandlesUsed = 0;
}
#ifdef DEBUG
+2 -2
View File
@@ -342,7 +342,7 @@ class nsHtml5Highlighter
/**
* Memory for element handles.
*/
nsAutoArrayPtr<nsIContent*> mHandles;
mozilla::UniquePtr<nsIContent*[]> mHandles;
/**
* Number of handles used in mHandles
@@ -352,7 +352,7 @@ class nsHtml5Highlighter
/**
* A holder for old contents of mHandles
*/
nsTArray<nsAutoArrayPtr<nsIContent*> > mOldHandles;
nsTArray<mozilla::UniquePtr<nsIContent*[]>> mOldHandles;
/**
* The element stack.
+11 -10
View File
@@ -17,6 +17,7 @@
#include "nsHtml5RefPtr.h"
#include "nsIScriptError.h"
#include "mozilla/Preferences.h"
#include "mozilla/UniquePtrExtensions.h"
#include "nsHtml5Highlighter.h"
#include "expat_config.h"
#include "expat.h"
@@ -300,7 +301,7 @@ nsHtml5StreamParser::SetupDecodingAndWriteSniffingBufferAndCurrentSegment(const
mUnicodeDecoder = EncodingUtils::DecoderForEncoding(mCharset);
if (mSniffingBuffer) {
uint32_t writeCount;
rv = WriteStreamBytes(mSniffingBuffer, mSniffingLength, &writeCount);
rv = WriteStreamBytes(mSniffingBuffer.get(), mSniffingLength, &writeCount);
NS_ENSURE_SUCCESS(rv, rv);
mSniffingBuffer = nullptr;
}
@@ -783,13 +784,13 @@ nsHtml5StreamParser::SniffStreamBytes(const uint8_t* aFromSegment,
}
if (!mSniffingBuffer) {
mSniffingBuffer = new (mozilla::fallible)
uint8_t[NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE];
mSniffingBuffer =
MakeUniqueFallible<uint8_t[]>(NS_HTML5_STREAM_PARSER_SNIFFING_BUFFER_SIZE);
if (!mSniffingBuffer) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
memcpy(mSniffingBuffer + mSniffingLength, aFromSegment, aCount);
memcpy(&mSniffingBuffer[mSniffingLength], aFromSegment, aCount);
mSniffingLength += aCount;
*aWriteCount = aCount;
return NS_OK;
@@ -1126,20 +1127,20 @@ class nsHtml5DataAvailable : public nsRunnable
{
private:
nsHtml5RefPtr<nsHtml5StreamParser> mStreamParser;
nsAutoArrayPtr<uint8_t> mData;
UniquePtr<uint8_t[]> mData;
uint32_t mLength;
public:
nsHtml5DataAvailable(nsHtml5StreamParser* aStreamParser,
uint8_t* aData,
UniquePtr<uint8_t[]> aData,
uint32_t aLength)
: mStreamParser(aStreamParser)
, mData(aData)
, mData(Move(aData))
, mLength(aLength)
{}
NS_IMETHODIMP Run()
{
mozilla::MutexAutoLock autoLock(mStreamParser->mTokenizerMutex);
mStreamParser->DoDataAvailable(mData, mLength);
mStreamParser->DoDataAvailable(mData.get(), mLength);
return NS_OK;
}
};
@@ -1160,7 +1161,7 @@ nsHtml5StreamParser::OnDataAvailable(nsIRequest* aRequest,
uint32_t totalRead;
// Main thread to parser thread dispatch requires copying to buffer first.
if (NS_IsMainThread()) {
nsAutoArrayPtr<uint8_t> data(new (mozilla::fallible) uint8_t[aLength]);
auto data = MakeUniqueFallible<uint8_t[]>(aLength);
if (!data) {
return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
}
@@ -1170,7 +1171,7 @@ nsHtml5StreamParser::OnDataAvailable(nsIRequest* aRequest,
NS_ASSERTION(totalRead <= aLength, "Read more bytes than were available?");
nsCOMPtr<nsIRunnable> dataAvailable = new nsHtml5DataAvailable(this,
data.forget(),
Move(data),
totalRead);
if (NS_FAILED(mThread->Dispatch(dataAvailable, nsIThread::DISPATCH_NORMAL))) {
NS_WARNING("Dispatching DataAvailable event failed.");
+2 -1
View File
@@ -15,6 +15,7 @@
#include "nsHtml5OwningUTF16Buffer.h"
#include "nsIInputStream.h"
#include "mozilla/Mutex.h"
#include "mozilla/UniquePtr.h"
#include "nsHtml5AtomTable.h"
#include "nsHtml5Speculation.h"
#include "nsITimer.h"
@@ -398,7 +399,7 @@ class nsHtml5StreamParser : public nsICharsetDetectionObserver {
/**
* The buffer for sniffing the character encoding
*/
nsAutoArrayPtr<uint8_t> mSniffingBuffer;
mozilla::UniquePtr<uint8_t[]> mSniffingBuffer;
/**
* The number of meaningful bytes in mSniffingBuffer
@@ -9,6 +9,7 @@
#include "nsNodeUtils.h"
#include "nsIFrame.h"
#include "mozilla/Likely.h"
#include "mozilla/UniquePtr.h"
nsHtml5TreeBuilder::nsHtml5TreeBuilder(nsHtml5OplessBuilder* aBuilder)
: scriptingEnabled(false)
@@ -128,7 +129,7 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace, nsIAtom* aName,
nsString* crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
nsString* referrerPolicy =
aAttributes->getValue(nsHtml5AttributeName::ATTR_REFERRER);
aAttributes->getValue(nsHtml5AttributeName::ATTR_REFERRERPOLICY);
nsString* sizes =
aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES);
mSpeculativeLoadQueue.AppendElement()->
@@ -997,8 +998,8 @@ nsHtml5TreeBuilder::AllocateContentHandle()
return nullptr;
}
if (mHandlesUsed == NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH) {
mOldHandles.AppendElement(mHandles.forget());
mHandles = new nsIContent*[NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH];
mOldHandles.AppendElement(Move(mHandles));
mHandles = MakeUnique<nsIContent*[]>(NS_HTML5_TREE_BUILDER_HANDLE_ARRAY_LENGTH);
mHandlesUsed = 0;
}
#ifdef DEBUG
+2 -2
View File
@@ -14,9 +14,9 @@
nsTArray<nsHtml5TreeOperation> mOpQueue;
nsTArray<nsHtml5SpeculativeLoad> mSpeculativeLoadQueue;
nsAHtml5TreeOpSink* mOpSink;
nsAutoArrayPtr<nsIContent*> mHandles;
mozilla::UniquePtr<nsIContent*[]> mHandles;
int32_t mHandlesUsed;
nsTArray<nsAutoArrayPtr<nsIContent*> > mOldHandles;
nsTArray<mozilla::UniquePtr<nsIContent*[]>> mOldHandles;
nsHtml5TreeOpStage* mSpeculativeLoadStage;
nsresult mBroken;
bool mCurrentHtmlScriptIsAsyncOrDefer;
+9
View File
@@ -1051,6 +1051,15 @@ nsHtml5TreeOpExecutor::AddSpeculationCSP(const nsAString& aCSP)
true); // delivered through the meta tag
NS_ENSURE_SUCCESS_VOID(rv);
// Record "speculated" referrer policy for preloads
bool hasReferrerPolicy = false;
uint32_t referrerPolicy = mozilla::net::RP_Default;
rv = preloadCsp->GetReferrerPolicy(&referrerPolicy, &hasReferrerPolicy);
NS_ENSURE_SUCCESS_VOID(rv);
if (hasReferrerPolicy) {
SetSpeculationReferrerPolicy(static_cast<ReferrerPolicy>(referrerPolicy));
}
mDocument->ApplySettingsFromCSP(true);
}
+11 -3
View File
@@ -29,6 +29,7 @@
#include "nsXPCOMCIDInternal.h"
#include "nsUnicharInputStream.h"
#include "nsContentUtils.h"
#include "nsNullPrincipal.h"
#include "mozilla/IntegerTypeTraits.h"
#include "mozilla/Logging.h"
@@ -804,14 +805,21 @@ nsExpatDriver::OpenInputStreamFromExternalDTD(const char16_t* aFPIStr,
NS_ASSERTION(mSink == nsCOMPtr<nsIExpatSink>(do_QueryInterface(mOriginalSink)),
"In nsExpatDriver::OpenInputStreamFromExternalDTD: "
"mOriginalSink not the same object as mSink?");
nsCOMPtr<nsIDocument> doc;
nsCOMPtr<nsIPrincipal> loadingPrincipal;
if (mOriginalSink) {
nsCOMPtr<nsIDocument> doc;
doc = do_QueryInterface(mOriginalSink->GetTarget());
if (doc) {
loadingPrincipal = doc->NodePrincipal();
}
}
if (!loadingPrincipal) {
loadingPrincipal = nsNullPrincipal::Create();
NS_ENSURE_TRUE(loadingPrincipal, NS_ERROR_FAILURE);
}
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
rv = NS_NewChannel(getter_AddRefs(channel),
uri,
doc,
loadingPrincipal,
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS |
nsILoadInfo::SEC_ALLOW_CHROME,
nsIContentPolicy::TYPE_DTD);
+2 -280
View File
@@ -14,287 +14,9 @@
using namespace mozilla;
// C++ sucks! There's no way to do this with a macro, at least not
// that I know, if you know how to do this with a macro then please do
// so...
static const char16_t sHTMLTagUnicodeName_a[] =
{'a', '\0'};
static const char16_t sHTMLTagUnicodeName_abbr[] =
{'a', 'b', 'b', 'r', '\0'};
static const char16_t sHTMLTagUnicodeName_acronym[] =
{'a', 'c', 'r', 'o', 'n', 'y', 'm', '\0'};
static const char16_t sHTMLTagUnicodeName_address[] =
{'a', 'd', 'd', 'r', 'e', 's', 's', '\0'};
static const char16_t sHTMLTagUnicodeName_applet[] =
{'a', 'p', 'p', 'l', 'e', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_area[] =
{'a', 'r', 'e', 'a', '\0'};
static const char16_t sHTMLTagUnicodeName_article[] =
{'a', 'r', 't', 'i', 'c', 'l', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_aside[] =
{'a', 's', 'i', 'd', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_audio[] =
{'a', 'u', 'd', 'i', 'o', '\0'};
static const char16_t sHTMLTagUnicodeName_b[] =
{'b', '\0'};
static const char16_t sHTMLTagUnicodeName_base[] =
{'b', 'a', 's', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_basefont[] =
{'b', 'a', 's', 'e', 'f', 'o', 'n', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_bdo[] =
{'b', 'd', 'o', '\0'};
static const char16_t sHTMLTagUnicodeName_bgsound[] =
{'b', 'g', 's', 'o', 'u', 'n', 'd', '\0'};
static const char16_t sHTMLTagUnicodeName_big[] =
{'b', 'i', 'g', '\0'};
static const char16_t sHTMLTagUnicodeName_blockquote[] =
{'b', 'l', 'o', 'c', 'k', 'q', 'u', 'o', 't', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_body[] =
{'b', 'o', 'd', 'y', '\0'};
static const char16_t sHTMLTagUnicodeName_br[] =
{'b', 'r', '\0'};
static const char16_t sHTMLTagUnicodeName_button[] =
{'b', 'u', 't', 't', 'o', 'n', '\0'};
static const char16_t sHTMLTagUnicodeName_canvas[] =
{'c', 'a', 'n', 'v', 'a', 's', '\0'};
static const char16_t sHTMLTagUnicodeName_caption[] =
{'c', 'a', 'p', 't', 'i', 'o', 'n', '\0'};
static const char16_t sHTMLTagUnicodeName_center[] =
{'c', 'e', 'n', 't', 'e', 'r', '\0'};
static const char16_t sHTMLTagUnicodeName_cite[] =
{'c', 'i', 't', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_code[] =
{'c', 'o', 'd', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_col[] =
{'c', 'o', 'l', '\0'};
static const char16_t sHTMLTagUnicodeName_colgroup[] =
{'c', 'o', 'l', 'g', 'r', 'o', 'u', 'p', '\0'};
static const char16_t sHTMLTagUnicodeName_content[] =
{'c', 'o', 'n', 't', 'e', 'n', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_data[] =
{'d', 'a', 't', 'a', '\0'};
static const char16_t sHTMLTagUnicodeName_datalist[] =
{'d', 'a', 't', 'a', 'l', 'i', 's', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_dd[] =
{'d', 'd', '\0'};
static const char16_t sHTMLTagUnicodeName_del[] =
{'d', 'e', 'l', '\0'};
static const char16_t sHTMLTagUnicodeName_details[] =
{'d', 'e', 't', 'a', 'i', 'l', 's', '\0'};
static const char16_t sHTMLTagUnicodeName_dfn[] =
{'d', 'f', 'n', '\0'};
static const char16_t sHTMLTagUnicodeName_dir[] =
{'d', 'i', 'r', '\0'};
static const char16_t sHTMLTagUnicodeName_div[] =
{'d', 'i', 'v', '\0'};
static const char16_t sHTMLTagUnicodeName_dl[] =
{'d', 'l', '\0'};
static const char16_t sHTMLTagUnicodeName_dt[] =
{'d', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_em[] =
{'e', 'm', '\0'};
static const char16_t sHTMLTagUnicodeName_embed[] =
{'e', 'm', 'b', 'e', 'd', '\0'};
static const char16_t sHTMLTagUnicodeName_extapp[] =
{'e', 'x', 't', 'a', 'p', 'p', '\0'};
static const char16_t sHTMLTagUnicodeName_fieldset[] =
{'f', 'i', 'e', 'l', 'd', 's', 'e', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_figcaption[] =
{'f', 'i', 'g', 'c', 'a', 'p', 't', 'i', 'o', 'n', '\0'};
static const char16_t sHTMLTagUnicodeName_figure[] =
{'f', 'i', 'g', 'u', 'r', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_font[] =
{'f', 'o', 'n', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_footer[] =
{'f', 'o', 'o', 't', 'e', 'r', '\0'};
static const char16_t sHTMLTagUnicodeName_form[] =
{'f', 'o', 'r', 'm', '\0'};
static const char16_t sHTMLTagUnicodeName_frame[] =
{'f', 'r', 'a', 'm', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_frameset[] =
{'f', 'r', 'a', 'm', 'e', 's', 'e', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_h1[] =
{'h', '1', '\0'};
static const char16_t sHTMLTagUnicodeName_h2[] =
{'h', '2', '\0'};
static const char16_t sHTMLTagUnicodeName_h3[] =
{'h', '3', '\0'};
static const char16_t sHTMLTagUnicodeName_h4[] =
{'h', '4', '\0'};
static const char16_t sHTMLTagUnicodeName_h5[] =
{'h', '5', '\0'};
static const char16_t sHTMLTagUnicodeName_h6[] =
{'h', '6', '\0'};
static const char16_t sHTMLTagUnicodeName_head[] =
{'h', 'e', 'a', 'd', '\0'};
static const char16_t sHTMLTagUnicodeName_header[] =
{'h', 'e', 'a', 'd', 'e', 'r', '\0'};
static const char16_t sHTMLTagUnicodeName_hgroup[] =
{'h', 'g', 'r', 'o', 'u', 'p', '\0'};
static const char16_t sHTMLTagUnicodeName_hr[] =
{'h', 'r', '\0'};
static const char16_t sHTMLTagUnicodeName_html[] =
{'h', 't', 'm', 'l', '\0'};
static const char16_t sHTMLTagUnicodeName_i[] =
{'i', '\0'};
static const char16_t sHTMLTagUnicodeName_iframe[] =
{'i', 'f', 'r', 'a', 'm', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_image[] =
{'i', 'm', 'a', 'g', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_img[] =
{'i', 'm', 'g', '\0'};
static const char16_t sHTMLTagUnicodeName_input[] =
{'i', 'n', 'p', 'u', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_ins[] =
{'i', 'n', 's', '\0'};
static const char16_t sHTMLTagUnicodeName_kbd[] =
{'k', 'b', 'd', '\0'};
static const char16_t sHTMLTagUnicodeName_keygen[] =
{'k', 'e', 'y', 'g', 'e', 'n', '\0'};
static const char16_t sHTMLTagUnicodeName_label[] =
{'l', 'a', 'b', 'e', 'l', '\0'};
static const char16_t sHTMLTagUnicodeName_legend[] =
{'l', 'e', 'g', 'e', 'n', 'd', '\0'};
static const char16_t sHTMLTagUnicodeName_li[] =
{'l', 'i', '\0'};
static const char16_t sHTMLTagUnicodeName_link[] =
{'l', 'i', 'n', 'k', '\0'};
static const char16_t sHTMLTagUnicodeName_listing[] =
{'l', 'i', 's', 't', 'i', 'n', 'g', '\0'};
static const char16_t sHTMLTagUnicodeName_main[] =
{'m', 'a', 'i', 'n', '\0'};
static const char16_t sHTMLTagUnicodeName_map[] =
{'m', 'a', 'p', '\0'};
static const char16_t sHTMLTagUnicodeName_mark[] =
{'m', 'a', 'r', 'k', '\0'};
static const char16_t sHTMLTagUnicodeName_marquee[] =
{'m', 'a', 'r', 'q', 'u', 'e', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_menu[] =
{'m', 'e', 'n', 'u', '\0'};
static const char16_t sHTMLTagUnicodeName_menuitem[] =
{'m', 'e', 'n', 'u', 'i', 't', 'e', 'm', '\0'};
static const char16_t sHTMLTagUnicodeName_meta[] =
{'m', 'e', 't', 'a', '\0'};
static const char16_t sHTMLTagUnicodeName_meter[] =
{'m', 'e', 't', 'e', 'r', '\0'};
static const char16_t sHTMLTagUnicodeName_multicol[] =
{'m', 'u', 'l', 't', 'i', 'c', 'o', 'l', '\0'};
static const char16_t sHTMLTagUnicodeName_nav[] =
{'n', 'a', 'v', '\0'};
static const char16_t sHTMLTagUnicodeName_nobr[] =
{'n', 'o', 'b', 'r', '\0'};
static const char16_t sHTMLTagUnicodeName_noembed[] =
{'n', 'o', 'e', 'm', 'b', 'e', 'd', '\0'};
static const char16_t sHTMLTagUnicodeName_noframes[] =
{'n', 'o', 'f', 'r', 'a', 'm', 'e', 's', '\0'};
static const char16_t sHTMLTagUnicodeName_noscript[] =
{'n', 'o', 's', 'c', 'r', 'i', 'p', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_object[] =
{'o', 'b', 'j', 'e', 'c', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_ol[] =
{'o', 'l', '\0'};
static const char16_t sHTMLTagUnicodeName_optgroup[] =
{'o', 'p', 't', 'g', 'r', 'o', 'u', 'p', '\0'};
static const char16_t sHTMLTagUnicodeName_option[] =
{'o', 'p', 't', 'i', 'o', 'n', '\0'};
static const char16_t sHTMLTagUnicodeName_output[] =
{'o', 'u', 't', 'p', 'u', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_p[] =
{'p', '\0'};
static const char16_t sHTMLTagUnicodeName_param[] =
{'p', 'a', 'r', 'a', 'm', '\0'};
static const char16_t sHTMLTagUnicodeName_picture[] =
{'p', 'i', 'c', 't', 'u', 'r', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_plaintext[] =
{'p', 'l', 'a', 'i', 'n', 't', 'e', 'x', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_pre[] =
{'p', 'r', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_progress[] =
{'p', 'r', 'o', 'g', 'r', 'e', 's', 's', '\0'};
static const char16_t sHTMLTagUnicodeName_q[] =
{'q', '\0'};
static const char16_t sHTMLTagUnicodeName_rb[] =
{'r', 'b', '\0'};
static const char16_t sHTMLTagUnicodeName_rp[] =
{'r', 'p', '\0'};
static const char16_t sHTMLTagUnicodeName_rt[] =
{'r', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_rtc[] =
{'r', 't', 'c', '\0'};
static const char16_t sHTMLTagUnicodeName_ruby[] =
{'r', 'u', 'b', 'y', '\0'};
static const char16_t sHTMLTagUnicodeName_s[] =
{'s', '\0'};
static const char16_t sHTMLTagUnicodeName_samp[] =
{'s', 'a', 'm', 'p', '\0'};
static const char16_t sHTMLTagUnicodeName_script[] =
{'s', 'c', 'r', 'i', 'p', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_section[] =
{'s', 'e', 'c', 't', 'i', 'o', 'n', '\0'};
static const char16_t sHTMLTagUnicodeName_select[] =
{'s', 'e', 'l', 'e', 'c', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_shadow[] =
{'s', 'h', 'a', 'd', 'o', 'w', '\0'};
static const char16_t sHTMLTagUnicodeName_small[] =
{'s', 'm', 'a', 'l', 'l', '\0'};
static const char16_t sHTMLTagUnicodeName_source[] =
{'s', 'o', 'u', 'r', 'c', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_span[] =
{'s', 'p', 'a', 'n', '\0'};
static const char16_t sHTMLTagUnicodeName_strike[] =
{'s', 't', 'r', 'i', 'k', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_strong[] =
{'s', 't', 'r', 'o', 'n', 'g', '\0'};
static const char16_t sHTMLTagUnicodeName_style[] =
{'s', 't', 'y', 'l', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_sub[] =
{'s', 'u', 'b', '\0'};
static const char16_t sHTMLTagUnicodeName_summary[] =
{'s', 'u', 'm', 'm', 'a', 'r', 'y', '\0'};
static const char16_t sHTMLTagUnicodeName_sup[] =
{'s', 'u', 'p', '\0'};
static const char16_t sHTMLTagUnicodeName_table[] =
{'t', 'a', 'b', 'l', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_tbody[] =
{'t', 'b', 'o', 'd', 'y', '\0'};
static const char16_t sHTMLTagUnicodeName_td[] =
{'t', 'd', '\0'};
static const char16_t sHTMLTagUnicodeName_textarea[] =
{'t', 'e', 'x', 't', 'a', 'r', 'e', 'a', '\0'};
static const char16_t sHTMLTagUnicodeName_tfoot[] =
{'t', 'f', 'o', 'o', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_th[] =
{'t', 'h', '\0'};
static const char16_t sHTMLTagUnicodeName_thead[] =
{'t', 'h', 'e', 'a', 'd', '\0'};
static const char16_t sHTMLTagUnicodeName_template[] =
{'t', 'e', 'm', 'p', 'l', 'a', 't', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_time[] =
{'t', 'i', 'm', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_title[] =
{'t', 'i', 't', 'l', 'e', '\0'};
static const char16_t sHTMLTagUnicodeName_tr[] =
{'t', 'r', '\0'};
static const char16_t sHTMLTagUnicodeName_track[] =
{'t', 'r', 'a', 'c', 'k', '\0'};
static const char16_t sHTMLTagUnicodeName_tt[] =
{'t', 't', '\0'};
static const char16_t sHTMLTagUnicodeName_u[] =
{'u', '\0'};
static const char16_t sHTMLTagUnicodeName_ul[] =
{'u', 'l', '\0'};
static const char16_t sHTMLTagUnicodeName_var[] =
{'v', 'a', 'r', '\0'};
static const char16_t sHTMLTagUnicodeName_video[] =
{'v', 'i', 'd', 'e', 'o', '\0'};
static const char16_t sHTMLTagUnicodeName_wbr[] =
{'w', 'b', 'r', '\0'};
static const char16_t sHTMLTagUnicodeName_xmp[] =
{'x', 'm', 'p', '\0'};
// static array of unicode tag names
#define HTML_TAG(_tag, _classname) sHTMLTagUnicodeName_##_tag,
#define HTML_HTMLELEMENT_TAG(_tag) sHTMLTagUnicodeName_##_tag,
#define HTML_TAG(_tag, _classname) MOZ_UTF16(#_tag),
#define HTML_HTMLELEMENT_TAG(_tag) MOZ_UTF16(#_tag),
#define HTML_OTHER(_tag)
const char16_t* const nsHTMLTags::sTagUnicodeTable[] = {
#include "nsHTMLTagList.h"
@@ -385,4 +385,47 @@ test(function() {
el.removeAttributeNS(null, "pre:fix")
assert_equals(el.attributes[0], unprefixed)
}, "Attribute with prefix in local name")
test(function() {
var el = document.createElement("div")
el.setAttribute("foo", "bar")
var attr = el.attributes[0]
assert_equals(attr.ownerElement, el)
el.removeAttribute("foo")
assert_equals(attr.ownerElement, null)
}, "Attribute loses its owner when removed")
test(function() {
var el = document.createElement("div");
el.setAttribute("foo", "bar");
assert_equals(el.getAttributeNames().length, 1);
assert_equals(el.getAttributeNames()[0], el.attributes[0].name);
assert_equals(el.getAttributeNames()[0], "foo");
el.removeAttribute("foo");
assert_equals(el.getAttributeNames().length, 0);
el.setAttribute("foo", "bar");
el.setAttributeNS("", "FOO", "bar");
el.setAttributeNS("dummy1", "foo", "bar");
el.setAttributeNS("dummy2", "dummy:foo", "bar");
assert_equals(el.getAttributeNames().length, 4);
assert_equals(el.getAttributeNames()[0], "foo");
assert_equals(el.getAttributeNames()[1], "FOO");
assert_equals(el.getAttributeNames()[2], "foo");
assert_equals(el.getAttributeNames()[3], "dummy:foo");
assert_equals(el.getAttributeNames()[0], el.attributes[0].name);
assert_equals(el.getAttributeNames()[1], el.attributes[1].name);
assert_equals(el.getAttributeNames()[2], el.attributes[2].name);
assert_equals(el.getAttributeNames()[3], el.attributes[3].name);
el.removeAttributeNS("", "FOO");
assert_equals(el.getAttributeNames().length, 3);
assert_equals(el.getAttributeNames()[0], "foo");
assert_equals(el.getAttributeNames()[1], "foo");
assert_equals(el.getAttributeNames()[2], "dummy:foo");
assert_equals(el.getAttributeNames()[0], el.attributes[0].name);
assert_equals(el.getAttributeNames()[1], el.attributes[1].name);
assert_equals(el.getAttributeNames()[2], el.attributes[2].name);
}, "getAttributeNames tests");
</script>
+67 -48
View File
@@ -448,11 +448,10 @@ ContentCacheInChild::SetSelection(nsIWidget* aWidget,
ContentCacheInParent::ContentCacheInParent()
: ContentCache()
, mCommitStringByRequest(nullptr)
, mCompositionStart(UINT32_MAX)
, mCompositionEventsDuringRequest(0)
, mPendingEventsNeedingAck(0)
, mIsComposing(false)
, mRequestedToCommitOrCancelComposition(false)
{
}
@@ -827,48 +826,34 @@ ContentCacheInParent::OnCompositionEvent(const WidgetCompositionEvent& aEvent)
("ContentCacheInParent: 0x%p OnCompositionEvent(aEvent={ "
"mMessage=%s, mData=\"%s\" (Length()=%u), mRanges->Length()=%u }), "
"mPendingEventsNeedingAck=%u, mIsComposing=%s, "
"mRequestedToCommitOrCancelComposition=%s",
"mCommitStringByRequest=0x%p",
this, ToChar(aEvent.mMessage),
NS_ConvertUTF16toUTF8(aEvent.mData).get(), aEvent.mData.Length(),
aEvent.mRanges ? aEvent.mRanges->Length() : 0, mPendingEventsNeedingAck,
GetBoolName(mIsComposing),
GetBoolName(mRequestedToCommitOrCancelComposition)));
if (!aEvent.CausesDOMTextEvent()) {
MOZ_ASSERT(aEvent.mMessage == eCompositionStart);
mIsComposing = !aEvent.CausesDOMCompositionEndEvent();
mCompositionStart = mSelection.StartOffset();
// XXX What's this case??
if (mRequestedToCommitOrCancelComposition) {
mCommitStringByRequest = aEvent.mData;
mCompositionEventsDuringRequest++;
return false;
}
mPendingEventsNeedingAck++;
return true;
}
// XXX Why do we ignore following composition events here?
// TextComposition must handle following events correctly!
// During REQUEST_TO_COMMIT_COMPOSITION or REQUEST_TO_CANCEL_COMPOSITION,
// widget usually sends a eCompositionChange event to finalize or
// clear the composition, respectively.
// Because the event will not reach content in time, we intercept it
// here and pass the text as the DidRequestToCommitOrCancelComposition()
// return value.
if (mRequestedToCommitOrCancelComposition) {
mCommitStringByRequest = aEvent.mData;
mCompositionEventsDuringRequest++;
return false;
}
GetBoolName(mIsComposing), mCommitStringByRequest));
// We must be able to simulate the selection because
// we might not receive selection updates in time
if (!mIsComposing) {
mCompositionStart = mSelection.StartOffset();
}
mIsComposing = !aEvent.CausesDOMCompositionEndEvent();
// During REQUEST_TO_COMMIT_COMPOSITION or REQUEST_TO_CANCEL_COMPOSITION,
// widget usually sends a eCompositionChange and/or eCompositionCommit event
// to finalize or clear the composition, respectively. In this time,
// we need to intercept all composition events here and pass the commit
// string for returning to the remote process as a result of
// RequestIMEToCommitComposition(). Then, eCommitComposition event will
// be dispatched with the committed string in the remote process internally.
if (mCommitStringByRequest) {
MOZ_ASSERT(aEvent.mMessage == eCompositionChange ||
aEvent.mMessage == eCompositionCommit);
*mCommitStringByRequest = aEvent.mData;
return false;
}
mPendingEventsNeedingAck++;
return true;
}
@@ -912,29 +897,63 @@ ContentCacheInParent::OnEventNeedingAckHandled(nsIWidget* aWidget,
FlushPendingNotifications(aWidget);
}
uint32_t
ContentCacheInParent::RequestToCommitComposition(nsIWidget* aWidget,
bool aCancel,
nsAString& aLastString)
bool
ContentCacheInParent::RequestIMEToCommitComposition(nsIWidget* aWidget,
bool aCancel,
nsAString& aCommittedString)
{
MOZ_LOG(sContentCacheLog, LogLevel::Info,
("ContentCacheInParent: 0x%p RequestToCommitComposition(aWidget=%p, "
"aCancel=%s), mIsComposing=%s, mRequestedToCommitOrCancelComposition=%s, "
"mCompositionEventsDuringRequest=%u",
"aCancel=%s), mIsComposing=%s, mCommitStringByRequest=%p",
this, aWidget, GetBoolName(aCancel), GetBoolName(mIsComposing),
GetBoolName(mRequestedToCommitOrCancelComposition),
mCompositionEventsDuringRequest));
mCommitStringByRequest));
mRequestedToCommitOrCancelComposition = true;
mCompositionEventsDuringRequest = 0;
MOZ_ASSERT(!mCommitStringByRequest);
RefPtr<TextComposition> composition =
IMEStateManager::GetTextCompositionFor(aWidget);
if (NS_WARN_IF(!composition)) {
MOZ_LOG(sContentCacheLog, LogLevel::Warning,
(" ContentCacheInParent: 0x%p RequestToCommitComposition(), "
"does nothing due to no composition", this));
return false;
}
mCommitStringByRequest = &aCommittedString;
aWidget->NotifyIME(IMENotification(aCancel ? REQUEST_TO_CANCEL_COMPOSITION :
REQUEST_TO_COMMIT_COMPOSITION));
mRequestedToCommitOrCancelComposition = false;
aLastString = mCommitStringByRequest;
mCommitStringByRequest.Truncate(0);
return mCompositionEventsDuringRequest;
mCommitStringByRequest = nullptr;
MOZ_LOG(sContentCacheLog, LogLevel::Info,
(" ContentCacheInParent: 0x%p RequestToCommitComposition(), "
"mIsComposing=%s, the composition %s committed synchronously",
this, GetBoolName(mIsComposing),
composition->Destroyed() ? "WAS" : "has NOT been"));
if (!composition->Destroyed()) {
// When the composition isn't committed synchronously, the remote process's
// TextComposition instance will synthesize commit events and wait to
// receive delayed composition events. When TextComposition instances both
// in this process and the remote process will be destroyed when delayed
// composition events received. TextComposition instance in the parent
// process will dispatch following composition events and be destroyed
// normally. On the other hand, TextComposition instance in the remote
// process won't dispatch following composition events and will be
// destroyed by IMEStateManager::DispatchCompositionEvent().
return false;
}
// When the composition is committed synchronously, the commit string will be
// returned to the remote process. Then, PuppetWidget will dispatch
// eCompositionCommit event with the returned commit string (i.e., the value
// is aCommittedString of this method). Finally, TextComposition instance in
// the remote process will be destroyed by
// IMEStateManager::DispatchCompositionEvent() at receiving the
// eCompositionCommit event (Note that TextComposition instance in this
// process was already destroyed).
return true;
}
void
+14 -16
View File
@@ -325,22 +325,22 @@ public:
void OnEventNeedingAckHandled(nsIWidget* aWidget, EventMessage aMessage);
/**
* RequestToCommitComposition() requests to commit or cancel composition to
* the widget. If it's handled synchronously, this returns the number of
* composition events after that.
* RequestIMEToCommitComposition() requests aWidget to commit or cancel
* composition. If it's handled synchronously, this returns true.
*
* @param aWidget The widget to be requested to commit or cancel
* the composition.
* @param aCancel When the caller tries to cancel the composition, true.
* Otherwise, i.e., tries to commit the composition, false.
* @param aLastString The last composition string before requesting to
* commit or cancel composition.
* @return The count of composition events ignored after a call of
* WillRequestToCommitOrCancelComposition().
* @param aCommittedString The committed string (i.e., the last data of
* dispatched composition events during requesting
* IME to commit composition.
* @return Whether the composition is actually committed
* synchronously.
*/
uint32_t RequestToCommitComposition(nsIWidget* aWidget,
bool aCancel,
nsAString& aLastString);
bool RequestIMEToCommitComposition(nsIWidget* aWidget,
bool aCancel,
nsAString& aCommittedString);
/**
* MaybeNotifyIME() may notify IME of the notification. If child process
@@ -356,20 +356,18 @@ private:
IMENotification mPendingLayoutChange;
IMENotification mPendingCompositionUpdate;
// This is commit string which is caused by our request.
nsString mCommitStringByRequest;
// This is not nullptr only while the instance is requesting IME to
// composition. Then, data value of dispatched composition events should
// be stored into the instance.
nsAString* mCommitStringByRequest;
// Start offset of the composition string.
uint32_t mCompositionStart;
// Count of composition events during requesting commit or cancel the
// composition.
uint32_t mCompositionEventsDuringRequest;
// mPendingEventsNeedingAck is increased before sending a composition event or
// a selection event and decreased after they are received in the child
// process.
uint32_t mPendingEventsNeedingAck;
bool mIsComposing;
bool mRequestedToCommitOrCancelComposition;
bool GetCaretRect(uint32_t aOffset, LayoutDeviceIntRect& aCaretRect) const;
bool GetTextRect(uint32_t aOffset,
+51 -7
View File
@@ -10,6 +10,8 @@
#include "nsRect.h"
#include "nsStringGlue.h"
class nsIWidget;
namespace mozilla {
class WritingMode;
@@ -224,11 +226,58 @@ struct IMEState final
}
};
// NS_ONLY_ONE_NATIVE_IME_CONTEXT is a special value of native IME context.
// If there can be only one IME composition in a process, this can be used.
#define NS_ONLY_ONE_NATIVE_IME_CONTEXT \
(reinterpret_cast<void*>(static_cast<intptr_t>(-1)))
struct NativeIMEContext final
{
// Pointer to native IME context. Typically this is the result of
// nsIWidget::GetNativeData(NS_RAW_NATIVE_IME_CONTEXT) in the parent process.
// See also NS_ONLY_ONE_NATIVE_IME_CONTEXT.
uintptr_t mRawNativeIMEContext;
// Process ID of the origin of mNativeIMEContext.
uint64_t mOriginProcessID;
NativeIMEContext()
{
Init(nullptr);
}
explicit NativeIMEContext(nsIWidget* aWidget)
{
Init(aWidget);
}
bool IsValid() const
{
return mRawNativeIMEContext &&
mOriginProcessID != static_cast<uintptr_t>(-1);
}
void Init(nsIWidget* aWidget);
void InitWithRawNativeIMEContext(const void* aRawNativeIMEContext)
{
InitWithRawNativeIMEContext(const_cast<void*>(aRawNativeIMEContext));
}
void InitWithRawNativeIMEContext(void* aRawNativeIMEContext);
bool operator==(const NativeIMEContext& aOther) const
{
return mRawNativeIMEContext == aOther.mRawNativeIMEContext &&
mOriginProcessID == aOther.mOriginProcessID;
}
bool operator!=(const NativeIMEContext& aOther) const
{
return !(*this == aOther);
}
};
struct InputContext final
{
InputContext()
: mNativeIMEContext(nullptr)
, mOrigin(XRE_IsParentProcess() ? ORIGIN_MAIN : ORIGIN_CONTENT)
: mOrigin(XRE_IsParentProcess() ? ORIGIN_MAIN : ORIGIN_CONTENT)
, mMayBeIMEUnaware(false)
{
}
@@ -249,11 +298,6 @@ struct InputContext final
/* A hint for the action that is performed when the input is submitted */
nsString mActionHint;
/* Native IME context for the widget. This doesn't come from the argument of
SetInputContext(). If there is only one context in the process, this may
be nullptr. */
void* mNativeIMEContext;
/**
* mOrigin indicates whether this focus event refers to main or remote
* content.
+77 -25
View File
@@ -79,9 +79,9 @@ PuppetWidget::PuppetWidget(TabChild* aTabChild)
, mMemoryPressureObserver(nullptr)
, mDPI(-1)
, mDefaultScale(-1)
, mNativeKeyCommandsValid(false)
, mCursorHotspotX(0)
, mCursorHotspotY(0)
, mNativeKeyCommandsValid(false)
{
MOZ_COUNT_CTOR(PuppetWidget);
@@ -159,6 +159,11 @@ PuppetWidget::CreateChild(const LayoutDeviceIntRect& aRect,
NS_IMETHODIMP
PuppetWidget::Destroy()
{
if (mOnDestroyCalled) {
return NS_OK;
}
mOnDestroyCalled = true;
Base::OnDestroy();
Base::Destroy();
mPaintTask.Revoke();
@@ -317,6 +322,24 @@ PuppetWidget::DispatchEvent(WidgetGUIEvent* event, nsEventStatus& aStatus)
}
}
if (event->mClass == eCompositionEventClass) {
// Store the latest native IME context of parent process's widget or
// TextEventDispatcher if it's in this process.
WidgetCompositionEvent* compositionEvent = event->AsCompositionEvent();
#ifdef DEBUG
if (mNativeIMEContext.IsValid() &&
mNativeIMEContext != compositionEvent->mNativeIMEContext) {
RefPtr<TextComposition> composition =
IMEStateManager::GetTextCompositionFor(this);
MOZ_ASSERT(!composition,
"When there is composition caused by old native IME context, "
"composition events caused by different native IME context are not "
"allowed");
}
#endif // #ifdef DEBUG
mNativeIMEContext = compositionEvent->mNativeIMEContext;
}
aStatus = nsEventStatus_eIgnore;
if (GetCurrentWidgetListener()) {
@@ -566,29 +589,51 @@ PuppetWidget::GetLayerManager(PLayerTransactionChild* aShadowManager,
}
nsresult
PuppetWidget::IMEEndComposition(bool aCancel)
PuppetWidget::RequestIMEToCommitComposition(bool aCancel)
{
#ifndef MOZ_CROSS_PROCESS_IME
return NS_OK;
#endif
nsEventStatus status;
bool noCompositionEvent = true;
WidgetCompositionEvent compositionCommitEvent(true, eCompositionCommit, this);
InitEvent(compositionCommitEvent, nullptr);
// SendEndIMEComposition is always called since ResetInputState
// should always be called even if we aren't composing something.
if (!mTabChild ||
!mTabChild->SendEndIMEComposition(aCancel, &noCompositionEvent,
&compositionCommitEvent.mData)) {
#ifdef MOZ_CROSS_PROCESS_IME
if (!mTabChild) {
return NS_ERROR_FAILURE;
}
if (noCompositionEvent) {
MOZ_ASSERT(!Destroyed());
// There must not be composition which is caused by the PuppetWidget instance.
if (NS_WARN_IF(!mNativeIMEContext.IsValid())) {
return NS_OK;
}
RefPtr<TextComposition> composition =
IMEStateManager::GetTextCompositionFor(this);
// This method shouldn't be called when there is no text composition instance.
if (NS_WARN_IF(!composition)) {
return NS_OK;
}
bool isCommitted = false;
nsAutoString committedString;
if (NS_WARN_IF(!mTabChild->SendRequestIMEToCommitComposition(
aCancel, &isCommitted, &committedString))) {
return NS_ERROR_FAILURE;
}
// If the composition wasn't committed synchronously, we need to wait async
// composition events for destroying the TextComposition instance.
if (!isCommitted) {
return NS_OK;
}
// Dispatch eCompositionCommit event.
WidgetCompositionEvent compositionCommitEvent(true, eCompositionCommit, this);
InitEvent(compositionCommitEvent, nullptr);
compositionCommitEvent.mData = committedString;
nsEventStatus status = nsEventStatus_eIgnore;
DispatchEvent(&compositionCommitEvent, status);
// NOTE: PuppetWidget might be destroyed already.
#endif // #ifdef MOZ_CROSS_PROCESS_IME
return NS_OK;
}
@@ -597,9 +642,9 @@ PuppetWidget::NotifyIMEInternal(const IMENotification& aIMENotification)
{
switch (aIMENotification.mMessage) {
case REQUEST_TO_COMMIT_COMPOSITION:
return IMEEndComposition(false);
return RequestIMEToCommitComposition(false);
case REQUEST_TO_CANCEL_COMPOSITION:
return IMEEndComposition(true);
return RequestIMEToCommitComposition(true);
case NOTIFY_IME_OF_FOCUS:
case NOTIFY_IME_OF_BLUR:
return NotifyIMEOfFocusChange(aIMENotification);
@@ -673,15 +718,20 @@ PuppetWidget::GetInputContext()
InputContext context;
if (mTabChild) {
int32_t enabled, open;
intptr_t nativeIMEContext;
mTabChild->SendGetInputContext(&enabled, &open, &nativeIMEContext);
// TODO: This is too expensive. PuppetWidget should cache IMEState.
mTabChild->SendGetInputContext(&enabled, &open);
context.mIMEState.mEnabled = static_cast<IMEState::Enabled>(enabled);
context.mIMEState.mOpen = static_cast<IMEState::Open>(open);
context.mNativeIMEContext = reinterpret_cast<void*>(nativeIMEContext);
}
return context;
}
NS_IMETHODIMP_(NativeIMEContext)
PuppetWidget::GetNativeIMEContext()
{
return mNativeIMEContext;
}
nsresult
PuppetWidget::NotifyIMEOfFocusChange(const IMENotification& aIMENotification)
{
@@ -1115,14 +1165,16 @@ PuppetWidget::GetNativeData(uint32_t aDataType)
}
return (void*)nativeData;
}
case NS_NATIVE_WINDOW:
case NS_NATIVE_WIDGET:
case NS_NATIVE_DISPLAY:
// These types are ignored (see bug 1183828).
break;
case NS_RAW_NATIVE_IME_CONTEXT:
MOZ_CRASH("You need to call GetNativeIMEContext() instead");
case NS_NATIVE_WINDOW:
case NS_NATIVE_PLUGIN_PORT:
case NS_NATIVE_GRAPHIC:
case NS_NATIVE_SHELLWIDGET:
case NS_NATIVE_WIDGET:
NS_WARNING("nsWindow::GetNativeData not implemented for this type");
break;
default:
NS_WARNING("nsWindow::GetNativeData called with bad value");
break;
+16 -6
View File
@@ -179,6 +179,7 @@ public:
NS_IMETHOD_(void) SetInputContext(const InputContext& aContext,
const InputContextAction& aAction) override;
NS_IMETHOD_(InputContext) GetInputContext() override;
NS_IMETHOD_(NativeIMEContext) GetNativeIMEContext() override;
virtual nsIMEUpdatePreference GetIMEUpdatePreference() override;
NS_IMETHOD SetCursor(nsCursor aCursor) override;
@@ -254,9 +255,6 @@ public:
virtual void StartAsyncScrollbarDrag(const AsyncDragMetrics& aDragMetrics) override;
protected:
bool mEnabled;
bool mVisible;
virtual nsresult NotifyIMEInternal(
const IMENotification& aIMENotification) override;
@@ -265,7 +263,7 @@ private:
void SetChild(PuppetWidget* aChild);
nsresult IMEEndComposition(bool aCancel);
nsresult RequestIMEToCommitComposition(bool aCancel);
nsresult NotifyIMEOfFocusChange(const IMENotification& aIMENotification);
nsresult NotifyIMEOfSelectionChange(const IMENotification& aIMENotification);
nsresult NotifyIMEOfCompositionUpdate(const IMENotification& aIMENotification);
@@ -322,21 +320,33 @@ private:
// IME
nsIMEUpdatePreference mIMEPreferenceOfParent;
InputContext mInputContext;
// mNativeIMEContext is initialized when this dispatches every composition
// event both from parent process's widget and TextEventDispatcher in same
// process. If it hasn't been started composition yet, this isn't necessary
// for XP code since there is no TextComposition instance which is caused by
// the PuppetWidget instance.
NativeIMEContext mNativeIMEContext;
ContentCacheInChild mContentCache;
bool mNeedIMEStateInit;
// The DPI of the screen corresponding to this widget
float mDPI;
double mDefaultScale;
// Precomputed answers for ExecuteNativeKeyBinding
bool mNativeKeyCommandsValid;
InfallibleTArray<mozilla::CommandInt> mSingleLineCommands;
InfallibleTArray<mozilla::CommandInt> mMultiLineCommands;
InfallibleTArray<mozilla::CommandInt> mRichTextCommands;
nsCOMPtr<imgIContainer> mCustomCursor;
uint32_t mCursorHotspotX, mCursorHotspotY;
protected:
bool mEnabled;
bool mVisible;
private:
bool mNeedIMEStateInit;
bool mNativeKeyCommandsValid;
};
struct AutoCacheNativeKeyCommands
+11
View File
@@ -134,6 +134,17 @@ TextEventDispatcher::InitEvent(WidgetGUIEvent& aEvent) const
aEvent.time = PR_IntervalNow();
aEvent.refPoint = LayoutDeviceIntPoint(0, 0);
aEvent.mFlags.mIsSynthesizedForTests = mForTests;
if (aEvent.mClass != eCompositionEventClass) {
return;
}
// Currently, we should set special native IME context when composition
// events are dispatched from PuppetWidget since PuppetWidget may have not
// known actual native IME context yet and it caches native IME context
// when it dispatches every WidgetCompositionEvent.
if (XRE_IsContentProcess()) {
aEvent.AsCompositionEvent()->
mNativeIMEContext.InitWithRawNativeIMEContext(mWidget);
}
}
nsresult
+5
View File
@@ -366,6 +366,7 @@ public:
WidgetCompositionEvent(bool aIsTrusted, EventMessage aMessage,
nsIWidget* aWidget)
: WidgetGUIEvent(aIsTrusted, aMessage, aWidget, eCompositionEventClass)
, mNativeIMEContext(aWidget)
, mOriginalMessage(eVoidEvent)
{
// XXX compositionstart is cancelable in draft of DOM3 Events.
@@ -393,6 +394,10 @@ public:
RefPtr<TextRangeArray> mRanges;
// mNativeIMEContext stores the native IME context which causes the
// composition event.
widget::NativeIMEContext mNativeIMEContext;
// If the instance is a clone of another event, mOriginalMessage stores
// the another event's mMessage.
EventMessage mOriginalMessage;
+11 -7
View File
@@ -684,6 +684,17 @@ void* nsChildView::GetNativeData(uint32_t aDataType)
case NS_NATIVE_OFFSETY:
retVal = 0;
break;
case NS_RAW_NATIVE_IME_CONTEXT:
retVal = [mView inputContext];
// If input context isn't available on this widget, we should set |this|
// instead of nullptr since if this returns nullptr, IMEStateManager
// cannot manage composition with TextComposition instance. Although,
// this case shouldn't occur.
if (NS_WARN_IF(!retVal)) {
retVal = this;
}
break;
}
return retVal;
@@ -1769,13 +1780,6 @@ nsChildView::GetInputContext()
mInputContext.mIMEState.mOpen = IMEState::CLOSED;
break;
}
mInputContext.mNativeIMEContext = [mView inputContext];
// If input context isn't available on this widget, we should set |this|
// instead of nullptr since nullptr means that the platform has only one
// context per process.
if (!mInputContext.mNativeIMEContext) {
mInputContext.mNativeIMEContext = this;
}
return mInputContext;
}
-10
View File
@@ -349,16 +349,6 @@ public:
const InputContextAction& aAction) override;
NS_IMETHOD_(InputContext) GetInputContext() override
{
NSView* view = mWindow ? [mWindow contentView] : nil;
if (view) {
mInputContext.mNativeIMEContext = [view inputContext];
}
// If inputContext isn't available on this window, returns this window's
// pointer since nullptr means the platform has only one context per
// process.
if (!mInputContext.mNativeIMEContext) {
mInputContext.mNativeIMEContext = this;
}
return mInputContext;
}
NS_IMETHOD_(bool) ExecuteNativeKeyBinding(
+14
View File
@@ -581,6 +581,20 @@ void* nsCocoaWindow::GetNativeData(uint32_t aDataType)
// and it doesn't matter so just return nullptr.
NS_ERROR("Requesting NS_NATIVE_GRAPHIC on a top-level window!");
break;
case NS_RAW_NATIVE_IME_CONTEXT: {
NSView* view = mWindow ? [mWindow contentView] : nil;
if (view) {
retVal = [view inputContext];
}
// If inputContext isn't available on this window, return this window's
// pointer instead of nullptr since if this returns nullptr,
// IMEStateManager cannot manage composition with TextComposition
// instance. Although, this case shouldn't occur.
if (NS_WARN_IF(!retVal)) {
retVal = this;
}
break;
}
}
return retVal;
+9
View File
@@ -446,9 +446,18 @@ nsScreenGonk::GetEGLDisplay()
hwc_surface_t
nsScreenGonk::GetEGLSurface()
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
return mEGLSurface;
}
already_AddRefed<mozilla::gl::GLContext>
nsScreenGonk::GetGLContext()
{
MOZ_ASSERT(CompositorParent::IsInCompositorThread());
RefPtr<mozilla::gl::GLContext>glContext = mGLContext;
return glContext.forget();
}
static void
UpdateMirroringWidgetSync(RefPtr<nsScreenGonk>&& aScreen, nsWindow* aWindow)
{
+1
View File
@@ -117,6 +117,7 @@ public:
mozilla::gl::GLContext* aGLContext);
hwc_display_t GetEGLDisplay();
hwc_surface_t GetEGLSurface();
already_AddRefed<mozilla::gl::GLContext> GetGLContext();
void UpdateMirroringWidget(already_AddRefed<nsWindow>& aWindow); // Primary screen only
nsWindow* GetMirroringWidget(); // Primary screen only
+7 -3
View File
@@ -537,7 +537,13 @@ nsWindow::GetNativeData(uint32_t aDataType)
case NS_NATIVE_WINDOW:
// Called before primary display's EGLSurface creation.
return mScreen->GetNativeWindow();
case NS_NATIVE_OPENGL_CONTEXT:
return mScreen->GetGLContext().take();
case NS_RAW_NATIVE_IME_CONTEXT:
// There is only one IME context on Gonk.
return NS_ONLY_ONE_NATIVE_IME_CONTEXT;
}
return nullptr;
}
@@ -579,8 +585,6 @@ nsWindow::SetInputContext(const InputContext& aContext,
NS_IMETHODIMP_(InputContext)
nsWindow::GetInputContext()
{
// There is only one IME context on Gonk.
mInputContext.mNativeIMEContext = nullptr;
return mInputContext;
}
@@ -747,7 +751,7 @@ nsWindow::GetDefaultScaleInternal()
if (dpi < 200.0) {
return 1.0; // mdpi devices.
}
if (dpi < 300.0) {
if (dpi < 280.0) {
return 1.5; // hdpi devices.
}
// xhdpi devices and beyond.
+9 -5
View File
@@ -1737,6 +1737,15 @@ nsWindow::GetNativeData(uint32_t aDataType)
return (void *) GDK_WINDOW_XID(gdk_window_get_toplevel(mGdkWindow));
case NS_NATIVE_PLUGIN_OBJECT_PTR:
return (void *) mPluginNativeWindow;
case NS_RAW_NATIVE_IME_CONTEXT:
// If IME context isn't available on this widget, we should set |this|
// instead of nullptr since if we return nullptr, IMEStateManager
// cannot manage composition with TextComposition instance. Although,
// this case shouldn't occur.
if (NS_WARN_IF(!mIMContext)) {
return this;
}
return mIMContext.get();
default:
NS_WARNING("nsWindow::GetNativeData called with bad value");
return nullptr;
@@ -6170,13 +6179,8 @@ nsWindow::GetInputContext()
if (!mIMContext) {
context.mIMEState.mEnabled = IMEState::DISABLED;
context.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
// If IME context isn't available on this widget, we should set |this|
// instead of nullptr since nullptr means that the platform has only one
// context per process.
context.mNativeIMEContext = this;
} else {
context = mIMContext->GetInputContext();
context.mNativeIMEContext = mIMContext;
}
return context;
}
+42
View File
@@ -53,6 +53,7 @@
#include "mozilla/layers/ChromeProcessController.h"
#include "mozilla/layers/InputAPZContext.h"
#include "mozilla/layers/APZCCallbackHelper.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/Move.h"
#include "mozilla/Services.h"
@@ -86,6 +87,7 @@ static nsRefPtrHashtable<nsVoidPtrHashKey, nsIWidget>* sPluginWidgetList;
nsIRollupListener* nsBaseWidget::gRollupListener = nullptr;
using namespace mozilla::dom;
using namespace mozilla::layers;
using namespace mozilla::ipc;
using namespace mozilla::widget;
@@ -2057,9 +2059,49 @@ nsIWidget::SnapshotWidgetOnScreen()
return dt->Snapshot();
}
NS_IMETHODIMP_(nsIWidget::NativeIMEContext)
nsIWidget::GetNativeIMEContext()
{
return NativeIMEContext(this);
}
namespace mozilla {
namespace widget {
void
NativeIMEContext::Init(nsIWidget* aWidget)
{
if (!aWidget) {
mRawNativeIMEContext = reinterpret_cast<uintptr_t>(nullptr);
mOriginProcessID = static_cast<uint64_t>(-1);
return;
}
if (!XRE_IsContentProcess()) {
mRawNativeIMEContext = reinterpret_cast<uintptr_t>(
aWidget->GetNativeData(NS_RAW_NATIVE_IME_CONTEXT));
mOriginProcessID = 0;
return;
}
// If this is created in a child process, aWidget is an instance of
// PuppetWidget which doesn't support NS_RAW_NATIVE_IME_CONTEXT.
// Instead of that PuppetWidget::GetNativeIMEContext() returns cached
// native IME context of the parent process.
*this = aWidget->GetNativeIMEContext();
}
void
NativeIMEContext::InitWithRawNativeIMEContext(void* aRawNativeIMEContext)
{
if (NS_WARN_IF(!aRawNativeIMEContext)) {
mRawNativeIMEContext = reinterpret_cast<uintptr_t>(nullptr);
mOriginProcessID = static_cast<uint64_t>(-1);
return;
}
mRawNativeIMEContext = reinterpret_cast<uintptr_t>(aRawNativeIMEContext);
mOriginProcessID =
XRE_IsContentProcess() ? ContentChild::GetSingleton()->GetID() : 0;
}
void
IMENotification::TextChangeDataBase::MergeWith(
const IMENotification::TextChangeDataBase& aOther)
+20
View File
@@ -544,6 +544,7 @@ struct ParamTraits<mozilla::WidgetCompositionEvent>
{
WriteParam(aMsg, static_cast<mozilla::WidgetGUIEvent>(aParam));
WriteParam(aMsg, aParam.mData);
WriteParam(aMsg, aParam.mNativeIMEContext);
bool hasRanges = !!aParam.mRanges;
WriteParam(aMsg, hasRanges);
if (hasRanges) {
@@ -557,6 +558,7 @@ struct ParamTraits<mozilla::WidgetCompositionEvent>
if (!ReadParam(aMsg, aIter,
static_cast<mozilla::WidgetGUIEvent*>(aResult)) ||
!ReadParam(aMsg, aIter, &aResult->mData) ||
!ReadParam(aMsg, aIter, &aResult->mNativeIMEContext) ||
!ReadParam(aMsg, aIter, &hasRanges)) {
return false;
}
@@ -681,6 +683,24 @@ struct ParamTraits<nsIMEUpdatePreference>
}
};
template<>
struct ParamTraits<mozilla::widget::NativeIMEContext>
{
typedef mozilla::widget::NativeIMEContext paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mRawNativeIMEContext);
WriteParam(aMsg, aParam.mOriginProcessID);
}
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
{
return ReadParam(aMsg, aIter, &aResult->mRawNativeIMEContext) &&
ReadParam(aMsg, aIter, &aResult->mOriginProcessID);
}
};
template<>
struct ParamTraits<mozilla::widget::IMENotification::Point>
{
+16 -1
View File
@@ -103,7 +103,14 @@ typedef void* nsNativeWidget;
#define NS_NATIVE_SHAREABLE_WINDOW 11
#define NS_NATIVE_OPENGL_CONTEXT 12
// See RegisterPluginWindowForRemoteUpdates
#define NS_NATIVE_PLUGIN_ID 13
#define NS_NATIVE_PLUGIN_ID 13
// This is available only with GetNativeData() in parent process. Anybody
// shouldn't access this pointer as a valid pointer since the result may be
// special value like NS_ONLY_ONE_NATIVE_IME_CONTEXT. So, the result is just
// an identifier of distinguishing a text composition is caused by which native
// IME context. Note that the result is only valid in the process. So,
// XP code should use nsIWidget::GetNativeIMEContext() instead of using this.
#define NS_RAW_NATIVE_IME_CONTEXT 14
#ifdef XP_MACOSX
#define NS_NATIVE_PLUGIN_PORT_QD 100
#define NS_NATIVE_PLUGIN_PORT_CG 101
@@ -328,6 +335,7 @@ class nsIWidget : public nsISupports {
typedef mozilla::widget::IMEState IMEState;
typedef mozilla::widget::InputContext InputContext;
typedef mozilla::widget::InputContextAction InputContextAction;
typedef mozilla::widget::NativeIMEContext NativeIMEContext;
typedef mozilla::widget::SizeConstraints SizeConstraints;
typedef mozilla::widget::TextEventDispatcher TextEventDispatcher;
typedef mozilla::CompositorVsyncDispatcher CompositorVsyncDispatcher;
@@ -1763,6 +1771,13 @@ public:
*/
NS_IMETHOD_(InputContext) GetInputContext() = 0;
/**
* Get native IME context. This is different from GetNativeData() with
* NS_RAW_NATIVE_IME_CONTEXT, the result is unique even if in a remote
* process.
*/
NS_IMETHOD_(NativeIMEContext) GetNativeIMEContext();
/*
* Given a WidgetKeyboardEvent, this method synthesizes a corresponding
* native (OS-level) event for it. This method allows tests to simulate
+4 -4
View File
@@ -664,6 +664,10 @@ nsWindow::GetNativeData(uint32_t aDataType)
case NS_NATIVE_SHELLWIDGET: {
break;
}
case NS_RAW_NATIVE_IME_CONTEXT:
// Our qt widget looks like using only one context per process.
// However, it's better to set the context's pointer.
return qApp->inputMethod();
default:
NS_WARNING("nsWindow::GetNativeData called with bad value");
return nullptr;
@@ -716,10 +720,6 @@ NS_IMETHODIMP_(InputContext)
nsWindow::GetInputContext()
{
mInputContext.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
// Our qt widget looks like using only one context per process.
// However, it's better to set the context's pointer.
mInputContext.mNativeIMEContext = qApp->inputMethod();
return mInputContext;
}

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