-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlazy-image.php
133 lines (117 loc) · 4.03 KB
/
lazy-image.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<?php
namespace Grav\Plugin;
use Grav\Common\Plugin;
use RocketTheme\Toolbox\Event\Event;
use DiDom\Document;
/**
* Class LazyImagePlugin parses content for images and updates
* the attributes to support lazy loading. The frontend logic is
* provided by the https://github.com/tuupola/jquery_lazyload
* project.
*
* @package Grav\Plugin
*/
class LazyImagePlugin extends Plugin
{
/**
* @return array
*
* The getSubscribedEvents() gives the core a list of events
* that the plugin wants to listen to. The key of each
* array section is the event that the plugin listens to
* and the value (in the form of an array) contains the
* callable (or function) as well as the priority. The
* higher the number the higher the priority.
*/
public static function getSubscribedEvents()
{
return [
'onPluginsInitialized' => ['onPluginsInitialized', 0]
];
}
/**
* Initialize the plugin
*/
public function onPluginsInitialized()
{
// Don't proceed if we are in the admin plugin
if ($this->isAdmin()) {
return;
}
include __DIR__.'/vendor/autoload.php';
// Enable the main event we are interested in
$this->enable([
'onPageContentProcessed' => ['onPageContentProcessed', 0],
'onTwigSiteVariables' => ['onTwigSiteVariables', 0]
]);
}
/**
* Add the lazyload JS and add supporting code to initialize it.
*/
public function onTwigSiteVariables()
{
$assets = $this->grav['assets'];
$assets->addJs('plugin://lazy-image/vendor/lazyload.min.js');
// Get the class used to identify lazy-load images
$class_for_images = $this->grav['config']->get('plugins.lazy-image.lazy_img_class');
if($this->isValidClass($class_for_images))
{
$script = "// Grav Lazy Image Plugin - START\n";
$script .= "document.onreadystatechange = function() {\n";
$script .= " if(document.readyState == \"complete\") {\n";
$script .= " let lazyLoadImages = document.querySelectorAll(\".".$class_for_images."\");\n";
$script .= " lazyload(lazyLoadImages);\n";
$script .= " }\n";
$script .= "};\n";
$script .= "// Grav Lazy Image Plugin - END\n";
$assets->addInlineJs($script, $group="bottom");
}
}
/**
* Process the content and let the cache serve it again.
*
* @param Event $e
*/
public function onPageContentProcessed(Event $e)
{
$page = $e['page'];
$content = $this->updateImages($page->content());
$page->setRawContent($content);
}
/**
* Determines validity of user-specified CSS class.
*
* @param String $c
*/
protected function isValidClass($c = "")
{
$pattern = '/^[a-zA-Z0-9_\-]+$/';
return preg_match($pattern, $c);
}
protected function updateImages($content)
{
if(!is_string($content) || trim($content) === '')
{
return;
}
$class_for_images = $this->grav['config']->get('plugins.lazy-image.lazy_img_class');
if($this->isValidClass($class_for_images))
{
$document = new Document($content, false, 'UTF-8', 'html');
if (count($images = $document->find("img.".$class_for_images)) > 0) {
foreach ($images as $image) {
if(!$image->getAttribute("data-src")) {
$img_src = $image->getAttribute("src");
$img_srset = $image->getAttribute("srcset");
$image->setAttribute("data-src", $img_src);
$image->setAttribute("data-srcset", $img_srset);
$image->removeAttribute("src");
$image->removeAttribute("srcset");
}
}
return $document->html();
}
}
return $content;
}
}