@@ -623,15 +623,37 @@ class QrScanner {
623
623
if ( workerPath ) {
624
624
console . warn ( 'Specifying a worker path is not required and not supported anymore.' ) ;
625
625
}
626
- const useNativeBarcodeDetector = ! QrScanner . _disableBarcodeDetector
627
- && ( 'BarcodeDetector' in window && BarcodeDetector . getSupportedFormats
628
- ? ( await BarcodeDetector . getSupportedFormats ( ) ) . includes ( 'qr_code' )
629
- : false ) ;
630
- return useNativeBarcodeDetector
631
- ? new BarcodeDetector ( { formats : [ 'qr_code' ] } )
632
- // @ts -ignore no types defined
633
- : ( import ( './qr-scanner-worker.min.js' ) as Promise < { createWorker : ( ) => Worker } > )
634
- . then ( ( module ) => module . createWorker ( ) ) ;
626
+
627
+ // @ts -ignore no types defined for import
628
+ const createWorker = ( ) => ( import ( './qr-scanner-worker.min.js' ) as Promise < { createWorker : ( ) => Worker } > )
629
+ . then ( ( module ) => module . createWorker ( ) ) ;
630
+
631
+ const useBarcodeDetector = ! QrScanner . _disableBarcodeDetector
632
+ && 'BarcodeDetector' in window
633
+ && BarcodeDetector . getSupportedFormats
634
+ && ( await BarcodeDetector . getSupportedFormats ( ) ) . includes ( 'qr_code' ) ;
635
+
636
+ if ( ! useBarcodeDetector ) return createWorker ( ) ;
637
+
638
+ // On Macs with an M1/M2 processor and macOS Ventura (macOS version 13), the BarcodeDetector is broken in
639
+ // Chromium based browsers, regardless of the version. For that constellation, the BarcodeDetector does not
640
+ // error but does not detect QR codes. Macs without an M1/M2 or before Ventura are fine.
641
+ // See issue #209 and https://bugs.chromium.org/p/chromium/issues/detail?id=1382442
642
+ // TODO update this once the issue in macOS is fixed
643
+ const userAgentData = navigator . userAgentData ;
644
+ const isChromiumOnMacWithArmVentura = userAgentData // all Chromium browsers support userAgentData
645
+ && userAgentData . brands . some ( ( { brand } ) => / C h r o m i u m / i. test ( brand ) )
646
+ && / m a c ? O S / i. test ( userAgentData . platform )
647
+ // Does it have an ARM chip (e.g. M1/M2) and Ventura? Check this last as getHighEntropyValues can
648
+ // theoretically trigger a browser prompt, although no browser currently does seem to show one.
649
+ // If browser or user refused to return the requested values, assume broken ARM Ventura, to be safe.
650
+ && await userAgentData . getHighEntropyValues ( [ 'architecture' , 'platformVersion' ] )
651
+ . then ( ( { architecture, platformVersion } ) =>
652
+ / a r m / i. test ( architecture || 'arm' ) && parseInt ( platformVersion || '13' ) >= /* Ventura */ 13 )
653
+ . catch ( ( ) => true ) ;
654
+ if ( isChromiumOnMacWithArmVentura ) return createWorker ( ) ;
655
+
656
+ return new BarcodeDetector ( { formats : [ 'qr_code' ] } ) ;
635
657
}
636
658
637
659
private _onPlay ( ) : void {
@@ -1083,4 +1105,21 @@ declare class BarcodeDetector {
1083
1105
detect ( image : ImageBitmapSource ) : Promise < Array < { rawValue : string , cornerPoints : QrScanner . Point [ ] } > > ;
1084
1106
}
1085
1107
1108
+ // simplified from https://github.com/lukewarlow/user-agent-data-types/blob/master/index.d.ts
1109
+ declare global {
1110
+ interface Navigator {
1111
+ readonly userAgentData ?: {
1112
+ readonly platform : string ;
1113
+ readonly brands : Array < {
1114
+ readonly brand : string ;
1115
+ readonly version : string ;
1116
+ } > ;
1117
+ getHighEntropyValues ( hints : string [ ] ) : Promise < {
1118
+ readonly architecture ?: string ;
1119
+ readonly platformVersion ?: string ;
1120
+ } > ;
1121
+ } ;
1122
+ }
1123
+ }
1124
+
1086
1125
export default QrScanner ;
0 commit comments