qr-secure-send 1.3.0 → 1.4.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.
- package/index.html +75 -30
- package/package.json +1 -1
package/index.html
CHANGED
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
button.secondary:hover { background: #30363d; }
|
|
74
74
|
|
|
75
75
|
#qr-output { text-align: center; margin-top: 1rem; }
|
|
76
|
-
#qr-output canvas { border-radius: 8px; max-width: 100%; }
|
|
76
|
+
#qr-output canvas { border-radius: 8px; max-width: 100%; image-rendering: pixelated; }
|
|
77
77
|
|
|
78
78
|
#scanner-region { width: 100%; border-radius: 8px; overflow: hidden; position: relative; }
|
|
79
79
|
#scanner-region video { width: 100%; border-radius: 8px; display: block; }
|
|
@@ -244,15 +244,15 @@
|
|
|
244
244
|
const VERSION_TABLE = [
|
|
245
245
|
null, // index 0 unused
|
|
246
246
|
[16,10,1,16,0,0],[28,16,1,28,0,0],[44,26,1,44,0,0],[64,18,2,32,0,0],
|
|
247
|
-
[86,24,2,43,0,0],[108,16,
|
|
248
|
-
[182,22,
|
|
249
|
-
[334,22,
|
|
250
|
-
[507,28,
|
|
251
|
-
[714,
|
|
252
|
-
[1000,
|
|
253
|
-
[1267,
|
|
254
|
-
[1631,28,
|
|
255
|
-
[1992,28,
|
|
247
|
+
[86,24,2,43,0,0],[108,16,4,27,0,0],[124,18,4,31,0,0],[154,22,2,38,2,39],
|
|
248
|
+
[182,22,3,36,2,37],[216,26,4,43,1,44],[254,30,1,50,4,51],[290,22,6,36,2,37],
|
|
249
|
+
[334,22,8,37,1,38],[365,24,4,40,5,41],[415,24,5,41,5,42],[453,28,7,45,3,46],
|
|
250
|
+
[507,28,10,46,1,47],[563,26,9,43,4,44],[627,26,3,44,11,45],[669,26,3,41,13,42],
|
|
251
|
+
[714,26,17,42,0,0],[782,28,17,46,0,0],[860,28,4,47,14,48],[914,28,6,45,14,46],
|
|
252
|
+
[1000,28,8,47,13,48],[1062,28,19,46,4,47],[1128,28,22,45,3,46],[1193,28,3,45,23,46],
|
|
253
|
+
[1267,28,21,45,7,46],[1373,28,19,47,10,48],[1455,28,2,46,29,47],[1541,28,10,46,23,47],
|
|
254
|
+
[1631,28,14,46,21,47],[1725,28,14,46,23,47],[1812,28,12,47,26,48],[1914,28,6,47,34,48],
|
|
255
|
+
[1992,28,29,46,14,47],[2102,28,13,46,32,47],[2216,28,40,47,7,48],[2334,28,18,47,31,48]
|
|
256
256
|
];
|
|
257
257
|
|
|
258
258
|
// Byte-mode capacity per version at EC level M
|
|
@@ -715,13 +715,15 @@
|
|
|
715
715
|
|
|
716
716
|
function toCanvas(container, text, options = {}) {
|
|
717
717
|
const { matrix, size } = encode(text);
|
|
718
|
-
const scale = Math.max(
|
|
718
|
+
const scale = Math.max(4, Math.floor((options.width || 500) / size));
|
|
719
719
|
const margin = (options.margin !== undefined ? options.margin : 2) * scale;
|
|
720
720
|
|
|
721
721
|
const canvas = document.createElement("canvas");
|
|
722
722
|
const total = size * scale + margin * 2;
|
|
723
723
|
canvas.width = total;
|
|
724
724
|
canvas.height = total;
|
|
725
|
+
canvas.style.maxWidth = "100%";
|
|
726
|
+
canvas.style.height = "auto";
|
|
725
727
|
const ctx = canvas.getContext("2d");
|
|
726
728
|
|
|
727
729
|
ctx.fillStyle = "#ffffff";
|
|
@@ -742,25 +744,47 @@
|
|
|
742
744
|
|
|
743
745
|
|
|
744
746
|
// =========================================================================
|
|
745
|
-
// QR CODE SCANNER — Uses native BarcodeDetector API
|
|
746
|
-
//
|
|
747
|
-
// No external libraries required.
|
|
747
|
+
// QR CODE SCANNER — Uses native BarcodeDetector API where available,
|
|
748
|
+
// falls back to jsQR library (loaded from CDN) for other browsers.
|
|
748
749
|
// =========================================================================
|
|
749
750
|
|
|
750
751
|
const QRScan = (() => {
|
|
751
752
|
let stream = null;
|
|
752
753
|
let animId = null;
|
|
753
754
|
let running = false;
|
|
755
|
+
let jsQRPromise = null;
|
|
756
|
+
|
|
757
|
+
const hasBarcodeDetector = "BarcodeDetector" in window;
|
|
758
|
+
|
|
759
|
+
function loadJsQR() {
|
|
760
|
+
if (jsQRPromise) return jsQRPromise;
|
|
761
|
+
jsQRPromise = new Promise((resolve, reject) => {
|
|
762
|
+
const script = document.createElement("script");
|
|
763
|
+
script.src = "https://cdn.jsdelivr.net/npm/jsqr@1.4.0/dist/jsQR.min.js";
|
|
764
|
+
script.onload = () => resolve(window.jsQR);
|
|
765
|
+
script.onerror = () => reject(new Error("Failed to load QR scanner library"));
|
|
766
|
+
document.head.appendChild(script);
|
|
767
|
+
});
|
|
768
|
+
return jsQRPromise;
|
|
769
|
+
}
|
|
754
770
|
|
|
755
|
-
|
|
771
|
+
// Always report supported — we have a fallback
|
|
772
|
+
const isSupported = true;
|
|
756
773
|
|
|
757
774
|
async function start(regionEl, onResult, onError) {
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
return false;
|
|
761
|
-
}
|
|
775
|
+
let detector = null;
|
|
776
|
+
let jsQRFn = null;
|
|
762
777
|
|
|
763
|
-
|
|
778
|
+
if (hasBarcodeDetector) {
|
|
779
|
+
detector = new BarcodeDetector({ formats: ["qr_code"] });
|
|
780
|
+
} else {
|
|
781
|
+
try {
|
|
782
|
+
jsQRFn = await loadJsQR();
|
|
783
|
+
} catch (e) {
|
|
784
|
+
onError("Failed to load QR scanner. Check your internet connection.");
|
|
785
|
+
return false;
|
|
786
|
+
}
|
|
787
|
+
}
|
|
764
788
|
|
|
765
789
|
try {
|
|
766
790
|
stream = await navigator.mediaDevices.getUserMedia({
|
|
@@ -783,14 +807,35 @@
|
|
|
783
807
|
|
|
784
808
|
running = true;
|
|
785
809
|
|
|
810
|
+
// Reusable canvas for jsQR frame capture
|
|
811
|
+
let scanCanvas = null;
|
|
812
|
+
let scanCtx = null;
|
|
813
|
+
|
|
786
814
|
const scan = async () => {
|
|
787
815
|
if (!running) return;
|
|
788
816
|
try {
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
817
|
+
if (detector) {
|
|
818
|
+
const codes = await detector.detect(video);
|
|
819
|
+
if (codes.length > 0) {
|
|
820
|
+
const shouldStop = await onResult(codes[0].rawValue);
|
|
821
|
+
if (shouldStop) return;
|
|
822
|
+
}
|
|
823
|
+
} else if (jsQRFn) {
|
|
824
|
+
if (video.videoWidth > 0 && video.videoHeight > 0) {
|
|
825
|
+
if (!scanCanvas) {
|
|
826
|
+
scanCanvas = document.createElement("canvas");
|
|
827
|
+
scanCanvas.width = video.videoWidth;
|
|
828
|
+
scanCanvas.height = video.videoHeight;
|
|
829
|
+
scanCtx = scanCanvas.getContext("2d", { willReadFrequently: true });
|
|
830
|
+
}
|
|
831
|
+
scanCtx.drawImage(video, 0, 0, scanCanvas.width, scanCanvas.height);
|
|
832
|
+
const imageData = scanCtx.getImageData(0, 0, scanCanvas.width, scanCanvas.height);
|
|
833
|
+
const code = jsQRFn(imageData.data, imageData.width, imageData.height);
|
|
834
|
+
if (code) {
|
|
835
|
+
const shouldStop = await onResult(code.data);
|
|
836
|
+
if (shouldStop) return;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
794
839
|
}
|
|
795
840
|
} catch (_) {}
|
|
796
841
|
animId = requestAnimationFrame(scan);
|
|
@@ -912,19 +957,19 @@
|
|
|
912
957
|
return;
|
|
913
958
|
}
|
|
914
959
|
|
|
915
|
-
QRGen.toCanvas(output, payload, { width:
|
|
960
|
+
QRGen.toCanvas(output, payload, { width: 500, margin: 2 });
|
|
916
961
|
info.style.display = "block";
|
|
917
962
|
} catch (e) {
|
|
918
963
|
errEl.textContent = "Failed to generate QR code: " + e.message;
|
|
919
964
|
}
|
|
920
965
|
});
|
|
921
966
|
|
|
922
|
-
// Browser compatibility
|
|
923
|
-
if (!
|
|
967
|
+
// Browser compatibility note
|
|
968
|
+
if (!("BarcodeDetector" in window)) {
|
|
924
969
|
document.getElementById("compat-warning").style.display = "block";
|
|
925
970
|
document.getElementById("compat-warning").textContent =
|
|
926
|
-
"Your browser
|
|
927
|
-
"
|
|
971
|
+
"Your browser lacks native QR scanning. A fallback library will be " +
|
|
972
|
+
"loaded from the internet when you start the camera.";
|
|
928
973
|
}
|
|
929
974
|
|
|
930
975
|
// QR Scanning
|