diff --git a/dom/base/DOMIntersectionObserver.cpp b/dom/base/DOMIntersectionObserver.cpp index 478c11eccd53..3bf9eba0f428 100644 --- a/dom/base/DOMIntersectionObserver.cpp +++ b/dom/base/DOMIntersectionObserver.cpp @@ -10,6 +10,7 @@ #include "nsContentUtils.h" #include "nsLayoutUtils.h" #include "mozilla/PresShell.h" +#include "mozilla/StaticPrefs_dom.h" #include "mozilla/ServoBindings.h" #include "mozilla/dom/BrowserChild.h" #include "mozilla/dom/BrowsingContext.h" @@ -121,22 +122,39 @@ already_AddRefed DOMIntersectionObserver::Constructor( return observer.forget(); } +static void LazyLoadCallback( + const Sequence>& aEntries) { + for (const auto& entry : aEntries) { + MOZ_ASSERT(entry->Target()->IsHTMLElement(nsGkAtoms::img)); + if (entry->IsIntersecting()) { + static_cast(entry->Target()) + ->StopLazyLoadingAndStartLoadIfNeeded(); + } + } +} + +static LengthPercentage PrefMargin(float aValue, bool aIsPercentage) { + return aIsPercentage ? LengthPercentage::FromPercentage(aValue / 100.0f) + : LengthPercentage::FromPixels(aValue); +} + already_AddRefed DOMIntersectionObserver::CreateLazyLoadObserver(nsPIDOMWindowInner* aOwner) { - RefPtr observer = new DOMIntersectionObserver( - aOwner, - [](const Sequence>& entries) { - for (const auto& entry : entries) { - MOZ_ASSERT(entry->Target()->IsHTMLElement(nsGkAtoms::img)); - if (entry->IsIntersecting()) { - static_cast(entry->Target()) - ->StopLazyLoadingAndStartLoadIfNeeded(); - } - } - }); - + RefPtr observer = + new DOMIntersectionObserver(aOwner, LazyLoadCallback); observer->mThresholds.AppendElement(std::numeric_limits::min()); +#define SET_MARGIN(side_, side_lower_) \ + observer->mRootMargin.Get(eSide##side_) = PrefMargin( \ + StaticPrefs::dom_image_lazy_loading_root_margin_##side_lower_(), \ + StaticPrefs:: \ + dom_image_lazy_loading_root_margin_##side_lower_##_percentage()); + SET_MARGIN(Top, top); + SET_MARGIN(Right, right); + SET_MARGIN(Bottom, bottom); + SET_MARGIN(Left, left); +#undef SET_MARGIN + return observer.forget(); } diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml index 442ba1a5565a..4bd7083b96ea 100644 --- a/modules/libpref/init/StaticPrefList.yaml +++ b/modules/libpref/init/StaticPrefList.yaml @@ -1666,6 +1666,51 @@ value: true mirror: always +# The root margin for image lazy loading, defined as four (value, percentage) +# pairs. +# +# (0px, 0px, 0px, 0px) by default, for now. We could also consider an +# adaptative version of this. +- name: dom.image-lazy-loading.root-margin.top + type: float + value: 0 + mirror: always + +- name: dom.image-lazy-loading.root-margin.top.percentage + type: bool + value: false + mirror: always + +- name: dom.image-lazy-loading.root-margin.bottom + type: float + value: 0 + mirror: always + +- name: dom.image-lazy-loading.root-margin.bottom.percentage + type: bool + value: false + mirror: always + +- name: dom.image-lazy-loading.root-margin.left + type: float + value: 0 + mirror: always + +- name: dom.image-lazy-loading.root-margin.left.percentage + type: bool + value: false + mirror: always + +- name: dom.image-lazy-loading.root-margin.right + type: float + value: 0 + mirror: always + +- name: dom.image-lazy-loading.root-margin.right.percentage + type: bool + value: false + mirror: always + # Enable passing the "storage" option to indexedDB.open. - name: dom.indexedDB.storageOption.enabled type: RelaxedAtomicBool