mirror of
https://gitee.com/LongbowEnterprise/BootstrapBlazor.git
synced 2024-11-29 10:38:29 +08:00
!2671 feat(#I537X5): remove zxing.min.js from bundle.min.js
* refactor: 更新打包文件名 * feat: BarcodeReader 增加动态加载功能 * feat: 增加 JSModule 扩展方法 * chore: 增加 esm 配置 * refactor: 移动 zxing 包到动态加载目录 * refactor: 移动震动脚本到扩展类中
This commit is contained in:
parent
5a92056a97
commit
98f2f9af60
@ -25,6 +25,10 @@
|
||||
},
|
||||
"extensionToExtension": {
|
||||
"add": {
|
||||
".esm.js": [
|
||||
".cs",
|
||||
".razor"
|
||||
],
|
||||
".js": [
|
||||
".cs",
|
||||
".razor",
|
||||
|
@ -0,0 +1,84 @@
|
||||
let codeReader = null;
|
||||
|
||||
export function bb_barcode(el, method, auto, obj) {
|
||||
var $el = $(el);
|
||||
codeReader = new ZXing.BrowserMultiFormatReader();
|
||||
|
||||
if ($el.attr('data-scan') === 'Camera') {
|
||||
codeReader.getVideoInputDevices().then((videoInputDevices) => {
|
||||
obj.invokeMethodAsync("InitDevices", videoInputDevices).then(() => {
|
||||
if (auto && videoInputDevices.length > 0) {
|
||||
var button = $el.find('button[data-method="scan"]');
|
||||
var data_method = $el.attr('data-scan');
|
||||
if (data_method === 'Camera') button.trigger('click');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$el.on('click', 'button[data-method]', function () {
|
||||
var data_method = $(this).attr('data-method');
|
||||
if (data_method === 'scan') {
|
||||
obj.invokeMethodAsync("Start");
|
||||
var deviceId = $el.find('.dropdown-item.active').attr('data-val');
|
||||
var video = $el.find('video').attr('id');
|
||||
codeReader.decodeFromVideoDevice(deviceId, video, (result, err) => {
|
||||
if (result) {
|
||||
$.bb_vibrate();
|
||||
console.log(result.text);
|
||||
obj.invokeMethodAsync("GetResult", result.text);
|
||||
|
||||
var autostop = $el.attr('data-autostop') === 'true';
|
||||
if (autostop) {
|
||||
codeReader.reset();
|
||||
}
|
||||
}
|
||||
if (err && !(err instanceof ZXing.NotFoundException)) {
|
||||
console.error(err)
|
||||
obj.invokeMethodAsync('GetError', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (data_method === 'scanImage') {
|
||||
codeReader = new ZXing.BrowserMultiFormatReader();
|
||||
$el.find(':file').remove();
|
||||
var $img = $('.scanner-image');
|
||||
var $file = $('<input type="file" hidden accept="image/*">');
|
||||
$el.append($file);
|
||||
|
||||
$file.on('change', function () {
|
||||
if (this.files.length === 0) {
|
||||
return;
|
||||
}
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function (e) {
|
||||
$img.attr('src', e.target.result);
|
||||
codeReader.decodeFromImage($img[0]).then((result) => {
|
||||
if (result) {
|
||||
$.bb_vibrate();
|
||||
console.log(result.text);
|
||||
obj.invokeMethodAsync('GetResult', result.text);
|
||||
}
|
||||
}).catch((err) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
obj.invokeMethodAsync('GetError', err.message);
|
||||
}
|
||||
})
|
||||
};
|
||||
reader.readAsDataURL(this.files[0]);
|
||||
})
|
||||
$file.trigger('click');
|
||||
}
|
||||
else if (data_method === 'close') {
|
||||
codeReader.reset();
|
||||
obj.invokeMethodAsync("Stop");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export function bb_barcode_dispose() {
|
||||
if (codeReader != null) {
|
||||
codeReader.reset();
|
||||
}
|
||||
};
|
@ -1,94 +0,0 @@
|
||||
(function ($) {
|
||||
$.extend({
|
||||
bb_vibrate: function () {
|
||||
if ('vibrate' in window.navigator) {
|
||||
window.navigator.vibrate([200, 100, 200]);
|
||||
var handler = window.setTimeout(function () {
|
||||
window.clearTimeout(handler);
|
||||
window.navigator.vibrate([]);
|
||||
}, 1000);
|
||||
}
|
||||
},
|
||||
bb_barcode: function (el, obj, method, auto) {
|
||||
var $el = $(el);
|
||||
var codeReader = new ZXing.BrowserMultiFormatReader();
|
||||
|
||||
if (method === 'dispose') {
|
||||
codeReader.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
if ($el.attr('data-scan') === 'Camera') {
|
||||
codeReader.getVideoInputDevices().then((videoInputDevices) => {
|
||||
obj.invokeMethodAsync("InitDevices", videoInputDevices).then(() => {
|
||||
if (auto && videoInputDevices.length > 0) {
|
||||
var button = $el.find('button[data-method="scan"]');
|
||||
var data_method = $el.attr('data-scan');
|
||||
if (data_method === 'Camera') button.trigger('click');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$el.on('click', 'button[data-method]', function () {
|
||||
var data_method = $(this).attr('data-method');
|
||||
if (data_method === 'scan') {
|
||||
obj.invokeMethodAsync("Start");
|
||||
var deviceId = $el.find('.dropdown-item.active').attr('data-val');
|
||||
var video = $el.find('video').attr('id');
|
||||
codeReader.decodeFromVideoDevice(deviceId, video, (result, err) => {
|
||||
if (result) {
|
||||
$.bb_vibrate();
|
||||
console.log(result.text);
|
||||
obj.invokeMethodAsync("GetResult", result.text);
|
||||
|
||||
var autostop = $el.attr('data-autostop') === 'true';
|
||||
if (autostop) {
|
||||
codeReader.reset();
|
||||
}
|
||||
}
|
||||
if (err && !(err instanceof ZXing.NotFoundException)) {
|
||||
console.error(err)
|
||||
obj.invokeMethodAsync('GetError', err);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (data_method === 'scanImage') {
|
||||
codeReader = new ZXing.BrowserMultiFormatReader();
|
||||
$el.find(':file').remove();
|
||||
var $img = $('.scanner-image');
|
||||
var $file = $('<input type="file" hidden accept="image/*">');
|
||||
$el.append($file);
|
||||
|
||||
$file.on('change', function () {
|
||||
if (this.files.length === 0) {
|
||||
return;
|
||||
}
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function (e) {
|
||||
$img.attr('src', e.target.result);
|
||||
codeReader.decodeFromImage($img[0]).then((result) => {
|
||||
if (result) {
|
||||
$.bb_vibrate();
|
||||
console.log(result.text);
|
||||
obj.invokeMethodAsync('GetResult', result.text);
|
||||
}
|
||||
}).catch((err) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
obj.invokeMethodAsync('GetError', err.message);
|
||||
}
|
||||
})
|
||||
};
|
||||
reader.readAsDataURL(this.files[0]);
|
||||
})
|
||||
$file.trigger('click');
|
||||
}
|
||||
else if (data_method === 'close') {
|
||||
codeReader.reset();
|
||||
obj.invokeMethodAsync("Stop");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})(jQuery);
|
@ -13,7 +13,7 @@ namespace BootstrapBlazor.Components;
|
||||
/// </summary>
|
||||
public partial class BarcodeReader : IAsyncDisposable
|
||||
{
|
||||
private JSInterop<BarcodeReader>? Interop { get; set; }
|
||||
private JSModule<BarcodeReader>? Module { get; set; }
|
||||
|
||||
private string AutoStopString => AutoStop ? "true" : "false";
|
||||
|
||||
@ -147,8 +147,8 @@ public partial class BarcodeReader : IAsyncDisposable
|
||||
{
|
||||
if (firstRender)
|
||||
{
|
||||
Interop = new JSInterop<BarcodeReader>(JSRuntime);
|
||||
await Interop.InvokeVoidAsync(this, ScannerElement, "bb_barcode", "init", AutoStart);
|
||||
Module = await JSRuntime.LoadModule("barcodereader.bundle.js", this);
|
||||
await Module.InvokeVoidAsync("bb_barcode", ScannerElement, "init", AutoStart);
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,24 +222,21 @@ public partial class BarcodeReader : IAsyncDisposable
|
||||
/// DisposeAsyncCore 方法
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual async ValueTask DisposeAsyncCore(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
if (Interop != null)
|
||||
if (Module != null)
|
||||
{
|
||||
await Interop.InvokeVoidAsync(this, ScannerElement, "bb_barcode", "dispose");
|
||||
Interop.Dispose();
|
||||
Interop = null;
|
||||
await Module.InvokeVoidAsync("bb_barcode_dispose");
|
||||
await Module.DisposeAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// DisposeAsync 方法
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
await DisposeAsyncCore(true);
|
||||
|
@ -81,7 +81,7 @@ internal static class JSRuntimeExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// IJSRuntime 扩展方法 动态加载脚本 脚本目录为 modules
|
||||
/// </summary>
|
||||
/// <param name="jsRuntime"></param>
|
||||
/// <param name="path"></param>
|
||||
@ -93,15 +93,16 @@ internal static class JSRuntimeExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// IJSRuntime 扩展方法 动态加载脚本 脚本目录为 modules
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
/// <param name="jsRuntime"></param>
|
||||
/// <param name="component"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<JSModule> LoadModule<TComponent>(this IJSRuntime jsRuntime, TComponent component) where TComponent : ComponentBase
|
||||
public static async Task<JSModule<TValue>> LoadModule<TValue>(this IJSRuntime jsRuntime, string path, TValue value) where TValue : class
|
||||
{
|
||||
var fileName = $"{component.GetType().Name}.js";
|
||||
var jSObjectReference = await jsRuntime.InvokeAsync<IJSObjectReference>(identifier: "import", $"./_content/BootstrapBlazor/modules/{fileName}");
|
||||
return new JSModule(jSObjectReference);
|
||||
var jSObjectReference = await jsRuntime.InvokeAsync<IJSObjectReference>(identifier: "import", $"./_content/BootstrapBlazor/modules/{path}");
|
||||
return new JSModule<TValue>(jSObjectReference, value);
|
||||
}
|
||||
}
|
||||
|
@ -117,8 +117,11 @@ public class JSInterop<TValue> : IDisposable where TValue : class
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
_objRef?.Dispose();
|
||||
_objRef = null;
|
||||
if (_objRef != null)
|
||||
{
|
||||
_objRef.Dispose();
|
||||
_objRef = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,11 +11,14 @@ namespace BootstrapBlazor.Components;
|
||||
/// </summary>
|
||||
public class JSModule : IAsyncDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// IJSObjectReference 实例
|
||||
/// </summary>
|
||||
[NotNull]
|
||||
private IJSObjectReference? Module { get; set; }
|
||||
protected IJSObjectReference? Module { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="jSObjectReference"></param>
|
||||
public JSModule(IJSObjectReference? jSObjectReference)
|
||||
@ -24,12 +27,20 @@ public class JSModule : IAsyncDisposable
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// InvokeVoidAsync 方法
|
||||
/// </summary>
|
||||
/// <param name="identifier"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
public ValueTask InvokeVoidAsync(string identifier, params object[] args) => Module.InvokeVoidAsync(identifier, args);
|
||||
public virtual ValueTask InvokeVoidAsync(string identifier, params object?[] args) => Module.InvokeVoidAsync(identifier, args);
|
||||
|
||||
/// <summary>
|
||||
/// InvokeVoidAsync 方法
|
||||
/// </summary>
|
||||
/// <param name="identifier"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
public virtual ValueTask<TValue> InvokeAsync<TValue>(string identifier, params object?[] args) => Module.InvokeAsync<TValue>(identifier, args);
|
||||
|
||||
/// <summary>
|
||||
/// Dispose 方法
|
||||
@ -56,3 +67,55 @@ public class JSModule : IAsyncDisposable
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模块加载器
|
||||
/// </summary>
|
||||
/// <typeparam name="TValue"></typeparam>
|
||||
public class JSModule<TValue> : JSModule where TValue : class
|
||||
{
|
||||
/// <summary>
|
||||
/// DotNetReference 实例
|
||||
/// </summary>
|
||||
protected DotNetObjectReference<TValue> DotNetReference { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="jSObjectReference"></param>
|
||||
/// <param name="value"></param>
|
||||
public JSModule(IJSObjectReference? jSObjectReference, TValue value) : base(jSObjectReference)
|
||||
{
|
||||
DotNetReference = DotNetObjectReference.Create(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// InvokeVoidAsync 方法
|
||||
/// </summary>
|
||||
/// <param name="identifier"></param>
|
||||
/// <param name="args"></param>
|
||||
/// <returns></returns>
|
||||
public override ValueTask InvokeVoidAsync(string identifier, params object?[] args)
|
||||
{
|
||||
var paras = new List<object?>();
|
||||
if (args != null)
|
||||
{
|
||||
paras.AddRange(args);
|
||||
}
|
||||
paras.Add(DotNetReference);
|
||||
return Module.InvokeVoidAsync(identifier, paras.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Dispose 方法
|
||||
/// </summary>
|
||||
/// <param name="disposing"></param>
|
||||
protected override ValueTask DisposeAsyncCore(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
DotNetReference.Dispose();
|
||||
}
|
||||
return base.DisposeAsyncCore(disposing);
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
"outputFileName": "wwwroot/js/bootstrap.blazor.min.js",
|
||||
"inputFiles": [
|
||||
"wwwroot/lib/extensions/*.js",
|
||||
"Components/**/*.js"
|
||||
"Components/**/!(*.esm).js"
|
||||
],
|
||||
"minify": {
|
||||
"enabled": true,
|
||||
@ -35,5 +35,15 @@
|
||||
"enabled": false,
|
||||
"renameLocals": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"outputFileName": "wwwroot/modules/barcodereader.bundle.js",
|
||||
"inputFiles": [
|
||||
"Components/barcodereader/*.esm.js"
|
||||
],
|
||||
"minify": {
|
||||
"enabled": false,
|
||||
"renameLocals": true
|
||||
}
|
||||
}
|
||||
]
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -114,6 +114,15 @@
|
||||
obj.invokeMethodAsync(method, '', '', data.Os, data.Browser, data.Device, data.Language, data.Engine, data.UserAgent);
|
||||
}
|
||||
});
|
||||
},
|
||||
bb_vibrate: function () {
|
||||
if ('vibrate' in window.navigator) {
|
||||
window.navigator.vibrate([200, 100, 200]);
|
||||
var handler = window.setTimeout(function () {
|
||||
window.clearTimeout(handler);
|
||||
window.navigator.vibrate([]);
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
86
src/BootstrapBlazor/wwwroot/modules/barcodereader.bundle.js
Normal file
86
src/BootstrapBlazor/wwwroot/modules/barcodereader.bundle.js
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user