@w0s/input-file-preview 3.0.4 → 3.0.6
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 +4 -2
- package/dist/attribute/Preview.d.ts.map +1 -1
- package/dist/attribute/Preview.js +20 -4
- package/dist/attribute/Preview.js.map +1 -1
- package/dist/event/change.d.ts +15 -0
- package/dist/event/change.d.ts.map +1 -0
- package/dist/event/change.js +76 -0
- package/dist/event/change.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/inputFilePreview.d.ts +9 -0
- package/dist/inputFilePreview.d.ts.map +1 -0
- package/dist/inputFilePreview.js +20 -0
- package/dist/inputFilePreview.js.map +1 -0
- package/package.json +50 -51
- package/dist/InputFilePreview.d.ts +0 -11
- package/dist/InputFilePreview.d.ts.map +0 -1
- package/dist/InputFilePreview.js +0 -94
- package/dist/InputFilePreview.js.map +0 -1
package/README.md
CHANGED
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
inputFilePreview(document.querySelectorAll('.js-input-file-preview')); // `getElementById()` or `getElementsByClassName()` or `getElementsByTagName()` or `querySelector()` or `querySelectorAll()`
|
|
26
26
|
</script>
|
|
27
27
|
|
|
28
|
-
<input type="file" class="js-input-file-preview"
|
|
28
|
+
<input type="file" id="input-file" class="js-input-file-preview"
|
|
29
29
|
data-preview="preview"
|
|
30
30
|
data-max-size="1048576"
|
|
31
31
|
/>
|
|
32
32
|
<template id="preview">
|
|
33
|
-
<output><code>${name}</code> (<data value="${size}">${size} byte</data>) cannot be previewed.</output>
|
|
33
|
+
<output for="input-file"><code>${name}</code> (<data value="${size}">${size} byte</data>) cannot be previewed.</output>
|
|
34
34
|
</template>
|
|
35
35
|
```
|
|
36
36
|
|
|
@@ -49,7 +49,9 @@
|
|
|
49
49
|
|
|
50
50
|
- `<template>` element must have one `<output>` element.
|
|
51
51
|
- 🆗 `<template> <output>Message</output> </template>`
|
|
52
|
+
- 🆗 `<template> <output>Message</output> <!-- comment --> </template>`
|
|
52
53
|
- 🆗 `<ul> <template> <li> <output>Message</output> </li> </template> </ul>`
|
|
54
|
+
- 🆖 `<template> <output>Message</output> text </template>` (Text node other than empty string are not permitted as child nodes)
|
|
53
55
|
- 🆖 `<template> <p>Message</p> </template>`
|
|
54
56
|
- Include the error message in the `<output>` element.
|
|
55
57
|
- `${name}` in the `<output>` element is converted to the file name, and `${size}` is converted to the file size (in bytes).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Preview.d.ts","sourceRoot":"","sources":["../../src/attribute/Preview.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,OAAO;;IAKb;;OAEG;gBACS,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;
|
|
1
|
+
{"version":3,"file":"Preview.d.ts","sourceRoot":"","sources":["../../src/attribute/Preview.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,OAAO;;IAKb;;OAEG;gBACS,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAyC5C,IAAI,QAAQ,IAAI,mBAAmB,CAElC;IAED,IAAI,UAAU,IAAI,MAAM,CAKvB;CACD"}
|
|
@@ -19,17 +19,33 @@ export default class {
|
|
|
19
19
|
throw new Error(`Element \`#${value}\` must be a \`<template>\` element.`);
|
|
20
20
|
}
|
|
21
21
|
this.#template = template;
|
|
22
|
-
const
|
|
23
|
-
if (
|
|
22
|
+
const templateContent = template.content;
|
|
23
|
+
if (Array.from(templateContent.childNodes).some((node) => {
|
|
24
|
+
const { nodeType, nodeValue } = node;
|
|
25
|
+
if ([Node.ELEMENT_NODE, Node.COMMENT_NODE].includes(nodeType)) {
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
if (nodeType === Node.TEXT_NODE && nodeValue?.trim() === '') {
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
return true;
|
|
32
|
+
})) {
|
|
33
|
+
throw new Error('There must be only Element node, comment node, or empty text node within the `<template>` element.');
|
|
34
|
+
}
|
|
35
|
+
const outputElement = templateContent.querySelector('output');
|
|
36
|
+
if (outputElement === null) {
|
|
24
37
|
throw new Error('There must be one `<output>` element within the `<template>` element.');
|
|
25
38
|
}
|
|
26
|
-
this.#output =
|
|
39
|
+
this.#output = outputElement;
|
|
27
40
|
}
|
|
28
41
|
get template() {
|
|
29
42
|
return this.#template;
|
|
30
43
|
}
|
|
31
44
|
get outputHtml() {
|
|
32
|
-
|
|
45
|
+
if ('getHTML' in HTMLOutputElement) {
|
|
46
|
+
return this.#output.getHTML();
|
|
47
|
+
}
|
|
48
|
+
return this.#output.innerHTML;
|
|
33
49
|
}
|
|
34
50
|
}
|
|
35
51
|
//# sourceMappingURL=Preview.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Preview.js","sourceRoot":"","sources":["../../src/attribute/Preview.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,OAAO;IACJ,SAAS,CAAsB;IAE/B,OAAO,CAAoB;IAEpC;;OAEG;IACH,YAAY,KAAgC;QAC3C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC3C,MAAM,IAAI,SAAS,CAAC,0CAA0C,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAChD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,eAAe,CAAC,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,CAAC,QAAQ,YAAY,mBAAmB,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,sCAAsC,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAE1B,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"Preview.js","sourceRoot":"","sources":["../../src/attribute/Preview.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,CAAC,OAAO;IACJ,SAAS,CAAsB;IAE/B,OAAO,CAAoB;IAEpC;;OAEG;IACH,YAAY,KAAgC;QAC3C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YAC3C,MAAM,IAAI,SAAS,CAAC,0CAA0C,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QAChD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,eAAe,CAAC,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,CAAC,QAAQ,YAAY,mBAAmB,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,cAAc,KAAK,sCAAsC,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAE1B,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC;QACzC,IACC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YACpD,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;YAErC,IAAK,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,CAAc,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7E,OAAO,KAAK,CAAC;YACd,CAAC;YAED,IAAI,QAAQ,KAAK,IAAI,CAAC,SAAS,IAAI,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;gBAC7D,OAAO,KAAK,CAAC;YACd,CAAC;YAED,OAAO,IAAI,CAAC;QACb,CAAC,CAAC,EACD,CAAC;YACF,MAAM,IAAI,KAAK,CAAC,oGAAoG,CAAC,CAAC;QACvH,CAAC;QAED,MAAM,aAAa,GAAG,eAAe,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC9D,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;QAC1F,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,aAAa,CAAC;IAC9B,CAAC;IAED,IAAI,QAAQ;QACX,OAAO,IAAI,CAAC,SAAS,CAAC;IACvB,CAAC;IAED,IAAI,UAAU;QACb,IAAI,SAAS,IAAI,iBAAiB,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QAC/B,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;IAC/B,CAAC;CACD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type MaxSize from '../attribute/MaxSize.ts';
|
|
2
|
+
import type Preview from '../attribute/Preview.ts';
|
|
3
|
+
/**
|
|
4
|
+
* `submit` event
|
|
5
|
+
*
|
|
6
|
+
* @param ev - Event
|
|
7
|
+
* @param data - Elements, attributes and others
|
|
8
|
+
* @param data.previewElements -
|
|
9
|
+
*/
|
|
10
|
+
declare const _default: (ev: Event, data: Readonly<{
|
|
11
|
+
preview: Preview;
|
|
12
|
+
maxSize: MaxSize;
|
|
13
|
+
}>) => void;
|
|
14
|
+
export default _default;
|
|
15
|
+
//# sourceMappingURL=change.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change.d.ts","sourceRoot":"","sources":["../../src/event/change.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,OAAO,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,OAAO,MAAM,yBAAyB,CAAC;AAEnD;;;;;;GAMG;yBAEF,IAAI,KAAK,EACT,MAAM,QAAQ,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CACjB,CAAC,KACA,IAAI;AANP,wBAoFE"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import MIMEType from 'whatwg-mimetype';
|
|
2
|
+
import { convert } from "../util/errorMessage.js";
|
|
3
|
+
/**
|
|
4
|
+
* `submit` event
|
|
5
|
+
*
|
|
6
|
+
* @param ev - Event
|
|
7
|
+
* @param data - Elements, attributes and others
|
|
8
|
+
* @param data.previewElements -
|
|
9
|
+
*/
|
|
10
|
+
export default (ev, data) => {
|
|
11
|
+
const inputFileElement = ev.currentTarget;
|
|
12
|
+
const { files } = inputFileElement;
|
|
13
|
+
const { parentNode: templateParentNode } = data.preview.template;
|
|
14
|
+
if (templateParentNode === null) {
|
|
15
|
+
throw new Error('The parent element of the `<template>` element does not exist.'); // `<template>` 要素がルート要素ないし `DocumentFragment` であることはあり得ないのでここには到達しない
|
|
16
|
+
}
|
|
17
|
+
/* 既存のプレビューをクリア */
|
|
18
|
+
Array.from(templateParentNode.querySelectorAll(':scope > [data-cloned="template"]')).forEach((element) => {
|
|
19
|
+
element.remove();
|
|
20
|
+
});
|
|
21
|
+
const fragment = document.createDocumentFragment();
|
|
22
|
+
[...files].forEach((file) => {
|
|
23
|
+
const templateElementClone = data.preview.template.content.cloneNode(true);
|
|
24
|
+
/* 次の change イベント発生時に子要素を削除するために目印を付ける */
|
|
25
|
+
Array.from(templateElementClone.children).forEach((element) => {
|
|
26
|
+
element.dataset['cloned'] = 'template';
|
|
27
|
+
});
|
|
28
|
+
const outputElement = templateElementClone.querySelector('output');
|
|
29
|
+
outputElement?.replaceChildren();
|
|
30
|
+
fragment.appendChild(templateElementClone);
|
|
31
|
+
const { name: fileName, size: fileSize, type: fileType } = file;
|
|
32
|
+
const type = fileType !== '' ? new MIMEType(fileType).type : undefined;
|
|
33
|
+
/* ファイルが読み込み対象であるかどうかのチェック */
|
|
34
|
+
if ((data.maxSize.value !== undefined && fileSize > data.maxSize.value) || type === undefined || !['image', 'audio', 'video'].includes(type)) {
|
|
35
|
+
outputElement?.insertAdjacentHTML('beforeend', convert(data.preview.outputHtml, file));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const fileReader = new FileReader();
|
|
39
|
+
fileReader.readAsDataURL(file);
|
|
40
|
+
fileReader.addEventListener('load', () => {
|
|
41
|
+
const fileReaderResult = fileReader.result;
|
|
42
|
+
if (fileReaderResult === null) {
|
|
43
|
+
throw new Error('File load failed.');
|
|
44
|
+
}
|
|
45
|
+
let mediaElement;
|
|
46
|
+
switch (type) {
|
|
47
|
+
case 'image': {
|
|
48
|
+
mediaElement = document.createElement('img');
|
|
49
|
+
mediaElement.src = fileReaderResult;
|
|
50
|
+
mediaElement.alt = fileName;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
case 'audio': {
|
|
54
|
+
mediaElement = document.createElement('audio');
|
|
55
|
+
mediaElement.src = fileReaderResult;
|
|
56
|
+
mediaElement.controls = true;
|
|
57
|
+
mediaElement.textContent = fileName;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
case 'video': {
|
|
61
|
+
mediaElement = document.createElement('video');
|
|
62
|
+
mediaElement.src = fileReaderResult;
|
|
63
|
+
mediaElement.controls = true;
|
|
64
|
+
mediaElement.textContent = fileName;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
default:
|
|
68
|
+
/* 文字列チェックを行っているのでここには来ない */
|
|
69
|
+
throw new Error();
|
|
70
|
+
}
|
|
71
|
+
outputElement?.appendChild(mediaElement);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
templateParentNode.insertBefore(fragment, data.preview.template);
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=change.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"change.js","sourceRoot":"","sources":["../../src/event/change.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"yBAcgB,mBAAmB,UAAU,CAAC,OAAO,CAAC,GAAG,gBAAgB,CAAC,OAAO,CAAC,GAAG,OAAO,GAAG,IAAI,KAAG,IAAI;AAA1G,wBAYE"}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import inputFilePreview from "./inputFilePreview.js";
|
|
2
2
|
const validate = (element) => {
|
|
3
3
|
if (!(element instanceof HTMLInputElement)) {
|
|
4
4
|
throw new Error('Element must be a `HTMLInputElement`');
|
|
5
5
|
}
|
|
6
|
+
if (element.type !== 'file') {
|
|
7
|
+
throw new Error('Element must be a `<input type=file>`');
|
|
8
|
+
}
|
|
6
9
|
return element;
|
|
7
10
|
};
|
|
8
11
|
export default (elementOrElements) => {
|
|
@@ -10,11 +13,11 @@ export default (elementOrElements) => {
|
|
|
10
13
|
return;
|
|
11
14
|
}
|
|
12
15
|
if (elementOrElements instanceof Element) {
|
|
13
|
-
|
|
16
|
+
inputFilePreview(validate(elementOrElements));
|
|
14
17
|
}
|
|
15
18
|
else {
|
|
16
19
|
Array.from(elementOrElements).forEach((element) => {
|
|
17
|
-
|
|
20
|
+
inputFilePreview(validate(element));
|
|
18
21
|
});
|
|
19
22
|
}
|
|
20
23
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,gBAAgB,MAAM,uBAAuB,CAAC;AAErD,MAAM,QAAQ,GAAG,CAAC,OAAgB,EAAwB,EAAE;IAC3D,IAAI,CAAC,CAAC,OAAO,YAAY,gBAAgB,CAAC,EAAE,CAAC;QAC5C,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAC1D,CAAC;IAED,OAAO,OAA+B,CAAC;AACxC,CAAC,CAAC;AAEF,eAAe,CAAC,iBAAmF,EAAQ,EAAE;IAC5G,IAAI,iBAAiB,KAAK,IAAI,EAAE,CAAC;QAChC,OAAO;IACR,CAAC;IAED,IAAI,iBAAiB,YAAY,OAAO,EAAE,CAAC;QAC1C,gBAAgB,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACP,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YACjD,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACJ,CAAC;AACF,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { HTMLInputFileElement } from '../@types/lib.dom.ts';
|
|
2
|
+
/**
|
|
3
|
+
* Show preview with `<input type=file>`
|
|
4
|
+
*
|
|
5
|
+
* @param thisElement - Target element
|
|
6
|
+
*/
|
|
7
|
+
declare const _default: (thisElement: HTMLInputFileElement) => void;
|
|
8
|
+
export default _default;
|
|
9
|
+
//# sourceMappingURL=inputFilePreview.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inputFilePreview.d.ts","sourceRoot":"","sources":["../src/inputFilePreview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAKjE;;;;GAIG;yBACa,aAAa,oBAAoB,KAAG,IAAI;AAAxD,wBAiBE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import Preview from "./attribute/Preview.js";
|
|
2
|
+
import MaxSize from "./attribute/MaxSize.js";
|
|
3
|
+
import changeEvent from "./event/change.js";
|
|
4
|
+
/**
|
|
5
|
+
* Show preview with `<input type=file>`
|
|
6
|
+
*
|
|
7
|
+
* @param thisElement - Target element
|
|
8
|
+
*/
|
|
9
|
+
export default (thisElement) => {
|
|
10
|
+
const { preview: previewAttribute, maxSize: maxSizeAttribute } = thisElement.dataset;
|
|
11
|
+
const preview = new Preview(previewAttribute);
|
|
12
|
+
const maxSize = new MaxSize(maxSizeAttribute ?? '10485760');
|
|
13
|
+
thisElement.addEventListener('change', (ev) => {
|
|
14
|
+
changeEvent(ev, {
|
|
15
|
+
preview: preview,
|
|
16
|
+
maxSize: maxSize,
|
|
17
|
+
});
|
|
18
|
+
}, { passive: true });
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=inputFilePreview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inputFilePreview.js","sourceRoot":"","sources":["../src/inputFilePreview.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,wBAAwB,CAAC;AAC7C,OAAO,OAAO,MAAM,wBAAwB,CAAC;AAC7C,OAAO,WAAW,MAAM,mBAAmB,CAAC;AAE5C;;;;GAIG;AACH,eAAe,CAAC,WAAiC,EAAQ,EAAE;IAC1D,MAAM,EAAE,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,gBAAgB,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC;IAErF,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAE9C,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,gBAAgB,IAAI,UAAU,CAAC,CAAC;IAE5D,WAAW,CAAC,gBAAgB,CAC3B,QAAQ,EACR,CAAC,EAAS,EAAE,EAAE;QACb,WAAW,CAAC,EAAE,EAAE;YACf,OAAO,EAAE,OAAO;YAChB,OAAO,EAAE,OAAO;SAChB,CAAC,CAAC;IACJ,CAAC,EACD,EAAE,OAAO,EAAE,IAAI,EAAE,CACjB,CAAC;AACH,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,51 +1,50 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@w0s/input-file-preview",
|
|
3
|
-
"version": "3.0.
|
|
4
|
-
"description": "Show preview with `<input type=file>`",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"file"
|
|
7
|
-
],
|
|
8
|
-
"homepage": "https://github.com/SaekiTominaga/js-library-browser#readme",
|
|
9
|
-
"bugs": {
|
|
10
|
-
"url": "https://github.com/SaekiTominaga/js-library-browser/issues"
|
|
11
|
-
},
|
|
12
|
-
"license": "MIT",
|
|
13
|
-
"author": "Saeki Tominaga",
|
|
14
|
-
"files": [
|
|
15
|
-
"dist/**/*.d.ts",
|
|
16
|
-
"!dist/**/*.test.d.ts",
|
|
17
|
-
"dist/**/*.d.ts.map",
|
|
18
|
-
"!dist/**/*.test.d.ts.map",
|
|
19
|
-
"dist/**/*.js",
|
|
20
|
-
"!dist/**/*.test.js",
|
|
21
|
-
"dist/**/*.js.map",
|
|
22
|
-
"!dist/**/*.test.js.map"
|
|
23
|
-
],
|
|
24
|
-
"type": "module",
|
|
25
|
-
"main": "dist/index.js",
|
|
26
|
-
"module": "dist/index.js",
|
|
27
|
-
"types": "dist/index.d.ts",
|
|
28
|
-
"repository": {
|
|
29
|
-
"type": "git",
|
|
30
|
-
"url": "git+https://github.com/SaekiTominaga/js-library-browser.git"
|
|
31
|
-
},
|
|
32
|
-
"scripts": {
|
|
33
|
-
"
|
|
34
|
-
"prebuild": "rimraf dist/* -g",
|
|
35
|
-
"build": "tsc",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@w0s/input-file-preview",
|
|
3
|
+
"version": "3.0.6",
|
|
4
|
+
"description": "Show preview with `<input type=file>`",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"file"
|
|
7
|
+
],
|
|
8
|
+
"homepage": "https://github.com/SaekiTominaga/js-library-browser#readme",
|
|
9
|
+
"bugs": {
|
|
10
|
+
"url": "https://github.com/SaekiTominaga/js-library-browser/issues"
|
|
11
|
+
},
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"author": "Saeki Tominaga",
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/**/*.d.ts",
|
|
16
|
+
"!dist/**/*.test.d.ts",
|
|
17
|
+
"dist/**/*.d.ts.map",
|
|
18
|
+
"!dist/**/*.test.d.ts.map",
|
|
19
|
+
"dist/**/*.js",
|
|
20
|
+
"!dist/**/*.test.js",
|
|
21
|
+
"dist/**/*.js.map",
|
|
22
|
+
"!dist/**/*.test.js.map"
|
|
23
|
+
],
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "dist/index.js",
|
|
26
|
+
"module": "dist/index.js",
|
|
27
|
+
"types": "dist/index.d.ts",
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "git+https://github.com/SaekiTominaga/js-library-browser.git"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"dev": "conc \"http-server -o demo -c-1\" \"tsc -w\"",
|
|
34
|
+
"prebuild": "rimraf dist/* -g",
|
|
35
|
+
"build": "tsc",
|
|
36
|
+
"lint": "eslint src/**/*.ts",
|
|
37
|
+
"pretest": "npm run build",
|
|
38
|
+
"test": "cross-env NODE_OPTIONS=--experimental-vm-modules jest dist/.+\\.test\\.js -c ../../jest.config.mjs --roots packages/input-file-preview"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"@w0s/html-escape": "^4.0.2",
|
|
42
|
+
"whatwg-mimetype": "^4.0.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/whatwg-mimetype": "^3.0.2"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"InputFilePreview.d.ts","sourceRoot":"","sources":["../src/InputFilePreview.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,CAAC,OAAO;;IASb;;OAEG;gBACS,WAAW,EAAE,gBAAgB;CAkGzC"}
|
package/dist/InputFilePreview.js
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import MIMEType from 'whatwg-mimetype';
|
|
2
|
-
import { convert } from "./util/errorMessage.js";
|
|
3
|
-
import Preview from "./attribute/Preview.js";
|
|
4
|
-
import MaxSize from "./attribute/MaxSize.js";
|
|
5
|
-
/**
|
|
6
|
-
* Show preview with `<input type=file>`
|
|
7
|
-
*/
|
|
8
|
-
export default class {
|
|
9
|
-
#inputFileElement;
|
|
10
|
-
#preview; // プレビューを表示するテンプレート
|
|
11
|
-
#maxSize; // プレビューを行う最大サイズ
|
|
12
|
-
#previewElements = new Set(); // プレビューを表示する要素
|
|
13
|
-
/**
|
|
14
|
-
* @param thisElement - Target element
|
|
15
|
-
*/
|
|
16
|
-
constructor(thisElement) {
|
|
17
|
-
this.#inputFileElement = thisElement;
|
|
18
|
-
const { files } = thisElement;
|
|
19
|
-
if (files === null) {
|
|
20
|
-
throw new Error('Not a `<input type=file>`.');
|
|
21
|
-
}
|
|
22
|
-
const { preview: previewAttribute, maxSize: maxSizeAttribute } = thisElement.dataset;
|
|
23
|
-
this.#preview = new Preview(previewAttribute);
|
|
24
|
-
this.#maxSize = new MaxSize(maxSizeAttribute ?? '10485760');
|
|
25
|
-
thisElement.addEventListener('change', this.#changeEvent, { passive: true });
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* ファイル選択時の処理
|
|
29
|
-
*/
|
|
30
|
-
#changeEvent = () => {
|
|
31
|
-
const { files } = this.#inputFileElement;
|
|
32
|
-
/* 既存のプレビューをリセット */
|
|
33
|
-
this.#previewElements.forEach((element) => {
|
|
34
|
-
element.remove();
|
|
35
|
-
});
|
|
36
|
-
const fragment = document.createDocumentFragment();
|
|
37
|
-
[...files].forEach((file) => {
|
|
38
|
-
const templateElementClone = this.#preview.template.content.cloneNode(true);
|
|
39
|
-
const outputElement = templateElementClone.querySelector('output');
|
|
40
|
-
outputElement.replaceChildren();
|
|
41
|
-
fragment.appendChild(templateElementClone);
|
|
42
|
-
const { name: fileName, size: fileSize, type: fileType } = file;
|
|
43
|
-
const { type } = new MIMEType(fileType);
|
|
44
|
-
/* ファイルが読み込み対象であるかどうかのチェック */
|
|
45
|
-
if ((this.#maxSize.value !== undefined && fileSize > this.#maxSize.value) || !['image', 'audio', 'video'].includes(type)) {
|
|
46
|
-
outputElement.insertAdjacentHTML('beforeend', convert(this.#preview.outputHtml, file));
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
const fileReader = new FileReader();
|
|
50
|
-
fileReader.readAsDataURL(file);
|
|
51
|
-
fileReader.addEventListener('load', () => {
|
|
52
|
-
const fileReaderResult = fileReader.result;
|
|
53
|
-
if (fileReaderResult === null) {
|
|
54
|
-
throw new Error('File load failed.');
|
|
55
|
-
}
|
|
56
|
-
let mediaElement;
|
|
57
|
-
switch (type) {
|
|
58
|
-
case 'image': {
|
|
59
|
-
mediaElement = document.createElement('img');
|
|
60
|
-
mediaElement.src = fileReaderResult;
|
|
61
|
-
mediaElement.alt = fileName;
|
|
62
|
-
break;
|
|
63
|
-
}
|
|
64
|
-
case 'audio': {
|
|
65
|
-
mediaElement = document.createElement('audio');
|
|
66
|
-
mediaElement.src = fileReaderResult;
|
|
67
|
-
mediaElement.controls = true;
|
|
68
|
-
mediaElement.textContent = fileName;
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
case 'video': {
|
|
72
|
-
mediaElement = document.createElement('video');
|
|
73
|
-
mediaElement.src = fileReaderResult;
|
|
74
|
-
mediaElement.controls = true;
|
|
75
|
-
mediaElement.textContent = fileName;
|
|
76
|
-
break;
|
|
77
|
-
}
|
|
78
|
-
default:
|
|
79
|
-
}
|
|
80
|
-
outputElement.appendChild(mediaElement);
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
let count = fragment.childElementCount;
|
|
84
|
-
this.#preview.template.parentNode?.insertBefore(fragment, this.#preview.template);
|
|
85
|
-
let previousElement = this.#preview.template.previousElementSibling;
|
|
86
|
-
// eslint-disable-next-line functional/no-loop-statements
|
|
87
|
-
while (count > 0) {
|
|
88
|
-
this.#previewElements.add(previousElement);
|
|
89
|
-
count -= 1;
|
|
90
|
-
previousElement = previousElement.previousElementSibling;
|
|
91
|
-
}
|
|
92
|
-
};
|
|
93
|
-
}
|
|
94
|
-
//# sourceMappingURL=InputFilePreview.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"InputFilePreview.js","sourceRoot":"","sources":["../src/InputFilePreview.ts"],"names":[],"mappings":"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"}
|