@parksb/markdown-it-image-lazy-loading 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,69 @@
1
+ A markdown-it plugin supporting Chrome 75's [native image lazy-loading](https://addyosmani.com/blog/lazy-loading/) and [async decoding](https://github.com/whatwg/html/pull/3221).
2
+
3
+ ## Install
4
+
5
+ ```bash
6
+ $ npm install markdown-it-image-lazy-loading
7
+ ```
8
+
9
+ ## Usage
10
+
11
+ Load it in ES module.
12
+
13
+ ```javascript
14
+ import markdownit from 'markdown-it';
15
+ import lazy_loading from 'markdown-it-image-lazy-loading';
16
+
17
+ const md = markdownit();
18
+ md.use(lazy_loading);
19
+ md.render(`![](example.png "image title")`);
20
+ // <p><img src="example.png" alt="" title="image title" loading="lazy"></p>\n
21
+ ```
22
+
23
+ Or load it in CommonJS module.
24
+
25
+ ```javascript
26
+ const md = require('markdown-it')();
27
+ const lazy_loading = require('markdown-it-image-lazy-loading');
28
+ md.use(lazy_loading);
29
+
30
+ md.render(`![](example.png "image title")`);
31
+ // <p><img src="example.png" alt="" title="image title" loading="lazy"></p>\n
32
+ ```
33
+
34
+ If you want the `decoding="async"` attribute, enable the plugin's `decoding` option.
35
+
36
+ ```javascript
37
+ md.use(lazy_loading, {
38
+ decoding: true,
39
+ });
40
+
41
+ md.render(`![](example.png "image title")`);
42
+ // <p><img src="example.png" alt="" title="image title" loading="lazy" decoding="async"></p>\n
43
+ ```
44
+
45
+ The plugin can also add `width` and `height` attributes to each image. This can prevent [cumulative layout shifts (CLS)](https://web.dev/cls/):
46
+
47
+ ```javascript
48
+ md.use(lazy_loading, {
49
+ image_size: true,
50
+
51
+ // Where your images are stored
52
+ base_path: __dirname + 'src/',
53
+ });
54
+
55
+ md.render(`![](example.png "image title")`);
56
+ // <p><img src="example.png" alt="" title="image title" loading="lazy" width="100" height="100"></p>\n
57
+ ```
58
+
59
+ To keep images responsive, also include the following CSS:
60
+ ```css
61
+ img{
62
+ max-width: 100%;
63
+ height: auto;
64
+ }
65
+ ```
66
+
67
+ ## License
68
+
69
+ MIT
package/index.js ADDED
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+
3
+ var imageSize = require('image-size');
4
+ var path = require('node:path');
5
+
6
+ function lazy_loading_plugin(md, mdOptions) {
7
+ var defaultImageRenderer = md.renderer.rules.image;
8
+ var count = 0;
9
+
10
+ var skipCount = mdOptions && mdOptions.skip_count !== undefined ? mdOptions.skip_count : 0;
11
+ var excludeExtensions = mdOptions && mdOptions.exclude_extensions || [];
12
+ var maxWidth = mdOptions && mdOptions.max_width !== undefined ? mdOptions.max_width : null;
13
+
14
+ md.renderer.rules.image = function (tokens, idx, options, env, self) {
15
+ var token = tokens[idx];
16
+ if (count >= skipCount) {
17
+ token.attrSet('loading', 'lazy');
18
+ }
19
+
20
+ if (mdOptions && mdOptions.decoding === true) {
21
+ token.attrSet('decoding', 'async');
22
+ }
23
+
24
+ if (mdOptions && mdOptions.base_path && mdOptions.image_size === true) {
25
+ const imgSrc = token.attrGet('src');
26
+
27
+ const imgExt = path.extname(imgSrc);
28
+ if (excludeExtensions.includes(imgExt)) {
29
+ return defaultImageRenderer(tokens, idx, options, env, self);
30
+ }
31
+
32
+ const imgPath = path.join(mdOptions.base_path, imgSrc);
33
+ const dimensions = imageSize(imgPath);
34
+
35
+ if (maxWidth !== null && dimensions.width > maxWidth) {
36
+ dimensions.height = Math.round(dimensions.height * (maxWidth / dimensions.width));
37
+ dimensions.width = maxWidth;
38
+ }
39
+
40
+ token.attrSet('width', dimensions.width);
41
+ token.attrSet('height', dimensions.height);
42
+ }
43
+
44
+ count += 1;
45
+
46
+ return defaultImageRenderer(tokens, idx, options, env, self);
47
+ };
48
+ }
49
+
50
+ module.exports = lazy_loading_plugin;
package/index.mjs ADDED
@@ -0,0 +1,48 @@
1
+ import imageSize from 'image-size';
2
+ import path from 'node:path';
3
+
4
+ function lazy_loading_plugin(md, mdOptions) {
5
+ var defaultImageRenderer = md.renderer.rules.image;
6
+ var count = 0;
7
+
8
+ var skipCount = mdOptions && mdOptions.skip_count !== undefined ? mdOptions.skip_count : 0;
9
+ var excludeExtensions = mdOptions && mdOptions.exclude_extensions || [];
10
+ var maxWidth = mdOptions && mdOptions.max_width !== undefined ? mdOptions.max_width : null;
11
+
12
+ md.renderer.rules.image = function (tokens, idx, options, env, self) {
13
+ var token = tokens[idx];
14
+ if (count >= skipCount) {
15
+ token.attrSet('loading', 'lazy');
16
+ }
17
+
18
+ if (mdOptions && mdOptions.decoding === true) {
19
+ token.attrSet('decoding', 'async');
20
+ }
21
+
22
+ if (mdOptions && mdOptions.base_path && mdOptions.image_size === true) {
23
+ const imgSrc = token.attrGet('src');
24
+
25
+ const imgExt = path.extname(imgSrc);
26
+ if (excludeExtensions.includes(imgExt)) {
27
+ return defaultImageRenderer(tokens, idx, options, env, self);
28
+ }
29
+
30
+ const imgPath = path.join(mdOptions.base_path, imgSrc);
31
+ const dimensions = imageSize(imgPath);
32
+
33
+ if (maxWidth !== null && dimensions.width > maxWidth) {
34
+ dimensions.height = Math.round(dimensions.height * (maxWidth / dimensions.width));
35
+ dimensions.width = maxWidth;
36
+ }
37
+
38
+ token.attrSet('width', dimensions.width);
39
+ token.attrSet('height', dimensions.height);
40
+ }
41
+
42
+ count += 1;
43
+
44
+ return defaultImageRenderer(tokens, idx, options, env, self);
45
+ };
46
+ };
47
+
48
+ export default lazy_loading_plugin;
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@parksb/markdown-it-image-lazy-loading",
3
+ "version": "2.0.2",
4
+ "description": "a markdown-it plugin supporting Chrome 75's native image lazy-loading",
5
+ "main": "index.js",
6
+ "exports": {
7
+ ".": {
8
+ "import": "./index.mjs",
9
+ "require": "./index.js"
10
+ }
11
+ },
12
+ "scripts": {
13
+ "build": "rollup --config rollup.config.mjs",
14
+ "test": "npm run build && npx tape test/*.js",
15
+ "prepublishOnly": "npm run build"
16
+ },
17
+ "keywords": [
18
+ "markdown-it-plugin",
19
+ "markdown-it",
20
+ "lazyload"
21
+ ],
22
+ "author": "parksb <parkgds@gmail.com>",
23
+ "homepage": "https://github.com/parksb/markdown-it-image-lazy-loading",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/parksb/markdown-it-image-lazy-loading.git"
27
+ },
28
+ "license": "MIT",
29
+ "dependencies": {
30
+ "image-size": "^1.0.0"
31
+ },
32
+ "devDependencies": {
33
+ "markdown-it": "^14.0.0",
34
+ "rollup": "^4.9.1",
35
+ "tape": "^5.3.2"
36
+ }
37
+ }
@@ -0,0 +1,8 @@
1
+ export default {
2
+ input: 'index.mjs',
3
+ output: {
4
+ file: 'index.js',
5
+ format: 'cjs'
6
+ },
7
+ external: ['image-size', 'node:path']
8
+ };