зеркало из https://github.com/mozilla/gecko-dev.git
179 строки
4.1 KiB
C++
179 строки
4.1 KiB
C++
#include "Mutations.h"
|
|
#include "mozilla/dom/DocumentInlines.h"
|
|
|
|
namespace mozilla {
|
|
namespace dom {
|
|
namespace l10n {
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_CLASS(Mutations)
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(Mutations)
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingElements)
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mPendingElementsHash)
|
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(Mutations)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingElements)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPendingElementsHash)
|
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
|
|
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(Mutations)
|
|
NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
|
|
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
|
NS_INTERFACE_MAP_END
|
|
|
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(Mutations)
|
|
NS_IMPL_CYCLE_COLLECTING_RELEASE(Mutations)
|
|
|
|
Mutations::Mutations(DocumentL10n* aDocumentL10n)
|
|
: mDocumentL10n(aDocumentL10n) {
|
|
mObserving = true;
|
|
}
|
|
|
|
void Mutations::AttributeChanged(dom::Element* aElement, int32_t aNameSpaceID,
|
|
nsAtom* aAttribute, int32_t aModType,
|
|
const nsAttrValue* aOldValue) {
|
|
if (!mObserving) {
|
|
return;
|
|
}
|
|
Document* uncomposedDoc = aElement->GetUncomposedDoc();
|
|
if (uncomposedDoc) {
|
|
if (aNameSpaceID == kNameSpaceID_None &&
|
|
(aAttribute == nsGkAtoms::datal10nid ||
|
|
aAttribute == nsGkAtoms::datal10nargs)) {
|
|
L10nElementChanged(aElement);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Mutations::ContentAppended(nsIContent* aChild) {
|
|
if (!mObserving) {
|
|
return;
|
|
}
|
|
ErrorResult rv;
|
|
Sequence<OwningNonNull<Element>> elements;
|
|
|
|
nsINode* node = aChild;
|
|
while (node) {
|
|
if (node->IsElement()) {
|
|
Element* elem = node->AsElement();
|
|
|
|
Document* uncomposedDoc = elem->GetUncomposedDoc();
|
|
if (uncomposedDoc) {
|
|
mDocumentL10n->GetTranslatables(*node, elements, rv);
|
|
}
|
|
}
|
|
|
|
node = node->GetNextSibling();
|
|
}
|
|
|
|
for (auto& elem : elements) {
|
|
L10nElementChanged(elem);
|
|
}
|
|
}
|
|
|
|
void Mutations::ContentInserted(nsIContent* aChild) {
|
|
if (!mObserving) {
|
|
return;
|
|
}
|
|
ErrorResult rv;
|
|
Sequence<OwningNonNull<Element>> elements;
|
|
|
|
if (!aChild->IsElement()) {
|
|
return;
|
|
}
|
|
Element* elem = aChild->AsElement();
|
|
|
|
Document* uncomposedDoc = elem->GetUncomposedDoc();
|
|
if (!uncomposedDoc) {
|
|
return;
|
|
}
|
|
mDocumentL10n->GetTranslatables(*aChild, elements, rv);
|
|
|
|
for (auto& elem : elements) {
|
|
L10nElementChanged(elem);
|
|
}
|
|
}
|
|
|
|
void Mutations::L10nElementChanged(Element* aElement) {
|
|
if (!mPendingElementsHash.Contains(aElement)) {
|
|
mPendingElements.AppendElement(aElement);
|
|
mPendingElementsHash.PutEntry(aElement);
|
|
}
|
|
|
|
if (!mRefreshObserver) {
|
|
StartRefreshObserver();
|
|
}
|
|
}
|
|
|
|
void Mutations::PauseObserving() { mObserving = false; }
|
|
|
|
void Mutations::ResumeObserving() { mObserving = true; }
|
|
|
|
void Mutations::WillRefresh(mozilla::TimeStamp aTime) {
|
|
StopRefreshObserver();
|
|
FlushPendingTranslations();
|
|
}
|
|
|
|
void Mutations::FlushPendingTranslations() {
|
|
if (!mDocumentL10n) {
|
|
return;
|
|
}
|
|
|
|
ErrorResult rv;
|
|
|
|
Sequence<OwningNonNull<Element>> elements;
|
|
|
|
for (auto& elem : mPendingElements) {
|
|
if (!elem->HasAttr(kNameSpaceID_None, nsGkAtoms::datal10nid)) {
|
|
continue;
|
|
}
|
|
|
|
elements.AppendElement(*elem, fallible);
|
|
}
|
|
|
|
mPendingElementsHash.Clear();
|
|
mPendingElements.Clear();
|
|
|
|
RefPtr<Promise> promise = mDocumentL10n->TranslateElements(elements, rv);
|
|
}
|
|
|
|
void Mutations::Disconnect() {
|
|
StopRefreshObserver();
|
|
mDocumentL10n = nullptr;
|
|
}
|
|
|
|
void Mutations::StartRefreshObserver() {
|
|
if (!mDocumentL10n) {
|
|
return;
|
|
}
|
|
|
|
if (!mRefreshDriver) {
|
|
nsPresContext* ctx = mDocumentL10n->GetDocument()->GetPresContext();
|
|
if (!ctx) {
|
|
return;
|
|
}
|
|
mRefreshDriver = ctx->RefreshDriver();
|
|
}
|
|
|
|
if (mRefreshDriver) {
|
|
mRefreshDriver->AddRefreshObserver(this, FlushType::Style);
|
|
mRefreshObserver = true;
|
|
}
|
|
}
|
|
|
|
void Mutations::StopRefreshObserver() {
|
|
if (!mDocumentL10n) {
|
|
return;
|
|
}
|
|
|
|
if (mRefreshDriver) {
|
|
mRefreshDriver->RemoveRefreshObserver(this, FlushType::Style);
|
|
mRefreshObserver = false;
|
|
}
|
|
}
|
|
|
|
} // namespace l10n
|
|
} // namespace dom
|
|
} // namespace mozilla
|