Loda fayil
Yana haɗa zaɓen fayil, ja da saukewa, da liƙa abin da fayiloli kawai suke ciki zuwa tsarin loda fayil. Demo na wannan shafi ba ya aika komai zuwa sabar; a sabis ɗinka dole ne ka haɗa mai loda fayil da kan ka wanda zai karɓi fayil ya mayar da URL.
Domin saka sakamakon loda a matsayin tubalin hoto, ana bukatar wing ɗin hoto; domin saka sauran fayiloli a matsayin mahaɗin abin da aka haɗa, ana bukatar wing ɗin mahaɗi. Idan sabis yana karɓar nau'ikan biyu, zaɓi wings ɗin biyu a bayyane tare. Yayin lodawa editan yana kulle, kuma fayilolin da suka yi nasara suna shiga tare a mataki guda na soke aiki.
npm install nabi-noteimport {
createLocale, createNabiWith, mountSurface, mountToolbar,
mountContextToolbar, mountHints, watchSettle, boldWing, italicWing,
underlineWing, strikeWing, linkWing, imageWing, uploadWing,
clearFormatWing, mountUpload, mountUploadView, mountViewTools,
} from 'nabi-note'
const selected = [
boldWing,
italicWing,
underlineWing,
strikeWing,
linkWing,
imageWing,
uploadWing,
clearFormatWing,
]
const locale = createLocale('ha')
const { nabi, registry } = createNabiWith(selected, { locale })
const root = document.querySelector('.nabi')!
const content = document.querySelector('.nabi-content')!
const view = mountUploadView({ nabi, surface: content, locale })
const upload = mountUpload({
nabi, root: content, locale,
// your upload goes here — report progress with task.onProgress(0–100)
uploader: async (task) => ({ uri: 'https://cdn.example/uploaded' }),
extensions: ['png', 'jpg', 'pdf'], maxFileSize: 10 * 1024 * 1024,
onStart: (tasks) => view.start(tasks),
onProgress: (id, percent) => view.progress(id, percent),
onSettle: () => view.settle(),
onDone: () => view.done(),
})
// The locale also sets the direction — Arabic and Urdu run right to left
mountSurface({ nabi, registry, root: content, locale, fileSink: upload.take })
const settle = watchSettle(document, { surface: content })
const shared = { nabi, registry, surface: content, settle, locale }
const toolbar = mountToolbar({ ...shared, root: document.querySelector('#toolbar')!, onFiles: upload.take })
const context = mountContextToolbar({ ...shared, root: document.querySelector('#context')! })
mountHints({ toolbar, context, root, surface: content })
// The preview and fullscreen buttons — they stand their own box at the end of the row
mountViewTools({ ...shared, root, container: document.querySelector('#toolbar')! })
// on every change — hook up your own code here
// nabi.onChange(() => user_callback(nabi.getHtml()))
// Call from your language selector. Content and editing history stay intact.
// locale.setLocale('ko')const selected = wings()
.use('img')
.use('a')
.use('upload', { allowLocalUrls: false })
.build()Idan ka zaɓi upload shi kaɗai, zai ƙara ɗaya daga dogarorin hoto da mahaɗi wanda ba ya nan ta atomatik. Ana haɗa tura fayil da mountUpload(), kuma galibi ana haɗa nunin ci gaba na allon edita da mountUploadView(). Idan sabar ta mayar da URL na HTTPS, ba a bukatar zaɓin yarda da URL na gida.
Wurin saka fayilolin da aka loda
Ana tuna wurin da aka buɗe zaɓen fayil ko aka fara lodawa. Idan siginar rubutu kawai aka matsar, ana sakawa a wurin farko. Idan lodawa ta fara a sel na tebur, alamar ci gaba da abin da aka gama suna nan cikin sel ɗin. Sakamakon lodawa da aka fara a yankin iyo ma yana shiga yankin. Ba za a saka lodawa a zaɓin da ya ketare iyakokin sel da yawa ba.
Gyara ko maye gurbin takarda yayin zaɓen fayil ko aiki na bayan fage yana soke sakawa tare da sanarwa. Ko soke aiki ya dawo da abun ciki iri ɗaya, ba a sake sakawa a tsohon wurin. Kada ka tantance kammalawa daga nasarar aikawa kaɗai: bincika committed da cancelled da onDone yake karɓa. committed shi ne yawan fayilolin da suka shiga takarda da gaske.
Yarjejeniyar API na sabar
NABI NOTE ba ya aika fayil zuwa sabar. Aikin uploader ne yake aika fayil guda zuwa sabar, kuma idan ya yi nasara ya mayar da URL na https: wanda jama'a ko masu izini kawai za su iya samu. Yarjejeniyar API mafi sauƙi ita ce kamar haka.
POST /api/uploads
Content-Type: multipart/form-data
Sunan fili: file
Nasara: { "url": "https://cdn.example.com/uploads/8f2c.webp" }
Kuskure: amsar 4xx ko 5xxKada sabar ta amince da asalin sunan fayil, tsawo, ko MIME da mai bincike ya aiko kawai. Dole ne ta fara bincika tabbatarwa da izini, ta iyakance girman fayil a lokacin gudana, kuma ta duba ainihin nau'in fayil. Sabar ce za ta ƙirƙiri sabon sunan ajiya, kuma idan hoto ne za ta iya sake tsarawa ko ƙirƙirar ƙaramin hoto yadda ya dace. Idan wasu ba za su iya sauke fayilolin da aka loda ba, mayar da hanyar saukewa mai bukatar tabbatarwa maimakon URL.
| Abin da za a bincika a sabar | Dalili |
|---|---|
| Mai amfani da ya shiga da izinin loda | Hana amfani da wurin ajiyar wasu masu amfani |
| Girman fayil guda da dukan buƙata | Hana ƙarewar ƙwaƙwalwa da wurin ajiya |
| Ainihin MIME da tsawon da aka yarda | Tare fayil mai zartarwa da aka canza sunansa |
| Sunan ajiya bazuwar da ma'ajiyar rabuwa | Hana sarrafa hanya da maye gurbin fayil da yake akwai |
| Izinin samun URL na amsa da manufofin ƙarewa | Hana bayyanar fayil na sirri saboda URL kawai |
extensions da maxFileSize na abokin ciniki mataki ne na farko kawai don sanar da mai amfani da sauri. Dole ne ka sa irin wannan iyaka a sabar ma.
Haɗa mai loda a mai bincike
Misalin da ke ƙasa shi ne ainihin haɗawar da NABI NOTE yake tsammani. Dalilin amfani da XMLHttpRequest shi ne fetch() na asali a mai bincike ba ya ba da ci gaban loda fayil. Idan kawai ka mayar da url da sabar ta amsa, hoto zai shiga tubalin hoto, sauran fayiloli kuma za su shiga mahaɗin abin da aka haɗa.
import {
createNabiWith,
mountSurface,
mountToolbar,
mountUpload,
mountUploadView,
wings,
type UploadTask,
} from 'nabi-note'
const content = document.querySelector<HTMLElement>('#content')!
const { nabi, registry } = createNabiWith(
wings().use('img').use('a').use('upload').build(),
{ locale: 'ha' },
)
function sendUpload(task: UploadTask): Promise<{ uri: string } | null> {
return new Promise((resolve, reject) => {
const request = new XMLHttpRequest()
request.open('POST', '/api/uploads')
request.responseType = 'json'
request.upload.addEventListener('progress', (event) => {
if (event.lengthComputable) task.onProgress((event.loaded / event.total) * 100)
})
request.addEventListener('load', () => {
const url = request.response?.url
if (request.status >= 200 && request.status < 300 && typeof url === 'string') {
resolve({ uri: url })
} else {
resolve(null)
}
})
request.addEventListener('error', () => reject(new Error('Buƙatar loda fayil ta kasa.')))
task.signal.addEventListener('abort', () => request.abort(), { once: true })
const body = new FormData()
body.append('file', task.file as File, task.name)
request.send(body)
})
}
let uploadView: ReturnType<typeof mountUploadView>
const upload = mountUpload({
nabi,
root: content,
uploader: sendUpload,
extensions: ['png', 'jpg', 'jpeg', 'webp', 'pdf'],
maxFileSize: 10 * 1024 * 1024,
maxTotalSize: 20 * 1024 * 1024,
locale: 'ha',
onStart: (tasks) => uploadView.start(tasks),
onProgress: (id, percent) => uploadView.progress(id, percent),
onSettle: () => uploadView.settle(),
onDone: () => uploadView.done(),
})
uploadView = mountUploadView({ nabi, surface: content, upload, locale: 'ha' })
const surface = mountSurface({
nabi,
registry,
root: content,
fileSink: upload.take,
locale: 'ha',
})
const toolbar = mountToolbar({
nabi,
registry,
root: document.querySelector<HTMLElement>('#toolbar')!,
surface: content,
onFiles: upload.take,
locale: 'ha',
})Haɗa fileSink: upload.take domin ja da saukewa da liƙa fayiloli kawai su shiga tsarin lodawa. Haɗa maɓallin zaɓen fayil da onFiles: upload.take na sandar kayan aiki. Yayin lodawa editan yana kulle, kuma fayilolin da suka yi nasara suna shiga a matakin soke aiki ɗaya ga kowace rukuni. upload.cancel() ko maɓallin soke na uploadView suna katse buƙatun da ke gudana ta AbortSignal.
Kuskure da cire allo
Idan sabar ta ba da amsar kuskure ko uploader ya mayar da null, ba a saka wannan fayil cikin daftari. Sauran fayiloli a batch iri ɗaya suna ci gaba da aiki. Idan an wuce iyakar dukan girma, batch ɗin gaba ɗaya ba zai fara ba. Lokacin rufe allo, cire haɗin a kishiyar tsarin ƙirƙira.
function dispose() {
toolbar.unmount()
surface.unmount()
uploadView.unmount()
upload.unmount()
}A lokacin haɓakawa kawai za ka iya amfani da URL na blob: don ƙirƙirar samfoti nan da nan. A wannan yanayin, dole ne ka kunna allowLocalUrls: true a haɗawar edita, wing ɗin hoto, da wing ɗin loda bi da bi. Idan ainihin lodawa zuwa sabar tana mayar da URL na HTTPS, ya fi aminci kada ka kunna wannan zaɓi.
Tsarin CSS
Ana nuna kammalallen fayil na yau da kullum da a[data-nabi-file] na wing ɗin mahaɗi. Domin canza kamannin abin da aka haɗa kawai a shafin wallafa, yi amfani da wannan zaɓaɓɓen.
.article-body a[data-nabi-file] {
padding: .3em .6em;
border: 1px solid var(--nabi-line);
border-radius: 8px;
background: var(--nabi-soft);
}Sakamakon loda hoto yana bin CSS na wing ɗin hoto. Ana nuna ci gaban loda ne kawai a allon edita, saboda haka ba a bukatar ƙirƙirar yanayin ci gaba da CSS na shafin wallafa.