mirror of
https://gitee.com/LongbowEnterprise/BootstrapBlazor.git
synced 2024-11-30 02:58:37 +08:00
feat(Upload): use JavaScript isolation (#1189)
* feat: 增加更新预览集合方法 * feat: upload 组件使用脚本隔离 * feat: 增加 ShowZoomButton 参数 * test: 更新单元测试 * test: 更新单元测试
This commit is contained in:
parent
42c8523550
commit
26964d6041
@ -16,7 +16,7 @@
|
||||
{
|
||||
<img alt="prevUrl" src="@item.PrevUrl" />
|
||||
}
|
||||
else if(IconTemplate != null)
|
||||
else if (IconTemplate != null)
|
||||
{
|
||||
@IconTemplate(item)
|
||||
}
|
||||
@ -28,12 +28,15 @@
|
||||
<div class="upload-item-size"><span>@item.GetFileName()</span> (@item.Size.ToFileSizeString())</div>
|
||||
<div class="upload-item-actions">
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-sm btn-secondary btn-zoom" disabled="@GetDiabledString(item)" @onclick="() => OnClickZoom(item)" aria-label="zoom">
|
||||
<i class="@ZoomIcon"></i>
|
||||
</button>
|
||||
@if(ShowDownloadButton)
|
||||
@if (ShowZoomButton)
|
||||
{
|
||||
<button type="button" class="btn btn-sm btn-secondary" disabled="@GetDiabledString(item)" @onclick="() => OnClickDownload(item)" aria-label="download">
|
||||
<button type="button" class="btn btn-sm btn-secondary btn-zoom" disabled="@GetDiabledString(item)" @onclick="() => OnClickZoom(item)" aria-label="zoom">
|
||||
<i class="@ZoomIcon"></i>
|
||||
</button>
|
||||
}
|
||||
@if (ShowDownloadButton)
|
||||
{
|
||||
<button type="button" class="btn btn-sm btn-secondary btn-download" disabled="@GetDiabledString(item)" @onclick="() => OnClickDownload(item)" aria-label="download">
|
||||
<i class="@DownloadIcon"></i>
|
||||
</button>
|
||||
}
|
||||
|
@ -73,6 +73,12 @@ public partial class CardUpload<TValue>
|
||||
[Parameter]
|
||||
public string? ZoomIcon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得/设置 是否显示放大按钮 默认 true
|
||||
/// </summary>
|
||||
[Parameter]
|
||||
public bool ShowZoomButton { get; set; } = true;
|
||||
|
||||
[Inject]
|
||||
[NotNull]
|
||||
private IIconTheme? IconTheme { get; set; }
|
||||
|
@ -9,7 +9,7 @@ namespace BootstrapBlazor.Components;
|
||||
/// <summary>
|
||||
/// Upload 组件基类
|
||||
/// </summary>
|
||||
[JSModuleAutoLoader("upload", ModuleName = "Upload")]
|
||||
[JSModuleAutoLoader(ModuleName = "upload")]
|
||||
public abstract class UploadBase<TValue> : ValidateBase<TValue>, IUpload
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -1,93 +1,81 @@
|
||||
import Data from "./data.js"
|
||||
import EventHandler from "./base/event-handler.js"
|
||||
import BlazorComponent from "./base/blazor-component.js"
|
||||
import EventHandler from "./event-handler.js"
|
||||
import Viewer from "./viewer.js"
|
||||
|
||||
export class Upload extends BlazorComponent {
|
||||
static get Default() {
|
||||
return {
|
||||
browserClass: '.btn-browser'
|
||||
export function init(id) {
|
||||
const el = document.getElementById(id)
|
||||
if (el === null) {
|
||||
return
|
||||
}
|
||||
const preventHandler = e => e.preventDefault()
|
||||
const upload = { el, preventHandler }
|
||||
Data.set(id, upload)
|
||||
|
||||
const inputFile = el.querySelector('[type="file"]')
|
||||
EventHandler.on(el, 'click', '.btn-browser', () => {
|
||||
inputFile.click()
|
||||
})
|
||||
|
||||
//阻止浏览器默认行为
|
||||
EventHandler.on(document, "dragleave", preventHandler)
|
||||
EventHandler.on(document, 'drop', preventHandler)
|
||||
EventHandler.on(document, 'dragenter', preventHandler)
|
||||
EventHandler.on(document, 'dragover', preventHandler)
|
||||
|
||||
EventHandler.on(el, 'drop', e => {
|
||||
try {
|
||||
//获取文件对象
|
||||
const fileList = e.dataTransfer.files
|
||||
|
||||
//检测是否是拖拽文件到页面的操作
|
||||
if (fileList.length === 0) {
|
||||
return false
|
||||
}
|
||||
|
||||
inputFile.files = e.dataTransfer.files
|
||||
const event = new Event('change', { bubbles: true })
|
||||
inputFile.dispatchEvent(event)
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
_init() {
|
||||
this._inputFile = this._element.querySelector('[type="file"]')
|
||||
this._setListeners()
|
||||
}
|
||||
EventHandler.on(el, 'paste', e => {
|
||||
inputFile.files = e.clipboardData.files
|
||||
const event = new Event('change', { bubbles: true })
|
||||
inputFile.dispatchEvent(event)
|
||||
})
|
||||
|
||||
_setListeners() {
|
||||
EventHandler.on(this._element, 'click', this._config.browserClass, () => {
|
||||
this._inputFile.click()
|
||||
})
|
||||
|
||||
//阻止浏览器默认行为
|
||||
EventHandler.on(document, "dragleave", e => {
|
||||
e.preventDefault()
|
||||
})
|
||||
EventHandler.on(document, 'drop', e => {
|
||||
e.preventDefault()
|
||||
})
|
||||
EventHandler.on(document, 'dragenter', e => {
|
||||
e.preventDefault()
|
||||
})
|
||||
EventHandler.on(document, 'dragover', e => {
|
||||
e.preventDefault()
|
||||
})
|
||||
|
||||
EventHandler.on(this._element, 'drop', e => {
|
||||
try {
|
||||
//获取文件对象
|
||||
const fileList = e.dataTransfer.files
|
||||
|
||||
//检测是否是拖拽文件到页面的操作
|
||||
if (fileList.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._inputFile.files = e.dataTransfer.files;
|
||||
const event = new Event('change', { bubbles: true });
|
||||
this._inputFile.dispatchEvent(event);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
})
|
||||
|
||||
EventHandler.on(this._element, 'paste', e => {
|
||||
this._inputFile.files = e.clipboardData.files;
|
||||
const event = new Event('change', { bubbles: true });
|
||||
this._inputFile.dispatchEvent(event);
|
||||
});
|
||||
|
||||
EventHandler.on(this._element, 'click', '.btn-zoom', e => {
|
||||
if (!this._previewer) {
|
||||
this._previewer = Data.get(this._config.previewerId)
|
||||
}
|
||||
const button = e.delegateTarget
|
||||
const buttons = [...this._element.querySelectorAll('.btn-zoom')]
|
||||
this._previewer.viewer.show(buttons.indexOf(button))
|
||||
})
|
||||
}
|
||||
|
||||
_execute(args) {
|
||||
const tooltipId = args[0]
|
||||
const method = args[1]
|
||||
if (method === 'disposeTooltip' && tooltipId) {
|
||||
const element = document.getElementById(tooltipId)
|
||||
if (element) {
|
||||
const tooltip = bootstrap.Tooltip.getInstance(element)
|
||||
if (tooltip) {
|
||||
tooltip.dispose()
|
||||
}
|
||||
}
|
||||
EventHandler.on(el, 'click', '.btn-zoom', e => {
|
||||
if (!upload.viewer) {
|
||||
const previewId = el.getAttribute('data-bb-previewer-id')
|
||||
const viewEl = document.getElementById(previewId)
|
||||
upload.viewer = Viewer.init(viewEl, [])
|
||||
upload.viewEl = viewEl
|
||||
}
|
||||
}
|
||||
const button = e.delegateTarget
|
||||
const buttons = [...el.querySelectorAll('.btn-zoom')]
|
||||
upload.viewer.updatePrevList([...el.querySelectorAll('.upload-body img')].map(v => v.src))
|
||||
upload.viewer.show(buttons.indexOf(button))
|
||||
})
|
||||
}
|
||||
|
||||
_dispose() {
|
||||
EventHandler.off(this._element, 'click', this._config.browserClass)
|
||||
EventHandler.off(document, 'dragleave');
|
||||
EventHandler.off(document, 'drop');
|
||||
EventHandler.off(document, 'dragenter');
|
||||
EventHandler.off(document, 'dragover');
|
||||
EventHandler.off(this._element, 'drop');
|
||||
EventHandler.off(this._element, 'paste');
|
||||
export function dispose(id) {
|
||||
const upload = Data.get(id)
|
||||
Data.remove(id)
|
||||
|
||||
const el = upload.el
|
||||
const preventHandler = upload.preventHandler
|
||||
if (upload) {
|
||||
if (upload.viewer) {
|
||||
upload.viewer.dispose(upload.viewEl)
|
||||
}
|
||||
EventHandler.off(el, 'click')
|
||||
EventHandler.off(el, 'drop')
|
||||
EventHandler.off(el, 'paste')
|
||||
EventHandler.off(document, 'dragleave', preventHandler)
|
||||
EventHandler.off(document, 'drop', preventHandler)
|
||||
EventHandler.off(document, 'dragenter', preventHandler)
|
||||
EventHandler.off(document, 'dragover', preventHandler)
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,10 @@ export default {
|
||||
viewer.el.classList.add('show')
|
||||
}
|
||||
|
||||
viewer.updatePrevList = prevList => {
|
||||
viewer.prevList = prevList
|
||||
}
|
||||
|
||||
viewer.resetImage = () => {
|
||||
viewer.prevImg.classList.add('transition-none')
|
||||
viewer.prevImg.style.transform = 'scale(1) rotate(0deg)'
|
||||
|
@ -755,11 +755,40 @@ public class UploadTest : BootstrapBlazorTestBase
|
||||
});
|
||||
});
|
||||
|
||||
var button = cut.FindAll(".btn-secondary");
|
||||
await cut.InvokeAsync(() => button[1].Click());
|
||||
var button = cut.Find(".btn-download");
|
||||
await cut.InvokeAsync(() => button.Click());
|
||||
Assert.True(clicked);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CardUpload_ShowZoom()
|
||||
{
|
||||
var clicked = false;
|
||||
var cut = Context.RenderComponent<CardUpload<string>>(pb =>
|
||||
{
|
||||
pb.Add(a => a.ShowZoomButton, true);
|
||||
pb.Add(a => a.OnZoomAsync, file =>
|
||||
{
|
||||
clicked = true;
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
pb.Add(a => a.DefaultFileList, new List<UploadFile>()
|
||||
{
|
||||
new UploadFile() { FileName = "Test-File1.text" }
|
||||
});
|
||||
});
|
||||
|
||||
var button = cut.Find(".btn-zoom");
|
||||
await cut.InvokeAsync(() => button.Click());
|
||||
Assert.True(clicked);
|
||||
|
||||
cut.SetParametersAndRender(pb =>
|
||||
{
|
||||
pb.Add(a => a.ShowZoomButton, false);
|
||||
});
|
||||
cut.DoesNotContain("btn-zoom");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CardUpload_ValidateForm_Ok()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user