Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@blocksuite/editor

Package Overview
Dependencies
Maintainers
5
Versions
634
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@blocksuite/editor - npm Package Compare versions

Comparing version 0.3.0-20221224062401-54874d6 to 0.3.0-20221224075546-5606029

4

dist/components/editor-container/editor-container.d.ts
import { LitElement } from 'lit';
import type { Page } from '@blocksuite/store';
import { Page } from '@blocksuite/store';
import { ClipboardManager, ContentParser } from '../../index.js';

@@ -15,5 +15,3 @@ import type { MouseMode, PageBlockModel } from '@blocksuite/blocks';

private _disposables;
private _subscribeStore;
createRenderRoot(): this;
private _handleSwitchMouseMode;
connectedCallback(): void;

@@ -20,0 +18,0 @@ disconnectedCallback(): void;

@@ -10,2 +10,4 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {

import { choose } from 'lit/directives/choose.js';
import { Signal } from '@blocksuite/store';
import { DisposableGroup } from '@blocksuite/store';
import { ClipboardManager, ContentParser } from '../../index.js';

@@ -23,6 +25,3 @@ let EditorContainer = class EditorContainer extends LitElement {

this.contentParser = new ContentParser(this);
this._disposables = [];
this._handleSwitchMouseMode = ({ detail }) => {
this.mouseMode = detail;
};
this._disposables = new DisposableGroup();
}

@@ -32,8 +31,2 @@ get model() {

}
_subscribeStore() {
const rootAddedDisposable = this.page.signals.rootAdded.on(() => {
this.requestUpdate();
});
this._disposables.push(rootAddedDisposable);
}
// disable shadow DOM to workaround quill

@@ -45,12 +38,19 @@ createRenderRoot() {

super.connectedCallback();
window.addEventListener('keydown', e => {
// Question: Why do we prevent this?
this._disposables.add(Signal.fromEvent(window, 'keydown').on(e => {
if (e.altKey && e.metaKey && e.code === 'KeyC') {
e.preventDefault();
}
});
}));
if (!this.page) {
throw new Error('Missing page for EditorContainer!');
}
window.addEventListener('affine.switch-mouse-mode', this._handleSwitchMouseMode);
this._subscribeStore();
// connect mouse mode event changes
this._disposables.add(Signal.fromEvent(window, 'affine.switch-mouse-mode').on(({ detail }) => {
this.mouseMode = detail;
}));
// subscribe store
this._disposables.add(this.page.signals.rootAdded.on(() => {
this.requestUpdate();
}));
this._placeholderInput?.focus();

@@ -60,4 +60,4 @@ }

super.disconnectedCallback();
window.removeEventListener('affine.switch-mouse-mode', this._handleSwitchMouseMode);
this._disposables.forEach(disposable => disposable.dispose());
this._disposables.dispose();
this._disposables = new DisposableGroup();
}

@@ -64,0 +64,0 @@ render() {

@@ -27,3 +27,3 @@ import { marked } from 'marked';

const htmlContent = this.block2Html(this._getSelectedBlock(root).children);
FileExporter.exportMarkdown(root.title, htmlContent);
FileExporter.exportHtmlAsMarkdown(root.title, htmlContent);
}

