Added support for Native lazyloading API

This commit is contained in:
alistair3149 2019-08-15 18:31:54 -04:00
parent 36f6c94ec1
commit 9a6e12c3d8
4 changed files with 119 additions and 87 deletions

View file

@ -32,20 +32,38 @@ class CitizenHooks {
return true; return true;
} }
public static function onOutputPageBeforeHTML( &$out, &$text ) {
return true;
}
/** /**
* Lazyload images * Lazyload images
* Modified from the Lazyload extension * Modified from the Lazyload extension
* Looks for thumbnail and swap src to data-src
*/ */
public static function ThumbnailBeforeProduceHTML($thumb, &$attribs, &$linkAttribs) { public static function ThumbnailBeforeProduceHTML($thumb, &$attribs, &$linkAttribs) {
global $wgRequest, $wgTitle;
if (defined('MW_API') && $wgRequest->getVal('action') === 'parse') return true;
if (isset($wgTitle) && $wgTitle->getNamespace() === NS_FILE) return true;
$attribs['data-src'] = $attribs['src'];
$attribs['src'] = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'; $file = $thumb->getFile();
if (isset($attribs['srcset'])) {
$attribs['data-srcset'] = $attribs['srcset']; if ( $file ) {
unset($attribs['srcset']); global $wgRequest, $wgTitle;
if (defined('MW_API') && $wgRequest->getVal('action') === 'parse') return true;
if (isset($wgTitle) && $wgTitle->getNamespace() === NS_FILE) return true;
// Set lazy class for the img
$attribs['class'] = 'lazy';
// Native API
$attribs['loading'] = 'lazy';
$attribs['data-src'] = $attribs['src'];
$attribs['src'] = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
if (isset($attribs['srcset'])) {
$attribs['data-srcset'] = $attribs['srcset'];
unset($attribs['srcset']);
}
} }
return true; return true;
} }

View file

@ -5,25 +5,34 @@
* Lazyloading images with Native API or IntersectionObserver * Lazyloading images with Native API or IntersectionObserver
*/ */
// TODO: Implement Native API
// IntersectionObserver API // Native API
if( typeof IntersectionObserver !== "undefined" && "forEach" in NodeList.prototype ) { if ("loading" in HTMLImageElement.prototype) {
var observer = new IntersectionObserver(function(changes) { document.querySelectorAll("img.lazy").forEach(function(img) {
if ("connection" in navigator && navigator.connection.saveData === true) { img.setAttribute("src", img.getAttribute("data-src"));
return; if (img.hasAttribute("data-srcset")) {
img.setAttribute("srcset", img.getAttribute("data-srcset"));
} }
changes.forEach(function(change) { });
if(change.isIntersecting) { } else {
change.target.setAttribute("src", change.target.getAttribute("data-src")); // IntersectionObserver API
if(change.target.hasAttribute("data-srcset")) { if (typeof IntersectionObserver !== "undefined" && "forEach" in NodeList.prototype) {
change.target.setAttribute("srcset", change.target.getAttribute("data-srcset")); var observer = new IntersectionObserver(function(changes) {
} if ("connection" in navigator && navigator.connection.saveData === true) {
observer.unobserve(change.target); return;
} }
changes.forEach(function(change) {
if (change.isIntersecting) {
change.target.setAttribute("src", change.target.getAttribute("data-src"));
if (change.target.hasAttribute("data-srcset")) {
change.target.setAttribute("srcset", change.target.getAttribute("data-srcset"));
}
observer.unobserve(change.target);
}
});
}); });
}); document.querySelectorAll("img.lazy").forEach(function(img) {
document.querySelectorAll("img[data-src]").forEach(function(img) { observer.observe(img);
observer.observe(img); });
}); }
} }

View file

@ -216,6 +216,9 @@
"BeforePageDisplay": [ "BeforePageDisplay": [
"CitizenHooks::BeforePageDisplay" "CitizenHooks::BeforePageDisplay"
], ],
"onOutputPageBeforeHTML": [
"CitizenHooks::onOutputPageBeforeHTML"
],
"ThumbnailBeforeProduceHTML": [ "ThumbnailBeforeProduceHTML": [
"CitizenHooks::ThumbnailBeforeProduceHTML" "CitizenHooks::ThumbnailBeforeProduceHTML"
] ]

