Skip to content

Commit 8131ae8

Browse files
committed
qual: pin latest metadata-parser
See Frameright/image-display-control-metadata-parser#3
1 parent 36a60a9 commit 8131ae8

File tree

9 files changed

+1224
-1759
lines changed

9 files changed

+1224
-1759
lines changed

Diff for: .github/workflows/main.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ jobs:
4848
- name: Upload component
4949
uses: actions/upload-artifact@v3
5050
with:
51-
name: image-display-control-metadata-parser
51+
name: react-image-display-control
5252
path: frameright-react-image-display-control-*.tgz
5353
if-no-files-found: error
5454

Diff for: README.md

+4
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ An easy way to do [Image Display Control](https://frameright.io) in your React
2323
web app. Made with :heart: by [Frameright](https://frameright.io). Power
2424
to the pictures!
2525

26+
> **Less than 5kB in your final client-side bundle.**
27+
2628
  :sparkles: [Live demo](https://react.frameright.io)
2729

2830
  💻 [CodeSandbox](https://codesandbox.io/s/image-display-control-react-component-m6qj9r)
@@ -144,6 +146,8 @@ In your Node.js-based project (e.g. using [Next.js](https://nextjs.org/) or
144146
npm install @frameright/react-image-display-control
145147
```
146148

149+
> **Less than 5kB in your final client-side bundle.**
150+
147151
  :floppy_disk:
148152
[Importing in your project](https://docs.frameright.io/react/importing)
149153

Diff for: example/index.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ const App = () => {
2121
>
2222
<ImageDisplayControl data-debug>
2323
<img
24-
src="https://react.frameright.io/assets/pics/skater.jpg"
25-
alt="Skater"
24+
src="https://webc.frameright.io/assets/pics/skater1_highres.jpg"
25+
alt="Skater 1"
2626
style={{
2727
width: '50%',
2828
height: '100%',
2929
verticalAlign: 'top', // avoid spurious margin when height becomes smaller than the font size
3030
}}
3131
/>
3232
<img
33-
src="https://webc.frameright.io/assets/pics/birds.jpg"
34-
alt="Birds"
33+
src="https://webc.frameright.io/assets/pics/skater2.jpg"
34+
alt="Skater 2"
3535
style={{
3636
width: '50%',
3737
height: '100%',

Diff for: example/package.json

+2-4
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@
1414
"devDependencies": {
1515
"@types/react": "^18.2.20",
1616
"@types/react-dom": "^18.2.7",
17-
"events": "^3.3.0",
17+
"buffer": "^6.0.3",
1818
"parcel": "^2.9.1",
19-
"path-browserify": "^1.0.1",
2019
"process": "^0.11.10",
21-
"typescript": "^5.0.4",
22-
"util": "^0.12.5"
20+
"typescript": "^5.0.4"
2321
}
2422
}

Diff for: package-lock.json

+1,169-1,639
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"react-component",
1919
"reactjs"
2020
],
21-
"version": "1.0.5",
21+
"version": "1.0.6",
2222
"license": "MIT",
2323
"repository": "https://github.com/Frameright/react-image-display-control",
2424
"author": {
@@ -80,7 +80,7 @@
8080
"typescript": "^5.2.0"
8181
},
8282
"dependencies": {
83-
"@frameright/image-display-control-metadata-parser": "^1.1.0",
83+
"@frameright/image-display-control-metadata-parser": "^2.0.0",
8484
"@frameright/image-display-control-web-component": "^1.1.7",
8585
"uuid": "^9.0.0"
8686
}

Diff for: src/index.tsx

+31-104
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,21 @@ import { v4 as uuidv4 } from 'uuid';
22

33
import * as React from 'react';
44

5-
// Note: this import is successful only if "moduleResolution" is set to "Node"
6-
// in tsconfig.json. However if this is set to "bundler" instead and this can't
7-
// be resolved, the entire code is still type-valid with `Parser` being of type
8-
// `any`.
9-
import type { Parser } from '@frameright/image-display-control-metadata-parser/dist/index.d';
5+
import { Parser } from '@frameright/image-display-control-metadata-parser';
106

117
// If true, we are either running on the server at request-time, or at
128
// build time, building a static (e.g. Next.js) page.
139
const isServerOrStatic = typeof window === 'undefined';
1410

1511
const isBrowser = !isServerOrStatic;
1612

17-
// See https://stackoverflow.com/questions/50940640/how-to-determine-if-jest-is-running-the-code-or-not
18-
const isRunningTests = process.env.JEST_WORKER_ID !== undefined;
13+
let isRunningTests = false;
14+
try {
15+
// See https://stackoverflow.com/questions/50940640/how-to-determine-if-jest-is-running-the-code-or-not
16+
isRunningTests = process.env.JEST_WORKER_ID !== undefined;
17+
} catch (e) {
18+
// Probably "ReferenceError: process is not defined", ignore.
19+
}
1920

2021
// See https://docs.frameright.io/web-component/importing
2122
if (isBrowser && !isRunningTests) {
@@ -25,67 +26,24 @@ if (isBrowser && !isRunningTests) {
2526
);
2627
}
2728

28-
type ParserConstructor = {
29-
new (buffer: Buffer): Parser;
30-
};
31-
32-
// In the browser, importing image-display-control-metadata-parser-standalone
33-
// will define window.ImageDisplayControl and window.Buffer.
34-
interface ExtendedWindow extends Window {
35-
Buffer: { Buffer: BufferConstructor } | undefined;
36-
ImageDisplayControl:
37-
| {
38-
Parser: ParserConstructor;
39-
}
40-
| undefined;
41-
}
42-
4329
interface FsModule {
4430
readFileSync: (path: string) => Buffer;
4531
}
4632

4733
let fs: FsModule | null = null;
48-
let parserConstructor: ParserConstructor | null = null;
49-
if (isBrowser) {
50-
// Defines window.ImageDisplayControl and window.Buffer.
51-
52-
// Note: this has no .d.ts file, so we have to use `"noImplicitAny": false`
53-
// in tsconfig.json for this import to work. Ideally we should get rid of
54-
// this special standalone file, as it ships Node polyfills for the browser.
55-
// Instead, the library should not require Node polyfills. See
56-
// https://github.com/Frameright/image-display-control-metadata-parser/issues/3
57-
import(
58-
'@frameright/image-display-control-metadata-parser/dist/image-display-control-metadata-parser-standalone.min.js'
59-
).then(() => {
60-
const extendedWindow = window as unknown as ExtendedWindow;
61-
if (extendedWindow.ImageDisplayControl) {
62-
parserConstructor = extendedWindow.ImageDisplayControl.Parser;
63-
}
64-
});
65-
} else {
66-
// We need to use `require()` here with vite-plugin-ssr in prod as otherwise
34+
if (!isBrowser) {
35+
// We need to use `require()` here with Vite/Vike in prod as otherwise
6736
// `import()` will happen later than the server-side rendering. However
6837
// `require()` isn't defined in dev mode, so then we fall back to `import()`.
6938
if (require) {
7039
// FIXME: for this to work on Next.js, we need to set
7140
// `config.resolve.fallback = { fs: false };` in next.config.js. See
72-
// * https://github.com/Frameright/image-display-control-metadata-parser/issues/3
73-
// * https://stackoverflow.com/questions/64926174/module-not-found-cant-resolve-fs-in-next-js-application
41+
// https://stackoverflow.com/questions/64926174/module-not-found-cant-resolve-fs-in-next-js-application
7442
fs = require('fs');
75-
76-
// eslint-disable-next-line @typescript-eslint/no-var-requires
77-
const parserModule = require('@frameright/image-display-control-metadata-parser');
78-
79-
parserConstructor = parserModule.Parser;
8043
} else {
8144
import('fs').then((fsModule) => {
8245
fs = fsModule;
8346
});
84-
import('@frameright/image-display-control-metadata-parser').then(
85-
(parserModule) => {
86-
parserConstructor = parserModule.Parser;
87-
}
88-
);
8947
}
9048
}
9149

@@ -145,7 +103,16 @@ export function ImageDisplayControl({
145103

146104
++numImgChildren;
147105

148-
const newAttrs = {
106+
const newAttrs: {
107+
is: string;
108+
class: string;
109+
ref: React.MutableRefObject<null>;
110+
'data-idc-uuid': string;
111+
suppressHydrationWarning: boolean;
112+
'data-src-prop': string;
113+
'data-path-on-server'?: string;
114+
'data-image-regions'?: string;
115+
} = {
149116
// Note: thanks to this, react will recognize this as a custom element.
150117
// https://react.dev/reference/react-dom/components#custom-html-elements
151118
is: 'image-display-control',
@@ -337,7 +304,7 @@ async function _populateImageRegionsMap(
337304
}
338305

339306
await _waitForImports(debug);
340-
const regions = _readImageRegionsJsonFromArrayBuffer(arrayBuffer);
307+
const regions = _readImageRegionsJsonFromBuffer(arrayBuffer);
341308
if (regions) {
342309
_traceIfDebug(
343310
debug,
@@ -431,42 +398,8 @@ function _readImageRegionsJsonFromDisk(
431398
return result;
432399
}
433400

434-
// To be used only on client-side.
435-
function _readImageRegionsJsonFromArrayBuffer(
436-
arrayBuffer: ArrayBuffer
437-
): string {
438-
let result = '';
439-
try {
440-
const extendedWindow = window as unknown as ExtendedWindow;
441-
if (!extendedWindow.Buffer) {
442-
// See
443-
// https://github.com/Frameright/image-display-control-metadata-parser/issues/3
444-
_warn(
445-
"Buffer module not available, can't read image regions from",
446-
'ArrayBuffer.'
447-
);
448-
} else {
449-
const buffer = extendedWindow.Buffer.Buffer.from(arrayBuffer);
450-
result = _readImageRegionsJsonFromBuffer(buffer);
451-
}
452-
} catch (error) {
453-
_warn('Error while reading image regions from array buffer:', error);
454-
}
455-
return result;
456-
}
457-
458-
function _readImageRegionsJsonFromBuffer(buffer: Buffer): string {
459-
if (!parserConstructor) {
460-
// See
461-
// https://github.com/Frameright/image-display-control-metadata-parser/issues/3
462-
_warn(
463-
"parserConstructor module not available, can't read image regions from",
464-
'Buffer.'
465-
);
466-
return '';
467-
}
468-
469-
const parser = new parserConstructor(buffer);
401+
function _readImageRegionsJsonFromBuffer(buffer: Buffer | ArrayBuffer): string {
402+
const parser = new Parser(buffer);
470403
const regions = parser.getIdcMetadata('rectangle', 'crop');
471404
return JSON.stringify(regions);
472405
}
@@ -509,8 +442,8 @@ function _getImageSource(
509442

510443
result = {
511444
src:
512-
element.attributes['data-src-prop']?.value ||
513-
element.attributes['src']?.value ||
445+
element.attributes.getNamedItem('data-src-prop')?.value ||
446+
element.attributes.getNamedItem('src')?.value ||
514447
element.src,
515448
};
516449
}
@@ -528,21 +461,15 @@ function _isImgElement(
528461
return !!element.props.src;
529462
} else if ('attributes' in element) {
530463
// HTML element
531-
return !!element.attributes['src'].value;
464+
return !!element.attributes.getNamedItem('src')?.value;
532465
}
533466
return false;
534467
}
535468

536-
// Workaround for
537-
// https://github.com/Frameright/image-display-control-metadata-parser/issues/3
469+
// FIXME: workaround for async import() on Vite/Vike in dev mode.
538470
async function _waitForImports(debug: boolean) {
539-
const extendedWindow = window as unknown as ExtendedWindow;
540471
for (const waitMs of [100, 200, 500, 1000, 1000]) {
541-
if (
542-
(fs || isBrowser) &&
543-
(extendedWindow.Buffer || isServerOrStatic) &&
544-
parserConstructor
545-
) {
472+
if (fs || isBrowser) {
546473
_traceIfDebug(debug, 'All imports have resolved.');
547474
return;
548475
}
@@ -554,11 +481,11 @@ async function _waitForImports(debug: boolean) {
554481

555482
const consolePrefix = '[idc]';
556483

557-
function _warn(...args) {
484+
function _warn(...args: any[]) {
558485
console.warn(consolePrefix, '[warn]', ...args);
559486
}
560487

561-
function _traceIfDebug(debug: boolean, ...args) {
488+
function _traceIfDebug(debug: boolean, ...args: any[]) {
562489
if (debug) {
563490
console.log(consolePrefix, '[debug]', ...args);
564491
}

Diff for: test/index.test.tsx

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
import * as React from 'react';
22
import { createRoot } from 'react-dom/client';
3+
4+
// Workaround for "ReferenceError: TextDecoder is not defined". See
5+
// * https://stackoverflow.com/questions/68468203/why-am-i-getting-textencoder-is-not-defined-in-jest
6+
// * https://mattbatman.com/textencoder-textdecoder-jest-and-jsdom/
7+
import { TextDecoder } from 'util';
8+
Object.defineProperty(window, 'TextDecoder', {
9+
writable: true,
10+
value: TextDecoder,
11+
});
12+
// eslint-disable-next-line import/first
313
import { ImageDisplayControl } from '../src';
414

515
describe('it', () => {

Diff for: tsconfig.json

+1-5
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,7 @@
1818
"strict": true,
1919
// linter checks for common issues
2020
"noImplicitReturns": true,
21-
22-
// Needed for importing image-display-control-metadata-parser-standalone in
23-
// src/index.tsx
24-
"noImplicitAny": false,
25-
21+
"noImplicitAny": true,
2622
"noFallthroughCasesInSwitch": true,
2723
// noUnused* overlap with @typescript-eslint/no-unused-vars, can disable if duplicative
2824
"noUnusedLocals": true,

0 commit comments

Comments
 (0)