markmap-autoloader 0.15.0-alpha.0 → 0.15.0

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.
Files changed (3) hide show
  1. package/README.md +33 -28
  2. package/dist/index.js +290 -49
  3. package/package.json +8 -7
package/README.md CHANGED
@@ -12,18 +12,23 @@ HTML:
12
12
 
13
13
  ```html
14
14
  <style>
15
- .markmap > svg {
16
- width: 100%;
17
- height: 300px;
18
- }
15
+ .markmap {
16
+ position: relative;
17
+ }
18
+ .markmap > svg {
19
+ width: 100%;
20
+ height: 300px;
21
+ }
19
22
  </style>
20
23
 
21
- <div class="markmap"><script type="text/template">
22
- - markmap
23
- - autoloader
24
- - transformer
25
- - view
26
- </script></div>
24
+ <div class="markmap">
25
+ <script type="text/template">
26
+ - markmap
27
+ - autoloader
28
+ - transformer
29
+ - view
30
+ </script>
31
+ </div>
27
32
  ```
28
33
 
29
34
  Note that `<script type="text/template">` is optional, for the content inside to be invisible before the markmap is rendered.
@@ -44,16 +49,16 @@ Load manually:
44
49
 
45
50
  ```html
46
51
  <script>
47
- window.markmap = {
48
- autoLoader: { manual: true },
49
- };
52
+ window.markmap = {
53
+ autoLoader: { manual: true },
54
+ };
50
55
  </script>
51
56
  <script src="https://cdn.jsdelivr.net/npm/markmap-autoloader"></script>
52
57
  <script>
53
- // Render in 5s
54
- setTimeout(() => {
55
- markmap.autoLoader.renderAll();
56
- }, 5000);
58
+ // Render in 5s
59
+ setTimeout(() => {
60
+ markmap.autoLoader.renderAll();
61
+ }, 5000);
57
62
  </script>
58
63
  ```
59
64
 
@@ -61,11 +66,11 @@ Disable built-in plugins:
61
66
 
62
67
  ```html
63
68
  <script>
64
- window.markmap = {
65
- autoLoader: {
66
- transformPlugins: [],
67
- },
68
- };
69
+ window.markmap = {
70
+ autoLoader: {
71
+ transformPlugins: [],
72
+ },
73
+ };
69
74
  </script>
70
75
  <script src="https://cdn.jsdelivr.net/npm/markmap-autoloader"></script>
71
76
  ```