View file

@ -7,103 +7,105 @@
@import '../resources/mixins.less'; @import '../resources/mixins.less';
.mw-pt-languages { .mw-pt-languages {
display: block; display: block;
border: 0; border: 0;
background: 0; width: auto;
margin: 0 @negative-margin; background: 0;
padding: @margin-side; margin: 0 @negative-margin;
padding: @margin-side;
} }
.mw-pt-languages-label { .mw-pt-languages-label {
display: block; display: block;
border: 0; border: 0;
padding: 0; padding: 0;
color: @base-30; color: @base-30;
background: 0; background: 0;
font-size: 0.8125rem; font-size: 0.8125rem;
font-weight: normal; font-weight: normal;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 1px; letter-spacing: 1px;
width: auto; width: auto;
} }
.mw-pt-languages-list { .mw-pt-languages-list {
padding: @content-margin-top 0 0 0; padding: @content-margin-top 0 0 0;
display: flex; display: flex;
width: auto; width: auto;
visibility: hidden; // Hide dots visibility: hidden; // Hide dots
> * { >* {
visibility: visible; visibility: visible;
} }
} }
.mw-pt-languages-selected, .mw-pt-languages-selected,
.mw-pt-languages-ui { .mw-pt-languages-ui {
font-weight: 400; font-weight: 400;
.boxshadow(2)!important; .boxshadow(2) !important;
&:hover { &:hover {
transform: none!important; transform: none !important;
} }
} }
.mw-pt-progress { .mw-pt-progress {
margin: 0 0 @margin-side / 2 0; margin: 0 0 @margin-side / 2 0;
padding: @margin-side / 4 @margin-side / 2; padding: @margin-side / 4 @margin-side / 2;
display: block; display: block;
border: 1px solid @base-90; border: 1px solid @base-90;
background: @base-90; background: @base-90;
color: @base-30; color: @base-30;
font-size: @content-caption-size; font-size: @content-caption-size;
.boxshadow(1); .boxshadow(1);
transition: @transition-transform-quick, transition: @transition-transform-quick,
@transition-box-shadow-quick; @transition-box-shadow-quick;
&:hover { &:hover {
.boxshadow(2); .boxshadow(2);
transform: translateY(-2px); transform: translateY(-2px);
} }
} }
.mw-pt-progress--stub { .mw-pt-progress--stub {
background: @base-90; background: @base-90;
} }
.mw-pt-progress--low { .mw-pt-progress--low {
background: @red-50; background: @red-50;
border-color: @red-50;; border-color: @red-50;
color: @base-100; ;
color: @base-100;
} }
.mw-pt-progress--med { .mw-pt-progress--med {
background: @yellow-50; background: @yellow-50;
border-color: @yellow-50; border-color: @yellow-50;
color: @base-100; color: @base-100;
} }
.mw-pt-progress--high { .mw-pt-progress--high {
background: @green-50; background: @green-50;
border-color: @green-50; border-color: @green-50;
color: @base-100; color: @base-100;
} }
.mw-pt-progress--complete { .mw-pt-progress--complete {
background: @green-30; background: @green-30;
border-color: @green-30; border-color: @green-30;
color: @base-100; color: @base-100;
} }
@media only screen and (max-width: @screen1) { @media only screen and (max-width: @screen1) {
.mw-pt-languages { .mw-pt-languages {
margin: 0!important; // somehow got overrided margin: 0 !important; // somehow got overrided
padding: @margin-side 0; padding: @margin-side 0;
} }
} }
@media only screen and (max-width: @screen2) { @media only screen and (max-width: @screen2) {
.mw-pt-languages { .mw-pt-languages {
margin: 0 ~"calc((100vw - @{page-width}) / -2)"; margin: 0~"calc((100vw - @{page-width}) / -2)";
} }
} }