Bug 1455649 - DocumentL10n, part 2 - Extend nsIDocument to use DocumentL10n. r=smaug

--HG--
extra : rebase_source : d6dbe9fb0090716cf180e2d96c70d12cc467eb1f
This commit is contained in:
Zibi Braniecki 2018-09-06 18:26:18 -07:00
parent 431a5526d8
commit d105ed85e4
4 changed files with 185 additions and 0 deletions

View File

@ -211,6 +211,7 @@
#include "mozilla/dom/ClientInfo.h"
#include "mozilla/dom/ClientState.h"
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/DocumentL10n.h"
#include "mozilla/dom/DocumentTimeline.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/HTMLBodyElement.h"
@ -1885,6 +1886,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDisplayDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFontFaceSet)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mReadyForIdle)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentL10n)
// Traverse all nsDocument nsCOMPtrs.
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParser)
@ -2031,6 +2033,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFontFaceSet)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mReadyForIdle);
NS_IMPL_CYCLE_COLLECTION_UNLINK(mCommandDispatcher)
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocumentL10n);
tmp->mParentDocument = nullptr;
@ -2229,6 +2232,23 @@ nsIDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup)
mChannel = aChannel;
}
/**
* DocumentL10n is currently allowed for system
* principal.
*
* In the future we'll want to expose it to non-web-exposed
* about:* pages.
*/
bool
PrincipalAllowsL10n(nsIPrincipal* principal)
{
if (nsContentUtils::IsSystemPrincipal(principal)) {
return true;
}
return false;
}
void
nsIDocument::ResetToURI(nsIURI* aURI,
nsILoadGroup* aLoadGroup,
@ -3303,6 +3323,102 @@ nsIDocument::GetAllowPlugins()
return true;
}
void
nsIDocument::InitializeLocalization(nsTArray<nsString>& aResourceIds)
{
MOZ_ASSERT(!mDocumentL10n, "mDocumentL10n should not be initialized yet");
DocumentL10n* l10n = new DocumentL10n(this);
MOZ_ALWAYS_TRUE(l10n->Init(aResourceIds));
mDocumentL10n = l10n;
}
DocumentL10n*
nsIDocument::GetL10n()
{
return mDocumentL10n;
}
bool
nsDocument::DocumentSupportsL10n(JSContext* aCx, JSObject* aObject)
{
return PrincipalAllowsL10n(nsContentUtils::SubjectPrincipal(aCx));
}
void
nsIDocument::LocalizationLinkAdded(Element* aLinkElement)
{
if (!PrincipalAllowsL10n(NodePrincipal())) {
return;
}
nsAutoString href;
aLinkElement->GetAttr(kNameSpaceID_None, nsGkAtoms::href, href);
// If the link is added after the DocumentL10n instance
// has been initialized, just pass the resource ID to it.
if (mDocumentL10n) {
AutoTArray<nsString, 1> resourceIds;
resourceIds.AppendElement(href);
mDocumentL10n->AddResourceIds(resourceIds);
} else {
// Otherwise, we're still parsing the document.
// In that case, add it to the pending list. This list
// will be resolved once the end of l10n resource
// container is reached.
mL10nResources.AppendElement(href);
}
}
void
nsIDocument::LocalizationLinkRemoved(Element* aLinkElement)
{
if (!PrincipalAllowsL10n(NodePrincipal())) {
return;
}
nsAutoString href;
aLinkElement->GetAttr(kNameSpaceID_None, nsGkAtoms::href, href);
if (mDocumentL10n) {
AutoTArray<nsString, 1> resourceIds;
resourceIds.AppendElement(href);
uint32_t remaining = mDocumentL10n->RemoveResourceIds(resourceIds);
if (remaining == 0) {
mDocumentL10n = nullptr;
}
} else {
mL10nResources.RemoveElement(href);
}
}
/**
* This method should be called once the end of the l10n
* resource container has been parsed.
*
* In XUL this is the end of the first </linkset>,
* In XHTML/HTML this is the end of </head>.
*
* This milestone is used to allow for batch
* localization context I/O and building done
* once when all resources in the document have been
* collected.
*/
void
nsIDocument::OnL10nResourceContainerParsed()
{
if (!mL10nResources.IsEmpty()) {
InitializeLocalization(mL10nResources);
mL10nResources.Clear();
}
}
void
nsIDocument::TriggerInitialDocumentTranslation()
{
if (mDocumentL10n) {
mDocumentL10n->TriggerInitialDocumentTranslation();
}
}
bool
nsDocument::IsWebAnimationsEnabled(JSContext* aCx, JSObject* /*unused*/)
{

View File

@ -158,6 +158,7 @@ public:
virtual void StopDocumentLoad() override;
static bool DocumentSupportsL10n(JSContext* aCx, JSObject* aObject);
static bool IsWebAnimationsEnabled(JSContext* aCx, JSObject* aObject);
static bool IsWebAnimationsEnabled(mozilla::dom::CallerType aCallerType);
static bool IsWebAnimationsGetAnimationsEnabled(JSContext* aCx,

View File

@ -147,6 +147,7 @@ class CDATASection;
class Comment;
struct CustomElementDefinition;
class DocGroup;
class DocumentL10n;
class DocumentFragment;
class DocumentTimeline;
class DocumentType;
@ -3562,6 +3563,69 @@ public:
// For more information on Flash classification, see
// toolkit/components/url-classifier/flash-block-lists.rst
mozilla::dom::FlashClassification DocumentFlashClassification();
/**
* Localization
*
* For more information on DocumentL10n see
* intl/l10n/docs/fluent_tutorial.rst
*/
public:
/**
* This is a public method exposed on Document WebIDL
* to chrome only documents.
*/
mozilla::dom::DocumentL10n* GetL10n();
/**
* This method should be called when the container
* of l10n resources parsing is completed.
*
* It triggers initial async fetch of the resources
* as early as possible.
*
* In HTML case this is </head>.
* In XUL case this is </linkset>.
*/
void OnL10nResourceContainerParsed();
/**
* This method should be called when a link element
* with rel="localization" is being added to the
* l10n resource container element.
*/
void LocalizationLinkAdded(Element* aLinkElement);
/**
* This method should be called when a link element
* with rel="localization" is being removed.
*/
void LocalizationLinkRemoved(Element* aLinkElement);
protected:
/**
* This method should be collect as soon as the
* parsing of the document is completed.
*
* In HTML this happens when readyState becomes
* `interactive`.
* In XUL it happens at `DoneWalking`, during
* `MozBeforeInitialXULLayout`.
*
* It triggers the initial translation of the
* document.
*/
void TriggerInitialDocumentTranslation();
RefPtr<mozilla::dom::DocumentL10n> mDocumentL10n;
private:
void InitializeLocalization(nsTArray<nsString>& aResourceIds);
nsTArray<nsString> mL10nResources;
public:
bool IsThirdParty();
bool IsScopedStyleEnabled();

View File

@ -525,6 +525,10 @@ partial interface Document {
[ChromeOnly] readonly attribute unsigned long numTrackersBlocked;
};
partial interface Document {
[Func="nsDocument::DocumentSupportsL10n"] readonly attribute DocumentL10n? l10n;
};
Document implements XPathEvaluator;
Document implements GlobalEventHandlers;
Document implements DocumentAndElementEventHandlers;