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;
}
public static function onOutputPageBeforeHTML( &$out, &$text ) {
return true;
}
/**
* Lazyload images
* Modified from the Lazyload extension
* Looks for thumbnail and swap src to data-src
*/
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';
if (isset($attribs['srcset'])) {
$attribs['data-srcset'] = $attribs['srcset'];
unset($attribs['srcset']);
$file = $thumb->getFile();
if ( $file ) {
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;
}

View file

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

View file

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

View file

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