@@ -76,17 +81,17 @@ window.markmap = {
76
81
 
77
82
  If `window.markmap.autoLoader` is defined before this package is loaded, it will be regarded as autoLoader options.
78
83
 
79
- - `autoLoader.manual` *boolean* default as `false`
84
+ - `autoLoader.manual` _boolean_ default as `false`
80
85
 
81
- Whether to render markmaps manually. If false, all elements matching `.markmap` will be rendered once this package loads or DOMContentLoaded is emitted, whichever later.
86
+ Whether to render markmaps manually. If false, all elements matching `.markmap` will be rendered once this package loads or DOMContentLoaded is emitted, whichever later.
82
87
 
83
- - `autoLoader.transformPlugins` *ITransformPlugin[]*
88
+ - `autoLoader.transformPlugins` _ITransformPlugin[]_
84
89
 
85
- Override built-in plugins if provided. Set to `[]` to disable all built-in plugins for auto-loader.
90
+ Override built-in plugins if provided. Set to `[]` to disable all built-in plugins for auto-loader.
86
91
 
87
- - `autoLoader.onReady` *function*
92
+ - `autoLoader.onReady` _function_
88
93
 
89
- Callback when markmap-lib/markmap-view and their dependencies are loaded. We can tweak global options in this callback.
94
+ Callback when markmap-lib/markmap-view and their dependencies are loaded. We can tweak global options in this callback.
90
95
 
91
96
  ### markmap.autoLoader.renderAll()
92
97
 
package/dist/index.js CHANGED
@@ -1,9 +1,24 @@
1
- /*! markmap-autoloader v0.15.0-alpha.0 | MIT License */
1
+ /*! markmap-autoloader v0.15.0 | MIT License */
2
2
  this.markmap = this.markmap || {};
3
3
  (function (exports) {
4
4
  'use strict';
5
5
 
6
- /*! markmap-common v0.15.0-alpha.0 | MIT License */
6
+ function _extends$1() {
7
+ _extends$1 = Object.assign ? Object.assign.bind() : function (target) {
8
+ for (var i = 1; i < arguments.length; i++) {
9
+ var source = arguments[i];
10
+ for (var key in source) {
11
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
12
+ target[key] = source[key];
13
+ }
14
+ }
15
+ }
16
+ return target;
17
+ };
18
+ return _extends$1.apply(this, arguments);
19
+ }
20
+
21
+ /*! markmap-common v0.15.0 | MIT License */
7
22
  function _extends() {
8
23
  _extends = Object.assign ? Object.assign.bind() : function (target) {
9
24
  for (var i = 1; i < arguments.length; i++) {
@@ -18,6 +33,49 @@ function _extends() {
18
33
  };
19
34
  return _extends.apply(this, arguments);
20
35
  }
36
+ const testPath = "npm2url/dist/index.cjs";
37
+ const defaultProviders = {
38
+ jsdelivr: path => `https://cdn.jsdelivr.net/npm/${path}`,
39
+ unpkg: path => `https://unpkg.com/${path}`
40
+ };
41
+ class UrlBuilder {
42
+ constructor() {
43
+ this.providers = _extends({}, defaultProviders);
44
+ this.provider = "jsdelivr";
45
+ }
46
+ getFastestProvider(path = testPath) {
47
+ return Promise.any(Object.entries(this.providers).map(async ([name, factory]) => {
48
+ const res = await fetch(factory(path));
49
+ if (!res.ok) {
50
+ throw res;
51
+ }
52
+ await res.text();
53
+ return name;
54
+ }));
55
+ }
56
+ async findFastestProvider() {
57
+ this.provider = await this.getFastestProvider();
58
+ return this.provider;
59
+ }
60
+ setProvider(name, factory) {
61
+ if (factory) {
62
+ this.providers[name] = factory;
63
+ } else {
64
+ delete this.providers[name];
65
+ }
66
+ }
67
+ getFullUrl(path, provider = this.provider) {
68
+ if (path.includes("://")) {
69
+ return path;
70
+ }
71
+ const factory = this.providers[provider];
72
+ if (!factory) {
73
+ throw new Error(`Provider ${provider} not found`);
74
+ }
75
+ return factory(path);
76
+ }
77
+ }
78
+ const urlBuilder = new UrlBuilder();
21
79
  Math.random().toString(36).slice(2, 8);
22
80
  function memoize(fn) {
23
81
  const cache = {};
@@ -33,52 +91,189 @@ function memoize(fn) {
33
91
  return data.value;
34
92
  };
35
93
  }
36
- const providers = {
37
- jsdelivr: path => `https://cdn.jsdelivr.net/npm/${path}`,
38
- unpkg: path => `https://unpkg.com/${path}`
94
+
95
+ /*! @gera2ld/jsx-dom v2.2.2 | ISC License */
96
+ const VTYPE_ELEMENT = 1;
97
+ const VTYPE_FUNCTION = 2;
98
+ const SVG_NS = 'http://www.w3.org/2000/svg';
99
+ const XLINK_NS = 'http://www.w3.org/1999/xlink';
100
+ const NS_ATTRS = {
101
+ show: XLINK_NS,
102
+ actuate: XLINK_NS,
103
+ href: XLINK_NS
39
104
  };
40
- function cdnUrl(provider, path) {
41
- const factory = providers[provider];
42
- if (!factory) {
43
- throw new Error(`Provider ${provider} not found`);
44
- }
45
- return factory(path);
46
- }
47
- function createElement(tagName, props, attrs) {
48
- const el = document.createElement(tagName);
49
- if (props) {
50
- Object.entries(props).forEach(([key, value]) => {
51
- el[key] = value;
52
- });
105
+ const isLeaf = c => typeof c === 'string' || typeof c === 'number';
106
+ const isElement = c => (c == null ? void 0 : c.vtype) === VTYPE_ELEMENT;
107
+ const isRenderFunction = c => (c == null ? void 0 : c.vtype) === VTYPE_FUNCTION;
108
+ function h(type, props, ...children) {
109
+ props = Object.assign({}, props, {
110
+ children: children.length === 1 ? children[0] : children
111
+ });
112
+ return jsx(type, props);
113
+ }
114
+ function jsx(type, props) {
115
+ let vtype;
116
+ if (typeof type === 'string') vtype = VTYPE_ELEMENT;else if (typeof type === 'function') vtype = VTYPE_FUNCTION;else throw new Error('Invalid VNode type');
117
+ return {
118
+ vtype,
119
+ type,
120
+ props
121
+ };
122
+ }
123
+ function Fragment(props) {
124
+ return props.children;
125
+ }
126
+ const DEFAULT_ENV = {
127
+ isSvg: false
128
+ };
129
+ function insertDom(parent, nodes) {
130
+ if (!Array.isArray(nodes)) nodes = [nodes];
131
+ nodes = nodes.filter(Boolean);
132
+ if (nodes.length) parent.append(...nodes);
133
+ }
134
+ function mountAttributes(domElement, props, env) {
135
+ for (const key in props) {
136
+ if (key === 'key' || key === 'children' || key === 'ref') continue;
137
+ if (key === 'dangerouslySetInnerHTML') {
138
+ domElement.innerHTML = props[key].__html;
139
+ } else if (key === 'innerHTML' || key === 'textContent' || key === 'innerText' || key === 'value' && ['textarea', 'select'].includes(domElement.tagName)) {
140
+ const value = props[key];
141
+ if (value != null) domElement[key] = value;
142
+ } else if (key.startsWith('on')) {
143
+ domElement[key.toLowerCase()] = props[key];
144
+ } else {
145
+ setDOMAttribute(domElement, key, props[key], env.isSvg);
146
+ }
53
147
  }
54
- if (attrs) {
55
- Object.entries(attrs).forEach(([key, value]) => {
56
- el.setAttribute(key, value);
57
- });
148
+ }
149
+ const attrMap = {
150
+ className: 'class',
151
+ labelFor: 'for'
152
+ };
153
+ function setDOMAttribute(el, attr, value, isSVG) {
154
+ attr = attrMap[attr] || attr;
155
+ if (value === true) {
156
+ el.setAttribute(attr, '');
157
+ } else if (value === false) {
158
+ el.removeAttribute(attr);
159
+ } else {
160
+ const namespace = isSVG ? NS_ATTRS[attr] : undefined;
161
+ if (namespace !== undefined) {
162
+ el.setAttributeNS(namespace, attr, value);
163
+ } else {
164
+ el.setAttribute(attr, value);
165
+ }
166
+ }
167
+ }
168
+ function flatten(arr) {
169
+ return arr.reduce((prev, item) => prev.concat(item), []);
170
+ }
171
+ function mountChildren(children, env) {
172
+ return Array.isArray(children) ? flatten(children.map(child => mountChildren(child, env))) : mount(children, env);
173
+ }
174
+ function mount(vnode, env = DEFAULT_ENV) {
175
+ if (vnode == null || typeof vnode === 'boolean') {
176
+ return null;
177
+ }
178
+ if (vnode instanceof Node) {
179
+ return vnode;
180
+ }
181
+ if (isRenderFunction(vnode)) {
182
+ const {
183
+ type,
184
+ props
185
+ } = vnode;
186
+ if (type === Fragment) {
187
+ const node = document.createDocumentFragment();
188
+ if (props.children) {
189
+ const children = mountChildren(props.children, env);
190
+ insertDom(node, children);
191
+ }
192
+ return node;
193
+ }
194
+ const childVNode = type(props);
195
+ return mount(childVNode, env);
196
+ }
197
+ if (isLeaf(vnode)) {
198
+ return document.createTextNode(`${vnode}`);
199
+ }
200
+ if (isElement(vnode)) {
201
+ let node;
202
+ const {
203
+ type,
204
+ props
205
+ } = vnode;
206
+ if (!env.isSvg && type === 'svg') {
207
+ env = Object.assign({}, env, {
208
+ isSvg: true
209
+ });
210
+ }
211
+ if (!env.isSvg) {
212
+ node = document.createElement(type);
213
+ } else {
214
+ node = document.createElementNS(SVG_NS, type);
215
+ }
216
+ mountAttributes(node, props, env);
217
+ if (props.children) {
218
+ let childEnv = env;
219
+ if (env.isSvg && type === 'foreignObject') {
220
+ childEnv = Object.assign({}, childEnv, {
221
+ isSvg: false
222
+ });
223
+ }
224
+ const children = mountChildren(props.children, childEnv);
225
+ if (children != null) insertDom(node, children);
226
+ }
227
+ const {
228
+ ref
229
+ } = props;
230
+ if (typeof ref === 'function') ref(node);
231
+ return node;
58
232
  }
59
- return el;
233
+ throw new Error('mount: Invalid Vnode!');
234
+ }
235
+
236
+ /**
237
+ * Mount vdom as real DOM nodes.
238
+ */
239
+ function mountDom(vnode) {
240
+ return mount(vnode);
241
+ }
242
+
243
+ /**
244
+ * Render and mount without returning VirtualDOM, useful when you don't need SVG support.
245
+ */
246
+ function hm(...args) {
247
+ return mountDom(h(...args));
60
248
  }
61
249
  const memoizedPreloadJS = memoize(url => {
62
- document.head.append(createElement('link', {
250
+ document.head.append(hm('link', {
63
251
  rel: 'preload',
64
252
  as: 'script',
65
253
  href: url
66
254
  }));
67
255
  });
256
+ const jsCache = {};
257
+ const cssCache = {};
68
258
  async function loadJSItem(item, context) {
259
+ var _item$data;
260
+ const src = item.type === 'script' && ((_item$data = item.data) == null ? void 0 : _item$data.src) || '';
261
+ item.loaded || (item.loaded = jsCache[src]);
69
262
  if (!item.loaded) {
70
263
  if (item.type === 'script') {
71
264
  item.loaded = new Promise((resolve, reject) => {
72
- var _item$data;
73
- document.head.append(createElement('script', _extends({}, item.data, {
74
- onload: resolve,
75
- onerror: reject
265
+ document.head.append(hm('script', _extends({}, item.data, {
266
+ onLoad: resolve,
267
+ onError: reject
76
268
  })));
77
- // Run inline script synchronously
78
- if (!((_item$data = item.data) != null && _item$data.src)) resolve(undefined);
269
+ if (!src) {
270
+ // Run inline script synchronously
271
+ resolve(undefined);
272
+ }
79
273
  }).then(() => {
80
274
  item.loaded = true;
81
275
  });
276
+ if (src) jsCache[src] = item.loaded;
82
277
  }
83
278
  if (item.type === 'iife') {
84
279
  const {
@@ -91,12 +286,29 @@ async function loadJSItem(item, context) {
91
286
  }
92
287
  await item.loaded;
93
288
  }
289
+ function loadCSSItem(item) {
290
+ const url = item.type === 'stylesheet' && item.data.href || '';
291
+ item.loaded || (item.loaded = cssCache[url]);
292
+ if (item.loaded) return;
293
+ item.loaded = true;
294
+ if (url) cssCache[url] = true;
295
+ if (item.type === 'style') {
296
+ document.head.append(hm('style', {
297
+ textContent: item.data
298
+ }));
299
+ } else if (item.type === 'stylesheet') {
300
+ document.head.append(hm('link', _extends({
301
+ rel: 'stylesheet'
302
+ }, item.data)));
303
+ }
304
+ }
94
305
  async function loadJS(items, context) {
95
- const needPreload = items.filter(item => {
306
+ items.forEach(item => {
96
307
  var _item$data2;
97
- return item.type === 'script' && ((_item$data2 = item.data) == null ? void 0 : _item$data2.src);
308
+ if (item.type === 'script' && (_item$data2 = item.data) != null && _item$data2.src) {
309
+ memoizedPreloadJS(item.data.src);
310
+ }
98
311
  });
99
- if (needPreload.length > 1) needPreload.forEach(item => memoizedPreloadJS(item.data.src));
100
312
  context = _extends({
101
313
  getMarkmap: () => window.markmap
102
314
  }, context);
@@ -104,24 +316,39 @@ async function loadJS(items, context) {
104
316
  await loadJSItem(item, context);
105
317
  }
106
318
  }
107
- let provider = 'jsdelivr';
108
- function getFullUrl(path) {
109
- if (path.includes('://')) return path;
110
- return cdnUrl(provider, path);
319
+ function loadCSS(items) {
320
+ for (const item of items) {
321
+ loadCSSItem(item);
322
+ }
111
323
  }
112
324
  function buildJSItem(path) {
113
325
  return {
114
326
  type: 'script',
115
327
  data: {
116
- src: getFullUrl(path)
328
+ src: path
329
+ }
330
+ };
331
+ }
332
+ function buildCSSItem(path) {
333
+ return {
334
+ type: 'stylesheet',
335
+ data: {
336
+ href: path
117
337
  }
118
338
  };
119
339
  }
120
340
 
121
- var _window$markmap, _window$markmap2;
341
+ var _window$markmap;
122
342
  const enabled = {};
123
- const ready = loadJS(((_window$markmap = window.markmap) == null || (_window$markmap = _window$markmap.autoLoader) == null ? void 0 : _window$markmap.baseJs) || [`d3@${"6.2.0"}`, `markmap-lib@${"0.15.0-alpha.0"}`, `markmap-view@${"0.15.0-alpha.0"}`].map(buildJSItem)).then(() => {
124
- var _markmap$autoLoader;
343
+ const autoLoaderOptions = _extends$1({
344
+ baseJs: [`d3@${"7.8.5"}`, `markmap-lib@${"0.15.0"}`, `markmap-view@${"0.15.0"}`, `markmap-toolbar@${"0.15.0"}`],
345
+ baseCss: [`markmap-toolbar@${"0.15.0"}/dist/style.css`],
346
+ manual: false,
347
+ toolbar: false
348
+ }, (_window$markmap = window.markmap) == null ? void 0 : _window$markmap.autoLoader);
349
+ async function initialize() {
350
+ await urlBuilder.findFastestProvider();
351
+ await Promise.all([loadJS(autoLoaderOptions.baseJs.map(item => typeof item === 'string' ? buildJSItem(urlBuilder.getFullUrl(item)) : item)), loadCSS(autoLoaderOptions.baseCss.map(item => typeof item === 'string' ? buildCSSItem(urlBuilder.getFullUrl(item)) : item))]);
125
352
  const {
126
353
  markmap
127
354
  } = window;
@@ -129,8 +356,9 @@ const ready = loadJS(((_window$markmap = window.markmap) == null || (_window$mar
129
356
  style.textContent = markmap.globalCSS;
130
357
  // Insert global CSS to body so it has higher priority than prism.css, etc.
131
358
  document.body.prepend(style);
132
- (_markmap$autoLoader = markmap.autoLoader) == null || _markmap$autoLoader.onReady == null ? void 0 : _markmap$autoLoader.onReady();
133
- });
359
+ autoLoaderOptions.onReady == null ? void 0 : autoLoaderOptions.onReady();
360
+ }
361
+ const ready = initialize();
134
362
  function transform(transformer, content) {
135
363
  const result = transformer.transform(content);
136
364
  const keys = Object.keys(result.features).filter(key => !enabled[key]);
@@ -149,25 +377,38 @@ function transform(transformer, content) {
149
377
  return result;
150
378
  }
151
379
  function render(el) {
380
+ var _el$textContent;
152
381
  const {
153
382
  Transformer,
154
383
  Markmap,
155
- autoLoader,
156
- deriveOptions
384
+ deriveOptions,
385
+ Toolbar
157
386
  } = window.markmap;
158
- const lines = el.textContent.split('\n');
387
+ const lines = ((_el$textContent = el.textContent) == null ? void 0 : _el$textContent.split('\n')) || [];
159
388
  let indent = Infinity;
160
389
  lines.forEach(line => {
161
- const spaces = line.match(/^\s*/)[0].length;
390
+ var _line$match;
391
+ const spaces = ((_line$match = line.match(/^\s*/)) == null ? void 0 : _line$match[0].length) || 0;
162
392
  if (spaces < line.length) indent = Math.min(indent, spaces);
163
393
  });
164
394
  const content = lines.map(line => line.slice(indent)).join('\n').trim();
165
- const transformer = new Transformer(autoLoader == null ? void 0 : autoLoader.transformPlugins);
395
+ const transformer = new Transformer(autoLoaderOptions.transformPlugins);
166
396
  el.innerHTML = '<svg></svg>';
167
397
  const svg = el.firstChild;
168
398
  const mm = Markmap.create(svg, {
169
399
  embedGlobalCSS: false
170
400
  });
401
+ if (autoLoaderOptions.toolbar) {
402
+ const {
403
+ el: toolbar
404
+ } = Toolbar.create(mm);
405
+ Object.assign(toolbar.style, {
406
+ position: 'absolute',
407
+ right: '20px',
408
+ bottom: '20px'
409
+ });
410
+ el.append(toolbar);
411
+ }
171
412
  const doRender = () => {
172
413
  const {
173
414
  root,
@@ -188,7 +429,7 @@ async function renderAllUnder(container) {
188
429
  function renderAll() {
189
430
  return renderAllUnder(document);
190
431
  }
191
- if (!((_window$markmap2 = window.markmap) != null && (_window$markmap2 = _window$markmap2.autoLoader) != null && _window$markmap2.manual)) {
432
+ if (!autoLoaderOptions.manual) {
192
433
  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', () => {
193
434
  renderAll();
194
435
  });else renderAll();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "markmap-autoloader",
3
- "version": "0.15.0-alpha.0",
3
+ "version": "0.15.0",
4
4
  "description": "Load markmaps automatically in HTML",
5
5
  "author": "Gerald <gera2ld@live.com>",
6
6
  "license": "MIT",
@@ -19,10 +19,10 @@
19
19
  "url": "git+https://github.com/markmap/markmap.git"
20
20
  },
21
21
  "scripts": {
22
- "dev": "rollup -wc rollup.conf.js",
22
+ "dev": "rollup -wc",
23
23
  "clean": "del-cli dist types",
24
24
  "build:types": "tsc",
25
- "build:js": "rollup -c rollup.conf.js"
25
+ "build:js": "rollup -c"
26
26
  },
27
27
  "bugs": {
28
28
  "url": "https://github.com/markmap/markmap/issues"
@@ -38,9 +38,10 @@
38
38
  "markmap-common": "*"
39
39
  },
40
40
  "devDependencies": {
41
- "markmap-common": "0.15.0-alpha.0",
42
- "markmap-lib": "0.15.0-alpha.0",
43
- "markmap-view": "0.15.0-alpha.0"
41
+ "markmap-common": "0.15.0",
42
+ "markmap-lib": "0.15.0",
43
+ "markmap-toolbar": "0.15.0",
44
+ "markmap-view": "0.15.0"
44
45
  },
45
- "gitHead": "cea14d4791b8483481a99baa5d256017f52f267c"
46
+ "gitHead": "9c13bae5e28346ec613362046a023839ef64538b"
46
47
  }