@@ -30,0 +30,0 @@ block2Html(blocks) {

@@ -1,9 +0,26 @@

declare const FileExporter: {
injectHtmlCss: () => string;
exportFile: (filename: string, text: string, format: string) => void;
decorateHtml: (pageTitle: string, htmlContent: string) => string;
exportHtml: (pageTitle: string, htmlContent: string) => void;
exportMarkdown: (pageTitle: string, htmlContent: string) => void;
/** Tools for exporting files to device. For example, via browser download. */
export declare const FileExporter: {
/**
* Create a download for the user's browser.
*
* @param mimeType like `"text/plain"`, `"text/html"`, `"application/javascript"`, etc. See {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types mdn docs List of MIME types}.
*
* @remarks
* Only accepts data in utf-8 encoding (html files, javascript source, text files, etc).
*
* @example
* const todoMDText = `# Todo items
* [ ] Item 1
* [ ] Item 2
* `
* FileExporter.exportFile("Todo list.md", todoMDText, "text/plain")
*
* @example
* const stateJsonContent = JSON.stringify({ a: 1, b: 2, c: 3 })
* FileExporter.exportFile("state.json", jsonContent, "application/json")
*/
exportTextFile(filename: string, text: string, mimeType: string): void;
exportHtml(pageTitle: string | undefined, htmlContent: string): void;
exportHtmlAsMarkdown(pageTitle: string | undefined, htmlContent: string): void;
};
export { FileExporter };
//# sourceMappingURL=file-exporter.d.ts.map
import TurndownService from 'turndown';
const FileExporter = {
injectHtmlCss: () => {
//TODO why not use css file?
return `
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<style>
:root {
--affine-primary-color: #3a4c5c;
--affine-font-family: Avenir Next, apple-system, BlinkMacSystemFont, Helvetica Neue, Tahoma, PingFang SC, Microsoft Yahei, Arial, Hiragino Sans GB, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
--affine-font-family2: Roboto Mono, apple-system, BlinkMacSystemFont, Helvetica Neue, Tahoma, PingFang SC, Microsoft Yahei, Arial, Hiragino Sans GB, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
}
body {
font-family: var(--affine-font-family);
color: var(--affine-primary-color);
}
</style>
`;
},
exportFile: (filename, text, format) => {
// Context: Lean towards breaking out any localizable content into constants so it's
// easier to track content we may need to localize in the future. (i18n)
const UNTITLED_PAGE_NAME = 'Untitled';
/** Tools for exporting files to device. For example, via browser download. */
export const FileExporter = {
/**
* Create a download for the user's browser.
*
* @param mimeType like `"text/plain"`, `"text/html"`, `"application/javascript"`, etc. See {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types mdn docs List of MIME types}.
*
* @remarks
* Only accepts data in utf-8 encoding (html files, javascript source, text files, etc).
*
* @example
* const todoMDText = `# Todo items
* [ ] Item 1
* [ ] Item 2
* `
* FileExporter.exportFile("Todo list.md", todoMDText, "text/plain")
*
* @example
* const stateJsonContent = JSON.stringify({ a: 1, b: 2, c: 3 })
* FileExporter.exportFile("state.json", jsonContent, "application/json")
*/
exportTextFile(filename, text, mimeType) {
const element = document.createElement('a');
element.setAttribute('href', 'data:' + format + ';charset=utf-8,' + encodeURIComponent(text));
element.setAttribute('href', 'data:' + mimeType + ';charset=utf-8,' + encodeURIComponent(text));
// Consider if we should replace invalid characters in filenames before downloading, or if the browser
// will do that for us automatically...
// // replace illegal characters that cannot appear in file names
// const safeFilename = filename.replace(/[ <>:/|?*]+/g, " ")
element.setAttribute('download', filename);

@@ -29,22 +39,7 @@ element.style.display = 'none';

},
decorateHtml: (pageTitle, htmlContent) => {
const htmlCss = FileExporter.injectHtmlCss();
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>${pageTitle}</title>
${htmlCss}
</head>
<body>
<div style="margin:0 auto;width:720px" >
${htmlContent}
</div>
</body>
</html>`;
exportHtml(pageTitle, htmlContent) {
const title = pageTitle?.trim() || UNTITLED_PAGE_NAME;
FileExporter.exportTextFile(title + '.html', wrapHtmlWithHtmlDocumentText(title, htmlContent), 'text/html');
},
exportHtml: (pageTitle, htmlContent) => {
FileExporter.exportFile((pageTitle || 'Untitled') + '.html', FileExporter.decorateHtml(pageTitle, htmlContent), 'text/html');
},
exportMarkdown: (pageTitle, htmlContent) => {
exportHtmlAsMarkdown(pageTitle, htmlContent) {
const turndownService = new TurndownService();

@@ -60,6 +55,37 @@ turndownService.addRule('input', {

const markdown = turndownService.turndown(htmlContent);
FileExporter.exportFile((pageTitle || 'Undefined') + '.md', markdown, 'text/plain');
const title = pageTitle?.trim() || UNTITLED_PAGE_NAME;
FileExporter.exportTextFile(title + '.md', markdown, 'text/plain');
},
};
export { FileExporter };
/** @internal surround plain html content in a document with head and basic styles */
function wrapHtmlWithHtmlDocumentText(pageTitle, htmlContent) {
// Question: Why not embed css directly into html?
const htmlCss = `<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<style>
:root {
--affine-primary-color: #3a4c5c;
--affine-font-family: Avenir Next, apple-system, BlinkMacSystemFont, Helvetica Neue, Tahoma, PingFang SC, Microsoft Yahei, Arial, Hiragino Sans GB, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
--affine-font-family2: Roboto Mono, apple-system, BlinkMacSystemFont, Helvetica Neue, Tahoma, PingFang SC, Microsoft Yahei, Arial, Hiragino Sans GB, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
}
body {
font-family: var(--affine-font-family);
color: var(--affine-primary-color);
}
</style>`;
// Question: Do we really need the extra div container?
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>${pageTitle}</title>
${htmlCss}
</head>
<body>
<div style="margin:0 auto;padding:1rem;max-width:720px">
${htmlContent}
</div>
</body>
</html>
`;
}
//# sourceMappingURL=file-exporter.js.map
{
"name": "@blocksuite/editor",
"version": "0.3.0-20221224062401-54874d6",
"version": "0.3.0-20221224075546-5606029",
"description": "Default BlockSuite-based editor built for AFFiNE.",

@@ -11,4 +11,4 @@ "main": "dist/index.js",

"dependencies": {
"@blocksuite/blocks": "0.3.0-20221224062401-54874d6",
"@blocksuite/store": "0.3.0-20221224062401-54874d6",
"@blocksuite/blocks": "0.3.0-20221224075546-5606029",
"@blocksuite/store": "0.3.0-20221224075546-5606029",
"lit": "^2.3.1",

@@ -15,0 +15,0 @@ "marked": "^4.1.0",

@@ -5,3 +5,4 @@ import { html, LitElement } from 'lit';

import type { Page, Disposable } from '@blocksuite/store';
import { Page, Signal } from '@blocksuite/store';
import { DisposableGroup } from '@blocksuite/store';
import { ClipboardManager, ContentParser } from '../../index.js';

@@ -40,11 +41,4 @@ import type { MouseMode, PageBlockModel } from '@blocksuite/blocks';

private _disposables: Disposable[] = [];
private _disposables = new DisposableGroup();
private _subscribeStore() {
const rootAddedDisposable = this.page.signals.rootAdded.on(() => {
this.requestUpdate();
});
this._disposables.push(rootAddedDisposable);
}
// disable shadow DOM to workaround quill

@@ -55,14 +49,13 @@ createRenderRoot() {

private _handleSwitchMouseMode = ({ detail }: CustomEvent<MouseMode>) => {
this.mouseMode = detail;
};
override connectedCallback() {
super.connectedCallback();
window.addEventListener('keydown', e => {
if (e.altKey && e.metaKey && e.code === 'KeyC') {
e.preventDefault();
}
});
// Question: Why do we prevent this?
this._disposables.add(
Signal.fromEvent(window, 'keydown').on(e => {
if (e.altKey && e.metaKey && e.code === 'KeyC') {
e.preventDefault();
}
})
);

@@ -73,8 +66,15 @@ if (!this.page) {

window.addEventListener(
'affine.switch-mouse-mode',
this._handleSwitchMouseMode
// connect mouse mode event changes
this._disposables.add(
Signal.fromEvent(window, 'affine.switch-mouse-mode').on(({ detail }) => {
this.mouseMode = detail;
})
);
this._subscribeStore();
// subscribe store
this._disposables.add(
this.page.signals.rootAdded.on(() => {
this.requestUpdate();
})
);

@@ -86,8 +86,4 @@ this._placeholderInput?.focus();

super.disconnectedCallback();
window.removeEventListener(
'affine.switch-mouse-mode',
this._handleSwitchMouseMode
);
this._disposables.forEach(disposable => disposable.dispose());
this._disposables.dispose();
this._disposables = new DisposableGroup();
}

@@ -94,0 +90,0 @@

@@ -39,3 +39,6 @@ import { marked } from 'marked';

const htmlContent = this.block2Html(this._getSelectedBlock(root).children);
FileExporter.exportMarkdown((root as PageBlockModel).title, htmlContent);
FileExporter.exportHtmlAsMarkdown(
(root as PageBlockModel).title,
htmlContent
);
}

@@ -42,0 +45,0 @@

import TurndownService from 'turndown';
const FileExporter = {
injectHtmlCss: () => {
//TODO why not use css file?
return `
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<style>
:root {
--affine-primary-color: #3a4c5c;
--affine-font-family: Avenir Next, apple-system, BlinkMacSystemFont, Helvetica Neue, Tahoma, PingFang SC, Microsoft Yahei, Arial, Hiragino Sans GB, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
--affine-font-family2: Roboto Mono, apple-system, BlinkMacSystemFont, Helvetica Neue, Tahoma, PingFang SC, Microsoft Yahei, Arial, Hiragino Sans GB, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
}
body {
font-family: var(--affine-font-family);
color: var(--affine-primary-color);
}
</style>
`;
},
exportFile: (filename: string, text: string, format: string) => {
// Context: Lean towards breaking out any localizable content into constants so it's
// easier to track content we may need to localize in the future. (i18n)
const UNTITLED_PAGE_NAME = 'Untitled';
/** Tools for exporting files to device. For example, via browser download. */
export const FileExporter = {
/**
* Create a download for the user's browser.
*
* @param mimeType like `"text/plain"`, `"text/html"`, `"application/javascript"`, etc. See {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types mdn docs List of MIME types}.
*
* @remarks
* Only accepts data in utf-8 encoding (html files, javascript source, text files, etc).
*
* @example
* const todoMDText = `# Todo items
* [ ] Item 1
* [ ] Item 2
* `
* FileExporter.exportFile("Todo list.md", todoMDText, "text/plain")
*
* @example
* const stateJsonContent = JSON.stringify({ a: 1, b: 2, c: 3 })
* FileExporter.exportFile("state.json", jsonContent, "application/json")
*/
exportTextFile(filename: string, text: string, mimeType: string) {
const element = document.createElement('a');
element.setAttribute(
'href',
'data:' + format + ';charset=utf-8,' + encodeURIComponent(text)
'data:' + mimeType + ';charset=utf-8,' + encodeURIComponent(text)
);
// Consider if we should replace invalid characters in filenames before downloading, or if the browser
// will do that for us automatically...
// // replace illegal characters that cannot appear in file names
// const safeFilename = filename.replace(/[ <>:/|?*]+/g, " ")
element.setAttribute('download', filename);

@@ -36,27 +47,11 @@

},
decorateHtml: (pageTitle: string, htmlContent: string) => {
const htmlCss = FileExporter.injectHtmlCss();
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>${pageTitle}</title>
${htmlCss}
</head>
<body>
<div style="margin:0 auto;width:720px" >
${htmlContent}
</div>
</body>
</html>`;
},
exportHtml: (pageTitle: string, htmlContent: string) => {
FileExporter.exportFile(
(pageTitle || 'Untitled') + '.html',
FileExporter.decorateHtml(pageTitle, htmlContent),
exportHtml(pageTitle: string | undefined, htmlContent: string) {
const title = pageTitle?.trim() || UNTITLED_PAGE_NAME;
FileExporter.exportTextFile(
title + '.html',
wrapHtmlWithHtmlDocumentText(title, htmlContent),
'text/html'
);
},
exportMarkdown: (pageTitle: string, htmlContent: string) => {
exportHtmlAsMarkdown(pageTitle: string | undefined, htmlContent: string) {
const turndownService = new TurndownService();

@@ -72,10 +67,37 @@ turndownService.addRule('input', {

const markdown = turndownService.turndown(htmlContent);
FileExporter.exportFile(
(pageTitle || 'Undefined') + '.md',
markdown,
'text/plain'
);
const title = pageTitle?.trim() || UNTITLED_PAGE_NAME;
FileExporter.exportTextFile(title + '.md', markdown, 'text/plain');
},
};
export { FileExporter };
/** @internal surround plain html content in a document with head and basic styles */
function wrapHtmlWithHtmlDocumentText(pageTitle: string, htmlContent: string) {
// Question: Why not embed css directly into html?
const htmlCss = `<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css">
<style>
:root {
--affine-primary-color: #3a4c5c;
--affine-font-family: Avenir Next, apple-system, BlinkMacSystemFont, Helvetica Neue, Tahoma, PingFang SC, Microsoft Yahei, Arial, Hiragino Sans GB, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
--affine-font-family2: Roboto Mono, apple-system, BlinkMacSystemFont, Helvetica Neue, Tahoma, PingFang SC, Microsoft Yahei, Arial, Hiragino Sans GB, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
}
body {
font-family: var(--affine-font-family);
color: var(--affine-primary-color);
}
</style>`;
// Question: Do we really need the extra div container?
return `<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>${pageTitle}</title>
${htmlCss}
</head>
<body>
<div style="margin:0 auto;padding:1rem;max-width:720px">
${htmlContent}
</div>
</body>
</html>
`;
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc