본문으로 건너뛰기

편집 가능한 파일 뷰어

파일 뷰어(context.ui.registerFileViewer, 컨텍스트: UI 와 Shadow DOM 격리 참고)는 보여 주는 파일을 고칠 수도 있습니다 — 텍스트로 저장하는 그림, 보드, 다이어그램 같은 것입니다. 텍스트는 Baram 이 가집니다. 열린 탭이 텍스트의 주인이고, 저장 · 저장 안 됨 점 · 자동 저장 · 외부 변경 · 종료 확인은 소스로 고친 파일과 똑같이 동작합니다. 뷰어가 하는 일은 둘입니다 — 문서가 바뀌었다고 알리고, Baram 이 요청하면 텍스트를 돌려줍니다.

편집 가능한 뷰어는 trusted 티어 API 입니다. sandboxed 플러그인에는 뷰어 화면이 없습니다.

ctx.ui.registerFileViewer({
id: "board",
extensions: ["board"],
editable: true,
getText: (el) => serialize(boardOf(el)),
onMount(el, viewerCtx) {
const edit = viewerCtx.edit;
if (!edit) return drawReadOnly(el, viewerCtx.assetUrl);
showBoard(el, parse(edit.text), () => edit.markChanged());
},
onUpdate(el, viewerCtx) {
const edit = viewerCtx.edit;
if (edit && edit.text !== serialize(boardOf(el))) {
showBoard(el, parse(edit.text), () => edit.markChanged());
}
},
onUnmount(el) {
forget(el);
},
});

editable: true 에는 두 가지가 필요합니다. 없으면 registerFileViewer 가 activate 안에서 던지고 플러그인이 로드되지 않습니다.

  • getText(el) 함수
  • files 권한(files:readonly 로는 안 됩니다). files 를 요청하는 것은 설치 확인 창이 “이 플러그인은 파일을 고칠 수 있다” 고 사용자에게 알리는 방법입니다. 동의이지 격리가 아닙니다 — trusted 플러그인은 어느 쪽이든 앱의 권한으로 실행됩니다.

onMount 는 아래가 모두 맞을 때만 ctx.edit 을 받습니다. 아니면 같은 뷰어가 그것 없이 마운트되고, 그리기만 해야 합니다.

  • 뷰어를 editable: true 로 등록했습니다.
  • 파일이 Baram 이 다시 쓸 수 있는 텍스트입니다 — 마크다운, HTML(Baram 자신의 미리보기가 HTML 을 그립니다), 래스터 이미지, PDF 가 아닙니다(.svg 는 텍스트라서 해당됩니다).
  • 탭의 텍스트를 읽어 왔습니다. 그 전에는 아무것도, 읽기 전용 화면도 마운트되지 않습니다.

ctx.edit 에 실리는 것:

필드 뜻
tabId 이 마운트가 보여 주는 탭. 화면 상태를 보관할 열쇠로 씁니다
text 탭의 지금 텍스트. 저장 안 한 변경을 포함합니다 — 디스크의 파일이 아닙니다
markChanged() 문서가 바뀔 때마다 부릅니다. 아무것도 직렬화하지 않습니다

변경 알리기와 텍스트 돌려주기

섹션 제목: “변경 알리기와 텍스트 돌려주기”

바뀔 때마다 ctx.edit.markChanged() 를 부르십시오. 몇 번이든 괜찮습니다 — 그리는 동안 포인터가 움직일 때마다 불러도 됩니다. 첫 호출이 탭을 저장 안 됨으로 표시하고, 그 뒤의 호출은 비용 없이 자동 저장 지연만 다시 겁니다. 그래서 저장은 사용자가 멈춘 뒤에 일어납니다.

Baram 은 텍스트가 필요하고 아직 가져가지 않은 변경이 있을 때 getText(el) 를 부릅니다 — 예를 들어 저장할 때(다른 이름으로 저장 포함), 탭을 바꿀 때, 소스 보기로 바꿀 때, 파일 이름을 바꿀 때, 디스크에서 바뀐 파일과 비교할 때, 배율을 바꿀 때, 플러그인을 끌 때, 그리고 뷰어를 내리기 직전입니다. 한 번 가져간 뒤에는 다음 markChanged() 까지 다시 부르지 않습니다. getText 는:

  • 동기이고 빨라야 합니다 — 저장과 탭 전환 처리 안에서 돕니다.
  • 부작용이 없어야 합니다.
  • 레이아웃을 읽지 않아야 합니다 — el 이 문서에서 떨어진 뒤에 불릴 수 있습니다.

getText 가 던지거나 문자열이 아닌 값을 돌려주면 Baram 은 마지막으로 가져간 텍스트를 지키고, 그 탭을 소스 보기로 바꾸고, 뷰어의 마지막 변경이 반영되지 않았다는 메시지를 보입니다. 미리보기로 되돌리면 그 텍스트로 뷰어를 다시 마운트합니다.

편집 마운트에 onUpdate 가 오는 경우는 둘입니다 — 뷰어가 아닌 쪽이 텍스트를 바꿨을 때(탭에 저장 안 한 변경이 없는 동안 파일이 Baram 밖에서 바뀌었거나, 사용자가 충돌을 해결했을 때), 그리고 배율이 바뀌었을 때입니다. 둘 다 ctx.edit.text 에 지금 텍스트를 싣습니다 — 배율 변경이면 직전에 가져간 여러분 자신의 텍스트입니다. 자기 직렬화와 비교해 같으면 다시 그리지 마십시오.

여러분 자신의 저장은 onUpdate 를 보내지 않습니다. 읽기 전용 뷰어와 달리 편집 마운트는 자기 변경을 디스크에서 다시 읽지 않습니다.

탭을 떠나면 뷰어가 내려가고, 돌아오면 탭의 텍스트로 다시 마운트되어 저장 안 한 작업이 돌아옵니다. 텍스트에 없는 것 — 스크롤 위치, 고른 도구, 실행 취소 기록 — 은 ctx.edit.tabId 를 열쇠로 직접 보관하지 않으면 사라집니다. 소스 보기를 켰다 끄는 것도 같은 방식으로 다시 마운트합니다. 개발 빌드에서는 React 의 Strict Mode 가 뷰어가 처음 나타날 때 두 번 마운트합니다. 정상입니다.

  • 뷰어 안의 실행 취소는 여러분의 몫입니다. Baram 에는 뷰어 문서를 위한 실행 취소가 없습니다.
  • 버전 히스토리는 마크다운 파일만 담으므로, 여러분의 파일 형식에는 없습니다.
  • 열린 파일을 ctx.files.writeFile 로 쓰지 마십시오. 그것은 탭을 거치지 않습니다 — 저장 안 됨 점과 자동 저장이 알지 못하고, Baram 은 그것을 외부 변경으로 보아 탭을 다시 읽거나 충돌을 묻습니다. 열린 파일은 ctx.edit 으로 고치십시오.

Baram 저장소의 examples/plugins/sketch-pad 는 .strokes 파일에 선을 긋습니다. 빌드 단계 없는 파일 하나이고, 위의 항목을 모두 보여 줍니다 — 포인터가 움직일 때마다의 markChanged(), 레이아웃을 읽지 않는 getText, 다른 텍스트일 때만 다시 그리기, 탭별로 보관하는 펜 굵기.